mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-25 11:58:55 +00:00
now we should find the right "next" folder when you hit next and there are no more unread messages in the current folder. we respect the folder pane sort order for determining what's next, which is what's "below" in the folder pane. r/sr=bienvenu
This commit is contained in:
parent
3ad6a737b0
commit
08c99a8091
@ -26,6 +26,89 @@ var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"
|
||||
promptService = promptService.QueryInterface(Components.interfaces.nsIPromptService);
|
||||
var accountManager = Components.classes["@mozilla.org/messenger/account-manager;1"].getService(Components.interfaces.nsIMsgAccountManager);
|
||||
|
||||
// we need the folder datasource and account manager datasource
|
||||
// for when trying to figure out which folder (or account) is next
|
||||
// in the folder pane.
|
||||
var gFolderDataSource = Components.classes["@mozilla.org/rdf/datasource;1?name=mailnewsfolders"].createInstance().QueryInterface(Components.interfaces.nsIRDFDataSource);
|
||||
|
||||
var gAccountManagerDataSource = Components.classes["@mozilla.org/rdf/datasource;1?name=msgaccountmanager"].createInstance().QueryInterface(Components.interfaces.nsIRDFDataSource);
|
||||
|
||||
// we can't compare the name to determine the order in the folder pane
|
||||
// we need to compare the value of the sort resource,
|
||||
// as that's what we use to sort on in the folder pane
|
||||
var gNameProperty = Components.classes["@mozilla.org/rdf/rdf-service;1"].getService(Components.interfaces.nsIRDFService).GetResource("http://home.netscape.com/NC-rdf#Name?sort=true");
|
||||
|
||||
function compareServerSortOrder(a,b)
|
||||
{
|
||||
return compareSortOrder(a,b, gAccountManagerDataSource);
|
||||
}
|
||||
|
||||
function compareFolderSortOrder(a,b)
|
||||
{
|
||||
return compareSortOrder(a,b, gFolderDataSource);
|
||||
}
|
||||
|
||||
function compareSortOrder(folder1, folder2, datasource)
|
||||
{
|
||||
var sortValue1, sortValue2;
|
||||
|
||||
try {
|
||||
var res1 = RDF.GetResource(folder1.URI);
|
||||
sortValue1 = datasource.GetTarget(res1, gNameProperty, true).QueryInterface(Components.interfaces.nsIRDFLiteral).Value;
|
||||
}
|
||||
catch (ex) {
|
||||
dump("XXX ex " + folder1.URI + "," + ex + "\n");
|
||||
sortValue1 = "";
|
||||
}
|
||||
|
||||
try {
|
||||
var res2 = RDF.GetResource(folder2.URI);
|
||||
sortValue2 = datasource.GetTarget(res2, gNameProperty, true).QueryInterface(Components.interfaces.nsIRDFLiteral).Value;
|
||||
}
|
||||
catch (ex) {
|
||||
dump("XXX ex " + folder2.URI + "," + ex + "\n");
|
||||
sortValue2 = "";
|
||||
}
|
||||
|
||||
if (sortValue1 < sortValue2)
|
||||
return -1;
|
||||
else if (sortValue1 > sortValue2)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
function GetSubFoldersInFolderPaneOrder(folder)
|
||||
{
|
||||
var subFolderEnumerator = folder.GetSubFolders();
|
||||
var done = false;
|
||||
var msgFolders = Array();
|
||||
|
||||
// get all the subfolders
|
||||
while (!done) {
|
||||
try {
|
||||
var element = subFolderEnumerator.currentItem();
|
||||
msgFolders[msgFolders.length] = element.QueryInterface(Components.interfaces.nsIMsgFolder);
|
||||
|
||||
subFolderEnumerator.next();
|
||||
}
|
||||
catch (ex) {
|
||||
done = true;
|
||||
}
|
||||
}
|
||||
|
||||
// sort the subfolders
|
||||
msgFolders.sort(compareFolderSortOrder);
|
||||
return msgFolders;
|
||||
}
|
||||
|
||||
function IgnoreFolderForNextNavigation(folder)
|
||||
{
|
||||
// if there is unread mail in the trash, sent, drafts, unsent messages
|
||||
// or templates folders, we ignore it
|
||||
// when doing cross folder "next" navigation
|
||||
return IsSpecialFolder(folder, MSG_FOLDER_FLAG_TRASH | MSG_FOLDER_FLAG_SENTMAIL | MSG_FOLDER_FLAG_DRAFTS | MSG_FOLDER_FLAG_QUEUE | MSG_FOLDER_FLAG_TEMPLATES)
|
||||
}
|
||||
|
||||
function FindNextFolder(originalFolderURI)
|
||||
{
|
||||
@ -35,62 +118,110 @@ function FindNextFolder(originalFolderURI)
|
||||
var folder = originalFolderResource.QueryInterface(Components.interfaces.nsIFolder);
|
||||
if (!folder) return null;
|
||||
|
||||
try {
|
||||
var subFolderEnumerator = folder.GetSubFolders();
|
||||
var done = false;
|
||||
while (!done) {
|
||||
var element = subFolderEnumerator.currentItem();
|
||||
var currentSubFolder = element.QueryInterface(Components.interfaces.nsIMsgFolder);
|
||||
var originalMsgFolder = folder.QueryInterface(Components.interfaces.nsIMsgFolder);
|
||||
|
||||
// don't land in the Trash folder.
|
||||
if(!IsSpecialFolder(currentSubFolder, MSG_FOLDER_FLAG_TRASH)) {
|
||||
if (currentSubFolder.getNumUnread(false /* don't descend */) > 0) {
|
||||
// if the child has unread, use it.
|
||||
return currentSubFolder.URI;
|
||||
}
|
||||
else if (currentSubFolder.getNumUnread(true /* descend */) > 0) {
|
||||
// if the child doesn't have any unread, but it's children do, recurse
|
||||
return FindNextFolder(currentSubFolder.URI);
|
||||
}
|
||||
}
|
||||
try {
|
||||
subFolderEnumerator.next();
|
||||
}
|
||||
catch (ex) {
|
||||
done=true;
|
||||
}
|
||||
} // while
|
||||
// don't land on folders or subfolder of folders
|
||||
// that we don't care about
|
||||
if(!IgnoreFolderForNextNavigation(originalMsgFolder)) {
|
||||
if (originalMsgFolder.getNumUnread(false /* don't descend */) > 0) {
|
||||
return originalMsgFolder.URI;
|
||||
}
|
||||
}
|
||||
catch (ex) {
|
||||
// one way to get here is if the folder has no sub folders
|
||||
|
||||
// first check the children
|
||||
var msgFolders = GetSubFoldersInFolderPaneOrder(folder);
|
||||
var i;
|
||||
for (i=0;i<msgFolders.length;i++) {
|
||||
var currentSubFolder = msgFolders[i];
|
||||
// don't land on folders we don't care about
|
||||
if(!IgnoreFolderForNextNavigation(currentSubFolder)) {
|
||||
if (currentSubFolder.getNumUnread(false /* don't descend */) > 0) {
|
||||
// if the child has unread, use it.
|
||||
return currentSubFolder.URI;
|
||||
}
|
||||
else if (currentSubFolder.getNumUnread(true /* descend */) > 0) {
|
||||
// if the child doesn't have any unread, but it's children do, recurse
|
||||
return FindNextFolder(currentSubFolder.URI);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// didn't find folder in children
|
||||
// go up to the parent, and start at the folder after the current one
|
||||
// unless we are at a server, in which case bail out.
|
||||
if (originalMsgFolder.isServer) {
|
||||
return null;
|
||||
}
|
||||
|
||||
msgFolders = GetSubFoldersInFolderPaneOrder(folder.parent);
|
||||
for (i=0;i<msgFolders.length;i++) {
|
||||
if (msgFolders[i].URI == folder.URI)
|
||||
break;
|
||||
}
|
||||
|
||||
// the current folder is at index i
|
||||
// start at the next folder after that, if there is one
|
||||
if (i+1 < msgFolders.length) {
|
||||
return FindNextFolder(msgFolders[i+1].URI);
|
||||
}
|
||||
|
||||
if (folder.parent && folder.parent.URI) {
|
||||
return FindNextFolder(folder.parent.URI);
|
||||
try {
|
||||
// none at this level after the current folder. go up.
|
||||
if (folder.parent && folder.parent.URI) {
|
||||
var parentMsgFolder = folder.parent.QueryInterface(Components.interfaces.nsIMsgFolder);
|
||||
if (parentMsgFolder.isServer) {
|
||||
// we've already search the parent's children below us.
|
||||
// don't search the server again, return null and let
|
||||
// the caller search the next server
|
||||
return null;
|
||||
}
|
||||
else {
|
||||
FindNextFolder(folder.parent.URI);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (ex) {
|
||||
dump("XXX ex " + ex + "\n");
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function GetTopLevelMessageForMessage(message, folder)
|
||||
{
|
||||
if(!folder)
|
||||
folder = message.msgFolder;
|
||||
if(!folder)
|
||||
folder = message.msgFolder;
|
||||
|
||||
var thread = folder.getThreadForMessage(message);
|
||||
var outIndex = new Object();
|
||||
var rootHdr = thread.GetRootHdr(outIndex);
|
||||
var thread = folder.getThreadForMessage(message);
|
||||
var outIndex = new Object();
|
||||
var rootHdr = thread.GetRootHdr(outIndex);
|
||||
|
||||
var topMessage = folder.createMessageFromMsgDBHdr(rootHdr);
|
||||
var topMessage = folder.createMessageFromMsgDBHdr(rootHdr);
|
||||
return topMessage;
|
||||
}
|
||||
|
||||
return topMessage;
|
||||
function GetRootFoldersInFolderPaneOrder()
|
||||
{
|
||||
var allServers = accountManager.allServers;
|
||||
var numServers = allServers.Count();
|
||||
var i;
|
||||
|
||||
var serversMsgFolders = Array(numServers);
|
||||
for (i=0;i<numServers;i++) {
|
||||
serversMsgFolders[i] = allServers.GetElementAt(i).QueryInterface(Components.interfaces.nsIMsgIncomingServer).RootFolder.QueryInterface(Components.interfaces.nsIMsgFolder);
|
||||
}
|
||||
|
||||
// sort accounts, so they are in the same order as folder pane
|
||||
serversMsgFolders.sort(compareServerSortOrder);
|
||||
|
||||
return serversMsgFolders;
|
||||
}
|
||||
|
||||
function CrossFolderNavigation(type, supportsFolderPane )
|
||||
{
|
||||
if (type != nsMsgNavigationType.nextUnreadMessage)
|
||||
{
|
||||
// only do cross folder navigation for "next unread message"
|
||||
return null;
|
||||
if (type != nsMsgNavigationType.nextUnreadMessage) {
|
||||
// only do cross folder navigation for "next unread message"
|
||||
return null;
|
||||
}
|
||||
|
||||
var nextMode = pref.GetIntPref("mailnews.nav_crosses_folders");
|
||||
@ -105,61 +236,63 @@ function CrossFolderNavigation(type, supportsFolderPane )
|
||||
var nextFolderURI = null;
|
||||
var done = false;
|
||||
var startAtURI = originalFolderURI;
|
||||
var i = 0;
|
||||
var allServers = accountManager.allServers;
|
||||
var numServers = allServers.Count();
|
||||
var i,j;
|
||||
var rootFolders;
|
||||
|
||||
// XXX fix this
|
||||
// this will search the originalFolderURI server twice
|
||||
while (!done)
|
||||
{
|
||||
nextFolderURI = FindNextFolder(startAtURI);
|
||||
if (!nextFolderURI)
|
||||
{
|
||||
if (i == numServers)
|
||||
{
|
||||
// no more servers, we're done
|
||||
done = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// get the uri for the next server and start there
|
||||
startAtURI = allServers.GetElementAt(i).QueryInterface(Components.interfaces.nsIMsgIncomingServer).serverURI;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// got a folder with unread messages, start with it
|
||||
done = true;
|
||||
}
|
||||
// look for the next folder, this will only look on the current account
|
||||
// and below us, in the folder pane
|
||||
nextFolderURI = FindNextFolder(startAtURI);
|
||||
|
||||
// if nothing in the current account, start with the next account (below)
|
||||
// and try until we hit the bottom of the folder pane
|
||||
if (!nextFolderURI) {
|
||||
// start at the account after the current account
|
||||
rootFolders = GetRootFoldersInFolderPaneOrder();
|
||||
for (i=0;i<rootFolders.length;i++) {
|
||||
if (rootFolders[i].URI == gDBView.msgFolder.server.serverURI)
|
||||
break;
|
||||
}
|
||||
|
||||
if (nextFolderURI && (originalFolderURI != nextFolderURI))
|
||||
{
|
||||
var nextFolderResource = RDF.GetResource(nextFolderURI);
|
||||
var nextFolder = nextFolderResource.QueryInterface(Components.interfaces.nsIMsgFolder);
|
||||
switch (nextMode)
|
||||
{
|
||||
case 0:
|
||||
// do this unconditionally
|
||||
gNextMessageAfterLoad = type;
|
||||
if (supportsFolderPane)
|
||||
SelectFolder(nextFolderURI);
|
||||
break;
|
||||
case 1:
|
||||
default:
|
||||
var promptText = gMessengerBundle.getFormattedString("advanceNextPrompt", [ nextFolder.name ], 1);
|
||||
if (promptService.confirm(window, promptText, promptText)) {
|
||||
gNextMessageAfterLoad = type;
|
||||
if (supportsFolderPane)
|
||||
SelectFolder(nextFolderURI);
|
||||
}
|
||||
break;
|
||||
}
|
||||
for (j=i+1; j<rootFolders.length; j++) {
|
||||
nextFolderURI = FindNextFolder(rootFolders[j].URI);
|
||||
if (nextFolderURI)
|
||||
break;
|
||||
}
|
||||
|
||||
// if nothing from the current account down to the bottom
|
||||
// (of the folder pane), start again at the top.
|
||||
if (!nextFolderURI) {
|
||||
for (j=0; j<rootFolders.length; j++) {
|
||||
nextFolderURI = FindNextFolder(rootFolders[j].URI);
|
||||
if (nextFolderURI)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nextFolderURI;
|
||||
if (nextFolderURI && (originalFolderURI != nextFolderURI)) {
|
||||
var nextFolderResource = RDF.GetResource(nextFolderURI);
|
||||
var nextFolder = nextFolderResource.QueryInterface(Components.interfaces.nsIMsgFolder);
|
||||
switch (nextMode) {
|
||||
case 0:
|
||||
// do this unconditionally
|
||||
gNextMessageAfterLoad = type;
|
||||
if (supportsFolderPane)
|
||||
SelectFolder(nextFolderURI);
|
||||
break;
|
||||
case 1:
|
||||
default:
|
||||
var promptText = gMessengerBundle.getFormattedString("advanceNextPrompt", [ nextFolder.name ], 1);
|
||||
if (promptService.confirm(window, promptText, promptText)) {
|
||||
gNextMessageAfterLoad = type;
|
||||
if (supportsFolderPane)
|
||||
SelectFolder(nextFolderURI);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return nextFolderURI;
|
||||
}
|
||||
|
||||
// from MailNewsTypes.h
|
||||
|
Loading…
x
Reference in New Issue
Block a user