diff --git a/NEWS b/NEWS index e5a247a3a..a3f835143 100644 --- a/NEWS +++ b/NEWS @@ -6,6 +6,7 @@ New features using SOGoCalendarDefaultReminder - select multiple files to attach to a message or drag'n'drop files onto the mail editor; will also now display progress of uploads + - new popup menu to download all attachments of a mail Enhancements - we now automatically convert into file attachments diff --git a/UI/MailerUI/English.lproj/Localizable.strings b/UI/MailerUI/English.lproj/Localizable.strings index ed65e4dda..761f0b6d8 100644 --- a/UI/MailerUI/English.lproj/Localizable.strings +++ b/UI/MailerUI/English.lproj/Localizable.strings @@ -97,11 +97,11 @@ "Reply-To" = "Reply-To"; "Add address" = "Add address"; -"Attachments:" = "Attachments:"; "Open" = "Open"; "Select All" = "Select All"; "Attach Web Page..." = "Attach Web Page..."; -"Attach File(s)..." = "Attach File(s)..."; +"file" = "file"; +"files" = "files"; "to" = "To"; "cc" = "Cc"; diff --git a/UI/MailerUI/UIxMailEditor.m b/UI/MailerUI/UIxMailEditor.m index e2b2c7ffd..470e2a93c 100644 --- a/UI/MailerUI/UIxMailEditor.m +++ b/UI/MailerUI/UIxMailEditor.m @@ -163,6 +163,11 @@ static NSArray *infoKeys = nil; return item; } +- (NSString *) uid +{ + return [[self clientObject] nameInContainer]; +} + - (NSArray *) priorityClasses { static NSArray *priorities = nil; @@ -382,16 +387,16 @@ static NSArray *infoKeys = nil; ASSIGN (attachment, newAttachment); } -- (NSFormatter *) sizeFormatter -{ - return [UIxMailSizeFormatter sharedMailSizeFormatter]; -} - - (NSDictionary *) attachment { return attachment; } +- (NSFormatter *) sizeFormatter +{ + return [UIxMailSizeFormatter sharedMailSizeFormatter]; +} + /* from addresses */ - (NSArray *) fromEMails @@ -672,11 +677,6 @@ static NSArray *infoKeys = nil; return [[self attachmentAttrs] count] > 0 ? YES : NO; } -- (NSString *) uid -{ - return [[self clientObject] nameInContainer]; -} - - (id) defaultAction { SOGoDraftObject *co; diff --git a/UI/MailerUI/UIxMailView.m b/UI/MailerUI/UIxMailView.m index e714bf6ab..371a2a504 100644 --- a/UI/MailerUI/UIxMailView.m +++ b/UI/MailerUI/UIxMailView.m @@ -47,11 +47,12 @@ #import #import #import +#import #import #import #import -#import #import // cyclic +#import #import "WOContext+UIxMailer.h" @@ -60,6 +61,8 @@ id currentAddress; NSString *shouldAskReceipt; NSString *matchingIdentityEMail; + NSDictionary *attachment; + NSArray *attachmentAttrs; } @end @@ -80,6 +83,8 @@ static NSString *mailETag = nil; - (void) dealloc { [matchingIdentityEMail release]; + [attachment release]; + [attachmentAttrs release]; [super dealloc]; } @@ -111,6 +116,16 @@ static NSString *mailETag = nil; [self messageSubject]]; } +- (void) setAttachment: (NSDictionary *) newAttachment +{ + ASSIGN (attachment, newAttachment); +} + +- (NSDictionary *) attachment +{ + return attachment; +} + /* links (DUP to UIxMailPartViewer!) */ - (NSString *) linkToEnvelopeAddress: (NGImap4EnvelopeAddress *) _address @@ -146,6 +161,36 @@ static NSString *mailETag = nil; return [[[self clientObject] replyToEnvelopeAddresses] count] > 0 ? YES : NO; } +/* attachment helper */ + +- (NSArray *) attachmentAttrs +{ + if (!attachmentAttrs) + { + ASSIGN (attachmentAttrs, [[self clientObject] fetchFileAttachmentKeys]); + } + + return attachmentAttrs; +} + +- (BOOL) hasAttachments +{ + return [[self attachmentAttrs] count] > 0 ? YES : NO; +} + +- (NSFormatter *) sizeFormatter +{ + return [UIxMailSizeFormatter sharedMailSizeFormatter]; +} + +- (NSString *) attachmentsText +{ + if ([[self attachmentAttrs] count] > 1) + return [self labelForKey: @"files"]; + else + return [self labelForKey: @"file"]; +} + /* viewers */ - (id) contentViewerComponent diff --git a/UI/Templates/MailerUI/UIxMailMainFrame.wox b/UI/Templates/MailerUI/UIxMailMainFrame.wox index f79b9755f..94c775b4e 100644 --- a/UI/Templates/MailerUI/UIxMailMainFrame.wox +++ b/UI/Templates/MailerUI/UIxMailMainFrame.wox @@ -211,12 +211,6 @@ - -
diff --git a/UI/Templates/MailerUI/UIxMailPopupView.wox b/UI/Templates/MailerUI/UIxMailPopupView.wox index 1ae438566..f3d17c577 100644 --- a/UI/Templates/MailerUI/UIxMailPopupView.wox +++ b/UI/Templates/MailerUI/UIxMailPopupView.wox @@ -9,13 +9,11 @@ const:jsFiles="SOGoAutoCompletion.js" const:userDefaultsKeys="SOGoMailDisplayRemoteInlineImages" const:popup="YES"> - - - - + + - - + diff --git a/UI/Templates/MailerUI/UIxMailView.wox b/UI/Templates/MailerUI/UIxMailView.wox index a0f3945ba..fcec52799 100644 --- a/UI/Templates/MailerUI/UIxMailView.wox +++ b/UI/Templates/MailerUI/UIxMailView.wox @@ -5,14 +5,25 @@ xmlns:uix="OGo:uix" xmlns:rsrc="OGo:url" xmlns:label="OGo:label"> + + + + - + > + @@ -93,11 +104,19 @@ + + + + + +
:
+ +
- +
diff --git a/UI/WebServerResources/MailerUI.css b/UI/WebServerResources/MailerUI.css index 837a56bee..fd0c7132b 100644 --- a/UI/WebServerResources/MailerUI.css +++ b/UI/WebServerResources/MailerUI.css @@ -374,21 +374,21 @@ TR.mailer_listcell_regular TD A } /* mail viewer */ -INPUT#editDraftButton +#editDraftButton { position: absolute; top: 2.5em; right: 1em; } -INPUT#loadImagesButton +#loadImagesButton { position: absolute; top: 2.5em; right: 1em; } -.popup INPUT#loadImagesButton +.popup #loadImagesButton { top: 9.0em; right: 1em; @@ -434,7 +434,8 @@ DIV.mailer_mailcontent TABLE } /* collapsable header */ -TD.mailer_fieldname IMG +TD.mailer_fieldname IMG.collapse, +TD.mailer_fieldname IMG.expand { cursor: pointer; padding-right: 5px; } TD.mailer_fieldvalue SPAN.collapse @@ -577,7 +578,7 @@ DIV.linked_attachment_meta { color: #444444; border-width: 0; - padding: 2px; + padding: 2px 4px; } TABLE.linked_attachment_meta @@ -585,6 +586,25 @@ TABLE.linked_attachment_meta color: #444444; } +.linked_attachment_body a:hover +{ + text-decoration: none; +} + +.linked_attachment_body a:hover .linked_attachment_meta +{ + background-color: #9ABCD8; + color: #fff; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; +} + +.linked_attachment_body a:hover .muted +{ + color: #fff !important; +} + DIV.linked_attachment_body HR { border: 0px; diff --git a/UI/WebServerResources/MailerUI.js b/UI/WebServerResources/MailerUI.js index 847b64a99..106187f16 100644 --- a/UI/WebServerResources/MailerUI.js +++ b/UI/WebServerResources/MailerUI.js @@ -1357,13 +1357,27 @@ function configureLinksInMessage() { anchor.observe("contextmenu", onEmailAddressClick); anchor.writeAttribute("moz-do-not-send", false); } - else + else if (!anchor.id) anchor.observe("click", onMessageAnchorClick); } - var attachments = messageDiv.select ("DIV.linked_attachment_body"); - for (var i = 0; i < attachments.length; i++) - $(attachments[i]).observe("contextmenu", onAttachmentClick); + var attachmentsMenu = $("attachmentsMenu"); + if (attachmentsMenu) { + var options = attachmentsMenu.select("li"); + var callbacks = []; + for (var i = 0; i < options.length; i++) { + if (options[i].className == 'separator') + callbacks.push(null); + else + callbacks.push(saveAttachment); + } + initMenu(attachmentsMenu, callbacks); + $("attachmentsHref").on("click", function (event) { + popupMenu(event, 'attachmentsMenu', this); + preventDefault(event); + return false; + }); + } var images = messageDiv.select("IMG.mailer_imagecontent"); for (var i = 0; i < images.length; i++) @@ -1371,12 +1385,11 @@ function configureLinksInMessage() { var editDraftButton = $("editDraftButton"); if (editDraftButton) - editDraftButton.observe("click", - onMessageEditDraft.bindAsEventListener(editDraftButton)); + editDraftButton.on("click", onMessageEditDraft); var loadImagesButton = $("loadImagesButton"); if (loadImagesButton) - $(loadImagesButton).observe("click", onMessageLoadImages); + loadImagesButton.on("click", onMessageLoadImages); configureiCalLinksInMessage(); } @@ -1562,12 +1575,13 @@ function onMessageContentMenu(event) { } function onMessageEditDraft(event) { + Event.stop(event); return openMessageWindowsForSelection("edit", true); } function onMessageLoadImages(event) { - loadRemoteImages(); Event.stop(event); + loadRemoteImages(); } function loadRemoteImages() { @@ -1613,12 +1627,6 @@ function onImageClick(event) { return false; } -function onAttachmentClick (event) { - popupMenu (event, 'attachmentMenu', this); - preventDefault (event); - return false; -} - function handleReturnReceipt() { var input = $("shouldAskReceipt"); if (input) { @@ -1773,13 +1781,29 @@ function saveImage(event) { window.location.href = urlAsAttachment; } -function saveAttachment(event) { - var div = document.menuTarget; - var link = div.select ("a").first (); - var url = link.getAttribute("href"); - var urlAsAttachment = url.replace(/(\/[^\/]*)$/,"/asAttachment$1"); +/* Download a file using a temporary iframe that we delete once the download is started */ +function download(url) { + var form = createElement('form', null, 'hidden', { action: url, method: 'GET'}); + $(document.body).appendChild(form); + var div = AIM.submit(form); + form.submit(); + setTimeout(function () { + form.remove(); + div.remove(); + }, 2000); +} - window.location.href = urlAsAttachment; +function saveAttachment(event) { + var url = $(this).readAttribute('data-url'); + if (url) { + download(url); + } + else { + $(this).up('ul').select('li[data-url]').each(function (item) { + url = $(item).readAttribute('data-url'); + download(url); + }); + } } /* contacts */ @@ -2820,7 +2844,6 @@ function getMenus() { saveAs, null, null, onMenuDeleteMessage ], imageMenu: [ saveImage ], - attachmentMenu: [ saveAttachment ], messageContentMenu: [ onMenuReplyToSender, onMenuReplyToAll, onMenuForwardMessage, diff --git a/UI/WebServerResources/generic.css b/UI/WebServerResources/generic.css index 3ac0be8e3..22f723911 100644 --- a/UI/WebServerResources/generic.css +++ b/UI/WebServerResources/generic.css @@ -251,7 +251,8 @@ DIV.contactSelector DIV.contactList padding-bottom: .15em; margin: 0px; width: auto; - white-space: nowrap; } + white-space: nowrap; + cursor: pointer; } .menu LI.disabled, .popuMenu LI.disabled, @@ -283,10 +284,11 @@ UL.choiceMenu LI._chosen:hover { list-style-image: url("menu-check-hover.gif"); } .menu LI:hover, +.menu LI:hover .muted, .menu LI.selected, .menu LI.submenu-selected { background-color: #9ABCD8; - color: #fff; } + color: #fff !important; } .menu LI.disabled:hover { background-color: inherit; } diff --git a/UI/WebServerResources/generic.js b/UI/WebServerResources/generic.js index 04b67c9fb..0b621f0a3 100644 --- a/UI/WebServerResources/generic.js +++ b/UI/WebServerResources/generic.js @@ -1925,7 +1925,7 @@ AIM = { d.innerHTML = ''; document.body.appendChild(d); - var i = $(n); // TODO: useful? + var i = $(n); if (c && typeof(c.onComplete) == 'function') i.onComplete = c.onComplete; return n; @@ -1936,27 +1936,28 @@ AIM = { }, submit: function(f, c) { - AIM.form(f, AIM.frame(c)); + var id = AIM.frame(c); + AIM.form(f, id); if (c && typeof(c.onStart) == 'function') return c.onStart(); else - return true; + return $(id); }, loaded: function(id) { var i = $(id); + var d; if (i.contentDocument) { - var d = i.contentDocument; + d = i.contentDocument; } else if (i.contentWindow) { - var d = i.contentWindow.document; + d = i.contentWindow.document; } else { - var d = window.frames[id].document; + d = window.frames[id].document; } if (d.location.href == "about:blank") return; - if (typeof(i.onComplete) == 'function') { i.onComplete(Element.allTextContent(d.body)); }