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