#include #include "tlmpmail.h" #include "tlmpmail.m" #include static ARRAY_OBJS facts; PUBLIC FOLDER_FACTORY::FOLDER_FACTORY() { facts.neverdelete(); facts.add (this); } /* Get the list of all special folders */ int folders_list (SSTRINGS &tb) { int ret = 0; for (int i=0; ilist(tb); } return ret; } /* Manage allocation and de-allocation of folders */ PUBLIC FOLDER_VIEW *FOLDERS::getitem(int no) const { return (FOLDER_VIEW*)ARRAY::getitem (no); } static FOLDERS folders; static MAIL_MESSAGES messages; static FOLDER_VIEW *folders_locate0 (const char *path) { FOLDER_VIEW *ret = NULL; for (int i=0; igetid(id)!=-1 && id.cmp(path)==0){ ret = f; break; } } return ret; } /* Locate an already opened folder. Return NULL if not found. */ FOLDER_VIEW *folders_locate (const char *path) { FOLDER_VIEW *ret = folders_locate0(path); if (ret == NULL){ SSTRING abspath; folder_2abs (path,abspath); ret = folders_locate0(abspath.get()); } return ret; } /* Trigger a status or full (clean) update on a folder if alive. This is called (generally) before appending message to a folder */ void folders_update(const char *path, bool clean) { FOLDER_VIEW *p = folders_locate (path); if (p != NULL) p->update (clean); } /* Convert INBOX into the default path. */ static const char *folders_checkinbox(const char *path) { if (strcmp(path,MSG_R(I_INBOX))==0) path = prefs_getinbox(); return path; } /* Return true if a folder exist */ bool folders_exist (const char *path) { bool ret = false; path = folders_checkinbox (path); for (int i=0; iexist(path)){ ret = true; break; } } if (!ret){ SSTRING abspath; folder_2abs (path,abspath); ret = file_exist (abspath.get()); } return ret; } /* Allocate a new folder and register it in the garbage collector If this folder is already opened, it return the existing object. So opening the same folder several time produces several views of the same folder. */ FOLDER_VIEW *folders_alloc (const char *path) { FOLDER_VIEW *ret = NULL; path = folders_checkinbox (path); ret = folders_locate (path); if (ret == NULL){ for (int i=0; ibuild(path); } if (ret == NULL){ ret = new FOLDER_FILE (path); } folders_register (ret); } return ret; } /* Register a folder in the garbage collector. Participant must call FOLDER_VIEW::incrusage() and then decrusage() and call folders_free() once done. */ void folders_register (FOLDER_VIEW *f) { folders.add (f); } /* Register a message in the garbage collector. Participant must call MAIL_MESSAGE::incrusage() and then decrusage() and call folders_free() once done. */ void folders_register (MAIL_MESSAGE *m) { n_debug ("collect message #%d %s count=%d\n",messages.getnb()+1 ,m->getauthor(),m->getusage()); messages.add (m); } /* Delete a folder if needed (usage count has reached 0) */ void folders_free () { // Clean up un-used folder. // This is iterative because folders may reference other folders while (1){ bool deleted_one = false; for (int i=0; igetusage()==0){ n_debug ("Deleting folder %s\n",v->gettitle()); folders.remove_del(i); i--; deleted_one = true; } } if (!deleted_one) break; } // Cleanup older messages n_debug ("cleanup messages %d\n",messages.getnb()); int n=messages.getnb(); for (int i=n-1; i>=0; i--){ if (messages.getitem(i)->getusage()==0){ n_debug ("collect-del "); messages.remove_del(i); } } } /* Ask folder to send a PRIVATE_MESSAGE if they have been updated */ void folders_checkupdate() { for (int i=0; icheckupdate(); }