📄 folderc.c
字号:
{ if ( sortMgr ) return sortMgr; else return ishApp->mainWin->sortMgr;}/*------------------------------------------------------------------------ * Method to move a message from the message list to the deleted list. */voidFolderC::MsgDeleted(MsgC *msg){//// Update the lists// if ( msg->icon ) { //cout <<"Adding message " <<msg->Number() // <<" to deleted list with icon " <<msg->icon <<endl; delItemList->add(msg->icon); msgItemList->remove(msg->icon); } SetChanged(True); UpdateIcon();} // End MsgDeleted/*------------------------------------------------------------------------ * Method to update folder icon when message status changes */voidFolderC::MsgStatusChanged(MsgC*){ SetChanged(True); if ( scanned ) UpdateIcon();}/*------------------------------------------------------------------------ * Method to move the specified messages from the message list to the deleted * list. */voidFolderC::ItemsDeleted(VItemListC& list){ Boolean listChanged = False; u_int count = list.size(); int i=0; for (i=0; i<count; i++) { MsgItemC *item = (MsgItemC *)list[i]; if ( msgItemList->includes(item) ) { //cout <<"Adding message " <<item->msg->Number() // <<" to deleted list with icon " <<item <<endl; delItemList->add(item); listChanged = True; } } if ( !listChanged ) return;////// Remove them from the message list// for (i=0; i<count; i++) { MsgItemC *item = (MsgItemC *)list[i]; int index = msgItemList->indexOf(item); if ( index != msgItemList->NULL_INDEX ) msgItemList->replace(NULL, index); } msgItemList->removeNulls(); SetChanged(True); UpdateIcon();} // End ItemsDeleted/*------------------------------------------------------------------------ * Function used to sort the message items by number. This is not used * to sort the visible list, only the internal list */static intSortByNumber(const void *a, const void *b){ MsgItemC *mia = *(MsgItemC **)a; MsgItemC *mib = *(MsgItemC **)b; int result = 0; if ( mia->msg->Number() < mib->msg->Number() ) result = -1; else if ( mia->msg->Number() > mib->msg->Number() ) result = 1; return result;}/*------------------------------------------------------------------------ * Method to move a message from the deleted list to the message list. */voidFolderC::MsgUndeleted(MsgC *msg){//// Update the lists// if ( msg->icon ) { //cout <<"Removing message " <<msg->Number() // <<" from deleted list with icon " <<msg->icon <<endl; delItemList->remove(msg->icon); msgItemList->add(msg->icon); msgItemList->sort(SortByNumber); } SetChanged(True); UpdateIcon();} // End MsgUndeleted/*------------------------------------------------------------------------ * Method to move the specified messages from the deleted list to the message * list. */voidFolderC::ItemsUndeleted(VItemListC& list){ Boolean listChanged = False; u_int count = list.size(); int i=0; for (i=0; i<count; i++) { MsgItemC *item = (MsgItemC *)list[i]; if ( delItemList->includes(item) ) { msgItemList->add(item); listChanged = True; } } if ( !listChanged ) return;////// Remove them from the deleted list// for (i=0; i<count; i++) { MsgItemC *item = (MsgItemC *)list[i]; int index = delItemList->indexOf(item); //cout <<"Removing message " <<item->msg->Number() // <<" from deleted list with icon " <<item <<endl; //cout <<"Adding NULL to deleted list in position " <<index <<endl; delItemList->replace(NULL, index); } //cout <<"Removing NULLs from deleted list" <<endl; delItemList->removeNulls();//// Re-sort the message list// msgItemList->sort(SortByNumber); SetChanged(True); UpdateIcon();} // End ItemsUndeleted/*------------------------------------------------------------------------ * Function to build a list of headers from a character array */static HeaderC*CutHeaders(CharC& data){ if ( data.Length() == 0 ) return NULL; if ( data.StartsWith('\n') ) { data.CutBeg(1); return NULL; }//// Read a header line// StringC headStr = data.NextWord(0, '\n'); data.CutBeg(headStr.size()+1); if ( headStr.size() == 0 ) return NULL;//// Read continuation lines// CharC lineStr = data.NextWord(0, '\n'); while ( isspace(lineStr[0]) ) { headStr += lineStr; data.CutBeg(lineStr.Length()+1); lineStr = data.NextWord(0, '\n'); }//// Create a new header object// HeaderC *newHead = new HeaderC(headStr);//// Read and set links to additional headers// newHead->next = CutHeaders(data); return newHead;} // End CutHeaders/*------------------------------------------------------------------------ * Method to handle a partial mime message */BooleanFolderC::AddPartial(MsgC *msg){//// Parse the content-type header// MsgPartC *body = msg->QuickBody(); // Just need headers ParamC *idParam = body->Param("id"); ParamC *numParam = body->Param("number"); if ( !idParam || !numParam ) return False; ParamC *totParam = body->Param("total");//// See if id exists in partial dictionary// StringC idVal = idParam->val; PartialMsgPtr *ptr = partialMsgDict->definitionOf(idVal); PartialMsgC *pm = (ptr ? *ptr : (PartialMsgC*)NULL);//// If no matching id was found, create a new entry// if ( !pm ) { pm = new PartialMsgC; pm->folder = this; partialMsgDict->add(idVal, pm); }//// Insert part in list// StringC numVal = numParam->val; int partNum = atoi(numVal); int partIndex = partNum-1;//// Add blank entries until the list is large enough to hold this part// MsgC *tmp = NULL; while ( pm->msgList.size() <= partIndex ) pm->msgList.add(tmp);//// Store this message at its index// pm->msgList.replace(msg, partIndex); //// See if all the parts have arrived.// if ( pm->expected == 0 && totParam ) { StringC totVal = totParam->val; pm->expected = atoi(totVal); } if ( pm->msgList.size() != pm->expected ) return True;//// Count the number of non-null pointers. If we hit any nulls, we can return// immediately// int received = 0; MsgC *msgP; int i=0; for (i=0; i<pm->expected; i++) { msgP = pm->msgList[i]; if ( !msgP ) return True; received++; }//// If we don't have all the parts, return// if ( received != pm->expected ) return True;//// Create a temporary file for the complete message// char *cs = tempnam(NULL, "part."); StringC tmpfile(cs); free(cs); FILE *fp = fopen(tmpfile, "w+"); if ( !fp ) { StringC errmsg("Could not create temp file \""); errmsg += tmpfile; errmsg += "\" while combining partial messages.\n"; errmsg += SystemErrorMessage(errno); halApp->PopupMessage(errmsg); return False; }//// Create a list of headers for the new message. Start with the headers from// part 1.// StringListC headList; MsgC *part1 = pm->msgList[0]; HeaderC *extHeaders = part1->Headers();//// Write all external headers except for "content-*", "subject", "message-id",// "encrypted" and "mime-version".// Boolean error = False; HeaderC *head = extHeaders; CharC headStr; CharC nlStr("\n"); while ( head && !error ) { Boolean skipIt = (head->key.StartsWith("Content-", IGNORE_CASE) || head->key.Equals("Subject", IGNORE_CASE) || head->key.Equals("Message-Id", IGNORE_CASE) || head->key.Equals("Encrypted", IGNORE_CASE) || head->key.Equals("Mime-Version", IGNORE_CASE)); if ( !skipIt ) { headStr = head->full; error = (!headStr.WriteFile(fp) || !nlStr.WriteFile(fp)); } head = head->next; }//// Separate the internal headers from the first body// StringC bodyStr; part1->GetBodyText(bodyStr); CharC realBody(bodyStr); HeaderC *intHeaders = NULL; if ( !bodyStr.StartsWith('\n') ) // No headers if starts with '\n' intHeaders = CutHeaders(realBody);//// Write all internal headers that match: "content-*", "subject", "message-id",// "encrypted" and "mime-version".// head = intHeaders; while ( head && !error ) { Boolean writeIt = (head->key.StartsWith("Content-", IGNORE_CASE) || head->key.Equals("Subject", IGNORE_CASE) || head->key.Equals("Message-Id", IGNORE_CASE) || head->key.Equals("Encrypted", IGNORE_CASE) || head->key.Equals("Mime-Version", IGNORE_CASE)); if ( writeIt ) { headStr = head->full; error = (!headStr.WriteFile(fp) || !nlStr.WriteFile(fp)); } head = head->next; }//// Write a blank line// if ( !error ) error = !nlStr.WriteFile(fp);//// Write the "non-header" portion of the body of the first part.// if ( !error ) error = !realBody.WriteFile(fp);//// Write the bodies for the remaining parts// u_int count = pm->expected; for (i=1; !error && i<count; i++) { msgP = pm->msgList[i]; error = !msgP->WriteBody(fp, /*addBlank=*/False, /*protectFroms=*/False); } long size = 0; if ( !error ) { fseek(fp, 0, SEEK_END); size = ftell(fp); } fclose(fp); if ( error ) { StringC errmsg("Could not write temp file \""); errmsg += tmpfile; errmsg += "\" while combining partial messages.\n"; errmsg += SystemErrorMessage(errno); halApp->PopupMessage(errmsg); unlink(tmpfile); return False; }//// Create a new message item from that file and add it to the folder// FileMsgC *newMsg = new FileMsgC(tmpfile, 0, (int)size, /*del=*/True, this); msgList->add(newMsg); newMsg->SetNumber(msgList->size()); VBoxC& vbox = ishApp->mainWin->MsgVBox(); if ( active ) { newMsg->CreateIcon(); InsertInThread(newMsg->icon); msgItemList->add(newMsg->icon); vbox.AddItem(*newMsg->icon); }//// Mark the partials for deletion// VItemListC list; count = pm->expected; for (i=0; i<count; i++) { msgP = pm->msgList[i]; msgP->SetDeleted(); if ( active ) list.add(msgP->icon); else MsgDeleted(msgP); } if ( active ) { ishApp->mainWin->DeleteItems(list); if ( ishApp->appPrefs->scrollToNew ) vbox.View()->ScrollToItem(*newMsg->icon); vbox.Refresh(); } ishApp->mainWin->GetNewMail(this); partialMsgDict->remove(idVal); delete pm; UpdateIndex(); return True;} // End AddPartial/*------------------------------------------------------------------------ * Method to insert a new message in place of another. This could happen * after a MIME conversion or an edit. */voidFolderC::ReplaceMsg(MsgC *oldMsg, MsgC *newMsg){//// Insert the new message in the message list// int index = msgList->indexOf(oldMsg); msgList->insert(newMsg, index+1);//// Create a new message item from that file and add it to the folder// VBoxC& vbox = ishApp->mainWin->MsgVBox(); if ( active ) { newMsg->CreateIcon(); InsertInThread(newMsg->icon); msgItemList->add(newMsg->icon); vbox.AddItem(*newMsg->icon); }//// Mark the old message for deletion// oldMsg->SetDeleted(); if ( active ) { ishApp->mainWin->DeleteMsg(oldMsg); vbox.View()->ScrollToItem(*newMsg->icon); vbox.Refresh(); } else MsgDeleted(oldMsg); UpdateIndex();} // End ReplaceMsg/*------------------------------------------------------------------------ * Method to return value of changed flag */BooleanFolderC::Changed(){ return (changed || HasDeletedMessages());}/*------------------------------------------------------------------------ * Method to update value of changed flag */voidFolderC::SetChanged(Boolean val){ if ( changed == val ) return; changed = val;//// Use the Changed() call because it checks other things// Boolean someNew = HasNewMessages(); char *tag; if ( Changed() ) tag = (char *) (someNew ? "bold-italic" : "bold"); else tag = (char *) (someNew ? "italic" : "plain"); icon->SetLabelTag(tag);}/*------------------------------------------------------------------------ * Method to determine if the index is up-to-date */BooleanFolderC::IndexValid(){ Boolean valid = False;#if 0 struct stat istats; if ( stat(indexFile, &istats) == 0 ) {#endif time_t folderTime = ModTime(); valid = (istats.st_mtime >= folderTime);#if 0 }#endif return valid;}/*------------------------------------------------------------------------ * Method to determine if the index summary value is up-to-date */BooleanFolderC::IndexSumValid(){ Boolean valid = False;#if 0 struct stat istats; if ( stat(indexFile, &istats) == 0 )#endif valid = (indexSumTime >= istats.st_mtime); return valid;}/*------------------------------------------------------------------------ * Method to add a new entry to the index file */longFolderC::AddIndexEntry(u_int status, int bytes, int lines, char *id){ if ( !OpenIndex() ) return -1;//// Don't write out the Viewed bit// status = (status & (u_int)~MSG_VIEWED); fseek(indexfp, 0, SEEK_END); long offset = ftell(indexfp); fprintf(indexfp, MSG_INDEX_WFMT, status, bytes, lines, id); CloseIndex(); if ( indexOpenLevel == 0 ) stat(indexFile, &istats);//// Add this status to the sum// indexSum |= status; indexSumTime = time(0); return offset;} // End AddIndexEntry/*------------------------------------------------------------------------ * Method to update an existing entry in the index file */BooleanFolderC::UpdateIndexEntry(MsgC *msg){//// IMAP folders don't have an index// if ( msg->IsImap() ) return True; if ( !OpenIndex() ) return False; if ( fseek(indexfp, msg->indexOffset, SEEK_SET) != 0 ) { CloseIndex(); return False; }//// Don't write out the Viewed bit// u_int status = (msg->status & (u_int)~MSG_VIEWED); int bytes = msg->BodyBytes(); int lines = msg->BodyLines(); char *id = msg->Id(); fprintf(indexfp, MSG_INDEX_WFMT, status, bytes, lines, id); CloseIndex(); if ( indexOpenLevel == 0 ) stat(indexFile, &istats);//// Updating invalidates the sum// indexSum = 0; indexSumTime = 0; return True;} // End UpdateIndexEntry
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -