update dev300-m58
[ooovba.git] / svx / source / table / tablertfimporter.cxx
blob399c6d20158e46516cf5a37585c87cc12b15564e
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: tablertfimporter.cxx,v $
10 * $Revision: 1.4 $
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"
34 #include <vector>
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>
47 #include "cell.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"
54 #include "svxrtf.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 {
64 struct RTFCellDefault
66 SfxItemSet maItemSet;
67 sal_Int32 mnCol;
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;
76 struct RTFCellInfo
78 SfxItemSet maItemSet;
79 sal_Int32 mnStartPara;
80 sal_Int32 mnParaCount;
81 sal_Int32 mnColSpan;
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
95 public:
96 SdrTableRTFParser( SdrTableObj& rTableObj );
97 ~SdrTableRTFParser();
99 void Read( SvStream& rStream );
101 void ProcToken( ImportInfo* pInfo );
103 void NextRow();
104 void NextColumn();
105 void NewCellRow();
107 void InsertCell( ImportInfo* pInfo );
109 void FillTable();
111 DECL_LINK( RTFImportHdl, ImportInfo* );
113 private:
114 SdrTableObj& mrTableObj;
115 SdrOutliner* mpOutliner;
116 SfxItemPool& mrItemPool;
118 RTFCellDefaultVector maDefaultList;
119 RTFCellDefaultVector::iterator maDefaultIterator;
121 int mnLastToken;
122 sal_Int32 mnLastWidth;
123 bool mbNewDef;
125 USHORT mnStartPara;
127 sal_Int32 mnColCnt;
128 sal_Int32 mnRowCnt;
129 sal_Int32 mnColMax;
131 std::vector< sal_Int32 > maColumnEdges;
133 RTFRowVector maRows;
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() )
146 , mnLastToken( 0 )
147 , mnLastWidth( 0 )
148 , mbNewDef( false )
149 , mnStartPara( 0 )
150 , mnColCnt( 0 )
151 , mnRowCnt( 0 )
152 , mnColMax( 0 )
153 , mpActDefault( 0 )
154 , mpDefMerge( 0 )
155 , mxTable( rTableObj.getTable() )
157 mpOutliner->SetUpdateMode(TRUE);
158 mpOutliner->SetStyleSheet( 0, mrTableObj.GetStyleSheet() );
159 mpInsDefault = new RTFCellDefault( &mrItemPool );
162 SdrTableRTFParser::~SdrTableRTFParser()
164 delete mpOutliner;
165 delete mpInsDefault;
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 );
177 FillTable();
180 IMPL_LINK( SdrTableRTFParser, RTFImportHdl, ImportInfo*, pInfo )
182 switch ( pInfo->eState )
184 case RTFIMP_NEXTTOKEN:
185 ProcToken( pInfo );
186 break;
187 case RTFIMP_UNKNOWNATTR:
188 ProcToken( pInfo );
189 break;
190 case RTFIMP_START:
192 SvxRTFParser* pParser = (SvxRTFParser*) pInfo->pParser;
193 pParser->SetAttrPool( &mrItemPool );
194 RTFPardAttrMapIds& rMap = pParser->GetPardMap();
195 rMap.nBox = SDRATTR_TABLE_BORDER;
197 break;
198 case RTFIMP_END:
199 if ( pInfo->aSelection.nEndPos )
201 mpActDefault = NULL;
202 pInfo->nToken = RTF_PAR;
203 pInfo->aSelection.nEndPara++;
204 ProcToken( pInfo );
206 break;
207 case RTFIMP_SETATTR:
208 break;
209 case RTFIMP_INSERTTEXT:
210 break;
211 case RTFIMP_INSERTPARA:
212 break;
213 default:
214 DBG_ERRORFILE("unknown ImportInfo.eState");
216 return 0;
219 void SdrTableRTFParser::NextRow()
221 ++mnRowCnt;
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 ) );
267 nLastEdge += 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 );
294 if( pTextObject )
296 SdrOutliner& rOutliner=mrTableObj.ImpGetDrawOutliner();
297 rOutliner.SetUpdateMode(TRUE);
298 rOutliner.SetText( *pTextObject );
299 mrTableObj.NbcSetOutlinerParaObjectForText( rOutliner.CreateParaObject(), xCell.get() );
300 delete pTextObject;
306 Rectangle aRect( mrTableObj.GetSnapRect() );
307 aRect.nRight = aRect.nLeft + nLastEdge;
308 mrTableObj.NbcSetSnapRect( aRect );
311 catch( Exception& e )
313 (void)e;
314 DBG_ERROR("sdr::table::SdrTableRTFParser::InsertCell(), exception caught!" );
318 void SdrTableRTFParser::NewCellRow()
320 if( mbNewDef )
322 mbNewDef = FALSE;
324 maRows.push_back( RTFColumnVectorPtr( new RTFColumnVector() ) );
326 mpDefMerge = NULL;
327 maDefaultIterator = maDefaultList.begin();
329 NextColumn();
331 DBG_ASSERT( mpActDefault, "NewCellRow: pActDefault==0" );
334 void SdrTableRTFParser::NextColumn()
336 if( maDefaultIterator != maDefaultList.end() )
337 mpActDefault = (*maDefaultIterator++).get();
338 else
339 mpActDefault = 0;
342 long TwipsToHundMM( long nIn )
344 long nRet = OutputDevice::LogicToLogic( nIn, MAP_TWIP, MAP_100TH_MM );
345 return nRet;
348 void SdrTableRTFParser::ProcToken( ImportInfo* pInfo )
350 switch ( pInfo->nToken )
352 case RTF_TROWD: // denotes table row defauls, before RTF_CELLX
354 mnColCnt = 0;
355 maDefaultList.clear();
356 mpDefMerge = NULL;
357 mnLastToken = pInfo->nToken;
359 break;
360 case RTF_CLMGF: // The first cell of cells to be merged
362 mpDefMerge = mpInsDefault;
363 mnLastToken = pInfo->nToken;
365 break;
366 case RTF_CLMRG: // A cell to be merged with the preceding cell
368 if ( !mpDefMerge )
369 mpDefMerge = maDefaultList.back().get();
370 DBG_ASSERT( mpDefMerge, "RTF_CLMRG: pDefMerge==0" );
371 if( mpDefMerge )
372 mpDefMerge->mnColSpan++;
373 mpInsDefault->mnColSpan = 0;
374 mnLastToken = pInfo->nToken;
376 break;
377 case RTF_CELLX: // closes cell default
379 mbNewDef = TRUE;
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 )
391 mnColMax = mnColCnt;
392 mnLastToken = pInfo->nToken;
394 break;
395 case RTF_INTBL: // before the first RTF_CELL
397 if ( mnLastToken != RTF_INTBL && mnLastToken != RTF_CELL && mnLastToken != RTF_PAR )
399 NewCellRow();
400 mnLastToken = pInfo->nToken;
403 break;
404 case RTF_CELL: // denotes the end of a cell.
406 DBG_ASSERT( mpActDefault, "RTF_CELL: pActDefault==0" );
407 if ( mbNewDef || !mpActDefault )
408 NewCellRow();
409 if ( !mpActDefault )
410 mpActDefault = mpInsDefault;
411 if ( mpActDefault->mnColSpan > 0 )
413 InsertCell(pInfo);
415 NextColumn();
416 mnLastToken = pInfo->nToken;
418 break;
419 case RTF_ROW: // means the end of a row
421 NextRow();
422 mnLastToken = pInfo->nToken;
424 break;
425 case RTF_PAR: // Paragraph
426 mnLastToken = pInfo->nToken;
427 break;
428 default:
429 { // do not set nLastToken
430 switch ( pInfo->nToken & ~(0xff | RTF_TABLEDEF) )
432 case RTF_SHADINGDEF:
433 // ((SvxRTFParser*)pInfo->pParser)->ReadBackgroundAttr(pInfo->nToken, mpInsDefault->maItemSet, TRUE );
434 break;
435 case RTF_BRDRDEF:
436 ((SvxRTFParser*)pInfo->pParser)->ReadBorderAttr(pInfo->nToken, mpInsDefault->maItemSet, TRUE );
437 break;
443 void SdrTableObj::ImportAsRTF( SvStream& rStream, SdrTableObj& rObj )
445 SdrTableRTFParser aParser( rObj );
446 aParser.Read( rStream );