Update of /cvsroot/mahogany/M/src/mail
In directory usw-pr-cvs1:/tmp/cvs-serv7121/src/mail
Modified Files:
ASMailFolder.cpp MailFolder.cpp MailFolderCC.cpp
MailFolderCmn.cpp
Added Files:
MFDriver.cpp MFPool.cpp
Removed Files:
MMailFolder.cpp
Log Message:
redesigned the MailFolder and related classes to virtualize access to the folder
functions via folder drivers -- this should allow to plug in a virtual folder
implementation easily now
WARNING: many untested changes, don't use for now for anything but testing!
***** Error reading new file: [Errno 2] No such file or directory: 'MFDriver.cpp'
***** Error reading new file: [Errno 2] No such file or directory: 'MFPool.cpp'
Index: ASMailFolder.cpp
===================================================================
RCS file: /cvsroot/mahogany/M/src/mail/ASMailFolder.cpp,v
retrieving revision 1.62
retrieving revision 1.63
diff -b -u -2 -r1.62 -r1.63
--- ASMailFolder.cpp 4 Jul 2002 17:22:37 -0000 1.62
+++ ASMailFolder.cpp 14 Jul 2002 23:41:22 -0000 1.63
@@ -41,4 +41,8 @@
#endif
+// subscription code is not used for now and probably broken, so it is not
+// compiled in -- but keep it for the future
+//#define USE_SUBSCRIBE
+
ASMailFolder::ResultImpl::~ResultImpl()
{
@@ -605,4 +609,6 @@
};
+#ifdef USE_SUBSCRIBE
+
class MT_Subscribe : public MailThread
{
@@ -635,4 +641,6 @@
};
+#endif // USE_SUBSCRIBE
+
class MT_ListFolders : public MailThread
{
@@ -958,4 +966,5 @@
/**@name Subscription management */
//@{
+#ifdef USE_SUBSCRIBE
/** Subscribe to a given mailbox (related to the
mailfolder/mailstream underlying this folder.
@@ -974,4 +983,6 @@
mailboxname, subscribe))->Start();
}
+#endif // USE_SUBSCRIBE
+
/** Get a listing of all mailboxes.
@param pattern a wildcard matching the folders to list
@@ -1134,4 +1145,6 @@
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+#ifdef USE_SUBSCRIBE
+
/** Subscribe to a given mailbox (related to the
mailfolder/mailstream underlying this folder.
@@ -1149,4 +1162,6 @@
return ASMailFolderImpl::Subscribe(host, protocol, mailboxname, subscribe, ud);
}
+
+#endif // USE_SUBSCRIBE
Ticket
Index: MailFolder.cpp
===================================================================
RCS file: /cvsroot/mahogany/M/src/mail/MailFolder.cpp,v
retrieving revision 1.283
retrieving revision 1.284
diff -b -u -2 -r1.283 -r1.284
--- MailFolder.cpp 5 Jul 2002 22:34:16 -0000 1.283
+++ MailFolder.cpp 14 Jul 2002 23:41:22 -0000 1.284
@@ -4,5 +4,5 @@
// use cclient (i.e. don't really work with mail folders)
// Purpose: handling of mail folders with c-client lib
-// Author: Karsten Ball�der
+// Author: Karsten Ball�der, Vadim Zeitlin
// Modified by:
// Created: 1997
@@ -16,6 +16,10 @@
// ============================================================================
+// ----------------------------------------------------------------------------
+// headers
+// ----------------------------------------------------------------------------
+
#ifdef __GNUG__
-# pragma implementation "MailFolder.h"
+ #pragma implementation "MailFolder.h"
#endif
@@ -50,8 +54,8 @@
#include "LogCircle.h"
-#include "MFFactory.h"
#include "MFPrivate.h"
-
-#include "MailFolderCC.h"
+#include "mail/Driver.h"
+#include "mail/FolderPool.h"
+#include "mail/ServerInfo.h"
#include "Composer.h"
@@ -64,6 +68,4 @@
extern const MOption MP_DEFAULT_REPLY_KIND;
extern const MOption MP_FOLDER_COMMENT;
-extern const MOption MP_FOLDER_LOGIN;
-extern const MOption MP_FOLDER_PASSWORD;
extern const MOption MP_FOLDER_PATH;
extern const MOption MP_FOLDER_TYPE;
@@ -79,9 +81,62 @@
extern const MOption MP_USERNAME;
+// ----------------------------------------------------------------------------
+// persistent msgboxes we use here
+// ----------------------------------------------------------------------------
+
+extern const MPersMsgBox *M_MSGBOX_DIALUP_ON_OPEN_FOLDER;
+extern const MPersMsgBox *M_MSGBOX_KEEP_PWD;
+extern const MPersMsgBox *M_MSGBOX_NET_DOWN_OPEN_ANYWAY;
+extern const MPersMsgBox *M_MSGBOX_REMEMBER_PWD;
+
+// ----------------------------------------------------------------------------
+// global static variables
+// ----------------------------------------------------------------------------
+
+ServerInfoEntry::ServerInfoList ServerInfoEntry::ms_servers;
+
+MFSubSystem *MFSubSystem::ms_initilizers = NULL;
+
// ============================================================================
-// implementation
+// MailFolder implementation
// ============================================================================
-MFFactory *MFFactory::ms_factories = NULL;
+// ----------------------------------------------------------------------------
+// MailFolder initialization and shutdown
+// ----------------------------------------------------------------------------
+
+/* static */
+bool
+MailFolder::Init()
+{
+ for ( MFSubSystem *subsys = MFSubSystem::GetFirst();
+ subsys;
+ subsys = subsys->GetNext() )
+ {
+ if ( !subsys->Init() )
+ {
+ // any error here is fatal because normally we don't do anything
+ // error-prone in the Init() functions
+ return false;
+ }
+ }
+
+ return true;
+}
+
+/* static */
+void
+MailFolder::CleanUp()
+{
+ ServerInfoEntry::DeleteAll();
+ MFPool::DeleteAll();
+
+ for ( MFSubSystem *subsys = MFSubSystem::GetFirst();
+ subsys;
+ subsys = subsys->GetNext() )
+ {
+ subsys->CleanUp();
+ }
+}
// ----------------------------------------------------------------------------
@@ -89,51 +144,169 @@
// ----------------------------------------------------------------------------
+/**
+ initialize all mail subsystems and return the folder driver or NULL if none
+ (logging the error message in this case)
+ */
+static MFDriver *GetFolderDriver(const MFolder *folder)
+{
+ if ( !MailFolder::Init() )
+ return NULL;
+
+ CHECK( folder, NULL, "MailFolder: NULL folder object" );
+
+ const String kind = folder->GetClass();
+
+ // find the creation function for this kind of folders
+ MFDriver *driver = MFDriver::Get(kind);
+ if ( !driver )
+ {
+ ERRORMESSAGE((_("Unknown folder kind '%s'"), kind.c_str()));
+ }
+
+ return driver;
+}
+
/* static */
MailFolder *
MailFolder::OpenFolder(const MFolder *folder, OpenMode mode, wxFrame *frame)
{
- if ( !Init() )
+ MFDriver *driver = GetFolderDriver(folder);
+ if ( !driver )
return NULL;
- CHECK( folder, NULL, "NULL MFolder in OpenFolder()" );
+ // ensure that we have the authentification information for this folder
+ // before trying to open it
+ bool userEnteredPwd = false;
+ String login, password;
+ if ( !GetAuthInfoForFolder(folder, login, password, &userEnteredPwd) )
+ {
+ // can't continue without login/password
+ return NULL;
+ }
- String kind = folder->GetClass();
+ // look if we don't already have it opened
+ //
+ // NB: if the folder is already opened, the password [possibly] asked for
+ // above is unused and not checked at all and although it's not a
+ // serious problem it still doesn't look right (fixme)
+ MailFolder *mf = MFPool::Find(driver, folder, login);
+ if ( mf )
+ {
+ // make sure it's updated
+ mf->Ping();
- // this is a hack needed for backwards compatibility and which also allows
- // to have the empty default value for the folder class which saves quite
- // some bytes in the profile
- if ( kind.empty() )
+ // the connection could have been lost from inside Ping() so check for it
+ // yet again and reopen the folder if this is what happened
+ if ( !mf->IsOpened() )
{
- kind = "cclient";
+ mf->DecRef();
+ mf = NULL;
+ }
}
- // find the creation function for this kind of folders
- for ( const MFFactory *factory = MFFactory::GetHead();
- factory;
- factory = factory->GetNext() )
+ if ( !mf )
{
- if ( factory->GetName() == kind )
+ // check whether this folder is accessible
+ if ( !CheckNetwork(folder, frame) )
{
- return factory->OpenFolder(folder, mode, frame);
+ return NULL;
+ }
+
+ // and now do [try to] open the folder
+ mf = driver->OpenFolder(folder, login, password, mode, frame);
+
+ // if we have succeeded to open the folder ...
+ if ( mf )
+ {
+ // ... add it to the pool
+ MFPool::Add(driver, mf, folder, login);
+
+ // ... and propose to the user to save the password so that he doesn't
+ // have to enter it again during the subsequent attempts to open it
+ if ( userEnteredPwd )
+ {
+ // const_cast needed, unfortunately
+ ProposeSavePassword(mf, (MFolder *)folder, login, password);
+ }
}
}
- ERRORMESSAGE((_("Unknown folder kind '%s'"), kind.c_str()));
+ return mf;
+}
- return NULL;
+/* static */
+bool MailFolder::CheckNetwork(const MFolder *folder, wxFrame *frame)
+{
+#ifdef USE_DIALUP
+ // check if we need to dial up to open this folder
+ if ( folder->NeedsNetwork() && !mApplication->IsOnline() )
+ {
+ String msg;
+ msg.Printf(_("To open the folder '%s', network access is required "
+ "but it is currently not available.\n"
+ "Would you like to connect to the network now?"),
+ folder->GetFullName().c_str());
+
+ if ( MDialog_YesNoDialog(msg,
+ frame,
+ MDIALOG_YESNOTITLE,
+ M_DLG_YES_DEFAULT,
+ M_MSGBOX_DIALUP_ON_OPEN_FOLDER,
+ folder->GetFullName()) )
+ {
+ mApplication->GoOnline();
+ }
+
+ if ( !mApplication->IsOnline() ) // still not?
+ {
+ if ( !MDialog_YesNoDialog(_("Opening this folder will probably fail!\n"
+ "Continue anyway?"),
+ frame,
+ MDIALOG_YESNOTITLE,
+ M_DLG_NO_DEFAULT,
+ M_MSGBOX_NET_DOWN_OPEN_ANYWAY,
+ folder->GetFullName()) )
+ {
+ // remember that the user cancelled opening the folder
+ mApplication->SetLastError(M_ERROR_CANCEL);
+
+ return false;
+ }
+ }
+ }
+#endif // USE_DIALUP
+
+ return true;
}
/* static */
bool
-MailFolder::CloseFolder(const MFolder *mfolder)
+MailFolder::CloseFolder(const MFolder *folder)
{
- // don't try to close the folder which can't be opened
- if ( !mfolder->CanOpen() )
+ CHECK( folder, false, "MailFolder::CloseFolder(): NULL folder" );
+
+ // don't try to close the folder which can't be opened, it's a NOOP
+ if ( !folder->CanOpen() )
{
return true;
}
- // for now there is only one implementation to call:
- return MailFolderCC::CloseFolder(mfolder);
+ MFDriver *driver = GetFolderDriver(folder);
+ if ( !driver )
+ return false;
+
+ // find the associated open folder
+ //
+ // FIXME: using GetLogin() here is wrong, see comments before MFPool::Find()
+ MailFolder_obj mf = MFPool::Find(driver, folder, folder->GetLogin());
+ if ( !mf )
+ {
+ // nothing to close
+ return false;
+ }
+
+ mf->Close();
+
+ return true;
}
@@ -142,41 +315,37 @@
MailFolder::CloseAll()
{
- MailFolder **mfOpened = GetAllOpened();
- if ( !mfOpened )
- return 0;
-
+ // count the number of folders we close
size_t n = 0;
- while ( mfOpened[n] )
- {
- MailFolder *mf = mfOpened[n++];
+ MFPool::Cookie cookie;
+ for ( MailFolder *mf = MFPool::GetFirst(cookie);
+ mf;
+ mf = MFPool::GetNext(cookie) )
+ {
mf->Close();
// notify any opened folder views
MEventManager::Send(new MEventFolderClosedData(mf));
- }
- delete [] mfOpened;
+ mf->DecRef();
+ }
return n;
}
+
// ----------------------------------------------------------------------------
// MailFolder: other operations
// ----------------------------------------------------------------------------
-/* static */
-MailFolder **
-MailFolder::GetAllOpened()
-{
- // if we ever have other kinds of folders, we should append them to the
- // same array too
- return MailFolderCC::GetAllOpened();
-}
-
MailFolder *
MailFolder::GetOpenedFolderFor(const MFolder *folder)
{
- return MailFolderCC::FindFolder(folder);
+ MFDriver *driver = GetFolderDriver(folder);
+ if ( !driver )
+ return NULL;
+
+ // FIXME: login problem again
+ return MFPool::Find(driver, folder, folder->GetLogin());
}
@@ -184,13 +353,11 @@
bool MailFolder::PingAllOpened(wxFrame *frame)
{
- MailFolder **mfOpened = GetAllOpened();
- if ( !mfOpened )
- return 0;
-
bool rc = true;
- for ( size_t n = 0; mfOpened[n]; n++ )
- {
- MailFolder *mf = mfOpened[n];
+ MFPool::Cookie cookie;
+ for ( MailFolder *mf = MFPool::GetFirst(cookie);
+ mf;
+ mf = MFPool::GetNext(cookie) )
+ {
NonInteractiveLock noInter(mf, frame != NULL);
@@ -200,7 +367,7 @@
rc = false;
}
- }
- delete [] mfOpened;
+ mf->DecRef();
+ }
return rc;
@@ -211,7 +378,4 @@
MailFolder::CheckFolder(const MFolder *folder, wxFrame *frame)
{
- if ( !Init() )
- return false;
-
bool rc;
@@ -227,6 +391,8 @@
else // not opened
{
+ MFDriver *driver = GetFolderDriver(folder);
+
// check its status without opening it
- return MailFolderCC::CheckStatus(folder);
+ rc = driver ? driver->CheckFolder(folder) : false;
}
@@ -236,21 +402,18 @@
/* static */
bool
-MailFolder::DeleteFolder(const MFolder *mfolder)
+MailFolder::DeleteFolder(const MFolder *folder)
{
- if ( !Init() )
- return false;
+ MFDriver *driver = GetFolderDriver(folder);
- // for now there is only one implementation to call:
- return MailFolderCC::DeleteFolder(mfolder);
+ return driver ? driver->DeleteFolder(folder) : false;
}
/* static */
bool
-MailFolder::Rename(const MFolder *mfolder, const String& name)
+MailFolder::Rename(const MFolder *folder, const String& name)
{
- if ( !Init() )
- return false;
+ MFDriver *driver = GetFolderDriver(folder);
- return MailFolderCC::Rename(mfolder, name);
+ return driver ? driver->RenameFolder(folder, name) : false;
}
@@ -259,51 +422,25 @@
MailFolder::ClearFolder(const MFolder *folder)
{
- if ( !Init() )
- return -1;
+ MFDriver *driver = GetFolderDriver(folder);
- // for now there is only one implementation to call:
- return MailFolderCC::ClearFolder(folder);
+ return driver ? driver->ClearFolder(folder) : -1;
}
/* static */
-bool
-MailFolder::CreateFolder(const String& name,
- MFolderType type,
- int flags,
- const String &path,
- const String &comment)
+bool MailFolder::CanExit(String *which)
{
- if ( !Init() )
- return false;
-
- MFolder *mfolder = MFolder::Create(name, type);
- if ( !mfolder )
- return false;
-
- mfolder->SetFlags(flags);
- mfolder->SetPath(path);
- mfolder->SetComment(comment);
-
- // So far the drivers do an auto-create when we open a folder, so now we
- // attempt to open the folder to see what happens:
- MailFolder_obj mf = MailFolder::OpenFolder(mfolder);
-
- mfolder->DecRef();
+ bool rc = true;
- return true;
-}
+ MFPool::Cookie cookie;
+ for ( MailFolder *mf = MFPool::GetFirst(cookie);
+ mf && rc;
+ mf = MFPool::GetNext(cookie) )
+ {
+ rc = !mf->IsInCriticalSection();
-/* static */
-bool MailFolder::CanExit(String *which)
-{
- return MailFolderCC::CanExit(which);
-}
+ mf->DecRef();
+ }
-/* static */
-bool
-MailFolder::Subscribe(const String &host, MFolderType protocol,
- const String &mailboxname, bool subscribe)
-{
- return MailFolderCC::Subscribe(host, protocol, mailboxname, subscribe);
+ return rc;
}
@@ -937,43 +1074,5 @@
// ----------------------------------------------------------------------------
-// static functions used by MailFolder
-// ----------------------------------------------------------------------------
-
-/* static */
-bool
-MailFolder::Init()
-{
- static bool s_initialized = false;
-
- if ( !s_initialized )
- {
- if ( !MailFolderCmnInit() || !MailFolderCCInit() )
- {
- wxLogError(_("Failed to initialize mail subsystem."));
- }
- else // remember that we're initialized now
- {
-#ifdef USE_DIALUP
- // must be done before using the network
- mApplication->SetupOnlineManager();
-#endif // USE_DIALUP
-
- s_initialized = true;
- }
- }
-
- return s_initialized;
-}
-
-/* static */
-void
-MailFolder::CleanUp(void)
-{
- MailFolderCmnCleanup();
- MailFolderCCCleanup();
-}
-
-// ----------------------------------------------------------------------------
-// misc
+// misc static MailFolder methods
// ----------------------------------------------------------------------------
@@ -1044,4 +1143,109 @@
return s_LogCircle;
+}
+
+// ----------------------------------------------------------------------------
+// MailFolder login/password management
+// ----------------------------------------------------------------------------
+
+/* static */
+void
+MailFolder::ProposeSavePassword(MailFolder *mf,
+ MFolder *folder,
+ const String& login,
+ const String& password)
+{
+ // do not process the events while we're showing the dialog boxes below:
+ // this could lead to the new calls to OpenFolder() which would be bad as
+ // we're called from inside OpenFolder()
+ MEventManagerSuspender suspendEvents;
+
+ // ask the user if he'd like to remember the password for the future:
+ // this is especially useful for the folders created initially by the
+ // setup wizard as it doesn't ask for the passwords
+ if ( MDialog_YesNoDialog
+ (
+ String::Format
+ (
+ _("Would you like to permanently remember the password "
+ "for the folder '%s'?\n"
+ "(WARNING: don't do it if you are concerned about security)"),
+ mf->GetName().c_str()
+ ),
+ NULL,
+ MDIALOG_YESNOTITLE,
+ M_DLG_YES_DEFAULT,
+ M_MSGBOX_REMEMBER_PWD,
+ mf->GetName()
+ ) )
+ {
+ folder->SetAuthInfo(login, password);
+ }
+ else // don't save password permanently
+ {
+ // but should we keep it at least during this session?
+ if ( MDialog_YesNoDialog
+ (
+ _("Should the password be kept in memory during this\n"
+ "session only (it won't be saved to a disk file)?\n"
+ "If you answer \"No\", you will be asked for the password\n"
+ "each time when the folder is accessed."),
+ NULL,
+ MDIALOG_YESNOTITLE,
+ M_DLG_YES_DEFAULT,
+ M_MSGBOX_KEEP_PWD,
+ mf->GetName()
+ ) )
+ {
+ ServerInfoEntry *server = ServerInfoEntry::GetOrCreate(folder, mf);
+ CHECK_RET( server, "folder which has login must have server as well!" );
+
+ server->SetAuthInfo(login, password);
+ }
+ //else: don't keep the login info even in memory
+ }
+}
+
+/* static */
+bool MailFolder::GetAuthInfoForFolder(const MFolder *mfolder,
+ String& login,
+ String& password,
+ bool *userEnteredPwd)
+{
+ if ( !mfolder->NeedsLogin() )
+ {
+ // nothing to do then, everything is already fine
+ return true;
+ }
+
+ login = mfolder->GetLogin();
+ password = mfolder->GetPassword();
+
+ if ( login.empty() || password.empty() )
+ {
+ // do we already have login/password for this folder?
+ ServerInfoEntry *server = ServerInfoEntry::Get(mfolder);
+ if ( server && server->GetAuthInfo(login, password) )
+ {
+ return true;
+ }
+
+ // we don't have password for this folder, ask the user about it
+ if ( !MDialog_GetPassword(mfolder->GetFullName(), &login, &password) )
+ {
+ ERRORMESSAGE((_("Cannot access this folder without a password.")));
+
+ mApplication->SetLastError(M_ERROR_CANCEL);
+
+ return false;
+ }
+
+ // remember that the password was entered interactively and propose to
+ // remember it if it really works later
+ if ( userEnteredPwd )
+ *userEnteredPwd = true;
+ }
+
+ return true;
}
Index: MailFolderCC.cpp
===================================================================
RCS file: /cvsroot/mahogany/M/src/mail/MailFolderCC.cpp,v
retrieving revision 1.629
retrieving revision 1.630
diff -b -u -2 -r1.629 -r1.630
--- MailFolderCC.cpp 5 Jul 2002 17:58:35 -0000 1.629
+++ MailFolderCC.cpp 14 Jul 2002 23:41:22 -0000 1.630
@@ -60,5 +60,8 @@
#include "Sequence.h"
-#include "MFFactory.h"
+#include "MFPrivate.h"
+#include "mail/Driver.h"
+#include "mail/FolderPool.h"
+#include "mail/ServerInfo.h"
// just to use wxFindFirstFile()/wxFindNextFile() for lockfile checking and
@@ -133,11 +136,4 @@
//@}
[...1205 lines suppressed...]
+ // any connections left?
+ return !m_connections.empty();
}
/* static */
-void ServerInfoEntry::CheckTimeoutAll()
+void ServerInfoEntryCC::CheckTimeoutAll()
{
bool hasAnyConns = false;
@@ -6779,9 +6234,6 @@
++i )
{
- // micro optimization
- if ( !i->m_connections.empty() )
+ if ( i->CheckTimeout() )
{
- i->CheckTimeout();
-
hasAnyConns = true;
}
Index: MailFolderCmn.cpp
===================================================================
RCS file: /cvsroot/mahogany/M/src/mail/MailFolderCmn.cpp,v
retrieving revision 1.97
retrieving revision 1.98
diff -b -u -2 -r1.97 -r1.98
--- MailFolderCmn.cpp 5 Jul 2002 16:56:18 -0000 1.97
+++ MailFolderCmn.cpp 14 Jul 2002 23:41:23 -0000 1.98
@@ -64,4 +64,5 @@
#include "MailFolderCmn.h"
#include "MFPrivate.h"
+#include "mail/FolderPool.h"
#include <wx/timer.h>
@@ -481,4 +482,9 @@
void MailFolderCmn::Close(void)
{
+ // this folder shouldn't be reused by MailFolder::OpenFolder() any more as
+ // it is being closed anyhow, so prevent this from happening by removing it
+ // from the pool of available folders
+ MFPool::Remove(this);
+
if ( m_headers )
{
@@ -2125,5 +2131,5 @@
// ----------------------------------------------------------------------------
-extern bool MailFolderCmnInit()
+bool MailFolderCmnInit()
{
if ( !gs_MailFolderCloser )
@@ -2135,5 +2141,5 @@
}
-extern void MailFolderCmnCleanup()
+void MailFolderCmnCleanup()
{
if ( gs_MailFolderCloser )
@@ -2147,3 +2153,5 @@
}
}
+
+static MFSubSystem gs_subsysCmn(MailFolderCmnInit, MailFolderCmnCleanup);
--- MMailFolder.cpp DELETED ---
-------------------------------------------------------
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