Back to index

lightning-sunbird  0.9+nobinonly
Public Member Functions | Public Attributes | Protected Member Functions | Protected Attributes | Friends
nsMsgThread Class Reference

#include <nsMsgThread.h>

Inheritance diagram for nsMsgThread:
Inheritance graph
[legend]
Collaboration diagram for nsMsgThread:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 nsMsgThread ()
 nsMsgThread (nsMsgDatabase *db, nsIMdbTable *table)
virtual ~nsMsgThread ()
NS_DECL_ISUPPORTS
NS_DECL_NSIMSGTHREAD
nsIMdbTable
GetMDBTable ()
nsIMdbRowGetMetaRow ()
void AddChild (in nsIMsgDBHdr child, in nsIMsgDBHdr inReplyTo, in boolean threadInThread, in nsIDBChangeAnnouncer announcer)
nsIMsgDBHdr GetChildAt (in long index)
nsMsgKey GetChildKeyAt (in long index)
nsIMsgDBHdr GetChild (in nsMsgKey msgKey)
nsIMsgDBHdr GetChildHdrAt (in long index)
nsIMsgDBHdr GetRootHdr (out long index)
void RemoveChildAt (in long index)
void RemoveChildHdr (in nsIMsgDBHdr child, in nsIDBChangeAnnouncer announcer)
void MarkChildRead (in boolean bRead)
nsIMsgDBHdr GetFirstUnreadChild ()
nsISimpleEnumerator EnumerateMessages (in nsMsgKey parent)

Public Attributes

nsMsgDatabasem_mdbDB
attribute nsMsgKey threadKey
attribute unsigned long flags
attribute string subject
attribute unsigned long newestMsgDate
readonly attribute unsigned long numChildren
readonly attribute unsigned long numUnreadChildren

Protected Member Functions

void Init ()
virtual nsresult InitCachedValues ()
nsresult ChangeChildCount (PRInt32 delta)
nsresult ChangeUnreadChildCount (PRInt32 delta)
nsresult RemoveChild (nsMsgKey msgKey)
nsresult SetThreadRootKey (nsMsgKey threadRootKey)
nsresult GetChildHdrForKey (nsMsgKey desiredKey, nsIMsgDBHdr **result, PRInt32 *resultIndex)
nsresult RerootThread (nsIMsgDBHdr *newParentOfOldRoot, nsIMsgDBHdr *oldRoot, nsIDBChangeAnnouncer *announcer)
nsresult ReparentChildrenOf (nsMsgKey oldParent, nsMsgKey newParent, nsIDBChangeAnnouncer *announcer)
nsresult ReparentNonReferenceChildrenOf (nsIMsgDBHdr *topLevelHdr, nsMsgKey newParentKey, nsIDBChangeAnnouncer *announcer)
nsresult ReparentMsgsWithInvalidParent (PRUint32 numChildren, nsMsgKey threadParentKey)

Protected Attributes

nsMsgKey m_threadKey
PRUint32 m_numChildren
PRUint32 m_numUnreadChildren
PRUint32 m_flags
nsIMdbTablem_mdbTable
nsIMdbRowm_metaRow
PRBool m_cachedValuesInitialized
nsMsgKey m_threadRootKey
PRUint32 m_newestMsgDate

Friends

class nsMsgThreadEnumerator

Detailed Description

Definition at line 50 of file nsMsgThread.h.


Constructor & Destructor Documentation

Definition at line 48 of file nsMsgThread.cpp.

Here is the call graph for this function:

Definition at line 54 of file nsMsgThread.cpp.

{
  MOZ_COUNT_CTOR(nsMsgThread);
  Init();
  m_mdbTable = table;
  m_mdbDB = db;
  if (db)
    db->AddRef();
  
  if (table && db)
  {
    table->GetMetaRow(db->GetEnv(), nsnull, nsnull, &m_metaRow);
    InitCachedValues();
  }
}

Here is the call graph for this function:

Definition at line 85 of file nsMsgThread.cpp.

{
  MOZ_COUNT_DTOR(nsMsgThread);
  if (m_mdbTable)
    m_mdbTable->Release();
  if (m_mdbDB)
    m_mdbDB->Release();
  if (m_metaRow)
    m_metaRow->Release();
}

Member Function Documentation

void nsIMsgThread::AddChild ( in nsIMsgDBHdr  child,
in nsIMsgDBHdr  inReplyTo,
in boolean  threadInThread,
in nsIDBChangeAnnouncer  announcer 
) [inherited]

Here is the caller graph for this function:

Definition at line 987 of file nsMsgThread.cpp.

