зеркало из https://github.com/mozilla/pjs.git
Composer work: Check for valid charset in metatag, paste character style, split table cell, optimization for table cell layout (not turned on), remove P_MENU, P_DIRECTORY support for UIs
This commit is contained in:
Родитель
b3671f82b9
Коммит
bb022be61f
|
@ -1035,9 +1035,15 @@ intn EDT_ProcessTag(void *data_object, PA_Tag *tag, intn status){
|
||||||
}
|
}
|
||||||
parseRet = pDocData->edit_buffer->ParseTag( pDocData, 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 ){
|
if( parseRet != OK_IGNORE ){
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
//
|
//
|
||||||
// Check to see if the tag went away. Text without an Edit Element
|
// Check to see if the tag went away. Text without an Edit Element
|
||||||
|
@ -1061,7 +1067,7 @@ intn EDT_ProcessTag(void *data_object, PA_Tag *tag, intn status){
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
PA_FreeTag(tag);
|
PA_FreeTag(tag);
|
||||||
return 1;
|
return OK_CONTINUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1492,9 +1498,16 @@ void EDT_SetTableAlign( MWContext *pContext, ED_Alignment eAlign ){
|
||||||
void EDT_MorphContainer( MWContext *pContext, TagType t ){
|
void EDT_MorphContainer( MWContext *pContext, TagType t ){
|
||||||
GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer);
|
GET_WRITABLE_EDIT_BUF_OR_RETURN(pContext, pEditBuffer);
|
||||||
pEditBuffer->BeginBatchChanges(kParagraphAlignCommandID);
|
pEditBuffer->BeginBatchChanges(kParagraphAlignCommandID);
|
||||||
|
// These are no longer supported
|
||||||
|
if( t == P_DIRECTORY ||
|
||||||
|
t == P_MENU )
|
||||||
|
{
|
||||||
|
t = P_UNUM_LIST;
|
||||||
|
}
|
||||||
|
|
||||||
if( t == P_BLOCKQUOTE ||
|
if( t == P_BLOCKQUOTE ||
|
||||||
t == P_DIRECTORY ||
|
t == P_UNUM_LIST ||
|
||||||
t == P_MENU ||
|
t == P_NUM_LIST ||
|
||||||
t == P_DESC_LIST){
|
t == P_DESC_LIST){
|
||||||
pEditBuffer->MorphListContainer( t );
|
pEditBuffer->MorphListContainer( t );
|
||||||
} else {
|
} else {
|
||||||
|
@ -1898,10 +1911,9 @@ void EDT_ConvertTableToText(MWContext *pMWContext)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Save the character and paragraph style of selection or at caret */
|
/* Save the character and paragraph style of selection or at caret */
|
||||||
|
/* TODO: REMOVE AFTER CONFIRMING ITS NOT BEING USED ON ALL PLATFORMS */
|
||||||
void EDT_CopyStyle(MWContext *pMWContext)
|
void EDT_CopyStyle(MWContext *pMWContext)
|
||||||
{
|
{
|
||||||
GET_EDIT_BUF_OR_RETURN(pMWContext, pEditBuffer);
|
|
||||||
pEditBuffer->CopyStyle();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TRUE if no mouse actions taken since last EDT_CopyStyle call */
|
/* TRUE if no mouse actions taken since last EDT_CopyStyle call */
|
||||||
|
|
|
@ -1263,7 +1263,8 @@ public:
|
||||||
void SetSpecialSelected(XP_Bool bSelected) { m_bSpecialSelected = bSelected; }
|
void SetSpecialSelected(XP_Bool bSelected) { m_bSpecialSelected = bSelected; }
|
||||||
|
|
||||||
// Move contents of supplied cell into this cell
|
// Move contents of supplied cell into this cell
|
||||||
void MergeCells(CEditTableCellElement* pCell);
|
// If merging results in a row deletion, iNewRowSpan is adjusted
|
||||||
|
void MergeCells(CEditTableCellElement* pCell, int32& iNewRowSpan);
|
||||||
void SplitCell();
|
void SplitCell();
|
||||||
|
|
||||||
// Delete all contents, leaving just the minimum empty text element
|
// Delete all contents, leaving just the minimum empty text element
|
||||||
|
@ -3368,10 +3369,7 @@ public:
|
||||||
// Convert the table into text - unravel existing paragraphs in cells
|
// Convert the table into text - unravel existing paragraphs in cells
|
||||||
void ConvertTableToText();
|
void ConvertTableToText();
|
||||||
|
|
||||||
// Save the character and paragraph style of selection or at caret
|
// This is TRUE after any HTML is copied
|
||||||
void CopyStyle();
|
|
||||||
|
|
||||||
// This is TRUE after EDT_CopyStyle is called, until the next left mouse up call
|
|
||||||
XP_Bool CanPasteStyle() { return (m_pCopyStyleCharacterData != NULL); }
|
XP_Bool CanPasteStyle() { return (m_pCopyStyleCharacterData != NULL); }
|
||||||
|
|
||||||
// Apply the style to selection or at caret. Use bApplyStyle = FALSE to cancel
|
// Apply the style to selection or at caret. Use bApplyStyle = FALSE to cancel
|
||||||
|
@ -3497,9 +3495,11 @@ public:
|
||||||
void SetMetaData( EDT_MetaData *pMetaData );
|
void SetMetaData( EDT_MetaData *pMetaData );
|
||||||
void DeleteMetaData( EDT_MetaData *pMetaData );
|
void DeleteMetaData( EDT_MetaData *pMetaData );
|
||||||
static void FreeMetaData( EDT_MetaData *pMetaData );
|
static void FreeMetaData( EDT_MetaData *pMetaData );
|
||||||
void ParseMetaTag( PA_Tag *pTag );
|
void ParseMetaTag( PA_Tag *pTag, intn& retVal );
|
||||||
void PrintMetaData( CPrintState *pPrintState );
|
void PrintMetaData( CPrintState *pPrintState );
|
||||||
void PrintMetaData( CPrintState *pPrintState, int index );
|
void PrintMetaData( CPrintState *pPrintState, int index );
|
||||||
|
// Return FALSE only if we are closing down
|
||||||
|
XP_Bool CheckCharset( EDT_MetaData *pData,int16 win_csid );
|
||||||
|
|
||||||
EDT_HorizRuleData* GetHorizRuleData();
|
EDT_HorizRuleData* GetHorizRuleData();
|
||||||
void SetHorizRuleData( EDT_HorizRuleData* pData );
|
void SetHorizRuleData( EDT_HorizRuleData* pData );
|
||||||
|
@ -3986,6 +3986,8 @@ public:
|
||||||
|
|
||||||
void ChangeEncoding(int16 csid);
|
void ChangeEncoding(int16 csid);
|
||||||
void SetEncoding(int16 csid);
|
void SetEncoding(int16 csid);
|
||||||
|
void SetEncoding(char *pCharset);
|
||||||
|
|
||||||
XP_Bool HasEncoding();
|
XP_Bool HasEncoding();
|
||||||
|
|
||||||
// Used for QA only - Ctrl+Alt+Shift+N accelerator for automated testing
|
// Used for QA only - Ctrl+Alt+Shift+N accelerator for automated testing
|
||||||
|
|
|
@ -23,7 +23,8 @@
|
||||||
#include "prefapi.h"
|
#include "prefapi.h"
|
||||||
#include "intl_csi.h"
|
#include "intl_csi.h"
|
||||||
|
|
||||||
#define CONTENT_TYPE "Content-Type"
|
#define CONTENT_TYPE "Content-Type"
|
||||||
|
#define PARAM_CHARSET "charset"
|
||||||
|
|
||||||
// Maximum length of "positional text" - see GetPositionalText().
|
// Maximum length of "positional text" - see GetPositionalText().
|
||||||
#ifdef XP_WIN16
|
#ifdef XP_WIN16
|
||||||
|
@ -567,6 +568,11 @@ intn CEditBuffer::ParseTag(pa_DocData *pData, PA_Tag* pTag, intn status){
|
||||||
XP_Bool bTagIsEnd = (XP_Bool) pTag->is_end;
|
XP_Bool bTagIsEnd = (XP_Bool) pTag->is_end;
|
||||||
|
|
||||||
NormalizeEOLsInTag(pTag);
|
NormalizeEOLsInTag(pTag);
|
||||||
|
|
||||||
|
// 8/31/98: List types no longer supported
|
||||||
|
// (they were always displayed the same as P_UNUM_LIST anyway)
|
||||||
|
if( pTag->type == P_MENU || P_DIRECTORY )
|
||||||
|
pTag->type == P_UNUM_LIST;
|
||||||
|
|
||||||
/* P_STRIKE is a synonym for P_STRIKEOUT. Since pre-3.0 versions of
|
/* P_STRIKE is a synonym for P_STRIKEOUT. Since pre-3.0 versions of
|
||||||
* Navigator don't recognize P_STRIKE ( "<S>" ), we switch it to
|
* Navigator don't recognize P_STRIKE ( "<S>" ), we switch it to
|
||||||
|
@ -1187,7 +1193,7 @@ intn CEditBuffer::ParseOpenTag(pa_DocData *pData, PA_Tag* pTag, intn status){
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case P_META:
|
case P_META:
|
||||||
ParseMetaTag( pTag );
|
ParseMetaTag( pTag, retVal );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case P_BASE:
|
case P_BASE:
|
||||||
|
@ -2123,7 +2129,7 @@ void CEditBuffer::Reflow( CEditElement* pStartElement,
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
XP_Bool bInTableCell = pStartElement ? (pStartElement->GetTableIgnoreSubdoc() != NULL) : FALSE;
|
CEditTableCellElement *pCell = FALSE;
|
||||||
|
|
||||||
// laying out from the beginning of the document
|
// laying out from the beginning of the document
|
||||||
if( pNewStartElement == 0 ){
|
if( pNewStartElement == 0 ){
|
||||||
|
@ -2156,23 +2162,39 @@ void CEditBuffer::Reflow( CEditElement* pStartElement,
|
||||||
// Note: If here, we must have a pStartElement and associated LO_Element
|
// Note: If here, we must have a pStartElement and associated LO_Element
|
||||||
XP_ASSERT(pStartElement && pLayoutElement);
|
XP_ASSERT(pStartElement && pLayoutElement);
|
||||||
|
|
||||||
// Find the first element on this line and get the current line number
|
// If we are entirely within one cell, then use new cell reflow
|
||||||
pLoStartLine = FirstElementOnLine( pLayoutElement, &iLineNum );
|
// ****** TODO: FINISH THIS WORK BEFORE ACTIVATING
|
||||||
//
|
//pCell = pStartElement->GetTableCellIgnoreSubdoc();
|
||||||
// Position the tag cursor at this position
|
|
||||||
//
|
if( pCell && pCell == pEndElement->GetTableCellIgnoreSubdoc() )
|
||||||
pLoStartLine = FirstElementOnLine( pLayoutElement, &iLineNum );
|
{
|
||||||
pEdStart = pLoStartLine->lo_any.edit_element;
|
// Start with first element in the cell
|
||||||
iOffset = pLoStartLine->lo_any.edit_offset;
|
pEdStart = pCell->GetFirstMostChild()->Leaf();
|
||||||
|
XP_ASSERT(pEdStart);
|
||||||
|
iOffset = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Clear this - we use it below to tell how to reflow
|
||||||
|
pCell = NULL;
|
||||||
|
|
||||||
|
// Find the first element on this line and get the current line number
|
||||||
|
pLoStartLine = FirstElementOnLine( pLayoutElement, &iLineNum );
|
||||||
|
//
|
||||||
|
// Position the tag cursor at this position
|
||||||
|
//
|
||||||
|
pLoStartLine = FirstElementOnLine( pLayoutElement, &iLineNum );
|
||||||
|
pEdStart = pLoStartLine->lo_any.edit_element;
|
||||||
|
iOffset = pLoStartLine->lo_any.edit_offset;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create a new cursor and reflow
|
||||||
// Create a new cursor.
|
|
||||||
CEditTagCursor cursor(this, pEdStart, iOffset, pEndElement);
|
CEditTagCursor cursor(this, pEdStart, iOffset, pEndElement);
|
||||||
//CEditTagCursor *pCursor = new CEditTagCursor(this, m_pRoot, iOffset);
|
if( pCell )
|
||||||
|
lo_EditorCellReflow(m_pContext, &cursor, GetLoCell(pCell));
|
||||||
LO_EditorReflow(m_pContext, &cursor, iLineNum, iOffset);
|
else
|
||||||
|
lo_EditorReflow(m_pContext, &cursor, iLineNum, iOffset);
|
||||||
|
|
||||||
#if defined( DEBUG_shannon )
|
#if defined( DEBUG_shannon )
|
||||||
XP_TRACE(("\n\nEDITOR REFLOW"));
|
XP_TRACE(("\n\nEDITOR REFLOW"));
|
||||||
|
@ -4245,7 +4267,9 @@ void CEditBuffer::MorphContainer( TagType t )
|
||||||
TagType tList = pList->GetType();
|
TagType tList = pList->GetType();
|
||||||
// Assure that list-type items are only contained in their proper parents.
|
// Assure that list-type items are only contained in their proper parents.
|
||||||
// If not the right type, terminate the list
|
// If not the right type, terminate the list
|
||||||
if( ((tList == P_UNUM_LIST || tList == P_NUM_LIST || tList == P_MENU || tList == P_DIRECTORY) &&
|
// We should never see P_MENU or P_DIRECTORY any more
|
||||||
|
// (translated into P_UNUM_LIST in ::ParseTag() )
|
||||||
|
if( ((tList == P_UNUM_LIST || tList == P_NUM_LIST /*|| tList == P_MENU || tList == P_DIRECTORY*/) &&
|
||||||
t != P_LIST_ITEM) ||
|
t != P_LIST_ITEM) ||
|
||||||
(tList == P_DESC_LIST && !(t == P_DESC_TITLE || t == P_DESC_TEXT)) )
|
(tList == P_DESC_LIST && !(t == P_DESC_TITLE || t == P_DESC_TEXT)) )
|
||||||
{
|
{
|
||||||
|
@ -5872,16 +5896,8 @@ void CEditBuffer::ConvertTableToText()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save the character and paragraph style of selection or at caret
|
// Apply the style to selection or at caret.
|
||||||
void CEditBuffer::CopyStyle()
|
// Use bApplyStyle = FALSE to delete the saved style data
|
||||||
{
|
|
||||||
if( m_pCopyStyleCharacterData )
|
|
||||||
EDT_FreeCharacterData(m_pCopyStyleCharacterData);
|
|
||||||
|
|
||||||
m_pCopyStyleCharacterData = GetCharacterData();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply the style to selection or at caret. Use bApplyStyle = FALSE to cancel
|
|
||||||
void CEditBuffer::PasteStyle(XP_Bool bApplyStyle)
|
void CEditBuffer::PasteStyle(XP_Bool bApplyStyle)
|
||||||
{
|
{
|
||||||
if( m_pCopyStyleCharacterData )
|
if( m_pCopyStyleCharacterData )
|
||||||
|
@ -5890,8 +5906,11 @@ void CEditBuffer::PasteStyle(XP_Bool bApplyStyle)
|
||||||
{
|
{
|
||||||
SetCharacterData(m_pCopyStyleCharacterData);
|
SetCharacterData(m_pCopyStyleCharacterData);
|
||||||
}
|
}
|
||||||
EDT_FreeCharacterData(m_pCopyStyleCharacterData);
|
else
|
||||||
m_pCopyStyleCharacterData = NULL;
|
{
|
||||||
|
EDT_FreeCharacterData(m_pCopyStyleCharacterData);
|
||||||
|
m_pCopyStyleCharacterData = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6160,38 +6179,209 @@ void CEditBuffer::FreeMetaData( EDT_MetaData *pData ){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CEditBuffer::ParseMetaTag( PA_Tag *pTag ){
|
void CEditBuffer::ParseMetaTag( PA_Tag *pTag, intn& retVal )
|
||||||
|
{
|
||||||
XP_Bool bHttpEquiv = TRUE;
|
XP_Bool bHttpEquiv = TRUE;
|
||||||
char *pName;
|
char *pName;
|
||||||
char *pContent;
|
char *pContent;
|
||||||
INTL_CharSetInfo c = LO_GetDocumentCharacterSetInfo(m_pContext);
|
INTL_CharSetInfo c = LO_GetDocumentCharacterSetInfo(m_pContext);
|
||||||
int16 win_csid = INTL_GetCSIWinCSID(c);
|
int16 win_csid = INTL_GetCSIWinCSID(c);
|
||||||
|
retVal = OK_CONTINUE;
|
||||||
|
|
||||||
pContent = edt_FetchParamString( pTag, PARAM_CONTENT, win_csid );
|
pContent = edt_FetchParamString( pTag, PARAM_CONTENT, win_csid );
|
||||||
pName = edt_FetchParamString( pTag, PARAM_HTTP_EQUIV, win_csid );
|
pName = edt_FetchParamString( pTag, PARAM_HTTP_EQUIV, win_csid );
|
||||||
|
|
||||||
// if we didn't get http-equiv, try for name=
|
// if we didn't get http-equiv, try for name=
|
||||||
if( pName == 0 ){
|
if( pName == 0 )
|
||||||
|
{
|
||||||
bHttpEquiv = FALSE;
|
bHttpEquiv = FALSE;
|
||||||
pName = edt_FetchParamString( pTag, PARAM_NAME, win_csid );
|
pName = edt_FetchParamString( pTag, PARAM_NAME, win_csid );
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we got one or the other, add it to the list of meta tags.
|
// if we got one or the other, add it to the list of meta tags.
|
||||||
if( pName ){
|
if( pName )
|
||||||
|
{
|
||||||
EDT_MetaData *pData = MakeMetaData( bHttpEquiv, pName, pContent );
|
EDT_MetaData *pData = MakeMetaData( bHttpEquiv, pName, pContent );
|
||||||
// We want to allow multiple entries with the same NAME,
|
|
||||||
// as long as CONTENT is different. So setting these the same
|
// Check our charset string for validity
|
||||||
// will make FindMetaData() match CONTENT as well as NAME
|
// (We may close done the buffer in this routine)
|
||||||
// when deciding to replace and existing meta entry
|
if( CheckCharset(pData, win_csid) )
|
||||||
pData->pPrevContent = pData->pContent;
|
{
|
||||||
SetMetaData( pData );
|
|
||||||
FreeMetaData( pData );
|
// We want to allow multiple entries with the same NAME,
|
||||||
|
// as long as CONTENT is different. So setting these the same
|
||||||
|
// will make FindMetaData() match CONTENT as well as NAME
|
||||||
|
// when deciding to replace and existing meta entry
|
||||||
|
pData->pPrevContent = pData->pContent;
|
||||||
|
SetMetaData( pData );
|
||||||
|
FreeMetaData( pData );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Signal to stop parsing
|
||||||
|
// This alone seems to be enough to abort parsing,
|
||||||
|
// the net stream, and close the window!
|
||||||
|
retVal = NOT_OK;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( pName ) XP_FREE( pName );
|
if( pName ) XP_FREE( pName );
|
||||||
if( pContent ) XP_FREE( pContent );
|
if( pContent ) XP_FREE( pContent );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void edt_ReplaceCharset(EDT_MetaData *pData, char *pNewCharset)
|
||||||
|
{
|
||||||
|
// Find the string "charset" in the content string
|
||||||
|
char *pCharset = XP_STRSTR(pData->pContent, PARAM_CHARSET);
|
||||||
|
if( !pCharset )
|
||||||
|
{
|
||||||
|
CHARSET_ERROR:
|
||||||
|
XP_ASSERT(0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Find the '=' after "charset"
|
||||||
|
char *pEqual = XP_STRCHR(pCharset, '=');
|
||||||
|
if( !pEqual )
|
||||||
|
goto CHARSET_ERROR;
|
||||||
|
|
||||||
|
char *tptr = pEqual+1;
|
||||||
|
|
||||||
|
// Terminate here -- this is where we will append the new string
|
||||||
|
*tptr = '\0';
|
||||||
|
tptr++;
|
||||||
|
|
||||||
|
// Skip over whitespace before chaset name
|
||||||
|
while (XP_IS_SPACE(*tptr))
|
||||||
|
tptr++;
|
||||||
|
|
||||||
|
//Then find end of old charset string
|
||||||
|
// This assumes charset string can have no spaces in it
|
||||||
|
while( *tptr && !XP_IS_SPACE(*tptr) && *tptr != '\"' && *tptr != '>')
|
||||||
|
tptr++;
|
||||||
|
|
||||||
|
// Copy this to append at the end,
|
||||||
|
// (this allows other params after charset to be retained)
|
||||||
|
char *pEnd = NULL;
|
||||||
|
if( *tptr )
|
||||||
|
pEnd = XP_STRDUP(tptr);
|
||||||
|
|
||||||
|
// Rebuild complete "Content=" string
|
||||||
|
// This avoids realloc if new and old string are the same size
|
||||||
|
pData->pContent = PR_sprintf_append(pData->pContent, pNewCharset);
|
||||||
|
if( pEnd )
|
||||||
|
{
|
||||||
|
pData->pContent = PR_sprintf_append(pData->pContent, pEnd);
|
||||||
|
XP_FREE(pEnd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return FALSE only if we are closing down
|
||||||
|
XP_Bool CEditBuffer::CheckCharset( EDT_MetaData *pData, int16 win_csid )
|
||||||
|
{
|
||||||
|
XP_Bool bRetVal = TRUE;
|
||||||
|
int16 default_csid = FE_DefaultDocCharSetID(m_pContext);
|
||||||
|
|
||||||
|
if( CS_USRDEF2 != default_csid &&
|
||||||
|
CS_USER_DEFINED_ENCODING != default_csid &&
|
||||||
|
pData && pData->bHttpEquiv && pData->pName && pData->pContent &&
|
||||||
|
0 == XP_STRCASECMP(pData->pName, CONTENT_TYPE) )
|
||||||
|
{
|
||||||
|
// Example of a charset meta tag:
|
||||||
|
//<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
|
||||||
|
|
||||||
|
// Create a simple tag so we can use tag-parsing to extract charset
|
||||||
|
// PA_FetchParamValue (called from edt_FetchParamString)
|
||||||
|
// needs a terminal '>' to work
|
||||||
|
int iLen = XP_STRLEN(pData->pContent);
|
||||||
|
char *pContent = (char*)XP_ALLOC(iLen+1);
|
||||||
|
if( !pContent )
|
||||||
|
return FALSE; //Abort if not enough memory?
|
||||||
|
|
||||||
|
XP_STRCPY(pContent, pData->pContent);
|
||||||
|
pContent[iLen] = '>';
|
||||||
|
iLen++;
|
||||||
|
pContent[iLen] = '\0';
|
||||||
|
|
||||||
|
PA_Tag *pTag = XP_NEW( PA_Tag );
|
||||||
|
XP_BZERO( pTag, sizeof( PA_Tag ) );
|
||||||
|
pTag->data_len = iLen;
|
||||||
|
pTag->data_str = XP_STRDUP(pContent);
|
||||||
|
|
||||||
|
char *pCharset = edt_FetchParamString(pTag, PARAM_CHARSET, win_csid );
|
||||||
|
PA_FREE(pTag);
|
||||||
|
|
||||||
|
if( pCharset )
|
||||||
|
{
|
||||||
|
int iBufLen = 255;
|
||||||
|
char buf[256];
|
||||||
|
char *pMsg = NULL;
|
||||||
|
|
||||||
|
//ftang: Implement this!
|
||||||
|
// if(CS_UNKNOWN == INTL_NameToCharSetID(pCharset))
|
||||||
|
if(FALSE)
|
||||||
|
{
|
||||||
|
// Get the default charset
|
||||||
|
//INTL_CharSetIDToName(default_csid, &pDefaultCharset);
|
||||||
|
// Above uses presized buffer, but calls following, so this is safer:
|
||||||
|
// (Don't free this string!)
|
||||||
|
char *pDefaultCharset = (char *)INTL_CsidToCharsetNamePt(default_csid);
|
||||||
|
if( pDefaultCharset )
|
||||||
|
{
|
||||||
|
// Build a very wordy message box with the default and current
|
||||||
|
// charset strings inserted
|
||||||
|
PR_snprintf(buf, iBufLen, XP_GetString(XP_EDT_CHARSET_LABEL), pCharset);
|
||||||
|
pMsg = PR_sprintf_append(pMsg, buf);
|
||||||
|
pMsg = PR_sprintf_append(pMsg, XP_GetString(XP_EDT_CHARSET_CANT_EDIT));
|
||||||
|
PR_snprintf(buf, iBufLen, XP_GetString(XP_EDT_CURRENT_CHARSET), pDefaultCharset);
|
||||||
|
pMsg = PR_sprintf_append(pMsg, buf);
|
||||||
|
PR_snprintf(buf, iBufLen, XP_GetString(XP_EDT_CHARSET_EDIT_REPLACE), pDefaultCharset);
|
||||||
|
pMsg = PR_sprintf_append(pMsg, buf);
|
||||||
|
pMsg = PR_sprintf_append(pMsg, XP_GetString(XP_EDT_CHARSET_EDIT_CANCEL));
|
||||||
|
// If user chooses "Cancel", then we should abort editing
|
||||||
|
bRetVal = FE_Confirm(m_pContext, pMsg);
|
||||||
|
if( bRetVal )
|
||||||
|
{
|
||||||
|
// Change to the default charset
|
||||||
|
edt_ReplaceCharset(pData, pDefaultCharset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
bRetVal = FALSE; //Abort if no default charset?
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//ftang: Implement this! If this should NOT be freed,
|
||||||
|
// then please remove the XP_FREEIF below
|
||||||
|
//pNewCharset = INTL_CharsetCorrection(pCharset);
|
||||||
|
char *pCorrectCharset = XP_STRDUP(pCharset);
|
||||||
|
// ftang: If this should be XP_STRCMP instead, please change it
|
||||||
|
if( pCorrectCharset && 0 != XP_STRCASECMP(pCorrectCharset, pCharset) )
|
||||||
|
{
|
||||||
|
// See if user wants to replace charset with the "correct" string
|
||||||
|
// In either case, we continue editing
|
||||||
|
PR_snprintf(buf, iBufLen, XP_GetString(XP_EDT_CHARSET_LABEL), pCharset);
|
||||||
|
pMsg = PR_sprintf_append(pMsg, buf);
|
||||||
|
PR_snprintf(buf, iBufLen, XP_GetString(XP_EDT_CURRENT_CHARSET), pCorrectCharset);
|
||||||
|
pMsg = PR_sprintf_append(pMsg, buf);
|
||||||
|
PR_snprintf(buf, iBufLen, XP_GetString(XP_EDT_CHARSET_EDIT_REPLACE), pCorrectCharset);
|
||||||
|
pMsg = PR_sprintf_append(pMsg, buf);
|
||||||
|
PR_snprintf(buf, iBufLen, XP_GetString(XP_EDT_CHARSET_EDIT_NOREPLACE), pCharset);
|
||||||
|
pMsg = PR_sprintf_append(pMsg, buf);
|
||||||
|
|
||||||
|
if( FE_Confirm(m_pContext, pMsg) )
|
||||||
|
{
|
||||||
|
// Change to the "correct" charset
|
||||||
|
edt_ReplaceCharset(pData, pCorrectCharset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
XP_FREEIF(pCorrectCharset);
|
||||||
|
}
|
||||||
|
XP_FREE(pCharset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return bRetVal;
|
||||||
|
}
|
||||||
|
|
||||||
// Image
|
// Image
|
||||||
|
|
||||||
|
@ -6798,7 +6988,7 @@ void CEditBuffer::MergeTableCells()
|
||||||
EDT_FreeTableCellData(pNextCellData);
|
EDT_FreeTableCellData(pNextCellData);
|
||||||
}
|
}
|
||||||
// Move all contents of Next cell into First cell and delete Next cell
|
// Move all contents of Next cell into First cell and delete Next cell
|
||||||
pFirstCell->MergeCells(pNextCell);
|
pFirstCell->MergeCells(pNextCell, pFirstCellData->iRowSpan);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// We are merging with just the next cell to the right
|
// We are merging with just the next cell to the right
|
||||||
|
@ -6809,7 +6999,7 @@ void CEditBuffer::MergeTableCells()
|
||||||
pFirstCellData->iColSpan += pNextCellData->iColSpan;
|
pFirstCellData->iColSpan += pNextCellData->iColSpan;
|
||||||
EDT_FreeTableCellData(pNextCellData);
|
EDT_FreeTableCellData(pNextCellData);
|
||||||
}
|
}
|
||||||
pFirstCell->MergeCells( pNextCell );
|
pFirstCell->MergeCells(pNextCell, pFirstCellData->iRowSpan);
|
||||||
}
|
}
|
||||||
// Set the COLSPAN and ROWSPAN data for the merged cell
|
// Set the COLSPAN and ROWSPAN data for the merged cell
|
||||||
pFirstCell->SetData(pFirstCellData);
|
pFirstCell->SetData(pFirstCellData);
|
||||||
|
@ -6832,13 +7022,19 @@ void CEditBuffer::MergeTableCells()
|
||||||
*/
|
*/
|
||||||
void CEditBuffer::SplitTableCell()
|
void CEditBuffer::SplitTableCell()
|
||||||
{
|
{
|
||||||
|
// Set beginning of UNDO block
|
||||||
|
BeginBatchChanges(kGroupOfChangesCommandID);
|
||||||
|
|
||||||
CEditInsertPoint ip;
|
CEditInsertPoint ip;
|
||||||
GetTableInsertPoint(ip);
|
GetTableInsertPoint(ip);
|
||||||
|
CEditTableElement* pTable = ip.m_pElement->GetTableIgnoreSubdoc();
|
||||||
CEditTableCellElement* pCell = ip.m_pElement->GetTableCellIgnoreSubdoc();
|
CEditTableCellElement* pCell = ip.m_pElement->GetTableCellIgnoreSubdoc();
|
||||||
if( !pCell )
|
if( pTable == NULL || pCell == NULL )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
pCell->SplitCell();
|
pCell->SplitCell();
|
||||||
|
Relayout(pTable, 0, pTable);
|
||||||
|
|
||||||
|
EndBatchChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -13952,6 +14148,17 @@ EDT_ClipboardResult CEditBuffer::CopySelection( char **ppText, int32* pTextLen,
|
||||||
// Get normal selection
|
// Get normal selection
|
||||||
GetSelection(selection);
|
GetSelection(selection);
|
||||||
iCopyType = ED_COPY_NORMAL;
|
iCopyType = ED_COPY_NORMAL;
|
||||||
|
|
||||||
|
// Copy character attributes only if start of selection is text
|
||||||
|
// This can be "pasted" onto a selection or at the caret
|
||||||
|
if( selection.m_start.m_pElement->IsText() )
|
||||||
|
{
|
||||||
|
if( m_pCopyStyleCharacterData )
|
||||||
|
EDT_FreeCharacterData(m_pCopyStyleCharacterData);
|
||||||
|
|
||||||
|
// Save attributes of start element only
|
||||||
|
m_pCopyStyleCharacterData = selection.m_start.m_pElement->Text()->GetData();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Build the HTML stream from the selection
|
// Build the HTML stream from the selection
|
||||||
if( !selection.IsEmpty() )
|
if( !selection.IsEmpty() )
|
||||||
|
@ -17043,17 +17250,31 @@ void CEditBuffer::ChangeEncoding(int16 csid) {
|
||||||
// See RFC 2070, "Internationalization of the Hypertext Markup Language"
|
// See RFC 2070, "Internationalization of the Hypertext Markup Language"
|
||||||
// http://ds.internic.net/rfc/rfc2070.txt
|
// http://ds.internic.net/rfc/rfc2070.txt
|
||||||
// <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=ISO-2022-JP">
|
// <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=ISO-2022-JP">
|
||||||
void CEditBuffer::SetEncoding(int16 csid) {
|
void CEditBuffer::SetEncoding(int16 csid)
|
||||||
char contentValue[200];
|
{
|
||||||
char charSet[100];
|
|
||||||
int16 plainCSID = csid & ~CS_AUTO;
|
int16 plainCSID = csid & ~CS_AUTO;
|
||||||
INTL_CharSetIDToName(plainCSID, charSet);
|
// This is better than INTL_CharSetIDToName, which needs presized buffer;
|
||||||
XP_SPRINTF(contentValue, "text/html; charset=%.100s", charSet);
|
// (Don't free this string!)
|
||||||
|
char *charSet = (char *)INTL_CsidToCharsetNamePt(plainCSID);
|
||||||
|
SetEncoding(charSet);
|
||||||
|
}
|
||||||
|
|
||||||
EDT_MetaData *pData = MakeMetaData( TRUE, CONTENT_TYPE, contentValue);
|
void CEditBuffer::SetEncoding(char *pCharset)
|
||||||
|
{
|
||||||
|
char pContent[128];
|
||||||
|
if( pCharset && *pCharset )
|
||||||
|
{
|
||||||
|
XP_SPRINTF(pContent, "text/html; charset=%.100s", pCharset);
|
||||||
|
|
||||||
SetMetaData( pData );
|
EDT_MetaData *pData = MakeMetaData( TRUE, CONTENT_TYPE, pContent);
|
||||||
FreeMetaData( pData );
|
if( pData )
|
||||||
|
{
|
||||||
|
SetMetaData( pData );
|
||||||
|
FreeMetaData( pData );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
XP_ASSERT(0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
XP_Bool CEditBuffer::HasEncoding() {
|
XP_Bool CEditBuffer::HasEncoding() {
|
||||||
|
|
|
@ -6239,29 +6239,94 @@ void CEditTableCellElement::SplitCell()
|
||||||
|
|
||||||
pBuffer->SetFillNewCellWithSpace();
|
pBuffer->SetFillNewCellWithSpace();
|
||||||
CEditTableCellElement *pNewCell;
|
CEditTableCellElement *pNewCell;
|
||||||
for( intn iRow = 0; iRow < m_iRowSpan; iRow++ )
|
int32 iNewRows = m_iRowSpan - 1;
|
||||||
|
int32 iNewCells = m_iColSpan - 1;
|
||||||
|
intn iNextRow = m_iRow + 1;
|
||||||
|
CEditTableRowElement *pCurrentRow = (CEditTableRowElement*)GetParent();
|
||||||
|
XP_ASSERT(pCurrentRow && pCurrentRow->IsTableRow());
|
||||||
|
CEditTableRowElement *pRow = pCurrentRow;
|
||||||
|
|
||||||
|
// Copy current cell's color and background image to all new cells
|
||||||
|
EDT_TableCellData *pData = GetData();
|
||||||
|
EDT_TableCellData *pNewData = NewData();
|
||||||
|
XP_ASSERT(pData && pNewData);
|
||||||
|
if( !pData || !pNewData )
|
||||||
|
return;
|
||||||
|
pData->mask = CF_BACK_COLOR | CF_BACK_IMAGE;
|
||||||
|
edt_CopyTableCellData(pNewData, pData);
|
||||||
|
|
||||||
|
// Insert new cells in the current row if needed
|
||||||
|
for( int i = 0; i < iNewCells; i++ )
|
||||||
{
|
{
|
||||||
for( intn iCol = 0; iCol < m_iColSpan; iCol++ )
|
pNewCell = new CEditTableCellElement;
|
||||||
|
pNewCell->InsertAfter(this);
|
||||||
|
pNewCell->FinishedLoad(pBuffer);
|
||||||
|
// Set background attributes
|
||||||
|
pNewCell->SetData(pNewData);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert new cells in following rows
|
||||||
|
for( int iRow = 0; iRow < iNewRows; iRow++ )
|
||||||
|
{
|
||||||
|
// Get the next existing row
|
||||||
|
if( pRow )
|
||||||
|
pRow = (CEditTableRowElement*)pRow->GetNextSibling();
|
||||||
|
|
||||||
|
if( pRow )
|
||||||
{
|
{
|
||||||
pNewCell = new CEditTableCellElement;
|
// Starting with first cell in row, find the cell
|
||||||
pNewCell->InsertAfter(this);
|
// just after "this" cell's column
|
||||||
pNewCell->FinishedLoad(pBuffer);
|
CEditTableCellElement *pCell = (CEditTableCellElement*)pRow->GetChild();
|
||||||
|
while( pCell && pCell->GetX() <= m_X )
|
||||||
|
pCell = (CEditTableCellElement*)pCell->GetNextSibling();
|
||||||
|
|
||||||
|
// Insert new cells before the one we found
|
||||||
|
for( int i = 0; i < m_iColSpan; i++ )
|
||||||
|
{
|
||||||
|
pNewCell = new CEditTableCellElement;
|
||||||
|
if( pCell )
|
||||||
|
pNewCell->InsertBefore(pCell);
|
||||||
|
else
|
||||||
|
// Row has no cells! (Table is messed up)
|
||||||
|
pNewCell->InsertAsFirstChild(pRow);
|
||||||
|
|
||||||
|
pNewCell->FinishedLoad(pBuffer);
|
||||||
|
// Set background attributes
|
||||||
|
pNewCell->SetData(pNewData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If no row, table is messed up.
|
||||||
|
// But we can fix it by simply inserting a new row
|
||||||
|
CEditTableRowElement *pNewRow = new CEditTableRowElement(m_iColSpan);
|
||||||
|
if( pNewRow == NULL )
|
||||||
|
break;
|
||||||
|
pNewRow->InsertAfter(pCurrentRow);
|
||||||
|
pCurrentRow = pNewRow;
|
||||||
|
pRow->FinishedLoad(pBuffer);
|
||||||
|
// Set background attributes in cells created with the row
|
||||||
|
CEditTableCellElement *pNewRowCell = (CEditTableCellElement*)pRow->GetChild();
|
||||||
|
while( pNewRowCell )
|
||||||
|
{
|
||||||
|
pNewRowCell->SetData(pNewData);
|
||||||
|
pNewRowCell = (CEditTableCellElement*)pNewRowCell->GetNextSibling();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now reset values in current cell
|
// Now reset values in current cell
|
||||||
EDT_TableCellData *pData = GetData();
|
pData->iColSpan = 1;
|
||||||
if( pData )
|
pData->iRowSpan = 1;
|
||||||
{
|
SetData(pData);
|
||||||
pData->iColSpan = 1;
|
EDT_FreeTableCellData(pData);
|
||||||
pData->iRowSpan = 1;
|
EDT_FreeTableCellData(pNewData);
|
||||||
SetData(pData);
|
|
||||||
EDT_FreeTableCellData(pData);
|
|
||||||
}
|
|
||||||
pBuffer->ClearFillNewCellWithSpace();
|
pBuffer->ClearFillNewCellWithSpace();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Move all contents of supplied cell into this cell
|
// Move all contents of supplied cell into this cell
|
||||||
void CEditTableCellElement::MergeCells(CEditTableCellElement* pCell)
|
void CEditTableCellElement::MergeCells(CEditTableCellElement* pCell, int32& iNewRowSpan)
|
||||||
{
|
{
|
||||||
if( !pCell || pCell == this )
|
if( !pCell || pCell == this )
|
||||||
return;
|
return;
|
||||||
|
@ -6317,7 +6382,19 @@ void CEditTableCellElement::MergeCells(CEditTableCellElement* pCell)
|
||||||
// Clear pointer to children just moved
|
// Clear pointer to children just moved
|
||||||
pCell->SetChild(0);
|
pCell->SetChild(0);
|
||||||
}
|
}
|
||||||
delete pCell;
|
CEditElement *pNext = pCell->GetNextSibling();
|
||||||
|
CEditElement *pPrev = pCell->GetPreviousSibling();
|
||||||
|
if( pCell->GetNextSibling() == NULL && pCell->GetPreviousSibling() == NULL )
|
||||||
|
{
|
||||||
|
// pCell is the only cell in this row, so delete the row
|
||||||
|
delete pCell->GetParent();
|
||||||
|
// Because we removed a row, the ROWSPAN is now 1 less
|
||||||
|
iNewRowSpan--;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
delete pCell;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CEditTableCellElement::DeleteContents(XP_Bool bMarkAsDeleted)
|
void CEditTableCellElement::DeleteContents(XP_Bool bMarkAsDeleted)
|
||||||
|
|
|
@ -6193,31 +6193,34 @@ void EDT_SetRefresh( MWContext* pContext, XP_Bool bRefreshOn ){
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Warning this deletes (and recreates) the CEditBuffer.
|
// Warning this deletes (and recreates) the CEditBuffer if we ChangeEncoding
|
||||||
XP_Bool EDT_SetEncoding(MWContext* pContext, int16 csid){
|
XP_Bool EDT_SetEncoding(MWContext* pContext, int16 csid){
|
||||||
GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) FALSE;
|
GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) FALSE;
|
||||||
ED_CharsetEncode bDoIt;
|
ED_CharsetEncode result;
|
||||||
// if ( pEditBuffer->HasEncoding() ) {
|
|
||||||
char* pMessage = XP_GetString(XP_EDT_I18N_HAS_CHARSET);
|
char* pMessage = XP_GetString(XP_EDT_I18N_HAS_CHARSET);
|
||||||
if ( pMessage ) {
|
if ( pMessage ) {
|
||||||
bDoIt = FE_EncodingDialog(pContext);
|
result = FE_EncodingDialog(pContext);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
XP_ASSERT(0);
|
XP_ASSERT(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (bDoIt)
|
switch (result)
|
||||||
{
|
{
|
||||||
case ED_ENDCODE_CHANGE_CHARSET:
|
case ED_ENDCODE_CHANGE_CHARSET:
|
||||||
// Change encoding and translate document
|
// Change encoding and translate document
|
||||||
pEditBuffer->ChangeEncoding(csid);
|
pEditBuffer->ChangeEncoding(csid);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
||||||
case ED_ENCODE_CHANGE_METATAG:
|
case ED_ENCODE_CHANGE_METATAG:
|
||||||
// Change encoding and but don't translate document
|
// Set charset param in Content-Type metatag, but don't translate document
|
||||||
XP_ASSERT(0); // Not implemented yet
|
pEditBuffer->SetEncoding(csid);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
case ED_ENCODE_CANCEL:
|
case ED_ENCODE_CANCEL:
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
XP_ASSERT(0);
|
XP_ASSERT(0);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
|
@ -990,6 +990,130 @@ void lo_CreateCellFromSubDoc( MWContext *context, lo_DocState *state,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
** New functions used by the editor to improve the performance of typing in tables
|
||||||
|
**/
|
||||||
|
|
||||||
|
/* Creates and returns a new lo_DocState for an existing LO_CELL layout element to get
|
||||||
|
relaid out on. Sets the dimensions of the lo_DocState structure to those
|
||||||
|
of the LO_CELL element. */
|
||||||
|
lo_DocState * lo_CreateStateForCellLayout(MWContext *context, LO_CellStruct *cell)
|
||||||
|
{
|
||||||
|
lo_DocState *new_doc = NULL;
|
||||||
|
|
||||||
|
if (context && cell)
|
||||||
|
{
|
||||||
|
new_doc = lo_NewLayout( context, cell->width, cell->height, 0, 0, NULL );
|
||||||
|
}
|
||||||
|
|
||||||
|
return new_doc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This function is identical to lo_ShiftCell() except that it does not move
|
||||||
|
the cell's layers */
|
||||||
|
static void
|
||||||
|
lo_OffsetCellContents(LO_CellStruct *cell, int32 dx, int32 dy)
|
||||||
|
{
|
||||||
|
LO_Element *eptr;
|
||||||
|
|
||||||
|
if (cell == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
eptr = cell->cell_list;
|
||||||
|
while (eptr != NULL)
|
||||||
|
{
|
||||||
|
eptr->lo_any.x += dx;
|
||||||
|
eptr->lo_any.y += dy;
|
||||||
|
if (eptr->type == LO_CELL)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* This would cause an infinite loop.
|
||||||
|
*/
|
||||||
|
if ((LO_CellStruct *)eptr == cell)
|
||||||
|
{
|
||||||
|
XP_ASSERT(FALSE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
lo_OffsetCellContents((LO_CellStruct *)eptr, dx, dy);
|
||||||
|
}
|
||||||
|
|
||||||
|
lo_MoveElementLayers( eptr );
|
||||||
|
eptr = eptr->lo_any.next;
|
||||||
|
}
|
||||||
|
|
||||||
|
eptr = cell->cell_float_list;
|
||||||
|
while (eptr != NULL)
|
||||||
|
{
|
||||||
|
eptr->lo_any.x += dx;
|
||||||
|
eptr->lo_any.y += dy;
|
||||||
|
if (eptr->type == LO_CELL)
|
||||||
|
{
|
||||||
|
lo_OffsetCellContents((LO_CellStruct *)eptr, dx, dy);
|
||||||
|
}
|
||||||
|
|
||||||
|
lo_MoveElementLayers( eptr );
|
||||||
|
|
||||||
|
eptr = eptr->lo_any.next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Populates the LO_CELL element with the freshly generated contents of the
|
||||||
|
lo_DocState structure. Assumes that the layout elements on the lo_DocState
|
||||||
|
are hooked up to their peer editor elements in the editor content model.
|
||||||
|
Recycles the old layout elements contained in the LO_CELL element. */
|
||||||
|
void lo_RebuildCell(MWContext *context, lo_DocState *state, LO_CellStruct *cell)
|
||||||
|
{
|
||||||
|
/*** Recycle old contents of the cell ***/
|
||||||
|
if (!cell)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* If cell list exists, cell_list_end must exist too */
|
||||||
|
XP_ASSERT((cell->cell_list && cell->cell_list_end) ||
|
||||||
|
(!cell->cell_list && !cell->cell_list_end));
|
||||||
|
|
||||||
|
if (cell->cell_list && cell->cell_list_end)
|
||||||
|
{
|
||||||
|
XP_ASSERT(cell->cell_list_end->lo_any.next == NULL);
|
||||||
|
lo_RecycleElements(context, state, cell->cell_list);
|
||||||
|
}
|
||||||
|
if (cell->cell_float_list)
|
||||||
|
lo_RecycleElements(context, state, cell->cell_float_list);
|
||||||
|
|
||||||
|
cell->cell_list = NULL;
|
||||||
|
cell->cell_float_list = NULL;
|
||||||
|
cell->cell_list_end = NULL;
|
||||||
|
|
||||||
|
/*** Copy pointers to new content from the doc state to the cell ***/
|
||||||
|
|
||||||
|
/* If line array exists, end_last_line must exist too */
|
||||||
|
XP_ASSERT((state->line_array[0] && state->end_last_line) ||
|
||||||
|
(!state->line_array[0] && !state->end_last_line));
|
||||||
|
|
||||||
|
/* Ensure that the line list on the doc state has been flushed to
|
||||||
|
the line array */
|
||||||
|
XP_ASSERT(state->line_list == NULL);
|
||||||
|
|
||||||
|
if (state->line_array[0] && state->end_last_line)
|
||||||
|
{
|
||||||
|
XP_ASSERT(state->end_last_line->lo_any.next == NULL);
|
||||||
|
cell->cell_list = state->line_array[0];
|
||||||
|
cell->cell_list_end = state->end_last_line;
|
||||||
|
|
||||||
|
state->line_array[0] = NULL;
|
||||||
|
state->end_last_line = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state->float_list)
|
||||||
|
{
|
||||||
|
cell->cell_float_list = state->float_list;
|
||||||
|
state->float_list = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*** Offset new content of the cell relative to the cell's position ***/
|
||||||
|
lo_OffsetCellContents( cell, cell->x, cell->y );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef TEST_16BIT
|
#ifdef TEST_16BIT
|
||||||
#undef XP_WIN16
|
#undef XP_WIN16
|
||||||
#endif /* TEST_16BIT */
|
#endif /* TEST_16BIT */
|
||||||
|
|
|
@ -773,7 +773,7 @@ lo_DisplayElement(MWContext *context, LO_Element *tptr,
|
||||||
if (((LO_CellStruct*)tptr)->cell_inflow_layer)
|
if (((LO_CellStruct*)tptr)->cell_inflow_layer)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* cmanske: reversed order so cell selection highlighing
|
/* cmanske: reversed order so cell selection highlighting
|
||||||
shows up over text in the cell */
|
shows up over text in the cell */
|
||||||
lo_DisplayCellContents(context, (LO_CellStruct *)tptr,
|
lo_DisplayCellContents(context, (LO_CellStruct *)tptr,
|
||||||
base_x, base_y, x, y, width, height);
|
base_x, base_y, x, y, width, height);
|
||||||
|
|
|
@ -734,9 +734,11 @@ void lo_MergeElements( MWContext *context, lo_DocState *old_state, int32 iStartL
|
||||||
#endif /* DEBUG */
|
#endif /* DEBUG */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
PRIVATE
|
PRIVATE
|
||||||
LO_RelayoutData* lo_NewRelayoutData( MWContext* context, ED_TagCursor* pCursor,
|
LO_RelayoutData* lo_NewRelayoutData( MWContext* context, ED_TagCursor* pCursor,
|
||||||
int32 iStartLine, int iStartEditOffset )
|
int32 iStartLine, int iStartEditOffset, lo_DocState *new_state )
|
||||||
{
|
{
|
||||||
int32 doc_id;
|
int32 doc_id;
|
||||||
LO_RelayoutData *pRd;
|
LO_RelayoutData *pRd;
|
||||||
|
@ -765,9 +767,14 @@ LO_RelayoutData* lo_NewRelayoutData( MWContext* context, ED_TagCursor* pCursor,
|
||||||
pRd->iStartLine = iStartLine;
|
pRd->iStartLine = iStartLine;
|
||||||
pRd->iStartEditOffset = iStartEditOffset;
|
pRd->iStartEditOffset = iStartEditOffset;
|
||||||
|
|
||||||
pRd->new_state = lo_NewLayout( context, pRd->old_state->win_width,
|
/* new state was supplied */
|
||||||
pRd->old_state->win_height, pRd->old_state->win_left,
|
if( new_state )
|
||||||
pRd->old_state->win_top, pRd->old_state );
|
pRd->new_state = new_state;
|
||||||
|
else
|
||||||
|
pRd->new_state = lo_NewLayout( context, pRd->old_state->win_width,
|
||||||
|
pRd->old_state->win_height, pRd->old_state->win_left,
|
||||||
|
pRd->old_state->win_top, pRd->old_state );
|
||||||
|
|
||||||
pRd->new_state->display_blocked = TRUE;
|
pRd->new_state->display_blocked = TRUE;
|
||||||
pRd->new_state->edit_relayout_display_blocked = TRUE;
|
pRd->new_state->edit_relayout_display_blocked = TRUE;
|
||||||
|
|
||||||
|
@ -862,7 +869,310 @@ LO_Element *lo_strip_mquotes(LO_Element **elist)
|
||||||
return mquotes;
|
return mquotes;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LO_EditorReflow(MWContext *context, ED_TagCursor *pCursor,
|
void lo_EditorCellReflow(MWContext *context, ED_TagCursor *pCursor, LO_CellStruct *pCell)
|
||||||
|
{
|
||||||
|
PA_Tag *pTag;
|
||||||
|
PA_Tag *pNextTag = 0;
|
||||||
|
LO_Element *eptr;
|
||||||
|
LO_Element **line_array;
|
||||||
|
int32 changedY, changedHeight;
|
||||||
|
LO_RelayoutData* pRd;
|
||||||
|
Bool bFoundBreak, bBreakIsEndTag;
|
||||||
|
int32 iEndLine = -1;
|
||||||
|
LO_Element *leadingMquotes = NULL;
|
||||||
|
|
||||||
|
int32 x = pCell->x + 1;
|
||||||
|
int32 y = pCell->y + 1;
|
||||||
|
lo_DocState *new_state;
|
||||||
|
int iStartEditOffset = 0;
|
||||||
|
int32 iStartLine;
|
||||||
|
|
||||||
|
if( !context || !pCursor || !pCell )
|
||||||
|
return;
|
||||||
|
|
||||||
|
LO_FirstElementOnLine(context, x, y, &iStartLine);
|
||||||
|
context->is_editor |= EDT_RELAYOUT_FLAG; /* Relayout flag */
|
||||||
|
|
||||||
|
/* Create a new doc state to layout into */
|
||||||
|
new_state = lo_CreateStateForCellLayout(context, pCell);
|
||||||
|
pRd = lo_NewRelayoutData( context, pCursor, iStartLine, iStartEditOffset, new_state );
|
||||||
|
|
||||||
|
/*************************************************************/
|
||||||
|
/* This block was copied from lo_Relayout
|
||||||
|
TODO: When things work, extract common code into a separate function */
|
||||||
|
|
||||||
|
/* save the floating element list for later deletion. */
|
||||||
|
if( pRd->old_state->float_list != 0 )
|
||||||
|
{
|
||||||
|
lo_relayout_recycle(context, pRd->new_state, pRd->old_state->float_list);
|
||||||
|
pRd->old_state->float_list = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
while( (pTag = pNextTag) != 0
|
||||||
|
|| (pTag = EDT_TagCursorGetNextState(pCursor)) != 0 )
|
||||||
|
{
|
||||||
|
lo_LayoutTag(pRd->context, pRd->new_state, pTag);
|
||||||
|
pNextTag = pTag->next;
|
||||||
|
PA_FreeTag(pTag);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* What the heck is this doing? */
|
||||||
|
eptr = NULL;
|
||||||
|
XP_LOCK_BLOCK(line_array, LO_Element **, pRd->new_state->line_array);
|
||||||
|
eptr = line_array[0];
|
||||||
|
if (eptr != NULL )
|
||||||
|
{
|
||||||
|
lo_relayout_recycle(context, pRd->new_state, eptr);
|
||||||
|
}
|
||||||
|
XP_UNLOCK_BLOCK(pRd->old_state->line_array);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Get list of any mailing quote bullets, removing them from line_list.
|
||||||
|
These are the only elements that we want to preserve.
|
||||||
|
lo_strip_mquotes deals properly with a NULL input.
|
||||||
|
Note that this can change the value of pRd->new_state->line_list.
|
||||||
|
*/
|
||||||
|
leadingMquotes = lo_strip_mquotes(&pRd->new_state->line_list);
|
||||||
|
if ( pRd->new_state->line_list ) {
|
||||||
|
lo_relayout_recycle(context, pRd->new_state, pRd->new_state->line_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Only leave the leading mquote bullets, if any. */
|
||||||
|
pRd->new_state->line_list = leadingMquotes;
|
||||||
|
pRd->new_state->line_num = 1;
|
||||||
|
|
||||||
|
/* while there are tags to parse... */
|
||||||
|
bFoundBreak = FALSE;
|
||||||
|
pNextTag = NULL;
|
||||||
|
while( !bFoundBreak )
|
||||||
|
{
|
||||||
|
if( pNextTag == NULL )
|
||||||
|
{
|
||||||
|
pTag = EDT_TagCursorGetNext(pRd->pTagCursor);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pTag = pNextTag;
|
||||||
|
}
|
||||||
|
if( pTag == NULL ){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
pRd->new_state->display_blocked = TRUE;
|
||||||
|
pNextTag = pTag->next;
|
||||||
|
if( iStartEditOffset && pTag->type == P_TEXT )
|
||||||
|
{
|
||||||
|
pRd->new_state->edit_current_offset = iStartEditOffset;
|
||||||
|
pRd->new_state->edit_force_offset = TRUE;
|
||||||
|
lo_LayoutTag(pRd->context, pRd->new_state, pTag);
|
||||||
|
iStartEditOffset = 0;
|
||||||
|
pRd->new_state->edit_force_offset = FALSE;
|
||||||
|
PA_FreeTag(pTag);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* lo_LayoutTag(pRd->context, pRd->new_state, pTag);*/
|
||||||
|
/* Matches code at end of LO_ProcessTag */
|
||||||
|
lo_DocState *state = pRd->new_state;
|
||||||
|
lo_DocState *orig_state;
|
||||||
|
lo_DocState *up_state;
|
||||||
|
PA_Tag* tag = pTag;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Divert all tags to the current sub-document if there is one.
|
||||||
|
*/
|
||||||
|
up_state = NULL;
|
||||||
|
orig_state = state;
|
||||||
|
|
||||||
|
/* Note: we always display tables, so we ignore bDisplayTables now */
|
||||||
|
while (state->sub_state != NULL)
|
||||||
|
{
|
||||||
|
lo_DocState *new_state;
|
||||||
|
|
||||||
|
up_state = state;
|
||||||
|
new_state = state->sub_state;
|
||||||
|
state = new_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* orig_state->top_state->layout_status = status; */
|
||||||
|
|
||||||
|
{
|
||||||
|
lo_DocState *tmp_state;
|
||||||
|
Bool may_save;
|
||||||
|
|
||||||
|
if ((state->is_a_subdoc == SUBDOC_CELL)||
|
||||||
|
(state->is_a_subdoc == SUBDOC_CAPTION))
|
||||||
|
{
|
||||||
|
may_save = TRUE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
may_save = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Some table routines reach out to find the top doc state.
|
||||||
|
* So we replace it for the duration of this call.
|
||||||
|
*/
|
||||||
|
pRd->top_state->doc_state = pRd->new_state;
|
||||||
|
state->edit_relayout_display_blocked = TRUE;
|
||||||
|
state->display_blocked = TRUE;
|
||||||
|
|
||||||
|
lo_LayoutTag(context, state, tag);
|
||||||
|
pRd->top_state->doc_state = pRd->old_state;
|
||||||
|
tmp_state = lo_CurrentSubState(orig_state);
|
||||||
|
|
||||||
|
if (may_save != FALSE)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* That tag popped us up one state level. If this new
|
||||||
|
* state is still a subdoc, save the tag there.
|
||||||
|
*/
|
||||||
|
if (tmp_state == up_state)
|
||||||
|
{
|
||||||
|
if ((tmp_state->is_a_subdoc == SUBDOC_CELL)||
|
||||||
|
(tmp_state->is_a_subdoc == SUBDOC_CAPTION))
|
||||||
|
{
|
||||||
|
lo_SaveSubdocTags(context, tmp_state, tag);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PA_FreeTag(tag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Else that tag put us in a new subdoc on the same
|
||||||
|
* level. It needs to be saved one level up,
|
||||||
|
* if the parent is also a subdoc.
|
||||||
|
*/
|
||||||
|
else if ((up_state != NULL)&&
|
||||||
|
(tmp_state == up_state->sub_state)&&
|
||||||
|
(tmp_state != state))
|
||||||
|
{
|
||||||
|
if ((up_state->is_a_subdoc == SUBDOC_CELL)||
|
||||||
|
(up_state->is_a_subdoc == SUBDOC_CAPTION))
|
||||||
|
{
|
||||||
|
lo_SaveSubdocTags(context, up_state, tag);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PA_FreeTag(tag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Else we are still in the same subdoc
|
||||||
|
*/
|
||||||
|
else if (tmp_state == state)
|
||||||
|
{
|
||||||
|
lo_SaveSubdocTags(context, state, tag);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Else that tag started a new, nested subdoc.
|
||||||
|
* Add the starting tag to the parent.
|
||||||
|
*/
|
||||||
|
else if (tmp_state == state->sub_state)
|
||||||
|
{
|
||||||
|
lo_SaveSubdocTags(context, state, tag);
|
||||||
|
/*
|
||||||
|
* Since we have extended the parent chain,
|
||||||
|
* we need to reset the child to the new
|
||||||
|
* parent end-chain.
|
||||||
|
*/
|
||||||
|
if ((tmp_state->is_a_subdoc == SUBDOC_CELL)||
|
||||||
|
(tmp_state->is_a_subdoc == SUBDOC_CAPTION))
|
||||||
|
{
|
||||||
|
tmp_state->subdoc_tags =
|
||||||
|
state->subdoc_tags_end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* This can never happen.
|
||||||
|
*/
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PA_FreeTag(tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
state = tmp_state;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PA_FreeTag(tag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* pNextTag = pTag->next;
|
||||||
|
PA_FreeTag(pTag);
|
||||||
|
*/ if( pNextTag == 0 ){
|
||||||
|
bFoundBreak = EDT_TagCursorAtBreak( pRd->pTagCursor, &bBreakIsEndTag );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( bFoundBreak )
|
||||||
|
{
|
||||||
|
if( bBreakIsEndTag ){
|
||||||
|
pTag = EDT_TagCursorGetNext(pRd->pTagCursor);
|
||||||
|
lo_LayoutTag(pRd->context, pRd->new_state, pTag);
|
||||||
|
iEndLine = EDT_TagCursorCurrentLine( pRd->pTagCursor );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
iEndLine = EDT_TagCursorCurrentLine( pRd->pTagCursor );
|
||||||
|
pTag = EDT_TagCursorGetNext(pRd->pTagCursor);
|
||||||
|
if ( pTag->type == P_TABLE ) {
|
||||||
|
lo_CloseOutLayout( pRd->context, pRd->new_state);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lo_LayoutTag(pRd->context, pRd->new_state, pTag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EDT_DeleteTagChain(pTag);
|
||||||
|
|
||||||
|
/* don't close layout. We just flushed this line to the proper
|
||||||
|
* height, there is a start of a new tag in the buffer.
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lo_CloseOutLayout( pRd->context, pRd->new_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if( iEndLine == -1 ){
|
||||||
|
iEndLine = pRd->old_state->line_num-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Go up the liststack, closing out any mquotes. */
|
||||||
|
{
|
||||||
|
lo_ListStack *lptr;
|
||||||
|
lptr = pRd->new_state->list_stack;
|
||||||
|
while (lptr->type != P_UNKNOWN && lptr->next != NULL)
|
||||||
|
{
|
||||||
|
if (lptr->quote_type == QUOTE_MQUOTE)
|
||||||
|
{
|
||||||
|
lo_add_leading_bullets(context,pRd->new_state,
|
||||||
|
lptr->mquote_line_num - 1,
|
||||||
|
pRd->new_state->line_num - 2,
|
||||||
|
lptr->mquote_x);
|
||||||
|
}
|
||||||
|
|
||||||
|
lptr = lptr->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************/
|
||||||
|
|
||||||
|
lo_RebuildCell(context, new_state, pCell);
|
||||||
|
/* TODO -- RESET POINTERS SO NEW TAGS ARE NOT DELETED AND DELETE new_state */
|
||||||
|
|
||||||
|
/* For now, assume same Y and height doesn't change */
|
||||||
|
changedY = pCell->y;
|
||||||
|
/* Note: using -1 for this will redraw to the end of the window */
|
||||||
|
changedHeight = pCell->line_height;
|
||||||
|
|
||||||
|
context->is_editor &= ~EDT_RELAYOUT_FLAG;
|
||||||
|
FE_DocumentChanged( context, changedY, changedHeight );
|
||||||
|
}
|
||||||
|
|
||||||
|
void lo_EditorReflow(MWContext *context, ED_TagCursor *pCursor,
|
||||||
int32 iStartLine, int iStartEditOffset)
|
int32 iStartLine, int iStartEditOffset)
|
||||||
{
|
{
|
||||||
PA_Tag *pTag;
|
PA_Tag *pTag;
|
||||||
|
@ -880,7 +1190,7 @@ void LO_EditorReflow(MWContext *context, ED_TagCursor *pCursor,
|
||||||
LO_Element ** old_line_array;
|
LO_Element ** old_line_array;
|
||||||
|
|
||||||
context->is_editor |= EDT_RELAYOUT_FLAG; /* Relayout flag */
|
context->is_editor |= EDT_RELAYOUT_FLAG; /* Relayout flag */
|
||||||
pRd = lo_NewRelayoutData( context, pCursor, iStartLine, iStartEditOffset );
|
pRd = lo_NewRelayoutData( context, pCursor, iStartLine, iStartEditOffset, 0 );
|
||||||
|
|
||||||
/* save the floating element list for later deletion. */
|
/* save the floating element list for later deletion. */
|
||||||
if( pRd->old_state->float_list != 0 )
|
if( pRd->old_state->float_list != 0 )
|
||||||
|
@ -1077,7 +1387,7 @@ void LO_Relayout(MWContext *context, ED_TagCursor *pCursor,
|
||||||
int32 iEndLine = -1;
|
int32 iEndLine = -1;
|
||||||
LO_Element *leadingMquotes = NULL;
|
LO_Element *leadingMquotes = NULL;
|
||||||
context->is_editor |= EDT_RELAYOUT_FLAG; /* Relayout flag */
|
context->is_editor |= EDT_RELAYOUT_FLAG; /* Relayout flag */
|
||||||
pRd = lo_NewRelayoutData( context, pCursor, iStartLine, iStartEditOffset );
|
pRd = lo_NewRelayoutData( context, pCursor, iStartLine, iStartEditOffset, 0 );
|
||||||
|
|
||||||
/* We need to keep images loaded during relayout. Images are reference counted.
|
/* We need to keep images loaded during relayout. Images are reference counted.
|
||||||
* When the total number of layout elements that use an image drops to zero,
|
* When the total number of layout elements that use an image drops to zero,
|
||||||
|
|
|
@ -1570,12 +1570,17 @@ lo_ScriptEvalExitFn(void * data, char * str, size_t len, char * wysiwyg_url,
|
||||||
char * base_href, Bool valid);
|
char * base_href, Bool valid);
|
||||||
|
|
||||||
extern Bool
|
extern Bool
|
||||||
lo_ConvertMochaEntities(MWContext * context, lo_DocState *state, PA_Tag * tag);
|
lo_ConvertMochaEntities(MWContext * pContext, lo_DocState *state, PA_Tag * tag);
|
||||||
|
|
||||||
extern void
|
extern void
|
||||||
LO_EditorReflow(MWContext *context, ED_TagCursor *pCursor,
|
lo_EditorReflow(MWContext *pContext, ED_TagCursor *pCursor,
|
||||||
int32 iStartLine, int iStartEditOffset);
|
int32 iStartLine, int iStartEditOffset);
|
||||||
|
|
||||||
|
/* Reflow contents of a cell into a new docstate, then merge back into table */
|
||||||
|
extern void
|
||||||
|
lo_EditorCellReflow(MWContext *context, ED_TagCursor *pCursor, LO_CellStruct *pCell);
|
||||||
|
|
||||||
|
|
||||||
/********************** Image observers and observer lists. ******************/
|
/********************** Image observers and observer lists. ******************/
|
||||||
/* The layout observer for an image request. */
|
/* The layout observer for an image request. */
|
||||||
extern void
|
extern void
|
||||||
|
@ -1679,4 +1684,7 @@ int32 lo_GetRowSpan(LO_Element *pCellElement);
|
||||||
int32 lo_GetColSpan(LO_Element *pCellElement);
|
int32 lo_GetColSpan(LO_Element *pCellElement);
|
||||||
int32 lo_GetCellPadding(LO_Element *pCellElement);
|
int32 lo_GetCellPadding(LO_Element *pCellElement);
|
||||||
|
|
||||||
|
lo_DocState * lo_CreateStateForCellLayout(MWContext *context, LO_CellStruct *cell);
|
||||||
|
void lo_RebuildCell(MWContext *context, lo_DocState *state, LO_CellStruct *cell);
|
||||||
|
|
||||||
#endif /* _Layout_h_ */
|
#endif /* _Layout_h_ */
|
||||||
|
|
|
@ -341,7 +341,7 @@ void LO_Reflow(MWContext *context, lo_DocState * state, LO_Element *startElement
|
||||||
|
|
||||||
/* init this by hand as we don't want to create a new state */
|
/* init this by hand as we don't want to create a new state */
|
||||||
relay_state.context = context;
|
relay_state.context = context;
|
||||||
relay_state.top_state = lo_FetchTopState(XP_DOCID(context));
|
relay_state.top_state = top_state; /*lo_FetchTopState(XP_DOCID(context));*/
|
||||||
relay_state.doc_state = state;
|
relay_state.doc_state = state;
|
||||||
|
|
||||||
firstElement = TRUE;
|
firstElement = TRUE;
|
||||||
|
|
Загрузка…
Ссылка в новой задаче