/* -*- 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. */ // // Public interface and shared subsystem data. // #ifdef EDITOR #include "editor.h" #include "rosetta.h" #include "fsfile.h" // For XP Strings extern "C" { #include "xpgetstr.h" #define WANT_ENUM_STRING_IDS #include "allxpstr.h" #undef WANT_ENUM_STRING_IDS } #include "xp_str.h" #include "prefapi.h" #include "secnav.h" #include "msgcom.h" #include "intl_csi.h" //extern "C" int XP_EDT_HEAD_FAILED; CBitArray *edt_setNoEndTag = 0; CBitArray *edt_setWriteEndTag = 0; CBitArray *edt_setHeadTags = 0; CBitArray *edt_setSoloTags = 0; CBitArray *edt_setBlockFormat = 0; CBitArray *edt_setCharFormat = 0; CBitArray *edt_setList = 0; CBitArray *edt_setUnsupported = 0; CBitArray *edt_setAutoStartBody = 0; CBitArray *edt_setTextContainer = 0; CBitArray *edt_setListContainer = 0; CBitArray *edt_setParagraphBreak = 0; CBitArray *edt_setFormattedText = 0; CBitArray *edt_setContainerSupportsAlign = 0; CBitArray *edt_setIgnoreWhiteSpace = 0; CBitArray *edt_setSuppressNewlineBefore = 0; CBitArray *edt_setRequireNewlineAfter = 0; CBitArray *edt_setContainerBreakConvert = 0; CBitArray *edt_setContainerHasLineAfter = 0; CBitArray *edt_setIgnoreBreakAfterClose = 0; //----------------------------------------------------------------------------- // BitArrays //----------------------------------------------------------------------------- static XP_Bool bBitsInited = FALSE; void edt_InitBitArrays() { if( bBitsInited ){ return; } bBitsInited = TRUE; int size = P_MAX + 1; // +1 because CEditRootElements are of type P_MAX. // Note -- P_UNKNOWN can't be in these arrays because it has a value of -1. edt_setNoEndTag = new CBitArray( size, P_TEXT, P_PARAGRAPH, P_IMAGE, P_NEW_IMAGE, P_INPUT, P_LIST_ITEM, P_HRULE, P_DESC_TITLE, P_NSDT, P_DESC_TEXT, P_LINEBREAK, P_WORDBREAK, P_INDEX, P_BASE, P_LINK, P_META, P_GRID_CELL, P_INPUT, //cmanske - forms End tag is "forbidden" BIT_ARRAY_END ); edt_setWriteEndTag = new CBitArray( size, P_HEADER_1, P_HEADER_2, P_HEADER_3, P_HEADER_4, P_HEADER_5, P_HEADER_6, P_PARAGRAPH, P_ADDRESS, P_PREFORMAT, P_LIST_ITEM, P_DESC_TITLE, P_DESC_TEXT, P_NSDT, BIT_ARRAY_END ); edt_setHeadTags = new CBitArray( size, P_INDEX, P_BASE, P_LINK, BIT_ARRAY_END ); edt_setSoloTags = new CBitArray( size, P_TEXT, P_IMAGE, P_NEW_IMAGE, P_HRULE, P_LINEBREAK, P_WORDBREAK, P_AREA, P_INPUT, BIT_ARRAY_END ); edt_setBlockFormat = new CBitArray( size, P_ANCHOR, P_CENTER, P_DIVISION, P_BLINK, BIT_ARRAY_END ); // // Character formatting tags // edt_setCharFormat = new CBitArray( size, P_BOLD, P_ITALIC, P_FONT, P_EMPHASIZED, P_STRONG, P_SAMPLE, P_KEYBOARD, P_VARIABLE, P_ANCHOR, P_STRIKEOUT, P_UNDERLINE, P_FIXED, P_EMPHASIZED, P_STRONG, P_CODE, P_SAMPLE, P_KEYBOARD, P_VARIABLE, P_CITATION, P_CENTER, P_BLINK, P_BIG, P_SMALL, P_SUPER, P_SUB, P_NOBREAK, P_SERVER, P_SCRIPT, P_STYLE, P_SPELL, P_INLINEINPUT, P_INLINEINPUTTHICK, P_INLINEINPUTDOTTED, BIT_ARRAY_END ); edt_setList = new CBitArray( size, P_UNUM_LIST, P_NUM_LIST, P_DESC_LIST, P_MENU, P_DIRECTORY, P_BLOCKQUOTE, P_MQUOTE, BIT_ARRAY_END ); // All the tags that are known to navigator, but not to us. edt_setUnsupported = new CBitArray( size, P_AREA, P_CELL, P_CERTIFICATE, P_ILAYER, P_LAYER, P_NOLAYER, //cmanske - added 9/4/97 P_COLORMAP, P_EMBED, P_BUILTIN, P_FORM, P_INPUT, P_OPTION, P_SELECT, P_TEXTAREA, P_GRID, P_GRID_CELL, P_HYPE, P_INDEX, P_JAVA_APPLET, P_KEYGEN, P_MAP, P_MULTICOLUMN, P_NOEMBED, P_NOGRIDS, P_NOSCRIPT, P_OBJECT, P_PARAM, P_SPACER, P_SUBDOC, P_WORDBREAK, P_NOSCRIPT, P_SPAN, BIT_ARRAY_END ); // Any of these tags, when they appear, automatically start the body of // the document. edt_setAutoStartBody = new CBitArray( size, P_TEXT, // P_TITLE, // P_INDEX, // P_BASE, // P_LINK, P_HEADER_1, P_HEADER_2, P_HEADER_3, P_HEADER_4, P_HEADER_5, P_HEADER_6, P_ANCHOR, P_PARAGRAPH, P_ADDRESS, P_IMAGE, P_PLAIN_TEXT, P_PLAIN_PIECE, P_PREFORMAT, P_LISTING_TEXT, P_UNUM_LIST, P_NUM_LIST, P_MENU, P_DIRECTORY, P_LIST_ITEM, P_DESC_LIST, P_DESC_TITLE, P_DESC_TEXT, P_STRIKEOUT, P_FIXED, P_BOLD, P_ITALIC, P_EMPHASIZED, P_STRONG, P_CODE, P_SAMPLE, P_KEYBOARD, P_VARIABLE, P_CITATION, P_BLOCKQUOTE, P_FORM, P_INPUT, P_SELECT, P_OPTION, P_TEXTAREA, P_HRULE, P_LINEBREAK, P_WORDBREAK, P_NOBREAK, P_BASEFONT, P_FONT, P_BLINK, P_NEW_IMAGE, P_CENTER, P_SUBDOC, P_CELL, P_TABLE, P_CAPTION, P_TABLE_ROW, P_TABLE_HEADER, P_TABLE_DATA, P_EMBED, // P_BODY, // P_META, P_COLORMAP, P_HYPE, P_BIG, P_SMALL, P_SUPER, P_SUB, // P_GRID, // P_GRID_CELL, // P_NOGRIDS, P_JAVA_APPLET, P_PARAM, P_MAP, P_AREA, P_DIVISION, P_KEYGEN, // P_SCRIPT, // P_NOSCRIPT, P_NOEMBED, // P_HEAD, // P_HTML, // P_SERVER, P_CERTIFICATE, P_ILAYER, P_STRIKE, P_UNDERLINE, P_SPACER, P_MULTICOLUMN, P_NSCP_CLOSE, P_NSCP_OPEN, P_BLOCK, P_LAYER, //cmanske - fix for bug // P_STYLE, P_MQUOTE, P_SPAN, P_SPELL, P_INLINEINPUT, P_NSCP_REBLOCK, P_OBJECT, P_NSDT, P_INLINEINPUTTHICK, P_INLINEINPUTDOTTED, P_NOLAYER, P_BUILTIN, BIT_ARRAY_END ); edt_setTextContainer = new CBitArray( size, P_TITLE, P_HEADER_1, P_HEADER_2, P_HEADER_3, P_HEADER_4, P_HEADER_5, P_HEADER_6, P_PARAGRAPH, P_ADDRESS, P_PREFORMAT, P_LIST_ITEM, P_DESC_TITLE, P_DESC_TEXT, P_NSDT, BIT_ARRAY_END ); edt_setContainerSupportsAlign = new CBitArray( size, P_HEADER_1, P_HEADER_2, P_HEADER_3, P_HEADER_4, P_HEADER_5, P_HEADER_6, // unfortunately, HRules end paragraph containment, implictly. So we // either need to change the way we deal with
or change the // code. until then, we can't generate "align=center" as part of a // paragraph. //P_PARAGRAPH, //P_ADDRESS, //P_PREFORMAT, //P_LIST_ITEM, //P_DESC_TITLE, //P_DESC_TEXT, BIT_ARRAY_END ); edt_setListContainer = new CBitArray( size, P_UNUM_LIST, P_NUM_LIST, P_MENU, P_DIRECTORY, P_BLOCKQUOTE, P_MQUOTE, BIT_ARRAY_END ); edt_setParagraphBreak = new CBitArray( size, P_TITLE, P_HEADER_1, P_HEADER_2, P_HEADER_3, P_HEADER_4, P_HEADER_5, P_HEADER_6, P_PARAGRAPH, P_LINEBREAK, P_ADDRESS, P_PREFORMAT, P_LIST_ITEM, P_UNUM_LIST, P_NUM_LIST, P_LINEBREAK, P_HRULE, P_DESC_LIST, P_DESC_TITLE, P_DESC_TEXT, P_NSDT, P_MQUOTE, P_TABLE, BIT_ARRAY_END ); edt_setContainerBreakConvert = new CBitArray( size, P_PARAGRAPH, P_LIST_ITEM, P_ADDRESS, P_LIST_ITEM, P_DESC_TITLE, P_DESC_TEXT, P_NSDT , BIT_ARRAY_END ); edt_setFormattedText = new CBitArray( size, P_PREFORMAT, P_PLAIN_PIECE, P_PLAIN_TEXT, P_LISTING_TEXT, BIT_ARRAY_END ); edt_setIgnoreWhiteSpace = new CBitArray( size, P_TABLE, P_TABLE_ROW, BIT_ARRAY_END ); // // Suppress printing a newline before these tags. // edt_setSuppressNewlineBefore = new CBitArray( size, P_LINEBREAK, BIT_ARRAY_END ); // // Print a newline after these tags. // edt_setRequireNewlineAfter = new CBitArray( size, P_LINEBREAK, BIT_ARRAY_END ); edt_setContainerHasLineAfter = new CBitArray( size, P_HEADER_1, P_HEADER_2, P_HEADER_3, P_HEADER_4, P_HEADER_5, P_HEADER_6, P_PREFORMAT, BIT_ARRAY_END ); edt_setIgnoreBreakAfterClose = new CBitArray( size, P_HEADER_1, P_HEADER_2, P_HEADER_3, P_HEADER_4, P_HEADER_5, P_HEADER_6, P_PARAGRAPH, P_ADDRESS, P_PREFORMAT, P_LIST_ITEM, P_DESC_TITLE, P_DESC_TEXT, P_NSDT, BIT_ARRAY_END ); } char *edt_GetPathURL( char* pURL ){ char *pRet = XP_STRDUP(pURL); char * pLastSlash = XP_STRRCHR( pRet, '/' ); if ( pLastSlash == NULL ) { XP_FREE(pRet); return NULL; } pLastSlash++; *pLastSlash = 0; // Actually returning a string with unused space after the /0. return pRet; } //----------------------------------------------------------------------------- // External Interface //----------------------------------------------------------------------------- char* EDT_GetEmptyDocumentString(){ return ""; } ED_Buffer* EDT_MakeEditBuffer(MWContext *pContext, XP_Bool bImportText){ return new CEditBuffer(pContext, bImportText); } XP_Bool EDT_HaveEditBuffer(MWContext * pContext){ return (LO_GetEDBuffer( pContext ) != NULL); } ED_FileError EDT_SaveFile( MWContext * pContext, char * pSourceURL, char * pDestURL, XP_Bool bSaveAs, XP_Bool bKeepImagesWithDoc, XP_Bool bAutoAdjustLinks ) { GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) ED_ERROR_BLOCKED; #if 0 //TODO: SHOULD WE REPLACE SPACES FOR LOCAL FILES? (We do when publishing) // Replace spaces with "_" char *pTemp = pDestURL; while( XP_STRLEN(pTemp) ) { if( *pTemp == ' ' ) *pTemp = '_'; pTemp++; } #endif // Create Abstract file system to write to disk. char *pDestPathURL = edt_GetPathURL(pDestURL); XP_ASSERT(pDestPathURL); ITapeFileSystem *tapeFS = new CTapeFSFile(pDestPathURL,pDestURL); XP_ASSERT(tapeFS); XP_FREE(pDestPathURL); // tapeFS freed by CEditSaveObject. // go to the newly saved document. return pEditBuffer->SaveFile( ED_FINISHED_GOTO_NEW, pSourceURL, tapeFS, bSaveAs, bKeepImagesWithDoc, bAutoAdjustLinks, FALSE, // not AutoSave NULL ); // default files to send with doc } // Declared here since it is only used by edt_publish_head_done and EDT_PublishFile. // Takes care of cleaning itself up. class CEditPublishData { public: CEditPublishData(CEditBuffer *b, ED_SaveFinishedOption finOpt, char *src, char **inclFiles, char *loc, char *user, char *pass, XP_Bool keepIm, XP_Bool autoAdj) :pBuf(b), finishedOpt(finOpt), pSourceURL(XP_STRDUP(src)), ppIncludedFiles(inclFiles), pLocation(XP_STRDUP(loc)), pUsername(XP_STRDUP(user)), pPassword(XP_STRDUP(pass)), bKeepImagesWithDoc(keepIm),bAutoAdjustLinks(autoAdj) {} ~CEditPublishData() {XP_FREEIF(pSourceURL); XP_FREEIF(pLocation); XP_FREE(pUsername); XP_FREEIF(pPassword);} CEditBuffer *pBuf; ED_SaveFinishedOption finishedOpt; char *pSourceURL; char **ppIncludedFiles; // char *pDestFullURL; char *pLocation; // destination. char *pUsername; char *pPassword; XP_Bool bKeepImagesWithDoc; XP_Bool bAutoAdjustLinks; }; // Characters that are not allowed in the destination URL for publishing. // RFC 1808 and RFC 2068, we are erring on the safe side and allowing // some potentially illegal URLs. #define ED_BAD_PUBLISH_URL_CHARS "%# <>\"" // Return a STATIC string, don't free. PRIVATE int edt_CheckPublishURL(char *pURL) { // NULL or empty string. if (!pURL || !(*pURL)) return XP_EDT_PUBLISH_BAD_URL; // Must be ftp:// or http:// int result = NET_URL_Type(pURL); if (result != FTP_TYPE_URL && result != HTTP_TYPE_URL && result != SECURE_HTTP_TYPE_URL) { return XP_EDT_PUBLISH_BAD_PROTOCOL; } // Must not end in a slash, i.e. no filename if (pURL[XP_STRLEN(pURL)-1] == '/') return XP_EDT_PUBLISH_NO_FILE; // Bad characters. char *p = pURL; while (*p) { if (XP_IS_CNTRL(*p) || XP_STRCHR(ED_BAD_PUBLISH_URL_CHARS,*p)) return XP_EDT_PUBLISH_BAD_CHAR; p++; } // The part of the URL after the last slash must have a file extension. // Maybe we should be more strict and require that the extension // be .html, .htm, or .shtml. char *pLastSlash = XP_STRRCHR(pURL,'/'); if (!pLastSlash) return XP_EDT_PUBLISH_NO_EXTENSION; // Search for '.'. if (!XP_STRCHR(pLastSlash,'.')) return XP_EDT_PUBLISH_NO_EXTENSION; return 0; } // Check the URL that will be passed into EDT_PublishFile. // Now corrects for bad characters and appending file extension while here, // so supplied URL string may be changed // MAC AND UNIX -- REMOVE IFDEFs AFTER CHANGING FE CALLS TO USE ppURL #ifdef XP_WIN ED_PublishError EDT_CheckPublishURL( MWContext *pContext, char **ppURL) { char *pURL = *ppURL; #else XP_Bool EDT_CheckPublishURL( MWContext *pContext, char *pURL) { #endif ED_PublishError iRetVal = ED_PUBLISH_OK; int xpStrId = edt_CheckPublishURL(pURL); if (xpStrId) { char *message = XP_GetString(xpStrId); if (message) { // Allocate memory for message. message = XP_STRDUP(message); if( xpStrId == XP_EDT_PUBLISH_BAD_CHAR ) { // Ask user if they want to replace bad chars with '_' if( FE_Confirm(pContext, message) ) { char *p = pURL; while (*p) { if (XP_IS_CNTRL(*p) || XP_STRCHR(ED_BAD_PUBLISH_URL_CHARS,*p)) *p = '_'; p++; } XP_FREEIF(message); // Check for any other errors #ifdef XP_WIN return EDT_CheckPublishURL(pContext, ppURL); #else // TO MAC AND UNIX - DELETE THIS WHEN YOUR CALLS TO EDT_CheckPublishURL USE ppURL return EDT_CheckPublishURL(pContext, pURL); #endif } // Let user edit their mistakes // We don't know if the error was in location part or filename else return ED_PUBLISH_ERROR_FILENAME; } else if( xpStrId == XP_EDT_PUBLISH_NO_EXTENSION ) { // Ask user if they want to append missing extension: ".html" if( FE_Confirm(pContext, message) ) { #ifdef XP_WIN char *pNewLocation = pURL; // Append extension and reallocate if necessary pNewLocation = PR_sprintf_append(pNewLocation, ".html"); *ppURL = pNewLocation; XP_FREEIF(message); // Prevent infinite loop if we had an allocation error if( !pNewLocation ) return ED_PUBLISH_ERROR_FILENAME; // Check for any other errors return EDT_CheckPublishURL(pContext, ppURL); #else // TO MAC AND UNIX - DELETE THIS WHEN YOUR CALLS TO EDT_CheckPublishURL USE ppURL return FALSE; #endif } else return ED_PUBLISH_ERROR_FILENAME; } else { // Report the error, but give the user the option of trying to publish anyway. StrAllocCat(message,"\n\n"); StrAllocCat(message,XP_GetString(XP_EDT_PUBLISH_ERROR_BODY)); if( !FE_Confirm(pContext,message) ) { // The only other filename-specific error is no filename at all iRetVal = (xpStrId == XP_EDT_PUBLISH_NO_FILE) ? ED_PUBLISH_ERROR_FILENAME : ED_PUBLISH_ERROR_LOCATION; } } XP_FREEIF(message); } else { XP_ASSERT(0); } } return iRetVal; } ED_FileError EDT_PublishFile( MWContext * pContext, ED_SaveFinishedOption finishedOpt, char * pSourceURL, char ** ppIncludedFiles, char * pDestFullURL, /* may not have trailing slash */ XP_Bool bKeepImagesWithDoc, XP_Bool bAutoAdjustLinks, XP_Bool /*bSavePassword*/ ) // Not used any more { GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) ED_ERROR_BLOCKED; int type = NET_URL_Type(pDestFullURL); ED_FileError retVal; char *pLocation = NULL; char *pUsername = NULL; char *pPassword = NULL; // This also checks if the URL is complete garbage. if (!NET_ParseUploadURL( pDestFullURL, &pLocation, &pUsername, &pPassword )) return ED_ERROR_BAD_URL; #if 0 // WE NOW ASK USER IF THEY WANT TO DO THIS IN EDT_CheckPublishingURL() // Replace spaces with "_" char *pTemp = pLocation; while( XP_STRLEN(pTemp) ) { if( *pTemp = ' ' ) *pTemp = '_'; pTemp++; } #endif // Assemble a URL that includes username, but not password and filename char * pDestDirectory = EDT_ReplaceFilename(pLocation, NULL, TRUE); // Save the location and username preferences if( pDestDirectory ) { char * pPrefLocation = NULL; if (NET_MakeUploadURL(&pPrefLocation, pDestDirectory, pUsername, NULL)) { // Save as the "last location" in preferences PREF_SetCharPref("editor.publish_last_loc", pPrefLocation); } XP_FREEIF(pPrefLocation); } // FTP if (type == FTP_TYPE_URL) { // For ftp, set dest URL to ftp://username@path, so will edit // properly. Explicitly put the username in the URL. if (pUsername) { char *pUsernameLocation = NULL; if (NET_MakeUploadURL(&pUsernameLocation, pLocation, pUsername,NULL)) { XP_FREEIF(pLocation); pLocation = pUsernameLocation; } } // Note that we rely on SingleSignon to supply a memorized password now retVal = pEditBuffer->PublishFile(finishedOpt, pSourceURL, ppIncludedFiles, pLocation, pUsername,0, bKeepImagesWithDoc,bAutoAdjustLinks); } // HTTP else if (type == HTTP_TYPE_URL || type == SECURE_HTTP_TYPE_URL) { retVal = pEditBuffer->PublishFile(finishedOpt, pSourceURL, ppIncludedFiles, pLocation, pUsername, pPassword, bKeepImagesWithDoc,bAutoAdjustLinks); } else { // We should have already made sure pDestURL is ftp or http before getting here. XP_ASSERT(0); retVal = ED_ERROR_BLOCKED; } XP_FREEIF(pLocation); XP_FREEIF(pUsername); XP_FREEIF(pPassword); return retVal; } ED_FileError EDT_SaveFileTo( MWContext * pContext, ED_SaveFinishedOption finishedOpt, char * pSourceURL, //ITapeFileSystem *tapeFS, void *_tapeFS, XP_Bool bKeepImagesWithDoc, XP_Bool bAutoAdjustLinks ) { GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) ED_ERROR_BLOCKED; ITapeFileSystem *tapeFS = (ITapeFileSystem *)_tapeFS; XP_ASSERT(tapeFS); // tapeFS freed by CEditSaveObject. // saveAs set to TRUE, why not? return pEditBuffer->SaveFile( finishedOpt, pSourceURL, tapeFS, TRUE, bKeepImagesWithDoc, bAutoAdjustLinks, FALSE, // not auto-saving NULL ); // default files to send with doc } char *EDT_GetDocTempDir(MWContext *pContext) { GET_EDIT_BUF_OR_RETURN(pContext,pEditBuffer) NULL; CEditCommandLog *pLog = CGlobalHistoryGroup::GetGlobalHistoryGroup()->GetLog(pEditBuffer); return pLog ? pLog->GetDocTempDir() : 0; } char *EDT_CreateDocTempFilename(MWContext *pContext,char *pPrefix,char *pExtension) { GET_EDIT_BUF_OR_RETURN(pContext,pEditBuffer) NULL; CEditCommandLog *pLog = CGlobalHistoryGroup::GetGlobalHistoryGroup()->GetLog(pEditBuffer); return pLog ? pLog->CreateDocTempFilename(pPrefix,pExtension) : 0; } void EDT_SaveToTempFile(MWContext *pContext,EDT_SaveToTempCallbackFn doneFn, void *hook) { GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); // Get a temporary file name. CEditCommandLog *pLog = CGlobalHistoryGroup::GetGlobalHistoryGroup()->GetLog(pEditBuffer); if (!pLog) { return; } // For printing, ".TMP" doesn't work on Windows. #if defined(XP_WIN) || defined(XP_OS2) char *pTemp = pLog->CreateDocTempFilename(NULL,"htm"); #else char *pTemp = pLog->CreateDocTempFilename(NULL,"html"); #endif if (!pTemp) { XP_ASSERT(0); (*doneFn)(NULL,hook); return; } // pTemp is in xpURL format, so just prepend file:// char *pFileURL = PR_smprintf("file://%s",pTemp); XP_FREE(pTemp); if (!pFileURL) { XP_ASSERT(0); (*doneFn)(NULL,hook); return; } CEditSaveToTempData *pData = new CEditSaveToTempData; if (!pData) { XP_ASSERT(0); XP_FREE(pFileURL); (*doneFn)(NULL,hook); return; } // Fill CEditSaveToTempData structure. pData->doneFn = doneFn; pData->hook = hook; pData->pFileURL = pFileURL; // Takes responsibility for this memory. History_entry * hist_entry = SHIST_GetCurrent(&(pContext->hist)); if(!hist_entry || !hist_entry->address) { XP_ASSERT(0); delete pData; (*doneFn)(NULL,hook); return; } /////// ! Duplicating some code from EDT_SaveFile, but I didn't want to change /////// ! the interface for EDT_SaveFile(), but we still need to pass in the /////// ! CEditSaveToTempData. We really need a better interface for these /////// ! saving functions. Need some sort of CEditSaveOptions structure. // Create Abstract file system to write to disk. char *pDestPathURL = edt_GetPathURL(pFileURL); XP_ASSERT(pDestPathURL); ITapeFileSystem *tapeFS = new CTapeFSFile(pDestPathURL,pFileURL); XP_ASSERT(tapeFS); XP_FREEIF(pDestPathURL); // tapeFS freed by CEditSaveObject. if (!tapeFS) { XP_ASSERT(0); delete pData; (*doneFn)(NULL,hook); return; } char **ppEmptyList = (char **)XP_ALLOC(sizeof(char *)); XP_ASSERT(ppEmptyList); ppEmptyList[0] = NULL; pEditBuffer->SaveFile(ED_FINISHED_REVERT_BUFFER, // Don't want to actually change the buffer. hist_entry->address,tapeFS, TRUE, // saveAs is true, probably doesn't matter. FALSE, // Don't move any images. TRUE, // Adjust the links FALSE, // not auto-saving ppEmptyList, // Don't send along any files, even LOCALDATA. pData); // So will callback. } void EDT_RemoveTempFile(MWContext *pContext,char *pFileURL) { GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); char *pFileURLPath = NET_ParseURL(pFileURL,GET_PATH_PART); if (pFileURLPath) { XP_FileRemove(pFileURLPath,xpURL); } } #if defined(MOZ_MAIL_COMPOSE) || defined(MOZ_MAIL_NEWS) PRIVATE void edt_MailDocumentCB(char *pFileURL,void *hook) { if (!hook) { XP_ASSERT(0); return; } if (!pFileURL) { // Failed to save temp file. return; } MWContext *pContext = (MWContext *)hook; MSG_MailDocumentURL(pContext,pFileURL); } void EDT_MailDocument(MWContext *pContext) { GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); if (EDT_IS_NEW_DOCUMENT(pContext) || EDT_DirtyFlag(pContext)) { // Write to temp file and mail that instead. EDT_SaveToTempFile(pContext,(EDT_SaveToTempCallbackFn) edt_MailDocumentCB,(void *)pContext); } else { MSG_MailDocumentURL(pContext,NULL); } } #endif void EDT_SaveToBuffer(MWContext* pContext, XP_HUGE_CHAR_PTR* pBuffer ) { GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->WriteToBuffer(pBuffer, FALSE); } void EDT_ReadFromBuffer(MWContext* pContext, XP_HUGE_CHAR_PTR pBuffer ) { GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->ReadFromBuffer(pBuffer); } #ifdef MOZ_ENDER_MIME extern "C" { void *MSG_CreateMimeRelatedStreamSaver(MWContext *, char **, char **); }; ED_FileError EDT_SaveMimeToBuffer(MWContext *pContext, XP_HUGE_CHAR_PTR *pBuffer, XP_Bool async) { ED_FileError status = ED_ERROR_NONE; char *pRootPartName = 0; void *fs = MSG_CreateMimeRelatedStreamSaver(pContext, &pRootPartName, (char **)pBuffer); if (!fs) return ED_ERROR_FILE_WRITE; status = EDT_SaveFileTo(pContext, ED_FINISHED_MAIL_SEND, pRootPartName, fs, TRUE, TRUE); if (!async && status == ED_ERROR_NONE) { while ( pContext->edit_saving_url ) FEU_StayingAlive(); } return status; } void EDT_ReadMimeFromBuffer(MWContext* pContext, XP_HUGE_CHAR_PTR pBuffer ) { GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->ReadMimeFromBuffer(pBuffer); } #endif /*MOZ_ENDER_MIME*/ void EDT_SaveCancel( MWContext *pContext ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); if( pEditBuffer->m_pSaveObject){ pEditBuffer->m_pSaveObject->Cancel(); } } void EDT_SetAutoSavePeriod(MWContext *pContext, int32 minutes){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->SetAutoSavePeriod( minutes ); } int32 EDT_GetAutoSavePeriod(MWContext *pContext){ GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) -1; return pEditBuffer->GetAutoSavePeriod(); } // // we are blocked if we are blocked or saving an object. // XP_Bool EDT_IsBlocked( MWContext *pContext ){ CEditBuffer *pEditBuffer = LO_GetEDBuffer( pContext ); return (! pEditBuffer || pEditBuffer->IsBlocked() || pEditBuffer->m_pSaveObject != 0); } // // Streams the edit buffer to a big buffer. // void EDT_DisplaySource( MWContext *pContext ){ GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); //char *pSource = 0; pEditBuffer->DisplaySource(); //pEditBuffer->WriteToBuffer( &pSource ); //FE_DisplaySource( pContext, pSource ); } void EDT_DestroyEditBuffer(MWContext * pContext){ if ( pContext ) { int32 doc_id; lo_TopState *top_state; /* * Get the unique document ID, and retreive this * documents layout state. */ doc_id = XP_DOCID(pContext); top_state = lo_FetchTopState(doc_id); if ((top_state == NULL)||(top_state->doc_state == NULL)) { return; } CEditBuffer *pEditBuffer = top_state->edit_buffer; delete pEditBuffer; top_state->edit_buffer = NULL; } } // // Hooked into the GetURL state machine. We do intermitent processing to // let the layout engine to the initial processing and fetch all the nested // images. // // Returns: 1 - Done ok, continuing. // 0 - Done ok, stopping. // -1 - not done, error. // intn EDT_ProcessTag(void *data_object, PA_Tag *tag, intn status) { pa_DocData *pDocData = (pa_DocData*)data_object; int parseRet = OK_CONTINUE; intn retVal; XP_Bool bCreatedEditor = FALSE; if( !tag || !EDT_IS_EDITOR(pDocData->window_id) ) return LO_ProcessTag( data_object, tag, status ); CEditBuffer* pEditBuffer = (CEditBuffer*) LO_GetEDBuffer(pDocData->window_id); if( pDocData->edit_buffer == 0 ) { // Libnet does not seem to be able to supply us with a reliable // "content_type" in the URL_Struct passed around to the front ends, // so we need to figure out when we are converting a text file into HTML here. // We decide we are importing text if the tag type we encounter for the first tag = PLAIN_TEXT pDocData->edit_buffer = EDT_MakeEditBuffer( pDocData->window_id, tag->type == P_PLAIN_TEXT ); bCreatedEditor = pDocData->edit_buffer != NULL; } if( tag ) { if( tag->type == P_HTML && tag->is_end ) { XP_TRACE(("P_HTML tag")); } // Fix bug 67427 - if the MWContext doesn't have an editor at this point, it // means that the editor has been deleted. CEditBuffer* pEditBuffer = (CEditBuffer*) LO_GetEDBuffer(pDocData->window_id); if ( pEditBuffer != pDocData->edit_buffer && ! bCreatedEditor ){ return LO_ProcessTag( data_object, tag, status ); } parseRet = pDocData->edit_buffer->ParseTag( pDocData, tag, status ); } //Braindead: Any value except NOT_OK will continue parsing // 9/1/98 OK_STOP is not currently used at all // NOT_OK is used to abort while parsing the Content-Type metatag // because charset is bad if( parseRet == NOT_OK ) return NOT_OK; if( parseRet != OK_IGNORE ) { retVal = LO_ProcessTag( data_object, tag, status ); if( tag == 0 ){ //pDocData->edit_buffer->FinishedLoad(); } return retVal; } else { PA_FreeTag(tag); return OK_CONTINUE; } } #if 0 static char *loTypeNames[] = { "LO_NONE", "LO_TEXT", "LO_LINEFEED", "LO_HRULE", "LO_IMAGE", "LO_BULLET", "LO_FORM_ELE", "LO_SUBDOC", "LO_TABLE", "LO_CELL", "LO_EMBED", "LO_BUILTIN", }; // // Debug routine // PRIVATE void EDT_ShowElement( LO_Element* le ){ char buff[512]; CEditTextElement *pText; XP_TRACE((" Type: %s", loTypeNames[le->type] )); XP_TRACE((" ele_id: %d", le->lo_any.ele_id )); XP_TRACE((" edit_element 0x%x", le->lo_any.edit_element)); XP_TRACE((" edit_offset %d", le->lo_any.edit_offset)); if( le->type == LO_TEXT && le->lo_any.edit_element->IsA( P_TEXT ) ){ pText = le->lo_any.edit_element->Text(); XP_TRACE((" lo_element(text) '%s'", le->lo_text.text )); XP_TRACE((" edit_element(text) '%s'", pText->GetText())); strncpy( buff, pText->GetText()+le->lo_any.edit_offset, le->lo_text.text_len ); buff[le->lo_text.text_len] = '\0'; XP_TRACE((" edit_element text( %d, %d ) = '%s' ", le->lo_any.edit_offset, le->lo_text.text_len, buff)); } } #endif void EDT_SetInsertPoint( ED_Buffer *pBuffer, ED_Element* pElement, int iPosition, XP_Bool bStickyAfter ){ if( pBuffer->IsBlocked() ){ return; } if ( ! pElement->IsLeaf() ){ XP_ASSERT(FALSE); return; } pBuffer->SetInsertPoint( pElement->Leaf(), iPosition, bStickyAfter ); } void EDT_SetLayoutElement( ED_Element* pElement, intn iEditOffset, intn lo_type, LO_Element *pLayoutElement ){ // XP_TRACE(("EDT_SetLayoutElement pElement(0x%08x) iEditOffset(%d) pLayoutElement(0x%08x)", pElement, iEditOffset, pLayoutElement)); if( pElement != 0 && pElement->IsLeaf() ) { pElement->Leaf()->SetLayoutElement( iEditOffset, lo_type, pLayoutElement ); } } void EDT_ResetLayoutElement( ED_Element* /* pElement */, intn /* iEditOffset */, LO_Element * /*pLayoutElement */ ){ /* The lifetime of a layout element can be greater than that of the corresponding edit element. An example is when you browse to the home page, hit edit, then cancel the save. When EDT_ResetLayoutElement happens, pElement may already have been deleted. We were only doing this book keeping to be neat. So it's OK to disable it. */ #if 0 XP_TRACE(("EDT_ResetLayoutElement pElement(0x%08x) iEditOffset(%d) pLayoutElement(0x%08x)", pElement, iEditOffset, pLayoutElement)); if( pElement != 0 && pElement->IsLeaf()) { pElement->Leaf()->ResetLayoutElement( iEditOffset, pLayoutElement ); } #endif } #ifdef DEBUG void EDT_VerifyLayoutElement( LO_Element *pLoElement ){ CEditElement *pElement = pLoElement->lo_any.edit_element; if( pElement ){ if( !pElement->IsLeaf() ){ // die here. } LO_Element *pEle; intn iLayoutOffset; if( !pElement->Leaf()->GetLOElementAndOffset( pLoElement->lo_any.edit_offset, TRUE, pEle, iLayoutOffset ) ) { XP_TRACE((" couldn't find layout element %8x(%d) from edit_element %8x", pLoElement, pLoElement->lo_any.ele_id, pElement )); XP_ASSERT(FALSE); return; } if( pEle != pLoElement ){ XP_TRACE(("Found wrong layout element\n" " Original Element %8x(%d)\n" " Found Element %8x(%d)\n", pLoElement, pLoElement->lo_any.ele_id, pEle, pEle != NULL ? pEle->lo_any.ele_id : 0)); XP_ASSERT(FALSE); } } } #endif //DEBUG void EDT_DeleteTagChain( PA_Tag* pTag ){ while( pTag ){ PA_Tag* pNext = pTag->next; PA_FreeTag( pTag ); pTag = pNext; } } PA_Tag* EDT_TagCursorGetNext( ED_TagCursor* pCursor ){ return pCursor->GetNextTag(); } PA_Tag* EDT_TagCursorGetNextState( ED_TagCursor* pCursor ){ return pCursor->GetNextTagState(); } XP_Bool EDT_TagCursorAtBreak( ED_TagCursor* pCursor, XP_Bool* pEndTag ){ return pCursor->AtBreak(pEndTag); } int32 EDT_TagCursorCurrentLine( ED_TagCursor* pCursor ){ return pCursor->CurrentLine(); } XP_Bool EDT_TagCursorClearRelayoutState( ED_TagCursor* pCursor ){ return pCursor->ClearRelayoutState(); } ED_TagCursor* EDT_TagCursorClone( ED_TagCursor *pCursor ){ return pCursor->Clone(); } void EDT_TagCursorDelete( ED_TagCursor* pCursor ){ delete pCursor; } //----------------------------------------------------------------------------- // FE Keyboard interface. //----------------------------------------------------------------------------- EDT_ClipboardResult EDT_KeyDown( MWContext *pContext, uint16 nChar, uint16 /* b */, uint16 /* c */ ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) EDT_COP_DOCUMENT_BUSY; if( pEditBuffer && nChar >= ' ' ){ return pEditBuffer->InsertChar(nChar, TRUE); } return EDT_COP_OK; } EDT_ClipboardResult EDT_InsertNonbreakingSpace( MWContext *pContext ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) EDT_COP_DOCUMENT_BUSY; EDT_ClipboardResult result = EDT_COP_OK; const char *p; INTL_CharSetInfo c = LO_GetDocumentCharacterSetInfo(pContext); // Nonbreaking space can be string for multibyte p = INTL_NonBreakingSpace(INTL_GetCSIWinCSID(c)); for (; *p; p++){ result = pEditBuffer->InsertChar(*p, TRUE); if ( result != EDT_COP_OK) break; } return result; } EDT_ClipboardResult EDT_DeletePreviousChar( MWContext *pContext ){ GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) EDT_COP_DOCUMENT_BUSY; return pEditBuffer->DeletePreviousChar(); } EDT_ClipboardResult EDT_DeleteChar( MWContext *pContext ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) EDT_COP_DOCUMENT_BUSY; return pEditBuffer->DeleteNextChar(); } //--------------------------------------------------------------------------- // Navigation //--------------------------------------------------------------------------- void EDT_PreviousChar( MWContext *pContext, XP_Bool bSelect ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); // pEditBuffer->PreviousChar( bSelect ); pEditBuffer->NavigateChunk( bSelect, LO_NA_CHARACTER, FALSE ); } void EDT_NextChar( MWContext *pContext, XP_Bool bSelect ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->NavigateChunk( bSelect, LO_NA_CHARACTER, TRUE ); } void EDT_Up( MWContext *pContext, XP_Bool bSelect ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->UpDown( bSelect, FALSE ); } void EDT_Down( MWContext *pContext, XP_Bool bSelect ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->UpDown( bSelect, TRUE ); } #endif //EDITOR #ifdef EDITOR void EDT_BeginOfLine( MWContext *pContext, XP_Bool bSelect ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->NavigateChunk( bSelect, LO_NA_LINEEDGE, FALSE ); } void EDT_EndOfLine( MWContext *pContext, XP_Bool bSelect ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->NavigateChunk( bSelect, LO_NA_LINEEDGE, TRUE ); } void EDT_BeginOfDocument( MWContext *pContext, XP_Bool bSelect ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->NavigateDocument( bSelect, FALSE ); } void EDT_EndOfDocument( MWContext *pContext, XP_Bool bSelect ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->NavigateDocument( bSelect, TRUE ); } void EDT_PageUp( MWContext *pContext, XP_Bool bSelect ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->PageUpDown( bSelect, FALSE); } void EDT_PageDown( MWContext *pContext, XP_Bool bSelect ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->PageUpDown( bSelect ,TRUE); } void EDT_PreviousWord( MWContext *pContext, XP_Bool bSelect ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->NavigateChunk( bSelect, LO_NA_WORD, FALSE ); } void EDT_NextWord( MWContext *pContext, XP_Bool bSelect ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->NavigateChunk( bSelect, LO_NA_WORD, TRUE ); } // Navigate from cell to cell void EDT_NextTableCell( MWContext *pContext, XP_Bool bEndOfCell ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->NextTableCell(TRUE, bEndOfCell); } void EDT_PreviousTableCell( MWContext *pContext, XP_Bool bEndOfCell ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->NextTableCell(FALSE, bEndOfCell); } // // Kind of a bizarre routine, Order of calls is as follows: // FE_OnMouseDown - determines x and y in layout coords. calls: // EDT_PositionCaret - clears movement and calls // LO_PositionCaret - figures out which layout element is under caret and calls // EDT_SetInsertPoint - which sets the edit element and offset and then calls // FE_DisplayTextCaret - which actually positions the caret. // // There are some more levels in there, but from an external view, this is how // it occurs. // void EDT_PositionCaret( MWContext *pContext, int32 x, int32 y ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->PositionCaret(x, y); } void EDT_DeleteSelectionAndPositionCaret( MWContext *pContext, int32 x, int32 y ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->DeleteSelectionAndPositionCaret(x, y); } XP_Bool EDT_PositionDropCaret( MWContext *pContext, int32 x, int32 y ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) FALSE; return pEditBuffer->PositionDropCaret(x, y); } XP_Bool EDT_StartDragTable( MWContext *pContext, int32 x, int32 y ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) FALSE; return pEditBuffer->StartDragTable(x, y); } void EDT_StopDragTable( MWContext *pContext ) { GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->StopDragTable(); } XP_Bool EDT_IsDraggingTable( MWContext *pContext ) { GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) FALSE; return pEditBuffer->IsDraggingTable(); } void EDT_DoubleClick( MWContext *pContext, int32 x, int32 y ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->StartSelection(x,y, TRUE); } void EDT_SelectObject( MWContext *pContext, int32 x, int32 y ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->SelectObject(x,y); } void EDT_WindowScrolled( MWContext *pContext ){ GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->WindowScrolled(); } EDT_ClipboardResult EDT_ReturnKey( MWContext *pContext ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) EDT_COP_DOCUMENT_BUSY; // TRUE = user is typing, FALSE = don't indent after return action return pEditBuffer->ReturnKey(TRUE, FALSE); } /* Do normal Return (Enter) key processing, then indent one level */ EDT_ClipboardResult EDT_ReturnKeyAndIndent( MWContext *pContext ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) EDT_COP_DOCUMENT_BUSY; // 2nd TRUE = indent after return action return pEditBuffer->ReturnKey(TRUE, TRUE); } EDT_ClipboardResult EDT_TabKey( MWContext *pContext, XP_Bool bForward, XP_Bool bForceTabChar ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) EDT_COP_DOCUMENT_BUSY; return pEditBuffer->TabKey(bForward, bForceTabChar); } void EDT_Indent( MWContext *pContext ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); { CEditSelection selection; pEditBuffer->GetSelection(selection); if ( selection.CrossesSubDocBoundary() ) { return; } } pEditBuffer->BeginBatchChanges(kIndentCommandID); pEditBuffer->Indent(); pEditBuffer->EndBatchChanges(); } void EDT_Outdent( MWContext *pContext ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->BeginBatchChanges(kIndentCommandID); pEditBuffer->Outdent(); pEditBuffer->EndBatchChanges(); } void EDT_RemoveList( MWContext *pContext ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); // Repeat removing indent until last Unnumbered list is gone pEditBuffer->BeginBatchChanges(kParagraphAlignCommandID); pEditBuffer->MorphContainer( P_NSDT ); EDT_ListData * pListData; while ( (pListData = pEditBuffer->GetListData()) != NULL ){ EDT_FreeListData(pListData); pEditBuffer->Outdent(); } pEditBuffer->EndBatchChanges(); } void EDT_ToggleList(MWContext *pContext, intn iTagType) { GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); EDT_BeginBatchChanges(pContext); pEditBuffer->ToggleList(iTagType); EDT_EndBatchChanges(pContext); } XP_Bool EDT_GetToggleListState(MWContext *pContext, intn iTagType) { GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) FALSE; TagType nParagraphFormat = EDT_GetParagraphFormatting( pContext ); EDT_ListData * pData = NULL; XP_Bool bIsMyList = FALSE; // Description list is a special case - it doesn't (and shouldn't) // have
  • items. It should contain
    (Desc.Title) and //
    (Desc. text) items. if ( nParagraphFormat == P_LIST_ITEM || iTagType == P_DESC_LIST || iTagType == P_BLOCKQUOTE ) { pData = EDT_GetListData(pContext); bIsMyList = ( pData && pData->iTagType == iTagType ); } if ( pData ) { EDT_FreeListData( pData ); } return bIsMyList; } void EDT_SetParagraphAlign( MWContext *pContext, ED_Alignment eAlign ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->BeginBatchChanges(kParagraphAlignCommandID); pEditBuffer->SetParagraphAlign( eAlign ); pEditBuffer->EndBatchChanges(); } ED_Alignment EDT_GetParagraphAlign( MWContext *pContext){ GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) ED_ALIGN_LEFT; ED_Alignment align = pEditBuffer->GetParagraphAlign(); // Translate old NS values for FE only, // so they won't be changed unless explicitly edited if( align == ED_ALIGN_CENTER ) align = ED_ALIGN_ABSCENTER; return align; } void EDT_SetTableAlign( MWContext *pContext, ED_Alignment eAlign ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->BeginBatchChanges(kParagraphAlignCommandID); pEditBuffer->SetTableAlign( eAlign ); pEditBuffer->EndBatchChanges(); } void EDT_MorphContainer( MWContext *pContext, TagType t ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->BeginBatchChanges(kParagraphAlignCommandID); // These are no longer supported if( t == P_DIRECTORY || t == P_MENU ) { t = P_UNUM_LIST; } if( t == P_BLOCKQUOTE || t == P_UNUM_LIST || t == P_NUM_LIST || t == P_DESC_LIST){ pEditBuffer->MorphListContainer( t ); } else { pEditBuffer->MorphContainer( t ); } pEditBuffer->EndBatchChanges(); } void EDT_FormatCharacter( MWContext *pContext, ED_TextFormat tf ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->FormatCharacter( tf ); } EDT_CharacterData* EDT_GetCharacterData( MWContext *pContext ){ GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) 0; return pEditBuffer->GetCharacterData(); } void EDT_SetCharacterData( MWContext *pContext, EDT_CharacterData *pData ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->SetCharacterData( pData ); } EDT_CharacterData* EDT_NewCharacterData(){ EDT_CharacterData* pData = XP_NEW( EDT_CharacterData ); XP_BZERO( pData, sizeof( EDT_CharacterData )); return pData; } void EDT_FreeCharacterData( EDT_CharacterData *pData ){ if( pData->pHREFData ){ EDT_FreeHREFData( pData->pHREFData ); } if( pData->pColor ){ XP_FREE( pData->pColor ); } if( pData->pFontFace ){ XP_FREE( pData->pFontFace ); } XP_FREE( pData ); } #if 0 PRIVATE ED_BitArray* EDT_BitArrayCreate(){ return new CBitArray(P_MAX, 0); } PRIVATE void EDT_BitArrayDestroy( ED_BitArray* pBitArray){ delete pBitArray; } PRIVATE XP_Bool EDT_BitArrayTest( ED_BitArray* pBitArray, TagType t ){ return (*pBitArray)[t]; } #endif ED_TextFormat EDT_GetCharacterFormatting( MWContext *pContext){ GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) 0; return pEditBuffer->GetCharacterFormatting(); } /* CM: "Current" is superfluous! */ ED_ElementType EDT_GetCurrentElementType( MWContext *pContext){ GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) ED_ELEMENT_TEXT; return pEditBuffer->GetCurrentElementType(); } TagType EDT_GetParagraphFormatting( MWContext *pContext ){ GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) P_UNKNOWN; return pEditBuffer->GetParagraphFormatting( ); } int EDT_GetFontSize( MWContext *pContext ){ GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) 0; return pEditBuffer->GetFontSize(); } void EDT_DecreaseFontSize( MWContext *pContext ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); // Size is a relative change, signaled by TRUE param pEditBuffer->SetFontSize(-1, TRUE); } void EDT_IncreaseFontSize( MWContext *pContext ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); // Size is a relative change, signalled by TRUE param pEditBuffer->SetFontSize(1, TRUE); } void EDT_SetFontSize( MWContext *pContext, int iSize ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->SetFontSize(iSize, FALSE); } int EDT_GetFontPointSize( MWContext *pContext ){ GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) 0; return pEditBuffer->GetFontPointSize(); } void EDT_SetFontPointSize( MWContext *pContext, int iPoints ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->SetFontPointSize(iPoints); } int EDT_GetFontFaceIndex(MWContext *pContext){ GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) -1; return pEditBuffer->GetFontFaceIndex(); } char * EDT_GetFontFace(MWContext *pContext){ GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) NULL; return pEditBuffer->GetFontFace(); } // // Some macros for packing and unpacking colors. // XP_Bool EDT_GetFontColor( MWContext *pContext, LO_Color* pDestColor ){ GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) FALSE; ED_Color i = pEditBuffer->GetFontColor(); if( i.IsDefined() ){ pDestColor->red = EDT_RED(i); pDestColor->green = EDT_GREEN(i); pDestColor->blue = EDT_BLUE(i); return TRUE; } else { return FALSE; } } void EDT_SetFontColor( MWContext *pContext, LO_Color *pColor){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); if( pColor ){ pEditBuffer->SetFontColor( EDT_LO_COLOR( pColor ) ); } else { pEditBuffer->SetFontColor(ED_Color::GetUndefined()); } } ED_ElementType EDT_GetBackgroundColor( MWContext *pContext, LO_Color *pColor ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) ED_ELEMENT_NONE; return pEditBuffer->GetBackgroundColor(pColor); } void EDT_SetBackgroundColor( MWContext *pContext, LO_Color *pColor){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->SetBackgroundColor(pColor); } void EDT_StartSelection(MWContext *pContext, int32 x, int32 y){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->StartSelection(x,y, FALSE); } void EDT_ExtendSelection(MWContext *pContext, int32 x, int32 y){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->ExtendSelection(x,y); } void EDT_EndSelection(MWContext *pContext, int32 x, int32 y){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->EndSelection(x, y); } void EDT_SelectAll(MWContext *pContext){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->SelectAll(); } void EDT_SelectTable(MWContext *pContext){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->SelectTable(); } void EDT_SelectTableCell(MWContext *pContext){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->SelectTableCell(); } void EDT_ClearTableAndCellSelection(MWContext *pContext) { GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->ClearTableAndCellSelection(); } XP_Bool EDT_IsTableSelected(MWContext *pContext) { GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) FALSE; return pEditBuffer->IsTableSelected(); } int EDT_GetSelectedCellCount(MWContext *pContext) { GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) 0; return pEditBuffer->GetSelectedCellCount(); } void EDT_ClearCellSelectionIfNotInside(MWContext *pContext) { GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->ClearCellSelectionIfNotInside(); } void EDT_StartSpecialCellSelection(MWContext *pContext, EDT_TableCellData *pCellData) { GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->StartSpecialCellSelection(pCellData); } void EDT_ClearSpecialCellSelection(MWContext *pContext) { GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->ClearSpecialCellSelection(); } void EDT_ClearSelection(MWContext *pContext){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); CEditSelection selection; pEditBuffer->GetSelection(selection); selection.m_end = selection.m_start; // Leave cursor at left, so table cell change data works. CSetSelectionCommand* pSelectCommand = new CSetSelectionCommand(pEditBuffer, selection); pEditBuffer->AdoptAndDo(pSelectCommand); } EDT_ClipboardResult EDT_InsertText( MWContext *pContext, char *pText ) { GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) EDT_COP_DOCUMENT_BUSY; pEditBuffer->DeleteSelection(); pEditBuffer->StartTyping(TRUE); EDT_ClipboardResult result = pEditBuffer->PasteText( pText, FALSE, TRUE, TRUE ,TRUE); return result; } /* Front end check for spreadsheet formated text (tabs between cells, CR at end of row, equal number of cells per row) */ XP_Bool EDT_CanPasteTextAsTable(MWContext *pContext, char * pText, intn *pRows, intn *pCols, XP_Bool *pIsInTable) { GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) FALSE; XP_Bool bResult = FALSE; // Determine format of paste text - use tabs as cell delimiters, as end of row intn iCols; intn iRows; XP_Bool bEqualCols = pEditBuffer->CountRowsAndColsInPasteText(pText, &iRows, &iCols); // Return number of rows and columns to caller if( pRows ) *pRows = iRows; if( pCols ) *pCols = iCols; // See if we have a well-formed table with > 1 column to paste if( bEqualCols && iCols > 1 && iRows > 0 ) { if( pIsInTable ) *pIsInTable = pEditBuffer->IsInsertPointInTableCell(); bResult = TRUE; } return bResult; } EDT_ClipboardResult EDT_PasteTextAsTable( MWContext *pContext, char *pText, ED_PasteType iPasteType ) { GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) EDT_COP_DOCUMENT_BUSY; EDT_ClipboardResult result = EDT_COP_OK; intn iCols; intn iRows; // Check if we really can do do this if( EDT_CanPasteTextAsTable(pContext, pText, &iRows, &iCols, NULL) ) { // Do we need batch changes? pEditBuffer->BeginBatchChanges(kPasteTextCommandID); result = pEditBuffer->PasteTextAsTable(pText, iPasteType, iRows, iCols ); pEditBuffer->EndBatchChanges(); } return result; } EDT_ClipboardResult EDT_PasteText( MWContext *pContext, char *pText ) { GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) EDT_COP_DOCUMENT_BUSY; pEditBuffer->BeginBatchChanges(kPasteTextCommandID); EDT_ClipboardResult result; pEditBuffer->DeleteSelection(); result = pEditBuffer->PasteText( pText, FALSE, FALSE, TRUE ,TRUE); pEditBuffer->EndBatchChanges(); return result; } #if 0 EDT_ClipboardResult EDT_SetDefaultText( MWContext *pContext, char *pText ) { CEditBuffer* pEditBuffer = LO_GetEDBuffer( pContext ); if (pEditBuffer && pText) { if (!CEditBuffer::IsAlive(pEditBuffer) || !pEditBuffer->IsReady() || !pEditBuffer->IsWritable() ) { //set up the default data for finishedload2 pEditBuffer->m_pImportedStream=XP_STRDUP(pText); return EDT_COP_OK; } else return EDT_PasteText(pContext,pText); } return EDT_COP_DOCUMENT_BUSY; } #endif #ifdef ENDER EDT_ClipboardResult EDT_SetDefaultHTML( MWContext *pContext, char *pHTML ) { #ifdef MOZ_ENDER_MIME return EDT_SetDefaultMimeHTML(pContext, pHTML); #else CEditBuffer* pEditBuffer = LO_GetEDBuffer( pContext ); if (pEditBuffer) { if (!CEditBuffer::IsAlive(pEditBuffer) || !pEditBuffer->IsReady() || !pEditBuffer->IsWritable() ) { //set up the default data for finishedload2 if (pHTML) pEditBuffer->m_pImportedHTMLStream=XP_STRDUP(pHTML); return EDT_COP_OK; } else { pEditBuffer->ReadFromBuffer(pHTML); return EDT_COP_OK; } } return EDT_COP_DOCUMENT_BUSY; #endif } #ifdef MOZ_ENDER_MIME EDT_ClipboardResult EDT_SetDefaultMimeHTML( MWContext *pContext, char *pHTML ) { CEditBuffer* pEditBuffer = LO_GetEDBuffer( pContext ); if (pEditBuffer) { if (!CEditBuffer::IsAlive(pEditBuffer) || !pEditBuffer->IsReady() || !pEditBuffer->IsWritable() ) { //set up the default data for finishedload2 if (pHTML) pEditBuffer->m_pImportedHTMLStream=XP_STRDUP(pHTML); return EDT_COP_OK; } else { pEditBuffer->ReadMimeFromBuffer(pHTML); return EDT_COP_OK; } } return EDT_COP_DOCUMENT_BUSY; } #endif /*MOZ_ENDER_MIME*/ void EDT_SetEmbeddedEditorData( MWContext *pContext, void *pData ) { CEditBuffer* pEditBuffer = LO_GetEDBuffer( pContext ); if (pEditBuffer) { pEditBuffer->m_bEmbedded = TRUE; pEditBuffer->m_pEmbeddedData = pData; } } #endif //ENDER EDT_ClipboardResult EDT_PasteQuoteBegin( MWContext *pContext, XP_Bool bHTML ) { GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) EDT_COP_DOCUMENT_BUSY; EDT_ClipboardResult result = pEditBuffer->PasteQuoteBegin( bHTML ); return result; } EDT_ClipboardResult EDT_PasteQuote( MWContext *pContext, char *pText ) { GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) EDT_COP_DOCUMENT_BUSY; EDT_ClipboardResult result = pEditBuffer->PasteQuote( pText ); return result; } EDT_ClipboardResult EDT_PasteQuoteINTL( MWContext *pContext, char *pText, int16 csid ) { GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) EDT_COP_DOCUMENT_BUSY; EDT_ClipboardResult result = pEditBuffer->PasteQuoteINTL( pText, csid ); return result; } EDT_ClipboardResult EDT_PasteQuoteEnd( MWContext *pContext ) { GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) EDT_COP_DOCUMENT_BUSY; EDT_ClipboardResult result = pEditBuffer->PasteQuoteEnd(); return result; } EDT_ClipboardResult EDT_PasteHTML( MWContext *pContext, char *pText, ED_PasteType iPasteType ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) EDT_COP_DOCUMENT_BUSY; pEditBuffer->BeginBatchChanges(kGroupOfChangesCommandID); pEditBuffer->DeleteSelection(); EDT_ClipboardResult result = pEditBuffer->PasteHTML( pText, iPasteType ); pEditBuffer->EndBatchChanges(); return result; } EDT_ClipboardResult EDT_CopySelection( MWContext *pContext, char **ppText, int32* pTextLen, XP_HUGE_CHAR_PTR* ppHtml, int32* pHtmlLen){ GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) EDT_COP_DOCUMENT_BUSY; return pEditBuffer->CopySelection( ppText, pTextLen, (char **)ppHtml, pHtmlLen ); } EDT_ClipboardResult EDT_CutSelection( MWContext *pContext, char **ppText, int32* pTextLen, XP_HUGE_CHAR_PTR* ppHtml, int32* pHtmlLen){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) EDT_COP_DOCUMENT_BUSY; EDT_ClipboardResult result = pEditBuffer->CutSelection( ppText, pTextLen, (char **)ppHtml, pHtmlLen ); return result; } char *EDT_GetTabDelimitedTextFromSelectedCells( MWContext *pContext ) { GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) NULL; return pEditBuffer->GetTabDelimitedTextFromSelectedCells(); } XP_Bool EDT_CanConvertTextToTable(MWContext *pMWContext) { GET_WRITABLE_EDIT_BUF_OR_RETURN(pMWContext, pEditBuffer) FALSE; return pEditBuffer->CanConvertTextToTable(); } void EDT_ConvertTextToTable(MWContext *pMWContext, intn iColumns) { GET_WRITABLE_EDIT_BUF_OR_RETURN(pMWContext, pEditBuffer); pEditBuffer->ConvertTextToTable(iColumns); } /* Convert the table into text - unravel existing paragraphs in cells */ void EDT_ConvertTableToText(MWContext *pMWContext) { GET_WRITABLE_EDIT_BUF_OR_RETURN(pMWContext, pEditBuffer); pEditBuffer->ConvertTableToText(); } /* TRUE if there is global style data available */ XP_Bool EDT_CanPasteStyle(MWContext *pMWContext) { GET_EDIT_BUF_OR_RETURN(pMWContext, pEditBuffer) FALSE; return pEditBuffer->CanPasteStyle(); } /* Apply the style to selection or at caret */ void EDT_PasteStyle(MWContext *pMWContext, XP_Bool bApplyStyle) { GET_WRITABLE_EDIT_BUF_OR_RETURN(pMWContext, pEditBuffer); pEditBuffer->PasteStyle(bApplyStyle); } XP_Bool EDT_DirtyFlag( MWContext *pContext ){ GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) FALSE; return pEditBuffer->GetDirtyFlag(); } void EDT_SetDirtyFlag( MWContext *pContext, XP_Bool bValue ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); if ( bValue ) { XP_ASSERT(FALSE); // Use BeginBatchChanges instead. } else { pEditBuffer->DocumentStored(); } } EDT_ClipboardResult EDT_CanCut(MWContext *pContext, XP_Bool bStrictChecking){ GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) EDT_COP_DOCUMENT_BUSY; return pEditBuffer->CanCut( bStrictChecking, (XP_Bool)FALSE ); } EDT_ClipboardResult EDT_CanCopy(MWContext *pContext, XP_Bool bStrictChecking){ GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) EDT_COP_DOCUMENT_BUSY; return pEditBuffer->CanCopy( bStrictChecking, (XP_Bool)FALSE ); } EDT_ClipboardResult EDT_CanPaste(MWContext *pContext, XP_Bool bStrictChecking){ GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) EDT_COP_DOCUMENT_BUSY; return pEditBuffer->CanPaste( bStrictChecking ); } XP_Bool EDT_CanSetHREF( MWContext *pContext ){ GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) FALSE; return pEditBuffer->CanSetHREF( ); } char *EDT_GetHREF( MWContext *pContext ){ GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) NULL; return pEditBuffer->GetHREF( ); } char *EDT_GetHREFText(MWContext *pContext){ GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) NULL; return pEditBuffer->GetHREFText(); } void EDT_SetHREF(MWContext *pContext, char *pHREF ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->SetHREF( pHREF, 0 ); } /* * Returns colors of all the different fonts. * Must call XP_FREE( pDest ) after use. */ int EDT_GetExtraColors( MWContext * /* pContext */, LO_Color ** /* pDest */ ){ return 0; } void EDT_RefreshLayout( MWContext *pContext ){ LO_RefetchWindowDimensions( pContext ); GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->RefreshLayout(); } XP_Bool EDT_IsSelected( MWContext *pContext ){ GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) FALSE; return pEditBuffer->IsSelected(); } // Check current file-update time and // return TRUE if it is different XP_Bool EDT_IsFileModified( MWContext* pContext ){ GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) FALSE; return pEditBuffer->IsFileModified(); } // This should probably be moved into CEditBuffer, // Note that we return FALSE if we are text type // and not selected, even if caret is in a link, // so don't use this to test for link. // TODO: Move this into CEditBuffer::SelectionContainsLink() // after CharacterData functions are implemented XP_Bool EDT_SelectionContainsLink( MWContext *pContext ){ if( EDT_IsSelected(pContext) || EDT_GetSelectedTableElement(pContext, NULL) ) { ED_ElementType type = EDT_GetCurrentElementType(pContext); // If we have a Table selected, then we ignore character actions, // but we do look into Table Rows, columns, and cells if( type == ED_ELEMENT_SELECTION || type > ED_ELEMENT_TABLE) { EDT_CharacterData *pData = EDT_GetCharacterData(pContext); if( pData ) { // We aren't certain about HREF state accross // entire selection if mask bit is off XP_Bool bUncertain = ( (pData->mask & TF_HREF) == 0 || ((pData->mask & TF_HREF) && (pData->values & TF_HREF)) ); EDT_FreeCharacterData(pData); return bUncertain; } } else if ( type == ED_ELEMENT_IMAGE ) { LO_Element *pStart; // // Grab the current selection. // LO_GetSelectionEndPoints( pContext, &pStart, 0, 0, 0, 0, 0 ); // Check if image has an HREF return (pStart && pStart->lo_image.anchor_href != NULL ); } } return FALSE; } void EDT_DropHREF( MWContext *pContext, char *pHref, char* pTitle, int32 x, int32 y ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); EDT_BeginBatchChanges(pContext); EDT_PositionCaret( pContext, x, y ); EDT_PasteText( pContext, pHref ); EDT_PasteText( pContext, pTitle ); EDT_EndBatchChanges(pContext); } EDT_ClipboardResult EDT_PasteHREF( MWContext *pContext, char **ppHref, char **ppTitle, int iCount){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) EDT_COP_DOCUMENT_BUSY; EDT_ClipboardResult result = EDT_COP_DOCUMENT_BUSY; pEditBuffer->BeginBatchChanges(kPasteHREFCommandID); pEditBuffer->DeleteSelection(); result = pEditBuffer->PasteHREF( ppHref, ppTitle, iCount ); pEditBuffer->EndBatchChanges(); return result; } XP_Bool EDT_CanDropHREF( MWContext * pContext, int32 /* x */, int32 /* y */){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) FALSE; return TRUE; } EDT_HREFData *EDT_GetHREFData( MWContext *pContext ){ GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) 0; EDT_HREFData* pData = EDT_NewHREFData(); if(pData){ pEditBuffer->GetHREFData(pData); } return pData; } void EDT_SetHREFData( MWContext *pContext, EDT_HREFData *pData ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); /* Allow clearing existing HREF with NULL pURL */ if(pData /*&& pData->pURL*/){ pEditBuffer->SetHREFData(pData); } } EDT_HREFData *EDT_NewHREFData() { EDT_HREFData* pData = XP_NEW( EDT_HREFData ); if( pData ){ XP_BZERO( pData, sizeof( EDT_HREFData ) ); return pData; } return NULL; } EDT_HREFData *EDT_DupHREFData( EDT_HREFData *pOldData) { EDT_HREFData* pData = EDT_NewHREFData(); if( pOldData ){ if(pOldData->pURL) pData->pURL = XP_STRDUP( pOldData->pURL ); if(pOldData->pExtra) pData->pExtra = XP_STRDUP( pOldData->pExtra ); } return pData; } void EDT_FreeHREFData( EDT_HREFData *pData ) { //Move this to an EditBuffer function? if(pData){ if(pData->pURL) XP_FREE(pData->pURL); if(pData->pExtra) XP_FREE(pData->pExtra); XP_FREE(pData); } } void EDT_FinishedLayout( MWContext *pContext ){ /* we know that the buffer is not ready */ /* we're actually not "ready" here because FinishedLoad will call */ /* the timer which will ensure that FinishedLoad2 gets called which */ /* completes the initialization of pEditBuffer */ GET_EDIT_BUF_OR_RETURN_READY_OR_NOT(pContext, pEditBuffer); pEditBuffer->FinishedLoad(); } // Page EDT_PageData *EDT_GetPageData( MWContext *pContext ){ GET_EDIT_BUF_OR_RETURN_READY_OR_NOT(pContext, pEditBuffer) NULL; return pEditBuffer->GetPageData(); } EDT_PageData *EDT_NewPageData(){ EDT_PageData* pData = XP_NEW( EDT_PageData ); if( pData ){ XP_BZERO( pData, sizeof( EDT_PageData ) ); pData->bKeepImagesWithDoc = TRUE; return pData; } return NULL; } void EDT_SetPageData( MWContext *pContext, EDT_PageData *pData ){ GET_WRITABLE_EDIT_BUF_OR_RETURN_READY_OR_NOT(pContext, pEditBuffer); pEditBuffer->AdoptAndDo(new CChangePageDataCommand(pEditBuffer, kChangePageDataCommandID)); pEditBuffer->SetPageData( pData ); } void EDT_FreePageData( EDT_PageData *pData ){ CEditBuffer::FreePageData( pData ); } void EDT_SetImageAsBackground( MWContext *pContext ){ GET_WRITABLE_EDIT_BUF_OR_RETURN_READY_OR_NOT(pContext, pEditBuffer); pEditBuffer->SetImageAsBackground(); } // Meta intn EDT_MetaDataCount( MWContext *pContext ){ GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) 0; return pEditBuffer->m_metaData.Size(); } EDT_MetaData* EDT_GetMetaData( MWContext *pContext, intn n ){ GET_EDIT_BUF_OR_RETURN_READY_OR_NOT(pContext, pEditBuffer) NULL; return pEditBuffer->GetMetaData( n ); } EDT_MetaData* EDT_NewMetaData(){ EDT_MetaData *pData = XP_NEW( EDT_MetaData ); if( pData ){ XP_BZERO( pData, sizeof( EDT_MetaData ) ); return pData; } return NULL; } void EDT_SetMetaData( MWContext *pContext, EDT_MetaData *pMetaData ){ GET_WRITABLE_EDIT_BUF_OR_RETURN_READY_OR_NOT(pContext, pEditBuffer); // CSetMetaDataCommand actually performs the operation in the // constructor of the command. So in order for save-based undo to // work, we must wrap its constructor in BeginBatchChanges. pEditBuffer->BeginBatchChanges(kSetMetaDataCommandID); pEditBuffer->AdoptAndDo(new CSetMetaDataCommand(pEditBuffer, pMetaData, FALSE, kSetMetaDataCommandID)); pEditBuffer->EndBatchChanges(); } void EDT_DeleteMetaData( MWContext *pContext, EDT_MetaData *pMetaData ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); // CSetMetaDataCommand actually performs the operation in the // constructor of the command. So in order for save-based undo to // work, we must wrap its constructor in BeginBatchChanges. pEditBuffer->BeginBatchChanges(kDeleteMetaDataCommandID); pEditBuffer->AdoptAndDo(new CSetMetaDataCommand(pEditBuffer, pMetaData, TRUE, kDeleteMetaDataCommandID)); pEditBuffer->EndBatchChanges(); } void EDT_FreeMetaData( EDT_MetaData *pMetaData ){ CEditBuffer::FreeMetaData( pMetaData ); } // Image EDT_ImageData *EDT_GetImageData( MWContext *pContext ) { GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) NULL; EDT_ImageData *pData =pEditBuffer->GetImageData(); if( pData ) { // Translate old NS values for FE only, // so they won't be changed unless explicitly edited if( pData->align == ED_ALIGN_ABSBOTTOM || pData->align == ED_ALIGN_BOTTOM ) pData->align = ED_ALIGN_BASELINE; // This is default (no param written) else if( pData->align == ED_ALIGN_CENTER ) pData->align = ED_ALIGN_ABSCENTER; } return pData; } int32 EDT_GetDefaultBorderWidth( MWContext *pContext ){ GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) NULL; return pEditBuffer->GetDefaultBorderWidth(); } void EDT_SetImageData( MWContext *pContext, EDT_ImageData *pData, XP_Bool bKeepImagesWithDoc ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->BeginBatchChanges(kSetImageDataCommandID); pEditBuffer->SetImageData( pData, bKeepImagesWithDoc ); pEditBuffer->EndBatchChanges(); } EDT_ImageData *EDT_NewImageData(){ return edt_NewImageData( ); } void EDT_FreeImageData( EDT_ImageData *pData ){ edt_FreeImageData( pData ); } void EDT_InsertImage( MWContext *pContext, EDT_ImageData *pData, XP_Bool bKeepImagesWithDoc ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->BeginBatchChanges(kInsertImageCommandID); pEditBuffer->LoadImage( pData, bKeepImagesWithDoc, FALSE ); pEditBuffer->EndBatchChanges(); #if defined(ENDER) && defined(MOZ_ENDER_MIME) if (bKeepImagesWithDoc && pEditBuffer->m_bEmbedded) EDT_AddURLToSafeList(pEditBuffer->m_pEmbeddedData, pData->pSrc); #endif /* ENDER && MOZ_ENDER_MIME */ } void EDT_ImageLoadCancel( MWContext *pContext ){ CEditBuffer* pEditBuffer = LO_GetEDBuffer( pContext ); if( !pEditBuffer ) return; if( CEditBuffer::IsAlive(pEditBuffer) && pEditBuffer->IsReady() && pEditBuffer->m_pLoadingImage ) { delete pEditBuffer->m_pLoadingImage; } else { FE_ImageLoadDialogDestroy( pContext ); FE_EnableClicking( pContext ); } } void EDT_SetImageInfo(MWContext *pContext, int32 /* ele_id */, int32 width, int32 height){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); if( pEditBuffer->m_pLoadingImage ){ pEditBuffer->m_pLoadingImage->SetImageInfo( width, height ); } } // HorizRule EDT_HorizRuleData *EDT_GetHorizRuleData( MWContext *pContext ){ GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) NULL; return pEditBuffer->GetHorizRuleData(); } void EDT_SetHorizRuleData( MWContext *pContext, EDT_HorizRuleData *pData ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->BeginBatchChanges(kSetHorizRuleDataCommandID); pEditBuffer->SetHorizRuleData( pData ); pEditBuffer->EndBatchChanges(); } EDT_HorizRuleData* EDT_NewHorizRuleData(){ return CEditHorizRuleElement::NewData( ); } void EDT_FreeHorizRuleData( EDT_HorizRuleData *pData ){ CEditHorizRuleElement::FreeData( pData ); } void EDT_InsertHorizRule( MWContext *pContext, EDT_HorizRuleData *pData ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->InsertHorizRule( pData ); } // Targets char *EDT_GetTargetData( MWContext *pContext ){ GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) NULL; return pEditBuffer->GetTargetData(); } void EDT_SetTargetData( MWContext *pContext, char *pData ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->BeginBatchChanges(kSetTargetDataCommandID); pEditBuffer->SetTargetData( pData ); pEditBuffer->EndBatchChanges(); } void EDT_InsertTarget( MWContext *pContext, char* pData ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->BeginBatchChanges(kInsertTargetCommandID); pEditBuffer->InsertTarget( pData ); pEditBuffer->EndBatchChanges(); } char *EDT_GetAllDocumentTargets( MWContext *pContext ){ GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) NULL; return pEditBuffer->GetAllDocumentTargets(); } char *EDT_GetAllDocumentTargetsInFile( MWContext *pContext, char *pHref ){ GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) NULL; return pEditBuffer->GetAllDocumentTargetsInFile(pHref); } // For backwards compatibility with non-Windows Front Ends. char *EDT_GetAllDocumentFiles( MWContext *pContext ){ GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) NULL; return pEditBuffer->GetAllDocumentFiles(NULL,TRUE); } // New version. char *EDT_GetAllDocumentFilesSelected( MWContext *pContext, XP_Bool **ppSelected, XP_Bool bKeepImages ){ GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) NULL; return pEditBuffer->GetAllDocumentFiles(ppSelected,bKeepImages); } // Unknown Tags char *EDT_GetUnknownTagData( MWContext *pContext ){ GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) NULL; return pEditBuffer->GetUnknownTagData(); } void EDT_SetUnknownTagData( MWContext *pContext, char *pData ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->BeginBatchChanges(kSetUnknownTagDataCommandID); pEditBuffer->SetUnknownTagData( pData ); pEditBuffer->EndBatchChanges(); } void EDT_InsertUnknownTag( MWContext *pContext, char* pData ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->BeginBatchChanges(kInsertUnknownTagCommandID); pEditBuffer->InsertUnknownTag( pData ); pEditBuffer->EndBatchChanges(); } ED_TagValidateResult EDT_ValidateTag( char *pData, XP_Bool bNoBrackets ){ return CEditIconElement::ValidateTag( pData, bNoBrackets ); } // List EDT_ListData *EDT_GetListData( MWContext *pContext ){ GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) NULL; return pEditBuffer->GetListData(); } void EDT_SetListData( MWContext *pContext, EDT_ListData *pData ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); CSetListDataCommand* pCommand = new CSetListDataCommand(pEditBuffer, *pData); pEditBuffer->AdoptAndDo(pCommand); } void EDT_FreeListData( EDT_ListData *pData ){ CEditListElement::FreeData( pData ); } // Break void EDT_InsertBreak( MWContext *pContext, ED_BreakType eBreak ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); // A break is treated like a character as far as the typing command goes. // So we don't do a command at this level. pEditBuffer->InsertBreak( eBreak ); } // Tables XP_Bool EDT_IsInsertPointInTable(MWContext *pContext ){ GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) FALSE; return pEditBuffer->IsInsertPointInTable(); } XP_Bool EDT_IsInsertPointInNestedTable(MWContext *pContext ){ GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) FALSE; return pEditBuffer->IsInsertPointInNestedTable(); } EDT_TableData* EDT_GetTableData( MWContext *pContext ){ GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) NULL; return pEditBuffer->GetTableData();; } void EDT_GetTableParentSize( MWContext *pContext, XP_Bool bCell, int32 *pWidth, int32 *pHeight ) { GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); CEditInsertPoint ip; pEditBuffer->GetInsertPoint(ip); CEditTableElement* pTable = ip.m_pElement->GetTableIgnoreSubdoc(); if ( pTable ) { if( bCell ) { CEditTableCellElement* pCell = ip.m_pElement->GetTableCellIgnoreSubdoc(); if( pCell ) { if( pWidth ) *pWidth = pCell->GetParentWidth(); if( pHeight ) *pHeight = pCell->GetParentHeight(); } } else { pTable->GetParentSize(pEditBuffer->GetContext(), pWidth, pHeight, NULL); } } } void EDT_SetTableData( MWContext *pContext, EDT_TableData *pData ) { GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); // Even though this is checked in SetTableData, // doing it here preserves the UNDO buffer in case // we are called and we're not inside a table if( pEditBuffer->IsInsertPointInTable() ) { pEditBuffer->BeginBatchChanges(kSetTableDataCommandID); pEditBuffer->SetTableData(pData); // CSetTableDataCommand* pCommand = new CSetTableDataCommand(pEditBuffer, pData); // pEditBuffer->AdoptAndDo(pCommand); pEditBuffer->EndBatchChanges(); } } EDT_TableData* EDT_NewTableData() { return CEditTableElement::NewData(); } void EDT_FreeTableData( EDT_TableData *pData ) { CEditTableElement::FreeData( pData ); } void EDT_InsertTable( MWContext *pContext, EDT_TableData *pData){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->InsertTable( pData ); } void EDT_DeleteTable( MWContext *pContext ){ GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->DeleteTable(); } ED_MergeType EDT_GetMergeTableCellsType( MWContext *pContext ) { GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) ED_MERGE_NONE; return pEditBuffer->GetMergeTableCellsType(); } XP_Bool EDT_CanSplitTableCell( MWContext *pContext ) { GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) FALSE; return pEditBuffer->CanSplitTableCell(); } void EDT_MergeTableCells( MWContext *pContext ) { GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->MergeTableCells(); } void EDT_SplitTableCell( MWContext *pContext ) { GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->SplitTableCell(); } // Table Caption XP_Bool EDT_IsInsertPointInTableCaption(MWContext *pContext ){ GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) FALSE; return pEditBuffer->IsInsertPointInTableCaption(); } EDT_TableCaptionData* EDT_GetTableCaptionData( MWContext *pContext ){ GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) NULL; return pEditBuffer->GetTableCaptionData(); } void EDT_SetTableCaptionData( MWContext *pContext, EDT_TableCaptionData *pData ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); // CSetTableCaptionDataCommand actually performs the operation in the // constructor of the command. So in order for save-based undo to // work, we must wrap its constructor in BeginBatchChanges. pEditBuffer->BeginBatchChanges(kSetTableCaptionDataCommandID); CSetTableCaptionDataCommand* pCommand = new CSetTableCaptionDataCommand(pEditBuffer, pData); pEditBuffer->AdoptAndDo(pCommand); pEditBuffer->EndBatchChanges(); } EDT_TableCaptionData* EDT_NewTableCaptionData() { return CEditCaptionElement::NewData(); } void EDT_FreeTableCaptionData( EDT_TableCaptionData *pData ) { CEditCaptionElement::FreeData( pData ); } void EDT_InsertTableCaption( MWContext *pContext, EDT_TableCaptionData *pData){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->InsertTableCaption( pData ); } void EDT_DeleteTableCaption( MWContext *pContext){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->DeleteTableCaption(); } // Table Row XP_Bool EDT_IsInsertPointInTableRow(MWContext *pContext ){ GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) FALSE; return pEditBuffer->IsInsertPointInTableRow(); } EDT_TableRowData* EDT_GetTableRowData( MWContext *pContext ){ GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) NULL; return pEditBuffer->GetTableRowData(); } void EDT_SetTableRowData( MWContext *pContext, EDT_TableRowData *pData ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); // CSetTableRowDataCommand actually performs the operation in the // constructor of the command. So in order for save-based undo to // work, we must wrap its constructor in BeginBatchChanges. pEditBuffer->BeginBatchChanges(kSetTableRowDataCommandID); CSetTableRowDataCommand* pCommand = new CSetTableRowDataCommand(pEditBuffer, pData); pEditBuffer->AdoptAndDo(pCommand); pEditBuffer->EndBatchChanges(); } EDT_TableRowData* EDT_NewTableRowData() { return CEditTableRowElement::NewData(); } void EDT_FreeTableRowData( EDT_TableRowData *pData ) { CEditTableRowElement::FreeData( pData ); } void EDT_InsertTableRows( MWContext *pContext, EDT_TableRowData *pData, XP_Bool bAfterCurrentRow, intn number){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->BeginBatchChanges(kInsertTableRowCommandID); pEditBuffer->InsertTableRows( pData, bAfterCurrentRow, number ); pEditBuffer->EndBatchChanges(); } void EDT_DeleteTableRows( MWContext *pContext, intn number){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->DeleteTableRows(number); } // Table Cell XP_Bool EDT_IsInsertPointInTableCell(MWContext *pContext ){ GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) FALSE; return pEditBuffer->IsInsertPointInTableCell(); } EDT_TableCellData* EDT_GetTableCellData( MWContext *pContext ){ GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) NULL; EDT_TableCellData *pData = pEditBuffer->GetTableCellData(); // Translate old NS values for FE only, // so they won't be changed unless explicitly edited if( pData ) { if( pData->valign == ED_ALIGN_BASELINE || pData->valign == ED_ALIGN_BOTTOM ) pData->valign = ED_ALIGN_ABSBOTTOM; } return pData; } void EDT_ChangeTableSelection(MWContext *pContext, ED_HitType iHitType, ED_MoveSelType iMoveType, EDT_TableCellData *pData) { GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->ChangeTableSelection(iHitType, iMoveType, pData); } void EDT_SetTableCellData( MWContext *pContext, EDT_TableCellData *pData ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); // CSetTableCellDataCommand actually performs the operation in the // constructor of the command. So in order for save-based undo to // work, we must wrap its constructor in BeginBatchChanges. pEditBuffer->BeginBatchChanges(kSetTableCellDataCommandID); pEditBuffer->SetTableCellData(pData); // CSetTableCellDataCommand* pCommand = new CSetTableCellDataCommand(pEditBuffer, pData); // pEditBuffer->AdoptAndDo(pCommand); pEditBuffer->EndBatchChanges(); } EDT_TableCellData* EDT_NewTableCellData() { return CEditTableCellElement::NewData(); } void EDT_FreeTableCellData( EDT_TableCellData *pData ) { CEditTableCellElement::FreeData( pData ); } void EDT_InsertTableCells( MWContext *pContext, EDT_TableCellData *pData, XP_Bool bAfterCurrentColumn, intn number){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->InsertTableCells( pData, bAfterCurrentColumn, number ); } void EDT_DeleteTableCells( MWContext *pContext, intn number){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->DeleteTableCells(number); } void EDT_InsertTableColumns( MWContext *pContext, EDT_TableCellData *pData, XP_Bool bAfterCurrentColumn, intn number){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->BeginBatchChanges(kInsertTableColumnCommandID); pEditBuffer->InsertTableColumns( pData, bAfterCurrentColumn, number ); pEditBuffer->EndBatchChanges(); } void EDT_DeleteTableColumns( MWContext *pContext, intn number){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->DeleteTableColumns(number); } // Layer XP_Bool EDT_IsInsertPointInLayer(MWContext *pContext ){ GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) FALSE; return pEditBuffer->IsInsertPointInLayer(); } EDT_LayerData* EDT_GetLayerData( MWContext *pContext ){ GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) NULL; return pEditBuffer->GetLayerData(); } void EDT_SetLayerData( MWContext *pContext, EDT_LayerData *pData ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); CEditInsertPoint ip; pEditBuffer->GetInsertPoint(ip); CEditLayerElement* pLayer = ip.m_pElement->GetLayerIgnoreSubdoc(); if ( pLayer ){ pEditBuffer->BeginBatchChanges(kSetLayerDataCommandID); pLayer->SetData(pData); pEditBuffer->EndBatchChanges(); } } EDT_LayerData* EDT_NewLayerData() { return CEditLayerElement::NewData(); } void EDT_FreeLayerData( EDT_LayerData *pData ) { CEditLayerElement::FreeData( pData ); } void EDT_InsertLayer( MWContext *pContext, EDT_LayerData *pData){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->InsertLayer( pData ); } void EDT_DeleteLayer( MWContext *pContext ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->DeleteLayer(); } // Undo/Redo void EDT_Undo( MWContext *pContext ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->Undo( ); } void EDT_Redo( MWContext *pContext ){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->Redo( ); } #if 0 PRIVATE intn EDT_GetCommandHistoryLimit(MWContext *pContext){ GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) 0; return pEditBuffer->GetCommandHistoryLimit( ); } PRIVATE void EDT_SetCommandHistoryLimit(MWContext *pContext, intn newLimit){ GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->SetCommandHistoryLimit( newLimit ); } #endif intn EDT_GetUndoCommandID( MWContext *pContext, intn index ){ GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) CEDITCOMMAND_ID_NULL; return pEditBuffer->GetUndoCommand( index ); } intn EDT_GetRedoCommandID( MWContext *pContext, intn index ){ GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) CEDITCOMMAND_ID_NULL; return pEditBuffer->GetRedoCommand( index ); } void EDT_BeginBatchChanges(MWContext *pContext){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->BeginBatchChanges(kGroupOfChangesCommandID); } void EDT_EndBatchChanges(MWContext *pContext){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->EndBatchChanges( ); } void EDT_SetDisplayParagraphMarks(MWContext *pContext, XP_Bool display){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->SetDisplayParagraphMarks( display ); } XP_Bool EDT_GetDisplayParagraphMarks(MWContext *pContext){ GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) FALSE; return pEditBuffer->GetDisplayParagraphMarks(); } void EDT_SetDisplayTables(MWContext *pContext, XP_Bool display){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer); pEditBuffer->SetDisplayTables( display ); } XP_Bool EDT_GetDisplayTables(MWContext *pContext){ GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) FALSE; return pEditBuffer->GetDisplayTables(); } XP_Bool EDT_IsWritableBuffer(MWContext *pContext){ GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext,pEditBuffer) FALSE; return TRUE; } #endif //EDITOR