Update of /cvsroot/mahogany/M/src/mail
In directory usw-pr-cvs1:/tmp/cvs-serv10213/src/mail

Modified Files:
        MailFolderCC.cpp MailFolderCmn.cpp Message.cpp VFolder.cpp 
Added Files:
        VMessage.cpp 
Log Message:
1. added MessageVirt class implementing a Message in MailFolderVirt
   (solves the problem with previewing messages in the virtual folders)
2. refactored the status change processing code (fixes changing status
   of a message in a virtual folder)


***** Error reading new file: [Errno 2] No such file or directory: 'VMessage.cpp'
Index: MailFolderCC.cpp
===================================================================
RCS file: /cvsroot/mahogany/M/src/mail/MailFolderCC.cpp,v
retrieving revision 1.633
retrieving revision 1.634
diff -b -u -2 -r1.633 -r1.634
--- MailFolderCC.cpp    16 Jul 2002 20:21:44 -0000      1.633
+++ MailFolderCC.cpp    17 Jul 2002 14:43:55 -0000      1.634
@@ -1435,33 +1435,4 @@
 }
 
-// msg status info
-//
-// NB: name MessageStatus is already taken by MailFolder
-struct MsgStatus
-{
-   bool recent;
-   bool unread;
-   bool newmsgs;
-   bool flagged;
-   bool searched;
-};
-
-// is this message recent/new/unread/...?
-static MsgStatus AnalyzeStatus(int stat)
-{
-   MsgStatus status;
-
-   // deal with recent and new (== recent and !seen)
-   status.recent = (stat & MailFolder::MSG_STAT_RECENT) != 0;
-   status.unread = !(stat & MailFolder::MSG_STAT_SEEN);
-   status.newmsgs = status.recent && status.unread;
-
-   // and also count flagged and searched messages
-   status.flagged = (stat & MailFolder::MSG_STAT_FLAGGED) != 0;
-   status.searched = (stat & MailFolder::MSG_STAT_SEARCHED ) != 0;
-
-   return status;
-}
-
 // ----------------------------------------------------------------------------
 // header decoding
@@ -1733,8 +1704,5 @@
 
    m_expungedMsgnos =
-   m_expungedPositions =
-   m_statusChangedMsgnos =
-   m_statusChangedOld =
-   m_statusChangedNew = NULL;
+   m_expungedPositions = NULL;
 
    m_gotUnprocessedNewMail =
@@ -1773,14 +1741,4 @@
    }
 
-   // these arrays must have been cleared by OnMsgStatusChanged() earlier
-   if ( m_statusChangedMsgnos )
-   {
-      FAIL_MSG( "m_statusChangedMsgnos unexpectedly != NULL" );
-
-      delete m_statusChangedMsgnos;
-      delete m_statusChangedOld;
-      delete m_statusChangedNew;
-   }
-
    m_Profile->DecRef();
    m_mfolder->DecRef();
@@ -2446,13 +2404,9 @@
    DiscardExpungeData();
 
-   if ( m_statusChangedMsgnos )
+   if ( m_statusChangeData )
    {
-      delete m_statusChangedMsgnos;
-      delete m_statusChangedOld;
-      delete m_statusChangedNew;
-
-      m_statusChangedMsgnos =
-      m_statusChangedOld =
-      m_statusChangedNew = NULL;
+      delete m_statusChangeData;
+
+      m_statusChangeData = NULL;
    }
 
@@ -3691,79 +3645,4 @@
 
 void
