Bug 573392 - Port |Bug 522761 Need option 'keep folders scheme' under the archive feature to don't forget the messages organization| to SeaMonkey. Also fixes Bug 494266 - [IMAP] Archive subfolders not shown in folder pane directly after their creation. r=Mnyromyr sr=Neil

This commit is contained in:
Jens Hatlak 2010-06-28 19:06:53 +02:00
Родитель d145129cec
Коммит 8f9553b273
2 изменённых файлов: 102 добавлений и 16 удалений

Просмотреть файл

@ -347,7 +347,18 @@ var DefaultController =
case "button_file":
case "cmd_file":
case "cmd_archive":
return (GetNumSelectedMessages() > 0);
let selectedMessages = gFolderDisplay.selectedMessages;
if (selectedMessages.length == 0)
return false;
// If the server of the first message's folder is configured to keep
// the folder structure on archiving, check that we're not in the Archive
// folder or below it. Otherwise allow re-archiving, e.g. in case the
// user switched from monthly to yearly archiving.
if (selectedMessages[0].folder && selectedMessages[0].folder.server &&
selectedMessages[0].folder.server.archiveKeepFolderStructure)
return gFolderDisplay.displayedFolder && !gFolderDisplay.displayedFolder
.isSpecialFolder(Components.interfaces.nsMsgFolderFlags.Archive, true);
return true;
case "cmd_markAsJunk":
case "cmd_markAsNotJunk":
if (gDBView)

Просмотреть файл

