1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: tablertfimporter.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svx.hxx"
35 #include <boost/shared_ptr.hpp>
37 #include <com/sun/star/table/XTable.hpp>
39 #include <tools/stream.hxx>
40 #include <svtools/rtftoken.h>
42 #include <svx/eeitem.hxx>
43 #include <svx/svdetc.hxx>
44 #include <svx/fhgtitem.hxx>
45 #include <svx/outlobj.hxx>
48 #include "celltypes.hxx"
49 #include "svx/svdotable.hxx"
50 #include "svx/svdoutl.hxx"
51 #include "svx/editeng.hxx"
52 #include "svx/editdata.hxx"
53 #include "svx/svdmodel.hxx"
56 using ::rtl::OUString
;
57 using namespace ::com::sun::star::uno
;
58 using namespace ::com::sun::star::table
;
59 using namespace ::com::sun::star::container
;
60 using namespace ::com::sun::star::beans
;
62 namespace sdr
{ namespace table
{
68 USHORT mnTwips
; // right border of the cell
69 sal_Int32 mnColSpan
; // MergeCell if >1, merged cells if 0
71 RTFCellDefault( SfxItemPool
* pPool
) : maItemSet( *pPool
), mnCol(0), mnTwips(0 ), mnColSpan(1) {}
74 typedef std::vector
< boost::shared_ptr
< RTFCellDefault
> > RTFCellDefaultVector
;
79 sal_Int32 mnStartPara
;
80 sal_Int32 mnParaCount
;
83 RTFCellInfo( SfxItemPool
& rPool
) : maItemSet( rPool
), mnStartPara(0), mnParaCount(0), mnColSpan(0) {}
86 typedef boost::shared_ptr
< RTFCellInfo
> RTFCellInfoPtr
;
87 typedef std::vector
< RTFCellInfoPtr
> RTFColumnVector
;
89 typedef boost::shared_ptr
< RTFColumnVector
> RTFColumnVectorPtr
;
91 typedef std::vector
< RTFColumnVectorPtr
> RTFRowVector
;
93 class SdrTableRTFParser
96 SdrTableRTFParser( SdrTableObj
& rTableObj
);
99 void Read( SvStream
& rStream
);
101 void ProcToken( ImportInfo
* pInfo
);
107 void InsertCell( ImportInfo
* pInfo
);
111 DECL_LINK( RTFImportHdl
, ImportInfo
* );
114 SdrTableObj
& mrTableObj
;
115 SdrOutliner
* mpOutliner
;
116 SfxItemPool
& mrItemPool
;
118 RTFCellDefaultVector maDefaultList
;
119 RTFCellDefaultVector::iterator maDefaultIterator
;
122 sal_Int32 mnLastWidth
;
131 std::vector
< sal_Int32
> maColumnEdges
;
135 RTFCellDefault
* mpInsDefault
;
136 RTFCellDefault
* mpActDefault
;
137 RTFCellDefault
* mpDefMerge
;
139 Reference
< XTable
> mxTable
;
142 SdrTableRTFParser::SdrTableRTFParser( SdrTableObj
& rTableObj
)
143 : mrTableObj( rTableObj
)
144 , mpOutliner( SdrMakeOutliner( OUTLINERMODE_TEXTOBJECT
, rTableObj
.GetModel() ) )
145 , mrItemPool( rTableObj
.GetModel()->GetItemPool() )
155 , mxTable( rTableObj
.getTable() )
157 mpOutliner
->SetUpdateMode(TRUE
);
158 mpOutliner
->SetStyleSheet( 0, mrTableObj
.GetStyleSheet() );
159 mpInsDefault
= new RTFCellDefault( &mrItemPool
);
162 SdrTableRTFParser::~SdrTableRTFParser()
168 void SdrTableRTFParser::Read( SvStream
& rStream
)
170 EditEngine
& rEdit
= const_cast< EditEngine
& >( mpOutliner
->GetEditEngine() );
172 Link
aOldLink( rEdit
.GetImportHdl() );
173 rEdit
.SetImportHdl( LINK( this, SdrTableRTFParser
, RTFImportHdl
) );
174 mpOutliner
->Read( rStream
, String(), EE_FORMAT_RTF
);
175 rEdit
.SetImportHdl( aOldLink
);
180 IMPL_LINK( SdrTableRTFParser
, RTFImportHdl
, ImportInfo
*, pInfo
)
182 switch ( pInfo
->eState
)
184 case RTFIMP_NEXTTOKEN
:
187 case RTFIMP_UNKNOWNATTR
:
192 SvxRTFParser
* pParser
= (SvxRTFParser
*) pInfo
->pParser
;
193 pParser
->SetAttrPool( &mrItemPool
);
194 RTFPardAttrMapIds
& rMap
= pParser
->GetPardMap();
195 rMap
.nBox
= SDRATTR_TABLE_BORDER
;
199 if ( pInfo
->aSelection
.nEndPos
)
202 pInfo
->nToken
= RTF_PAR
;
203 pInfo
->aSelection
.nEndPara
++;
209 case RTFIMP_INSERTTEXT
:
211 case RTFIMP_INSERTPARA
:
214 DBG_ERRORFILE("unknown ImportInfo.eState");
219 void SdrTableRTFParser::NextRow()
224 void SdrTableRTFParser::InsertCell( ImportInfo
* pInfo
)
226 sal_Int32 nCol
= mpActDefault
->mnCol
;
228 RTFCellInfoPtr
xCellInfo( new RTFCellInfo(mrItemPool
) );
230 xCellInfo
->mnStartPara
= mnStartPara
;
231 xCellInfo
->mnParaCount
= pInfo
->aSelection
.nEndPara
- 1 - mnStartPara
;
233 if( !maRows
.empty() )
235 RTFColumnVectorPtr
xColumn( maRows
.back() );
237 if( xColumn
->size() <= (size_t)nCol
)
238 xColumn
->resize( nCol
+1 );
240 (*xColumn
)[nCol
] = xCellInfo
;
243 mnStartPara
= pInfo
->aSelection
.nEndPara
- 1;
246 void SdrTableRTFParser::FillTable()
250 sal_Int32 nColCount
= mxTable
->getColumnCount();
251 Reference
< XTableColumns
> xCols( mxTable
->getColumns(), UNO_QUERY_THROW
);
253 if( nColCount
< mnColMax
)
255 xCols
->insertByIndex( nColCount
, mnColMax
- nColCount
);
256 nColCount
= mxTable
->getColumnCount();
259 const OUString
sWidth( RTL_CONSTASCII_USTRINGPARAM("Width") );
260 sal_Int32 nCol
, nLastEdge
= 0;
261 for( nCol
= 0; nCol
< nColCount
; nCol
++ )
263 Reference
< XPropertySet
> xSet( xCols
->getByIndex( nCol
), UNO_QUERY_THROW
);
264 sal_Int32 nWidth
= maColumnEdges
[nCol
] - nLastEdge
;
266 xSet
->setPropertyValue( sWidth
, Any( nWidth
) );
270 const sal_Int32 nRowCount
= mxTable
->getRowCount();
271 if( nRowCount
< mnRowCnt
)
273 Reference
< XTableRows
> xRows( mxTable
->getRows(), UNO_QUERY_THROW
);
274 xRows
->insertByIndex( nRowCount
, mnRowCnt
- nRowCount
);
277 for( sal_Int32 nRow
= 0; nRow
< (sal_Int32
)maRows
.size(); nRow
++ )
279 RTFColumnVectorPtr
xColumn( maRows
[nRow
] );
280 for( nCol
= 0; nCol
< (sal_Int32
)xColumn
->size(); nCol
++ )
282 RTFCellInfoPtr
xCellInfo( (*xColumn
)[nCol
] );
284 CellRef
xCell( dynamic_cast< Cell
* >( mxTable
->getCellByPosition( nCol
, nRow
).get() ) );
285 if( xCell
.is() && xCellInfo
.get() )
287 const SfxPoolItem
*pPoolItem
= 0;
288 if( xCellInfo
->maItemSet
.GetItemState(SDRATTR_TABLE_BORDER
,FALSE
,&pPoolItem
)==SFX_ITEM_SET
)
289 xCell
->SetMergedItem( *pPoolItem
);
291 String sDebug
= mpOutliner
->GetText( mpOutliner
->GetParagraph( xCellInfo
->mnStartPara
), xCellInfo
->mnParaCount
);
293 OutlinerParaObject
* pTextObject
= mpOutliner
->CreateParaObject( (USHORT
)xCellInfo
->mnStartPara
, (USHORT
)xCellInfo
->mnParaCount
);
296 SdrOutliner
& rOutliner
=mrTableObj
.ImpGetDrawOutliner();
297 rOutliner
.SetUpdateMode(TRUE
);
298 rOutliner
.SetText( *pTextObject
);
299 mrTableObj
.NbcSetOutlinerParaObjectForText( rOutliner
.CreateParaObject(), xCell
.get() );
306 Rectangle
aRect( mrTableObj
.GetSnapRect() );
307 aRect
.nRight
= aRect
.nLeft
+ nLastEdge
;
308 mrTableObj
.NbcSetSnapRect( aRect
);
311 catch( Exception
& e
)
314 DBG_ERROR("sdr::table::SdrTableRTFParser::InsertCell(), exception caught!" );
318 void SdrTableRTFParser::NewCellRow()
324 maRows
.push_back( RTFColumnVectorPtr( new RTFColumnVector() ) );
327 maDefaultIterator
= maDefaultList
.begin();
331 DBG_ASSERT( mpActDefault
, "NewCellRow: pActDefault==0" );
334 void SdrTableRTFParser::NextColumn()
336 if( maDefaultIterator
!= maDefaultList
.end() )
337 mpActDefault
= (*maDefaultIterator
++).get();
342 long TwipsToHundMM( long nIn
)
344 long nRet
= OutputDevice::LogicToLogic( nIn
, MAP_TWIP
, MAP_100TH_MM
);
348 void SdrTableRTFParser::ProcToken( ImportInfo
* pInfo
)
350 switch ( pInfo
->nToken
)
352 case RTF_TROWD
: // denotes table row defauls, before RTF_CELLX
355 maDefaultList
.clear();
357 mnLastToken
= pInfo
->nToken
;
360 case RTF_CLMGF
: // The first cell of cells to be merged
362 mpDefMerge
= mpInsDefault
;
363 mnLastToken
= pInfo
->nToken
;
366 case RTF_CLMRG
: // A cell to be merged with the preceding cell
369 mpDefMerge
= maDefaultList
.back().get();
370 DBG_ASSERT( mpDefMerge
, "RTF_CLMRG: pDefMerge==0" );
372 mpDefMerge
->mnColSpan
++;
373 mpInsDefault
->mnColSpan
= 0;
374 mnLastToken
= pInfo
->nToken
;
377 case RTF_CELLX
: // closes cell default
380 mpInsDefault
->mnCol
= mnColCnt
;
381 maDefaultList
.push_back( boost::shared_ptr
< RTFCellDefault
>( mpInsDefault
) );
383 if( (sal_Int32
)maColumnEdges
.size() <= mnColCnt
)
384 maColumnEdges
.resize( mnColCnt
+ 1 );
386 const sal_Int32 nSize
= TwipsToHundMM( pInfo
->nTokenValue
);
387 maColumnEdges
[mnColCnt
] = std::max( maColumnEdges
[mnColCnt
], nSize
);
389 mpInsDefault
= new RTFCellDefault( &mrItemPool
);
390 if ( ++mnColCnt
> mnColMax
)
392 mnLastToken
= pInfo
->nToken
;
395 case RTF_INTBL
: // before the first RTF_CELL
397 if ( mnLastToken
!= RTF_INTBL
&& mnLastToken
!= RTF_CELL
&& mnLastToken
!= RTF_PAR
)
400 mnLastToken
= pInfo
->nToken
;
404 case RTF_CELL
: // denotes the end of a cell.
406 DBG_ASSERT( mpActDefault
, "RTF_CELL: pActDefault==0" );
407 if ( mbNewDef
|| !mpActDefault
)
410 mpActDefault
= mpInsDefault
;
411 if ( mpActDefault
->mnColSpan
> 0 )
416 mnLastToken
= pInfo
->nToken
;
419 case RTF_ROW
: // means the end of a row
422 mnLastToken
= pInfo
->nToken
;
425 case RTF_PAR
: // Paragraph
426 mnLastToken
= pInfo
->nToken
;
429 { // do not set nLastToken
430 switch ( pInfo
->nToken
& ~(0xff | RTF_TABLEDEF
) )
433 // ((SvxRTFParser*)pInfo->pParser)->ReadBackgroundAttr(pInfo->nToken, mpInsDefault->maItemSet, TRUE );
436 ((SvxRTFParser
*)pInfo
->pParser
)->ReadBorderAttr(pInfo
->nToken
, mpInsDefault
->maItemSet
, TRUE
);
443 void SdrTableObj::ImportAsRTF( SvStream
& rStream
, SdrTableObj
& rObj
)
445 SdrTableRTFParser
aParser( rObj
);
446 aParser
.Read( rStream
);