mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 14:22:01 +00:00
2864 lines
92 KiB
C++
2864 lines
92 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.
|
|
*/
|
|
|
|
|
|
//
|
|
// 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 <HR> 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 "<html></html>";
|
|
}
|
|
|
|
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 <LI> items. It should contain <DT> (Desc.Title) and
|
|
// <DD> (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, <CR><LF> 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
|