gecko-dev/lib/mailto/msgglue.cpp

828 lines
21 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
#include "rosetta.h"
#include "msg.h"
#include "msgcom.h"
#include "error.h"
#include "client.h"
#include "xpgetstr.h"
#include "msgcpane.h"
#include "msgprefs.h"
#include "msgmast.h"
#include "msgcflds.h"
#include "shist.h"
#include "msgppane.h"
#include "mime.h"
#include "msgbg.h"
#include "prefapi.h"
#include "msgurlq.h"
#include "msgsend.h"
#include "pw_public.h"
#include HG99874
extern "C"
{
extern int MK_OUT_OF_MEMORY;
extern int MK_MSG_ID_NOT_IN_FOLDER;
extern int MK_MSG_CANT_OPEN;
extern int MK_MSG_INBOX_L10N_NAME;
extern int MK_MSG_OUTBOX_L10N_NAME;
extern int MK_MSG_OUTBOX_L10N_NAME_OLD;
extern int MK_MSG_TRASH_L10N_NAME;
extern int MK_MSG_DRAFTS_L10N_NAME;
extern int MK_MSG_SENT_L10N_NAME;
extern int MK_MSG_TEMPLATES_L10N_NAME;
extern int XP_MSG_IMAP_ACL_FULL_RIGHTS;
extern int XP_MSG_IMAP_PERSONAL_FOLDER_TYPE_NAME;
extern int XP_MSG_IMAP_PERSONAL_FOLDER_TYPE_DESCRIPTION;
}
#ifndef IMAP4_PORT_SSL_DEFAULT
#define IMAP4_PORT_SSL_DEFAULT 993 /* use a separate port for imap4 over ssl */
#endif
#if defined(XP_MAC) && defined (__MWERKS__)
#pragma require_prototypes off
#endif
extern "C"
int ConvertMsgErrToMKErr(uint32 err); // ### Need to get from a header file...
inline MSG_CompositionPane* CastCompositionPane(MSG_Pane* pane) {
XP_ASSERT(pane && pane->GetPaneType() == MSG_COMPOSITIONPANE);
return (MSG_CompositionPane*) pane;
}
extern "C" MSG_Pane* MSG_FindPane(MWContext* context, MSG_PaneType type) {
return MSG_Pane::FindPane(context, type, FALSE);
}
extern "C" XP_Bool
MSG_RequiresMailWindow (const char *) { return FALSE; }
extern "C" XP_Bool
MSG_RequiresNewsWindow (const char *) { return FALSE; }
/* If this URL requires a particular kind of window, and this is not
that kind of window, then we need to find or create one.
*/
XP_Bool msg_NewWindowRequired (MWContext *context, const char *url)
{
if (!context)
return TRUE;
if (context->type == MWContextSearch || context->type == MWContextPrint || context->type == MWContextBiff)
return FALSE;
/* Search URLs always run in the pane they started in */
if (!XP_STRNCASECMP(url, "search-libmsg:", 14))
return FALSE;
// If we can figure out the content type, and there is no converter,
// return FALSE so we'll run the save as url in our window instead
// of creating an empty browser window.
char *contentType = MimeGetURLContentType(context, url);
if (contentType && !NET_HaveConverterForMimeType(contentType))
return FALSE;
/* This is not a browser window, and one is required. */
if (context->type != MWContextBrowser && context->type != MWContextPane && MSG_RequiresBrowserWindow(url))
return TRUE;
return FALSE; /*!msgPane && threadPane; */ // if msgPane is NULL, but we have a thread pane, return FALSE because we have the wrong window.
}
extern "C" XP_Bool MSG_NewWindowRequiredForURL (MWContext *context, URL_Struct *urlStruct)
{
if (urlStruct->open_new_window_specified)
return urlStruct->open_new_window;
if (context->type != MWContextBrowser && !strncasecomp (urlStruct->address, "about:", 6) && !urlStruct->internal_url
&& strncasecomp(urlStruct->address, "about:editfilenew", 17))
return TRUE;
return msg_NewWindowRequired(context, urlStruct->address);
}
extern "C"
{
void MSG_InitMsgLib(void) { } ;
}
extern "C" MSG_Master* MSG_InitializeMail(MSG_Prefs* prefs)
{
MSG_Master *master = prefs->GetMasterForBiff();
if (master)
return (master); // already initialized
MSG_InitMsgLib(); // make sure db code is initialized
master = new MSG_Master(prefs);
prefs->SetMasterForBiff(master);
return master;
}
extern "C" MSG_Pane* MSG_CreateProgressPane (MWContext *context,
MSG_Master *master,
MSG_Pane *parentPane)
{
return new MSG_ProgressPane(context, master, parentPane);
}
extern "C" MSG_Pane* MSG_CreateCompositionPane(MWContext* context,
MWContext* old_context,
MSG_Prefs* prefs,
MSG_CompositionFields* fields,
MSG_Master* master)
{
return new MSG_CompositionPane(context, old_context, prefs, fields, master);
}
extern "C" int
MSG_SetCompositionPaneCallbacks(MSG_Pane* composepane,
MSG_CompositionPaneCallbacks* callbacks,
void* closure)
{
return CastCompositionPane(composepane)->SetCallbacks(callbacks, closure);
}
extern "C" MSG_Pane* MSG_CreateCompositionPaneNoInit(MWContext* context,
MSG_Prefs* prefs,
MSG_Master* master)
{
return new MSG_CompositionPane(context, prefs, master);
}
extern "C" int MSG_InitializeCompositionPane(MSG_Pane* comppane,
MWContext* old_context,
MSG_CompositionFields* fields)
{
return CastCompositionPane(comppane)->Initialize(old_context, fields);
}
extern "C" void MSG_SetFEData(MSG_Pane* pane, void* data) {
pane->SetFEData(data);
}
extern "C" void* MSG_GetFEData(MSG_Pane* pane) {
return pane->GetFEData();
}
extern "C" MSG_PaneType MSG_GetPaneType(MSG_Pane* pane) {
return pane->GetPaneType();
}
extern "C" MWContext* MSG_GetContext(MSG_Pane* pane) {
if (pane)
return pane->GetContext();
else
return NULL;
}
extern "C" MSG_Prefs* MSG_GetPrefs(MSG_Pane* pane) {
return pane->GetPrefs();
}
extern "C" void MSG_WriteNewProfileAge() {
PREF_SetIntPref("mailnews.profile_age", MSG_IMAP_CURRENT_START_FLAGS);
}
extern "C" MSG_Prefs* MSG_GetPrefsForMaster(MSG_Master* master) {
return master->GetPrefs();
}
extern "C" int MSG_GetURL(MSG_Pane *pane, URL_Struct* url)
{
XP_ASSERT(pane && url);
if (pane && url)
{
url->msg_pane = pane;
return msg_GetURL(pane->GetContext(), url, FALSE);
}
else
return 0;
}
extern "C" void MSG_Command(MSG_Pane* pane, MSG_CommandType command,
MSG_ViewIndex* indices, int32 numindices) {
int status =
ConvertMsgErrToMKErr(pane->DoCommand(command, indices, numindices));
if (status < 0) {
char* pString = XP_GetString(status);
if (pString && strlen(pString))
FE_Alert(pane->GetContext(), pString);
}
}
extern "C" int MSG_CommandStatus(MSG_Pane* pane,
MSG_CommandType command,
MSG_ViewIndex* indices, int32 numindices,
XP_Bool *selectable_p,
MSG_COMMAND_CHECK_STATE *selected_p,
const char **display_string,
XP_Bool *plural_p) {
return ConvertMsgErrToMKErr(pane->GetCommandStatus(command,
indices, numindices,
selectable_p,
selected_p,
display_string,
plural_p));
}
extern "C" int MSG_SetToggleStatus(MSG_Pane* pane, MSG_CommandType command,
MSG_ViewIndex* indices, int32 numindices,
MSG_COMMAND_CHECK_STATE value) {
return ConvertMsgErrToMKErr(pane->SetToggleStatus(command,
indices, numindices,
value));
}
extern "C" MSG_COMMAND_CHECK_STATE MSG_GetToggleStatus(MSG_Pane* pane,
MSG_CommandType command,
MSG_ViewIndex* indices,
int32 numindices)
{
return pane->GetToggleStatus(command, indices, numindices);
}
extern "C" void MSG_DestroyMaster (MSG_Master* master) {
delete master;
}
extern "C" void MSG_DestroyPane(MSG_Pane* pane) {
delete pane;
}
extern "C" void MSG_SetLineWidth(MSG_Pane* composepane, int width)
{
CastCompositionPane(composepane)->SetLineWidth(width);
}
extern "C" int MSG_SetHTMLAction(MSG_Pane* composepane,
MSG_HTMLComposeAction action)
{
return CastCompositionPane(composepane)->SetHTMLAction(action);
}
extern "C" MSG_HTMLComposeAction MSG_GetHTMLAction(MSG_Pane* composepane)
{
return CastCompositionPane(composepane)->GetHTMLAction();
}
extern "C" int MSG_PutUpRecipientsDialog(MSG_Pane* composepane, void *pWnd)
{
return CastCompositionPane(composepane)->PutUpRecipientsDialog(pWnd);
}
extern "C" int MSG_ResultsRecipients(MSG_Pane* composepane,
XP_Bool cancelled,
int32* nohtml,
int32* htmlok)
{
return CastCompositionPane(composepane)->ResultsRecipients(cancelled,
nohtml,
htmlok);
}
extern "C" XP_Bool MSG_GetHTMLMarkup(MSG_Pane * composepane) {
return CastCompositionPane(composepane)->GetHTMLMarkup();
}
extern "C" XP_Bool MSG_DeliveryInProgress(MSG_Pane * composepane) {
if (!composepane || MSG_COMPOSITIONPANE != MSG_GetPaneType(composepane))
return FALSE;
return CastCompositionPane(composepane)->DeliveryInProgress();
}
extern "C" void MSG_SetHTMLMarkup(MSG_Pane * composepane, XP_Bool flag) {
CastCompositionPane(composepane)->SetHTMLMarkup(flag);
}
extern "C" const char *MSG_GetMessageIdFromState(void *state)
{
if (state)
{
MSG_SendMimeDeliveryState *deliveryState =
(MSG_SendMimeDeliveryState *) state;
return deliveryState->m_fields->GetMessageId();
}
return NULL;
}
extern "C" XP_Bool MSG_IsSaveDraftDeliveryState(void *state)
{
if (state)
return (((MSG_SendMimeDeliveryState *) state)->m_deliver_mode ==
MSG_SaveAsDraft);
return FALSE;
}
extern "C" int MSG_SetPreloadedAttachments ( MSG_Pane *composepane,
MWContext *context,
void *attachmentData,
void *attachments,
int attachments_count )
{
return ConvertMsgErrToMKErr ( CastCompositionPane(
composepane)->SetPreloadedAttachments (
context,
(MSG_AttachmentData *) attachmentData,
(MSG_AttachedFile *) attachments,
attachments_count) );
}
extern "C" MSG_Prefs* MSG_CreatePrefs() {
return new MSG_Prefs();
}
extern "C" void MSG_DestroyPrefs(MSG_Prefs* prefs) {
delete prefs;
}
extern "C" XP_Bool
MSG_GetNoInlineAttachments(MSG_Prefs* prefs)
{
return prefs->GetNoInlineAttachments();
}
extern "C" XP_Bool MSG_GetAutoQuoteReply(MSG_Prefs* prefs) {
return prefs->GetAutoQuoteReply();
}
extern MSG_Pane*
MSG_GetParentPane(MSG_Pane* progresspane)
{
return progresspane->GetParentPane();
}
#ifdef XP_UNIX
extern "C" MSG_Pane*
MSG_MailDocument (MWContext *old_context)
{
// For backwards compatability.
return MSG_MailDocumentURL(old_context,NULL);
}
extern "C" MSG_Pane*
MSG_MailDocumentURL (MWContext *old_context,const char *url)
{
// Don't allow a compose window to be created if the user hasn't
// specified an email address
const char *real_addr = FE_UsersMailAddress();
if (MISC_ValidateReturnAddress(old_context, real_addr) < 0)
return NULL;
MSG_CompositionFields* fields = new MSG_CompositionFields();
if (!fields) return NULL; // Out of memory.
/* If url is not specified, grab current history entry. */
if (!url) {
History_entry *h =
(old_context ? SHIST_GetCurrent (&old_context->hist) : 0);
if (h && h->address && *h->address) {
url = h->address;
}
}
#if 1 /* Do this if we want to attach the target of Mail Document by default */
if (url) {
fields->SetHeader(MSG_ATTACHMENTS_HEADER_MASK, url);
}
#endif
if (old_context && old_context->title) {
fields->SetHeader(MSG_SUBJECT_HEADER_MASK, old_context->title);
}
if (url) {
fields->SetBody(url);
}
XP_Bool prefBool = FALSE;
PREF_GetBoolPref("mail.attach_vcard",&prefBool);
fields->SetAttachVCard(prefBool);
MSG_CompositionPane* comppane = (MSG_CompositionPane*)
FE_CreateCompositionPane(old_context, fields, NULL, MSG_DEFAULT);
if (!comppane) {
delete fields;
return NULL;
}
HG42420
XP_ASSERT(comppane->GetPaneType() == MSG_COMPOSITIONPANE);
return comppane;
}
extern "C" MSG_Pane*
MSG_Mail (MWContext *old_context)
{
MSG_CompositionFields* fields = new MSG_CompositionFields();
if (!fields) return NULL; // Out of memory.
XP_Bool prefBool = FALSE;
PREF_GetBoolPref("mail.attach_vcard",&prefBool);
fields->SetAttachVCard(prefBool);
MSG_CompositionPane* comppane = (MSG_CompositionPane*)
FE_CreateCompositionPane(old_context, fields, NULL, MSG_DEFAULT);
if (!comppane) {
delete fields;
return NULL;
}
HG52965
XP_ASSERT(comppane->GetPaneType() == MSG_COMPOSITIONPANE);
return comppane;
}
extern "C" void
MSG_ResetUUEncode(MSG_Pane *pane)
{
CastCompositionPane(pane)->m_confirmed_uuencode_p = FALSE;
}
extern "C" MSG_CompositionFields*
MSG_CreateCompositionFields (
const char *from,
const char *reply_to,
const char *to,
const char *cc,
const char *bcc,
const char *fcc,
const char *newsgroups,
const char *followup_to,
const char *organization,
const char *subject,
const char *references,
const char *other_random_headers,
const char *priority,
const char *attachment,
const char *newspost_url
)
{
MSG_CompositionFields* fields = new MSG_CompositionFields();
fields->SetFrom(from);
fields->SetReplyTo(reply_to);
fields->SetTo(to);
fields->SetCc(cc);
fields->SetBcc(bcc);
fields->SetFcc(fcc);
fields->SetNewsgroups(newsgroups);
fields->SetFollowupTo(followup_to);
fields->SetOrganization(organization);
fields->SetSubject(subject);
fields->SetReferences(references);
fields->SetOtherRandomHeaders(other_random_headers);
fields->SetAttachments(attachment);
fields->SetNewspostUrl(newspost_url);
fields->SetPriority(priority);
return fields;
}
extern "C" void
MSG_DestroyCompositionFields(MSG_CompositionFields *fields)
{
delete fields;
}
#endif //XP_UNIX
extern "C" void
MSG_SetCompFieldsReceiptType(MSG_CompositionFields *fields,
int32 type)
{
fields->SetReturnReceiptType(type);
}
extern "C" int32
MSG_GetCompFieldsReceiptType(MSG_CompositionFields *fields)
{
return fields->GetReturnReceiptType();
}
extern "C" int
MSG_SetCompFieldsBoolHeader(MSG_CompositionFields *fields,
MSG_BOOL_HEADER_SET header,
XP_Bool bValue)
{
return fields->SetBoolHeader(header, bValue);
}
extern "C" XP_Bool
MSG_GetCompFieldsBoolHeader(MSG_CompositionFields *fields,
MSG_BOOL_HEADER_SET header)
{
return fields->GetBoolHeader(header);
}
extern "C" XP_Bool
MSG_GetForcePlainText(MSG_CompositionFields* fields)
{
return fields->GetForcePlainText();
}
#ifdef XP_UNIX
extern "C" MSG_Pane*
MSG_ComposeMessage (MWContext *old_context,
const char *from,
const char *reply_to,
const char *to,
const char *cc,
const char *bcc,
const char *fcc,
const char *newsgroups,
const char *followup_to,
const char *organization,
const char *subject,
const char *references,
const char *other_random_headers,
const char *priority,
const char *attachment,
const char *newspost_url,
const char *body,
XP_Bool force_plain_text,
const char* html_part
)
{
// Don't allow a compose window to be created if the user hasn't
// specified an email address
const char *real_addr = FE_UsersMailAddress();
if (MISC_ValidateReturnAddress(old_context, real_addr) < 0)
return NULL;
MSG_CompositionFields* fields =
MSG_CreateCompositionFields(from, reply_to, to, cc, bcc,
fcc, newsgroups, followup_to,
organization, subject, references,
other_random_headers, priority, attachment,
newspost_url);
fields->SetForcePlainText(force_plain_text);
fields->SetHTMLPart(html_part);
fields->SetDefaultBody(body);
XP_Bool prefBool = FALSE;
PREF_GetBoolPref("mail.attach_vcard",&prefBool);
fields->SetAttachVCard(prefBool);
MSG_CompositionPane* comppane = (MSG_CompositionPane*)
FE_CreateCompositionPane(old_context, fields, NULL, MSG_DEFAULT);
if (!comppane) {
delete fields;
return NULL;
}
XP_ASSERT(comppane->GetPaneType() == MSG_COMPOSITIONPANE);
return comppane;
}
#endif //XP_UNIX
extern "C" XP_Bool
MSG_ShouldAutoQuote(MSG_Pane* comppane)
{
return CastCompositionPane(comppane)->ShouldAutoQuote();
}
extern "C" const char*
MSG_GetCompHeader(MSG_Pane* comppane, MSG_HEADER_SET header)
{
return CastCompositionPane(comppane)->GetCompHeader(header);
}
extern "C" int
MSG_SetCompHeader(MSG_Pane* comppane, MSG_HEADER_SET header, const char* value)
{
return CastCompositionPane(comppane)->SetCompHeader(header, value);
}
extern "C" XP_Bool
MSG_GetCompBoolHeader(MSG_Pane* comppane, MSG_BOOL_HEADER_SET header)
{
return CastCompositionPane(comppane)->GetCompBoolHeader(header);
}
extern "C" int
MSG_SetCompBoolHeader(MSG_Pane* comppane, MSG_BOOL_HEADER_SET header, XP_Bool bValue)
{
return CastCompositionPane(comppane)->SetCompBoolHeader(header, bValue);
}
extern "C" const char*
MSG_GetCompBody(MSG_Pane* comppane)
{
return CastCompositionPane(comppane)->GetCompBody();
}
extern "C" int
MSG_SetCompBody(MSG_Pane* comppane, const char* value)
{
return CastCompositionPane(comppane)->SetCompBody(value);
}
extern "C" void
MSG_QuoteMessage(MSG_Pane* comppane,
int (*func)(void* closure, const char* data),
void* closure)
{
CastCompositionPane(comppane)->QuoteMessage(func, closure);
}
extern "C" int
MSG_SanityCheck(MSG_Pane* comppane, int skippast)
{
return CastCompositionPane(comppane)->SanityCheck(skippast);
}
extern "C" const char*
MSG_GetAssociatedURL(MSG_Pane* comppane)
{
return CastCompositionPane(comppane)->GetDefaultURL();
}
extern "C" void
MSG_MailCompositionAllConnectionsComplete(MSG_Pane* comppane)
{
CastCompositionPane(comppane)->MailCompositionAllConnectionsComplete();
}
extern "C" int
MSG_PastePlaintextQuotation(MSG_Pane* comppane, const char* string)
{
return CastCompositionPane(comppane)->PastePlaintextQuotation(string);
}
extern "C" char*
MSG_UpdateHeaderContents(MSG_Pane* comppane,
MSG_HEADER_SET header,
const char* value)
{
return CastCompositionPane(comppane)->UpdateHeaderContents(header, value);
}
extern "C" int
MSG_SetAttachmentList(MSG_Pane* comppane,
struct MSG_AttachmentData* list)
{
return CastCompositionPane(comppane)->SetAttachmentList(list);
}
extern "C" const struct MSG_AttachmentData*
MSG_GetAttachmentList(MSG_Pane* comppane)
{
return CastCompositionPane(comppane)->GetAttachmentList();
}
extern "C" MSG_HEADER_SET MSG_GetInterestingHeaders(MSG_Pane* comppane)
{
return CastCompositionPane(comppane)->GetInterestingHeaders();
}
extern "C" XP_Bool MSG_IsDuplicatePost(MSG_Pane* comppane) {
// if we're sending from the outbox, we don't have a compostion pane, so guess NO.
return (comppane->GetPaneType() == MSG_COMPOSITIONPANE)
? CastCompositionPane(comppane)->IsDuplicatePost()
: FALSE;
}
extern "C" void
MSG_ClearCompositionMessageID(MSG_Pane* comppane)
{
if (comppane->GetPaneType() == MSG_COMPOSITIONPANE)
CastCompositionPane(comppane)->ClearCompositionMessageID();
}
extern "C" const char*
MSG_GetCompositionMessageID(MSG_Pane* comppane)
{
return (comppane->GetPaneType() == MSG_COMPOSITIONPANE)
? CastCompositionPane(comppane)->GetCompositionMessageID()
: 0;
}
/* What are we going to do about error messages and codes? Internally, we'd
like a nice error range system, but we need to export errors too... ###
*/
extern "C"
int ConvertMsgErrToMKErr(MsgERR err)
{
switch (err)
{
case eSUCCESS:
return 0;
case eOUT_OF_MEMORY:
return MK_OUT_OF_MEMORY;
case eID_NOT_FOUND:
return MK_MSG_ID_NOT_IN_FOLDER;
case eUNKNOWN:
return -1;
}
// Well, most likely, someone returned a negative number that
// got cast somewhere into a MsgERR. If so, just return that value.
if (int(err) < 0) return int(err);
// Punt, and return the generic unknown error.
return -1;
}
extern "C"
int MSG_RetrieveStandardHeaders(MSG_Pane * pane, MSG_HeaderEntry ** return_list)
{
XP_ASSERT(pane && pane->GetPaneType() == MSG_COMPOSITIONPANE);
return CastCompositionPane(pane)->RetrieveStandardHeaders(return_list);
}
extern "C"
void MSG_SetHeaderEntries(MSG_Pane * pane,MSG_HeaderEntry * in_list,int count)
{
XP_ASSERT(pane && pane->GetPaneType() == MSG_COMPOSITIONPANE);
CastCompositionPane(pane)->SetHeaderEntries(in_list,count);
}
extern "C"
void MSG_ClearComposeHeaders(MSG_Pane * pane)
{
XP_ASSERT(pane && pane->GetPaneType() == MSG_COMPOSITIONPANE);
CastCompositionPane(pane)->ClearComposeHeaders();
}
extern "C"
int MSG_ProcessBackground(URL_Struct* urlstruct)
{
return msg_Background::ProcessBackground(urlstruct);
}
extern "C" XP_Bool MSG_RequestForReturnReceipt(MSG_Pane *pane)
{
return pane->GetRequestForReturnReceipt();
}
extern "C" XP_Bool MSG_SendingMDNInProgress(MSG_Pane *pane)
{
return pane->GetSendingMDNInProgress();
}
//
// NET_IsOffline() is declared in net.h, but libnet doesn't define it
// publically anywhere. There's one in network/protocols/nntp/mknews.c
// but it's declared MODULE_PRIVATE and we can't see it from here,
// at least not in MOZ_MAIL_COMPOSE mode.
//
#ifndef MOZ_MAIL_NEWS
XP_Bool NET_IsOffline() { return FALSE; }
#endif /* MOZ_MAIL_NEWS */