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 : : #include "hintids.hxx"
30 : :
31 : : #include <limits.h>
32 : : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
33 : : #include <com/sun/star/text/XTextTable.hpp>
34 : : #include <com/sun/star/table/XCellRange.hpp>
35 : : #include <svl/itemset.hxx>
36 : : #include <svl/zformat.hxx>
37 : : #include <sax/tools/converter.hxx>
38 : : #include <xmloff/xmlnmspe.hxx>
39 : : #include <xmloff/xmltkmap.hxx>
40 : : #include <xmloff/nmspmap.hxx>
41 : :
42 : : #include <xmloff/families.hxx>
43 : : #include <xmloff/xmluconv.hxx>
44 : : #include <xmloff/i18nmap.hxx>
45 : : #include <editeng/protitem.hxx>
46 : : #include "poolfmt.hxx"
47 : : #include "fmtfsize.hxx"
48 : : #include "fmtornt.hxx"
49 : : #include "fmtfordr.hxx"
50 : : #include "doc.hxx"
51 : : #include "swtable.hxx"
52 : : #include "swtblfmt.hxx"
53 : : #include "pam.hxx"
54 : : #include "unotbl.hxx"
55 : : #include "unotextrange.hxx"
56 : : #include "unocrsr.hxx"
57 : : #include "cellatr.hxx"
58 : : #include "swddetbl.hxx"
59 : : #include "ddefld.hxx"
60 : : #include <sfx2/linkmgr.hxx> // for cTokenSeparator
61 : : #include "xmlimp.hxx"
62 : : #include "xmltbli.hxx"
63 : :
64 : : // for locking SolarMutex: svapp + mutex
65 : : #include <vcl/svapp.hxx>
66 : : #include <osl/mutex.hxx>
67 : : #include "ndtxt.hxx"
68 : :
69 : : using ::rtl::OUString;
70 : : using namespace ::com::sun::star;
71 : : using namespace ::com::sun::star::uno;
72 : : using namespace ::com::sun::star::lang;
73 : : using namespace ::com::sun::star::text;
74 : : using namespace ::com::sun::star::frame;
75 : : using namespace ::com::sun::star::table;
76 : : using namespace ::com::sun::star::xml::sax;
77 : : using namespace ::xmloff::token;
78 : : using ::boost::unordered_map;
79 : : using rtl::OUString;
80 : :
81 : : enum SwXMLTableElemTokens
82 : : {
83 : : XML_TOK_TABLE_HEADER_COLS,
84 : : XML_TOK_TABLE_COLS,
85 : : XML_TOK_TABLE_COL,
86 : : XML_TOK_TABLE_HEADER_ROWS,
87 : : XML_TOK_TABLE_ROWS,
88 : : XML_TOK_TABLE_ROW,
89 : : XML_TOK_OFFICE_DDE_SOURCE,
90 : : XML_TOK_TABLE_ELEM_END=XML_TOK_UNKNOWN
91 : : };
92 : :
93 : : enum SwXMLTableCellAttrTokens
94 : : {
95 : : XML_TOK_TABLE_XMLID,
96 : : XML_TOK_TABLE_STYLE_NAME,
97 : : XML_TOK_TABLE_NUM_COLS_SPANNED,
98 : : XML_TOK_TABLE_NUM_ROWS_SPANNED,
99 : : XML_TOK_TABLE_NUM_COLS_REPEATED,
100 : : XML_TOK_TABLE_FORMULA,
101 : : XML_TOK_TABLE_VALUE,
102 : : XML_TOK_TABLE_TIME_VALUE,
103 : : XML_TOK_TABLE_DATE_VALUE,
104 : : XML_TOK_TABLE_BOOLEAN_VALUE,
105 : : XML_TOK_TABLE_PROTECTED,
106 : : XML_TOK_TABLE_STRING_VALUE,
107 : : XML_TOK_TABLE_CELL_ATTR_END=XML_TOK_UNKNOWN
108 : : };
109 : :
110 : : static SvXMLTokenMapEntry aTableElemTokenMap[] =
111 : : {
112 : : { XML_NAMESPACE_TABLE, XML_TABLE_HEADER_COLUMNS,
113 : : XML_TOK_TABLE_HEADER_COLS },
114 : : { XML_NAMESPACE_TABLE, XML_TABLE_COLUMNS, XML_TOK_TABLE_COLS },
115 : : { XML_NAMESPACE_TABLE, XML_TABLE_COLUMN, XML_TOK_TABLE_COL },
116 : : { XML_NAMESPACE_TABLE, XML_TABLE_HEADER_ROWS,
117 : : XML_TOK_TABLE_HEADER_ROWS },
118 : : { XML_NAMESPACE_TABLE, XML_TABLE_ROWS, XML_TOK_TABLE_ROWS },
119 : : { XML_NAMESPACE_TABLE, XML_TABLE_ROW, XML_TOK_TABLE_ROW },
120 : : { XML_NAMESPACE_OFFICE, XML_DDE_SOURCE,
121 : : XML_TOK_OFFICE_DDE_SOURCE },
122 : :
123 : : // There are slight differences between <table:table-columns> and
124 : : // <table:table-columns-groups>. However, none of these are
125 : : // supported in Writer (they are Calc-only features), so we
126 : : // support column groups by simply using the <table:table-columns>
127 : : // token for column groups, too.
128 : : { XML_NAMESPACE_TABLE, XML_TABLE_COLUMN_GROUP, XML_TOK_TABLE_COLS },
129 : :
130 : : XML_TOKEN_MAP_END
131 : : };
132 : :
133 : : static SvXMLTokenMapEntry aTableCellAttrTokenMap[] =
134 : : {
135 : : { XML_NAMESPACE_XML, XML_ID, XML_TOK_TABLE_XMLID },
136 : : { XML_NAMESPACE_TABLE, XML_STYLE_NAME, XML_TOK_TABLE_STYLE_NAME },
137 : : { XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_SPANNED, XML_TOK_TABLE_NUM_COLS_SPANNED },
138 : : { XML_NAMESPACE_TABLE, XML_NUMBER_ROWS_SPANNED, XML_TOK_TABLE_NUM_ROWS_SPANNED },
139 : : { XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_REPEATED, XML_TOK_TABLE_NUM_COLS_REPEATED },
140 : : { XML_NAMESPACE_TABLE, XML_FORMULA, XML_TOK_TABLE_FORMULA },
141 : : { XML_NAMESPACE_OFFICE, XML_VALUE, XML_TOK_TABLE_VALUE },
142 : : { XML_NAMESPACE_OFFICE, XML_TIME_VALUE, XML_TOK_TABLE_TIME_VALUE },
143 : : { XML_NAMESPACE_OFFICE, XML_DATE_VALUE, XML_TOK_TABLE_DATE_VALUE },
144 : : { XML_NAMESPACE_OFFICE, XML_BOOLEAN_VALUE, XML_TOK_TABLE_BOOLEAN_VALUE },
145 : : { XML_NAMESPACE_TABLE, XML_PROTECTED, XML_TOK_TABLE_PROTECTED },
146 : : { XML_NAMESPACE_TABLE, XML_PROTECT, XML_TOK_TABLE_PROTECTED }, // for backwards compatibility with SRC629 (and before)
147 : : { XML_NAMESPACE_OFFICE, XML_STRING_VALUE, XML_TOK_TABLE_STRING_VALUE },
148 : : XML_TOKEN_MAP_END
149 : : };
150 : :
151 : 72 : const SvXMLTokenMap& SwXMLImport::GetTableElemTokenMap()
152 : : {
153 [ + + ]: 72 : if( !pTableElemTokenMap )
154 [ + - ]: 3 : pTableElemTokenMap = new SvXMLTokenMap( aTableElemTokenMap );
155 : :
156 : 72 : return *pTableElemTokenMap;
157 : : }
158 : :
159 : 396 : const SvXMLTokenMap& SwXMLImport::GetTableCellAttrTokenMap()
160 : : {
161 [ + + ]: 396 : if( !pTableCellAttrTokenMap )
162 [ + - ]: 3 : pTableCellAttrTokenMap = new SvXMLTokenMap( aTableCellAttrTokenMap );
163 : :
164 : 396 : return *pTableCellAttrTokenMap;
165 : : }
166 : :
167 : : // ---------------------------------------------------------------------
168 : :
169 [ + - ]: 345 : class SwXMLTableCell_Impl
170 : : {
171 : : OUString aStyleName;
172 : :
173 : : OUString mXmlId;
174 : :
175 : : OUString sFormula; // cell formula; valid if length > 0
176 : : double dValue; // formula value
177 : :
178 : : SvXMLImportContextRef xSubTable;
179 : :
180 : : const SwStartNode *pStartNode;
181 : : sal_uInt32 nRowSpan;
182 : : sal_uInt32 nColSpan;
183 : :
184 : : sal_Bool bProtected : 1;
185 : : sal_Bool bHasValue; // determines whether dValue attribute is valid
186 : : sal_Bool mbCovered;
187 : : sal_Bool mbTextValue;
188 : :
189 : : public:
190 : :
191 : 345 : SwXMLTableCell_Impl( sal_uInt32 nRSpan=1UL, sal_uInt32 nCSpan=1UL ) :
192 : : pStartNode( 0 ),
193 : : nRowSpan( nRSpan ),
194 : : nColSpan( nCSpan ),
195 : : bProtected( sal_False ),
196 : 345 : mbCovered( sal_False )
197 : 345 : {}
198 : :
199 : : inline void Set( const OUString& rStyleName,
200 : : sal_uInt32 nRSpan, sal_uInt32 nCSpan,
201 : : const SwStartNode *pStNd, SwXMLTableContext *pTable,
202 : : sal_Bool bProtect = sal_False,
203 : : const OUString* pFormula = NULL,
204 : : sal_Bool bHasValue = sal_False,
205 : : sal_Bool mbCovered = sal_False,
206 : : double dVal = 0.0,
207 : : sal_Bool mbTextValue = sal_False,
208 : : OUString const& i_rXmlId = OUString());
209 : :
210 : 345 : sal_Bool IsUsed() const { return pStartNode!=0 ||
211 [ + - ][ + - ]: 345 : xSubTable.Is() || bProtected;}
[ - + ]
212 : :
213 : 345 : sal_uInt32 GetRowSpan() const { return nRowSpan; }
214 : 0 : void SetRowSpan( sal_uInt32 nSet ) { nRowSpan = nSet; }
215 : 690 : sal_uInt32 GetColSpan() const { return nColSpan; }
216 : 345 : const OUString& GetStyleName() const { return aStyleName; }
217 : 690 : const OUString& GetFormula() const { return sFormula; }
218 : 0 : double GetValue() const { return dValue; }
219 : 1380 : sal_Bool HasValue() const { return bHasValue; }
220 : 690 : sal_Bool IsProtected() const { return bProtected; }
221 : 345 : sal_Bool IsCovered() const { return mbCovered; }
222 : 345 : sal_Bool HasTextValue() const { return mbTextValue; }
223 : : const OUString& GetXmlId() const { return mXmlId; }
224 : :
225 : 1779 : const SwStartNode *GetStartNode() const { return pStartNode; }
226 : : inline void SetStartNode( const SwStartNode *pSttNd );
227 : :
228 : : inline SwXMLTableContext *GetSubTable() const;
229 : :
230 : : inline void Dispose();
231 : : };
232 : :
233 : 345 : inline void SwXMLTableCell_Impl::Set( const OUString& rStyleName,
234 : : sal_uInt32 nRSpan, sal_uInt32 nCSpan,
235 : : const SwStartNode *pStNd,
236 : : SwXMLTableContext *pTable,
237 : : sal_Bool bProtect,
238 : : const OUString* pFormula,
239 : : sal_Bool bHasVal,
240 : : sal_Bool bCov,
241 : : double dVal,
242 : : sal_Bool bTextVal,
243 : : OUString const& i_rXmlId )
244 : : {
245 : 345 : aStyleName = rStyleName;
246 : 345 : nRowSpan = nRSpan;
247 : 345 : nColSpan = nCSpan;
248 : 345 : pStartNode = pStNd;
249 : 345 : xSubTable = pTable;
250 : 345 : dValue = dVal;
251 : 345 : bHasValue = bHasVal;
252 : 345 : mbCovered = bCov;
253 : 345 : mbTextValue = bTextVal;
254 : 345 : bProtected = bProtect;
255 : :
256 [ + - ]: 345 : if (!mbCovered) // ensure uniqueness
257 : : {
258 : 345 : mXmlId = i_rXmlId;
259 : : }
260 : :
261 : : // set formula, if valid
262 [ + - ]: 345 : if (pFormula != NULL)
263 : : {
264 : 345 : sFormula = *pFormula;
265 : : }
266 : 345 : }
267 : :
268 : 0 : inline void SwXMLTableCell_Impl::SetStartNode( const SwStartNode *pSttNd )
269 : : {
270 : 0 : pStartNode = pSttNd;
271 : 0 : xSubTable = 0;
272 : 0 : }
273 : :
274 : 0 : inline SwXMLTableContext *SwXMLTableCell_Impl::GetSubTable() const
275 : : {
276 : 0 : return (SwXMLTableContext *)&xSubTable;
277 : : }
278 : :
279 : 345 : inline void SwXMLTableCell_Impl::Dispose()
280 : : {
281 [ - + ]: 345 : if( xSubTable.Is() )
282 : 0 : xSubTable = 0;
283 : 345 : }
284 : :
285 : : // ---------------------------------------------------------------------
286 : :
287 : : typedef boost::ptr_vector<SwXMLTableCell_Impl> SwXMLTableCells_Impl;
288 : :
289 : : class SwXMLTableRow_Impl
290 : : {
291 : : OUString aStyleName;
292 : : OUString aDfltCellStyleName;
293 : : OUString mXmlId;
294 : :
295 : : SwXMLTableCells_Impl aCells;
296 : :
297 : : sal_Bool bSplitable;
298 : :
299 : : public:
300 : :
301 : : SwXMLTableRow_Impl( const OUString& rStyleName, sal_uInt32 nCells,
302 : : const OUString *pDfltCellStyleName = 0,
303 : : const OUString& i_rXmlId = OUString() );
304 [ + - ]: 69 : ~SwXMLTableRow_Impl() {}
305 : :
306 : : inline const SwXMLTableCell_Impl *GetCell( sal_uInt32 nCol ) const;
307 : : inline SwXMLTableCell_Impl *GetCell( sal_uInt32 nCol );
308 : :
309 : : inline void Set( const OUString& rStyleName,
310 : : const OUString& rDfltCellStyleName,
311 : : const OUString& i_rXmlId );
312 : :
313 : : void Expand( sal_uInt32 nCells, sal_Bool bOneCell );
314 : :
315 : 345 : void SetSplitable( sal_Bool bSet ) { bSplitable = bSet; }
316 : 0 : sal_Bool IsSplitable() const { return bSplitable; }
317 : :
318 : 69 : const OUString& GetStyleName() const { return aStyleName; }
319 : 294 : const OUString& GetDefaultCellStyleName() const { return aDfltCellStyleName; }
320 : : const OUString& GetXmlId() const { return mXmlId; }
321 : :
322 : : void Dispose();
323 : : };
324 : :
325 : 69 : SwXMLTableRow_Impl::SwXMLTableRow_Impl( const OUString& rStyleName,
326 : : sal_uInt32 nCells,
327 : : const OUString *pDfltCellStyleName,
328 : : const OUString& i_rXmlId ) :
329 : : aStyleName( rStyleName ),
330 : : mXmlId( i_rXmlId ),
331 [ + - ]: 69 : bSplitable( sal_False )
332 : : {
333 [ + - ]: 69 : if( pDfltCellStyleName )
334 : 69 : aDfltCellStyleName = *pDfltCellStyleName;
335 : : OSL_ENSURE( nCells <= USHRT_MAX,
336 : : "SwXMLTableRow_Impl::SwXMLTableRow_Impl: too many cells" );
337 [ - + ]: 69 : if( nCells > USHRT_MAX )
338 : 0 : nCells = USHRT_MAX;
339 : :
340 [ + + ]: 414 : for( sal_uInt16 i=0U; i<nCells; i++ )
341 : : {
342 [ + - ][ + - ]: 345 : aCells.push_back( new SwXMLTableCell_Impl );
[ + - ]
343 : : }
344 : 69 : }
345 : :
346 : 0 : inline const SwXMLTableCell_Impl *SwXMLTableRow_Impl::GetCell( sal_uInt32 nCol ) const
347 : : {
348 : : OSL_ENSURE( nCol < USHRT_MAX,
349 : : "SwXMLTableRow_Impl::GetCell: column number is to big" );
350 : : // #i95726# - some fault tolerance
351 : : OSL_ENSURE( nCol < aCells.size(),
352 : : "SwXMLTableRow_Impl::GetCell: column number is out of bound" );
353 [ # # ]: 0 : return nCol < aCells.size() ? &aCells[(sal_uInt16)nCol] : 0;
354 : : }
355 : :
356 : 1380 : inline SwXMLTableCell_Impl *SwXMLTableRow_Impl::GetCell( sal_uInt32 nCol )
357 : : {
358 : : OSL_ENSURE( nCol < USHRT_MAX,
359 : : "SwXMLTableRow_Impl::GetCell: column number is to big" );
360 : : // #i95726# - some fault tolerance
361 : : OSL_ENSURE( nCol < aCells.size(),
362 : : "SwXMLTableRow_Impl::GetCell: column number is out of bound" );
363 [ + - ]: 1380 : return nCol < aCells.size() ? &aCells[(sal_uInt16)nCol] : 0;
364 : : }
365 : :
366 : 0 : void SwXMLTableRow_Impl::Expand( sal_uInt32 nCells, sal_Bool bOneCell )
367 : : {
368 : : OSL_ENSURE( nCells <= USHRT_MAX,
369 : : "SwXMLTableRow_Impl::Expand: too many cells" );
370 [ # # ]: 0 : if( nCells > USHRT_MAX )
371 : 0 : nCells = USHRT_MAX;
372 : :
373 : 0 : sal_uInt32 nColSpan = nCells - aCells.size();
374 [ # # ]: 0 : for( sal_uInt16 i=aCells.size(); i<nCells; i++ )
375 : : {
376 : : aCells.push_back( new SwXMLTableCell_Impl( 1UL,
377 [ # # ][ # # ]: 0 : bOneCell ? nColSpan : 1UL ) );
378 : 0 : nColSpan--;
379 : : }
380 : :
381 : : OSL_ENSURE( nCells<=aCells.size(),
382 : : "SwXMLTableRow_Impl::Expand: wrong number of cells" );
383 : 0 : }
384 : :
385 : 0 : inline void SwXMLTableRow_Impl::Set( const OUString& rStyleName,
386 : : const OUString& rDfltCellStyleName,
387 : : const OUString& i_rXmlId )
388 : : {
389 : 0 : aStyleName = rStyleName;
390 : 0 : aDfltCellStyleName = rDfltCellStyleName;
391 : 0 : mXmlId = i_rXmlId;
392 : 0 : }
393 : :
394 : 69 : void SwXMLTableRow_Impl::Dispose()
395 : : {
396 [ + + ]: 414 : for( sal_uInt16 i=0; i < aCells.size(); i++ )
397 : 345 : aCells[i].Dispose();
398 : 69 : }
399 : :
400 : : // ---------------------------------------------------------------------
401 : :
402 : : class SwXMLTableCellContext_Impl : public SvXMLImportContext
403 : : {
404 : : OUString aStyleName;
405 : : OUString sFormula;
406 : : OUString sSaveParaDefault;
407 : : OUString mXmlId;
408 : :
409 : : SvXMLImportContextRef xMyTable;
410 : :
411 : : double fValue;
412 : : sal_Bool bHasValue;
413 : : sal_Bool bHasTextValue;
414 : : sal_Bool bProtect;
415 : :
416 : : sal_uInt32 nRowSpan;
417 : : sal_uInt32 nColSpan;
418 : : sal_uInt32 nColRepeat;
419 : :
420 : : sal_Bool bHasTextContent : 1;
421 : : sal_Bool bHasTableContent : 1;
422 : :
423 : 1380 : SwXMLTableContext *GetTable() { return (SwXMLTableContext *)&xMyTable; }
424 : :
425 [ + - ][ - + ]: 345 : sal_Bool HasContent() const { return bHasTextContent || bHasTableContent; }
426 : : inline void _InsertContent();
427 : : inline void InsertContent();
428 : : inline void InsertContentIfNotThere();
429 : : inline void InsertContent( SwXMLTableContext *pTable );
430 : :
431 : : public:
432 : :
433 : : SwXMLTableCellContext_Impl(
434 : : SwXMLImport& rImport, sal_uInt16 nPrfx, const OUString& rLName,
435 : : const Reference< xml::sax::XAttributeList > & xAttrList,
436 : : SwXMLTableContext *pTable );
437 : :
438 : : virtual ~SwXMLTableCellContext_Impl();
439 : :
440 : : virtual SvXMLImportContext *CreateChildContext(
441 : : sal_uInt16 nPrefix, const OUString& rLocalName,
442 : : const Reference< xml::sax::XAttributeList > & xAttrList );
443 : : virtual void EndElement();
444 : :
445 : 396 : SwXMLImport& GetSwImport() { return (SwXMLImport&)GetImport(); }
446 : : };
447 : :
448 : 345 : SwXMLTableCellContext_Impl::SwXMLTableCellContext_Impl(
449 : : SwXMLImport& rImport, sal_uInt16 nPrfx, const OUString& rLName,
450 : : const Reference< xml::sax::XAttributeList > & xAttrList,
451 : : SwXMLTableContext *pTable ) :
452 : : SvXMLImportContext( rImport, nPrfx, rLName ),
453 : : sFormula(),
454 : : xMyTable( pTable ),
455 : : fValue( 0.0 ),
456 : : bHasValue( sal_False ),
457 : : bHasTextValue( sal_False ),
458 : : bProtect( sal_False ),
459 : : nRowSpan( 1UL ),
460 : : nColSpan( 1UL ),
461 : : nColRepeat( 1UL ),
462 : : bHasTextContent( sal_False ),
463 : 345 : bHasTableContent( sal_False )
464 : : {
465 [ + - ][ + - ]: 345 : sSaveParaDefault = GetImport().GetTextImport()->GetCellParaStyleDefault();
[ + - ][ + - ]
466 [ + - ][ + - ]: 345 : sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
[ + - ]
467 [ + + ]: 741 : for( sal_Int16 i=0; i < nAttrCount; i++ )
468 : : {
469 [ + - ][ + - ]: 396 : const OUString& rAttrName = xAttrList->getNameByIndex( i );
470 : :
471 : 396 : OUString aLocalName;
472 : : sal_uInt16 nPrefix =
473 : 396 : GetImport().GetNamespaceMap().GetKeyByAttrName( rAttrName,
474 [ + - ]: 396 : &aLocalName );
475 [ + - ][ + - ]: 396 : const OUString& rValue = xAttrList->getValueByIndex( i );
476 : : const SvXMLTokenMap& rTokenMap =
477 [ + - ]: 396 : GetSwImport().GetTableCellAttrTokenMap();
478 [ + - ][ - + : 396 : switch( rTokenMap.Get( nPrefix, aLocalName ) )
- - - - -
- - - - -
+ ]
479 : : {
480 : : case XML_TOK_TABLE_XMLID:
481 : 0 : mXmlId = rValue;
482 : 0 : break;
483 : : case XML_TOK_TABLE_STYLE_NAME:
484 : 51 : aStyleName = rValue;
485 [ + - ][ + - ]: 51 : GetImport().GetTextImport()->SetCellParaStyleDefault(rValue);
[ + - ][ + - ]
486 : 51 : break;
487 : : case XML_TOK_TABLE_NUM_COLS_SPANNED:
488 : 0 : nColSpan = (sal_uInt32)rValue.toInt32();
489 [ # # ]: 0 : if( nColSpan < 1UL )
490 : 0 : nColSpan = 1UL;
491 : 0 : break;
492 : : case XML_TOK_TABLE_NUM_ROWS_SPANNED:
493 : 0 : nRowSpan = (sal_uInt32)rValue.toInt32();
494 [ # # ]: 0 : if( nRowSpan < 1UL )
495 : 0 : nRowSpan = 1UL;
496 : 0 : break;
497 : : case XML_TOK_TABLE_NUM_COLS_REPEATED:
498 : 0 : nColRepeat = (sal_uInt32)rValue.toInt32();
499 [ # # ]: 0 : if( nColRepeat < 1UL )
500 : 0 : nColRepeat = 1UL;
501 : 0 : break;
502 : : case XML_TOK_TABLE_FORMULA:
503 : : {
504 : 0 : OUString sTmp;
505 : 0 : sal_uInt16 nPrefix2 = GetImport().GetNamespaceMap().
506 [ # # ]: 0 : _GetKeyByAttrName( rValue, &sTmp, sal_False );
507 [ # # ]: 0 : sFormula = XML_NAMESPACE_OOOW == nPrefix2 ? sTmp : rValue;
508 : : }
509 : 0 : break;
510 : : case XML_TOK_TABLE_VALUE:
511 : : {
512 : : double fTmp;
513 [ # # ][ # # ]: 0 : if (::sax::Converter::convertDouble(fTmp, rValue))
514 : : {
515 : 0 : fValue = fTmp;
516 : 0 : bHasValue = sal_True;
517 : : }
518 : : }
519 : 0 : break;
520 : : case XML_TOK_TABLE_TIME_VALUE:
521 : : {
522 : : double fTmp;
523 [ # # ][ # # ]: 0 : if (::sax::Converter::convertDuration(fTmp, rValue))
524 : : {
525 : 0 : fValue = fTmp;
526 : 0 : bHasValue = sal_True;
527 : : }
528 : : }
529 : 0 : break;
530 : : case XML_TOK_TABLE_DATE_VALUE:
531 : : {
532 : : double fTmp;
533 [ # # ][ # # ]: 0 : if (GetImport().GetMM100UnitConverter().convertDateTime(fTmp,
534 : : rValue))
535 : : {
536 : 0 : fValue = fTmp;
537 : 0 : bHasValue = sal_True;
538 : : }
539 : : }
540 : 0 : break;
541 : : case XML_TOK_TABLE_BOOLEAN_VALUE:
542 : : {
543 : 0 : bool bTmp(false);
544 [ # # ][ # # ]: 0 : if (::sax::Converter::convertBool(bTmp, rValue))
545 : : {
546 [ # # ]: 0 : fValue = (bTmp ? 1.0 : 0.0);
547 : 0 : bHasValue = sal_True;
548 : : }
549 : : }
550 : 0 : break;
551 : : case XML_TOK_TABLE_PROTECTED:
552 : : {
553 : 0 : bool bTmp(false);
554 [ # # ][ # # ]: 0 : if (::sax::Converter::convertBool(bTmp, rValue))
555 : : {
556 : 0 : bProtect = bTmp;
557 : : }
558 : : }
559 : 0 : break;
560 : : case XML_TOK_TABLE_STRING_VALUE:
561 : : {
562 : 0 : bHasTextValue = sal_True;
563 : : }
564 : 0 : break;
565 : : }
566 : 396 : }
567 : 345 : }
568 : :
569 [ + - ]: 345 : SwXMLTableCellContext_Impl::~SwXMLTableCellContext_Impl()
570 : : {
571 [ - + ]: 690 : }
572 : :
573 : 345 : inline void SwXMLTableCellContext_Impl::_InsertContent()
574 : : {
575 : : GetTable()->InsertCell( aStyleName, nRowSpan, nColSpan,
576 : : GetTable()->InsertTableSection(),
577 : : mXmlId,
578 : 345 : NULL, bProtect, &sFormula, bHasValue, fValue, bHasTextValue );
579 : 345 : }
580 : :
581 : 345 : inline void SwXMLTableCellContext_Impl::InsertContent()
582 : : {
583 : : OSL_ENSURE( !HasContent(), "content already there" );
584 : 345 : bHasTextContent = sal_True;
585 : 345 : _InsertContent();
586 : 345 : }
587 : :
588 : 345 : inline void SwXMLTableCellContext_Impl::InsertContentIfNotThere()
589 : : {
590 [ + - ]: 345 : if( !HasContent() )
591 : 345 : InsertContent();
592 : 345 : }
593 : :
594 : 0 : inline void SwXMLTableCellContext_Impl::InsertContent(
595 : : SwXMLTableContext *pTable )
596 : : {
597 : 0 : GetTable()->InsertCell( aStyleName, nRowSpan, nColSpan, 0, mXmlId, pTable, bProtect );
598 : 0 : bHasTableContent = sal_True;
599 : 0 : }
600 : :
601 : 345 : SvXMLImportContext *SwXMLTableCellContext_Impl::CreateChildContext(
602 : : sal_uInt16 nPrefix,
603 : : const OUString& rLocalName,
604 : : const Reference< xml::sax::XAttributeList > & xAttrList )
605 : : {
606 : 345 : SvXMLImportContext *pContext = 0;
607 : :
608 : 345 : OUString sXmlId;
609 : 345 : sal_Bool bSubTable = sal_False;
610 [ # # ][ - + ]: 345 : if( XML_NAMESPACE_TABLE == nPrefix &&
[ - + ]
611 [ # # ]: 0 : IsXMLToken( rLocalName, XML_TABLE ) )
612 : : {
613 [ # # ][ # # ]: 0 : sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
[ # # ]
614 [ # # ]: 0 : for( sal_Int16 i=0; i < nAttrCount; i++ )
615 : : {
616 [ # # ][ # # ]: 0 : const OUString& rAttrName = xAttrList->getNameByIndex( i );
617 : :
618 : 0 : OUString aLocalName;
619 : : sal_uInt16 nPrefix2 =
620 : 0 : GetImport().GetNamespaceMap().GetKeyByAttrName( rAttrName,
621 [ # # ]: 0 : &aLocalName );
622 [ # # ][ # # ]: 0 : if( XML_NAMESPACE_TABLE == nPrefix2 &&
[ # # ][ # # ]
623 [ # # ]: 0 : IsXMLToken( aLocalName, XML_IS_SUB_TABLE ) &&
624 [ # # ][ # # ]: 0 : IsXMLToken( xAttrList->getValueByIndex( i ), XML_TRUE ) )
[ # # ][ # # ]
[ # # ]
625 : : {
626 : 0 : bSubTable = sal_True;
627 : : }
628 [ # # ][ # # ]: 0 : else if ( (XML_NAMESPACE_XML == nPrefix2) &&
[ # # ]
629 [ # # ]: 0 : IsXMLToken( aLocalName, XML_ID ) )
630 : : {
631 [ # # ][ # # ]: 0 : sXmlId = xAttrList->getValueByIndex( i );
632 : : }
633 : : //FIXME: RDFa
634 : 0 : }
635 : : }
636 : :
637 [ - + ]: 345 : if( bSubTable )
638 : : {
639 [ # # ]: 0 : if( !HasContent() )
640 : : {
641 : : SwXMLTableContext *pTblContext =
642 : : new SwXMLTableContext( GetSwImport(), nPrefix, rLocalName,
643 [ # # ][ # # ]: 0 : xAttrList, GetTable(), sXmlId );
644 : 0 : pContext = pTblContext;
645 [ # # ]: 0 : if( GetTable()->IsValid() )
646 [ # # ]: 0 : InsertContent( pTblContext );
647 : :
648 : 0 : GetTable()->SetHasSubTables( sal_True );
649 : : }
650 : : }
651 : : else
652 : : {
653 [ + - ]: 345 : if( GetTable()->IsValid() )
654 [ + - ]: 345 : InsertContentIfNotThere();
655 : 345 : pContext = GetImport().GetTextImport()->CreateTextChildContext(
656 : 345 : GetImport(), nPrefix, rLocalName, xAttrList,
657 [ + - ][ + - ]: 345 : XML_TEXT_TYPE_CELL );
[ + - ][ + - ]
658 : : }
659 : :
660 [ - + ]: 345 : if( !pContext )
661 [ # # ][ # # ]: 0 : pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
662 : :
663 : 345 : return pContext;
664 : : }
665 : :
666 : 345 : void SwXMLTableCellContext_Impl::EndElement()
667 : : {
668 [ + - ]: 345 : if( GetTable()->IsValid() )
669 : : {
670 [ + - ]: 345 : if( bHasTextContent )
671 : : {
672 [ + - ][ + - ]: 345 : GetImport().GetTextImport()->DeleteParagraph();
673 [ # # ][ - + ]: 345 : if( nColRepeat > 1 && nColSpan == 1 )
674 : : {
675 : : // The original text is invalid after deleting the last
676 : : // paragraph
677 : : Reference < XTextCursor > xSrcTxtCursor =
678 [ # # ][ # # ]: 0 : GetImport().GetTextImport()->GetText()->createTextCursor();
[ # # ][ # # ]
[ # # ][ # # ]
679 [ # # ][ # # ]: 0 : xSrcTxtCursor->gotoEnd( sal_True );
680 : :
681 : : // Until we have an API for copying we have to use the core.
682 [ # # ]: 0 : Reference<XUnoTunnel> xSrcCrsrTunnel( xSrcTxtCursor, UNO_QUERY);
683 : : OSL_ENSURE( xSrcCrsrTunnel.is(), "missing XUnoTunnel for Cursor" );
684 : : OTextCursorHelper *pSrcTxtCrsr = reinterpret_cast< OTextCursorHelper * >(
685 [ # # ][ # # ]: 0 : sal::static_int_cast< sal_IntPtr >( xSrcCrsrTunnel->getSomething( OTextCursorHelper::getUnoTunnelId() )));
[ # # ]
686 : : OSL_ENSURE( pSrcTxtCrsr, "SwXTextCursor missing" );
687 [ # # ]: 0 : SwDoc *pDoc = pSrcTxtCrsr->GetDoc();
688 [ # # ]: 0 : const SwPaM *pSrcPaM = pSrcTxtCrsr->GetPaM();
689 : :
690 [ # # ][ # # ]: 0 : while( nColRepeat > 1 && GetTable()->IsInsertCellPossible() )
[ # # ][ # # ]
691 : : {
692 [ # # ]: 0 : _InsertContent();
693 : :
694 : : Reference<XUnoTunnel> xDstCrsrTunnel(
695 [ # # ][ # # ]: 0 : GetImport().GetTextImport()->GetCursor(), UNO_QUERY);
[ # # ][ # # ]
[ # # ]
696 : : OSL_ENSURE( xDstCrsrTunnel.is(),
697 : : "missing XUnoTunnel for Cursor" );
698 : : OTextCursorHelper *pDstTxtCrsr = reinterpret_cast< OTextCursorHelper * >(
699 [ # # ][ # # ]: 0 : sal::static_int_cast< sal_IntPtr >( xDstCrsrTunnel->getSomething( OTextCursorHelper::getUnoTunnelId() )) );
[ # # ]
700 : : OSL_ENSURE( pDstTxtCrsr, "SwXTextCursor missing" );
701 : 0 : SwPaM aSrcPaM( *pSrcPaM->GetPoint(),
702 [ # # ]: 0 : *pSrcPaM->GetMark() );
703 [ # # ][ # # ]: 0 : SwPosition aDstPos( *pDstTxtCrsr->GetPaM()->GetPoint() );
704 [ # # ]: 0 : pDoc->CopyRange( aSrcPaM, aDstPos, false );
705 : :
706 : 0 : nColRepeat--;
707 [ # # ][ # # ]: 0 : }
708 : : }
709 : : }
710 [ # # ]: 0 : else if( !bHasTableContent )
711 : : {
712 : 0 : InsertContent();
713 [ # # ][ # # ]: 0 : if( nColRepeat > 1 && nColSpan == 1 )
714 : : {
715 [ # # ][ # # ]: 0 : while( nColRepeat > 1 && GetTable()->IsInsertCellPossible() )
[ # # ]
716 : : {
717 : 0 : _InsertContent();
718 : 0 : nColRepeat--;
719 : : }
720 : : }
721 : : }
722 : : }
723 [ + - ][ + - ]: 345 : GetImport().GetTextImport()->SetCellParaStyleDefault(sSaveParaDefault);
724 : 345 : }
725 : :
726 : : // ---------------------------------------------------------------------
727 : :
728 : : class SwXMLTableColContext_Impl : public SvXMLImportContext
729 : : {
730 : : SvXMLImportContextRef xMyTable;
731 : :
732 : 30 : SwXMLTableContext *GetTable() { return (SwXMLTableContext *)&xMyTable; }
733 : :
734 : : public:
735 : :
736 : : SwXMLTableColContext_Impl(
737 : : SwXMLImport& rImport, sal_uInt16 nPrfx, const OUString& rLName,
738 : : const Reference< xml::sax::XAttributeList > & xAttrList,
739 : : SwXMLTableContext *pTable );
740 : :
741 : : virtual ~SwXMLTableColContext_Impl();
742 : :
743 : 3 : SwXMLImport& GetSwImport() { return (SwXMLImport&)GetImport(); }
744 : : };
745 : :
746 : 3 : SwXMLTableColContext_Impl::SwXMLTableColContext_Impl(
747 : : SwXMLImport& rImport, sal_uInt16 nPrfx, const OUString& rLName,
748 : : const Reference< xml::sax::XAttributeList > & xAttrList,
749 : : SwXMLTableContext *pTable ) :
750 : : SvXMLImportContext( rImport, nPrfx, rLName ),
751 : 3 : xMyTable( pTable )
752 : : {
753 : 3 : sal_uInt32 nColRep = 1UL;
754 : 3 : OUString aStyleName, aDfltCellStyleName;
755 : :
756 [ + - ][ + - ]: 3 : sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
[ + - ]
757 [ + + ]: 9 : for( sal_Int16 i=0; i < nAttrCount; i++ )
758 : : {
759 [ + - ][ + - ]: 6 : const OUString& rAttrName = xAttrList->getNameByIndex( i );
760 : :
761 : 6 : OUString aLocalName;
762 : : sal_uInt16 nPrefix =
763 : 6 : GetImport().GetNamespaceMap().GetKeyByAttrName( rAttrName,
764 [ + - ]: 6 : &aLocalName );
765 [ + - ][ + - ]: 6 : const OUString& rValue = xAttrList->getValueByIndex( i );
766 [ + - ]: 6 : if( XML_NAMESPACE_TABLE == nPrefix )
767 : : {
768 [ + - ][ + + ]: 6 : if( IsXMLToken( aLocalName, XML_STYLE_NAME ) )
769 : 3 : aStyleName = rValue;
770 [ + - ][ + - ]: 3 : else if( IsXMLToken( aLocalName, XML_NUMBER_COLUMNS_REPEATED ) )
771 : 3 : nColRep = (sal_uInt32)rValue.toInt32();
772 [ # # ][ # # ]: 0 : else if( IsXMLToken( aLocalName, XML_DEFAULT_CELL_STYLE_NAME ) )
773 : 0 : aDfltCellStyleName = rValue;
774 : : }
775 [ # # ][ # # ]: 0 : else if ( (XML_NAMESPACE_XML == nPrefix) &&
776 [ # # ]: 0 : IsXMLToken( aLocalName, XML_ID ) )
777 : : {
778 : : (void) rValue;
779 : : //FIXME where to put this??? columns do not actually exist in writer...
780 : : }
781 : 6 : }
782 : :
783 : 3 : sal_Int32 nWidth = MINLAY;
784 : 3 : sal_Bool bRelWidth = sal_True;
785 [ + - ]: 3 : if( !aStyleName.isEmpty() )
786 : : {
787 : : const SfxPoolItem *pItem;
788 : 3 : const SfxItemSet *pAutoItemSet = 0;
789 [ + - ][ + - ]: 9 : if( GetSwImport().FindAutomaticStyle(
[ + - ][ + - ]
790 : : XML_STYLE_FAMILY_TABLE_COLUMN,
791 [ + - ]: 3 : aStyleName, &pAutoItemSet ) &&
792 : : pAutoItemSet &&
793 : : SFX_ITEM_SET == pAutoItemSet->GetItemState( RES_FRM_SIZE, sal_False,
794 [ + - ]: 3 : &pItem ) )
795 : : {
796 : 3 : const SwFmtFrmSize *pSize = ((const SwFmtFrmSize *)pItem);
797 : 3 : nWidth = pSize->GetWidth();
798 : 3 : bRelWidth = ATT_VAR_SIZE == pSize->GetHeightSizeType();
799 : : }
800 : : }
801 : :
802 [ + - ]: 3 : if( nWidth )
803 : : {
804 [ + + ][ + - ]: 18 : while( nColRep-- && GetTable()->IsInsertColPossible() )
[ + + ]
805 [ + - ]: 15 : GetTable()->InsertColumn( nWidth, bRelWidth, &aDfltCellStyleName );
806 : 3 : }
807 : 3 : }
808 : :
809 [ + - ]: 3 : SwXMLTableColContext_Impl::~SwXMLTableColContext_Impl()
810 : : {
811 [ - + ]: 6 : }
812 : :
813 : : // ---------------------------------------------------------------------
814 : :
815 : : class SwXMLTableColsContext_Impl : public SvXMLImportContext
816 : : {
817 : : SvXMLImportContextRef xMyTable;
818 : : sal_Bool bHeader;
819 : :
820 : 0 : SwXMLTableContext *GetTable() { return (SwXMLTableContext *)&xMyTable; }
821 : :
822 : : public:
823 : :
824 : : SwXMLTableColsContext_Impl(
825 : : SwXMLImport& rImport, sal_uInt16 nPrfx,
826 : : const OUString& rLName,
827 : : const Reference< xml::sax::XAttributeList > & xAttrList,
828 : : SwXMLTableContext *pTable,
829 : : sal_Bool bHead );
830 : :
831 : : virtual ~SwXMLTableColsContext_Impl();
832 : :
833 : : virtual SvXMLImportContext *CreateChildContext(
834 : : sal_uInt16 nPrefix, const OUString& rLocalName,
835 : : const Reference< xml::sax::XAttributeList > & xAttrList );
836 : :
837 : 0 : SwXMLImport& GetSwImport() { return (SwXMLImport&)GetImport(); }
838 : : };
839 : :
840 : 0 : SwXMLTableColsContext_Impl::SwXMLTableColsContext_Impl(
841 : : SwXMLImport& rImport, sal_uInt16 nPrfx, const OUString& rLName,
842 : : const Reference< xml::sax::XAttributeList > &,
843 : : SwXMLTableContext *pTable, sal_Bool bHead ) :
844 : : SvXMLImportContext( rImport, nPrfx, rLName ),
845 : : xMyTable( pTable ),
846 : 0 : bHeader( bHead )
847 : : {
848 : 0 : }
849 : :
850 [ # # ]: 0 : SwXMLTableColsContext_Impl::~SwXMLTableColsContext_Impl()
851 : : {
852 [ # # ]: 0 : }
853 : :
854 : 0 : SvXMLImportContext *SwXMLTableColsContext_Impl::CreateChildContext(
855 : : sal_uInt16 nPrefix,
856 : : const OUString& rLocalName,
857 : : const Reference< xml::sax::XAttributeList > & xAttrList )
858 : : {
859 : 0 : SvXMLImportContext *pContext = 0;
860 : :
861 [ # # # # : 0 : if( XML_NAMESPACE_TABLE == nPrefix &&
# # ][ # # ]
862 : 0 : IsXMLToken( rLocalName, XML_TABLE_COLUMN ) &&
863 : 0 : GetTable()->IsInsertColPossible() )
864 : : pContext = new SwXMLTableColContext_Impl( GetSwImport(), nPrefix,
865 : : rLocalName, xAttrList,
866 [ # # ]: 0 : GetTable() );
867 : :
868 [ # # ]: 0 : if( !pContext )
869 [ # # ]: 0 : pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
870 : :
871 : 0 : return pContext;
872 : : }
873 : :
874 : : // ---------------------------------------------------------------------
875 : :
876 : : class SwXMLTableRowContext_Impl : public SvXMLImportContext
877 : : {
878 : : SvXMLImportContextRef xMyTable;
879 : :
880 : : sal_uInt32 nRowRepeat;
881 : :
882 : 1311 : SwXMLTableContext *GetTable() { return (SwXMLTableContext *)&xMyTable; }
883 : :
884 : : public:
885 : :
886 : : SwXMLTableRowContext_Impl(
887 : : SwXMLImport& rImport, sal_uInt16 nPrfx, const OUString& rLName,
888 : : const Reference< xml::sax::XAttributeList > & xAttrList,
889 : : SwXMLTableContext *pTable, sal_Bool bInHead=sal_False );
890 : :
891 : : virtual ~SwXMLTableRowContext_Impl();
892 : :
893 : : virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
894 : : const OUString& rLocalName,
895 : : const Reference< xml::sax::XAttributeList > & xAttrList );
896 : :
897 : : virtual void EndElement();
898 : :
899 : 345 : SwXMLImport& GetSwImport() { return (SwXMLImport&)GetImport(); }
900 : : };
901 : :
902 : 69 : SwXMLTableRowContext_Impl::SwXMLTableRowContext_Impl( SwXMLImport& rImport,
903 : : sal_uInt16 nPrfx,
904 : : const OUString& rLName,
905 : : const Reference< xml::sax::XAttributeList > & xAttrList,
906 : : SwXMLTableContext *pTable,
907 : : sal_Bool bInHead ) :
908 : : SvXMLImportContext( rImport, nPrfx, rLName ),
909 : : xMyTable( pTable ),
910 : 69 : nRowRepeat( 1 )
911 : : {
912 : 69 : OUString aStyleName, aDfltCellStyleName;
913 : 69 : OUString sXmlId;
914 : :
915 [ + - ][ + - ]: 69 : sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
[ + - ]
916 [ - + ]: 69 : for( sal_Int16 i=0; i < nAttrCount; i++ )
917 : : {
918 [ # # ][ # # ]: 0 : const OUString& rAttrName = xAttrList->getNameByIndex( i );
919 : :
920 : 0 : OUString aLocalName;
921 : : sal_uInt16 nPrefix =
922 : 0 : GetImport().GetNamespaceMap().GetKeyByAttrName( rAttrName,
923 [ # # ]: 0 : &aLocalName );
924 [ # # ][ # # ]: 0 : const OUString& rValue = xAttrList->getValueByIndex( i );
925 [ # # ]: 0 : if( XML_NAMESPACE_TABLE == nPrefix )
926 : : {
927 [ # # ][ # # ]: 0 : if( IsXMLToken( aLocalName, XML_STYLE_NAME ) )
928 : : {
929 : 0 : aStyleName = rValue;
930 : : }
931 [ # # ][ # # ]: 0 : else if( IsXMLToken( aLocalName, XML_NUMBER_ROWS_REPEATED ) )
932 : : {
933 : 0 : nRowRepeat = (sal_uInt32)rValue.toInt32();
934 [ # # ]: 0 : if( nRowRepeat < 1UL )
935 : 0 : nRowRepeat = 1UL;
936 : : }
937 [ # # ][ # # ]: 0 : else if( IsXMLToken( aLocalName, XML_DEFAULT_CELL_STYLE_NAME ) )
938 : : {
939 : 0 : aDfltCellStyleName = rValue;
940 : : }
941 : : }
942 [ # # ][ # # ]: 0 : else if ( (XML_NAMESPACE_XML == nPrefix) &&
[ # # ]
943 [ # # ]: 0 : IsXMLToken( aLocalName, XML_ID ) )
944 : : {
945 : 0 : sXmlId = rValue;
946 : : }
947 : 0 : }
948 [ + - ]: 69 : if( GetTable()->IsValid() )
949 : : GetTable()->InsertRow( aStyleName, aDfltCellStyleName, bInHead,
950 [ + - ]: 69 : sXmlId );
951 : 69 : }
952 : :
953 : 69 : void SwXMLTableRowContext_Impl::EndElement()
954 : : {
955 [ + - ]: 69 : if( GetTable()->IsValid() )
956 : : {
957 : 69 : GetTable()->FinishRow();
958 : :
959 [ - + ]: 69 : if( nRowRepeat > 1UL )
960 : 0 : GetTable()->InsertRepRows( nRowRepeat );
961 : : }
962 : 69 : }
963 : :
964 [ + - ]: 69 : SwXMLTableRowContext_Impl::~SwXMLTableRowContext_Impl()
965 : : {
966 [ - + ]: 138 : }
967 : :
968 : 345 : SvXMLImportContext *SwXMLTableRowContext_Impl::CreateChildContext(
969 : : sal_uInt16 nPrefix, const OUString& rLocalName,
970 : : const Reference< xml::sax::XAttributeList > & xAttrList )
971 : : {
972 : 345 : SvXMLImportContext *pContext = 0;
973 : :
974 [ + - ]: 345 : if( XML_NAMESPACE_TABLE == nPrefix )
975 : : {
976 [ + - ]: 345 : if( IsXMLToken( rLocalName, XML_TABLE_CELL ) )
977 : : {
978 [ + - ][ + - ]: 345 : if( !GetTable()->IsValid() || GetTable()->IsInsertCellPossible() )
[ + - ]
979 : : pContext = new SwXMLTableCellContext_Impl( GetSwImport(),
980 : : nPrefix,
981 : : rLocalName,
982 : : xAttrList,
983 [ + - ]: 345 : GetTable() );
984 : : }
985 [ # # ]: 0 : else if( IsXMLToken( rLocalName, XML_COVERED_TABLE_CELL ) )
986 : 0 : pContext = new SvXMLImportContext( GetImport(), nPrefix,
987 [ # # ]: 0 : rLocalName );
988 : : }
989 : :
990 [ - + ]: 345 : if( !pContext )
991 [ # # ]: 0 : pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
992 : :
993 : 345 : return pContext;
994 : : }
995 : :
996 : : // ---------------------------------------------------------------------
997 : :
998 : : class SwXMLTableRowsContext_Impl : public SvXMLImportContext
999 : : {
1000 : : SvXMLImportContextRef xMyTable;
1001 : :
1002 : : sal_Bool bHeader;
1003 : :
1004 : 0 : SwXMLTableContext *GetTable() { return (SwXMLTableContext *)&xMyTable; }
1005 : :
1006 : : public:
1007 : :
1008 : : SwXMLTableRowsContext_Impl( SwXMLImport& rImport, sal_uInt16 nPrfx,
1009 : : const OUString& rLName,
1010 : : const Reference< xml::sax::XAttributeList > & xAttrList,
1011 : : SwXMLTableContext *pTable,
1012 : : sal_Bool bHead );
1013 : :
1014 : : virtual ~SwXMLTableRowsContext_Impl();
1015 : :
1016 : : virtual SvXMLImportContext *CreateChildContext( sal_uInt16 nPrefix,
1017 : : const OUString& rLocalName,
1018 : : const Reference< xml::sax::XAttributeList > & xAttrList );
1019 : :
1020 : 0 : SwXMLImport& GetSwImport() { return (SwXMLImport&)GetImport(); }
1021 : : };
1022 : :
1023 : 0 : SwXMLTableRowsContext_Impl::SwXMLTableRowsContext_Impl( SwXMLImport& rImport,
1024 : : sal_uInt16 nPrfx,
1025 : : const OUString& rLName,
1026 : : const Reference< xml::sax::XAttributeList > &,
1027 : : SwXMLTableContext *pTable,
1028 : : sal_Bool bHead ) :
1029 : : SvXMLImportContext( rImport, nPrfx, rLName ),
1030 : : xMyTable( pTable ),
1031 : 0 : bHeader( bHead )
1032 : : {
1033 : 0 : }
1034 : :
1035 [ # # ]: 0 : SwXMLTableRowsContext_Impl::~SwXMLTableRowsContext_Impl()
1036 : : {
1037 [ # # ]: 0 : }
1038 : :
1039 : 0 : SvXMLImportContext *SwXMLTableRowsContext_Impl::CreateChildContext(
1040 : : sal_uInt16 nPrefix,
1041 : : const OUString& rLocalName,
1042 : : const Reference< xml::sax::XAttributeList > & xAttrList )
1043 : : {
1044 : 0 : SvXMLImportContext *pContext = 0;
1045 : :
1046 [ # # # # : 0 : if( XML_NAMESPACE_TABLE == nPrefix &&
# # ][ # # ]
1047 : 0 : IsXMLToken( rLocalName, XML_TABLE_ROW ) &&
1048 : 0 : GetTable()->IsInsertRowPossible() )
1049 : : pContext = new SwXMLTableRowContext_Impl( GetSwImport(), nPrefix,
1050 : : rLocalName, xAttrList,
1051 : : GetTable(),
1052 [ # # ]: 0 : bHeader );
1053 : :
1054 [ # # ]: 0 : if( !pContext )
1055 [ # # ]: 0 : pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
1056 : :
1057 : 0 : return pContext;
1058 : : }
1059 : :
1060 : : // ---------------------------------------------------------------------
1061 : :
1062 : : class SwXMLDDETableContext_Impl : public SvXMLImportContext
1063 : : {
1064 : : OUString sConnectionName;
1065 : : OUString sDDEApplication;
1066 : : OUString sDDEItem;
1067 : : OUString sDDETopic;
1068 : : sal_Bool bIsAutomaticUpdate;
1069 : :
1070 : : public:
1071 : :
1072 : : TYPEINFO();
1073 : :
1074 : : SwXMLDDETableContext_Impl(
1075 : : SwXMLImport& rImport, sal_uInt16 nPrfx, const OUString& rLName);
1076 : :
1077 : : ~SwXMLDDETableContext_Impl();
1078 : :
1079 : : virtual void StartElement(
1080 : : const Reference<xml::sax::XAttributeList> & xAttrList);
1081 : :
1082 : 0 : OUString& GetConnectionName() { return sConnectionName; }
1083 : 0 : OUString& GetDDEApplication() { return sDDEApplication; }
1084 : 0 : OUString& GetDDEItem() { return sDDEItem; }
1085 : 0 : OUString& GetDDETopic() { return sDDETopic; }
1086 : 0 : sal_Bool GetIsAutomaticUpdate() { return bIsAutomaticUpdate; }
1087 : : };
1088 : :
1089 [ # # ][ # # ]: 0 : TYPEINIT1( SwXMLDDETableContext_Impl, SvXMLImportContext );
1090 : :
1091 : 0 : SwXMLDDETableContext_Impl::SwXMLDDETableContext_Impl(
1092 : : SwXMLImport& rImport, sal_uInt16 nPrfx, const OUString& rLName) :
1093 : : SvXMLImportContext(rImport, nPrfx, rLName),
1094 : : sConnectionName(),
1095 : : sDDEApplication(),
1096 : : sDDEItem(),
1097 : : sDDETopic(),
1098 : 0 : bIsAutomaticUpdate(sal_False)
1099 : : {
1100 : 0 : }
1101 : :
1102 : 0 : SwXMLDDETableContext_Impl::~SwXMLDDETableContext_Impl()
1103 : : {
1104 [ # # ]: 0 : }
1105 : :
1106 : 0 : void SwXMLDDETableContext_Impl::StartElement(
1107 : : const Reference<xml::sax::XAttributeList> & xAttrList)
1108 : : {
1109 [ # # ]: 0 : sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
1110 [ # # ]: 0 : for( sal_Int16 i = 0; i < nAttrCount; i++ )
1111 : : {
1112 [ # # ][ # # ]: 0 : const OUString& rAttrName = xAttrList->getNameByIndex( i );
1113 : :
1114 : 0 : OUString aLocalName;
1115 : : sal_uInt16 nPrefix =
1116 : 0 : GetImport().GetNamespaceMap().GetKeyByAttrName( rAttrName,
1117 [ # # ]: 0 : &aLocalName );
1118 [ # # ][ # # ]: 0 : const OUString& rValue = xAttrList->getValueByIndex( i );
1119 : :
1120 [ # # ]: 0 : if (XML_NAMESPACE_OFFICE == nPrefix)
1121 : : {
1122 [ # # ][ # # ]: 0 : if ( IsXMLToken( aLocalName, XML_DDE_APPLICATION ) )
1123 : : {
1124 : 0 : sDDEApplication = rValue;
1125 : : }
1126 [ # # ][ # # ]: 0 : else if ( IsXMLToken( aLocalName, XML_DDE_TOPIC ) )
1127 : : {
1128 : 0 : sDDETopic = rValue;
1129 : : }
1130 [ # # ][ # # ]: 0 : else if ( IsXMLToken( aLocalName, XML_DDE_ITEM ) )
1131 : : {
1132 : 0 : sDDEItem = rValue;
1133 : : }
1134 [ # # ][ # # ]: 0 : else if ( IsXMLToken( aLocalName, XML_NAME ) )
1135 : : {
1136 : 0 : sConnectionName = rValue;
1137 : : }
1138 [ # # ][ # # ]: 0 : else if ( IsXMLToken( aLocalName, XML_AUTOMATIC_UPDATE ) )
1139 : : {
1140 : 0 : bool bTmp(false);
1141 [ # # ][ # # ]: 0 : if (::sax::Converter::convertBool(bTmp, rValue))
1142 : : {
1143 : 0 : bIsAutomaticUpdate = bTmp;
1144 : : }
1145 : : }
1146 : : // else: unknown attribute
1147 : : }
1148 : : // else: unknown attribute namespace
1149 : 0 : }
1150 : 0 : }
1151 : :
1152 : : // generate a new name for DDE field type (called by lcl_GetDDEFieldType below)
1153 : 0 : String lcl_GenerateFldTypeName(OUString sPrefix, SwTableNode* pTableNode)
1154 : : {
1155 [ # # ]: 0 : String sPrefixStr(sPrefix);
1156 : :
1157 [ # # ]: 0 : if (sPrefixStr.Len() == 0)
1158 : : {
1159 [ # # ]: 0 : sPrefixStr = rtl::OUString('_');
1160 : : }
1161 : :
1162 : : // increase count until we find a name that is not yet taken
1163 [ # # ]: 0 : String sName;
1164 : 0 : sal_Int32 nCount = 0;
1165 [ # # ]: 0 : do
1166 : : {
1167 : : // this is crazy, but just in case all names are taken: exit gracefully
1168 [ # # ]: 0 : if (nCount < 0)
1169 : : return sName;
1170 : :
1171 : 0 : nCount++;
1172 [ # # ]: 0 : sName = sPrefixStr;
1173 [ # # ][ # # ]: 0 : sName += String::CreateFromInt32(nCount);
[ # # ]
1174 : :
1175 : : }
1176 [ # # ]: 0 : while (NULL != pTableNode->GetDoc()->GetFldType(RES_DDEFLD, sName, false));
1177 : :
1178 [ # # ]: 0 : return sName;
1179 : : }
1180 : :
1181 : : // set table properties
1182 : 0 : SwDDEFieldType* lcl_GetDDEFieldType(SwXMLDDETableContext_Impl* pContext,
1183 : : SwTableNode* pTableNode)
1184 : : {
1185 : : // make command string
1186 [ # # ]: 0 : String sCommand(pContext->GetDDEApplication());
1187 [ # # ]: 0 : sCommand += sfx2::cTokenSeperator;
1188 [ # # ][ # # ]: 0 : sCommand += String(pContext->GetDDEItem());
[ # # ]
1189 [ # # ]: 0 : sCommand += sfx2::cTokenSeperator;
1190 [ # # ][ # # ]: 0 : sCommand += String(pContext->GetDDETopic());
[ # # ]
1191 : :
1192 : 0 : sal_uInt16 nType = static_cast< sal_uInt16 >(pContext->GetIsAutomaticUpdate() ? sfx2::LINKUPDATE_ALWAYS
1193 [ # # ]: 0 : : sfx2::LINKUPDATE_ONCALL);
1194 : :
1195 [ # # ]: 0 : String sName(pContext->GetConnectionName());
1196 : :
1197 : : // field type to be returned
1198 : 0 : SwDDEFieldType* pType = NULL;
1199 : :
1200 : : // valid name?
1201 [ # # ]: 0 : if (sName.Len() == 0)
1202 : : {
1203 : 0 : sName = lcl_GenerateFldTypeName(pContext->GetDDEApplication(),
1204 [ # # ][ # # ]: 0 : pTableNode);
[ # # ]
1205 : : }
1206 : : else
1207 : : {
1208 : : // check for existing DDE field type with the same name
1209 [ # # ]: 0 : SwDDEFieldType* pOldType = (SwDDEFieldType*)pTableNode->GetDoc()->GetFldType(RES_DDEFLD, sName, false);
1210 [ # # ]: 0 : if (NULL != pOldType)
1211 : : {
1212 : : // same values -> return old type
1213 [ # # ][ # # ]: 0 : if ( (pOldType->GetCmd() == sCommand) &&
[ # # ][ # # ]
[ # # ][ # # ]
[ # # # # ]
1214 [ # # ]: 0 : (pOldType->GetType() == nType) )
1215 : : {
1216 : : // same name, same values -> return old type!
1217 : 0 : pType = pOldType;
1218 : : }
1219 : : else
1220 : : {
1221 : : // same name, different values -> think of new name
1222 : 0 : sName = lcl_GenerateFldTypeName(pContext->GetDDEApplication(),
1223 [ # # ][ # # ]: 0 : pTableNode);
[ # # ]
1224 : : }
1225 : : }
1226 : : // no old type -> create new one
1227 : : }
1228 : :
1229 : : // create new field type (unless we already have one)
1230 [ # # ]: 0 : if (NULL == pType)
1231 : : {
1232 : : // create new field type and return
1233 [ # # ]: 0 : SwDDEFieldType aDDEFieldType(sName, sCommand, nType);
1234 : : pType = (SwDDEFieldType*)pTableNode->
1235 [ # # ][ # # ]: 0 : GetDoc()->InsertFldType(aDDEFieldType);
1236 : : }
1237 : :
1238 : : OSL_ENSURE(NULL != pType, "We really want a SwDDEFieldType here!");
1239 [ # # ][ # # ]: 0 : return pType;
1240 : : }
1241 : :
1242 : :
1243 : : // ---------------------------------------------------------------------
1244 : :
1245 : 561 : class TableBoxIndex
1246 : : {
1247 : : public:
1248 : : OUString msName;
1249 : : sal_Int32 mnWidth;
1250 : : sal_Bool mbProtected;
1251 : :
1252 : 345 : TableBoxIndex( const OUString& rName, sal_Int32 nWidth,
1253 : : sal_Bool bProtected ) :
1254 : : msName( rName ),
1255 : : mnWidth( nWidth ),
1256 : 345 : mbProtected( bProtected )
1257 : 345 : { }
1258 : :
1259 : 291 : bool operator== ( const TableBoxIndex& rArg ) const
1260 : : {
1261 : : return (rArg.mnWidth == mnWidth) &&
1262 : : (rArg.mbProtected == mbProtected) &&
1263 [ + - ][ + - ]: 291 : (rArg.msName == msName);
[ + - ]
1264 : : }
1265 : : };
1266 : :
1267 : : class TableBoxIndexHasher
1268 : : {
1269 : : public:
1270 : 396 : size_t operator() (const TableBoxIndex& rArg) const
1271 : : {
1272 : 396 : return rArg.msName.hashCode() + rArg.mnWidth + rArg.mbProtected;
1273 : : }
1274 : : };
1275 : :
1276 : :
1277 : :
1278 : :
1279 : : typedef boost::ptr_vector<SwXMLTableRow_Impl> SwXMLTableRows_Impl;
1280 : :
1281 : 0 : const SwXMLTableCell_Impl *SwXMLTableContext::GetCell( sal_uInt32 nRow,
1282 : : sal_uInt32 nCol ) const
1283 : : {
1284 : 0 : return (*pRows)[(sal_uInt16)nRow].GetCell( (sal_uInt16)nCol );
1285 : : }
1286 : :
1287 : 1380 : SwXMLTableCell_Impl *SwXMLTableContext::GetCell( sal_uInt32 nRow,
1288 : : sal_uInt32 nCol )
1289 : : {
1290 : 1380 : return (*pRows)[(sal_uInt16)nRow].GetCell( (sal_uInt16)nCol );
1291 : : }
1292 : :
1293 [ # # ][ # # ]: 0 : TYPEINIT1( SwXMLTableContext, XMLTextTableContext );
1294 : :
1295 : 3 : SwXMLTableContext::SwXMLTableContext( SwXMLImport& rImport,
1296 : : sal_uInt16 nPrfx,
1297 : : const OUString& rLName,
1298 : : const Reference< xml::sax::XAttributeList > & xAttrList ) :
1299 : : XMLTextTableContext( rImport, nPrfx, rLName ),
1300 : : pColumnDefaultCellStyleNames( 0 ),
1301 [ + - ]: 3 : pRows( new SwXMLTableRows_Impl ),
1302 : : pTableNode( 0 ),
1303 : : pBox1( 0 ),
1304 : : pSttNd1( 0 ),
1305 : : pBoxFmt( 0 ),
1306 : : pLineFmt( 0 ),
1307 : : pSharedBoxFormats(NULL),
1308 : : pDDESource(NULL),
1309 : : bFirstSection( sal_True ),
1310 : : bRelWidth( sal_True ),
1311 : : bHasSubTables( sal_False ),
1312 : : nHeaderRows( 0 ),
1313 : : nCurRow( 0UL ),
1314 : : nCurCol( 0UL ),
1315 [ + - ][ + - ]: 6 : nWidth( 0UL )
1316 : : {
1317 : 3 : OUString aName;
1318 : 3 : OUString sXmlId;
1319 : :
1320 : : // this method will modify the document directly -> lock SolarMutex
1321 [ + - ]: 3 : SolarMutexGuard aGuard;
1322 : :
1323 [ + - ][ + - ]: 3 : sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
[ + - ]
1324 [ + + ]: 9 : for( sal_Int16 i=0; i < nAttrCount; i++ )
1325 : : {
1326 [ + - ][ + - ]: 6 : const OUString& rAttrName = xAttrList->getNameByIndex( i );
1327 : :
1328 : 6 : OUString aLocalName;
1329 : : sal_uInt16 nPrefix =
1330 : 6 : GetImport().GetNamespaceMap().GetKeyByAttrName( rAttrName,
1331 [ + - ]: 6 : &aLocalName );
1332 [ + - ][ + - ]: 6 : const OUString& rValue = xAttrList->getValueByIndex( i );
1333 [ + - ]: 6 : if( XML_NAMESPACE_TABLE == nPrefix )
1334 : : {
1335 [ + - ][ + + ]: 6 : if( IsXMLToken( aLocalName, XML_STYLE_NAME ) )
1336 : 3 : aStyleName = rValue;
1337 [ + - ][ + - ]: 3 : else if( IsXMLToken( aLocalName, XML_NAME ) )
1338 : 3 : aName = rValue;
1339 [ # # ][ # # ]: 0 : else if( IsXMLToken( aLocalName, XML_DEFAULT_CELL_STYLE_NAME ) )
1340 : 0 : aDfltCellStyleName = rValue;
1341 : : }
1342 [ # # ][ # # ]: 0 : else if ( (XML_NAMESPACE_XML == nPrefix) &&
[ # # ]
1343 [ # # ]: 0 : IsXMLToken( aLocalName, XML_ID ) )
1344 : : {
1345 : 0 : sXmlId = rValue;
1346 : : }
1347 : 6 : }
1348 : :
1349 [ + - ]: 3 : SwDoc *pDoc = SwImport::GetDocFromXMLImport( GetSwImport() );
1350 : :
1351 [ + - ]: 3 : String sTblName;
1352 [ + - ]: 3 : if( !aName.isEmpty() )
1353 : : {
1354 [ + - ][ + - ]: 3 : const SwTableFmt *pTblFmt = pDoc->FindTblFmtByName( aName );
[ + - ]
1355 [ + - ]: 3 : if( !pTblFmt )
1356 [ + - ]: 3 : sTblName = aName;
1357 : : }
1358 [ - + ]: 3 : if( !sTblName.Len() )
1359 : : {
1360 [ # # ][ # # ]: 0 : sTblName = pDoc->GetUniqueTblName();
[ # # ]
1361 : 0 : GetImport().GetTextImport()
1362 [ # # # # ]: 0 : ->GetRenameMap().Add( XML_TEXT_RENAME_TYPE_TABLE, aName, sTblName );
[ # # ][ # # ]
[ # # ][ # # ]
1363 : : }
1364 : :
1365 : 3 : Reference< XTextTable > xTable;
1366 : 3 : const SwXTextTable *pXTable = 0;
1367 : 3 : Reference<XMultiServiceFactory> xFactory( GetImport().GetModel(),
1368 [ + - ]: 3 : UNO_QUERY );
1369 : : OSL_ENSURE( xFactory.is(), "factory missing" );
1370 [ + - ]: 3 : if( xFactory.is() )
1371 : : {
1372 : : OUString sService(
1373 [ + - ]: 3 : RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.text.TextTable" ) );
1374 [ + - ][ + - ]: 3 : Reference<XInterface> xIfc = xFactory->createInstance( sService );
1375 : : OSL_ENSURE( xIfc.is(), "Couldn't create a table" );
1376 : :
1377 [ + - ]: 3 : if( xIfc.is() )
1378 [ + - ][ + - ]: 3 : xTable = Reference< XTextTable > ( xIfc, UNO_QUERY );
1379 : : }
1380 : :
1381 [ + - ]: 3 : if( xTable.is() )
1382 : : {
1383 [ + - ][ + - ]: 3 : xTable->initialize( 1, 1 );
1384 : :
1385 : : try
1386 : : {
1387 [ + - ][ + - ]: 3 : xTextContent = Reference< XTextContent >( xTable, UNO_QUERY );
1388 [ + - ][ + - ]: 3 : GetImport().GetTextImport()->InsertTextContent( xTextContent );
[ + - ][ + - ]
1389 : : }
1390 [ # # # # ]: 0 : catch( IllegalArgumentException& )
1391 : : {
1392 [ # # ]: 0 : xTable = 0;
1393 : : }
1394 : : }
1395 : :
1396 [ + - ]: 3 : if( xTable.is() )
1397 : : {
1398 : : //FIXME
1399 : : // xml:id for RDF metadata
1400 [ + - ]: 3 : GetImport().SetXmlId(xTable, sXmlId);
1401 : :
1402 [ + - ]: 3 : Reference<XUnoTunnel> xTableTunnel( xTable, UNO_QUERY);
1403 [ + - ]: 3 : if( xTableTunnel.is() )
1404 : : {
1405 : : pXTable = reinterpret_cast< SwXTextTable * >(
1406 [ + - ][ + - ]: 3 : sal::static_int_cast< sal_IntPtr >( xTableTunnel->getSomething( SwXTextTable::getUnoTunnelId() )));
[ + - ]
1407 : : OSL_ENSURE( pXTable, "SwXTextTable missing" );
1408 : : }
1409 : :
1410 [ + - ]: 3 : Reference < XCellRange > xCellRange( xTable, UNO_QUERY );
1411 [ + - ][ + - ]: 3 : Reference < XCell > xCell = xCellRange->getCellByPosition( 0, 0 );
1412 [ + - ]: 3 : Reference < XText> xText( xCell, UNO_QUERY );
1413 [ + - ][ + - ]: 3 : xOldCursor = GetImport().GetTextImport()->GetCursor();
[ + - ][ + - ]
[ + - ]
1414 [ + - ][ + - ]: 3 : GetImport().GetTextImport()->SetCursor( xText->createTextCursor() );
[ + - ][ + - ]
[ + - ][ + - ]
1415 : :
1416 : : // take care of open redlines for tables
1417 [ + - ][ + - ]: 3 : GetImport().GetTextImport()->RedlineAdjustStartNodeCursor(sal_True);
[ + - ][ + - ]
1418 : : }
1419 [ + - ]: 3 : if( pXTable )
1420 : : {
1421 : 3 : SwFrmFmt *pTblFrmFmt = pXTable->GetFrmFmt();
1422 : : OSL_ENSURE( pTblFrmFmt, "table format missing" );
1423 [ + - ]: 3 : SwTable *pTbl = SwTable::FindTable( pTblFrmFmt );
1424 : : OSL_ENSURE( pTbl, "table missing" );
1425 [ + - ]: 3 : pTableNode = pTbl->GetTableNode();
1426 : : OSL_ENSURE( pTableNode, "table node missing" );
1427 : :
1428 [ + - ]: 3 : pTblFrmFmt->SetName( sTblName );
1429 : :
1430 : 3 : SwTableLine *pLine1 = pTableNode->GetTable().GetTabLines()[0U];
1431 : 3 : pBox1 = pLine1->GetTabBoxes()[0U];
1432 : 3 : pSttNd1 = pBox1->GetSttNd();
1433 [ + - ][ + - ]: 3 : }
1434 : 3 : }
1435 : :
1436 : 0 : SwXMLTableContext::SwXMLTableContext( SwXMLImport& rImport,
1437 : : sal_uInt16 nPrfx,
1438 : : const OUString& rLName,
1439 : : const Reference< xml::sax::XAttributeList > &,
1440 : : SwXMLTableContext *pTable,
1441 : : OUString const & i_rXmlId ) :
1442 : : XMLTextTableContext( rImport, nPrfx, rLName ),
1443 : : mXmlId( i_rXmlId ),
1444 : : pColumnDefaultCellStyleNames( 0 ),
1445 [ # # ]: 0 : pRows( new SwXMLTableRows_Impl ),
1446 : : pTableNode( pTable->pTableNode ),
1447 : : pBox1( 0 ),
1448 : : pSttNd1( 0 ),
1449 : : pBoxFmt( 0 ),
1450 : : pLineFmt( 0 ),
1451 : : pSharedBoxFormats(NULL),
1452 : : xParentTable( pTable ),
1453 : : pDDESource(NULL),
1454 : : bFirstSection( sal_False ),
1455 : : bRelWidth( sal_True ),
1456 : : bHasSubTables( sal_False ),
1457 : : nHeaderRows( 0 ),
1458 : : nCurRow( 0UL ),
1459 : : nCurCol( 0UL ),
1460 [ # # ][ # # ]: 0 : nWidth( 0UL )
1461 : : {
1462 : 0 : }
1463 : :
1464 [ + - ]: 3 : SwXMLTableContext::~SwXMLTableContext()
1465 : : {
1466 [ - + ]: 3 : delete pColumnDefaultCellStyleNames;
1467 [ + - ][ + - ]: 3 : delete pSharedBoxFormats;
1468 [ + - ][ + - ]: 3 : delete pRows;
1469 : :
1470 : : // close redlines on table end nodes
1471 [ + - ][ + - ]: 3 : GetImport().GetTextImport()->RedlineAdjustStartNodeCursor(sal_False);
[ + - ][ + - ]
1472 [ - + ]: 6 : }
1473 : :
1474 : 72 : SvXMLImportContext *SwXMLTableContext::CreateChildContext( sal_uInt16 nPrefix,
1475 : : const OUString& rLocalName,
1476 : : const Reference< xml::sax::XAttributeList > & xAttrList )
1477 : : {
1478 : 72 : SvXMLImportContext *pContext = 0;
1479 : :
1480 : 72 : const SvXMLTokenMap& rTokenMap = GetSwImport().GetTableElemTokenMap();
1481 : 72 : sal_Bool bHeader = sal_False;
1482 [ - - + - : 72 : switch( rTokenMap.Get( nPrefix, rLocalName ) )
- + - - ]
1483 : : {
1484 : : case XML_TOK_TABLE_HEADER_COLS:
1485 : 0 : bHeader = sal_True;
1486 : : case XML_TOK_TABLE_COLS:
1487 [ # # ]: 0 : if( IsValid() )
1488 : : pContext = new SwXMLTableColsContext_Impl( GetSwImport(), nPrefix,
1489 : : rLocalName, xAttrList,
1490 [ # # ]: 0 : this, bHeader );
1491 : 0 : break;
1492 : : case XML_TOK_TABLE_COL:
1493 [ + - ][ + - ]: 3 : if( IsValid() && IsInsertColPossible() )
[ + - ]
1494 : : pContext = new SwXMLTableColContext_Impl( GetSwImport(), nPrefix,
1495 : : rLocalName, xAttrList,
1496 [ + - ]: 3 : this );
1497 : 3 : break;
1498 : : case XML_TOK_TABLE_HEADER_ROWS:
1499 : 0 : bHeader = sal_True;
1500 : : case XML_TOK_TABLE_ROWS:
1501 : : pContext = new SwXMLTableRowsContext_Impl( GetSwImport(), nPrefix,
1502 : : rLocalName, xAttrList,
1503 [ # # ]: 0 : this, bHeader );
1504 : 0 : break;
1505 : : case XML_TOK_TABLE_ROW:
1506 [ + - ]: 69 : if( IsInsertRowPossible() )
1507 : : pContext = new SwXMLTableRowContext_Impl( GetSwImport(), nPrefix,
1508 : : rLocalName, xAttrList,
1509 [ + - ]: 69 : this );
1510 : 69 : break;
1511 : : case XML_TOK_OFFICE_DDE_SOURCE:
1512 : : // save context for later processing (discard old context, if approp.)
1513 [ # # ]: 0 : if( IsValid() )
1514 : : {
1515 [ # # ]: 0 : if (pDDESource != NULL)
1516 : : {
1517 : 0 : pDDESource->ReleaseRef();
1518 : : }
1519 : : pDDESource = new SwXMLDDETableContext_Impl( GetSwImport(), nPrefix,
1520 [ # # ]: 0 : rLocalName );
1521 : 0 : pDDESource->AddRef();
1522 : 0 : pContext = pDDESource;
1523 : : }
1524 : 0 : break;
1525 : : }
1526 : :
1527 [ - + ]: 72 : if( !pContext )
1528 [ # # ]: 0 : pContext = new SvXMLImportContext( GetImport(), nPrefix, rLocalName );
1529 : :
1530 : 72 : return pContext;
1531 : : }
1532 : :
1533 : 15 : void SwXMLTableContext::InsertColumn( sal_Int32 nWidth2, sal_Bool bRelWidth2,
1534 : : const OUString *pDfltCellStyleName )
1535 : : {
1536 : : OSL_ENSURE( nCurCol < USHRT_MAX,
1537 : : "SwXMLTableContext::InsertColumn: no space left" );
1538 [ - + ]: 15 : if( nCurCol >= USHRT_MAX )
1539 : 15 : return;
1540 : :
1541 [ - + ]: 15 : if( nWidth2 < MINLAY )
1542 : 0 : nWidth2 = MINLAY;
1543 [ - + ]: 15 : else if( nWidth2 > USHRT_MAX )
1544 : 0 : nWidth2 = USHRT_MAX;
1545 [ + - ]: 15 : aColumnWidths.push_back( ColumnWidthInfo(nWidth2, bRelWidth2) );
1546 [ + - ][ + - ]: 15 : if( (pDfltCellStyleName && !pDfltCellStyleName->isEmpty()) ||
[ - + ][ - + ]
1547 : : pColumnDefaultCellStyleNames )
1548 : : {
1549 [ # # ]: 0 : if( !pColumnDefaultCellStyleNames )
1550 : : {
1551 [ # # ]: 0 : pColumnDefaultCellStyleNames = new std::vector<String>;
1552 : 0 : sal_uLong nCount = aColumnWidths.size() - 1;
1553 [ # # ]: 0 : while( nCount-- )
1554 [ # # ]: 0 : pColumnDefaultCellStyleNames->push_back(String());
1555 : : }
1556 : :
1557 [ # # ]: 0 : if(pDfltCellStyleName)
1558 [ # # ]: 0 : pColumnDefaultCellStyleNames->push_back(*pDfltCellStyleName);
1559 : : else
1560 [ # # ]: 0 : pColumnDefaultCellStyleNames->push_back(String());
1561 : : }
1562 : : }
1563 : :
1564 : 345 : sal_Int32 SwXMLTableContext::GetColumnWidth( sal_uInt32 nCol,
1565 : : sal_uInt32 nColSpan ) const
1566 : : {
1567 : 345 : sal_uInt32 nLast = nCol+nColSpan;
1568 [ - + ]: 345 : if( nLast > aColumnWidths.size() )
1569 : 0 : nLast = aColumnWidths.size();
1570 : :
1571 : 345 : sal_Int32 nWidth2 = 0L;
1572 [ + + ]: 690 : for( sal_uInt32 i=nCol; i < nLast; ++i )
1573 : 345 : nWidth2 += aColumnWidths[i].width;
1574 : :
1575 : 345 : return nWidth2;
1576 : : }
1577 : :
1578 : 0 : OUString SwXMLTableContext::GetColumnDefaultCellStyleName( sal_uInt32 nCol ) const
1579 : : {
1580 [ # # ][ # # ]: 0 : if( pColumnDefaultCellStyleNames && nCol < pColumnDefaultCellStyleNames->size())
[ # # ]
1581 : 0 : return (*pColumnDefaultCellStyleNames)[static_cast<size_t>(nCol)];
1582 : :
1583 : 0 : return OUString();
1584 : : }
1585 : :
1586 : 345 : void SwXMLTableContext::InsertCell( const OUString& rStyleName,
1587 : : sal_uInt32 nRowSpan, sal_uInt32 nColSpan,
1588 : : const SwStartNode *pStartNode,
1589 : : const OUString & i_rXmlId,
1590 : : SwXMLTableContext *pTable,
1591 : : sal_Bool bProtect,
1592 : : const OUString* pFormula,
1593 : : sal_Bool bHasValue,
1594 : : double fValue,
1595 : : sal_Bool bTextValue )
1596 : : {
1597 : : OSL_ENSURE( nCurCol < GetColumnCount(),
1598 : : "SwXMLTableContext::InsertCell: row is full" );
1599 : : OSL_ENSURE( nCurRow < USHRT_MAX,
1600 : : "SwXMLTableContext::InsertCell: table is full" );
1601 [ + - ][ + - ]: 345 : if( nCurCol >= USHRT_MAX || nCurRow > USHRT_MAX )
1602 : 345 : return;
1603 : :
1604 : : OSL_ENSURE( nRowSpan >=1UL, "SwXMLTableContext::InsertCell: row span is 0" );
1605 [ - + ]: 345 : if( 0UL == nRowSpan )
1606 : 0 : nRowSpan = 1UL;
1607 : : OSL_ENSURE( nColSpan >=1UL, "SwXMLTableContext::InsertCell: col span is 0" );
1608 [ - + ]: 345 : if( 0UL == nColSpan )
1609 : 0 : nColSpan = 1UL;
1610 : :
1611 : : sal_uInt32 i, j;
1612 : :
1613 : : // Until it is possible to add columns here, fix the column span.
1614 : 345 : sal_uInt32 nColsReq = nCurCol + nColSpan;
1615 [ - + ]: 345 : if( nColsReq > GetColumnCount() )
1616 : : {
1617 : 0 : nColSpan = GetColumnCount() - nCurCol;
1618 : 0 : nColsReq = GetColumnCount();
1619 : : }
1620 : :
1621 : : // Check whether there are cells from a previous line already that reach
1622 : : // into the current row.
1623 [ + + ][ - + ]: 345 : if( nCurRow > 0UL && nColSpan > 1UL )
1624 : : {
1625 [ # # ]: 0 : SwXMLTableRow_Impl *pCurRow = &(*pRows)[(sal_uInt16)nCurRow];
1626 : 0 : sal_uInt32 nLastCol = GetColumnCount() < nColsReq ? GetColumnCount()
1627 [ # # ]: 0 : : nColsReq;
1628 [ # # ]: 0 : for( i=nCurCol+1UL; i<nLastCol; i++ )
1629 : : {
1630 [ # # ][ # # ]: 0 : if( pCurRow->GetCell(i)->IsUsed() )
1631 : : {
1632 : : // If this cell is used, the column span is truncated
1633 : 0 : nColSpan = i - nCurCol;
1634 : 0 : nColsReq = i;
1635 : 0 : break;
1636 : : }
1637 : : }
1638 : : }
1639 : :
1640 : 345 : sal_uInt32 nRowsReq = nCurRow + nRowSpan;
1641 [ - + ]: 345 : if( nRowsReq > USHRT_MAX )
1642 : : {
1643 : 0 : nRowSpan = USHRT_MAX - nCurRow;
1644 : 0 : nRowsReq = USHRT_MAX;
1645 : : }
1646 : :
1647 : : // Add columns (if # required columns greater than # columns):
1648 : : // This should never happen, since we require column definitions!
1649 [ - + ]: 345 : if ( nColsReq > GetColumnCount() )
1650 : : {
1651 [ # # ]: 0 : for( i=GetColumnCount(); i<nColsReq; i++ )
1652 : : {
1653 [ # # ]: 0 : aColumnWidths.push_back( ColumnWidthInfo(MINLAY, sal_True) );
1654 : : }
1655 : : // adjust columns in *all* rows, if columns must be inserted
1656 [ # # ]: 0 : for( i=0; i<pRows->size(); i++ )
1657 [ # # ][ # # ]: 0 : (*pRows)[(sal_uInt16)i].Expand( nColsReq, i<nCurRow );
1658 : : }
1659 : :
1660 : : // Add rows
1661 [ - + ]: 345 : if( pRows->size() < nRowsReq )
1662 : : {
1663 : 0 : OUString aStyleName2;
1664 [ # # ]: 0 : for( i = pRows->size(); i < nRowsReq; ++i )
1665 [ # # ][ # # ]: 0 : pRows->push_back( new SwXMLTableRow_Impl(aStyleName2, GetColumnCount()) );
[ # # ]
1666 : : }
1667 : :
1668 : 345 : OUString sStyleName( rStyleName );
1669 [ + + ]: 345 : if( sStyleName.isEmpty() )
1670 : : {
1671 [ + - ]: 294 : sStyleName = (*pRows)[(sal_uInt16)nCurRow].GetDefaultCellStyleName();
1672 [ - + ][ - + ]: 294 : if( sStyleName.isEmpty() && HasColumnDefaultCellStyleNames() )
[ + - ]
1673 : : {
1674 [ # # ]: 0 : sStyleName = GetColumnDefaultCellStyleName( nCurCol );
1675 [ # # ]: 0 : if( sStyleName.isEmpty() )
1676 : 0 : sStyleName = aDfltCellStyleName;
1677 : : }
1678 : : }
1679 : :
1680 : : // Fill the cells
1681 [ + + ]: 690 : for( i=nColSpan; i>0UL; i-- )
1682 : : {
1683 [ + + ]: 690 : for( j=nRowSpan; j>0UL; j-- )
1684 : : {
1685 [ + - ][ - + ]: 345 : const bool bCovered = i != nColSpan || j != nRowSpan;
1686 : : GetCell( nRowsReq-j, nColsReq-i )
1687 : : ->Set( sStyleName, j, i, pStartNode,
1688 : : pTable, bProtect, pFormula, bHasValue, bCovered, fValue,
1689 [ + - ][ + - ]: 345 : bTextValue, i_rXmlId );
1690 : : }
1691 : : }
1692 : :
1693 : : // Set current col to the next (free) column
1694 : 345 : nCurCol = nColsReq;
1695 [ + + ][ + - ]: 345 : while( nCurCol<GetColumnCount() && GetCell(nCurRow,nCurCol)->IsUsed() )
[ - + ][ - + ]
1696 : 345 : nCurCol++;
1697 : : }
1698 : :
1699 : 69 : void SwXMLTableContext::InsertRow( const OUString& rStyleName,
1700 : : const OUString& rDfltCellStyleName,
1701 : : sal_Bool bInHead,
1702 : : const OUString & i_rXmlId )
1703 : : {
1704 : : OSL_ENSURE( nCurRow < USHRT_MAX,
1705 : : "SwXMLTableContext::InsertRow: no space left" );
1706 [ - + ]: 69 : if( nCurRow >= USHRT_MAX )
1707 : 69 : return;
1708 : :
1709 : : // Make sure there is at least one column.
1710 [ + + ][ - + ]: 69 : if( 0==nCurRow && 0UL == GetColumnCount() )
[ - + ]
1711 : 0 : InsertColumn( USHRT_MAX, sal_True );
1712 : :
1713 [ - + ]: 69 : if( nCurRow < pRows->size() )
1714 : : {
1715 : : // The current row has already been inserted because of a row span
1716 : : // of a previous row.
1717 : 0 : (*pRows)[(sal_uInt16)nCurRow].Set(
1718 : 0 : rStyleName, rDfltCellStyleName, i_rXmlId );
1719 : : }
1720 : : else
1721 : : {
1722 : : // add a new row
1723 : : pRows->push_back( new SwXMLTableRow_Impl( rStyleName, GetColumnCount(),
1724 [ + - ]: 69 : &rDfltCellStyleName, i_rXmlId ) );
1725 : : }
1726 : :
1727 : : // We start at the first column ...
1728 : 69 : nCurCol=0UL;
1729 : :
1730 : : // ... but this cell may be occupied already.
1731 [ + - ][ - + ]: 69 : while( nCurCol<GetColumnCount() && GetCell(nCurRow,nCurCol)->IsUsed() )
[ - + ]
1732 : 0 : nCurCol++;
1733 : :
1734 [ - + ][ # # ]: 69 : if( bInHead && nHeaderRows == nCurRow )
1735 : 0 : nHeaderRows++;
1736 : : }
1737 : :
1738 : 0 : void SwXMLTableContext::InsertRepRows( sal_uInt32 nCount )
1739 : : {
1740 : 0 : const SwXMLTableRow_Impl *pSrcRow = &(*pRows)[(sal_uInt16)nCurRow-1];
1741 [ # # ][ # # ]: 0 : while( nCount > 1 && IsInsertRowPossible() )
[ # # ]
1742 : : {
1743 : 0 : InsertRow( pSrcRow->GetStyleName(), pSrcRow->GetDefaultCellStyleName(),
1744 [ # # ]: 0 : sal_False );
1745 [ # # ]: 0 : while( nCurCol < GetColumnCount() )
1746 : : {
1747 [ # # ]: 0 : if( !GetCell(nCurRow,nCurCol)->IsUsed() )
1748 : : {
1749 : : const SwXMLTableCell_Impl *pSrcCell =
1750 : 0 : GetCell( nCurRow-1, nCurCol );
1751 : 0 : InsertCell( pSrcCell->GetStyleName(), 1U,
1752 : : pSrcCell->GetColSpan(),
1753 : : InsertTableSection(),
1754 : : OUString(),
1755 : 0 : 0, pSrcCell->IsProtected(),
1756 : 0 : &pSrcCell->GetFormula(),
1757 : 0 : pSrcCell->HasValue(), pSrcCell->GetValue(),
1758 [ # # ][ # # ]: 0 : pSrcCell->HasTextValue() );
1759 : : }
1760 : : }
1761 : 0 : FinishRow();
1762 : 0 : nCount--;
1763 : : }
1764 : 0 : }
1765 : :
1766 : 69 : void SwXMLTableContext::FinishRow()
1767 : : {
1768 : : // Insert an empty cell at the end of the line if the row is not complete
1769 [ - + ]: 69 : if( nCurCol < GetColumnCount() )
1770 : : {
1771 : 0 : OUString aStyleName2;
1772 : 0 : InsertCell( aStyleName2, 1U, GetColumnCount() - nCurCol,
1773 [ # # # # ]: 0 : InsertTableSection() );
1774 : : }
1775 : :
1776 : : // Move to the next row.
1777 : 69 : nCurRow++;
1778 : 69 : }
1779 : :
1780 : 0 : const SwStartNode *SwXMLTableContext::GetPrevStartNode( sal_uInt32 nRow,
1781 : : sal_uInt32 nCol ) const
1782 : : {
1783 : 0 : const SwXMLTableCell_Impl *pPrevCell = 0;
1784 [ # # ]: 0 : if( GetColumnCount() == nCol )
1785 : : {
1786 : : // The last cell is the right one here.
1787 : 0 : pPrevCell = GetCell( pRows->size()-1U, GetColumnCount()-1UL );
1788 : : }
1789 [ # # ]: 0 : else if( 0UL == nRow )
1790 : : {
1791 : : // There are no vertically merged cells within the first row, so the
1792 : : // previous cell is the right one always.
1793 [ # # ]: 0 : if( nCol > 0UL )
1794 : 0 : pPrevCell = GetCell( nRow, nCol-1UL );
1795 : : }
1796 : : else
1797 : : {
1798 : : // If there is a previous cell in the current row that is not spanned
1799 : : // from the previous row, its the right one.
1800 : 0 : const SwXMLTableRow_Impl *pPrevRow = &(*pRows)[(sal_uInt16)nRow-1U];
1801 : 0 : sal_uInt32 i = nCol;
1802 [ # # ][ # # ]: 0 : while( !pPrevCell && i > 0UL )
[ # # ]
1803 : : {
1804 : 0 : i--;
1805 [ # # ]: 0 : if( 1UL == pPrevRow->GetCell( i )->GetRowSpan() )
1806 : 0 : pPrevCell = GetCell( nRow, i );
1807 : : }
1808 : :
1809 : : // Otherwise, the last cell from the previous row is the right one.
1810 [ # # ]: 0 : if( !pPrevCell )
1811 : 0 : pPrevCell = pPrevRow->GetCell( GetColumnCount()-1UL );
1812 : : }
1813 : :
1814 : 0 : const SwStartNode *pSttNd = 0;
1815 [ # # ]: 0 : if( pPrevCell )
1816 : : {
1817 [ # # ]: 0 : if( pPrevCell->GetStartNode() )
1818 : 0 : pSttNd = pPrevCell->GetStartNode();
1819 : : // #i95726# - Some fault tolerance
1820 : : // else
1821 [ # # ]: 0 : else if ( pPrevCell->GetSubTable() )
1822 : 0 : pSttNd = pPrevCell->GetSubTable()->GetLastStartNode();
1823 : :
1824 : : OSL_ENSURE( pSttNd != 0,
1825 : : "table corrupt" );
1826 : : }
1827 : :
1828 : 0 : return pSttNd;
1829 : : }
1830 : :
1831 : 0 : void SwXMLTableContext::FixRowSpan( sal_uInt32 nRow, sal_uInt32 nCol,
1832 : : sal_uInt32 nColSpan )
1833 : : {
1834 : 0 : sal_uInt32 nLastCol = nCol + nColSpan;
1835 [ # # ]: 0 : for( sal_uInt16 i = (sal_uInt16)nCol; i < nLastCol; i++ )
1836 : : {
1837 : 0 : sal_uInt32 j = nRow;
1838 : 0 : sal_uInt32 nRowSpan = 1UL;
1839 : 0 : SwXMLTableCell_Impl *pCell = GetCell( j, i );
1840 [ # # ][ # # ]: 0 : while( pCell && pCell->GetRowSpan() > 1UL )
[ # # ]
1841 : : {
1842 : 0 : pCell->SetRowSpan( nRowSpan++ );
1843 [ # # ]: 0 : pCell = j > 0UL ? GetCell( --j, i ) : 0;
1844 : : }
1845 : : }
1846 : 0 : }
1847 : :
1848 : 0 : void SwXMLTableContext::ReplaceWithEmptyCell( sal_uInt32 nRow, sal_uInt32 nCol, bool bRows )
1849 : : {
1850 : 0 : const SwStartNode *pPrevSttNd = GetPrevStartNode( nRow, nCol );
1851 : 0 : const SwStartNode *pSttNd = InsertTableSection( pPrevSttNd );
1852 : :
1853 : 0 : const SwXMLTableCell_Impl *pCell = GetCell( nRow, nCol );
1854 [ # # ]: 0 : sal_uInt32 nLastRow = bRows ? nRow + pCell->GetRowSpan() : nRow + 1;
1855 : 0 : sal_uInt32 nLastCol = nCol + pCell->GetColSpan();
1856 : :
1857 [ # # ]: 0 : for( sal_uInt32 i=nRow; i<nLastRow; i++ )
1858 : : {
1859 : 0 : SwXMLTableRow_Impl *pRow = &(*pRows)[(sal_uInt16)i];
1860 [ # # ]: 0 : for( sal_uInt32 j=nCol; j<nLastCol; j++ )
1861 : 0 : pRow->GetCell( j )->SetStartNode( pSttNd );
1862 : : }
1863 : :
1864 : 0 : }
1865 : :
1866 : 345 : SwTableBox *SwXMLTableContext::NewTableBox( const SwStartNode *pStNd,
1867 : : SwTableLine *pUpper )
1868 : : {
1869 : : // The topmost table is the only table that maintains the two members
1870 : : // pBox1 and bFirstSection.
1871 [ - + ]: 345 : if( xParentTable.Is() )
1872 : 0 : return ((SwXMLTableContext *)&xParentTable)->NewTableBox( pStNd,
1873 : 0 : pUpper );
1874 : :
1875 : : SwTableBox *pBox;
1876 : :
1877 [ + + + - ]: 348 : if( pBox1 &&
[ + + ]
1878 : 3 : pBox1->GetSttNd() == pStNd )
1879 : : {
1880 : : // if the StartNode is equal to the StartNode of the initially
1881 : : // created box, we use this box
1882 : 3 : pBox = pBox1;
1883 : 3 : pBox->SetUpper( pUpper );
1884 : 3 : pBox1 = 0;
1885 : : }
1886 : : else
1887 [ + - ]: 342 : pBox = new SwTableBox( pBoxFmt, *pStNd, pUpper );
1888 : :
1889 : 345 : return pBox;
1890 : : }
1891 : :
1892 : 345 : SwTableBoxFmt* SwXMLTableContext::GetSharedBoxFormat(
1893 : : SwTableBox* pBox,
1894 : : const OUString& rStyleName,
1895 : : sal_Int32 nColumnWidth,
1896 : : sal_Bool bProtected,
1897 : : sal_Bool bMayShare,
1898 : : sal_Bool& bNew,
1899 : : sal_Bool* pModifyLocked )
1900 : : {
1901 [ + + ]: 345 : if ( pSharedBoxFormats == NULL )
1902 [ + - ][ + - ]: 3 : pSharedBoxFormats = new map_BoxFmt();
1903 : :
1904 : : SwTableBoxFmt* pBoxFmt2;
1905 : :
1906 : 345 : TableBoxIndex aKey( rStyleName, nColumnWidth, bProtected );
1907 [ + - ]: 345 : map_BoxFmt::iterator aIter = pSharedBoxFormats->find( aKey );
1908 [ + - ][ + + ]: 345 : if ( aIter == pSharedBoxFormats->end() )
1909 : : {
1910 : : // unknown format so far -> construct a new one
1911 : :
1912 : : // get the old format, and reset all attributes
1913 : : // (but preserve FillOrder)
1914 [ + - ]: 54 : pBoxFmt2 = (SwTableBoxFmt*)pBox->ClaimFrmFmt();
1915 [ + - ][ + - ]: 54 : SwFmtFillOrder aFillOrder( pBoxFmt2->GetFillOrder() );
1916 [ + - ]: 54 : pBoxFmt2->ResetAllFmtAttr(); // #i73790# - method renamed
1917 [ + - ]: 54 : pBoxFmt2->SetFmtAttr( aFillOrder );
1918 : 54 : bNew = sal_True; // it's a new format now
1919 : :
1920 : : // share this format, if allowed
1921 [ + - ]: 54 : if ( bMayShare )
1922 [ + - ][ + - ]: 54 : (*pSharedBoxFormats)[ aKey ] = pBoxFmt2;
1923 : : }
1924 : : else
1925 : : {
1926 : : // set the shared format
1927 [ + - ]: 291 : pBoxFmt2 = aIter->second;
1928 [ + - ]: 291 : pBox->ChgFrmFmt( pBoxFmt2 );
1929 : 291 : bNew = sal_False; // copied from an existing format
1930 : :
1931 : : // claim it, if we are not allowed to share
1932 [ - + ]: 291 : if ( !bMayShare )
1933 [ # # ]: 0 : pBoxFmt2 = (SwTableBoxFmt*)pBox->ClaimFrmFmt();
1934 : : }
1935 : :
1936 : : // lock format (if so desired)
1937 [ + - ]: 345 : if ( pModifyLocked != NULL )
1938 : : {
1939 : 345 : (*pModifyLocked) = pBoxFmt2->IsModifyLocked();
1940 : 345 : pBoxFmt2->LockModify();
1941 : : }
1942 : :
1943 : 345 : return pBoxFmt2;
1944 : : }
1945 : :
1946 : 0 : SwTableBox *SwXMLTableContext::MakeTableBox( SwTableLine *pUpper,
1947 : : sal_uInt32 nTopRow,
1948 : : sal_uInt32 nLeftCol,
1949 : : sal_uInt32 nBottomRow,
1950 : : sal_uInt32 nRightCol )
1951 : : {
1952 : : //FIXME: here would be a great place to handle XmlId for cell
1953 [ # # ][ # # ]: 0 : SwTableBox *pBox = new SwTableBox( pBoxFmt, 0, pUpper );
1954 : :
1955 : 0 : sal_uInt32 nColSpan = nRightCol - nLeftCol;
1956 [ # # ]: 0 : sal_Int32 nColWidth = GetColumnWidth( nLeftCol, nColSpan );
1957 : :
1958 : : // TODO: Share formats!
1959 [ # # ]: 0 : SwFrmFmt *pFrmFmt = pBox->ClaimFrmFmt();
1960 [ # # ][ # # ]: 0 : SwFmtFillOrder aFillOrder( pFrmFmt->GetFillOrder() );
1961 [ # # ]: 0 : pFrmFmt->ResetAllFmtAttr(); // #i73790# - method renamed
1962 [ # # ]: 0 : pFrmFmt->SetFmtAttr( aFillOrder );
1963 : :
1964 [ # # ][ # # ]: 0 : pFrmFmt->SetFmtAttr( SwFmtFrmSize( ATT_VAR_SIZE, nColWidth ) );
[ # # ]
1965 : :
1966 : 0 : SwTableLines& rLines = pBox->GetTabLines();
1967 : 0 : sal_Bool bSplitted = sal_False;
1968 : :
1969 [ # # ]: 0 : while( !bSplitted )
1970 : : {
1971 : 0 : sal_uInt32 nStartRow = nTopRow;
1972 : : sal_uInt32 i;
1973 : :
1974 [ # # ]: 0 : for( i = nTopRow; i < nBottomRow; i++ )
1975 : : {
1976 : : // Could the table be splitted behind the current row?
1977 : 0 : sal_Bool bSplit = sal_True;
1978 [ # # ]: 0 : SwXMLTableRow_Impl *pRow = &(*pRows)[(sal_uInt16)i];
1979 [ # # ]: 0 : for( sal_uInt32 j=nLeftCol; j<nRightCol; j++ )
1980 : : {
1981 [ # # ]: 0 : bSplit = ( 1UL == pRow->GetCell(j)->GetRowSpan() );
1982 [ # # ]: 0 : if( !bSplit )
1983 : 0 : break;
1984 : : }
1985 [ # # ][ # # ]: 0 : if( bSplit && (nStartRow>nTopRow || i+1UL<nBottomRow) )
[ # # ]
1986 : : {
1987 : : SwTableLine *pLine =
1988 : : MakeTableLine( pBox, nStartRow, nLeftCol, i+1UL,
1989 [ # # ]: 0 : nRightCol );
1990 : :
1991 [ # # ]: 0 : rLines.push_back( pLine );
1992 : :
1993 : 0 : nStartRow = i+1UL;
1994 : 0 : bSplitted = sal_True;
1995 : : }
1996 : : }
1997 [ # # ]: 0 : if( !bSplitted )
1998 : : {
1999 : : // No splitting was possible. That for, we have to force it.
2000 : : // Ruthless!
2001 : :
2002 : 0 : nStartRow = nTopRow;
2003 [ # # ]: 0 : while( nStartRow < nBottomRow )
2004 : : {
2005 : 0 : sal_uInt32 nMaxRowSpan = 0UL;
2006 [ # # ]: 0 : SwXMLTableRow_Impl *pStartRow = &(*pRows)[(sal_uInt16)nStartRow];
2007 : : const SwXMLTableCell_Impl *pCell;
2008 [ # # ]: 0 : for( i=nLeftCol; i<nRightCol; i++ )
2009 [ # # # # ]: 0 : if( ( pCell=pStartRow->GetCell(i),
2010 : 0 : pCell->GetRowSpan() > nMaxRowSpan ) )
2011 : 0 : nMaxRowSpan = pCell->GetRowSpan();
2012 : :
2013 : 0 : nStartRow += nMaxRowSpan;
2014 [ # # ]: 0 : if( nStartRow<nBottomRow )
2015 : : {
2016 : : SwXMLTableRow_Impl *pPrevRow =
2017 [ # # ]: 0 : &(*pRows)[(sal_uInt16)nStartRow-1U];
2018 : 0 : i = nLeftCol;
2019 [ # # ]: 0 : while( i < nRightCol )
2020 : : {
2021 [ # # ][ # # ]: 0 : if( pPrevRow->GetCell(i)->GetRowSpan() > 1UL )
2022 : : {
2023 : : const SwXMLTableCell_Impl *pCell2 =
2024 [ # # ]: 0 : GetCell( nStartRow, i );
2025 : 0 : const sal_uInt32 nColSpan2 = pCell2->GetColSpan();
2026 [ # # ]: 0 : FixRowSpan( nStartRow-1UL, i, nColSpan2 );
2027 [ # # ]: 0 : ReplaceWithEmptyCell( nStartRow, i, true );
2028 : 0 : i += nColSpan2;
2029 : : }
2030 : : else
2031 : : {
2032 : 0 : i++;
2033 : : }
2034 : : }
2035 : : }
2036 : : }
2037 : : // und jetzt nochmal von vorne ...
2038 : : }
2039 : : }
2040 : :
2041 [ # # ]: 0 : return pBox;
2042 : : }
2043 : :
2044 : 345 : SwTableBox *SwXMLTableContext::MakeTableBox(
2045 : : SwTableLine *pUpper, const SwXMLTableCell_Impl *pCell,
2046 : : sal_uInt32 /*nTopRow*/, sal_uInt32 nLeftCol, sal_uInt32 /*nBottomRow*/,
2047 : : sal_uInt32 nRightCol )
2048 : : {
2049 : : //FIXME: here would be a great place to handle XmlId for cell
2050 : : SwTableBox *pBox;
2051 : 345 : sal_uInt32 nColSpan = nRightCol - nLeftCol;
2052 [ + - ]: 345 : sal_Int32 nColWidth = GetColumnWidth( nLeftCol, nColSpan );
2053 : :
2054 [ + - ]: 345 : if( pCell->GetStartNode() )
2055 : : {
2056 [ + - ]: 345 : pBox = NewTableBox( pCell->GetStartNode(), pUpper );
2057 : : }
2058 : : else
2059 : : {
2060 : : // and it is a table: therefore we build a new box and
2061 : : // put the rows of the table into the rows of the box
2062 [ # # ][ # # ]: 0 : pBox = new SwTableBox( pBoxFmt, 0, pUpper );
2063 [ # # ]: 0 : pCell->GetSubTable()->MakeTable( pBox, nColWidth );
2064 : : }
2065 : :
2066 : : // Share formats!
2067 : 345 : OUString sStyleName = pCell->GetStyleName();
2068 : : sal_Bool bModifyLocked;
2069 : : sal_Bool bNew;
2070 : : SwTableBoxFmt *pBoxFmt2 = GetSharedBoxFormat(
2071 : 345 : pBox, sStyleName, nColWidth, pCell->IsProtected(),
2072 : 690 : pCell->GetStartNode() && pCell->GetFormula().isEmpty() &&
2073 : 345 : ! pCell->HasValue(),
2074 [ + - ][ + - : 1380 : bNew, &bModifyLocked );
+ - + - ]
2075 : :
2076 : : // if a new format was created, then we need to set the style
2077 [ + + ]: 345 : if ( bNew )
2078 : : {
2079 : : // set style
2080 : 54 : const SfxItemSet *pAutoItemSet = 0;
2081 [ + - ][ + + ]: 105 : if( pCell->GetStartNode() && !sStyleName.isEmpty() &&
[ + - ][ + + ]
2082 : 51 : GetSwImport().FindAutomaticStyle(
2083 [ + - ]: 51 : XML_STYLE_FAMILY_TABLE_CELL, sStyleName, &pAutoItemSet ) )
2084 : : {
2085 [ + - ]: 51 : if( pAutoItemSet )
2086 [ + - ]: 54 : pBoxFmt2->SetFmtAttr( *pAutoItemSet );
2087 : : }
2088 : : }
2089 : :
2090 [ + - ]: 345 : if( pCell->GetStartNode() )
2091 : : {
2092 : :
2093 : : // try to rescue broken documents with a certain pattern
2094 : : // if: 1) the cell has a default number format (number 0)
2095 : : // 2) the call has no formula
2096 : : // 3) the value is 0.0
2097 : : // 4) the text doesn't look anything like 0.0
2098 : : // [read: length > 10, or length smaller 10 and no 0 in it]
2099 : : // then make it a text cell!
2100 : 345 : bool bSuppressNumericContent = false;
2101 [ - + ][ # # : 345 : if( pCell->HasValue() && (pCell->GetValue() == 0.0) &&
# # # # ]
[ - + ]
2102 : 0 : pCell->GetFormula().isEmpty() &&
2103 : 0 : !sStyleName.isEmpty() )
2104 : : {
2105 : : // default num format?
2106 : 0 : const SfxPoolItem* pItem = NULL;
2107 [ # # ][ # # ]: 0 : if( pBoxFmt2->GetItemState( RES_BOXATR_FORMAT, sal_False, &pItem )
2108 : : == SFX_ITEM_SET )
2109 : : {
2110 : : const SwTblBoxNumFormat* pNumFormat =
2111 : 0 : static_cast<const SwTblBoxNumFormat*>( pItem );
2112 [ # # ][ # # ]: 0 : if( ( pNumFormat != NULL ) && ( pNumFormat->GetValue() == 0 ) )
[ # # ]
2113 : : {
2114 : : // only one text node?
2115 [ # # ]: 0 : SwNodeIndex aNodeIndex( *(pCell->GetStartNode()), 1 );
2116 [ # # ]: 0 : if( ( aNodeIndex.GetNode().EndOfSectionIndex() -
2117 : 0 : aNodeIndex.GetNode().StartOfSectionIndex() ) == 2 )
2118 : : {
2119 : 0 : SwTxtNode* pTxtNode= aNodeIndex.GetNode().GetTxtNode();
2120 [ # # ]: 0 : if( pTxtNode != NULL )
2121 : : {
2122 : : // check text: does it look like some form of 0.0?
2123 : 0 : const String& rText = pTxtNode->GetTxt();
2124 [ # # ][ # # ]: 0 : if( ( rText.Len() > 10 ) ||
[ # # ]
2125 [ # # ]: 0 : ( rText.Search( '0' ) == STRING_NOTFOUND ) )
2126 : : {
2127 : 0 : bSuppressNumericContent = true;
2128 : : }
2129 : : }
2130 : : }
2131 : : else
2132 [ # # ]: 0 : bSuppressNumericContent = true; // several nodes
2133 : : }
2134 : : }
2135 : : }
2136 : :
2137 [ - + ]: 345 : if( bSuppressNumericContent )
2138 : : {
2139 : : // suppress numeric content? Then reset number format!
2140 [ # # ]: 0 : pBoxFmt2->ResetFmtAttr( RES_BOXATR_FORMULA );
2141 [ # # ]: 0 : pBoxFmt2->ResetFmtAttr( RES_BOXATR_FORMAT );
2142 [ # # ]: 0 : pBoxFmt2->ResetFmtAttr( RES_BOXATR_VALUE );
2143 : : }
2144 : : else
2145 : : {
2146 : : // the normal case: set formula and value (if available)
2147 : :
2148 : 345 : const OUString& rFormula = pCell->GetFormula();
2149 [ - + ]: 345 : if (!rFormula.isEmpty())
2150 : : {
2151 : : // formula cell: insert formula if valid
2152 [ # # ][ # # ]: 0 : SwTblBoxFormula aFormulaItem( rFormula );
[ # # ]
2153 [ # # ][ # # ]: 0 : pBoxFmt2->SetFmtAttr( aFormulaItem );
2154 : : }
2155 [ + - ][ - + ]: 345 : else if( !pCell->HasValue() && pCell->HasTextValue() )
[ - + ]
2156 : : {
2157 : : // Check for another inconsistency:
2158 : : // No value but a non-textual format, i.e. a number format
2159 : : // Solution: the number format will be removed,
2160 : : // the cell gets the default text format.
2161 : 0 : const SfxPoolItem* pItem = NULL;
2162 [ # # ][ # # ]: 0 : if( pBoxFmt->GetItemState( RES_BOXATR_FORMAT, sal_False, &pItem )
2163 : : == SFX_ITEM_SET )
2164 : : {
2165 : 0 : const SwDoc* pDoc = pBoxFmt->GetDoc();
2166 : : const SvNumberFormatter* pNumberFormatter = pDoc ?
2167 [ # # ][ # # ]: 0 : pDoc->GetNumberFormatter() : 0;
2168 : : const SwTblBoxNumFormat* pNumFormat =
2169 : 0 : static_cast<const SwTblBoxNumFormat*>( pItem );
2170 [ # # ]: 0 : if( pNumFormat != NULL && pNumberFormatter &&
[ # # # # ]
[ # # ]
2171 [ # # ]: 0 : !pNumberFormatter->GetEntry( pNumFormat->GetValue() )->IsTextFormat() )
2172 [ # # ]: 0 : pBoxFmt->ResetFmtAttr( RES_BOXATR_FORMAT );
2173 : : }
2174 : : }
2175 : : // always insert value, even if default
2176 [ - + ]: 345 : if( pCell->HasValue() )
2177 : : {
2178 [ # # ]: 0 : SwTblBoxValue aValueItem( pCell->GetValue() );
2179 [ # # ][ # # ]: 0 : pBoxFmt2->SetFmtAttr( aValueItem );
2180 : : }
2181 : : }
2182 : :
2183 : : // update cell content depend on the default language
2184 [ + - ]: 345 : pBox->ActualiseValueBox();
2185 : : }
2186 : :
2187 : : // table cell protection
2188 [ - + ]: 345 : if( pCell->IsProtected() )
2189 : : {
2190 [ # # ]: 0 : SvxProtectItem aProtectItem( RES_PROTECT );
2191 : 0 : aProtectItem.SetCntntProtect( sal_True );
2192 [ # # ][ # # ]: 0 : pBoxFmt2->SetFmtAttr( aProtectItem );
2193 : : }
2194 : :
2195 : : // restore old modify-lock state
2196 [ + - ]: 345 : if (! bModifyLocked)
2197 : 345 : pBoxFmt2->UnlockModify();
2198 : :
2199 [ + - ][ + - ]: 345 : pBoxFmt2->SetFmtAttr( SwFmtFrmSize( ATT_VAR_SIZE, nColWidth ) );
[ + - ]
2200 : :
2201 : 345 : return pBox;
2202 : : }
2203 : :
2204 : 69 : SwTableLine *SwXMLTableContext::MakeTableLine( SwTableBox *pUpper,
2205 : : sal_uInt32 nTopRow,
2206 : : sal_uInt32 nLeftCol,
2207 : : sal_uInt32 nBottomRow,
2208 : : sal_uInt32 nRightCol )
2209 : : {
2210 : : //FIXME: here would be a great place to handle XmlId for row
2211 : : SwTableLine *pLine;
2212 [ + - ][ + + ]: 69 : if( !pUpper && 0UL==nTopRow )
2213 : : {
2214 : 3 : pLine = pTableNode->GetTable().GetTabLines()[0U];
2215 : : }
2216 : : else
2217 : : {
2218 [ + - ][ + - ]: 66 : pLine = new SwTableLine( pLineFmt, 0, pUpper );
2219 : : }
2220 : :
2221 : : // TODO: Share formats!
2222 [ + - ]: 69 : SwFrmFmt *pFrmFmt = pLine->ClaimFrmFmt();
2223 [ + - ][ + - ]: 69 : SwFmtFillOrder aFillOrder( pFrmFmt->GetFillOrder() );
2224 [ + - ]: 69 : pFrmFmt->ResetAllFmtAttr(); // #i73790# - method renamed
2225 [ + - ]: 69 : pFrmFmt->SetFmtAttr( aFillOrder );
2226 : :
2227 : 69 : const SfxItemSet *pAutoItemSet = 0;
2228 [ + - ]: 69 : const OUString& rStyleName = (*pRows)[(sal_uInt16)nTopRow].GetStyleName();
2229 [ # # ][ - + ]: 138 : if( 1UL == (nBottomRow - nTopRow) &&
[ + - - + ]
2230 : 69 : !rStyleName.isEmpty() &&
2231 : 0 : GetSwImport().FindAutomaticStyle(
2232 [ # # ]: 0 : XML_STYLE_FAMILY_TABLE_ROW, rStyleName, &pAutoItemSet ) )
2233 : : {
2234 [ # # ]: 0 : if( pAutoItemSet )
2235 [ # # ]: 0 : pFrmFmt->SetFmtAttr( *pAutoItemSet );
2236 : : }
2237 : :
2238 : 69 : SwTableBoxes& rBoxes = pLine->GetTabBoxes();
2239 : :
2240 : 69 : sal_uInt32 nStartCol = nLeftCol;
2241 [ + + ]: 414 : while( nStartCol < nRightCol )
2242 : : {
2243 [ + + ]: 690 : for( sal_uInt32 nRow=nTopRow; nRow<nBottomRow; nRow++ )
2244 [ + - ]: 345 : (*pRows)[(sal_uInt16)nRow].SetSplitable( sal_True );
2245 : :
2246 : 345 : sal_uInt32 nCol = nStartCol;
2247 : 345 : sal_uInt32 nSplitCol = nRightCol;
2248 : 345 : sal_Bool bSplitted = sal_False;
2249 [ + + ]: 690 : while( !bSplitted )
2250 : : {
2251 : : OSL_ENSURE( nCol < nRightCol, "Zu weit gelaufen" );
2252 : :
2253 : : // Can be split after current HTML table column?
2254 : : // If yes, can the created region still be split to
2255 : : // rows if the next column is added to it?
2256 : 345 : sal_Bool bSplit = sal_True;
2257 : 345 : sal_Bool bHoriSplitMayContinue = sal_False;
2258 : 345 : sal_Bool bHoriSplitPossible = sal_False;
2259 : :
2260 [ - + ]: 345 : if ( bHasSubTables )
2261 : : {
2262 : : // Convert row spans if the table has subtables:
2263 [ # # ]: 0 : for( sal_uInt32 nRow=nTopRow; nRow<nBottomRow; nRow++ )
2264 : : {
2265 [ # # ]: 0 : SwXMLTableCell_Impl *pCell = GetCell(nRow,nCol);
2266 : : // Could the table fragment be splitted horizontally behind
2267 : : // the current line?
2268 [ # # ]: 0 : sal_Bool bHoriSplit = (*pRows)[(sal_uInt16)nRow].IsSplitable() &&
2269 : : nRow+1UL < nBottomRow &&
2270 [ # # ][ # # ]: 0 : 1UL == pCell->GetRowSpan();
[ # # ]
2271 [ # # ]: 0 : (*pRows)[(sal_uInt16)nRow].SetSplitable( bHoriSplit );
2272 : :
2273 : : // Could the table fragment be splitted vertically behind the
2274 : : // current column (uptp the current line?
2275 : 0 : bSplit &= ( 1UL == pCell->GetColSpan() );
2276 [ # # ]: 0 : if( bSplit )
2277 : : {
2278 : 0 : bHoriSplitPossible |= bHoriSplit;
2279 : :
2280 : : // Could the current table fragment be splitted
2281 : : // horizontally behind the next collumn, too?
2282 : : bHoriSplit &= (nCol+1UL < nRightCol &&
2283 [ # # ][ # # ]: 0 : 1UL == GetCell(nRow,nCol+1UL)->GetRowSpan());
[ # # ]
2284 : 0 : bHoriSplitMayContinue |= bHoriSplit;
2285 : : }
2286 : : }
2287 : : }
2288 : : else
2289 : : {
2290 : : // No subtabels: We use the new table model.
2291 [ + - ]: 345 : SwXMLTableCell_Impl *pCell = GetCell(nTopRow,nCol);
2292 : :
2293 : : // #i95726# - some fault tolerance
2294 [ - + ]: 345 : if ( pCell == 0 )
2295 : : {
2296 : : OSL_FAIL( "table seems to be corrupt." );
2297 : 0 : break;
2298 : : }
2299 : :
2300 : : // Could the table fragment be splitted vertically behind the
2301 : : // current column (uptp the current line?
2302 : 345 : bSplit = 1UL == pCell->GetColSpan();
2303 : : }
2304 : :
2305 : : #if OSL_DEBUG_LEVEL > 0
2306 : : if( nCol == nRightCol-1UL )
2307 : : {
2308 : : OSL_ENSURE( bSplit, "Split-Flag falsch" );
2309 : : if ( bHasSubTables )
2310 : : {
2311 : : OSL_ENSURE( !bHoriSplitMayContinue,
2312 : : "HoriSplitMayContinue-Flag falsch" );
2313 : : SwXMLTableCell_Impl *pTmpCell = GetCell( nTopRow, nStartCol );
2314 : : OSL_ENSURE( pTmpCell->GetRowSpan() != (nBottomRow-nTopRow) ||
2315 : : !bHoriSplitPossible, "HoriSplitPossible-Flag falsch" );
2316 : : }
2317 : : }
2318 : : #endif
2319 : :
2320 : : OSL_ENSURE( !bHasSubTables || !bHoriSplitMayContinue || bHoriSplitPossible,
2321 : : "bHoriSplitMayContinue, aber nicht bHoriSplitPossible" );
2322 : :
2323 [ + - ]: 345 : if( bSplit )
2324 : : {
2325 : 345 : SwTableBox* pBox = 0;
2326 [ + - ]: 345 : SwXMLTableCell_Impl *pCell = GetCell( nTopRow, nStartCol );
2327 : : // #i95726# - some fault tolerance
2328 [ - + ][ # # : 1035 : if( ( !bHasSubTables || ( pCell->GetRowSpan() == (nBottomRow-nTopRow) ) ) &&
+ - - + #
# ][ + - ]
2329 : 345 : pCell->GetColSpan() == (nCol+1UL-nStartCol) &&
2330 : 345 : ( pCell->GetStartNode() || pCell->GetSubTable() ) )
2331 : : {
2332 : : // insert new empty cell for covered cells:
2333 : 345 : long nBoxRowSpan = 1;
2334 [ + - ]: 345 : if ( !bHasSubTables )
2335 : : {
2336 : 345 : nBoxRowSpan = pCell->GetRowSpan();
2337 [ - + ]: 345 : if ( pCell->IsCovered() )
2338 : : {
2339 : 0 : nBoxRowSpan = -1 * nBoxRowSpan;
2340 [ # # ]: 0 : ReplaceWithEmptyCell( nTopRow, nStartCol, false );
2341 : : }
2342 : : }
2343 : :
2344 : : // The remaining box neither contains lines nor rows (i.e.
2345 : : // is a content box
2346 : 345 : nSplitCol = nCol + 1UL;
2347 : :
2348 : : pBox = MakeTableBox( pLine, pCell,
2349 : : nTopRow, nStartCol,
2350 [ + - ]: 345 : nBottomRow, nSplitCol );
2351 : :
2352 [ - + ]: 345 : if ( 1 != nBoxRowSpan )
2353 [ # # ]: 0 : pBox->setRowSpan( nBoxRowSpan );
2354 : :
2355 : 345 : bSplitted = sal_True;
2356 : : }
2357 [ # # ][ # # ]: 0 : else if( bHasSubTables && bHoriSplitPossible && bHoriSplitMayContinue )
[ # # ]
2358 : : {
2359 : : // The table fragment could be splitted behind the current
2360 : : // column, and the remaining fragment could be divided
2361 : : // into lines. Anyway, it could be that this applies to
2362 : : // the next column, too. That for, we check the next
2363 : : // column but rememeber the current one as a good place to
2364 : : // split.
2365 : 0 : nSplitCol = nCol + 1UL;
2366 : : }
2367 [ # # ]: 0 : else if ( bHasSubTables )
2368 : : {
2369 : : // If the table resulting table fragment could be divided
2370 : : // into lines if spllitting behind the current column, but
2371 : : // this doesn't apply for thr next column, we split begind
2372 : : // the current column. This applies for the last column,
2373 : : // too.
2374 : : // If the resulting box cannot be splitted into rows,
2375 : : // the split at the last split position we remembered.
2376 [ # # ][ # # ]: 0 : if( bHoriSplitPossible || nSplitCol > nCol+1 )
2377 : : {
2378 : : OSL_ENSURE( !bHoriSplitMayContinue,
2379 : : "bHoriSplitMayContinue==sal_True" );
2380 : : OSL_ENSURE( bHoriSplitPossible || nSplitCol == nRightCol,
2381 : : "bHoriSplitPossible-Flag sollte gesetzt sein" );
2382 : :
2383 : 0 : nSplitCol = nCol + 1UL;
2384 : : }
2385 : :
2386 : : pBox = MakeTableBox( pLine, nTopRow, nStartCol,
2387 [ # # ]: 0 : nBottomRow, nSplitCol );
2388 : 0 : bSplitted = sal_True;
2389 : : }
2390 : :
2391 : : OSL_ENSURE( bHasSubTables || pBox, "Colspan trouble" );
2392 : :
2393 [ + - ]: 345 : if( pBox )
2394 [ + - ]: 345 : rBoxes.push_back( pBox );
2395 : : }
2396 : 345 : nCol++;
2397 : : }
2398 : 345 : nStartCol = nSplitCol;
2399 : : }
2400 : :
2401 [ + - ]: 69 : return pLine;
2402 : : }
2403 : :
2404 : 3 : void SwXMLTableContext::_MakeTable( SwTableBox *pBox )
2405 : : {
2406 : : // fix column widths
2407 : 3 : std::vector<ColumnWidthInfo>::iterator colIter;
2408 : 3 : sal_uInt32 nCols = GetColumnCount();
2409 : :
2410 : : // If there are empty rows (because of some row span of previous rows)
2411 : : // the have to be deleted. The previous rows have to be truncated.
2412 : :
2413 [ - + ]: 3 : if( pRows->size() > nCurRow )
2414 : : {
2415 [ # # ]: 0 : SwXMLTableRow_Impl *pPrevRow = &(*pRows)[(sal_uInt16)nCurRow-1U];
2416 : : const SwXMLTableCell_Impl *pCell;
2417 [ # # ]: 0 : for( sal_uLong i = 0; i < aColumnWidths.size(); ++i )
2418 : : {
2419 [ # # ][ # # ]: 0 : if( ( pCell=pPrevRow->GetCell(i), pCell->GetRowSpan() > 1UL ) )
2420 : : {
2421 [ # # ]: 0 : FixRowSpan( nCurRow-1UL, i, 1UL );
2422 : : }
2423 : : }
2424 [ # # ]: 0 : for( sal_uLong i = pRows->size()-1UL; i>=nCurRow; --i )
2425 [ # # ][ # # ]: 0 : pRows->pop_back();
2426 : : }
2427 : :
2428 [ - + ]: 3 : if( pRows->empty() )
2429 : : {
2430 : 0 : OUString aStyleName2;
2431 [ # # ][ # # ]: 0 : InsertCell( aStyleName2, 1U, nCols, InsertTableSection() );
2432 : : }
2433 : :
2434 : : // TODO: Do we have to keep both values, the relative and the absolute
2435 : : // width?
2436 : 3 : sal_Int32 nAbsWidth = 0L;
2437 : 3 : sal_Int32 nMinAbsColWidth = 0L;
2438 : 3 : sal_Int32 nRelWidth = 0L;
2439 : 3 : sal_Int32 nMinRelColWidth = 0L;
2440 : 3 : sal_uInt32 nRelCols = 0UL;
2441 [ + - ][ + + ]: 18 : for( colIter = aColumnWidths.begin(); colIter < aColumnWidths.end(); ++colIter)
2442 : : {
2443 [ + - ]: 15 : if( colIter->isRelative )
2444 : : {
2445 : 15 : nRelWidth += colIter->width;
2446 [ - + ][ + + ]: 15 : if( 0L == nMinRelColWidth || colIter->width < nMinRelColWidth )
[ + + ]
2447 : 3 : nMinRelColWidth = colIter->width;
2448 : 15 : nRelCols++;
2449 : : }
2450 : : else
2451 : : {
2452 : 0 : nAbsWidth += colIter->width;
2453 [ # # ][ # # ]: 0 : if( 0L == nMinAbsColWidth || colIter->width < nMinAbsColWidth )
[ # # ]
2454 : 0 : nMinAbsColWidth = colIter->width;
2455 : : }
2456 : : }
2457 : 3 : sal_uInt32 nAbsCols = nCols - nRelCols;
2458 : :
2459 [ + - ]: 3 : if( bRelWidth )
2460 : : {
2461 : : // If there a columns that have an absolute width, we have to
2462 : : // calculate a relative one for them.
2463 [ - + ]: 3 : if( nAbsCols > 0UL )
2464 : : {
2465 : : // All column that have absolute widths get relative widths;
2466 : : // these widths relate to each over like the original absolute
2467 : : // widths. The smallest column gets a width that hat the same
2468 : : // value as the smallest column that has an relative width
2469 : : // already.
2470 [ # # ]: 0 : if( 0L == nMinRelColWidth )
2471 : 0 : nMinRelColWidth = nMinAbsColWidth;
2472 : :
2473 [ # # ][ # # ]: 0 : for( colIter = aColumnWidths.begin(); nAbsCols > 0UL && colIter < aColumnWidths.end(); ++colIter)
[ # # ][ # # ]
[ # # # # ]
2474 : : {
2475 [ # # ]: 0 : if( !colIter->isRelative )
2476 : : {
2477 : 0 : sal_Int32 nRelCol = ( colIter->width * nMinRelColWidth) / nMinAbsColWidth;
2478 : 0 : colIter->width = nRelCol;
2479 : 0 : colIter->isRelative = true;
2480 : 0 : nRelWidth += nRelCol;
2481 : 0 : nAbsCols--;
2482 : : }
2483 : : }
2484 : : }
2485 : :
2486 [ - + ]: 3 : if( !nWidth )
2487 : : {
2488 : : // This happens only for percentage values for the table itself.
2489 : : // In this case, the columns get the correct width even if the
2490 : : // the sum of the relative withs is smaller than the available
2491 : : // width in TWIP. Therfore, we can use the relative width.
2492 : : //
2493 : 0 : nWidth = nRelWidth > USHRT_MAX ? USHRT_MAX : nRelWidth;
2494 : : }
2495 [ - + ][ # # ]: 3 : if( nRelWidth != nWidth && nRelWidth && nCols )
[ # # ]
2496 : : {
2497 : 0 : double n = (double)nWidth / (double)nRelWidth;
2498 : 0 : nRelWidth = 0L;
2499 [ # # ][ # # ]: 0 : for( colIter = aColumnWidths.begin(); colIter < aColumnWidths.end() - 1; ++colIter)
[ # # ]
2500 : : {
2501 : 0 : sal_Int32 nW = (sal_Int32)( colIter->width * n);
2502 : 0 : colIter->width = (sal_uInt16)nW;
2503 : 0 : nRelWidth += nW;
2504 : : }
2505 [ # # ]: 0 : aColumnWidths.back().width = (nWidth-nRelWidth);
2506 : : }
2507 : : }
2508 : : else
2509 : : {
2510 : : // If there are columns that have relative widths, we have to
2511 : : // calculate a absolute widths for them.
2512 [ # # ]: 0 : if( nRelCols > 0UL )
2513 : : {
2514 : : // The absolute space that is available for all columns with a
2515 : : // relative width.
2516 : : sal_Int32 nAbsForRelWidth =
2517 [ # # ]: 0 : nWidth > nAbsWidth ? nWidth - nAbsWidth : (sal_Int32)0L;
2518 : :
2519 : : // The relative width that has to be distributed in addition to
2520 : : // equally widthed columns.
2521 : 0 : sal_Int32 nExtraRel = nRelWidth - (nRelCols * nMinRelColWidth);
2522 : :
2523 : : // The absolute space that may be distributed in addition to
2524 : : // minumum widthed columns.
2525 : 0 : sal_Int32 nMinAbs = nRelCols * MINLAY;
2526 : : sal_Int32 nExtraAbs =
2527 [ # # ]: 0 : nAbsForRelWidth > nMinAbs ? nAbsForRelWidth - nMinAbs : (sal_Int32)0L;
2528 : :
2529 : 0 : sal_Bool bMin = sal_False; // Do all columns get the mininum width?
2530 : 0 : sal_Bool bMinExtra = sal_False; // Do all columns get the minimum width plus
2531 : : // some extra space?
2532 : :
2533 [ # # ]: 0 : if( nAbsForRelWidth <= nMinAbs )
2534 : : {
2535 : : // If there is not enough space left for all columns to
2536 : : // get the minimum width, they get the minimum width, anyway.
2537 : 0 : nAbsForRelWidth = nMinAbs;
2538 : 0 : bMin = sal_True;
2539 : : }
2540 [ # # ]: 0 : else if( nAbsForRelWidth <= (nRelWidth * MINLAY) /
2541 : : nMinRelColWidth )
2542 : : {
2543 : : // If there is enougth space for all columns to get the
2544 : : // minimum width, but not to get a width that takes the
2545 : : // relative width into account, each column gets the minimum
2546 : : // width plus some extra space that is based on the additional
2547 : : // space that is available.
2548 : 0 : bMinExtra = sal_True;
2549 : : }
2550 : : // Otherwise, if there is enouth space for every column, every
2551 : : // column gets this space.
2552 : :
2553 [ # # ][ # # ]: 0 : for( colIter = aColumnWidths.begin(); nRelCols > 0UL && colIter < aColumnWidths.end(); ++colIter )
[ # # ][ # # ]
[ # # # # ]
2554 : : {
2555 [ # # ]: 0 : if( colIter->isRelative )
2556 : : {
2557 : : sal_Int32 nAbsCol;
2558 [ # # ]: 0 : if( 1UL == nRelCols )
2559 : : {
2560 : : // The last column that has a relative width gets
2561 : : // all absolute space that is left.
2562 : 0 : nAbsCol = nAbsForRelWidth;
2563 : : }
2564 : : else
2565 : : {
2566 [ # # ]: 0 : if( bMin )
2567 : : {
2568 : 0 : nAbsCol = MINLAY;
2569 : : }
2570 [ # # ]: 0 : else if( bMinExtra )
2571 : : {
2572 : 0 : sal_Int32 nExtraRelCol = colIter->width - nMinRelColWidth;
2573 : : nAbsCol = MINLAY + (nExtraRelCol * nExtraAbs) /
2574 : 0 : nExtraRel;
2575 : : }
2576 : : else
2577 : : {
2578 : 0 : nAbsCol = ( colIter->width * nAbsForRelWidth) / nRelWidth;
2579 : : }
2580 : : }
2581 : 0 : colIter->width = nAbsCol;
2582 : 0 : colIter->isRelative = false;
2583 : 0 : nAbsForRelWidth -= nAbsCol;
2584 : 0 : nAbsWidth += nAbsCol;
2585 : 0 : nRelCols--;
2586 : : }
2587 : : }
2588 : : }
2589 : :
2590 [ # # ][ # # ]: 0 : if( nCols && nAbsWidth )
2591 : : {
2592 [ # # ]: 0 : if( nAbsWidth < nWidth )
2593 : : {
2594 : : // If the table's width is larger than the sum of the absolute
2595 : : // column widths, every column get some extra width.
2596 : 0 : sal_Int32 nExtraAbs = nWidth - nAbsWidth;
2597 [ # # ]: 0 : sal_Int32 nAbsLastCol = aColumnWidths.back().width + nExtraAbs;
2598 [ # # ][ # # ]: 0 : for( colIter = aColumnWidths.begin(); colIter < aColumnWidths.end()-1UL; ++colIter )
[ # # ]
2599 : : {
2600 : 0 : sal_Int32 nAbsCol = colIter->width;
2601 : : sal_Int32 nExtraAbsCol = (nAbsCol * nExtraAbs) /
2602 : 0 : nAbsWidth;
2603 : 0 : nAbsCol += nExtraAbsCol;
2604 : 0 : colIter->width = nAbsCol;
2605 : 0 : nAbsLastCol -= nExtraAbsCol;
2606 : : }
2607 [ # # ]: 0 : aColumnWidths.back().width = nAbsLastCol;
2608 : : }
2609 [ # # ]: 0 : else if( nAbsWidth > nWidth )
2610 : : {
2611 : : // If the table's width is smaller than the sum of the absolute
2612 : : // column widths, every column needs to shrink.
2613 : : // Every column gets the minimum width plus some extra width.
2614 : 0 : sal_Int32 nExtraAbs = nWidth - (nCols * MINLAY);
2615 : 0 : sal_Int32 nAbsLastCol = MINLAY + nExtraAbs;
2616 [ # # ][ # # ]: 0 : for( colIter = aColumnWidths.begin(); colIter < aColumnWidths.end()-1UL; ++colIter )
[ # # ]
2617 : : {
2618 : 0 : sal_Int32 nAbsCol = colIter->width;
2619 : : sal_Int32 nExtraAbsCol = (nAbsCol * nExtraAbs) /
2620 : 0 : nAbsWidth;
2621 : 0 : nAbsCol = MINLAY + nExtraAbsCol;
2622 : 0 : colIter->width = nAbsCol;
2623 : 0 : nAbsLastCol -= nExtraAbsCol;
2624 : : }
2625 [ # # ]: 0 : aColumnWidths.back().width = nAbsLastCol;
2626 : : }
2627 : : }
2628 : : }
2629 : :
2630 : : SwTableLines& rLines =
2631 : : pBox ? pBox->GetTabLines()
2632 [ - + ]: 3 : : pTableNode->GetTable().GetTabLines();
2633 : :
2634 : 3 : sal_uInt32 nStartRow = 0UL;
2635 : 3 : sal_uInt32 nRows = pRows->size();
2636 [ + + ]: 72 : for(sal_uInt32 i=0UL; i<nRows; ++i )
2637 : : {
2638 : : // Could we split the table behind the current line?
2639 : 69 : sal_Bool bSplit = sal_True;
2640 [ - + ]: 69 : if ( bHasSubTables )
2641 : : {
2642 [ # # ]: 0 : SwXMLTableRow_Impl *pRow = &(*pRows)[(sal_uInt16)i];
2643 [ # # ]: 0 : for( sal_uInt32 j=0UL; j<nCols; j++ )
2644 : : {
2645 [ # # ]: 0 : bSplit = ( 1UL == pRow->GetCell(j)->GetRowSpan() );
2646 [ # # ]: 0 : if( !bSplit )
2647 : 0 : break;
2648 : : }
2649 : : }
2650 : :
2651 [ + - ]: 69 : if( bSplit )
2652 : : {
2653 : : SwTableLine *pLine =
2654 [ + - ]: 69 : MakeTableLine( pBox, nStartRow, 0UL, i+1UL, nCols );
2655 [ + - ][ + + ]: 69 : if( pBox || nStartRow>0UL )
2656 [ + - ]: 66 : rLines.push_back( pLine );
2657 : 69 : nStartRow = i+1UL;
2658 : : }
2659 : : }
2660 : 3 : }
2661 : :
2662 : 3 : void SwXMLTableContext::MakeTable()
2663 : : {
2664 : : // this method will modify the document directly -> lock SolarMutex
2665 : : // This will call all other MakeTable*(..) methods, so
2666 : : // those don't need to be locked separately.
2667 [ + - ]: 3 : SolarMutexGuard aGuard;
2668 : :
2669 : : // #i97274# handle invalid tables
2670 [ + - ][ + - ]: 3 : if (!pRows || pRows->empty() || !GetColumnCount())
[ - + ][ - + ]
2671 : : {
2672 : : OSL_FAIL("invalid table: no cells; deleting...");
2673 [ # # ]: 0 : pTableNode->GetDoc()->DeleteSection( pTableNode );
2674 : 0 : pTableNode = 0;
2675 : 0 : pBox1 = 0;
2676 : 0 : pSttNd1 = 0;
2677 : 3 : return;
2678 : : }
2679 : :
2680 : 3 : SwXMLImport& rSwImport = GetSwImport();
2681 : :
2682 : 3 : SwFrmFmt *pFrmFmt = pTableNode->GetTable().GetFrmFmt();
2683 : :
2684 : 3 : sal_Int16 eHoriOrient = text::HoriOrientation::FULL;
2685 : 3 : sal_Bool bSetHoriOrient = sal_False;
2686 : :
2687 : 3 : sal_uInt16 nPrcWidth = 0U;
2688 : :
2689 : 3 : pTableNode->GetTable().SetRowsToRepeat( nHeaderRows );
2690 : 3 : pTableNode->GetTable().SetTableModel( !bHasSubTables );
2691 : :
2692 : 3 : const SfxItemSet *pAutoItemSet = 0;
2693 [ + - ][ + - ]: 6 : if( !aStyleName.isEmpty() &&
[ + - ][ + - ]
2694 : : rSwImport.FindAutomaticStyle(
2695 [ + - ]: 3 : XML_STYLE_FAMILY_TABLE_TABLE, aStyleName, &pAutoItemSet ) &&
2696 : : pAutoItemSet )
2697 : : {
2698 : : const SfxPoolItem *pItem;
2699 : 3 : const SvxLRSpaceItem *pLRSpace = 0;
2700 [ - + ]: 3 : if( SFX_ITEM_SET == pAutoItemSet->GetItemState( RES_LR_SPACE, sal_False,
2701 [ + - ]: 3 : &pItem ) )
2702 : 0 : pLRSpace = (const SvxLRSpaceItem *)pItem;
2703 : :
2704 [ + - ]: 3 : if( SFX_ITEM_SET == pAutoItemSet->GetItemState( RES_HORI_ORIENT, sal_False,
2705 [ + - ]: 3 : &pItem ) )
2706 : : {
2707 : 3 : eHoriOrient = ((const SwFmtHoriOrient *)pItem)->GetHoriOrient();
2708 [ + - - ]: 3 : switch( eHoriOrient )
2709 : : {
2710 : : case text::HoriOrientation::FULL:
2711 [ - + ]: 3 : if( pLRSpace )
2712 : : {
2713 : 0 : eHoriOrient = text::HoriOrientation::NONE;
2714 : 0 : bSetHoriOrient = sal_True;
2715 : : }
2716 : 3 : break;
2717 : : case text::HoriOrientation::LEFT:
2718 [ # # ]: 0 : if( pLRSpace )
2719 : : {
2720 : 0 : eHoriOrient = text::HoriOrientation::LEFT_AND_WIDTH;
2721 : 0 : bSetHoriOrient = sal_True;
2722 : : }
2723 : 3 : break;
2724 : : default:
2725 : : ;
2726 : : }
2727 : : }
2728 : : else
2729 : : {
2730 : 0 : bSetHoriOrient = sal_True;
2731 : : }
2732 : :
2733 : 3 : const SwFmtFrmSize *pSize = 0;
2734 [ + - ]: 3 : if( SFX_ITEM_SET == pAutoItemSet->GetItemState( RES_FRM_SIZE, sal_False,
2735 [ + - ]: 3 : &pItem ) )
2736 : 3 : pSize = (const SwFmtFrmSize *)pItem;
2737 : :
2738 [ + - ]: 3 : switch( eHoriOrient )
2739 : : {
2740 : : case text::HoriOrientation::FULL:
2741 : : case text::HoriOrientation::NONE:
2742 : : // For text::HoriOrientation::NONE we would prefere to use the sum
2743 : : // of the relative column widths as reference width.
2744 : : // Unfortunately this works only if this sum interpreted as
2745 : : // twip value is larger than the space that is avaialable.
2746 : : // We don't know that space, so we have to use USHRT_MAX, too.
2747 : : // Even if a size is speczified, it will be ignored!
2748 : 3 : nWidth = USHRT_MAX;
2749 : 3 : break;
2750 : : default:
2751 [ # # ]: 0 : if( pSize )
2752 : : {
2753 [ # # ]: 0 : if( pSize->GetWidthPercent() )
2754 : : {
2755 : : // The width will be set in _MakeTable
2756 : 0 : nPrcWidth = pSize->GetWidthPercent();
2757 : : }
2758 : : else
2759 : : {
2760 : 0 : nWidth = pSize->GetWidth();
2761 [ # # ]: 0 : if( nWidth < (sal_Int32)GetColumnCount() * MINLAY )
2762 : : {
2763 : 0 : nWidth = GetColumnCount() * MINLAY;
2764 : : }
2765 [ # # ]: 0 : else if( nWidth > USHRT_MAX )
2766 : : {
2767 : 0 : nWidth = USHRT_MAX;
2768 : : }
2769 : 0 : bRelWidth = sal_False;
2770 : : }
2771 : : }
2772 : : else
2773 : : {
2774 : : eHoriOrient = text::HoriOrientation::LEFT_AND_WIDTH == eHoriOrient
2775 [ # # ]: 0 : ? text::HoriOrientation::NONE : text::HoriOrientation::FULL;
2776 : 0 : bSetHoriOrient = sal_True;
2777 : 0 : nWidth = USHRT_MAX;
2778 : : }
2779 : 0 : break;
2780 : : }
2781 : :
2782 [ + - ]: 3 : pFrmFmt->SetFmtAttr( *pAutoItemSet );
2783 : : }
2784 : : else
2785 : : {
2786 : 0 : bSetHoriOrient = sal_True;
2787 : 0 : nWidth = USHRT_MAX;
2788 : : }
2789 : :
2790 : 3 : SwTableLine *pLine1 = pTableNode->GetTable().GetTabLines()[0U];
2791 : : OSL_ENSURE( pBox1 == pLine1->GetTabBoxes()[0U],
2792 : : "Why is box 1 change?" );
2793 : 3 : pBox1->pSttNd = pSttNd1;
2794 [ + - ]: 3 : pLine1->GetTabBoxes().erase( pLine1->GetTabBoxes().begin() );
2795 : :
2796 : 3 : pLineFmt = (SwTableLineFmt*)pLine1->GetFrmFmt();
2797 : 3 : pBoxFmt = (SwTableBoxFmt*)pBox1->GetFrmFmt();
2798 : :
2799 [ + - ]: 3 : _MakeTable( 0 );
2800 : :
2801 [ - + ]: 3 : if( bSetHoriOrient )
2802 [ # # ][ # # ]: 0 : pFrmFmt->SetFmtAttr( SwFmtHoriOrient( 0, eHoriOrient ) );
[ # # ]
2803 : :
2804 : : // This must be after the call to _MakeTable, because nWidth might be
2805 : : // changed there.
2806 : 3 : pFrmFmt->LockModify();
2807 [ + - ]: 3 : SwFmtFrmSize aSize( ATT_VAR_SIZE, nWidth );
2808 : 3 : aSize.SetWidthPercent( (sal_Int8)nPrcWidth );
2809 [ + - ]: 3 : pFrmFmt->SetFmtAttr( aSize );
2810 : 3 : pFrmFmt->UnlockModify();
2811 : :
2812 : :
2813 [ + + ]: 72 : for( sal_uInt16 i=0; i<pRows->size(); i++ )
2814 [ + - ][ + - ]: 69 : (*pRows)[i].Dispose();
2815 : :
2816 : : // now that table is complete, change into DDE table (if appropriate)
2817 [ - + ]: 3 : if (NULL != pDDESource)
2818 : : {
2819 : : // change existing table into DDE table:
2820 : : // 1) Get DDE field type (get data from dde-source context),
2821 : : SwDDEFieldType* pFldType = lcl_GetDDEFieldType( pDDESource,
2822 [ # # ]: 0 : pTableNode );
2823 : :
2824 : : // 2) release the DDE source context,
2825 [ # # ]: 0 : pDDESource->ReleaseRef();
2826 : :
2827 : : // 3) create new DDE table, and
2828 : 0 : SwDDETable* pDDETable = new SwDDETable( pTableNode->GetTable(),
2829 [ # # ][ # # ]: 0 : pFldType, sal_False );
2830 : :
2831 : : // 4) set new (DDE)table at node.
2832 [ # # ]: 0 : pTableNode->SetNewTable(pDDETable, sal_False);
2833 : : }
2834 : :
2835 : : // ??? this is always false: root frame is only created in ViewShell::Init
2836 [ + - ][ - + ]: 3 : if( pTableNode->GetDoc()->GetCurrentViewShell() ) //swmod 071108//swmod 071225
2837 : : {
2838 [ # # ]: 0 : pTableNode->DelFrms();
2839 [ # # ]: 0 : SwNodeIndex aIdx( *pTableNode->EndOfSectionNode(), 1 );
2840 [ # # ][ # # ]: 0 : pTableNode->MakeFrms( &aIdx );
2841 [ + - ][ + - ]: 3 : }
[ + - ]
2842 : : }
2843 : :
2844 : 0 : void SwXMLTableContext::MakeTable( SwTableBox *pBox, sal_Int32 nW )
2845 : : {
2846 : : //FIXME: here would be a great place to handle XmlId for subtable
2847 : 0 : pLineFmt = GetParentTable()->pLineFmt;
2848 : 0 : pBoxFmt = GetParentTable()->pBoxFmt;
2849 : 0 : nWidth = nW;
2850 : 0 : bRelWidth = GetParentTable()->bRelWidth;
2851 : :
2852 : 0 : _MakeTable( pBox );
2853 : 0 : }
2854 : :
2855 : 345 : const SwStartNode *SwXMLTableContext::InsertTableSection(
2856 : : const SwStartNode *pPrevSttNd )
2857 : : {
2858 : : // The topmost table is the only table that maintains the two members
2859 : : // pBox1 and bFirstSection.
2860 [ - + ]: 345 : if( xParentTable.Is() )
2861 [ # # ]: 0 : return ((SwXMLTableContext *)&xParentTable)->InsertTableSection( pPrevSttNd );
2862 : :
2863 : : const SwStartNode *pStNd;
2864 [ + - ][ + - ]: 690 : Reference<XUnoTunnel> xCrsrTunnel( GetImport().GetTextImport()->GetCursor(),
[ + - ][ + - ]
2865 [ + - ]: 345 : UNO_QUERY);
2866 : : OSL_ENSURE( xCrsrTunnel.is(), "missing XUnoTunnel for Cursor" );
2867 : : OTextCursorHelper *pTxtCrsr = reinterpret_cast< OTextCursorHelper * >(
2868 [ + - ][ + - ]: 345 : sal::static_int_cast< sal_IntPtr >( xCrsrTunnel->getSomething( OTextCursorHelper::getUnoTunnelId() )));
[ + - ]
2869 : : OSL_ENSURE( pTxtCrsr, "SwXTextCursor missing" );
2870 : :
2871 [ + + ]: 345 : if( bFirstSection )
2872 : : {
2873 : : // The Cursor already is in the first section
2874 [ + - ][ + - ]: 3 : pStNd = pTxtCrsr->GetPaM()->GetNode()->FindTableBoxStartNode();
2875 : 3 : bFirstSection = sal_False;
2876 [ + - ]: 3 : OUString sStyleName( RTL_CONSTASCII_USTRINGPARAM("Standard") );
2877 : 3 : GetImport().GetTextImport()->SetStyleAndAttrs( GetImport(),
2878 [ + - ][ + - ]: 6 : GetImport().GetTextImport()->GetCursor(), sStyleName, sal_True );
[ + - + - ]
[ + - ][ + - ]
[ + - ][ + - ]
2879 : : }
2880 : : else
2881 : : {
2882 [ + - ]: 342 : SwDoc* pDoc = SwImport::GetDocFromXMLImport( GetSwImport() );
2883 : 0 : const SwEndNode *pEndNd = pPrevSttNd ? pPrevSttNd->EndOfSectionNode()
2884 [ - + ]: 342 : : pTableNode->EndOfSectionNode();
2885 : : // #i78921# - make code robust
2886 : : OSL_ENSURE( pDoc, "<SwXMLTableContext::InsertTableSection(..)> - no <pDoc> at <SwXTextCursor> instance - <SwXTextCurosr> doesn't seem to be registered at a <SwUnoCrsr> instance." );
2887 [ - + ]: 342 : if ( !pDoc )
2888 : : {
2889 : 0 : pDoc = const_cast<SwDoc*>(pEndNd->GetDoc());
2890 : : }
2891 [ - + ]: 342 : sal_uInt32 nOffset = pPrevSttNd ? 1UL : 0UL;
2892 [ + - ]: 342 : SwNodeIndex aIdx( *pEndNd, nOffset );
2893 : : SwTxtFmtColl *pColl =
2894 [ + - ]: 342 : pDoc->GetTxtCollFromPool( RES_POOLCOLL_STANDARD, false );
2895 [ + - ]: 342 : pStNd = pDoc->GetNodes().MakeTextSection( aIdx, SwTableBoxStartNode,
2896 [ + - ]: 342 : pColl );
2897 : : // Consider the case that a table is defined without a row.
2898 [ + - ][ + - ]: 342 : if( !pPrevSttNd && pBox1 != NULL )
2899 : :
2900 : : {
2901 : 342 : pBox1->pSttNd = pStNd;
2902 [ + - ]: 342 : SwCntntNode *pCNd = pDoc->GetNodes()[ pStNd->GetIndex() + 1 ]
2903 [ + - ]: 342 : ->GetCntntNode();
2904 [ + - ]: 342 : SwPosition aPos( *pCNd );
2905 [ + - ][ + - ]: 342 : aPos.nContent.Assign( pCNd, 0U );
2906 : :
2907 : : const uno::Reference< text::XTextRange > xTextRange =
2908 [ + - ]: 342 : SwXTextRange::CreateXTextRange( *pDoc, aPos, 0 );
2909 [ + - ][ + - ]: 342 : Reference < XText > xText = xTextRange->getText();
2910 : : Reference < XTextCursor > xTextCursor =
2911 [ + - ][ + - ]: 342 : xText->createTextCursorByRange( xTextRange );
2912 [ + - ][ + - ]: 342 : GetImport().GetTextImport()->SetCursor( xTextCursor );
[ + - ][ + - ]
[ + - ]
2913 [ + - ]: 342 : }
2914 : : }
2915 : :
2916 : 345 : return pStNd;
2917 : : }
2918 : :
2919 : 3 : void SwXMLTableContext::EndElement()
2920 : : {
2921 [ + - ][ + - ]: 3 : if( IsValid() && !xParentTable.Is() )
[ + - ]
2922 : : {
2923 : 3 : MakeTable();
2924 [ + - ][ + - ]: 3 : GetImport().GetTextImport()->SetCursor( xOldCursor );
2925 : : }
2926 : 3 : }
2927 : :
2928 : 0 : Reference < XTextContent > SwXMLTableContext::GetXTextContent() const
2929 : : {
2930 : 0 : return xTextContent;
2931 : : }
2932 : :
2933 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|