gecko-dev/cmd/winfe/compfe.cpp
1998-03-28 02:44:41 +00:00

630 lines
20 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.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "stdafx.h"
#include "template.h"
#include "msgcom.h"
#include "wfemsg.h"
#include "compstd.h"
#include "compbar.h"
#include "compmisc.h"
#include "compfrm.h"
#include "edt.h"
#include "edview.h"
#include "intl_csi.h"
#include "prefapi.h"
#include "apiaddr.h"
#include "postal.h"
#include "mailmisc.h"
#include "dlghtmrp.h"
#include "dlghtmmq.h"
extern "C" {
#include "xpgetstr.h"
extern int MK_MSG_MSG_COMPOSITION;
};
extern "C" int FE_LoadExchangeInfo(MWContext * context);
extern "C" MSG_Pane * DoAltMailComposition(MWContext *pOldContext, MSG_CompositionFields* fields);
int WFE_InsertMessage(void *closure, const char * data);
extern "C" void FE_DestroyMailCompositionContext(MWContext *pContext)
{
CGenericFrame * pFrame = wfe_FrameFromXPContext(pContext);
if ( pFrame ) {
CComposeFrame * pCompose = (CComposeFrame *) pFrame;
if (pCompose->UseHtml())
EDT_SetDirtyFlag(pContext,FALSE);
else
pCompose->GetEditorParent()->m_bModified = FALSE;
pCompose->SetMsgPane(NULL);
if(pCompose) {
pCompose->PostMessage ( WM_CLOSE );
}
}
}
extern "C" int FE_GetMessageBody(MSG_Pane *pPane, char **ppBody, uint32 *ulBodySize, MSG_FontCode **ppFontChanges)
{
ASSERT(pPane);
CComposeFrame * pCompose = (CComposeFrame *) MSG_GetFEData(pPane);
ASSERT(pCompose);
MWContext *pContext = pCompose->GetMainContext()->GetContext();
ASSERT(pContext);
if (pCompose->UseHtml())
{
MSG_SetHTMLMarkup(pPane,TRUE);
*ppBody = NULL;
*ulBodySize = 0;
if ( pCompose )
{
// Danger!!! This is not legal!!! We must change this to be a real XP_HUGE for win16.
// see bug #39756
EDT_SaveToBuffer(pContext,(XP_HUGE_CHAR_PTR*) ppBody);
if ( !*ppBody)
return 1;
else {
size_t lsize;
lsize = strlen(*ppBody);
*ulBodySize = lsize;
return lsize;
}
}
return 0;
}
// new compose window code
size_t lsize = 0;
#ifdef XP_WIN16
unsigned int textLength; // Cannot use uint32/int32; the compiler won't
// generate the correct code. Use unsigned int, at least
// we could get over with the 32767 boundary.
// Although 16-bit CEdit::GetWindowTextLength returns int casting it to
// unsigned int we can still get the correct text length if the text length is
// greater than 32767
textLength = (unsigned int) pCompose->GetEditor()->GetWindowTextLength();
#else
int32 textLength;
textLength = pCompose->GetEditor()->GetWindowTextLength();
#endif
if ( textLength >= 0 )
{
char * tmp = (char *)XP_CALLOC(1,textLength+1);
ASSERT ( tmp );
pCompose->GetEditor()->GetWindowText(tmp, textLength+1);
if (pCompose->GetWrapLongLines())
{
int32 lineWidth = 72;
PREF_GetIntPref("mailnews.wraplength", &lineWidth);
if (lineWidth < 10) lineWidth = 10;
if (lineWidth > 30000) lineWidth = 30000;
*ppBody = (char *) XP_WordWrap(INTL_DefaultWinCharSetID(pContext),
(unsigned char *)tmp, lineWidth, 1 /* look for '>' */);
free(tmp);
}
else
{
/* Else, don't wrap it at all. */
*ppBody = tmp;
}
if (ppBody && *ppBody)
for (const char *ptr = *ppBody; ptr && *ptr; ptr++)
lsize++;
}
*ulBodySize = lsize;
return 0;
}
//
// Create a composition window
//
extern "C" void FE_InitializeMailCompositionContext(MSG_Pane *pComposePane,
const char *pFrom,
const char *pReplyTo,
const char *pTo,
const char *pCc,
const char *pBcc,
const char *pFcc,
const char *pNewsgroups,
const char *pFollowupTo,
const char *pSubject,
const char *pAttachment)
{
MSG_SetCompHeader(pComposePane, MSG_TO_HEADER_MASK, pTo);
MSG_SetCompHeader(pComposePane, MSG_FROM_HEADER_MASK, pFrom);
MSG_SetCompHeader(pComposePane, MSG_SUBJECT_HEADER_MASK, pSubject);
MSG_SetCompHeader(pComposePane, MSG_CC_HEADER_MASK, pCc);
MSG_SetCompHeader(pComposePane, MSG_BCC_HEADER_MASK, pBcc);
MSG_SetCompHeader(pComposePane, MSG_FCC_HEADER_MASK, pFcc);
MSG_SetCompHeader(pComposePane, MSG_REPLY_TO_HEADER_MASK, pReplyTo);
MSG_SetCompHeader(pComposePane, MSG_FOLLOWUP_TO_HEADER_MASK, pFollowupTo);
MSG_SetCompHeader(pComposePane, MSG_NEWSGROUPS_HEADER_MASK, pNewsgroups);
}
MWContext * g_NastyContextSavingHack = NULL;
// create a new xpContext with type == MWContextMessageComposition
extern "C" MSG_Pane *FE_CreateCompositionPane(MWContext *pOldContext,
MSG_CompositionFields* fields,
const char *pInitialText,
MSG_EditorType editorType)
{
if(!theApp.m_hPostalLib) {
CGenericDoc * pDocument;
// 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(pOldContext, real_addr) < 0)
return NULL;
XP_Bool htmlCompose;
PREF_GetBoolPref("mail.html_compose",&htmlCompose);
if (editorType == MSG_HTML_EDITOR)
htmlCompose = TRUE;
else if (editorType == MSG_PLAINTEXT_EDITOR)
htmlCompose = FALSE;
INTL_CharSetInfo csi = LO_GetDocumentCharacterSetInfo(pOldContext);
int16 win_csid = INTL_GetCSIWinCSID(csi);
if (!MSG_GetForcePlainText(fields) && htmlCompose)
pDocument = (CGenericDoc*)theApp.m_ComposeTemplate->OpenDocumentFile(NULL, win_csid);
else
pDocument = (CGenericDoc*)theApp.m_TextComposeTemplate->OpenDocumentFile(NULL, win_csid);
g_NastyContextSavingHack = pOldContext;
if ( pDocument )
{
CWinCX * pContext = (CWinCX*) pDocument->GetContext();
if ( pContext ) {
MSG_CompositionPaneCallbacks Callbacks;
Callbacks.CreateRecipientsDialog= CreateRecipientsDialog;
Callbacks.CreateAskHTMLDialog= CreateAskHTMLDialog;
MWContext *context = pContext->GetContext();
CComposeFrame *pCompose = (CComposeFrame *) pContext->GetFrame()->GetFrameWnd();
pCompose->SetComposeStuff(pOldContext,fields); // squirl away stuff for post-create
// This needs to be set TRUE if using the old non-HTML text frame
// to prevent dropping dragged URLs
pContext->m_bDragging = !pCompose->UseHtml();
if (!pCompose->UseHtml())
{
pCompose->SetMsgPane(MSG_CreateCompositionPane(
pContext->GetContext(),
pOldContext, g_MsgPrefs.m_pMsgPrefs, fields,
WFE_MSGGetMaster()));
}
else
{
pCompose->SetMsgPane(MSG_CreateCompositionPaneNoInit(
pContext->GetContext(),
g_MsgPrefs.m_pMsgPrefs,
WFE_MSGGetMaster()));
//set the callbacks for askHTML and Recipients dialogs
MSG_SetCompositionPaneCallbacks( pCompose->GetMsgPane(),
&Callbacks,
0);
if (pCompose->GetMsgPane())
MSG_SetHTMLMarkup(pCompose->GetMsgPane(), TRUE);
}
ASSERT(pCompose->GetMsgPane());
MSG_SetFEData(pCompose->GetMsgPane(),(void *)pCompose);
pCompose->UpdateAttachmentInfo();
// Pass doccsid and win_csid info to new context for MailToWin conversion
INTL_CharSetInfo old_csi = LO_GetDocumentCharacterSetInfo(pOldContext);
INTL_CharSetInfo new_csi = LO_GetDocumentCharacterSetInfo(context);
int16 doccsid = INTL_GetCSIDocCSID(old_csi);
INTL_SetCSIDocCSID(new_csi,
(doccsid ? doccsid : INTL_DefaultDocCharSetID(pOldContext)));
INTL_SetCSIWinCSID(new_csi,
(win_csid ? win_csid : INTL_DocToWinCharSetID(INTL_GetCSIDocCSID(new_csi))));
pCompose->DisplayHeaders(NULL);
CComposeBar * pBar = pCompose->GetComposeBar();
ASSERT(pBar);
LPADDRESSCONTROL pIAddressList = pBar->GetAddressWidgetInterface();
if (!pIAddressList->IsCreated())
{
pBar->CreateAddressingBlock();
}
if (!pCompose->UseHtml())
{
pCompose->CompleteComposeInitialization();
const char * pBody = pInitialText ? pInitialText : MSG_GetCompBody(pCompose->GetMsgPane());
if (pBody)
{
FE_InsertMessageCompositionText(context,pBody,TRUE);
// We don't want to quote the original if open as draft
// Check for the editorType before we do the quoting
// Since only draft code will specify what editor to
// use, checking for editorType == MSG_DEFAULT will do
// the work.
if (MSG_ShouldAutoQuote(pCompose->GetMsgPane()) &&
editorType == MSG_DEFAULT)
{
pCompose->SetQuoteSelection();
MSG_QuoteMessage(
pCompose->GetMsgPane(),
WFE_InsertMessage,
(void*)pCompose->GetMainContext()->GetContext());
}
}
}
else
{
pCompose->SetInitialText (pInitialText);
URL_Struct * pUrl = NET_CreateURLStruct(EDT_NEW_DOC_URL,NET_DONT_RELOAD);
if (pUrl != NULL)
{
// pUrl->pre_exit_fn = wfe_GoldDoneLoading;
pContext->GetUrl(pUrl, FO_CACHE_AND_PRESENT);
pContext->GetContext()->bIsComposeWindow = TRUE;
}
}
if (MSG_GetAttachmentList(pCompose->GetMsgPane()))
pCompose->SetModified(TRUE);
else
pCompose->SetModified(FALSE);
// Post message to compose window to set the initial focus.
pCompose->PostMessage(WM_COMP_SET_INITIAL_FOCUS);
return pCompose->GetMsgPane();
}
}
return NULL;
}
else
return DoAltMailComposition(pOldContext, fields);
}
extern "C" void FE_RaiseMailCompositionWindow(MSG_Pane *pPane)
{
CComposeFrame * pCompose = (CComposeFrame *) MSG_GetFEData(pPane);
#ifdef XP_WIN32
if(!theApp.m_hPostalLib) {
#endif
pCompose->SendMessageToDescendants(WM_INITIALUPDATE, 0, 0, TRUE, TRUE);
pCompose->ShowWindow(SW_SHOW);
// Make Sure OnInitialUpdate gets called for the view.
pCompose->DisplayHeaders(pCompose->GetSavedHeaders());
#ifdef XP_WIN32
}
else {
FE_LoadExchangeInfo(pCompose->GetMainContext()->GetContext());
}
#endif
}
extern "C" void FE_InsertMessageCompositionText(MWContext * context,
const char* text,
XP_Bool leaveCursorAtBeginning)
{
if (context) {
if (ABSTRACTCX(context)->IsDestroyed())
return;
CGenericFrame * pFrame = wfe_FrameFromXPContext(context);
if (pFrame)
{
CComposeFrame * pCompose = (CComposeFrame *) pFrame;
if ( pCompose )
{
int nStartChar, nEndChar;
if (!pCompose->UseHtml())
{
if ( leaveCursorAtBeginning )
pCompose->GetEditor()->GetSel(nStartChar, nEndChar);
pCompose->GetEditor()->ReplaceSel ( text );
if ( leaveCursorAtBeginning )
pCompose->GetEditor()->SetSel (nStartChar, nEndChar, TRUE );
}
else
{
ED_BufferOffset ins = -1;
if ( leaveCursorAtBeginning ){
ins = EDT_GetInsertPointOffset( context );
}
EDT_PasteQuote( context, (char*) text );
if ( leaveCursorAtBeginning && ins != -1 ) {
EDT_SetInsertPointToOffset( context, ins, 0 );
}
}
pCompose->GetChrome()->StopAnimation();
}
}
}
}
extern "C" void FE_DoneWithMessageBody(MSG_Pane *pPane, char* body,
uint32 body_size)
{
XP_FREE(body);
}
extern "C" char * FE_PromptMessageSubject (MWContext * pContext)
{
HWND hWnd = GetFocus();
CString csText;
CString csDefault;
csText.LoadString(IDS_COMPOSE_NOSUBJECT);
csDefault.LoadString(IDS_COMPOSE_DEFAULTNOSUBJECT);
char * ptr = CFE_Prompt(pContext, csText, csDefault );
SetFocus(hWnd);
if (!ptr)
{
CGenericFrame * pFrame = wfe_FrameFromXPContext(pContext);
CComposeFrame * pCompose = (CComposeFrame *) pFrame;
pCompose->GetChrome()->StopAnimation();
}
return ptr;
}
#ifdef XP_WIN32
extern void FE_UpdateComposeWindowRecipients(MWContext *pContext,
char *pTo, char *pCc, char *pBcc)
{
CGenericFrame * pFrame = wfe_FrameFromXPContext(pContext);
CComposeFrame * pCompose = (CComposeFrame *) pFrame;
if ( pCompose )
{
CComposeBar * pBar = pCompose->GetComposeBar();
ASSERT(pBar);
pBar->UpdateRecipientInfo (pTo, pCc, pBcc);
}
}
#endif
extern "C" MSG_Pane * DoAltMailComposition(MWContext *pOldContext, MSG_CompositionFields* fields)
{
CGenericDoc * pDocument;
INTL_CharSetInfo csi = LO_GetDocumentCharacterSetInfo(pOldContext);
pDocument = (CGenericDoc*)theApp.m_TextComposeTemplate->OpenDocumentFile(NULL, INTL_GetCSIWinCSID(csi));
g_NastyContextSavingHack = pOldContext;
if ( pDocument )
{
CWinCX * pContext = (CWinCX*) pDocument->GetContext();
if ( pContext )
{
MWContext *context = pContext->GetContext();
CComposeFrame *pCompose = (CComposeFrame *) pContext->GetFrame()->GetFrameWnd();
pCompose->SetComposeStuff(pOldContext,fields); // squirl away stuff for post-create
pCompose->SetMsgPane(MSG_CreateCompositionPane(
pContext->GetContext(),
pOldContext, g_MsgPrefs.m_pMsgPrefs, fields,
WFE_MSGGetMaster()));
ASSERT(pCompose->GetMsgPane());
MSG_SetFEData(pCompose->GetMsgPane(),(void *)pCompose);
pCompose->DisplayHeaders(NULL);
FE_LoadExchangeInfo(context);
return pCompose->GetMsgPane();
}
}
return NULL;
}
#define MAX_MAIL_SIZE 300000
extern "C" void FE_DoneMailTo(PrintSetup * print)
{
ASSERT(print);
MWContext * context = (MWContext *) print->carg;
CGenericFrame * pFrame = wfe_FrameFromXPContext(context);
ASSERT(pFrame);
CComposeFrame * pCompose;
pCompose = (CComposeFrame *) pFrame;
ASSERT(pFrame);
MSG_Pane * pMsgPane = pCompose->GetMsgPane();
ASSERT(pMsgPane);
fclose(print->out);
//
// No no no, get the size the right way
//
char * buffer;
buffer = (char *) malloc(MAX_MAIL_SIZE + 5);
FILE * fp = fopen(print->filename, "r");
int len = fread(buffer, 1, MAX_MAIL_SIZE + 5, fp);
buffer[len] = '\0';
fclose(fp);
if(theApp.m_hPostalLib) {
if(theApp.m_bInitMapi) {
if(theApp.m_fnOpenMailSession) {
POSTCODE status = (*theApp.m_fnOpenMailSession) (NULL, NULL);
if(status == POST_OK) {
theApp.m_bInitMapi = FALSE;
}
else {
FE_DestroyMailCompositionContext(context);
return;
}
}
}
// create mail window with no quoting
if(theApp.m_fnComposeMailMessage)
(*theApp.m_fnComposeMailMessage) ((const char *) (const char *) MSG_GetCompHeader(pMsgPane, MSG_TO_HEADER_MASK),
(const char *) "", /* no refs field. BAD! BUG! */
(const char *) MSG_GetCompHeader(pMsgPane, MSG_ORGANIZATION_HEADER_MASK),
(const char *) "", /* no URL */
(const char *) MSG_GetCompHeader(pMsgPane, MSG_SUBJECT_HEADER_MASK),
buffer,
(const char *) MSG_GetCompHeader(pMsgPane, MSG_CC_HEADER_MASK),
(const char *) MSG_GetCompHeader(pMsgPane, MSG_BCC_HEADER_MASK));
// get rid of the file and free the memory
remove(print->filename);
// XP_FREE(print->filename);
// print->filename = NULL;
XP_FREE(buffer);
FE_DestroyMailCompositionContext(context);
return;
}
}
extern "C" int FE_LoadExchangeInfo(MWContext * context)
{
if(!context)
return(FALSE);
if(!theApp.m_hPostalLib)
return(FALSE);
CGenericFrame * pFrame = wfe_FrameFromXPContext(context);
ASSERT(pFrame);
CComposeFrame * pCompose;
pCompose = (CComposeFrame *) pFrame;
ASSERT(pFrame);
MSG_Pane * pMsgPane = pCompose->GetMsgPane();
ASSERT(pMsgPane);
History_entry * hist_ent = NULL;
if(g_NastyContextSavingHack)
hist_ent = SHIST_GetCurrent(&(g_NastyContextSavingHack->hist));
CString csURL;
if(hist_ent)
csURL = hist_ent->address;
else
csURL = "";
//Set hist_ent to NULL if context->title is "Message Composition"
//This is a nasty way of determining if we're in here in response
//to "Mail Doc" or "New Mail Message".
//Also, if there's To: field info present(pBar->m_pszTo) then
//we know that it's a Mailto: and set hist_ent to NULL
//Without this differentiation the code always sends the contents
//of the previously mailed document even when someone chooses
//"New Mail Message" or "Mailto:"
const char * pszTo = MSG_GetCompHeader(pMsgPane, MSG_TO_HEADER_MASK);
if(!strcmp(XP_GetString(MK_MSG_MSG_COMPOSITION), context->title) || strlen(pszTo) )
hist_ent = NULL;
// make sure there was a document loaded
if(!hist_ent) {
if(theApp.m_bInitMapi) {
if(theApp.m_fnOpenMailSession) {
POSTCODE status = (*theApp.m_fnOpenMailSession) (NULL, NULL);
if(status == POST_OK) {
theApp.m_bInitMapi = FALSE;
}
else {
FE_DestroyMailCompositionContext(context);
return(FALSE);
}
}
}
// create mail window with no quoting
if(theApp.m_fnComposeMailMessage)
(*theApp.m_fnComposeMailMessage) ((const char *) MSG_GetCompHeader(pMsgPane, MSG_TO_HEADER_MASK),
(const char *) "", /* no refs field. BAD! BUG! */
(const char *) MSG_GetCompHeader(pMsgPane, MSG_ORGANIZATION_HEADER_MASK),
(const char *) "", /* no URL */
(const char *) MSG_GetCompHeader(pMsgPane, MSG_SUBJECT_HEADER_MASK),
"",
(const char *) MSG_GetCompHeader(pMsgPane, MSG_CC_HEADER_MASK),
(const char *) MSG_GetCompHeader(pMsgPane, MSG_BCC_HEADER_MASK));
FE_DestroyMailCompositionContext(context);
return(TRUE);
}
URL_Struct * URL_s = SHIST_CreateURLStructFromHistoryEntry(g_NastyContextSavingHack, hist_ent);
// Zero out the saved data
memset(&URL_s->savedData, 0, sizeof(URL_s->savedData));
PrintSetup print;
XL_InitializeTextSetup(&print);
print.width = 68;
print.prefix = "";
print.eol = "\r\n";
char * name = WH_TempName(xpTemporary, NULL);
if(!name) {
FE_DestroyMailCompositionContext(context);
return(FALSE);
}
print.out = fopen(name, "w");
print.completion = (XL_CompletionRoutine) FE_DoneMailTo;
print.carg = context;
print.filename = name;
print.url = URL_s;
// leave pCompose window alive until completion routine
XL_TranslateText(g_NastyContextSavingHack, URL_s, &print);
return(TRUE);
}
extern "C" void FE_SecurityOptionsChanged(MWContext * pContext)
{
CGenericFrame * pFrame = wfe_FrameFromXPContext(pContext);
if ( pFrame ) {
CComposeFrame * pCompose = (CComposeFrame *) pFrame;
pCompose->UpdateSecurityOptions();
}
}