richedit: Added in support for streaming in and out nested tables.

This commit is contained in:
Dylan Smith 2008-08-07 12:31:46 -04:00 committed by Alexandre Julliard
parent 300db3765f
commit 59195ed2ec
4 changed files with 135 additions and 28 deletions

View File

@ -482,6 +482,7 @@ static void ME_RTFParAttrHook(RTF_Info *info)
* table anymore.
*/
info->tableDef->tableRowStart = NULL;
info->canInheritInTbl = FALSE;
}
}
} else { /* v1.0 - v3.0 */
@ -489,13 +490,42 @@ static void ME_RTFParAttrHook(RTF_Info *info)
fmt.wEffects &= ~PFE_TABLE;
}
break;
case rtfInTable:
{
ME_Cursor cursor;
case rtfNestLevel:
if (!info->editor->bEmulateVersion10) /* v4.1 */
{
if (!info->tableDef || !info->tableDef->tableRowStart ||
info->tableDef->tableRowStart->member.para.nFlags & MEPF_ROWEND)
while (info->rtfParam > info->nestingLevel) {
RTFTable *tableDef = ALLOC_OBJ(RTFTable);
ZeroMemory(tableDef, sizeof(RTFTable));
tableDef->parent = info->tableDef;
info->tableDef = tableDef;
RTFFlushOutputBuffer(info);
if (tableDef->tableRowStart &&
tableDef->tableRowStart->member.para.nFlags & MEPF_ROWEND)
{
ME_DisplayItem *para = tableDef->tableRowStart;
para = para->member.para.next_para;
para = ME_InsertTableRowStartAtParagraph(info->editor, para);
tableDef->tableRowStart = para;
} else {
ME_Cursor cursor;
WCHAR endl = '\r';
cursor = info->editor->pCursors[0];
if (cursor.nOffset || cursor.pRun->member.run.nCharOfs)
ME_InsertTextFromCursor(info->editor, 0, &endl, 1, info->style);
tableDef->tableRowStart = ME_InsertTableRowStartFromCursor(info->editor);
}
info->nestingLevel++;
}
info->canInheritInTbl = FALSE;
}
break;
case rtfInTable:
{
if (!info->editor->bEmulateVersion10) /* v4.1 */
{
if (info->nestingLevel < 1)
{
RTFTable *tableDef;
if (!info->tableDef)
@ -505,20 +535,24 @@ static void ME_RTFParAttrHook(RTF_Info *info)
}
tableDef = info->tableDef;
RTFFlushOutputBuffer(info);
if (!tableDef->tableRowStart)
if (tableDef->tableRowStart &&
tableDef->tableRowStart->member.para.nFlags & MEPF_ROWEND)
{
ME_DisplayItem *para = tableDef->tableRowStart;
para = para->member.para.next_para;
para = ME_InsertTableRowStartAtParagraph(info->editor, para);
tableDef->tableRowStart = para;
} else {
ME_Cursor cursor;
WCHAR endl = '\r';
cursor = info->editor->pCursors[0];
if (cursor.nOffset || cursor.pRun->member.run.nCharOfs)
ME_InsertTextFromCursor(info->editor, 0, &endl, 1, info->style);
}
/* FIXME: Remove the following condition once nested tables are supported */
if (ME_GetParagraph(info->editor->pCursors[0].pRun)->member.para.pCell)
break;
tableDef->tableRowStart = ME_InsertTableRowStartFromCursor(info->editor);
}
info->nestingLevel = 1;
info->canInheritInTbl = TRUE;
}
return;
} else { /* v1.0 - v3.0 */
fmt.dwMask |= PFM_TABLE;
@ -763,6 +797,10 @@ static void ME_RTFSpecialCharHook(RTF_Info *info)
RTFTable *tableDef = info->tableDef;
switch (info->rtfMinor)
{
case rtfNestCell:
if (info->editor->bEmulateVersion10) /* v1.0 - v3.0 */
break;
/* else fall through since v4.1 treats rtfNestCell and rtfCell the same */
case rtfCell:
if (!tableDef)
break;
@ -770,12 +808,14 @@ static void ME_RTFSpecialCharHook(RTF_Info *info)
if (!info->editor->bEmulateVersion10) { /* v4.1 */
if (tableDef->tableRowStart)
{
if (tableDef->tableRowStart->member.para.nFlags & MEPF_ROWEND)
if (!info->nestingLevel &&
tableDef->tableRowStart->member.para.nFlags & MEPF_ROWEND)
{
ME_DisplayItem *para = tableDef->tableRowStart;
para = para->member.para.next_para;
para = ME_InsertTableRowStartAtParagraph(info->editor, para);
tableDef->tableRowStart = para;
info->nestingLevel = 1;
}
ME_InsertTableCellFromCursor(info->editor);
}
@ -791,6 +831,10 @@ static void ME_RTFSpecialCharHook(RTF_Info *info)
}
}
break;
case rtfNestRow:
if (info->editor->bEmulateVersion10) /* v1.0 - v3.0 */
break;
/* else fall through since v4.1 treats rtfNestRow and rtfRow the same */
case rtfRow:
{
ME_DisplayItem *para, *cell, *run;
@ -802,12 +846,14 @@ static void ME_RTFSpecialCharHook(RTF_Info *info)
if (!info->editor->bEmulateVersion10) { /* v4.1 */
if (!tableDef->tableRowStart)
break;
if (tableDef->tableRowStart->member.para.nFlags & MEPF_ROWEND)
if (!info->nestingLevel &&
tableDef->tableRowStart->member.para.nFlags & MEPF_ROWEND)
{
para = tableDef->tableRowStart;
para = para->member.para.next_para;
para = ME_InsertTableRowStartAtParagraph(info->editor, para);
tableDef->tableRowStart = para;
info->nestingLevel++;
}
para = tableDef->tableRowStart;
cell = ME_FindItemFwd(para, diCell);
@ -855,7 +901,23 @@ static void ME_RTFSpecialCharHook(RTF_Info *info)
ME_InternalDeleteText(info->editor, nOfs, nChars, TRUE);
}
tableDef->tableRowStart = ME_InsertTableRowEndFromCursor(info->editor);
para = ME_InsertTableRowEndFromCursor(info->editor);
info->nestingLevel--;
if (!info->nestingLevel)
{
if (info->canInheritInTbl) {
tableDef->tableRowStart = para;
} else {
while (info->tableDef) {
tableDef = info->tableDef;
info->tableDef = tableDef->parent;
heap_free(tableDef);
}
}
} else {
info->tableDef = tableDef->parent;
heap_free(tableDef);
}
} else { /* v1.0 - v3.0 */
WCHAR endl = '\r';
ME_DisplayItem *para = ME_GetParagraph(info->editor->pCursors[0].pRun);
@ -1276,6 +1338,8 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre
RTFSetReadHook(&parser, ME_RTFReadHook);
RTFSetDestinationCallback(&parser, rtfPict, ME_RTFReadPictGroup);
RTFSetDestinationCallback(&parser, rtfObject, ME_RTFReadObjectGroup);
if (!parser.editor->bEmulateVersion10) /* v4.1 */
RTFSetDestinationCallback(&parser, rtfNoNestTables, RTFSkipGroup);
BeginFile(&parser);
/* do the parsing */
@ -1295,8 +1359,15 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre
* By doing it this way we will have the current paragraph format set
* properly to reflect that is not in the complete table, and undo items
* will be added for this change to the current paragraph format. */
if (parser.nestingLevel > 0)
{
while (parser.nestingLevel--)
ME_RTFSpecialCharHook(&parser);
if (para->member.para.nFlags & MEPF_ROWEND)
} else if (parser.canInheritInTbl) {
ME_RTFSpecialCharHook(&parser);
}
if (parser.tableDef && parser.tableDef->tableRowStart &&
para->member.para.nFlags & MEPF_ROWEND)
{
para = para->member.para.next_para;
}

View File

@ -169,10 +169,11 @@ RTFDestroy(RTF_Info *info)
}
RTFDestroyAttrs(info);
heap_free(info->cpOutputBuffer);
if (info->tableDef)
while (info->tableDef)
{
heap_free(info->tableDef);
info->tableDef = NULL;
RTFTable *tableDef = info->tableDef;
info->tableDef = tableDef->parent;
heap_free(tableDef);
}
}
@ -244,6 +245,8 @@ void RTFInit(RTF_Info *info)
if (info->tableDef)
ZeroMemory(info->tableDef, sizeof(info->tableDef));
info->tableDef = NULL;
info->nestingLevel = 0;
info->canInheritInTbl = FALSE;
}
/*
@ -1447,6 +1450,8 @@ static RTFKey rtfKey[] =
/* is this valid? */
{ rtfSpecialChar, rtfCurHeadPict, "chpict", 0 },
{ rtfSpecialChar, rtfUnicode, "u", 0 },
{ rtfSpecialChar, rtfNestCell, "nestcell", 0 },
{ rtfSpecialChar, rtfNestRow, "nestrow", 0 },
/*
* Character formatting attributes
@ -1610,6 +1615,7 @@ static RTFKey rtfKey[] =
{ rtfParAttr, rtfDarkDiagHatchBgPat, "bgdkdcross", 0 },
{ rtfParAttr, rtfBgPatLineColor, "cfpat", 0 },
{ rtfParAttr, rtfBgPatColor, "cbpat", 0 },
{ rtfParAttr, rtfNestLevel, "itap", 0 },
/*
* Section formatting attributes
@ -1912,6 +1918,8 @@ static RTFKey rtfKey[] =
{ rtfDestination, rtfIndexRange, "rxe", 0 },
{ rtfDestination, rtfTOC, "tc", 0 },
{ rtfDestination, rtfNeXTGraphic, "NeXTGraphic", 0 },
{ rtfDestination, rtfNestTableProps, "nesttableprops", 0 },
{ rtfDestination, rtfNoNestTables, "nonesttables", 0 },
/*
* Font families

View File

@ -182,7 +182,9 @@
# define rtfTOC 72
# define rtfNeXTGraphic 73
# define rtfGenerator 74
# define rtfMaxDestination 75 /* highest dest + 1 */
# define rtfNestTableProps 75
# define rtfNoNestTables 76
# define rtfMaxDestination 77 /* highest dest + 1 */
# define rtfFontFamily 4
# define rtfFFNil 0
@ -261,6 +263,8 @@
# define rtfCurHeadPict 57 /* valid? */
/*# define rtfCurAnnot 58*/ /* apparently not used */
# define rtfUnicode 58 /* no better category*/
# define rtfNestCell 59
# define rtfNestRow 60
# define rtfStyleAttr 7
# define rtfAdditive 0 /* new in 1.10 */
@ -551,6 +555,7 @@
# define rtfDarkDiagHatchBgPat 101
# define rtfBgPatLineColor 102
# define rtfBgPatColor 103
# define rtfNestLevel 104
# define rtfCharAttr 12
# define rtfPlain 0
@ -1021,6 +1026,9 @@ struct RTFTable
* or it may store the end of the previous row if it may still be
* continued, otherwise NULL is stored. */
ME_DisplayItem *tableRowStart;
/* Table definitions are stored as a stack to support nested tables. */
RTFTable *parent;
};
/*
@ -1129,6 +1137,8 @@ struct _RTF_Info {
LPRICHEDITOLE lpRichEditOle;
RTFTable *tableDef;
int nestingLevel;
BOOL canInheritInTbl;
};

View File

@ -334,6 +334,8 @@ ME_StreamOutRTFParaProps(ME_TextEditor *editor, ME_OutStream *pStream,
if (!editor->bEmulateVersion10) { /* v4.1 */
if (pStream->nNestingLevel > 0)
strcat(props, "\\intbl");
if (pStream->nNestingLevel > 1)
sprintf(props + strlen(props), "\\itap%d", pStream->nNestingLevel);
} else { /* v1.0 - 3.0 */
if (fmt->dwMask & PFM_TABLE && fmt->wEffects & PFE_TABLE)
strcat(props, "\\intbl");
@ -715,12 +717,23 @@ ME_StreamOutRTF(ME_TextEditor *editor, ME_OutStream *pStream, int nStart, int nC
if (!editor->bEmulateVersion10) { /* v4.1 */
if (p->member.para.nFlags & MEPF_ROWSTART) {
pStream->nNestingLevel++;
if (pStream->nNestingLevel == 1) {
if (!ME_StreamOutRTFTableProps(editor, pStream, p))
return FALSE;
}
} else if (p->member.para.nFlags & MEPF_ROWEND) {
pStream->nNestingLevel--;
if (pStream->nNestingLevel > 1) {
if (!ME_StreamOutPrint(pStream, "{\\*\\nesttableprops"))
return FALSE;
if (!ME_StreamOutRTFTableProps(editor, pStream, p))
return FALSE;
if (!ME_StreamOutPrint(pStream, "\\nestrow}{\\nonesttables\\par}\r\n"))
return FALSE;
} else {
if (!ME_StreamOutPrint(pStream, "\\row \r\n"))
return FALSE;
}
} else if (!ME_StreamOutRTFParaProps(editor, pStream, p)) {
return FALSE;
}
@ -757,8 +770,13 @@ ME_StreamOutRTF(ME_TextEditor *editor, ME_OutStream *pStream, int nStart, int nC
return FALSE;
}
} else if (p->member.run.nFlags & MERF_ENDCELL) {
if (pStream->nNestingLevel > 1) {
if (!ME_StreamOutPrint(pStream, "\\nestcell "))
return FALSE;
} else {
if (!ME_StreamOutPrint(pStream, "\\cell "))
return FALSE;
}
nChars--;
} else if (p->member.run.nFlags & MERF_ENDPARA) {
if (pPara->member.para.pFmt->dwMask & PFM_TABLE &&