зеркало из 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 );
|
||||
}
|
||||
|
||||
//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 0
|
||||
//
|
||||
// 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{
|
||||
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 ){
|
||||
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_DIRECTORY ||
|
||||
t == P_MENU ||
|
||||
t == P_UNUM_LIST ||
|
||||
t == P_NUM_LIST ||
|
||||
t == P_DESC_LIST){
|
||||
pEditBuffer->MorphListContainer( t );
|
||||
} else {
|
||||
|
@ -1898,10 +1911,9 @@ void EDT_ConvertTableToText(MWContext *pMWContext)
|
|||
}
|
||||
|
||||
/* 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)
|
||||
{
|
||||
GET_EDIT_BUF_OR_RETURN(pMWContext, pEditBuffer);
|
||||
pEditBuffer->CopyStyle();
|
||||
}
|
||||
|
||||
/* TRUE if no mouse actions taken since last EDT_CopyStyle call */
|
||||
|
|
|
@ -1263,7 +1263,8 @@ public:
|
|||
void SetSpecialSelected(XP_Bool bSelected) { m_bSpecialSelected = bSelected; }
|
||||
|
||||
// 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();
|
||||
|
||||
// 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
|
||||
void ConvertTableToText();
|
||||
|
||||
// Save the character and paragraph style of selection or at caret
|
||||
void CopyStyle();
|
||||
|
||||
// This is TRUE after EDT_CopyStyle is called, until the next left mouse up call
|
||||
// This is TRUE after any HTML is copied
|
||||
XP_Bool CanPasteStyle() { return (m_pCopyStyleCharacterData != NULL); }
|
||||
|
||||
// Apply the style to selection or at caret. Use bApplyStyle = FALSE to cancel
|
||||
|
@ -3497,9 +3495,11 @@ public:
|
|||
void SetMetaData( EDT_MetaData *pMetaData );
|
||||
void DeleteMetaData( 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, int index );
|
||||
// Return FALSE only if we are closing down
|
||||
XP_Bool CheckCharset( EDT_MetaData *pData,int16 win_csid );
|
||||
|
||||
EDT_HorizRuleData* GetHorizRuleData();
|
||||
void SetHorizRuleData( EDT_HorizRuleData* pData );
|
||||
|
@ -3986,6 +3986,8 @@ public:
|
|||
|
||||
void ChangeEncoding(int16 csid);
|
||||
void SetEncoding(int16 csid);
|
||||
void SetEncoding(char *pCharset);
|
||||
|
||||
XP_Bool HasEncoding();
|
||||
|
||||
// Used for QA only - Ctrl+Alt+Shift+N accelerator for automated testing
|
||||
|
|
|
@ -23,7 +23,8 @@
|
|||
#include "prefapi.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().
|
||||
#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;
|
||||
|
||||
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
|
||||
* 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;
|
||||
|
||||
case P_META:
|
||||
ParseMetaTag( pTag );
|
||||
ParseMetaTag( pTag, retVal );
|
||||
break;
|
||||
|
||||
case P_BASE:
|
||||
|
@ -2123,7 +2129,7 @@ void CEditBuffer::Reflow( CEditElement* pStartElement,
|
|||
}
|
||||
#endif
|
||||
|
||||
XP_Bool bInTableCell = pStartElement ? (pStartElement->GetTableIgnoreSubdoc() != NULL) : FALSE;
|
||||
CEditTableCellElement *pCell = FALSE;
|
||||
|
||||
// laying out from the beginning of the document
|
||||
if( pNewStartElement == 0 ){
|
||||
|
@ -2156,23 +2162,39 @@ void CEditBuffer::Reflow( CEditElement* pStartElement,
|
|||
// Note: If here, we must have a pStartElement and associated LO_Element
|
||||
XP_ASSERT(pStartElement && pLayoutElement);
|
||||
|
||||
// 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;
|
||||
// If we are entirely within one cell, then use new cell reflow
|
||||
// ****** TODO: FINISH THIS WORK BEFORE ACTIVATING
|
||||
//pCell = pStartElement->GetTableCellIgnoreSubdoc();
|
||||
|
||||
if( pCell && pCell == pEndElement->GetTableCellIgnoreSubdoc() )
|
||||
{
|
||||
// Start with first element in the cell
|
||||
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.
|
||||
// Create a new cursor and reflow
|
||||
CEditTagCursor cursor(this, pEdStart, iOffset, pEndElement);
|
||||
//CEditTagCursor *pCursor = new CEditTagCursor(this, m_pRoot, iOffset);
|
||||
|
||||
LO_EditorReflow(m_pContext, &cursor, iLineNum, iOffset);
|
||||
|
||||
if( pCell )
|
||||
lo_EditorCellReflow(m_pContext, &cursor, GetLoCell(pCell));
|
||||
else
|
||||
lo_EditorReflow(m_pContext, &cursor, iLineNum, iOffset);
|
||||
|
||||
#if defined( DEBUG_shannon )
|
||||
XP_TRACE(("\n\nEDITOR REFLOW"));
|
||||
|
@ -4245,7 +4267,9 @@ void CEditBuffer::MorphContainer( TagType t )
|
|||
TagType tList = pList->GetType();
|
||||
// Assure that list-type items are only contained in their proper parents.
|
||||
// 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) ||
|
||||
(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
|
||||
void CEditBuffer::CopyStyle()
|
||||
{
|
||||
if( m_pCopyStyleCharacterData )
|
||||
EDT_FreeCharacterData(m_pCopyStyleCharacterData);
|
||||
|
||||
m_pCopyStyleCharacterData = GetCharacterData();
|
||||
}
|
||||
|
||||
// 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 delete the saved style data
|
||||
void CEditBuffer::PasteStyle(XP_Bool bApplyStyle)
|
||||
{
|
||||
if( m_pCopyStyleCharacterData )
|
||||
|
@ -5890,8 +5906,11 @@ void CEditBuffer::PasteStyle(XP_Bool bApplyStyle)
|
|||
{
|
||||
SetCharacterData(m_pCopyStyleCharacterData);
|
||||
}
|
||||
EDT_FreeCharacterData(m_pCopyStyleCharacterData);
|
||||
m_pCopyStyleCharacterData = NULL;
|
||||
else
|
||||
{
|
||||
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;
|
||||
char *pName;
|
||||
char *pContent;
|
||||
INTL_CharSetInfo c = LO_GetDocumentCharacterSetInfo(m_pContext);
|
||||
int16 win_csid = INTL_GetCSIWinCSID(c);
|
||||
retVal = OK_CONTINUE;
|
||||
|
||||
pContent = edt_FetchParamString( pTag, PARAM_CONTENT, win_csid );
|
||||
pName = edt_FetchParamString( pTag, PARAM_HTTP_EQUIV, win_csid );
|
||||
|
||||
// if we didn't get http-equiv, try for name=
|
||||
if( pName == 0 ){
|
||||
if( pName == 0 )
|
||||
{
|
||||
bHttpEquiv = FALSE;
|
||||
pName = edt_FetchParamString( pTag, PARAM_NAME, win_csid );
|
||||
}
|
||||
|
||||
// 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 );
|
||||
// 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 );
|
||||
|
||||
// Check our charset string for validity
|
||||
// (We may close done the buffer in this routine)
|
||||
if( CheckCharset(pData, win_csid) )
|
||||
{
|
||||
|
||||
// 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( 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
|
||||
|
||||
|
@ -6798,7 +6988,7 @@ void CEditBuffer::MergeTableCells()
|
|||
EDT_FreeTableCellData(pNextCellData);
|
||||
}
|
||||
// Move all contents of Next cell into First cell and delete Next cell
|
||||
pFirstCell->MergeCells(pNextCell);
|
||||
pFirstCell->MergeCells(pNextCell, pFirstCellData->iRowSpan);
|
||||
}
|
||||
} else {
|
||||
// We are merging with just the next cell to the right
|
||||
|
@ -6809,7 +6999,7 @@ void CEditBuffer::MergeTableCells()
|
|||
pFirstCellData->iColSpan += pNextCellData->iColSpan;
|
||||
EDT_FreeTableCellData(pNextCellData);
|
||||
}
|
||||
pFirstCell->MergeCells( pNextCell );
|
||||
pFirstCell->MergeCells(pNextCell, pFirstCellData->iRowSpan);
|
||||
}
|
||||
// Set the COLSPAN and ROWSPAN data for the merged cell
|
||||
pFirstCell->SetData(pFirstCellData);
|
||||
|
@ -6832,13 +7022,19 @@ void CEditBuffer::MergeTableCells()
|
|||
*/
|
||||
void CEditBuffer::SplitTableCell()
|
||||
{
|
||||
// Set beginning of UNDO block
|
||||
BeginBatchChanges(kGroupOfChangesCommandID);
|
||||
|
||||
CEditInsertPoint ip;
|
||||
GetTableInsertPoint(ip);
|
||||
CEditTableElement* pTable = ip.m_pElement->GetTableIgnoreSubdoc();
|
||||
CEditTableCellElement* pCell = ip.m_pElement->GetTableCellIgnoreSubdoc();
|
||||
if( !pCell )
|
||||
if( pTable == NULL || pCell == NULL )
|
||||
return;
|
||||
|
||||
pCell->SplitCell();
|
||||
Relayout(pTable, 0, pTable);
|
||||
|
||||
EndBatchChanges();
|
||||
}
|
||||
|
||||
|
||||
|
@ -13952,6 +14148,17 @@ EDT_ClipboardResult CEditBuffer::CopySelection( char **ppText, int32* pTextLen,
|
|||
// Get normal selection
|
||||
GetSelection(selection);
|
||||
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
|
||||
if( !selection.IsEmpty() )
|
||||
|
@ -17043,17 +17250,31 @@ void CEditBuffer::ChangeEncoding(int16 csid) {
|
|||
// See RFC 2070, "Internationalization of the Hypertext Markup Language"
|
||||
// http://ds.internic.net/rfc/rfc2070.txt
|
||||
// <META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=ISO-2022-JP">
|
||||
void CEditBuffer::SetEncoding(int16 csid) {
|
||||
char contentValue[200];
|
||||
char charSet[100];
|
||||
void CEditBuffer::SetEncoding(int16 csid)
|
||||
{
|
||||
int16 plainCSID = csid & ~CS_AUTO;
|
||||
INTL_CharSetIDToName(plainCSID, charSet);
|
||||
XP_SPRINTF(contentValue, "text/html; charset=%.100s", charSet);
|
||||
// This is better than INTL_CharSetIDToName, which needs presized buffer;
|
||||
// (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 );
|
||||
FreeMetaData( pData );
|
||||
EDT_MetaData *pData = MakeMetaData( TRUE, CONTENT_TYPE, pContent);
|
||||
if( pData )
|
||||
{
|
||||
SetMetaData( pData );
|
||||
FreeMetaData( pData );
|
||||
}
|
||||
else
|
||||
XP_ASSERT(0);
|
||||
}
|
||||
}
|
||||
|
||||
XP_Bool CEditBuffer::HasEncoding() {
|
||||
|
|
|
@ -6239,29 +6239,94 @@ void CEditTableCellElement::SplitCell()
|
|||
|
||||
pBuffer->SetFillNewCellWithSpace();
|
||||
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;
|
||||
pNewCell->InsertAfter(this);
|
||||
pNewCell->FinishedLoad(pBuffer);
|
||||
// Starting with first cell in row, find the cell
|
||||
// just after "this" cell's column
|
||||
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
|
||||
EDT_TableCellData *pData = GetData();
|
||||
if( pData )
|
||||
{
|
||||
pData->iColSpan = 1;
|
||||
pData->iRowSpan = 1;
|
||||
SetData(pData);
|
||||
EDT_FreeTableCellData(pData);
|
||||
}
|
||||
pData->iColSpan = 1;
|
||||
pData->iRowSpan = 1;
|
||||
SetData(pData);
|
||||
EDT_FreeTableCellData(pData);
|
||||
EDT_FreeTableCellData(pNewData);
|
||||
|
||||
pBuffer->ClearFillNewCellWithSpace();
|
||||
}
|
||||
|
||||
// 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 )
|
||||
return;
|
||||
|
@ -6317,7 +6382,19 @@ void CEditTableCellElement::MergeCells(CEditTableCellElement* pCell)
|
|||
// Clear pointer to children just moved
|
||||
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)
|
||||
|
|
|
@ -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){
|
||||
GET_EDIT_BUF_OR_RETURN(pContext, pEditBuffer) FALSE;
|
||||
ED_CharsetEncode bDoIt;
|
||||
// if ( pEditBuffer->HasEncoding() ) {
|
||||
ED_CharsetEncode result;
|
||||
|
||||
char* pMessage = XP_GetString(XP_EDT_I18N_HAS_CHARSET);
|
||||
if ( pMessage ) {
|
||||
bDoIt = FE_EncodingDialog(pContext);
|
||||
result = FE_EncodingDialog(pContext);
|
||||
}
|
||||
else {
|
||||
XP_ASSERT(0);
|
||||
}
|
||||
|
||||
switch (bDoIt)
|
||||
switch (result)
|
||||
{
|
||||
case ED_ENDCODE_CHANGE_CHARSET:
|
||||
// Change encoding and translate document
|
||||
pEditBuffer->ChangeEncoding(csid);
|
||||
return TRUE;
|
||||
|
||||
case ED_ENCODE_CHANGE_METATAG:
|
||||
// Change encoding and but don't translate document
|
||||
XP_ASSERT(0); // Not implemented yet
|
||||
// Set charset param in Content-Type metatag, but don't translate document
|
||||
pEditBuffer->SetEncoding(csid);
|
||||
return FALSE;
|
||||
|
||||
case ED_ENCODE_CANCEL:
|
||||
return FALSE;
|
||||
|
||||
default:
|
||||
XP_ASSERT(0);
|
||||
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
|
||||
#undef XP_WIN16
|
||||
#endif /* TEST_16BIT */
|
||||
|
|
|
@ -773,7 +773,7 @@ lo_DisplayElement(MWContext *context, LO_Element *tptr,
|
|||
if (((LO_CellStruct*)tptr)->cell_inflow_layer)
|
||||
break;
|
||||
|
||||
/* cmanske: reversed order so cell selection highlighing
|
||||
/* cmanske: reversed order so cell selection highlighting
|
||||
shows up over text in the cell */
|
||||
lo_DisplayCellContents(context, (LO_CellStruct *)tptr,
|
||||
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 */
|
||||
}
|
||||
|
||||
|
||||
|
||||
PRIVATE
|
||||
LO_RelayoutData* lo_NewRelayoutData( MWContext* context, ED_TagCursor* pCursor,
|
||||
int32 iStartLine, int iStartEditOffset )
|
||||
int32 iStartLine, int iStartEditOffset, lo_DocState *new_state )
|
||||
{
|
||||
int32 doc_id;
|
||||
LO_RelayoutData *pRd;
|
||||
|
@ -765,9 +767,14 @@ LO_RelayoutData* lo_NewRelayoutData( MWContext* context, ED_TagCursor* pCursor,
|
|||
pRd->iStartLine = iStartLine;
|
||||
pRd->iStartEditOffset = iStartEditOffset;
|
||||
|
||||
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 );
|
||||
/* new state was supplied */
|
||||
if( new_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->edit_relayout_display_blocked = TRUE;
|
||||
|
||||
|
@ -862,7 +869,310 @@ LO_Element *lo_strip_mquotes(LO_Element **elist)
|
|||
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)
|
||||
{
|
||||
PA_Tag *pTag;
|
||||
|
@ -880,7 +1190,7 @@ void LO_EditorReflow(MWContext *context, ED_TagCursor *pCursor,
|
|||
LO_Element ** old_line_array;
|
||||
|
||||
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. */
|
||||
if( pRd->old_state->float_list != 0 )
|
||||
|
@ -1077,7 +1387,7 @@ void LO_Relayout(MWContext *context, ED_TagCursor *pCursor,
|
|||
int32 iEndLine = -1;
|
||||
LO_Element *leadingMquotes = NULL;
|
||||
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.
|
||||
* 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);
|
||||
|
||||
extern Bool
|
||||
lo_ConvertMochaEntities(MWContext * context, lo_DocState *state, PA_Tag * tag);
|
||||
lo_ConvertMochaEntities(MWContext * pContext, lo_DocState *state, PA_Tag * tag);
|
||||
|
||||
extern void
|
||||
LO_EditorReflow(MWContext *context, ED_TagCursor *pCursor,
|
||||
lo_EditorReflow(MWContext *pContext, ED_TagCursor *pCursor,
|
||||
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. ******************/
|
||||
/* The layout observer for an image request. */
|
||||
extern void
|
||||
|
@ -1679,4 +1684,7 @@ int32 lo_GetRowSpan(LO_Element *pCellElement);
|
|||
int32 lo_GetColSpan(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_ */
|
||||
|
|
|
@ -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 */
|
||||
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;
|
||||
|
||||
firstElement = TRUE;
|
||||
|
|
Загрузка…
Ссылка в новой задаче