diff options
| -rw-r--r-- | CHANGELOG | 1 | ||||
| -rw-r--r-- | program/include/rcmail_output_html.php | 4 | ||||
| -rw-r--r-- | program/js/app.js | 21 | ||||
| -rw-r--r-- | program/localization/en_US/labels.inc | 1 | ||||
| -rw-r--r-- | program/steps/mail/show.inc | 23 | ||||
| -rw-r--r-- | skins/classic/functions.js | 53 | ||||
| -rw-r--r-- | skins/classic/mail.css | 20 | ||||
| -rw-r--r-- | skins/classic/templates/message.html | 8 | ||||
| -rw-r--r-- | skins/classic/templates/messagepreview.html | 12 | ||||
| -rw-r--r-- | skins/larry/images/buttons.gif | bin | 13054 -> 14997 bytes | |||
| -rw-r--r-- | skins/larry/images/buttons.png | bin | 36693 -> 48308 bytes | |||
| -rw-r--r-- | skins/larry/mail.css | 2 | ||||
| -rw-r--r-- | skins/larry/styles.css | 13 | ||||
| -rw-r--r-- | skins/larry/templates/message.html | 8 | ||||
| -rw-r--r-- | skins/larry/templates/messagepreview.html | 8 | ||||
| -rw-r--r-- | skins/larry/ui.js | 42 | 
16 files changed, 181 insertions, 35 deletions
@@ -1,6 +1,7 @@  CHANGELOG Roundcube Webmail  =========================== +- Add attachment menu with Open and Download options (#1488975)  - Fix thumbnail size when GD extension is used for image resize (#1488985)  - Display user-friendly message on IMAP "over quota" errors (#1484164)  - Display notice that message is encrypted also for application/pkcs7-mime messages (#1488526) diff --git a/program/include/rcmail_output_html.php b/program/include/rcmail_output_html.php index 2babe1cbb..ade2bd4a4 100644 --- a/program/include/rcmail_output_html.php +++ b/program/include/rcmail_output_html.php @@ -1175,6 +1175,10 @@ class rcmail_output_html extends rcmail_output              $out = sprintf('<a%s>%s</a>', $attrib_str, $btn_content);          } +        if ($attrib['wrapper']) { +            $out = html::tag($attrib['wrapper'], null, $out); +        } +          return $out;      } diff --git a/program/js/app.js b/program/js/app.js index 4011fa593..55c71d776 100644 --- a/program/js/app.js +++ b/program/js/app.js @@ -179,7 +179,8 @@ function rcube_webmail()      }      // enable general commands -    this.enable_command('close', 'logout', 'mail', 'addressbook', 'settings', 'save-pref', 'compose', 'undo', 'about', 'switch-task', true); +    this.enable_command('close', 'logout', 'mail', 'addressbook', 'settings', 'save-pref', +      'compose', 'undo', 'about', 'switch-task', 'menu-open', 'menu-save', true);      if (this.env.permaurl)        this.enable_command('permaurl', 'extwin', true); @@ -211,7 +212,7 @@ function rcube_webmail()            this.gui_objects.messagelist.parentNode.onmousedown = function(e){ return p.click_on_list(e); };            this.message_list.init(); -          this.enable_command('toggle_status', 'toggle_flag', 'menu-open', 'menu-save', 'sort', true); +          this.enable_command('toggle_status', 'toggle_flag', 'sort', true);            // load messages            this.command('list'); @@ -227,7 +228,7 @@ function rcube_webmail()          this.env.message_commands = ['show', 'reply', 'reply-all', 'reply-list',            'moveto', 'copy', 'delete', 'open', 'mark', 'edit', 'viewsource', -          'print', 'load-attachment', 'show-headers', 'hide-headers', 'download', +          'print', 'load-attachment', 'download-attachment', 'show-headers', 'hide-headers', 'download',            'forward', 'forward-inline', 'forward-attachment'];          if (this.env.action == 'show' || this.env.action == 'preview') { @@ -608,6 +609,11 @@ function rcube_webmail()          break;        case 'menu-open': +        if (props && props.menu == 'attachmentmenu') { +          var mimetype = this.env.attachments[props.id]; +          this.enable_command('open-attachment', mimetype && this.env.mimetypes && $.inArray(mimetype, this.env.mimetypes) >= 0); +        } +        case 'menu-save':          this.triggerEvent(command, {props:props});          return false; @@ -833,11 +839,14 @@ function rcube_webmail()          break;        case 'load-attachment': -        var qstring = '_mbox='+urlencode(this.env.mailbox)+'&_uid='+this.env.uid+'&_part='+props.part; +      case 'open-attachment': +      case 'download-attachment': +        var qstring = '_mbox='+urlencode(this.env.mailbox)+'&_uid='+this.env.uid+'&_part='+props, +          mimetype = this.env.attachments[props];          // open attachment in frame if it's of a supported mimetype -        if (this.env.uid && props.mimetype && this.env.mimetypes && $.inArray(props.mimetype, this.env.mimetypes) >= 0) { -          var attachment_win = window.open(this.env.comm_path+'&_action=get&'+qstring+'&_frame=1', 'rcubemailattachment'+this.env.uid+props.part); +        if (command != 'download-attachment' && mimetype && this.env.mimetypes && $.inArray(mimetype, this.env.mimetypes) >= 0) { +          var attachment_win = window.open(this.env.comm_path+'&_action=get&'+qstring+'&_frame=1', 'rcubemailattachment'+this.env.uid+props);            if (attachment_win) {              setTimeout(function(){ attachment_win.focus(); }, 10);              break; diff --git a/program/localization/en_US/labels.inc b/program/localization/en_US/labels.inc index 0750e7848..61a13e9ab 100644 --- a/program/localization/en_US/labels.inc +++ b/program/localization/en_US/labels.inc @@ -64,6 +64,7 @@ $labels['copy']     = 'Copy';  $labels['move']     = 'Move';  $labels['moveto']   = 'Move to...';  $labels['download'] = 'Download'; +$labels['open']     = 'Open';  $labels['showattachment'] = 'Show';  $labels['showanyway'] = 'Show it anyway'; diff --git a/program/steps/mail/show.inc b/program/steps/mail/show.inc index 437dbaafa..87555cbbe 100644 --- a/program/steps/mail/show.inc +++ b/program/steps/mail/show.inc @@ -147,6 +147,7 @@ function rcmail_message_attachments($attrib)    global $PRINT_MODE, $MESSAGE, $RCMAIL;    $out = $ol = ''; +  $attachments = array();    if (sizeof($MESSAGE->attachments)) {      foreach ($MESSAGE->attachments as $attach_prop) { @@ -165,21 +166,23 @@ function rcmail_message_attachments($attrib)            $title = '';          } -        $ol .= html::tag('li', rcmail_filetype2classname($attach_prop->mimetype, $filename), -          html::a(array( +        $mimetype = rcmail_fix_mimetype($attach_prop->mimetype); +        $class    = rcmail_filetype2classname($mimetype, $filename); +        $id       = 'attach' . $attach_prop->mime_id; +        $link     = html::a(array(              'href' => $MESSAGE->get_part_url($attach_prop->mime_id, false), -            'onclick' => sprintf( -              'return %s.command(\'load-attachment\',{part:\'%s\', mimetype:\'%s\'},this)', -              JS_OBJECT_NAME, -              $attach_prop->mime_id, -              rcmail_fix_mimetype($attach_prop->mimetype)), -              'title' => Q($title), -            ), -            Q($filename))); +            'onclick' => sprintf('return %s.command(\'load-attachment\',\'%s\',this)', +              JS_OBJECT_NAME, $attach_prop->mime_id), +            'title' => Q($title), +            ), Q($filename)); +        $ol .= html::tag('li', array('class' => $class, 'id' => $id), $link); + +        $attachments[$attach_prop->mime_id] = $mimetype;        }      }      $out = html::tag('ul', $attrib, $ol, html::$common_attrib); +    $RCMAIL->output->set_env('attachments', $attachments);    }    return $out; diff --git a/skins/classic/functions.js b/skins/classic/functions.js index c59ea9bf8..499783b3f 100644 --- a/skins/classic/functions.js +++ b/skins/classic/functions.js @@ -92,6 +92,7 @@ function rcube_mail_ui()      forwardmenu:    {id:'forwardmenu', editable:1},      searchmenu:     {id:'searchmenu', editable:1},      messagemenu:    {id:'messagemenu'}, +    attachmentmenu: {id:'attachmentmenu'},      listmenu:       {id:'listmenu', editable:1},      dragmessagemenu:{id:'dragmessagemenu', sticky:1},      groupmenu:      {id:'groupoptionsmenu', above:1}, @@ -133,24 +134,24 @@ show_popupmenu: function(popup, show)  {    var obj = this.popups[popup].obj,      above = this.popups[popup].above, -    ref = rcube_find_object(popup+'link'); +    ref = $(this.popups[popup].link ? this.popups[popup].link : rcube_find_object(popup+'link'));    if (typeof show == 'undefined')      show = obj.is(':visible') ? false : true;    else if (this.popups[popup].toggle && show && this.popups[popup].obj.is(':visible') )      show = false; -  if (show && ref) { -    var parent = $(ref).parent(), +  if (show && ref.length) { +    var parent = ref.parent(),        win = $(window), -      pos = parent.hasClass('dropbutton') ? parent.offset() : $(ref).offset(); +      pos = parent.hasClass('dropbutton') ? parent.offset() : ref.offset(); -    if (!above && pos.top + ref.offsetHeight + obj.height() > win.height()) +    if (!above && pos.top + ref.height() + obj.height() > win.height())        above = true;      if (pos.left + obj.width() > win.width())        pos.left = win.width() - obj.width() - 30; -    obj.css({ left:pos.left, top:(pos.top + (above ? -obj.height() : ref.offsetHeight)) }); +    obj.css({ left:pos.left, top:(pos.top + (above ? -obj.height() : ref.height())) });    }    obj[show?'show':'hide'](); @@ -325,7 +326,7 @@ listmenu: function(show)    };  }, -open_listmenu: function(e) +open_listmenu: function()  {    this.listmenu();  }, @@ -380,6 +381,35 @@ spellmenu: function(show)    this.show_popupmenu('spellmenu', show);  }, +show_attachmentmenu: function(elem) +{ +  var id = elem.parentNode.id.replace(/^attach/, ''); + +  $('#attachmenuopen').unbind('click').attr('onclick', '').click(function(e) { +    return rcmail.command('open-attachment', id, this); +  }); + +  $('#attachmenudownload').unbind('click').attr('onclick', '').click(function() { +    rcmail.command('download-attachment', id, this); +  }); + +  this.popups.attachmentmenu.link = elem; +  rcmail.command('menu-open', {menu: 'attachmentmenu', id: id}); +}, + +menu_open: function(p) +{ +  if (p && p.props && p.props.menu == 'attachmentmenu') +    this.show_popup('attachmentmenu'); +  else +    this.open_listmenu(); +}, + +menu_save: function(prop) +{ +  this.save_listmenu(); +}, +  body_mouseup: function(evt, p)  {    var i, target = rcube_event.get_target(evt); @@ -800,8 +830,8 @@ function rcube_init_mail_ui()      .contents().mouseup(function(e){rcmail_ui.body_mouseup(e)});    if (rcmail.env.task == 'mail') { -    rcmail.addEventListener('menu-open', 'open_listmenu', rcmail_ui); -    rcmail.addEventListener('menu-save', 'save_listmenu', rcmail_ui); +    rcmail.addEventListener('menu-open', 'menu_open', rcmail_ui); +    rcmail.addEventListener('menu-save', 'menu_save', rcmail_ui);      rcmail.addEventListener('aftersend-attachment', 'uploadmenu', rcmail_ui);      rcmail.addEventListener('aftertoggle-editor', 'resize_compose_body_ev', rcmail_ui);      rcmail.gui_object('message_dragmenu', 'dragmessagemenu'); @@ -817,6 +847,11 @@ function rcube_init_mail_ui()      if (rcmail.env.action == 'compose')        rcmail_ui.init_compose_form(); +    else if (rcmail.env.action == 'show' || rcmail.env.action == 'preview') +      // add menu link for each attachment +      $('#attachment-list > li[id^="attach"]').each(function() { +        $(this).append($('<a class="drop">').click(function() { rcmail_ui.show_attachmentmenu(this); })); +      });    }    else if (rcmail.env.task == 'addressbook') {      rcmail.addEventListener('afterupload-photo', function(){ rcmail_ui.show_popup('uploadform', false); }); diff --git a/skins/classic/mail.css b/skins/classic/mail.css index 8be35aaa6..4d42d98ff 100644 --- a/skins/classic/mail.css +++ b/skins/classic/mail.css @@ -173,13 +173,15 @@  }  #messagemenu li a.active:hover, +#attachmentmenu li a.active:hover,  #markmessagemenu li a.active:hover  {    color: #fff;    background-color: #c00;  } -#messagemenu li a +#messagemenu li a, +#attachmentmenu li a  {    background: url(images/messageactions.png) no-repeat 7px 0;    background-position: 7px 20px; @@ -190,7 +192,8 @@    background-position: 7px 1px;  } -#messagemenu li a.downloadlink +#messagemenu li a.downloadlink, +#attachmentmenu li a.downloadlink  {    background-position: 7px -17px;  } @@ -200,7 +203,8 @@    background-position: 7px -35px;  } -#messagemenu li a.openlink +#messagemenu li a.openlink, +#attachmentmenu li a.openlink  {    background-position: 7px -53px;  } @@ -1135,6 +1139,16 @@ table.headers-table tr td.header span    text-decoration: underline;  } +#attachment-list li a.drop { +  background: url(images/icons/down_small.gif) no-repeat center 6px; +  width: 12px; +  height: 7px; +  cursor: pointer; +  padding: 5px 0 0; +  margin-left: 3px; +  display: inline-block; +} +  #messagebody  {    position:relative; diff --git a/skins/classic/templates/message.html b/skins/classic/templates/message.html index d1594ea28..73dfcb976 100644 --- a/skins/classic/templates/message.html +++ b/skins/classic/templates/message.html @@ -65,5 +65,13 @@  </script>  <roundcube:endif /> +<div id="attachmentmenu" class="popupmenu"> +  <ul class="toolbarmenu"> +    <li><roundcube:button command="open-attachment" id="attachmenuopen" type="link" label="open" class="openlink" classAct="openlink active" innerclass="openlink" /></li> +    <li><roundcube:button command="download-attachment" id="attachmenudownload" type="link" label="download" class="downloadlink" classAct="downloadlink active" innerclass="downloadlink" /></li> +    <roundcube:container name="attachmentmenu" id="attachmentmenu" /> +  </ul> +</div> +  </body>  </html> diff --git a/skins/classic/templates/messagepreview.html b/skins/classic/templates/messagepreview.html index 78b2306f6..935238edf 100644 --- a/skins/classic/templates/messagepreview.html +++ b/skins/classic/templates/messagepreview.html @@ -3,8 +3,10 @@  <head>  <title><roundcube:object name="pagetitle" /></title>  <roundcube:include file="/includes/links.html" /> +<script type="text/javascript" src="/splitter.js"></script> +<script type="text/javascript" src="/functions.js"></script>  </head> -<body class="iframe"> +<body class="iframe" onload="rcube_init_mail_ui()">  <div class="messageheaderbox">  <roundcube:button command="extwin" image="/images/icons/extwin.png" width="15" height="15" title="openinextwin" id="openextwinlink" /> @@ -16,5 +18,13 @@  <roundcube:object name="messageObjects" id="message-objects" />  <roundcube:object name="messageBody" id="messagebody" /> +<div id="attachmentmenu" class="popupmenu"> +  <ul class="toolbarmenu"> +    <li><roundcube:button command="open-attachment" id="attachmenuopen" type="link" label="open" class="openlink" classAct="openlink active" innerclass="openlink" /></li> +    <li><roundcube:button command="download-attachment" id="attachmenudownload" type="link" label="download" class="downloadlink" classAct="downloadlink active" innerclass="downloadlink" /></li> +    <roundcube:container name="attachmentmenu" id="attachmentmenu" /> +  </ul> +</div> +  </body>  </html> diff --git a/skins/larry/images/buttons.gif b/skins/larry/images/buttons.gif Binary files differindex d8a33d6b2..8a4a78ee4 100644 --- a/skins/larry/images/buttons.gif +++ b/skins/larry/images/buttons.gif diff --git a/skins/larry/images/buttons.png b/skins/larry/images/buttons.png Binary files differindex 4438d9cbc..0ec061a78 100644 --- a/skins/larry/images/buttons.png +++ b/skins/larry/images/buttons.png diff --git a/skins/larry/mail.css b/skins/larry/mail.css index c99370830..e6529d118 100644 --- a/skins/larry/mail.css +++ b/skins/larry/mail.css @@ -868,7 +868,7 @@ div.more-headers {  }  div.hide-headers { -	background-position: center -1589px; +	background-position: center -1600px;  }  #all-headers { diff --git a/skins/larry/styles.css b/skins/larry/styles.css index 044a09e05..1e3e6f7d5 100644 --- a/skins/larry/styles.css +++ b/skins/larry/styles.css @@ -2219,7 +2219,7 @@ ul.toolbarmenu li span.conversation {  	display: block;  	color: #333;  	font-weight: bold; -	padding: 8px 4px 3px 30px; +	padding: 8px 15px 3px 30px;  	text-shadow: 0px 1px 1px #fff;  	text-decoration: none;  	white-space: nowrap; @@ -2227,6 +2227,17 @@ ul.toolbarmenu li span.conversation {  	text-overflow: ellipsis;  } +.attachmentslist li a.drop { +	background: url(images/buttons.png) no-repeat scroll center -1570px; +	width: 14px; +	height: 26px; +	cursor: pointer; +	position: absolute; +	right: 0; +	top: 0; +	padding: 0; +} +  #compose-attachments ul li {  	padding-right: 28px;  } diff --git a/skins/larry/templates/message.html b/skins/larry/templates/message.html index b4ceb6a6c..36e0efa0a 100644 --- a/skins/larry/templates/message.html +++ b/skins/larry/templates/message.html @@ -73,6 +73,14 @@  </div><!-- end mainscreen --> +<div id="attachmentmenu" class="popupmenu dropdown"> +	<ul class="toolbarmenu"> +		<li><roundcube:button command="open-attachment" id="attachmenuopen" type="link" label="open" class="icon" classAct="icon active" innerclass="icon extwin" /></li> +		<li><roundcube:button command="download-attachment" id="attachmenudownload" type="link" label="download" class="icon" classAct="icon active" innerclass="icon download" /></li> +		<roundcube:container name="attachmentmenu" id="attachmentmenu" /> +	</ul> +</div> +  <roundcube:include file="/includes/footer.html" />  </body> diff --git a/skins/larry/templates/messagepreview.html b/skins/larry/templates/messagepreview.html index aef282ac9..dbfe2dc7b 100644 --- a/skins/larry/templates/messagepreview.html +++ b/skins/larry/templates/messagepreview.html @@ -51,6 +51,14 @@  </div>  </div> +<div id="attachmentmenu" class="popupmenu dropdown"> +	<ul class="toolbarmenu"> +		<li><roundcube:button command="open-attachment" id="attachmenuopen" type="link" label="open" class="icon" classAct="icon active" innerclass="icon extwin" /></li> +		<li><roundcube:button command="download-attachment" id="attachmenudownload" type="link" label="download" class="icon" classAct="icon active" innerclass="icon download" /></li> +		<roundcube:container name="attachmentmenu" id="attachmentmenu" /> +	</ul> +</div> +  <roundcube:include file="/includes/footer.html" />  </body> diff --git a/skins/larry/ui.js b/skins/larry/ui.js index d2638bbca..6b2a5c7d0 100644 --- a/skins/larry/ui.js +++ b/skins/larry/ui.js @@ -17,6 +17,7 @@ function rcube_mail_ui()    var popupconfig = {      forwardmenu:        { editable:1 },      searchmenu:         { editable:1, callback:searchmenu }, +    attachmentmenu:     { },      listoptions:        { editable:1 },      dragmessagemenu:    { sticky:1 },      groupmenu:          { above:1 }, @@ -81,8 +82,8 @@ function rcube_mail_ui()      /***  mail task  ***/      if (rcmail.env.task == 'mail') { -      rcmail.addEventListener('menu-open', show_listoptions); -      rcmail.addEventListener('menu-save', save_listoptions); +      rcmail.addEventListener('menu-open', menu_open); +      rcmail.addEventListener('menu-save', menu_save);        rcmail.addEventListener('responseafterlist', function(e){ switch_view_mode(rcmail.env.threading ? 'thread' : 'list') });        var dragmenu = $('#dragmessagemenu'); @@ -95,6 +96,11 @@ function rcube_mail_ui()          rcmail.addEventListener('aftershow-headers', function() { layout_messageview(); });          rcmail.addEventListener('afterhide-headers', function() { layout_messageview(); });          $('#previewheaderstoggle').click(function(e){ toggle_preview_headers(this); return false }); + +        // add menu link for each attachment +        $('#attachment-list > li').each(function() { +          $(this).append($('<a class="drop">').click(function() { attachmentmenu(this); })); +        });        }        else if (rcmail.env.action == 'compose') {          rcmail.addEventListener('aftertoggle-editor', function(){ window.setTimeout(function(){ layout_composeview() }, 200); }); @@ -436,7 +442,7 @@ function rcube_mail_ui()    {      var obj = popups[popup],        config = popupconfig[popup], -      ref = $('#'+popup+'link'), +      ref = $(config.link ? config.link : '#'+popup+'link'),        above = config.above;      if (!obj) { @@ -452,7 +458,7 @@ function rcube_mail_ui()      else if (config.toggle && show && obj.is(':visible'))        show = false; -    if (show && ref) { +    if (show && ref.length) {        var parent = ref.parent(),          win = $(window),          pos; @@ -575,6 +581,19 @@ function rcube_mail_ui()    /**** popup callbacks ****/ +  function menu_open(p) +  { +    if (p && p.props && p.props.menu == 'attachmentmenu') +      show_popupmenu('attachmentmenu'); +    else +      show_listoptions(); +  } + +  function menu_save(prop) +  { +    save_listoptions(); +  } +    function searchmenu(show)    {      if (show && rcmail.env.search_mods) { @@ -605,6 +624,21 @@ function rcube_mail_ui()      }    } +  function attachmentmenu(elem) +  { +    var id = elem.parentNode.id.replace(/^attach/, ''); + +    $('#attachmenuopen').unbind('click').attr('onclick', '').click(function(e) { +      return rcmail.command('open-attachment', id, this); +    }); + +    $('#attachmenudownload').unbind('click').attr('onclick', '').click(function() { +      rcmail.command('download-attachment', id, this); +    }); + +    popupconfig.attachmentmenu.link = elem; +    rcmail.command('menu-open', {menu: 'attachmentmenu', id: id}); +  }    function spellmenu(show)    {  | 
