Move & copy messages between different accounts
parent
009cfccb2c
commit
7130cec4d1
3
NEWS
3
NEWS
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue