engine/sw/qa/extras/rtfexport/data/FWDP90_min.rtf | 373 +++++++++++++
engine/sw/qa/extras/rtfexport/rtfexport7.cxx | 40 +
engine/sw/source/filter/basflt/shellio.cxx | 6
engine/sw/source/writerfilter/rtftok/rtfdispatchflag.cxx | 2
engine/sw/source/writerfilter/rtftok/rtfdispatchsymbol.cxx | 114 ++-
engine/sw/source/writerfilter/rtftok/rtfdispatchvalue.cxx | 22
engine/sw/source/writerfilter/rtftok/rtfdocumentimpl.cxx | 17
engine/sw/source/writerfilter/rtftok/rtfdocumentimpl.hxx | 76 ++
8 files changed, 558 insertions(+), 92 deletions(-)
New commits:
commit 5667f90febb0d62dc920af2c805ca54ec5238414
Author: Michael Stahl <
michae...@collabora.com>
AuthorDate: Tue Apr 21 15:33:29 2026 +0200
Commit: Miklos Vajna <
vmi...@collabora.com>
CommitDate: Wed Apr 22 10:59:37 2026 +0000
sw: RTF import: ignore spurious table properties like Word, part 2
The bugdoc has several consecutive table definitions before a table, and
the first one's borders are erroneously applied to the table cells,
instead of the last one's (no borders).
Create a new struct `TableRowDef` for the top-level table cells state,
and actually clear it on `\trowd`.
Also use it for both "backup" and "previous" table row.
Move the sending of `tblStart` from `\cellx` handling to `\par` and
`\cell` where it is determined if it is actually a table.
`m_nTopLevelCells` is redundant and can be removed.
Leave the table row properties as-is for now, could be added to
`TableRowDef` later...
Unfortunately UITest_sw_table sheetToTable.sheetToTable.test_tdf116685
fails with `~SwIndexReg` assert.
This is because previously, `tblStart` was sent from `\cellx`, and in
`DomainMapper::sprmWithProps()` the `rContext` did not exist yet, so
the whole `AddDummyParaForTableInSection` was skipped; now it is done
and the `pUndoPam` in `SwReader::Read()` points to the deleted node.
Change-Id: Iba60e871e6c3ac0bc2559c975358edc14a7e2d6b
Reviewed-on:
https://gerrit.collaboraoffice.com/c/online/+/1331
diff --git a/engine/sw/qa/extras/rtfexport/data/FWDP90_min.rtf b/engine/sw/qa/extras/rtfexport/data/FWDP90_min.rtf
new file mode 100644
index 000000000000..41e28f78b58d
--- /dev/null
+++ b/engine/sw/qa/extras/rtfexport/data/FWDP90_min.rtf
@@ -0,0 +1,373 @@
+{\rtf1\ansi\deff0\adeff0
+{\fonttbl{\f0\fbidi\froman\fcharset0\fprq2
+{\*\panose 02020603050405020304}
+{\*\falt Times New Roman}
+Times New Roman;}{\f41\fbidi\fswiss\fcharset0\fprq2
+{\*\panose 020b0604030504040204}
+{\*\falt Times New Roman}
+Tahoma;}{\f42\fbidi\fswiss\fcharset0\fprq2
+{\*\panose 020b0502040204020203}
+Segoe UI;}}
+{\colortbl;\red0\green0\blue0;\red0\green0\blue255;\red0\green255\blue255;
+\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255
+\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0
+\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128
+\green0\blue0;\red128\green128\blue0;\red128\green128\blue128;\red192
+\green192\blue192;\red153\green0\blue0;\red51\green153\blue102;\red255
+\green255\blue255;}
+\adeflang1025\ansicpg1252\stshfdbch0\stshfloch0\stshfhich0
+\stshfbi0\deflang3079\deflangfe3079\themelang3079\themelangfe0\themelangcs0
+{\*\defchp\fs22}
+{\*\defpap\ql\li0\ri0\sa160\sl259\slmult1\widctlpar\wrapdefault\aspalpha
+\aspnum\faauto\adjustright\rin0\lin0\itap0}
+{\stylesheet{\ql\li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto
+\adjustright\rin0\lin0\itap0\rtlch\fcs1\af0\afs24\alang1025\ltrch\fcs0\fs24
+\lang3079\langfe3079\cgrid\langnp3079\langfenp3079\snext0\sqformat
+\spriority0 Normal;}
+{\*\cs10\additive\ssemihidden Default Paragraph Font;}
+{\*\ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3
+\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tblind0\tblindtype3\tsvertalt
+\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv\ql\li0
+\ri0\sa160\sl259\slmult1\widctlpar\wrapdefault\aspalpha\aspnum\faauto
+\adjustright\rin0\lin0\itap0\rtlch\fcs1\af0\afs22\alang1025\ltrch\fcs0\fs22
+\lang3079\langfe3079\cgrid\langnp3079\langfenp3079\snext11\ssemihidden
+\sunhideused Normal Table;}
+{\*\ts15\tsrowd\trbrdrt\brdrs\brdrw10\trbrdrl\brdrs\brdrw10\trbrdrb\brdrs
+\brdrw10\trbrdrr\brdrs\brdrw10\trbrdrh\brdrs\brdrw10\trbrdrv\brdrs\brdrw10
+\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3
+\trcbpat1\trcfpat1\tblind0\tblindtype0\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb
+\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv\ql\li0\ri0\widctlpar
+\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\rtlch\fcs1
+\af0\afs20\alang1025\ltrch\fcs0\fs20\lang3079\langfe3079\cgrid\langnp3079
+\langfenp3079\sbasedon11\snext15 Table Grid;}
+{\s16\ql\li0\ri0\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright
+\rin0\lin0\itap0\rtlch\fcs1\af41\afs16\alang1025\ltrch\fcs0\f41\fs16
+\lang3079\langfe3079\cgrid\langnp3079\langfenp3079\sbasedon0\snext16
+\slink18\ssemihidden Balloon Text;}{\s17\ql\li0\ri0
+\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0
+\cbpat9\rtlch\fcs1\af41\afs20\alang1025\ltrch\fcs0\f41\fs20\lang3079
+\langfe3079\cgrid\langnp3079\langfenp3079\sbasedon0\snext17\slink20
+\ssemihidden Document Map;}
+{\*\cs18\additive\rtlch\fcs1\af42\afs18\ltrch\fcs0\f42\fs18\sbasedon10
+\slink16\slocked\ssemihidden Balloon Text Char;}
+{\*\cs19\additive\rtlch\fcs1\af0\ltrch\fcs0\cf17\sbasedon10
+t1;}
+{\*\cs20\additive\rtlch\fcs1\af42\afs16\ltrch\fcs0\f42\fs16\sbasedon10
+\slink17\slocked\ssemihidden Document Map Char;}
+{\s21\ql\li0\ri0\widctlpar\tqc\tx4536\tqr\tx9072\wrapdefault\aspalpha
+\aspnum\faauto\adjustright\rin0\lin0\itap0\rtlch\fcs1\af0\afs24\alang1025
+\ltrch\fcs0\fs24\lang3079\langfe3079\cgrid\langnp3079\langfenp3079
+\sbasedon0\snext21\slink23 header;}{\s22\ql\li0\ri0\widctlpar
+\tqc\tx4536\tqr\tx9072\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0
+\lin0\itap0\rtlch\fcs1\af0\afs24\alang1025\ltrch\fcs0\fs24\lang3079
+\langfe3079\cgrid\langnp3079\langfenp3079\sbasedon0\snext22\slink25
+ footer;}
+{\*\cs23\additive\rtlch\fcs1\af0\afs24\ltrch\fcs0\fs24\sbasedon10\slink21
+\slocked\ssemihidden Header Char;}
+{\*\cs24\additive\rtlch\fcs1\ab\af0\ltrch\fcs0\b\sbasedon10
+tx1;}
+{\*\cs25\additive\rtlch\fcs1\af0\afs24\ltrch\fcs0\fs24\sbasedon10\slink22
+\slocked\ssemihidden Footer Char;}
+}
+{\*\revtbl Unknown;}
+\paperw16838\paperh11906\margl567\margr567\margt567\margb567\gutter0
+\deftab709\widowctrl\ftnbj\aenddoc\hyphhotz425\trackmoves0\trackformatting1
+\donotembedsysfont0\relyonvml0\donotembedlingdata1\grfdocevents0
+\validatexml0\showplaceholdtext0\ignoremixedcontent0\saveinvalidxml0
+\showxmlerrors0\noxlattoyen\expshrtn\noultrlspc\dntblnsbdb\nospaceforul
+\hyphcaps0\formshade\horzdoc\dgmargin\dghspace180\dgvspace180\dghorigin567
+\dgvorigin567\dghshow1\dgvshow1\jexpand\viewkind1\viewscale100\splytwnine
+\ftnlytwnine\nolnhtadjtbl\useltbaln\alntblind\lytcalctblwd\lyttblrtgr
+\lnbrkrule\nobrkwrptbl\snaptogridincell\allowfieldendsel\wrppunct
+\asianbrkrule\rsidroot4195955\newtblstyruls\nogrowautofit\usenormstyforlist
+\noindnmbrts\felnbrelev\nocxsptable\indrlsweleven\noafcnsttbl\afelev\utinl
+\hwelev\spltpgpar\notcvasp\notbrkcnstfrctbl\notvatxbx\krnprsnet
+\cachedcolbal\nouicompat\fet0
+{\*\wgrffmtfilter 013f}
+\nofeaturethrottle1\ilfomacatclnup0
+{\*\ftnsep\ltrpar\pard\plain\ltrpar\ql\li0\ri0\widctlpar\wrapdefault
+\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\rtlch\fcs1\af0\afs24
+\alang1025\ltrch\fcs0\fs24\lang3079\langfe3079\cgrid\langnp3079
+\langfenp3079{\rtlch\fcs1\af0\ltrch\fcs0\chftnsep\par
+}}
+{\*\ftnsepc\ltrpar\pard\plain\ltrpar\ql\li0\ri0\widctlpar\wrapdefault
+\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\rtlch\fcs1\af0\afs24
+\alang1025\ltrch\fcs0\fs24\lang3079\langfe3079\cgrid\langnp3079
+\langfenp3079{\rtlch\fcs1\af0\ltrch\fcs0\chftnsepc\par
+}}
+{\*\aftnsep\ltrpar\pard\plain\ltrpar\ql\li0\ri0\widctlpar\wrapdefault
+\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\rtlch\fcs1\af0\afs24
+\alang1025\ltrch\fcs0\fs24\lang3079\langfe3079\cgrid\langnp3079
+\langfenp3079{\rtlch\fcs1\af0\ltrch\fcs0\chftnsep\par
+}}
+{\*\aftnsepc\ltrpar\pard\plain\ltrpar\ql\li0\ri0\widctlpar\wrapdefault
+\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0\rtlch\fcs1\af0\afs24
+\alang1025\ltrch\fcs0\fs24\lang3079\langfe3079\cgrid\langnp3079
+\langfenp3079{\rtlch\fcs1\af0\ltrch\fcs0\chftnsepc\par
+}}
+{\*\generator CIB merge 3.9.184}
+\uc1\noqfpromote{\mmathPr\mmathFont34\mbrkBin0\mbrkBinSub0\msmallFrac0
+\mdispDef1\mlMargin0\mrMargin0\mdefJc1\mwrapIndent1440\mintLim0\mnaryLim1}
+{\*\xmlnstbl{\xmlns1
http://schemas.microsoft.com/office/word/2003/wordml}}
+\ltrsect\pgbrdrhead\pgbrdrfoot
+
+\ltrpar\sectd\ltrsect\lndscpsxn
+\psz9\linex0\headery709\footery709\colsx708\endnhere\pgbrdropt32
+\sectlinegrid360\sectdefaultcl\sftnbj
+{\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang
+{\pntxta.}}
+{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang
+{\pntxta.}}
+{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang
+{\pntxta.}}
+{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang
+{\pntxta)}}
+{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang
+{\pntxtb(}
+{\pntxta)}}
+{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang
+{\pntxtb(}
+{\pntxta)}}
+{\*\pnseclvl7\pnlcrm\pnstart1\pnindent720\pnhang
+{\pntxtb(}
+{\pntxta)}}
+{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang
+{\pntxtb(}
+{\pntxta)}}
+{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang
+{\pntxtb(}
+{\pntxta)}}\pard\plain\ltrpar\ql\li0\ri0\widctlpar\wrapdefault\aspalpha
+\aspnum\faauto\adjustright\rin0\lin0\itap0\rtlch\fcs1\af0
+\afs24\alang1025\ltrch\fcs0\fs24\lang3079\langfe3079\cgrid\langnp3079
+\langfenp3079\sectd\ltrsect\lndscpsxn\psz9\linex0\headery709\footery709
+\colsx708\endnhere\pgbrdropt32\sectlinegrid360\sectdefaultcl
+\sftnbj{\rtlch\fcs1\af0\afs18\ltrch\fcs0\v\fs18
+\line
+}\sectd\ltrsect\lndscpsxn\psz9\linex0\headery709\footery709\colsx708
+\endnhere\pgbrdropt32\sectlinegrid360\sectdefaultcl\sftnbj
+{\rtlch\fcs1\af0\afs18\ltrch\fcs0\v\fs18
+\line
+}\sectd\ltrsect\lndscpsxn\psz9\linex0\headery709\footery709\colsx708
+\endnhere\pgbrdropt32\sectlinegrid360\sectdefaultcl\sftnbj
+{\rtlch\fcs1\af0\afs18\ltrch\fcs0\v\fs18
+\line
+}\sectd\ltrsect\lndscpsxn\psz9\linex0\headery709\footery709\colsx708
+\endnhere\pgbrdropt32\sectlinegrid360\sectdefaultcl\sftnbj
+{\rtlch\fcs1\af0\afs18\ltrch\fcs0\v\fs18
+\line
+}\sectd\ltrsect\lndscpsxn\psz9\linex0\headery709\footery709\colsx708
+\endnhere\pgbrdropt32\sectlinegrid360\sectdefaultcl\sftnbj
+{\rtlch\fcs1\af0\afs18\ltrch\fcs0\v\fs18\line
+}\sectd\ltrsect\lndscpsxn\psz9\linex0\headery709\footery709\colsx708
+\endnhere\pgbrdropt32\sectlinegrid360\sectdefaultcl\sftnbj
+{\rtlch\fcs1\af0\afs18\ltrch\fcs0\v\fs18\line
+}\sectd\ltrsect\lndscpsxn\psz9\linex0\headery709\footery709\colsx708
+\endnhere\pgbrdropt32\sectlinegrid360\sectdefaultcl\sftnbj
+{\rtlch\fcs1\af0\afs18\ltrch\fcs0\v\fs18\line
+}\sectd\ltrsect\lndscpsxn\psz9\linex0\headery709\footery709\colsx708
+\endnhere\pgbrdropt32\sectlinegrid360\sectdefaultcl\sftnbj
+{\rtlch\fcs1\af0\afs18\ltrch\fcs0\v\fs18
+\line
+}\sectd\ltrsect\lndscpsxn\psz9\linex0\headery709\footery709\colsx708
+\endnhere\pgbrdropt32\sectlinegrid360\sectdefaultcl\sftnbj
+{\rtlch\fcs1\af0\afs18\ltrch\fcs0\v\fs18\par
+}
+{\sectd\ltrsect\lndscpsxn\psz9\linex0\headery709\footery709\colsx708
+\endnhere\pgbrdropt32\sectlinegrid360\sectdefaultcl\sftnbj
+\sectd\ltrsect\lndscpsxn\psz9\linex0\headery709\footery709\colsx708
+\endnhere\pgbrdropt32\sectlinegrid360\sectdefaultcl\sftnbj
+\sectd\ltrsect\lndscpsxn\psz9\linex0\headery709\footery709\colsx708
+\endnhere\pgbrdropt32\sectlinegrid360\sectdefaultcl\sftnbj
+{\sectd\ltrsect\lndscpsxn\psz9\linex0\headery709\footery709\colsx708
+\endnhere\pgbrdropt32\sectlinegrid360\sectdefaultcl\sftnbj
+\trowd\ltrrow\ts15\trgaph70\trleft-70\trbrdrt\brdrs\brdrw10\trbrdrl\brdrs
+\brdrw10\trbrdrb\brdrs\brdrw10\trbrdrr\brdrs\brdrw10\trbrdrh\brdrs\brdrw10
+\trbrdrv\brdrs\brdrw10\trftsWidth1\trftsWidthB3\trftsWidthA3\trautofit1
+\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1
+\trcfpat1\tbllkhdrrows\tbllklastrow\tbllkhdrcols
+\tbllklastcol\tblind38\tblindtype3\clvertalt\clbrdrt\brdrs\brdrw10\clbrdrl
+\brdrs\brdrw10\clbrdrb\brdrs\brdrw10\clbrdrr\brdrs\brdrw10\clcfpat1
+\clcbpat8\cltxlrtb\clftsWidth3\clwWidth2279\clcbpatraw8\clcfpatraw1
+\cellx2209\clvertalt\clbrdrt\brdrs\brdrw10\clbrdrl\brdrs\brdrw10\clbrdrb
+\brdrs\brdrw10\clbrdrr\brdrs\brdrw10\clcfpat1\clcbpat8\cltxlrtb\clftsWidth3
+\clwWidth1372\clcbpatraw8\clcfpatraw1\cellx3581\clvertalt\clbrdrt\brdrs
+\brdrw10\clbrdrl\brdrs\brdrw10\clbrdrb\brdrs\brdrw10\clbrdrr\brdrs\brdrw10
+\clcfpat1\clcbpat8\cltxlrtb\clftsWidth3\clwWidth1372\clcbpatraw8
+\clcfpatraw1\cellx4953\pard\plain\ltrpar\ql\li0\ri0\keep\nowidctlpar\intbl
+\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0
+\yts15\rtlch\fcs1\af0\afs24\alang1025\ltrch\fcs0\fs24\lang3079\langfe3079
+\cgrid\langnp3079\langfenp3079\pard\plain\ltrpar\ql\li0\ri0\sa160\sl259
+\slmult1\widctlpar\intbl\wrapdefault\aspalpha\aspnum\faauto\adjustright
+\rin0\lin0\rtlch\fcs1\af0\afs24\alang1025\ltrch\fcs0\fs24\lang3079
+\langfe3079\cgrid\langnp3079\langfenp3079\trowd\ltrrow\ts15\trgaph70
+\trleft-70\trbrdrt\brdrs\brdrw10\trbrdrl\brdrs\brdrw10\trbrdrb\brdrs
+\brdrw10\trbrdrr\brdrs\brdrw10\trbrdrh\brdrs\brdrw10\trbrdrv\brdrs\brdrw10
+\trftsWidth1\trftsWidthB3\trftsWidthA3\trautofit1\trpaddl108\trpaddr108
+\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1
+\tbllkhdrrows\tbllklastrow\tbllkhdrcols\tbllklastcol\tblind38\tblindtype3
+\clvertalt\clbrdrt\brdrs\brdrw10\clbrdrl\brdrs\brdrw10\clbrdrb\brdrnone
+\clbrdrr\brdrs\brdrw10\clcfpat1\clcbpat8\cltxlrtb\clftsWidth3\clwWidth2279
+\clcbpatraw8\clcfpatraw1\cellx2209\clvertalt\clbrdrt\brdrs\brdrw10\clbrdrl
+\brdrs\brdrw10\clbrdrb\brdrnone\clbrdrr\brdrs\brdrw10\clcfpat1\clcbpat8
+\cltxlrtb\clftsWidth3\clwWidth1372\clcbpatraw8\clcfpatraw1\cellx3581
+\clvertalt\clbrdrt\brdrs\brdrw10\clbrdrl\brdrs\brdrw10\clbrdrb\brdrnone
+\clbrdrr\brdrs\brdrw10\clcfpat1\clcbpat8\cltxlrtb\clftsWidth3\clwWidth1372
+\clcbpatraw8\clcfpatraw1\cellx4953\pard\plain\ltrpar\ql\li0\ri0\keep
+\nowidctlpar\intbl\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0
+\yts15\rtlch\fcs1\af0\afs24\alang1025\ltrch\fcs0\fs24
+\lang3079\langfe3079\cgrid\langnp3079\langfenp3079\pard\ltrpar\qr\li0\ri0
+\keep\nowidctlpar\intbl\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0
+\lin0\yts15\sectd\ltrsect\lndscpsxn\psz9\linex0\headery709
+\footery709\colsx708\endnhere\pgbrdropt32\sectlinegrid360\sectdefaultcl
+\sftnbj\sectd\ltrsect\lndscpsxn\psz9\linex0\headery709
+\footery709\colsx708\endnhere\pgbrdropt32\sectlinegrid360\sectdefaultcl
+\sftnbj\pard\plain\ltrpar\ql\li0\ri0\sa160\sl259\slmult1
+\widctlpar\intbl\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0
+\rtlch\fcs1\af0\afs24\alang1025\ltrch\fcs0\fs24\lang3079\langfe3079\cgrid
+\langnp3079\langfenp3079\trowd\ltrrow\ts15\trgaph70\trleft-70\trbrdrt\brdrs
+\brdrw10\trbrdrl\brdrs\brdrw10\trbrdrb\brdrs\brdrw10\trbrdrr\brdrs\brdrw10
+\trbrdrh\brdrs\brdrw10\trbrdrv\brdrs\brdrw10\trftsWidth1\trftsWidthB3
+\trftsWidthA3\trautofit1\trpaddl108\trpaddr108\trpaddfl3\trpaddft3
+\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tbllkhdrrows
+\tbllklastrow\tbllkhdrcols\tbllklastcol\tblind38\tblindtype3\clvertalt
+\clbrdrt\brdrnone\clbrdrl\brdrnone\clbrdrb\brdrnone\clbrdrr\brdrnone
+\clcfpat1\clcbpat8\cltxlrtb\clftsWidth3\clwWidth2279\clcbpatraw8
+\clcfpatraw1\cellx2209\clvertalt\clbrdrt\brdrnone\clbrdrl\brdrnone\clbrdrb
+\brdrnone\clbrdrr\brdrnone\clcfpat1\clcbpat8\cltxlrtb\clftsWidth3
+\clwWidth1372\clcbpatraw8\clcfpatraw1\cellx3581\clvertalt\clbrdrt\brdrnone
+\clbrdrl\brdrnone\clbrdrb\brdrnone\clbrdrr\brdrnone\clcfpat1\clcbpat8
+\cltxlrtb\clftsWidth3\clwWidth1372\clcbpatraw8\clcfpatraw1\cellx4953\pard
+\plain\ltrpar\ql\li0\ri0\keep\nowidctlpar\intbl\wrapdefault\aspalpha\aspnum
+\faauto\adjustright\rin0\lin0\yts15\rtlch\fcs1\af0\afs24
+\alang1025\ltrch\fcs0\fs24\lang3079\langfe3079\cgrid\langnp3079
+\langfenp3079\pard\ltrpar\qr\li0\ri0\keep\nowidctlpar\intbl\wrapdefault
+\aspalpha\aspnum\faauto\adjustright\rin0\lin0\yts15\sectd
+\ltrsect\lndscpsxn\psz9\linex0\headery709\footery709\colsx708\endnhere
+\pgbrdropt32\sectlinegrid360\sectdefaultcl\sftnbj\sectd
+\ltrsect\lndscpsxn\psz9\linex0\headery709\footery709\colsx708\endnhere
+\pgbrdropt32\sectlinegrid360\sectdefaultcl\sftnbj\pard
+\plain\ltrpar\ql\li0\ri0\sa160\sl259\slmult1\widctlpar\intbl\wrapdefault
+\aspalpha\aspnum\faauto\adjustright\rin0\lin0\rtlch\fcs1\af0\afs24
+\alang1025\ltrch\fcs0\fs24\lang3079\langfe3079\cgrid\langnp3079
+\langfenp3079\pard\plain\ltrpar\ql\li0\ri0\keep\nowidctlpar\intbl
+\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0
+\yts15\rtlch\fcs1\af0\afs24\alang1025\ltrch\fcs0\fs24\lang3079\langfe3079
+\cgrid\langnp3079\langfenp3079\pard\ltrpar\qr\li0\ri0\keep\nowidctlpar
+\intbl\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0
+\yts15\sectd\ltrsect\lndscpsxn\psz9\linex0\headery709
+\footery709\colsx708\endnhere\pgbrdropt32\sectlinegrid360\sectdefaultcl
+\sftnbj\sectd\ltrsect\lndscpsxn\psz9\linex0\headery709
+\footery709\colsx708\endnhere\pgbrdropt32\sectlinegrid360\sectdefaultcl
+\sftnbj\pard\plain\ltrpar\ql\li0\ri0\sa160\sl259\slmult1
+\widctlpar\intbl\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0
+\rtlch\fcs1\af0\afs24\alang1025\ltrch\fcs0\fs24\lang3079\langfe3079\cgrid
+\langnp3079\langfenp3079\pard\plain\ltrpar\ql\li0\ri0\keep\nowidctlpar
+\intbl\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0
+\yts15\rtlch\fcs1\af0\afs24\alang1025\ltrch\fcs0\fs24
+\lang3079\langfe3079\cgrid\langnp3079\langfenp3079\pard\ltrpar\qr\li0\ri0
+\keep\nowidctlpar\intbl\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0
+\lin0\yts15\sectd\ltrsect\lndscpsxn\psz9\linex0\headery709
+\footery709\colsx708\endnhere\pgbrdropt32\sectlinegrid360\sectdefaultcl
+\sftnbj\sectd\ltrsect\lndscpsxn\psz9\linex0\headery709
+\footery709\colsx708\endnhere\pgbrdropt32\sectlinegrid360\sectdefaultcl
+\sftnbj\pard\plain\ltrpar\ql\li0\ri0\sa160\sl259\slmult1
+\widctlpar\intbl\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0
+\rtlch\fcs1\af0\afs24\alang1025\ltrch\fcs0\fs24\lang3079\langfe3079\cgrid
+\langnp3079\langfenp3079\pard\plain\ltrpar\ql\li0\ri0\keep\nowidctlpar
+\intbl\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0
+\yts15\rtlch\fcs1\af0\afs24\alang1025\ltrch\fcs0\fs24
+\lang3079\langfe3079\cgrid\langnp3079\langfenp3079\pard\ltrpar\qr\li0\ri0
+\keep\nowidctlpar\intbl\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0
+\lin0\yts15\pard\plain\ltrpar\ql\li0\ri0\sa160\sl259
+\slmult1\widctlpar\intbl\wrapdefault\aspalpha\aspnum\faauto\adjustright
+\rin0\lin0\rtlch\fcs1\af0\afs24\alang1025\ltrch\fcs0\fs24\lang3079
+\langfe3079\cgrid\langnp3079\langfenp3079\pard\plain\ltrpar\ql\li0\ri0\keep
+\nowidctlpar\intbl\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0
+\yts15\rtlch\fcs1\af0\afs24\alang1025\ltrch\fcs0\fs24
+\lang3079\langfe3079\cgrid\langnp3079\langfenp3079\pard\ltrpar\qr\li0\ri0
+\keep\nowidctlpar\intbl\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0
+\lin0\yts15\sectd\ltrsect\lndscpsxn\psz9\linex0\headery709
+\footery709\colsx708\endnhere\pgbrdropt32\sectlinegrid360\sectdefaultcl
+\sftnbj\sectd\ltrsect\lndscpsxn\psz9\linex0\headery709
+\footery709\colsx708\endnhere\pgbrdropt32\sectlinegrid360\sectdefaultcl
+\sftnbj\pard\plain\ltrpar\ql\li0\ri0\sa160\sl259\slmult1
+\widctlpar\intbl\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0
+\rtlch\fcs1\af0\afs24\alang1025\ltrch\fcs0\fs24\lang3079\langfe3079\cgrid
+\langnp3079\langfenp3079\pard\plain\ltrpar\ql\li0\ri0\keep\nowidctlpar
+\intbl\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0
+\yts15\rtlch\fcs1\af0\afs24\alang1025\ltrch\fcs0\fs24
+\lang3079\langfe3079\cgrid\langnp3079\langfenp3079\sectd\ltrsect\lndscpsxn
+\psz9\linex0\headery709\footery709\colsx708\endnhere\pgbrdropt32
+\sectlinegrid360\sectdefaultcl\sftnbj\pard\ltrpar\qr\li0
+\ri0\keep\nowidctlpar\intbl\wrapdefault\aspalpha\aspnum\faauto\adjustright
+\rin0\lin0\yts15\sectd\ltrsect\lndscpsxn\psz9\linex0
+\headery709\footery709\colsx708\endnhere\pgbrdropt32\sectlinegrid360
+\sectdefaultcl\sftnbj\sectd\ltrsect\lndscpsxn\psz9\linex0
+\headery709\footery709\colsx708\endnhere\pgbrdropt32\sectlinegrid360
+\sectdefaultcl\sftnbj\pard\plain\ltrpar\ql\li0\ri0\sa160
+\sl259\slmult1\widctlpar\intbl\wrapdefault\aspalpha\aspnum\faauto
+\adjustright\rin0\lin0\rtlch\fcs1\af0\afs24\alang1025\ltrch\fcs0\fs24
+\lang3079\langfe3079\cgrid\langnp3079\langfenp3079\pard\plain\ltrpar\ql\li0
+\ri0\keep\nowidctlpar\intbl\wrapdefault\aspalpha\aspnum\faauto\adjustright
+\rin0\lin0\yts15\rtlch\fcs1\af0\afs24\alang1025\ltrch\fcs0
+\fs24\lang3079\langfe3079\cgrid\langnp3079\langfenp3079\pard\ltrpar\qr\li0
+\ri0\keep\nowidctlpar\intbl\wrapdefault\aspalpha\aspnum\faauto\adjustright
+\rin0\lin0\yts15\sectd\ltrsect\lndscpsxn\psz9\linex0
+\headery709\footery709\colsx708\endnhere\pgbrdropt32\sectlinegrid360
+\sectdefaultcl\sftnbj\sectd\ltrsect\lndscpsxn\psz9\linex0
+\headery709\footery709\colsx708\endnhere\pgbrdropt32\sectlinegrid360
+\sectdefaultcl\sftnbj\pard\plain\ltrpar\ql\li0\ri0\sa160
+\sl259\slmult1\widctlpar\intbl\wrapdefault\aspalpha\aspnum\faauto
+\adjustright\rin0\lin0\rtlch\fcs1\af0\afs24\alang1025\ltrch\fcs0\fs24
+\lang3079\langfe3079\cgrid\langnp3079\langfenp3079\pard\ltrpar\ql\li0\ri0
+\widctlpar\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0
+{\sectd\ltrsect\lndscpsxn\psz9\linex0\headery709
+\footery709\colsx708\endnhere\pgbrdropt32\sectlinegrid360\sectdefaultcl
+\sftnbj{\rtlch\fcs1\af0\afs18\ltrch\fcs0\fs18\cf1
+\par
+}\trowd\ltrrow\ts15\trgaph70\trleft-70\trbrdrt\brdrs\brdrw10\trbrdrl\brdrs
+\brdrw10\trbrdrb\brdrs\brdrw10\trbrdrr\brdrs\brdrw10\trbrdrh\brdrs\brdrw10
+\trbrdrv\brdrs\brdrw10\trftsWidth1\trftsWidthB3\trftsWidthA3\trautofit1
+\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1
+\trcfpat1\tbllkhdrrows\tbllklastrow\tbllkhdrcols
+\tbllklastcol\tblind38\tblindtype3\clvertalt\clbrdrt\brdrnone\clbrdrl
+\brdrnone\clbrdrb\brdrnone\clbrdrr\brdrnone\clcfpat1\clcbpat8\cltxlrtb
+\clftsWidth3\clwWidth2279\clcbpatraw8\clcfpatraw1\cellx2209\clvertalt
+\clbrdrt\brdrnone\clbrdrl\brdrnone\clbrdrb\brdrnone\clbrdrr\brdrnone
+\clcfpat1\clcbpat8\cltxlrtb\clftsWidth3\clwWidth1372\clcbpatraw8
+\clcfpatraw1\cellx3581\pard\plain\ltrpar\ql\li0\ri0\keep\nowidctlpar\intbl
+\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0
+\yts15\rtlch\fcs1\af0\afs24\alang1025\ltrch\fcs0\fs24\lang3079\langfe3079
+\cgrid\langnp3079\langfenp3079{\rtlch\fcs1\af0\afs18\ltrch\fcs0\fs18\cf1
+ Einkommen der letzten\cell
+3 Monate\cell
+}\pard\plain\ltrpar\ql\li0\ri0\sa160\sl259\slmult1\widctlpar\intbl
+\wrapdefault\aspalpha\aspnum\faauto\adjustright\rin0\lin0\rtlch\fcs1\af0
+\afs24\alang1025\ltrch\fcs0\fs24\lang3079\langfe3079\cgrid\langnp3079
+\langfenp3079{\rtlch\fcs1\af0\afs18\ltrch\fcs0\fs18\cf1
+\trowd\ltrrow\ts15\trgaph70\trleft-70\trbrdrt\brdrs\brdrw10
+\trbrdrl\brdrs\brdrw10\trbrdrb\brdrs\brdrw10\trbrdrr\brdrs\brdrw10\trbrdrh
+\brdrs\brdrw10\trbrdrv\brdrs\brdrw10\trftsWidth1\trftsWidthB3\trftsWidthA3
+\trautofit1\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3
+\trcbpat1\trcfpat1\tbllkhdrrows\tbllklastrow\tbllkhdrcols
+\tbllklastcol\tblind38\tblindtype3\clvertalt\clbrdrt\brdrnone\clbrdrl
+\brdrnone\clbrdrb\brdrnone\clbrdrr\brdrnone\clcfpat1\clcbpat8\cltxlrtb
+\clftsWidth3\clwWidth2279\clcbpatraw8\clcfpatraw1\cellx2209\clvertalt
+\clbrdrt\brdrnone\clbrdrl\brdrnone\clbrdrb\brdrnone\clbrdrr\brdrnone
+\clcfpat1\clcbpat8\cltxlrtb\clftsWidth3\clwWidth1372\clcbpatraw8
+\clcfpatraw1\cellx3581\row
+}
+}
+}}
+\sectd\ltrsect\lndscpsxn\psz9\linex0\headery709\footery709\colsx708
+\endnhere\pgbrdropt32\sectlinegrid360\sectdefaultcl\sftnbj
+\sectd\ltrsect\lndscpsxn\psz9\linex0\headery709\footery709\colsx708
+\endnhere\pgbrdropt32\sectlinegrid360\sectdefaultcl\sftnbj
+{\rtlch\fcs1\af0\afs18\ltrch\fcs0\v\fs18
+\line
+}}
+\sectd\ltrsect\lndscpsxn\linex0\headery709\footery709\colsx708\endnhere
+\pgbrdropt32\sectlinegrid360\sectdefaultcl\sftnbj{\rtlch
+\fcs1\af0\afs18\ltrch\fcs0\v\fs18\par
+}
+}
diff --git a/engine/sw/qa/extras/rtfexport/rtfexport7.cxx b/engine/sw/qa/extras/rtfexport/rtfexport7.cxx
index fe0fcf47e1b0..6b1e841f5720 100644
--- a/engine/sw/qa/extras/rtfexport/rtfexport7.cxx
+++ b/engine/sw/qa/extras/rtfexport/rtfexport7.cxx
@@ -888,6 +888,46 @@ CPPUNIT_TEST_FIXTURE(Test, testItapIntblCell)
verify("reload");
}
+CPPUNIT_TEST_FIXTURE(Test, testIgnoreTableDefinitionBorders)
+{
+ createSwDoc("FWDP90_min.rtf");
+
+ auto verify = [this]() {
+ uno::Reference<text::XTextTable> xTable{ getParagraphOrTable(3), uno::UNO_QUERY };
+ uno::Reference<text::XTextRange> xA1(xTable->getCellByName(u"A1"_ustr), uno::UNO_QUERY);
+ // problem was that the cells had borders from an unused table definition
+ CPPUNIT_ASSERT_BORDER_EQUAL(
+ table::BorderLine2(0x000000, 0, 0, 0, table::BorderLineStyle::NONE, 0),
+ getProperty<table::BorderLine2>(xA1, u"TopBorder"_ustr));
+ CPPUNIT_ASSERT_BORDER_EQUAL(
+ table::BorderLine2(0x000000, 0, 0, 0, table::BorderLineStyle::NONE, 0),
+ getProperty<table::BorderLine2>(xA1, u"BottomBorder"_ustr));
+ CPPUNIT_ASSERT_BORDER_EQUAL(
+ table::BorderLine2(0x000000, 0, 0, 0, table::BorderLineStyle::NONE, 0),
+ getProperty<table::BorderLine2>(xA1, u"LeftBorder"_ustr));
+ CPPUNIT_ASSERT_BORDER_EQUAL(
+ table::BorderLine2(0x000000, 0, 0, 0, table::BorderLineStyle::NONE, 0),
+ getProperty<table::BorderLine2>(xA1, u"RightBorder"_ustr));
+ uno::Reference<text::XTextRange> xB1(xTable->getCellByName(u"B1"_ustr), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_BORDER_EQUAL(
+ table::BorderLine2(0x000000, 0, 0, 0, table::BorderLineStyle::NONE, 0),
+ getProperty<table::BorderLine2>(xB1, u"TopBorder"_ustr));
+ CPPUNIT_ASSERT_BORDER_EQUAL(
+ table::BorderLine2(0x000000, 0, 0, 0, table::BorderLineStyle::NONE, 0),
+ getProperty<table::BorderLine2>(xB1, u"BottomBorder"_ustr));
+ CPPUNIT_ASSERT_BORDER_EQUAL(
+ table::BorderLine2(0x000000, 0, 0, 0, table::BorderLineStyle::NONE, 0),
+ getProperty<table::BorderLine2>(xB1, u"LeftBorder"_ustr));
+ CPPUNIT_ASSERT_BORDER_EQUAL(
+ table::BorderLine2(0x000000, 0, 0, 0, table::BorderLineStyle::NONE, 0),
+ getProperty<table::BorderLine2>(xB1, u"RightBorder"_ustr));
+ };
+
+ verify();
+ saveAndReload(TestFilter::RTF);
+ verify();
+}
+
CPPUNIT_TEST_FIXTURE(Test, testTdf113550)
{
auto verify = [this]() {
diff --git a/engine/sw/source/filter/basflt/shellio.cxx b/engine/sw/source/filter/basflt/shellio.cxx
index 419cb5ae915e..3cca73aef383 100644
--- a/engine/sw/source/filter/basflt/shellio.cxx
+++ b/engine/sw/source/filter/basflt/shellio.cxx
@@ -178,12 +178,14 @@ ErrCodeMsg SwReader::Read( const Reader& rOptions )
mxDoc->getIDocumentRedlineAccess().SetRedlineFlags_intern( RedlineFlags::Ignore );
- std::optional<SwPaM> pUndoPam;
+ ::std::shared_ptr<SwUnoCursor> pUndoPam;
if( bDocUndo || mpCursor )
{
// set Pam to the previous node, so that it is not also moved
const SwNode& rTmp = pPam->GetPoint()->GetNode();
- pUndoPam.emplace( rTmp, rTmp, SwNodeOffset(0), SwNodeOffset(-1) );
+ pUndoPam = mxDoc->CreateUnoCursor(*pPam->GetPoint(), false);
+ pUndoPam->SetMark();
+ *pUndoPam->GetPoint() = SwPosition(rTmp, SwNodeOffset(-1));
}
// store for now all Fly's
diff --git a/engine/sw/source/writerfilter/rtftok/rtfdispatchflag.cxx b/engine/sw/source/writerfilter/rtftok/rtfdispatchflag.cxx
index 6b1165972db4..2ea1670e46a2 100644
--- a/engine/sw/source/writerfilter/rtftok/rtfdispatchflag.cxx
+++ b/engine/sw/source/writerfilter/rtftok/rtfdispatchflag.cxx
@@ -590,7 +590,7 @@ RTFError RTFDocumentImpl::dispatchFlag(RTFKeyword nKeyword)
m_aStates.top().getParagraphSprms() = m_aDefaultState.getParagraphSprms();
m_aStates.top().getParagraphAttributes() = m_aDefaultState.getParagraphAttributes();
- if (m_nTopLevelCells != 0 || m_nNestedCells != 0)
+ if (m_TopLevelTableRow.getCells() != 0 || m_nNestedCells != 0)
{
// Ideally getDefaultSPRM() would take care of this, but it would not when we're buffering.
// TODO: is this the right place to do this?
diff --git a/engine/sw/source/writerfilter/rtftok/rtfdispatchsymbol.cxx b/engine/sw/source/writerfilter/rtftok/rtfdispatchsymbol.cxx
index 4ddd44bc1078..6604f4ad72d8 100644
--- a/engine/sw/source/writerfilter/rtftok/rtfdispatchsymbol.cxx
+++ b/engine/sw/source/writerfilter/rtftok/rtfdispatchsymbol.cxx
@@ -24,6 +24,37 @@ using namespace com::sun::star;
namespace writerfilter::rtftok
{
+void RTFDocumentImpl::checkTableStart()
+{
+ if (m_TopLevelTableRow.checkTableStart())
+ {
+ // Wasn't in table, but now is -> tblStart.
+ // (this detection only works if the table definition
+ // precedes the cells...)
+ RTFSprms aAttributes;
+ RTFSprms aSprms;
+ aSprms.set(NS_ooxml::LN_tblStart, new RTFValue(1));
+ writerfilter::Reference<Properties>::Pointer_t pProperties
+ = new RTFReferenceProperties(std::move(aAttributes), std::move(aSprms));
+ Mapper().props(pProperties);
+ }
+}
+
+void RTFDocumentImpl::checkTableEnd()
+{
+ // Not in table? Reset max width.
+ if (m_TopLevelTableRow.checkTableEnd())
+ {
+ // Was in table, but not anymore -> tblEnd.
+ RTFSprms aAttributes;
+ RTFSprms aSprms;
+ aSprms.set(NS_ooxml::LN_tblEnd, new RTFValue(1));
+ writerfilter::Reference<Properties>::Pointer_t pProperties
+ = new RTFReferenceProperties(std::move(aAttributes), std::move(aSprms));
+ Mapper().props(pProperties);
+ }
+}
+
RTFError RTFDocumentImpl::dispatchSymbol(RTFKeyword nKeyword)
{
setNeedSect(true);
@@ -124,30 +155,24 @@ RTFError RTFDocumentImpl::dispatchSymbol(RTFKeyword nKeyword)
pCurrentBuffer->push_back(Buf_t(RTFBufferTypes::PAR, pValue, nullptr));
}
- if (!isTable)
+ if (isTable)
+ {
+ checkTableStart();
+ }
+ else
{
// Not actually in table!
// Clear the buffer so this new \par will not be seen
// when next \par or \cell checks the buffer.
replayBuffer(*pCurrentBuffer, nullptr, nullptr);
assert(pCurrentBuffer->empty());
+ checkTableEnd();
}
}
else
{
parBreak();
- // Not in table? Reset max width.
- if (m_nCellxMax)
- {
- // Was in table, but not anymore -> tblEnd.
- RTFSprms aAttributes;
- RTFSprms aSprms;
- aSprms.set(NS_ooxml::LN_tblEnd, new RTFValue(1));
- writerfilter::Reference<Properties>::Pointer_t pProperties
- = new RTFReferenceProperties(std::move(aAttributes), std::move(aSprms));
- Mapper().props(pProperties);
- }
- m_nCellxMax = 0;
+ checkTableEnd();
}
// but don't emit properties yet, since they may change till the first text token arrives
@@ -238,6 +263,7 @@ RTFError RTFDocumentImpl::dispatchSymbol(RTFKeyword nKeyword)
// if there was no \par, it is also a table regardless of \itap
if (iter == pCurrentBuffer->end() || ::std::get<0>(*iter) == RTFBufferTypes::Props)
{
+ checkTableStart(); // testTdf59454
// must send *all* paragraph properties (testTdf164945),
// else getDefaultSPRM() will overwrite things
oSprms.emplace(m_aStates.top().getParagraphSprms());
@@ -309,7 +335,7 @@ RTFError RTFDocumentImpl::dispatchSymbol(RTFKeyword nKeyword)
RTFConflictPolicy::Append);
dispatchSymbol(RTFKeyword::CELL);
// Adjust total width, which is done in the \cellx handler for normal cells.
- m_nTopLevelCurrentCellX += m_aStates.top().getTableRowWidthAfter();
+ m_TopLevelTableRow.nCurrentCellX += m_aStates.top().getTableRowWidthAfter();
int nCellCount = 0;
for (Buf_t& i : m_aTableBufferStack.back())
@@ -317,20 +343,19 @@ RTFError RTFDocumentImpl::dispatchSymbol(RTFKeyword nKeyword)
if (RTFBufferTypes::CellEnd == std::get<0>(i))
++nCellCount;
}
- if (m_nTopLevelCells < nCellCount)
+ if (m_TopLevelTableRow.getCells() < o3tl::make_unsigned(nCellCount))
{
- m_nTopLevelCells++;
- m_aTopLevelTableCellsSprms.push_back(m_aStates.top().getTableCellSprms());
- m_aTopLevelTableCellsAttributes.push_back(
+ m_TopLevelTableRow.cellSprms.push_back(m_aStates.top().getTableCellSprms());
+ m_TopLevelTableRow.cellAttributes.push_back(
m_aStates.top().getTableCellAttributes());
}
- if (m_aTopLevelTableCellsSprms.size() >= o3tl::make_unsigned(nCellCount))
+ if (m_TopLevelTableRow.getCells() >= o3tl::make_unsigned(nCellCount))
{
Id aBorderIds[]
= { NS_ooxml::LN_CT_TcBorders_bottom, NS_ooxml::LN_CT_TcBorders_top,
NS_ooxml::LN_CT_TcBorders_left, NS_ooxml::LN_CT_TcBorders_right };
- RTFSprms& rCurrentCellSprms = m_aTopLevelTableCellsSprms[nCellCount - 1];
+ RTFSprms& rCurrentCellSprms{ m_TopLevelTableRow.cellSprms[nCellCount - 1] };
for (size_t i = 0; i < 4; i++)
{
RTFSprms aAttributes;
@@ -395,39 +420,37 @@ RTFError RTFDocumentImpl::dispatchSymbol(RTFKeyword nKeyword)
bool bRestored = false;
// Ending a row, but no cells defined?
// See if there was an invalid table row reset, so we can restore cell infos to help invalid documents.
- if (!m_nTopLevelCurrentCellX && m_nBackupTopLevelCurrentCellX)
+ if (!m_TopLevelTableRow.nCurrentCellX && m_BackupTopLevelTableRow.nCurrentCellX)
{
restoreTableRowProperties();
bRestored = true;
}
- // If the right edge of the last cell (row width) is smaller than the width of some other row, mimic WW8TabDesc::CalcDefaults(): resize the last cell
- const int MINLAY = 23; // sw/inc/swtypes.hxx, minimal possible size of frames.
- if ((m_nCellxMax - m_nTopLevelCurrentCellX) >= MINLAY)
+ if (m_TopLevelTableRow.getCells() != 0)
{
- auto pXValueLast = m_aStates.top().getTableRowSprms().find(
- NS_ooxml::LN_CT_TblGridBase_gridCol, false);
- const int nXValueLast = pXValueLast ? pXValueLast->getInt() : 0;
- auto pXValue = new RTFValue(nXValueLast + m_nCellxMax - m_nTopLevelCurrentCellX);
- m_aStates.top().getTableRowSprms().eraseLast(NS_ooxml::LN_CT_TblGridBase_gridCol);
- m_aStates.top().getTableRowSprms().set(NS_ooxml::LN_CT_TblGridBase_gridCol, pXValue,
- RTFConflictPolicy::Append);
- m_nTopLevelCurrentCellX = m_nCellxMax;
- }
+ // If the right edge of the last cell (row width) is smaller than the width of some other row, mimic WW8TabDesc::CalcDefaults(): resize the last cell
+ const int MINLAY = 23; // sw/inc/swtypes.hxx, minimal possible size of frames.
+ if ((m_TopLevelTableRow.nCellXMax - m_TopLevelTableRow.nCurrentCellX) >= MINLAY)
+ {
+ auto pXValueLast = m_aStates.top().getTableRowSprms().find(
+ NS_ooxml::LN_CT_TblGridBase_gridCol, false);
+ const int nXValueLast = pXValueLast ? pXValueLast->getInt() : 0;
+ auto pXValue = new RTFValue(nXValueLast + m_TopLevelTableRow.nCellXMax
+ - m_TopLevelTableRow.nCurrentCellX);
+ m_aStates.top().getTableRowSprms().eraseLast(
+ NS_ooxml::LN_CT_TblGridBase_gridCol);
+ m_aStates.top().getTableRowSprms().set(NS_ooxml::LN_CT_TblGridBase_gridCol,
+ pXValue, RTFConflictPolicy::Append);
+ m_TopLevelTableRow.nCurrentCellX = m_TopLevelTableRow.nCellXMax;
+ }
- if (m_nTopLevelCells)
- {
// Make a backup before we start popping elements
- m_aTableInheritingCellsSprms = m_aTopLevelTableCellsSprms;
- m_aTableInheritingCellsAttributes = m_aTopLevelTableCellsAttributes;
- m_nInheritingCells = m_nTopLevelCells;
+ m_PreviousTopLevelTableRow = m_TopLevelTableRow;
}
else
{
// No table definition? Then inherit from the previous row
- m_aTopLevelTableCellsSprms = m_aTableInheritingCellsSprms;
- m_aTopLevelTableCellsAttributes = m_aTableInheritingCellsAttributes;
- m_nTopLevelCells = m_nInheritingCells;
+ m_TopLevelTableRow = m_PreviousTopLevelTableRow;
}
while (m_aTableBufferStack.size() > 1)
@@ -444,8 +467,9 @@ RTFError RTFDocumentImpl::dispatchSymbol(RTFKeyword nKeyword)
m_aTableBufferStack.pop_back();
}
- replayRowBuffer(m_aTableBufferStack.back(), m_aTopLevelTableCellsSprms,
- m_aTopLevelTableCellsAttributes, m_nTopLevelCells);
+ auto const nCells{ m_TopLevelTableRow.getCells() }; // replayRowBuffer clears it!
+ replayRowBuffer(m_aTableBufferStack.back(), m_TopLevelTableRow.cellSprms,
+ m_TopLevelTableRow.cellAttributes, nCells);
// The scope of the table cell defaults is one row.
m_aDefaultState.getTableCellSprms().clear();
@@ -456,13 +480,13 @@ RTFError RTFDocumentImpl::dispatchSymbol(RTFKeyword nKeyword)
writerfilter::Reference<Properties>::Pointer_t frameProperties;
writerfilter::Reference<Properties>::Pointer_t rowProperties;
prepareProperties(m_aStates.top(), paraProperties, frameProperties, rowProperties,
- m_nTopLevelCells, m_nTopLevelCurrentCellX, m_nTopLevelTRLeft);
+ nCells, m_TopLevelTableRow.nCurrentCellX, m_TopLevelTableRow.nTRLeft);
sendProperties(paraProperties, frameProperties, rowProperties);
m_bNeedPap = true;
m_bNeedFinalPar = true;
m_aTableBufferStack.back().clear();
- m_nTopLevelCells = 0;
+ m_TopLevelTableRow.reset();
// reset buffer => outside of table, until next \trowd
// table buffer is our own concept, doesn't map to RTF pushState/popState
// ... see test165805Tdf where \row is in deeper scope than \intbl
diff --git a/engine/sw/source/writerfilter/rtftok/rtfdispatchvalue.cxx b/engine/sw/source/writerfilter/rtftok/rtfdispatchvalue.cxx
index ebc654e64acf..0a77c5bf9a06 100644
--- a/engine/sw/source/writerfilter/rtftok/rtfdispatchvalue.cxx
+++ b/engine/sw/source/writerfilter/rtftok/rtfdispatchvalue.cxx
@@ -394,7 +394,7 @@ bool RTFDocumentImpl::dispatchTableValue(RTFKeyword nKeyword, int nParam)
int& rCurrentCellX(
(Destination::NESTEDTABLEPROPERTIES == m_aStates.top().getDestination())
? m_nNestedCurrentCellX
- : m_nTopLevelCurrentCellX);
+ : m_TopLevelTableRow.nCurrentCellX);
int nCellWidth = nParam - rCurrentCellX;
rCurrentCellX = nParam;
auto pXValue = new RTFValue(nCellWidth);
@@ -409,26 +409,16 @@ bool RTFDocumentImpl::dispatchTableValue(RTFKeyword nKeyword, int nParam)
}
else
{
- m_nTopLevelCells++;
// Push cell properties.
- m_aTopLevelTableCellsSprms.push_back(m_aStates.top().getTableCellSprms());
- m_aTopLevelTableCellsAttributes.push_back(m_aStates.top().getTableCellAttributes());
+ m_TopLevelTableRow.cellSprms.push_back(m_aStates.top().getTableCellSprms());
+ m_TopLevelTableRow.cellAttributes.push_back(
+ m_aStates.top().getTableCellAttributes());
+ m_TopLevelTableRow.setCellXMax();
}
m_aStates.top().getTableCellSprms() = m_aDefaultState.getTableCellSprms();
m_aStates.top().getTableCellAttributes() = m_aDefaultState.getTableCellAttributes();
// Don't assume that following text is in a table!
- if (!m_nCellxMax)
- {
- // Wasn't in table, but now is -> tblStart.
- RTFSprms aAttributes;
- RTFSprms aSprms;
- aSprms.set(NS_ooxml::LN_tblStart, new RTFValue(1));
- writerfilter::Reference<Properties>::Pointer_t pProperties
- = new RTFReferenceProperties(std::move(aAttributes), std::move(aSprms));
- Mapper().props(pProperties);
- }
- m_nCellxMax = std::max(m_nCellxMax, nParam);
return true;
}
break;
@@ -461,7 +451,7 @@ bool RTFDocumentImpl::dispatchTableValue(RTFKeyword nKeyword, int nParam)
auto const aDestination = m_aStates.top().getDestination();
int& rCurrentTRLeft((Destination::NESTEDTABLEPROPERTIES == aDestination)
? m_nNestedTRLeft
- : m_nTopLevelTRLeft);
+ : m_TopLevelTableRow.nTRLeft);
rCurrentTRLeft = nParam;
return true;
}
diff --git a/engine/sw/source/writerfilter/rtftok/rtfdocumentimpl.cxx b/engine/sw/source/writerfilter/rtftok/rtfdocumentimpl.cxx
index 5a1bbf150878..2c473595247f 100644
--- a/engine/sw/source/writerfilter/rtftok/rtfdocumentimpl.cxx
+++ b/engine/sw/source/writerfilter/rtftok/rtfdocumentimpl.cxx
@@ -317,13 +317,8 @@ RTFDocumentImpl::RTFDocumentImpl(uno::Reference<uno::XComponentContext> const& x
, m_bNeedPar(true)
, m_bNeedFinalPar(false)
, m_nNestedCells(0)
- , m_nTopLevelCells(0)
- , m_nInheritingCells(0)
, m_nNestedTRLeft(0)
- , m_nTopLevelTRLeft(0)
, m_nNestedCurrentCellX(0)
- , m_nTopLevelCurrentCellX(0)
- , m_nBackupTopLevelCurrentCellX(0)
, m_aTableBufferStack(1) // create top-level buffer already
, m_pSuperstream(nullptr)
, m_nStreamType(0)
@@ -343,7 +338,6 @@ RTFDocumentImpl::RTFDocumentImpl(uno::Reference<uno::XComponentContext> const& x
, m_bWasInFrame(false)
, m_bHadPicture(false)
, m_bHadSect(false)
- , m_nCellxMax(0)
, m_nListPictureId(0)
, m_bIsNewDoc(!rMediaDescriptor.getUnpackedValueOrDefault(u"InsertMode"_ustr, false))
, m_rMediaDescriptor(rMediaDescriptor)
@@ -1668,7 +1662,7 @@ void RTFDocumentImpl::text(OUString& rString)
// Are we in the middle of the table definition? (No cell defs yet, but we already have some cell props.)
if (m_aStates.top().getTableCellSprms().find(NS_ooxml::LN_CT_TcPrBase_vAlign)
- && m_nTopLevelCells == 0)
+ && m_TopLevelTableRow.getCells() == 0)
{
m_aTableBufferStack.back().emplace_back(RTFBufferTypes::UText, new RTFValue(rString),
nullptr);
@@ -1990,11 +1984,11 @@ bool findPropertyName(const std::vector<beans::PropertyValue>& rProperties, cons
void RTFDocumentImpl::backupTableRowProperties()
{
- if (m_nTopLevelCurrentCellX)
+ if (m_TopLevelTableRow.nCurrentCellX)
{
m_aBackupTableRowSprms = m_aStates.top().getTableRowSprms();
m_aBackupTableRowAttributes = m_aStates.top().getTableRowAttributes();
- m_nBackupTopLevelCurrentCellX = m_nTopLevelCurrentCellX;
+ m_BackupTopLevelTableRow = m_TopLevelTableRow;
}
}
@@ -2002,7 +1996,7 @@ void RTFDocumentImpl::restoreTableRowProperties()
{
m_aStates.top().getTableRowSprms() = m_aBackupTableRowSprms;
m_aStates.top().getTableRowAttributes() = m_aBackupTableRowAttributes;
- m_nTopLevelCurrentCellX = m_nBackupTopLevelCurrentCellX;
+ m_TopLevelTableRow = m_BackupTopLevelTableRow;
}
void RTFDocumentImpl::resetTableRowProperties()
@@ -2018,8 +2012,7 @@ void RTFDocumentImpl::resetTableRowProperties()
}
else
{
- m_nTopLevelTRLeft = 0;
- m_nTopLevelCurrentCellX = 0;
+ m_TopLevelTableRow.reset();
}
}
diff --git a/engine/sw/source/writerfilter/rtftok/rtfdocumentimpl.hxx b/engine/sw/source/writerfilter/rtftok/rtfdocumentimpl.hxx
index 4ac391327eaa..bc6ed52c4fdb 100644
--- a/engine/sw/source/writerfilter/rtftok/rtfdocumentimpl.hxx
+++ b/engine/sw/source/writerfilter/rtftok/rtfdocumentimpl.hxx
@@ -811,6 +811,8 @@ private:
void checkUnicode(bool bUnicode, bool bHex);
/// If we need a final section break at the end of the document.
void setNeedSect(bool bNeedSect);
+ void checkTableStart();
+ void checkTableEnd();
void resetTableRowProperties();
void backupTableRowProperties();
void restoreTableRowProperties();
@@ -877,6 +879,60 @@ private:
std::shared_ptr<oox::GraphicHelper> m_pGraphicHelper;
+ struct TableRowDef
+ {
+ /// cell props
+ std::deque<RTFSprms> cellSprms;
+ std::deque<RTFSprms> cellAttributes;
+
+ /// Left row margin
+ int nTRLeft{ 0 };
+
+ /// Current cellx value (top-level table)
+ int nCurrentCellX{ 0 };
+
+ /// Max width of the rows in the current table.
+ int nCellXMax{ 0 };
+ bool isStartTable{ false };
+
+ void reset()
+ {
+ cellSprms.clear();
+ cellAttributes.clear();
+ nTRLeft = 0;
+ nCurrentCellX = 0;
+ // leave nCellXMax / isStartTable alone - very special handling!
+ }
+
+ void setCellXMax()
+ {
+ if (nCellXMax == 0)
+ {
+ isStartTable = true;
+ }
+ nCellXMax = ::std::max(nCurrentCellX, nCellXMax);
+ }
+ bool checkTableStart()
+ {
+ bool const ret{ isStartTable };
+ isStartTable = false;
+ return ret;
+ }
+ bool checkTableEnd()
+ {
+ bool const ret{ nCellXMax != 0 };
+ nCellXMax = 0;
+ return ret;
+ }
+
+ size_t getCells() { return cellSprms.size(); }
+ };
+
+ /// cell props buffer for top-level table, reset by \row or \trowd
+ TableRowDef m_TopLevelTableRow;
+ /// backup of top-level props, to support inheriting cell props
+ TableRowDef m_PreviousTopLevelTableRow;
+
/// cell props buffer for nested tables, reset by \nestrow
/// the \nesttableprops is a destination and must follow the
/// nested cells, so it should be sufficient to store the
@@ -884,28 +940,18 @@ private:
int m_nNestedCells;
std::deque<RTFSprms> m_aNestedTableCellsSprms;
std::deque<RTFSprms> m_aNestedTableCellsAttributes;
- /// cell props buffer for top-level table, reset by \row
- int m_nTopLevelCells;
- std::deque<RTFSprms> m_aTopLevelTableCellsSprms;
- std::deque<RTFSprms> m_aTopLevelTableCellsAttributes;
- /// backup of top-level props, to support inheriting cell props
- int m_nInheritingCells;
- std::deque<RTFSprms> m_aTableInheritingCellsSprms;
- std::deque<RTFSprms> m_aTableInheritingCellsAttributes;
- // Left row margin (for nested and top-level rows)
+ // Left row margin (for nested rows)
int m_nNestedTRLeft;
- int m_nTopLevelTRLeft;
/// Current cellx value (nested table)
int m_nNestedCurrentCellX;
- /// Current cellx value (top-level table)
- int m_nTopLevelCurrentCellX;
- // Backup of what \trowd clears, to work around invalid input.
+ // Backup of what \trowd clears, purely to work around input that Word
+ // considers invalid but which OpenOffice.org was able to import as table.
RTFSprms m_aBackupTableRowSprms;
RTFSprms m_aBackupTableRowAttributes;
- int m_nBackupTopLevelCurrentCellX;
+ TableRowDef m_BackupTopLevelTableRow;
/// Buffered table cells, till cell definitions are not reached.
/// for nested table, one buffer per table level
@@ -978,8 +1024,6 @@ private:
bool m_bHadPicture;
/// The document has multiple sections.
bool m_bHadSect;
- /// Max width of the rows in the current table.
- int m_nCellxMax;
/// ID of the next \listlevel picture.
int m_nListPictureId;