25589. r=timeless, sr=bienvenu, sspitzer. Adding feature drag and drop of folder.
Thanks to sspitzer and david for good review. git-svn-id: svn://10.0.0.236/trunk@86107 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
parent
a7fd5e9473
commit
683df5eaa9
@ -61,7 +61,11 @@ interface nsIMessenger : nsISupports {
|
||||
in nsIRDFResource dstFolder,
|
||||
in nsISupportsArray messages,
|
||||
in boolean isMove);
|
||||
|
||||
void CopyFolders(in nsIRDFCompositeDataSource database,
|
||||
in nsIRDFResource dstFolder,
|
||||
in nsISupportsArray folders,
|
||||
in boolean isMoveFolder);
|
||||
|
||||
void OpenURL(in string url);
|
||||
void RenameFolder(in nsIRDFCompositeDataSource db,
|
||||
in nsIRDFResource folder, in wstring name);
|
||||
|
||||
@ -51,7 +51,13 @@ interface nsIMsgCopyService : nsISupports {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
void CopyFileMessage(in nsIFileSpec fileSpec,
|
||||
void CopyFolders( in nsISupportsArray folders,
|
||||
in nsIMsgFolder dstFolder,
|
||||
in boolean isMove,
|
||||
in nsIMsgCopyServiceListener listener,
|
||||
in nsIMsgWindow msgWindow);
|
||||
|
||||
void CopyFileMessage(in nsIFileSpec fileSpec,
|
||||
in nsIMsgFolder dstFolder,
|
||||
in nsIMessage msgToReplace,
|
||||
in boolean isDraftOrTemplate,
|
||||
|
||||
@ -284,7 +284,10 @@ const nsMsgBiffState nsMsgBiffState_Unknown = 2; // We dunno whether there is ne
|
||||
|
||||
void copyMessages(in nsIMsgFolder srcFolder, in nsISupportsArray messages,
|
||||
in boolean isMove, in nsIMsgWindow msgWindow,
|
||||
in nsIMsgCopyServiceListener listener);
|
||||
in nsIMsgCopyServiceListener listener, in boolean isFolder);
|
||||
|
||||
void copyFolder(in nsIMsgFolder srcFolder, in boolean isMoveFolder,
|
||||
in nsIMsgWindow msgWindow, in nsIMsgCopyServiceListener listener );
|
||||
|
||||
void copyFileMessage(in nsIFileSpec fileSpec, in nsIMessage msgToReplace,
|
||||
in boolean isDraft, in nsIMsgWindow msgWindow,
|
||||
|
||||
@ -86,10 +86,6 @@ function LoadMessageByUri(uri)
|
||||
|
||||
function ChangeFolderByDOMNode(folderNode)
|
||||
{
|
||||
if (folderNode.getAttribute('NoSelect') == "true" ) {
|
||||
ClearThreadPane();
|
||||
return;
|
||||
}
|
||||
var uri = folderNode.getAttribute('id');
|
||||
dump(uri + "\n");
|
||||
|
||||
|
||||
@ -23,6 +23,7 @@
|
||||
*/
|
||||
|
||||
var ctrlKeydown = false;
|
||||
var gSrcCanRename;
|
||||
|
||||
function debugDump(msg)
|
||||
{
|
||||
@ -50,13 +51,15 @@ function GetRDFService()
|
||||
|
||||
function DragOverTree(event)
|
||||
{
|
||||
if (event.target.localName != "treecell" &&
|
||||
event.target.localName != "treeitem") {
|
||||
event.preventBubble();
|
||||
return false;
|
||||
}
|
||||
if (event.target.localName != "treecell" &&
|
||||
event.target.localName != "treeitem") {
|
||||
event.preventBubble();
|
||||
return false;
|
||||
}
|
||||
|
||||
var msgFlavor = false;
|
||||
var folderFlavor = false;
|
||||
|
||||
var validFlavor = false;
|
||||
var dragSession = null;
|
||||
|
||||
var dragService = GetDragService();
|
||||
@ -65,47 +68,143 @@ function DragOverTree(event)
|
||||
dragSession = dragService.getCurrentSession();
|
||||
if ( !dragSession ) return(false);
|
||||
|
||||
if ( dragSession.isDataFlavorSupported("text/nsmessage") ) validFlavor = true;
|
||||
if ( dragSession.isDataFlavorSupported("text/nsmessage") ) msgFlavor = true;
|
||||
if ( dragSession.isDataFlavorSupported("text/nsfolder") ) folderFlavor = true;
|
||||
|
||||
var treeItem = event.target.parentNode.parentNode;
|
||||
if (!treeItem) return(false);
|
||||
|
||||
var trans = Components.classes["@mozilla.org/widget/transferable;1"].createInstance(Components.interfaces.nsITransferable);
|
||||
if ( !trans ) return(false);
|
||||
|
||||
|
||||
if (msgFlavor)
|
||||
{
|
||||
var isServer = treeItem.getAttribute("IsServer");
|
||||
if (isServer == "true")
|
||||
{
|
||||
debugDump("***isServer == true\n");
|
||||
return(false);
|
||||
}
|
||||
var canFileMessages = treeItem.getAttribute("CanFileMessages");
|
||||
if (canFileMessages != "true")
|
||||
{
|
||||
debugDump("***canFileMessages == false\n");
|
||||
return(false);
|
||||
}
|
||||
var noSelect = treeItem.getAttribute("NoSelect");
|
||||
if (noSelect == "true")
|
||||
{
|
||||
debugDump("***NoSelect == true\n");
|
||||
return(false);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (folderFlavor)
|
||||
{
|
||||
debugDump("***isFolderFlavor == true \n");
|
||||
|
||||
if (event.ctrlKey) //ctrlkey does not apply to folder drag
|
||||
return(false);
|
||||
|
||||
var canCreateSubfolders = treeItem.getAttribute('CanCreateSubfolders');
|
||||
if ( canCreateSubfolders == "false") // if cannot create subfolders then a folder cannot be dropped here
|
||||
{
|
||||
debugDump("***canCreateSubfolders == false \n");
|
||||
return(false);
|
||||
}
|
||||
var serverType = treeItem.getAttribute('ServerType');
|
||||
if ( serverType != "none" && gSrcCanRename == "false")
|
||||
{ //folders that cannot be renamed can be dropped only on local folders.
|
||||
return(false);
|
||||
}
|
||||
|
||||
var targetID = treeItem.getAttribute("id");
|
||||
var targetNode = RDF.GetResource(targetID, true);
|
||||
if (!targetNode) return(false);
|
||||
var targetfolder = targetNode.QueryInterface(Components.interfaces.nsIMsgFolder);
|
||||
var targetServer = targetfolder.server;
|
||||
|
||||
trans.addDataFlavor("text/nsfolder");
|
||||
|
||||
for ( var i = 0; i < dragSession.numDropItems; ++i )
|
||||
{
|
||||
dragSession.getData ( trans, i );
|
||||
var dataObj = new Object();
|
||||
var bestFlavor = new Object();
|
||||
var len = new Object();
|
||||
trans.getAnyTransferData ( bestFlavor, dataObj, len );
|
||||
if ( dataObj ) dataObj = dataObj.value.QueryInterface(Components.interfaces.nsISupportsWString);
|
||||
if ( !dataObj ) continue;
|
||||
|
||||
// pull the URL out of the data object
|
||||
var sourceID = dataObj.data.substring(0, len.value);
|
||||
if (!sourceID) continue;
|
||||
|
||||
var sourceNode = RDF.GetResource(sourceID, true);
|
||||
var folder = sourceNode.QueryInterface(Components.interfaces.nsIFolder);
|
||||
var sourceResource = folder.QueryInterface(Components.interfaces.nsIRDFResource);
|
||||
var sourcefolder = sourceResource.QueryInterface(Components.interfaces.nsIMsgFolder);
|
||||
var sourceServer = sourcefolder.server;
|
||||
|
||||
if (sourceNode == targetNode)
|
||||
return (false);
|
||||
|
||||
if (sourceServer != targetServer && targetServer.type == "imap") //don't allow drop on different imap servers.
|
||||
return (false);
|
||||
|
||||
if (targetfolder.URI == sourcefolder.parent.URI) //don't allow immediate child to be dropped to it's parent
|
||||
{
|
||||
debugDump(targetfolder.URI + "\n");
|
||||
debugDump(sourcefolder.parent.URI + "\n");
|
||||
return (false);
|
||||
}
|
||||
|
||||
var isAncestor = sourcefolder.isAncestorOf(targetfolder);
|
||||
if (isAncestor) // don't allow parent to be dropped on its ancestors
|
||||
return (false);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//XXX other flavors here...
|
||||
|
||||
// touch the attribute on the treeItem to trigger the repaint with the drop feedback
|
||||
// (recall that it is two levels above the target, which is a treeCell).
|
||||
if ( validFlavor )
|
||||
if ( msgFlavor || folderFlavor )
|
||||
{
|
||||
//XXX this is really slow and likes to refresh N times per second.
|
||||
event.target.parentNode.parentNode.setAttribute ( "dd-triggerrepaint", 0 );
|
||||
dragSession.canDrop = true;
|
||||
event.preventBubble(); // do not propagate message
|
||||
return true;
|
||||
//XXX this is really slow and likes to refresh N times per second.
|
||||
event.target.parentNode.parentNode.setAttribute ( "dd-triggerrepaint", 0 );
|
||||
dragSession.canDrop = true;
|
||||
event.preventBubble(); // do not propagate message
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function BeginDragFolderTree(event)
|
||||
function BeginDragTree(event, tree, flavor)
|
||||
{
|
||||
debugDump("BeginDragFolderTree\n");
|
||||
if (event.target.localName != "treecell" &&
|
||||
event.target.localName != "treeitem")
|
||||
return false;
|
||||
return(false);
|
||||
}
|
||||
|
||||
function BeginDragThreadTree(event)
|
||||
{
|
||||
debugDump("BeginDragThreadTree\n");
|
||||
if (event.target.localName != "treecell" &&
|
||||
event.target.localName != "treeitem")
|
||||
return false;
|
||||
|
||||
//XXX we rely on a capturer to already have determined which item the mouse was over
|
||||
//XXX and have set an attribute.
|
||||
|
||||
// if the click is on the tree proper, ignore it. We only care about clicks on items.
|
||||
|
||||
var tree = GetThreadTree();
|
||||
if ( event.target == tree )
|
||||
return(true); // continue propagating the event
|
||||
return(true); // continue propagating the event
|
||||
|
||||
var treeItem = event.target.parentNode.parentNode;
|
||||
if (!treeItem) return(false);
|
||||
|
||||
if (flavor == "text/nsfolder")
|
||||
{
|
||||
|
||||
gSrcCanRename = treeItem.getAttribute('CanRename'); //used in DragOverTree
|
||||
|
||||
var serverType = treeItem.getAttribute('ServerType') // do not allow the drag when news is the source
|
||||
if ( serverType == "nntp")
|
||||
{
|
||||
debugDump("***serverType == nntp \n");
|
||||
return(false);
|
||||
}
|
||||
}
|
||||
|
||||
var childWithDatabase = tree;
|
||||
if ( ! childWithDatabase )
|
||||
return(false);
|
||||
@ -114,11 +213,6 @@ function BeginDragThreadTree(event)
|
||||
var rdf = GetRDFService();
|
||||
if ((!rdf) || (!database)) { debugDump("CAN'T GET DATABASE\n"); return(false); }
|
||||
|
||||
if (event.ctrlKey)
|
||||
ctrlKeydown = true;
|
||||
else
|
||||
ctrlKeydown = false;
|
||||
|
||||
var dragStarted = false;
|
||||
|
||||
var dragService = GetDragService();
|
||||
@ -132,20 +226,21 @@ function BeginDragThreadTree(event)
|
||||
debugDump("selArray.length = " + count + "\n");
|
||||
for ( var i = 0; i < count; ++i )
|
||||
{
|
||||
|
||||
var trans = Components.classes["@mozilla.org/widget/transferable;1"].createInstance(Components.interfaces.nsITransferable);
|
||||
if ( !trans ) return(false);
|
||||
|
||||
var genTextData = Components.classes["@mozilla.org/supports-wstring;1"].createInstance(Components.interfaces.nsISupportsWString);
|
||||
if (!genTextData) return(false);
|
||||
|
||||
trans.addDataFlavor("text/nsmessage");
|
||||
trans.addDataFlavor(flavor);
|
||||
|
||||
// get id (url)
|
||||
var id = selArray[i].getAttribute("id");
|
||||
genTextData.data = id;
|
||||
debugDump(" ID #" + i + " = " + id + "\n");
|
||||
|
||||
trans.setTransferData ( "text/nsmessage", genTextData, id.length * 2 ); // doublebyte byte data
|
||||
trans.setTransferData ( flavor, genTextData, id.length * 2 ); // doublebyte byte data
|
||||
|
||||
// put it into the transferable as an |nsISupports|
|
||||
var genTrans = trans.QueryInterface(Components.interfaces.nsISupports);
|
||||
@ -154,12 +249,44 @@ function BeginDragThreadTree(event)
|
||||
|
||||
var nsIDragService = Components.interfaces.nsIDragService;
|
||||
dragService.invokeDragSession ( event.target, transArray, null, nsIDragService.DRAGDROP_ACTION_COPY +
|
||||
nsIDragService.DRAGDROP_ACTION_MOVE );
|
||||
nsIDragService.DRAGDROP_ACTION_MOVE );
|
||||
|
||||
dragStarted = true;
|
||||
|
||||
return(!dragStarted); // don't propagate the event if a drag has begun
|
||||
}
|
||||
|
||||
function BeginDragFolderTree(event)
|
||||
{
|
||||
debugDump("BeginDragFolderTree\n");
|
||||
if (event.target.localName != "treecell" &&
|
||||
event.target.localName != "treeitem")
|
||||
return false;
|
||||
|
||||
var tree = GetFolderTree();
|
||||
|
||||
return BeginDragTree(event, tree, "text/nsfolder");
|
||||
|
||||
}
|
||||
|
||||
|
||||
function BeginDragThreadTree(event)
|
||||
{
|
||||
debugDump("BeginDragThreadTree\n");
|
||||
if (event.target.localName != "treecell" &&
|
||||
event.target.localName != "treeitem")
|
||||
return false;
|
||||
|
||||
//XXX we rely on a capturer to already have determined which item the mouse was over
|
||||
//XXX and have set an attribute.
|
||||
|
||||
// if the click is on the tree proper, ignore it. We only care about clicks on items.
|
||||
|
||||
var tree = GetThreadTree();
|
||||
|
||||
return BeginDragTree(event, tree, "text/nsmessage");
|
||||
}
|
||||
|
||||
function DropOnFolderTree(event)
|
||||
{
|
||||
debugDump("DropOnTree\n");
|
||||
@ -196,24 +323,6 @@ function DropOnFolderTree(event)
|
||||
debugDump("***targetID = " + targetID + "\n");
|
||||
|
||||
//make sure target is a folder
|
||||
var isServer = treeItem.getAttribute("IsServer");
|
||||
if (isServer == "true")
|
||||
{
|
||||
debugDump("***isServer == true\n");
|
||||
return(false);
|
||||
}
|
||||
var canFileMessages = treeItem.getAttribute("CanFileMessages");
|
||||
if (canFileMessages != "true")
|
||||
{
|
||||
debugDump("***canFileMessages == false\n");
|
||||
return(false);
|
||||
}
|
||||
var noSelect = treeItem.getAttribute("NoSelect");
|
||||
if (noSelect == "true")
|
||||
{
|
||||
debugDump("***NoSelect == true\n");
|
||||
return(false);
|
||||
}
|
||||
|
||||
var dragService = GetDragService();
|
||||
if ( !dragService ) return(false);
|
||||
@ -223,11 +332,29 @@ function DropOnFolderTree(event)
|
||||
|
||||
var trans = Components.classes["@mozilla.org/widget/transferable;1"].createInstance(Components.interfaces.nsITransferable);
|
||||
if ( !trans ) return(false);
|
||||
trans.addDataFlavor("text/nsmessage");
|
||||
|
||||
var isNews = false;
|
||||
var messageList = Components.classes["@mozilla.org/supports-array;1"].createInstance(Components.interfaces.nsISupportsArray);
|
||||
var list = Components.classes["@mozilla.org/supports-array;1"].createInstance(Components.interfaces.nsISupportsArray);
|
||||
|
||||
var dropMessage = false;
|
||||
if (dragSession.isDataFlavorSupported("text/nsmessage"))
|
||||
{
|
||||
dropMessage = true;
|
||||
debugDump( "dropMessage == true \n");
|
||||
}
|
||||
|
||||
var dropFolder = false;
|
||||
if (dragSession.isDataFlavorSupported("text/nsfolder"))
|
||||
{
|
||||
dropFolder = true;
|
||||
debugDump( "dropFolder == true \n");
|
||||
}
|
||||
|
||||
if ( dropMessage )
|
||||
trans.addDataFlavor("text/nsmessage");
|
||||
else if ( dropFolder )
|
||||
trans.addDataFlavor("text/nsfolder");
|
||||
|
||||
var listCount =0;
|
||||
for ( var i = 0; i < dragSession.numDropItems; ++i )
|
||||
{
|
||||
dragSession.getData ( trans, i );
|
||||
@ -248,64 +375,97 @@ function DropOnFolderTree(event)
|
||||
var sourceNode = RDF.GetResource(sourceID, true);
|
||||
if (!sourceNode)
|
||||
continue;
|
||||
|
||||
// Prevent dropping of a node before, after, or on itself
|
||||
if (sourceNode == targetNode) continue;
|
||||
|
||||
messageList.AppendElement(sourceNode);
|
||||
// Prevent dropping of a node before, after, or on itself
|
||||
if (sourceNode == targetNode)
|
||||
continue;
|
||||
else
|
||||
listCount ++;
|
||||
|
||||
list.AppendElement(sourceNode);
|
||||
}
|
||||
|
||||
isNews = isNewsURI(sourceID);
|
||||
if (listCount < 1)
|
||||
return false;
|
||||
|
||||
var isSourceNews = false;
|
||||
isSourceNews = isNewsURI(sourceID);
|
||||
|
||||
var targetNode = RDF.GetResource(targetID, true);
|
||||
if (!targetNode) return(false);
|
||||
var targetfolder = targetNode.QueryInterface(Components.interfaces.nsIMsgFolder);
|
||||
var targetServer = targetfolder.server;
|
||||
|
||||
var message = sourceNode.QueryInterface(Components.interfaces.nsIMessage);
|
||||
var folder = message.msgFolder;
|
||||
var sourceRescource = folder.QueryInterface(Components.interfaces.nsIRDFResource);
|
||||
var sourcefolder = sourceRescource.QueryInterface(Components.interfaces.nsIMsgFolder);
|
||||
var sourceServer = sourcefolder.server;
|
||||
var nextMessage;
|
||||
var messageTree;
|
||||
if (dropMessage)
|
||||
{
|
||||
var message = sourceNode.QueryInterface(Components.interfaces.nsIMessage);
|
||||
var folder = message.msgFolder;
|
||||
var sourceResource = folder.QueryInterface(Components.interfaces.nsIRDFResource);
|
||||
var sourcefolder = sourceResource.QueryInterface(Components.interfaces.nsIMsgFolder);
|
||||
var sourceServer = sourcefolder.server;
|
||||
var nextMessage;
|
||||
var messageTree;
|
||||
|
||||
if (isNews) //news to pop or imap is always a copy
|
||||
{
|
||||
try
|
||||
{
|
||||
messenger.CopyMessages(treeDatabase,
|
||||
sourceRescource,
|
||||
targetNode, messageList, false);
|
||||
}
|
||||
catch(e)
|
||||
{
|
||||
dump ( "Exception : CopyMessages \n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isSourceNews) //news to pop or imap is always a copy
|
||||
{
|
||||
try
|
||||
{
|
||||
messenger.CopyMessages(treeDatabase,
|
||||
sourceResource,
|
||||
targetNode, list, false);
|
||||
}
|
||||
catch(e)
|
||||
{
|
||||
dump ( "Exception : CopyMessages \n");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//temperary for single mail window, not working when supporting multiple mail windows
|
||||
if (!ctrlKeydown)
|
||||
{
|
||||
messageTree = GetThreadTree();
|
||||
nextMessage = GetNextMessageAfterDelete(messageTree.selectedItems);
|
||||
if(nextMessage)
|
||||
gNextMessageAfterDelete = nextMessage.getAttribute('id');
|
||||
else
|
||||
gNextMessageAfterDelete = null;
|
||||
}
|
||||
try {
|
||||
messenger.CopyMessages(treeDatabase,
|
||||
sourceRescource,
|
||||
targetNode, messageList, !ctrlKeydown);
|
||||
}
|
||||
catch(e)
|
||||
{
|
||||
gNextMessageAfterDelete = null;
|
||||
dump ( "Exception : CopyMessages \n");
|
||||
}
|
||||
if (!ctrlKeydown)
|
||||
{
|
||||
messageTree = GetThreadTree();
|
||||
nextMessage = GetNextMessageAfterDelete(messageTree.selectedItems);
|
||||
if(nextMessage)
|
||||
gNextMessageAfterDelete = nextMessage.getAttribute('id');
|
||||
else
|
||||
gNextMessageAfterDelete = null;
|
||||
}
|
||||
try {
|
||||
messenger.CopyMessages(treeDatabase,
|
||||
sourceResource,
|
||||
targetNode, list, !ctrlKeydown);
|
||||
}
|
||||
catch(e)
|
||||
{
|
||||
gNextMessageAfterDelete = null;
|
||||
dump ( "Exception : CopyMessages \n");
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (dropFolder)
|
||||
{
|
||||
|
||||
var sourceNode = RDF.GetResource(sourceID, true);
|
||||
folder = sourceNode.QueryInterface(Components.interfaces.nsIFolder);
|
||||
sourceResource = folder.QueryInterface(Components.interfaces.nsIRDFResource);
|
||||
sourcefolder = sourceResource.QueryInterface(Components.interfaces.nsIMsgFolder);
|
||||
sourceServer = sourcefolder.server;
|
||||
var moveFolder = false;
|
||||
|
||||
if (sourceServer == targetServer)
|
||||
moveFolder = true;
|
||||
|
||||
try
|
||||
{
|
||||
messenger.CopyFolders(treeDatabase,targetNode,list,moveFolder);
|
||||
}
|
||||
catch(e)
|
||||
{
|
||||
dump ("Exception : CopyFolder \n");
|
||||
}
|
||||
}
|
||||
|
||||
return(false);
|
||||
}
|
||||
|
||||
|
||||
@ -1125,6 +1125,29 @@ nsMessenger::CopyMessages(nsIRDFCompositeDataSource *database,
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMessenger::CopyFolders(nsIRDFCompositeDataSource *database,
|
||||
nsIRDFResource *dstResource,
|
||||
nsISupportsArray *argumentArray, // nsIFolders
|
||||
PRBool isMoveFolder)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
if(!dstResource || !argumentArray)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsCOMPtr<nsISupportsArray> folderArray;
|
||||
|
||||
rv = NS_NewISupportsArray(getter_AddRefs(folderArray));
|
||||
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
folderArray->AppendElement(dstResource);
|
||||
|
||||
return DoCommand(database, isMoveFolder ? (char *)NC_RDF_MOVEFOLDER : (char *)NC_RDF_COPYFOLDER, folderArray, argumentArray);
|
||||
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMessenger::RenameFolder(nsIRDFCompositeDataSource* db,
|
||||
nsIRDFResource* folderResource,
|
||||
|
||||
@ -218,9 +218,17 @@ nsMsgCopyService::DoNextCopy()
|
||||
rv = copyRequest->m_dstFolder->CopyMessages
|
||||
(copySource->m_msgFolder, copySource->m_messageArray,
|
||||
copyRequest->m_isMoveOrDraftOrTemplate,
|
||||
copyRequest->m_msgWindow, copyRequest->m_listener);
|
||||
copyRequest->m_msgWindow, copyRequest->m_listener, PR_FALSE); //isFolder operation PR_FALSE
|
||||
|
||||
}
|
||||
else if (copyRequest->m_requestType == nsCopyFoldersType )
|
||||
{
|
||||
copySource->m_processed = PR_TRUE;
|
||||
rv = copyRequest->m_dstFolder->CopyFolder
|
||||
(copySource->m_msgFolder,
|
||||
copyRequest->m_isMoveOrDraftOrTemplate,
|
||||
copyRequest->m_msgWindow, copyRequest->m_listener);
|
||||
}
|
||||
else if (copyRequest->m_requestType == nsCopyFileMessageType)
|
||||
{
|
||||
nsCOMPtr<nsIFileSpec> aSpec(do_QueryInterface(copyRequest->m_srcSupport, &rv));
|
||||
@ -369,6 +377,57 @@ done:
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMsgCopyService::CopyFolders( nsISupportsArray* folders,
|
||||
nsIMsgFolder* dstFolder,
|
||||
PRBool isMove,
|
||||
nsIMsgCopyServiceListener* listener,
|
||||
nsIMsgWindow* window)
|
||||
{
|
||||
nsCopyRequest* copyRequest;
|
||||
nsCopySource* copySource = nsnull;
|
||||
nsresult rv = NS_ERROR_NULL_POINTER;
|
||||
PRUint32 cnt;
|
||||
nsCOMPtr<nsIFolder> folder;
|
||||
nsCOMPtr<nsIMsgFolder> curFolder;
|
||||
nsCOMPtr<nsISupports> support;
|
||||
|
||||
if (!folders || !dstFolder) return rv;
|
||||
|
||||
rv = folders->Count(&cnt); //if cnt is zero it cannot to get this point, will be detected earlier
|
||||
if ( cnt > 1)
|
||||
NS_ASSERTION((NS_SUCCEEDED(rv)),"More than one folders to copy");
|
||||
|
||||
support = getter_AddRefs(folders->ElementAt(0));
|
||||
|
||||
copyRequest = new nsCopyRequest();
|
||||
if (!copyRequest) return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
rv = copyRequest->Init(nsCopyFoldersType, support, dstFolder,
|
||||
isMove, listener, window);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
folder = do_QueryInterface(support, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
curFolder = do_QueryInterface(folder, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
copySource = copyRequest->AddNewCopySource(curFolder);
|
||||
if (!copySource)
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
if (NS_FAILED(rv))
|
||||
{
|
||||
delete copyRequest;
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
else
|
||||
rv = DoCopy(copyRequest);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMsgCopyService::CopyFileMessage(nsIFileSpec* fileSpec,
|
||||
nsIMsgFolder* dstFolder,
|
||||
|
||||
@ -33,7 +33,8 @@
|
||||
typedef enum _nsCopyRequestType
|
||||
{
|
||||
nsCopyMessagesType = 0x0,
|
||||
nsCopyFileMessageType = 0x1
|
||||
nsCopyFileMessageType = 0x1,
|
||||
nsCopyFoldersType = 0x2
|
||||
} nsCopyRequestType;
|
||||
|
||||
class nsCopyRequest;
|
||||
|
||||
@ -83,6 +83,8 @@ nsIRDFResource* nsMsgFolderDataSource::kNC_NewFolder= nsnull;
|
||||
nsIRDFResource* nsMsgFolderDataSource::kNC_GetNewMessages= nsnull;
|
||||
nsIRDFResource* nsMsgFolderDataSource::kNC_Copy= nsnull;
|
||||
nsIRDFResource* nsMsgFolderDataSource::kNC_Move= nsnull;
|
||||
nsIRDFResource* nsMsgFolderDataSource::kNC_CopyFolder= nsnull;
|
||||
nsIRDFResource* nsMsgFolderDataSource::kNC_MoveFolder= nsnull;
|
||||
nsIRDFResource* nsMsgFolderDataSource::kNC_MarkAllMessagesRead= nsnull;
|
||||
nsIRDFResource* nsMsgFolderDataSource::kNC_Compact= nsnull;
|
||||
nsIRDFResource* nsMsgFolderDataSource::kNC_Rename= nsnull;
|
||||
@ -133,6 +135,8 @@ nsMsgFolderDataSource::nsMsgFolderDataSource()
|
||||
rdf->GetResource(NC_RDF_GETNEWMESSAGES, &kNC_GetNewMessages);
|
||||
rdf->GetResource(NC_RDF_COPY, &kNC_Copy);
|
||||
rdf->GetResource(NC_RDF_MOVE, &kNC_Move);
|
||||
rdf->GetResource(NC_RDF_COPYFOLDER, &kNC_CopyFolder);
|
||||
rdf->GetResource(NC_RDF_MOVEFOLDER, &kNC_MoveFolder);
|
||||
rdf->GetResource(NC_RDF_MARKALLMESSAGESREAD,
|
||||
&kNC_MarkAllMessagesRead);
|
||||
rdf->GetResource(NC_RDF_COMPACT, &kNC_Compact);
|
||||
@ -187,6 +191,8 @@ nsMsgFolderDataSource::~nsMsgFolderDataSource (void)
|
||||
NS_RELEASE2(kNC_GetNewMessages, refcnt);
|
||||
NS_RELEASE2(kNC_Copy, refcnt);
|
||||
NS_RELEASE2(kNC_Move, refcnt);
|
||||
NS_RELEASE2(kNC_CopyFolder, refcnt);
|
||||
NS_RELEASE2(kNC_MoveFolder, refcnt);
|
||||
NS_RELEASE2(kNC_MarkAllMessagesRead, refcnt);
|
||||
NS_RELEASE2(kNC_Compact, refcnt);
|
||||
NS_RELEASE2(kNC_Rename, refcnt);
|
||||
@ -562,6 +568,8 @@ nsMsgFolderDataSource::GetAllCommands(nsIRDFResource* source,
|
||||
cmds->AppendElement(kNC_GetNewMessages);
|
||||
cmds->AppendElement(kNC_Copy);
|
||||
cmds->AppendElement(kNC_Move);
|
||||
cmds->AppendElement(kNC_CopyFolder);
|
||||
cmds->AppendElement(kNC_MoveFolder);
|
||||
cmds->AppendElement(kNC_MarkAllMessagesRead);
|
||||
cmds->AppendElement(kNC_Compact);
|
||||
cmds->AppendElement(kNC_Rename);
|
||||
@ -604,6 +612,8 @@ nsMsgFolderDataSource::IsCommandEnabled(nsISupportsArray/*<nsIRDFResource>*/* aS
|
||||
(aCommand == kNC_NewFolder) ||
|
||||
(aCommand == kNC_Copy) ||
|
||||
(aCommand == kNC_Move) ||
|
||||
(aCommand == kNC_CopyFolder) ||
|
||||
(aCommand == kNC_MoveFolder) ||
|
||||
(aCommand == kNC_GetNewMessages) ||
|
||||
(aCommand == kNC_MarkAllMessagesRead) ||
|
||||
(aCommand == kNC_Compact) ||
|
||||
@ -664,6 +674,14 @@ nsMsgFolderDataSource::DoCommand(nsISupportsArray/*<nsIRDFResource>*/* aSources,
|
||||
{
|
||||
rv = DoCopyToFolder(folder, aArguments, mWindow, PR_TRUE);
|
||||
}
|
||||
else if((aCommand == kNC_CopyFolder))
|
||||
{
|
||||
rv = DoFolderCopyToFolder(folder, aArguments, mWindow, PR_FALSE);
|
||||
}
|
||||
else if((aCommand == kNC_MoveFolder))
|
||||
{
|
||||
rv = DoFolderCopyToFolder(folder, aArguments, mWindow, PR_TRUE);
|
||||
}
|
||||
else if((aCommand == kNC_MarkAllMessagesRead))
|
||||
{
|
||||
rv = folder->MarkAllMessagesRead();
|
||||
@ -1536,6 +1554,50 @@ nsresult nsMsgFolderDataSource::DoCopyToFolder(nsIMsgFolder *dstFolder, nsISuppo
|
||||
//return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsMsgFolderDataSource::DoFolderCopyToFolder(nsIMsgFolder *dstFolder, nsISupportsArray *arguments,
|
||||
nsIMsgWindow *msgWindow, PRBool isMoveFolder)
|
||||
{
|
||||
nsresult rv;
|
||||
PRUint32 itemCount;
|
||||
rv = arguments->Count(&itemCount);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
//need at least one item to copy
|
||||
if(itemCount < 1)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (!isMoveFolder) // copy folder not on the same server
|
||||
{
|
||||
//Call copyservice with dstFolder, srcFolder, folders and isMoveFolder
|
||||
nsCOMPtr<nsIMsgCopyService> copyService = do_GetService(kMsgCopyServiceCID, &rv);
|
||||
if(NS_SUCCEEDED(rv))
|
||||
{
|
||||
rv = copyService->CopyFolders(arguments, dstFolder, isMoveFolder,
|
||||
nsnull, msgWindow);
|
||||
|
||||
}
|
||||
}
|
||||
else //within the same server therefore no need for copy service
|
||||
{
|
||||
|
||||
nsCOMPtr<nsISupports> supports;
|
||||
nsCOMPtr<nsIMsgFolder> msgFolder;
|
||||
for (PRUint32 i=0;i< itemCount; i++)
|
||||
{
|
||||
supports = getter_AddRefs(arguments->ElementAt(i));
|
||||
msgFolder = do_QueryInterface(supports,&rv);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
rv = dstFolder->CopyFolder(msgFolder, isMoveFolder , msgWindow, nsnull);
|
||||
NS_ASSERTION((NS_SUCCEEDED(rv)),"Copy folder failed.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
//return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsMsgFolderDataSource::DoDeleteFromFolder(
|
||||
nsIMsgFolder *folder, nsISupportsArray *arguments,
|
||||
nsIMsgWindow *msgWindow, PRBool reallyDelete)
|
||||
|
||||
@ -148,6 +148,9 @@ protected:
|
||||
nsresult DoCopyToFolder(nsIMsgFolder *dstFolder, nsISupportsArray *arguments,
|
||||
nsIMsgWindow *msgWindow, PRBool isMove);
|
||||
|
||||
nsresult DoFolderCopyToFolder(nsIMsgFolder *dstFolder, nsISupportsArray *arguments,
|
||||
nsIMsgWindow *msgWindow, PRBool isMoveFolder);
|
||||
|
||||
nsresult DoNewFolder(nsIMsgFolder *folder,
|
||||
nsISupportsArray *arguments);
|
||||
|
||||
@ -209,6 +212,8 @@ protected:
|
||||
static nsIRDFResource* kNC_GetNewMessages;
|
||||
static nsIRDFResource* kNC_Copy;
|
||||
static nsIRDFResource* kNC_Move;
|
||||
static nsIRDFResource* kNC_CopyFolder;
|
||||
static nsIRDFResource* kNC_MoveFolder;
|
||||
static nsIRDFResource* kNC_MarkAllMessagesRead;
|
||||
static nsIRDFResource* kNC_Compact;
|
||||
static nsIRDFResource* kNC_Rename;
|
||||
|
||||
@ -102,6 +102,8 @@ typedef struct _nsMsgRDFNotification {
|
||||
#define NC_RDF_GETNEWMESSAGES NC_NAMESPACE_URI "GetNewMessages"
|
||||
#define NC_RDF_COPY NC_NAMESPACE_URI "Copy"
|
||||
#define NC_RDF_MOVE NC_NAMESPACE_URI "Move"
|
||||
#define NC_RDF_COPYFOLDER NC_NAMESPACE_URI "CopyFolder"
|
||||
#define NC_RDF_MOVEFOLDER NC_NAMESPACE_URI "MoveFolder"
|
||||
#define NC_RDF_MARKALLMESSAGESREAD NC_NAMESPACE_URI "MarkAllMessagesRead"
|
||||
#define NC_RDF_MARKTHREADREAD NC_NAMESPACE_URI "MarkThreadRead"
|
||||
#define NC_RDF_COMPACT NC_NAMESPACE_URI "Compact"
|
||||
|
||||
@ -931,6 +931,7 @@ NS_IMETHODIMP nsMsgFolder::GetChildWithURI(const char *uri, PRBool deep, nsIMsgF
|
||||
if(NS_FAILED(rv)) return rv;
|
||||
|
||||
// case-insensitive compare is probably LCD across OS filesystems
|
||||
|
||||
PRBool equal = (folderURI && nsCRT::strcasecmp(folderURI, uri)==0);
|
||||
nsMemory::Free(folderURI);
|
||||
if (equal)
|
||||
@ -2156,8 +2157,19 @@ nsMsgFolder::CopyMessages(nsIMsgFolder* srcFolder,
|
||||
nsISupportsArray *messages,
|
||||
PRBool isMove,
|
||||
nsIMsgWindow *window,
|
||||
nsIMsgCopyServiceListener* listener,
|
||||
PRBool isFolder)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMsgFolder::CopyFolder(nsIMsgFolder* srcFolder,
|
||||
PRBool isMoveFolder,
|
||||
nsIMsgWindow *window,
|
||||
nsIMsgCopyServiceListener* listener)
|
||||
{
|
||||
NS_ASSERTION(PR_FALSE, "should be overridden by child class");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
@ -2479,3 +2491,4 @@ NS_IMETHODIMP nsMsgFolder::GetMessageHeader(nsMsgKey msgKey, nsIMsgDBHdr **aMsgH
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -140,7 +140,8 @@ hasMessages);
|
||||
NS_IMETHOD GetFoldersWithFlag(PRUint32 flags, PRUint32 resultsize, PRUint32 *numFolders, nsIMsgFolder **result);
|
||||
NS_IMETHOD GetExpansionArray(nsISupportsArray *expansionArray);
|
||||
// NS_IMETHOD DeleteMessages(nsISupportsArray *message, nsITransactionManager *txnMgr, PRBool deleteStorage);
|
||||
NS_IMETHOD CopyMessages(nsIMsgFolder *srcFolder, nsISupportsArray *messages, PRBool isMove, nsIMsgWindow *window, nsIMsgCopyServiceListener *listener);
|
||||
NS_IMETHOD CopyMessages(nsIMsgFolder *srcFolder, nsISupportsArray *messages, PRBool isMove, nsIMsgWindow *window, nsIMsgCopyServiceListener *listener, PRBool isFolder);
|
||||
NS_IMETHOD CopyFolder(nsIMsgFolder *srcFolder,PRBool isMoveFolder, nsIMsgWindow *window, nsIMsgCopyServiceListener *listener);
|
||||
NS_IMETHOD CopyFileMessage(nsIFileSpec *fileSpec, nsIMessage *msgToReplace, PRBool isDraft, nsIMsgWindow *window, nsIMsgCopyServiceListener *listener);
|
||||
NS_IMETHOD AcquireSemaphore(nsISupports *semHolder);
|
||||
NS_IMETHOD ReleaseSemaphore(nsISupports *semHolder);
|
||||
|
||||
@ -31,7 +31,7 @@ interface nsIMsgImapMailFolder : nsISupports {
|
||||
void RemoveSubFolder(in nsIMsgFolder folder);
|
||||
void CreateClientSubfolderInfo(in string folderName, in wchar hierarchyDelimiter, in long flags);
|
||||
void List();
|
||||
void RenameLocal(in string newname);
|
||||
void RenameLocal(in string newname, in nsIMsgFolder parent);
|
||||
void PrepareToRename();
|
||||
void PerformExpand(in nsIMsgWindow aMsgWindow);
|
||||
void RecursiveCloseActiveConnections(in nsIImapIncomingServer aImapServer);
|
||||
|
||||
@ -1101,16 +1101,30 @@ NS_IMETHODIMP nsImapIncomingServer::OnlineFolderRename(const char *oldName, cons
|
||||
rv = GetFolder(oldName, getter_AddRefs(me));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsCOMPtr<nsIMsgFolder> parent ;
|
||||
|
||||
nsCAutoString newNameString(newName);
|
||||
nsCAutoString parentName;
|
||||
PRInt32 folderStart = newNameString.RFindChar('/');
|
||||
if (folderStart > 0)
|
||||
{
|
||||
newNameString.Left(parentName, folderStart);
|
||||
rv = GetFolder(parentName.get(),getter_AddRefs(parent));
|
||||
}
|
||||
else // root is the parent
|
||||
{
|
||||
nsCOMPtr<nsIFolder> rootFolder;
|
||||
rv = GetRootFolder(getter_AddRefs(rootFolder));
|
||||
parent = do_QueryInterface(rootFolder,&rv);
|
||||
}
|
||||
if (NS_SUCCEEDED(rv) && parent)
|
||||
{
|
||||
nsCOMPtr<nsIMsgImapMailFolder> folder;
|
||||
folder = do_QueryInterface(me, &rv);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
folder->RenameLocal(newName);
|
||||
folder->RenameLocal(newName,parent);
|
||||
|
||||
nsCOMPtr<nsIFolder> parent ;
|
||||
rv = me->GetParent(getter_AddRefs(parent));
|
||||
if (NS_SUCCEEDED(rv) && parent)
|
||||
{
|
||||
nsCOMPtr<nsIMsgImapMailFolder> parentImapFolder = do_QueryInterface(parent);
|
||||
nsCOMPtr<nsIMsgImapMailFolder> parentImapFolder = do_QueryInterface(parent);
|
||||
if (parentImapFolder)
|
||||
parentImapFolder->RenameClient(me,oldName, newName);
|
||||
}
|
||||
|
||||
@ -90,6 +90,73 @@ static NS_DEFINE_CID(kPrefCID, NS_PREF_CID);
|
||||
|
||||
#define FOUR_K 4096
|
||||
|
||||
/*
|
||||
Copies the contents of srcDir into destDir.
|
||||
destDir will be created if it doesn't exist.
|
||||
*/
|
||||
|
||||
static
|
||||
nsresult RecursiveCopy(nsIFile* srcDir, nsIFile* destDir)
|
||||
{
|
||||
nsresult rv;
|
||||
PRBool isDir;
|
||||
|
||||
rv = srcDir->IsDirectory(&isDir);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (!isDir) return NS_ERROR_INVALID_ARG;
|
||||
|
||||
PRBool exists;
|
||||
rv = destDir->Exists(&exists);
|
||||
if (NS_SUCCEEDED(rv) && !exists)
|
||||
rv = destDir->Create(nsIFile::DIRECTORY_TYPE, 0775);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
PRBool hasMore = PR_FALSE;
|
||||
nsCOMPtr<nsISimpleEnumerator> dirIterator;
|
||||
rv = srcDir->GetDirectoryEntries(getter_AddRefs(dirIterator));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = dirIterator->HasMoreElements(&hasMore);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsCOMPtr<nsIFile> dirEntry;
|
||||
|
||||
while (hasMore)
|
||||
{
|
||||
rv = dirIterator->GetNext((nsISupports**)getter_AddRefs(dirEntry));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
rv = dirEntry->IsDirectory(&isDir);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
if (isDir)
|
||||
{
|
||||
nsCOMPtr<nsIFile> destClone;
|
||||
rv = destDir->Clone(getter_AddRefs(destClone));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
nsCOMPtr<nsILocalFile> newChild(do_QueryInterface(destClone));
|
||||
nsXPIDLCString leafName;
|
||||
dirEntry->GetLeafName(getter_Copies(leafName));
|
||||
newChild->AppendRelativePath(leafName);
|
||||
rv = newChild->Exists(&exists);
|
||||
if (NS_SUCCEEDED(rv) && !exists)
|
||||
rv = newChild->Create(nsIFile::DIRECTORY_TYPE, 0775);
|
||||
rv = RecursiveCopy(dirEntry, newChild);
|
||||
}
|
||||
}
|
||||
else
|
||||
rv = dirEntry->CopyTo(destDir, nsnull);
|
||||
}
|
||||
|
||||
}
|
||||
rv = dirIterator->HasMoreElements(&hasMore);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsImapMailFolder::nsImapMailFolder() :
|
||||
m_initialized(PR_FALSE),m_haveDiscoveredAllFolders(PR_FALSE),
|
||||
m_haveReadNameFromDB(PR_FALSE),
|
||||
@ -1092,14 +1159,14 @@ NS_IMETHODIMP nsImapMailFolder::PrepareToRename()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImapMailFolder::RenameLocal(const char *newName)
|
||||
NS_IMETHODIMP nsImapMailFolder::RenameLocal(const char *newName, nsIMsgFolder *parent)
|
||||
{
|
||||
nsCAutoString leafname(newName);
|
||||
nsCAutoString parentName;
|
||||
// newName always in the canonical form "greatparent/parentname/leafname"
|
||||
PRInt32 leafpos = leafname.RFindChar('/');
|
||||
if (leafpos >0)
|
||||
if (leafpos >0)
|
||||
leafname.Cut(0, leafpos+1);
|
||||
|
||||
m_msgParser = null_nsCOMPtr();
|
||||
PrepareToRename();
|
||||
NotifyStoreClosedAllHeaders();
|
||||
@ -1109,10 +1176,18 @@ NS_IMETHODIMP nsImapMailFolder::RenameLocal(const char *newName)
|
||||
nsCOMPtr<nsIFileSpec> oldPathSpec;
|
||||
rv = GetPath(getter_AddRefs(oldPathSpec));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
nsCOMPtr<nsIFolder> parent;
|
||||
rv = GetParent(getter_AddRefs(parent));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
nsCOMPtr<nsIMsgFolder> parentFolder = do_QueryInterface(parent);
|
||||
|
||||
nsCOMPtr<nsIFileSpec> parentPathSpec;
|
||||
rv = parent->GetPath(getter_AddRefs(parentPathSpec));
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
nsFileSpec parentPath;
|
||||
rv = parentPathSpec->GetFileSpec(&parentPath);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
if (!parentPath.IsDirectory())
|
||||
AddDirectorySeparator(parentPath);
|
||||
|
||||
PRUint32 cnt = 0;
|
||||
nsFileSpec dirSpec;
|
||||
|
||||
@ -1133,7 +1208,39 @@ NS_IMETHODIMP nsImapMailFolder::RenameLocal(const char *newName)
|
||||
{
|
||||
newNameStr = leafname;
|
||||
newNameStr += ".sbd";
|
||||
dirSpec.Rename(newNameStr.GetBuffer());
|
||||
char *leafName = dirSpec.GetLeafName();
|
||||
if (nsCRT::strcmp(leafName, newNameStr) != 0 )
|
||||
{
|
||||
dirSpec.Rename(newNameStr.GetBuffer()); // in case of rename operation leaf names will differ
|
||||
nsCRT::free(leafName);
|
||||
return rv;
|
||||
}
|
||||
nsCRT::free(leafName);
|
||||
|
||||
parentPath += newNameStr; //only for move we need to progress further in case the parent differs
|
||||
|
||||
if (!parentPath.IsDirectory())
|
||||
parentPath.CreateDirectory();
|
||||
else
|
||||
NS_ASSERTION(0,"Directory already exists.");
|
||||
|
||||
nsCOMPtr<nsILocalFile> srcDir = (do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv));
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
nsCOMPtr<nsILocalFile> destDir = (do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv));
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
nsCString oldPathStr (dirSpec.GetNativePathCString());
|
||||
srcDir->InitWithPath(oldPathStr.GetBuffer());
|
||||
|
||||
nsCString newPathStr (parentPath.GetNativePathCString());
|
||||
destDir->InitWithPath(newPathStr.GetBuffer());
|
||||
|
||||
rv = RecursiveCopy(srcDir, destDir);
|
||||
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
dirSpec.Delete(PR_TRUE); // moving folders
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
@ -1702,7 +1809,7 @@ NS_IMETHODIMP nsImapMailFolder::DeleteMessages(nsISupportsArray *messages,
|
||||
|
||||
rv = QueryInterface(NS_GET_IID(nsIMsgFolder),
|
||||
getter_AddRefs(srcFolder));
|
||||
rv = trashFolder->CopyMessages(srcFolder, messages, PR_TRUE, msgWindow, nsnull);
|
||||
rv = trashFolder->CopyMessages(srcFolder, messages, PR_TRUE, msgWindow, nsnull,PR_FALSE);
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
@ -1825,7 +1932,7 @@ nsImapMailFolder::DeleteSubFolders(nsISupportsArray* folders, nsIMsgWindow *msgW
|
||||
}
|
||||
}
|
||||
|
||||
if (confirmed)
|
||||
if (confirmed && deleteNoTrash) //delete subfolders only if you are deleting things from trash
|
||||
return nsMsgFolder::DeleteSubFolders(folders, nsnull);
|
||||
else
|
||||
return rv;
|
||||
@ -2443,6 +2550,7 @@ NS_IMETHODIMP nsImapMailFolder::EndCopy(PRBool copySucceeded)
|
||||
m_copyState->m_selectedState,
|
||||
urlListener, nsnull,
|
||||
copySupport);
|
||||
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
@ -4677,7 +4785,8 @@ nsImapMailFolder::CopyMessages(nsIMsgFolder* srcFolder,
|
||||
nsISupportsArray* messages,
|
||||
PRBool isMove,
|
||||
nsIMsgWindow *msgWindow,
|
||||
nsIMsgCopyServiceListener* listener)
|
||||
nsIMsgCopyServiceListener* listener,
|
||||
PRBool isFolder) //isFolder for future use when we do cross-server folder move/copy
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
nsCAutoString messageIds;
|
||||
@ -4770,6 +4879,38 @@ done:
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsImapMailFolder::CopyFolder(nsIMsgFolder* srcFolder,
|
||||
PRBool isMoveFolder,
|
||||
nsIMsgWindow *msgWindow,
|
||||
nsIMsgCopyServiceListener* listener)
|
||||
{
|
||||
|
||||
NS_ENSURE_ARG_POINTER(srcFolder);
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
if (isMoveFolder) //move folder permitted when dstFolder and the srcFolder are on same server
|
||||
{
|
||||
nsCOMPtr <nsIImapService> imapService = do_GetService (kCImapService, &rv);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
nsCOMPtr <nsIUrlListener> urlListener = do_QueryInterface(srcFolder);
|
||||
rv = imapService->MoveFolder(m_eventQueue,
|
||||
srcFolder,
|
||||
this,
|
||||
urlListener,
|
||||
nsnull);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
NS_ASSERTION(0,"isMoveFolder is false. Trying to copy to a different server.");
|
||||
|
||||
return rv;
|
||||
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsImapMailFolder::SetTransactionManager(nsITransactionManager* txnMgr)
|
||||
{
|
||||
@ -5075,7 +5216,7 @@ NS_IMETHODIMP nsImapMailFolder::RenameClient( nsIMsgFolder *msgFolder, const cha
|
||||
nsFileSpec path;
|
||||
rv = pathSpec->GetFileSpec(&path);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
|
||||
nsCOMPtr<nsIMsgImapMailFolder> oldImapFolder = do_QueryInterface(msgFolder, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
@ -5084,17 +5225,18 @@ NS_IMETHODIMP nsImapMailFolder::RenameClient( nsIMsgFolder *msgFolder, const cha
|
||||
PRInt32 boxflags=0;
|
||||
oldImapFolder->GetBoxFlags(&boxflags);
|
||||
|
||||
nsAutoString newLeafName;
|
||||
newLeafName.AssignWithConversion(newName);
|
||||
nsAutoString parentName = newLeafName;
|
||||
nsAutoString newLeafName;
|
||||
nsAutoString newNameString;
|
||||
newNameString.AssignWithConversion(newName);
|
||||
newLeafName = newNameString;
|
||||
nsAutoString parentName;
|
||||
nsAutoString folderNameStr;
|
||||
PRInt32 folderStart = newLeafName.RFindChar('/'); //internal use of hierarchyDelimiter is always '/'
|
||||
if (folderStart > 0)
|
||||
{
|
||||
parentName.Right(newLeafName, newLeafName.Length() - folderStart - 1);
|
||||
rv = AddDirectorySeparator(path);
|
||||
}
|
||||
|
||||
newNameString.Right(newLeafName, newLeafName.Length() - folderStart - 1);
|
||||
CreateDirectoryForFolder(path); //needed when we move a folder to a folder with no subfolders.
|
||||
}
|
||||
|
||||
// if we get here, it's really a leaf, and "this" is the parent.
|
||||
folderNameStr = newLeafName;
|
||||
@ -5165,8 +5307,11 @@ NS_IMETHODIMP nsImapMailFolder::RenameClient( nsIMsgFolder *msgFolder, const cha
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIFolder> parent;
|
||||
msgFolder->GetParent(getter_AddRefs(parent));
|
||||
nsCOMPtr<nsIMsgFolder> msgParent = do_QueryInterface(parent);
|
||||
msgFolder->SetParent(nsnull);
|
||||
PropagateDelete(msgFolder,PR_FALSE);
|
||||
msgParent->PropagateDelete(msgFolder,PR_FALSE);
|
||||
|
||||
if(NS_SUCCEEDED(rv) && child)
|
||||
{
|
||||
|
||||
@ -168,6 +168,8 @@ public:
|
||||
NS_IMETHOD CopyMessages(nsIMsgFolder *srcFolder,
|
||||
nsISupportsArray* messages,
|
||||
PRBool isMove, nsIMsgWindow *msgWindow,
|
||||
nsIMsgCopyServiceListener* listener, PRBool isFolder);
|
||||
NS_IMETHOD CopyFolder(nsIMsgFolder *srcFolder, PRBool isMove, nsIMsgWindow *msgWindow,
|
||||
nsIMsgCopyServiceListener* listener);
|
||||
NS_IMETHOD CopyFileMessage(nsIFileSpec* fileSpec,
|
||||
nsIMessage* msgToReplace,
|
||||
|
||||
@ -132,7 +132,7 @@ nsresult nsImapMoveCoalescer::PlaybackMoves(nsIEventQueue *eventQueue)
|
||||
}
|
||||
rv = destFolder->CopyMessages(m_sourceFolder,
|
||||
messages, PR_TRUE, m_msgWindow,
|
||||
/*nsIMsgCopyServiceListener* listener*/ nsnull);
|
||||
/*nsIMsgCopyServiceListener* listener*/ nsnull, PR_FALSE);
|
||||
// rv = imapService->OnlineMessageCopy(eventQueue,
|
||||
// m_sourceFolder, messageIds.GetBuffer(),
|
||||
// destFolder, PR_TRUE, PR_TRUE,
|
||||
|
||||
@ -5452,8 +5452,9 @@ void nsImapProtocol::OnMoveFolderHierarchy(const char * sourceMailbox)
|
||||
leafName = oldBoxName; // this is a root level box
|
||||
else
|
||||
oldBoxName.Right(leafName, length-(leafStart+1));
|
||||
|
||||
newBoxName.Append(onlineDirSeparator);
|
||||
|
||||
if ( newBoxName.Length() > 0 )
|
||||
newBoxName.Append(onlineDirSeparator);
|
||||
newBoxName.Append(leafName);
|
||||
PRBool renamed = RenameHierarchyByHand(sourceMailbox,
|
||||
newBoxName.GetBuffer());
|
||||
|
||||
@ -2033,8 +2033,11 @@ nsImapService::MoveFolder(nsIEventQueue* eventQueue, nsIMsgFolder* srcFolder,
|
||||
urlSpec.Append('>');
|
||||
folderName = "";
|
||||
GetFolderName(dstFolder, getter_Copies(folderName));
|
||||
urlSpec.Append(hierarchySeparator);
|
||||
urlSpec.Append((const char *) folderName);
|
||||
if ( folderName && folderName[0])
|
||||
{
|
||||
urlSpec.Append(hierarchySeparator);
|
||||
urlSpec.Append((const char *) folderName);
|
||||
}
|
||||
rv = uri->SetSpec((char*) urlSpec.GetBuffer());
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
|
||||
@ -1493,7 +1493,7 @@ nsMsgLocalMailFolder::InitCopyState(nsISupports* aSupport,
|
||||
nsISupportsArray* messages,
|
||||
PRBool isMove,
|
||||
nsIMsgCopyServiceListener* listener,
|
||||
nsIMsgWindow *msgWindow)
|
||||
nsIMsgWindow *msgWindow, PRBool isFolder)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
nsFileSpec path;
|
||||
@ -1539,6 +1539,7 @@ nsMsgLocalMailFolder::InitCopyState(nsISupports* aSupport,
|
||||
if (NS_FAILED(rv)) goto done;
|
||||
mCopyState->m_curCopyIndex = 0;
|
||||
mCopyState->m_isMove = isMove;
|
||||
mCopyState->m_isFolder = isFolder;
|
||||
rv = messages->Count(&mCopyState->m_totalMsgCount);
|
||||
if (listener)
|
||||
mCopyState->m_listener = do_QueryInterface(listener, &rv);
|
||||
@ -1571,13 +1572,13 @@ NS_IMETHODIMP
|
||||
nsMsgLocalMailFolder::CopyMessages(nsIMsgFolder* srcFolder, nsISupportsArray*
|
||||
messages, PRBool isMove,
|
||||
nsIMsgWindow *msgWindow,
|
||||
nsIMsgCopyServiceListener* listener)
|
||||
nsIMsgCopyServiceListener* listener, PRBool isFolder)
|
||||
{
|
||||
if (!srcFolder || !messages)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
nsCOMPtr <nsITransactionManager> txnMgr;
|
||||
|
||||
if (msgWindow)
|
||||
if (msgWindow && !isFolder) // no undo for folder move/copy
|
||||
{
|
||||
msgWindow->GetTransactionManager(getter_AddRefs(txnMgr));
|
||||
|
||||
@ -1595,7 +1596,7 @@ nsMsgLocalMailFolder::CopyMessages(nsIMsgFolder* srcFolder, nsISupportsArray*
|
||||
// don't update the counts in the dest folder until it is all over
|
||||
EnableNotifications(allMessageCountNotifications, PR_FALSE);
|
||||
|
||||
rv = InitCopyState(aSupport, messages, isMove, listener, msgWindow);
|
||||
rv = InitCopyState(aSupport, messages, isMove, listener, msgWindow, isFolder);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
char *uri = nsnull;
|
||||
rv = srcFolder->GetURI(&uri);
|
||||
@ -1618,35 +1619,39 @@ nsMsgLocalMailFolder::CopyMessages(nsIMsgFolder* srcFolder, nsISupportsArray*
|
||||
}
|
||||
|
||||
// undo stuff
|
||||
nsLocalMoveCopyMsgTxn* msgTxn = nsnull;
|
||||
|
||||
msgTxn = new nsLocalMoveCopyMsgTxn(srcFolder, this, isMove);
|
||||
|
||||
if (msgTxn)
|
||||
rv =
|
||||
msgTxn->QueryInterface(NS_GET_IID(nsLocalMoveCopyMsgTxn),
|
||||
getter_AddRefs(mCopyState->m_undoMsgTxn));
|
||||
else
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
if (NS_FAILED(rv))
|
||||
if (!isFolder) //no undo for folder move/copy
|
||||
{
|
||||
ClearCopyState();
|
||||
}
|
||||
else
|
||||
{
|
||||
msgTxn->SetMsgWindow(msgWindow);
|
||||
if (isMove)
|
||||
{
|
||||
if (mFlags & MSG_FOLDER_FLAG_TRASH)
|
||||
msgTxn->SetTransactionType(nsIMessenger::eDeleteMsg);
|
||||
nsLocalMoveCopyMsgTxn* msgTxn = nsnull;
|
||||
|
||||
msgTxn = new nsLocalMoveCopyMsgTxn(srcFolder, this, isMove);
|
||||
|
||||
if (msgTxn)
|
||||
rv =
|
||||
msgTxn->QueryInterface(NS_GET_IID(nsLocalMoveCopyMsgTxn),
|
||||
getter_AddRefs(mCopyState->m_undoMsgTxn));
|
||||
else
|
||||
msgTxn->SetTransactionType(nsIMessenger::eMoveMsg);
|
||||
}
|
||||
else
|
||||
{
|
||||
msgTxn->SetTransactionType(nsIMessenger::eCopyMsg);
|
||||
}
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
if (NS_FAILED(rv))
|
||||
{
|
||||
ClearCopyState();
|
||||
}
|
||||
else
|
||||
{
|
||||
msgTxn->SetMsgWindow(msgWindow);
|
||||
if (isMove)
|
||||
{
|
||||
if (mFlags & MSG_FOLDER_FLAG_TRASH)
|
||||
msgTxn->SetTransactionType(nsIMessenger::eDeleteMsg);
|
||||
else
|
||||
msgTxn->SetTransactionType(nsIMessenger::eMoveMsg);
|
||||
}
|
||||
else
|
||||
{
|
||||
msgTxn->SetTransactionType(nsIMessenger::eCopyMsg);
|
||||
}
|
||||
}
|
||||
}
|
||||
PRUint32 numMsgs = 0;
|
||||
messages->Count(&numMsgs);
|
||||
if (numMsgs > 1 && protocolType.EqualsIgnoreCase("imap"))
|
||||
@ -1667,9 +1672,212 @@ nsMsgLocalMailFolder::CopyMessages(nsIMsgFolder* srcFolder, nsISupportsArray*
|
||||
ClearCopyState();
|
||||
}
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
// for srcFolder that are on different server than the dstFolder.
|
||||
nsresult
|
||||
nsMsgLocalMailFolder::CopyFolderAcrossServer(nsIMsgFolder *destFolder, nsIMsgFolder* srcFolder, nsIMsgWindow *msgWindow,
|
||||
nsIMsgCopyServiceListener *listener )
|
||||
{
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIFolder> newFolder;
|
||||
nsCOMPtr<nsIMsgFolder> newMsgFolder;
|
||||
|
||||
nsXPIDLString folderName;
|
||||
srcFolder->GetName(getter_Copies(folderName));
|
||||
|
||||
rv = destFolder->CreateSubfolder(folderName,msgWindow);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
destFolder->FindSubFolder(NS_ConvertUCS2toUTF8(folderName.get()), getter_AddRefs(newFolder));
|
||||
|
||||
newMsgFolder = do_QueryInterface(newFolder,&rv);
|
||||
|
||||
nsCOMPtr<nsISimpleEnumerator> messages;
|
||||
rv = srcFolder->GetMessages(msgWindow, getter_AddRefs(messages));
|
||||
|
||||
nsCOMPtr<nsISupportsArray> msgSupportsArray;
|
||||
NS_NewISupportsArray(getter_AddRefs(msgSupportsArray));
|
||||
|
||||
PRBool hasMoreElements;
|
||||
nsCOMPtr<nsISupports> aSupport;
|
||||
|
||||
if (messages)
|
||||
messages->HasMoreElements(&hasMoreElements);
|
||||
|
||||
while (hasMoreElements && NS_SUCCEEDED(rv))
|
||||
{
|
||||
rv = messages->GetNext(getter_AddRefs(aSupport));
|
||||
rv = msgSupportsArray->AppendElement(aSupport);
|
||||
messages->HasMoreElements(&hasMoreElements);
|
||||
}
|
||||
|
||||
PRUint32 numMsgs=0;
|
||||
msgSupportsArray->Count(&numMsgs);
|
||||
|
||||
if (numMsgs > 0 ) //if only srcFolder has messages..
|
||||
newMsgFolder->CopyMessages(srcFolder, msgSupportsArray, PR_FALSE, msgWindow, listener, PR_TRUE);
|
||||
else
|
||||
DoNextSubFolder(newMsgFolder, srcFolder, msgWindow, listener);
|
||||
|
||||
return NS_OK; // otherwise the front-end will say Exception::CopyFolder
|
||||
}
|
||||
|
||||
nsresult //Continue with next subfolder
|
||||
nsMsgLocalMailFolder::DoNextSubFolder(nsIMsgFolder *newMsgFolder,
|
||||
nsIMsgFolder *srcFolder,
|
||||
nsIMsgWindow *msgWindow,
|
||||
nsIMsgCopyServiceListener *listener )
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIEnumerator> aEnumerator;
|
||||
srcFolder->GetSubFolders(getter_AddRefs(aEnumerator));
|
||||
nsCOMPtr<nsIMsgFolder>folder;
|
||||
nsCOMPtr<nsISupports> aSupports;
|
||||
rv = aEnumerator->First();
|
||||
while (NS_SUCCEEDED(rv))
|
||||
{
|
||||
rv = aEnumerator->CurrentItem(getter_AddRefs(aSupports));
|
||||
folder = do_QueryInterface(aSupports);
|
||||
rv = aEnumerator->Next();
|
||||
if (folder)
|
||||
CopyFolderAcrossServer(newMsgFolder,folder, msgWindow, listener);
|
||||
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMsgLocalMailFolder::CopyFolder( nsIMsgFolder* srcFolder, PRBool isMoveFolder,
|
||||
nsIMsgWindow *msgWindow,
|
||||
nsIMsgCopyServiceListener* listener)
|
||||
{
|
||||
nsresult rv;
|
||||
NS_ENSURE_ARG_POINTER(srcFolder);
|
||||
|
||||
if (isMoveFolder) // isMoveFolder == true when "this" and srcFolder are on same server
|
||||
rv = CopyFolderLocal(this, srcFolder, isMoveFolder, msgWindow, listener );
|
||||
else
|
||||
rv = CopyFolderAcrossServer(this, srcFolder, msgWindow, listener );
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsMsgLocalMailFolder::CopyFolderLocal( nsIMsgFolder *destFolder, nsIMsgFolder *srcFolder, PRBool isMoveFolder,
|
||||
nsIMsgWindow *msgWindow,
|
||||
nsIMsgCopyServiceListener *listener )
|
||||
{
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIFolder> newFolder;
|
||||
nsCOMPtr<nsIMsgFolder> newMsgFolder;
|
||||
|
||||
nsXPIDLString idlName;
|
||||
srcFolder->GetName(getter_Copies(idlName));
|
||||
nsAutoString folderName;
|
||||
folderName.Assign(idlName);
|
||||
|
||||
srcFolder->ForceDBClosed();
|
||||
|
||||
nsCOMPtr<nsIFileSpec> oldPathSpec;
|
||||
rv = srcFolder->GetPath(getter_AddRefs(oldPathSpec));
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
nsFileSpec oldPath;
|
||||
rv = oldPathSpec->GetFileSpec(&oldPath);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
nsLocalFolderSummarySpec summarySpec(oldPath);
|
||||
|
||||
nsCOMPtr<nsIFileSpec> newPathSpec;
|
||||
rv = destFolder->GetPath(getter_AddRefs(newPathSpec));
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
nsFileSpec newPath;
|
||||
rv = newPathSpec->GetFileSpec(&newPath);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
if (!newPath.IsDirectory())
|
||||
{
|
||||
AddDirectorySeparator(newPath);
|
||||
newPath.CreateDirectory();
|
||||
}
|
||||
|
||||
PRBool exists = PR_FALSE;
|
||||
nsFileSpec checkPath = newPath;
|
||||
|
||||
checkPath += folderName;
|
||||
exists=checkPath.Exists();
|
||||
|
||||
if (exists)
|
||||
{
|
||||
if (msgWindow)
|
||||
AlertFolderExists(msgWindow);
|
||||
return NS_MSG_FOLDER_EXISTS;
|
||||
}
|
||||
|
||||
nsFileSpec path = oldPath;
|
||||
|
||||
path.MoveToDir(newPath);
|
||||
summarySpec.MoveToDir(newPath);
|
||||
|
||||
destFolder->AddSubfolder(&folderName, getter_AddRefs(newMsgFolder));
|
||||
|
||||
PRUint32 flags;
|
||||
srcFolder->GetFlags(&flags);
|
||||
newMsgFolder->SetFlags(flags);
|
||||
|
||||
if (newMsgFolder)
|
||||
{
|
||||
newMsgFolder->SetName(folderName.GetUnicode());
|
||||
nsCOMPtr<nsISupports> supports = do_QueryInterface(newMsgFolder);
|
||||
nsCOMPtr<nsISupports> parentSupports = do_QueryInterface(destFolder);
|
||||
|
||||
if (supports && parentSupports)
|
||||
{
|
||||
NotifyItemAdded(parentSupports, supports, "folderView");
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIEnumerator> aEnumerator;
|
||||
srcFolder->GetSubFolders(getter_AddRefs(aEnumerator));
|
||||
nsCOMPtr<nsIMsgFolder>folder;
|
||||
nsCOMPtr<nsISupports> supports;
|
||||
rv = aEnumerator->First();
|
||||
while (NS_SUCCEEDED(rv))
|
||||
{
|
||||
rv = aEnumerator->CurrentItem(getter_AddRefs(supports));
|
||||
folder = do_QueryInterface(supports);
|
||||
rv = aEnumerator->Next();
|
||||
if (folder)
|
||||
CopyFolderLocal(newMsgFolder,folder, PR_FALSE, msgWindow, listener); // PR_FALSE needed to avoid un-necessary deletions
|
||||
|
||||
}
|
||||
|
||||
if (isMoveFolder )
|
||||
{
|
||||
nsCOMPtr <nsIFolder> parent;
|
||||
nsCOMPtr<nsIMsgFolder> msgParent;
|
||||
srcFolder->GetParent(getter_AddRefs(parent));
|
||||
srcFolder->SetParent(nsnull);
|
||||
if (parent)
|
||||
{
|
||||
msgParent = do_QueryInterface(parent);
|
||||
if (msgParent)
|
||||
msgParent->PropagateDelete(srcFolder, PR_FALSE); // The files have already been moved, so delete storage PR_FALSE
|
||||
if (!oldPath.IsDirectory())
|
||||
{
|
||||
AddDirectorySeparator(oldPath);
|
||||
oldPath.Delete(PR_TRUE); //delete the .sbd directory and it's content. All subfolders have been moved
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMsgLocalMailFolder::CopyFileMessage(nsIFileSpec* fileSpec, nsIMessage*
|
||||
@ -1698,7 +1906,7 @@ nsMsgLocalMailFolder::CopyFileMessage(nsIFileSpec* fileSpec, nsIMessage*
|
||||
}
|
||||
|
||||
rv = InitCopyState(fileSupport, messages, msgToReplace ? PR_TRUE:PR_FALSE,
|
||||
listener, msgWindow);
|
||||
listener, msgWindow, PR_FALSE);
|
||||
if (NS_FAILED(rv)) goto done;
|
||||
|
||||
parseMsgState = new nsParseMailMessageState();
|
||||
@ -2158,6 +2366,11 @@ NS_IMETHODIMP nsMsgLocalMailFolder::EndCopy(PRBool copySucceeded)
|
||||
nsresult result;
|
||||
if(!mCopyState->m_isMove)
|
||||
{
|
||||
nsCOMPtr<nsIMsgFolder> srcFolder;
|
||||
srcFolder = do_QueryInterface(mCopyState->m_srcSupport);
|
||||
if (mCopyState->m_isFolder)
|
||||
DoNextSubFolder(this, srcFolder, nsnull, nsnull); //Copy all subfolders then notify completion
|
||||
|
||||
NS_WITH_SERVICE(nsIMsgCopyService, copyService,
|
||||
kMsgCopyServiceCID, &result);
|
||||
|
||||
@ -2168,10 +2381,8 @@ NS_IMETHODIMP nsMsgLocalMailFolder::EndCopy(PRBool copySucceeded)
|
||||
mTxnMgr->Do(mCopyState->m_undoMsgTxn);
|
||||
|
||||
|
||||
nsCOMPtr<nsIMsgFolder> srcFolder;
|
||||
srcFolder = do_QueryInterface(mCopyState->m_srcSupport);
|
||||
if (srcFolder)
|
||||
srcFolder->NotifyFolderEvent(mDeleteOrMoveMsgCompletedAtom);
|
||||
if (srcFolder && !mCopyState->m_isFolder)
|
||||
srcFolder->NotifyFolderEvent(mDeleteOrMoveMsgCompletedAtom);
|
||||
ClearCopyState();
|
||||
}
|
||||
|
||||
@ -2765,3 +2976,4 @@ nsMsgLocalMailFolder::setSubfolderFlag(PRUnichar* aFolderName,
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
@ -62,6 +62,7 @@ struct nsLocalMailCopyState
|
||||
nsIMsgMessageService* m_messageService;
|
||||
PRUint32 m_totalMsgCount;
|
||||
PRBool m_isMove;
|
||||
PRBool m_isFolder; // isFolder move/copy
|
||||
PRBool m_dummyEnvelopeNeeded;
|
||||
char m_dataBuffer[FOUR_K+1];
|
||||
PRUint32 m_leftOver;
|
||||
@ -134,6 +135,8 @@ public:
|
||||
deleteStorage, PRBool isMove);
|
||||
NS_IMETHOD CopyMessages(nsIMsgFolder *srcFolder, nsISupportsArray* messages,
|
||||
PRBool isMove, nsIMsgWindow *msgWindow,
|
||||
nsIMsgCopyServiceListener* listener, PRBool isFolder );
|
||||
NS_IMETHOD CopyFolder(nsIMsgFolder *srcFolder, PRBool isMoveFolder, nsIMsgWindow *msgWindow,
|
||||
nsIMsgCopyServiceListener* listener);
|
||||
NS_IMETHOD CopyFileMessage(nsIFileSpec* fileSpec, nsIMessage* msgToReplace,
|
||||
PRBool isDraftOrTemplate,
|
||||
@ -144,6 +147,13 @@ public:
|
||||
|
||||
|
||||
protected:
|
||||
nsresult CopyFolderLocal(nsIMsgFolder *destFolder, nsIMsgFolder *srcFolder, PRBool isMoveFolder, nsIMsgWindow *msgWindow,
|
||||
nsIMsgCopyServiceListener* listener);
|
||||
nsresult CopyFolderAcrossServer(nsIMsgFolder *destFolder, nsIMsgFolder *srcFolder, nsIMsgWindow *msgWindow,nsIMsgCopyServiceListener* listener);
|
||||
|
||||
nsresult DoNextSubFolder(nsIMsgFolder *newMsgFolder, nsIMsgFolder *srcFolder,
|
||||
nsIMsgWindow *msgWindow, nsIMsgCopyServiceListener *listener );
|
||||
|
||||
nsresult CreateSubFolders(nsFileSpec &path);
|
||||
nsresult AddDirectorySeparator(nsFileSpec &path);
|
||||
nsresult GetDatabase(nsIMsgWindow *aMsgWindow);
|
||||
@ -161,7 +171,8 @@ protected:
|
||||
|
||||
nsresult DeleteMessage(nsIMessage *message, nsIMsgWindow *msgWindow,
|
||||
PRBool deleteStorage);
|
||||
// copy message helper
|
||||
|
||||
// copy message helper
|
||||
nsresult CopyMessageTo(nsIMessage *message, nsIMsgFolder *dstFolder,
|
||||
nsIMsgWindow *msgWindow, PRBool isMove);
|
||||
|
||||
@ -173,7 +184,7 @@ protected:
|
||||
virtual const char* GetIncomingServerType();
|
||||
nsresult SetTransactionManager(nsITransactionManager* txnMgr);
|
||||
nsresult InitCopyState(nsISupports* aSupport, nsISupportsArray* messages,
|
||||
PRBool isMove, nsIMsgCopyServiceListener* listener, nsIMsgWindow *msgWindow);
|
||||
PRBool isMove, nsIMsgCopyServiceListener* listener, nsIMsgWindow *msgWindow, PRBool isMoveFolder);
|
||||
void ClearCopyState();
|
||||
virtual nsresult CreateBaseMessageURI(const char *aURI);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user