@ -31,6 +31,7 @@
* Karsten Düsterloh <mnyromyr@tprac.de>
* Christopher Thomas <cst@yecc.com>
* Jeremy Morton <bugzilla@game-point.net>
* Jens Hatlak <jh@junetz.de>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
@ -1174,6 +1175,8 @@ function BatchMessageMover()
{
this._batches = {};
this._currentKey = null;
this._dstFolderParent = null;
this._dstFolderName = null;
}
BatchMessageMover.prototype =
@ -1194,14 +1197,36 @@ BatchMessageMover.prototype =
for (let i = 0; i < aMsgHdrs.length; ++i)
{
let msgHdr = aMsgHdrs[i];
let server = msgHdr.folder.server;
let msgDate = new Date(msgHdr.date / 1000); // convert date to JS date object
let msgYear = msgDate.getFullYear().toString();
let dstFolderName = msgDate.toLocaleFormat("%Y-%m");
let copyBatchKey = msgHdr.folder.URI + '\000' + dstFolderName;
let monthFolderName = msgDate.toLocaleFormat("%Y-%m");
// RSS servers don't have an identity so we special case the archives URI.
let archiveFolderUri;
if (server.type == 'rss')
archiveFolderUri = server.serverURI + "/Archives";
else
archiveFolderUri = GetIdentityForHeader(msgHdr,
Components.interfaces.nsIMsgCompType.ReplyAll).archiveFolder;
let archiveFolder = GetMsgFolderFromUri(archiveFolderUri, false);
let afServer = archiveFolder.server;
let copyBatchKey = msgHdr.folder.URI + '\000' + monthFolderName;
if (!(copyBatchKey in this._batches))
this._batches[copyBatchKey] = [msgHdr.folder, msgYear, dstFolderName];
this._batches[copyBatchKey] = [msgHdr.folder,
archiveFolderUri,
afServer.archiveGranularity,
afServer.archiveKeepFolderStructure,
msgYear,
monthFolderName];
this._batches[copyBatchKey].push(msgHdr);
}
let notificationService = Components.classes["@mozilla.org/messenger/msgnotificationservice;1"]
.getService(Components.interfaces.nsIMsgFolderNotificationService);
notificationService.addListener(this, notificationService.folderAdded);
// Now we launch the code iterating over all message copies, one in turn.
this.processNextBatch();
},
@ -1212,21 +1237,11 @@ BatchMessageMover.prototype =
{
this._currentKey = key;
let batch = this._batches[key];
let srcFolder = batch[0];
let msgYear = batch[1];
let msgMonth = batch[2];
let msgs = batch.slice(3);
// RSS servers don't have an identity so we special case the archives URI.
let archiveFolderUri;
if (srcFolder.server.type == 'rss')
archiveFolderUri = srcFolder.server.serverURI + "/Archives";
else
archiveFolderUri = GetIdentityForHeader(msgs[0],
Components.interfaces.nsIMsgCompType.ReplyAll).archiveFolder;
let [srcFolder, archiveFolderUri, granularity, keepFolderStructure, msgYear, msgMonth] = batch;
let msgs = batch.slice(6);
let archiveFolder = GetMsgFolderFromUri(archiveFolderUri, false);
let dstFolder = archiveFolder;
let granularity = archiveFolder.server.archiveGranularity;
// For imap folders, we need to create the sub-folders asynchronously,
// so we chain the urls using the listener called back from
// createStorageIfMissing. For local, createStorageIfMissing is
@ -1263,8 +1278,49 @@ BatchMessageMover.prototype =
return;
}
}
// Create the folder structure in Archives
// For imap folders, we need to create the sub-folders asynchronously,
// so we chain the actions using the listener called back from
// createSubfolder. For local, createSubfolder is synchronous.
if (archiveFolder.canCreateSubfolders && keepFolderStructure)
{
// Collect in-order list of folders of source folder structure,
// excluding top-level INBOX folder
let folderNames = [];
let rootFolder = srcFolder.server.rootFolder;
let inboxFolder = GetInboxFolder(srcFolder.server);
let folder = srcFolder;
while (folder != rootFolder && folder != inboxFolder)
{
folderNames.unshift(folder.name);
folder = folder.parent;
}
// Determine Archive folder structure
for (let i = 0; i < folderNames.length; ++i)
{
let folderName = folderNames[i];
if (!dstFolder.containsChildNamed(folderName))
{
// Create Archive sub-folder (IMAP: async)
if (isImap)
{
this._dstFolderParent = dstFolder;
this._dstFolderName = folderName;
}
dstFolder.createSubfolder(folderName, msgWindow);
if (isImap)
return;
}
dstFolder = dstFolder.getChildNamed(folderName);
}
}
if (dstFolder != srcFolder)
{
// Make sure the target folder is visible in the folder tree.
EnsureFolderIndex(GetFolderTree().builderView, dstFolder);
let array = Components.classes["@mozilla.org/array;1"]
.createInstance(Components.interfaces.nsIMutableArray);
msgs.forEach(function(item){array.appendElement(item, false);});
@ -1277,6 +1333,10 @@ BatchMessageMover.prototype =
delete this._batches[key];
}
Components.classes["@mozilla.org/messenger/msgnotificationservice;1"]
.getService(Components.interfaces.nsIMsgFolderNotificationService)
.removeListener(this);
// We're just going to select the message now.
let treeView = gDBView.QueryInterface(Components.interfaces.nsITreeView);
treeView.selection.select(this.messageToSelectAfterWereDone);
@ -1326,10 +1386,25 @@ BatchMessageMover.prototype =
}
},
// This also implements nsIMsgFolderListener, but we only care about the
// folderAdded (createSubfolder callback).
folderAdded: function(aFolder)
{
// Check that this is the folder we're interested in.
if (aFolder.parent == this._dstFolderParent &&
aFolder.name == this._dstFolderName)
{
this._dstFolderParent = null;
this._dstFolderName = null;
this.processNextBatch();
}
},
QueryInterface: function(aIID)
{
if (aIID.equals(Components.interfaces.nsIUrlListener) ||
aIID.equals(Components.interfaces.nsIMsgCopyServiceListener) ||
aIID.equals(Components.interfaces.nsIMsgFolderListener) ||
aIID.equals(Components.interfaces.nsISupports))
return this;
throw Components.results.NS_ERROR_NO_INTERFACE;