-MailFolderCC::OnMsgStatusChanged()
-{
-   // we only send MEventId_MailFolder_OnMsgStatus events if something really
-   // changed, so this is not suposed to happen
-   CHECK_RET( m_statusChangedMsgnos, "unexpected OnMsgStatusChanged() call" );
-
-   // first update the cached status
-   MailFolderStatus status;
-   MfStatusCache *mfStatusCache = MfStatusCache::Get();
-   if ( mfStatusCache->GetStatus(GetName(), &status) )
-   {
-      size_t count = m_statusChangedMsgnos->GetCount();
-      for ( size_t n = 0; n < count; n++ )
-      {
-         int statusNew = m_statusChangedNew->Item(n),
-             statusOld = m_statusChangedOld->Item(n);
-
-         bool wasDeleted = (statusOld & MSG_STAT_DELETED) != 0,
-              isDeleted = (statusNew & MSG_STAT_DELETED) != 0;
-
-         MsgStatus msgStatusOld = AnalyzeStatus(statusOld),
-                   msgStatusNew = AnalyzeStatus(statusNew);
-
-         // we consider that a message has some flag only if it is not deleted
-         // (which is discussable at least for flagged and searched flags
-         // although, OTOH, why flag a deleted message?)
-
-         #define UPDATE_NUM_OF(what)   \
-            if ( (!isDeleted && msgStatusNew.what) && \
-                 (wasDeleted || !msgStatusOld.what) ) \
-            { \
-               wxLogTrace(M_TRACE_MFSTATUS, "%s: " #what "++ (now %lu)", \
-                          GetName().c_str(), status.what + 1); \
-               status.what++; \
-            } \
-            else if ( (!wasDeleted && msgStatusOld.what) && \
-                      (isDeleted || !msgStatusNew.what) ) \
-               if ( status.what > 0 ) \
-               { \
-                  wxLogTrace(M_TRACE_MFSTATUS, "%s: " #what "-- (now %lu)", \
-                             GetName().c_str(), status.what - 1); \
-                  status.what--; \
-               } \
-               else \
-                  FAIL_MSG( "error in msg status change logic" )
-
-         UPDATE_NUM_OF(recent);
-         UPDATE_NUM_OF(unread);
-         UPDATE_NUM_OF(newmsgs);
-         UPDATE_NUM_OF(flagged);
-         UPDATE_NUM_OF(searched);
-
-         #undef UPDATE_NUM_OF
-      }
-
-      mfStatusCache->UpdateStatus(GetName(), status);
-   }
-
-   // next notify everyone else about the status change
-   wxLogTrace(TRACE_MF_EVENTS,
-              "Sending MsgStatus event for %u msgs in folder '%s'",
-              m_statusChangedMsgnos->GetCount(), GetName().c_str());
-
-   MEventManager::Send(new MEventMsgStatusData(this,
-                                               m_statusChangedMsgnos,
-                                               m_statusChangedOld,
-                                               m_statusChangedNew));
-
-   // MEventMsgStatusData will delete them
-   m_statusChangedMsgnos =
-   m_statusChangedOld =
-   m_statusChangedNew = NULL;
-}
-
-void
 MailFolderCC::UpdateMessageStatus(unsigned long msgno)
 {
@@ -3800,9 +3679,7 @@
          // also when we allocate the arrays for msg status change data
          bool sendEvent;
-         if ( !m_statusChangedMsgnos )
+         if ( !m_statusChangeData )
          {
-            m_statusChangedMsgnos = new wxArrayInt;
-            m_statusChangedOld = new wxArrayInt;
-            m_statusChangedNew = new wxArrayInt;
+            m_statusChangeData = new StatusChangeData;
 
             sendEvent = true;
@@ -3814,7 +3691,7 @@
 
          // remember who changed and how
-         m_statusChangedMsgnos->Add(msgno);
-         m_statusChangedOld->Add(statusOld);
-         m_statusChangedNew->Add(statusNew);
+         m_statusChangeData->msgnos.Add(msgno);
+         m_statusChangeData->statusOld.Add(statusOld);
+         m_statusChangeData->statusNew.Add(statusNew);
 
          // and schedule call to our OnMsgStatusChanged() if not done yet
@@ -3831,4 +3708,13 @@
    }
    //else: flags didn't really change
+}
+
+void MailFolderCC::OnMsgStatusChanged()
+{
+   // normally the CCEventReflector event is generated only if the status of
+   // something has really changed...
+   ASSERT_MSG( m_statusChangeData, "unexpected OnMsgStatusChanged() call" );
+
+   SendMsgStatusChangeEvent();
 }
 

Index: MailFolderCmn.cpp
===================================================================
RCS file: /cvsroot/mahogany/M/src/mail/MailFolderCmn.cpp,v
retrieving revision 1.99
retrieving revision 1.100
diff -b -u -2 -r1.99 -r1.100
--- MailFolderCmn.cpp   16 Jul 2002 20:21:44 -0000      1.99
+++ MailFolderCmn.cpp   17 Jul 2002 14:43:56 -0000      1.100
@@ -612,4 +612,6 @@
    m_frame = NULL;
 
