plugins/kolab_files
Aleksander Machniak
machniak at kolabsys.com
Wed Oct 15 16:09:02 CEST 2014
plugins/kolab_files/kolab_files.js | 285 ++++++++--
plugins/kolab_files/lib/kolab_files_engine.php | 137 ++++
plugins/kolab_files/localization/en_US.inc | 7
plugins/kolab_files/package.xml | 4
plugins/kolab_files/skins/larry/style.css | 38 +
plugins/kolab_files/skins/larry/templates/compose_plugin.html | 4
plugins/kolab_files/skins/larry/templates/files.html | 14
plugins/kolab_files/skins/larry/templates/message_plugin.html | 4
8 files changed, 432 insertions(+), 61 deletions(-)
New commits:
commit 35814a47fcd70507de425555395f65ec321e6236
Author: Aleksander Machniak <machniak at kolabsys.com>
Date: Tue Oct 14 14:12:09 2014 -0400
Support multi-driver capabilities of Chwala (#3774)
diff --git a/plugins/kolab_files/kolab_files.js b/plugins/kolab_files/kolab_files.js
index a525c39..898a682 100644
--- a/plugins/kolab_files/kolab_files.js
+++ b/plugins/kolab_files/kolab_files.js
@@ -118,6 +118,7 @@ window.rcmail && rcmail.addEventListener('init', function() {
else {
file_api.folder_list();
file_api.browser_capabilities_check();
+ rcmail.enable_command('folder-mount', rcmail.env.external_sources);
}
}
});
@@ -340,11 +341,7 @@ function kolab_files_folder_create_dialog()
// show dialog window
kolab_dialog_show(dialog, {
title: rcmail.gettext('kolab_files.foldercreate'),
- buttons: buttons,
- minWidth: 400,
- minHeight: 300,
- width: 500,
- height: 400
+ buttons: buttons
});
// Fix submitting form with Enter
@@ -365,6 +362,61 @@ function kolab_files_folder_create_dialog()
});
};
+// folder mounting dialog
+function kolab_files_folder_mount_dialog()
+{
+ var args = {buttons: {}, title: rcmail.gettext('kolab_files.foldermount')},
+ dialog = $('#files-folder-mount-dialog'),
+ input = $('#folder-mount-name').val('');
+
+ args.buttons[rcmail.gettext('kolab_files.save')] = function () {
+ var args = {}, folder = input.val(),
+ driver = $('input[name="driver"]:checked', dialog).val();
+
+ if (!folder || !driver)
+ return;
+
+ args.folder = folder;
+ args.driver = driver;
+
+ $('#source-' + driver + ' input').each(function() {
+ if (this.name.startsWith(driver + '[')) {
+ args[this.name.substring(driver.length + 1, this.name.length - 1)] = this.value;
+ }
+ });
+
+ file_api.folder_mount(args);
+ kolab_dialog_close(this);
+ };
+
+ args.buttons[rcmail.gettext('kolab_files.cancel')] = function () {
+ kolab_dialog_close(this);
+ };
+
+ // close folderoption menu
+ rcmail.hide_menu('folderoptions');
+
+ // initialize drivers list
+ if (!rcmail.drivers_list_initialized) {
+ rcmail.drivers_list_initialized = true;
+
+ $('td.source', dialog).each(function() {
+ $(this).click(function() {
+ $('td.selected', dialog).removeClass('selected');
+ dialog.find('.driverform').hide();
+ $(this).addClass('selected').find('.driverform').show();
+ $('input[type="radio"]', this).prop('checked', true);
+ });
+ });
+ }
+
+ // show dialog window
+ kolab_dialog_show(dialog, args, function() {
+ $('td.source:first', dialog).click();
+ input.focus();
+ });
+};
+
// file edition dialog
function kolab_files_file_edit_dialog(file)
{
@@ -901,6 +953,11 @@ rcube_webmail.prototype.folder_create = function()
kolab_files_folder_create_dialog();
};
+rcube_webmail.prototype.folder_mount = function()
+{
+ kolab_files_folder_mount_dialog();
+};
+
/**********************************************************/
/********* Files API handler **********/
@@ -968,36 +1025,10 @@ function kolab_files_ui()
elem.html('').append(list);
- this.env.folders = this.folder_list_parse(response.result);
+ this.env.folders = this.folder_list_parse(response.result ? response.result.list : []);
$.each(this.env.folders, function(i, f) {
- var row = $('<li class="mailbox"><span class="branch"></span></li>');
-
- row.attr('id', f.id).data('folder', i)
- .append($('<span class="name"></span>').text(f.name));
-
- if (f.depth) {
- $('span.branch', row).width(15 * f.depth);
- row.addClass('child');
- }
-
- if (f.virtual)
- row.addClass('virtual');
- else
- row.attr('tabindex', 0)
- .keypress(function(e) { if (e.which == 13 || e.which == 32) file_api.folder_select(i); })
- .click(function() { file_api.folder_select(i); })
- .mouseenter(function() {
- if (rcmail.file_list && rcmail.file_list.drag_active && !$(this).hasClass('selected'))
- $(this).addClass('droptarget');
- })
- .mouseleave(function() {
- if (rcmail.file_list && rcmail.file_list.drag_active)
- $(this).removeClass('droptarget');
- });
-
- list.append(row);
-
+ list.append(file_api.folder_list_row(i, f));
if (!first)
first = i;
});
@@ -1013,16 +1044,19 @@ function kolab_files_ui()
list.append(row);
});
- // select first folder?
- 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);
+ // select first folder?
+ 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);
+
+ // handle authentication errors on external sources
+ this.folder_list_auth_errors(response.result);
};
this.folder_select = function(folder, is_collection)
@@ -1070,6 +1104,36 @@ function kolab_files_ui()
this.env.collection = null;
};
+ this.folder_list_row = function(i, folder)
+ {
+ var row = $('<li class="mailbox"><span class="branch"></span></li>');
+
+ row.attr('id', folder.id).data('folder', i)
+ .append($('<span class="name"></span>').text(folder.name));
+
+ if (folder.depth) {
+ $('span.branch', row).width(15 * folder.depth);
+ row.addClass('child');
+ }
+
+ if (folder.virtual)
+ row.addClass('virtual');
+ else
+ row.attr('tabindex', 0)
+ .keypress(function(e) { if (e.which == 13 || e.which == 32) file_api.folder_select(i); })
+ .click(function() { file_api.folder_select(i); })
+ .mouseenter(function() {
+ if (rcmail.file_list && rcmail.file_list.drag_active && !$(this).hasClass('selected'))
+ $(this).addClass('droptarget');
+ })
+ .mouseleave(function() {
+ if (rcmail.file_list && rcmail.file_list.drag_active)
+ $(this).removeClass('droptarget');
+ });
+
+ return row;
+ };
+
// folder create request
this.folder_create = function(folder)
{
@@ -1089,6 +1153,25 @@ function kolab_files_ui()
this.folder_list();
};
+ // folder mount (external storage) request
+ this.folder_mount = function(data)
+ {
+ this.req = this.set_busy(true, 'kolab_files.foldermounting');
+ this.request('folder_create', data, 'folder_mount_response');
+ };
+
+ // folder create response handler
+ this.folder_mount_response = function(response)
+ {
+ if (!this.response(response))
+ return;
+
+ this.display_message('kolab_files.foldermountnotice', 'confirmation');
+
+ // refresh folders list
+ this.folder_list();
+ };
+
// folder delete request
this.folder_delete = function(folder)
{
@@ -1727,4 +1810,126 @@ function kolab_files_ui()
}
};
+ // handle auth errors on folder list
+ this.folder_list_auth_errors = function(result)
+ {
+ if (result && result.auth_errors) {
+ if (!this.auth_errors)
+ this.auth_errors = {};
+
+ $.extend(this.auth_errors, result.auth_errors);
+ }
+
+ // ask for password to the first storage on the list
+ $.each(this.auth_errors || [], function(i, v) {
+ file_api.folder_list_auth_dialog(i, v);
+ return false;
+ });
+ };
+
+ // create dialog for user credentials of external storage
+ this.folder_list_auth_dialog = function(label, driver)
+ {
+ var args = {width: 400, height: 300, buttons: {}},
+ dialog = $('#files-folder-auth-dialog'),
+ content = this.folder_list_auth_form(driver);
+
+ dialog.find('table.propform').remove();
+ dialog.append(content);
+
+ args.buttons[this.t('kolab_files.save')] = function() {
+ var data = {folder: label, list: 1};
+
+ $('input', dialog).each(function() {
+ data[this.name] = this.value;
+ });
+
+ file_api.open_dialog = this;
+ file_api.req = file_api.set_busy(true, 'kolab_files.authenticating');
+ file_api.request('folder_auth', data, 'folder_auth_response');
+ };
+
+ args.buttons[this.t('kolab_files.cancel')] = function() {
+ delete file_api.auth_errors[label];
+ kolab_dialog_close(this);
+ // go to the next one
+ file_api.folder_list_auth_errors();
+ };
+
+ args.title = this.t('kolab_files.folderauthtitle').replace('$title', label);
+
+ // show dialog window
+ kolab_dialog_show(dialog, args, function() {
+ // focus first empty input
+ $('input', dialog).each(function() {
+ if (!this.value) {
+ this.focus();
+ return false;
+ }
+ });
+ });
+ };
+
+ // folder_auth handler
+ this.folder_auth_response = function(response)
+ {
+ if (!this.response(response))
+ return;
+
+ var cnt = 0, folders,
+ folder = response.result.folder,
+ parent = $('#' + this.env.folders[folder].id);
+
+ // try parent window if the folder element does not exist
+ if (!parent.length && window.parent && window.parent.rcmail) {
+ parent = $('#' + this.env.folders[folder].id, window.parent.document.body);
+ }
+
+ delete this.auth_errors[folder];
+ kolab_dialog_close(this.open_dialog);
+
+ // go to the next one
+ this.folder_list_auth_errors();
+
+ // count folders on the list
+ $.each(this.env.folders, function() { cnt++; });
+
+ // parse result
+ folders = this.folder_list_parse(response.result.list, cnt);
+ delete folders[folder]; // remove root added in folder_list_parse()
+
+ // add folders from the external source to the list
+ $.each(folders, function(i, f) {
+ var row = file_api.folder_list_row(i, f);
+ parent.after(row);
+ parent = row;
+ });
+
+ // add tree icons
+ this.folder_list_tree(folders);
+
+ $.extend(this.env.folders, folders);
+ };
+
+ // returns content of the external storage authentication form
+ this.folder_list_auth_form = function(driver)
+ {
+ var rows = [];
+
+ $.each(driver.form, function(fi, fv) {
+ var id = 'authinput' + fi,
+ attrs = {type: fi.match(/pass/) ? 'password' : 'text', size: 25, name: fi, id: id},
+ input = $('<input>').attr(attrs);
+
+ if (driver.form_values && driver.form_values[fi])
+ input.attr({value: driver.form_values[fi]});
+
+ rows.push($('<tr>')
+ .append($('<td class="title">').append($('<label>').attr('for', id).text(fv)))
+ .append($('<td>').append(input))
+ );
+ });
+
+ return $('<table class="propform">').append(rows);
+ };
};
diff --git a/plugins/kolab_files/lib/kolab_files_engine.php b/plugins/kolab_files/lib/kolab_files_engine.php
index 8cb408b..4dce8eb 100644
--- a/plugins/kolab_files/lib/kolab_files_engine.php
+++ b/plugins/kolab_files/lib/kolab_files_engine.php
@@ -26,7 +26,7 @@ class kolab_files_engine
{
private $plugin;
private $rc;
- private $timeout = 60;
+ private $timeout = 600;
private $sort_cols = array('name', 'mtime', 'size');
/**
@@ -34,9 +34,10 @@ class kolab_files_engine
*/
public function __construct($plugin, $url)
{
- $this->url = rcube_utils::resolve_url($url);
- $this->plugin = $plugin;
- $this->rc = $plugin->rc;
+ $this->url = rcube_utils::resolve_url($url);
+ $this->plugin = $plugin;
+ $this->rc = $plugin->rc;
+ $this->timeout = $this->rc->config->get('session_lifetime') * 60;
}
/**
@@ -85,11 +86,15 @@ class kolab_files_engine
$this->plugin->add_label('save', 'cancel', 'saveto',
'saveall', 'fromcloud', 'attachsel', 'selectfiles', 'attaching',
- 'collection_audio', 'collection_video', 'collection_image', 'collection_document'
+ 'collection_audio', 'collection_video', 'collection_image', 'collection_document',
+ 'folderauthtitle', 'authenticating'
);
}
else if ($this->rc->task == 'files') {
$template = 'files';
+
+ // get list of external sources
+ $this->get_external_storage_drivers();
}
// add taskbar button
@@ -114,6 +119,7 @@ class kolab_files_engine
// register template objects for dialogs (and main interface)
$this->rc->output->add_handlers(array(
'folder-create-form' => array($this, 'folder_create_form'),
+ 'folder-mount-form' => array($this, 'folder_mount_form'),
'file-search-form' => array($this, 'file_search_form'),
'file-edit-form' => array($this, 'file_edit_form'),
'filelist' => array($this, 'file_list'),
@@ -165,9 +171,9 @@ class kolab_files_engine
$select_parent = new html_select(array('id' => 'folder-parent', 'name' => 'parent'));
$table = new html_table(array('cols' => 2, 'class' => 'propform'));
- $table->add('title', html::label('folder-name', Q($this->plugin->gettext('foldername'))));
+ $table->add('title', html::label('folder-name', rcube::Q($this->plugin->gettext('foldername'))));
$table->add(null, $input_name->show());
- $table->add('title', html::label('folder-parent', Q($this->plugin->gettext('folderinside'))));
+ $table->add('title', html::label('folder-parent', rcube::Q($this->plugin->gettext('folderinside'))));
$table->add(null, $select_parent->show());
$out = $table->show();
@@ -184,6 +190,72 @@ class kolab_files_engine
}
/**
+ * Template object for folder mounting form
+ */
+ public function folder_mount_form($attrib)
+ {
+ $sources = $this->rc->output->get_env('external_sources');
+
+ if (empty($sources) || !is_array($sources)) {
+ return '';
+ }
+
+ $attrib['name'] = 'folder-mount-form';
+ if (empty($attrib['id'])) {
+ $attrib['id'] = 'folder-mount-form';
+ }
+
+ // build form content
+ $table = new html_table(array('cols' => 2, 'class' => 'propform'));
+ $input_name = new html_inputfield(array('id' => 'folder-mount-name', 'name' => 'name', 'size' => 30));
+ $input_driver = new html_radiobutton(array('name' => 'driver', 'size' => 30));
+
+ $table->add('title', html::label('folder-mount-name', rcube::Q($this->plugin->gettext('name'))));
+ $table->add(null, $input_name->show());
+
+ foreach ($sources as $key => $source) {
+ $id = 'source-' . $key;
+ $form = new html_table(array('cols' => 2, 'class' => 'propform driverform'));
+
+ foreach ((array) $source['form'] as $idx => $label) {
+ $iid = $id . '-' . $idx;
+ $type = stripos($idx, 'pass') !== false ? 'html_passwordfield' : 'html_inputfield';
+ $input = new $type(array('size' => 30));
+
+ $form->add('title', html::label($iid, rcube::Q($label)));
+ $form->add(null, $input->show('', array(
+ 'id' => $iid,
+ 'name' => $key . '[' . $idx . ']'
+ )));
+ }
+
+ $row = $input_driver->show(null, array('value' => $key))
+ . html::img(array('src' => $source['image'], 'alt' => $key, 'title' => $source['name']))
+ . html::div(null, html::span('name', rcube::Q($source['name']))
+ . html::br()
+ . html::span('description', rcube::Q($source['description']))
+ . $form->show()
+ );
+
+ $table->add(array('id' => $id, 'colspan' => 2, 'class' => 'source'), $row);
+ }
+
+ $out = $table->show();
+
+ // add form tag around text field
+ if (empty($attrib['form'])) {
+ $out = $this->rc->output->form_tag($attrib, $out);
+ }
+
+ $this->plugin->add_label('foldermounting', 'foldermountnotice', 'foldermount',
+ 'save', 'cancel', 'folderauthtitle', 'authenticating'
+ );
+ $this->rc->output->add_gui_object('folder-mount-form', $attrib['id']);
+
+ return $out;
+ }
+
+ /**
* Template object for file_edit form
*/
public function file_edit_form($attrib)
@@ -193,10 +265,10 @@ class kolab_files_engine
$attrib['id'] = 'file-edit-form';
}
- $input_name = new html_inputfield(array('id' => 'file-name', 'name' => 'name', 'size' => 30));
- $table = new html_table(array('cols' => 2, 'class' => 'propform'));
+ $input_name = new html_inputfield(array('id' => 'file-name', 'name' => 'name', 'size' => 30));
+ $table = new html_table(array('cols' => 2, 'class' => 'propform'));
- $table->add('title', html::label('file-name', Q($this->plugin->gettext('filename'))));
+ $table->add('title', html::label('file-name', rcube::Q($this->plugin->gettext('filename'))));
$table->add(null, $input_name->show());
$out = $table->show();
@@ -367,7 +439,7 @@ class kolab_files_engine
$col_name = $list_menu;
break;
default:
- $col_name = Q($this->plugin->gettext($col));
+ $col_name = rcube::Q($this->plugin->gettext($col));
}
// make sort links
@@ -511,6 +583,7 @@ class kolab_files_engine
}
}
catch (Exception $e) {
+ rcube::raise_error($e, true, false);
$quota = array('total' => 0, 'percent' => 0);
}
@@ -530,12 +603,12 @@ class kolab_files_engine
$time = $_SESSION['kolab_files_time'];
if ($token && time() - $this->timeout < $time) {
- return $token;
+ if (time() - $time <= $this->timeout / 2) {
+ return $token;
+ }
}
- if (!($request = $this->get_request())) {
- return $token;
- }
+ $request = $this->get_request(array('method' => 'ping'), $token);
try {
$url = $request->getUrl();
@@ -950,7 +1023,7 @@ class kolab_files_engine
));
}
else {
- $button = Q($this->rc->gettext('delete'));
+ $button = rcube::Q($this->rc->gettext('delete'));
}
$content = html::a(array(
@@ -960,7 +1033,7 @@ class kolab_files_engine
'class' => 'delete',
), $button);
- $content .= Q($attachment['name']);
+ $content .= rcube::Q($attachment['name']);
$this->rc->output->command('add2attachment_list', "rcmfile$id", array(
'html' => $content,
@@ -1017,4 +1090,34 @@ class kolab_files_engine
return $mimetypes;
}
+
+ /**
+ * Get list of available external storage drivers
+ */
+ protected function get_external_storage_drivers()
+ {
+ // first get configured sources from Chwala
+ $token = $this->get_api_token();
+ $request = $this->get_request(array('method' => 'folder_types'), $token);
+
+ // send request to the API
+ try {
+ $response = $request->send();
+ $status = $response->getStatus();
+ $body = @json_decode($response->getBody(), true);
+
+ if ($status == 200 && $body['status'] == 'OK') {
+ $sources = $body['result'];
+ }
+ else {
+ throw new Exception($body['reason']);
+ }
+ }
+ catch (Exception $e) {
+ rcube::raise_error($e, true, false);
+ return;
+ }
+
+ $this->rc->output->set_env('external_sources', $sources);
+ }
}
diff --git a/plugins/kolab_files/localization/en_US.inc b/plugins/kolab_files/localization/en_US.inc
index a1fc814..3ecd1fc 100644
--- a/plugins/kolab_files/localization/en_US.inc
+++ b/plugins/kolab_files/localization/en_US.inc
@@ -20,6 +20,7 @@ $labels['fromcloud'] = 'From cloud...';
$labels['selectfiles'] = 'Select file(s) to attach...';
$labels['attachsel'] = 'Attach selected';
$labels['foldercreate'] = 'Create folder';
+$labels['foldermount'] = 'Add storage';
$labels['folderrename'] = 'Rename folder';
$labels['folderdelete'] = 'Delete folder';
@@ -51,11 +52,15 @@ $labels['collection_document'] = 'Documents';
$labels['uploading'] = 'Uploading file(s)...';
$labels['attaching'] = 'Attaching file(s)...';
+$labels['authenticating'] = 'Authenticating...';
$labels['foldercreating'] = 'Creating folder...';
+$labels['foldermounting'] = 'Adding external storage...';
$labels['folderdeleting'] = 'Deleting folder...';
$labels['folderdeleteconfirm'] = 'Are you sure you want to delete selected folder?';
$labels['folderdeletenotice'] = 'Folder deleted successfully.';
$labels['foldercreatenotice'] = 'Folder created successfully.';
+$labels['foldermountnotice'] = 'Storage added successfully.';
+$labels['folderauthtitle'] = 'Logon to $title';
$labels['saveallnotice'] = 'Successfully saved $n file(s).';
$labels['saveallerror'] = 'Saving $n file(s) failed.';
$labels['attacherror'] = 'Failed to attach file(s) from the cloud';
@@ -82,6 +87,8 @@ $labels['arialabellistoptions'] = 'Files list options';
$labels['arialabelfolderoptions'] = 'Folder actions';
$labels['arialabelfileeditform'] = 'File editing form';
$labels['arialabelfoldercreateform'] = 'Folder creation form';
+$labels['arialabelfoldermountform'] = 'External storage form';
+$labels['arialabelfolderauthform'] = 'External storage authentication form';
$labels['arialabelfolderlist'] = 'Folder/Collection selection';
$labels['arialabelfileselectdialog'] = 'File selection dialog';
$labels['arialabelattachmentoptions'] = 'Attachment save options';
diff --git a/plugins/kolab_files/package.xml b/plugins/kolab_files/package.xml
index 8ac6e5b..e8552ea 100644
--- a/plugins/kolab_files/package.xml
+++ b/plugins/kolab_files/package.xml
@@ -13,9 +13,9 @@
<email>machniak at kolabsys.com</email>
<active>yes</active>
</lead>
- <date>2013-08-25</date>
+ <date>2014-10-15</date>
<version>
- <release>1.0</release>
+ <release>1.1</release>
<api>1.0</api>
</version>
<stability>
diff --git a/plugins/kolab_files/skins/larry/style.css b/plugins/kolab_files/skins/larry/style.css
index 20621e8..de0735c 100644
--- a/plugins/kolab_files/skins/larry/style.css
+++ b/plugins/kolab_files/skins/larry/style.css
@@ -293,6 +293,8 @@
#files-dialog,
#files-compose-dialog,
#files-file-edit-dialog,
+#files-folder-mount-dialog,
+#files-folder-auth-dialog,
#files-folder-create-dialog {
display: none;
}
@@ -362,3 +364,39 @@ a.filesaveall {
ul.toolbarmenu li span.saveas {
background: url(images/buttons.png) -5px -253px no-repeat;
}
+
+
+table.propform td.source.selected {
+ background-color: #c7e3ef;
+}
+
+table.propform td.source div {
+ display: inline-block;
+ padding-left: 3px;
+ vertical-align: middle;
+}
+
+table.propform td.source .name {
+ font-weight: bold;
+}
+
+table.propform td.source .description {
+ font-size: 9px;
+ color: #666;
+}
+
+table.propform td.source img {
+ vertical-align: middle;
+ background-color: #e0e0e0;
+ border-radius: 3px;
+ margin: 3px;
+ background-image: -moz-linear-gradient(center top, #888, #333);
+ background-image: -webkit-linear-gradient(top, #888, #333);
+ background-image: -ms-linear-gradient(top, #888, #333);
+}
+
+table.propform td.source table.propform td {
+ border-bottom: 0;
+ padding: 2px 10px;
+ background-color: inherit;
+}
diff --git a/plugins/kolab_files/skins/larry/templates/compose_plugin.html b/plugins/kolab_files/skins/larry/templates/compose_plugin.html
index 613a24a..ceb56cc 100644
--- a/plugins/kolab_files/skins/larry/templates/compose_plugin.html
+++ b/plugins/kolab_files/skins/larry/templates/compose_plugin.html
@@ -25,3 +25,7 @@
<li role="menuitem"><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>
+
+<div id="files-folder-auth-dialog" role="dialog" aria-labelledby="aria-label-folderauthform" aria-hidden="true">
+ <h3 id="aria-label-folderauthform" class="voice"><roundcube:label name="kolab_files.arialabelfolderauthform" /></h3>
+</div>
diff --git a/plugins/kolab_files/skins/larry/templates/files.html b/plugins/kolab_files/skins/larry/templates/files.html
index e6e2500..e33d1d0 100644
--- a/plugins/kolab_files/skins/larry/templates/files.html
+++ b/plugins/kolab_files/skins/larry/templates/files.html
@@ -26,7 +26,7 @@
<div id="quicksearchbar" class="quicksearchbox" role="search" aria-labelledby="aria-label-searchform">
<h2 id="aria-label-searchform" class="voice"><roundcube:label name="kolab_files.arialabelsearchform" /></h2>
<label for="quicksearchbox" class="voice"><roundcube:label name="arialabelquicksearchbox" /></label>
- <roundcube:button name="filesearchmenulink" id="filesearchmenulink" class="iconbutton searchoptions" onclick="return UI.toggle_popup('filesearchmenu', event)" title="searchmod" label="options" aria-haspopup="true" aria-expanded="false" aria-owns="filesearchmenu-menu" />
+ <roundcube:button name="filesearchmenulink" id="filesearchmenulink" class="iconbutton searchoptions" onclick="UI.toggle_popup('filesearchmenu', event); return false" title="searchmod" label="options" aria-haspopup="true" aria-expanded="false" aria-owns="filesearchmenu-menu" />
<roundcube:object name="file-search-form" id="quicksearchbox" />
<roundcube:button command="files-search-reset" id="searchreset" class="iconbutton reset" title="resetsearch" label="resetsearch" />
</div>
@@ -60,6 +60,9 @@
<li role="menuitem"><roundcube:button command="files-folder-edit" label="edit" classAct="active" /></li>
-->
<li role="menuitem"><roundcube:button command="files-folder-delete" label="delete" classAct="active" /></li>
+ <roundcube:if condition="!empty(env:external_sources)" />
+ <li role="menuitem"><roundcube:button command="folder-mount" label="kolab_files.foldermount" classAct="active" /></li>
+ <roundcube:endif />
<li role="menuitem"><roundcube:button command="folders" task="settings" type="link" label="managefolders" classAct="active" /></li>
<roundcube:container name="filesfolderoptions" id="folderoptionsmenu" />
</ul>
@@ -69,14 +72,21 @@
<h3 id="aria-label-foldercreateform" class="voice"><roundcube:label name="kolab_files.arialabelfoldercreateform" /></h3>
<roundcube:object name="folder-create-form" />
</div>
+<div id="files-folder-mount-dialog" role="dialog" aria-labelledby="aria-label-foldermountform" aria-hidden="true">
+ <h3 id="aria-label-foldermountform" class="voice"><roundcube:label name="kolab_files.arialabelfoldermountform" /></h3>
+ <roundcube:object name="folder-mount-form" />
+</div>
<div id="files-file-edit-dialog" role="dialog" aria-labelledby="aria-label-fileeditform" aria-hidden="true">
<h3 id="aria-label-fileeditform" class="voice"><roundcube:label name="kolab_files.arialabelfileeditform" /></h3>
<roundcube:object name="file-edit-form" />
</div>
+<div id="files-folder-auth-dialog" role="dialog" aria-labelledby="aria-label-folderauthform" aria-hidden="true">
+ <h3 id="aria-label-folderauthform" class="voice"><roundcube:label name="kolab_files.arialabelfolderauthform" /></h3>
+</div>
<div id="listoptions" class="propform popupdialog" data-editable="true" role="dialog" aria-labelledby="aria-label-listoptions" aria-hidden="true">
<h3 id="aria-label-listoptions" class="voice"><roundcube:label name="kolab_files.arialabellistoptions" /></h3>
-<roundcube:if condition="!in_array('kolab_files_list_cols', (array)config:dont_override)" />
+ <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">
diff --git a/plugins/kolab_files/skins/larry/templates/message_plugin.html b/plugins/kolab_files/skins/larry/templates/message_plugin.html
index eeb78fd..26c2525 100644
--- a/plugins/kolab_files/skins/larry/templates/message_plugin.html
+++ b/plugins/kolab_files/skins/larry/templates/message_plugin.html
@@ -18,4 +18,8 @@
<roundcube:object name="folder-create-form" />
</div>
+<div id="files-folder-auth-dialog" role="dialog" aria-labelledby="aria-label-folderauthform" aria-hidden="true">
+ <h3 id="aria-label-folderauthform" class="voice"><roundcube:label name="kolab_files.arialabelfolderauthform" /></h3>
+</div>
+
<script src="plugins/kolab_files/skins/larry/ui.js" type="text/javascript"></script>
More information about the commits
mailing list