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