+   m_statusChangeData = NULL;
+
    m_MEventReceiver = new MfCmnEventReceiver(this);
 }
@@ -620,4 +622,12 @@
                "mismatch between Suspend/ResumeUpdates()" );
 
+   // this must have been cleared by SendMsgStatusChangeEvent() call earlier
+   if ( m_statusChangeData )
+   {
+      FAIL_MSG( "m_statusChangeData unexpectedly != NULL" );
+
+      delete m_statusChangeData;
+   }
+
    delete m_Timer;
    delete m_MEventReceiver;
@@ -2077,4 +2087,109 @@
 
    return status->HasSomething();
+}
+
+// ----------------------------------------------------------------------------
+// MailFolderCmn message status
+// ----------------------------------------------------------------------------
+
+// msg status info
+//
+// NB: name MessageStatus is already taken by MailFolder
+struct MsgStatus
+{
+   bool recent;
+   bool unread;
+   bool newmsgs;
+   bool flagged;
+   bool searched;
+};
+
+// is this message recent/new/unread/...?
+static MsgStatus AnalyzeStatus(int stat)
+{
+   MsgStatus status;
+
+   // deal with recent and new (== recent and !seen)
+   status.recent = (stat & MailFolder::MSG_STAT_RECENT) != 0;
+   status.unread = !(stat & MailFolder::MSG_STAT_SEEN);
+   status.newmsgs = status.recent && status.unread;
+
+   // and also count flagged and searched messages
+   status.flagged = (stat & MailFolder::MSG_STAT_FLAGGED) != 0;
+   status.searched = (stat & MailFolder::MSG_STAT_SEARCHED ) != 0;
+
+   return status;
+}
+
+void
+MailFolderCmn::SendMsgStatusChangeEvent()
+{
+   if ( !m_statusChangeData )
+   {
+      // nothing to do
+      return;
+   }
+
+   // first update the cached status
+   MailFolderStatus status;
+   MfStatusCache *mfStatusCache = MfStatusCache::Get();
+   if ( mfStatusCache->GetStatus(GetName(), &status) )
+   {
+      size_t count = m_statusChangeData->msgnos.GetCount();
+      for ( size_t n = 0; n < count; n++ )
+      {
+         int statusNew = m_statusChangeData->statusNew[n],
+             statusOld = m_statusChangeData->statusOld[n];
+
+         bool wasDeleted = (statusOld & MSG_STAT_DELETED) != 0,
+              isDeleted = (statusNew & MSG_STAT_DELETED) != 0;
+
+         MsgStatus msgStatusOld = AnalyzeStatus(statusOld),
+                   msgStatusNew = AnalyzeStatus(statusNew);
+
+         // we consider that a message has some flag only if it is not deleted
+         // (which is discussable at least for flagged and searched flags
+         // although, OTOH, why flag a deleted message?)
+
+         #define UPDATE_NUM_OF(what)   \
+            if ( (!isDeleted && msgStatusNew.what) && \
+                 (wasDeleted || !msgStatusOld.what) ) \
+            { \
+               wxLogTrace(M_TRACE_MFSTATUS, "%s: " #what "++ (now %lu)", \
+                          GetName().c_str(), status.what + 1); \
+               status.what++; \
+            } \
+            else if ( (!wasDeleted && msgStatusOld.what) && \
+                      (isDeleted || !msgStatusNew.what) ) \
+               if ( status.what > 0 ) \
+               { \
+                  wxLogTrace(M_TRACE_MFSTATUS, "%s: " #what "-- (now %lu)", \
+                             GetName().c_str(), status.what - 1); \
+                  status.what--; \
+               } \
+               else \
+                  FAIL_MSG( "error in msg status change logic" )
+
+         UPDATE_NUM_OF(recent);
+         UPDATE_NUM_OF(unread);
+         UPDATE_NUM_OF(newmsgs);
+         UPDATE_NUM_OF(flagged);
+         UPDATE_NUM_OF(searched);
+
+         #undef UPDATE_NUM_OF
+      }
+
+      mfStatusCache->UpdateStatus(GetName(), status);
+   }
+
+   // next notify everyone else about the status change
+   wxLogTrace(TRACE_MF_EVENTS,
+              "Sending MsgStatus event for %u msgs in folder '%s'",
+              m_statusChangeData->msgnos.GetCount(), GetName().c_str());
+
+   MEventManager::Send(new MEventMsgStatusData(this, m_statusChangeData));
+
+   // MEventMsgStatusData will delete them
+   m_statusChangeData = NULL;
 }
 

