diff --git a/plugins/kolab_files/kolab_files.js b/plugins/kolab_files/kolab_files.js
index 097e038a..fde61886 100644
--- a/plugins/kolab_files/kolab_files.js
+++ b/plugins/kolab_files/kolab_files.js
@@ -67,6 +67,7 @@ window.rcmail && rcmail.addEventListener('init', function() {
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('dblclick', function(o){ kolab_files_list_dblclick(o); });
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); });
@@ -87,7 +88,14 @@ window.rcmail && rcmail.addEventListener('init', function() {
rcmail.env.file_commands_all = ['files-delete', 'files-move', 'files-copy'];
kolab_files_init();
- file_api.folder_list();
+
+ if (rcmail.env.action == 'open') {
+ rcmail.enable_command('files-get', 'files-delete', rcmail.env.file);
+ }
+ else {
+ file_api.folder_list();
+ file_api.browser_capabilities_check();
+ }
}
});
@@ -110,7 +118,9 @@ function kolab_files_init()
url: rcmail.env.files_url,
sort_col: 'name',
sort_reverse: false,
- search_threads: rcmail.env.search_threads
+ search_threads: rcmail.env.search_threads,
+ resources_dir: 'program/resources',
+ supported_mimetypes: rcmail.env.file_mimetypes
});
file_api.translations = rcmail.labels;
@@ -435,6 +445,11 @@ kolab_files_click_on_list = function(e)
return true;
};
+kolab_files_list_dblclick = function(list)
+{
+ rcmail.command('files-open');
+};
+
kolab_files_list_select = function(list)
{
var selected = list.selection.length;
@@ -445,6 +460,25 @@ kolab_files_list_select = function(list)
// reset all-pages-selection
// if (list.selection.length && list.selection.length != list.rowcount)
// rcmail.select_all_mode = false;
+
+ // enable files-
+ if (selected == 1) {
+ // get file mimetype
+ var type = $('tr.selected', list.list).data('type');
+ rcmail.env.viewer = file_api.file_type_supported(type);
+ }
+ else
+ rcmail.env.viewer = 0;
+/*
+ ) {
+// caps = this.browser_capabilities().join();
+ href = '?' + $.param({_task: 'files', _action: 'open', file: file, viewer: viewer == 2 ? 1 : 0});
+ var win = window.open(href, rcmail.html_identifier('rcubefile'+file));
+ if (win)
+ setTimeout(function() { win.focus(); }, 10);
+ }
+*/
+ rcmail.enable_command('files-open', rcmail.env.viewer);
};
kolab_files_drag_end = function(e)
@@ -544,7 +578,7 @@ rcube_webmail.prototype.files_delete = function()
if (!confirm(this.get_label('kolab_files.filedeleteconfirm')))
return;
- var files = kolab_files_selected();
+ var files = this.env.file ? [this.env.file] : kolab_files_selected();
file_api.file_delete(files);
};
@@ -584,12 +618,19 @@ rcube_webmail.prototype.files_list_update = function(head)
rcube_webmail.prototype.files_get = function()
{
- var files = kolab_files_selected();
+ var files = this.env.file ? [this.env.file] : kolab_files_selected();
if (files.length == 1)
file_api.file_get(files[0], {'force-download': true});
};
+rcube_webmail.prototype.files_open = function()
+{
+ var files = kolab_files_selected();
+
+ if (files.length == 1)
+ file_api.file_open(files[0], rcmail.env.viewer);
+};
/**********************************************************/
/********* Files API handler **********/
@@ -831,13 +872,18 @@ function kolab_files_ui()
if (!this.response(response))
return;
- var i = 0, table = $('#filelist');
+ var i = 0, list = [], table = $('#filelist');
$.each(response.result, function(key, data) {
i++;
var row = file_api.file_list_row(key, data, i);
rcmail.file_list.insert_row(row);
+ data.row = row;
+ data.filename = key;
+ list.push(data);
});
+
+ this.env.file_list = list;
};
// call file_list request for every folder (used for search and virt. collections)
@@ -918,6 +964,7 @@ function kolab_files_ui()
var row = this.file_list_row(i, result[i], index++);
table.insert_row(row, elem.row);
result[i].row = row;
+ result[i].filename = i;
list.push(result[i]);
delete result[i];
}
@@ -930,6 +977,7 @@ function kolab_files_ui()
var row = file_api.file_list_row(key, data, index++);
table.insert_row(row);
result[key].row = row;
+ result[key].filename = key;
list.push(result[key]);
});
@@ -986,7 +1034,7 @@ function kolab_files_ui()
row = $('
')
.html(row)
- .attr({id: 'rcmrow' + index, 'data-file': file});
+ .attr({id: 'rcmrow' + index, 'data-file': file, 'data-type': data.type});
// collection (or search) lists files from all folders
// display file name with full path as title
@@ -1039,7 +1087,12 @@ function kolab_files_ui()
return;
this.display_message('kolab_files.filedeletenotice', 'confirmation');
- this.file_list();
+ if (rcmail.env.file) {
+ // @TODO: reload files list in parent window
+ window.close();
+ }
+ else
+ this.file_list();
};
// file(s) move request
@@ -1269,4 +1322,13 @@ function kolab_files_ui()
.submit();
};
+ // open file in new window, using file API viewer
+ this.file_open = function(file, viewer)
+ {
+ var href = '?' + $.param({_task: 'files', _action: 'open', file: file, viewer: viewer == 2 ? 1 : 0}),
+ win = window.open(href, rcmail.html_identifier('rcubefile'+file));
+
+ if (win)
+ setTimeout(function() { win.focus(); }, 10);
+ };
};
diff --git a/plugins/kolab_files/kolab_files.php b/plugins/kolab_files/kolab_files.php
index bbd410cb..27500633 100644
--- a/plugins/kolab_files/kolab_files.php
+++ b/plugins/kolab_files/kolab_files.php
@@ -47,6 +47,7 @@ class kolab_files extends rcube_plugin
// Register plugin task actions
$this->register_action('index', array($this, 'actions'));
$this->register_action('prefs', array($this, 'actions'));
+ $this->register_action('open', array($this, 'actions'));
$this->ui();
}
diff --git a/plugins/kolab_files/lib/kolab_files_engine.php b/plugins/kolab_files/lib/kolab_files_engine.php
index 4e42c82a..f8b1bb86 100644
--- a/plugins/kolab_files/lib/kolab_files_engine.php
+++ b/plugins/kolab_files/lib/kolab_files_engine.php
@@ -346,7 +346,7 @@ class kolab_files_engine
}
$a_show_cols = $attrib['columns'];
- $head = '';
+ $head = '';
foreach ($this->file_list_head($attrib, $a_show_cols) as $cell) {
$head .= html::tag('td', array('class' => $cell['className'], 'id' => $cell['id']), $cell['html']);
@@ -358,6 +358,64 @@ class kolab_files_engine
$this->rc->output->command('files_list_update', $head);
}
+ /**
+ * Template object for file info box
+ */
+ public function file_info_box($attrib)
+ {
+ // print_r($this->file_data, true);
+ $table = new html_table(array('cols' => 2, 'class' => $attrib['class']));
+
+ // file name
+ $table->add('label', $this->plugin->gettext('name').':');
+ $table->add('data filename', $this->file_data['name']);
+
+ // file type
+ // @TODO: human-readable type name
+ $table->add('label', $this->plugin->gettext('type').':');
+ $table->add('data filetype', $this->file_data['type']);
+
+ // file size
+ $table->add('label', $this->plugin->gettext('size').':');
+ $table->add('data filesize', $this->rc->show_bytes($this->file_data['size']));
+
+ // file modification time
+ $table->add('label', $this->plugin->gettext('mtime').':');
+ $table->add('data filemtime', $this->file_data['mtime']);
+
+ // @TODO: for images: width, height, color depth, etc.
+ // @TODO: for text files: count of characters, lines, words
+
+ return $table->show();
+ }
+
+ /**
+ * Template object for file preview frame
+ */
+ public function file_preview_frame($attrib)
+ {
+ if (empty($attrib['id'])) {
+ $attrib['id'] = 'filepreviewframe';
+ }
+
+ if ($frame = $this->file_data['viewer']['frame']) {
+ return $frame;
+ }
+
+ if ($href = $this->file_data['viewer']['href']) {
+ }
+ else {
+ $token = $this->get_api_token();
+ $href = $this->url . '/api/?method=file_get'
+ . '&file=' . urlencode($this->file_data['filename'])
+ . '&token=' . urlencode($token);
+ }
+
+ $this->rc->output->add_gui_object('preview_frame', $attrib['id']);
+
+ return html::iframe(array('id' => 'file-content', 'src' => $href));
+ }
+
/**
* Get API token for current user session, authenticate if needed
*/
@@ -421,7 +479,7 @@ class kolab_files_engine
/**
* Initialize HTTP_Request object
*/
- protected function get_request()
+ protected function get_request($get = null, $token = null)
{
$url = $this->url . '/api/';
@@ -441,23 +499,37 @@ class kolab_files_engine
catch (Exception $e) {
rcube::raise_error($e, true, true);
}
+
+ // proxy User-Agent string
+ $this->request->setHeader('user-agent', $_SERVER['HTTP_USER_AGENT']);
}
- if ($this->request) {
- // cleanup
- try {
- $this->request->setBody('');
- $this->request->setUrl($url);
- $this->request->setMethod(HTTP_Request2::METHOD_GET);
- }
- catch (Exception $e) {
- rcube::raise_error($e, true, true);
- }
+ // cleanup
+ try {
+ $this->request->setBody('');
+ $this->request->setUrl($url);
+ $this->request->setMethod(HTTP_Request2::METHOD_GET);
+ }
+ catch (Exception $e) {
+ rcube::raise_error($e, true, true);
+ }
+
+ if ($token) {
+ $this->request->setHeader('X-Session-Token', $token);
+ }
+
+ if (!empty($get)) {
+ $url = $this->request->getUrl();
+ $url->setQueryVariables($get);
+ $this->request->setUrl($url);
}
return $this->request;
}
+ /**
+ * Handler for main files interface (Files task)
+ */
protected function action_index()
{
$this->plugin->add_label(
@@ -469,6 +541,7 @@ class kolab_files_engine
);
$this->rc->output->set_pagetitle($this->plugin->gettext('files'));
+ $this->rc->output->set_env('file_mimetypes', $this->get_mimetypes());
$this->rc->output->send('kolab_files.files');
}
@@ -510,6 +583,60 @@ class kolab_files_engine
$this->rc->output->send();
}
+ /**
+ * Handler for file open action
+ */
+ protected function action_open()
+ {
+ $file = rcube_utils::get_input_value('file', rcube_utils::INPUT_GET);
+
+ // get file info
+ $token = $this->get_api_token();
+ $request = $this->get_request(array(
+ 'method' => 'file_info',
+ 'file' => $file,
+ 'viewer' => !empty($_GET['viewer']),
+ ), $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') {
+ $this->file_data = $body['result'];
+ }
+ else {
+ throw new Exception($body['reason']);
+ }
+ }
+ catch (Exception $e) {
+ rcube::raise_error(array(
+ 'code' => 500, 'type' => 'php', 'line' => __LINE__, 'file' => __FILE__,
+ 'message' => $e->getMessage()),
+ true, true);
+ }
+
+ $this->file_data['filename'] = $file;
+
+ $this->plugin->add_label('filedeleteconfirm', 'filedeleting', 'filedeletenotice');
+
+ // this one is for styling purpose
+ $this->rc->output->set_env('extwin', true);
+
+ // register template objects for dialogs (and main interface)
+ $this->rc->output->add_handlers(array(
+ 'fileinfobox' => array($this, 'file_info_box'),
+ 'filepreviewframe' => array($this, 'file_preview_frame'),
+ ));
+
+ $this->rc->output->set_env('file', $file);
+ $this->rc->output->set_env('file_data', $this->file_data);
+ $this->rc->output->set_pagetitle(rcube::Q($file));
+ $this->rc->output->send('kolab_files.filepreview');
+ }
+
/**
* Handler for "save all attachments into cloud" action
*/
@@ -759,4 +886,35 @@ class kolab_files_engine
$this->rc->output->command('auto_save_start', false);
$this->rc->output->send();
}
+
+ /**
+ * Returns mimetypes supported by File API viewers
+ */
+ protected function get_mimetypes()
+ {
+ $token = $this->get_api_token();
+ $request = $this->get_request(array('method' => 'mimetypes'), $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') {
+ $mimetypes = $body['result'];
+ }
+ else {
+ throw new Exception($body['reason']);
+ }
+ }
+ catch (Exception $e) {
+ rcube::raise_error(array(
+ 'code' => 500, 'type' => 'php', 'line' => __LINE__, 'file' => __FILE__,
+ 'message' => $e->getMessage()),
+ true, false);
+ }
+
+ return $mimetypes;
+ }
}
diff --git a/plugins/kolab_files/localization/en_US.inc b/plugins/kolab_files/localization/en_US.inc
index 1b6eb819..96c49bf9 100644
--- a/plugins/kolab_files/localization/en_US.inc
+++ b/plugins/kolab_files/localization/en_US.inc
@@ -18,6 +18,7 @@ $labels['folderinside'] = 'Insert inside';
$labels['foldername'] = 'Folder name';
$labels['name'] = 'Name';
$labels['mtime'] = 'Modified';
+$labels['type'] = 'Type';
$labels['upload'] = 'Upload';
$labels['uploadfile'] = 'Upload file(s)';
diff --git a/plugins/kolab_files/skins/larry/style.css b/plugins/kolab_files/skins/larry/style.css
index fcaaea6e..06ff3e13 100644
--- a/plugins/kolab_files/skins/larry/style.css
+++ b/plugins/kolab_files/skins/larry/style.css
@@ -34,7 +34,7 @@
background-position: center -94px;
}
-#filestoolbar a.button.view {
+#filestoolbar a.button.open {
background-position: center -131px;
}
@@ -52,7 +52,8 @@
left: 6px;
}
-#folderlistbox {
+#folderlistbox,
+#fileinfobox {
position: absolute;
top: 42px;
left: 0;
@@ -60,7 +61,8 @@
bottom: 0;
}
-#filelistcontainer {
+#filelistcontainer,
+#filecontent {
position: absolute;
top: 42px;
left: 232px;
@@ -78,6 +80,17 @@
width: 100%;
}
+#filecontent {
+ overflow: hidden;
+}
+
+#filecontent iframe {
+ width: 100%;
+ height: 100%;
+ margin: 0;
+ border: 0;
+}
+
#files-folder-list ul li span.name {
background: url(../../../../skins/larry/images/listicons.png) 6px 3px no-repeat;
padding: 6px 8px 2px 32px;
@@ -218,6 +231,19 @@
}
*/
+#fileinfobox table td.label {
+ width: 1%;
+ font-weight: bold;
+ padding-right: 0;
+}
+
+#fileinfobox table td.data.filename {
+ font-weight: bold;
+}
+
+#fileinfobox table tr:first-child td {
+ border-top: 0;
+}
/* plugin dialogs */
diff --git a/plugins/kolab_files/skins/larry/templates/filepreview.html b/plugins/kolab_files/skins/larry/templates/filepreview.html
new file mode 100644
index 00000000..416cbc74
--- /dev/null
+++ b/plugins/kolab_files/skins/larry/templates/filepreview.html
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/plugins/kolab_files/skins/larry/templates/files.html b/plugins/kolab_files/skins/larry/templates/files.html
index ba52300d..13f6619d 100644
--- a/plugins/kolab_files/skins/larry/templates/files.html
+++ b/plugins/kolab_files/skins/larry/templates/files.html
@@ -16,7 +16,7 @@
-
+
diff --git a/plugins/kolab_files/skins/larry/ui.js b/plugins/kolab_files/skins/larry/ui.js
index fda15c84..954e5b54 100644
--- a/plugins/kolab_files/skins/larry/ui.js
+++ b/plugins/kolab_files/skins/larry/ui.js
@@ -1,7 +1,11 @@
function kolab_files_ui_init()
{
- var filesviewsplit = new rcube_splitter({ id:'filesviewsplitter', p1:'#folderlistbox', p2:'#filelistcontainer',
- orientation:'v', relative:true, start:226, min:150, size:12 }).init();
+ if (rcmail.env.action == 'open')
+ var filesviewsplit = new rcube_splitter({ id:'filesopensplitter', p1:'#fileinfobox', p2:'#filecontent',
+ orientation:'v', relative:true, start:226, min:150, size:12 }).init();
+ else
+ var filesviewsplit = new rcube_splitter({ id:'filesviewsplitter', p1:'#folderlistbox', p2:'#filelistcontainer',
+ orientation:'v', relative:true, start:226, min:150, size:12 }).init();
$(document).ready(function() {
rcmail.addEventListener('menu-open', kolab_files_show_listoptions);