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 : : #include <vcl/svapp.hxx>
31 : : #include <svtools/htmlout.hxx>
32 : : #include <svtools/htmltokn.h>
33 : : #include <svtools/htmlkywd.hxx>
34 : : #include <vcl/wrkwin.hxx>
35 : : #include <editeng/ulspitem.hxx>
36 : : #include <editeng/lrspitem.hxx>
37 : : #include <editeng/brshitem.hxx>
38 : : #include <editeng/boxitem.hxx>
39 : : #include <com/sun/star/form/XFormsSupplier.hpp>
40 : : #include <com/sun/star/form/XForm.hpp>
41 : : #include <com/sun/star/form/XImageProducerSupplier.hpp>
42 : : #include <com/sun/star/form/XFormController.hpp>
43 : : #include <com/sun/star/container/XContainer.hpp>
44 : : #include <com/sun/star/container/XIndexContainer.hpp>
45 : : #include <com/sun/star/container/XSet.hpp>
46 : : #include <fmtornt.hxx>
47 : : #include <frmfmt.hxx>
48 : : #include <fmtfsize.hxx>
49 : : #include <fmtsrnd.hxx>
50 : : #include <frmatr.hxx>
51 : : #include <doc.hxx>
52 : : #include <pam.hxx>
53 : : #include <ndtxt.hxx>
54 : : #include <swrect.hxx>
55 : : #include <cellatr.hxx>
56 : : #include <poolfmt.hxx>
57 : : #include <swtable.hxx>
58 : : #include <htmltbl.hxx>
59 : : #include <htmlnum.hxx>
60 : : #include <wrthtml.hxx>
61 : : #include <wrtswtbl.hxx>
62 : : #ifdef DBG_UTIL
63 : : #include <viewsh.hxx>
64 : : #include <viewopt.hxx>
65 : : #endif
66 : : #include <rtl/strbuf.hxx>
67 : : #include <sal/types.h>
68 : :
69 : : #define MAX_DEPTH (3)
70 : :
71 : : using namespace ::com::sun::star;
72 : :
73 : :
74 [ # # ]: 0 : class SwHTMLWrtTable : public SwWriteTable
75 : : {
76 : : void Pixelize( sal_uInt16& rValue );
77 : : void PixelizeBorders();
78 : :
79 : : void OutTableCell( SwHTMLWriter& rWrt, const SwWriteTableCell *pCell,
80 : : sal_Bool bOutVAlign ) const;
81 : :
82 : : void OutTableCells( SwHTMLWriter& rWrt,
83 : : const SwWriteTableCells& rCells,
84 : : const SvxBrushItem *pBrushItem ) const;
85 : :
86 : : virtual sal_Bool ShouldExpandSub( const SwTableBox *pBox,
87 : : sal_Bool bExpandedBefore, sal_uInt16 nDepth ) const;
88 : :
89 : : static sal_Bool HasTabBackground( const SwTableLine& rLine,
90 : : sal_Bool bTop, sal_Bool bBottom, sal_Bool bLeft, sal_Bool bRight );
91 : : static sal_Bool HasTabBackground( const SwTableBox& rBox,
92 : : sal_Bool bTop, sal_Bool bBottom, sal_Bool bLeft, sal_Bool bRight );
93 : :
94 : : public:
95 : : SwHTMLWrtTable( const SwTableLines& rLines, long nWidth, sal_uInt32 nBWidth,
96 : : sal_Bool bRel, sal_uInt16 nNumOfRowsToRepeat,
97 : : sal_uInt16 nLeftSub=0, sal_uInt16 nRightSub=0 );
98 : : SwHTMLWrtTable( const SwHTMLTableLayout *pLayoutInfo );
99 : :
100 : : void Write( SwHTMLWriter& rWrt, sal_Int16 eAlign=text::HoriOrientation::NONE,
101 : : sal_Bool bTHead=sal_False, const SwFrmFmt *pFrmFmt=0,
102 : : const String *pCaption=0, sal_Bool bTopCaption=sal_False,
103 : : sal_uInt16 nHSpace=0, sal_uInt16 nVSpace=0 ) const;
104 : : };
105 : :
106 : :
107 : 0 : SwHTMLWrtTable::SwHTMLWrtTable( const SwTableLines& rLines, long nWidth,
108 : : sal_uInt32 nBWidth, sal_Bool bRel, sal_uInt16 nNumOfRowsToRepeat,
109 : : sal_uInt16 nLSub, sal_uInt16 nRSub )
110 : 0 : : SwWriteTable( rLines, nWidth, nBWidth, bRel, MAX_DEPTH, nLSub, nRSub, nNumOfRowsToRepeat )
111 : : {
112 [ # # ]: 0 : PixelizeBorders();
113 : 0 : }
114 : :
115 : 0 : SwHTMLWrtTable::SwHTMLWrtTable( const SwHTMLTableLayout *pLayoutInfo )
116 : 0 : : SwWriteTable( pLayoutInfo )
117 : : {
118 : : // Einige Twip-Werte an Pixel-Grenzen anpassen
119 [ # # ]: 0 : if( bCollectBorderWidth )
120 [ # # ]: 0 : PixelizeBorders();
121 : 0 : }
122 : :
123 : 0 : void SwHTMLWrtTable::Pixelize( sal_uInt16& rValue )
124 : : {
125 [ # # ][ # # ]: 0 : if( rValue && Application::GetDefaultDevice() )
[ # # ]
126 : : {
127 : 0 : Size aSz( rValue, 0 );
128 [ # # ][ # # ]: 0 : aSz = Application::GetDefaultDevice()->LogicToPixel( aSz, MapMode(MAP_TWIP) );
[ # # ][ # # ]
129 [ # # ]: 0 : if( !aSz.Width() )
130 : 0 : aSz.Width() = 1;
131 [ # # ][ # # ]: 0 : aSz = Application::GetDefaultDevice()->PixelToLogic( aSz, MapMode(MAP_TWIP) );
[ # # ][ # # ]
132 : 0 : rValue = (sal_uInt16)aSz.Width();
133 : : }
134 : 0 : }
135 : :
136 : 0 : void SwHTMLWrtTable::PixelizeBorders()
137 : : {
138 : 0 : Pixelize( nBorder );
139 : 0 : Pixelize( nCellSpacing );
140 : 0 : Pixelize( nCellPadding );
141 : 0 : }
142 : :
143 : 0 : sal_Bool SwHTMLWrtTable::HasTabBackground( const SwTableBox& rBox,
144 : : sal_Bool bTop, sal_Bool bBottom, sal_Bool bLeft, sal_Bool bRight )
145 : : {
146 : : OSL_ENSURE( bTop || bBottom || bLeft || bRight,
147 : : "HasTabBackground: darf nicht aufgerufen werden" );
148 : :
149 : 0 : sal_Bool bRet = sal_False;
150 [ # # ]: 0 : if( rBox.GetSttNd() )
151 : : {
152 : : const SvxBrushItem& rBrushItem =
153 : 0 : rBox.GetFrmFmt()->GetBackground();
154 : :
155 : : /// The table box has a background, if its background color is not "no fill"/
156 : : /// "auto fill" or it has a background graphic.
157 [ # # ][ # # ]: 0 : bRet = rBrushItem.GetColor() != COL_TRANSPARENT ||
158 [ # # ][ # # ]: 0 : rBrushItem.GetGraphicLink() || rBrushItem.GetGraphic();
[ # # ][ # # ]
159 : : }
160 : : else
161 : : {
162 : 0 : const SwTableLines& rLines = rBox.GetTabLines();
163 : 0 : sal_uInt16 nCount = rLines.size();
164 [ # # ][ # # ]: 0 : sal_Bool bLeftRight = bLeft || bRight;
165 [ # # ][ # # ]: 0 : for( sal_uInt16 i=0; !bRet && i<nCount; i++ )
[ # # ]
166 : : {
167 [ # # ][ # # ]: 0 : sal_Bool bT = bTop && 0 == i;
168 [ # # ][ # # ]: 0 : sal_Bool bB = bBottom && nCount-1 == i;
169 [ # # ][ # # ]: 0 : if( bT || bB || bLeftRight )
[ # # ]
170 : 0 : bRet = HasTabBackground( *rLines[i], bT, bB, bLeft, bRight);
171 : : }
172 : : }
173 : :
174 : 0 : return bRet;
175 : : }
176 : :
177 : 0 : sal_Bool SwHTMLWrtTable::HasTabBackground( const SwTableLine& rLine,
178 : : sal_Bool bTop, sal_Bool bBottom, sal_Bool bLeft, sal_Bool bRight )
179 : : {
180 : : OSL_ENSURE( bTop || bBottom || bLeft || bRight,
181 : : "HasTabBackground: darf nicht aufgerufen werden" );
182 : :
183 : 0 : sal_Bool bRet = sal_False;
184 : 0 : const SvxBrushItem& rBrushItem = rLine.GetFrmFmt()->GetBackground();
185 : : /// The table line has a background, if its background color is not "no fill"/
186 : : /// "auto fill" or it has a background graphic.
187 [ # # ][ # # ]: 0 : bRet = rBrushItem.GetColor() != COL_TRANSPARENT ||
188 [ # # ][ # # ]: 0 : rBrushItem.GetGraphicLink() || rBrushItem.GetGraphic();
[ # # ][ # # ]
189 : :
190 [ # # ]: 0 : if( !bRet )
191 : : {
192 : 0 : const SwTableBoxes& rBoxes = rLine.GetTabBoxes();
193 : 0 : sal_uInt16 nCount = rBoxes.size();
194 [ # # ][ # # ]: 0 : sal_Bool bTopBottom = bTop || bBottom;
195 [ # # ][ # # ]: 0 : for( sal_uInt16 i=0; !bRet && i<nCount; i++ )
[ # # ]
196 : : {
197 [ # # ][ # # ]: 0 : sal_Bool bL = bLeft && 0 == i;
198 [ # # ][ # # ]: 0 : sal_Bool bR = bRight && nCount-1 == i;
199 [ # # ][ # # ]: 0 : if( bTopBottom || bL || bR )
[ # # ]
200 : 0 : bRet = HasTabBackground( *rBoxes[i], bTop, bBottom, bL, bR );
201 : : }
202 : : }
203 : :
204 : 0 : return bRet;
205 : : }
206 : :
207 : : static sal_Bool lcl_TableLine_HasTabBorders( const SwTableLine* pLine, sal_Bool *pBorders );
208 : :
209 : 0 : static sal_Bool lcl_TableBox_HasTabBorders( const SwTableBox* pBox, sal_Bool *pBorders )
210 : : {
211 [ # # ]: 0 : if( *pBorders )
212 : 0 : return sal_False;
213 : :
214 [ # # ]: 0 : if( !pBox->GetSttNd() )
215 : : {
216 [ # # ][ # # ]: 0 : for( SwTableLines::const_iterator it = pBox->GetTabLines().begin();
217 : 0 : it != pBox->GetTabLines().end(); ++it)
218 : : {
219 [ # # ][ # # ]: 0 : if ( lcl_TableLine_HasTabBorders( *it, pBorders ) )
220 : 0 : break;
221 : : }
222 : : }
223 : : else
224 : : {
225 : : const SvxBoxItem& rBoxItem =
226 : 0 : (const SvxBoxItem&)pBox->GetFrmFmt()->GetFmtAttr( RES_BOX );
227 : :
228 : 0 : *pBorders = rBoxItem.GetTop() || rBoxItem.GetBottom() ||
229 [ # # ][ # # ]: 0 : rBoxItem.GetLeft() || rBoxItem.GetRight();
[ # # # # ]
230 : : }
231 : :
232 : 0 : return !*pBorders;
233 : : }
234 : :
235 : 0 : static sal_Bool lcl_TableLine_HasTabBorders( const SwTableLine* pLine, sal_Bool *pBorders )
236 : : {
237 [ # # ]: 0 : if( *pBorders )
238 : 0 : return sal_False;
239 : :
240 [ # # ][ # # ]: 0 : for( SwTableBoxes::const_iterator it = pLine->GetTabBoxes().begin();
241 : 0 : it != pLine->GetTabBoxes().end(); ++it)
242 : : {
243 [ # # ][ # # ]: 0 : if ( lcl_TableBox_HasTabBorders( *it, pBorders ) )
244 : 0 : break;
245 : : }
246 : 0 : return !*pBorders;
247 : : }
248 : :
249 : :
250 : 0 : sal_Bool SwHTMLWrtTable::ShouldExpandSub( const SwTableBox *pBox,
251 : : sal_Bool bExpandedBefore,
252 : : sal_uInt16 nDepth ) const
253 : : {
254 [ # # ][ # # ]: 0 : sal_Bool bExpand = !pBox->GetSttNd() && nDepth>0;
255 [ # # ][ # # ]: 0 : if( bExpand && bExpandedBefore )
256 : : {
257 : : // MIB 30.6.97: Wenn schon eine Box expandiert wurde, wird eine
258 : : // weitere nur expandiert, wenn sie Umrandungen besitzt.
259 : 0 : sal_Bool bBorders = sal_False;
260 [ # # ]: 0 : lcl_TableBox_HasTabBorders( pBox, &bBorders );
261 [ # # ]: 0 : if( !bBorders )
262 [ # # ]: 0 : bBorders = HasTabBackground( *pBox, sal_True, sal_True, sal_True, sal_True );
263 : 0 : bExpand = bBorders;
264 : : }
265 : :
266 : 0 : return bExpand;
267 : : }
268 : :
269 : :
270 : : // Eine Box als einzelne Zelle schreiben
271 : 0 : void SwHTMLWrtTable::OutTableCell( SwHTMLWriter& rWrt,
272 : : const SwWriteTableCell *pCell,
273 : : sal_Bool bOutVAlign ) const
274 : : {
275 : 0 : const SwTableBox *pBox = pCell->GetBox();
276 : 0 : sal_uInt16 nRow = pCell->GetRow();
277 : 0 : sal_uInt16 nCol = pCell->GetCol();
278 : 0 : sal_uInt16 nRowSpan = pCell->GetRowSpan();
279 : 0 : sal_uInt16 nColSpan = pCell->GetColSpan();
280 : :
281 [ # # ]: 0 : if ( !nRowSpan )
282 : 0 : return;
283 : :
284 : : #ifndef PURE_HTML
285 [ # # ]: 0 : SwWriteTableCol *pCol = aCols[nCol];
286 : : #endif
287 : :
288 : 0 : sal_Bool bOutWidth = sal_True;
289 : :
290 : 0 : const SwStartNode* pSttNd = pBox->GetSttNd();
291 : 0 : sal_Bool bHead = sal_False;
292 [ # # ]: 0 : if( pSttNd )
293 : : {
294 : 0 : sal_uLong nNdPos = pSttNd->GetIndex()+1;
295 : :
296 : : // Art der Zelle (TD/TH) bestimmen
297 : : SwNode* pNd;
298 [ # # ][ # # ]: 0 : while( !( pNd = rWrt.pDoc->GetNodes()[nNdPos])->IsEndNode() )
[ # # ]
299 : : {
300 [ # # ]: 0 : if( pNd->IsTxtNode() )
301 : : {
302 : : // nur Absaetzte betrachten, an denen man was erkennt
303 : : // Das ist der Fall, wenn die Vorlage eine der Tabellen-Vorlagen
304 : : // ist oder von einer der beiden abgelitten ist.
305 [ # # ]: 0 : const SwFmt *pFmt = &((SwTxtNode*)pNd)->GetAnyFmtColl();
306 : 0 : sal_uInt16 nPoolId = pFmt->GetPoolFmtId();
307 [ # # ][ # # ]: 0 : while( !pFmt->IsDefault() &&
[ # # ][ # # ]
308 : : RES_POOLCOLL_TABLE_HDLN!=nPoolId &&
309 : : RES_POOLCOLL_TABLE!=nPoolId )
310 : : {
311 : 0 : pFmt = pFmt->DerivedFrom();
312 : 0 : nPoolId = pFmt->GetPoolFmtId();
313 : : }
314 : :
315 [ # # ]: 0 : if( !pFmt->IsDefault() )
316 : : {
317 : 0 : bHead = (RES_POOLCOLL_TABLE_HDLN==nPoolId);
318 : 0 : break;
319 : : }
320 : : }
321 : 0 : nNdPos++;
322 : : }
323 : : }
324 : :
325 [ # # ]: 0 : rWrt.OutNewLine(); // <TH>/<TD> in neue Zeile
326 : 0 : rtl::OStringBuffer sOut;
327 [ # # ]: 0 : sOut.append('<');
328 [ # # ][ # # ]: 0 : sOut.append(bHead ? OOO_STRING_SVTOOLS_HTML_tableheader : OOO_STRING_SVTOOLS_HTML_tabledata);
329 : :
330 : : // ROW- und COLSPAN ausgeben
331 [ # # ]: 0 : if( nRowSpan>1 )
332 : : {
333 [ # # ][ # # ]: 0 : sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_rowspan).
334 [ # # ][ # # ]: 0 : append('=').append(static_cast<sal_Int32>(nRowSpan));
335 : : }
336 [ # # ]: 0 : if( nColSpan > 1 )
337 : : {
338 [ # # ][ # # ]: 0 : sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_colspan).
339 [ # # ][ # # ]: 0 : append('=').append(static_cast<sal_Int32>(nColSpan));
340 : : }
341 : : #ifndef PURE_HTML
342 : 0 : long nWidth = 0;
343 : 0 : sal_uInt32 nPrcWidth = USHRT_MAX;
344 [ # # ]: 0 : if( bOutWidth )
345 : : {
346 [ # # ]: 0 : if( bLayoutExport )
347 : : {
348 [ # # ]: 0 : if( pCell->HasPrcWidthOpt() )
349 : : {
350 : 0 : nPrcWidth = pCell->GetWidthOpt();
351 : : }
352 : : else
353 : : {
354 : 0 : nWidth = pCell->GetWidthOpt();
355 [ # # ]: 0 : if( !nWidth )
356 : 0 : bOutWidth = sal_False;
357 : : }
358 : : }
359 : : else
360 : : {
361 [ # # ]: 0 : if( HasRelWidths() )
362 [ # # ]: 0 : nPrcWidth = (sal_uInt16)GetPrcWidth(nCol,nColSpan);
363 : : else
364 [ # # ]: 0 : nWidth = GetAbsWidth( nCol, nColSpan );
365 : : }
366 : : }
367 : :
368 : 0 : long nHeight = pCell->GetHeight() > 0
369 : 0 : ? GetAbsHeight( pCell->GetHeight(), nRow, nRowSpan )
370 [ # # # # ]: 0 : : 0;
371 : 0 : Size aPixelSz( nWidth, nHeight );
372 : :
373 : : // WIDTH ausgeben (Grrr: nur fuer Netscape)
374 [ # # ][ # # ]: 0 : if( (aPixelSz.Width() || aPixelSz.Height()) && Application::GetDefaultDevice() )
[ # # ][ # # ]
[ # # ]
375 : : {
376 : 0 : Size aOldSz( aPixelSz );
377 : : aPixelSz = Application::GetDefaultDevice()->LogicToPixel( aPixelSz,
378 [ # # ][ # # ]: 0 : MapMode(MAP_TWIP) );
[ # # ][ # # ]
379 [ # # ][ # # ]: 0 : if( aOldSz.Width() && !aPixelSz.Width() )
[ # # ]
380 : 0 : aPixelSz.Width() = 1;
381 [ # # ][ # # ]: 0 : if( aOldSz.Height() && !aPixelSz.Height() )
[ # # ]
382 : 0 : aPixelSz.Height() = 1;
383 : : }
384 : :
385 : : // WIDTH ausgeben: Aus Layout oder berechnet
386 [ # # ]: 0 : if( bOutWidth )
387 : : {
388 [ # # ][ # # ]: 0 : sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_width).
389 [ # # ]: 0 : append('=');
390 [ # # ]: 0 : if( nPrcWidth != USHRT_MAX )
391 : : {
392 [ # # ][ # # ]: 0 : sOut.append(static_cast<sal_Int32>(nPrcWidth)).append('%');
393 : : }
394 : : else
395 : : {
396 [ # # ]: 0 : sOut.append(static_cast<sal_Int32>(aPixelSz.Width()));
397 : : }
398 [ # # ][ # # ]: 0 : if( !bLayoutExport && nColSpan==1 )
399 : 0 : pCol->SetOutWidth( sal_False );
400 : : }
401 : :
402 [ # # ]: 0 : if( nHeight )
403 : : {
404 [ # # ][ # # ]: 0 : sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_height).
405 [ # # ][ # # ]: 0 : append('=').append(static_cast<sal_Int32>(aPixelSz.Height()));
406 : : }
407 : : #endif
408 : :
409 : 0 : const SfxItemSet& rItemSet = pBox->GetFrmFmt()->GetAttrSet();
410 : : const SfxPoolItem *pItem;
411 : :
412 : : // ALIGN wird jetzt nur noch an den Absaetzen ausgegeben
413 : :
414 : : // VALIGN ausgeben
415 [ # # ]: 0 : if( bOutVAlign )
416 : : {
417 [ # # ]: 0 : sal_Int16 eVertOri = pCell->GetVertOri();
418 [ # # ][ # # ]: 0 : if( text::VertOrientation::TOP==eVertOri || text::VertOrientation::BOTTOM==eVertOri )
419 : : {
420 [ # # ][ # # ]: 0 : sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_valign).
421 [ # # ]: 0 : append('=').append(text::VertOrientation::TOP==eVertOri ?
422 : : OOO_STRING_SVTOOLS_HTML_VA_top :
423 [ # # ][ # # ]: 0 : OOO_STRING_SVTOOLS_HTML_VA_bottom);
424 : : }
425 : : }
426 : :
427 [ # # ][ # # ]: 0 : rWrt.Strm() << sOut.makeStringAndClear().getStr();
428 : :
429 : 0 : rWrt.bTxtAttr = sal_False;
430 : 0 : rWrt.bOutOpts = sal_True;
431 : 0 : const SvxBrushItem *pBrushItem = 0;
432 [ # # ][ # # ]: 0 : if( SFX_ITEM_SET==rItemSet.GetItemState( RES_BACKGROUND, sal_False, &pItem ) )
433 : : {
434 : 0 : pBrushItem = (const SvxBrushItem *)pItem;
435 : : }
436 [ # # ]: 0 : if( !pBrushItem )
437 : 0 : pBrushItem = pCell->GetBackground();
438 : :
439 [ # # ]: 0 : if( pBrushItem )
440 : : {
441 : : // Hintergrund ausgeben
442 [ # # ]: 0 : String aDummy;
443 [ # # ]: 0 : rWrt.OutBackground( pBrushItem, aDummy, sal_False );
444 : :
445 [ # # ]: 0 : if( rWrt.bCfgOutStyles )
446 [ # # ][ # # ]: 0 : OutCSS1_TableBGStyleOpt( rWrt, *pBrushItem );
447 : : }
448 : :
449 [ # # ]: 0 : rWrt.OutCSS1_TableCellBorderHack(*pBox->GetFrmFmt());
450 : :
451 : 0 : sal_uInt32 nNumFmt = 0;
452 : 0 : double nValue = 0.0;
453 : 0 : sal_Bool bNumFmt = sal_False, bValue = sal_False;
454 [ # # ][ # # ]: 0 : if( SFX_ITEM_SET==rItemSet.GetItemState( RES_BOXATR_FORMAT, sal_False, &pItem ) )
455 : : {
456 : 0 : nNumFmt = ((const SwTblBoxNumFormat *)pItem)->GetValue();
457 : 0 : bNumFmt = sal_True;
458 : : }
459 [ # # ][ # # ]: 0 : if( SFX_ITEM_SET==rItemSet.GetItemState( RES_BOXATR_VALUE, sal_False, &pItem ) )
460 : : {
461 : 0 : nValue = ((const SwTblBoxValue *)pItem)->GetValue();
462 : 0 : bValue = sal_True;
463 [ # # ]: 0 : if( !bNumFmt )
464 [ # # ]: 0 : nNumFmt = pBox->GetFrmFmt()->GetTblBoxNumFmt().GetValue();
465 : : }
466 : :
467 [ # # ][ # # ]: 0 : if( bNumFmt || bValue )
468 : : {
469 : : sOut.append(HTMLOutFuncs::CreateTableDataOptionsValNum(bValue, nValue,
470 [ # # ]: 0 : nNumFmt, *rWrt.pDoc->GetNumberFormatter(), rWrt.eDestEnc,
471 [ # # ][ # # ]: 0 : &rWrt.aNonConvertableCharacters));
472 : : }
473 [ # # ]: 0 : sOut.append('>');
474 [ # # ][ # # ]: 0 : rWrt.Strm() << sOut.makeStringAndClear().getStr();
475 : 0 : rWrt.bLFPossible = sal_True;
476 : :
477 : 0 : rWrt.IncIndentLevel(); // den Inhalt von <TD>...</TD> einruecken
478 : :
479 [ # # ]: 0 : if( pSttNd )
480 : : {
481 : 0 : HTMLSaveData aSaveData( rWrt, pSttNd->GetIndex()+1,
482 [ # # ]: 0 : pSttNd->EndOfSectionIndex() );
483 [ # # ][ # # ]: 0 : rWrt.Out_SwDoc( rWrt.pCurPam );
484 : : }
485 : : else
486 : : {
487 : : sal_uInt16 nTWidth;
488 : : sal_uInt32 nBWidth;
489 : : sal_uInt16 nLSub, nRSub;
490 [ # # ]: 0 : if( HasRelWidths() )
491 : : {
492 : 0 : nTWidth = 100;
493 [ # # ]: 0 : nBWidth = GetRawWidth( nCol, nColSpan );
494 : 0 : nLSub = 0;
495 : 0 : nRSub = 0;
496 : : }
497 : : else
498 : : {
499 [ # # ]: 0 : nTWidth = GetAbsWidth( nCol, nColSpan );
500 : 0 : nBWidth = nTWidth;
501 [ # # ]: 0 : nLSub = GetLeftSpace( nCol );
502 [ # # ]: 0 : nRSub = GetRightSpace( nCol, nColSpan );
503 : : }
504 : :
505 : 0 : SwHTMLWrtTable aTableWrt( pBox->GetTabLines(), nTWidth,
506 [ # # ]: 0 : nBWidth, HasRelWidths(), nLSub, nRSub );
507 [ # # ][ # # ]: 0 : aTableWrt.Write( rWrt );
508 : : }
509 : :
510 : 0 : rWrt.DecIndentLevel(); // den Inhalt von <TD>...</TD> einruecken
511 : :
512 [ # # ]: 0 : if( rWrt.bLFPossible )
513 [ # # ]: 0 : rWrt.OutNewLine();
514 [ # # ]: 0 : HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), bHead ? OOO_STRING_SVTOOLS_HTML_tableheader
515 : : : OOO_STRING_SVTOOLS_HTML_tabledata,
516 [ # # ][ # # ]: 0 : sal_False );
517 : 0 : rWrt.bLFPossible = sal_True;
518 : : }
519 : :
520 : :
521 : : // Eine Line als Zeilen ausgeben
522 : 0 : void SwHTMLWrtTable::OutTableCells( SwHTMLWriter& rWrt,
523 : : const SwWriteTableCells& rCells,
524 : : const SvxBrushItem *pBrushItem ) const
525 : : {
526 : : // Wenn die Zeile mehr als eine Zelle nethaelt und alle Zellen
527 : : // die gleiche Ausrichtung besitzen, das VALIGN an der Zeile statt der
528 : : // Zelle ausgeben
529 : 0 : sal_Int16 eRowVertOri = text::VertOrientation::NONE;
530 [ # # ]: 0 : if( rCells.size() > 1 )
531 : : {
532 [ # # ]: 0 : for( sal_uInt16 nCell = 0; nCell<rCells.size(); nCell++ )
533 : : {
534 : 0 : sal_Int16 eCellVertOri = rCells[nCell].GetVertOri();
535 [ # # ]: 0 : if( 0==nCell )
536 : : {
537 : 0 : eRowVertOri = eCellVertOri;
538 : : }
539 [ # # ]: 0 : else if( eRowVertOri != eCellVertOri )
540 : : {
541 : 0 : eRowVertOri = text::VertOrientation::NONE;
542 : 0 : break;
543 : : }
544 : : }
545 : : }
546 : :
547 : 0 : rWrt.OutNewLine(); // <TR> in neuer Zeile
548 : 0 : rWrt.Strm() << '<' << OOO_STRING_SVTOOLS_HTML_tablerow;
549 [ # # ]: 0 : if( pBrushItem )
550 : : {
551 [ # # ]: 0 : String aDummy;
552 [ # # ]: 0 : rWrt.OutBackground( pBrushItem, aDummy, sal_False );
553 : :
554 : 0 : rWrt.bTxtAttr = sal_False;
555 : 0 : rWrt.bOutOpts = sal_True;
556 [ # # ]: 0 : if( rWrt.bCfgOutStyles )
557 [ # # ][ # # ]: 0 : OutCSS1_TableBGStyleOpt( rWrt, *pBrushItem );
558 : : }
559 : :
560 [ # # ][ # # ]: 0 : if( text::VertOrientation::TOP==eRowVertOri || text::VertOrientation::BOTTOM==eRowVertOri )
561 : : {
562 : 0 : rtl::OStringBuffer sOut;
563 [ # # ][ # # ]: 0 : sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_valign)
564 [ # # ][ # # ]: 0 : .append('=').append(text::VertOrientation::TOP==eRowVertOri ? OOO_STRING_SVTOOLS_HTML_VA_top : OOO_STRING_SVTOOLS_HTML_VA_bottom);
[ # # ]
565 [ # # ][ # # ]: 0 : rWrt.Strm() << sOut.makeStringAndClear().getStr();
566 : : }
567 : :
568 : 0 : rWrt.Strm() << '>';
569 : :
570 : 0 : rWrt.IncIndentLevel(); // Inhalt von <TR>...</TR> einruecken
571 : :
572 [ # # ]: 0 : for( sal_uInt16 nCell = 0; nCell<rCells.size(); nCell++ )
573 : 0 : OutTableCell( rWrt, &rCells[nCell], text::VertOrientation::NONE==eRowVertOri );
574 : :
575 : 0 : rWrt.DecIndentLevel(); // Inhalt von <TR>...</TR> einruecken
576 : :
577 : 0 : rWrt.OutNewLine(); // </TR> in neuer Zeile
578 : 0 : HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_tablerow, sal_False );
579 : 0 : }
580 : :
581 : :
582 : :
583 : 0 : void SwHTMLWrtTable::Write( SwHTMLWriter& rWrt, sal_Int16 eAlign,
584 : : sal_Bool bTHead, const SwFrmFmt *pFrmFmt,
585 : : const String *pCaption, sal_Bool bTopCaption,
586 : : sal_uInt16 nHSpace, sal_uInt16 nVSpace ) const
587 : : {
588 : : sal_uInt16 nRow;
589 : :
590 : : // Wert fuer FRAME bestimmen
591 : 0 : sal_uInt16 nFrameMask = 15;
592 [ # # ][ # # ]: 0 : if( !(aRows.front())->bTopBorder )
593 : 0 : nFrameMask &= ~1;
594 [ # # ][ # # ]: 0 : if( !(aRows.back())->bBottomBorder )
595 : 0 : nFrameMask &= ~2;
596 [ # # ][ # # ]: 0 : if( !(aCols.front())->bLeftBorder )
597 : 0 : nFrameMask &= ~4;
598 [ # # ][ # # ]: 0 : if( !(aCols.back())->bRightBorder )
599 : 0 : nFrameMask &= ~8;
600 : :
601 : : // Wert fur RULES bestimmen
602 : 0 : sal_Bool bRowsHaveBorder = sal_False;
603 : 0 : sal_Bool bRowsHaveBorderOnly = sal_True;
604 [ # # ]: 0 : SwWriteTableRow *pRow = aRows[0];
605 [ # # ]: 0 : for( nRow=1; nRow < aRows.size(); nRow++ )
606 : : {
607 [ # # ]: 0 : SwWriteTableRow *pNextRow = aRows[nRow];
608 [ # # ][ # # ]: 0 : sal_Bool bBorder = ( pRow->bBottomBorder || pNextRow->bTopBorder );
609 : 0 : bRowsHaveBorder |= bBorder;
610 : 0 : bRowsHaveBorderOnly &= bBorder;
611 : :
612 [ # # ]: 0 : sal_uInt16 nBorder2 = pRow->bBottomBorder ? pRow->nBottomBorder : USHRT_MAX;
613 [ # # ][ # # ]: 0 : if( pNextRow->bTopBorder && pNextRow->nTopBorder < nBorder2 )
614 : 0 : nBorder2 = pNextRow->nTopBorder;
615 : :
616 : 0 : pRow->bBottomBorder = bBorder;
617 : 0 : pRow->nBottomBorder = nBorder2;
618 : :
619 : 0 : pNextRow->bTopBorder = bBorder;
620 : 0 : pNextRow->nTopBorder = nBorder2;
621 : :
622 : 0 : pRow = pNextRow;
623 : : }
624 : :
625 : 0 : sal_Bool bColsHaveBorder = sal_False;
626 : 0 : sal_Bool bColsHaveBorderOnly = sal_True;
627 [ # # ]: 0 : SwWriteTableCol *pCol = aCols[0];
628 : : sal_uInt16 nCol;
629 [ # # ]: 0 : for( nCol=1; nCol<aCols.size(); nCol++ )
630 : : {
631 [ # # ]: 0 : SwWriteTableCol *pNextCol = aCols[nCol];
632 [ # # ][ # # ]: 0 : sal_Bool bBorder = ( pCol->bRightBorder || pNextCol->bLeftBorder );
633 : 0 : bColsHaveBorder |= bBorder;
634 : 0 : bColsHaveBorderOnly &= bBorder;
635 : 0 : pCol->bRightBorder = bBorder;
636 : 0 : pNextCol->bLeftBorder = bBorder;
637 : 0 : pCol = pNextCol;
638 : : }
639 : :
640 : :
641 : : // vorhergende Aufzaehlung etc. beenden
642 [ # # ]: 0 : rWrt.ChangeParaToken( 0 );
643 : :
644 [ # # ]: 0 : if( rWrt.bLFPossible )
645 [ # # ]: 0 : rWrt.OutNewLine(); // <TABLE> in neue Zeile
646 : 0 : rtl::OStringBuffer sOut;
647 [ # # ][ # # ]: 0 : sOut.append('<').append(OOO_STRING_SVTOOLS_HTML_table);
648 : :
649 : 0 : sal_uInt16 nOldDirection = rWrt.nDirection;
650 [ # # ]: 0 : if( pFrmFmt )
651 [ # # ]: 0 : rWrt.nDirection = rWrt.GetHTMLDirection( pFrmFmt->GetAttrSet() );
652 [ # # ][ # # ]: 0 : if( rWrt.bOutFlyFrame || nOldDirection != rWrt.nDirection )
653 : : {
654 [ # # ][ # # ]: 0 : rWrt.Strm() << sOut.makeStringAndClear().getStr();
655 [ # # ]: 0 : rWrt.OutDirection( rWrt.nDirection );
656 : : }
657 : :
658 : : // COLS ausgeben: Nur bei Export ueber Layout, wenn es beim Import
659 : : // vorhanden war.
660 [ # # ]: 0 : if( bColsOption )
661 : : {
662 [ # # ][ # # ]: 0 : sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_cols).
663 [ # # ][ # # ]: 0 : append('=').append(static_cast<sal_Int32>(aCols.size()));
664 : : }
665 : :
666 : : // ALIGN= ausgeben
667 [ # # ]: 0 : if( text::HoriOrientation::RIGHT == eAlign )
668 : : {
669 [ # # ][ # # ]: 0 : sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_align).
670 [ # # ][ # # ]: 0 : append('=').append(OOO_STRING_SVTOOLS_HTML_AL_right);
671 : : }
672 [ # # ]: 0 : else if( text::HoriOrientation::CENTER == eAlign )
673 : : {
674 [ # # ][ # # ]: 0 : sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_align).
675 [ # # ][ # # ]: 0 : append('=').append(OOO_STRING_SVTOOLS_HTML_AL_center);
676 : : }
677 [ # # ]: 0 : else if( text::HoriOrientation::LEFT == eAlign )
678 : : {
679 [ # # ][ # # ]: 0 : sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_align).
680 [ # # ][ # # ]: 0 : append('=').append(OOO_STRING_SVTOOLS_HTML_AL_left);
681 : : }
682 : :
683 : : // WIDTH ausgeben: Stammt aus Layout oder ist berechnet
684 [ # # ]: 0 : if( nTabWidth )
685 : : {
686 [ # # ][ # # ]: 0 : sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_width).
687 [ # # ]: 0 : append('=');
688 [ # # ]: 0 : if( HasRelWidths() )
689 [ # # ][ # # ]: 0 : sOut.append(static_cast<sal_Int32>(nTabWidth)).append('%');
690 [ # # ][ # # ]: 0 : else if( Application::GetDefaultDevice() )
691 : : {
692 : : sal_Int32 nPixWidth = Application::GetDefaultDevice()->LogicToPixel(
693 [ # # ][ # # ]: 0 : Size(nTabWidth,0), MapMode(MAP_TWIP) ).Width();
[ # # ][ # # ]
694 [ # # ]: 0 : if( !nPixWidth )
695 : 0 : nPixWidth = 1;
696 : :
697 [ # # ]: 0 : sOut.append(nPixWidth);
698 : : }
699 : : else
700 : : {
701 : : OSL_ENSURE( Application::GetDefaultDevice(), "kein Application-Window!?" );
702 [ # # ]: 0 : sOut.append(RTL_CONSTASCII_STRINGPARAM("100%"));
703 : : }
704 : : }
705 : :
706 [ # # ][ # # ]: 0 : if( (nHSpace || nVSpace) && Application::GetDefaultDevice())
[ # # ][ # # ]
[ # # ]
707 : : {
708 : : Size aPixelSpc =
709 : : Application::GetDefaultDevice()->LogicToPixel( Size(nHSpace,nVSpace),
710 [ # # ][ # # ]: 0 : MapMode(MAP_TWIP) );
[ # # ][ # # ]
711 [ # # ][ # # ]: 0 : if( !aPixelSpc.Width() && nHSpace )
[ # # ]
712 : 0 : aPixelSpc.Width() = 1;
713 [ # # ][ # # ]: 0 : if( !aPixelSpc.Height() && nVSpace )
[ # # ]
714 : 0 : aPixelSpc.Height() = 1;
715 : :
716 [ # # ]: 0 : if( aPixelSpc.Width() )
717 : : {
718 [ # # ][ # # ]: 0 : sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_hspace).
719 [ # # ][ # # ]: 0 : append('=').append(static_cast<sal_Int32>(aPixelSpc.Width()));
720 : : }
721 : :
722 [ # # ]: 0 : if( aPixelSpc.Height() )
723 : : {
724 [ # # ][ # # ]: 0 : sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_vspace).
725 [ # # ][ # # ]: 0 : append('=').append(static_cast<sal_Int32>(aPixelSpc.Height()));
726 : : }
727 : : }
728 : :
729 : : // CELLPADDING ausgeben: Stammt aus Layout oder ist berechnet
730 [ # # ][ # # ]: 0 : sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_cellpadding).
731 [ # # ][ # # ]: 0 : append('=').append(static_cast<sal_Int32>(rWrt.ToPixel(nCellPadding)));
[ # # ]
732 : :
733 : : // CELLSPACING ausgeben: Stammt aus Layout oder ist berechnet
734 [ # # ][ # # ]: 0 : sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_cellspacing).
735 [ # # ][ # # ]: 0 : append('=').append(static_cast<sal_Int32>(rWrt.ToPixel(nCellSpacing)));
[ # # ]
736 : :
737 [ # # ][ # # ]: 0 : rWrt.Strm() << sOut.makeStringAndClear().getStr();
738 : :
739 : : // Hintergrund ausgeben
740 [ # # ]: 0 : if( pFrmFmt )
741 : : {
742 [ # # ]: 0 : String aDummy;
743 [ # # ]: 0 : rWrt.OutBackground( pFrmFmt->GetAttrSet(), aDummy, sal_False );
744 : :
745 [ # # ][ # # ]: 0 : if( rWrt.bCfgOutStyles && pFrmFmt )
746 [ # # ][ # # ]: 0 : rWrt.OutCSS1_TableFrmFmtOptions( *pFrmFmt );
747 : : }
748 : :
749 [ # # ]: 0 : sOut.append('>');
750 [ # # ][ # # ]: 0 : rWrt.Strm() << sOut.makeStringAndClear().getStr();
751 : :
752 : 0 : rWrt.IncIndentLevel(); // Inhalte von Table einruecken
753 : :
754 : : // Ueberschrift ausgeben
755 [ # # ][ # # ]: 0 : if( pCaption && pCaption->Len() )
[ # # ]
756 : : {
757 [ # # ]: 0 : rWrt.OutNewLine(); // <CAPTION> in neue Zeile
758 [ # # ]: 0 : rtl::OStringBuffer sOutStr(RTL_CONSTASCII_STRINGPARAM(OOO_STRING_SVTOOLS_HTML_caption));
759 [ # # ][ # # ]: 0 : sOutStr.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_align).append('=')
[ # # ]
760 [ # # ][ # # ]: 0 : .append(bTopCaption ? OOO_STRING_SVTOOLS_HTML_VA_top : OOO_STRING_SVTOOLS_HTML_VA_bottom);
761 [ # # ][ # # ]: 0 : HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), sOutStr.getStr(), sal_True );
762 [ # # ][ # # ]: 0 : HTMLOutFuncs::Out_String( rWrt.Strm(), *pCaption, rWrt.eDestEnc, &rWrt.aNonConvertableCharacters );
763 [ # # ][ # # ]: 0 : HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_caption, sal_False );
764 : : }
765 : :
766 : 0 : sal_uInt16 nCols = aCols.size();
767 : :
768 : : // <COLGRP>/<COL> ausgeben: Bei Export ueber Layout nur wenn beim
769 : : // Import welche da waren, sonst immer.
770 [ # # ][ # # ]: 0 : sal_Bool bColGroups = (bColsHaveBorder && !bColsHaveBorderOnly);
771 [ # # ]: 0 : if( bColTags )
772 : : {
773 [ # # ]: 0 : if( bColGroups )
774 : : {
775 [ # # ]: 0 : rWrt.OutNewLine(); // <COLGRP> in neue Zeile
776 [ # # ][ # # ]: 0 : HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_colgroup, sal_True );
777 : :
778 : 0 : rWrt.IncIndentLevel(); // Inhalt von <COLGRP> einruecken
779 : : }
780 : :
781 [ # # ]: 0 : for( nCol=0; nCol<nCols; nCol++ )
782 : : {
783 [ # # ]: 0 : rWrt.OutNewLine(); // <COL> in neue Zeile
784 : :
785 [ # # ]: 0 : const SwWriteTableCol *pColumn = aCols[nCol];
786 : :
787 : 0 : rtl::OStringBuffer sOutStr;
788 [ # # ][ # # ]: 0 : sOutStr.append('<').append(OOO_STRING_SVTOOLS_HTML_col);
789 : :
790 : : sal_uInt32 nWidth;
791 : : sal_Bool bRel;
792 [ # # ]: 0 : if( bLayoutExport )
793 : : {
794 : 0 : bRel = pColumn->HasRelWidthOpt();
795 : 0 : nWidth = pColumn->GetWidthOpt();
796 : : }
797 : : else
798 : : {
799 : 0 : bRel = HasRelWidths();
800 [ # # ][ # # ]: 0 : nWidth = bRel ? GetRelWidth(nCol,1) : GetAbsWidth(nCol,1);
[ # # ]
801 : : }
802 : :
803 [ # # ][ # # ]: 0 : sOutStr.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_width).
804 [ # # ]: 0 : append('=');
805 [ # # ]: 0 : if( bRel )
806 [ # # ][ # # ]: 0 : sOutStr.append(static_cast<sal_Int32>(nWidth)).append('*');
807 : : else
808 [ # # ][ # # ]: 0 : sOutStr.append(static_cast<sal_Int32>(rWrt.ToPixel(nWidth)));
809 [ # # ]: 0 : sOutStr.append('>');
810 [ # # ][ # # ]: 0 : rWrt.Strm() << sOutStr.makeStringAndClear().getStr();
811 : :
812 [ # # ][ # # ]: 0 : if( bColGroups && pColumn->bRightBorder && nCol<nCols-1 )
[ # # ]
813 : : {
814 : 0 : rWrt.DecIndentLevel(); // Inhalt von <COLGRP> einruecken
815 [ # # ]: 0 : rWrt.OutNewLine(); // </COLGRP> in neue Zeile
816 [ # # ]: 0 : HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_colgroup,
817 [ # # ]: 0 : sal_False );
818 [ # # ]: 0 : rWrt.OutNewLine(); // <COLGRP> in neue Zeile
819 [ # # ]: 0 : HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_colgroup,
820 [ # # ]: 0 : sal_True );
821 : 0 : rWrt.IncIndentLevel(); // Inhalt von <COLGRP> einruecken
822 : : }
823 : 0 : }
824 [ # # ]: 0 : if( bColGroups )
825 : : {
826 : 0 : rWrt.DecIndentLevel(); // Inhalt von <COLGRP> einruecken
827 : :
828 [ # # ]: 0 : rWrt.OutNewLine(); // </COLGRP> in neue Zeile
829 [ # # ]: 0 : HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_colgroup,
830 [ # # ]: 0 : sal_False );
831 : : }
832 : : }
833 : :
834 : : // die Lines als Tabellenzeilen rausschreiben
835 : :
836 : : // <TBODY> ausgeben?
837 [ # # ][ # # ]: 0 : sal_Bool bTSections = (bRowsHaveBorder && !bRowsHaveBorderOnly);
838 : 0 : sal_Bool bTBody = bTSections;
839 : :
840 : : // Wenn Sections ausgegeben werden muessen darf ein THEAD um die erste
841 : : // Zeile nur ausgegeben werden, wenn unter der Zeile eine Linie ist
842 [ # # ][ # # ]: 0 : if( bTHead &&
[ # # # # ]
[ # # ][ # # ]
843 : : (bTSections || bColGroups) &&
844 [ # # ]: 0 : nHeadEndRow<aRows.size()-1 && !aRows[nHeadEndRow]->bBottomBorder )
845 : 0 : bTHead = sal_False;
846 : :
847 : : // <TBODY> aus ausgeben, wenn <THEAD> ausgegeben wird.
848 : 0 : bTSections |= bTHead;
849 : :
850 [ # # ]: 0 : if( bTSections )
851 : : {
852 [ # # ]: 0 : rWrt.OutNewLine(); // <THEAD>/<TDATA> in neue Zeile
853 [ # # ]: 0 : HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(),
854 [ # # ][ # # ]: 0 : bTHead ? OOO_STRING_SVTOOLS_HTML_thead : OOO_STRING_SVTOOLS_HTML_tbody, sal_True );
855 : :
856 : 0 : rWrt.IncIndentLevel(); // Inhalt von <THEAD>/<TDATA> einr.
857 : : }
858 : :
859 [ # # ]: 0 : for( nRow = 0; nRow < aRows.size(); nRow++ )
860 : : {
861 [ # # ]: 0 : const SwWriteTableRow *pRow2 = aRows[nRow];
862 : :
863 [ # # ]: 0 : OutTableCells( rWrt, pRow2->GetCells(), pRow2->GetBackground() );
864 [ # # ][ # # ]: 0 : if( !nCellSpacing && nRow < aRows.size()-1 && pRow2->bBottomBorder &&
[ # # ][ # # ]
[ # # ]
865 : : pRow2->nBottomBorder > DEF_LINE_WIDTH_1 )
866 : : {
867 : 0 : sal_uInt16 nCnt = (pRow2->nBottomBorder / DEF_LINE_WIDTH_1) - 1;
868 [ # # ]: 0 : for( ; nCnt; nCnt-- )
869 : : {
870 [ # # ]: 0 : rWrt.OutNewLine();
871 [ # # ]: 0 : HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_tablerow,
872 [ # # ]: 0 : sal_True );
873 [ # # ]: 0 : HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_tablerow,
874 [ # # ]: 0 : sal_False );
875 : : }
876 : : }
877 [ # # ][ # # ]: 0 : if( ( (bTHead && nRow==nHeadEndRow) ||
[ # # ]
[ # # # # ]
[ # # ]
878 : : (bTBody && pRow2->bBottomBorder) ) &&
879 : 0 : nRow < aRows.size()-1 )
880 : : {
881 : 0 : rWrt.DecIndentLevel(); // Inhalt von <THEAD>/<TDATA> einr.
882 [ # # ]: 0 : rWrt.OutNewLine(); // </THEAD>/</TDATA> in neue Zeile
883 [ # # ]: 0 : HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(),
884 [ # # ][ # # ]: 0 : bTHead ? OOO_STRING_SVTOOLS_HTML_thead : OOO_STRING_SVTOOLS_HTML_tbody, sal_False );
885 [ # # ]: 0 : rWrt.OutNewLine(); // <THEAD>/<TDATA> in neue Zeile
886 : :
887 [ # # ][ # # ]: 0 : if( bTHead && nRow==nHeadEndRow )
888 : 0 : bTHead = sal_False;
889 : :
890 [ # # ]: 0 : HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(),
891 [ # # ][ # # ]: 0 : bTHead ? OOO_STRING_SVTOOLS_HTML_thead : OOO_STRING_SVTOOLS_HTML_tbody, sal_True );
892 : 0 : rWrt.IncIndentLevel(); // Inhalt von <THEAD>/<TDATA> einr.
893 : : }
894 : : }
895 : :
896 [ # # ]: 0 : if( bTSections )
897 : : {
898 : 0 : rWrt.DecIndentLevel(); // Inhalt von <THEAD>/<TDATA> einr.
899 : :
900 [ # # ]: 0 : rWrt.OutNewLine(); // </THEAD>/</TDATA> in neue Zeile
901 [ # # ]: 0 : HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(),
902 [ # # ][ # # ]: 0 : bTHead ? OOO_STRING_SVTOOLS_HTML_thead : OOO_STRING_SVTOOLS_HTML_tbody, sal_False );
903 : : }
904 : :
905 : 0 : rWrt.DecIndentLevel(); // Inhalt von <TABLE> einr.
906 : :
907 [ # # ]: 0 : rWrt.OutNewLine(); // </TABLE> in neue Zeile
908 [ # # ][ # # ]: 0 : HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_table, sal_False );
909 : :
910 : 0 : rWrt.nDirection = nOldDirection;
911 : 0 : }
912 : :
913 : 0 : Writer& OutHTML_SwTblNode( Writer& rWrt, SwTableNode & rNode,
914 : : const SwFrmFmt *pFlyFrmFmt,
915 : : const String *pCaption, sal_Bool bTopCaption )
916 : : {
917 : :
918 : 0 : SwTable& rTbl = rNode.GetTable();
919 : :
920 : 0 : SwHTMLWriter & rHTMLWrt = (SwHTMLWriter&)rWrt;
921 : 0 : rHTMLWrt.bOutTable = sal_True;
922 : :
923 : : // die horizontale Ausrichtung des Rahmens hat (falls vorhanden)
924 : : // Prioritaet. NONE bedeutet, dass keine horizontale
925 : : // Ausrichtung geschrieben wird.
926 : 0 : sal_Int16 eFlyHoriOri = text::HoriOrientation::NONE;
927 : 0 : SwSurround eSurround = SURROUND_NONE;
928 : 0 : sal_uInt8 nFlyPrcWidth = 0;
929 : 0 : long nFlyWidth = 0;
930 : 0 : sal_uInt16 nFlyHSpace = 0;
931 : 0 : sal_uInt16 nFlyVSpace = 0;
932 [ # # ]: 0 : if( pFlyFrmFmt )
933 : : {
934 : 0 : eSurround = pFlyFrmFmt->GetSurround().GetSurround();
935 : 0 : const SwFmtFrmSize& rFrmSize = pFlyFrmFmt->GetFrmSize();
936 : 0 : nFlyPrcWidth = rFrmSize.GetWidthPercent();
937 : 0 : nFlyWidth = rFrmSize.GetSize().Width();
938 : :
939 : 0 : eFlyHoriOri = pFlyFrmFmt->GetHoriOrient().GetHoriOrient();
940 [ # # ]: 0 : if( text::HoriOrientation::NONE == eFlyHoriOri )
941 : 0 : eFlyHoriOri = text::HoriOrientation::LEFT;
942 : :
943 : 0 : const SvxLRSpaceItem& rLRSpace = pFlyFrmFmt->GetLRSpace();
944 : 0 : nFlyHSpace = static_cast< sal_uInt16 >((rLRSpace.GetLeft() + rLRSpace.GetRight()) / 2);
945 : :
946 : 0 : const SvxULSpaceItem& rULSpace = pFlyFrmFmt->GetULSpace();
947 : 0 : nFlyVSpace = (rULSpace.GetUpper() + rULSpace.GetLower()) / 2;
948 : : }
949 : :
950 : : // ggf. eine FORM oeffnen
951 : 0 : sal_Bool bPreserveForm = sal_False;
952 [ # # ]: 0 : if( !rHTMLWrt.bPreserveForm )
953 : : {
954 : 0 : rHTMLWrt.OutForm( sal_True, &rNode );
955 [ # # ][ # # ]: 0 : bPreserveForm = (rHTMLWrt.pxFormComps && rHTMLWrt.pxFormComps->is() );
956 : 0 : rHTMLWrt.bPreserveForm = bPreserveForm;
957 : : }
958 : :
959 : 0 : SwFrmFmt *pFmt = rTbl.GetFrmFmt();
960 : :
961 : 0 : const SwFmtFrmSize& rFrmSize = pFmt->GetFrmSize();
962 : 0 : long nWidth = rFrmSize.GetSize().Width();
963 : 0 : sal_uInt8 nPrcWidth = rFrmSize.GetWidthPercent();
964 : 0 : sal_uInt16 nBaseWidth = (sal_uInt16)nWidth;
965 : :
966 : 0 : sal_Int16 eTabHoriOri = pFmt->GetHoriOrient().GetHoriOrient();
967 : :
968 : : // text::HoriOrientation::NONE und text::HoriOrientation::FULL Tabellen benoetigen relative Breiten
969 : 0 : sal_uInt16 nNewDefListLvl = 0;
970 : 0 : sal_Bool bRelWidths = sal_False;
971 : 0 : sal_Bool bCheckDefList = sal_False;
972 [ # # # # ]: 0 : switch( eTabHoriOri )
973 : : {
974 : : case text::HoriOrientation::FULL:
975 : : // Tabellen mit automatischer Ausrichtung werden zu Tabellen
976 : : // mit 100%-Breite
977 : 0 : bRelWidths = sal_True;
978 : 0 : nWidth = 100;
979 : 0 : eTabHoriOri = text::HoriOrientation::LEFT;
980 : 0 : break;
981 : : case text::HoriOrientation::NONE:
982 : : {
983 : 0 : const SvxLRSpaceItem& aLRItem = pFmt->GetLRSpace();
984 [ # # ]: 0 : if( aLRItem.GetRight() )
985 : : {
986 : : // Die Tabellenbreite wird anhand des linken und rechten
987 : : // Abstandes bestimmt. Deshalb versuchen wir die
988 : : // tatsaechliche Breite der Tabelle zu bestimmen. Wenn
989 : : // das nicht geht, machen wir eine 100% breite Tabelle
990 : : // draus.
991 : 0 : nWidth = pFmt->FindLayoutRect(sal_True).Width();
992 [ # # ]: 0 : if( !nWidth )
993 : : {
994 : 0 : bRelWidths = sal_True;
995 : 0 : nWidth = 100;
996 : : }
997 : :
998 : : }
999 [ # # ]: 0 : else if( nPrcWidth )
1000 : : {
1001 : : // Ohne rechten Rand bleibt die %-Breite erhalten
1002 : 0 : nWidth = nPrcWidth;
1003 : 0 : bRelWidths = sal_True;
1004 : : }
1005 : : else
1006 : : {
1007 : : // Ohne rechten Rand bleibt auch eine absolute Breite erhalten
1008 : : // Wir versuchen aber trotzdem ueber das Layout die
1009 : : // tatsachliche Breite zu ermitteln.
1010 : 0 : long nRealWidth = pFmt->FindLayoutRect(sal_True).Width();
1011 [ # # ]: 0 : if( nRealWidth )
1012 : 0 : nWidth = nRealWidth;
1013 : : }
1014 : 0 : bCheckDefList = sal_True;
1015 : : }
1016 : 0 : break;
1017 : : case text::HoriOrientation::LEFT_AND_WIDTH:
1018 : 0 : eTabHoriOri = text::HoriOrientation::LEFT;
1019 : 0 : bCheckDefList = sal_True;
1020 : : // no break
1021 : : default:
1022 : : // In allen anderen Faellen kann eine absolute oder relative
1023 : : // Breite direkt uebernommen werden.
1024 [ # # ]: 0 : if( nPrcWidth )
1025 : : {
1026 : 0 : bRelWidths = sal_True;
1027 : 0 : nWidth = nPrcWidth;
1028 : : }
1029 : 0 : break;
1030 : : }
1031 : :
1032 [ # # ]: 0 : if( bCheckDefList )
1033 : : {
1034 : : OSL_ENSURE( !rHTMLWrt.GetNumInfo().GetNumRule() ||
1035 : : rHTMLWrt.GetNextNumInfo(),
1036 : : "NumInfo fuer naechsten Absatz fehlt!" );
1037 : 0 : const SvxLRSpaceItem& aLRItem = pFmt->GetLRSpace();
1038 [ # # # # : 0 : if( aLRItem.GetLeft() > 0 && rHTMLWrt.nDefListMargin > 0 &&
# # # # #
# ][ # # ]
[ # # ]
1039 : 0 : ( !rHTMLWrt.GetNumInfo().GetNumRule() ||
1040 : 0 : ( rHTMLWrt.GetNextNumInfo() &&
1041 : 0 : (rHTMLWrt.GetNextNumInfo()->IsRestart() ||
1042 : 0 : rHTMLWrt.GetNumInfo().GetNumRule() !=
1043 : 0 : rHTMLWrt.GetNextNumInfo()->GetNumRule()) ) ) )
1044 : : {
1045 : : // Wenn der Absatz vor der Tabelle nicht numeriert ist oder
1046 : : // der Absatz nach der Tabelle mit einer anderen oder
1047 : : // (gar keiner) Regel numeriert ist, koennen wir
1048 : : // die Einrueckung ueber eine DL regeln. Sonst behalten wir
1049 : : // die Einrueckung der Numerierung bei.
1050 : : nNewDefListLvl = static_cast< sal_uInt16 >(
1051 : 0 : (aLRItem.GetLeft() + (rHTMLWrt.nDefListMargin/2)) /
1052 : 0 : rHTMLWrt.nDefListMargin );
1053 : : }
1054 : : }
1055 : :
1056 [ # # ][ # # ]: 0 : if( !pFlyFrmFmt && nNewDefListLvl != rHTMLWrt.nDefListLvl )
1057 : 0 : rHTMLWrt.OutAndSetDefList( nNewDefListLvl );
1058 : :
1059 [ # # ]: 0 : if( nNewDefListLvl )
1060 : : {
1061 [ # # ]: 0 : if( rHTMLWrt.bLFPossible )
1062 : 0 : rHTMLWrt.OutNewLine();
1063 : 0 : HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_dd );
1064 : : }
1065 : :
1066 : : // eFlyHoriOri und eTabHoriOri besitzen nun nur noch die Werte
1067 : : // LEFT/CENTER und RIGHT!
1068 [ # # ]: 0 : if( eFlyHoriOri!=text::HoriOrientation::NONE )
1069 : : {
1070 : 0 : eTabHoriOri = eFlyHoriOri;
1071 : : // MIB 4.7.97: Wenn die Tabelle eine relative Breite besitzt,
1072 : : // dann richtet sich ihre Breite nach der des Rahmens, also
1073 : : // exportieren wir dessen Breite. Bei fixer Breite ist die Breite
1074 : : // der Tabelle massgeblich. Wer Tabellen mit relativer Breite <100%
1075 : : // in Rahmen steckt, ist selber schuld wenn nix Gutes bei rauskommt.
1076 [ # # ]: 0 : if( bRelWidths )
1077 : : {
1078 [ # # ]: 0 : nWidth = nFlyPrcWidth ? nFlyPrcWidth : nFlyWidth;
1079 : 0 : bRelWidths = nFlyPrcWidth > 0;
1080 : : }
1081 : : }
1082 : :
1083 : 0 : sal_Int16 eDivHoriOri = text::HoriOrientation::NONE;
1084 [ # # # # ]: 0 : switch( eTabHoriOri )
1085 : : {
1086 : : case text::HoriOrientation::LEFT:
1087 : : // Wenn eine linksbuendigeTabelle keinen rechtsseiigen Durchlauf
1088 : : // hat, brauchen wir auch kein ALIGN=LEFT in der Tabelle.
1089 [ # # ][ # # ]: 0 : if( eSurround==SURROUND_NONE || eSurround==SURROUND_LEFT )
1090 : 0 : eTabHoriOri = text::HoriOrientation::NONE;
1091 : 0 : break;
1092 : : case text::HoriOrientation::RIGHT:
1093 : : // Aehnliches gilt fuer rechtsbuendigeTabelle, hier nehmen wir
1094 : : // stattdessen ein <DIV ALIGN=RIGHT>.
1095 [ # # ][ # # ]: 0 : if( eSurround==SURROUND_NONE || eSurround==SURROUND_RIGHT )
1096 : : {
1097 : 0 : eDivHoriOri = text::HoriOrientation::RIGHT;
1098 : 0 : eTabHoriOri = text::HoriOrientation::NONE;
1099 : : }
1100 : 0 : break;
1101 : : case text::HoriOrientation::CENTER:
1102 : : // ALIGN=CENTER versteht so gut wie keiner, deshalb verzichten wir
1103 : : // daruf und nehmen ein <CENTER>.
1104 : 0 : eDivHoriOri = text::HoriOrientation::CENTER;
1105 : 0 : eTabHoriOri = text::HoriOrientation::NONE;
1106 : 0 : break;
1107 : : default:
1108 : : ;
1109 : : }
1110 [ # # ]: 0 : if( text::HoriOrientation::NONE==eTabHoriOri )
1111 : 0 : nFlyHSpace = nFlyVSpace = 0;
1112 : :
1113 [ # # ]: 0 : if( pFmt->GetName().Len() )
1114 : 0 : rHTMLWrt.OutImplicitMark( pFmt->GetName(), pMarkToTable );
1115 : :
1116 [ # # ]: 0 : if( text::HoriOrientation::NONE!=eDivHoriOri )
1117 : : {
1118 [ # # ]: 0 : if( rHTMLWrt.bLFPossible )
1119 : 0 : rHTMLWrt.OutNewLine(); // <CENTER> in neuer Zeile
1120 [ # # ]: 0 : if( text::HoriOrientation::CENTER==eDivHoriOri )
1121 : 0 : HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), OOO_STRING_SVTOOLS_HTML_center, sal_True );
1122 : : else
1123 : : {
1124 [ # # ]: 0 : rtl::OStringBuffer sOut(RTL_CONSTASCII_STRINGPARAM(OOO_STRING_SVTOOLS_HTML_division));
1125 [ # # ][ # # ]: 0 : sOut.append(' ').append(OOO_STRING_SVTOOLS_HTML_O_align).append('=')
[ # # ]
1126 [ # # ]: 0 : .append(OOO_STRING_SVTOOLS_HTML_AL_right);
1127 [ # # ]: 0 : HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(), sOut.getStr(),
1128 [ # # ]: 0 : sal_True );
1129 : : }
1130 : 0 : rHTMLWrt.IncIndentLevel(); // Inhalt von <CENTER> einruecken
1131 : 0 : rHTMLWrt.bLFPossible = sal_True;
1132 : : }
1133 : :
1134 : : // Wenn die Tabelle in keinem Rahmen ist kann man immer ein LF ausgeben.
1135 [ # # ]: 0 : if( text::HoriOrientation::NONE==eTabHoriOri )
1136 : 0 : rHTMLWrt.bLFPossible = sal_True;
1137 : :
1138 : 0 : const SwHTMLTableLayout *pLayout = rTbl.GetHTMLTableLayout();
1139 : :
1140 : : #ifdef DBG_UTIL
1141 : : {
1142 : : ViewShell *pSh;
1143 : : rWrt.pDoc->GetEditShell( &pSh );
1144 : : if ( pSh && pSh->GetViewOptions()->IsTest1() )
1145 : : pLayout = 0;
1146 : : }
1147 : : #endif
1148 : :
1149 [ # # ][ # # ]: 0 : if( pLayout && pLayout->IsExportable() )
[ # # ]
1150 : : {
1151 [ # # ]: 0 : SwHTMLWrtTable aTableWrt( pLayout );
1152 [ # # ]: 0 : aTableWrt.Write( rHTMLWrt, eTabHoriOri, rTbl.GetRowsToRepeat() > 0,
1153 : : pFmt, pCaption, bTopCaption,
1154 [ # # ][ # # ]: 0 : nFlyHSpace, nFlyVSpace );
1155 : : }
1156 : : else
1157 : : {
1158 : 0 : SwHTMLWrtTable aTableWrt( rTbl.GetTabLines(), nWidth,
1159 [ # # # # ]: 0 : nBaseWidth, bRelWidths, rTbl.GetRowsToRepeat() );
1160 [ # # ]: 0 : aTableWrt.Write( rHTMLWrt, eTabHoriOri, rTbl.GetRowsToRepeat() > 0,
1161 : : pFmt, pCaption, bTopCaption,
1162 [ # # ][ # # ]: 0 : nFlyHSpace, nFlyVSpace );
1163 : : }
1164 : :
1165 : : // Wenn die Tabelle in keinem Rahmen war kann man immer ein LF ausgeben.
1166 [ # # ]: 0 : if( text::HoriOrientation::NONE==eTabHoriOri )
1167 : 0 : rHTMLWrt.bLFPossible = sal_True;
1168 : :
1169 [ # # ]: 0 : if( text::HoriOrientation::NONE!=eDivHoriOri )
1170 : : {
1171 : 0 : rHTMLWrt.DecIndentLevel(); // Inhalt von <CENTER> einruecken
1172 : 0 : rHTMLWrt.OutNewLine(); // </CENTER> in neue Teile
1173 : 0 : HTMLOutFuncs::Out_AsciiTag( rWrt.Strm(),
1174 : : text::HoriOrientation::CENTER==eDivHoriOri ? OOO_STRING_SVTOOLS_HTML_center
1175 [ # # ]: 0 : : OOO_STRING_SVTOOLS_HTML_division, sal_False );
1176 : 0 : rHTMLWrt.bLFPossible = sal_True;
1177 : : }
1178 : :
1179 : : // Pam hinter die Tabelle verschieben
1180 : 0 : rHTMLWrt.pCurPam->GetPoint()->nNode = *rNode.EndOfSectionNode();
1181 : :
1182 [ # # ]: 0 : if( bPreserveForm )
1183 : : {
1184 : 0 : rHTMLWrt.bPreserveForm = sal_False;
1185 : 0 : rHTMLWrt.OutForm( sal_False );
1186 : : }
1187 : :
1188 : 0 : rHTMLWrt.bOutTable = sal_False;
1189 : :
1190 [ # # # # : 0 : if( rHTMLWrt.GetNextNumInfo() &&
# # ][ # # ]
1191 : 0 : !rHTMLWrt.GetNextNumInfo()->IsRestart() &&
1192 : 0 : rHTMLWrt.GetNextNumInfo()->GetNumRule() ==
1193 : 0 : rHTMLWrt.GetNumInfo().GetNumRule() )
1194 : : {
1195 : : // Wenn der Absatz hinter der Tabelle mit der gleichen Regel
1196 : : // numeriert ist wie der Absatz vor der Tabelle, dann steht in
1197 : : // der NumInfo des naechsten Absatzes noch die Ebene des Absatzes
1198 : : // vor der Tabelle. Es muss deshalb die NumInfo noch einmal geholt
1199 : : // werden um ggf. die Num-Liste noch zu beenden.
1200 : 0 : rHTMLWrt.ClearNextNumInfo();
1201 : 0 : rHTMLWrt.FillNextNumInfo();
1202 : 0 : OutHTML_NumBulListEnd( rHTMLWrt, *rHTMLWrt.GetNextNumInfo() );
1203 : : }
1204 : 0 : return rWrt;
1205 : : }
1206 : :
1207 : :
1208 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|