📄 folderc.c
字号:
*/voidFolderC::ReadIndex(){ if ( debuglev > 0 ) cout <<"Reading index file \"" <<indexFile <<"\"" <<endl; if ( !OpenIndex() ) return;//// Loop through messages and read index entry for each// u_int msgCount = msgList->size(); int i=0; for (i=0; i<msgCount; i++) { MsgC *msg = (*msgList)[i];//// Set the offset to the current position// msg->indexOffset = ftell(indexfp);//// If the entry cannot be read, ignore the rest// if ( !msg->ReadIndex(indexfp) ) { msg->indexOffset = -1; CloseIndex(); return; } } // End for each message CloseIndex();} // End ReadIndex/*------------------------------------------------------------------------ * Method to print information */voidFolderC::Print(ostream& strm) const{ strm <<"Folder: " <<name; switch (type) { case (UNIX_FOLDER): strm <<" (Unix)"; break; case (MH_FOLDER): strm <<" (MH)"; break; case (MMDF_FOLDER): strm <<" (MMDF)"; break; case (IMAP_FOLDER): strm <<" (IMAP)"; break; case (UNKNOWN_FOLDER): strm <<" (Unknown)"; break; } if ( !writable ) strm <<" read-only"; strm <<endl; u_int count = msgList->size(); int i=0; for (i=0; i<count; i++) { MsgC *msg = (*msgList)[i]; strm <<*msg <<endl; }} // End Print/*------------------------------------------------------------------------ * Method to return total number of messages */int FolderC::MsgCount() const { return msgList->size(); }/*------------------------------------------------------------------------ * Method to return n'th message */MsgC *FolderC::MsgWithIndex(u_int n) const { return (*msgList)[n]; }/*------------------------------------------------------------------------ * Method to return numbered message */MsgC *FolderC::MsgWithNumber(int n) const{ u_int count = msgList->size(); int i=0; for (i=0; i<count; i++) { MsgC *msg = (*msgList)[i]; if ( msg->Number() == n ) return msg; } return NULL;}/*------------------------------------------------------------------------ * Method to see if there are non-deleted messages with the specified status */BooleanFolderC::HasMessagesWithStatus(StatusFn *statFn){//// If we haven't scanned, we might need to bring the index up to date.// if ( !scanned && indexFile.size() > 0 && !IndexValid() ) { UpdateIndex(); } // End if we might need to scan//// If we've already scanned this folder, use the message list// if ( scanned ) { u_int count = msgList->size(); int i=0; for (i=0; i<count; i++) { MsgC *msg = (*msgList)[i]; if ( msg->IsNew() && !msg->IsDeleted() ) return True; } }//// If we haven't scanned, use the index file// else if ( indexFile.size() > 0 ) {//// See if we can use the summary value// if ( !IndexSumValid() ) { if ( debuglev > 0 ) cout <<"Checking index status: \"" <<indexFile <<"\"" <<endl; indexSum = 0; if ( !OpenIndex() ) return False;//// Read lines//#define MAXLINE 255#define MSG_INDEX_RFMT "%08x %08x %08x %[^\n]\n" char line[MAXLINE]; char buf[128]; buf[0] = 0; u_int statVal; int bytes; int lines; while ( fgets(line, MAXLINE-1, indexfp) ) { sscanf(line, MSG_INDEX_RFMT, &statVal, &bytes, &lines, buf); indexSum |= statVal; } // End for each index line CloseIndex(); indexSumTime = time(0); } // End if index summary value is not valid return (*statFn)(indexSum); } // End if folder not yet scanned return False;} // End HasMessagesWithStatus/*------------------------------------------------------------------------ * Method to see if there are new messages */static BooleanStatusIsNew(u_int status){ return ((status & MSG_NEW) && !(status & MSG_DELETED));}BooleanFolderC::HasNewMessages(){ return HasMessagesWithStatus(StatusIsNew);}/*------------------------------------------------------------------------ * Method to see if there are unread messages */static BooleanStatusIsUnread(u_int status){ return !(status & (MSG_READ|MSG_DELETED));}BooleanFolderC::HasUnreadMessages(){ return HasMessagesWithStatus(StatusIsUnread);}/*------------------------------------------------------------------------ * Method to see if there are deleted messages */static BooleanStatusIsDeleted(u_int status){ return (status & MSG_DELETED);}BooleanFolderC::HasDeletedMessages(){ if ( msgItemList->size() > 0 || delItemList->size() > 0 ) return (delItemList->size() > 0); else return HasMessagesWithStatus(StatusIsDeleted);}/*------------------------------------------------------------------------ * Method to return number of new messages */intFolderC::NewMsgCount() const{ int newCount = 0; u_int count = msgList->size(); int i=0; for (i=0; i<count; i++) { MsgC *msg = (*msgList)[i]; if ( !msg->IsDeleted() && msg->IsNew() ) newCount++; } return newCount;}/*------------------------------------------------------------------------ * Method to return number of unread messages */intFolderC::UnreadMsgCount() const{ int ucount = 0; u_int count = msgList->size(); int i=0; for (i=0; i<count; i++) { MsgC *msg = (*msgList)[i]; if ( !msg->IsDeleted() && !msg->IsRead() && !msg->IsNew() ) ucount++; } return ucount;}/*------------------------------------------------------------------------ * Method to return number of saved messages */intFolderC::SavedMsgCount() const{ int scount = 0; u_int count = msgList->size(); int i=0; for (i=0; i<count; i++) { MsgC *msg = (*msgList)[i]; if ( msg->IsSaved() ) scount++; } return scount;}/*------------------------------------------------------------------------ * Method to return number of deleted messages */intFolderC::DeletedMsgCount() const{ int dcount = 0; u_int count = msgList->size(); int i=0; for (i=0; i<count; i++) { MsgC *msg = (*msgList)[i]; if ( msg->IsDeleted() ) dcount++; } return dcount;}/*------------------------------------------------------------------------ * Method to display messages in message list */voidFolderC::Activate(){ if ( active || !icon ) return; ishApp->Broadcast(""); ishApp->mainWin->FolderVBox().View()->ScrollToItem(*icon); VBoxC& vbox = ishApp->mainWin->MsgVBox(); vbox.RemoveAllItems();//// Read the messages if they haven't already been read.// If they have been read, check for new mail unless we're using a POP server.// Lock(True); if ( !scanned ) Scan(); else if ( !isInBox || !ishApp->appPrefs->usingPop ) { if ( IsImap() ) { ImapFolderC *If = (ImapFolderC*)this; if ( !If->Select() ) return; } NewMail(); } Lock(False); if ( scanned ) { active = True;//// Update the folder icon// UpdateIcon();//// Create any message icons needed and select any items from last time// CreateIcons(); vbox.SelectItemsOnly(*lastSelList); }//// Refresh the message list// vbox.Refresh();//// Add a time-out proc to Reset the scroll bars to their last positions unless// we scrolled to a new message.// XtAppAddTimeOut(ishApp->context, 100/*ms*/, (XtTimerCallbackProc)ResetScrollBar, (XtPointer)this);} // End Activate/*------------------------------------------------------------------------ * Method to remove messages from display */voidFolderC::Deactivate(){ if ( !active || !icon ) return; active = False;//// Save the position of the vertical scroll bar// VBoxC& vbox = ishApp->mainWin->MsgVBox(); lastVScroll = vbox.VScrollValue(); *lastSelList = vbox.SelItems(); vbox.RemoveAllItems(); vbox.Refresh(); if ( ishApp->undelWin ) ishApp->undelWin->Clear(); UpdateIcon();} // End Deactivate/*--------------------------------------------------------------- * Method to create a display icons for messages */voidFolderC::CreateIcons(){ Boolean showCount = (ishApp->mainWin->IsShown() && /*!ishApp->mainWin->IsIconified() &&*/ msgItemList->size() == 0);//// Create any message icons needed// u_int count = msgList->size(); StringC statusStr; int i=0; for (i=0; i<count; i++) {//// Update progress message if necessary// if ( showCount && (i % 10) == 0 ) { statusStr = abbrev; statusStr += " - Creating message icons: "; statusStr += i; ishApp->mainWin->Message(statusStr); }//// Create message icon// MsgC *msg = (*msgList)[i]; if ( msg->icon ) continue; msg->CreateIcon(); InsertInThread(msg->icon); if ( msg->IsDeleted() ) { //cout <<"Adding message " <<msg->Number() // <<" to deleted list with icon " <<msg->icon <<endl; delItemList->add(msg->icon); } else msgItemList->add(msg->icon); } // End for each message//// Update progress message if necessary// if ( showCount ) { statusStr = abbrev; statusStr += " - Creating message icons: "; statusStr += i; ishApp->mainWin->Message(statusStr); }//// Display items// VBoxC& vbox = ishApp->mainWin->MsgVBox(); vbox.SetSorted(False); vbox.AddItems(*msgItemList); if ( ishApp->appPrefs->hideDeleted ) { if ( ishApp->undelWin ) ishApp->undelWin->SetItems(*delItemList); } else vbox.AddItems(*delItemList); vbox.SetSorted(True);//// See if we need to display new messages// if ( ishApp->appPrefs->scrollToNew ) { MsgItemC *firstNew = NULL; MsgItemC *lastNew = NULL; VItemListC& list = vbox.VisItems(); u_int count = list.size(); int i=0; for (i=0; i<count; i++) { MsgItemC *item = (MsgItemC*)list[i]; if ( !item->IsDeleted() && !item->IsRead() ) { if ( !firstNew ) firstNew = item; lastNew = item; } }//// Scroll to the last then the first to display as many new messages// as possible// if ( lastNew ) { vbox.View()->ScrollToItem(*lastNew); vbox.View()->ScrollToItem(*firstNew); } } // End if scrolling to new messages vbox.Refresh(); UpdateIcon(); ishApp->mainWin->ClearMessage();} // End CreateIcons/*--------------------------------------------------------------- * Timer proc to reset vertical scroll bar to its previous position */voidFolderC::ResetScrollBar(FolderC *This, XtIntervalId*){ if ( !This->icon ) return; VBoxC& vbox = ishApp->mainWin->MsgVBox(); MsgC *lastNew = (ishApp->appPrefs->scrollToNew ? This->NewestMsg() : (MsgC*)NULL); if ( lastNew ) vbox.View()->ScrollToItem(*lastNew->icon); else { Widget sb = vbox.VScrollBar(); int val, size, inc, pinc, max; XmScrollBarGetValues(sb, &val, &size, &inc, &pinc); XtVaGetValues(sb, XmNmaximum, &max, NULL); if ( This->lastVScroll + size > max ) This->lastVScroll = max - size; XmScrollBarSetValues(sb, This->lastVScroll, size, inc, pinc, /*notify*/True); }} // End ResetScrollBar/*------------------------------------------------------------------------ * Method to add the message item to a thread. */voidFolderC::InsertInThread(MsgItemC *newItem){//// Try to find a message with the same thread// u_int count = msgList->size(); MsgC *newMsg = newItem->msg; CharC newThread = newMsg->Thread(); int i=0; for (i=0; i<count; i++) {//// See if the thread matches// MsgC *msg = (*msgList)[i]; if ( msg != newMsg && newThread.Equals(msg->Thread(), IGNORE_CASE) ) {//// Find the last item in the thread// MsgItemC *item = msg->icon; if ( !item ) return; while ( item->nextInThread ) item = item->nextInThread;//// Add the new item to the thread// item->nextInThread = newItem; newItem->prevInThread = item; if ( debuglev > 1 ) cout <<"Inserted message " <<newMsg->Number() <<" after " <<msg->Number() <<endl; return; } }} // End InsertInThread/*------------------------------------------------------------------------ * Method to update the fields for all message items */voidFolderC::UpdateFields(){ if ( !icon ) return;//// Loop through all messages// u_int count = msgItemList->size(); int i=0; for (i=0; i<count; i++) { MsgItemC *item = (MsgItemC *)(*msgItemList)[i]; item->LoadFields(); } count = delItemList->size(); for (i=0; i<count; i++) { MsgItemC *item = (MsgItemC *)(*delItemList)[i]; item->LoadFields(); }} // End UpdateFields/*------------------------------------------------------------------------ * Method to return a pointer to the newest message in the folder */MsgC*FolderC::NewestMsg() const{//// Return the most recent new message// u_int count = msgList->size(); int i=count-1; for (i=count-1; i>=0; i--) { MsgC *msg = (*msgList)[i]; if ( msg->IsNew() && !msg->IsDeleted() ) return msg; } return NULL;} // End NewestMsg/*------------------------------------------------------------------------ * Method to give us a new sort manager */voidFolderC::SetSortMgr(SortMgrC *sort){ delete sortMgr; sortMgr = sort;//// If there is a new sort manager, look up the keys for this folder// RegexC tmp = name; if ( sortMgr ) { StringC *keys = ishApp->sortPrefs->folderSortKeys.definitionOf(tmp);//// If there is an existing entry, just update it. If not, create a new one// if ( keys ) *keys = sortMgr->KeyString(); else ishApp->sortPrefs->folderSortKeys.add(tmp, sortMgr->KeyString()); } // End if there is a new sort manager//// If there is no new sort manager, remove the keys for this folder// else ishApp->sortPrefs->folderSortKeys.remove(tmp);} // End SetSortMgr/*------------------------------------------------------------------------ * Method to apply the sort specified by the given string */voidFolderC::Sort(CharC keyString){ if ( sortMgr ) sortMgr->Set(keyString); else sortMgr = new SortMgrC(keyString);}/*------------------------------------------------------------------------ * Method to return the sort manager used for this folder */SortMgrC*FolderC::SortMgr() const
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -