summaryrefslogtreecommitdiff
path: root/sw/source/filter/rtf/rtftbl.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/filter/rtf/rtftbl.cxx')
-rw-r--r--sw/source/filter/rtf/rtftbl.cxx1024
1 files changed, 1024 insertions, 0 deletions
diff --git a/sw/source/filter/rtf/rtftbl.cxx b/sw/source/filter/rtf/rtftbl.cxx
new file mode 100644
index 000000000000..4fd06a26925f
--- /dev/null
+++ b/sw/source/filter/rtf/rtftbl.cxx
@@ -0,0 +1,1024 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: rtftbl.cxx,v $
+ * $Revision: 1.40 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sw.hxx"
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
+
+#ifdef WTC
+#define private public
+#endif
+#include <hintids.hxx>
+#include <svx/lrspitem.hxx>
+#include <svx/boxitem.hxx>
+#include <svx/frmdiritem.hxx>
+#include <svtools/rtftoken.h>
+#include <fmtfsize.hxx>
+#include <fmtpdsc.hxx>
+#include <ndtxt.hxx>
+#include <doc.hxx>
+#include <pam.hxx>
+#include <swparrtf.hxx>
+#include <swtable.hxx>
+#include <tblsel.hxx>
+#include <swtblfmt.hxx>
+#include <wrtswtbl.hxx>
+#include <tblenum.hxx>
+#include <frmatr.hxx>
+#include <fmtrowsplt.hxx>
+
+using namespace ::com::sun::star;
+
+typedef SwTableBoxFmt* SwTableBoxFmtPtr;
+SV_DECL_PTRARR( SwBoxFrmFmts, SwTableBoxFmtPtr, 25, 50 )
+
+class SwShareBoxFmts;
+extern void _DeleteBox( SwTable& rTbl, SwTableBox* pBox, SwUndo* = 0,
+ BOOL = TRUE, const BOOL = TRUE, SwShareBoxFmts* = 0 );
+
+struct Row
+{
+ bool mbUseLeftRowPad, mbUseRightRowPad, mbUseTopRowPad, mbUseBottomRowPad;
+ long mnLeftRowPad, mnRightRowPad, mnTopRowPad, mnBottomRowPad;
+ USHORT mnBrdDist;
+ Row() :
+ mbUseLeftRowPad(false), mbUseRightRowPad(false),
+ mbUseTopRowPad(false), mbUseBottomRowPad(false),
+ mnLeftRowPad(0), mnRightRowPad(0), mnTopRowPad(0), mnBottomRowPad(0),
+ mnBrdDist(MIN_BORDER_DIST)
+ {}
+};
+
+static void SetRowBorder(SfxItemSet& rSet, const Row &rRow)
+{
+#if 1
+ SvxBoxItem aBox((const SvxBoxItem&)rSet.Get(RES_BOX, false));
+ aBox.SetDistance( static_cast< USHORT >(rRow.mbUseLeftRowPad ? rRow.mnLeftRowPad : rRow.mnBrdDist),
+ BOX_LINE_LEFT);
+
+ aBox.SetDistance( static_cast< USHORT >(rRow.mbUseRightRowPad ? rRow.mnRightRowPad : rRow.mnBrdDist),
+ BOX_LINE_RIGHT);
+
+ aBox.SetDistance( static_cast< USHORT >(rRow.mbUseTopRowPad ? rRow.mnTopRowPad : 0),
+ BOX_LINE_TOP);
+
+ aBox.SetDistance( static_cast< USHORT >(rRow.mbUseBottomRowPad ? rRow.mnBottomRowPad : 0),
+ BOX_LINE_BOTTOM);
+
+ rSet.Put(aBox);
+#else
+ const SfxPoolItem* pItem;
+ if (SFX_ITEM_SET == rSet.GetItemState(RES_BOX, FALSE, &pItem))
+ {
+ SvxBoxItem aBox( *(SvxBoxItem*)pItem );
+ aBox.SetDistance(rRow.mbUseLeftRowPad ? rRow.mnLeftRowPad : rRow.mnBrdDist,
+ BOX_LINE_LEFT);
+
+ aBox.SetDistance(rRow.mbUseRightRowPad ? rRow.mnRightRowPad : rRow.mnBrdDist,
+ BOX_LINE_RIGHT);
+
+ aBox.SetDistance(rRow.mbUseTopRowPad ? rRow.mnTopRowPad : 0,
+ BOX_LINE_TOP);
+
+ aBox.SetDistance(rRow.mbUseBottomRowPad ? rRow.mnBottomRowPad : 0,
+ BOX_LINE_BOTTOM);
+
+ rSet.Put(aBox);
+ }
+#endif
+}
+
+void rtfSections::PrependedInlineNode(const SwPosition &rPos,
+ const SwNode &rNode)
+{
+ ASSERT(!mrReader.IsNewDoc() || !maSegments.empty(),
+ "should not be possible, must be at least one segment in a new document");
+ if ((!maSegments.empty()) && (maSegments.back().maStart == rPos.nNode))
+ maSegments.back().maStart = SwNodeIndex(rNode);
+}
+
+bool SwRTFParser::IsBorderToken(int nToken)
+{
+ /*
+ i30222 i28983
+ Our ability to sense border tokens is broken rtftoken.h is
+ organised in a way that ignores some border tokens. ReadBorderAttr
+ still doesn't support the more exotic borders but at least this
+ won't cause the parser to prematuerely exit the table
+ */
+ bool bResult = false;
+
+ bResult = (nToken >= RTF_BRDRDASHD && nToken <= RTF_BRDRTHTNMG) ||
+ (nToken >= RTF_BRDRTNTHSG && nToken <= RTF_BRDRWAVY);
+
+ return bResult;
+}
+
+void SwRTFParser::ReadTable( int nToken )
+{
+ nInsTblRow = USHRT_MAX;
+
+ if (CantUseTables())
+ {
+ // alle Tabellen-Tokens ueberlesen
+ nToken = GetNextToken(); // RTF_TROWD ueberlesen
+ do {
+ if( RTF_TABLEDEF != (nToken & ~(0xff | RTF_SWGDEFS)) &&
+ RTF_UNKNOWNCONTROL != nToken )
+ {
+ SkipToken( -1 );
+ break;
+ }
+ nToken = GetNextToken();
+ } while( IsParserWorking() );
+ return ;
+ }
+
+ // verhinder Tabelle in Tabelle/Footnote
+ SwTwips nTblSz = 0;
+ int bReadNewCell = FALSE, bChkExistTbl = FALSE;
+
+
+ enum Limits {eMAXCELLS=64000};
+
+ SvBools aMergeBackup;
+ int nCount = aMergeBoxes.Count();
+ for (USHORT i = 0; i < nCount; ++i)
+ aMergeBackup.Insert(aMergeBoxes[i], i);
+
+ // kein TROWD aber ein TabellenToken -> zwischen TROWD und Tab.Token
+ // waren andere Zeichen (siehe Bug 27445.rtf)
+ if( RTF_TROWD == nToken || !pTableNode )
+ {
+ if( RTF_TROWD == nToken )
+ nToken = GetNextToken(); // RTF_TROWD ueberlesen
+
+ // Flags fuer die gemergten Boxen loeschen
+ aMergeBoxes.Remove( 0, aMergeBoxes.Count() );
+ aMergeBoxes.Insert( (BOOL)FALSE, USHORT(0) );
+ nAktBox = 0;
+
+ // wenn schon in einer Tabellen, dann splitte oder benutze
+ // die bisherigen Boxen weiter
+ bChkExistTbl = 0 != pDoc->GetNodes()[ pPam->GetPoint()->nNode ]->FindTableNode();
+ }
+ else
+ {
+ bReadNewCell = TRUE;
+ SwTableLines& rLns = pTableNode->GetTable().GetTabLines();
+ SwTableLine* pLine = rLns[ rLns.Count()-1 ];
+ // very robust to avoid crashes like bug 127425 + crash reports 118743
+ if( pLine )
+ {
+ USHORT nTmpBox = nAktBox;
+ if( nTmpBox > pLine->GetTabBoxes().Count() )
+ nTmpBox = pLine->GetTabBoxes().Count();
+
+ for( USHORT n = nTmpBox; n; )
+ {
+ const SwTableBox *pTmp = pLine->GetTabBoxes()[ --n ];
+ if( pTmp )
+ {
+ const SwFrmFmt* pTmpFmt = pTmp->GetFrmFmt();
+ if( pTmpFmt )
+ nTblSz += pTmpFmt->GetFrmSize().GetWidth();
+ }
+ }
+ }
+ }
+
+
+ sal_Int16 eAdjust = text::HoriOrientation::LEFT; // default fuer Tabellen
+ SwTwips nLSpace = 0;
+ Row aRow;
+
+ bool bUseLeftCellPad = false, bUseRightCellPad = false,
+ bUseTopCellPad = false, bUseBottomCellPad = false;
+ long nLeftCellPad = 0, nRightCellPad = 0, nTopCellPad = 0,
+ nBottomCellPad = 0;
+
+ sal_Int16 eVerOrient = text::VertOrientation::NONE;
+ long nLineHeight = 0;
+ USHORT nBoxCnt = aMergeBoxes.Count()-1;
+ SwBoxFrmFmts aBoxFmts;
+ SwTableBoxFmt* pBoxFmt = pDoc->MakeTableBoxFmt();
+ SvxFrameDirection eDir = FRMDIR_HORI_LEFT_TOP;
+ bool bCantSplit = false;
+
+ int bWeiter = TRUE;
+ do {
+ switch( nToken )
+ {
+ case RTF_TRPADDFL:
+ aRow.mbUseLeftRowPad = (nTokenValue == 3) ? true : false;
+ break;
+ case RTF_TRPADDFT:
+ aRow.mbUseTopRowPad = (nTokenValue == 3) ? true : false;
+ break;
+ case RTF_TRPADDFR:
+ aRow.mbUseRightRowPad = (nTokenValue == 3) ? true : false;
+ break;
+ case RTF_TRPADDFB:
+ aRow.mbUseBottomRowPad = (nTokenValue == 3) ? true : false;
+ break;
+ case RTF_TRPADDL:
+ aRow.mnLeftRowPad = nTokenValue;
+ break;
+ case RTF_TRPADDT:
+ aRow.mnTopRowPad = nTokenValue;
+ break;
+ case RTF_TRPADDR:
+ aRow.mnRightRowPad = nTokenValue;
+ break;
+ case RTF_TRPADDB:
+ aRow.mnBottomRowPad = nTokenValue;
+ break;
+
+ case RTF_CLPADFL:
+ bUseLeftCellPad = (nTokenValue == 3) ? true : false;
+ break;
+ case RTF_CLPADFT:
+ bUseTopCellPad = (nTokenValue == 3) ? true : false;
+ break;
+ case RTF_CLPADFR:
+ bUseRightCellPad = (nTokenValue == 3) ? true : false;
+ break;
+ case RTF_CLPADFB:
+ bUseBottomCellPad = (nTokenValue == 3) ? true : false;
+ break;
+ case RTF_CLPADL:
+ nLeftCellPad = nTokenValue;
+ break;
+ case RTF_CLPADT:
+ nTopCellPad = nTokenValue;
+ break;
+ case RTF_CLPADR:
+ nRightCellPad = nTokenValue;
+ break;
+ case RTF_CLPADB:
+ nBottomCellPad = nTokenValue;
+ break;
+
+ case RTF_TRRH:
+ nLineHeight = nTokenValue;
+ break;
+
+ case RTF_CLMRG:
+ aMergeBoxes[ nBoxCnt ] = TRUE;
+ break;
+
+ case RTF_CELLX:
+ if (!bTrowdRead) {
+ SwTableBoxFmt* pFmt = pBoxFmt;
+ SwTwips nSize = nTokenValue - nTblSz;
+ if( aMergeBoxes[ nBoxCnt ] )
+ {
+ // neue Zellen lesen und noch keine Formate vorhanden,
+ // dann benutze das der vorhergebende
+ if( bReadNewCell && !aBoxFmts.Count() )
+ {
+ SwTableLines& rLns = pTableNode->GetTable().GetTabLines();
+ SwTableLine* pLine = rLns[ rLns.Count()-1 ];
+ if(nAktBox!=0)
+ --nAktBox;
+ pFmt = (SwTableBoxFmt*)pLine->GetTabBoxes()[ nAktBox ]->GetFrmFmt();
+ }
+ else
+ pFmt = aBoxFmts[ aBoxFmts.Count()-1 ];
+
+ // --> OD 2007-01-25 #i73790# - method renamed
+ pBoxFmt->ResetAllFmtAttr();
+ // <--
+ nSize += pFmt->GetFrmSize().GetWidth();
+ }
+ else
+ {
+ //
+ if (nSize<=2*aRow.mnBrdDist) {
+ aRow.mnRightRowPad=0;
+ aRow.mbUseRightRowPad=TRUE;
+ }
+ SetRowBorder((SfxItemSet&)pBoxFmt->GetAttrSet(), aRow);
+ aBoxFmts.Insert( pBoxFmt, aBoxFmts.Count() );
+ pBoxFmt = pDoc->MakeTableBoxFmt();
+ }
+
+ if( !nSize )
+ nSize = COL_DFLT_WIDTH;
+ pFmt->SetFmtAttr( SwFmtFrmSize( ATT_VAR_SIZE, nSize, 0 ));
+ nTblSz = nTokenValue;
+ aMergeBoxes.Insert( (BOOL)FALSE, ++nBoxCnt );
+
+ SvxBoxItem aBox(pFmt->GetBox());
+
+ if (bUseRightCellPad)
+ aBox.SetDistance( static_cast< USHORT >(nRightCellPad), BOX_LINE_RIGHT);
+ if (bUseBottomCellPad)
+ aBox.SetDistance( static_cast< USHORT >(nBottomCellPad), BOX_LINE_BOTTOM);
+
+ //Yes, these are the wrong way around, there appears to
+ //be a bug in word where these are swapped.
+ if (bUseLeftCellPad)
+ aBox.SetDistance( static_cast< USHORT >(nLeftCellPad), BOX_LINE_TOP);
+ if (bUseTopCellPad)
+ aBox.SetDistance( static_cast< USHORT >(nTopCellPad), BOX_LINE_LEFT);
+
+
+ /*#106415# The Cell Borders are now balanced on import to
+ improve the layout of tables.
+ */
+/*
+ if ( aBoxFmts.Count()>1)
+ {
+
+ SwTableBoxFmt* prevpFmt = aBoxFmts[ aBoxFmts.Count()-2 ];
+ SvxBoxItem prevaBox(prevpFmt->GetBox());
+ USHORT prevWidthRight=0;
+ USHORT currWidthLeft=0;
+ bool bDoubleLine=false;
+ const SvxBorderLine* brdrline ;
+ const Color* pPrevRightColor;
+ if(prevaBox.GetRight())
+ {
+ brdrline=prevaBox.GetRight();
+ prevWidthRight = brdrline->GetOutWidth();
+ pPrevRightColor = &brdrline->GetColor();
+ if(brdrline->GetInWidth())
+ bDoubleLine=true;
+ }
+ if(aBox.GetLeft())
+ {
+ brdrline=aBox.GetLeft();
+ currWidthLeft = brdrline->GetOutWidth();
+ if(brdrline->GetInWidth())
+ bDoubleLine=true;
+ }
+
+ if((currWidthLeft >0 || prevWidthRight >0) &&
+ !bDoubleLine)
+ {
+ USHORT newBorderWidth=(currWidthLeft+prevWidthRight)/2 ;
+ if(newBorderWidth /2 ==DEF_LINE_WIDTH_0 )
+ {
+ newBorderWidth =DEF_LINE_WIDTH_0;
+ }
+ else if(newBorderWidth /2 >=(DEF_LINE_WIDTH_4-DEF_LINE_WIDTH_3))
+ {
+ newBorderWidth =DEF_LINE_WIDTH_4;
+ }
+ else if(newBorderWidth /2 >=(DEF_LINE_WIDTH_3-DEF_LINE_WIDTH_2))
+ {
+ newBorderWidth =DEF_LINE_WIDTH_3;
+ }
+ else if(newBorderWidth /2>=(DEF_LINE_WIDTH_2-DEF_LINE_WIDTH_1))
+ {
+ newBorderWidth =DEF_LINE_WIDTH_2;
+ }
+ else if(newBorderWidth /2>=(DEF_LINE_WIDTH_1 - DEF_LINE_WIDTH_0) )
+ {
+ newBorderWidth =DEF_LINE_WIDTH_1;
+ }
+ else
+ {
+ newBorderWidth =DEF_LINE_WIDTH_0;
+ }
+ const SvxBorderLine newbrdrline(pPrevRightColor, newBorderWidth,0,0);
+ aBox.SetLine(&newbrdrline,BOX_LINE_LEFT);
+ prevaBox.SetLine(&newbrdrline,BOX_LINE_RIGHT);
+ prevpFmt->SetAttr(prevaBox);
+ }
+
+ }
+*/
+
+ pFmt->SetFmtAttr(aBox);
+
+ bUseLeftCellPad = false;
+ bUseRightCellPad = false;
+ bUseTopCellPad = false;
+ bUseBottomCellPad = false;
+ }
+ break;
+
+ case RTF_TRGAPH:
+ //$flr bug #117887#: RTF: wrong internal table cell margin imported (A13)
+ aRow.mnBrdDist = (nTokenValue>0?(USHORT)nTokenValue:0); // filter out negative values of \trgaph
+ break;
+
+ case RTF_TRQL: eAdjust = text::HoriOrientation::LEFT; break;
+ case RTF_TRQR: eAdjust = text::HoriOrientation::RIGHT; break;
+ case RTF_TRQC: eAdjust = text::HoriOrientation::CENTER; break;
+
+ // mit text::VertOrientation::TOP kommt der Dialog nicht klar!
+ // Bug #65126#
+ case RTF_CLVERTALT: eVerOrient = text::VertOrientation::NONE; break;
+
+ case RTF_CLVERTALC: eVerOrient = text::VertOrientation::CENTER; break;
+ case RTF_CLVERTALB: eVerOrient = text::VertOrientation::BOTTOM; break;
+
+ case RTF_TRLEFT:
+ if( text::HoriOrientation::LEFT == eAdjust )
+ eAdjust = text::HoriOrientation::LEFT_AND_WIDTH;
+ nLSpace = nTokenValue;
+ nTblSz = nTokenValue;
+ break;
+
+ case RTF_TRHDR:
+ nRowsToRepeat++;
+ break;
+
+ case RTF_CLTXLRTB:
+ case RTF_CLTXTBRL:
+ case RTF_INTBL: // das wissen wir !
+ case RTF_CLMGF:
+ case RTF_CLVMGF:
+ case RTF_CLVMRG:
+ break;
+ case RTF_LTRROW:
+ eDir = FRMDIR_HORI_LEFT_TOP;
+ break;
+ case RTF_RTLROW:
+ eDir = FRMDIR_HORI_RIGHT_TOP;
+ break;
+ case RTF_TRBRDRB:
+ case RTF_TRBRDRH:
+ case RTF_TRBRDRL:
+ case RTF_TRBRDRR:
+ case RTF_TRBRDRT:
+ case RTF_TRBRDRV:
+ break;
+ case RTF_TRKEEP:
+ bCantSplit = true;
+ break;
+
+ default:
+ if( ( nToken & ~(0xff | RTF_TABLEDEF)) == RTF_SHADINGDEF )
+ {
+ if( aMergeBoxes[ nBoxCnt ] )
+ break;
+ ReadBackgroundAttr( nToken,
+ (SfxItemSet&)pBoxFmt->GetAttrSet(), TRUE );
+ }
+ else if( ( nToken & ~(0xff | RTF_TABLEDEF) ) == RTF_BRDRDEF ||
+ IsBorderToken(nToken))
+ {
+ if( aMergeBoxes[ nBoxCnt ] )
+ break;
+
+ SfxItemSet& rSet = (SfxItemSet&)pBoxFmt->GetAttrSet();
+ if(!IsBorderToken( nToken ))
+ ReadBorderAttr( nToken, rSet, TRUE );
+ else
+ NextToken( nToken );
+ }
+ else if( RTF_TABLEDEF != (nToken & ~(0xff | RTF_SWGDEFS)) )
+ {
+ if( RTF_UNKNOWNCONTROL == nToken )
+ NextToken( nToken );
+ else
+ bWeiter = FALSE;
+ }
+ break;
+ }
+
+ if( text::VertOrientation::NONE != eVerOrient )
+ {
+ if( !aMergeBoxes[ nBoxCnt ] )
+ pBoxFmt->SetFmtAttr( SwFmtVertOrient( 0, eVerOrient ));
+ eVerOrient = text::VertOrientation::NONE;
+ }
+ if( bWeiter )
+ nToken = GetNextToken();
+ } while( bWeiter && IsParserWorking() );
+
+ // das letzte temp. BoxFmt loeschen
+ delete pBoxFmt;
+
+ // es wurde keine einzige Box erkannt
+ if( nAktBox == nBoxCnt || ( bReadNewCell && !pTableNode ))
+ {
+ int nC = aMergeBackup.Count();
+ for (USHORT i = 0; i < nC; ++i)
+ aMergeBoxes.Insert(aMergeBackup[i], i);
+ SkipToken( -1 ); // zum Letzen gueltigen zurueck
+ return;
+ }
+
+ nTblSz -= nLSpace;
+
+ int bNewTbl = TRUE;
+ SwTableLine* pNewLine;
+ bTrowdRead=true;
+
+ // lege eine neue Tabelle an oder erweiter die aktuelle um eine neue Line
+ // oder Box !
+ SwNode* pNd;
+
+ if( bChkExistTbl )
+ {
+ // es ist eine Tabelle vorhanden, teste mal ob die weiter benutzt
+ // werden kann oder ob sie abgesplittet und neu gefuellt werden
+ // muss.
+ pTableNode = pPam->GetNode()->FindTableNode();
+
+ // Cursor kann nur in der letzten Line stehen
+
+ // das Attribut darf nicht ueber das Modify an der
+ // Tabelle gesetzt werden, denn sonst werden alle
+ // Boxen wieder auf 0 zurueck gesetzt !!!!!
+ SwFrmFmt* pFmt = pTableNode->GetTable().GetFrmFmt();
+ const SwFmtFrmSize& rTblSz = pFmt->GetFrmSize();
+ const SwFmtHoriOrient& rHoriz = pFmt->GetHoriOrient();
+
+ const SwTableLines* pLns = &pTableNode->GetTable().GetTabLines();
+
+ if( 1 == pLns->Count() )
+ {
+ if( eAdjust != rHoriz.GetHoriOrient() )
+ {
+ ((SfxItemSet&)pFmt->GetAttrSet()).Put( SwFmtHoriOrient( 0,
+ eAdjust ) );
+ }
+ if( rTblSz.GetWidth() != nTblSz )
+ {
+ SwFmtFrmSize aSz( rTblSz );
+ aSz.SetWidth( nTblSz );
+ ((SfxItemSet&)pFmt->GetAttrSet()).Put( aSz );
+ }
+
+ if( text::HoriOrientation::LEFT_AND_WIDTH == eAdjust &&
+ nLSpace != pFmt->GetLRSpace().GetLeft() )
+ {
+ SvxLRSpaceItem aL( RES_LR_SPACE ); aL.SetLeft( nLSpace );
+ ((SfxItemSet&)pFmt->GetAttrSet()).Put( aL );
+ }
+ }
+ else if
+ (
+ 1 < pLns->Count() &&
+ (
+ rTblSz.GetWidth() != nTblSz ||
+ rHoriz.GetHoriOrient() != eAdjust ||
+ (
+ text::HoriOrientation::LEFT_AND_WIDTH == eAdjust &&
+ nLSpace != pFmt->GetLRSpace().GetLeft()
+ ) ||
+ pTableNode->GetTable().GetTabSortBoxes().Count() >= eMAXCELLS
+ )
+ )
+ {
+ // Tabelle ab der PaM-Position splitten
+ // die vorherige Line!
+ pNewLine = (*pLns)[ pLns->Count() - 2 ];
+ SwTableBox* pBox = pNewLine->GetTabBoxes()[ 0 ];
+ while( ( pLns = &pBox->GetTabLines() )->Count() )
+ pBox = (*pLns)[ 0 ]->GetTabBoxes()[ 0 ];
+
+ SwNodeIndex aTmpIdx( *pBox->GetSttNd() );
+ pDoc->GetNodes().SplitTable( aTmpIdx, HEADLINE_NONE, FALSE );
+ pTableNode = pPam->GetNode()->FindTableNode();
+ pFmt = pTableNode->GetTable().GetFrmFmt();
+
+ SwFmtFrmSize aSz( rTblSz );
+ aSz.SetWidth( nTblSz );
+ ((SfxItemSet&)pFmt->GetAttrSet()).Put( aSz );
+ ((SfxItemSet&)pFmt->GetAttrSet()).Put( SwFmtHoriOrient( 0,
+ eAdjust ) );
+ if( text::HoriOrientation::LEFT_AND_WIDTH == eAdjust && nLSpace )
+ {
+ SvxLRSpaceItem aL( RES_LR_SPACE ); aL.SetLeft( nLSpace );
+ ((SfxItemSet&)pFmt->GetAttrSet()).Put( aL );
+ }
+ }
+
+ pLns = &pTableNode->GetTable().GetTabLines();
+ pNewLine = (*pLns)[ pLns->Count() - 1 ];
+
+ // jetzt die Boxen abgleichen
+ USHORT nBoxes = Min( pNewLine->GetTabBoxes().Count(), aBoxFmts.Count() );
+ USHORT n;
+
+ for( n = 0; n < nBoxes; ++n )
+ {
+ SwTableBox* pBox = pNewLine->GetTabBoxes()[ n ];
+ *pBox->GetFrmFmt() = *aBoxFmts[ n ];
+ delete aBoxFmts[ n ];
+ }
+ aBoxFmts.Remove( 0, n );
+
+ if( aBoxFmts.Count() ) // es muessen noch neue zugefuegt werden
+ nAktBox = n;
+ else // es mussen noch Boxen geloescht werden
+ {
+ // remove ContentIndex of other Bound
+ pPam->SetMark(); pPam->DeleteMark();
+ while( n < pNewLine->GetTabBoxes().Count() )
+ _DeleteBox( pTableNode->GetTable(),
+ pNewLine->GetTabBoxes()[ n ], 0, FALSE, FALSE );
+ }
+
+ pOldTblNd = pTableNode;
+ bNewTbl = FALSE;
+
+ {
+ // JP 13.08.98: TabellenUmrandungen optimieren - Bug 53525
+ void* p = pFmt;
+ aTblFmts.Insert( p, aTblFmts.Count() );
+ }
+ }
+ else
+ {
+ if( !bReadNewCell && ( pNd = pDoc->GetNodes()[
+ pPam->GetPoint()->nNode.GetIndex()-1 ])->IsEndNode() )
+ {
+ pTableNode = pNd->StartOfSectionNode()->GetTableNode();
+ if( pTableNode )
+ {
+ // dann test mal ob wirklich nur eine neue Line eingefuegt
+ // werden soll!
+ SwTable &rTable = pTableNode->GetTable();
+ SwFrmFmt* pFmt = rTable.GetFrmFmt();
+ const SwFmtFrmSize& rTblSz = pFmt->GetFrmSize();
+ const SwFmtHoriOrient& rHoriz = pFmt->GetHoriOrient();
+ if (
+ rTblSz.GetWidth() != nTblSz ||
+ rHoriz.GetHoriOrient() != eAdjust ||
+ rTable.GetTabSortBoxes().Count() >= eMAXCELLS
+ )
+ {
+ pTableNode = 0;
+ }
+ }
+ }
+
+ if( pTableNode && !bForceNewTable)
+ {
+
+ // das Attribut darf nicht ueber das Modify an der
+ // Tabelle gesetzt werden, denn sonst werden alle
+ // Boxen wieder auf 0 zurueck gesetzt !!!!!
+ SwFrmFmt* pFmt = pTableNode->GetTable().GetFrmFmt();
+ const SwFmtFrmSize& rTblSz = pFmt->GetFrmSize();
+ if( rTblSz.GetWidth() < nTblSz )
+ {
+ SwFmtFrmSize aSz( rTblSz );
+ aSz.SetWidth( nTblSz );
+ ((SfxItemSet&)pFmt->GetAttrSet()).Put( aSz );
+ }
+
+ SwTableLines& rLns = pTableNode->GetTable().GetTabLines();
+
+ if( bReadNewCell )
+ pNewLine = rLns[ rLns.Count()-1 ];
+ else
+ {
+ pNewLine = new SwTableLine(
+ (SwTableLineFmt*)rLns[ rLns.Count()-1 ]->GetFrmFmt(),
+ aBoxFmts.Count(), 0 );
+ pNewLine->ClaimFrmFmt();
+ pNewLine->GetFrmFmt()->ResetFmtAttr( RES_FRM_SIZE );
+ rLns.C40_INSERT( SwTableLine, pNewLine, rLns.Count() );
+ }
+ bNewTbl = FALSE;
+ }
+ else
+ {
+ bForceNewTable = false;
+ const SwTable *pTable =
+ pDoc->InsertTable(
+ SwInsertTableOptions( tabopts::HEADLINE_NO_BORDER, 0 ),
+ *pPam->GetPoint(), 1, 1, eAdjust, 0, 0, FALSE, FALSE );
+ bContainsTablePara=true; //#117881#
+ pTableNode = pTable ? pTable->GetTableNode() : 0;
+
+ if (pTableNode)
+ {
+ maSegments.PrependedInlineNode(*pPam->GetPoint(),
+ *pTableNode);
+ }
+ else
+ {
+ SkipToken( -1 ); // zum Letzen gueltigen zurueck
+ return;
+ }
+
+ SwTableLines& rLns = pTableNode->GetTable().GetTabLines();
+ pNewLine = rLns[ rLns.Count()-1 ];
+
+ SwFrmFmt* pFmt = pTableNode->GetTable().GetFrmFmt();
+ SwFmtFrmSize aSz( pFmt->GetFrmSize() );
+ aSz.SetWidth( nTblSz );
+ ((SfxItemSet&)pFmt->GetAttrSet()).Put( aSz );
+ ((SfxItemSet&)pFmt->GetAttrSet()).Put(SvxFrameDirectionItem(eDir, RES_FRAMEDIR));
+
+ if( text::HoriOrientation::LEFT_AND_WIDTH == eAdjust && nLSpace )
+ {
+ SvxLRSpaceItem aL( RES_LR_SPACE ); aL.SetLeft( nLSpace );
+ ((SfxItemSet&)pFmt->GetAttrSet()).Put( aL );
+ }
+
+ nAktBox = 0;
+ pOldTblNd = pTableNode;
+
+ {
+ // JP 13.08.98: TabellenUmrandungen optimieren - Bug 53525
+ void* p = pFmt;
+ aTblFmts.Insert( p, aTblFmts.Count() );
+ }
+ }
+ }
+
+ if( nLineHeight )
+ {
+ SwFrmSize eSize;
+ if( 0 > nLineHeight )
+ eSize = ATT_FIX_SIZE, nLineHeight = -nLineHeight;
+ else
+ eSize = ATT_MIN_SIZE;
+ pNewLine->ClaimFrmFmt()->SetFmtAttr(SwFmtFrmSize(eSize, 0, nLineHeight));
+ }
+
+ pNewLine->ClaimFrmFmt()->SetFmtAttr(SwFmtRowSplit(!bCantSplit));
+
+ if( aBoxFmts.Count() )
+ {
+ // setze das default Style
+ SwTxtFmtColl* pColl = aTxtCollTbl.Get( 0 );
+ if( !pColl )
+ pColl = pDoc->GetTxtCollFromPool( RES_POOLCOLL_STANDARD, false );
+
+ USHORT nStt = 0;
+ if( bNewTbl )
+ {
+ SwTableBox* pBox = pNewLine->GetTabBoxes()[0];
+ pBoxFmt = (SwTableBoxFmt*)pBox->GetFrmFmt();
+ pBoxFmt->Remove( pBox );
+ delete pBoxFmt;
+ aBoxFmts[0]->Add( pBox );
+ SwTxtNode* pTNd = pDoc->GetNodes()[ pBox->GetSttIdx()+1 ]
+ ->GetTxtNode();
+ ASSERT( pTNd, "wo ist der Textnode dieser Box?" );
+ pTNd->ChgFmtColl( pColl );
+ ++nStt;
+ nRowsToRepeat=0;
+ }
+
+ for( ; nStt < aBoxFmts.Count(); ++nStt )
+ {
+ pDoc->GetNodes().InsBoxen( pTableNode, pNewLine,
+ aBoxFmts[ nStt ],
+ // Formate fuer den TextNode der Box
+ pColl, 0,
+ nAktBox + nStt, 1 );
+ }
+ }
+
+ if( bChkExistTbl )
+ nAktBox = 0;
+
+ maInsertedTables.InsertTable(*pTableNode, *pPam);
+
+ SwNodeIndex aOldIdx(pPam->GetPoint()->nNode);
+ SwNodeIdx aOldPos(aOldIdx);
+ SwPaM aRg(*pPam);
+
+ bool bFailure = true;
+ if (pNewLine)
+ {
+ SwTableBoxes &rBoxes = pNewLine->GetTabBoxes();
+ if (SwTableBox* pBox = (nAktBox < rBoxes.Count() ? rBoxes[nAktBox] : 0))
+ {
+ if (const SwStartNode *pStart = pBox->GetSttNd())
+ {
+ if (const SwEndNode *pEnd = pStart->EndOfSectionNode())
+ {
+ pPam->GetPoint()->nNode = *pEnd;
+ pPam->Move( fnMoveBackward, fnGoCntnt );
+ bFailure = false;
+ }
+ }
+ }
+ }
+
+ ASSERT(!bFailure, "RTF Table failure");
+ if (bFailure)
+ {
+ SkipToken( -1 ); // zum Letzen gueltigen zurueck
+ return;
+ }
+
+ //It might be that there was content at this point which is not already in
+ //a table, but which is being followed by properties to place it into the
+ //table. e.g. #109199#. If this is the case then move the para/char
+ //properties inside the table, and move any content of that paragraph into
+ //the table
+ bool bInTable = aRg.GetPoint()->nNode.GetNode().FindTableNode();
+ if (!bInTable)
+ {
+ SwNodeIndex aNewIdx(pPam->GetPoint()->nNode);
+ SwNodeIdx aNewPos(aNewIdx);
+
+ if (aRg.GetPoint()->nContent.GetIndex())
+ {
+ //If there is content in this node then move it entirely inside the
+ //table
+ aRg.SetMark();
+ aRg.GetMark()->nContent.Assign(aRg.GetCntntNode(), 0);
+ pDoc->MoveRange(aRg, *pPam->GetPoint(),
+ IDocumentContentOperations::DOC_MOVEDEFAULT);
+ }
+
+ //Update the attribute stack entries to reflect that the properties
+ //which were intended to be inside the tablerow are now left outside
+ //the table after the row was placed before the current insertion point
+ SvxRTFItemStack& rAttrStk = GetAttrStack();
+ for (USHORT n = 0; n < rAttrStk.Count(); ++n)
+ {
+ SvxRTFItemStackType* pStk = rAttrStk[n];
+ pStk->MoveFullNode(aOldPos, aNewPos);
+ }
+ }
+ SkipToken( -1 ); // zum Letzen gueltigen zurueck
+}
+
+// in die naechste Box dieser Line (opt.: falls es nicht die letzte ist)
+void SwRTFParser::GotoNextBox()
+{
+ nInsTblRow = USHRT_MAX;
+
+ ASSERT( pTableNode, "Kein Tabellennode, dann auch keine Box" );
+
+ if (!pTableNode)
+ return;
+
+ SwTableLines& rLns = pTableNode->GetTable().GetTabLines();
+ SwTableLine* pLine = rLns[ rLns.Count()-1 ];
+ SwTableBoxes& rBoxes = pLine->GetTabBoxes();
+ SwTableBox* pBox = rBoxes[ rBoxes.Count()-1 ];
+
+ if( ++nAktBox >= aMergeBoxes.Count() )
+ nAktBox = aMergeBoxes.Count()-1;
+
+ if( !aMergeBoxes[ nAktBox ] )
+ {
+ int bMove = TRUE;
+ if( pBox->GetSttIdx() > pPam->GetPoint()->nNode.GetIndex() )
+ {
+ USHORT nRealBox = 0;
+ for( USHORT nTmp = 0; nTmp < nAktBox; ++nTmp )
+ if( !aMergeBoxes[ nTmp ] )
+ ++nRealBox;
+
+ if( nRealBox < rBoxes.Count() )
+ {
+ pPam->GetPoint()->nNode = *rBoxes[ nRealBox ]->GetSttNd()->EndOfSectionNode();
+ pPam->Move( fnMoveBackward, fnGoCntnt );
+ bMove = FALSE;
+ }
+ }
+
+ if( bMove && nAktBox + 1 == aMergeBoxes.Count() )
+ // dann hinter die Tabelle
+ pPam->Move( fnMoveForward, fnGoNode );
+ }
+ else if( !pDoc->GetNodes()[ pPam->GetPoint()->nNode ]->IsCntntNode() )
+ // dann in die vorherige ans Ende
+ pPam->Move( fnMoveBackward, fnGoCntnt );
+}
+
+
+void SwRTFParser::NewTblLine()
+{
+ nInsTblRow = USHRT_MAX;
+
+ // erweiter die aktuelle um eine neue Line
+ BOOL bMakeCopy = FALSE;
+ SwNode* pNd = pDoc->GetNodes()[ pPam->GetPoint()->nNode.GetIndex()-1 ];
+ if( !pNd->IsEndNode() ||
+ !(pNd = pNd->StartOfSectionNode())->IsTableNode() )
+ {
+ if( !pOldTblNd )
+ return ;
+
+ bMakeCopy = TRUE;
+ pNd = pOldTblNd;
+ }
+ pTableNode = (SwTableNode*)pNd;
+
+ SwTableLines* pLns = &pTableNode->GetTable().GetTabLines();
+ SwTableLine* pLine = (*pLns)[ pLns->Count()-1 ];
+ SwTableBoxes& rBoxes = pLine->GetTabBoxes();
+ SwTableBox* pBox = rBoxes[ rBoxes.Count()-1 ];
+
+ if(nRowsToRepeat>0)
+ pTableNode->GetTable().SetRowsToRepeat( nRowsToRepeat );
+
+ if( !bMakeCopy &&
+ 64000 < pTableNode->GetTable().GetTabSortBoxes().Count() )
+ {
+ bMakeCopy = TRUE; // spaetestens jetzt eine neue anfangen!
+ }
+
+ if( bMakeCopy )
+ {
+ // und die Selektion kopieren
+ SwSelBoxes aBoxes;
+ pTableNode->GetTable().SelLineFromBox( pBox, aBoxes );
+ pTableNode->GetTable().MakeCopy( pDoc, *pPam->GetPoint(),
+ aBoxes, FALSE );
+ ULONG nNd = pPam->GetPoint()->nNode.GetIndex()-1;
+ pTableNode = pDoc->GetNodes()[ nNd ]->FindTableNode();
+ pOldTblNd = pTableNode;
+
+ nRowsToRepeat=0;
+ pTableNode->GetTable().SetRowsToRepeat(nRowsToRepeat);
+ pLns = &pTableNode->GetTable().GetTabLines();
+ }
+ else
+// pDoc->InsertRow( aBoxes );
+ pTableNode->GetTable().AppendRow( pDoc );
+
+ pBox = (*pLns)[ pLns->Count()-1 ]->GetTabBoxes()[0];
+
+ ULONG nOldPos = pPam->GetPoint()->nNode.GetIndex();
+ pPam->GetPoint()->nNode = *pBox->GetSttNd();
+ pPam->Move( fnMoveForward );
+ nAktBox = 0;
+
+ // alle Nodes in den Boxen auf die "default" Vorlage setzten
+ {
+ SwTxtFmtColl* pColl = aTxtCollTbl.Get( 0 );
+ if( !pColl )
+ pColl = pDoc->GetTxtCollFromPool( RES_POOLCOLL_STANDARD, false );
+ pPam->SetMark();
+
+ pLine = (*pLns)[ pLns->Count()-1 ];
+ pBox = pLine->GetTabBoxes()[ pLine->GetTabBoxes().Count() -1 ];
+ pPam->GetPoint()->nNode = *pBox->GetSttNd()->EndOfSectionNode();
+ pPam->Move( fnMoveBackward );
+ pDoc->SetTxtFmtColl( *pPam, pColl );
+ // Bug 73940 - remove ALL attributes (NumRules/Break/etc.)
+ {
+ SwNodeIndex aIdx( pPam->GetMark()->nNode );
+ SwNodeIndex& rEndIdx = pPam->GetPoint()->nNode;
+ while( aIdx <= rEndIdx )
+ {
+ SwCntntNode* pCNd = aIdx.GetNode().GetCntntNode();
+ if( pCNd && pCNd->HasSwAttrSet() )
+ pCNd->ResetAllAttr();
+ aIdx++;
+ }
+ }
+ pPam->Exchange();
+ pPam->DeleteMark();
+ }
+
+ // alle Attribute, die schon auf den nachfolgen zeigen auf die neue
+ // Box umsetzen !!
+ SvxRTFItemStack& rAttrStk = GetAttrStack();
+ const SvxRTFItemStackType* pStk;
+ for( USHORT n = 0; n < rAttrStk.Count(); ++n )
+ if( ( pStk = rAttrStk[ n ])->GetSttNodeIdx() == ULONG(nOldPos) &&
+ !pStk->GetSttCnt() )
+ ((SvxRTFItemStackType*)pStk)->SetStartPos( SwxPosition( pPam ) );
+}
+
+void SwRTFParser::CheckInsNewTblLine()
+{
+ if( USHRT_MAX != nInsTblRow )
+ {
+ if( nInsTblRow > GetOpenBrakets() || IsPardTokenRead() )
+ nInsTblRow = USHRT_MAX;
+ else if( !pTableNode ) // Tabelle nicht mehr vorhanden ?
+ NewTblLine(); // evt. Line copieren
+ }
+}
+
+/* vi:set tabstop=4 shiftwidth=4 expandtab: */