зеркало из https://github.com/mozilla/pjs.git
Implementing deleting/filing messages on single and multiple folders in search. Fixed regression introduced after merging performance branch that search does not display number of search hits. r=bhuvan,bienvenu. sr=bienvenu.
This commit is contained in:
Родитель
f859389a26
Коммит
a61462049b
|
@ -279,7 +279,8 @@ const nsMsgBiffState nsMsgBiffState_Unknown = 2; // We dunno whether there is ne
|
|||
|
||||
void deleteMessages(in nsISupportsArray message,
|
||||
in nsIMsgWindow msgWindow,
|
||||
in boolean deleteStorage, in boolean isMove);
|
||||
in boolean deleteStorage, in boolean isMove,
|
||||
in nsIMsgCopyServiceListener listener);
|
||||
|
||||
void copyMessages(in nsIMsgFolder srcFolder, in nsISupportsArray messages,
|
||||
in boolean isMove, in nsIMsgWindow msgWindow,
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "nsISupports.idl"
|
||||
#include "nsMsgSearchCore.idl"
|
||||
#include "nsIMsgSearchValue.idl"
|
||||
#include "nsIFolderListener.idl"
|
||||
|
||||
interface nsMsgResultElement;
|
||||
interface nsIMsgSearchAdapter;
|
||||
|
@ -118,4 +119,6 @@ interface nsIMsgSearchSession : nsISupports {
|
|||
const long BooleanOR=0;
|
||||
const long BooleanAND=1;
|
||||
|
||||
void addFolderListener(in nsIFolderListener listener);
|
||||
void removeFolderListener(in nsIFolderListener listener);
|
||||
};
|
||||
|
|
|
@ -39,14 +39,16 @@ var gStatusFeedback = new nsMsgStatusFeedback;
|
|||
var gNumOfSearchHits = 0;
|
||||
var RDF;
|
||||
var gSearchBundle;
|
||||
var gNextMessageViewIndexAfterDelete = -1;
|
||||
|
||||
// Datasource search listener -- made global as it has to be registered
|
||||
// and unregistered in different functions.
|
||||
var gDataSourceSearchListener;
|
||||
var gViewSearchListener;
|
||||
var gIsSearchHit = false;
|
||||
|
||||
var gButton;
|
||||
var gSearchSessionFolderListener;
|
||||
var gMailSession;
|
||||
|
||||
// Controller object for search results thread pane
|
||||
var nsSearchResultsController =
|
||||
|
@ -55,6 +57,8 @@ var nsSearchResultsController =
|
|||
{
|
||||
switch(command) {
|
||||
case "cmd_open":
|
||||
case "cmd_delete":
|
||||
case "file_message_button":
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
|
@ -80,6 +84,10 @@ var nsSearchResultsController =
|
|||
MsgOpenSelectedMessages(gSearchView);
|
||||
return true;
|
||||
|
||||
case "cmd_delete":
|
||||
MsgDeleteSelectedMessages();
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
@ -105,13 +113,17 @@ var gSearchNotificationListener =
|
|||
|
||||
var statusMsg;
|
||||
// if there are no hits, it means no matches were found in the search.
|
||||
if (!gIsSearchHit) {
|
||||
gStatusFeedback.showStatusString(gSearchBundle.getString("searchFailureMessage"));
|
||||
if (gNumOfSearchHits == 0) {
|
||||
statusMsg = gSearchBundle.getString("searchFailureMessage");
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
gStatusFeedback.showStatusString(gSearchBundle.getString("searchSuccessMessage"));
|
||||
gIsSearchHit = false;
|
||||
if (gNumOfSearchHits == 1)
|
||||
statusMsg = gSearchBundle.getString("searchSuccessMessage");
|
||||
else
|
||||
statusMsg = gSearchBundle.getFormattedString("searchSuccessMessages", [gNumOfSearchHits]);
|
||||
|
||||
gNumOfSearchHits = 0;
|
||||
}
|
||||
|
||||
gStatusFeedback.showProgress(100);
|
||||
|
@ -132,6 +144,34 @@ var gSearchNotificationListener =
|
|||
}
|
||||
}
|
||||
|
||||
// the folderListener object
|
||||
var gFolderListener = {
|
||||
OnItemAdded: function(parentItem, item, view) {},
|
||||
|
||||
OnItemRemoved: function(parentItem, item, view){},
|
||||
|
||||
OnItemPropertyChanged: function(item, property, oldValue, newValue) {},
|
||||
|
||||
OnItemIntPropertyChanged: function(item, property, oldValue, newValue) {},
|
||||
|
||||
OnItemBoolPropertyChanged: function(item, property, oldValue, newValue) {},
|
||||
|
||||
OnItemUnicharPropertyChanged: function(item, property, oldValue, newValue){},
|
||||
OnItemPropertyFlagChanged: function(item, property, oldFlag, newFlag) {},
|
||||
|
||||
OnItemEvent: function(folder, event) {
|
||||
var eventType = event.GetUnicode();
|
||||
|
||||
if (eventType == "DeleteOrMoveMsgCompleted") {
|
||||
HandleDeleteOrMoveMessageCompleted(folder);
|
||||
}
|
||||
else if (eventType == "DeleteOrMoveMsgFailed") {
|
||||
HandleDeleteOrMoveMessageFailed(folder);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function searchOnLoad()
|
||||
{
|
||||
initializeSearchWidgets();
|
||||
|
@ -156,6 +196,12 @@ function searchOnUnload()
|
|||
gSearchSession.unregisterListener(gViewSearchListener);
|
||||
gSearchSession.unregisterListener(gSearchNotificationListener);
|
||||
|
||||
gMailSession.RemoveFolderListener(gSearchSessionFolderListener);
|
||||
gSearchSession.removeFolderListener(gFolderListener);
|
||||
|
||||
gSearchView.close();
|
||||
gSearchView = null;
|
||||
|
||||
// release this early because msgWindow holds a weak reference
|
||||
msgWindow.rootDocShell = null;
|
||||
}
|
||||
|
@ -362,10 +408,14 @@ function setupDatasource() {
|
|||
// attributes about each message)
|
||||
gSearchSession = Components.classes[searchSessionContractID].createInstance(Components.interfaces.nsIMsgSearchSession);
|
||||
|
||||
gSearchSessionFolderListener = gSearchSession.QueryInterface(Components.interfaces.nsIFolderListener);
|
||||
gMailSession = Components.classes[mailSessionContractID].getService(Components.interfaces.nsIMsgMailSession);
|
||||
gMailSession.AddFolderListener(gSearchSessionFolderListener);
|
||||
|
||||
// the datasource is a listener on the search results
|
||||
gViewSearchListener = gSearchView.QueryInterface(Components.interfaces.nsIMsgSearchNotify);
|
||||
gSearchSession.registerListener(gViewSearchListener);
|
||||
gSearchSession.addFolderListener(gFolderListener);
|
||||
}
|
||||
|
||||
|
||||
|
@ -450,3 +500,105 @@ function GetDBView()
|
|||
{
|
||||
return gSearchView;
|
||||
}
|
||||
|
||||
function MsgDeleteSelectedMessages()
|
||||
{
|
||||
// we don't delete news messages, we just return in that case
|
||||
if (isNewsURI(gSearchView.getURIForViewIndex(0)))
|
||||
return;
|
||||
|
||||
// if mail messages delete
|
||||
SetNextMessageAfterDelete();
|
||||
gSearchView.doCommand(nsMsgViewCommandType.deleteMsg);
|
||||
}
|
||||
|
||||
function SetNextMessageAfterDelete()
|
||||
{
|
||||
dump("setting next msg view index after delete to " + gSearchView.firstSelected + "\n");
|
||||
gNextMessageViewIndexAfterDelete = gSearchView.firstSelected;
|
||||
}
|
||||
|
||||
function HandleDeleteOrMoveMessageFailed(folder)
|
||||
{
|
||||
gNextMessageViewIndexAfterDelete = -1;
|
||||
}
|
||||
|
||||
|
||||
function HandleDeleteOrMoveMessageCompleted(folder)
|
||||
{
|
||||
if(gNextMessageViewIndexAfterDelete != -1)
|
||||
{
|
||||
var outlinerView = gSearchView.QueryInterface(Components.interfaces.nsIOutlinerView);
|
||||
var outlinerSelection = outlinerView.selection;
|
||||
viewSize = outlinerView.rowCount;
|
||||
|
||||
if (gNextMessageViewIndexAfterDelete >= viewSize)
|
||||
{
|
||||
if (viewSize > 0)
|
||||
gNextMessageViewIndexAfterDelete = viewSize - 1;
|
||||
else
|
||||
gNextMessageViewIndexAfterDelete = -1;
|
||||
}
|
||||
|
||||
// if we are about to set the selection with a new element then DON'T clear
|
||||
// the selection then add the next message to select. This just generates
|
||||
// an extra round of command updating notifications that we are trying to
|
||||
// optimize away.
|
||||
if (gNextMessageViewIndexAfterDelete != -1) {
|
||||
outlinerSelection.select(gNextMessageViewIndexAfterDelete);
|
||||
// since gNextMessageViewIndexAfterDelete probably has the same value
|
||||
// as the last index we had selected, the outliner isn't generating a new
|
||||
// selectionChanged notification for the outliner view. So we aren't loading the
|
||||
// next message. to fix this, force the selection changed update.
|
||||
var outlinerView = gSearchView.QueryInterface(Components.interfaces.nsIOutlinerView);
|
||||
if (outlinerView)
|
||||
outlinerView.selectionChanged();
|
||||
|
||||
EnsureRowInThreadOutlinerIsVisible(gNextMessageViewIndexAfterDelete);
|
||||
}
|
||||
else
|
||||
outlinerSelection.clearSelection(); /* clear selection in either case */
|
||||
|
||||
gNextMessageViewIndexAfterDelete = -1;
|
||||
}
|
||||
}
|
||||
|
||||
function SetDatasources()
|
||||
{
|
||||
dump("XXX SetDatasources\n");
|
||||
|
||||
var button = document.getElementById("fileMessageButton");
|
||||
var datasourceContractIDPrefix = "@mozilla.org/rdf/datasource;1?name=";
|
||||
var accountManagerDSContractID = datasourceContractIDPrefix + "msgaccountmanager";
|
||||
var folderDSContractID = datasourceContractIDPrefix + "mailnewsfolders";
|
||||
var accountManagerDataSource = Components.classes[accountManagerDSContractID].createInstance();
|
||||
var folderDataSource = Components.classes[folderDSContractID].createInstance();
|
||||
accountManagerDataSource = accountManagerDataSource.QueryInterface(Components.interfaces.nsIRDFDataSource);
|
||||
folderDataSource = folderDataSource.QueryInterface(Components.interfaces.nsIRDFDataSource);
|
||||
button.database.AddDataSource(accountManagerDataSource);
|
||||
button.database.AddDataSource(folderDataSource);
|
||||
button.setAttribute('ref', 'msgaccounts:/');
|
||||
}
|
||||
|
||||
function MoveMessageInSearch(destFolder)
|
||||
{
|
||||
try {
|
||||
// get the msg folder we're moving messages into
|
||||
destUri = destFolder.getAttribute('id');
|
||||
destResource = RDF.GetResource(destUri);
|
||||
|
||||
destMsgFolder = destResource.QueryInterface(Components.interfaces.nsIMsgFolder);
|
||||
|
||||
// we don't move news messages, we copy them
|
||||
if (isNewsURI(gSearchView.getURIForViewIndex(0))) {
|
||||
gSearchView.doCommandWithFolder(nsMsgViewCommandType.copyMessages, destMsgFolder);
|
||||
}
|
||||
else {
|
||||
SetNextMessageAfterDelete();
|
||||
gSearchView.doCommandWithFolder(nsMsgViewCommandType.moveMessages, destMsgFolder);
|
||||
}
|
||||
}
|
||||
catch (ex) {
|
||||
dump("MsgMoveMessage failed: " + ex + "\n");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ Rights Reserved.
|
|||
|
||||
<window xmlns:html="http://www.w3.org/1999/xhtml"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onload="searchOnLoad();"
|
||||
onload="searchOnLoad(); SetDatasources()"
|
||||
onunload="searchOnUnload();"
|
||||
onclose="onSearchStop();"
|
||||
title="&searchDialogTitle.label;"
|
||||
|
@ -47,12 +47,15 @@ Rights Reserved.
|
|||
<stringbundle id="bundle_messenger" src="chrome://messenger/locale/messenger.properties"/>
|
||||
<stringbundle id="bundle_brand" src="chrome://global/locale/brand.properties"/>
|
||||
<!-- XXX: only mailWidgets.xml requires strres.js (<script> isn't valid in XBL yet - see hyatt)-->
|
||||
<script type="application/x-javascript" src="chrome://global/content/strres.js"/>
|
||||
<script type="application/x-javascript" src="chrome://messenger/content/mailWindow.js"/>
|
||||
<script type="application/x-javascript" src="chrome://messenger/content/threadPane.js"/>
|
||||
<script type="application/x-javascript" src="chrome://messenger/content/msgMail3PaneWindow.js"/>
|
||||
<script type="application/x-javascript" src="chrome://global/content/globalOverlay.js"/>
|
||||
<script type="application/x-javascript" src="chrome://messenger/content/SearchDialog.js"/>
|
||||
<script type="text/javascript" src="chrome://global/content/strres.js"/>
|
||||
<script src="chrome://messenger/content/mailWindow.js"/>
|
||||
<script src="chrome://messenger/content/threadPane.js"/>
|
||||
<script src="chrome://messenger/content/msgMail3PaneWindow.js"/>
|
||||
<script src="chrome://global/content/globalOverlay.js"/>
|
||||
<script src="chrome://messenger/content/mailCommands.js"/>
|
||||
<script src="chrome://messenger/content/mailWindowOverlay.js"/>
|
||||
<script src="chrome://messenger/content/commandglue.js"/>
|
||||
<script src="chrome://messenger/content/SearchDialog.js"/>
|
||||
|
||||
<commands id="commands">
|
||||
<commandset id="mailSearchItems"
|
||||
|
@ -60,6 +63,8 @@ Rights Reserved.
|
|||
events="mail-search"
|
||||
oncommandupdate="goUpdateSearchItems(this)">
|
||||
<command id="cmd_open" oncommand="goDoCommand('cmd_open')" disabled="true"/>
|
||||
<command id="cmd_delete" oncommand="goDoCommand('cmd_delete')" disabled="true"/>
|
||||
<command id="file_message_button"/>
|
||||
</commandset>
|
||||
</commands>
|
||||
|
||||
|
@ -98,9 +103,73 @@ Rights Reserved.
|
|||
<outliner id="threadOutliner" flex="1" context="threadPaneContext"/>
|
||||
</box>
|
||||
</titledbox>
|
||||
|
||||
|
||||
<box align="left">
|
||||
<menubutton class="menubutton-dual-dropmarker-box" id="fileMessageButton" observes="file_message_button" oncommand="MoveMessageInSearch(event.target)" datasources="rdf:null" ignore="http://home.netscape.com/NC-rdf#MessageChild" label="&fileButton.label;">
|
||||
<menupopup/>
|
||||
<template>
|
||||
<rule nc:NoSelect="true" iscontainer="true" isempty="false">
|
||||
<menupopup>
|
||||
<menu uri="..." class="folderMenuItem menu-iconic" label="rdf:http://home.netscape.com/NC-rdf#Name">
|
||||
<menupopup>
|
||||
<menuitem uri="..." label="&fileHereMenu.label;"/>
|
||||
<menuseparator/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
</menupopup>
|
||||
</rule>
|
||||
<rule nc:NoSelect="true">
|
||||
<menupopup>
|
||||
<menuitem uri="..." class="folderMenuItem menu-iconic" label="rdf:http://home.netscape.com/NC-rdf#Name"/>
|
||||
</menupopup>
|
||||
</rule>
|
||||
<rule nc:CanFileMessages="true" iscontainer="true" isempty="false">
|
||||
<menupopup>
|
||||
<menu uri="..." class="folderMenuItem menu-iconic" label="rdf:http://home.netscape.com/NC-rdf#Name"
|
||||
SpecialFolder="rdf:http://home.netscape.com/NC-rdf#SpecialFolder"
|
||||
BiffState="rdf:http://home.netscape.com/NC-rdf#BiffState"
|
||||
IsServer="rdf:http://home.netscape.com/NC-rdf#IsServer"
|
||||
ServerType="rdf:http://home.netscape.com/NC-rdf#ServerType">
|
||||
<menupopup>
|
||||
<menuitem uri="..." label="&fileHereMenu.label;"
|
||||
SpecialFolder="rdf:http://home.netscape.com/NC-rdf#SpecialFolder"
|
||||
BiffState="rdf:http://home.netscape.com/NC-rdf#BiffState"
|
||||
IsServer="rdf:http://home.netscape.com/NC-rdf#IsServer"
|
||||
ServerType="rdf:http://home.netscape.com/NC-rdf#ServerType"/>
|
||||
<menuseparator/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
</menupopup>
|
||||
</rule>
|
||||
<rule nc:CanFileMessages="false" nc:ServerType="nntp"/>
|
||||
<rule nc:CanFileMessages="false" iscontainer="true" isempty="false">
|
||||
<!-- note, there is no "file here" -->
|
||||
<menupopup>
|
||||
<menu uri="..." class="folderMenuItem menu-iconic" label="rdf:http://home.netscape.com/NC-rdf#Name"
|
||||
SpecialFolder="rdf:http://home.netscape.com/NC-rdf#SpecialFolder"
|
||||
BiffState="rdf:http://home.netscape.com/NC-rdf#BiffState"
|
||||
IsServer="rdf:http://home.netscape.com/NC-rdf#IsServer"
|
||||
ServerType="rdf:http://home.netscape.com/NC-rdf#ServerType">
|
||||
<menupopup/>
|
||||
</menu>
|
||||
</menupopup>
|
||||
</rule>
|
||||
<rule nc:CanFileMessages="true">
|
||||
<menupopup>
|
||||
<menuitem uri="..." class="folderMenuItem menuitem-iconic" label="rdf:http://home.netscape.com/NC-rdf#Name"
|
||||
SpecialFolder="rdf:http://home.netscape.com/NC-rdf#SpecialFolder"
|
||||
BiffState="rdf:http://home.netscape.com/NC-rdf#BiffState"
|
||||
IsServer="rdf:http://home.netscape.com/NC-rdf#IsServer"
|
||||
ServerType="rdf:http://home.netscape.com/NC-rdf#ServerType"/>
|
||||
</menupopup>
|
||||
</rule>
|
||||
</template>
|
||||
</menubutton>
|
||||
</box>
|
||||
|
||||
<box autostretch="never" align="right">
|
||||
<button label="&openButton.label;" id="openButton" observes="cmd_open"/>
|
||||
<button label="Delete" id="deleteButton" observes="cmd_delete"/>
|
||||
<button label="&closeButton.label;" oncommand="window.close();"/>
|
||||
</box>
|
||||
|
||||
|
|
|
@ -11,5 +11,8 @@
|
|||
<!ENTITY conditionDesc.label "Search for messages which:">
|
||||
<!ENTITY conditions.label "Criteria">
|
||||
<!ENTITY results.label "Results">
|
||||
<!ENTITY fileHereMenu.label "File Here">
|
||||
<!ENTITY fileButton.label "File">
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
#include "nsXPIDLString.h"
|
||||
#include "nsIMsgSearchNotify.h"
|
||||
|
||||
NS_IMPL_ISUPPORTS2(nsMsgSearchSession, nsIMsgSearchSession, nsIUrlListener)
|
||||
NS_IMPL_ISUPPORTS3(nsMsgSearchSession, nsIMsgSearchSession, nsIUrlListener, nsIFolderListener)
|
||||
|
||||
nsMsgSearchSession::nsMsgSearchSession()
|
||||
{
|
||||
|
@ -708,3 +708,113 @@ nsresult nsMsgSearchSession::TimeSliceSerial (PRBool *aDone)
|
|||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMsgSearchSession::AddFolderListener(nsIFolderListener *listener)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
if (!m_folderListenerList)
|
||||
rv = NS_NewISupportsArray(getter_AddRefs(m_folderListenerList));
|
||||
|
||||
if (NS_SUCCEEDED(rv) && m_folderListenerList)
|
||||
m_folderListenerList->AppendElement(listener);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMsgSearchSession::RemoveFolderListener(nsIFolderListener *listener)
|
||||
{
|
||||
if (m_folderListenerList)
|
||||
m_folderListenerList->RemoveElement(listener);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsIFolderListener methods.
|
||||
NS_IMETHODIMP
|
||||
nsMsgSearchSession::OnItemEvent(nsIFolder *aFolder,
|
||||
nsIAtom *aEvent)
|
||||
{
|
||||
nsresult rv;
|
||||
PRUint32 count;
|
||||
|
||||
NS_ASSERTION(m_folderListenerList, "no listeners");
|
||||
if (!m_folderListenerList) return NS_ERROR_FAILURE;
|
||||
|
||||
rv = m_folderListenerList->Count(&count);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
for(PRUint32 i = 0; i < count; i++)
|
||||
{
|
||||
nsCOMPtr<nsIFolderListener> listener = getter_AddRefs((nsIFolderListener*)m_folderListenerList->ElementAt(i));
|
||||
if(listener)
|
||||
listener->OnItemEvent(aFolder, aEvent);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMsgSearchSession::OnItemAdded(nsISupports *parentItem,
|
||||
nsISupports *item,
|
||||
const char* viewString)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMsgSearchSession::OnItemRemoved(nsISupports *parentItem,
|
||||
nsISupports *item,
|
||||
const char* viewString)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMsgSearchSession::OnItemPropertyChanged(nsISupports *item,
|
||||
nsIAtom *property,
|
||||
const char* oldValue,
|
||||
const char* newValue)
|
||||
{
|
||||
return NS_OK;
|
||||
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMsgSearchSession::OnItemIntPropertyChanged(nsISupports *item,
|
||||
nsIAtom *property,
|
||||
PRInt32 oldValue,
|
||||
PRInt32 newValue)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMsgSearchSession::OnItemBoolPropertyChanged(nsISupports *item,
|
||||
nsIAtom *property,
|
||||
PRBool oldValue,
|
||||
PRBool newValue)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMsgSearchSession::OnItemUnicharPropertyChanged(nsISupports *item,
|
||||
nsIAtom *property,
|
||||
const PRUnichar* oldValue,
|
||||
const PRUnichar* newValue)
|
||||
{
|
||||
return NS_OK;
|
||||
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMsgSearchSession::OnItemPropertyFlagChanged(nsISupports *item,
|
||||
nsIAtom *property,
|
||||
PRUint32 oldValue,
|
||||
PRUint32 newValue)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "nsMsgSearchCore.h"
|
||||
#include "nsIMsgSearchSession.h"
|
||||
#include "nsIUrlListener.h"
|
||||
#include "nsIFolderListener.h"
|
||||
#include "nsIMsgWindow.h"
|
||||
#include "nsITimer.h"
|
||||
#include "nsMsgSearchArray.h"
|
||||
|
@ -34,12 +35,13 @@
|
|||
|
||||
class nsMsgSearchAdapter;
|
||||
|
||||
class nsMsgSearchSession : public nsIMsgSearchSession, public nsIUrlListener
|
||||
class nsMsgSearchSession : public nsIMsgSearchSession, public nsIUrlListener, public nsIFolderListener
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIMSGSEARCHSESSION
|
||||
NS_DECL_NSIURLLISTENER
|
||||
NS_DECL_NSIFOLDERLISTENER
|
||||
|
||||
nsMsgSearchSession();
|
||||
virtual ~nsMsgSearchSession();
|
||||
|
@ -62,7 +64,8 @@ protected:
|
|||
|
||||
nsMsgSearchScopeTermArray m_scopeList;
|
||||
nsCOMPtr <nsISupportsArray> m_termList;
|
||||
nsCOMPtr <nsISupportsArray> m_listenerList;
|
||||
nsCOMPtr <nsISupportsArray> m_listenerList;
|
||||
nsCOMPtr <nsISupportsArray> m_folderListenerList;
|
||||
|
||||
nsMsgResultArray m_resultList;
|
||||
|
||||
|
|
|
@ -86,7 +86,7 @@ static nsresult DeleteMessage(nsIURI *aURL, nsIMsgFolder *srcFolder)
|
|||
nsCOMPtr<nsISupports> messageSupports(do_QueryInterface(message));
|
||||
if(messageSupports)
|
||||
messageArray->AppendElement(messageSupports);
|
||||
rv = srcFolder->DeleteMessages(messageArray, nsnull, PR_TRUE, PR_TRUE);
|
||||
rv = srcFolder->DeleteMessages(messageArray, nsnull, PR_TRUE, PR_TRUE, nsnull);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
|
|
@ -1561,7 +1561,7 @@ nsresult nsMsgDBView::DeleteMessages(nsIMsgWindow *window, nsMsgViewIndex *indic
|
|||
messageArray->AppendElement(msgHdr);
|
||||
|
||||
}
|
||||
m_folder->DeleteMessages(messageArray, window, deleteStorage, PR_FALSE);
|
||||
m_folder->DeleteMessages(messageArray, window, deleteStorage, PR_FALSE, nsnull);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -1761,6 +1761,9 @@ nsresult nsMsgDBView::ReverseThreads()
|
|||
nsresult nsMsgDBView::ReverseSort()
|
||||
{
|
||||
PRUint32 num = GetSize();
|
||||
|
||||
nsCOMPtr <nsISupportsArray> folders;
|
||||
GetFolders(getter_AddRefs(folders));
|
||||
|
||||
// go up half the array swapping values
|
||||
for (PRUint32 i = 0; i < (num / 2); i++) {
|
||||
|
@ -1775,6 +1778,15 @@ nsresult nsMsgDBView::ReverseSort()
|
|||
m_keys.SetAt(i, m_keys.GetAt(end));
|
||||
m_keys.SetAt(end, tempKey);
|
||||
|
||||
if (folders)
|
||||
{
|
||||
// swap folders --
|
||||
// needed when search is done across multiple folders
|
||||
nsCOMPtr <nsISupports> tmpSupports
|
||||
= getter_AddRefs(folders->ElementAt(i));
|
||||
folders->SetElementAt(i, folders->ElementAt(end));
|
||||
folders->SetElementAt(end, tmpSupports);
|
||||
}
|
||||
// no need to swap elements in m_levels,
|
||||
// since we won't call ReverseSort() if we
|
||||
// are in threaded mode, so m_levels are all the same.
|
||||
|
@ -1787,7 +1799,8 @@ typedef struct entryInfo {
|
|||
nsMsgKey id;
|
||||
PRUint32 bits;
|
||||
PRUint32 len;
|
||||
PRUint32 pad;
|
||||
//PRUint32 pad;
|
||||
nsIMsgFolder* folder;
|
||||
} EntryInfo;
|
||||
|
||||
typedef struct tagIdKey {
|
||||
|
@ -2114,6 +2127,10 @@ NS_IMETHODIMP nsMsgDBView::Sort(nsMsgViewSortTypeValue sortType, nsMsgViewSortOr
|
|||
|
||||
nsVoidArray ptrs;
|
||||
PRUint32 arraySize = GetSize();
|
||||
|
||||
nsCOMPtr <nsISupportsArray> folders;
|
||||
GetFolders(getter_AddRefs(folders));
|
||||
|
||||
// use IdPRTime, it is the biggest
|
||||
IdPRTime** pPtrBase = (IdPRTime**)PR_Malloc(arraySize * sizeof(IdPRTime*));
|
||||
NS_ASSERTION(pPtrBase, "out of memory, can't sort");
|
||||
|
@ -2218,6 +2235,17 @@ NS_IMETHODIMP nsMsgDBView::Sort(nsMsgViewSortTypeValue sortType, nsMsgViewSortOr
|
|||
info->len = actualFieldLen;
|
||||
//info->pad = 0;
|
||||
|
||||
if (folders)
|
||||
{
|
||||
nsCOMPtr <nsISupports> tmpSupports
|
||||
= getter_AddRefs(folders->ElementAt(numSoFar));
|
||||
nsCOMPtr<nsIMsgFolder> curFolder;
|
||||
if(tmpSupports) {
|
||||
curFolder = do_QueryInterface(tmpSupports);
|
||||
info->folder = curFolder;
|
||||
}
|
||||
}
|
||||
|
||||
pTemp += sizeof(EntryInfo);
|
||||
|
||||
PRInt32 bytesLeft = allocSize - (PRInt32)(pTemp - pBase);
|
||||
|
@ -2265,6 +2293,13 @@ NS_IMETHODIMP nsMsgDBView::Sort(nsMsgViewSortTypeValue sortType, nsMsgViewSortOr
|
|||
for (PRUint32 i = 0; i < numSoFar; i++) {
|
||||
m_keys.SetAt(i, pPtrBase[i]->info.id);
|
||||
m_flags.SetAt(i, pPtrBase[i]->info.bits);
|
||||
|
||||
if (folders)
|
||||
{
|
||||
nsCOMPtr <nsISupports> tmpSupports
|
||||
= do_QueryInterface(pPtrBase[i]->info.folder);
|
||||
folders->SetElementAt(i, tmpSupports);
|
||||
}
|
||||
}
|
||||
|
||||
m_sortType = sortType;
|
||||
|
@ -4125,3 +4160,12 @@ nsMsgDBView::GetKeyForFirstSelectedMessage(nsMsgKey *key)
|
|||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsMsgDBView::GetFolders(nsISupportsArray **aFolders)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aFolders);
|
||||
*aFolders = nsnull;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -160,7 +160,8 @@ protected:
|
|||
nsMsgViewIndex FindViewIndex(nsMsgKey key)
|
||||
{return (nsMsgViewIndex) (m_keys.FindIndex(key));}
|
||||
virtual nsMsgViewIndex FindKey(nsMsgKey key, PRBool expand);
|
||||
virtual nsresult GetDBForViewIndex(nsMsgViewIndex index, nsIMsgDatabase **db);
|
||||
virtual nsresult GetDBForViewIndex(nsMsgViewIndex index, nsIMsgDatabase **db);
|
||||
virtual nsresult GetFolders(nsISupportsArray **folders);
|
||||
|
||||
nsresult ListIdsInThread(nsIMsgThread *threadHdr, nsMsgViewIndex viewIndex, PRUint32 *pNumListed);
|
||||
nsresult ListUnreadIdsInThread(nsIMsgThread *threadHdr, nsMsgViewIndex startOfThreadViewIndex, PRUint32 *pNumListed);
|
||||
|
@ -182,8 +183,8 @@ protected:
|
|||
PRInt32 numIndices);
|
||||
nsresult ApplyCommandToIndicesWithFolder(nsMsgViewCommandTypeValue command, nsMsgViewIndex* indices,
|
||||
PRInt32 numIndices, nsIMsgFolder *destFolder);
|
||||
nsresult CopyMessages(nsIMsgWindow *window, nsMsgViewIndex *indices, PRInt32 numIndices, PRBool isMove, nsIMsgFolder *destFolder);
|
||||
nsresult DeleteMessages(nsIMsgWindow *window, nsMsgViewIndex *indices, PRInt32 numIndices, PRBool deleteStorage);
|
||||
virtual nsresult CopyMessages(nsIMsgWindow *window, nsMsgViewIndex *indices, PRInt32 numIndices, PRBool isMove, nsIMsgFolder *destFolder);
|
||||
virtual nsresult DeleteMessages(nsIMsgWindow *window, nsMsgViewIndex *indices, PRInt32 numIndices, PRBool deleteStorage);
|
||||
nsresult ToggleReadByIndex(nsMsgViewIndex index);
|
||||
nsresult SetReadByIndex(nsMsgViewIndex index, PRBool read);
|
||||
nsresult SetThreadOfMsgReadByIndex(nsMsgViewIndex index, nsMsgKeyArray &keysMarkedRead, PRBool read);
|
||||
|
|
|
@ -1668,7 +1668,7 @@ nsresult nsMsgFolderDataSource::DoDeleteFromFolder(
|
|||
rv = messageArray->Count(&cnt);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (cnt > 0)
|
||||
rv = folder->DeleteMessages(messageArray, msgWindow, reallyDelete, PR_FALSE);
|
||||
rv = folder->DeleteMessages(messageArray, msgWindow, reallyDelete, PR_FALSE, nsnull);
|
||||
|
||||
rv = folderArray->Count(&cnt);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
|
|
@ -24,6 +24,15 @@
|
|||
#include "nsMsgSearchDBView.h"
|
||||
#include "nsIMsgHdr.h"
|
||||
#include "nsIMsgThread.h"
|
||||
#include "nsQuickSort.h"
|
||||
#include "nsIDBFolderInfo.h"
|
||||
#include "nsXPIDLString.h"
|
||||
#include "nsMsgBaseCID.h"
|
||||
#include "nsIMsgCopyService.h"
|
||||
#include "nsICopyMsgStreamListener.h"
|
||||
|
||||
static NS_DEFINE_CID(kMsgCopyServiceCID, NS_MSGCOPYSERVICE_CID);
|
||||
static NS_DEFINE_CID(kCopyMessageStreamListenerCID, NS_COPYMESSAGESTREAMLISTENER_CID);
|
||||
|
||||
nsMsgSearchDBView::nsMsgSearchDBView()
|
||||
{
|
||||
|
@ -41,14 +50,18 @@ NS_IMPL_ADDREF_INHERITED(nsMsgSearchDBView, nsMsgDBView)
|
|||
NS_IMPL_RELEASE_INHERITED(nsMsgSearchDBView, nsMsgDBView)
|
||||
NS_IMPL_QUERY_HEAD(nsMsgSearchDBView)
|
||||
NS_IMPL_QUERY_BODY(nsIMsgSearchNotify)
|
||||
NS_IMPL_QUERY_BODY(nsIMsgCopyServiceListener)
|
||||
NS_IMPL_QUERY_TAIL_INHERITING(nsMsgDBView)
|
||||
|
||||
|
||||
NS_IMETHODIMP nsMsgSearchDBView::Open(nsIMsgFolder *folder, nsMsgViewSortTypeValue sortType, nsMsgViewSortOrderValue sortOrder, nsMsgViewFlagsTypeValue viewFlags, PRInt32 *pCount)
|
||||
{
|
||||
nsresult rv;
|
||||
m_folders = do_CreateInstance(NS_SUPPORTSARRAY_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
m_folders = do_CreateInstance(NS_SUPPORTSARRAY_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
m_dbToUseList = do_CreateInstance(NS_SUPPORTSARRAY_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = nsMsgDBView::Open(folder, sortType, sortOrder, viewFlags, pCount);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
@ -58,6 +71,25 @@ NS_IMETHODIMP nsMsgSearchDBView::Open(nsIMsgFolder *folder, nsMsgViewSortTypeVal
|
|||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgSearchDBView::Close()
|
||||
{
|
||||
nsresult rv;
|
||||
PRUint32 count;
|
||||
|
||||
NS_ASSERTION(m_dbToUseList, "no db used");
|
||||
//if (!m_dbToUseList) return NS_ERROR_FAILURE;
|
||||
|
||||
rv = m_dbToUseList->Count(&count);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
for(PRUint32 i = 0; i < count; i++)
|
||||
{
|
||||
((nsIMsgDatabase*)m_dbToUseList->ElementAt(i))->RemoveListener(this);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgSearchDBView::GetCellText(PRInt32 aRow, const PRUnichar * aColID, PRUnichar ** aValue)
|
||||
{
|
||||
nsresult rv;
|
||||
|
@ -159,4 +191,332 @@ nsMsgSearchDBView::OnNewSearch()
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsMsgSearchDBView::GetFolders(nsISupportsArray **aFolders)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aFolders);
|
||||
*aFolders = m_folders;
|
||||
NS_IF_ADDREF(*aFolders);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMsgSearchDBView::DoCommandWithFolder(nsMsgViewCommandTypeValue command, nsIMsgFolder *destFolder)
|
||||
{
|
||||
mCommand = command;
|
||||
mDestFolder = getter_AddRefs(destFolder);
|
||||
|
||||
return nsMsgDBView::DoCommandWithFolder(command, destFolder);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgSearchDBView::DoCommand(nsMsgViewCommandTypeValue command)
|
||||
{
|
||||
mCommand = command;
|
||||
return nsMsgDBView::DoCommand(command);
|
||||
}
|
||||
|
||||
// This method just removes the specified line from the view. It does
|
||||
// NOT delete it from the database.
|
||||
nsresult nsMsgSearchDBView::RemoveByIndex(nsMsgViewIndex index)
|
||||
{
|
||||
if (!IsValidIndex(index))
|
||||
return NS_MSG_INVALID_DBVIEW_INDEX;
|
||||
|
||||
m_folders->RemoveElementAt(index);
|
||||
|
||||
for (nsMsgViewIndex i = 0; i < (nsMsgViewIndex) mTotalIndices; i++)
|
||||
{
|
||||
mIndicesForChainedDeleteAndFile[i]--;
|
||||
}
|
||||
|
||||
return nsMsgDBView::RemoveByIndex(index);
|
||||
}
|
||||
|
||||
nsresult nsMsgSearchDBView::DeleteMessages(nsIMsgWindow *window, nsMsgViewIndex *indices, PRInt32 numIndices, PRBool deleteStorage)
|
||||
{
|
||||
nsresult rv;
|
||||
InitializeGlobalsForDeleteAndFile(indices, numIndices);
|
||||
|
||||
if (!deleteStorage)
|
||||
rv = ProcessChainedRequest(window, indices, numIndices);
|
||||
else
|
||||
rv = ProcessContinuousRequest(window, indices, numIndices);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsMsgSearchDBView::CopyMessages(nsIMsgWindow *window, nsMsgViewIndex *indices, PRInt32 numIndices, PRBool isMove, nsIMsgFolder *destFolder)
|
||||
{
|
||||
nsresult rv;
|
||||
InitializeGlobalsForDeleteAndFile(indices, numIndices);
|
||||
|
||||
rv = ProcessChainedRequest(window, indices, numIndices);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsMsgSearchDBView::InitializeGlobalsForDeleteAndFile(nsMsgViewIndex *indices, PRInt32 numIndices)
|
||||
{
|
||||
nsMsgViewIndex *outIndices, *nextIndices;
|
||||
nextIndices = outIndices = (nsMsgViewIndex *)nsMemory::Alloc(numIndices * sizeof(nsMsgViewIndex));
|
||||
if (!outIndices) return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
for (nsMsgViewIndex i = 0; i < (nsMsgViewIndex) numIndices; i++)
|
||||
{
|
||||
nextIndices[i] = indices[i];
|
||||
}
|
||||
|
||||
mIndicesForChainedDeleteAndFile = outIndices;
|
||||
mTotalIndices = numIndices;
|
||||
mCurIndex = 0;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsIMsgCopyServiceListener methods
|
||||
nsresult
|
||||
nsMsgSearchDBView::OnStartCopy()
|
||||
{
|
||||
#ifdef NS_DEBUG
|
||||
printf("nsIMsgCopyServiceListener::OnStartCopy()\n");
|
||||
#endif
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsMsgSearchDBView::OnProgress(PRUint32 aProgress, PRUint32 aProgressMax)
|
||||
{
|
||||
#ifdef NS_DEBUG
|
||||
printf("nsIMsgCopyServiceListener::OnProgress() - COPY\n");
|
||||
#endif
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsMsgSearchDBView::OnStopCopy(nsresult aStatus)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
if (NS_SUCCEEDED(aStatus))
|
||||
{
|
||||
if (mCurIndex != 0)
|
||||
{
|
||||
int tmpSize = mTotalIndices - mCurIndex;
|
||||
nsMsgViewIndex* tmpIndices = (PRUint32*)PR_Malloc(tmpSize*sizeof(PRUint32));
|
||||
nsCRT::memcpy(tmpIndices, &mIndicesForChainedDeleteAndFile[mCurIndex], tmpSize*sizeof(PRUint32));
|
||||
|
||||
PR_Free(mIndicesForChainedDeleteAndFile);
|
||||
|
||||
mIndicesForChainedDeleteAndFile = tmpIndices;
|
||||
mTotalIndices -= mCurIndex;
|
||||
mCurIndex = 0;
|
||||
|
||||
ProcessChainedRequest(mMsgWindow, mIndicesForChainedDeleteAndFile, mTotalIndices);
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsMsgSearchDBView::SetMessageKey(PRUint32 aMessageKey)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsMsgSearchDBView::GetMessageId(nsCString* aMessageId)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
// end nsIMsgCopyServiceListener methods
|
||||
|
||||
nsresult nsMsgSearchDBView::ProcessChainedRequest(nsIMsgWindow *window, nsMsgViewIndex *indices, PRInt32 numIndices)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
nsCOMPtr<nsISupportsArray> messageArray;
|
||||
NS_NewISupportsArray(getter_AddRefs(messageArray));
|
||||
|
||||
nsCOMPtr<nsIMsgCopyServiceListener> copyServListener;//= do_QueryInterface(this);
|
||||
rv = this->QueryInterface(NS_GET_IID(nsIMsgCopyServiceListener), getter_AddRefs(copyServListener));
|
||||
|
||||
// add error checking.
|
||||
nsCOMPtr <nsISupports> curSupports = getter_AddRefs(m_folders->ElementAt(indices[0]));
|
||||
nsCOMPtr<nsIMsgFolder> curFolder;
|
||||
if(curSupports)
|
||||
{
|
||||
curFolder = do_QueryInterface(curSupports);
|
||||
}
|
||||
|
||||
nsCOMPtr <nsIMsgDatabase> dbToUse;
|
||||
if (curFolder)
|
||||
{
|
||||
nsCOMPtr <nsIDBFolderInfo> folderInfo;
|
||||
rv = curFolder->GetDBFolderInfoAndDB(getter_AddRefs(folderInfo), getter_AddRefs(dbToUse));
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
dbToUse->AddListener(this);
|
||||
|
||||
nsCOMPtr <nsISupports> tmpSupports = do_QueryInterface(dbToUse);
|
||||
m_dbToUseList->AppendElement(tmpSupports);
|
||||
}
|
||||
|
||||
// error checking again.
|
||||
PRBool myFlag = PR_FALSE;
|
||||
|
||||
for (nsMsgViewIndex index = 0; index < (nsMsgViewIndex) numIndices; index++)
|
||||
{
|
||||
nsCOMPtr <nsISupports> supports = getter_AddRefs(m_folders->ElementAt(indices[index]));
|
||||
if(supports)
|
||||
{
|
||||
nsCOMPtr<nsIMsgFolder> currentFolder = do_QueryInterface(supports);
|
||||
if (currentFolder)
|
||||
{
|
||||
nsXPIDLCString curUri;
|
||||
nsXPIDLCString currentFolderUri;
|
||||
|
||||
curFolder->GetURI(getter_Copies(curUri));
|
||||
currentFolder->GetURI(getter_Copies(currentFolderUri));
|
||||
|
||||
if (nsCRT::strcmp(curUri, currentFolderUri) == 0)
|
||||
{
|
||||
nsMsgKey key = m_keys.GetAt(indices[index]);
|
||||
nsCOMPtr <nsIMsgDBHdr> msgHdr;
|
||||
rv = dbToUse->GetMsgHdrForKey(key, getter_AddRefs(msgHdr));
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
if (msgHdr)
|
||||
messageArray->AppendElement(msgHdr);
|
||||
|
||||
if ((nsMsgViewIndex)index < (nsMsgViewIndex) (numIndices-1))
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
mCurIndex = index;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// called for delete with trash, copy and move
|
||||
if (mCommand == nsMsgViewCommandType::deleteMsg)
|
||||
curFolder->DeleteMessages(messageArray, window, PR_FALSE /* delete storage */, PR_FALSE /* is move*/, copyServListener);
|
||||
else if (mCommand == nsMsgViewCommandType::moveMessages)
|
||||
mDestFolder->CopyMessages(curFolder, messageArray, PR_TRUE /* isMove */, window, copyServListener, PR_FALSE /* is folder */);
|
||||
else if (mCommand == nsMsgViewCommandType::copyMessages)
|
||||
mDestFolder->CopyMessages(curFolder, messageArray, PR_FALSE /* isMove */, window, copyServListener, PR_FALSE /* is folder */);
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult nsMsgSearchDBView::ProcessContinuousRequest(nsIMsgWindow *window, nsMsgViewIndex *indices, PRInt32 numIndices)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
nsCOMPtr<nsISupportsArray> messageArray;
|
||||
NS_NewISupportsArray(getter_AddRefs(messageArray));
|
||||
|
||||
nsCOMPtr<nsIMsgCopyServiceListener> copyServListener;//= do_QueryInterface(this);
|
||||
rv = this->QueryInterface(NS_GET_IID(nsIMsgCopyServiceListener), getter_AddRefs(copyServListener));
|
||||
|
||||
// add error checking.
|
||||
nsCOMPtr <nsISupports> curSupports = getter_AddRefs(m_folders->ElementAt(indices[0]));
|
||||
nsCOMPtr<nsIMsgFolder> curFolder;
|
||||
if(curSupports)
|
||||
{
|
||||
curFolder = do_QueryInterface(curSupports);
|
||||
}
|
||||
|
||||
nsCOMPtr <nsIMsgDatabase> dbToUse;
|
||||
if (curFolder)
|
||||
{
|
||||
nsCOMPtr <nsIDBFolderInfo> folderInfo;
|
||||
rv = curFolder->GetDBFolderInfoAndDB(getter_AddRefs(folderInfo), getter_AddRefs(dbToUse));
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
dbToUse->AddListener(this);
|
||||
|
||||
nsCOMPtr <nsISupports> tmpSupports = do_QueryInterface(dbToUse);
|
||||
m_dbToUseList->AppendElement(tmpSupports);
|
||||
}
|
||||
|
||||
// error checking again.
|
||||
PRBool myFlag = PR_FALSE;
|
||||
|
||||
for (nsMsgViewIndex index = 0; index < (nsMsgViewIndex) numIndices; index++)
|
||||
{
|
||||
nsCOMPtr <nsISupports> supports = getter_AddRefs(m_folders->ElementAt(indices[index]));
|
||||
if(supports)
|
||||
{
|
||||
nsCOMPtr<nsIMsgFolder> currentFolder = do_QueryInterface(supports);
|
||||
if (currentFolder)
|
||||
{
|
||||
nsXPIDLCString curUri;
|
||||
nsXPIDLCString currentFolderUri;
|
||||
|
||||
curFolder->GetURI(getter_Copies(curUri));
|
||||
currentFolder->GetURI(getter_Copies(currentFolderUri));
|
||||
|
||||
if (nsCRT::strcmp(curUri, currentFolderUri) == 0)
|
||||
{
|
||||
nsMsgKey key = m_keys.GetAt(indices[index]);
|
||||
nsCOMPtr <nsIMsgDBHdr> msgHdr;
|
||||
rv = dbToUse->GetMsgHdrForKey(key, getter_AddRefs(msgHdr));
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
if (msgHdr)
|
||||
messageArray->AppendElement(msgHdr);
|
||||
|
||||
if ((nsMsgViewIndex)index < (nsMsgViewIndex) (numIndices-1))
|
||||
continue;
|
||||
}
|
||||
else
|
||||
myFlag = PR_TRUE;
|
||||
|
||||
|
||||
if (mCommand == nsMsgViewCommandType::deleteMsg)
|
||||
curFolder->DeleteMessages(messageArray, window, PR_TRUE /* delete storage */, PR_FALSE /* is move*/, copyServListener);
|
||||
else if (mCommand == nsMsgViewCommandType::moveMessages)
|
||||
mDestFolder->CopyMessages(curFolder, messageArray, PR_FALSE /* isMove */, window, copyServListener, PR_FALSE /* is folder */);
|
||||
|
||||
// clean messages array
|
||||
// add element
|
||||
// define new curfolder
|
||||
if (myFlag)
|
||||
{
|
||||
curFolder = currentFolder;
|
||||
|
||||
messageArray->Clear();
|
||||
|
||||
nsCOMPtr <nsIDBFolderInfo> folderInfo;
|
||||
rv = curFolder->GetDBFolderInfoAndDB(getter_AddRefs(folderInfo), getter_AddRefs(dbToUse));
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
dbToUse->AddListener(this);
|
||||
|
||||
nsCOMPtr <nsISupports> tmpSupports = do_QueryInterface(dbToUse);
|
||||
m_dbToUseList->AppendElement(tmpSupports);
|
||||
|
||||
nsMsgKey key = m_keys.GetAt(indices[index]);
|
||||
nsCOMPtr <nsIMsgDBHdr> msgHdr;
|
||||
rv = dbToUse->GetMsgHdrForKey(key, getter_AddRefs(msgHdr));
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
if (msgHdr)
|
||||
messageArray->AppendElement(msgHdr);
|
||||
|
||||
if ((nsMsgViewIndex)index == (nsMsgViewIndex) (numIndices-1))
|
||||
{
|
||||
// called only for shift delete
|
||||
curFolder->DeleteMessages(messageArray, window, PR_TRUE /* delete storage */, PR_FALSE /* is move*/, copyServListener);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -25,27 +25,49 @@
|
|||
|
||||
#include "nsMsgDBView.h"
|
||||
#include "nsIMsgSearchNotify.h"
|
||||
#include "nsIMsgCopyServiceListener.h"
|
||||
|
||||
class nsMsgSearchDBView : public nsMsgDBView, public nsIMsgSearchNotify
|
||||
class nsMsgSearchDBView : public nsMsgDBView, public nsIMsgSearchNotify, public nsIMsgCopyServiceListener
|
||||
{
|
||||
public:
|
||||
nsMsgSearchDBView();
|
||||
virtual ~nsMsgSearchDBView();
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSIMSGSEARCHNOTIFY
|
||||
NS_DECL_NSIMSGSEARCHNOTIFY
|
||||
NS_DECL_NSIMSGCOPYSERVICELISTENER
|
||||
|
||||
virtual const char * GetViewName(void) {return "SearchView"; }
|
||||
NS_IMETHOD Open(nsIMsgFolder *folder, nsMsgViewSortTypeValue sortType, nsMsgViewSortOrderValue sortOrder,
|
||||
nsMsgViewFlagsTypeValue viewFlags, PRInt32 *pCount);
|
||||
NS_IMETHOD Close();
|
||||
NS_IMETHOD DoCommand(nsMsgViewCommandTypeValue command);
|
||||
NS_IMETHOD DoCommandWithFolder(nsMsgViewCommandTypeValue command, nsIMsgFolder *destFolder);
|
||||
// override to get location
|
||||
NS_IMETHOD GetCellText(PRInt32 aRow, const PRUnichar * aColID, PRUnichar ** aValue);
|
||||
virtual nsresult GetMsgHdrForViewIndex(nsMsgViewIndex index, nsIMsgDBHdr **msgHdr);
|
||||
NS_IMETHOD GetFolderForViewIndex(nsMsgViewIndex index, nsIMsgFolder **folder);
|
||||
virtual nsresult GetFolders(nsISupportsArray **aFolders);
|
||||
protected:
|
||||
nsresult FetchLocation(nsIMsgDBHdr * aHdr, PRUnichar ** aSizeString);
|
||||
virtual nsresult GetDBForViewIndex(nsMsgViewIndex index, nsIMsgDatabase **db);
|
||||
|
||||
virtual nsresult RemoveByIndex(nsMsgViewIndex index);
|
||||
virtual nsresult CopyMessages(nsIMsgWindow *window, nsMsgViewIndex *indices, PRInt32 numIndices, PRBool isMove, nsIMsgFolder *destFolder);
|
||||
virtual nsresult DeleteMessages(nsIMsgWindow *window, nsMsgViewIndex *indices, PRInt32 numIndices, PRBool deleteStorage);
|
||||
nsresult InitializeGlobalsForDeleteAndFile(nsMsgViewIndex *indices, PRInt32 numIndices);
|
||||
|
||||
nsCOMPtr <nsISupportsArray> m_folders; // maybe we should store ranges, or the actual headers instead.
|
||||
nsCOMPtr <nsISupportsArray> m_copyListenerList;
|
||||
PRInt32 mCurIndex;
|
||||
|
||||
nsMsgViewIndex* mIndicesForChainedDeleteAndFile;
|
||||
nsUInt32Array* mTestIndices;
|
||||
PRInt32 mTotalIndices;
|
||||
nsCOMPtr <nsISupportsArray> m_dbToUseList;
|
||||
nsMsgViewCommandTypeValue mCommand;
|
||||
nsCOMPtr <nsIMsgFolder> mDestFolder;
|
||||
nsresult ProcessChainedRequest(nsIMsgWindow *window, nsMsgViewIndex *indices, PRInt32 numIndices);
|
||||
nsresult ProcessContinuousRequest(nsIMsgWindow *window, nsMsgViewIndex *indices, PRInt32 numIndices);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -735,7 +735,7 @@ nsMsgSendLater::DeleteCurrentMessage()
|
|||
|
||||
nsCOMPtr<nsISupports> msgSupport = do_QueryInterface(mMessage, &res);
|
||||
msgArray->InsertElementAt(msgSupport, 0);
|
||||
res = mMessageFolder->DeleteMessages(msgArray, nsnull, PR_TRUE, PR_FALSE);
|
||||
res = mMessageFolder->DeleteMessages(msgArray, nsnull, PR_TRUE, PR_FALSE, nsnull);
|
||||
if (NS_FAILED(res))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
|
|
|
@ -1760,7 +1760,8 @@ nsresult nsImapMailFolder::MarkMessagesImapDeleted(nsMsgKeyArray *keyArray, PRBo
|
|||
|
||||
NS_IMETHODIMP nsImapMailFolder::DeleteMessages(nsISupportsArray *messages,
|
||||
nsIMsgWindow *msgWindow,
|
||||
PRBool deleteStorage, PRBool isMove)
|
||||
PRBool deleteStorage, PRBool isMove,
|
||||
nsIMsgCopyServiceListener* listener)
|
||||
{
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
// *** jt - assuming delete is move to the trash folder for now
|
||||
|
@ -1860,7 +1861,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,PR_FALSE);
|
||||
rv = trashFolder->CopyMessages(srcFolder, messages, PR_TRUE, msgWindow, listener,PR_FALSE);
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
|
@ -3845,6 +3846,8 @@ nsImapMailFolder::OnStopRunningUrl(nsIURI *aUrl, nsresult aExitCode)
|
|||
rv = mailUrl->UnRegisterListener(this);
|
||||
}
|
||||
SetGettingNewMessages(PR_FALSE); // if we're not running a url, we must not be getting new mail :-)
|
||||
if (mCopyListener)
|
||||
mCopyListener->OnStopCopy(aExitCode);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -4348,7 +4351,7 @@ nsImapMailFolder::CopyNextStreamMessage(nsIImapProtocol* aProtocol,
|
|||
if (NS_SUCCEEDED(rv) && srcFolder)
|
||||
{
|
||||
srcFolder->DeleteMessages(mailCopyState->m_messages, nsnull,
|
||||
PR_TRUE, PR_TRUE);
|
||||
PR_TRUE, PR_TRUE, nsnull);
|
||||
nsCOMPtr<nsIMsgLocalMailFolder> popFolder = do_QueryInterface(srcFolder);
|
||||
if (popFolder) //needed if move pop->imap to notify FE
|
||||
srcFolder->NotifyFolderEvent(mDeleteOrMoveMsgCompletedAtom);
|
||||
|
@ -4838,6 +4841,8 @@ nsImapMailFolder::CopyMessages(nsIMsgFolder* srcFolder,
|
|||
nsCOMPtr<nsISupports> srcSupport;
|
||||
nsCOMPtr<nsISupports> copySupport;
|
||||
|
||||
mCopyListener = listener;
|
||||
|
||||
if (msgWindow)
|
||||
{
|
||||
nsCOMPtr <nsITransactionManager> txnMgr;
|
||||
|
|
|
@ -164,7 +164,8 @@ public:
|
|||
nsIMsgDatabase **db);
|
||||
NS_IMETHOD DeleteMessages(nsISupportsArray *messages,
|
||||
nsIMsgWindow *msgWindow, PRBool
|
||||
deleteStorage, PRBool isMove);
|
||||
deleteStorage, PRBool isMove,
|
||||
nsIMsgCopyServiceListener* listener);
|
||||
NS_IMETHOD CopyMessages(nsIMsgFolder *srcFolder,
|
||||
nsISupportsArray* messages,
|
||||
PRBool isMove, nsIMsgWindow *msgWindow,
|
||||
|
@ -371,6 +372,7 @@ protected:
|
|||
PRBool m_folderNeedsACLListed;
|
||||
|
||||
nsCOMPtr<nsIMsgMailNewsUrl> mUrlToRelease;
|
||||
nsCOMPtr<nsIMsgCopyServiceListener> mCopyListener;
|
||||
|
||||
// offline imap support
|
||||
PRBool m_downloadMessageForOfflineUse;
|
||||
|
|
|
@ -1484,7 +1484,8 @@ nsMsgLocalMailFolder::GetTrashFolder(nsIMsgFolder** result)
|
|||
NS_IMETHODIMP
|
||||
nsMsgLocalMailFolder::DeleteMessages(nsISupportsArray *messages,
|
||||
nsIMsgWindow *msgWindow,
|
||||
PRBool deleteStorage, PRBool isMove)
|
||||
PRBool deleteStorage, PRBool isMove,
|
||||
nsIMsgCopyServiceListener* listener)
|
||||
{
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
PRBool isTrashFolder = mFlags & MSG_FOLDER_FLAG_TRASH;
|
||||
|
@ -1499,7 +1500,7 @@ nsMsgLocalMailFolder::DeleteMessages(nsISupportsArray *messages,
|
|||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
return copyService->CopyMessages(this, messages, trashFolder,
|
||||
PR_TRUE, nsnull, msgWindow);
|
||||
PR_TRUE, listener, msgWindow);
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
|
@ -2401,7 +2402,7 @@ NS_IMETHODIMP nsMsgLocalMailFolder::EndMove()
|
|||
if(srcFolder)
|
||||
{
|
||||
// lets delete these all at once - much faster that way
|
||||
result = srcFolder->DeleteMessages(mCopyState->m_messages, nsnull, PR_TRUE, PR_TRUE);
|
||||
result = srcFolder->DeleteMessages(mCopyState->m_messages, nsnull, PR_TRUE, PR_TRUE, nsnull);
|
||||
srcFolder->EnableNotifications(allMessageCountNotifications, PR_TRUE);
|
||||
srcFolder->NotifyFolderEvent(mDeleteOrMoveMsgCompletedAtom);
|
||||
}
|
||||
|
|
|
@ -132,7 +132,8 @@ public:
|
|||
|
||||
NS_IMETHOD DeleteMessages(nsISupportsArray *messages,
|
||||
nsIMsgWindow *msgWindow, PRBool
|
||||
deleteStorage, PRBool isMove);
|
||||
deleteStorage, PRBool isMove,
|
||||
nsIMsgCopyServiceListener* listener);
|
||||
NS_IMETHOD CopyMessages(nsIMsgFolder *srcFolder, nsISupportsArray* messages,
|
||||
PRBool isMove, nsIMsgWindow *msgWindow,
|
||||
nsIMsgCopyServiceListener* listener, PRBool isFolder );
|
||||
|
|
|
@ -932,7 +932,8 @@ NS_IMETHODIMP nsMsgNewsFolder::GetSizeOnDisk(PRUint32 *size)
|
|||
/* this is news, so remember that DeleteMessage is really CANCEL */
|
||||
NS_IMETHODIMP
|
||||
nsMsgNewsFolder::DeleteMessages(nsISupportsArray *messages, nsIMsgWindow *aMsgWindow,
|
||||
PRBool deleteStorage, PRBool isMove)
|
||||
PRBool deleteStorage, PRBool isMove,
|
||||
nsIMsgCopyServiceListener* listener)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
|
|
|
@ -84,7 +84,8 @@ public:
|
|||
NS_IMETHOD GetDBFolderInfoAndDB(nsIDBFolderInfo **folderInfo, nsIMsgDatabase **db);
|
||||
|
||||
NS_IMETHOD DeleteMessages(nsISupportsArray *messages,
|
||||
nsIMsgWindow *msgWindow, PRBool deleteStorage, PRBool isMove);
|
||||
nsIMsgWindow *msgWindow, PRBool deleteStorage, PRBool isMove,
|
||||
nsIMsgCopyServiceListener* listener);
|
||||
NS_IMETHOD GetNewMessages(nsIMsgWindow *aWindow);
|
||||
|
||||
NS_IMETHOD GetCanSubscribe(PRBool *aResult);
|
||||
|
|
Загрузка…
Ссылка в новой задаче