Move & copy messages between different accounts

pull/17/head
Francis Lachapelle 2014-01-03 16:56:51 -05:00
parent 009cfccb2c
commit 7130cec4d1
4 changed files with 108 additions and 45 deletions

3
NEWS
View File

@ -1,4 +1,4 @@
2.1.2 (2013-11-XX) 2.1.2 (2014-01-XX)
------------------ ------------------
New features New features
@ -7,6 +7,7 @@ New features
- select multiple files to attach to a message or drag'n'drop files onto the - select multiple files to attach to a message or drag'n'drop files onto the
mail editor; will also now display progress of uploads mail editor; will also now display progress of uploads
- new popup menu to download all attachments of a mail - new popup menu to download all attachments of a mail
- move & copy messages between different accounts
Enhancements Enhancements
- we now automatically convert <img src=data...> into file attachments - we now automatically convert <img src=data...> into file attachments

View File

@ -1,5 +1,5 @@
/* /*
Copyright (C) 2009-2013 Inverse inc. Copyright (C) 2009-2014 Inverse inc.
Copyright (C) 2004-2005 SKYRIX Software AG Copyright (C) 2004-2005 SKYRIX Software AG
This file is part of SOGo. This file is part of SOGo.
@ -614,20 +614,19 @@ static NSString *defaultUserID = @"anyone";
if (max > 1) if (max > 1)
{ {
currentAccountName = [[self mailAccountFolder] nameInContainer]; currentAccountName = [[self mailAccountFolder] nameInContainer];
if ([[folders objectAtIndex: 1] isEqualToString: currentAccountName]) client = [[self imap4Connection] client];
{ [imap4 selectFolder: [self imap4URL]];
for (count = 2; count < max; count++)
{
currentFolderName
= [[folders objectAtIndex: count] substringFromIndex: 6];
[imapDestinationFolder appendFormat: @"/%@", currentFolderName];
}
client = [[self imap4Connection] client]; for (count = 2; count < max; count++)
if (client) {
currentFolderName = [[folders objectAtIndex: count] substringFromIndex: 6];
[imapDestinationFolder appendFormat: @"/%@", currentFolderName];
}
if (client)
{
if ([[folders objectAtIndex: 1] isEqualToString: currentAccountName])
{ {
[imap4 selectFolder: [self imap4URL]];
// We make sure the destination IMAP folder exist, if not, we create it. // We make sure the destination IMAP folder exist, if not, we create it.
result = [[client status: imapDestinationFolder result = [[client status: imapDestinationFolder
flags: [NSArray arrayWithObject: @"UIDVALIDITY"]] flags: [NSArray arrayWithObject: @"UIDVALIDITY"]]
@ -647,13 +646,69 @@ static NSString *defaultUserID = @"anyone";
objectForKey: @"description"]]; objectForKey: @"description"]];
} }
else else
result = [NSException exceptionWithName: @"SOGoMailException" {
reason: @"IMAP connection is invalid" // Destination folder is in a different account
userInfo: nil]; SOGoMailAccounts *accounts;
SOGoMailAccount *account;
accounts = [[self container] container];
account = [accounts lookupName: [folders objectAtIndex: 1] inContext: localContext acquire: NO];
if ([account isKindOfClass: [NSException class]])
{
result = [NSException exceptionWithHTTPStatus: 500
reason: @"Cannot copy messages to other account."];
}
else
{
NSEnumerator *messages;
NSDictionary *message;
NSData *content;
NSArray *flags;
// Fetch messages
result = [client fetchUids: uids parts: [NSArray arrayWithObjects: @"RFC822", @"FLAGS", nil]];
if ([[result objectForKey: @"result"] boolValue])
{
result = [result valueForKey: @"fetch"];
if ([result isKindOfClass: [NSArray class]] && [result count] > 0)
{
// Copy each message to the other account
client = [[account imap4Connection] client];
[[account imap4Connection] selectFolder: imapDestinationFolder];
messages = [result objectEnumerator];
result = nil;
while (result == nil && (message = [messages nextObject]))
{
if ((content = [message valueForKey: @"message"]) != nil)
{
flags = [message valueForKey: @"flags"];
result = [client append: content toFolder: imapDestinationFolder withFlags: flags];
if ([[result objectForKey: @"result"] boolValue])
result = nil;
else
[self logWithFormat: @"ERROR: Can't append message: %@", result];
}
}
}
else
{
[self logWithFormat: @"ERROR: unexpected IMAP4 result (missing 'fetch'): %@", result];
result = [NSException exceptionWithHTTPStatus: 500
reason: @"Unexpected IMAP4 result"];
}
}
else
{
[self logWithFormat: @"ERROR: Can't fetch messages: %@", result];
result = [NSException exceptionWithHTTPStatus: 500
reason: @"Can't fetch messages"];
}
}
}
} }
else else
result = [NSException exceptionWithHTTPStatus: 500 result = [NSException exceptionWithName: @"SOGoMailException"
reason: @"Cannot copy messages across different accounts."]; reason: @"IMAP connection is invalid"
userInfo: nil];
} }
else else
result = [NSException exceptionWithHTTPStatus: 500 result = [NSException exceptionWithHTTPStatus: 500

View File

@ -118,6 +118,22 @@
</ul> </ul>
</div> </div>
<div class="menu" id="moveMailboxMenu">
<ul>
<var:foreach list="clientObject.mailAccounts" item="currentLabel">
<li><img rsrc:src="tbtv_account_17x17.png"/> <var:string value="currentLabel.name"/></li>
</var:foreach>
</ul>
</div>
<div class="menu" id="copyMailboxMenu">
<ul>
<var:foreach list="clientObject.mailAccounts" item="currentLabel">
<li><img rsrc:src="tbtv_account_17x17.png"/> <var:string value="currentLabel.name"/></li>
</var:foreach>
</ul>
</div>
<div class="menu" id="messageListMenu"> <div class="menu" id="messageListMenu">
<ul> <ul>
<li><var:string label:value="Open Message In New Window"/></li> <li><var:string label:value="Open Message In New Window"/></li>

View File

@ -2055,7 +2055,7 @@ function initMailboxTree() {
node.parentNode.removeChild(node); node.parentNode.removeChild(node);
mailboxTree = new dTree("mailboxTree"); mailboxTree = new dTree("mailboxTree");
mailboxTree.config.hideRoot = true; mailboxTree.config.hideRoot = true;
mailboxTree.icon.root = ResourcesURL + "/tbtv_account_17x17.gif"; mailboxTree.icon.root = ResourcesURL + "/tbtv_account_17x17.png";
mailboxTree.icon.folder = ResourcesURL + "/tbtv_leaf_corner_17x17.png"; mailboxTree.icon.folder = ResourcesURL + "/tbtv_leaf_corner_17x17.png";
mailboxTree.icon.folderOpen = ResourcesURL + "/tbtv_leaf_corner_17x17.png"; mailboxTree.icon.folderOpen = ResourcesURL + "/tbtv_leaf_corner_17x17.png";
mailboxTree.icon.node = ResourcesURL + "/tbtv_leaf_corner_17x17.png"; mailboxTree.icon.node = ResourcesURL + "/tbtv_leaf_corner_17x17.png";
@ -2257,12 +2257,15 @@ function generateMenuForMailbox(mailbox, prefix, callback) {
function updateMailboxMenus() { function updateMailboxMenus() {
var mailboxActions = { move: onMailboxMenuMove, var mailboxActions = { move: onMailboxMenuMove,
copy: onMailboxMenuCopy }; copy: onMailboxMenuCopy };
var accountsMenus = { move: $$('#moveMailboxMenu li'),
copy: $$('#copyMailboxMenu li') };
for (var key in mailboxActions) { for (var key in mailboxActions) {
for (var i = 0; i < mailAccounts.length; i++) { for (var i = 0; i < mailAccounts.length; i++) {
var mailbox = accounts[i]; var mailbox = accounts[i];
generateMenuForMailbox(mailbox, key + "-" + i, var id = generateMenuForMailbox(mailbox, key + "-" + i,
mailboxActions[key]); mailboxActions[key]);
accountsMenus[key][i].submenu = id;
} }
} }
} }
@ -2828,6 +2831,8 @@ function getMenus() {
"-", null, "-", null,
onMenuSharing ], onMenuSharing ],
addressMenu: [ newContactFromEmail, newEmailTo ], addressMenu: [ newContactFromEmail, newEmailTo ],
moveMailboxMenu: mailAccounts.collect(function (account) { return account.asCSSIdentifier() }),
copyMailboxMenu: mailAccounts.collect(function (account) { return account.asCSSIdentifier() }),
messageListMenu: [ onMenuOpenMessage, "-", messageListMenu: [ onMenuOpenMessage, "-",
onMenuReplyToSender, onMenuReplyToSender,
onMenuReplyToAll, onMenuReplyToAll,
@ -2877,14 +2882,6 @@ function getMenus() {
markMenu.prepareVisibility = onMarkMenuPrepareVisibility; markMenu.prepareVisibility = onMarkMenuPrepareVisibility;
} }
var listMenus = [ "messageListMenu", "messagesListMenu", "messageContentMenu" ];
for (var i = 0; i < listMenus.length; i++) {
var menu = $(listMenus[i]);
if (menu) {
menu.prepareVisibility = onMessageListMenuPrepareVisibility;
}
}
var accountIconMenu = $("accountIconMenu"); var accountIconMenu = $("accountIconMenu");
if (accountIconMenu) { if (accountIconMenu) {
accountIconMenu.prepareVisibility = onAccountIconMenuPrepareVisibility; accountIconMenu.prepareVisibility = onAccountIconMenuPrepareVisibility;
@ -3018,20 +3015,14 @@ function stopDragging(event, ui) {
function dropAction(event, ui) { function dropAction(event, ui) {
var destination = $(this).up("div.dTreeNode"); var destination = $(this).up("div.dTreeNode");
var f;
var sourceAct = Mailer.currentMailbox.split("/")[1]; if (ui.helper.hasClass("copy")) {
var destAct = destination.getAttribute("dataname").split("/")[1]; // Message(s) copied
if (sourceAct == destAct) { f = onMailboxMenuCopy.bind(destination);
var f;
if (ui.helper.hasClass("copy")) {
// Message(s) copied
f = onMailboxMenuCopy.bind(destination);
}
else {
// Message(s) moved
f = onMailboxMenuMove.bind(destination);
}
f();
} }
else {
// Message(s) moved
f = onMailboxMenuMove.bind(destination);
}
f();
} }