зеркало из https://github.com/mozilla/pjs.git
Fixes 17427, 17288. r=bienvenu. NextUnreadThread works and Next Unread Messages uses it
for optimization. Thread counts work in thread pane. Can now mark a replied or forwarded message as unread.
This commit is contained in:
Родитель
77ae5fdf0d
Коммит
d00e9f8117
|
@ -370,8 +370,8 @@ function ToggleMessageRead(treeItem)
|
|||
{
|
||||
|
||||
var tree = GetThreadTree();
|
||||
var status = treeItem.getAttribute('Status');
|
||||
var unread = (status == " ") || (status == "new");
|
||||
var isUnread = treeItem.getAttribute('IsUnread');
|
||||
var unread = (isUnread == "true");
|
||||
messenger.MarkMessageRead(tree.database, treeItem.resource, unread);
|
||||
}
|
||||
|
||||
|
|
|
@ -370,6 +370,8 @@ Rights Reserved.
|
|||
<menuitem value="&nextMsgCmd.label;" oncommand="MsgNextMessage();"/>
|
||||
<menuitem value="&nextUnreadMsgCmd.label;" oncommand="MsgNextUnreadMessage();"/>
|
||||
<menuitem value="&nextFlaggedMsgCmd.label;" oncommand="MsgNextFlaggedMessage();"/>
|
||||
<menuseparator/>
|
||||
<menuitem value="&nextUnreadThread.label;" oncommand="MsgNextUnreadThread();"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
<menu value="&prevMenu.label;">
|
||||
|
|
|
@ -32,14 +32,14 @@ function ResourceGoMessage(message)
|
|||
|
||||
function GoUnreadMessage(message)
|
||||
{
|
||||
var status = message.getAttribute('Status');
|
||||
return(status == ' ' || status == 'New');
|
||||
var isUnread = message.getAttribute('IsUnread');
|
||||
return(isUnread == 'true');
|
||||
}
|
||||
|
||||
function ResourceGoUnreadMessage(message)
|
||||
{
|
||||
var statusValue = GetMessageValue(message, "http://home.netscape.com/NC-rdf#Status");
|
||||
return(statusValue == ' ' || statusValue == 'New');
|
||||
var isUnreadValue = GetMessageValue(message, "http://home.netscape.com/NC-rdf#IsUnread");
|
||||
return(isUnreadValue == 'true');
|
||||
}
|
||||
|
||||
function GoFlaggedMessage(message)
|
||||
|
@ -67,13 +67,26 @@ function GetMessageValue(message, propertyURI)
|
|||
return null;
|
||||
}
|
||||
|
||||
function GoUnreadThread(messageElement)
|
||||
{
|
||||
var messageuri = messageElement.getAttribute('id');
|
||||
var messageResource = RDF.GetResource(messageuri);
|
||||
|
||||
var unreadCount = GetMessageValue(messageResource, "http://home.netscape.com/NC-rdf#TotalUnreadMessages");
|
||||
return (unreadCount !="");
|
||||
}
|
||||
|
||||
/*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.
|
||||
It must take a node and return a boolean.
|
||||
nextResourceFunction is the function that will be used to determine if a message in the form of a resource
|
||||
matches criteria. Takes a resource and returns a boolean
|
||||
nextThreadFunction is an optional function that can be used to optimize whether or not a thread will have a
|
||||
message that matches the criteria. Takes the top level message in the form of a node and returns a boolean.
|
||||
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, startFromBeginning)
|
||||
function GoNextMessage(nextFunction, nextResourceFunction, nextThreadFunction, startFromBeginning)
|
||||
{
|
||||
var tree = GetThreadTree();
|
||||
|
||||
|
@ -93,7 +106,7 @@ function GoNextMessage(nextFunction, nextResourceFunction, startFromBeginning)
|
|||
|
||||
if(messageView.showThreads)
|
||||
{
|
||||
nextMessage = GetNextMessageInThreads(tree, currentMessage, nextFunction, nextResourceFunction, startFromBeginning);
|
||||
nextMessage = GetNextMessageInThreads(tree, currentMessage, nextFunction, nextResourceFunction, nextThreadFunction, startFromBeginning);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -157,7 +170,7 @@ function GetNextMessage(tree, currentMessage, nextFunction, startFromBeginning)
|
|||
return nextMessage;
|
||||
}
|
||||
|
||||
function GetNextMessageInThreads(tree, currentMessage, nextFunction, nextResourceFunction, startFromBeginning)
|
||||
function GetNextMessageInThreads(tree, currentMessage, nextFunction, nextResourceFunction, nextThreadFunction, startFromBeginning)
|
||||
{
|
||||
var checkStartMessage = false;
|
||||
|
||||
|
@ -168,11 +181,14 @@ function GetNextMessageInThreads(tree, currentMessage, nextFunction, nextResourc
|
|||
checkStartMessage = true;
|
||||
}
|
||||
|
||||
return FindNextMessageInThreads(currentMessage, currentMessage, nextFunction, nextResourceFunction, startFromBeginning, checkStartMessage);
|
||||
return FindNextMessageInThreads(currentMessage, currentMessage, nextFunction, nextResourceFunction, nextThreadFunction, startFromBeginning, checkStartMessage);
|
||||
}
|
||||
|
||||
function FindNextMessageInThreads(startMessage, originalStartMessage, nextFunction, nextResourceFunction, 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)
|
||||
{
|
||||
|
@ -180,6 +196,17 @@ function FindNextMessageInThreads(startMessage, originalStartMessage, nextFuncti
|
|||
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)
|
||||
|
@ -210,7 +237,7 @@ function FindNextMessageInThreads(startMessage, originalStartMessage, nextFuncti
|
|||
{
|
||||
if(parentMessage.nextSibling != null)
|
||||
{
|
||||
nextMessage = FindNextMessageInThreads(parentMessage.nextSibling, originalStartMessage, nextFunction, nextResourceFunction, startFromBeginning, true);
|
||||
nextMessage = FindNextMessageInThreads(parentMessage.nextSibling, originalStartMessage, nextFunction, nextResourceFunction, nextThreadFunction, startFromBeginning, true);
|
||||
return nextMessage;
|
||||
}
|
||||
parentMessage = parentMessage.parentNode.parentNode;
|
||||
|
@ -218,7 +245,7 @@ function FindNextMessageInThreads(startMessage, originalStartMessage, nextFuncti
|
|||
//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, false, true);
|
||||
nextMessage = FindNextMessageInThreads(FindFirstMessage(parentMessage), originalStartMessage, nextFunction, nextResourceFunction, nextThreadFunction, false, true);
|
||||
return nextMessage;
|
||||
}
|
||||
return null;
|
||||
|
@ -390,11 +417,19 @@ function ChangeSelection(tree, newMessage)
|
|||
|
||||
function FindFirstMessage(tree)
|
||||
{
|
||||
var treeChildren = tree.getElementsByTagName('treechildren');
|
||||
if(treeChildren.length > 1)
|
||||
//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++)
|
||||
{
|
||||
//The first treeChildren will be for the template.
|
||||
return treeChildren[1].firstChild;
|
||||
if(children[i].nodeName == 'treechildren')
|
||||
{
|
||||
return children[i].firstChild;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -402,3 +437,130 @@ function FindFirstMessage(tree)
|
|||
|
||||
}
|
||||
|
||||
// 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
|
||||
// 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)
|
||||
{
|
||||
|
||||
if(messageView.showThreads)
|
||||
{
|
||||
var tree = GetThreadTree();
|
||||
|
||||
var selArray = tree.selectedItems;
|
||||
var length = selArray.length;
|
||||
|
||||
if ( selArray && ((length == 0) || (length == 1)) )
|
||||
{
|
||||
var currentMessage;
|
||||
|
||||
if(length == 0)
|
||||
currentMessage = null;
|
||||
else
|
||||
currentMessage = selArray[0];
|
||||
|
||||
var nextMessage;
|
||||
var currentTopMessage;
|
||||
var checkCurrentTopMessage;
|
||||
//Need to get the parent message for the current selection to begin to find thread
|
||||
if(currentMessage)
|
||||
{
|
||||
//need to find its top level message and we don't want it to be checked for criteria
|
||||
currentTopMessage = FindTopLevelMessage(currentMessage);
|
||||
checkCurrentTopMessage = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
//currentTopmessage is the first one in the tree and we want it to be checked for criteria.
|
||||
currentTopMessage = FindFirstMessage(tree);
|
||||
checkCurrentTopMessage = true;
|
||||
}
|
||||
|
||||
var nextTopMessage = FindNextThread(currentTopMessage, nextThreadFunction, startFromBeginning, checkCurrentTopMessage);
|
||||
var changeSelection = (nextTopMessage != null && ((currentTopMessage != nextTopMessage) || checkCurrentTopMessage));
|
||||
if(changeSelection)
|
||||
{
|
||||
if(gotoNextInThread)
|
||||
{
|
||||
nextMessage = GetNextInThread(nextTopMessage, nextMessageFunction, nextResourceFunction);
|
||||
ChangeSelection(tree, nextMessage);
|
||||
}
|
||||
else
|
||||
ChangeSelection(tree, nextTopMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//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;
|
||||
var parent = startMessage.parentNode.parentNode;
|
||||
|
||||
while(parent.nodeName == 'treeitem')
|
||||
{
|
||||
currentTop = parent;
|
||||
parent = parent.parentNode.parentNode;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -51,7 +51,8 @@ Rights Reserved.
|
|||
<treeitem uri="..."
|
||||
Status="rdf:http://home.netscape.com/NC-rdf#Status"
|
||||
Flagged="rdf:http://home.netscape.com/NC-rdf#Flagged"
|
||||
Priority="rdf:http://home.netscape.com/NC-rdf#Priority">
|
||||
Priority="rdf:http://home.netscape.com/NC-rdf#Priority"
|
||||
IsUnread="rdf:http://home.netscape.com/NC-rdf#IsUnread">
|
||||
<treerow>
|
||||
<treecell value="rdf:http://home.netscape.com/NC-rdf#Thread"/>
|
||||
<treecell indent="true" value="rdf:http://home.netscape.com/NC-rdf#Subject"/>
|
||||
|
|
|
@ -840,16 +840,21 @@ function MsgStop() {
|
|||
|
||||
function MsgNextMessage()
|
||||
{
|
||||
GoNextMessage(GoMessage, ResourceGoMessage, false);
|
||||
GoNextMessage(GoMessage, ResourceGoMessage, null, false);
|
||||
}
|
||||
|
||||
function MsgNextUnreadMessage()
|
||||
{
|
||||
GoNextMessage(GoUnreadMessage, ResourceGoUnreadMessage, true);
|
||||
GoNextMessage(GoUnreadMessage, ResourceGoUnreadMessage, GoUnreadThread, true);
|
||||
}
|
||||
function MsgNextFlaggedMessage()
|
||||
{
|
||||
GoNextMessage(GoFlaggedMessage, ResourceGoFlaggedMessage, true);
|
||||
GoNextMessage(GoFlaggedMessage, ResourceGoFlaggedMessage, null, true);
|
||||
}
|
||||
|
||||
function MsgNextUnreadThread()
|
||||
{
|
||||
GoNextThread(GoUnreadThread, GoUnreadMessage, ResourceGoUnreadMessage, true, true);
|
||||
}
|
||||
|
||||
function MsgPreviousMessage()
|
||||
|
|
|
@ -203,6 +203,7 @@ Rights Reserved.
|
|||
<!ENTITY nextUnreadMsgCmd.label "Unread Message">
|
||||
<!ENTITY nextFlaggedMsgCmd.label "Flagged Message">
|
||||
<!ENTITY nextUnflaggedMsgCmd.label "Unflagged Message">
|
||||
<!ENTITY nextUnreadThread.label "Unread Thread">
|
||||
<!ENTITY prevMenu.label "Previous">
|
||||
<!ENTITY prevMsgCmd.label "Message">
|
||||
<!ENTITY prevUnreadMsgCmd.label "Unread Message">
|
||||
|
|
|
@ -18,11 +18,7 @@
|
|||
* Rights Reserved.
|
||||
*/
|
||||
|
||||
treeitem[Status=" "] > treerow {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
treeitem[Status="new"] > treerow{
|
||||
treeitem[IsUnread="true"] > treerow {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
|
@ -59,11 +55,7 @@ treecell.unreadcol > .tree-button {
|
|||
list-style-image: url("chrome://messenger/skin/readmail.gif");
|
||||
}
|
||||
|
||||
treeitem[Status=" "] > treerow > treecell.unreadcol > .tree-button {
|
||||
list-style-image: url("chrome://messenger/skin/unreadmail.gif");
|
||||
}
|
||||
|
||||
treeitem[Status="new"] > treerow > treecell.unreadcol > tree-button {
|
||||
treeitem[IsUnread="true"] > treerow > treecell.unreadcol > .tree-button {
|
||||
list-style-image: url("chrome://messenger/skin/unreadmail.gif");
|
||||
}
|
||||
|
||||
|
|
|
@ -732,7 +732,7 @@ nsresult nsMsgFolderDataSource::OnItemAddedOrRemoved(nsISupports *parentItem, ns
|
|||
if(NS_SUCCEEDED(rv))
|
||||
{
|
||||
//Notify folders that a message was added or deleted.
|
||||
NotifyObservers(parentResource, kNC_MessageChild, itemNode, added);
|
||||
NotifyObservers(parentResource, kNC_MessageChild, itemNode, added, PR_FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -743,7 +743,7 @@ nsresult nsMsgFolderDataSource::OnItemAddedOrRemoved(nsISupports *parentItem, ns
|
|||
if(NS_SUCCEEDED(rv))
|
||||
{
|
||||
//Notify folders that a message was added or deleted.
|
||||
NotifyObservers(parentResource, kNC_Child, itemNode, added);
|
||||
NotifyObservers(parentResource, kNC_Child, itemNode, added, PR_FALSE);
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
|
@ -796,15 +796,12 @@ NS_IMETHODIMP nsMsgFolderDataSource::OnItemPropertyFlagChanged(nsISupports *item
|
|||
{
|
||||
if(PL_strcmp("BiffState", property) == 0)
|
||||
{
|
||||
nsCAutoString oldBiffStateStr, newBiffStateStr;
|
||||
nsCAutoString newBiffStateStr;
|
||||
|
||||
rv = GetBiffStateString(oldFlag, oldBiffStateStr);
|
||||
if(NS_FAILED(rv))
|
||||
return rv;
|
||||
rv = GetBiffStateString(newFlag, newBiffStateStr);
|
||||
if(NS_FAILED(rv))
|
||||
return rv;
|
||||
NotifyPropertyChanged(resource, kNC_BiffState, oldBiffStateStr, newBiffStateStr);
|
||||
NotifyPropertyChanged(resource, kNC_BiffState, newBiffStateStr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1208,12 +1205,10 @@ nsMsgFolderDataSource::OnUnreadMessagePropertyChanged(nsIMsgFolder *folder, PRIn
|
|||
if(folderResource)
|
||||
{
|
||||
//First send a regular unread message changed notification
|
||||
nsCOMPtr<nsIRDFNode> oldNode;
|
||||
nsCOMPtr<nsIRDFNode> newNode;
|
||||
|
||||
GetNumMessagesNode(oldValue, getter_AddRefs(oldNode));
|
||||
GetNumMessagesNode(newValue, getter_AddRefs(newNode));
|
||||
NotifyPropertyChanged(folderResource, kNC_TotalUnreadMessages, oldNode, newNode);
|
||||
NotifyPropertyChanged(folderResource, kNC_TotalUnreadMessages, newNode);
|
||||
|
||||
//Now see if hasUnreadMessages has changed
|
||||
nsCOMPtr<nsIRDFNode> oldHasUnreadMessages;
|
||||
|
@ -1222,13 +1217,12 @@ nsMsgFolderDataSource::OnUnreadMessagePropertyChanged(nsIMsgFolder *folder, PRIn
|
|||
{
|
||||
oldHasUnreadMessages = kFalseLiteral;
|
||||
newHasUnreadMessages = kTrueLiteral;
|
||||
NotifyPropertyChanged(folderResource, kNC_HasUnreadMessages, oldHasUnreadMessages, newHasUnreadMessages);
|
||||
NotifyPropertyChanged(folderResource, kNC_HasUnreadMessages, newHasUnreadMessages);
|
||||
}
|
||||
else if(oldValue > 0 && newValue <= 0)
|
||||
{
|
||||
oldHasUnreadMessages = kTrueLiteral;
|
||||
newHasUnreadMessages = kFalseLiteral;
|
||||
NotifyPropertyChanged(folderResource, kNC_HasUnreadMessages, oldHasUnreadMessages, newHasUnreadMessages);
|
||||
NotifyPropertyChanged(folderResource, kNC_HasUnreadMessages, newHasUnreadMessages);
|
||||
}
|
||||
//We will have to change the folderTreeName also
|
||||
|
||||
|
@ -1236,18 +1230,14 @@ nsMsgFolderDataSource::OnUnreadMessagePropertyChanged(nsIMsgFolder *folder, PRIn
|
|||
nsresult rv = folder->GetAbbreviatedName(getter_Copies(name));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
nsAutoString oldNameString(name);
|
||||
nsAutoString newNameString(name);
|
||||
|
||||
CreateUnreadMessagesNameString(oldValue, oldNameString);
|
||||
CreateUnreadMessagesNameString(newValue, newNameString);
|
||||
|
||||
nsCOMPtr<nsIRDFNode> oldNameNode;
|
||||
nsCOMPtr<nsIRDFNode> newNameNode;
|
||||
createNode(oldNameString, getter_AddRefs(oldNameNode), getRDFService());
|
||||
createNode(newNameString, getter_AddRefs(newNameNode), getRDFService());
|
||||
|
||||
NotifyPropertyChanged(folderResource, kNC_FolderTreeName, oldNameNode, newNameNode);
|
||||
NotifyPropertyChanged(folderResource, kNC_FolderTreeName, newNameNode);
|
||||
|
||||
}
|
||||
|
||||
|
@ -1263,12 +1253,10 @@ nsMsgFolderDataSource::OnTotalMessagePropertyChanged(nsIMsgFolder *folder, PRInt
|
|||
if(folderResource)
|
||||
{
|
||||
//First send a regular unread message changed notification
|
||||
nsCOMPtr<nsIRDFNode> oldNode;
|
||||
nsCOMPtr<nsIRDFNode> newNode;
|
||||
|
||||
GetNumMessagesNode(oldValue, getter_AddRefs(oldNode));
|
||||
GetNumMessagesNode(newValue, getter_AddRefs(newNode));
|
||||
NotifyPropertyChanged(folderResource, kNC_TotalMessages, oldNode, newNode);
|
||||
NotifyPropertyChanged(folderResource, kNC_TotalMessages, newNode);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -61,6 +61,7 @@ nsIRDFResource* nsMsgMessageDataSource::kNC_Size= nsnull;
|
|||
nsIRDFResource* nsMsgMessageDataSource::kNC_Total = nsnull;
|
||||
nsIRDFResource* nsMsgMessageDataSource::kNC_Unread = nsnull;
|
||||
nsIRDFResource* nsMsgMessageDataSource::kNC_MessageChild = nsnull;
|
||||
nsIRDFResource* nsMsgMessageDataSource::kNC_IsUnread = nsnull;
|
||||
|
||||
|
||||
//commands
|
||||
|
@ -107,6 +108,7 @@ nsMsgMessageDataSource::~nsMsgMessageDataSource (void)
|
|||
NS_RELEASE2(kNC_Total, refcnt);
|
||||
NS_RELEASE2(kNC_Unread, refcnt);
|
||||
NS_RELEASE2(kNC_MessageChild, refcnt);
|
||||
NS_RELEASE2(kNC_IsUnread, refcnt);
|
||||
|
||||
NS_RELEASE2(kNC_MarkRead, refcnt);
|
||||
NS_RELEASE2(kNC_MarkUnread, refcnt);
|
||||
|
@ -155,6 +157,7 @@ nsresult nsMsgMessageDataSource::Init()
|
|||
rdf->GetResource(NC_RDF_TOTALMESSAGES, &kNC_Total);
|
||||
rdf->GetResource(NC_RDF_TOTALUNREADMESSAGES, &kNC_Unread);
|
||||
rdf->GetResource(NC_RDF_MESSAGECHILD, &kNC_MessageChild);
|
||||
rdf->GetResource(NC_RDF_ISUNREAD, &kNC_IsUnread);
|
||||
|
||||
rdf->GetResource(NC_RDF_MARKREAD, &kNC_MarkRead);
|
||||
rdf->GetResource(NC_RDF_MARKUNREAD, &kNC_MarkUnread);
|
||||
|
@ -198,7 +201,10 @@ nsresult nsMsgMessageDataSource::CreateLiterals(nsIRDFService *rdf)
|
|||
createNode(str, getter_AddRefs(kNewLiteral), rdf);
|
||||
str = "read";
|
||||
createNode(str, getter_AddRefs(kReadLiteral), rdf);
|
||||
|
||||
str = "true";
|
||||
createNode(str, getter_AddRefs(kTrueLiteral), rdf);
|
||||
str = "false";
|
||||
createNode(str, getter_AddRefs(kFalseLiteral), rdf);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -355,7 +361,8 @@ NS_IMETHODIMP nsMsgMessageDataSource::GetTargets(nsIRDFResource* source,
|
|||
}
|
||||
else if((kNC_Subject == property) || (kNC_Date == property) ||
|
||||
(kNC_Status == property) || (kNC_Flagged == property) ||
|
||||
(kNC_Priority == property) || (kNC_Size == property))
|
||||
(kNC_Priority == property) || (kNC_Size == property) ||
|
||||
(kNC_IsUnread == property))
|
||||
{
|
||||
nsSingletonEnumerator* cursor =
|
||||
new nsSingletonEnumerator(source);
|
||||
|
@ -479,7 +486,7 @@ nsMsgMessageDataSource::getMessageArcLabelsOut(PRBool showThreads,
|
|||
(*arcs)->AppendElement(kNC_Flagged);
|
||||
(*arcs)->AppendElement(kNC_Priority);
|
||||
(*arcs)->AppendElement(kNC_Size);
|
||||
|
||||
(*arcs)->AppendElement(kNC_IsUnread);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -608,8 +615,20 @@ nsresult nsMsgMessageDataSource::OnItemAddedOrRemoved(nsISupports *parentItem, n
|
|||
if(NS_SUCCEEDED(rv))
|
||||
{
|
||||
//Notify folders that a message was deleted.
|
||||
NotifyObservers(parentResource, kNC_MessageChild, itemNode, added);
|
||||
NotifyObservers(parentResource, kNC_MessageChild, itemNode, added, PR_FALSE);
|
||||
}
|
||||
|
||||
//Unread and total message counts will have changed.
|
||||
PRUint32 flags;
|
||||
//use the changed message to get the flags, but use the parent message to change the counts since
|
||||
//it hasn't been removed from the thread yet.
|
||||
rv = message->GetFlags(&flags);
|
||||
if(NS_SUCCEEDED(rv))
|
||||
{
|
||||
if(!(flags & MSG_FLAG_READ))
|
||||
OnChangeUnreadMessageCount(parentMessage);
|
||||
}
|
||||
OnChangeTotalMessageCount(parentMessage);
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
|
@ -648,25 +667,15 @@ NS_IMETHODIMP nsMsgMessageDataSource::OnItemPropertyFlagChanged(nsISupports *ite
|
|||
{
|
||||
if(PL_strcmp("Status", property) == 0)
|
||||
{
|
||||
nsCAutoString oldStatusStr, newStatusStr;
|
||||
rv = createStatusStringFromFlag(oldFlag, oldStatusStr);
|
||||
if(NS_FAILED(rv))
|
||||
return rv;
|
||||
rv = createStatusStringFromFlag(newFlag, newStatusStr);
|
||||
if(NS_FAILED(rv))
|
||||
return rv;
|
||||
rv = NotifyPropertyChanged(resource, kNC_Status, oldStatusStr, newStatusStr);
|
||||
OnChangeStatus(resource, oldFlag, newFlag);
|
||||
}
|
||||
else if(PL_strcmp("Flagged", property) == 0)
|
||||
{
|
||||
nsCAutoString oldFlaggedStr, newFlaggedStr;
|
||||
rv = createFlaggedStringFromFlag(oldFlag, oldFlaggedStr);
|
||||
if(NS_FAILED(rv))
|
||||
return rv;
|
||||
nsCAutoString newFlaggedStr;
|
||||
rv = createFlaggedStringFromFlag(newFlag, newFlaggedStr);
|
||||
if(NS_FAILED(rv))
|
||||
return rv;
|
||||
rv = NotifyPropertyChanged(resource, kNC_Flagged, oldFlaggedStr, newFlaggedStr);
|
||||
rv = NotifyPropertyChanged(resource, kNC_Flagged, newFlaggedStr);
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
|
@ -678,7 +687,121 @@ NS_IMETHODIMP nsMsgMessageDataSource::OnFolderLoaded(nsIFolder *folder)
|
|||
return rv;
|
||||
}
|
||||
|
||||
nsresult nsMsgMessageDataSource::OnChangeStatus(nsIRDFResource *resource, PRUint32 oldFlag, PRUint32 newFlag)
|
||||
{
|
||||
OnChangeStatusString(resource, oldFlag, newFlag);
|
||||
|
||||
PRUint32 changedFlag = oldFlag ^ newFlag;
|
||||
if(changedFlag & MSG_FLAG_READ)
|
||||
{
|
||||
OnChangeIsUnread(resource, oldFlag, newFlag);
|
||||
PRBool showThreads;
|
||||
GetIsThreaded(&showThreads);
|
||||
if(showThreads)
|
||||
{
|
||||
nsCOMPtr<nsIMessage> message = do_QueryInterface(resource);
|
||||
if(message)
|
||||
OnChangeUnreadMessageCount(message);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsMsgMessageDataSource::OnChangeStatusString(nsIRDFResource *resource, PRUint32 oldFlag, PRUint32 newFlag)
|
||||
{
|
||||
|
||||
nsresult rv;
|
||||
nsCAutoString newStatusStr;
|
||||
rv = createStatusStringFromFlag(newFlag, newStatusStr);
|
||||
if(NS_FAILED(rv))
|
||||
return rv;
|
||||
rv = NotifyPropertyChanged(resource, kNC_Status, newStatusStr);
|
||||
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult nsMsgMessageDataSource::OnChangeIsUnread(nsIRDFResource *resource, PRUint32 oldFlag, PRUint32 newFlag)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIRDFNode> newIsUnreadNode;
|
||||
|
||||
newIsUnreadNode = (newFlag & MSG_FLAG_READ) ? kFalseLiteral : kTrueLiteral;
|
||||
|
||||
rv = NotifyPropertyChanged(resource, kNC_IsUnread, newIsUnreadNode);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult nsMsgMessageDataSource::OnChangeUnreadMessageCount(nsIMessage *message)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIMsgFolder> folder;
|
||||
nsCOMPtr<nsIMsgThread> thread;
|
||||
|
||||
rv = message->GetMsgFolder(getter_AddRefs(folder));
|
||||
if(NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
rv = folder->GetThreadForMessage(message, getter_AddRefs(thread));
|
||||
if(NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
nsCOMPtr<nsIRDFNode> unreadChildrenNode;
|
||||
rv = GetUnreadChildrenNode(thread, getter_AddRefs(unreadChildrenNode));
|
||||
if(NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
nsCOMPtr<nsIMessage> firstMessage;
|
||||
rv = GetThreadsFirstMessage(thread, folder, getter_AddRefs(firstMessage));
|
||||
if(NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
nsCOMPtr<nsIRDFResource> firstMessageResource = do_QueryInterface(firstMessage);
|
||||
if(firstMessageResource)
|
||||
rv = NotifyPropertyChanged(firstMessageResource, kNC_Unread, unreadChildrenNode);
|
||||
else
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return rv;
|
||||
|
||||
}
|
||||
|
||||
nsresult nsMsgMessageDataSource::OnChangeTotalMessageCount(nsIMessage *message)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIMsgFolder> folder;
|
||||
nsCOMPtr<nsIMsgThread> thread;
|
||||
|
||||
rv = message->GetMsgFolder(getter_AddRefs(folder));
|
||||
if(NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
rv = folder->GetThreadForMessage(message, getter_AddRefs(thread));
|
||||
if(NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
nsCOMPtr<nsIRDFNode> numChildrenNode;
|
||||
rv = GetTotalChildrenNode(thread, getter_AddRefs(numChildrenNode));
|
||||
if(NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
nsCOMPtr<nsIMessage> firstMessage;
|
||||
rv = GetThreadsFirstMessage(thread, folder, getter_AddRefs(firstMessage));
|
||||
if(NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
nsCOMPtr<nsIRDFResource> firstMessageResource = do_QueryInterface(firstMessage);
|
||||
if(firstMessageResource)
|
||||
rv = NotifyPropertyChanged(firstMessageResource, kNC_Total, numChildrenNode);
|
||||
else
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
return rv;
|
||||
|
||||
}
|
||||
nsresult
|
||||
nsMsgMessageDataSource::createMessageNode(nsIMessage *message,
|
||||
nsIRDFResource *property,
|
||||
|
@ -708,6 +831,8 @@ nsMsgMessageDataSource::createMessageNode(nsIMessage *message,
|
|||
rv = createMessageTotalNode(message, target);
|
||||
else if ((kNC_Unread == property))
|
||||
rv = createMessageUnreadNode(message, target);
|
||||
else if((kNC_IsUnread == property))
|
||||
rv = createMessageIsUnreadNode(message, target);
|
||||
else if ((kNC_MessageChild == property))
|
||||
rv = createMessageMessageChildNode(message, target);
|
||||
|
||||
|
@ -819,6 +944,23 @@ nsMsgMessageDataSource::createMessageStatusNode(nsIMessage *message,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsMsgMessageDataSource::createMessageIsUnreadNode(nsIMessage *message, nsIRDFNode **target)
|
||||
{
|
||||
nsresult rv;
|
||||
PRUint32 flags;
|
||||
rv = message->GetFlags(&flags);
|
||||
if(NS_FAILED(rv))
|
||||
return rv;
|
||||
if(flags & MSG_FLAG_READ)
|
||||
*target = kFalseLiteral;
|
||||
else
|
||||
*target = kTrueLiteral;
|
||||
|
||||
NS_IF_ADDREF(*target);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsMsgMessageDataSource::createMessageFlaggedNode(nsIMessage *message,
|
||||
nsIRDFNode **target)
|
||||
|
@ -971,15 +1113,7 @@ nsresult nsMsgMessageDataSource::createMessageTotalNode(nsIMessage *message, nsI
|
|||
{
|
||||
if(IsThreadsFirstMessage(thread, message))
|
||||
{
|
||||
PRUint32 numChildren;
|
||||
rv = thread->GetNumChildren(&numChildren);
|
||||
if(NS_SUCCEEDED(rv))
|
||||
{
|
||||
if(numChildren > 1)
|
||||
rv = createNode(numChildren, target, getRDFService());
|
||||
else
|
||||
rv = createNode(emptyString, target, getRDFService());
|
||||
}
|
||||
rv = GetTotalChildrenNode(thread, target);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1000,7 +1134,7 @@ nsresult nsMsgMessageDataSource::createMessageUnreadNode(nsIMessage *message, ns
|
|||
nsCOMPtr<nsIMsgFolder> folder;
|
||||
nsCOMPtr<nsIMsgThread> thread;
|
||||
nsresult rv;
|
||||
nsString emptyString("");
|
||||
nsAutoString emptyString("");
|
||||
|
||||
PRBool showThreads;
|
||||
rv = GetIsThreaded(&showThreads);
|
||||
|
@ -1015,15 +1149,7 @@ nsresult nsMsgMessageDataSource::createMessageUnreadNode(nsIMessage *message, ns
|
|||
{
|
||||
if(IsThreadsFirstMessage(thread, message))
|
||||
{
|
||||
PRUint32 numUnread;
|
||||
rv = thread->GetNumUnreadChildren(&numUnread);
|
||||
if(NS_SUCCEEDED(rv))
|
||||
{
|
||||
if(numUnread > 0)
|
||||
rv = createNode(numUnread, target, getRDFService());
|
||||
else
|
||||
rv = createNode(emptyString, target, getRDFService());
|
||||
}
|
||||
rv = GetUnreadChildrenNode(thread, target);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1038,6 +1164,40 @@ nsresult nsMsgMessageDataSource::createMessageUnreadNode(nsIMessage *message, ns
|
|||
return NS_RDF_NO_VALUE;
|
||||
}
|
||||
|
||||
nsresult nsMsgMessageDataSource::GetUnreadChildrenNode(nsIMsgThread *thread, nsIRDFNode **target)
|
||||
{
|
||||
nsresult rv;
|
||||
nsAutoString emptyString("");
|
||||
PRUint32 numUnread;
|
||||
rv = thread->GetNumUnreadChildren(&numUnread);
|
||||
if(NS_SUCCEEDED(rv))
|
||||
{
|
||||
if(numUnread > 0)
|
||||
rv = createNode(numUnread, target, getRDFService());
|
||||
else
|
||||
rv = createNode(emptyString, target, getRDFService());
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult nsMsgMessageDataSource::GetTotalChildrenNode(nsIMsgThread *thread, nsIRDFNode **target)
|
||||
{
|
||||
nsresult rv;
|
||||
nsAutoString emptyString("");
|
||||
PRUint32 numChildren;
|
||||
rv = thread->GetNumChildren(&numChildren);
|
||||
if(NS_SUCCEEDED(rv))
|
||||
{
|
||||
if(numChildren > 0)
|
||||
rv = createNode(numChildren, target, getRDFService());
|
||||
else
|
||||
rv = createNode(emptyString, target, getRDFService());
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsMsgMessageDataSource::createMessageMessageChildNode(nsIMessage *message,
|
||||
nsIRDFNode **target)
|
||||
|
@ -1098,6 +1258,20 @@ PRBool nsMsgMessageDataSource::IsThreadsFirstMessage(nsIMsgThread *thread, nsIMe
|
|||
|
||||
}
|
||||
|
||||
nsresult nsMsgMessageDataSource::GetThreadsFirstMessage(nsIMsgThread *thread, nsIMsgFolder *folder, nsIMessage **message)
|
||||
{
|
||||
nsCOMPtr<nsIMsgDBHdr> firstHdr;
|
||||
nsresult rv;
|
||||
|
||||
rv = thread->GetRootHdr(nsnull, getter_AddRefs(firstHdr));
|
||||
if(NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
rv = folder->CreateMessageFromMsgDBHdr(firstHdr, message);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsMsgMessageDataSource::DoMarkMessagesRead(nsISupportsArray *messages, PRBool markRead)
|
||||
{
|
||||
|
|
|
@ -141,12 +141,15 @@ protected:
|
|||
nsresult createMessageSizeNode(nsIMessage *message,
|
||||
nsIRDFNode **target);
|
||||
|
||||
nsresult createMessageIsUnreadNode(nsIMessage *message, nsIRDFNode **target);
|
||||
|
||||
nsresult createMessageUnreadNode(nsIMessage *message, nsIRDFNode **target);
|
||||
nsresult createMessageTotalNode(nsIMessage *message, nsIRDFNode **target);
|
||||
nsresult createMessageMessageChildNode(nsIMessage* message, nsIRDFNode **target);
|
||||
nsresult GetMessageFolderAndThread(nsIMessage *message, nsIMsgFolder **folder,
|
||||
nsIMsgThread **thread);
|
||||
PRBool IsThreadsFirstMessage(nsIMsgThread *thread, nsIMessage *message);
|
||||
nsresult GetThreadsFirstMessage(nsIMsgThread *thread, nsIMsgFolder *folder, nsIMessage **message);
|
||||
|
||||
nsresult DoMarkMessagesRead(nsISupportsArray *messages, PRBool markRead);
|
||||
nsresult DoMarkMessagesFlagged(nsISupportsArray *messages, PRBool markFlagged);
|
||||
|
@ -166,6 +169,15 @@ protected:
|
|||
nsresult OnItemAddedOrRemoved(nsISupports *parentItem, nsISupports *item, const char *viewString,
|
||||
PRBool added);
|
||||
|
||||
nsresult OnChangeStatus(nsIRDFResource *resource, PRUint32 oldFlag, PRUint32 newFlag);
|
||||
nsresult OnChangeStatusString(nsIRDFResource *resource, PRUint32 oldFlag, PRUint32 newFlag);
|
||||
nsresult OnChangeIsUnread(nsIRDFResource *resource, PRUint32 oldFlag, PRUint32 newFlag);
|
||||
nsresult OnChangeUnreadMessageCount(nsIMessage *message);
|
||||
nsresult OnChangeTotalMessageCount(nsIMessage *message);
|
||||
|
||||
nsresult GetUnreadChildrenNode(nsIMsgThread *thread, nsIRDFNode **target);
|
||||
nsresult GetTotalChildrenNode(nsIMsgThread *thread, nsIRDFNode **target);
|
||||
|
||||
static nsIRDFResource* kNC_Subject;
|
||||
static nsIRDFResource* kNC_SubjectCollation;
|
||||
static nsIRDFResource* kNC_Sender;
|
||||
|
@ -178,6 +190,7 @@ protected:
|
|||
static nsIRDFResource* kNC_Total;
|
||||
static nsIRDFResource* kNC_Unread;
|
||||
static nsIRDFResource* kNC_MessageChild;
|
||||
static nsIRDFResource* kNC_IsUnread;
|
||||
|
||||
|
||||
// commands
|
||||
|
@ -199,6 +212,8 @@ protected:
|
|||
nsCOMPtr<nsIRDFNode> kForwardedLiteral;
|
||||
nsCOMPtr<nsIRDFNode> kNewLiteral;
|
||||
nsCOMPtr<nsIRDFNode> kReadLiteral;
|
||||
nsCOMPtr<nsIRDFNode> kTrueLiteral;
|
||||
nsCOMPtr<nsIRDFNode> kFalseLiteral;
|
||||
|
||||
nsCOMPtr<nsISupportsArray> kThreadsArcsOutArray;
|
||||
nsCOMPtr<nsISupportsArray> kNoThreadsArcsOutArray;
|
||||
|
|
|
@ -348,24 +348,21 @@ nsMsgRDFDataSource::getRDFService()
|
|||
|
||||
nsresult nsMsgRDFDataSource::NotifyPropertyChanged(nsIRDFResource *resource,
|
||||
nsIRDFResource *propertyResource,
|
||||
const char *oldValue, const char *newValue)
|
||||
const char *newValue)
|
||||
{
|
||||
nsCOMPtr<nsIRDFNode> oldValueNode, newValueNode;
|
||||
nsString oldValueStr = oldValue;
|
||||
nsCOMPtr<nsIRDFNode> newValueNode;
|
||||
nsString newValueStr = newValue;
|
||||
createNode(oldValueStr,getter_AddRefs(oldValueNode), getRDFService());
|
||||
createNode(newValueStr, getter_AddRefs(newValueNode), getRDFService());
|
||||
NotifyPropertyChanged(resource, propertyResource, oldValueNode, newValueNode);
|
||||
NotifyPropertyChanged(resource, propertyResource, newValueNode);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsMsgRDFDataSource::NotifyPropertyChanged(nsIRDFResource *resource,
|
||||
nsIRDFResource *propertyResource,
|
||||
nsIRDFNode *oldNode, nsIRDFNode *newNode)
|
||||
nsIRDFNode *newNode)
|
||||
{
|
||||
|
||||
NotifyObservers(resource, propertyResource, oldNode, PR_FALSE);
|
||||
NotifyObservers(resource, propertyResource, newNode, PR_TRUE);
|
||||
NotifyObservers(resource, propertyResource, newNode, PR_FALSE, PR_TRUE);
|
||||
return NS_OK;
|
||||
|
||||
}
|
||||
|
@ -373,12 +370,14 @@ nsresult nsMsgRDFDataSource::NotifyPropertyChanged(nsIRDFResource *resource,
|
|||
nsresult nsMsgRDFDataSource::NotifyObservers(nsIRDFResource *subject,
|
||||
nsIRDFResource *property,
|
||||
nsIRDFNode *object,
|
||||
PRBool assert)
|
||||
PRBool assert, PRBool change)
|
||||
{
|
||||
if(mObservers)
|
||||
{
|
||||
nsMsgRDFNotification note = { subject, property, object };
|
||||
if (assert)
|
||||
if(change)
|
||||
mObservers->EnumerateForwards(changeEnumFunc, ¬e);
|
||||
else if (assert)
|
||||
mObservers->EnumerateForwards(assertEnumFunc, ¬e);
|
||||
else
|
||||
mObservers->EnumerateForwards(unassertEnumFunc, ¬e);
|
||||
|
@ -410,6 +409,17 @@ nsMsgRDFDataSource::unassertEnumFunc(nsISupports *aElement, void *aData)
|
|||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsMsgRDFDataSource::changeEnumFunc(nsISupports *aElement, void *aData)
|
||||
{
|
||||
nsMsgRDFNotification* note = (nsMsgRDFNotification *)aData;
|
||||
nsIRDFObserver* observer = (nsIRDFObserver *)aElement;
|
||||
|
||||
observer->OnChange(note->subject,
|
||||
note->property,
|
||||
nsnull, note->object);
|
||||
return PR_TRUE;
|
||||
}
|
||||
nsresult
|
||||
nsMsgRDFDataSource::GetTransactionManager(nsISupportsArray *aSources, nsITransactionManager **aTransactionManager)
|
||||
{
|
||||
|
|
|
@ -56,14 +56,15 @@ class nsMsgRDFDataSource : public nsIRDFDataSource,
|
|||
nsIRDFService *getRDFService();
|
||||
static PRBool assertEnumFunc(nsISupports *aElement, void *aData);
|
||||
static PRBool unassertEnumFunc(nsISupports *aElement, void *aData);
|
||||
static PRBool changeEnumFunc(nsISupports *aElement, void *aData);
|
||||
nsresult NotifyObservers(nsIRDFResource *subject, nsIRDFResource *property,
|
||||
nsIRDFNode *object, PRBool assert);
|
||||
nsIRDFNode *object, PRBool assert, PRBool change);
|
||||
nsresult NotifyPropertyChanged(nsIRDFResource *resource,
|
||||
nsIRDFResource *propertyResource,
|
||||
const char *oldValue, const char *newValue);
|
||||
const char *newValue);
|
||||
nsresult NotifyPropertyChanged(nsIRDFResource *resource,
|
||||
nsIRDFResource *propertyResource,
|
||||
nsIRDFNode *oldNode, nsIRDFNode *newNode);
|
||||
nsIRDFNode *newNode);
|
||||
nsresult GetTransactionManager(nsISupportsArray *sources, nsITransactionManager **aTransactionManager);
|
||||
|
||||
nsCOMPtr<nsIMsgWindow> mWindow;
|
||||
|
|
|
@ -45,6 +45,7 @@ typedef struct _nsMsgRDFNotification {
|
|||
#define NC_RDF_FLAGGED NC_NAMESPACE_URI "Flagged"
|
||||
#define NC_RDF_PRIORITY NC_NAMESPACE_URI "Priority"
|
||||
#define NC_RDF_SIZE NC_NAMESPACE_URI "Size"
|
||||
#define NC_RDF_ISUNREAD NC_NAMESPACE_URI "IsUnread"
|
||||
|
||||
#define NC_RDF_CHILD NC_NAMESPACE_URI "child"
|
||||
#define NC_RDF_MESSAGECHILD NC_NAMESPACE_URI "MessageChild"
|
||||
|
|
|
@ -467,6 +467,11 @@ NS_IMETHODIMP nsMsgThread::MarkChildRead(PRBool bRead)
|
|||
{
|
||||
nsresult ret = NS_OK;
|
||||
|
||||
if(bRead)
|
||||
ChangeUnreadChildCount(-1);
|
||||
else
|
||||
ChangeUnreadChildCount(1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче