richedit: Added in support for streaming in and out nested tables.
This commit is contained in:
parent
300db3765f
commit
59195ed2ec
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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 &&
|
||||
|
|
Loading…
Reference in New Issue