summaryrefslogtreecommitdiff
path: root/program
diff options
context:
space:
mode:
authorAleksander Machniak <alec@alec.pl>2013-12-15 10:01:38 +0100
committerAleksander Machniak <alec@alec.pl>2013-12-15 10:01:38 +0100
commit9a0153324eeb1f0e808cb1a063d1f37d49ad48e2 (patch)
treee8370c629b5b32c689da8362f5be78097572a0a3 /program
parent4187b3e26ff00b607d05cb9b588e83db18c3cab7 (diff)
Implemented menu actions to copy/move messages, added folder-selector widget (#1484086)
Diffstat (limited to 'program')
-rw-r--r--program/include/rcmail.php25
-rw-r--r--program/js/app.js113
-rw-r--r--program/localization/en_US/labels.inc1
3 files changed, 127 insertions, 12 deletions
diff --git a/program/include/rcmail.php b/program/include/rcmail.php
index 35ade8a41..cefbc4d14 100644
--- a/program/include/rcmail.php
+++ b/program/include/rcmail.php
@@ -1282,13 +1282,22 @@ class rcmail extends rcube
}
else {
$js_mailboxlist = array();
- $out = html::tag('ul', $attrib, $rcmail->render_folder_tree_html($a_mailboxes, $mbox_name, $js_mailboxlist, $attrib), html::$common_attrib);
+ $tree = $rcmail->render_folder_tree_html($a_mailboxes, $mbox_name, $js_mailboxlist, $attrib);
+
+ if ($type != 'js') {
+ $out = html::tag('ul', $attrib, $tree, html::$common_attrib);
+
+ $rcmail->output->include_script('treelist.js');
+ $rcmail->output->add_gui_object('mailboxlist', $attrib['id']);
+ $rcmail->output->set_env('unreadwrap', $attrib['unreadwrap']);
+ $rcmail->output->set_env('collapsed_folders', (string)$rcmail->config->get('collapsed_folders'));
+ }
- $rcmail->output->include_script('treelist.js');
- $rcmail->output->add_gui_object('mailboxlist', $attrib['id']);
$rcmail->output->set_env('mailboxes', $js_mailboxlist);
- $rcmail->output->set_env('unreadwrap', $attrib['unreadwrap']);
- $rcmail->output->set_env('collapsed_folders', (string)$rcmail->config->get('collapsed_folders'));
+
+ // we can't use object keys in javascript because they are unordered
+ // we need sorted folders list for folder-selector widget
+ $rcmail->output->set_env('mailboxes_list', array_keys($js_mailboxlist));
}
return $out;
@@ -1473,9 +1482,13 @@ class rcmail extends rcube
$jslist[$folder['id']] = array(
'id' => $folder['id'],
'name' => $foldername,
- 'virtual' => $folder['virtual']
+ 'virtual' => $folder['virtual'],
);
+ if (!empty($folder_class)) {
+ $jslist[$folder['id']]['class'] = $folder_class;
+ }
+
if (!empty($folder['folders'])) {
$out .= html::tag('ul', array('style' => ($is_collapsed ? "display:none;" : null)),
$this->render_folder_tree_html($folder['folders'], $mbox_name, $jslist, $attrib, $nestLevel+1));
diff --git a/program/js/app.js b/program/js/app.js
index cbe61ab4a..138fcbb13 100644
--- a/program/js/app.js
+++ b/program/js/app.js
@@ -842,14 +842,14 @@ function rcube_webmail()
case 'move':
case 'moveto': // deprecated
if (this.task == 'mail')
- this.move_messages(props);
+ this.move_messages(props, obj);
else if (this.task == 'addressbook')
this.move_contacts(props);
break;
case 'copy':
if (this.task == 'mail')
- this.copy_messages(props);
+ this.copy_messages(props, obj);
else if (this.task == 'addressbook')
this.copy_contacts(props);
break;
@@ -1411,8 +1411,6 @@ function rcube_webmail()
this.drag_start = function(list)
{
- var model = this.task == 'mail' ? this.env.mailboxes : this.env.contactfolders;
-
this.drag_active = true;
if (this.preview_timer)
@@ -2612,10 +2610,12 @@ function rcube_webmail()
};
// copy selected messages to the specified mailbox
- this.copy_messages = function(mbox)
+ this.copy_messages = function(mbox, obj)
{
if (mbox && typeof mbox === 'object')
mbox = mbox.id;
+ else if (!mbox)
+ return this.folder_selector(obj, function(folder) { ref.command('copy', folder); });
// exit if current or no mailbox specified
if (!mbox || mbox == this.env.mailbox)
@@ -2632,10 +2632,12 @@ function rcube_webmail()
};
// move selected messages to the specified mailbox
- this.move_messages = function(mbox)
+ this.move_messages = function(mbox, obj)
{
if (mbox && typeof mbox === 'object')
mbox = mbox.id;
+ else if (!mbox)
+ return this.folder_selector(obj, function(folder) { ref.command('move', folder); });
// exit if current or no mailbox specified
if (!mbox || mbox == this.env.mailbox)
@@ -6553,6 +6555,105 @@ function rcube_webmail()
elem.onclick = function() { rcmail.command('show-headers', '', elem); };
};
+ // create folder selector popup, position and display it
+ this.folder_selector = function(obj, callback)
+ {
+ var container = this.folder_selector_element;
+
+ if (!container) {
+ var rows = [],
+ delim = this.env.delimiter,
+ ul = $('<ul class="toolbarmenu iconized">'),
+ li = document.createElement('li'),
+ link = document.createElement('a'),
+ span = document.createElement('span');
+
+ container = $('<div id="folder-selector" class="popupmenu"></div>');
+ link.href = '#';
+ link.className = 'icon';
+
+ // loop over sorted folders list
+ $.each(this.env.mailboxes_list, function() {
+ var tmp, n = 0, s = 0,
+ folder = ref.env.mailboxes[this],
+ id = folder.id,
+ a = link.cloneNode(false), row = li.cloneNode(false);
+
+ if (folder.virtual)
+ a.className += ' virtual';
+ else {
+ a.className += ' active';
+ a.onclick = function() { container.hide().data('callback')(folder.id); };
+ }
+
+ if (folder['class'])
+ a.className += ' ' + folder['class'];
+
+ // calculate/set indentation level
+ while ((s = id.indexOf(delim, s)) >= 0) {
+ n++; s++;
+ }
+ a.style.paddingLeft = n ? (n * 16) + 'px' : 0;
+
+ // add folder name element
+ tmp = span.cloneNode(false);
+ $(tmp).text(folder.name);
+ a.appendChild(tmp);
+
+ row.appendChild(a);
+ rows.push(row);
+ });
+
+ ul.append(rows).appendTo(container);
+
+ // temporarily show element to calculate its size
+ container.css({left: '-1000px', top: '-1000px'})
+ .appendTo($('body')).show();
+
+ // set max-height if the list is long
+ if (rows.length > 10)
+ container.css('max-height', $('li', container)[0].offsetHeight * 10 + 9)
+
+ // hide selector on click out of selector element
+ var fn = function(e) { if (e.target != container.get(0)) container.hide(); };
+ $(document.body).on('mouseup', fn);
+ $('iframe').contents().on('mouseup', fn)
+ .load(function(e) { try { $(this).contents().on('mouseup', fn); } catch(e) {}; });
+
+ this.folder_selector_element = container;
+ }
+
+ // position menu on the screen
+ this.element_position(container, obj);
+
+ container.show().data('callback', callback);
+ };
+
+ // position a menu element on the screen in relation to other object
+ this.element_position = function(element, obj)
+ {
+ var obj = $(obj), win = $(window),
+ width = obj.width(),
+ height = obj.height(),
+ win_height = win.height(),
+ elem_height = $(element).height(),
+ elem_width = $(element).width(),
+ pos = obj.offset(),
+ top = pos.top,
+ left = pos.left + width;
+
+ if (top + elem_height > win_height) {
+ top -= elem_height - height;
+ if (top < 0)
+ top = Math.max(0, (win_height - elem_height) / 2);
+ }
+
+ if (left + elem_width > win.width())
+ left -= elem_width + width;
+
+ element.css({left: left + 'px', top: top + 'px'});
+ };
+
/********************************************************/
/********* html to text conversion functions *********/
diff --git a/program/localization/en_US/labels.inc b/program/localization/en_US/labels.inc
index 92ec82617..61890a642 100644
--- a/program/localization/en_US/labels.inc
+++ b/program/localization/en_US/labels.inc
@@ -64,6 +64,7 @@ $labels['fromtoshort'] = '$from – $to of $count';
$labels['copy'] = 'Copy';
$labels['move'] = 'Move';
$labels['moveto'] = 'Move to...';
+$labels['copyto'] = 'Copy to...';
$labels['download'] = 'Download';
$labels['open'] = 'Open';
$labels['showattachment'] = 'Show';