Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include <vector>
31 : : #include <boost/shared_ptr.hpp>
32 : :
33 : : #include <com/sun/star/table/XTable.hpp>
34 : :
35 : : #include <tools/stream.hxx>
36 : : #include <svtools/rtftoken.h>
37 : :
38 : : #include <editeng/eeitem.hxx>
39 : : #include <svx/svdetc.hxx>
40 : : #include <editeng/fhgtitem.hxx>
41 : : #include <editeng/outlobj.hxx>
42 : :
43 : : #include "cell.hxx"
44 : : #include "celltypes.hxx"
45 : : #include "svx/svdotable.hxx"
46 : : #include "svx/svdoutl.hxx"
47 : : #include "editeng/editeng.hxx"
48 : : #include "editeng/editdata.hxx"
49 : : #include "svx/svdmodel.hxx"
50 : : #include "editeng/svxrtf.hxx"
51 : :
52 : : using ::rtl::OUString;
53 : : using namespace ::com::sun::star::uno;
54 : : using namespace ::com::sun::star::table;
55 : : using namespace ::com::sun::star::container;
56 : : using namespace ::com::sun::star::beans;
57 : :
58 : : namespace sdr { namespace table {
59 : :
60 : 0 : struct RTFCellDefault
61 : : {
62 : : SfxItemSet maItemSet;
63 : : sal_Int32 mnCol;
64 : : sal_uInt16 mnTwips; // right border of the cell
65 : : sal_Int32 mnColSpan; // MergeCell if >1, merged cells if 0
66 : :
67 : 0 : RTFCellDefault( SfxItemPool* pPool ) : maItemSet( *pPool ), mnCol(0), mnTwips(0 ), mnColSpan(1) {}
68 : : };
69 : :
70 : : typedef std::vector< boost::shared_ptr< RTFCellDefault > > RTFCellDefaultVector;
71 : :
72 : 0 : struct RTFCellInfo
73 : : {
74 : : SfxItemSet maItemSet;
75 : : sal_Int32 mnStartPara;
76 : : sal_Int32 mnParaCount;
77 : : sal_Int32 mnColSpan;
78 : :
79 : 0 : RTFCellInfo( SfxItemPool& rPool ) : maItemSet( rPool ), mnStartPara(0), mnParaCount(0), mnColSpan(0) {}
80 : : };
81 : :
82 : : typedef boost::shared_ptr< RTFCellInfo > RTFCellInfoPtr;
83 : : typedef std::vector< RTFCellInfoPtr > RTFColumnVector;
84 : :
85 : : typedef boost::shared_ptr< RTFColumnVector > RTFColumnVectorPtr;
86 : :
87 : : typedef std::vector< RTFColumnVectorPtr > RTFRowVector;
88 : :
89 : : class SdrTableRTFParser
90 : : {
91 : : public:
92 : : SdrTableRTFParser( SdrTableObj& rTableObj );
93 : : ~SdrTableRTFParser();
94 : :
95 : : void Read( SvStream& rStream );
96 : :
97 : : void ProcToken( ImportInfo* pInfo );
98 : :
99 : : void NextRow();
100 : : void NextColumn();
101 : : void NewCellRow();
102 : :
103 : : void InsertCell( ImportInfo* pInfo );
104 : :
105 : : void FillTable();
106 : :
107 : : DECL_LINK( RTFImportHdl, ImportInfo* );
108 : :
109 : : private:
110 : : SdrTableObj& mrTableObj;
111 : : SdrOutliner* mpOutliner;
112 : : SfxItemPool& mrItemPool;
113 : :
114 : : RTFCellDefaultVector maDefaultList;
115 : : RTFCellDefaultVector::iterator maDefaultIterator;
116 : :
117 : : int mnLastToken;
118 : : bool mbNewDef;
119 : :
120 : : sal_uInt16 mnStartPara;
121 : :
122 : : sal_Int32 mnColCnt;
123 : : sal_Int32 mnRowCnt;
124 : : sal_Int32 mnColMax;
125 : :
126 : : std::vector< sal_Int32 > maColumnEdges;
127 : :
128 : : RTFRowVector maRows;
129 : :
130 : : RTFCellDefault* mpInsDefault;
131 : : RTFCellDefault* mpActDefault;
132 : : RTFCellDefault* mpDefMerge;
133 : :
134 : : Reference< XTable > mxTable;
135 : : };
136 : :
137 : 0 : SdrTableRTFParser::SdrTableRTFParser( SdrTableObj& rTableObj )
138 : : : mrTableObj( rTableObj )
139 : 0 : , mpOutliner( SdrMakeOutliner( OUTLINERMODE_TEXTOBJECT, rTableObj.GetModel() ) )
140 : 0 : , mrItemPool( rTableObj.GetModel()->GetItemPool() )
141 : : , mnLastToken( 0 )
142 : : , mbNewDef( false )
143 : : , mnStartPara( 0 )
144 : : , mnColCnt( 0 )
145 : : , mnRowCnt( 0 )
146 : : , mnColMax( 0 )
147 : : , mpActDefault( 0 )
148 : : , mpDefMerge( 0 )
149 [ # # ][ # # ]: 0 : , mxTable( rTableObj.getTable() )
[ # # ]
150 : : {
151 [ # # ]: 0 : mpOutliner->SetUpdateMode(sal_True);
152 [ # # ][ # # ]: 0 : mpOutliner->SetStyleSheet( 0, mrTableObj.GetStyleSheet() );
153 [ # # ][ # # ]: 0 : mpInsDefault = new RTFCellDefault( &mrItemPool );
154 : 0 : }
155 : :
156 : 0 : SdrTableRTFParser::~SdrTableRTFParser()
157 : : {
158 [ # # ][ # # ]: 0 : delete mpOutliner;
159 [ # # ][ # # ]: 0 : delete mpInsDefault;
160 : 0 : }
161 : :
162 : 0 : void SdrTableRTFParser::Read( SvStream& rStream )
163 : : {
164 : 0 : EditEngine& rEdit = const_cast< EditEngine& >( mpOutliner->GetEditEngine() );
165 : :
166 [ # # ]: 0 : Link aOldLink( rEdit.GetImportHdl() );
167 [ # # ][ # # ]: 0 : rEdit.SetImportHdl( LINK( this, SdrTableRTFParser, RTFImportHdl ) );
168 [ # # ][ # # ]: 0 : mpOutliner->Read( rStream, String(), EE_FORMAT_RTF );
[ # # ]
169 [ # # ]: 0 : rEdit.SetImportHdl( aOldLink );
170 : :
171 [ # # ]: 0 : FillTable();
172 : 0 : }
173 : :
174 : 0 : IMPL_LINK( SdrTableRTFParser, RTFImportHdl, ImportInfo*, pInfo )
175 : : {
176 [ # # # # : 0 : switch ( pInfo->eState )
# # # # ]
177 : : {
178 : : case RTFIMP_NEXTTOKEN:
179 : 0 : ProcToken( pInfo );
180 : 0 : break;
181 : : case RTFIMP_UNKNOWNATTR:
182 : 0 : ProcToken( pInfo );
183 : 0 : break;
184 : : case RTFIMP_START:
185 : : {
186 : 0 : SvxRTFParser* pParser = (SvxRTFParser*) pInfo->pParser;
187 : 0 : pParser->SetAttrPool( &mrItemPool );
188 : 0 : RTFPardAttrMapIds& rMap = pParser->GetPardMap();
189 : 0 : rMap.nBox = SDRATTR_TABLE_BORDER;
190 : : }
191 : 0 : break;
192 : : case RTFIMP_END:
193 [ # # ]: 0 : if ( pInfo->aSelection.nEndPos )
194 : : {
195 : 0 : mpActDefault = NULL;
196 : 0 : pInfo->nToken = RTF_PAR;
197 : 0 : pInfo->aSelection.nEndPara++;
198 : 0 : ProcToken( pInfo );
199 : : }
200 : 0 : break;
201 : : case RTFIMP_SETATTR:
202 : 0 : break;
203 : : case RTFIMP_INSERTTEXT:
204 : 0 : break;
205 : : case RTFIMP_INSERTPARA:
206 : 0 : break;
207 : : default:
208 : : SAL_WARN( "svx.table","unknown ImportInfo.eState");
209 : : }
210 : 0 : return 0;
211 : : }
212 : :
213 : 0 : void SdrTableRTFParser::NextRow()
214 : : {
215 : 0 : ++mnRowCnt;
216 : 0 : }
217 : :
218 : 0 : void SdrTableRTFParser::InsertCell( ImportInfo* pInfo )
219 : : {
220 : 0 : sal_Int32 nCol = mpActDefault->mnCol;
221 : :
222 [ # # ][ # # ]: 0 : RTFCellInfoPtr xCellInfo( new RTFCellInfo(mrItemPool) );
[ # # ]
223 : :
224 : 0 : xCellInfo->mnStartPara = mnStartPara;
225 : 0 : xCellInfo->mnParaCount = pInfo->aSelection.nEndPara - 1 - mnStartPara;
226 : :
227 [ # # ]: 0 : if( !maRows.empty() )
228 : : {
229 [ # # ][ # # ]: 0 : RTFColumnVectorPtr xColumn( maRows.back() );
230 : :
231 [ # # ]: 0 : if( xColumn->size() <= (size_t)nCol )
232 [ # # ]: 0 : xColumn->resize( nCol+1 );
233 : :
234 [ # # ][ # # ]: 0 : (*xColumn)[nCol] = xCellInfo;
235 : : }
236 : :
237 [ # # ]: 0 : mnStartPara = pInfo->aSelection.nEndPara - 1;
238 : 0 : }
239 : :
240 : 0 : void SdrTableRTFParser::FillTable()
241 : : {
242 : : try
243 : : {
244 [ # # ][ # # ]: 0 : sal_Int32 nColCount = mxTable->getColumnCount();
245 [ # # ][ # # ]: 0 : Reference< XTableColumns > xCols( mxTable->getColumns(), UNO_QUERY_THROW );
[ # # ]
246 : :
247 [ # # ]: 0 : if( nColCount < mnColMax )
248 : : {
249 [ # # ][ # # ]: 0 : xCols->insertByIndex( nColCount, mnColMax - nColCount );
250 [ # # ][ # # ]: 0 : nColCount = mxTable->getColumnCount();
251 : : }
252 : :
253 [ # # ]: 0 : const OUString sWidth( RTL_CONSTASCII_USTRINGPARAM("Width") );
254 : 0 : sal_Int32 nCol, nLastEdge = 0;
255 [ # # ]: 0 : for( nCol = 0; nCol < nColCount; nCol++ )
256 : : {
257 [ # # ][ # # ]: 0 : Reference< XPropertySet > xSet( xCols->getByIndex( nCol ), UNO_QUERY_THROW );
[ # # ]
258 [ # # ]: 0 : sal_Int32 nWidth = maColumnEdges[nCol] - nLastEdge;
259 : :
260 [ # # ][ # # ]: 0 : xSet->setPropertyValue( sWidth, Any( nWidth ) );
[ # # ]
261 : 0 : nLastEdge += nWidth;
262 : 0 : }
263 : :
264 [ # # ][ # # ]: 0 : const sal_Int32 nRowCount = mxTable->getRowCount();
265 [ # # ]: 0 : if( nRowCount < mnRowCnt )
266 : : {
267 [ # # ][ # # ]: 0 : Reference< XTableRows > xRows( mxTable->getRows(), UNO_QUERY_THROW );
[ # # ]
268 [ # # ][ # # ]: 0 : xRows->insertByIndex( nRowCount, mnRowCnt - nRowCount );
269 : : }
270 : :
271 [ # # ]: 0 : for( sal_Int32 nRow = 0; nRow < (sal_Int32)maRows.size(); nRow++ )
272 : : {
273 [ # # ]: 0 : RTFColumnVectorPtr xColumn( maRows[nRow] );
274 [ # # ]: 0 : for( nCol = 0; nCol < (sal_Int32)xColumn->size(); nCol++ )
275 : : {
276 [ # # ]: 0 : RTFCellInfoPtr xCellInfo( (*xColumn)[nCol] );
277 : :
278 [ # # ][ # # ]: 0 : CellRef xCell( dynamic_cast< Cell* >( mxTable->getCellByPosition( nCol, nRow ).get() ) );
[ # # ][ # # ]
279 [ # # ][ # # ]: 0 : if( xCell.is() && xCellInfo.get() )
[ # # ]
280 : : {
281 : 0 : const SfxPoolItem *pPoolItem = 0;
282 [ # # ][ # # ]: 0 : if( xCellInfo->maItemSet.GetItemState(SDRATTR_TABLE_BORDER,sal_False,&pPoolItem)==SFX_ITEM_SET)
283 [ # # ]: 0 : xCell->SetMergedItem( *pPoolItem );
284 : :
285 [ # # ][ # # ]: 0 : String sDebug = mpOutliner->GetText( mpOutliner->GetParagraph( xCellInfo->mnStartPara ), xCellInfo->mnParaCount );
286 : :
287 [ # # ]: 0 : OutlinerParaObject* pTextObject = mpOutliner->CreateParaObject( (sal_uInt16)xCellInfo->mnStartPara, (sal_uInt16)xCellInfo->mnParaCount );
288 [ # # ]: 0 : if( pTextObject )
289 : : {
290 [ # # ]: 0 : SdrOutliner& rOutliner=mrTableObj.ImpGetDrawOutliner();
291 [ # # ]: 0 : rOutliner.SetUpdateMode(sal_True);
292 [ # # ]: 0 : rOutliner.SetText( *pTextObject );
293 [ # # ][ # # ]: 0 : mrTableObj.NbcSetOutlinerParaObjectForText( rOutliner.CreateParaObject(), xCell.get() );
294 [ # # ][ # # ]: 0 : delete pTextObject;
295 [ # # ]: 0 : }
296 : : }
297 [ # # ]: 0 : }
298 [ # # ]: 0 : }
299 : :
300 [ # # ]: 0 : Rectangle aRect( mrTableObj.GetSnapRect() );
301 : 0 : aRect.nRight = aRect.nLeft + nLastEdge;
302 [ # # ][ # # ]: 0 : mrTableObj.NbcSetSnapRect( aRect );
303 : :
304 : : }
305 : 0 : catch( Exception& e )
306 : : {
307 : : (void)e;
308 : : OSL_FAIL("sdr::table::SdrTableRTFParser::InsertCell(), exception caught!" );
309 : : }
310 : 0 : }
311 : :
312 : 0 : void SdrTableRTFParser::NewCellRow()
313 : : {
314 [ # # ]: 0 : if( mbNewDef )
315 : : {
316 : 0 : mbNewDef = sal_False;
317 : :
318 [ # # ][ # # ]: 0 : maRows.push_back( RTFColumnVectorPtr( new RTFColumnVector() ) );
319 : : }
320 : 0 : mpDefMerge = NULL;
321 : 0 : maDefaultIterator = maDefaultList.begin();
322 : :
323 : 0 : NextColumn();
324 : :
325 : : DBG_ASSERT( mpActDefault, "NewCellRow: pActDefault==0" );
326 : 0 : }
327 : :
328 : 0 : void SdrTableRTFParser::NextColumn()
329 : : {
330 [ # # ][ # # ]: 0 : if( maDefaultIterator != maDefaultList.end() )
331 : 0 : mpActDefault = (*maDefaultIterator++).get();
332 : : else
333 : 0 : mpActDefault = 0;
334 : 0 : }
335 : :
336 : 0 : long TwipsToHundMM( long nIn )
337 : : {
338 : 0 : long nRet = OutputDevice::LogicToLogic( nIn, MAP_TWIP, MAP_100TH_MM );
339 : 0 : return nRet;
340 : : }
341 : :
342 : 0 : void SdrTableRTFParser::ProcToken( ImportInfo* pInfo )
343 : : {
344 [ # # # # : 0 : switch ( pInfo->nToken )
# # # #
# ]
345 : : {
346 : : case RTF_TROWD: // denotes table row defauls, before RTF_CELLX
347 : : {
348 : 0 : mnColCnt = 0;
349 : 0 : maDefaultList.clear();
350 : 0 : mpDefMerge = NULL;
351 : 0 : mnLastToken = pInfo->nToken;
352 : : }
353 : 0 : break;
354 : : case RTF_CLMGF: // The first cell of cells to be merged
355 : : {
356 : 0 : mpDefMerge = mpInsDefault;
357 : 0 : mnLastToken = pInfo->nToken;
358 : : }
359 : 0 : break;
360 : : case RTF_CLMRG: // A cell to be merged with the preceding cell
361 : : {
362 [ # # ]: 0 : if ( !mpDefMerge )
363 : 0 : mpDefMerge = maDefaultList.back().get();
364 : : DBG_ASSERT( mpDefMerge, "RTF_CLMRG: pDefMerge==0" );
365 [ # # ]: 0 : if( mpDefMerge )
366 : 0 : mpDefMerge->mnColSpan++;
367 : 0 : mpInsDefault->mnColSpan = 0;
368 : 0 : mnLastToken = pInfo->nToken;
369 : : }
370 : 0 : break;
371 : : case RTF_CELLX: // closes cell default
372 : : {
373 : 0 : mbNewDef = sal_True;
374 : 0 : mpInsDefault->mnCol = mnColCnt;
375 [ # # ][ # # ]: 0 : maDefaultList.push_back( boost::shared_ptr< RTFCellDefault >( mpInsDefault ) );
[ # # ]
376 : :
377 [ # # ]: 0 : if( (sal_Int32)maColumnEdges.size() <= mnColCnt )
378 [ # # ]: 0 : maColumnEdges.resize( mnColCnt + 1 );
379 : :
380 [ # # ]: 0 : const sal_Int32 nSize = TwipsToHundMM( pInfo->nTokenValue );
381 [ # # ][ # # ]: 0 : maColumnEdges[mnColCnt] = std::max( maColumnEdges[mnColCnt], nSize );
[ # # ]
382 : :
383 [ # # ][ # # ]: 0 : mpInsDefault = new RTFCellDefault( &mrItemPool );
384 [ # # ]: 0 : if ( ++mnColCnt > mnColMax )
385 : 0 : mnColMax = mnColCnt;
386 : 0 : mnLastToken = pInfo->nToken;
387 : : }
388 : 0 : break;
389 : : case RTF_INTBL: // before the first RTF_CELL
390 : : {
391 [ # # ][ # # ]: 0 : if ( mnLastToken != RTF_INTBL && mnLastToken != RTF_CELL && mnLastToken != RTF_PAR )
[ # # ]
392 : : {
393 : 0 : NewCellRow();
394 : 0 : mnLastToken = pInfo->nToken;
395 : : }
396 : : }
397 : 0 : break;
398 : : case RTF_CELL: // denotes the end of a cell.
399 : : {
400 : : DBG_ASSERT( mpActDefault, "RTF_CELL: pActDefault==0" );
401 [ # # ][ # # ]: 0 : if ( mbNewDef || !mpActDefault )
402 : 0 : NewCellRow();
403 [ # # ]: 0 : if ( !mpActDefault )
404 : 0 : mpActDefault = mpInsDefault;
405 [ # # ]: 0 : if ( mpActDefault->mnColSpan > 0 )
406 : : {
407 : 0 : InsertCell(pInfo);
408 : : }
409 : 0 : NextColumn();
410 : 0 : mnLastToken = pInfo->nToken;
411 : : }
412 : 0 : break;
413 : : case RTF_ROW: // means the end of a row
414 : : {
415 : 0 : NextRow();
416 : 0 : mnLastToken = pInfo->nToken;
417 : : }
418 : 0 : break;
419 : : case RTF_PAR: // Paragraph
420 : 0 : mnLastToken = pInfo->nToken;
421 : 0 : break;
422 : : default:
423 : : { // do not set nLastToken
424 [ # # # ]: 0 : switch ( pInfo->nToken & ~(0xff | RTF_TABLEDEF) )
425 : : {
426 : : case RTF_SHADINGDEF:
427 : : // ((SvxRTFParser*)pInfo->pParser)->ReadBackgroundAttr(pInfo->nToken, mpInsDefault->maItemSet, sal_True );
428 : 0 : break;
429 : : case RTF_BRDRDEF:
430 : 0 : ((SvxRTFParser*)pInfo->pParser)->ReadBorderAttr(pInfo->nToken, mpInsDefault->maItemSet, sal_True );
431 : 0 : break;
432 : : }
433 : : }
434 : : }
435 : 0 : }
436 : :
437 : 0 : void SdrTableObj::ImportAsRTF( SvStream& rStream, SdrTableObj& rObj )
438 : : {
439 [ # # ]: 0 : SdrTableRTFParser aParser( rObj );
440 [ # # ][ # # ]: 0 : aParser.Read( rStream );
441 : 0 : }
442 : :
443 : : } }
444 : :
445 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|