{
  nsresult ret;

  PRUint32 childCount = 0;
  m_mdbDB->RowCellColumnToUInt32(m_metaRow, m_mdbDB->m_threadChildrenColumnToken, childCount);
  
  NS_ASSERTION(childCount != 0 || delta > 0, "child count gone negative");
  childCount += delta;
  
  NS_ASSERTION((PRInt32) childCount >= 0, "child count gone to 0 or below");
  if ((PRInt32) childCount < 0)    // force child count to >= 0
    childCount = 0;
  
  ret = m_mdbDB->UInt32ToRowCellColumn(m_metaRow, m_mdbDB->m_threadChildrenColumnToken, childCount);
  m_numChildren = childCount;
  return ret;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 1006 of file nsMsgThread.cpp.

{
  nsresult ret;

  PRUint32 childCount = 0;
  m_mdbDB->RowCellColumnToUInt32(m_metaRow, m_mdbDB->m_threadUnreadChildrenColumnToken, childCount);
  childCount += delta;
  if ((PRInt32) childCount < 0)
  {
#ifdef DEBUG_bienvenu1
    NS_ASSERTION(PR_FALSE, "negative unread child count");
#endif
    childCount = 0;
  }
  ret = m_mdbDB->UInt32ToRowCellColumn(m_metaRow, m_mdbDB->m_threadUnreadChildrenColumnToken, childCount);
  m_numUnreadChildren = childCount;
  return ret;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Here is the caller graph for this function:

nsIMsgDBHdr nsIMsgThread::GetChild ( in nsMsgKey  msgKey) [inherited]

Here is the caller graph for this function:

nsIMsgDBHdr nsIMsgThread::GetChildAt ( in long  index) [inherited]

Here is the caller graph for this function:

nsresult nsMsgThread::GetChildHdrForKey ( nsMsgKey  desiredKey,
nsIMsgDBHdr **  result,
PRInt32 resultIndex 
) [protected]

Definition at line 1031 of file nsMsgThread.cpp.

{
  PRUint32 numChildren;
  PRUint32 childIndex = 0;
  nsresult rv = NS_OK;        // XXX or should this default to an error?
  
  if (!result)
    return NS_ERROR_NULL_POINTER;
  
  GetNumChildren(&numChildren);
  
  if ((PRInt32) numChildren < 0)
    numChildren = 0;
  
  for (childIndex = 0; childIndex < numChildren; childIndex++)
  {
    rv = GetChildHdrAt(childIndex, result);
    if (NS_SUCCEEDED(rv) && *result)
    {
      nsMsgKey msgKey;
      // we're only doing one level of threading, so check if caller is
      // asking for children of the first message in the thread or not.
      // if not, we will tell him there are no children.
      (*result)->GetMessageKey(&msgKey);
      
      if (msgKey == desiredKey)
      {
        nsMsgKey threadKey;
        (*result)->GetThreadId(&threadKey);
        if (threadKey != m_threadKey) // this msg isn't in this thread
        {
          PRUint32 msgSize;
          (*result)->GetMessageSize(&msgSize);
          if (msgSize == 0) // this is a phantom message - let's get rid of it.
            RemoveChild(msgKey);
          rv = NS_ERROR_UNEXPECTED;
        }
        break;
      }
      NS_RELEASE(*result);
    }
  }
  if (resultIndex)
    *resultIndex = childIndex;
  
  return rv;
}

Here is the call graph for this function:

nsMsgKey nsIMsgThread::GetChildKeyAt ( in long  index) [inherited]

Here is the caller graph for this function:

Here is the caller graph for this function:

NS_DECL_ISUPPORTS NS_DECL_NSIMSGTHREAD nsIMdbTable* nsMsgThread::GetMDBTable ( ) [inline]

Definition at line 62 of file nsMsgThread.h.

{return m_mdbTable;}

Definition at line 63 of file nsMsgThread.h.

{return m_metaRow;}
nsIMsgDBHdr nsIMsgThread::GetRootHdr ( out long  index) [inherited]

Here is the caller graph for this function:

void nsMsgThread::Init ( void  ) [protected]
nsresult nsMsgThread::InitCachedValues ( ) [protected, virtual]

Definition at line 96 of file nsMsgThread.cpp.

Here is the call graph for this function:

Here is the caller graph for this function:

void nsIMsgThread::MarkChildRead ( in boolean  bRead) [inherited]
nsresult nsMsgThread::RemoveChild ( nsMsgKey  msgKey) [protected]

Definition at line 543 of file nsMsgThread.cpp.

{
  nsresult ret;

  mdbOid             rowObjectId;
  rowObjectId.mOid_Id = msgKey;
  rowObjectId.mOid_Scope = m_mdbDB->m_hdrRowScopeToken;
  ret = m_mdbTable->CutOid(m_mdbDB->GetEnv(), &rowObjectId);
  // if this thread is empty, remove it from the all threads table.
  if (m_numChildren == 0 && m_mdbDB->m_mdbAllThreadsTable)
  {
    mdbOid rowID;
    rowID.mOid_Id = m_threadKey;
    rowID.mOid_Scope = m_mdbDB->m_threadRowScopeToken;
    
    m_mdbDB->m_mdbAllThreadsTable->CutOid(m_mdbDB->GetEnv(), &rowID);
  }
#if 0 // this seems to cause problems
  if (m_numChildren == 0 && m_metaRow && m_mdbDB)
    m_metaRow->CutAllColumns(m_mdbDB->GetEnv());
#endif
  
  return ret;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void nsIMsgThread::RemoveChildAt ( in long  index) [inherited]

Here is the caller graph for this function:

void nsIMsgThread::RemoveChildHdr ( in nsIMsgDBHdr  child,
in nsIDBChangeAnnouncer  announcer 
) [inherited]
nsresult nsMsgThread::ReparentChildrenOf ( nsMsgKey  oldParent,
nsMsgKey  newParent,
nsIDBChangeAnnouncer announcer 
) [protected]

Definition at line 595 of file nsMsgThread.cpp.

{
  nsresult rv = NS_OK;
  
  PRUint32 numChildren;
  PRUint32 childIndex = 0;
  
  GetNumChildren(&numChildren);
  
  nsCOMPtr <nsIMsgDBHdr> curHdr;
  if (numChildren > 0)
  {
    for (childIndex = 0; childIndex < numChildren; childIndex++)
    {
      rv = GetChildHdrAt(childIndex, getter_AddRefs(curHdr));
      if (NS_SUCCEEDED(rv) && curHdr)
      {
        nsMsgKey threadParent;
        
        curHdr->GetThreadParent(&threadParent);
        if (threadParent == oldParent)
        {
          nsMsgKey curKey;
          
          curHdr->SetThreadParent(newParent);
          curHdr->GetMessageKey(&curKey);
          if (announcer)
            announcer->NotifyParentChangedAll(curKey, oldParent, newParent, nsnull);
          // if the old parent was the root of the thread, then only the first child gets 
          // promoted to root, and other children become children of the new root.
          if (newParent == nsMsgKey_None)
          {
            SetThreadRootKey(curKey);
            newParent = curKey;
          }
        }
      }
    }
  }
  return rv;
}

Here is the call graph for this function:

nsresult nsMsgThread::ReparentMsgsWithInvalidParent ( PRUint32  numChildren,
nsMsgKey  threadParentKey 
) [protected]

Definition at line 902 of file nsMsgThread.cpp.

{
  nsresult ret = NS_OK;
  // run through looking for messages that don't have a correct parent, 
  // i.e., a parent that's in the thread!
  for (PRInt32 childIndex = 0; childIndex < (PRInt32) numChildren; childIndex++)
  {
    nsCOMPtr <nsIMsgDBHdr> curChild;
    ret  = GetChildHdrAt(childIndex, getter_AddRefs(curChild));
    if (NS_SUCCEEDED(ret) && curChild)
    {
      nsMsgKey parentKey;
      nsCOMPtr <nsIMsgDBHdr> parent;
      
      curChild->GetThreadParent(&parentKey);
      
      if (parentKey != nsMsgKey_None)
      {
        GetChild(parentKey, getter_AddRefs(parent));
        if (!parent)
          curChild->SetThreadParent(threadParentKey);
      }
    }
  }
  return ret;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsMsgThread::ReparentNonReferenceChildrenOf ( nsIMsgDBHdr topLevelHdr,
nsMsgKey  newParentKey,
nsIDBChangeAnnouncer announcer 
) [protected]

Definition at line 407 of file nsMsgThread.cpp.

{
  nsCOMPtr <nsIMsgDBHdr> curHdr;
  PRUint32 numChildren;
  PRUint32 childIndex = 0;
  
  GetNumChildren(&numChildren);
  for (childIndex = 0; childIndex < numChildren; childIndex++)
  {
    nsMsgKey oldTopLevelHdrKey;
    
    oldTopLevelHdr->GetMessageKey(&oldTopLevelHdrKey);
    nsresult ret = GetChildHdrAt(childIndex, getter_AddRefs(curHdr));
    if (NS_SUCCEEDED(ret) && curHdr)
    {
      nsMsgKey oldThreadParent, curHdrKey;
      nsMsgHdr* oldTopLevelMsgHdr = NS_STATIC_CAST(nsMsgHdr*, oldTopLevelHdr);      // closed system, cast ok
      curHdr->GetThreadParent(&oldThreadParent);
      curHdr->GetMessageKey(&curHdrKey);
      if (oldThreadParent == oldTopLevelHdrKey && curHdrKey != newParentKey && !oldTopLevelMsgHdr->IsParentOf(curHdr))
      {
        curHdr->GetThreadParent(&oldThreadParent);
        curHdr->SetThreadParent(newParentKey);
        // OK, this is a reparenting - need to send notification
        if (announcer)
          announcer->NotifyParentChangedAll(curHdrKey, oldThreadParent, newParentKey, nsnull);
      }
    }
  }
  return NS_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

nsresult nsMsgThread::RerootThread ( nsIMsgDBHdr newParentOfOldRoot,
nsIMsgDBHdr oldRoot,
nsIDBChangeAnnouncer announcer 
) [protected]

Definition at line 203 of file nsMsgThread.cpp.

{
  nsCOMPtr <nsIMsgDBHdr> ancestorHdr = newParentOfOldRoot;
  nsMsgKey newRoot;
  newParentOfOldRoot->GetMessageKey(&newRoot);
  mdb_pos outPos;

  nsMsgKey newHdrAncestor;
  ancestorHdr->GetMessageKey(&newRoot);
  nsresult rv = NS_OK;
  // loop trying to find the oldest ancestor of this msg
  // that is a parent of the root. The oldest ancestor will
  // become the root of the thread.
  do 
  {
    ancestorHdr->GetThreadParent(&newHdrAncestor);
    if (newHdrAncestor != nsMsgKey_None && newHdrAncestor != m_threadRootKey && newHdrAncestor != newRoot)
    {
      newRoot = newHdrAncestor;
      rv = m_mdbDB->GetMsgHdrForKey(newRoot, getter_AddRefs(ancestorHdr));
    }
  }
  while (NS_SUCCEEDED(rv) && ancestorHdr && newHdrAncestor != nsMsgKey_None && newHdrAncestor != m_threadRootKey
    && newHdrAncestor != newRoot);
  SetThreadRootKey(newRoot);
  ReparentNonReferenceChildrenOf(oldRoot, newRoot, announcer);
  if (ancestorHdr)
  {
    nsIMsgDBHdr *msgHdr = ancestorHdr;
    nsMsgHdr* rootMsgHdr = NS_STATIC_CAST(nsMsgHdr*, msgHdr);          // closed system, cast ok
    nsIMdbRow *newRootHdrRow = rootMsgHdr->GetMDBRow();
    // move the  root hdr to pos 0.
    m_mdbTable->MoveRow(m_mdbDB->GetEnv(), newRootHdrRow, -1, 0, &outPos);
    ancestorHdr->SetThreadParent(nsMsgKey_None);
  }
  return rv;
}

Here is the call graph for this function:

nsresult nsMsgThread::SetThreadRootKey ( nsMsgKey  threadRootKey) [protected]

Definition at line 1025 of file nsMsgThread.cpp.

Here is the call graph for this function:

Here is the caller graph for this function:


Friends And Related Function Documentation

friend class nsMsgThreadEnumerator [friend]

Definition at line 56 of file nsMsgThread.h.


Member Data Documentation

attribute unsigned long nsIMsgThread::flags [inherited]

Definition at line 49 of file nsIMsgThread.idl.

Definition at line 89 of file nsMsgThread.h.

Definition at line 86 of file nsMsgThread.h.

Definition at line 64 of file nsMsgThread.h.

Definition at line 87 of file nsMsgThread.h.

Definition at line 88 of file nsMsgThread.h.

Definition at line 91 of file nsMsgThread.h.

Definition at line 84 of file nsMsgThread.h.

Definition at line 85 of file nsMsgThread.h.

Definition at line 83 of file nsMsgThread.h.

Definition at line 90 of file nsMsgThread.h.

Definition at line 51 of file nsIMsgThread.idl.

readonly attribute unsigned long nsIMsgThread::numChildren [inherited]

Definition at line 52 of file nsIMsgThread.idl.

readonly attribute unsigned long nsIMsgThread::numUnreadChildren [inherited]

Definition at line 53 of file nsIMsgThread.idl.

Definition at line 50 of file nsIMsgThread.idl.

Definition at line 48 of file nsIMsgThread.idl.


The documentation for this class was generated from the following files: