зеркало из https://github.com/mozilla/pjs.git
Fix for 24768. r=alecf. Move view navigation code to C++ to speed up.
This commit is contained in:
Родитель
5b1dc5a3b2
Коммит
4170fc4b92
|
@ -275,4 +275,14 @@
|
|||
{ 0xbb460dff, 0x8bf0, 0x11d3, \
|
||||
{ 0x8a, 0xfe, 0x0, 0x60, 0xb0, 0xfc, 0x4, 0xd2}}
|
||||
|
||||
//
|
||||
//nsMsgViewNavigationService
|
||||
//
|
||||
#define NS_MSGVIEWNAVIGATIONSERVICE_PROGID \
|
||||
"component://netscape/messenger/msgviewnavigationservice"
|
||||
|
||||
/* 60D34FB4-D031-11d3-8B2E-0060B0FC04D2*/
|
||||
#define NS_MSGVIEWNAVIGATIONSERVICE_CID \
|
||||
{ 0x60d34fb4, 0xd031, 0x11d3, \
|
||||
{ 0x8b, 0x2e, 0x0, 0x60, 0xb0, 0xfc, 0x4, 0xd2}}
|
||||
#endif // nsMessageBaseCID_h__
|
||||
|
|
|
@ -70,6 +70,7 @@
|
|||
#include "nsMsgFilterService.h"
|
||||
#include "nsMessageView.h"
|
||||
#include "nsMsgWindow.h"
|
||||
#include "nsMsgViewNavigationService.h"
|
||||
|
||||
static NS_DEFINE_CID(kComponentManagerCID, NS_COMPONENTMANAGER_CID);
|
||||
|
||||
|
@ -123,6 +124,9 @@ static NS_DEFINE_CID(kMessageViewCID, NS_MESSAGEVIEW_CID);
|
|||
//MsgWindow
|
||||
static NS_DEFINE_CID(kMsgWindowCID, NS_MSGWINDOW_CID);
|
||||
|
||||
//MsgViewNavigationService
|
||||
static NS_DEFINE_CID(kMsgViewNavigationServiceCID, NS_MSGVIEWNAVIGATIONSERVICE_CID);
|
||||
|
||||
// private factory declarations for each component we know how to produce
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsMessengerBootstrap)
|
||||
|
@ -145,6 +149,7 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsMsgFolderCache)
|
|||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsMsgStatusFeedback)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsMessageView,Init)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsMsgWindow,Init)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsMsgViewNavigationService,Init)
|
||||
|
||||
// Module implementation for the sample library
|
||||
class nsMsgBaseModule : public nsIModule
|
||||
|
@ -184,6 +189,7 @@ protected:
|
|||
nsCOMPtr<nsIGenericFactory> mMsgStatusFeedbackFactory;
|
||||
nsCOMPtr<nsIGenericFactory> mMessageViewFactory;
|
||||
nsCOMPtr<nsIGenericFactory> mMsgWindowFactory;
|
||||
nsCOMPtr<nsIGenericFactory> mMsgViewNavigationServiceFactory;
|
||||
};
|
||||
|
||||
nsMsgBaseModule::nsMsgBaseModule()
|
||||
|
@ -233,6 +239,7 @@ void nsMsgBaseModule::Shutdown()
|
|||
mMsgStatusFeedbackFactory = null_nsCOMPtr();
|
||||
mMessageViewFactory = null_nsCOMPtr();
|
||||
mMsgWindowFactory = null_nsCOMPtr();
|
||||
mMsgViewNavigationServiceFactory = null_nsCOMPtr();
|
||||
}
|
||||
|
||||
// Create a factory object for creating instances of aClass.
|
||||
|
@ -381,6 +388,12 @@ NS_IMETHODIMP nsMsgBaseModule::GetClassObject(nsIComponentManager *aCompMgr,
|
|||
rv = NS_NewGenericFactory(getter_AddRefs(mMsgWindowFactory), &nsMsgWindowConstructor);
|
||||
fact = mMsgWindowFactory;
|
||||
}
|
||||
else if (aClass.Equals(kMsgViewNavigationServiceCID))
|
||||
{
|
||||
if (!mMsgViewNavigationServiceFactory)
|
||||
rv = NS_NewGenericFactory(getter_AddRefs(mMsgViewNavigationServiceFactory), &nsMsgViewNavigationServiceConstructor);
|
||||
fact = mMsgViewNavigationServiceFactory;
|
||||
}
|
||||
|
||||
|
||||
if (fact)
|
||||
|
@ -436,7 +449,9 @@ static Components gComponents[] = {
|
|||
{ "Mail/News MessageView", &kMessageViewCID,
|
||||
NS_MESSAGEVIEW_PROGID},
|
||||
{ "Mail/News MsgWindow", &kMsgWindowCID,
|
||||
NS_MSGWINDOW_PROGID}
|
||||
NS_MSGWINDOW_PROGID},
|
||||
{ "Mail/News Message Navigation Service", &kMsgViewNavigationServiceCID,
|
||||
NS_MSGVIEWNAVIGATIONSERVICE_PROGID}
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -36,3 +36,5 @@ nsIMsgProtocolInfo.idl
|
|||
nsIMsgRDFDataSource.idl
|
||||
nsIIncomingServerListener.idl
|
||||
nsIMsgHdr.idl
|
||||
nsIMsgViewNavigationService.idl
|
||||
|
||||
|
|
|
@ -72,6 +72,7 @@ XPIDLSRCS = \
|
|||
nsIIncomingServerListener.idl \
|
||||
nsIMsgHdr.idl \
|
||||
nsIMessengerMigrator.idl \
|
||||
nsIMsgViewNavigationService.idl \
|
||||
$(NULL)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
|
|
@ -57,6 +57,7 @@ XPIDLSRCS = \
|
|||
.\nsIMsgRDFDataSource.idl \
|
||||
.\nsIIncomingServerListener.idl \
|
||||
.\nsIMsgHdr.idl \
|
||||
.\nsIMsgViewNavigationService.idl \
|
||||
$(NULL)
|
||||
|
||||
################################################################################
|
||||
|
|
|
@ -164,8 +164,27 @@ interface nsIMsgFolder : nsIFolder {
|
|||
*/
|
||||
long getTotalMessages(in boolean deep);
|
||||
|
||||
/**
|
||||
* does this folder have new messages
|
||||
*
|
||||
*/
|
||||
boolean hasNewMessages();
|
||||
|
||||
/**
|
||||
* return the first new message in the folder
|
||||
*
|
||||
*/
|
||||
readonly attribute nsIMessage firstNewMessage;
|
||||
|
||||
/**
|
||||
* clear new status flag of all of the new messages
|
||||
*
|
||||
*/
|
||||
void clearNewMessages();
|
||||
|
||||
readonly attribute unsigned long expungedBytesCount;
|
||||
|
||||
|
||||
/**
|
||||
* can this folder be deleted?
|
||||
* for example, special folders cannot be deleted
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 2000 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
#include "nsISupports.idl"
|
||||
#include "xulstubs.idl"
|
||||
#include "domstubs.idl"
|
||||
#include "nsIRDFService.idl"
|
||||
|
||||
%{C++
|
||||
#include "nsIDOMXULTreeElement.h"
|
||||
#include "nsIDOMXULElement.h"
|
||||
#include "nsIDOMXULDocument.h"
|
||||
#include "nsIDOMNode.h"
|
||||
%}
|
||||
|
||||
[scriptable, uuid(BDD872B6-D02C-11d3-8B2E-0060B0FC04D2)]
|
||||
interface nsIMsgViewNavigationService : nsISupports {
|
||||
%{C++
|
||||
enum { eNavigateAny =0, eNavigateUnread=1, eNavigateFlagged =2 , eNavigateNew =3};
|
||||
%}
|
||||
|
||||
nsIDOMXULElement FindNextMessage(in long type, in nsIDOMXULTreeElement tree, in nsIDOMXULElement originalMessage,
|
||||
in nsIRDFService rdfService, in nsIDOMXULDocument document,
|
||||
in boolean wrapAround, in boolean isThreaded);
|
||||
|
||||
nsIDOMXULElement FindFirstMessage(in nsIDOMXULTreeElement tree);
|
||||
|
||||
nsIDOMXULElement FindNextThread(in long type, in nsIDOMXULTreeElement tree, in nsIDOMXULElement originalMessage,
|
||||
in nsIRDFService rdfService, in nsIDOMXULDocument document, in boolean wrapAround,
|
||||
in boolean checkOriginalMessage);
|
||||
|
||||
nsIDOMXULElement FindNextInThread(in long type, in nsIDOMXULTreeElement tree, in nsIDOMXULElement originalMessage,
|
||||
in nsIRDFService rdfService, in nsIDOMXULDocument document);
|
||||
|
||||
nsIDOMXULElement FindPreviousMessage(in long type, in nsIDOMXULTreeElement tree, in nsIDOMXULElement originalMessage,
|
||||
in nsIRDFService rdfService, in nsIDOMXULDocument document,
|
||||
in boolean wrapAround, in boolean isThreaded);
|
||||
|
||||
void OpenTreeitemAndDescendants(in nsIDOMNode treeitem);
|
||||
};
|
||||
|
|
@ -36,6 +36,9 @@ var prefs = Components.classes['component://netscape/preferences'].getService();
|
|||
prefs = prefs.QueryInterface(Components.interfaces.nsIPref);
|
||||
var showPerformance = prefs.GetBoolPref('mail.showMessengerPerformance');
|
||||
|
||||
var msgNavigationService = Components.classes['component://netscape/messenger/msgviewnavigationservice'].getService();
|
||||
msgNavigationService= msgNavigationService.QueryInterface(Components.interfaces.nsIMsgViewNavigationService);
|
||||
|
||||
var gBeforeFolderLoadTime;
|
||||
|
||||
function OpenURL(url)
|
||||
|
@ -270,11 +273,6 @@ function RerootFolder(uri, newFolder, isThreaded, sortID)
|
|||
folder.setAttribute('ref', uri);
|
||||
|
||||
UpdateStatusMessageCounts(newFolder);
|
||||
|
||||
var afterFolderLoadTime = new Date();
|
||||
var timeToLoad = (afterFolderLoadTime.getTime() - gBeforeFolderLoadTime.getTime())/1000;
|
||||
if(showPerformance)
|
||||
dump("Time to load " + uri + " is " + timeToLoad + " seconds\n");
|
||||
}
|
||||
|
||||
|
||||
|
@ -614,10 +612,10 @@ function GetNextMessageAfterDelete(messages)
|
|||
//search forward
|
||||
while(curMessage)
|
||||
{
|
||||
nextMessage = GetNextMessageUnthreaded(tree, curMessage, GoMessage, false);
|
||||
nextMessage = msgNavigationService.FindNextMessage(navigateAny, tree, curMessage, RDF, document, false, messageView.showThreads);
|
||||
if(nextMessage)
|
||||
{
|
||||
if(!MessageInSelection(nextMessage, messages))
|
||||
if(nextMessage.getAttribute("selected") != "true")
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
@ -633,10 +631,10 @@ function GetNextMessageAfterDelete(messages)
|
|||
//search forward
|
||||
while(curMessage)
|
||||
{
|
||||
nextMessage = GetPreviousMessage(curMessage, GoMessage, false);
|
||||
nextMessage = msgNavigationService.FindPreviousMessage(navigateAny, tree, curMessage, RDF, document, false, messageView.showThreads);
|
||||
if(nextMessage)
|
||||
{
|
||||
if(!MessageInSelection(nextMessage, messages))
|
||||
if(nextMessage.getAttribute("selected") != "true")
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
@ -650,18 +648,6 @@ function GetNextMessageAfterDelete(messages)
|
|||
return nextMessage;
|
||||
}
|
||||
|
||||
function MessageInSelection(message, messages)
|
||||
{
|
||||
var count = messages.length;
|
||||
|
||||
for(var i = 0; i < count; i++)
|
||||
{
|
||||
if(message == messages[i])
|
||||
return true;
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function SelectNextMessage(nextMessage)
|
||||
{
|
||||
|
|
|
@ -137,7 +137,19 @@ var folderListener = {
|
|||
{
|
||||
gCurrentLoadingFolderURI = "";
|
||||
//Now let's select the first new message if there is one
|
||||
var beforeScrollToNew = new Date();
|
||||
ScrollToFirstNewMessage();
|
||||
var afterScrollToNew = new Date();
|
||||
var timeToScroll = (afterScrollToNew.getTime() - beforeScrollToNew.getTime())/1000;
|
||||
|
||||
|
||||
var afterFolderLoadTime = new Date();
|
||||
var timeToLoad = (afterFolderLoadTime.getTime() - gBeforeFolderLoadTime.getTime())/1000;
|
||||
if(showPerformance)
|
||||
{
|
||||
dump("Time to load " + uri + " is " + timeToLoad + " seconds\n");
|
||||
dump("of which scrolling to new is" + timeToScroll + "seconds\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -162,6 +174,7 @@ function OnLoadMessenger()
|
|||
AddToSession();
|
||||
//need to add to session before trying to load start folder otherwise listeners aren't
|
||||
//set up correctly.
|
||||
dump('Before load start folder\n');
|
||||
loadStartFolder();
|
||||
|
||||
// FIX ME - later we will be able to use onload from the overlay
|
||||
|
@ -281,19 +294,22 @@ function loadStartFolder()
|
|||
|
||||
//now find Inbox
|
||||
var outNumFolders = new Object();
|
||||
dump('Before getting inbox\n');
|
||||
var inboxFolder = rootMsgFolder.getFoldersWithFlag(0x1000, 1, outNumFolders);
|
||||
if(!inboxFolder) return;
|
||||
dump('We have an inbox\n');
|
||||
|
||||
var resource = inboxFolder.QueryInterface(Components.interfaces.nsIRDFResource);
|
||||
var inboxURI = resource.Value;
|
||||
|
||||
dump('InboxURI = ' + inboxURI + '\n');
|
||||
//first, let's see if it's already in the dom. This will make life easier.
|
||||
var inbox = document.getElementById(inboxURI);
|
||||
|
||||
//if it's not here we will have to make sure it's open.
|
||||
if(!inbox)
|
||||
{
|
||||
|
||||
dump('There isnt an inbox in the tree yet\n');
|
||||
|
||||
}
|
||||
|
||||
|
@ -554,59 +570,13 @@ function ThreadPaneOnClick(event)
|
|||
if(open == "true")
|
||||
{
|
||||
//open all of the children of the treeitem
|
||||
OpenThread(treeitem);
|
||||
msgNavigationService.OpenTreeitemAndDescendants(treeitem);
|
||||
}
|
||||
dump('clicked on a twisty\n');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function OpenThread(treeitem)
|
||||
{
|
||||
treeitem.setAttribute('notreadytodisplay', 'true');
|
||||
OpenTreeItemAndDescendants(treeitem);
|
||||
treeitem.setAttribute('notreadytodisplay', 'false');
|
||||
}
|
||||
|
||||
function OpenTreeItemAndDescendants(treeitem)
|
||||
{
|
||||
var open = treeitem.getAttribute('open');
|
||||
if(open != "true")
|
||||
{
|
||||
treeitem.setAttribute('open', 'true');
|
||||
}
|
||||
|
||||
var treeitemChildNodes = treeitem.childNodes;
|
||||
var numTreeitemChildren = treeitemChildNodes.length;
|
||||
|
||||
//if there's only one child then there are no treechildren so close it.
|
||||
if(numTreeitemChildren == 1)
|
||||
treeitem.setAttribute('open', '');
|
||||
else
|
||||
{
|
||||
for(var i = 0; i < numTreeitemChildren; i++)
|
||||
{
|
||||
var treeitemChild = treeitemChildNodes[i];
|
||||
if(treeitemChild.nodeName == 'treechildren')
|
||||
{
|
||||
var treechildrenChildNodes = treeitemChildNodes[i].childNodes;
|
||||
var numTreechildrenChildren = treechildrenChildNodes.length;
|
||||
|
||||
for(var j = 0; j < numTreechildrenChildren; j++)
|
||||
{
|
||||
var treechildrenChild = treechildrenChildNodes[j];
|
||||
if(treechildrenChild.nodeName == 'treeitem')
|
||||
{
|
||||
treechildrenChild.setAttribute('open', 'true');
|
||||
//Open up all of this items
|
||||
OpenTreeItemAndDescendants(treechildrenChild);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function ChangeSelection(tree, newSelection)
|
||||
{
|
||||
|
|
|
@ -20,76 +20,12 @@
|
|||
|
||||
/* This file contains the js functions necessary to implement view navigation within the 3 pane. */
|
||||
|
||||
function GoMessage(message)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
// These are the types of navigation you can do
|
||||
var navigateAny=0;
|
||||
var navigateUnread = 1;
|
||||
var navigateFlagged = 2;
|
||||
var navigateNew = 3;
|
||||
|
||||
function ResourceGoMessage(message)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
function GoUnreadMessage(message)
|
||||
{
|
||||
var isUnread = message.getAttribute('IsUnread');
|
||||
return(isUnread == 'true');
|
||||
}
|
||||
|
||||
function ResourceGoUnreadMessage(message)
|
||||
{
|
||||
var isUnreadValue = GetMessageValue(message, "http://home.netscape.com/NC-rdf#IsUnread");
|
||||
return(isUnreadValue == 'true');
|
||||
}
|
||||
|
||||
function GoFlaggedMessage(message)
|
||||
{
|
||||
var flagged = message.getAttribute('Flagged');
|
||||
return(flagged == 'flagged');
|
||||
}
|
||||
|
||||
function ResourceGoFlaggedMessage(message)
|
||||
{
|
||||
var flaggedValue = GetMessageValue(message, "http://home.netscape.com/NC-rdf#Flagged");
|
||||
return(flaggedValue == 'flagged');
|
||||
}
|
||||
|
||||
function GoNewMessage(message)
|
||||
{
|
||||
var status = message.getAttribute('Status');
|
||||
return(status == 'new');
|
||||
}
|
||||
|
||||
function ResourceGoNewMessage(message)
|
||||
{
|
||||
var StatusValue = GetMessageValue(message, "http://home.netscape.com/NC-rdf#Status");
|
||||
return(StatusValue == 'new');
|
||||
}
|
||||
|
||||
function GetMessageValue(message, propertyURI)
|
||||
{
|
||||
var db = GetThreadTree().database;
|
||||
var propertyResource = RDF.GetResource(propertyURI);
|
||||
var node = db.GetTarget(message, propertyResource, true);
|
||||
var literal = node.QueryInterface(Components.interfaces.nsIRDFLiteral);
|
||||
if(literal)
|
||||
{
|
||||
return literal.Value;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function GoUnreadThread(messageElement)
|
||||
{
|
||||
var messageuri = messageElement.getAttribute('id');
|
||||
var messageResource = RDF.GetResource(messageuri);
|
||||
|
||||
var message = messageResource.QueryInterface(Components.interfaces.nsIMessage);
|
||||
var folder = message.GetMsgFolder();
|
||||
var thread = folder.getThreadForMessage(message);
|
||||
|
||||
return(thread.numUnreadChildren != 0);
|
||||
}
|
||||
|
||||
/*GoNextMessage finds the message that matches criteria and selects it.
|
||||
nextFunction is the function that will be used to detertime if a message matches criteria.
|
||||
|
@ -101,8 +37,10 @@ function GoUnreadThread(messageElement)
|
|||
startFromBeginning is a boolean that states whether or not we should start looking at the beginning
|
||||
if we reach the end
|
||||
*/
|
||||
function GoNextMessage(nextFunction, nextResourceFunction, nextThreadFunction, startFromBeginning)
|
||||
function GoNextMessage(type, startFromBeginning )
|
||||
{
|
||||
var beforeGoNextMessage = new Date();
|
||||
|
||||
var tree = GetThreadTree();
|
||||
|
||||
var selArray = tree.selectedItems;
|
||||
|
@ -117,251 +55,18 @@ function GoNextMessage(nextFunction, nextResourceFunction, nextThreadFunction, s
|
|||
else
|
||||
currentMessage = selArray[0];
|
||||
|
||||
var nextMessage = GetNextMessage(tree, currentMessage, nextFunction, nextResourceFunction, nextThreadFunction, startFromBeginning);
|
||||
|
||||
var nextMessage = msgNavigationService.FindNextMessage(type, tree, currentMessage, RDF, document, startFromBeginning, messageView.showThreads);
|
||||
//Only change the selection if there's a valid nextMessage
|
||||
if(nextMessage && (nextMessage != currentMessage))
|
||||
ChangeSelection(tree, nextMessage);
|
||||
}
|
||||
}
|
||||
|
||||
function GetNextMessage(tree, currentMessage, nextFunction, nextResourceFunction, nextThreadFunction, startFromBeginning)
|
||||
{
|
||||
var nextMessage;
|
||||
|
||||
if(messageView.showThreads)
|
||||
{
|
||||
nextMessage = GetNextMessageInThreads(tree, currentMessage, nextFunction, nextResourceFunction, nextThreadFunction, startFromBeginning);
|
||||
}
|
||||
else
|
||||
{
|
||||
nextMessage = GetNextMessageUnthreaded(tree, currentMessage, nextFunction, startFromBeginning);
|
||||
}
|
||||
|
||||
return nextMessage;
|
||||
}
|
||||
|
||||
/*GetNextMessageUnthreaded does the iterating for the Next menu item.
|
||||
currentMessage is the message we are starting from.
|
||||
nextFunction is the function that will be used to detertime if a message matches criteria.
|
||||
It must take a node and return a boolean.
|
||||
startFromBeginning is a boolean that states whether or not we should start looking at the beginning
|
||||
if we reach then end
|
||||
*/
|
||||
function GetNextMessageUnthreaded(tree, currentMessage, nextFunction, startFromBeginning)
|
||||
{
|
||||
var foundMessage = false;
|
||||
|
||||
var nextMessage;
|
||||
|
||||
if(currentMessage)
|
||||
nextMessage = currentMessage.nextSibling;
|
||||
else
|
||||
nextMessage = FindFirstMessage(tree);
|
||||
|
||||
//In case we are currently the bottom message
|
||||
if(!nextMessage && startFromBeginning)
|
||||
{
|
||||
dump('no next message\n');
|
||||
var parent = currentMessage.parentNode;
|
||||
nextMessage = parent.firstChild;
|
||||
}
|
||||
|
||||
|
||||
while(nextMessage && (nextMessage != currentMessage))
|
||||
{
|
||||
if(nextFunction(nextMessage))
|
||||
break;
|
||||
nextMessage = nextMessage.nextSibling;
|
||||
/*If there's no nextMessage we may have to start from top.*/
|
||||
if(!nextMessage && (nextMessage!= currentMessage) && startFromBeginning)
|
||||
{
|
||||
dump('We need to start from the top\n');
|
||||
var parent = currentMessage.parentNode;
|
||||
nextMessage = parent.firstChild;
|
||||
}
|
||||
}
|
||||
|
||||
if(nextMessage)
|
||||
{
|
||||
var id = nextMessage.getAttribute('id');
|
||||
dump(id + '\n');
|
||||
}
|
||||
else
|
||||
dump('No next message\n');
|
||||
return nextMessage;
|
||||
}
|
||||
|
||||
function GetNextMessageInThreads(tree, currentMessage, nextFunction, nextResourceFunction, nextThreadFunction, startFromBeginning)
|
||||
{
|
||||
var checkStartMessage = false;
|
||||
|
||||
//In the case where nothing is selected
|
||||
if(currentMessage == null)
|
||||
{
|
||||
currentMessage = FindFirstMessage(tree);
|
||||
checkStartMessage = true;
|
||||
}
|
||||
|
||||
return FindNextMessageInThreads(currentMessage, currentMessage, nextFunction, nextResourceFunction, nextThreadFunction, startFromBeginning, checkStartMessage);
|
||||
}
|
||||
|
||||
function FindNextMessageInThreads(startMessage, originalStartMessage, nextFunction, nextResourceFunction, nextThreadFunction, startFromBeginning, checkStartMessage)
|
||||
{
|
||||
var nextMessage;
|
||||
var nextChildMessage;
|
||||
|
||||
//First check startMessage if we are supposed to
|
||||
if(checkStartMessage)
|
||||
{
|
||||
if(nextFunction(startMessage))
|
||||
return startMessage;
|
||||
}
|
||||
|
||||
//if we're on the top level and a thread function has been passed in, we might be able to search faster.
|
||||
if(startMessage.parentNode.parentNode.nodeName != "treeitem" && nextThreadFunction)
|
||||
{
|
||||
var nextTopMessage = FindNextThread(startMessage, nextThreadFunction, startFromBeginning, true);
|
||||
nextMessage = GetNextInThread(nextTopMessage, nextFunction, nextResourceFunction);
|
||||
if(nextMessage)
|
||||
{
|
||||
return nextMessage;
|
||||
}
|
||||
}
|
||||
|
||||
//Next, search the current messages children.
|
||||
nextChildMessage = FindNextInChildren(startMessage, originalStartMessage, nextFunction, nextResourceFunction);
|
||||
if(nextChildMessage)
|
||||
return nextChildMessage;
|
||||
|
||||
//Next we need to search the current messages siblings
|
||||
nextMessage = startMessage.nextSibling;
|
||||
while(nextMessage)
|
||||
{
|
||||
//In case we've already been here before
|
||||
if(nextMessage == originalStartMessage)
|
||||
return nextMessage;
|
||||
|
||||
if(nextFunction(nextMessage))
|
||||
return nextMessage;
|
||||
|
||||
var nextChildMessage = FindNextInChildren(nextMessage, originalStartMessage, nextFunction, nextResourceFunction);
|
||||
if(nextChildMessage)
|
||||
return nextChildMessage;
|
||||
|
||||
nextMessage = nextMessage.nextSibling;
|
||||
}
|
||||
|
||||
//Finally, we need to find the next of the start message's ancestors that has a sibling
|
||||
var parentMessage = startMessage.parentNode.parentNode;
|
||||
|
||||
while(parentMessage.nodeName == 'treeitem')
|
||||
{
|
||||
if(parentMessage.nextSibling != null)
|
||||
{
|
||||
nextMessage = FindNextMessageInThreads(parentMessage.nextSibling, originalStartMessage, nextFunction, nextResourceFunction, nextThreadFunction, startFromBeginning, true);
|
||||
return nextMessage;
|
||||
}
|
||||
parentMessage = parentMessage.parentNode.parentNode;
|
||||
}
|
||||
//otherwise it's the tree so we need to stop and potentially start from the beginning
|
||||
if(startFromBeginning)
|
||||
{
|
||||
nextMessage = FindNextMessageInThreads(FindFirstMessage(parentMessage), originalStartMessage, nextFunction, nextResourceFunction, nextThreadFunction, false, true);
|
||||
return nextMessage;
|
||||
}
|
||||
return null;
|
||||
var afterGoNextMessage = new Date();
|
||||
var timeToGetNext = (afterGoNextMessage.getTime() - beforeGoNextMessage.getTime())/1000;
|
||||
dump("time to GoNextMessage is " + timeToGetNext + "seconds\n");
|
||||
|
||||
}
|
||||
|
||||
//Searches children messages in thread navigation.
|
||||
function FindNextInChildren(parentMessage, originalStartMessage, nextFunction, nextResourceFunction)
|
||||
{
|
||||
var isParentOpen = parentMessage.getAttribute('open') == 'true';
|
||||
//First we'll deal with the case where the parent is open. In this case we can use DOM calls.
|
||||
if(isParentOpen)
|
||||
{
|
||||
//In this case we have treechildren
|
||||
if(parentMessage.childNodes.length == 2)
|
||||
{
|
||||
var treechildren = parentMessage.childNodes[1];
|
||||
var childMessages = treechildren.childNodes;
|
||||
var numChildMessages = childMessages.length;
|
||||
|
||||
for(var i = 0; i < numChildMessages; i++)
|
||||
{
|
||||
var childMessage = childMessages[i];
|
||||
|
||||
//If we're at the original message again then stop.
|
||||
if(childMessage == originalStartMessage)
|
||||
return childMessage;
|
||||
|
||||
if(nextFunction(childMessage))
|
||||
return childMessage;
|
||||
else
|
||||
{
|
||||
//if this child isn't the message, perhaps one of its children is.
|
||||
var nextChildMessage = FindNextInChildren(childMessage, originalStartMessage, nextFunction);
|
||||
if(nextChildMessage)
|
||||
return nextChildMessage;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//We need to traverse the graph in rdf looking for the next resource that fits what we're searching for.
|
||||
var parentUri = parentMessage.getAttribute('id');
|
||||
var parentResource = RDF.GetResource(parentUri);
|
||||
|
||||
//If we find one, then we get the id and open up the parent and all of it's children. Then we find the element
|
||||
//with the id in the document and return that.
|
||||
if(parentResource)
|
||||
{
|
||||
var nextResource = FindNextInChildrenResources(parentResource, nextResourceFunction);
|
||||
if(nextResource)
|
||||
{
|
||||
OpenThread(parentMessage);
|
||||
var nextUri = nextResource.Value;
|
||||
var nextChildMessage = document.getElementById(nextUri);
|
||||
return nextChildMessage;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function FindNextInChildrenResources(parentResource, nextResourceFunction)
|
||||
{
|
||||
var db = GetThreadTree().database;
|
||||
|
||||
var childrenResource = RDF.GetResource("http://home.netscape.com/NC-rdf#MessageChild");
|
||||
var childrenEnumerator = db.GetTargets(parentResource, childrenResource, true);
|
||||
|
||||
if(childrenEnumerator)
|
||||
{
|
||||
while(childrenEnumerator.HasMoreElements())
|
||||
{
|
||||
var childResource = childrenEnumerator.GetNext().QueryInterface(Components.interfaces.nsIRDFResource);
|
||||
if(childResource)
|
||||
{
|
||||
if(nextResourceFunction(childResource))
|
||||
return childResource;
|
||||
|
||||
var nextMessageResource = FindNextInChildrenResources(childResource, nextResourceFunction);
|
||||
if(nextMessageResource)
|
||||
return nextMessageResource;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/*GoPreviousMessage finds the message that matches criteria and selects it.
|
||||
previousFunction is the function that will be used to detertime if a message matches criteria.
|
||||
|
@ -369,7 +74,7 @@ function FindNextInChildrenResources(parentResource, nextResourceFunction)
|
|||
startFromEnd is a boolean that states whether or not we should start looking at the end
|
||||
if we reach the beginning
|
||||
*/
|
||||
function GoPreviousMessage(previousFunction, startFromEnd)
|
||||
function GoPreviousMessage(type, startFromEnd)
|
||||
{
|
||||
var tree = GetThreadTree();
|
||||
|
||||
|
@ -377,85 +82,21 @@ function GoPreviousMessage(previousFunction, startFromEnd)
|
|||
if ( selArray && (selArray.length == 1) )
|
||||
{
|
||||
var currentMessage = selArray[0];
|
||||
var previousMessage = GetPreviousMessage(currentMessage, previousFunction, startFromEnd);
|
||||
var previousMessage = msgNavigationService.FindPreviousMessage(type, tree, currentMessage, RDF, document, startFromEnd, messageView.showThreads);
|
||||
//Only change selection if there's a valid previous message.
|
||||
if(previousMessage && (previousMessage != currentMessage))
|
||||
ChangeSelection(tree, previousMessage);
|
||||
}
|
||||
}
|
||||
|
||||
/*GetPreviousMessage does the iterating for the Previous menu item.
|
||||
currentMessage is the message we are starting from.
|
||||
previousFunction is the function that will be used to detertime if a message matches criteria.
|
||||
It must take a node and return a boolean.
|
||||
startFromEnd is a boolean that states whether or not we should start looking at the end
|
||||
if we reach then beginning
|
||||
*/
|
||||
function GetPreviousMessage(currentMessage, previousFunction, startFromEnd)
|
||||
{
|
||||
var foundMessage = false;
|
||||
|
||||
|
||||
var previousMessage = currentMessage.previousSibling;
|
||||
|
||||
//In case we're already at the top
|
||||
if(!previousMessage && startFromEnd)
|
||||
{
|
||||
var parent = currentMessage.parentNode;
|
||||
previousMessage = parent.lastChild;
|
||||
}
|
||||
|
||||
while(previousMessage && (previousMessage != currentMessage))
|
||||
{
|
||||
if(previousFunction(previousMessage))
|
||||
break;
|
||||
previousMessage = previousMessage.previousSibling;
|
||||
if(!previousMessage && startFromEnd)
|
||||
{
|
||||
var parent = currentMessage.parentNode;
|
||||
previousMessage = parent.lastChild;
|
||||
}
|
||||
}
|
||||
|
||||
if(previousMessage)
|
||||
{
|
||||
var id = previousMessage.getAttribute('id');
|
||||
dump(id + '\n');
|
||||
}
|
||||
else
|
||||
dump('No previous message\n');
|
||||
return previousMessage;
|
||||
}
|
||||
|
||||
|
||||
function FindFirstMessage(tree)
|
||||
{
|
||||
//getElementsByTagName is too slow which is why I'm using this loop. Just find the first
|
||||
//child of the tree that has the 'treechildren' tag and return it's first child. This will
|
||||
//be the first message.
|
||||
|
||||
var children = tree.childNodes;
|
||||
var numChildren = children.length;
|
||||
|
||||
for(var i = 0; i < numChildren; i++)
|
||||
{
|
||||
if(children[i].nodeName == 'treechildren')
|
||||
{
|
||||
return children[i].firstChild;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
// nextThreadFunction is the function that determines whether a top level message is part of a thread that fits criteria.
|
||||
// nextMessageFunction is the function that would be used to find the next message in a thread if gotoNextInThread is true
|
||||
// nextResourceFunction is the function that would be used to find the next message in a thread as a resource if gotoNextInThread is true
|
||||
// type is the the type of the next thread we are looking for.
|
||||
// startFromBeginning is true if we should start looking from the beginning after we get to the end of the thread pane.
|
||||
// gotoNextInThread is true if once we find an unrad thread we should select the first message in that thread that fits criteria
|
||||
function GoNextThread(nextThreadFunction, nextMessageFunction, nextResourceFunction, startFromBeginning, gotoNextInThread)
|
||||
function GoNextThread(type, startFromBeginning, gotoNextInThread)
|
||||
{
|
||||
|
||||
if(messageView.showThreads)
|
||||
|
@ -491,13 +132,14 @@ function GoNextThread(nextThreadFunction, nextMessageFunction, nextResourceFunct
|
|||
checkCurrentTopMessage = true;
|
||||
}
|
||||
|
||||
var nextTopMessage = FindNextThread(currentTopMessage, nextThreadFunction, startFromBeginning, checkCurrentTopMessage);
|
||||
var nextTopMessage = msgNavigationService.FindNextThread(type, tree, currentTopMessage, RDF, document, startFromBeginning, checkCurrentTopMessage);
|
||||
|
||||
var changeSelection = (nextTopMessage != null && ((currentTopMessage != nextTopMessage) || checkCurrentTopMessage));
|
||||
if(changeSelection)
|
||||
{
|
||||
if(gotoNextInThread)
|
||||
{
|
||||
nextMessage = GetNextInThread(nextTopMessage, nextMessageFunction, nextResourceFunction);
|
||||
nextMessage = msgNavigationService.FindNextInThread(type, tree, nextTopMessage, RDF, document);
|
||||
ChangeSelection(tree, nextMessage);
|
||||
}
|
||||
else
|
||||
|
@ -508,22 +150,6 @@ function GoNextThread(nextThreadFunction, nextMessageFunction, nextResourceFunct
|
|||
|
||||
}
|
||||
|
||||
//Given the top level message of a thread and the searching functions, this returns the first message in that thread that matches
|
||||
//the criteria
|
||||
function GetNextInThread(topMessage, nextMessageFunction, nextResourceFunction)
|
||||
{
|
||||
var nextMessage;
|
||||
|
||||
if(nextMessageFunction(topMessage))
|
||||
nextMessage = topMessage;
|
||||
else
|
||||
{
|
||||
nextMessage = FindNextInChildren(topMessage, null, nextMessageFunction, nextResourceFunction);
|
||||
}
|
||||
|
||||
return nextMessage;
|
||||
}
|
||||
|
||||
function FindTopLevelMessage(startMessage)
|
||||
{
|
||||
var currentTop = startMessage;
|
||||
|
@ -538,54 +164,58 @@ function FindTopLevelMessage(startMessage)
|
|||
return currentTop;
|
||||
}
|
||||
|
||||
function FindNextThread(startThread, nextThreadFunction, startFromBeginning, checkStartThread)
|
||||
{
|
||||
if(checkStartThread)
|
||||
{
|
||||
if(nextThreadFunction(startThread))
|
||||
return startThread;
|
||||
dump("start thread doesn't match\n");
|
||||
}
|
||||
|
||||
var nextThread = startThread.nextSibling;
|
||||
|
||||
//In case we are currently the bottom message
|
||||
if(!nextThread && startFromBeginning)
|
||||
{
|
||||
var parent = startThread.parentNode;
|
||||
nextThread = parent.firstChild;
|
||||
}
|
||||
|
||||
|
||||
while(nextThread && (nextThread != startThread))
|
||||
{
|
||||
if(nextThreadFunction(nextThread))
|
||||
{
|
||||
break;
|
||||
}
|
||||
nextThread = nextThread.nextSibling;
|
||||
/*If there's no nextMessage we may have to start from top.*/
|
||||
if(!nextThread && (nextThread!= startThread) && startFromBeginning)
|
||||
{
|
||||
var parent = startThread.parentNode;
|
||||
nextThread = parent.firstChild;
|
||||
}
|
||||
}
|
||||
|
||||
return nextThread;
|
||||
}
|
||||
|
||||
function ScrollToFirstNewMessage()
|
||||
{
|
||||
var tree = GetThreadTree();
|
||||
var treeFolder = GetThreadTreeFolder();
|
||||
|
||||
var newMessage = GetNextMessage(tree, null, GoNewMessage, ResourceGoNewMessage, null, false)
|
||||
|
||||
if(newMessage)
|
||||
var folderURI = treeFolder.getAttribute('ref');
|
||||
var folderResource = RDF.GetResource(folderURI);
|
||||
var folder = folderResource.QueryInterface(Components.interfaces.nsIMsgFolder);
|
||||
var hasNew = folder.hasNewMessages();
|
||||
if(hasNew)
|
||||
{
|
||||
tree.ensureElementIsVisible(newMessage);
|
||||
var newMessage = folder.firstNewMessage;
|
||||
|
||||
if(messageView.showThreads)
|
||||
{
|
||||
//if we're in thread mode, then we need to actually make sure the message is showing.
|
||||
var topLevelMessage = GetTopLevelMessageForMessage(newMessage, folder);
|
||||
var topLevelResource = topLevelMessage.QueryInterface(Components.interfaces.nsIRDFResource);
|
||||
var topLevelURI = topLevelResource.Value;
|
||||
var topElement = document.getElementById(topLevelURI);
|
||||
if(topElement)
|
||||
{
|
||||
msgNavigationService.OpenTreeitemAndDescendants(topElement);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var messageResource = newMessage.QueryInterface(Components.interfaces.nsIRDFResource);
|
||||
var messageURI = messageResource.Value;
|
||||
var messageElement = document.getElementById(messageURI);
|
||||
|
||||
if(messageElement)
|
||||
{
|
||||
tree.ensureElementIsVisible(messageElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function GetTopLevelMessageForMessage(message, folder)
|
||||
{
|
||||
if(!folder)
|
||||
folder = message.GetMsgFolder();
|
||||
|
||||
var thread = folder.getThreadForMessage(message);
|
||||
var outIndex = new Object();
|
||||
var rootHdr = thread.GetRootHdr(outIndex);
|
||||
|
||||
var topMessage = folder.createMessageFromMsgDBHdr(rootHdr);
|
||||
|
||||
return topMessage;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -958,36 +958,36 @@ function MsgStop() {
|
|||
|
||||
function MsgNextMessage()
|
||||
{
|
||||
GoNextMessage(GoMessage, ResourceGoMessage, null, false);
|
||||
GoNextMessage(navigateAny, false );
|
||||
}
|
||||
|
||||
function MsgNextUnreadMessage()
|
||||
{
|
||||
GoNextMessage(GoUnreadMessage, ResourceGoUnreadMessage, GoUnreadThread, true);
|
||||
GoNextMessage(navigateUnread, true);
|
||||
}
|
||||
function MsgNextFlaggedMessage()
|
||||
{
|
||||
GoNextMessage(GoFlaggedMessage, ResourceGoFlaggedMessage, null, true);
|
||||
GoNextMessage(navigateFlagged, true);
|
||||
}
|
||||
|
||||
function MsgNextUnreadThread()
|
||||
{
|
||||
GoNextThread(GoUnreadThread, GoUnreadMessage, ResourceGoUnreadMessage, true, true);
|
||||
GoNextThread(navigateUnread, true, true);
|
||||
}
|
||||
|
||||
function MsgPreviousMessage()
|
||||
{
|
||||
GoPreviousMessage(GoMessage, false);
|
||||
GoPreviousMessage(navigateAny, false);
|
||||
}
|
||||
|
||||
function MsgPreviousUnreadMessage()
|
||||
{
|
||||
GoPreviousMessage(GoUnreadMessage, true);
|
||||
GoPreviousMessage(navigateUnread, true);
|
||||
}
|
||||
|
||||
function MsgPreviousFlaggedMessage()
|
||||
{
|
||||
GoPreviousMessage(GoFlaggedMessage, true);
|
||||
GoPreviousMessage(navigateFlagged, true);
|
||||
}
|
||||
|
||||
function MsgGoBack() {}
|
||||
|
|
|
@ -39,6 +39,8 @@ nsMsgCopyService.h
|
|||
nsMsgStatusFeedback.h
|
||||
nsMessageView.h
|
||||
nsMsgWindow.h
|
||||
nsMsgViewNavigationService.h
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -54,6 +54,7 @@ CPPSRCS = \
|
|||
nsMessageView.cpp \
|
||||
nsMsgWindow.cpp \
|
||||
nsMessengerMigrator.cpp \
|
||||
nsMsgViewNavigationService.cpp \
|
||||
$(NULL)
|
||||
|
||||
EXPORTS = \
|
||||
|
@ -78,6 +79,7 @@ EXPORTS = \
|
|||
nsMessageView.h \
|
||||
nsMsgWindow.h \
|
||||
nsMessengerMigrator.h \
|
||||
nsMsgViewNavigationService.h \
|
||||
$(NULL)
|
||||
|
||||
# we don't want the shared lib, but we want to force the creation of a static lib.
|
||||
|
|
|
@ -50,6 +50,7 @@ EXPORTS= \
|
|||
nsMessageView.h \
|
||||
nsMsgWindow.h \
|
||||
nsMessengerMigrator.h \
|
||||
nsMsgViewNavigationService.h \
|
||||
$(NULL)
|
||||
|
||||
|
||||
|
@ -82,6 +83,7 @@ CPP_OBJS= \
|
|||
.\$(OBJDIR)\nsMessageView.obj \
|
||||
.\$(OBJDIR)\nsMsgWindow.obj \
|
||||
.\$(OBJDIR)\nsMessengerMigrator.obj \
|
||||
.\$(OBJDIR)\nsMsgViewNavigationService.obj \
|
||||
$(NULL)
|
||||
|
||||
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -236,6 +236,55 @@ NS_IMETHODIMP nsMsgDBFolder::SetCharset(const PRUnichar * aCharset)
|
|||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgDBFolder::HasNewMessages(PRBool *hasNewMessages)
|
||||
{
|
||||
if(!hasNewMessages)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
nsresult rv = GetDatabase(nsnull);
|
||||
|
||||
if(NS_SUCCEEDED(rv))
|
||||
{
|
||||
rv = mDatabase->HasNew(hasNewMessages);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgDBFolder::GetFirstNewMessage(nsIMessage **firstNewMessage)
|
||||
{
|
||||
nsresult rv = GetDatabase(nsnull);
|
||||
|
||||
if(NS_SUCCEEDED(rv))
|
||||
{
|
||||
nsMsgKey key;
|
||||
rv = mDatabase->GetFirstNew(&key);
|
||||
if(NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
nsCOMPtr<nsIMsgDBHdr> hdr;
|
||||
rv = mDatabase->GetMsgHdrForKey(key, getter_AddRefs(hdr));
|
||||
if(NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
rv = CreateMessageFromMsgDBHdr(hdr, firstNewMessage);
|
||||
if(NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgDBFolder::ClearNewMessages()
|
||||
{
|
||||
nsresult rv = GetDatabase(nsnull);
|
||||
|
||||
if(NS_SUCCEEDED(rv))
|
||||
{
|
||||
rv = mDatabase->ClearNewList(PR_FALSE);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult nsMsgDBFolder::ReadDBFolderInfo(PRBool force)
|
||||
{
|
||||
// Since it turns out to be pretty expensive to open and close
|
||||
|
|
|
@ -54,6 +54,9 @@ public:
|
|||
NS_IMETHOD HasMessage(nsIMessage *message, PRBool *hasMessage);
|
||||
NS_IMETHOD GetCharset(PRUnichar * *aCharset);
|
||||
NS_IMETHOD SetCharset(const PRUnichar * aCharset);
|
||||
NS_IMETHOD HasNewMessages(PRBool *hasNewMessages);
|
||||
NS_IMETHOD GetFirstNewMessage(nsIMessage **firstNewMessage);
|
||||
NS_IMETHOD ClearNewMessages();
|
||||
|
||||
NS_IMETHOD GetMsgDatabase(nsIMsgDatabase** aMsgDatabase);
|
||||
|
||||
|
|
|
@ -1214,10 +1214,6 @@ NS_IMETHODIMP nsMsgFolder::GetTotalMessages(PRBool deep, PRInt32 *totalMessages)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
#ifdef HAVE_DB
|
||||
NS_IMETHOD GetTotalMessagesInDB(PRUint32 *totalMessages) const; // How many messages in database.
|
||||
#endif
|
||||
|
||||
PRInt32 nsMsgFolder::GetNumPendingUnread()
|
||||
{
|
||||
return mNumPendingUnreadMessages;
|
||||
|
@ -1228,6 +1224,23 @@ PRInt32 nsMsgFolder::GetNumPendingTotalMessages()
|
|||
return mNumPendingTotalMessages;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgFolder::HasNewMessages(PRBool *hasNewMessages)
|
||||
{
|
||||
//we don't support this
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgFolder::GetFirstNewMessage(nsIMessage **firstNewMessage)
|
||||
{
|
||||
//we don't support this
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgFolder::ClearNewMessages()
|
||||
{
|
||||
//we don't support this
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void nsMsgFolder::ChangeNumPendingUnread(PRInt32 delta)
|
||||
{
|
||||
|
|
|
@ -101,6 +101,9 @@ public:
|
|||
NS_IMETHOD SummaryChanged(void);
|
||||
NS_IMETHOD GetNumUnread(PRBool deep, PRInt32 *_retval);
|
||||
NS_IMETHOD GetTotalMessages(PRBool deep, PRInt32 *_retval);
|
||||
NS_IMETHOD HasNewMessages(PRBool *hasNewMessages);
|
||||
NS_IMETHOD GetFirstNewMessage(nsIMessage **firstNewMessage);
|
||||
NS_IMETHOD ClearNewMessages();
|
||||
NS_IMETHOD GetExpungedBytesCount(PRUint32 *aExpungedBytesCount);
|
||||
NS_IMETHOD GetDeletable(PRBool *aDeletable);
|
||||
NS_IMETHOD GetRequiresCleanup(PRBool *aRequiresCleanup);
|
||||
|
|
Загрузка…
Ссылка в новой задаче