Index: Message.cpp
===================================================================
RCS file: /cvsroot/mahogany/M/src/mail/Message.cpp,v
retrieving revision 1.28
retrieving revision 1.29
diff -b -u -2 -r1.28 -r1.29
--- Message.cpp 18 Jun 2002 15:37:06 -0000      1.28
+++ Message.cpp 17 Jul 2002 14:43:56 -0000      1.29
@@ -459,2 +459,6 @@
 */
 
+Message::~Message()
+{
+}
+

Index: VFolder.cpp
===================================================================
RCS file: /cvsroot/mahogany/M/src/mail/VFolder.cpp,v
retrieving revision 1.3
retrieving revision 1.4
diff -b -u -2 -r1.3 -r1.4
--- VFolder.cpp 17 Jul 2002 13:02:54 -0000      1.3
+++ VFolder.cpp 17 Jul 2002 14:43:56 -0000      1.4
@@ -42,4 +42,5 @@
 #include "mail/Driver.h"
 #include "mail/VFolder.h"
+#include "mail/VMessage.h"
 #include "mail/ServerInfo.h"
 
@@ -481,7 +482,13 @@
 Message *MailFolderVirt::GetMessage(unsigned long uid)
 {
-   const Msg *msg = GetMsgFromUID(uid);
+   Msg *msg = GetMsgFromUID(uid);
+   if ( !msg )
+      return NULL;
 
-   return msg ? msg->mf->GetMessage(msg->uid) : NULL;
+   Message *message = msg->mf->GetMessage(msg->uid);
+   if ( !message )
+      return NULL;
+
+   return MessageVirt::Create(this, uid, &msg->flags, message);
 }
 
@@ -489,4 +496,15 @@
 MailFolderVirt::SetMessageFlag(unsigned long uid, int flag, bool set)
 {
+   if ( !DoSetMessageFlag(uid, flag, set) )
+      return false;
+
+   SendMsgStatusChangeEvent();
+
+   return true;
+}
+
+bool
+MailFolderVirt::DoSetMessageFlag(unsigned long uid, int flag, bool set)
+{
    Msg *msg = GetMsgFromUID(uid);
 
@@ -494,8 +512,32 @@
       return false;
 
-   if ( set )
-      msg->flags |= flag;
-   else
-      msg->flags &= ~flag;
+   int flagsOld = msg->flags;
+   int flagsNew = set ? (flagsOld | flag) : (flagsOld & ~flag);
+   if ( flagsOld == flagsNew )
+   {
+      // nothing changed
+      return true;
+   }
+
+   const MsgnoType msgno = uid; // UID == msgno here
+
+   HeaderInfoList_obj headers = GetHeaders();
+   CHECK( headers, false, "SetMessageFlag: couldn't get headers" );
+
+   HeaderInfo *hi = headers->GetItemByMsgno(msgno);
+   CHECK( hi, false, "SetMessageFlag: no header info for the given msgno?" );
+
+   // remember the old and new status of the changed messages
+   if ( !m_statusChangeData )
+   {
+      m_statusChangeData = new StatusChangeData;
+   }
+
+   m_statusChangeData->msgnos.Add(msgno);
+   m_statusChangeData->statusOld.Add(flagsOld);
+   m_statusChangeData->statusNew.Add(flagsNew);
+
+   hi->m_Status =
+   msg->flags = flagsNew;
 
    return true;
@@ -519,4 +561,6 @@
          rc = false;
    }
+
+   SendMsgStatusChangeEvent();
 
    return rc;



-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
_______________________________________________
Mahogany-cvsupdates mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/mahogany-cvsupdates

Reply via email to