Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include "hintids.hxx"
31 : : #include <vcl/svapp.hxx>
32 : : #include <vcl/wrkwin.hxx>
33 : : #include <editeng/boxitem.hxx>
34 : : #include <editeng/brshitem.hxx>
35 : : #include <editeng/adjitem.hxx>
36 : : #include <editeng/fhgtitem.hxx>
37 : : #include <editeng/ulspitem.hxx>
38 : : #include <editeng/lrspitem.hxx>
39 : : #include <editeng/brkitem.hxx>
40 : : #include <editeng/spltitem.hxx>
41 : : #include <svtools/htmltokn.h>
42 : : #include <svtools/htmlkywd.hxx>
43 : : #include <svl/urihelper.hxx>
44 : :
45 : :
46 : : #include <fmtornt.hxx>
47 : : #include <frmfmt.hxx>
48 : : #include <fmtfsize.hxx>
49 : : #include <fmtsrnd.hxx>
50 : : #include <fmtpdsc.hxx>
51 : : #include <fmtcntnt.hxx>
52 : : #include <fmtanchr.hxx>
53 : : #include <fmtlsplt.hxx>
54 : : #include "frmatr.hxx"
55 : : #include "pam.hxx"
56 : : #include "doc.hxx"
57 : : #include "ndtxt.hxx"
58 : : #include "shellio.hxx"
59 : : #include "poolfmt.hxx"
60 : : #include "swtable.hxx"
61 : : #include "cellatr.hxx"
62 : : #include "htmltbl.hxx"
63 : : #include "swtblfmt.hxx"
64 : : #include "htmlnum.hxx"
65 : : #include "swhtml.hxx"
66 : : #include "swcss1.hxx"
67 : : #include <numrule.hxx>
68 : :
69 : : #define NETSCAPE_DFLT_BORDER 1
70 : : #define NETSCAPE_DFLT_CELLSPACING 2
71 : :
72 : : using ::editeng::SvxBorderLine;
73 : : using namespace ::com::sun::star;
74 : :
75 : :
76 : : static HTMLOptionEnum aHTMLTblVAlignTable[] =
77 : : {
78 : : { OOO_STRING_SVTOOLS_HTML_VA_top, text::VertOrientation::NONE },
79 : : { OOO_STRING_SVTOOLS_HTML_VA_middle, text::VertOrientation::CENTER },
80 : : { OOO_STRING_SVTOOLS_HTML_VA_bottom, text::VertOrientation::BOTTOM },
81 : : { 0, 0 }
82 : : };
83 : :
84 : : // table tags options
85 : :
86 [ # # ][ # # ]: 0 : struct HTMLTableOptions
[ # # ][ # # ]
87 : : {
88 : : sal_uInt16 nCols;
89 : : sal_uInt16 nWidth;
90 : : sal_uInt16 nHeight;
91 : : sal_uInt16 nCellPadding;
92 : : sal_uInt16 nCellSpacing;
93 : : sal_uInt16 nBorder;
94 : : sal_uInt16 nHSpace;
95 : : sal_uInt16 nVSpace;
96 : :
97 : : SvxAdjust eAdjust;
98 : : sal_Int16 eVertOri;
99 : : HTMLTableFrame eFrame;
100 : : HTMLTableRules eRules;
101 : :
102 : : sal_Bool bPrcWidth : 1;
103 : : sal_Bool bTableAdjust : 1;
104 : : sal_Bool bBGColor : 1;
105 : :
106 : : Color aBorderColor;
107 : : Color aBGColor;
108 : :
109 : : String aBGImage, aStyle, aId, aClass, aDir;
110 : :
111 : : HTMLTableOptions( const HTMLOptions& rOptions, SvxAdjust eParentAdjust );
112 : : };
113 : :
114 : : class _HTMLTableContext
115 : : {
116 : : SwHTMLNumRuleInfo aNumRuleInfo; // Numbering valid before the table
117 : :
118 : : SwTableNode *pTblNd; // table node
119 : : SwFrmFmt *pFrmFmt; // der Fly frame::Frame, containing the table
120 : : SwPosition *pPos; // position behind the table
121 : :
122 : : sal_uInt16 nContextStAttrMin;
123 : : sal_uInt16 nContextStMin;
124 : :
125 : : sal_Bool bRestartPRE : 1;
126 : : sal_Bool bRestartXMP : 1;
127 : : sal_Bool bRestartListing : 1;
128 : :
129 : : public:
130 : :
131 : : _HTMLAttrTable aAttrTab; // attributes
132 : :
133 : 0 : _HTMLTableContext( SwPosition *pPs, sal_uInt16 nCntxtStMin,
134 : : sal_uInt16 nCntxtStAttrMin ) :
135 : : pTblNd( 0 ),
136 : : pFrmFmt( 0 ),
137 : : pPos( pPs ),
138 : : nContextStAttrMin( nCntxtStAttrMin ),
139 : : nContextStMin( nCntxtStMin ),
140 : : bRestartPRE( sal_False ),
141 : : bRestartXMP( sal_False ),
142 : 0 : bRestartListing( sal_False )
143 : : {
144 : 0 : memset( &aAttrTab, 0, sizeof( _HTMLAttrTable ));
145 : 0 : }
146 : :
147 : : ~_HTMLTableContext();
148 : :
149 : 0 : void SetNumInfo( const SwHTMLNumRuleInfo& rInf ) { aNumRuleInfo.Set(rInf); }
150 : 0 : const SwHTMLNumRuleInfo& GetNumInfo() const { return aNumRuleInfo; };
151 : :
152 : : void SavePREListingXMP( SwHTMLParser& rParser );
153 : : void RestorePREListingXMP( SwHTMLParser& rParser );
154 : :
155 : 0 : SwPosition *GetPos() const { return pPos; }
156 : :
157 : 0 : void SetTableNode( SwTableNode *pNd ) { pTblNd = pNd; }
158 : 0 : SwTableNode *GetTableNode() const { return pTblNd; }
159 : :
160 : 0 : void SetFrmFmt( SwFrmFmt *pFmt ) { pFrmFmt = pFmt; }
161 : 0 : SwFrmFmt *GetFrmFmt() const { return pFrmFmt; }
162 : :
163 : 0 : sal_uInt16 GetContextStMin() const { return nContextStMin; }
164 : 0 : sal_uInt16 GetContextStAttrMin() const { return nContextStAttrMin; }
165 : : };
166 : :
167 : :
168 : : // Cell content is a linked list with SwStartNodes and
169 : : // HTMLTables.
170 : :
171 : : class HTMLTableCnts
172 : : {
173 : : HTMLTableCnts *pNext; // next content
174 : :
175 : : // Only one of the next two pointers must be set!
176 : : const SwStartNode *pStartNode; // a paragraph
177 : : HTMLTable *pTable; // a table
178 : :
179 : : SwHTMLTableLayoutCnts* pLayoutInfo;
180 : :
181 : : sal_Bool bNoBreak;
182 : :
183 : : void InitCtor();
184 : :
185 : : public:
186 : :
187 : : HTMLTableCnts( const SwStartNode* pStNd );
188 : : HTMLTableCnts( HTMLTable* pTab );
189 : :
190 : : ~HTMLTableCnts(); // only allowed in ~HTMLTableCell
191 : :
192 : : // Determine SwStartNode and HTMLTable respectively
193 : 0 : const SwStartNode *GetStartNode() const { return pStartNode; }
194 : 0 : const HTMLTable *GetTable() const { return pTable; }
195 : 0 : HTMLTable *GetTable() { return pTable; }
196 : :
197 : : // Add a new node at the end of the list
198 : : void Add( HTMLTableCnts* pNewCnts );
199 : :
200 : : // Determine next node
201 : 0 : const HTMLTableCnts *Next() const { return pNext; }
202 : 0 : HTMLTableCnts *Next() { return pNext; }
203 : :
204 : : inline void SetTableBox( SwTableBox *pBox );
205 : :
206 : 0 : void SetNoBreak() { bNoBreak = sal_True; }
207 : :
208 : : SwHTMLTableLayoutCnts *CreateLayoutInfo();
209 : : };
210 : :
211 : :
212 : : // Cell of a HTML table
213 : : class HTMLTableCell
214 : : {
215 : : // !!!ATTENTION!!!!! For each new pointer the SetProtected
216 : : // method (and the dtor) has to be executed.
217 : : HTMLTableCnts *pContents; // cell content
218 : : SvxBrushItem *pBGBrush; // cell background
219 : : // !!!ATTENTION!!!!!
220 : : ::boost::shared_ptr<SvxBoxItem> m_pBoxItem;
221 : :
222 : : sal_uInt32 nNumFmt;
223 : : sal_uInt16 nRowSpan; // cell ROWSPAN
224 : : sal_uInt16 nColSpan; // cell COLSPAN
225 : : sal_uInt16 nWidth; // cell WIDTH
226 : : double nValue;
227 : : sal_Int16 eVertOri; // vertical alignment of the cell
228 : : sal_Bool bProtected : 1; // cell must not filled
229 : : sal_Bool bRelWidth : 1; // nWidth is given in %
230 : : sal_Bool bHasNumFmt : 1;
231 : : sal_Bool bHasValue : 1;
232 : : sal_Bool bNoWrap : 1;
233 : : sal_Bool mbCovered : 1;
234 : :
235 : : public:
236 : :
237 : : HTMLTableCell(); // new cells always empty
238 : :
239 : : ~HTMLTableCell(); // only allowed in ~HTMLTableRow
240 : :
241 : : // Fill a not empty cell
242 : : void Set( HTMLTableCnts *pCnts, sal_uInt16 nRSpan, sal_uInt16 nCSpan,
243 : : sal_Int16 eVertOri, SvxBrushItem *pBGBrush,
244 : : ::boost::shared_ptr<SvxBoxItem> const pBoxItem,
245 : : sal_Bool bHasNumFmt, sal_uInt32 nNumFmt,
246 : : sal_Bool bHasValue, double nValue, sal_Bool bNoWrap, sal_Bool bCovered );
247 : :
248 : : // Protect an empty 1x1 cell
249 : : void SetProtected();
250 : :
251 : : // Set/Get cell content
252 : 0 : void SetContents( HTMLTableCnts *pCnts ) { pContents = pCnts; }
253 : : const HTMLTableCnts *GetContents() const { return pContents; }
254 : 0 : HTMLTableCnts *GetContents() { return pContents; }
255 : :
256 : : // Set/Get cell ROWSPAN/COLSPAN
257 : 0 : void SetRowSpan( sal_uInt16 nRSpan ) { nRowSpan = nRSpan; }
258 : 0 : sal_uInt16 GetRowSpan() const { return nRowSpan; }
259 : :
260 : 0 : void SetColSpan( sal_uInt16 nCSpan ) { nColSpan = nCSpan; }
261 : 0 : sal_uInt16 GetColSpan() const { return nColSpan; }
262 : :
263 : : inline void SetWidth( sal_uInt16 nWidth, sal_Bool bRelWidth );
264 : :
265 : 0 : const SvxBrushItem *GetBGBrush() const { return pBGBrush; }
266 : 0 : ::boost::shared_ptr<SvxBoxItem> GetBoxItem() const { return m_pBoxItem; }
267 : :
268 : : inline sal_Bool GetNumFmt( sal_uInt32& rNumFmt ) const;
269 : : inline sal_Bool GetValue( double& rValue ) const;
270 : :
271 : 0 : sal_Int16 GetVertOri() const { return eVertOri; }
272 : :
273 : : // Is the cell filled or protected ?
274 [ # # ][ # # ]: 0 : sal_Bool IsUsed() const { return pContents!=0 || bProtected; }
275 : :
276 : : SwHTMLTableLayoutCell *CreateLayoutInfo();
277 : :
278 : 0 : sal_Bool IsCovered() const { return mbCovered; }
279 : : };
280 : :
281 : :
282 : : // Row of a HTML table
283 : : typedef boost::ptr_vector<HTMLTableCell> HTMLTableCells;
284 : :
285 : : class HTMLTableRow
286 : : {
287 : : HTMLTableCells *pCells; // cells of the row
288 : :
289 : : sal_Bool bIsEndOfGroup : 1;
290 : : sal_Bool bSplitable : 1;
291 : :
292 : : sal_uInt16 nHeight; // options of <TR>/<TD>
293 : : sal_uInt16 nEmptyRows; // number of empty rows are following
294 : :
295 : : SvxAdjust eAdjust;
296 : : sal_Int16 eVertOri;
297 : : SvxBrushItem *pBGBrush; // background of cell from STYLE
298 : :
299 : : public:
300 : :
301 : : sal_Bool bBottomBorder; // Is there a line after the row?
302 : :
303 : : HTMLTableRow( sal_uInt16 nCells=0 ); // cells of the row are empty
304 : :
305 : : ~HTMLTableRow();
306 : :
307 : : inline void SetHeight( sal_uInt16 nHeight );
308 : 0 : sal_uInt16 GetHeight() const { return nHeight; }
309 : :
310 : : inline HTMLTableCell *GetCell( sal_uInt16 nCell ) const;
311 : : inline const HTMLTableCells *GetCells() const { return pCells; }
312 : :
313 : 0 : inline void SetAdjust( SvxAdjust eAdj ) { eAdjust = eAdj; }
314 : 0 : inline SvxAdjust GetAdjust() const { return eAdjust; }
315 : :
316 : 0 : inline void SetVertOri( sal_Int16 eV) { eVertOri = eV; }
317 : 0 : inline sal_Int16 GetVertOri() const { return eVertOri; }
318 : :
319 : 0 : void SetBGBrush( SvxBrushItem *pBrush ) { pBGBrush = pBrush; }
320 : 0 : const SvxBrushItem *GetBGBrush() const { return pBGBrush; }
321 : :
322 : 0 : inline void SetEndOfGroup() { bIsEndOfGroup = sal_True; }
323 : 0 : inline sal_Bool IsEndOfGroup() const { return bIsEndOfGroup; }
324 : :
325 : 0 : void IncEmptyRows() { nEmptyRows++; }
326 : 0 : sal_uInt16 GetEmptyRows() const { return nEmptyRows; }
327 : :
328 : : // Expand row by adding empty cells
329 : : void Expand( sal_uInt16 nCells, sal_Bool bOneCell=sal_False );
330 : :
331 : : // Shrink row by deleting empty cells
332 : : void Shrink( sal_uInt16 nCells );
333 : :
334 : : void SetSplitable( sal_Bool bSet ) { bSplitable = bSet; }
335 : : sal_Bool IsSplitable() const { return bSplitable; }
336 : : };
337 : :
338 : :
339 : : // Column of a HTML table
340 : : class HTMLTableColumn
341 : : {
342 : : sal_Bool bIsEndOfGroup;
343 : :
344 : : sal_uInt16 nWidth; // options of <COL>
345 : : sal_Bool bRelWidth;
346 : :
347 : : SvxAdjust eAdjust;
348 : : sal_Int16 eVertOri;
349 : :
350 : : SwFrmFmt *aFrmFmts[6];
351 : :
352 : : inline sal_uInt16 GetFrmFmtIdx( sal_Bool bBorderLine,
353 : : sal_Int16 eVertOri ) const;
354 : :
355 : : public:
356 : :
357 : : sal_Bool bLeftBorder; // is there a line before the column
358 : :
359 : : HTMLTableColumn();
360 : :
361 : : inline void SetWidth( sal_uInt16 nWidth, sal_Bool bRelWidth);
362 : :
363 : 0 : inline void SetAdjust( SvxAdjust eAdj ) { eAdjust = eAdj; }
364 : 0 : inline SvxAdjust GetAdjust() const { return eAdjust; }
365 : :
366 : 0 : inline void SetVertOri( sal_Int16 eV) { eVertOri = eV; }
367 : 0 : inline sal_Int16 GetVertOri() const { return eVertOri; }
368 : :
369 : 0 : inline void SetEndOfGroup() { bIsEndOfGroup = sal_True; }
370 : 0 : inline sal_Bool IsEndOfGroup() const { return bIsEndOfGroup; }
371 : :
372 : : inline void SetFrmFmt( SwFrmFmt *pFmt, sal_Bool bBorderLine,
373 : : sal_Int16 eVertOri );
374 : : inline SwFrmFmt *GetFrmFmt( sal_Bool bBorderLine,
375 : : sal_Int16 eVertOri ) const;
376 : :
377 : : SwHTMLTableLayoutColumn *CreateLayoutInfo();
378 : : };
379 : :
380 : :
381 : : // HTML table
382 : : typedef boost::ptr_vector<HTMLTableRow> HTMLTableRows;
383 : :
384 : : typedef boost::ptr_vector<HTMLTableColumn> HTMLTableColumns;
385 : :
386 : : typedef std::vector<SdrObject *> SdrObjects;
387 : :
388 : : class HTMLTable
389 : : {
390 : : String aId;
391 : : String aStyle;
392 : : String aClass;
393 : : String aDir;
394 : :
395 : : SdrObjects *pResizeDrawObjs;// SDR objects
396 : : std::vector<sal_uInt16> *pDrawObjPrcWidths; // column of draw object and its rel. width
397 : :
398 : : HTMLTableRows *pRows; // table rows
399 : : HTMLTableColumns *pColumns; // table columns
400 : :
401 : : sal_uInt16 nRows; // number of rows
402 : : sal_uInt16 nCols; // number of columns
403 : : sal_uInt16 nFilledCols; // number of filled columns
404 : :
405 : : sal_uInt16 nCurRow; // aktuelle Zeile
406 : : sal_uInt16 nCurCol; // aktuelle Spalte
407 : :
408 : : sal_uInt16 nLeftMargin; // Abstand zum linken Rand (aus Absatz)
409 : : sal_uInt16 nRightMargin; // Abstand zum rechten Rand (aus Absatz)
410 : :
411 : : sal_uInt16 nCellPadding; // Abstand Umrandung zum Text
412 : : sal_uInt16 nCellSpacing; // Abstand zwischen zwei Zellen
413 : : sal_uInt16 nHSpace;
414 : : sal_uInt16 nVSpace;
415 : :
416 : : sal_uInt16 nBoxes; // Wievele Boxen enthaelt die Tabelle
417 : :
418 : : const SwStartNode *pPrevStNd; // der Table-Node oder der Start-Node
419 : : // der vorhergehenden Section
420 : : const SwTable *pSwTable; // die SW-Tabelle (nur auf dem Top-Level)
421 : : SwTableBox *pBox1; // die TableBox, die beim Erstellen
422 : : // der Top-Level-Tabelle angelegt wird
423 : :
424 : : SwTableBoxFmt *pBoxFmt; // das frame::Frame-Format einer SwTableBox
425 : : SwTableLineFmt *pLineFmt; // das frame::Frame-Format einer SwTableLine
426 : : SwTableLineFmt *pLineFrmFmtNoHeight;
427 : : SvxBrushItem *pBGBrush; // Hintergrund der Tabelle
428 : : SvxBrushItem *pInhBGBrush; // "geerbter" Hintergrund der Tabelle
429 : : const SwStartNode *pCaptionStartNode; // Start-Node der Tabellen-Ueberschrift
430 : :
431 : : SvxBorderLine aTopBorderLine; // die Linie fuer die Umrandung
432 : : SvxBorderLine aBottomBorderLine;// die Linie fuer die Umrandung
433 : : SvxBorderLine aLeftBorderLine; // die Linie fuer die Umrandung
434 : : SvxBorderLine aRightBorderLine; // die Linie fuer die Umrandung
435 : : SvxBorderLine aBorderLine; // die Linie fuer die Umrandung
436 : : SvxBorderLine aInhLeftBorderLine; // die Linie fuer die Umrandung
437 : : SvxBorderLine aInhRightBorderLine; // die Linie fuer die Umrandung
438 : : sal_Bool bTopBorder; // besitzt die Tabelle oben eine Linie
439 : : sal_Bool bRightBorder; // besitzt die Tabelle rechts eine Linie
440 : : sal_Bool bTopAlwd; // duerfen die Raender gesetzt werden?
441 : : sal_Bool bRightAlwd;
442 : : sal_Bool bFillerTopBorder; // bekommt eine linke/rechter Filler-
443 : : sal_Bool bFillerBottomBorder; // Zelle eine obere/untere Umrandung?
444 : : sal_Bool bInhLeftBorder;
445 : : sal_Bool bInhRightBorder;
446 : : sal_Bool bBordersSet; // die Umrandung wurde bereits gesetzt
447 : : sal_Bool bForceFrame;
448 : : sal_Bool bTableAdjustOfTag; // stammt nTableAdjust aus <TABLE>?
449 : : sal_uInt32 nHeadlineRepeat; // repeating rows
450 : : sal_Bool bIsParentHead;
451 : : sal_Bool bHasParentSection;
452 : : sal_Bool bMakeTopSubTable;
453 : : sal_Bool bHasToFly;
454 : : sal_Bool bFixedCols;
455 : : sal_Bool bColSpec; // Gab es COL(GROUP)-Elemente?
456 : : sal_Bool bPrcWidth; // Breite ist eine %-Angabe
457 : :
458 : : SwHTMLParser *pParser; // der aktuelle Parser
459 : : HTMLTable *pTopTable; // die Tabelle auf dem Top-Level
460 : : HTMLTableCnts *pParentContents;
461 : :
462 : : _HTMLTableContext *pContext; // der Kontext der Tabelle
463 : :
464 : : SwHTMLTableLayout *pLayoutInfo;
465 : :
466 : :
467 : : // die folgenden Parameter stammen aus der dem <TABLE>-Tag
468 : : sal_uInt16 nWidth; // die Breite der Tabelle
469 : : sal_uInt16 nHeight; // absolute Hoehe der Tabelle
470 : : SvxAdjust eTableAdjust; // drawing::Alignment der Tabelle
471 : : sal_Int16 eVertOri; // Default vertikale Ausr. der Zellen
472 : : sal_uInt16 nBorder; // Breite der auesseren Umrandung
473 : : HTMLTableFrame eFrame; // Rahmen um die Tabelle
474 : : HTMLTableRules eRules; // Ramhen in der Tabelle
475 : : sal_Bool bTopCaption; // Ueberschrift ueber der Tabelle
476 : :
477 : : void InitCtor( const HTMLTableOptions *pOptions );
478 : :
479 : : // Korigieren des Row-Spans fuer alle Zellen oberhalb der
480 : : // angegeben Zelle und der Zelle selbst, fuer die den anegebenen
481 : : // Inhalt besitzen. Die angegeben Zelle bekommt den Row-Span 1
482 : : void FixRowSpan( sal_uInt16 nRow, sal_uInt16 nCol, const HTMLTableCnts *pCnts );
483 : :
484 : : // Schuetzen der angegeben Zelle und den darunterliegenden
485 : : void ProtectRowSpan( sal_uInt16 nRow, sal_uInt16 nCol, sal_uInt16 nRowSpan );
486 : :
487 : : // Suchen des SwStartNodes der logisch vorhergehenden Box
488 : : // bei nRow==nCell==USHRT_MAX wird der allerletzte Start-Node
489 : : // der Tabelle zurueckgegeben
490 : : const SwStartNode* GetPrevBoxStartNode( sal_uInt16 nRow, sal_uInt16 nCell ) const;
491 : :
492 : : sal_uInt16 GetTopCellSpace( sal_uInt16 nRow, sal_uInt16 nRowSpan,
493 : : sal_Bool bSwBorders=sal_True ) const;
494 : : sal_uInt16 GetBottomCellSpace( sal_uInt16 nRow, sal_uInt16 nRowSpan,
495 : : sal_Bool bSwBorders=sal_True ) const;
496 : :
497 : : // Anpassen des frame::Frame-Formates einer Box
498 : : void FixFrameFmt( SwTableBox *pBox, sal_uInt16 nRow, sal_uInt16 nCol,
499 : : sal_uInt16 nRowSpan, sal_uInt16 nColSpan,
500 : : sal_Bool bFirstPara=sal_True, sal_Bool bLastPara=sal_True ) const;
501 : : void FixFillerFrameFmt( SwTableBox *pBox, sal_Bool bRight ) const;
502 : :
503 : : // den Inhalt (Lines/Boxen) eine Tabelle erstellen
504 : : void _MakeTable( SwTableBox *pUpper=0 );
505 : :
506 : : // Anlegen einer neuen SwTableBox, die einen SwStartNode enthaelt
507 : : SwTableBox *NewTableBox( const SwStartNode *pStNd,
508 : : SwTableLine *pUpper ) const;
509 : :
510 : : // Erstellen einer SwTableLine aus den Zellen des Rechtecks
511 : : // (nTopRow/nLeftCol) inklusive bis (nBottomRow/nRightRow) exklusive
512 : : SwTableLine *MakeTableLine( SwTableBox *pUpper,
513 : : sal_uInt16 nTopRow, sal_uInt16 nLeftCol,
514 : : sal_uInt16 nBottomRow, sal_uInt16 nRightCol );
515 : :
516 : : // Erstellen einer SwTableBox aus dem Inhalt einer Zelle
517 : : SwTableBox *MakeTableBox( SwTableLine *pUpper,
518 : : HTMLTableCnts *pCnts,
519 : : sal_uInt16 nTopRow, sal_uInt16 nLeftCol,
520 : : sal_uInt16 nBootomRow, sal_uInt16 nRightCol );
521 : :
522 : : // der Autolayout-Algorithmus
523 : :
524 : : // Setzen der Umrandung anhand der Vorgaben der Parent-Tabelle
525 : : void InheritBorders( const HTMLTable *pParent,
526 : : sal_uInt16 nRow, sal_uInt16 nCol,
527 : : sal_uInt16 nRowSpan, sal_uInt16 nColSpan,
528 : : sal_Bool bFirstPara, sal_Bool bLastPara );
529 : :
530 : : // Linke und rechte Umrandung der umgebenen Tabelle erben
531 : : void InheritVertBorders( const HTMLTable *pParent,
532 : : sal_uInt16 nCol, sal_uInt16 nColSpan );
533 : :
534 : :
535 : : // Setzen der Umrandung anhand der Benutzervorgaben
536 : : void SetBorders();
537 : :
538 : : // wurde die Umrandung der Tabelle schon gesetzt
539 : 0 : sal_Bool BordersSet() const { return bBordersSet; }
540 : :
541 : 0 : const SvxBrushItem *GetBGBrush() const { return pBGBrush; }
542 : 0 : const SvxBrushItem *GetInhBGBrush() const { return pInhBGBrush; }
543 : :
544 : : sal_uInt16 GetBorderWidth( const SvxBorderLine& rBLine,
545 : : sal_Bool bWithDistance=sal_False ) const;
546 : :
547 : : public:
548 : :
549 : : sal_Bool bFirstCell; // wurde schon eine Zelle angelegt?
550 : :
551 : : HTMLTable( SwHTMLParser* pPars, HTMLTable *pTopTab,
552 : : sal_Bool bParHead, sal_Bool bHasParentSec,
553 : : sal_Bool bTopTbl, sal_Bool bHasToFly,
554 : : const HTMLTableOptions *pOptions );
555 : :
556 : : ~HTMLTable();
557 : :
558 : : // Ermitteln einer Zelle
559 : : inline HTMLTableCell *GetCell( sal_uInt16 nRow, sal_uInt16 nCell ) const;
560 : :
561 : : // Ueberschrift setzen/ermitteln
562 : : inline void SetCaption( const SwStartNode *pStNd, sal_Bool bTop );
563 : 0 : const SwStartNode *GetCaptionStartNode() const { return pCaptionStartNode; }
564 : 0 : sal_Bool IsTopCaption() const { return bTopCaption; }
565 : :
566 : 0 : SvxAdjust GetTableAdjust( sal_Bool bAny ) const
567 : : {
568 [ # # ][ # # ]: 0 : return (bTableAdjustOfTag || bAny) ? eTableAdjust : SVX_ADJUST_END;
569 : : }
570 : : sal_Int16 GetVertOri() const { return eVertOri; }
571 : :
572 : 0 : sal_uInt16 GetHSpace() const { return nHSpace; }
573 : 0 : sal_uInt16 GetVSpace() const { return nVSpace; }
574 : :
575 : : sal_Bool HasPrcWidth() const { return bPrcWidth; }
576 : : sal_uInt8 GetPrcWidth() const { return bPrcWidth ? (sal_uInt8)nWidth : 0; }
577 : :
578 : : sal_uInt16 GetMinWidth() const
579 : : {
580 : : sal_uInt32 nMin = pLayoutInfo->GetMin();
581 : : return nMin < USHRT_MAX ? (sal_uInt16)nMin : USHRT_MAX;
582 : : }
583 : :
584 : : // von Zeilen oder Spalten geerbtes drawing::Alignment holen
585 : : SvxAdjust GetInheritedAdjust() const;
586 : : sal_Int16 GetInheritedVertOri() const;
587 : :
588 : : // Einfuegen einer Zelle an der aktuellen Position
589 : : void InsertCell( HTMLTableCnts *pCnts, sal_uInt16 nRowSpan, sal_uInt16 nColSpan,
590 : : sal_uInt16 nWidth, sal_Bool bRelWidth, sal_uInt16 nHeight,
591 : : sal_Int16 eVertOri, SvxBrushItem *pBGBrush,
592 : : boost::shared_ptr<SvxBoxItem> const pBoxItem,
593 : : sal_Bool bHasNumFmt, sal_uInt32 nNumFmt,
594 : : sal_Bool bHasValue, double nValue, sal_Bool bNoWrap );
595 : :
596 : : // Start/Ende einer neuen Zeile bekanntgeben
597 : : void OpenRow( SvxAdjust eAdjust, sal_Int16 eVertOri,
598 : : SvxBrushItem *pBGBrush );
599 : : void CloseRow( sal_Bool bEmpty );
600 : :
601 : : // Ende einer neuen Section bekanntgeben
602 : : inline void CloseSection( sal_Bool bHead );
603 : :
604 : : // Ende einer Spalten-Gruppe bekanntgeben
605 : : inline void CloseColGroup( sal_uInt16 nSpan, sal_uInt16 nWidth, sal_Bool bRelWidth,
606 : : SvxAdjust eAdjust, sal_Int16 eVertOri );
607 : :
608 : : // Einfuegen einer Spalte
609 : : void InsertCol( sal_uInt16 nSpan, sal_uInt16 nWidth, sal_Bool bRelWidth,
610 : : SvxAdjust eAdjust, sal_Int16 eVertOri );
611 : :
612 : : // Beenden einer Tab-Definition (MUSS fuer ALLE Tabs aufgerufen werden)
613 : : void CloseTable();
614 : :
615 : : // SwTable konstruieren (inkl. der Child-Tabellen)
616 : : void MakeTable( SwTableBox *pUpper, sal_uInt16 nAbsAvail,
617 : : sal_uInt16 nRelAvail=0, sal_uInt16 nAbsLeftSpace=0,
618 : : sal_uInt16 nAbsRightSpace=0, sal_uInt16 nInhAbsSpace=0 );
619 : :
620 : 0 : inline sal_Bool IsNewDoc() const { return pParser->IsNewDoc(); }
621 : :
622 : 0 : void SetHasParentSection( sal_Bool bSet ) { bHasParentSection = bSet; }
623 : 0 : sal_Bool HasParentSection() const { return bHasParentSection; }
624 : :
625 : 0 : void SetParentContents( HTMLTableCnts *pCnts ) { pParentContents = pCnts; }
626 : 0 : HTMLTableCnts *GetParentContents() const { return pParentContents; }
627 : :
628 : : void MakeParentContents();
629 : :
630 : 0 : sal_Bool GetIsParentHeader() const { return bIsParentHead; }
631 : :
632 : : sal_Bool IsMakeTopSubTable() const { return bMakeTopSubTable; }
633 : : void SetHasToFly() { bHasToFly=sal_True; }
634 : 0 : sal_Bool HasToFly() const { return bHasToFly; }
635 : :
636 : : void SetTable( const SwStartNode *pStNd, _HTMLTableContext *pCntxt,
637 : : sal_uInt16 nLeft, sal_uInt16 nRight,
638 : : const SwTable *pSwTab=0, sal_Bool bFrcFrame=sal_False );
639 : :
640 : 0 : _HTMLTableContext *GetContext() const { return pContext; }
641 : :
642 : : SwHTMLTableLayout *CreateLayoutInfo();
643 : :
644 : 0 : sal_Bool HasColTags() const { return bColSpec; }
645 : :
646 [ # # ]: 0 : sal_uInt16 IncGrfsThatResize() { return pSwTable ? ((SwTable *)pSwTable)->IncGrfsThatResize() : 0; }
647 : :
648 : : void RegisterDrawObject( SdrObject *pObj, sal_uInt8 nPrcWidth );
649 : :
650 : 0 : const SwTable *GetSwTable() const { return pSwTable; }
651 : :
652 [ # # ][ # # ]: 0 : void SetBGBrush( const SvxBrushItem& rBrush ) { delete pBGBrush; pBGBrush = new SvxBrushItem( rBrush ); }
653 : :
654 : 0 : const String& GetId() const { return aId; }
655 : 0 : const String& GetClass() const { return aClass; }
656 : 0 : const String& GetStyle() const { return aStyle; }
657 : 0 : const String& GetDirection() const { return aDir; }
658 : :
659 : 0 : void IncBoxCount() { nBoxes++; }
660 : 0 : sal_Bool IsOverflowing() const { return nBoxes > 64000; }
661 : : };
662 : :
663 : :
664 : :
665 : 0 : void HTMLTableCnts::InitCtor()
666 : : {
667 : 0 : pNext = 0;
668 : 0 : pLayoutInfo = 0;
669 : :
670 : 0 : bNoBreak = sal_False;
671 : 0 : }
672 : :
673 : 0 : HTMLTableCnts::HTMLTableCnts( const SwStartNode* pStNd ):
674 : 0 : pStartNode(pStNd), pTable(0)
675 : : {
676 : 0 : InitCtor();
677 : 0 : }
678 : :
679 : 0 : HTMLTableCnts::HTMLTableCnts( HTMLTable* pTab ):
680 : 0 : pStartNode(0), pTable(pTab)
681 : : {
682 : 0 : InitCtor();
683 : 0 : }
684 : :
685 : 0 : HTMLTableCnts::~HTMLTableCnts()
686 : : {
687 [ # # ]: 0 : delete pTable; // die Tabellen brauchen wir nicht mehr
688 [ # # ]: 0 : delete pNext;
689 : 0 : }
690 : :
691 : 0 : void HTMLTableCnts::Add( HTMLTableCnts* pNewCnts )
692 : : {
693 : 0 : HTMLTableCnts *pCnts = this;
694 : :
695 [ # # ]: 0 : while( pCnts->pNext )
696 : 0 : pCnts = pCnts->pNext;
697 : :
698 : 0 : pCnts->pNext = pNewCnts;
699 : 0 : }
700 : :
701 : 0 : inline void HTMLTableCnts::SetTableBox( SwTableBox *pBox )
702 : : {
703 : : OSL_ENSURE( pLayoutInfo, "Da sit noch keine Layout-Info" );
704 [ # # ]: 0 : if( pLayoutInfo )
705 : 0 : pLayoutInfo->SetTableBox( pBox );
706 : 0 : }
707 : :
708 : 0 : SwHTMLTableLayoutCnts *HTMLTableCnts::CreateLayoutInfo()
709 : : {
710 [ # # ]: 0 : if( !pLayoutInfo )
711 : : {
712 [ # # ]: 0 : SwHTMLTableLayoutCnts *pNextInfo = pNext ? pNext->CreateLayoutInfo() : 0;
713 [ # # ]: 0 : SwHTMLTableLayout *pTableInfo = pTable ? pTable->CreateLayoutInfo() : 0;
714 : :
715 : : pLayoutInfo = new SwHTMLTableLayoutCnts( pStartNode, pTableInfo,
716 [ # # ]: 0 : bNoBreak, pNextInfo );
717 : : }
718 : :
719 : 0 : return pLayoutInfo;
720 : : }
721 : :
722 : :
723 : 0 : HTMLTableCell::HTMLTableCell():
724 : : pContents(0),
725 : : pBGBrush(0),
726 : : nNumFmt(0),
727 : : nRowSpan(1),
728 : : nColSpan(1),
729 : : nWidth( 0 ),
730 : : nValue(0),
731 : : eVertOri( text::VertOrientation::NONE ),
732 : : bProtected(sal_False),
733 : : bRelWidth( sal_False ),
734 : : bHasNumFmt(sal_False),
735 : : bHasValue(sal_False),
736 : : bNoWrap(sal_False),
737 : 0 : mbCovered(sal_False)
738 : 0 : {}
739 : :
740 : 0 : HTMLTableCell::~HTMLTableCell()
741 : : {
742 : : // der Inhalt ist in mehrere Zellen eingetragen, darf aber nur einmal
743 : : // geloescht werden
744 [ # # ][ # # ]: 0 : if( 1==nRowSpan && 1==nColSpan )
745 : : {
746 [ # # ][ # # ]: 0 : delete pContents;
747 [ # # ][ # # ]: 0 : delete pBGBrush;
748 : : }
749 : 0 : }
750 : :
751 : 0 : void HTMLTableCell::Set( HTMLTableCnts *pCnts, sal_uInt16 nRSpan, sal_uInt16 nCSpan,
752 : : sal_Int16 eVert, SvxBrushItem *pBrush,
753 : : ::boost::shared_ptr<SvxBoxItem> const pBoxItem,
754 : : sal_Bool bHasNF, sal_uInt32 nNF, sal_Bool bHasV, double nVal,
755 : : sal_Bool bNWrap, sal_Bool bCovered )
756 : : {
757 : 0 : pContents = pCnts;
758 : 0 : nRowSpan = nRSpan;
759 : 0 : nColSpan = nCSpan;
760 : 0 : bProtected = sal_False;
761 : 0 : eVertOri = eVert;
762 : 0 : pBGBrush = pBrush;
763 : 0 : m_pBoxItem = pBoxItem;
764 : :
765 : 0 : bHasNumFmt = bHasNF;
766 : 0 : bHasValue = bHasV;
767 : 0 : nNumFmt = nNF;
768 : 0 : nValue = nVal;
769 : :
770 : 0 : bNoWrap = bNWrap;
771 : 0 : mbCovered = bCovered;
772 : 0 : }
773 : :
774 : 0 : inline void HTMLTableCell::SetWidth( sal_uInt16 nWdth, sal_Bool bRelWdth )
775 : : {
776 : 0 : nWidth = nWdth;
777 : 0 : bRelWidth = bRelWdth;
778 : 0 : }
779 : :
780 : 0 : void HTMLTableCell::SetProtected()
781 : : {
782 : : // Die Inhalte dieser Zelle mussen nich irgenwo anders verankert
783 : : // sein, weil sie nicht geloescht werden!!!
784 : :
785 : : // Inhalt loeschen
786 : 0 : pContents = 0;
787 : :
788 : : // Hintergrundfarbe kopieren.
789 [ # # ]: 0 : if( pBGBrush )
790 [ # # ]: 0 : pBGBrush = new SvxBrushItem( *pBGBrush );
791 : :
792 : 0 : nRowSpan = 1;
793 : 0 : nColSpan = 1;
794 : 0 : bProtected = sal_True;
795 : 0 : }
796 : :
797 : 0 : inline sal_Bool HTMLTableCell::GetNumFmt( sal_uInt32& rNumFmt ) const
798 : : {
799 : 0 : rNumFmt = nNumFmt;
800 : 0 : return bHasNumFmt;
801 : : }
802 : :
803 : 0 : inline sal_Bool HTMLTableCell::GetValue( double& rValue ) const
804 : : {
805 : 0 : rValue = nValue;
806 : 0 : return bHasValue;
807 : : }
808 : :
809 : 0 : SwHTMLTableLayoutCell *HTMLTableCell::CreateLayoutInfo()
810 : : {
811 [ # # ]: 0 : SwHTMLTableLayoutCnts *pCntInfo = pContents ? pContents->CreateLayoutInfo() : 0;
812 : :
813 : : return new SwHTMLTableLayoutCell( pCntInfo, nRowSpan, nColSpan, nWidth,
814 [ # # ]: 0 : bRelWidth, bNoWrap );
815 : : }
816 : :
817 : :
818 : 0 : HTMLTableRow::HTMLTableRow( sal_uInt16 nCells ):
819 [ # # ]: 0 : pCells(new HTMLTableCells),
820 : : bIsEndOfGroup(sal_False),
821 : : bSplitable( sal_False ),
822 : : nHeight(0),
823 : : nEmptyRows(0),
824 : : eAdjust(SVX_ADJUST_END),
825 : : eVertOri(text::VertOrientation::TOP),
826 : : pBGBrush(0),
827 : 0 : bBottomBorder(sal_False)
828 : : {
829 [ # # ]: 0 : for( sal_uInt16 i=0; i<nCells; i++ )
830 : : {
831 [ # # ]: 0 : pCells->push_back( new HTMLTableCell );
832 : : }
833 : :
834 : : OSL_ENSURE(nCells == pCells->size(),
835 : : "wrong Cell count in new HTML table row");
836 : 0 : }
837 : :
838 : 0 : HTMLTableRow::~HTMLTableRow()
839 : : {
840 [ # # ]: 0 : delete pCells;
841 [ # # ]: 0 : delete pBGBrush;
842 : 0 : }
843 : :
844 : 0 : inline void HTMLTableRow::SetHeight( sal_uInt16 nHght )
845 : : {
846 [ # # ]: 0 : if( nHght > nHeight )
847 : 0 : nHeight = nHght;
848 : 0 : }
849 : :
850 : 0 : inline HTMLTableCell *HTMLTableRow::GetCell( sal_uInt16 nCell ) const
851 : : {
852 : : OSL_ENSURE( nCell<pCells->size(),
853 : : "ungueltiger Zellen-Index in HTML-Tabellenzeile" );
854 : 0 : return &(*pCells)[nCell];
855 : : }
856 : :
857 : 0 : void HTMLTableRow::Expand( sal_uInt16 nCells, sal_Bool bOneCell )
858 : : {
859 : : // die Zeile wird mit einer einzigen Zelle aufgefuellt, wenn
860 : : // bOneCell gesetzt ist. Das geht, nur fuer Zeilen, in die keine
861 : : // Zellen mehr eingefuegt werden!
862 : :
863 : 0 : sal_uInt16 nColSpan = nCells-pCells->size();
864 [ # # ]: 0 : for( sal_uInt16 i=pCells->size(); i<nCells; i++ )
865 : : {
866 [ # # ]: 0 : HTMLTableCell *pCell = new HTMLTableCell;
867 [ # # ]: 0 : if( bOneCell )
868 : 0 : pCell->SetColSpan( nColSpan );
869 : :
870 : 0 : pCells->push_back( pCell );
871 : 0 : nColSpan--;
872 : : }
873 : :
874 : : OSL_ENSURE(nCells == pCells->size(),
875 : : "wrong Cell count in expanded HTML table row");
876 : 0 : }
877 : :
878 : 0 : void HTMLTableRow::Shrink( sal_uInt16 nCells )
879 : : {
880 : : OSL_ENSURE(nCells < pCells->size(), "number of cells too large");
881 : :
882 : : #if OSL_DEBUG_LEVEL > 0
883 : : sal_uInt16 nEnd = pCells->size();
884 : : #endif
885 : : // The colspan of empty cells at the end has to be fixed to the new
886 : : // number of cells.
887 : 0 : sal_uInt16 i=nCells;
888 [ # # ]: 0 : while( i )
889 : : {
890 : 0 : HTMLTableCell *pCell = &(*pCells)[--i];
891 [ # # ]: 0 : if( !pCell->GetContents() )
892 : : {
893 : : #if OSL_DEBUG_LEVEL > 0
894 : : OSL_ENSURE( pCell->GetColSpan() == nEnd - i,
895 : : "invalid col span for empty cell at row end" );
896 : : #endif
897 : 0 : pCell->SetColSpan( nCells-i);
898 : : }
899 : : else
900 : 0 : break;
901 : : }
902 : : #if OSL_DEBUG_LEVEL > 0
903 : : for( i=nCells; i<nEnd; i++ )
904 : : {
905 : : HTMLTableCell *pCell = &(*pCells)[i];
906 : : OSL_ENSURE( pCell->GetRowSpan() == 1,
907 : : "RowSpan von zu loesender Zelle ist falsch" );
908 : : OSL_ENSURE( pCell->GetColSpan() == nEnd - i,
909 : : "ColSpan von zu loesender Zelle ist falsch" );
910 : : OSL_ENSURE( !pCell->GetContents(), "Zu loeschende Zelle hat Inhalt" );
911 : : }
912 : : #endif
913 : :
914 : 0 : pCells->erase( pCells->begin() + nCells, pCells->end() );
915 : 0 : }
916 : :
917 : :
918 : 0 : HTMLTableColumn::HTMLTableColumn():
919 : : bIsEndOfGroup(sal_False),
920 : : nWidth(0), bRelWidth(sal_False),
921 : : eAdjust(SVX_ADJUST_END), eVertOri(text::VertOrientation::TOP),
922 : 0 : bLeftBorder(sal_False)
923 : : {
924 [ # # ]: 0 : for( sal_uInt16 i=0; i<6; i++ )
925 : 0 : aFrmFmts[i] = 0;
926 : 0 : }
927 : :
928 : 0 : inline void HTMLTableColumn::SetWidth( sal_uInt16 nWdth, sal_Bool bRelWdth )
929 : : {
930 [ # # ]: 0 : if( bRelWidth==bRelWdth )
931 : : {
932 [ # # ]: 0 : if( nWdth > nWidth )
933 : 0 : nWidth = nWdth;
934 : : }
935 : : else
936 : 0 : nWidth = nWdth;
937 : 0 : bRelWidth = bRelWdth;
938 : 0 : }
939 : :
940 : 0 : inline SwHTMLTableLayoutColumn *HTMLTableColumn::CreateLayoutInfo()
941 : : {
942 [ # # ]: 0 : return new SwHTMLTableLayoutColumn( nWidth, bRelWidth, bLeftBorder );
943 : : }
944 : :
945 : 0 : inline sal_uInt16 HTMLTableColumn::GetFrmFmtIdx( sal_Bool bBorderLine,
946 : : sal_Int16 eVertOrient ) const
947 : : {
948 : : OSL_ENSURE( text::VertOrientation::TOP != eVertOrient, "Top ist nicht erlaubt" );
949 [ # # ]: 0 : sal_uInt16 n = bBorderLine ? 3 : 0;
950 [ # # # ]: 0 : switch( eVertOrient )
951 : : {
952 : 0 : case text::VertOrientation::CENTER: n+=1; break;
953 : 0 : case text::VertOrientation::BOTTOM: n+=2; break;
954 : : default:
955 : : ;
956 : : }
957 : 0 : return n;
958 : : }
959 : :
960 : 0 : inline void HTMLTableColumn::SetFrmFmt( SwFrmFmt *pFmt, sal_Bool bBorderLine,
961 : : sal_Int16 eVertOrient )
962 : : {
963 : 0 : aFrmFmts[GetFrmFmtIdx(bBorderLine,eVertOrient)] = pFmt;
964 : 0 : }
965 : :
966 : 0 : inline SwFrmFmt *HTMLTableColumn::GetFrmFmt( sal_Bool bBorderLine,
967 : : sal_Int16 eVertOrient ) const
968 : : {
969 : 0 : return aFrmFmts[GetFrmFmtIdx(bBorderLine,eVertOrient)];
970 : : }
971 : :
972 : :
973 : :
974 : 0 : void HTMLTable::InitCtor( const HTMLTableOptions *pOptions )
975 : : {
976 : 0 : pResizeDrawObjs = 0;
977 : 0 : pDrawObjPrcWidths = 0;
978 : :
979 [ # # ][ # # ]: 0 : pRows = new HTMLTableRows;
980 [ # # ][ # # ]: 0 : pColumns = new HTMLTableColumns;
981 : 0 : nRows = 0;
982 : 0 : nCurRow = 0; nCurCol = 0;
983 : :
984 : 0 : pBox1 = 0;
985 : 0 : pBoxFmt = 0; pLineFmt = 0;
986 : 0 : pLineFrmFmtNoHeight = 0;
987 : 0 : pInhBGBrush = 0;
988 : :
989 : 0 : pPrevStNd = 0;
990 : 0 : pSwTable = 0;
991 : :
992 : 0 : bTopBorder = sal_False; bRightBorder = sal_False;
993 : 0 : bTopAlwd = sal_True; bRightAlwd = sal_True;
994 : 0 : bFillerTopBorder = sal_False; bFillerBottomBorder = sal_False;
995 : 0 : bInhLeftBorder = sal_False; bInhRightBorder = sal_False;
996 : 0 : bBordersSet = sal_False;
997 : 0 : bForceFrame = sal_False;
998 : 0 : nHeadlineRepeat = 0;
999 : :
1000 : 0 : nLeftMargin = 0;
1001 : 0 : nRightMargin = 0;
1002 : :
1003 : 0 : const Color& rBorderColor = pOptions->aBorderColor;
1004 : :
1005 : 0 : long nBorderOpt = (long)pOptions->nBorder;
1006 : : long nPWidth = nBorderOpt==USHRT_MAX ? NETSCAPE_DFLT_BORDER
1007 [ # # ]: 0 : : nBorderOpt;
1008 [ # # ]: 0 : long nPHeight = nBorderOpt==USHRT_MAX ? 0 : nBorderOpt;
1009 [ # # ]: 0 : SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
1010 : :
1011 : : // nBorder gibt die Breite der Umrandung an, wie sie in die
1012 : : // Breitenberechnung in Netscape einfliesst. Wenn pOption->nBorder
1013 : : // == USHRT_MAX, wurde keine BORDER-Option angegeben. Trotzdem fliesst
1014 : : // eine 1 Pixel breite Umrandung in die Breitenberechnung mit ein.
1015 : 0 : nBorder = (sal_uInt16)nPWidth;
1016 [ # # ]: 0 : if( nBorderOpt==USHRT_MAX )
1017 : 0 : nPWidth = 0;
1018 : :
1019 : : // HACK: ein Pixel-breite Linien sollen zur Haarlinie werden, wenn
1020 : : // wir mit doppelter Umrandung arbeiten
1021 [ # # ][ # # ]: 0 : if( pOptions->nCellSpacing!=0 && nBorderOpt==1 )
1022 : : {
1023 : 0 : nPWidth = 1;
1024 : 0 : nPHeight = 1;
1025 : : }
1026 : :
1027 [ # # ]: 0 : if ( pOptions->nCellSpacing != 0 )
1028 : : {
1029 [ # # ]: 0 : aTopBorderLine.SetBorderLineStyle(table::BorderLineStyle::DOUBLE);
1030 : : }
1031 : 0 : aTopBorderLine.SetWidth( nPHeight );
1032 : 0 : aTopBorderLine.SetColor( rBorderColor );
1033 [ # # ]: 0 : aBottomBorderLine = aTopBorderLine;
1034 : :
1035 [ # # ]: 0 : if( nPWidth == nPHeight )
1036 : : {
1037 [ # # ]: 0 : aLeftBorderLine = aTopBorderLine;
1038 : : }
1039 : : else
1040 : : {
1041 [ # # ]: 0 : if ( pOptions->nCellSpacing != 0 )
1042 : : {
1043 [ # # ]: 0 : aLeftBorderLine.SetBorderLineStyle(table::BorderLineStyle::DOUBLE);
1044 : : }
1045 : 0 : aLeftBorderLine.SetWidth( nPWidth );
1046 : 0 : aLeftBorderLine.SetColor( rBorderColor );
1047 : : }
1048 [ # # ]: 0 : aRightBorderLine = aLeftBorderLine;
1049 : :
1050 [ # # ]: 0 : if( pOptions->nCellSpacing != 0 )
1051 : : {
1052 [ # # ]: 0 : aBorderLine.SetBorderLineStyle(table::BorderLineStyle::DOUBLE);
1053 : 0 : aBorderLine.SetWidth( DEF_LINE_WIDTH_0 );
1054 : : }
1055 : : else
1056 : : {
1057 : 0 : aBorderLine.SetWidth( DEF_LINE_WIDTH_0 );
1058 : : }
1059 : 0 : aBorderLine.SetColor( rBorderColor );
1060 : :
1061 [ # # ]: 0 : if( nCellPadding )
1062 : : {
1063 [ # # ]: 0 : if( nCellPadding==USHRT_MAX )
1064 : 0 : nCellPadding = MIN_BORDER_DIST; // default
1065 : : else
1066 : : {
1067 [ # # ]: 0 : nCellPadding = pParser->ToTwips( nCellPadding );
1068 [ # # ]: 0 : if( nCellPadding<MIN_BORDER_DIST )
1069 : 0 : nCellPadding = MIN_BORDER_DIST;
1070 : : }
1071 : : }
1072 [ # # ]: 0 : if( nCellSpacing )
1073 : : {
1074 [ # # ]: 0 : if( nCellSpacing==USHRT_MAX )
1075 : 0 : nCellSpacing = NETSCAPE_DFLT_CELLSPACING;
1076 [ # # ]: 0 : nCellSpacing = pParser->ToTwips( nCellSpacing );
1077 : : }
1078 : :
1079 : 0 : nPWidth = pOptions->nHSpace;
1080 : 0 : nPHeight = pOptions->nVSpace;
1081 [ # # ]: 0 : SvxCSS1Parser::PixelToTwip( nPWidth, nPHeight );
1082 : 0 : nHSpace = (sal_uInt16)nPWidth;
1083 : 0 : nVSpace = (sal_uInt16)nPHeight;
1084 : :
1085 : 0 : bColSpec = sal_False;
1086 : :
1087 : : pBGBrush = pParser->CreateBrushItem(
1088 : : pOptions->bBGColor ? &(pOptions->aBGColor) : 0,
1089 [ # # ][ # # ]: 0 : pOptions->aBGImage, aEmptyStr, aEmptyStr, aEmptyStr );
1090 : :
1091 : 0 : pContext = 0;
1092 : 0 : pParentContents = 0;
1093 : :
1094 [ # # ]: 0 : aId = pOptions->aId;
1095 [ # # ]: 0 : aClass = pOptions->aClass;
1096 [ # # ]: 0 : aStyle = pOptions->aStyle;
1097 [ # # ]: 0 : aDir = pOptions->aDir;
1098 : 0 : }
1099 : :
1100 : 0 : HTMLTable::HTMLTable( SwHTMLParser* pPars, HTMLTable *pTopTab,
1101 : : sal_Bool bParHead,
1102 : : sal_Bool bHasParentSec, sal_Bool bTopTbl, sal_Bool bHasToFlw,
1103 : : const HTMLTableOptions *pOptions ) :
1104 : : nCols( pOptions->nCols ),
1105 : : nFilledCols( 0 ),
1106 : : nCellPadding( pOptions->nCellPadding ),
1107 : : nCellSpacing( pOptions->nCellSpacing ),
1108 : : nBoxes( 1 ),
1109 : : pCaptionStartNode( 0 ),
1110 : : bTableAdjustOfTag( pTopTab ? sal_False : pOptions->bTableAdjust ),
1111 : : bIsParentHead( bParHead ),
1112 : : bHasParentSection( bHasParentSec ),
1113 : : bMakeTopSubTable( bTopTbl ),
1114 : : bHasToFly( bHasToFlw ),
1115 : : bFixedCols( pOptions->nCols>0 ),
1116 : : bPrcWidth( pOptions->bPrcWidth ),
1117 : : pParser( pPars ),
1118 : : pTopTable( pTopTab ? pTopTab : this ),
1119 : : pLayoutInfo( 0 ),
1120 : : nWidth( pOptions->nWidth ),
1121 : : nHeight( pTopTab ? 0 : pOptions->nHeight ),
1122 : : eTableAdjust( pOptions->eAdjust ),
1123 : : eVertOri( pOptions->eVertOri ),
1124 : : eFrame( pOptions->eFrame ),
1125 : : eRules( pOptions->eRules ),
1126 : : bTopCaption( sal_False ),
1127 [ # # ][ # # ]: 0 : bFirstCell( !pTopTab )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1128 : : {
1129 [ # # ]: 0 : InitCtor( pOptions );
1130 : :
1131 [ # # ]: 0 : for( sal_uInt16 i=0; i<nCols; i++ )
1132 [ # # ][ # # ]: 0 : pColumns->push_back( new HTMLTableColumn );
1133 : 0 : }
1134 : :
1135 : :
1136 [ # # ][ # # ]: 0 : HTMLTable::~HTMLTable()
[ # # ]
1137 : : {
1138 [ # # ]: 0 : delete pResizeDrawObjs;
1139 [ # # ]: 0 : delete pDrawObjPrcWidths;
1140 : :
1141 [ # # ][ # # ]: 0 : delete pRows;
1142 [ # # ][ # # ]: 0 : delete pColumns;
1143 [ # # ][ # # ]: 0 : delete pBGBrush;
1144 [ # # ][ # # ]: 0 : delete pInhBGBrush;
1145 : :
1146 [ # # ][ # # ]: 0 : delete pContext;
1147 : :
1148 : : // pLayoutInfo wurde entweder bereits geloescht oder muss aber es
1149 : : // in den Besitz der SwTable uebergegangen.
1150 : 0 : }
1151 : :
1152 : 0 : SwHTMLTableLayout *HTMLTable::CreateLayoutInfo()
1153 : : {
1154 [ # # ]: 0 : sal_uInt16 nW = bPrcWidth ? nWidth : pParser->ToTwips( nWidth );
1155 : :
1156 : 0 : sal_uInt16 nBorderWidth = GetBorderWidth( aBorderLine, sal_True );
1157 : : sal_uInt16 nLeftBorderWidth =
1158 [ # # ]: 0 : ((*pColumns)[0]).bLeftBorder ? GetBorderWidth( aLeftBorderLine, sal_True ) : 0;
1159 : : sal_uInt16 nRightBorderWidth =
1160 [ # # ]: 0 : bRightBorder ? GetBorderWidth( aRightBorderLine, sal_True ) : 0;
1161 : 0 : sal_uInt16 nInhLeftBorderWidth = 0;
1162 : 0 : sal_uInt16 nInhRightBorderWidth = 0;
1163 : :
1164 : : pLayoutInfo = new SwHTMLTableLayout(
1165 : : pSwTable,
1166 : : nRows, nCols, bFixedCols, bColSpec,
1167 : : nW, bPrcWidth, nBorder, nCellPadding,
1168 : : nCellSpacing, eTableAdjust,
1169 : : nLeftMargin, nRightMargin,
1170 : : nBorderWidth, nLeftBorderWidth, nRightBorderWidth,
1171 [ # # ]: 0 : nInhLeftBorderWidth, nInhRightBorderWidth );
1172 : :
1173 : 0 : sal_Bool bExportable = sal_True;
1174 : : sal_uInt16 i;
1175 [ # # ]: 0 : for( i=0; i<nRows; i++ )
1176 : : {
1177 : 0 : HTMLTableRow *pRow = &(*pRows)[i];
1178 [ # # ]: 0 : for( sal_uInt16 j=0; j<nCols; j++ )
1179 : : {
1180 : : SwHTMLTableLayoutCell *pLayoutCell =
1181 : 0 : pRow->GetCell(j)->CreateLayoutInfo();
1182 : :
1183 : 0 : pLayoutInfo->SetCell( pLayoutCell, i, j );
1184 : :
1185 [ # # ]: 0 : if( bExportable )
1186 : : {
1187 : : SwHTMLTableLayoutCnts *pLayoutCnts =
1188 : 0 : pLayoutCell->GetContents();
1189 : : bExportable = !pLayoutCnts ||
1190 : 0 : ( pLayoutCnts->GetStartNode() &&
1191 [ # # ]: 0 : !pLayoutCnts->GetNext() );
[ # # # # ]
1192 : : }
1193 : : }
1194 : : }
1195 : :
1196 : 0 : pLayoutInfo->SetExportable( bExportable );
1197 : :
1198 [ # # ]: 0 : for( i=0; i<nCols; i++ )
1199 : 0 : pLayoutInfo->SetColumn( ((*pColumns)[i]).CreateLayoutInfo(), i );
1200 : :
1201 : 0 : return pLayoutInfo;
1202 : : }
1203 : :
1204 : 0 : inline void HTMLTable::SetCaption( const SwStartNode *pStNd, sal_Bool bTop )
1205 : : {
1206 : 0 : pCaptionStartNode = pStNd;
1207 : 0 : bTopCaption = bTop;
1208 : 0 : }
1209 : :
1210 : 0 : void HTMLTable::FixRowSpan( sal_uInt16 nRow, sal_uInt16 nCol,
1211 : : const HTMLTableCnts *pCnts )
1212 : : {
1213 : 0 : sal_uInt16 nRowSpan=1;
1214 : : HTMLTableCell *pCell;
1215 [ # # ]: 0 : while( ( pCell=GetCell(nRow,nCol), pCell->GetContents()==pCnts ) )
1216 : : {
1217 : 0 : pCell->SetRowSpan( nRowSpan );
1218 [ # # ]: 0 : if( pLayoutInfo )
1219 : 0 : pLayoutInfo->GetCell(nRow,nCol)->SetRowSpan( nRowSpan );
1220 : :
1221 [ # # ]: 0 : if( !nRow ) break;
1222 : 0 : nRowSpan++; nRow--;
1223 : : }
1224 : 0 : }
1225 : :
1226 : 0 : void HTMLTable::ProtectRowSpan( sal_uInt16 nRow, sal_uInt16 nCol, sal_uInt16 nRowSpan )
1227 : : {
1228 [ # # ]: 0 : for( sal_uInt16 i=0; i<nRowSpan; i++ )
1229 : : {
1230 : 0 : GetCell(nRow+i,nCol)->SetProtected();
1231 [ # # ]: 0 : if( pLayoutInfo )
1232 : 0 : pLayoutInfo->GetCell(nRow+i,nCol)->SetProtected();
1233 : : }
1234 : 0 : }
1235 : :
1236 : :
1237 : : // Suchen des SwStartNodes der letzten belegten Vorgaengerbox
1238 : 0 : const SwStartNode* HTMLTable::GetPrevBoxStartNode( sal_uInt16 nRow, sal_uInt16 nCol ) const
1239 : : {
1240 : 0 : const HTMLTableCnts *pPrevCnts = 0;
1241 : :
1242 [ # # ]: 0 : if( 0==nRow )
1243 : : {
1244 : : // immer die Vorgaenger-Zelle
1245 [ # # ]: 0 : if( nCol>0 )
1246 : 0 : pPrevCnts = GetCell( 0, nCol-1 )->GetContents();
1247 : : else
1248 : 0 : return pPrevStNd;
1249 : : }
1250 [ # # ][ # # ]: 0 : else if( USHRT_MAX==nRow && USHRT_MAX==nCol )
1251 : : // der Contents der letzten Zelle
1252 : 0 : pPrevCnts = GetCell( nRows-1, nCols-1 )->GetContents();
1253 : : else
1254 : : {
1255 : : sal_uInt16 i;
1256 : 0 : HTMLTableRow *pPrevRow = &(*pRows)[nRow-1];
1257 : :
1258 : : // evtl. eine Zelle in der aktuellen Zeile
1259 : 0 : i = nCol;
1260 [ # # ]: 0 : while( i )
1261 : : {
1262 : 0 : i--;
1263 [ # # ]: 0 : if( 1 == pPrevRow->GetCell(i)->GetRowSpan() )
1264 : : {
1265 : 0 : pPrevCnts = GetCell(nRow,i)->GetContents();
1266 : 0 : break;
1267 : : }
1268 : : }
1269 : :
1270 : : // sonst die letzte gefuellte Zelle der Zeile davor suchen
1271 [ # # ]: 0 : if( !pPrevCnts )
1272 : : {
1273 : 0 : i = nCols;
1274 [ # # ][ # # ]: 0 : while( !pPrevCnts && i )
[ # # ]
1275 : : {
1276 : 0 : i--;
1277 : 0 : pPrevCnts = pPrevRow->GetCell(i)->GetContents();
1278 : : }
1279 : : }
1280 : : }
1281 : : OSL_ENSURE( pPrevCnts, "keine gefuellte Vorgaenger-Zelle gefunden" );
1282 [ # # ]: 0 : if( !pPrevCnts )
1283 : : {
1284 : 0 : pPrevCnts = GetCell(0,0)->GetContents();
1285 [ # # ]: 0 : if( !pPrevCnts )
1286 : 0 : return pPrevStNd;
1287 : : }
1288 : :
1289 [ # # ]: 0 : while( pPrevCnts->Next() )
1290 : 0 : pPrevCnts = pPrevCnts->Next();
1291 : :
1292 : 0 : return ( pPrevCnts->GetStartNode() ? pPrevCnts->GetStartNode()
1293 [ # # ]: 0 : : pPrevCnts->GetTable()->GetPrevBoxStartNode( USHRT_MAX, USHRT_MAX ) );
1294 : : }
1295 : :
1296 : :
1297 : 0 : static sal_Bool IsBoxEmpty( const SwTableBox *pBox )
1298 : : {
1299 : 0 : const SwStartNode *pSttNd = pBox->GetSttNd();
1300 [ # # ]: 0 : if( pSttNd &&
[ # # # # ]
1301 : 0 : pSttNd->GetIndex() + 2 == pSttNd->EndOfSectionIndex() )
1302 : : {
1303 : : const SwCntntNode *pCNd =
1304 : 0 : pSttNd->GetNodes()[pSttNd->GetIndex()+1]->GetCntntNode();
1305 [ # # ][ # # ]: 0 : if( pCNd && !pCNd->Len() )
[ # # ]
1306 : 0 : return sal_True;
1307 : : }
1308 : :
1309 : 0 : return sal_False;
1310 : : }
1311 : :
1312 : 0 : sal_uInt16 HTMLTable::GetTopCellSpace( sal_uInt16 nRow, sal_uInt16 nRowSpan,
1313 : : sal_Bool bSwBorders ) const
1314 : : {
1315 : 0 : sal_uInt16 nSpace = nCellPadding;
1316 : :
1317 [ # # ]: 0 : if( nRow == 0 )
1318 : : {
1319 : 0 : nSpace += nBorder + nCellSpacing;
1320 [ # # ]: 0 : if( bSwBorders )
1321 : : {
1322 : : sal_uInt16 nTopBorderWidth =
1323 : 0 : GetBorderWidth( aTopBorderLine, sal_True );
1324 [ # # ]: 0 : if( nSpace < nTopBorderWidth )
1325 : 0 : nSpace = nTopBorderWidth;
1326 : : }
1327 : : }
1328 [ # # ][ # # ]: 0 : else if( bSwBorders && (*pRows)[nRow+nRowSpan-1].bBottomBorder &&
[ # # ][ # # ]
1329 : : nSpace < MIN_BORDER_DIST )
1330 : : {
1331 : : OSL_ENSURE( !nCellPadding, "GetTopCellSpace: CELLPADDING!=0" );
1332 : : // Wenn die Gegenueberliegende Seite umrandet ist muessen
1333 : : // wir zumindest den minimalen Abstand zum Inhalt
1334 : : // beruecksichtigen. (Koennte man zusaetzlich auch an
1335 : : // nCellPadding festmachen.)
1336 : 0 : nSpace = MIN_BORDER_DIST;
1337 : : }
1338 : :
1339 : 0 : return nSpace;
1340 : : }
1341 : :
1342 : 0 : sal_uInt16 HTMLTable::GetBottomCellSpace( sal_uInt16 nRow, sal_uInt16 nRowSpan,
1343 : : sal_Bool bSwBorders ) const
1344 : : {
1345 : 0 : sal_uInt16 nSpace = nCellSpacing + nCellPadding;
1346 : :
1347 [ # # ]: 0 : if( nRow+nRowSpan == nRows )
1348 : : {
1349 : 0 : nSpace = nSpace + nBorder;
1350 : :
1351 [ # # ]: 0 : if( bSwBorders )
1352 : : {
1353 : : sal_uInt16 nBottomBorderWidth =
1354 : 0 : GetBorderWidth( aBottomBorderLine, sal_True );
1355 [ # # ]: 0 : if( nSpace < nBottomBorderWidth )
1356 : 0 : nSpace = nBottomBorderWidth;
1357 : : }
1358 : : }
1359 [ # # ]: 0 : else if( bSwBorders )
1360 : : {
1361 [ # # ]: 0 : if( (*pRows)[nRow+nRowSpan+1].bBottomBorder )
1362 : : {
1363 : 0 : sal_uInt16 nBorderWidth = GetBorderWidth( aBorderLine, sal_True );
1364 [ # # ]: 0 : if( nSpace < nBorderWidth )
1365 : 0 : nSpace = nBorderWidth;
1366 : : }
1367 [ # # ][ # # ]: 0 : else if( nRow==0 && bTopBorder && nSpace < MIN_BORDER_DIST )
[ # # ]
1368 : : {
1369 : : OSL_ENSURE( GetBorderWidth( aTopBorderLine, sal_True ) > 0,
1370 : : "GetBottomCellSpace: |aTopLine| == 0" );
1371 : : OSL_ENSURE( !nCellPadding, "GetBottomCellSpace: CELLPADDING!=0" );
1372 : : // Wenn die Gegenueberliegende Seite umrandet ist muessen
1373 : : // wir zumindest den minimalen Abstand zum Inhalt
1374 : : // beruecksichtigen. (Koennte man zusaetzlich auch an
1375 : : // nCellPadding festmachen.)
1376 : 0 : nSpace = MIN_BORDER_DIST;
1377 : : }
1378 : : }
1379 : :
1380 : 0 : return nSpace;
1381 : : }
1382 : :
1383 : 0 : void HTMLTable::FixFrameFmt( SwTableBox *pBox,
1384 : : sal_uInt16 nRow, sal_uInt16 nCol,
1385 : : sal_uInt16 nRowSpan, sal_uInt16 nColSpan,
1386 : : sal_Bool bFirstPara, sal_Bool bLastPara ) const
1387 : : {
1388 : 0 : SwFrmFmt *pFrmFmt = 0; // frame::Frame-Format
1389 : 0 : sal_Int16 eVOri = text::VertOrientation::NONE;
1390 : 0 : const SvxBrushItem *pBGBrushItem = 0; // Hintergrund
1391 [ # # ]: 0 : boost::shared_ptr<SvxBoxItem> pBoxItem;
1392 : 0 : sal_Bool bTopLine = sal_False, bBottomLine = sal_False, bLastBottomLine = sal_False;
1393 : 0 : sal_Bool bReUsable = sal_False; // Format nochmals verwendbar?
1394 : 0 : sal_uInt16 nEmptyRows = 0;
1395 : 0 : sal_Bool bHasNumFmt = sal_False;
1396 : 0 : sal_Bool bHasValue = sal_False;
1397 : 0 : sal_uInt32 nNumFmt = 0;
1398 : 0 : double nValue = 0.0;
1399 : :
1400 [ # # ]: 0 : HTMLTableColumn *pColumn = &(*pColumns)[nCol];
1401 : :
1402 [ # # ]: 0 : if( pBox->GetSttNd() )
1403 : : {
1404 : : // die Hintergrundfarbe/-grafik bestimmen
1405 [ # # ]: 0 : const HTMLTableCell *pCell = GetCell( nRow, nCol );
1406 [ # # ][ # # ]: 0 : pBoxItem = pCell->GetBoxItem();
[ # # ]
1407 : 0 : pBGBrushItem = pCell->GetBGBrush();
1408 [ # # ]: 0 : if( !pBGBrushItem )
1409 : : {
1410 : : // Wenn die Zelle ueber mehrere Zeilen geht muss ein evtl.
1411 : : // an der Zeile gesetzter Hintergrund an die Zelle uebernommen
1412 : : // werden.
1413 : : // Wenn es sich um eine Tabelle in der Tabelle handelt und
1414 : : // die Zelle ueber die gesamte Heoehe der Tabelle geht muss
1415 : : // ebenfalls der Hintergrund der Zeile uebernommen werden, weil
1416 : : // die Line von der GC (zu Recht) wegoptimiert wird.
1417 [ # # ][ # # ]: 0 : if( nRowSpan > 1 || (this != pTopTable && nRowSpan==nRows) )
[ # # ]
1418 : : {
1419 [ # # ]: 0 : pBGBrushItem = (*pRows)[nRow].GetBGBrush();
1420 [ # # ][ # # ]: 0 : if( !pBGBrushItem && this != pTopTable )
1421 : : {
1422 : 0 : pBGBrushItem = GetBGBrush();
1423 [ # # ]: 0 : if( !pBGBrushItem )
1424 : 0 : pBGBrushItem = GetInhBGBrush();
1425 : : }
1426 : : }
1427 : : }
1428 : :
1429 [ # # ][ # # ]: 0 : bTopLine = 0==nRow && bTopBorder && bFirstPara;
[ # # ]
1430 [ # # ][ # # ]: 0 : if( (*pRows)[nRow+nRowSpan-1].bBottomBorder && bLastPara )
[ # # ][ # # ]
1431 : : {
1432 [ # # ]: 0 : nEmptyRows = (*pRows)[nRow+nRowSpan-1].GetEmptyRows();
1433 [ # # ]: 0 : if( nRow+nRowSpan == nRows )
1434 : 0 : bLastBottomLine = sal_True;
1435 : : else
1436 : 0 : bBottomLine = sal_True;
1437 : : }
1438 : :
1439 : 0 : eVOri = pCell->GetVertOri();
1440 : 0 : bHasNumFmt = pCell->GetNumFmt( nNumFmt );
1441 [ # # ]: 0 : if( bHasNumFmt )
1442 : 0 : bHasValue = pCell->GetValue( nValue );
1443 : :
1444 [ # # ][ # # ]: 0 : if( nColSpan==1 && !bTopLine && !bLastBottomLine && !nEmptyRows &&
[ # # ][ # # ]
[ # # ]
[ # # # # ]
[ # # ]
1445 : 0 : !pBGBrushItem && !bHasNumFmt && !pBoxItem)
1446 : : {
1447 : 0 : pFrmFmt = pColumn->GetFrmFmt( bBottomLine, eVOri );
1448 : 0 : bReUsable = !pFrmFmt;
1449 : : }
1450 : : }
1451 : :
1452 [ # # ]: 0 : if( !pFrmFmt )
1453 : : {
1454 [ # # ]: 0 : pFrmFmt = pBox->ClaimFrmFmt();
1455 : :
1456 : : // die Breite der Box berechnen
1457 : : SwTwips nFrmWidth = (SwTwips)pLayoutInfo->GetColumn(nCol)
1458 : 0 : ->GetRelColWidth();
1459 [ # # ]: 0 : for( sal_uInt16 i=1; i<nColSpan; i++ )
1460 : : nFrmWidth += (SwTwips)pLayoutInfo->GetColumn(nCol+i)
1461 : 0 : ->GetRelColWidth();
1462 : :
1463 : : // die Umrandung nur an Edit-Boxen setzen (bei der oberen und unteren
1464 : : // Umrandung muss beruecks. werden, ob es sich um den ersten oder
1465 : : // letzen Absatz der Zelle handelt)
1466 [ # # ]: 0 : if( pBox->GetSttNd() )
1467 : : {
1468 : 0 : sal_Bool bSet = (nCellPadding > 0);
1469 : :
1470 [ # # ]: 0 : SvxBoxItem aBoxItem( RES_BOX );
1471 : 0 : long nInnerFrmWidth = nFrmWidth;
1472 : :
1473 [ # # ]: 0 : if( bTopLine )
1474 : : {
1475 [ # # ]: 0 : aBoxItem.SetLine( &aTopBorderLine, BOX_LINE_TOP );
1476 : 0 : bSet = sal_True;
1477 : : }
1478 [ # # ]: 0 : if( bLastBottomLine )
1479 : : {
1480 [ # # ]: 0 : aBoxItem.SetLine( &aBottomBorderLine, BOX_LINE_BOTTOM );
1481 : 0 : bSet = sal_True;
1482 : : }
1483 [ # # ]: 0 : else if( bBottomLine )
1484 : : {
1485 [ # # ][ # # ]: 0 : if( nEmptyRows && !aBorderLine.GetInWidth() )
[ # # ][ # # ]
1486 : : {
1487 : : // Leere Zeilen koennen zur Zeit nur dann ueber
1488 : : // dicke Linien simuliert werden, wenn die Linie
1489 : : // einfach ist.
1490 [ # # ]: 0 : SvxBorderLine aThickBorderLine( aBorderLine );
1491 : :
1492 [ # # ]: 0 : sal_uInt16 nBorderWidth = aBorderLine.GetOutWidth();
1493 : 0 : nBorderWidth *= (nEmptyRows + 1);
1494 : : aThickBorderLine.SetBorderLineStyle(
1495 [ # # ]: 0 : table::BorderLineStyle::SOLID);
1496 : 0 : aThickBorderLine.SetWidth( nBorderWidth );
1497 [ # # ]: 0 : aBoxItem.SetLine( &aThickBorderLine, BOX_LINE_BOTTOM );
1498 : : }
1499 : : else
1500 : : {
1501 [ # # ]: 0 : aBoxItem.SetLine( &aBorderLine, BOX_LINE_BOTTOM );
1502 : : }
1503 : 0 : bSet = sal_True;
1504 : : }
1505 [ # # ][ # # ]: 0 : if( ((*pColumns)[nCol]).bLeftBorder )
1506 : : {
1507 : : const SvxBorderLine& rBorderLine =
1508 [ # # ]: 0 : 0==nCol ? aLeftBorderLine : aBorderLine;
1509 [ # # ]: 0 : aBoxItem.SetLine( &rBorderLine, BOX_LINE_LEFT );
1510 : 0 : nInnerFrmWidth -= GetBorderWidth( rBorderLine );
1511 : 0 : bSet = sal_True;
1512 : : }
1513 [ # # ][ # # ]: 0 : if( nCol+nColSpan == nCols && bRightBorder )
1514 : : {
1515 [ # # ]: 0 : aBoxItem.SetLine( &aRightBorderLine, BOX_LINE_RIGHT );
1516 : 0 : nInnerFrmWidth -= GetBorderWidth( aRightBorderLine );
1517 : 0 : bSet = sal_True;
1518 : : }
1519 : :
1520 [ # # ]: 0 : if (pBoxItem)
1521 : : {
1522 [ # # ]: 0 : pFrmFmt->SetFmtAttr( *pBoxItem );
1523 : : }
1524 [ # # ]: 0 : else if (bSet)
1525 : : {
1526 : : // BorderDist nicht mehr Bestandteil einer Zelle mit fixer Breite
1527 : : sal_uInt16 nBDist = static_cast< sal_uInt16 >(
1528 : : (2*nCellPadding <= nInnerFrmWidth) ? nCellPadding
1529 [ # # ]: 0 : : (nInnerFrmWidth / 2) );
1530 : : // wir setzen das Item nur, wenn es eine Umrandung gibt
1531 : : // oder eine sheet::Border-Distanz vorgegeben ist. Fehlt letztere,
1532 : : // dann gibt es eine Umrandung, und wir muessen die Distanz
1533 : : // setzen
1534 [ # # ]: 0 : aBoxItem.SetDistance( nBDist ? nBDist : MIN_BORDER_DIST );
1535 [ # # ]: 0 : pFrmFmt->SetFmtAttr( aBoxItem );
1536 : : }
1537 : : else
1538 [ # # ]: 0 : pFrmFmt->ResetFmtAttr( RES_BOX );
1539 : :
1540 [ # # ]: 0 : if( pBGBrushItem )
1541 : : {
1542 [ # # ]: 0 : pFrmFmt->SetFmtAttr( *pBGBrushItem );
1543 : : }
1544 : : else
1545 [ # # ]: 0 : pFrmFmt->ResetFmtAttr( RES_BACKGROUND );
1546 : :
1547 : : // Format nur setzten, wenn es auch einen Value gibt oder die Box leer ist.
1548 [ # # ][ # # ]: 0 : if( bHasNumFmt && (bHasValue || IsBoxEmpty(pBox)) )
[ # # ][ # # ]
[ # # ]
1549 : : {
1550 : : sal_Bool bLock = pFrmFmt->GetDoc()->GetNumberFormatter()
1551 [ # # ][ # # ]: 0 : ->IsTextFormat( nNumFmt );
1552 : 0 : SfxItemSet aItemSet( *pFrmFmt->GetAttrSet().GetPool(),
1553 [ # # ]: 0 : RES_BOXATR_FORMAT, RES_BOXATR_VALUE );
1554 : 0 : SvxAdjust eAdjust = SVX_ADJUST_END;
1555 : 0 : SwCntntNode *pCNd = 0;
1556 [ # # ]: 0 : if( !bLock )
1557 : : {
1558 : 0 : const SwStartNode *pSttNd = pBox->GetSttNd();
1559 : 0 : pCNd = pSttNd->GetNodes()[pSttNd->GetIndex()+1]
1560 [ # # ]: 0 : ->GetCntntNode();
1561 : : const SfxPoolItem *pItem;
1562 [ # # ][ # # ]: 0 : if( pCNd && pCNd->HasSwAttrSet() &&
[ # # ][ # # ]
[ # # ]
1563 [ # # ]: 0 : SFX_ITEM_SET==pCNd->GetpSwAttrSet()->GetItemState(
1564 [ # # ]: 0 : RES_PARATR_ADJUST, sal_False, &pItem ) )
1565 : : {
1566 : : eAdjust = ((const SvxAdjustItem *)pItem)
1567 : 0 : ->GetAdjust();
1568 : : }
1569 : : }
1570 [ # # ][ # # ]: 0 : aItemSet.Put( SwTblBoxNumFormat(nNumFmt) );
[ # # ]
1571 [ # # ]: 0 : if( bHasValue )
1572 [ # # ][ # # ]: 0 : aItemSet.Put( SwTblBoxValue(nValue) );
[ # # ]
1573 : :
1574 [ # # ]: 0 : if( bLock )
1575 : 0 : pFrmFmt->LockModify();
1576 [ # # ]: 0 : pFrmFmt->SetFmtAttr( aItemSet );
1577 [ # # ]: 0 : if( bLock )
1578 : 0 : pFrmFmt->UnlockModify();
1579 [ # # ][ # # ]: 0 : else if( pCNd && SVX_ADJUST_END != eAdjust )
1580 : : {
1581 [ # # ]: 0 : SvxAdjustItem aAdjItem( eAdjust, RES_PARATR_ADJUST );
1582 [ # # ][ # # ]: 0 : pCNd->SetAttr( aAdjItem );
1583 [ # # ]: 0 : }
1584 : : }
1585 : : else
1586 [ # # ]: 0 : pFrmFmt->ResetFmtAttr( RES_BOXATR_FORMAT );
1587 : :
1588 : : OSL_ENSURE( eVOri != text::VertOrientation::TOP, "text::VertOrientation::TOP ist nicht erlaubt!" );
1589 [ # # ]: 0 : if( text::VertOrientation::NONE != eVOri )
1590 : : {
1591 [ # # ][ # # ]: 0 : pFrmFmt->SetFmtAttr( SwFmtVertOrient( 0, eVOri ) );
[ # # ]
1592 : : }
1593 : : else
1594 [ # # ]: 0 : pFrmFmt->ResetFmtAttr( RES_VERT_ORIENT );
1595 : :
1596 [ # # ]: 0 : if( bReUsable )
1597 [ # # ]: 0 : pColumn->SetFrmFmt( pFrmFmt, bBottomLine, eVOri );
1598 : : }
1599 : : else
1600 : : {
1601 [ # # ]: 0 : pFrmFmt->ResetFmtAttr( RES_BOX );
1602 [ # # ]: 0 : pFrmFmt->ResetFmtAttr( RES_BACKGROUND );
1603 [ # # ]: 0 : pFrmFmt->ResetFmtAttr( RES_VERT_ORIENT );
1604 [ # # ]: 0 : pFrmFmt->ResetFmtAttr( RES_BOXATR_FORMAT );
1605 : : }
1606 : : }
1607 : : else
1608 : : {
1609 : : OSL_ENSURE( pBox->GetSttNd() ||
1610 : : SFX_ITEM_SET!=pFrmFmt->GetAttrSet().GetItemState(
1611 : : RES_VERT_ORIENT, sal_False ),
1612 : : "Box ohne Inhalt hat vertikale Ausrichtung" );
1613 [ # # ]: 0 : pBox->ChgFrmFmt( (SwTableBoxFmt*)pFrmFmt );
1614 [ # # ]: 0 : }
1615 : :
1616 : 0 : }
1617 : :
1618 : 0 : void HTMLTable::FixFillerFrameFmt( SwTableBox *pBox, sal_Bool bRight ) const
1619 : : {
1620 : 0 : SwFrmFmt *pFrmFmt = pBox->ClaimFrmFmt();
1621 : :
1622 [ # # ][ # # ]: 0 : if( bFillerTopBorder || bFillerBottomBorder ||
[ # # ][ # # ]
[ # # ][ # # ]
1623 : : (!bRight && bInhLeftBorder) || (bRight && bInhRightBorder) )
1624 : : {
1625 [ # # ]: 0 : SvxBoxItem aBoxItem( RES_BOX );
1626 [ # # ]: 0 : if( bFillerTopBorder )
1627 [ # # ]: 0 : aBoxItem.SetLine( &aTopBorderLine, BOX_LINE_TOP );
1628 [ # # ]: 0 : if( bFillerBottomBorder )
1629 [ # # ]: 0 : aBoxItem.SetLine( &aBottomBorderLine, BOX_LINE_BOTTOM );
1630 [ # # ][ # # ]: 0 : if( !bRight && bInhLeftBorder )
1631 [ # # ]: 0 : aBoxItem.SetLine( &aInhLeftBorderLine, BOX_LINE_LEFT );
1632 [ # # ][ # # ]: 0 : if( bRight && bInhRightBorder )
1633 [ # # ]: 0 : aBoxItem.SetLine( &aInhRightBorderLine, BOX_LINE_RIGHT );
1634 : 0 : aBoxItem.SetDistance( MIN_BORDER_DIST );
1635 [ # # ][ # # ]: 0 : pFrmFmt->SetFmtAttr( aBoxItem );
1636 : : }
1637 : : else
1638 : : {
1639 : 0 : pFrmFmt->ResetFmtAttr( RES_BOX );
1640 : : }
1641 : :
1642 [ # # ]: 0 : if( GetInhBGBrush() )
1643 : 0 : pFrmFmt->SetFmtAttr( *GetInhBGBrush() );
1644 : : else
1645 : 0 : pFrmFmt->ResetFmtAttr( RES_BACKGROUND );
1646 : :
1647 : 0 : pFrmFmt->ResetFmtAttr( RES_VERT_ORIENT );
1648 : 0 : pFrmFmt->ResetFmtAttr( RES_BOXATR_FORMAT );
1649 : 0 : }
1650 : :
1651 : 0 : SwTableBox *HTMLTable::NewTableBox( const SwStartNode *pStNd,
1652 : : SwTableLine *pUpper ) const
1653 : : {
1654 : : SwTableBox *pBox;
1655 : :
1656 [ # # # # ]: 0 : if( pTopTable->pBox1 &&
[ # # ]
1657 : 0 : pTopTable->pBox1->GetSttNd() == pStNd )
1658 : : {
1659 : : // wenn der StartNode dem StartNode der initial angelegten Box
1660 : : // entspricht nehmen wir diese Box
1661 : 0 : pBox = pTopTable->pBox1;
1662 : 0 : pBox->SetUpper( pUpper );
1663 : 0 : pTopTable->pBox1 = 0;
1664 : : }
1665 : : else
1666 [ # # ]: 0 : pBox = new SwTableBox( pBoxFmt, *pStNd, pUpper );
1667 : :
1668 : 0 : return pBox;
1669 : : }
1670 : :
1671 : :
1672 : 0 : static void ResetLineFrmFmtAttrs( SwFrmFmt *pFrmFmt )
1673 : : {
1674 : 0 : pFrmFmt->ResetFmtAttr( RES_FRM_SIZE );
1675 : 0 : pFrmFmt->ResetFmtAttr( RES_BACKGROUND );
1676 : : OSL_ENSURE( SFX_ITEM_SET!=pFrmFmt->GetAttrSet().GetItemState(
1677 : : RES_VERT_ORIENT, sal_False ),
1678 : : "Zeile hat vertikale Ausrichtung" );
1679 : 0 : }
1680 : :
1681 : : // !!! kann noch vereinfacht werden
1682 : 0 : SwTableLine *HTMLTable::MakeTableLine( SwTableBox *pUpper,
1683 : : sal_uInt16 nTopRow, sal_uInt16 nLeftCol,
1684 : : sal_uInt16 nBottomRow, sal_uInt16 nRightCol )
1685 : : {
1686 : : SwTableLine *pLine;
1687 [ # # ][ # # ]: 0 : if( this==pTopTable && !pUpper && 0==nTopRow )
[ # # ]
1688 : 0 : pLine = (pSwTable->GetTabLines())[0];
1689 : : else
1690 : : pLine = new SwTableLine( pLineFrmFmtNoHeight ? pLineFrmFmtNoHeight
1691 : : : pLineFmt,
1692 [ # # ][ # # ]: 0 : 0, pUpper );
1693 : :
1694 : 0 : HTMLTableRow *pTopRow = &(*pRows)[nTopRow];
1695 : 0 : sal_uInt16 nRowHeight = pTopRow->GetHeight();
1696 : 0 : const SvxBrushItem *pBGBrushItem = 0;
1697 [ # # ][ # # ]: 0 : if( this == pTopTable || nTopRow>0 || nBottomRow<nRows )
[ # # ]
1698 : : {
1699 : : // An der Line eine Frabe zu setzen macht keinen Sinn, wenn sie
1700 : : // die auesserste und gleichzeitig einzige Zeile einer Tabelle in
1701 : : // der Tabelle ist.
1702 : 0 : pBGBrushItem = pTopRow->GetBGBrush();
1703 : :
1704 [ # # ][ # # ]: 0 : if( !pBGBrushItem && this != pTopTable )
1705 : : {
1706 : : // Ein an einer Tabellen in der Tabelle gesetzter Hintergrund
1707 : : // wird an den Rows gesetzt. Das gilt auch fuer den Hintergrund
1708 : : // der Zelle, in dem die Tabelle vorkommt.
1709 : 0 : pBGBrushItem = GetBGBrush();
1710 [ # # ]: 0 : if( !pBGBrushItem )
1711 : 0 : pBGBrushItem = GetInhBGBrush();
1712 : : }
1713 : : }
1714 [ # # ][ # # ]: 0 : if( nTopRow==nBottomRow-1 && (nRowHeight || pBGBrushItem) )
[ # # ]
1715 : : {
1716 : 0 : SwTableLineFmt *pFrmFmt = (SwTableLineFmt*)pLine->ClaimFrmFmt();
1717 : 0 : ResetLineFrmFmtAttrs( pFrmFmt );
1718 : :
1719 [ # # ]: 0 : if( nRowHeight )
1720 : : {
1721 : : // Tabellenhoehe einstellen. Da es sich um eine
1722 : : // Mindesthoehe handelt, kann sie genauso wie in
1723 : : // Netscape berechnet werden, also ohne Beruecksichtigung
1724 : : // der tatsaechlichen Umrandungsbreite.
1725 : 0 : nRowHeight += GetTopCellSpace( nTopRow, 1, sal_False ) +
1726 : 0 : GetBottomCellSpace( nTopRow, 1, sal_False );
1727 : :
1728 [ # # ]: 0 : pFrmFmt->SetFmtAttr( SwFmtFrmSize( ATT_MIN_SIZE, 0, nRowHeight ) );
1729 : : }
1730 : :
1731 [ # # ]: 0 : if( pBGBrushItem )
1732 : : {
1733 : 0 : pFrmFmt->SetFmtAttr( *pBGBrushItem );
1734 : 0 : }
1735 : :
1736 : : }
1737 [ # # ]: 0 : else if( !pLineFrmFmtNoHeight )
1738 : : {
1739 : : // sonst muessen wir die Hoehe aus dem Attribut entfernen
1740 : : // und koennen uns das Format merken
1741 : 0 : pLineFrmFmtNoHeight = (SwTableLineFmt*)pLine->ClaimFrmFmt();
1742 : :
1743 : 0 : ResetLineFrmFmtAttrs( pLineFrmFmtNoHeight );
1744 : : }
1745 : :
1746 : :
1747 : 0 : SwTableBoxes& rBoxes = pLine->GetTabBoxes();
1748 : :
1749 : 0 : sal_uInt16 nStartCol = nLeftCol;
1750 [ # # ]: 0 : while( nStartCol<nRightCol )
1751 : : {
1752 : 0 : sal_uInt16 nCol = nStartCol;
1753 : 0 : sal_uInt16 nSplitCol = nRightCol;
1754 : 0 : sal_Bool bSplitted = sal_False;
1755 [ # # ]: 0 : while( !bSplitted )
1756 : : {
1757 : : OSL_ENSURE( nCol < nRightCol, "Zu weit gelaufen" );
1758 : :
1759 : 0 : HTMLTableCell *pCell = GetCell(nTopRow,nCol);
1760 : 0 : const sal_Bool bSplit = 1 == pCell->GetColSpan();
1761 : :
1762 : : OSL_ENSURE((nCol != nRightCol-1) || bSplit, "Split-Flag wrong");
1763 [ # # ]: 0 : if( bSplit )
1764 : : {
1765 : 0 : SwTableBox* pBox = 0;
1766 [ # # ]: 0 : HTMLTableCell *pCell2 = GetCell( nTopRow, nStartCol );
1767 [ # # ]: 0 : if( pCell2->GetColSpan() == (nCol+1-nStartCol) )
1768 : : {
1769 : : // Die HTML-Tabellen-Zellen bilden genau eine Box.
1770 : : // Dann muss hinter der Box gesplittet werden
1771 : 0 : nSplitCol = nCol + 1;
1772 : :
1773 : 0 : long nBoxRowSpan = pCell2->GetRowSpan();
1774 [ # # ][ # # ]: 0 : if ( !pCell2->GetContents() || pCell2->IsCovered() )
[ # # ]
1775 : : {
1776 [ # # ]: 0 : if ( pCell2->IsCovered() )
1777 : 0 : nBoxRowSpan = -1 * nBoxRowSpan;
1778 : :
1779 : : const SwStartNode* pPrevStartNd =
1780 [ # # ]: 0 : GetPrevBoxStartNode( nTopRow, nStartCol );
1781 : : HTMLTableCnts *pCnts = new HTMLTableCnts(
1782 [ # # ][ # # ]: 0 : pParser->InsertTableSection(pPrevStartNd) );
1783 : : SwHTMLTableLayoutCnts *pCntsLayoutInfo =
1784 [ # # ]: 0 : pCnts->CreateLayoutInfo();
1785 : :
1786 : 0 : pCell2->SetContents( pCnts );
1787 : 0 : SwHTMLTableLayoutCell *pCurrCell = pLayoutInfo->GetCell( nTopRow, nStartCol );
1788 : 0 : pCurrCell->SetContents( pCntsLayoutInfo );
1789 [ # # ]: 0 : if( nBoxRowSpan < 0 )
1790 : 0 : pCurrCell->SetRowSpan( 0 );
1791 : :
1792 : : // ggf. COLSPAN beachten
1793 [ # # ]: 0 : for( sal_uInt16 j=nStartCol+1; j<nSplitCol; j++ )
1794 : : {
1795 [ # # ]: 0 : GetCell(nTopRow,j)->SetContents( pCnts );
1796 : : pLayoutInfo->GetCell( nTopRow, j )
1797 : 0 : ->SetContents( pCntsLayoutInfo );
1798 : : }
1799 : : }
1800 : :
1801 : : pBox = MakeTableBox( pLine, pCell2->GetContents(),
1802 : : nTopRow, nStartCol,
1803 [ # # ]: 0 : nBottomRow, nSplitCol );
1804 : :
1805 [ # # ]: 0 : if ( 1 != nBoxRowSpan )
1806 [ # # ]: 0 : pBox->setRowSpan( nBoxRowSpan );
1807 : :
1808 : 0 : bSplitted = sal_True;
1809 : : }
1810 : :
1811 : : OSL_ENSURE( pBox, "Colspan trouble" );
1812 : :
1813 [ # # ]: 0 : if( pBox )
1814 [ # # ]: 0 : rBoxes.push_back( pBox );
1815 : : }
1816 : 0 : nCol++;
1817 : : }
1818 : 0 : nStartCol = nSplitCol;
1819 : : }
1820 : :
1821 : 0 : return pLine;
1822 : : }
1823 : :
1824 : 0 : SwTableBox *HTMLTable::MakeTableBox( SwTableLine *pUpper,
1825 : : HTMLTableCnts *pCnts,
1826 : : sal_uInt16 nTopRow, sal_uInt16 nLeftCol,
1827 : : sal_uInt16 nBottomRow, sal_uInt16 nRightCol )
1828 : : {
1829 : : SwTableBox *pBox;
1830 : 0 : sal_uInt16 nColSpan = nRightCol - nLeftCol;
1831 : 0 : sal_uInt16 nRowSpan = nBottomRow - nTopRow;
1832 : :
1833 [ # # ]: 0 : if( !pCnts->Next() )
1834 : : {
1835 : : // nur eine Inhalts-Section
1836 [ # # ]: 0 : if( pCnts->GetStartNode() )
1837 : : {
1838 : : // und die ist keine Tabelle
1839 : 0 : pBox = NewTableBox( pCnts->GetStartNode(), pUpper );
1840 : 0 : pCnts->SetTableBox( pBox );
1841 : : }
1842 : : else
1843 : : {
1844 : : pCnts->GetTable()->InheritVertBorders( this, nLeftCol,
1845 [ # # ]: 0 : nRightCol-nLeftCol );
1846 : : // und die ist eine Tabelle: dann bauen wir eine neue
1847 : : // Box und fuegen die Zeilen der Tabelle in die Zeilen
1848 : : // der Box ein
1849 [ # # ][ # # ]: 0 : pBox = new SwTableBox( pBoxFmt, 0, pUpper );
1850 : : sal_uInt16 nAbs, nRel;
1851 [ # # ]: 0 : pLayoutInfo->GetAvail( nLeftCol, nColSpan, nAbs, nRel );
1852 [ # # ]: 0 : sal_uInt16 nLSpace = pLayoutInfo->GetLeftCellSpace( nLeftCol, nColSpan );
1853 [ # # ]: 0 : sal_uInt16 nRSpace = pLayoutInfo->GetRightCellSpace( nLeftCol, nColSpan );
1854 [ # # ]: 0 : sal_uInt16 nInhSpace = pLayoutInfo->GetInhCellSpace( nLeftCol, nColSpan );
1855 : : pCnts->GetTable()->MakeTable( pBox, nAbs, nRel, nLSpace, nRSpace,
1856 [ # # ]: 0 : nInhSpace );
1857 : : }
1858 : : }
1859 : : else
1860 : : {
1861 : : // mehrere Inhalts Sections: dann brauchen wir eine Box mit Zeilen
1862 [ # # ]: 0 : pBox = new SwTableBox( pBoxFmt, 0, pUpper );
1863 : 0 : SwTableLines& rLines = pBox->GetTabLines();
1864 : 0 : sal_Bool bFirstPara = sal_True;
1865 : :
1866 [ # # ]: 0 : while( pCnts )
1867 : : {
1868 [ # # ]: 0 : if( pCnts->GetStartNode() )
1869 : : {
1870 : : // normale Absaetze werden zu einer Box in einer Zeile
1871 : : SwTableLine *pLine =
1872 : : new SwTableLine( pLineFrmFmtNoHeight ? pLineFrmFmtNoHeight
1873 [ # # ][ # # ]: 0 : : pLineFmt, 0, pBox );
[ # # ]
1874 [ # # ]: 0 : if( !pLineFrmFmtNoHeight )
1875 : : {
1876 : : // Wenn es noch kein Line-Format ohne Hoehe gibt, koennen
1877 : : // wir uns dieses her als soleches merken
1878 [ # # ]: 0 : pLineFrmFmtNoHeight = (SwTableLineFmt*)pLine->ClaimFrmFmt();
1879 : :
1880 [ # # ]: 0 : ResetLineFrmFmtAttrs( pLineFrmFmtNoHeight );
1881 : : }
1882 : :
1883 : : SwTableBox* pCntBox = NewTableBox( pCnts->GetStartNode(),
1884 [ # # ]: 0 : pLine );
1885 : 0 : pCnts->SetTableBox( pCntBox );
1886 : : FixFrameFmt( pCntBox, nTopRow, nLeftCol, nRowSpan, nColSpan,
1887 [ # # ]: 0 : bFirstPara, 0==pCnts->Next() );
1888 [ # # ]: 0 : pLine->GetTabBoxes().push_back( pCntBox );
1889 : :
1890 [ # # ]: 0 : rLines.push_back( pLine );
1891 : : }
1892 : : else
1893 : : {
1894 : : pCnts->GetTable()->InheritVertBorders( this, nLeftCol,
1895 [ # # ]: 0 : nRightCol-nLeftCol );
1896 : : // Tabellen werden direkt eingetragen
1897 : : sal_uInt16 nAbs, nRel;
1898 [ # # ]: 0 : pLayoutInfo->GetAvail( nLeftCol, nColSpan, nAbs, nRel );
1899 : : sal_uInt16 nLSpace = pLayoutInfo->GetLeftCellSpace( nLeftCol,
1900 [ # # ]: 0 : nColSpan );
1901 : : sal_uInt16 nRSpace = pLayoutInfo->GetRightCellSpace( nLeftCol,
1902 [ # # ]: 0 : nColSpan );
1903 [ # # ]: 0 : sal_uInt16 nInhSpace = pLayoutInfo->GetInhCellSpace( nLeftCol, nColSpan );
1904 : : pCnts->GetTable()->MakeTable( pBox, nAbs, nRel, nLSpace,
1905 [ # # ]: 0 : nRSpace, nInhSpace );
1906 : : }
1907 : :
1908 : 0 : pCnts = pCnts->Next();
1909 : 0 : bFirstPara = sal_False;
1910 : : }
1911 : : }
1912 : :
1913 : 0 : FixFrameFmt( pBox, nTopRow, nLeftCol, nRowSpan, nColSpan );
1914 : :
1915 : 0 : return pBox;
1916 : : }
1917 : :
1918 : 0 : void HTMLTable::InheritBorders( const HTMLTable *pParent,
1919 : : sal_uInt16 nRow, sal_uInt16 nCol,
1920 : : sal_uInt16 nRowSpan, sal_uInt16 /*nColSpan*/,
1921 : : sal_Bool bFirstPara, sal_Bool bLastPara )
1922 : : {
1923 : : OSL_ENSURE( nRows>0 && nCols>0 && nCurRow==nRows,
1924 : : "Wurde CloseTable nicht aufgerufen?" );
1925 : :
1926 : : // Die Child-Tabelle muss einen Rahmen bekommen, wenn die umgebende
1927 : : // Zelle einen Rand an der betreffenden Seite besitzt.
1928 : : // Der obere bzw. untere Rand wird nur gesetzt, wenn die Tabelle
1929 : : // ale erster bzw. letzter Absatz in der Zelle vorkommt. Ansonsten
1930 : : // Fuer den linken/rechten Rand kann noch nicht entschieden werden,
1931 : : // ob eine Umrandung der Tabelle noetig/moeglich ist, weil das davon
1932 : : // abhaengt, ob "Filler"-Zellen eingefuegt werden. Hier werden deshalb
1933 : : // erstmal nur Informationen gesammelt
1934 : : //
1935 [ # # ][ # # ]: 0 : if( 0==nRow && pParent->bTopBorder && bFirstPara )
[ # # ]
1936 : : {
1937 : 0 : bTopBorder = sal_True;
1938 : 0 : bFillerTopBorder = sal_True; // auch Filler bekommt eine Umrandung
1939 : 0 : aTopBorderLine = pParent->aTopBorderLine;
1940 : : }
1941 [ # # ][ # # ]: 0 : if( (*pParent->pRows)[nRow+nRowSpan-1].bBottomBorder && bLastPara )
[ # # ]
1942 : : {
1943 : 0 : (*pRows)[nRows-1].bBottomBorder = sal_True;
1944 : 0 : bFillerBottomBorder = sal_True; // auch Filler bekommt eine Umrandung
1945 : : aBottomBorderLine =
1946 : : nRow+nRowSpan==pParent->nRows ? pParent->aBottomBorderLine
1947 [ # # ]: 0 : : pParent->aBorderLine;
1948 : : }
1949 : :
1950 : :
1951 : : // Die Child Tabelle darf keinen oberen oder linken Rahmen bekommen,
1952 : : // wenn der bereits durch die umgebende Tabelle gesetzt ist.
1953 : : // Sie darf jedoch immer einen oberen Rand bekommen, wenn die Tabelle
1954 : : // nicht der erste Absatz in der Zelle ist.
1955 : : bTopAlwd = ( !bFirstPara || (pParent->bTopAlwd &&
1956 [ # # ][ # # ]: 0 : (0==nRow || !((*pParent->pRows)[nRow-1]).bBottomBorder)) );
[ # # ][ # # ]
1957 : :
1958 : : // die Child-Tabelle muss die Farbe der Zelle erben, in der sie
1959 : : // vorkommt, wenn sie keine eigene besitzt
1960 : 0 : const SvxBrushItem *pInhBG = pParent->GetCell(nRow,nCol)->GetBGBrush();
1961 [ # # # # ]: 0 : if( !pInhBG && pParent != pTopTable &&
[ # # ][ # # ]
1962 : 0 : pParent->GetCell(nRow,nCol)->GetRowSpan() == pParent->nRows )
1963 : : {
1964 : : // die ganze umgebende Tabelle ist eine Tabelle in der Tabelle
1965 : : // und besteht nur aus einer Line, die bei der GC (zu Recht)
1966 : : // wegoptimiert wird. Deshalb muss der Hintergrund der Line in
1967 : : // diese Tabelle uebernommen werden.
1968 : 0 : pInhBG = (*pParent->pRows)[nRow].GetBGBrush();
1969 [ # # ]: 0 : if( !pInhBG )
1970 : 0 : pInhBG = pParent->GetBGBrush();
1971 [ # # ]: 0 : if( !pInhBG )
1972 : 0 : pInhBG = pParent->GetInhBGBrush();
1973 : : }
1974 [ # # ]: 0 : if( pInhBG )
1975 [ # # ]: 0 : pInhBGBrush = new SvxBrushItem( *pInhBG );
1976 : 0 : }
1977 : :
1978 : 0 : void HTMLTable::InheritVertBorders( const HTMLTable *pParent,
1979 : : sal_uInt16 nCol, sal_uInt16 nColSpan )
1980 : : {
1981 : 0 : sal_uInt16 nInhLeftBorderWidth = 0;
1982 : 0 : sal_uInt16 nInhRightBorderWidth = 0;
1983 : :
1984 [ # # ][ # # ]: 0 : if( nCol+nColSpan==pParent->nCols && pParent->bRightBorder )
1985 : : {
1986 : 0 : bInhRightBorder = sal_True; // erstmal nur merken
1987 : 0 : aInhRightBorderLine = pParent->aRightBorderLine;
1988 : : nInhRightBorderWidth =
1989 : 0 : GetBorderWidth( aInhRightBorderLine, sal_True ) + MIN_BORDER_DIST;
1990 : : }
1991 : :
1992 [ # # ]: 0 : if( ((*pParent->pColumns)[nCol]).bLeftBorder )
1993 : : {
1994 : 0 : bInhLeftBorder = sal_True; // erstmal nur merken
1995 : : aInhLeftBorderLine = 0==nCol ? pParent->aLeftBorderLine
1996 [ # # ]: 0 : : pParent->aBorderLine;
1997 : : nInhLeftBorderWidth =
1998 : 0 : GetBorderWidth( aInhLeftBorderLine, sal_True ) + MIN_BORDER_DIST;
1999 : : }
2000 : :
2001 [ # # ][ # # ]: 0 : if( !bInhLeftBorder && (bFillerTopBorder || bFillerBottomBorder) )
[ # # ]
2002 : 0 : nInhLeftBorderWidth = 2 * MIN_BORDER_DIST;
2003 [ # # ][ # # ]: 0 : if( !bInhRightBorder && (bFillerTopBorder || bFillerBottomBorder) )
[ # # ]
2004 : 0 : nInhRightBorderWidth = 2 * MIN_BORDER_DIST;
2005 : : pLayoutInfo->SetInhBorderWidths( nInhLeftBorderWidth,
2006 : 0 : nInhRightBorderWidth );
2007 : :
2008 : : bRightAlwd = ( pParent->bRightAlwd &&
2009 : : (nCol+nColSpan==pParent->nCols ||
2010 [ # # ][ # # ]: 0 : !((*pParent->pColumns)[nCol+nColSpan]).bLeftBorder) );
[ # # ]
2011 : 0 : }
2012 : :
2013 : 0 : void HTMLTable::SetBorders()
2014 : : {
2015 : : sal_uInt16 i;
2016 [ # # ]: 0 : for( i=1; i<nCols; i++ )
2017 [ # # ][ # # ]: 0 : if( HTML_TR_ALL==eRules || HTML_TR_COLS==eRules ||
[ # # ]
[ # # # # ]
[ # # ]
2018 : : ((HTML_TR_ROWS==eRules || HTML_TR_GROUPS==eRules) &&
2019 : 0 : ((*pColumns)[i-1]).IsEndOfGroup()) )
2020 : 0 : ((*pColumns)[i]).bLeftBorder = sal_True;
2021 : :
2022 [ # # ]: 0 : for( i=0; i<nRows-1; i++ )
2023 [ # # ][ # # ]: 0 : if( HTML_TR_ALL==eRules || HTML_TR_ROWS==eRules ||
[ # # ]
[ # # # # ]
[ # # ]
2024 : : ((HTML_TR_COLS==eRules || HTML_TR_GROUPS==eRules) &&
2025 : 0 : (*pRows)[i].IsEndOfGroup()) )
2026 : 0 : (*pRows)[i].bBottomBorder = sal_True;
2027 : :
2028 [ # # ][ # # ]: 0 : if( bTopAlwd && (HTML_TF_ABOVE==eFrame || HTML_TF_HSIDES==eFrame ||
[ # # ][ # # ]
2029 : : HTML_TF_BOX==eFrame) )
2030 : 0 : bTopBorder = sal_True;
2031 [ # # ][ # # ]: 0 : if( HTML_TF_BELOW==eFrame || HTML_TF_HSIDES==eFrame ||
[ # # ]
2032 : : HTML_TF_BOX==eFrame )
2033 : 0 : (*pRows)[nRows-1].bBottomBorder = sal_True;
2034 [ # # ][ # # ]: 0 : if( (HTML_TF_RHS==eFrame || HTML_TF_VSIDES==eFrame ||
[ # # ]
2035 : : HTML_TF_BOX==eFrame) )
2036 : 0 : bRightBorder = sal_True;
2037 [ # # ][ # # ]: 0 : if( HTML_TF_LHS==eFrame || HTML_TF_VSIDES==eFrame || HTML_TF_BOX==eFrame )
[ # # ]
2038 : 0 : ((*pColumns)[0]).bLeftBorder = sal_True;
2039 : :
2040 [ # # ]: 0 : for( i=0; i<nRows; i++ )
2041 : : {
2042 : 0 : HTMLTableRow *pRow = &(*pRows)[i];
2043 [ # # ]: 0 : for( sal_uInt16 j=0; j<nCols; j++ )
2044 : : {
2045 : 0 : HTMLTableCell *pCell = pRow->GetCell(j);
2046 [ # # ]: 0 : if( pCell->GetContents() )
2047 : : {
2048 : 0 : HTMLTableCnts *pCnts = pCell->GetContents();
2049 : 0 : sal_Bool bFirstPara = sal_True;
2050 [ # # ]: 0 : while( pCnts )
2051 : : {
2052 : 0 : HTMLTable *pTable = pCnts->GetTable();
2053 [ # # ][ # # ]: 0 : if( pTable && !pTable->BordersSet() )
[ # # ]
2054 : : {
2055 : : pTable->InheritBorders( this, i, j,
2056 : 0 : pCell->GetRowSpan(),
2057 : 0 : pCell->GetColSpan(),
2058 : : bFirstPara,
2059 : 0 : 0==pCnts->Next() );
2060 : 0 : pTable->SetBorders();
2061 : : }
2062 : 0 : bFirstPara = sal_False;
2063 : 0 : pCnts = pCnts->Next();
2064 : : }
2065 : : }
2066 : : }
2067 : : }
2068 : :
2069 : 0 : bBordersSet = sal_True;
2070 : 0 : }
2071 : :
2072 : 0 : sal_uInt16 HTMLTable::GetBorderWidth( const SvxBorderLine& rBLine,
2073 : : sal_Bool bWithDistance ) const
2074 : : {
2075 : 0 : sal_uInt16 nBorderWidth = rBLine.GetWidth();
2076 [ # # ]: 0 : if( bWithDistance )
2077 : : {
2078 [ # # ]: 0 : if( nCellPadding )
2079 : 0 : nBorderWidth = nBorderWidth + nCellPadding;
2080 [ # # ]: 0 : else if( nBorderWidth )
2081 : 0 : nBorderWidth = nBorderWidth + MIN_BORDER_DIST;
2082 : : }
2083 : :
2084 : 0 : return nBorderWidth;
2085 : : }
2086 : :
2087 : 0 : inline HTMLTableCell *HTMLTable::GetCell( sal_uInt16 nRow,
2088 : : sal_uInt16 nCell ) const
2089 : : {
2090 : : OSL_ENSURE(nRow < pRows->size(), "invalid row index in HTML table");
2091 : 0 : return (*pRows)[nRow].GetCell( nCell );
2092 : : }
2093 : :
2094 : :
2095 : 0 : SvxAdjust HTMLTable::GetInheritedAdjust() const
2096 : : {
2097 : 0 : SvxAdjust eAdjust = (nCurCol<nCols ? ((*pColumns)[nCurCol]).GetAdjust()
2098 [ # # ]: 0 : : SVX_ADJUST_END );
2099 [ # # ]: 0 : if( SVX_ADJUST_END==eAdjust )
2100 : 0 : eAdjust = (*pRows)[nCurRow].GetAdjust();
2101 : :
2102 : 0 : return eAdjust;
2103 : : }
2104 : :
2105 : 0 : sal_Int16 HTMLTable::GetInheritedVertOri() const
2106 : : {
2107 : : // text::VertOrientation::TOP ist der default!
2108 : 0 : sal_Int16 eVOri = (*pRows)[nCurRow].GetVertOri();
2109 [ # # ][ # # ]: 0 : if( text::VertOrientation::TOP==eVOri && nCurCol<nCols )
2110 : 0 : eVOri = ((*pColumns)[nCurCol]).GetVertOri();
2111 [ # # ]: 0 : if( text::VertOrientation::TOP==eVOri )
2112 : 0 : eVOri = eVertOri;
2113 : :
2114 : : OSL_ENSURE( eVertOri != text::VertOrientation::TOP, "text::VertOrientation::TOP ist nicht erlaubt!" );
2115 : 0 : return eVOri;
2116 : : }
2117 : :
2118 : 0 : void HTMLTable::InsertCell( HTMLTableCnts *pCnts,
2119 : : sal_uInt16 nRowSpan, sal_uInt16 nColSpan,
2120 : : sal_uInt16 nCellWidth, sal_Bool bRelWidth, sal_uInt16 nCellHeight,
2121 : : sal_Int16 eVertOrient, SvxBrushItem *pBGBrushItem,
2122 : : boost::shared_ptr<SvxBoxItem> const pBoxItem,
2123 : : sal_Bool bHasNumFmt, sal_uInt32 nNumFmt,
2124 : : sal_Bool bHasValue, double nValue, sal_Bool bNoWrap )
2125 : : {
2126 [ # # ][ # # ]: 0 : if( !nRowSpan || (sal_uInt32)nCurRow + nRowSpan > USHRT_MAX )
2127 : 0 : nRowSpan = 1;
2128 : :
2129 [ # # ][ # # ]: 0 : if( !nColSpan || (sal_uInt32)nCurCol + nColSpan > USHRT_MAX )
2130 : 0 : nColSpan = 1;
2131 : :
2132 : 0 : sal_uInt16 nColsReq = nCurCol + nColSpan; // benoetigte Spalten
2133 : 0 : sal_uInt16 nRowsReq = nCurRow + nRowSpan; // benoetigte Zeilen
2134 : : sal_uInt16 i, j;
2135 : :
2136 : : // falls wir mehr Spalten benoetigen als wir zur Zeit haben,
2137 : : // muessen wir in allen Zeilen noch Zellen hinzufuegen
2138 [ # # ]: 0 : if( nCols < nColsReq )
2139 : : {
2140 [ # # ]: 0 : for( i=nCols; i<nColsReq; i++ )
2141 [ # # ][ # # ]: 0 : pColumns->push_back( new HTMLTableColumn );
2142 [ # # ]: 0 : for( i=0; i<nRows; i++ )
2143 [ # # ][ # # ]: 0 : (*pRows)[i].Expand( nColsReq, i<nCurRow );
2144 : 0 : nCols = nColsReq;
2145 : : OSL_ENSURE(pColumns->size() == nCols,
2146 : : "wrong number of columns after expanding");
2147 : : }
2148 [ # # ]: 0 : if( nColsReq > nFilledCols )
2149 : 0 : nFilledCols = nColsReq;
2150 : :
2151 : : // falls wir mehr Zeilen benoetigen als wir zur Zeit haben,
2152 : : // muessen wir noch neue Zeilen hinzufuegen
2153 [ # # ]: 0 : if( nRows < nRowsReq )
2154 : : {
2155 [ # # ]: 0 : for( i=nRows; i<nRowsReq; i++ )
2156 [ # # ][ # # ]: 0 : pRows->push_back( new HTMLTableRow(nCols) );
[ # # ]
2157 : 0 : nRows = nRowsReq;
2158 : : OSL_ENSURE(nRows == pRows->size(), "wrong number of rows in Insert");
2159 : : }
2160 : :
2161 : : // Testen, ob eine Ueberschneidung vorliegt und diese
2162 : : // gegebenfalls beseitigen
2163 : 0 : sal_uInt16 nSpanedCols = 0;
2164 [ # # ]: 0 : if( nCurRow>0 )
2165 : : {
2166 [ # # ]: 0 : HTMLTableRow *pCurRow = &(*pRows)[nCurRow];
2167 [ # # ]: 0 : for( i=nCurCol; i<nColsReq; i++ )
2168 : : {
2169 [ # # ]: 0 : HTMLTableCell *pCell = pCurRow->GetCell(i);
2170 [ # # ]: 0 : if( pCell->GetContents() )
2171 : : {
2172 : : // Der Inhalt reicht von einer weiter oben stehenden Zelle
2173 : : // hier herein. Inhalt und Farbe der Zelle sind deshalb in
2174 : : // jedem Fall noch dort verankert und koennen deshalb
2175 : : // ueberschrieben werden bzw. von ProtectRowSpan geloescht
2176 : : // (Inhalt) oder kopiert (Farbe) werden.
2177 : 0 : nSpanedCols = i + pCell->GetColSpan();
2178 [ # # ]: 0 : FixRowSpan( nCurRow-1, i, pCell->GetContents() );
2179 [ # # ]: 0 : if( pCell->GetRowSpan() > nRowSpan )
2180 : : ProtectRowSpan( nRowsReq, i,
2181 [ # # ]: 0 : pCell->GetRowSpan()-nRowSpan );
2182 : : }
2183 : : }
2184 [ # # ]: 0 : for( i=nColsReq; i<nSpanedCols; i++ )
2185 : : {
2186 : : // Auch diese Inhalte sind in jedem Fall nich in der Zeile
2187 : : // darueber verankert.
2188 [ # # ]: 0 : HTMLTableCell *pCell = pCurRow->GetCell(i);
2189 [ # # ]: 0 : FixRowSpan( nCurRow-1, i, pCell->GetContents() );
2190 [ # # ]: 0 : ProtectRowSpan( nCurRow, i, pCell->GetRowSpan() );
2191 : : }
2192 : : }
2193 : :
2194 : : // Fill the cells
2195 [ # # ]: 0 : for( i=nColSpan; i>0; i-- )
2196 : : {
2197 [ # # ]: 0 : for( j=nRowSpan; j>0; j-- )
2198 : : {
2199 [ # # ][ # # ]: 0 : const bool bCovered = i != nColSpan || j != nRowSpan;
2200 : : GetCell( nRowsReq-j, nColsReq-i )
2201 : : ->Set( pCnts, j, i, eVertOrient, pBGBrushItem, pBoxItem,
2202 [ # # ][ # # ]: 0 : bHasNumFmt, nNumFmt, bHasValue, nValue, bNoWrap, bCovered );
[ # # ][ # # ]
2203 : : }
2204 : : }
2205 : :
2206 [ # # ]: 0 : Size aTwipSz( bRelWidth ? 0 : nCellWidth, nCellHeight );
2207 [ # # ][ # # ]: 0 : if( (aTwipSz.Width() || aTwipSz.Height()) && Application::GetDefaultDevice() )
[ # # ][ # # ]
[ # # ]
2208 : : {
2209 : : aTwipSz = Application::GetDefaultDevice()
2210 [ # # ][ # # ]: 0 : ->PixelToLogic( aTwipSz, MapMode( MAP_TWIP ) );
[ # # ][ # # ]
2211 : : }
2212 : :
2213 : : // die Breite nur in die erste Zelle setzen!
2214 [ # # ]: 0 : if( nCellWidth )
2215 : : {
2216 [ # # ]: 0 : sal_uInt16 nTmp = bRelWidth ? nCellWidth : (sal_uInt16)aTwipSz.Width();
2217 [ # # ]: 0 : GetCell( nCurRow, nCurCol )->SetWidth( nTmp, bRelWidth );
2218 : : }
2219 : :
2220 : : // Ausserdem noch die Hoehe merken
2221 [ # # ][ # # ]: 0 : if( nCellHeight && 1==nRowSpan )
2222 : : {
2223 [ # # ]: 0 : if( nCellHeight < MINLAY )
2224 : 0 : nCellHeight = MINLAY;
2225 [ # # ]: 0 : (*pRows)[nCurRow].SetHeight( (sal_uInt16)aTwipSz.Height() );
2226 : : }
2227 : :
2228 : : // den Spaltenzaehler hinter die neuen Zellen setzen
2229 : 0 : nCurCol = nColsReq;
2230 [ # # ]: 0 : if( nSpanedCols > nCurCol )
2231 : 0 : nCurCol = nSpanedCols;
2232 : :
2233 : : // und die naechste freie Zelle suchen
2234 [ # # ][ # # ]: 0 : while( nCurCol<nCols && GetCell(nCurRow,nCurCol)->IsUsed() )
[ # # ][ # # ]
2235 : 0 : nCurCol++;
2236 : 0 : }
2237 : :
2238 : 0 : inline void HTMLTable::CloseSection( sal_Bool bHead )
2239 : : {
2240 : : // die vorhergende Section beenden, falls es schon eine Zeile gibt
2241 : : OSL_ENSURE( nCurRow<=nRows, "ungeultige aktuelle Zeile" );
2242 [ # # ][ # # ]: 0 : if( nCurRow>0 && nCurRow<=nRows )
2243 : 0 : (*pRows)[nCurRow-1].SetEndOfGroup();
2244 [ # # ]: 0 : if( bHead )
2245 : 0 : nHeadlineRepeat = nCurRow;
2246 : 0 : }
2247 : :
2248 : 0 : void HTMLTable::OpenRow( SvxAdjust eAdjust, sal_Int16 eVertOrient,
2249 : : SvxBrushItem *pBGBrushItem )
2250 : : {
2251 : 0 : sal_uInt16 nRowsReq = nCurRow+1; // Anzahl benoetigter Zeilen;
2252 : :
2253 : : // die naechste Zeile anlegen, falls sie nicht schon da ist
2254 [ # # ]: 0 : if( nRows<nRowsReq )
2255 : : {
2256 [ # # ]: 0 : for( sal_uInt16 i=nRows; i<nRowsReq; i++ )
2257 [ # # ]: 0 : pRows->push_back( new HTMLTableRow(nCols) );
2258 : 0 : nRows = nRowsReq;
2259 : : OSL_ENSURE( nRows==pRows->size(),
2260 : : "Zeilenzahl in OpenRow stimmt nicht" );
2261 : : }
2262 : :
2263 : 0 : HTMLTableRow *pCurRow = &((*pRows)[nCurRow]);
2264 : 0 : pCurRow->SetAdjust( eAdjust );
2265 : 0 : pCurRow->SetVertOri( eVertOrient );
2266 [ # # ]: 0 : if( pBGBrushItem )
2267 : 0 : (*pRows)[nCurRow].SetBGBrush( pBGBrushItem );
2268 : :
2269 : : // den Spaltenzaehler wieder an den Anfang setzen
2270 : 0 : nCurCol=0;
2271 : :
2272 : : // und die naechste freie Zelle suchen
2273 [ # # ][ # # ]: 0 : while( nCurCol<nCols && GetCell(nCurRow,nCurCol)->IsUsed() )
[ # # ]
2274 : 0 : nCurCol++;
2275 : 0 : }
2276 : :
2277 : 0 : void HTMLTable::CloseRow( sal_Bool bEmpty )
2278 : : {
2279 : : OSL_ENSURE( nCurRow<nRows, "aktulle Zeile hinter dem Tabellenende" );
2280 : :
2281 : : // leere Zellen bekommen einfach einen etwas dickeren unteren Rand!
2282 [ # # ]: 0 : if( bEmpty )
2283 : : {
2284 [ # # ]: 0 : if( nCurRow > 0 )
2285 : 0 : (*pRows)[nCurRow-1].IncEmptyRows();
2286 : 0 : return;
2287 : : }
2288 : :
2289 : 0 : HTMLTableRow *pRow = &(*pRows)[nCurRow];
2290 : :
2291 : : // den COLSPAN aller leeren Zellen am Zeilenende so anpassen, dass
2292 : : // eine Zelle daraus wird. Das kann man hier machen (und auf keinen
2293 : : // Fall frueher), weill jetzt keine Zellen mehr in die Zeile eingefuegt
2294 : : // werden.
2295 : 0 : sal_uInt16 i=nCols;
2296 [ # # ]: 0 : while( i )
2297 : : {
2298 : 0 : HTMLTableCell *pCell = pRow->GetCell(--i);
2299 [ # # ]: 0 : if( !pCell->GetContents() )
2300 : : {
2301 : 0 : sal_uInt16 nColSpan = nCols-i;
2302 [ # # ]: 0 : if( nColSpan > 1 )
2303 : 0 : pCell->SetColSpan( nColSpan );
2304 : : }
2305 : : else
2306 : 0 : break;
2307 : : }
2308 : :
2309 : :
2310 : 0 : nCurRow++;
2311 : : }
2312 : :
2313 : 0 : inline void HTMLTable::CloseColGroup( sal_uInt16 nSpan, sal_uInt16 _nWidth,
2314 : : sal_Bool bRelWidth, SvxAdjust eAdjust,
2315 : : sal_Int16 eVertOrient )
2316 : : {
2317 [ # # ]: 0 : if( nSpan )
2318 : 0 : InsertCol( nSpan, _nWidth, bRelWidth, eAdjust, eVertOrient );
2319 : :
2320 : : OSL_ENSURE( nCurCol<=nCols, "ungueltige Spalte" );
2321 [ # # ][ # # ]: 0 : if( nCurCol>0 && nCurCol<=nCols )
2322 : 0 : ((*pColumns)[nCurCol-1]).SetEndOfGroup();
2323 : 0 : }
2324 : :
2325 : 0 : void HTMLTable::InsertCol( sal_uInt16 nSpan, sal_uInt16 nColWidth, sal_Bool bRelWidth,
2326 : : SvxAdjust eAdjust, sal_Int16 eVertOrient )
2327 : : {
2328 : : // #i35143# - no columns, if rows already exist.
2329 [ # # ]: 0 : if ( nRows > 0 )
2330 : 0 : return;
2331 : :
2332 : : sal_uInt16 i;
2333 : :
2334 [ # # ]: 0 : if( !nSpan )
2335 : 0 : nSpan = 1;
2336 : :
2337 : 0 : sal_uInt16 nColsReq = nCurCol + nSpan; // benoetigte Spalten
2338 : :
2339 [ # # ]: 0 : if( nCols < nColsReq )
2340 : : {
2341 [ # # ]: 0 : for( i=nCols; i<nColsReq; i++ )
2342 [ # # ][ # # ]: 0 : pColumns->push_back( new HTMLTableColumn );
2343 : 0 : nCols = nColsReq;
2344 : : }
2345 : :
2346 [ # # ]: 0 : Size aTwipSz( bRelWidth ? 0 : nColWidth, 0 );
2347 [ # # ][ # # ]: 0 : if( aTwipSz.Width() && Application::GetDefaultDevice() )
[ # # ][ # # ]
2348 : : {
2349 : : aTwipSz = Application::GetDefaultDevice()
2350 [ # # ][ # # ]: 0 : ->PixelToLogic( aTwipSz, MapMode( MAP_TWIP ) );
[ # # ][ # # ]
2351 : : }
2352 : :
2353 [ # # ]: 0 : for( i=nCurCol; i<nColsReq; i++ )
2354 : : {
2355 [ # # ]: 0 : HTMLTableColumn *pCol = &(*pColumns)[i];
2356 [ # # ]: 0 : sal_uInt16 nTmp = bRelWidth ? nColWidth : (sal_uInt16)aTwipSz.Width();
2357 : 0 : pCol->SetWidth( nTmp, bRelWidth );
2358 : 0 : pCol->SetAdjust( eAdjust );
2359 : 0 : pCol->SetVertOri( eVertOrient );
2360 : : }
2361 : :
2362 : 0 : bColSpec = sal_True;
2363 : :
2364 : 0 : nCurCol = nColsReq;
2365 : : }
2366 : :
2367 : :
2368 : 0 : void HTMLTable::CloseTable()
2369 : : {
2370 : : sal_uInt16 i;
2371 : :
2372 : : // Die Anzahl der Tabellenzeilen richtet sich nur nach den
2373 : : // <TR>-Elementen (d.h. nach nCurRow). Durch ROWSPAN aufgespannte
2374 : : // Zeilen hinter Zeile nCurRow muessen wir deshalb loeschen
2375 : : // und vor allem aber den ROWSPAN in den darueberliegenden Zeilen
2376 : : // anpassen.
2377 [ # # ]: 0 : if( nRows>nCurRow )
2378 : : {
2379 : 0 : HTMLTableRow *pPrevRow = &(*pRows)[nCurRow-1];
2380 : : HTMLTableCell *pCell;
2381 [ # # ]: 0 : for( i=0; i<nCols; i++ )
2382 [ # # ]: 0 : if( ( (pCell=(pPrevRow->GetCell(i))), (pCell->GetRowSpan()) > 1 ) )
2383 : : {
2384 : 0 : FixRowSpan( nCurRow-1, i, pCell->GetContents() );
2385 : 0 : ProtectRowSpan( nCurRow, i, (*pRows)[nCurRow].GetCell(i)->GetRowSpan() );
2386 : : }
2387 [ # # ]: 0 : for( i=nRows-1; i>=nCurRow; i-- )
2388 : 0 : pRows->erase(pRows->begin() + i);
2389 : 0 : nRows = nCurRow;
2390 : : }
2391 : :
2392 : : // falls die Tabelle keine Spalte hat, muessen wir eine hinzufuegen
2393 [ # # ]: 0 : if( 0==nCols )
2394 : : {
2395 : 0 : pColumns->push_back( new HTMLTableColumn );
2396 [ # # ]: 0 : for( i=0; i<nRows; i++ )
2397 : 0 : (*pRows)[i].Expand(1);
2398 : 0 : nCols = 1;
2399 : 0 : nFilledCols = 1;
2400 : : }
2401 : :
2402 : : // falls die Tabelle keine Zeile hat, muessen wir eine hinzufuegen
2403 [ # # ]: 0 : if( 0==nRows )
2404 : : {
2405 [ # # ]: 0 : pRows->push_back( new HTMLTableRow(nCols) );
2406 : 0 : nRows = 1;
2407 : 0 : nCurRow = 1;
2408 : : }
2409 : :
2410 [ # # ]: 0 : if( nFilledCols < nCols )
2411 : : {
2412 : 0 : pColumns->erase( pColumns->begin() + nFilledCols, pColumns->begin() + nCols );
2413 [ # # ]: 0 : for( i=0; i<nRows; i++ )
2414 : 0 : (*pRows)[i].Shrink( nFilledCols );
2415 : 0 : nCols = nFilledCols;
2416 : : }
2417 : 0 : }
2418 : :
2419 : 0 : void HTMLTable::_MakeTable( SwTableBox *pBox )
2420 : : {
2421 : : SwTableLines& rLines = (pBox ? pBox->GetTabLines()
2422 [ # # ]: 0 : : ((SwTable *)pSwTable)->GetTabLines() );
2423 : :
2424 : : // jetzt geht's richtig los ...
2425 : :
2426 [ # # ]: 0 : for( sal_uInt16 i=0; i<nRows; i++ )
2427 : : {
2428 [ # # ]: 0 : SwTableLine *pLine = MakeTableLine( pBox, i, 0, i+1, nCols );
2429 [ # # ][ # # ]: 0 : if( pBox || i > 0 )
2430 [ # # ]: 0 : rLines.push_back( pLine );
2431 : : }
2432 : 0 : }
2433 : :
2434 : : /* Wie werden Tabellen ausgerichtet?
2435 : :
2436 : : erste Zeile: ohne Absatz-Einzuege
2437 : : zweite Zeile: mit Absatz-Einzuegen
2438 : :
2439 : : ALIGN= LEFT RIGHT CENTER -
2440 : : -------------------------------------------------------------------------
2441 : : xxx bei Tabellen mit WIDTH=nn% ist die Prozent-Angabe von Bedeutung:
2442 : : xxx nn = 100 text::HoriOrientation::FULL text::HoriOrientation::FULL text::HoriOrientation::FULL text::HoriOrientation::FULL %
2443 : : xxx text::HoriOrientation::NONE text::HoriOrientation::NONE text::HoriOrientation::NONE % text::HoriOrientation::NONE %
2444 : : xxx nn < 100 Rahmen F Rahmen F text::HoriOrientation::CENTER % text::HoriOrientation::LEFT %
2445 : : xxx Rahmen F Rahmen F text::HoriOrientation::CENTER % text::HoriOrientation::NONE %
2446 : :
2447 : : bei Tabellen mit WIDTH=nn% ist die Prozent-Angabe von Bedeutung:
2448 : : nn = 100 text::HoriOrientation::LEFT text::HoriOrientation::RIGHT text::HoriOrientation::CENTER % text::HoriOrientation::LEFT %
2449 : : text::HoriOrientation::LEFT_AND text::HoriOrientation::RIGHT text::HoriOrientation::CENTER % text::HoriOrientation::LEFT_AND %
2450 : : nn < 100 Rahmen F Rahmen F text::HoriOrientation::CENTER % text::HoriOrientation::LEFT %
2451 : : Rahmen F Rahmen F text::HoriOrientation::CENTER % text::HoriOrientation::NONE %
2452 : :
2453 : : sonst die berechnete Breite w
2454 : : w = avail* text::HoriOrientation::LEFT text::HoriOrientation::RIGHT text::HoriOrientation::CENTER text::HoriOrientation::LEFT
2455 : : HORI_LEDT_AND text::HoriOrientation::RIGHT text::HoriOrientation::CENTER text::HoriOrientation::LEFT_AND
2456 : : w < avail Rahmen L Rahmen L text::HoriOrientation::CENTER text::HoriOrientation::LEFT
2457 : : Rahmen L Rahmen L text::HoriOrientation::CENTER text::HoriOrientation::NONE
2458 : :
2459 : : xxx *) wenn fuer die Tabelle keine Groesse angegeben wurde, wird immer
2460 : : xxx text::HoriOrientation::FULL genommen
2461 : :
2462 : : */
2463 : :
2464 : 0 : void HTMLTable::MakeTable( SwTableBox *pBox, sal_uInt16 nAbsAvail,
2465 : : sal_uInt16 nRelAvail, sal_uInt16 nAbsLeftSpace,
2466 : : sal_uInt16 nAbsRightSpace, sal_uInt16 nInhAbsSpace )
2467 : : {
2468 : : OSL_ENSURE( nRows>0 && nCols>0 && nCurRow==nRows,
2469 : : "Wurde CloseTable nicht aufgerufen?" );
2470 : :
2471 : : OSL_ENSURE( (pLayoutInfo==0) == (this==pTopTable),
2472 : : "Top-Tabelle hat keine Layout-Info oder umgekehrt" );
2473 : :
2474 [ # # ]: 0 : if( this==pTopTable )
2475 : : {
2476 : : // Umrandung der Tabelle und aller in ihr enthaltenen berechnen
2477 : 0 : SetBorders();
2478 : :
2479 : : // Schritt 1: Die benoetigten Layout-Strukturen werden angelegt
2480 : : // (inklusive Tabellen in Tabellen).
2481 : 0 : CreateLayoutInfo();
2482 : :
2483 : : // Schritt 2: Die minimalen und maximalen Spaltenbreiten werden
2484 : : // berechnet (inklusive Tabellen in Tabellen). Da wir noch keine
2485 : : // Boxen haben, arabeiten wir noch auf den Start-Nodes.
2486 : 0 : pLayoutInfo->AutoLayoutPass1();
2487 : : }
2488 : :
2489 : : // Schritt 3: Die tatsaechlichen Spaltenbreiten dieser Tabelle werden
2490 : : // berechnet (nicht von Tabellen in Tabellen). Dies muss jetzt schon
2491 : : // sein, damit wir entscheiden koennen ob Filler-Zellen benoetigt werden
2492 : : // oder nicht (deshalb war auch Pass1 schon noetig).
2493 : : pLayoutInfo->AutoLayoutPass2( nAbsAvail, nRelAvail, nAbsLeftSpace,
2494 : 0 : nAbsRightSpace, nInhAbsSpace );
2495 : :
2496 [ # # ]: 0 : if( this!=pTopTable )
2497 : : {
2498 : : // die linke und rechte Umrandung der Tabelle kann jetzt entgueltig
2499 : : // festgelegt werden
2500 [ # # ]: 0 : if( pLayoutInfo->GetRelRightFill() == 0 )
2501 : : {
2502 [ # # ]: 0 : if( !bRightBorder )
2503 : : {
2504 : : // linke Umrandung von auesserer Tabelle uebernehmen
2505 [ # # ]: 0 : if( bInhRightBorder )
2506 : : {
2507 : 0 : bRightBorder = sal_True;
2508 : 0 : aRightBorderLine = aInhRightBorderLine;
2509 : : }
2510 : : }
2511 : : else
2512 : : {
2513 : : // Umrandung nur setzen, wenn es erlaubt ist
2514 : 0 : bRightBorder = bRightAlwd;
2515 : : }
2516 : : }
2517 : :
2518 [ # # # # ]: 0 : if( pLayoutInfo->GetRelLeftFill() == 0 &&
[ # # ][ # # ]
2519 : 0 : !((*pColumns)[0]).bLeftBorder &&
2520 : : bInhLeftBorder )
2521 : : {
2522 : : // ggf. rechte Umrandung von auesserer Tabelle uebernehmen
2523 : 0 : ((*pColumns)[0]).bLeftBorder = sal_True;
2524 : 0 : aLeftBorderLine = aInhLeftBorderLine;
2525 : : }
2526 : : }
2527 : :
2528 : : // Fuer die Top-Table muss die Ausrichtung gesetzt werden
2529 [ # # ]: 0 : if( this==pTopTable )
2530 : : {
2531 : : sal_Int16 eHoriOri;
2532 [ # # ]: 0 : if( bForceFrame )
2533 : : {
2534 : : // Die Tabelle soll in einen Rahmen und ist auch schmaler
2535 : : // als der verfuegbare Platz und nicht 100% breit.
2536 : : // Dann kommt sie in einen Rahmen
2537 [ # # ]: 0 : eHoriOri = bPrcWidth ? text::HoriOrientation::FULL : text::HoriOrientation::LEFT;
2538 : : }
2539 [ # # # ]: 0 : else switch( eTableAdjust )
2540 : : {
2541 : : // Die Tabelle passt entweder auf die Seite, soll aber in keinen
2542 : : // Rahmen oder sie ist Breiter als die Seite und soll deshalb
2543 : : // in keinen Rahmen
2544 : :
2545 : : case SVX_ADJUST_RIGHT:
2546 : : // in rechtsbuendigen Tabellen kann nicht auf den rechten
2547 : : // Rand Ruecksicht genommen werden
2548 : 0 : eHoriOri = text::HoriOrientation::RIGHT;
2549 : 0 : break;
2550 : : case SVX_ADJUST_CENTER:
2551 : : // zentrierte Tabellen nehmen keine Ruecksicht auf Raender!
2552 : 0 : eHoriOri = text::HoriOrientation::CENTER;
2553 : 0 : break;
2554 : : case SVX_ADJUST_LEFT:
2555 : : default:
2556 : : // linksbuendige Tabellen nehmen nur auf den linken Rand
2557 : : // Ruecksicht
2558 [ # # ]: 0 : eHoriOri = nLeftMargin ? text::HoriOrientation::LEFT_AND_WIDTH : text::HoriOrientation::LEFT;
2559 : 0 : break;
2560 : : }
2561 : :
2562 : : // das Tabellenform holen und anpassen
2563 : 0 : SwFrmFmt *pFrmFmt = pSwTable->GetFrmFmt();
2564 [ # # ]: 0 : pFrmFmt->SetFmtAttr( SwFmtHoriOrient(0,eHoriOri) );
2565 [ # # ]: 0 : if( text::HoriOrientation::LEFT_AND_WIDTH==eHoriOri )
2566 : : {
2567 : : OSL_ENSURE( nLeftMargin || nRightMargin,
2568 : : "Da gibt's wohl noch Reste von relativen Breiten" );
2569 : :
2570 : : // The right margin will be ignored anyway.
2571 [ # # ][ # # ]: 0 : SvxLRSpaceItem aLRItem( pSwTable->GetFrmFmt()->GetLRSpace() );
2572 : 0 : aLRItem.SetLeft( nLeftMargin );
2573 : 0 : aLRItem.SetRight( nRightMargin );
2574 [ # # ][ # # ]: 0 : pFrmFmt->SetFmtAttr( aLRItem );
2575 : : }
2576 : :
2577 [ # # ][ # # ]: 0 : if( bPrcWidth && text::HoriOrientation::FULL!=eHoriOri )
2578 : : {
2579 : 0 : pFrmFmt->LockModify();
2580 [ # # ][ # # ]: 0 : SwFmtFrmSize aFrmSize( pFrmFmt->GetFrmSize() );
2581 : 0 : aFrmSize.SetWidthPercent( (sal_uInt8)nWidth );
2582 [ # # ]: 0 : pFrmFmt->SetFmtAttr( aFrmSize );
2583 [ # # ]: 0 : pFrmFmt->UnlockModify();
2584 : : }
2585 : : }
2586 : :
2587 : : // die Default Line- und Box-Formate holen
2588 [ # # ]: 0 : if( this==pTopTable )
2589 : : {
2590 : : // die erste Box merken und aus der ersten Zeile ausketten
2591 : 0 : SwTableLine *pLine1 = (pSwTable->GetTabLines())[0];
2592 : 0 : pBox1 = (pLine1->GetTabBoxes())[0];
2593 : 0 : pLine1->GetTabBoxes().erase(pLine1->GetTabBoxes().begin());
2594 : :
2595 : 0 : pLineFmt = (SwTableLineFmt*)pLine1->GetFrmFmt();
2596 : 0 : pBoxFmt = (SwTableBoxFmt*)pBox1->GetFrmFmt();
2597 : : }
2598 : : else
2599 : : {
2600 : 0 : pLineFmt = (SwTableLineFmt*)pTopTable->pLineFmt;
2601 : 0 : pBoxFmt = (SwTableBoxFmt*)pTopTable->pBoxFmt;
2602 : : }
2603 : :
2604 : : // ggf. muessen fuer Tabellen in Tabellen "Filler"-Zellen eingefuegt
2605 : : // werden
2606 [ # # # # : 0 : if( this != pTopTable &&
# # ][ # # ]
2607 : 0 : ( pLayoutInfo->GetRelLeftFill() > 0 ||
2608 : 0 : pLayoutInfo->GetRelRightFill() > 0 ) )
2609 : : {
2610 : : OSL_ENSURE( pBox, "kein TableBox fuer Tabelle in Tabelle" );
2611 : :
2612 : 0 : SwTableLines& rLines = pBox->GetTabLines();
2613 : :
2614 : : // dazu brauchen wir erstmal ein eine neue Table-Line in der Box
2615 : : SwTableLine *pLine =
2616 : : new SwTableLine( pLineFrmFmtNoHeight ? pLineFrmFmtNoHeight
2617 [ # # ][ # # ]: 0 : : pLineFmt, 0, pBox );
[ # # ]
2618 [ # # ]: 0 : rLines.push_back( pLine );
2619 : :
2620 : : // Sicherstellen, dass wie ein Format ohne Hoehe erwischt haben
2621 [ # # ]: 0 : if( !pLineFrmFmtNoHeight )
2622 : : {
2623 : : // sonst muessen wir die Hoehe aus dem Attribut entfernen
2624 : : // und koennen uns das Format merken
2625 [ # # ]: 0 : pLineFrmFmtNoHeight = (SwTableLineFmt*)pLine->ClaimFrmFmt();
2626 : :
2627 [ # # ]: 0 : ResetLineFrmFmtAttrs( pLineFrmFmtNoHeight );
2628 : : }
2629 : :
2630 : 0 : SwTableBoxes& rBoxes = pLine->GetTabBoxes();
2631 : : SwTableBox *pNewBox;
2632 : :
2633 : : // ggf. links eine Zelle einfuegen
2634 [ # # ]: 0 : if( pLayoutInfo->GetRelLeftFill() > 0 )
2635 : : {
2636 : : // pPrevStNd ist der Vorgaenger-Start-Node der Tabelle. Den
2637 : : // "Filler"-Node fuegen wir einfach dahinter ein ...
2638 [ # # ]: 0 : pPrevStNd = pParser->InsertTableSection( pPrevStNd );
2639 : :
2640 [ # # ]: 0 : pNewBox = NewTableBox( pPrevStNd, pLine );
2641 [ # # ]: 0 : rBoxes.push_back( pNewBox );
2642 [ # # ]: 0 : FixFillerFrameFmt( pNewBox, sal_False );
2643 : 0 : pLayoutInfo->SetLeftFillerBox( pNewBox );
2644 : : }
2645 : :
2646 : : // jetzt die Tabelle bearbeiten
2647 [ # # ][ # # ]: 0 : pNewBox = new SwTableBox( pBoxFmt, 0, pLine );
2648 [ # # ]: 0 : rBoxes.push_back( pNewBox );
2649 : :
2650 [ # # ]: 0 : SwFrmFmt *pFrmFmt = pNewBox->ClaimFrmFmt();
2651 [ # # ]: 0 : pFrmFmt->ResetFmtAttr( RES_BOX );
2652 [ # # ]: 0 : pFrmFmt->ResetFmtAttr( RES_BACKGROUND );
2653 [ # # ]: 0 : pFrmFmt->ResetFmtAttr( RES_VERT_ORIENT );
2654 [ # # ]: 0 : pFrmFmt->ResetFmtAttr( RES_BOXATR_FORMAT );
2655 : :
2656 : :
2657 [ # # ]: 0 : _MakeTable( pNewBox );
2658 : :
2659 : : // und noch ggf. rechts eine Zelle einfuegen
2660 [ # # ]: 0 : if( pLayoutInfo->GetRelRightFill() > 0 )
2661 : : {
2662 : : const SwStartNode *pStNd =
2663 [ # # ]: 0 : GetPrevBoxStartNode( USHRT_MAX, USHRT_MAX );
2664 [ # # ]: 0 : pStNd = pParser->InsertTableSection( pStNd );
2665 : :
2666 [ # # ]: 0 : pNewBox = NewTableBox( pStNd, pLine );
2667 [ # # ]: 0 : rBoxes.push_back( pNewBox );
2668 : :
2669 [ # # ]: 0 : FixFillerFrameFmt( pNewBox, sal_True );
2670 : 0 : pLayoutInfo->SetRightFillerBox( pNewBox );
2671 : : }
2672 : : }
2673 : : else
2674 : : {
2675 : 0 : _MakeTable( pBox );
2676 : : }
2677 : :
2678 : : // zum Schluss fuehren wir noch eine Garbage-Collection fuer die
2679 : : // Top-Level-Tabelle durch
2680 [ # # ]: 0 : if( this==pTopTable )
2681 : : {
2682 [ # # ][ # # ]: 0 : if( 1==nRows && nHeight && 1==pSwTable->GetTabLines().size() )
[ # # ][ # # ]
2683 : : {
2684 : : // Hoehe einer einzeiligen Tabelle als Mindesthoehe der
2685 : : // Zeile setzen. (War mal fixe Hoehe, aber das gibt manchmal
2686 : : // Probleme (fix #34972#) und ist auch nicht Netscape 4.0
2687 : : // konform
2688 : 0 : nHeight = pParser->ToTwips( nHeight );
2689 [ # # ]: 0 : if( nHeight < MINLAY )
2690 : 0 : nHeight = MINLAY;
2691 : :
2692 : 0 : (pSwTable->GetTabLines())[0]->ClaimFrmFmt();
2693 : 0 : (pSwTable->GetTabLines())[0]->GetFrmFmt()
2694 [ # # ]: 0 : ->SetFmtAttr( SwFmtFrmSize( ATT_MIN_SIZE, 0, nHeight ) );
2695 : : }
2696 : :
2697 [ # # ]: 0 : if( GetBGBrush() )
2698 : 0 : pSwTable->GetFrmFmt()->SetFmtAttr( *GetBGBrush() );
2699 : :
2700 : 0 : ((SwTable *)pSwTable)->SetRowsToRepeat( static_cast< sal_uInt16 >(nHeadlineRepeat) );
2701 : 0 : ((SwTable *)pSwTable)->GCLines();
2702 : :
2703 [ # # ][ # # ]: 0 : sal_Bool bIsInFlyFrame = pContext && pContext->GetFrmFmt();
2704 [ # # ][ # # ]: 0 : if( bIsInFlyFrame && !nWidth )
2705 : : {
2706 : 0 : SvxAdjust eTblAdjust = GetTableAdjust(sal_False);
2707 [ # # ][ # # ]: 0 : if( eTblAdjust != SVX_ADJUST_LEFT &&
2708 : : eTblAdjust != SVX_ADJUST_RIGHT )
2709 : : {
2710 : : // Wenn eine Tabelle ohne Breitenangabe nicht links oder
2711 : : // rechts umflossen werden soll, dann stacken wir sie
2712 : : // in einem Rahmen mit 100%-Breite, damit ihre Groesse
2713 : : // angepasst wird. Der Rahmen darf nicht angepasst werden.
2714 : : OSL_ENSURE( HasToFly(), "Warum ist die Tabelle in einem Rahmen?" );
2715 : 0 : sal_uInt32 nMin = pLayoutInfo->GetMin();
2716 [ # # ]: 0 : if( nMin > USHRT_MAX )
2717 : 0 : nMin = USHRT_MAX;
2718 [ # # ]: 0 : SwFmtFrmSize aFlyFrmSize( ATT_VAR_SIZE, (SwTwips)nMin, MINLAY );
2719 : 0 : aFlyFrmSize.SetWidthPercent( 100 );
2720 [ # # ]: 0 : pContext->GetFrmFmt()->SetFmtAttr( aFlyFrmSize );
2721 [ # # ]: 0 : bIsInFlyFrame = sal_False;
2722 : : }
2723 : : else
2724 : : {
2725 : : // Links und rechts ausgerichtete Tabellen ohne Breite
2726 : : // duerfen leider nicht in der Breite angepasst werden, denn
2727 : : // sie wuerden nur schrumpfen aber nie wachsen.
2728 : 0 : pLayoutInfo->SetMustNotRecalc( sal_True );
2729 [ # # ]: 0 : if( pContext->GetFrmFmt()->GetAnchor().GetCntntAnchor()
2730 : 0 : ->nNode.GetNode().FindTableNode() )
2731 : : {
2732 : 0 : sal_uInt32 nMax = pLayoutInfo->GetMax();
2733 [ # # ]: 0 : if( nMax > USHRT_MAX )
2734 : 0 : nMax = USHRT_MAX;
2735 [ # # ]: 0 : SwFmtFrmSize aFlyFrmSize( ATT_VAR_SIZE, (SwTwips)nMax, MINLAY );
2736 [ # # ]: 0 : pContext->GetFrmFmt()->SetFmtAttr( aFlyFrmSize );
2737 [ # # ]: 0 : bIsInFlyFrame = sal_False;
2738 : : }
2739 : : else
2740 : : {
2741 : 0 : pLayoutInfo->SetMustNotResize( sal_True );
2742 : : }
2743 : : }
2744 : : }
2745 : 0 : pLayoutInfo->SetMayBeInFlyFrame( bIsInFlyFrame );
2746 : :
2747 : : // Nur Tabellen mit relativer Breite oder ohne Breite muessen
2748 : : // angepasst werden.
2749 [ # # ][ # # ]: 0 : pLayoutInfo->SetMustResize( bPrcWidth || !nWidth );
2750 : :
2751 : 0 : pLayoutInfo->SetWidths();
2752 : :
2753 : 0 : ((SwTable *)pSwTable)->SetHTMLTableLayout( pLayoutInfo );
2754 : :
2755 [ # # ]: 0 : if( pResizeDrawObjs )
2756 : : {
2757 : 0 : sal_uInt16 nCount = pResizeDrawObjs->size();
2758 [ # # ]: 0 : for( sal_uInt16 i=0; i<nCount; i++ )
2759 : : {
2760 : 0 : SdrObject *pObj = (*pResizeDrawObjs)[i];
2761 [ # # ]: 0 : sal_uInt16 nRow = (*pDrawObjPrcWidths)[3*i];
2762 [ # # ]: 0 : sal_uInt16 nCol = (*pDrawObjPrcWidths)[3*i+1];
2763 [ # # ]: 0 : sal_uInt8 nPrcWidth = (sal_uInt8)(*pDrawObjPrcWidths)[3*i+2];
2764 : :
2765 : : SwHTMLTableLayoutCell *pLayoutCell =
2766 : 0 : pLayoutInfo->GetCell( nRow, nCol );
2767 : 0 : sal_uInt16 nColSpan = pLayoutCell->GetColSpan();
2768 : :
2769 : : sal_uInt16 nWidth2, nDummy;
2770 [ # # ]: 0 : pLayoutInfo->GetAvail( nCol, nColSpan, nWidth2, nDummy );
2771 [ # # ]: 0 : nWidth2 = nWidth2 - pLayoutInfo->GetLeftCellSpace( nCol, nColSpan );
2772 [ # # ]: 0 : nWidth2 = nWidth2 - pLayoutInfo->GetRightCellSpace( nCol, nColSpan );
2773 : 0 : nWidth2 = static_cast< sal_uInt16 >(((long)nWidth * nPrcWidth) / 100);
2774 : :
2775 [ # # ]: 0 : pParser->ResizeDrawObject( pObj, nWidth2 );
2776 : : }
2777 : : }
2778 : : }
2779 : 0 : }
2780 : :
2781 : 0 : void HTMLTable::SetTable( const SwStartNode *pStNd, _HTMLTableContext *pCntxt,
2782 : : sal_uInt16 nLeft, sal_uInt16 nRight,
2783 : : const SwTable *pSwTab, sal_Bool bFrcFrame )
2784 : : {
2785 : 0 : pPrevStNd = pStNd;
2786 : 0 : pSwTable = pSwTab;
2787 : 0 : pContext = pCntxt;
2788 : :
2789 : 0 : nLeftMargin = nLeft;
2790 : 0 : nRightMargin = nRight;
2791 : :
2792 : 0 : bForceFrame = bFrcFrame;
2793 : 0 : }
2794 : :
2795 : 0 : void HTMLTable::RegisterDrawObject( SdrObject *pObj, sal_uInt8 nPrcWidth )
2796 : : {
2797 [ # # ]: 0 : if( !pResizeDrawObjs )
2798 [ # # ]: 0 : pResizeDrawObjs = new SdrObjects;
2799 : 0 : pResizeDrawObjs->push_back( pObj );
2800 : :
2801 [ # # ]: 0 : if( !pDrawObjPrcWidths )
2802 [ # # ]: 0 : pDrawObjPrcWidths = new std::vector<sal_uInt16>;
2803 : 0 : pDrawObjPrcWidths->push_back( nCurRow );
2804 : 0 : pDrawObjPrcWidths->push_back( nCurCol );
2805 [ # # ]: 0 : pDrawObjPrcWidths->push_back( (sal_uInt16)nPrcWidth );
2806 : 0 : }
2807 : :
2808 : 0 : void HTMLTable::MakeParentContents()
2809 : : {
2810 [ # # ][ # # ]: 0 : if( !GetContext() && !HasParentSection() )
[ # # ]
2811 : : {
2812 : : SetParentContents(
2813 : 0 : pParser->InsertTableContents( GetIsParentHeader() ) );
2814 : :
2815 : 0 : SetHasParentSection( sal_True );
2816 : : }
2817 : 0 : }
2818 : :
2819 : 0 : _HTMLTableContext::~_HTMLTableContext()
2820 : : {
2821 [ # # ]: 0 : delete pPos;
2822 : 0 : }
2823 : :
2824 : 0 : void _HTMLTableContext::SavePREListingXMP( SwHTMLParser& rParser )
2825 : : {
2826 : 0 : bRestartPRE = rParser.IsReadPRE();
2827 : 0 : bRestartXMP = rParser.IsReadXMP();
2828 : 0 : bRestartListing = rParser.IsReadListing();
2829 : 0 : rParser.FinishPREListingXMP();
2830 : 0 : }
2831 : :
2832 : 0 : void _HTMLTableContext::RestorePREListingXMP( SwHTMLParser& rParser )
2833 : : {
2834 : 0 : rParser.FinishPREListingXMP();
2835 : :
2836 [ # # ]: 0 : if( bRestartPRE )
2837 : 0 : rParser.StartPRE();
2838 : :
2839 [ # # ]: 0 : if( bRestartXMP )
2840 : 0 : rParser.StartXMP();
2841 : :
2842 [ # # ]: 0 : if( bRestartListing )
2843 : 0 : rParser.StartListing();
2844 : 0 : }
2845 : :
2846 : :
2847 : 0 : const SwStartNode *SwHTMLParser::InsertTableSection
2848 : : ( const SwStartNode *pPrevStNd )
2849 : : {
2850 : : OSL_ENSURE( pPrevStNd, "Start-Node ist NULL" );
2851 : :
2852 [ # # ]: 0 : pCSS1Parser->SetTDTagStyles();
2853 [ # # ]: 0 : SwTxtFmtColl *pColl = pCSS1Parser->GetTxtCollFromPool( RES_POOLCOLL_TABLE );
2854 : :
2855 : : const SwStartNode *pStNd;
2856 [ # # ][ # # ]: 0 : if( pTable && pTable->bFirstCell )
2857 : : {
2858 : 0 : SwNode *const pNd = & pPam->GetPoint()->nNode.GetNode();
2859 [ # # ]: 0 : pNd->GetTxtNode()->ChgFmtColl( pColl );
2860 [ # # ]: 0 : pStNd = pNd->FindTableBoxStartNode();
2861 : 0 : pTable->bFirstCell = sal_False;
2862 : : }
2863 : : else
2864 : : {
2865 : : const SwNode* pNd;
2866 [ # # ]: 0 : if( pPrevStNd->IsTableNode() )
2867 : 0 : pNd = pPrevStNd;
2868 : : else
2869 : 0 : pNd = pPrevStNd->EndOfSectionNode();
2870 [ # # ]: 0 : SwNodeIndex nIdx( *pNd, 1 );
2871 [ # # ]: 0 : pStNd = pDoc->GetNodes().MakeTextSection( nIdx, SwTableBoxStartNode,
2872 [ # # ]: 0 : pColl );
2873 [ # # ]: 0 : pTable->IncBoxCount();
2874 : : }
2875 : :
2876 : : //Added defaults to CJK and CTL
2877 [ # # ][ # # ]: 0 : SwCntntNode *pCNd = pDoc->GetNodes()[pStNd->GetIndex()+1] ->GetCntntNode();
2878 [ # # ]: 0 : SvxFontHeightItem aFontHeight( 40, 100, RES_CHRATR_FONTSIZE );
2879 [ # # ]: 0 : pCNd->SetAttr( aFontHeight );
2880 [ # # ]: 0 : SvxFontHeightItem aFontHeightCJK( 40, 100, RES_CHRATR_CJK_FONTSIZE );
2881 [ # # ]: 0 : pCNd->SetAttr( aFontHeightCJK );
2882 [ # # ]: 0 : SvxFontHeightItem aFontHeightCTL( 40, 100, RES_CHRATR_CTL_FONTSIZE );
2883 [ # # ]: 0 : pCNd->SetAttr( aFontHeightCTL );
2884 : :
2885 [ # # ][ # # ]: 0 : return pStNd;
[ # # ]
2886 : : }
2887 : :
2888 : 0 : const SwStartNode *SwHTMLParser::InsertTableSection( sal_uInt16 nPoolId )
2889 : : {
2890 [ # # # ]: 0 : switch( nPoolId )
2891 : : {
2892 : : case RES_POOLCOLL_TABLE_HDLN:
2893 : 0 : pCSS1Parser->SetTHTagStyles();
2894 : 0 : break;
2895 : : case RES_POOLCOLL_TABLE:
2896 : 0 : pCSS1Parser->SetTDTagStyles();
2897 : 0 : break;
2898 : : }
2899 : :
2900 : 0 : SwTxtFmtColl *pColl = pCSS1Parser->GetTxtCollFromPool( nPoolId );
2901 : :
2902 : 0 : SwNode *const pNd = & pPam->GetPoint()->nNode.GetNode();
2903 : : const SwStartNode *pStNd;
2904 [ # # ][ # # ]: 0 : if( pTable && pTable->bFirstCell )
2905 : : {
2906 : 0 : pNd->GetTxtNode()->ChgFmtColl( pColl );
2907 : 0 : pTable->bFirstCell = sal_False;
2908 : 0 : pStNd = pNd->FindTableBoxStartNode();
2909 : : }
2910 : : else
2911 : : {
2912 [ # # ]: 0 : SwTableNode *pTblNd = pNd->FindTableNode();
2913 [ # # ]: 0 : if( pTblNd->GetTable().GetHTMLTableLayout() )
2914 : : { // if there is already a HTMTableLayout, this table is already finished
2915 : : // and we have to look for the right table in the environment
2916 : 0 : SwTableNode *pOutTbl = pTblNd;
2917 [ # # # # ]: 0 : do {
[ # # ]
2918 : 0 : pTblNd = pOutTbl;
2919 [ # # ]: 0 : pOutTbl = pOutTbl->StartOfSectionNode()->FindTableNode();
2920 : 0 : } while( pOutTbl && pTblNd->GetTable().GetHTMLTableLayout() );
2921 : : }
2922 [ # # ]: 0 : SwNodeIndex aIdx( *pTblNd->EndOfSectionNode() );
2923 [ # # ]: 0 : pStNd = pDoc->GetNodes().MakeTextSection( aIdx, SwTableBoxStartNode,
2924 [ # # ]: 0 : pColl );
2925 : :
2926 [ # # ]: 0 : pPam->GetPoint()->nNode = pStNd->GetIndex() + 1;
2927 : 0 : SwTxtNode *pTxtNd = pPam->GetPoint()->nNode.GetNode().GetTxtNode();
2928 [ # # ][ # # ]: 0 : pPam->GetPoint()->nContent.Assign( pTxtNd, 0 );
2929 [ # # ]: 0 : pTable->IncBoxCount();
2930 : : }
2931 : :
2932 : 0 : return pStNd;
2933 : : }
2934 : :
2935 : 0 : SwStartNode *SwHTMLParser::InsertTempTableCaptionSection()
2936 : : {
2937 : 0 : SwTxtFmtColl *pColl = pCSS1Parser->GetTxtCollFromPool( RES_POOLCOLL_TEXT );
2938 : 0 : SwNodeIndex& rIdx = pPam->GetPoint()->nNode;
2939 : 0 : rIdx = pDoc->GetNodes().GetEndOfExtras();
2940 : 0 : SwStartNode *pStNd = pDoc->GetNodes().MakeTextSection( rIdx,
2941 : 0 : SwNormalStartNode, pColl );
2942 : :
2943 : 0 : rIdx = pStNd->GetIndex() + 1;
2944 [ # # ]: 0 : pPam->GetPoint()->nContent.Assign( rIdx.GetNode().GetTxtNode(), 0 );
2945 : :
2946 : 0 : return pStNd;
2947 : : }
2948 : :
2949 : :
2950 : 4 : xub_StrLen SwHTMLParser::StripTrailingLF()
2951 : : {
2952 : 4 : xub_StrLen nStripped = 0;
2953 : :
2954 : 4 : xub_StrLen nLen = pPam->GetPoint()->nContent.GetIndex();
2955 [ + + ]: 4 : if( nLen )
2956 : : {
2957 : 2 : SwTxtNode* pTxtNd = pPam->GetPoint()->nNode.GetNode().GetTxtNode();
2958 : : // vorsicht, wenn Kommentare nicht uebrlesen werden!!!
2959 [ + - ]: 2 : if( pTxtNd )
2960 : : {
2961 : 2 : xub_StrLen nPos = nLen;
2962 : 2 : xub_StrLen nLFCount = 0;
2963 [ + + ][ + - ]: 6 : while( nPos && '\x0a' == (pTxtNd->GetTxt()).GetChar(--nPos) )
[ + + ]
2964 : 4 : nLFCount++;
2965 : :
2966 [ + - ]: 2 : if( nLFCount )
2967 : : {
2968 [ - + ]: 2 : if( nLFCount > 2 )
2969 : : {
2970 : : // Bei Netscape entspricht ein Absatz-Ende zwei LFs
2971 : : // (mit einem kommt man in die naechste Zeile, das
2972 : : // zweite erzeugt eine Leerzeile) Diesen Abstand
2973 : : // erreichen wie aber schon mit dem unteren
2974 : : // Absatz-Abstand. Wenn nach den <BR> ein neuer
2975 : : // Absatz aufgemacht wird, wird das Maximum des Abstands,
2976 : : // der sich aus den BR und dem P ergibt genommen.
2977 : : // Deshalb muessen wir 2 bzw. alle bei weniger
2978 : : // als zweien loeschen
2979 : 0 : nLFCount = 2;
2980 : : }
2981 : :
2982 : 2 : nPos = nLen - nLFCount;
2983 [ + - ][ + - ]: 2 : SwIndex nIdx( pTxtNd, nPos );
2984 [ + - ]: 2 : pTxtNd->EraseText( nIdx, nLFCount );
2985 [ + - ]: 2 : nStripped = nLFCount;
2986 : : }
2987 : : }
2988 : : }
2989 : :
2990 : 4 : return nStripped;
2991 : : }
2992 : :
2993 : 0 : SvxBrushItem* SwHTMLParser::CreateBrushItem( const Color *pColor,
2994 : : const String& rImageURL,
2995 : : const String& rStyle,
2996 : : const String& rId,
2997 : : const String& rClass )
2998 : : {
2999 : 0 : SvxBrushItem *pBrushItem = 0;
3000 : :
3001 [ # # ][ # # ]: 0 : if( rStyle.Len() || rId.Len() || rClass.Len() )
[ # # ][ # # ]
3002 : : {
3003 : 0 : SfxItemSet aItemSet( pDoc->GetAttrPool(), RES_BACKGROUND,
3004 [ # # ]: 0 : RES_BACKGROUND );
3005 [ # # ]: 0 : SvxCSS1PropertyInfo aPropInfo;
3006 : :
3007 [ # # ]: 0 : if( rClass.Len() )
3008 : : {
3009 [ # # ]: 0 : String aClass( rClass );
3010 [ # # ]: 0 : SwCSS1Parser::GetScriptFromClass( aClass );
3011 [ # # ]: 0 : const SvxCSS1MapEntry *pClass = pCSS1Parser->GetClass( aClass );
3012 [ # # ]: 0 : if( pClass )
3013 [ # # ][ # # ]: 0 : aItemSet.Put( pClass->GetItemSet() );
3014 : : }
3015 : :
3016 [ # # ]: 0 : if( rId.Len() )
3017 : : {
3018 [ # # ]: 0 : const SvxCSS1MapEntry *pId = pCSS1Parser->GetId( rId );
3019 [ # # ]: 0 : if( pId )
3020 [ # # ]: 0 : aItemSet.Put( pId->GetItemSet() );
3021 : : }
3022 : :
3023 [ # # ]: 0 : pCSS1Parser->ParseStyleOption( rStyle, aItemSet, aPropInfo );
3024 : 0 : const SfxPoolItem *pItem = 0;
3025 [ # # ]: 0 : if( SFX_ITEM_SET == aItemSet.GetItemState( RES_BACKGROUND, sal_False,
3026 [ # # ]: 0 : &pItem ) )
3027 : : {
3028 [ # # ][ # # ]: 0 : pBrushItem = new SvxBrushItem( *((const SvxBrushItem *)pItem) );
3029 [ # # ][ # # ]: 0 : }
3030 : : }
3031 : :
3032 [ # # ][ # # ]: 0 : if( !pBrushItem && (pColor || rImageURL.Len()) )
[ # # ][ # # ]
3033 : : {
3034 [ # # ]: 0 : pBrushItem = new SvxBrushItem(RES_BACKGROUND);
3035 : :
3036 [ # # ]: 0 : if( pColor )
3037 : 0 : pBrushItem->SetColor(*pColor);
3038 : :
3039 [ # # ]: 0 : if( rImageURL.Len() )
3040 : : {
3041 [ # # ][ # # ]: 0 : pBrushItem->SetGraphicLink( URIHelper::SmartRel2Abs( INetURLObject(sBaseURL), rImageURL, Link(), false) );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
3042 : 0 : pBrushItem->SetGraphicPos( GPOS_TILED );
3043 : : }
3044 : : }
3045 : :
3046 : 0 : return pBrushItem;
3047 : : }
3048 : :
3049 : :
3050 : : class _SectionSaveStruct : public SwPendingStackData
3051 : : {
3052 : : sal_uInt16 nBaseFontStMinSave, nFontStMinSave, nFontStHeadStartSave;
3053 : : sal_uInt16 nDefListDeepSave, nContextStMinSave, nContextStAttrMinSave;
3054 : :
3055 : : public:
3056 : :
3057 : : HTMLTable *pTable;
3058 : :
3059 : : _SectionSaveStruct( SwHTMLParser& rParser );
3060 : : virtual ~_SectionSaveStruct();
3061 : :
3062 : : sal_uInt16 GetContextStAttrMin() const { return nContextStAttrMinSave; }
3063 : :
3064 : : void Restore( SwHTMLParser& rParser );
3065 : : };
3066 : :
3067 : 0 : _SectionSaveStruct::_SectionSaveStruct( SwHTMLParser& rParser ) :
3068 : : nBaseFontStMinSave(0), nFontStMinSave(0), nFontStHeadStartSave(0),
3069 : : nDefListDeepSave(0), nContextStMinSave(0), nContextStAttrMinSave(0),
3070 : 0 : pTable( 0 )
3071 : : {
3072 : : // Font-Stacks einfrieren
3073 : 0 : nBaseFontStMinSave = rParser.nBaseFontStMin;
3074 : 0 : rParser.nBaseFontStMin = rParser.aBaseFontStack.size();
3075 : :
3076 : 0 : nFontStMinSave = rParser.nFontStMin;
3077 : 0 : nFontStHeadStartSave = rParser.nFontStHeadStart;
3078 : 0 : rParser.nFontStMin = rParser.aFontStack.size();
3079 : :
3080 : : // Kontext-Stack einfrieren
3081 : 0 : nContextStMinSave = rParser.nContextStMin;
3082 : 0 : nContextStAttrMinSave = rParser.nContextStAttrMin;
3083 : 0 : rParser.nContextStMin = rParser.aContexts.size();
3084 : 0 : rParser.nContextStAttrMin = rParser.nContextStMin;
3085 : :
3086 : : // und noch ein par Zaehler retten
3087 : 0 : nDefListDeepSave = rParser.nDefListDeep;
3088 : 0 : rParser.nDefListDeep = 0;
3089 : 0 : }
3090 : :
3091 : 0 : _SectionSaveStruct::~_SectionSaveStruct()
3092 [ # # ]: 0 : {}
3093 : :
3094 : 0 : void _SectionSaveStruct::Restore( SwHTMLParser& rParser )
3095 : : {
3096 : : // Font-Stacks wieder auftauen
3097 : 0 : sal_uInt16 nMin = rParser.nBaseFontStMin;
3098 [ # # ]: 0 : if( rParser.aBaseFontStack.size() > nMin )
3099 : 0 : rParser.aBaseFontStack.erase( rParser.aBaseFontStack.begin() + nMin,
3100 [ # # ][ # # ]: 0 : rParser.aBaseFontStack.end() );
3101 : 0 : rParser.nBaseFontStMin = nBaseFontStMinSave;
3102 : :
3103 : :
3104 : 0 : nMin = rParser.nFontStMin;
3105 [ # # ]: 0 : if( rParser.aFontStack.size() > nMin )
3106 : 0 : rParser.aFontStack.erase( rParser.aFontStack.begin() + nMin,
3107 [ # # ][ # # ]: 0 : rParser.aFontStack.end() );
3108 : 0 : rParser.nFontStMin = nFontStMinSave;
3109 : 0 : rParser.nFontStHeadStart = nFontStHeadStartSave;
3110 : :
3111 : : OSL_ENSURE( rParser.aContexts.size() == rParser.nContextStMin &&
3112 : : rParser.aContexts.size() == rParser.nContextStAttrMin,
3113 : : "The Context Stack was not cleaned up" );
3114 : 0 : rParser.nContextStMin = nContextStMinSave;
3115 : 0 : rParser.nContextStAttrMin = nContextStAttrMinSave;
3116 : :
3117 : : // und noch ein par Zaehler rekonstruieren
3118 : 0 : rParser.nDefListDeep = nDefListDeepSave;
3119 : :
3120 : : // und ein par Flags zuruecksetzen
3121 : 0 : rParser.bNoParSpace = sal_False;
3122 : 0 : rParser.nOpenParaToken = 0;
3123 : :
3124 [ # # ]: 0 : if( !rParser.aParaAttrs.empty() )
3125 : 0 : rParser.aParaAttrs.clear();
3126 : 0 : }
3127 : :
3128 : :
3129 : : class _CellSaveStruct : public _SectionSaveStruct
3130 : : {
3131 : : String aStyle, aId, aClass, aLang, aDir;
3132 : : String aBGImage;
3133 : : Color aBGColor;
3134 : : boost::shared_ptr<SvxBoxItem> m_pBoxItem;
3135 : :
3136 : : HTMLTableCnts* pCnts; // Liste aller Inhalte
3137 : : HTMLTableCnts* pCurrCnts; // der aktuelle Inhalt oder 0
3138 : : SwNodeIndex *pNoBreakEndParaIdx;// Absatz-Index eines </NOBR>
3139 : :
3140 : : double nValue;
3141 : :
3142 : : sal_uInt32 nNumFmt;
3143 : :
3144 : : sal_uInt16 nRowSpan, nColSpan, nWidth, nHeight;
3145 : : xub_StrLen nNoBreakEndCntntPos; // Zeichen-Index eines </NOBR>
3146 : :
3147 : : SvxAdjust eAdjust;
3148 : : sal_Int16 eVertOri;
3149 : :
3150 : : sal_Bool bHead : 1;
3151 : : sal_Bool bPrcWidth : 1;
3152 : : sal_Bool bHasNumFmt : 1;
3153 : : sal_Bool bHasValue : 1;
3154 : : sal_Bool bBGColor : 1;
3155 : : sal_Bool bNoWrap : 1; // NOWRAP-Option
3156 : : sal_Bool bNoBreak : 1; // NOBREAK-Tag
3157 : :
3158 : : public:
3159 : :
3160 : : _CellSaveStruct( SwHTMLParser& rParser, HTMLTable *pCurTable, sal_Bool bHd,
3161 : : sal_Bool bReadOpt );
3162 : :
3163 : : virtual ~_CellSaveStruct();
3164 : :
3165 : : void AddContents( HTMLTableCnts *pNewCnts );
3166 : 0 : HTMLTableCnts *GetFirstContents() { return pCnts; }
3167 : :
3168 : 0 : void ClearIsInSection() { pCurrCnts = 0; }
3169 : 0 : sal_Bool IsInSection() const { return pCurrCnts!=0; }
3170 : : HTMLTableCnts *GetCurrContents() const { return pCurrCnts; }
3171 : :
3172 : : void InsertCell( SwHTMLParser& rParser, HTMLTable *pCurTable );
3173 : :
3174 : 0 : sal_Bool IsHeaderCell() const { return bHead; }
3175 : :
3176 : : void StartNoBreak( const SwPosition& rPos );
3177 : : void EndNoBreak( const SwPosition& rPos );
3178 : : void CheckNoBreak( const SwPosition& rPos, SwDoc *pDoc );
3179 : : };
3180 : :
3181 : :
3182 : 0 : _CellSaveStruct::_CellSaveStruct( SwHTMLParser& rParser, HTMLTable *pCurTable,
3183 : : sal_Bool bHd, sal_Bool bReadOpt ) :
3184 : : _SectionSaveStruct( rParser ),
3185 : : pCnts( 0 ),
3186 : : pCurrCnts( 0 ),
3187 : : pNoBreakEndParaIdx( 0 ),
3188 : : nValue( 0.0 ),
3189 : : nNumFmt( 0 ),
3190 : : nRowSpan( 1 ),
3191 : : nColSpan( 1 ),
3192 : : nWidth( 0 ),
3193 : : nHeight( 0 ),
3194 : : nNoBreakEndCntntPos( 0 ),
3195 [ # # ]: 0 : eAdjust( pCurTable->GetInheritedAdjust() ),
3196 [ # # ]: 0 : eVertOri( pCurTable->GetInheritedVertOri() ),
3197 : : bHead( bHd ),
3198 : : bPrcWidth( sal_False ),
3199 : : bHasNumFmt( sal_False ),
3200 : : bHasValue( sal_False ),
3201 : : bBGColor( sal_False ),
3202 : : bNoWrap( sal_False ),
3203 [ # # ][ # # ]: 0 : bNoBreak( sal_False )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
3204 : : {
3205 [ # # ][ # # ]: 0 : String aNumFmt, aValue;
3206 : :
3207 [ # # ]: 0 : if( bReadOpt )
3208 : : {
3209 [ # # ]: 0 : const HTMLOptions& rOptions = rParser.GetOptions();
3210 [ # # ]: 0 : for (size_t i = rOptions.size(); i; )
3211 : : {
3212 [ # # ]: 0 : const HTMLOption& rOption = rOptions[--i];
3213 [ # # # # : 0 : switch( rOption.GetToken() )
# # # # #
# # # # #
# # # ]
3214 : : {
3215 : : case HTML_O_ID:
3216 [ # # ]: 0 : aId = rOption.GetString();
3217 : 0 : break;
3218 : : case HTML_O_COLSPAN:
3219 [ # # ]: 0 : nColSpan = (sal_uInt16)rOption.GetNumber();
3220 : 0 : break;
3221 : : case HTML_O_ROWSPAN:
3222 [ # # ]: 0 : nRowSpan = (sal_uInt16)rOption.GetNumber();
3223 : 0 : break;
3224 : : case HTML_O_ALIGN:
3225 : : eAdjust = (SvxAdjust)rOption.GetEnum(
3226 [ # # ]: 0 : aHTMLPAlignTable, static_cast< sal_uInt16 >(eAdjust) );
3227 : 0 : break;
3228 : : case HTML_O_VALIGN:
3229 : : eVertOri = rOption.GetEnum(
3230 [ # # ]: 0 : aHTMLTblVAlignTable, eVertOri );
3231 : 0 : break;
3232 : : case HTML_O_WIDTH:
3233 [ # # ]: 0 : nWidth = (sal_uInt16)rOption.GetNumber(); // nur fuer Netscape
3234 [ # # ]: 0 : bPrcWidth = (rOption.GetString().Search('%') != STRING_NOTFOUND);
3235 [ # # ][ # # ]: 0 : if( bPrcWidth && nWidth>100 )
3236 : 0 : nWidth = 100;
3237 : 0 : break;
3238 : : case HTML_O_HEIGHT:
3239 [ # # ]: 0 : nHeight = (sal_uInt16)rOption.GetNumber(); // nur fuer Netscape
3240 [ # # ][ # # ]: 0 : if( rOption.GetString().Search('%') != STRING_NOTFOUND)
3241 : 0 : nHeight = 0; // keine %-Angaben beruecksichtigen
3242 : 0 : break;
3243 : : case HTML_O_BGCOLOR:
3244 : : // Leere BGCOLOR bei <TABLE>, <TR> und <TD>/<TH> wie Netscape
3245 : : // ignorieren, bei allen anderen Tags *wirklich* nicht.
3246 [ # # ]: 0 : if( rOption.GetString().Len() )
3247 : : {
3248 [ # # ]: 0 : rOption.GetColor( aBGColor );
3249 : 0 : bBGColor = sal_True;
3250 : : }
3251 : 0 : break;
3252 : : case HTML_O_BACKGROUND:
3253 [ # # ]: 0 : aBGImage = rOption.GetString();
3254 : 0 : break;
3255 : : case HTML_O_STYLE:
3256 [ # # ]: 0 : aStyle = rOption.GetString();
3257 : 0 : break;
3258 : : case HTML_O_CLASS:
3259 [ # # ]: 0 : aClass = rOption.GetString();
3260 : 0 : break;
3261 : : case HTML_O_LANG:
3262 [ # # ]: 0 : aLang = rOption.GetString();
3263 : 0 : break;
3264 : : case HTML_O_DIR:
3265 [ # # ]: 0 : aDir = rOption.GetString();
3266 : 0 : break;
3267 : : case HTML_O_SDNUM:
3268 [ # # ]: 0 : aNumFmt = rOption.GetString();
3269 : 0 : bHasNumFmt = sal_True;
3270 : 0 : break;
3271 : : case HTML_O_SDVAL:
3272 : 0 : bHasValue = sal_True;
3273 [ # # ]: 0 : aValue = rOption.GetString();
3274 : 0 : break;
3275 : : case HTML_O_NOWRAP:
3276 : 0 : bNoWrap = sal_True;
3277 : 0 : break;
3278 : : }
3279 : : }
3280 : :
3281 [ # # ]: 0 : if( aId.Len() )
3282 [ # # ]: 0 : rParser.InsertBookmark( aId );
3283 : : }
3284 : :
3285 [ # # ]: 0 : if( bHasNumFmt )
3286 : : {
3287 : : LanguageType eLang;
3288 : : nValue = rParser.GetTableDataOptionsValNum(
3289 : : nNumFmt, eLang, aValue, aNumFmt,
3290 [ # # ][ # # ]: 0 : *rParser.pDoc->GetNumberFormatter() );
3291 : : }
3292 : :
3293 : : // einen neuen Kontext anlegen, aber das drawing::Alignment-Attribut
3294 : : // nicht dort verankern, weil es noch ger keine Section gibt, in der
3295 : : // es gibt.
3296 : : sal_uInt16 nToken, nColl;
3297 [ # # ]: 0 : if( bHead )
3298 : : {
3299 : 0 : nToken = HTML_TABLEHEADER_ON;
3300 : 0 : nColl = RES_POOLCOLL_TABLE_HDLN;
3301 : : }
3302 : : else
3303 : : {
3304 : 0 : nToken = HTML_TABLEDATA_ON;
3305 : 0 : nColl = RES_POOLCOLL_TABLE;
3306 : : }
3307 [ # # ][ # # ]: 0 : _HTMLAttrContext *pCntxt = new _HTMLAttrContext( nToken, nColl, aEmptyStr, sal_True );
3308 [ # # ]: 0 : if( SVX_ADJUST_END != eAdjust )
3309 : : rParser.InsertAttr( &rParser.aAttrTab.pAdjust, SvxAdjustItem(eAdjust, RES_PARATR_ADJUST),
3310 [ # # ][ # # ]: 0 : pCntxt );
[ # # ]
3311 : :
3312 [ # # ]: 0 : if( rParser.HasStyleOptions( aStyle, aId, aClass, &aLang, &aDir ) )
3313 : : {
3314 : 0 : SfxItemSet aItemSet( rParser.pDoc->GetAttrPool(),
3315 [ # # # # ]: 0 : rParser.pCSS1Parser->GetWhichMap() );
3316 [ # # ]: 0 : SvxCSS1PropertyInfo aPropInfo;
3317 : :
3318 [ # # ]: 0 : if( rParser.ParseStyleOptions( aStyle, aId, aClass, aItemSet,
3319 [ # # ]: 0 : aPropInfo, &aLang, &aDir ) )
3320 : : {
3321 : : SfxPoolItem const* pItem;
3322 [ # # ][ # # ]: 0 : if (SFX_ITEM_SET == aItemSet.GetItemState(RES_BOX, false, &pItem))
3323 : : { // fdo#41796: steal box item to set it in FixFrameFmt later!
3324 [ # # ][ # # ]: 0 : m_pBoxItem.reset(dynamic_cast<SvxBoxItem *>(pItem->Clone()));
[ # # ]
3325 [ # # ]: 0 : aItemSet.ClearItem(RES_BOX);
3326 : : }
3327 [ # # ]: 0 : rParser.InsertAttrs( aItemSet, aPropInfo, pCntxt );
3328 [ # # ][ # # ]: 0 : }
3329 : : }
3330 : :
3331 [ # # ]: 0 : rParser.SplitPREListingXMP( pCntxt );
3332 : :
3333 [ # # ][ # # ]: 0 : rParser.PushContext( pCntxt );
[ # # ]
3334 : 0 : }
3335 : :
3336 [ # # ][ # # ]: 0 : _CellSaveStruct::~_CellSaveStruct()
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
3337 : : {
3338 [ # # ][ # # ]: 0 : delete pNoBreakEndParaIdx;
3339 [ # # ]: 0 : }
3340 : :
3341 : 0 : void _CellSaveStruct::AddContents( HTMLTableCnts *pNewCnts )
3342 : : {
3343 [ # # ]: 0 : if( pCnts )
3344 : 0 : pCnts->Add( pNewCnts );
3345 : : else
3346 : 0 : pCnts = pNewCnts;
3347 : :
3348 : 0 : pCurrCnts = pNewCnts;
3349 : 0 : }
3350 : :
3351 : 0 : void _CellSaveStruct::InsertCell( SwHTMLParser& rParser,
3352 : : HTMLTable *pCurTable )
3353 : : {
3354 : : #if OSL_DEBUG_LEVEL > 0
3355 : : // Die Attribute muessen schon beim Auefrauemen des Kontext-Stacks
3356 : : // entfernt worden sein, sonst ist etwas schiefgelaufen. Das
3357 : : // Checken wir mal eben ...
3358 : : // MIB 8.1.98: Wenn ausserhalb einer Zelle Attribute geoeffnet
3359 : : // wurden stehen diese noch in der Attribut-Tabelle und werden erst
3360 : : // ganz zum Schluss durch die CleanContext-Aufrufe in BuildTable
3361 : : // geloescht. Damit es in diesem Fall keine Asserts gibt findet dann
3362 : : // keine Ueberpruefung statt. Erkennen tut man diesen Fall an
3363 : : // nContextStAttrMin: Der gemerkte Wert nContextStAttrMinSave ist der
3364 : : // Wert, den nContextStAttrMin beim Start der Tabelle hatte. Und
3365 : : // der aktuelle Wert von nContextStAttrMin entspricht der Anzahl der
3366 : : // Kontexte, die beim Start der Zelle vorgefunden wurden. Sind beide
3367 : : // Werte unterschiedlich, wurden ausserhalb der Zelle Kontexte
3368 : : // angelegt und wir ueberpruefen nichts.
3369 : :
3370 : : if( rParser.nContextStAttrMin == GetContextStAttrMin() )
3371 : : {
3372 : : _HTMLAttr** pTbl = (_HTMLAttr**)&rParser.aAttrTab;
3373 : :
3374 : : for( sal_uInt16 nCnt = sizeof( _HTMLAttrTable ) / sizeof( _HTMLAttr* );
3375 : : nCnt--; ++pTbl )
3376 : : {
3377 : : OSL_ENSURE( !*pTbl, "Die Attribut-Tabelle ist nicht leer" );
3378 : : }
3379 : : }
3380 : : #endif
3381 : :
3382 : : // jetzt muessen wir noch die Zelle an der aktuellen Position einfuegen
3383 : : SvxBrushItem *pBrushItem =
3384 : : rParser.CreateBrushItem( bBGColor ? &aBGColor : 0, aBGImage,
3385 [ # # ]: 0 : aStyle, aId, aClass );
3386 : : pCurTable->InsertCell( pCnts, nRowSpan, nColSpan, nWidth,
3387 : : bPrcWidth, nHeight, eVertOri, pBrushItem, m_pBoxItem,
3388 : : bHasNumFmt, nNumFmt, bHasValue, nValue,
3389 [ # # ]: 0 : bNoWrap );
3390 : 0 : Restore( rParser );
3391 : 0 : }
3392 : :
3393 : 0 : void _CellSaveStruct::StartNoBreak( const SwPosition& rPos )
3394 : : {
3395 [ # # # # ]: 0 : if( !pCnts ||
[ # # # #
# # ][ # # ]
3396 : 0 : (!rPos.nContent.GetIndex() && pCurrCnts==pCnts &&
3397 : 0 : pCnts->GetStartNode() &&
3398 : 0 : pCnts->GetStartNode()->GetIndex() + 1 ==
3399 : 0 : rPos.nNode.GetIndex()) )
3400 : : {
3401 : 0 : bNoBreak = sal_True;
3402 : : }
3403 : 0 : }
3404 : :
3405 : 0 : void _CellSaveStruct::EndNoBreak( const SwPosition& rPos )
3406 : : {
3407 [ # # ]: 0 : if( bNoBreak )
3408 : : {
3409 [ # # ]: 0 : delete pNoBreakEndParaIdx;
3410 [ # # ]: 0 : pNoBreakEndParaIdx = new SwNodeIndex( rPos.nNode );
3411 : 0 : nNoBreakEndCntntPos = rPos.nContent.GetIndex();
3412 : 0 : bNoBreak = sal_False;
3413 : : }
3414 : 0 : }
3415 : :
3416 : 0 : void _CellSaveStruct::CheckNoBreak( const SwPosition& rPos, SwDoc * /*pDoc*/ )
3417 : : {
3418 [ # # ][ # # ]: 0 : if( pCnts && pCurrCnts==pCnts )
3419 : : {
3420 [ # # ]: 0 : if( bNoBreak )
3421 : : {
3422 : : // <NOBR> wurde nicht beendet
3423 : 0 : pCnts->SetNoBreak();
3424 : : }
3425 [ # # # # ]: 0 : else if( pNoBreakEndParaIdx &&
[ # # ]
3426 : 0 : pNoBreakEndParaIdx->GetIndex() == rPos.nNode.GetIndex() )
3427 : : {
3428 [ # # ]: 0 : if( nNoBreakEndCntntPos == rPos.nContent.GetIndex() )
3429 : : {
3430 : : // <NOBR> wurde unmittelbar vor dem Zellen-Ende beendet
3431 : 0 : pCnts->SetNoBreak();
3432 : : }
3433 [ # # ]: 0 : else if( nNoBreakEndCntntPos + 1 == rPos.nContent.GetIndex() )
3434 : : {
3435 : 0 : SwTxtNode const*const pTxtNd(rPos.nNode.GetNode().GetTxtNode());
3436 [ # # ]: 0 : if( pTxtNd )
3437 : : {
3438 : : sal_Unicode cLast =
3439 : 0 : pTxtNd->GetTxt().GetChar(nNoBreakEndCntntPos);
3440 [ # # ][ # # ]: 0 : if( ' '==cLast || '\x0a'==cLast )
3441 : : {
3442 : : // Zwischem dem </NOBR> und dem Zellen-Ende gibt es nur
3443 : : // ein Blank oder einen Zeilenumbruch.
3444 : 0 : pCnts->SetNoBreak();
3445 : : }
3446 : : }
3447 : : }
3448 : : }
3449 : : }
3450 : 0 : }
3451 : :
3452 : :
3453 : :
3454 : 0 : HTMLTableCnts *SwHTMLParser::InsertTableContents(
3455 : : sal_Bool bHead )
3456 : : {
3457 : : // eine neue Section anlegen, der PaM steht dann darin
3458 : : const SwStartNode *pStNd =
3459 : : InsertTableSection( static_cast< sal_uInt16 >(bHead ? RES_POOLCOLL_TABLE_HDLN
3460 [ # # ]: 0 : : RES_POOLCOLL_TABLE) );
3461 : :
3462 [ # # ]: 0 : if( GetNumInfo().GetNumRule() )
3463 : : {
3464 : : // 1. Absatz auf nicht numeriert setzen
3465 : 0 : sal_uInt8 nLvl = GetNumInfo().GetLevel();
3466 : :
3467 : 0 : SetNodeNum( nLvl, false );
3468 : : }
3469 : :
3470 : : // Attributierungs-Anfang neu setzen
3471 : 0 : const SwNodeIndex& rSttPara = pPam->GetPoint()->nNode;
3472 : 0 : xub_StrLen nSttCnt = pPam->GetPoint()->nContent.GetIndex();
3473 : :
3474 : 0 : _HTMLAttr** pTbl = (_HTMLAttr**)&aAttrTab;
3475 [ # # ]: 0 : for( sal_uInt16 nCnt = sizeof( _HTMLAttrTable ) / sizeof( _HTMLAttr* );
3476 : : nCnt--; ++pTbl )
3477 : : {
3478 : :
3479 : 0 : _HTMLAttr *pAttr = *pTbl;
3480 [ # # ]: 0 : while( pAttr )
3481 : : {
3482 : : OSL_ENSURE( !pAttr->GetPrev(), "Attribut hat Previous-Liste" );
3483 : 0 : pAttr->nSttPara = rSttPara;
3484 : 0 : pAttr->nEndPara = rSttPara;
3485 : 0 : pAttr->nSttCntnt = nSttCnt;
3486 : 0 : pAttr->nEndCntnt = nSttCnt;
3487 : :
3488 : 0 : pAttr = pAttr->GetNext();
3489 : : }
3490 : : }
3491 : :
3492 : 0 : return new HTMLTableCnts( pStNd );
3493 : : }
3494 : :
3495 : 0 : sal_uInt16 SwHTMLParser::IncGrfsThatResizeTable()
3496 : : {
3497 [ # # ]: 0 : return pTable ? pTable->IncGrfsThatResize() : 0;
3498 : : }
3499 : :
3500 : 0 : void SwHTMLParser::RegisterDrawObjectToTable( HTMLTable *pCurTable,
3501 : : SdrObject *pObj, sal_uInt8 nPrcWidth )
3502 : : {
3503 : 0 : pCurTable->RegisterDrawObject( pObj, nPrcWidth );
3504 : 0 : }
3505 : :
3506 : 0 : void SwHTMLParser::BuildTableCell( HTMLTable *pCurTable, sal_Bool bReadOptions,
3507 : : sal_Bool bHead )
3508 : : {
3509 [ # # ][ # # ]: 0 : if( !IsParserWorking() && !pPendStack )
[ # # ]
3510 : 0 : return;
3511 : :
3512 : : _CellSaveStruct* pSaveStruct;
3513 : :
3514 : 0 : int nToken = 0;
3515 : 0 : sal_Bool bPending = sal_False;
3516 [ # # ]: 0 : if( pPendStack )
3517 : : {
3518 : 0 : pSaveStruct = (_CellSaveStruct*)pPendStack->pData;
3519 : :
3520 : 0 : SwPendingStack* pTmp = pPendStack->pNext;
3521 : 0 : delete pPendStack;
3522 : 0 : pPendStack = pTmp;
3523 [ # # ]: 0 : nToken = pPendStack ? pPendStack->nToken : GetSaveToken();
3524 [ # # ][ # # ]: 0 : bPending = SVPAR_ERROR == eState && pPendStack != 0;
3525 : :
3526 : 0 : SaveState( nToken );
3527 : : }
3528 : : else
3529 : : {
3530 : : // <TH> bzw. <TD> wurde bereits gelesen
3531 [ # # ]: 0 : if( pTable->IsOverflowing() )
3532 : : {
3533 : 0 : SaveState( 0 );
3534 : 0 : return;
3535 : : }
3536 : :
3537 [ # # ]: 0 : if( !pCurTable->GetContext() )
3538 : : {
3539 : 0 : sal_Bool bTopTable = pTable==pCurTable;
3540 : :
3541 : : // die Tabelle besitzt noch keinen Inhalt, d.h. die eigentliche
3542 : : // Tabelle muss erst noch angelegt werden
3543 : :
3544 : : static sal_uInt16 aWhichIds[] =
3545 : : {
3546 : : RES_PARATR_SPLIT, RES_PARATR_SPLIT,
3547 : : RES_PAGEDESC, RES_PAGEDESC,
3548 : : RES_BREAK, RES_BREAK,
3549 : : RES_BACKGROUND, RES_BACKGROUND,
3550 : : RES_KEEP, RES_KEEP,
3551 : : RES_LAYOUT_SPLIT, RES_LAYOUT_SPLIT,
3552 : : RES_FRAMEDIR, RES_FRAMEDIR,
3553 : : 0
3554 : : };
3555 : :
3556 [ # # ]: 0 : SfxItemSet aItemSet( pDoc->GetAttrPool(), aWhichIds );
3557 [ # # ]: 0 : SvxCSS1PropertyInfo aPropInfo;
3558 : :
3559 : 0 : sal_Bool bStyleParsed = ParseStyleOptions( pCurTable->GetStyle(),
3560 : 0 : pCurTable->GetId(),
3561 : 0 : pCurTable->GetClass(),
3562 : : aItemSet, aPropInfo,
3563 [ # # ]: 0 : 0, &pCurTable->GetDirection() );
3564 : 0 : const SfxPoolItem *pItem = 0;
3565 [ # # ]: 0 : if( bStyleParsed )
3566 : : {
3567 [ # # ]: 0 : if( SFX_ITEM_SET == aItemSet.GetItemState(
3568 [ # # ]: 0 : RES_BACKGROUND, sal_False, &pItem ) )
3569 : : {
3570 [ # # ]: 0 : pCurTable->SetBGBrush( *(const SvxBrushItem *)pItem );
3571 [ # # ]: 0 : aItemSet.ClearItem( RES_BACKGROUND );
3572 : : }
3573 [ # # ]: 0 : if( SFX_ITEM_SET == aItemSet.GetItemState(
3574 [ # # ]: 0 : RES_PARATR_SPLIT, sal_False, &pItem ) )
3575 : : {
3576 : : aItemSet.Put(
3577 : : SwFmtLayoutSplit( ((const SvxFmtSplitItem *)pItem)
3578 [ # # ][ # # ]: 0 : ->GetValue() ) );
[ # # ]
3579 [ # # ]: 0 : aItemSet.ClearItem( RES_PARATR_SPLIT );
3580 : : }
3581 : : }
3582 : :
3583 : : // Den linken/rechten Absatzeinzug ermitteln
3584 : 0 : sal_uInt16 nLeftSpace = 0;
3585 : 0 : sal_uInt16 nRightSpace = 0;
3586 : : short nIndent;
3587 [ # # ]: 0 : GetMarginsFromContextWithNumBul( nLeftSpace, nRightSpace, nIndent );
3588 : :
3589 : : // die aktuelle Position an die wir irgendwann zurueckkehren
3590 : 0 : SwPosition *pSavePos = 0;
3591 : 0 : sal_Bool bForceFrame = sal_False;
3592 : 0 : sal_Bool bAppended = sal_False;
3593 : 0 : sal_Bool bParentLFStripped = sal_False;
3594 [ # # ]: 0 : if( bTopTable )
3595 : : {
3596 : 0 : SvxAdjust eTblAdjust = pTable->GetTableAdjust(sal_False);
3597 : :
3598 : : // Wenn die Tabelle links oder rechts ausgerivchtet ist,
3599 : : // oder in einen Rahmen soll, dann kommt sie auch in einen
3600 : : // solchen.
3601 : : bForceFrame = eTblAdjust == SVX_ADJUST_LEFT ||
3602 : : eTblAdjust == SVX_ADJUST_RIGHT ||
3603 [ # # ][ # # ]: 0 : pCurTable->HasToFly();
[ # # ]
3604 : :
3605 : : // Entweder kommt die Tabelle in keinen Rahmen und befindet
3606 : : // sich in keinem Rahmen (wird also durch Zellen simuliert),
3607 : : // oder es gibt bereits Inhalt an der entsprechenden Stelle.
3608 : : OSL_ENSURE( !bForceFrame || pCurTable->HasParentSection(),
3609 : : "Tabelle im Rahmen hat keine Umgebung!" );
3610 : :
3611 : 0 : sal_Bool bAppend = sal_False;
3612 [ # # ]: 0 : if( bForceFrame )
3613 : : {
3614 : : // Wenn die Tabelle in einen Rahmen kommt, muss
3615 : : // nur ein neuer Absatz aufgemacht werden, wenn
3616 : : // der Absatz Rahmen ohne Umlauf enthaelt.
3617 [ # # ]: 0 : bAppend = HasCurrentParaFlys(sal_True);
3618 : : }
3619 : : else
3620 : : {
3621 : : // Sonst muss ein neuer Absatz aufgemacht werden,
3622 : : // wenn der Absatz nicht leer ist, oder Rahmen
3623 : : // oder text::Bookmarks enthaelt.
3624 : : bAppend =
3625 : 0 : pPam->GetPoint()->nContent.GetIndex() ||
3626 [ # # ]: 0 : HasCurrentParaFlys() ||
3627 [ # # ][ # # ]: 0 : HasCurrentParaBookmarks();
[ # # ][ # # ]
3628 : : }
3629 [ # # ]: 0 : if( bAppend )
3630 : : {
3631 [ # # ]: 0 : if( !pPam->GetPoint()->nContent.GetIndex() )
3632 : : {
3633 : : //Set default to CJK and CTL
3634 : : pDoc->SetTxtFmtColl( *pPam,
3635 [ # # ][ # # ]: 0 : pCSS1Parser->GetTxtCollFromPool(RES_POOLCOLL_STANDARD) );
3636 [ # # ]: 0 : SvxFontHeightItem aFontHeight( 40, 100, RES_CHRATR_FONTSIZE );
3637 : :
3638 : : _HTMLAttr* pTmp =
3639 [ # # ][ # # ]: 0 : new _HTMLAttr( *pPam->GetPoint(), aFontHeight );
3640 [ # # ]: 0 : aSetAttrTab.push_back( pTmp );
3641 : :
3642 [ # # ]: 0 : SvxFontHeightItem aFontHeightCJK( 40, 100, RES_CHRATR_CJK_FONTSIZE );
3643 : : pTmp =
3644 [ # # ][ # # ]: 0 : new _HTMLAttr( *pPam->GetPoint(), aFontHeightCJK );
3645 [ # # ]: 0 : aSetAttrTab.push_back( pTmp );
3646 : :
3647 [ # # ]: 0 : SvxFontHeightItem aFontHeightCTL( 40, 100, RES_CHRATR_CTL_FONTSIZE );
3648 : : pTmp =
3649 [ # # ][ # # ]: 0 : new _HTMLAttr( *pPam->GetPoint(), aFontHeightCTL );
3650 [ # # ]: 0 : aSetAttrTab.push_back( pTmp );
3651 : :
3652 : 0 : pTmp = new _HTMLAttr( *pPam->GetPoint(),
3653 [ # # ][ # # ]: 0 : SvxULSpaceItem( 0, 0, RES_UL_SPACE ) );
[ # # ][ # # ]
3654 [ # # ][ # # ]: 0 : aSetAttrTab.push_front( pTmp ); // ja, 0, weil schon
[ # # ][ # # ]
3655 : : // vom Tabellenende vorher
3656 : : // was gesetzt sein kann.
3657 : : }
3658 [ # # ]: 0 : AppendTxtNode( AM_NOSPACE );
3659 : 0 : bAppended = sal_True;
3660 : : }
3661 [ # # ]: 0 : else if( !aParaAttrs.empty() )
3662 : : {
3663 [ # # ]: 0 : if( !bForceFrame )
3664 : : {
3665 : : // Der Absatz wird gleich hinter die Tabelle
3666 : : // verschoben. Deshalb entfernen wir alle harten
3667 : : // Attribute des Absatzes
3668 : :
3669 [ # # ]: 0 : for( sal_uInt16 i=0; i<aParaAttrs.size(); i++ )
3670 [ # # ]: 0 : aParaAttrs[i]->Invalidate();
3671 : : }
3672 : :
3673 : 0 : aParaAttrs.clear();
3674 : : }
3675 : :
3676 [ # # ][ # # ]: 0 : pSavePos = new SwPosition( *pPam->GetPoint() );
3677 : : }
3678 [ # # ]: 0 : else if( pCurTable->HasParentSection() )
3679 : : {
3680 [ # # ]: 0 : bParentLFStripped = StripTrailingLF() > 0;
3681 : :
3682 : : // Absaetze bzw. ueberschriften beeenden
3683 : 0 : nOpenParaToken = 0;
3684 : 0 : nFontStHeadStart = nFontStMin;
3685 : :
3686 : : // die harten Attribute an diesem Absatz werden nie mehr ungueltig
3687 [ # # ]: 0 : if( !aParaAttrs.empty() )
3688 : 0 : aParaAttrs.clear();
3689 : : }
3690 : :
3691 : : // einen Tabellen Kontext anlegen
3692 : : _HTMLTableContext *pTCntxt =
3693 : : new _HTMLTableContext( pSavePos, nContextStMin,
3694 [ # # ]: 0 : nContextStAttrMin );
3695 : :
3696 : : // alle noch offenen Attribute beenden und hinter der Tabelle
3697 : : // neu aufspannen
3698 : 0 : _HTMLAttrs *pPostIts = 0;
3699 [ # # ][ # # ]: 0 : if( !bForceFrame && (bTopTable || pCurTable->HasParentSection()) )
[ # # ][ # # ]
3700 : : {
3701 [ # # ]: 0 : SplitAttrTab( pTCntxt->aAttrTab, bTopTable );
3702 : : // Wenn wir einen schon vorhandenen Absatz verwenden, duerfen
3703 : : // in den keine PostIts eingefuegt werden, weil der Absatz
3704 : : // ja hinter die Tabelle wandert. Sie werden deshalb in den
3705 : : // ersten Absatz der Tabelle verschoben.
3706 : : // Bei Tabellen in Tabellen duerfen ebenfalls keine PostIts
3707 : : // in einen noch leeren Absatz eingefuegt werden, weil
3708 : : // der sonat nicht geloescht wird.
3709 [ # # ][ # # ]: 0 : if( (bTopTable && !bAppended) ||
[ # # ]
[ # # # # ]
[ # # ]
3710 : : (!bTopTable && !bParentLFStripped &&
3711 : 0 : !pPam->GetPoint()->nContent.GetIndex()) )
3712 [ # # ][ # # ]: 0 : pPostIts = new _HTMLAttrs;
3713 [ # # ]: 0 : SetAttr( bTopTable, bTopTable, pPostIts );
3714 : : }
3715 : : else
3716 : : {
3717 [ # # ]: 0 : SaveAttrTab( pTCntxt->aAttrTab );
3718 [ # # ][ # # ]: 0 : if( bTopTable && !bAppended )
3719 : : {
3720 [ # # ][ # # ]: 0 : pPostIts = new _HTMLAttrs;
3721 [ # # ]: 0 : SetAttr( sal_True, sal_True, pPostIts );
3722 : : }
3723 : : }
3724 : 0 : bNoParSpace = sal_False;
3725 : :
3726 : : // Aktuelle Numerierung retten und auschalten.
3727 : 0 : pTCntxt->SetNumInfo( GetNumInfo() );
3728 : 0 : GetNumInfo().Clear();
3729 : 0 : pTCntxt->SavePREListingXMP( *this );
3730 : :
3731 [ # # ]: 0 : if( bTopTable )
3732 : : {
3733 [ # # ]: 0 : if( bForceFrame )
3734 : : {
3735 : : // Die Tabelle soll in einen Rahmen geschaufelt werden.
3736 : :
3737 : 0 : SfxItemSet aFrmSet( pDoc->GetAttrPool(),
3738 [ # # ]: 0 : RES_FRMATR_BEGIN, RES_FRMATR_END-1 );
3739 [ # # ]: 0 : if( !pCurTable->IsNewDoc() )
3740 [ # # ]: 0 : Reader::ResetFrmFmtAttrs( aFrmSet );
3741 : :
3742 : 0 : SwSurround eSurround = SURROUND_NONE;
3743 : : sal_Int16 eHori;
3744 : :
3745 [ # # # # ]: 0 : switch( pCurTable->GetTableAdjust(sal_True) )
3746 : : {
3747 : : case SVX_ADJUST_RIGHT:
3748 : 0 : eHori = text::HoriOrientation::RIGHT;
3749 : 0 : eSurround = SURROUND_LEFT;
3750 : 0 : break;
3751 : : case SVX_ADJUST_CENTER:
3752 : 0 : eHori = text::HoriOrientation::CENTER;
3753 : 0 : break;
3754 : : case SVX_ADJUST_LEFT:
3755 : 0 : eSurround = SURROUND_RIGHT;
3756 : : default:
3757 : 0 : eHori = text::HoriOrientation::LEFT;
3758 : 0 : break;
3759 : : }
3760 : : SetAnchorAndAdjustment( text::VertOrientation::NONE, eHori, aFrmSet,
3761 [ # # ]: 0 : sal_True );
3762 [ # # ][ # # ]: 0 : aFrmSet.Put( SwFmtSurround(eSurround) );
[ # # ]
3763 : :
3764 [ # # ]: 0 : SwFmtFrmSize aFrmSize( ATT_VAR_SIZE, 20*MM50, MINLAY );
3765 : 0 : aFrmSize.SetWidthPercent( 100 );
3766 [ # # ]: 0 : aFrmSet.Put( aFrmSize );
3767 : :
3768 : 0 : sal_uInt16 nSpace = pCurTable->GetHSpace();
3769 [ # # ]: 0 : if( nSpace )
3770 [ # # ][ # # ]: 0 : aFrmSet.Put( SvxLRSpaceItem(nSpace,nSpace, 0, 0, RES_LR_SPACE) );
[ # # ]
3771 : 0 : nSpace = pCurTable->GetVSpace();
3772 [ # # ]: 0 : if( nSpace )
3773 [ # # ][ # # ]: 0 : aFrmSet.Put( SvxULSpaceItem(nSpace,nSpace, RES_UL_SPACE) );
[ # # ]
3774 : :
3775 : : RndStdIds eAnchorId = ((const SwFmtAnchor&)aFrmSet.
3776 [ # # ]: 0 : Get( RES_ANCHOR )).
3777 : 0 : GetAnchorId();
3778 : : SwFrmFmt *pFrmFmt = pDoc->MakeFlySection(
3779 [ # # ]: 0 : eAnchorId, pPam->GetPoint(), &aFrmSet );
3780 : :
3781 : 0 : pTCntxt->SetFrmFmt( pFrmFmt );
3782 [ # # ]: 0 : const SwFmtCntnt& rFlyCntnt = pFrmFmt->GetCntnt();
3783 [ # # ]: 0 : pPam->GetPoint()->nNode = *rFlyCntnt.GetCntntIdx();
3784 : : SwCntntNode *pCNd =
3785 [ # # ][ # # ]: 0 : pDoc->GetNodes().GoNext( &(pPam->GetPoint()->nNode) );
3786 [ # # ][ # # ]: 0 : pPam->GetPoint()->nContent.Assign( pCNd, 0 );
[ # # ][ # # ]
3787 : :
3788 : : }
3789 : :
3790 : : // eine SwTable mit einer Box anlegen und den PaM in den
3791 : : // Inhalt der Box-Section bewegen (der Ausrichtungs-Parameter
3792 : : // ist erstmal nur ein Dummy und wird spaeter noch richtig
3793 : : // gesetzt)
3794 : : OSL_ENSURE( !pPam->GetPoint()->nContent.GetIndex(),
3795 : : "Der Absatz hinter der Tabelle ist nicht leer!" );
3796 : : const SwTable* pSwTable = pDoc->InsertTable(
3797 : : SwInsertTableOptions( tabopts::HEADLINE_NO_BORDER, 1 ),
3798 [ # # ]: 0 : *pPam->GetPoint(), 1, 1, text::HoriOrientation::LEFT );
3799 : :
3800 [ # # ]: 0 : if( bForceFrame )
3801 : : {
3802 [ # # ]: 0 : SwNodeIndex aDstIdx( pPam->GetPoint()->nNode );
3803 [ # # ]: 0 : pPam->Move( fnMoveBackward );
3804 [ # # ][ # # ]: 0 : pDoc->GetNodes().Delete( aDstIdx );
[ # # ]
3805 : : }
3806 : : else
3807 : : {
3808 [ # # ]: 0 : if( bStyleParsed )
3809 : : {
3810 [ # # ]: 0 : pCSS1Parser->SetFmtBreak( aItemSet, aPropInfo );
3811 [ # # ]: 0 : pSwTable->GetFrmFmt()->SetFmtAttr( aItemSet );
3812 : : }
3813 [ # # ]: 0 : pPam->Move( fnMoveBackward );
3814 : : }
3815 : :
3816 : 0 : SwNode const*const pNd = & pPam->GetPoint()->nNode.GetNode();
3817 [ # # ][ # # ]: 0 : if( !bAppended && !bForceFrame )
3818 : : {
3819 : : SwTxtNode *const pOldTxtNd =
3820 : 0 : pSavePos->nNode.GetNode().GetTxtNode();
3821 : : OSL_ENSURE( pOldTxtNd, "Wieso stehen wir in keinem Txt-Node?" );
3822 : 0 : SwFrmFmt *pFrmFmt = pSwTable->GetFrmFmt();
3823 : :
3824 : : const SfxPoolItem* pItem2;
3825 [ # # # # ]: 0 : if( SFX_ITEM_SET == pOldTxtNd->GetSwAttrSet()
[ # # ][ # # ]
3826 [ # # ]: 0 : .GetItemState( RES_PAGEDESC, sal_False, &pItem2 ) &&
3827 : 0 : ((SwFmtPageDesc *)pItem2)->GetPageDesc() )
3828 : : {
3829 [ # # ]: 0 : pFrmFmt->SetFmtAttr( *pItem2 );
3830 [ # # ]: 0 : pOldTxtNd->ResetAttr( RES_PAGEDESC );
3831 : : }
3832 [ # # ][ # # ]: 0 : if( SFX_ITEM_SET == pOldTxtNd->GetSwAttrSet()
3833 [ # # ]: 0 : .GetItemState( RES_BREAK, sal_True, &pItem2 ) )
3834 : : {
3835 [ # # ]: 0 : switch( ((SvxFmtBreakItem *)pItem2)->GetBreak() )
3836 : : {
3837 : : case SVX_BREAK_PAGE_BEFORE:
3838 : : case SVX_BREAK_PAGE_AFTER:
3839 : : case SVX_BREAK_PAGE_BOTH:
3840 [ # # ]: 0 : pFrmFmt->SetFmtAttr( *pItem2 );
3841 [ # # ]: 0 : pOldTxtNd->ResetAttr( RES_BREAK );
3842 : : default:
3843 : : ;
3844 : : }
3845 : : }
3846 : : }
3847 : :
3848 [ # # ][ # # ]: 0 : if( !bAppended && pPostIts )
3849 : : {
3850 : : // noch vorhandene PostIts in den ersten Absatz
3851 : : // der Tabelle setzen
3852 [ # # ]: 0 : InsertAttrs( *pPostIts );
3853 [ # # ]: 0 : delete pPostIts;
3854 : 0 : pPostIts = 0;
3855 : : }
3856 : :
3857 [ # # ]: 0 : pTCntxt->SetTableNode( (SwTableNode *)pNd->FindTableNode() );
3858 : :
3859 : 0 : pCurTable->SetTable( pTCntxt->GetTableNode(), pTCntxt,
3860 : : nLeftSpace, nRightSpace,
3861 : 0 : pSwTable, bForceFrame );
3862 : :
3863 : : OSL_ENSURE( !pPostIts, "ubenutzte PostIts" );
3864 : : }
3865 : : else
3866 : : {
3867 : : // noch offene Bereiche muessen noch entfernt werden
3868 [ # # ][ # # ]: 0 : if( EndSections( bParentLFStripped ) )
3869 : 0 : bParentLFStripped = sal_False;
3870 : :
3871 [ # # ]: 0 : if( pCurTable->HasParentSection() )
3872 : : {
3873 : : // dannach entfernen wir ein ggf. zu viel vorhandenen
3874 : : // leeren Absatz, aber nur, wenn er schon vor dem
3875 : : // entfernen von LFs leer war
3876 [ # # ]: 0 : if( !bParentLFStripped )
3877 [ # # ]: 0 : StripTrailingPara();
3878 : :
3879 [ # # ]: 0 : if( pPostIts )
3880 : : {
3881 : : // noch vorhandene PostIts an das Ende des jetzt
3882 : : // aktuellen Absatzes schieben
3883 [ # # ]: 0 : InsertAttrs( *pPostIts );
3884 [ # # ]: 0 : delete pPostIts;
3885 : 0 : pPostIts = 0;
3886 : : }
3887 : : }
3888 : :
3889 : 0 : SwNode const*const pNd = & pPam->GetPoint()->nNode.GetNode();
3890 : : const SwStartNode *pStNd = (pTable->bFirstCell ? pNd->FindTableNode()
3891 [ # # ][ # # ]: 0 : : pNd->FindTableBoxStartNode() );
[ # # ]
3892 : :
3893 : 0 : pCurTable->SetTable( pStNd, pTCntxt, nLeftSpace, nRightSpace );
3894 : : }
3895 : :
3896 : : // Den Kontext-Stack einfrieren, denn es koennen auch mal
3897 : : // irgendwo ausserhalb von Zellen Attribute gesetzt werden.
3898 : : // Darf nicht frueher passieren, weil eventuell noch im
3899 : : // Stack gesucht wird!!!
3900 : 0 : nContextStMin = aContexts.size();
3901 [ # # ][ # # ]: 0 : nContextStAttrMin = nContextStMin;
3902 : : }
3903 : :
3904 : : pSaveStruct = new _CellSaveStruct( *this, pCurTable, bHead,
3905 [ # # ]: 0 : bReadOptions );
3906 : :
3907 : : // ist beim ersten GetNextToken schon pending, muss bei
3908 : : // wiederaufsetzen auf jedenfall neu gelesen werden!
3909 : 0 : SaveState( 0 );
3910 : : }
3911 : :
3912 [ # # ]: 0 : if( !nToken )
3913 : 0 : nToken = GetNextToken(); // Token nach <TABLE>
3914 : :
3915 : 0 : sal_Bool bDone = sal_False;
3916 [ # # ][ # # ]: 0 : while( (IsParserWorking() && !bDone) || bPending )
[ # # ][ # # ]
3917 : : {
3918 : 0 : SaveState( nToken );
3919 : :
3920 : 0 : nToken = FilterToken( nToken );
3921 : :
3922 : : OSL_ENSURE( pPendStack || !bCallNextToken || pSaveStruct->IsInSection(),
3923 : : "Wo ist die Section gebieben?" );
3924 [ # # ][ # # ]: 0 : if( !pPendStack && bCallNextToken && pSaveStruct->IsInSection() )
[ # # ][ # # ]
3925 : : {
3926 : : // NextToken direkt aufrufen (z.B. um den Inhalt von
3927 : : // Floating-Frames oder Applets zu ignorieren)
3928 : 0 : NextToken( nToken );
3929 : : }
3930 [ # # # # : 0 : else switch( nToken )
# # # #
# ]
3931 : : {
3932 : : case HTML_TABLEHEADER_ON:
3933 : : case HTML_TABLEDATA_ON:
3934 : : case HTML_TABLEROW_ON:
3935 : : case HTML_TABLEROW_OFF:
3936 : : case HTML_THEAD_ON:
3937 : : case HTML_THEAD_OFF:
3938 : : case HTML_TFOOT_ON:
3939 : : case HTML_TFOOT_OFF:
3940 : : case HTML_TBODY_ON:
3941 : : case HTML_TBODY_OFF:
3942 : : case HTML_TABLE_OFF:
3943 : 0 : SkipToken(-1);
3944 : : case HTML_TABLEHEADER_OFF:
3945 : : case HTML_TABLEDATA_OFF:
3946 : 0 : bDone = sal_True;
3947 : 0 : break;
3948 : : case HTML_TABLE_ON:
3949 : : {
3950 : 0 : sal_Bool bTopTable = sal_False;
3951 : 0 : sal_Bool bHasToFly = sal_False;
3952 : 0 : SvxAdjust eTabAdjust = SVX_ADJUST_END;
3953 [ # # ]: 0 : if( !pPendStack )
3954 : : {
3955 : : // nur wenn eine neue Tabelle aufgemacht wird, aber
3956 : : // nicht wenn nach einem Pending in der Tabelle
3957 : : // weitergelesen wird!
3958 : 0 : pSaveStruct->pTable = pTable;
3959 : :
3960 : : // HACK: Eine Section fuer eine Tabelle anlegen, die
3961 : : // in einen Rahmen kommt.
3962 [ # # ]: 0 : if( !pSaveStruct->IsInSection() )
3963 : : {
3964 : : // Diese Schleife muss vorwartes sein, weil die
3965 : : // erste Option immer gewinnt.
3966 : 0 : sal_Bool bNeedsSection = sal_False;
3967 : 0 : const HTMLOptions& rHTMLOptions = GetOptions();
3968 [ # # ]: 0 : for (size_t i = 0; i < rHTMLOptions.size(); ++i)
3969 : : {
3970 : 0 : const HTMLOption& rOption = rHTMLOptions[i];
3971 [ # # ]: 0 : if( HTML_O_ALIGN==rOption.GetToken() )
3972 : : {
3973 : : SvxAdjust eAdjust =
3974 : : (SvxAdjust)rOption.GetEnum(
3975 : 0 : aHTMLPAlignTable, SVX_ADJUST_END );
3976 : : bNeedsSection = SVX_ADJUST_LEFT == eAdjust ||
3977 [ # # ][ # # ]: 0 : SVX_ADJUST_RIGHT == eAdjust;
3978 : 0 : break;
3979 : : }
3980 : : }
3981 [ # # ]: 0 : if( bNeedsSection )
3982 : : {
3983 : : pSaveStruct->AddContents(
3984 : 0 : InsertTableContents(bHead ) );
3985 : : }
3986 : : }
3987 : : else
3988 : : {
3989 : : // Wenn wir mitlerweile in einem Rahmen stehen
3990 : : // koennen wir erneut eine echte Tabelle aufmachen.
3991 : : // Wir erkennen das daran, dass wir keinen
3992 : : // Tabellen-Node mehr finden.
3993 : : bTopTable = (0 ==
3994 : 0 : pPam->GetPoint()->nNode.GetNode().FindTableNode());
3995 : :
3996 : : // Wenn im aktuellen Absatz Flys verankert sind,
3997 : : // muss die neue Tabelle in einen Rahmen.
3998 : 0 : bHasToFly = HasCurrentParaFlys(sal_False,sal_True);
3999 : : }
4000 : :
4001 : : // in der Zelle kann sich ein Bereich befinden!
4002 : : eTabAdjust = aAttrTab.pAdjust
4003 : 0 : ? ((const SvxAdjustItem&)aAttrTab.pAdjust->GetItem()).
4004 : : GetAdjust()
4005 [ # # ]: 0 : : SVX_ADJUST_END;
4006 : : }
4007 : :
4008 : : HTMLTable *pSubTable = BuildTable( eTabAdjust,
4009 : : bHead,
4010 : 0 : pSaveStruct->IsInSection(),
4011 : 0 : bTopTable, bHasToFly );
4012 [ # # ]: 0 : if( SVPAR_PENDING != GetStatus() )
4013 : : {
4014 : : // nur wenn die Tabelle wirklich zu Ende ist!
4015 [ # # ]: 0 : if( pSubTable )
4016 : : {
4017 : : OSL_ENSURE( pSubTable->GetTableAdjust(sal_False)!= SVX_ADJUST_LEFT &&
4018 : : pSubTable->GetTableAdjust(sal_False)!= SVX_ADJUST_RIGHT,
4019 : : "links oder rechts ausgerichtete Tabellen gehoehren in Rahmen" );
4020 : :
4021 : :
4022 : : HTMLTableCnts *pParentContents =
4023 : 0 : pSubTable->GetParentContents();
4024 [ # # ]: 0 : if( pParentContents )
4025 : : {
4026 : : OSL_ENSURE( !pSaveStruct->IsInSection(),
4027 : : "Wo ist die Section geblieben" );
4028 : :
4029 : : // Wenn jetzt keine Tabelle kommt haben wir eine
4030 : : // Section
4031 : 0 : pSaveStruct->AddContents( pParentContents );
4032 : : }
4033 : :
4034 : : const SwStartNode *pCapStNd =
4035 : 0 : pSubTable->GetCaptionStartNode();
4036 : :
4037 [ # # ]: 0 : if( pSubTable->GetContext() )
4038 : : {
4039 : : OSL_ENSURE( !pSubTable->GetContext()->GetFrmFmt(),
4040 : : "Tabelle steht im Rahmen" );
4041 : :
4042 [ # # ][ # # ]: 0 : if( pCapStNd && pSubTable->IsTopCaption() )
[ # # ]
4043 : : {
4044 : : pSaveStruct->AddContents(
4045 : 0 : new HTMLTableCnts(pCapStNd) );
4046 : : }
4047 : :
4048 : : pSaveStruct->AddContents(
4049 : 0 : new HTMLTableCnts(pSubTable) );
4050 : :
4051 [ # # ][ # # ]: 0 : if( pCapStNd && !pSubTable->IsTopCaption() )
[ # # ]
4052 : : {
4053 : : pSaveStruct->AddContents(
4054 : 0 : new HTMLTableCnts(pCapStNd) );
4055 : : }
4056 : :
4057 : : // Jetzt haben wir keine Section mehr
4058 : 0 : pSaveStruct->ClearIsInSection();
4059 : : }
4060 [ # # ]: 0 : else if( pCapStNd )
4061 : : {
4062 : : // Da wir diese Sction nicht mehr loeschen
4063 : : // koennen (sie koeente zur erster Box
4064 : : // gehoeren), fuegen wir sie ein.
4065 : : pSaveStruct->AddContents(
4066 : 0 : new HTMLTableCnts(pCapStNd) );
4067 : :
4068 : : // Jetzt haben wir keine Section mehr
4069 : 0 : pSaveStruct->ClearIsInSection();
4070 : : }
4071 : : }
4072 : :
4073 : 0 : pTable = pSaveStruct->pTable;
4074 : : }
4075 : : }
4076 : 0 : break;
4077 : :
4078 : : case HTML_NOBR_ON:
4079 : : // HACK fuer MS: Steht das <NOBR> zu beginn der Zelle?
4080 : 0 : pSaveStruct->StartNoBreak( *pPam->GetPoint() );
4081 : 0 : break;
4082 : :
4083 : : case HTML_NOBR_OFF:
4084 : 0 : pSaveStruct->EndNoBreak( *pPam->GetPoint() );
4085 : 0 : break;
4086 : :
4087 : : case HTML_COMMENT:
4088 : : // Mit Kommentar-Feldern werden Spaces nicht mehr geloescht
4089 : : // ausserdem wollen wir fuer einen Kommentar keine neue Zelle
4090 : : // anlegen !!!
4091 : 0 : NextToken( nToken );
4092 : 0 : break;
4093 : :
4094 : : case HTML_MARQUEE_ON:
4095 [ # # ]: 0 : if( !pSaveStruct->IsInSection() )
4096 : : {
4097 : : // eine neue Section anlegen, der PaM steht dann darin
4098 : : pSaveStruct->AddContents(
4099 : 0 : InsertTableContents( bHead ) );
4100 : : }
4101 : 0 : bCallNextToken = sal_True;
4102 : 0 : NewMarquee( pCurTable );
4103 : 0 : break;
4104 : :
4105 : : case HTML_TEXTTOKEN:
4106 : : // keine Section fuer einen leeren String anlegen
4107 [ # # ]: 0 : if( !pSaveStruct->IsInSection() && 1==aToken.Len() &&
[ # # # # ]
[ # # ]
4108 : 0 : ' '==aToken.GetChar(0) )
4109 : 0 : break;
4110 : : default:
4111 [ # # ]: 0 : if( !pSaveStruct->IsInSection() )
4112 : : {
4113 : : // eine neue Section anlegen, der PaM steht dann darin
4114 : : pSaveStruct->AddContents(
4115 : 0 : InsertTableContents( bHead ) );
4116 : : }
4117 : :
4118 [ # # ][ # # ]: 0 : if( IsParserWorking() || bPending )
[ # # ]
4119 : 0 : NextToken( nToken );
4120 : 0 : break;
4121 : : }
4122 : :
4123 : : OSL_ENSURE( !bPending || !pPendStack,
4124 : : "SwHTMLParser::BuildTableCell: Es gibt wieder einen Pend-Stack" );
4125 : 0 : bPending = sal_False;
4126 [ # # ]: 0 : if( IsParserWorking() )
4127 : 0 : SaveState( 0 );
4128 : :
4129 [ # # ]: 0 : if( !bDone )
4130 : 0 : nToken = GetNextToken();
4131 : : }
4132 : :
4133 [ # # ]: 0 : if( SVPAR_PENDING == GetStatus() )
4134 : : {
4135 : : pPendStack = new SwPendingStack( bHead ? HTML_TABLEHEADER_ON
4136 [ # # ]: 0 : : HTML_TABLEDATA_ON, pPendStack );
4137 : 0 : pPendStack->pData = pSaveStruct;
4138 : :
4139 : 0 : return;
4140 : : }
4141 : :
4142 : : // Falls der Inhalt der Zelle leer war, muessen wir noch einen
4143 : : // leeren Inhalt anlegen. Ausserdem legen wir einen leeren Inhalt
4144 : : // an, wenn die Zelle mit einer Tabelle aufgehoert hat und keine
4145 : : // COL-Tags hatte (sonst wurde sie wahrscheinlich von uns exportiert,
4146 : : // und dann wollen wir natuerlich keinen zusaetzlichen Absatz haben).
4147 [ # # # # : 0 : if( !pSaveStruct->GetFirstContents() ||
# # ][ # # ]
4148 : 0 : (!pSaveStruct->IsInSection() && !pCurTable->HasColTags()) )
4149 : : {
4150 : : OSL_ENSURE( pSaveStruct->GetFirstContents() ||
4151 : : !pSaveStruct->IsInSection(),
4152 : : "Section oder nicht, das ist hier die Frage" );
4153 : : const SwStartNode *pStNd =
4154 : 0 : InsertTableSection( static_cast< sal_uInt16 >(pSaveStruct->IsHeaderCell()
4155 : : ? RES_POOLCOLL_TABLE_HDLN
4156 [ # # ][ # # ]: 0 : : RES_POOLCOLL_TABLE ));
4157 : 0 : const SwEndNode *pEndNd = pStNd->EndOfSectionNode();
4158 [ # # ][ # # ]: 0 : SwCntntNode *pCNd = pDoc->GetNodes()[pEndNd->GetIndex()-1] ->GetCntntNode();
4159 : : //Added defaults to CJK and CTL
4160 [ # # ]: 0 : SvxFontHeightItem aFontHeight( 40, 100, RES_CHRATR_FONTSIZE );
4161 [ # # ]: 0 : pCNd->SetAttr( aFontHeight );
4162 [ # # ]: 0 : SvxFontHeightItem aFontHeightCJK( 40, 100, RES_CHRATR_CJK_FONTSIZE );
4163 [ # # ]: 0 : pCNd->SetAttr( aFontHeightCJK );
4164 [ # # ]: 0 : SvxFontHeightItem aFontHeightCTL( 40, 100, RES_CHRATR_CTL_FONTSIZE );
4165 [ # # ]: 0 : pCNd->SetAttr( aFontHeightCTL );
4166 : :
4167 [ # # ]: 0 : pSaveStruct->AddContents( new HTMLTableCnts(pStNd) );
4168 [ # # ][ # # ]: 0 : pSaveStruct->ClearIsInSection();
[ # # ]
4169 : : }
4170 : :
4171 [ # # ]: 0 : if( pSaveStruct->IsInSection() )
4172 : : {
4173 : 0 : pSaveStruct->CheckNoBreak( *pPam->GetPoint(), pDoc );
4174 : :
4175 : : // Alle noch offenen Kontexte beenden. Wir nehmen hier
4176 : : // AttrMin, weil nContxtStMin evtl. veraendert wurde.
4177 : : // Da es durch EndContext wieder restauriert wird, geht das.
4178 [ # # ]: 0 : while( (sal_uInt16)aContexts.size() > nContextStAttrMin+1 )
4179 : : {
4180 : 0 : _HTMLAttrContext *pCntxt = PopContext();
4181 : 0 : EndContext( pCntxt );
4182 [ # # ]: 0 : delete pCntxt;
4183 : : }
4184 : :
4185 : : // LFs am Absatz-Ende entfernen
4186 [ # # ][ # # ]: 0 : if( StripTrailingLF()==0 && !pPam->GetPoint()->nContent.GetIndex() )
[ # # ]
4187 : 0 : StripTrailingPara();
4188 : :
4189 : : // falls fuer die Zelle eine Ausrichtung gesetzt wurde, muessen
4190 : : // wir die beenden
4191 : 0 : _HTMLAttrContext *pCntxt = PopContext();
4192 : 0 : EndContext( pCntxt );
4193 [ # # ]: 0 : delete pCntxt;
4194 : : }
4195 : : else
4196 : : {
4197 : : // Alle noch offenen Kontexte beenden
4198 [ # # ]: 0 : while( aContexts.size() > nContextStAttrMin )
4199 : : {
4200 : 0 : _HTMLAttrContext *pCntxt = PopContext();
4201 : 0 : ClearContext( pCntxt );
4202 [ # # ]: 0 : delete pCntxt;
4203 : : }
4204 : : }
4205 : :
4206 : : // auch eine Numerierung muss beendet werden
4207 : 0 : GetNumInfo().Clear();
4208 : :
4209 : 0 : SetAttr( sal_False );
4210 : :
4211 : 0 : pSaveStruct->InsertCell( *this, pCurTable );
4212 : :
4213 : : // wir stehen jetzt (wahrschenlich) vor <TH>, <TD>, <TR> oder </TABLE>
4214 [ # # ]: 0 : delete pSaveStruct;
4215 : : }
4216 : :
4217 : :
4218 [ # # ]: 0 : class _RowSaveStruct : public SwPendingStackData
4219 : : {
4220 : : public:
4221 : : SvxAdjust eAdjust;
4222 : : sal_Int16 eVertOri;
4223 : : sal_Bool bHasCells;
4224 : :
4225 : 0 : _RowSaveStruct() :
4226 : 0 : eAdjust( SVX_ADJUST_END ), eVertOri( text::VertOrientation::TOP ), bHasCells( sal_False )
4227 : 0 : {}
4228 : : };
4229 : :
4230 : :
4231 : 0 : void SwHTMLParser::BuildTableRow( HTMLTable *pCurTable, sal_Bool bReadOptions,
4232 : : SvxAdjust eGrpAdjust,
4233 : : sal_Int16 eGrpVertOri )
4234 : : {
4235 : : // <TR> wurde bereist gelesen
4236 : :
4237 [ # # ][ # # ]: 0 : if( !IsParserWorking() && !pPendStack )
[ # # ]
4238 : 0 : return;
4239 : :
4240 : 0 : int nToken = 0;
4241 : : _RowSaveStruct* pSaveStruct;
4242 : :
4243 : 0 : sal_Bool bPending = sal_False;
4244 [ # # ]: 0 : if( pPendStack )
4245 : : {
4246 : 0 : pSaveStruct = (_RowSaveStruct*)pPendStack->pData;
4247 : :
4248 : 0 : SwPendingStack* pTmp = pPendStack->pNext;
4249 : 0 : delete pPendStack;
4250 : 0 : pPendStack = pTmp;
4251 [ # # ]: 0 : nToken = pPendStack ? pPendStack->nToken : GetSaveToken();
4252 [ # # ][ # # ]: 0 : bPending = SVPAR_ERROR == eState && pPendStack != 0;
4253 : :
4254 : 0 : SaveState( nToken );
4255 : : }
4256 : : else
4257 : : {
4258 : 0 : SvxAdjust eAdjust = eGrpAdjust;
4259 : 0 : sal_Int16 eVertOri = eGrpVertOri;
4260 : 0 : Color aBGColor;
4261 [ # # ][ # # ]: 0 : String aBGImage, aStyle, aId, aClass;
[ # # ][ # # ]
4262 : 0 : sal_Bool bBGColor = sal_False;
4263 [ # # ]: 0 : pSaveStruct = new _RowSaveStruct;
4264 : :
4265 [ # # ]: 0 : if( bReadOptions )
4266 : : {
4267 [ # # ]: 0 : const HTMLOptions& rHTMLOptions = GetOptions();
4268 [ # # ]: 0 : for (size_t i = rHTMLOptions.size(); i; )
4269 : : {
4270 [ # # ]: 0 : const HTMLOption& rOption = rHTMLOptions[--i];
4271 [ # # # # : 0 : switch( rOption.GetToken() )
# # # # ]
4272 : : {
4273 : : case HTML_O_ID:
4274 [ # # ]: 0 : aId = rOption.GetString();
4275 : 0 : break;
4276 : : case HTML_O_ALIGN:
4277 : : eAdjust = (SvxAdjust)rOption.GetEnum(
4278 [ # # ]: 0 : aHTMLPAlignTable, static_cast< sal_uInt16 >(eAdjust) );
4279 : 0 : break;
4280 : : case HTML_O_VALIGN:
4281 : : eVertOri = rOption.GetEnum(
4282 [ # # ]: 0 : aHTMLTblVAlignTable, eVertOri );
4283 : 0 : break;
4284 : : case HTML_O_BGCOLOR:
4285 : : // Leere BGCOLOR bei <TABLE>, <TR> und <TD>/<TH> wie Netsc.
4286 : : // ignorieren, bei allen anderen Tags *wirklich* nicht.
4287 [ # # ]: 0 : if( rOption.GetString().Len() )
4288 : : {
4289 [ # # ]: 0 : rOption.GetColor( aBGColor );
4290 : 0 : bBGColor = sal_True;
4291 : : }
4292 : 0 : break;
4293 : : case HTML_O_BACKGROUND:
4294 [ # # ]: 0 : aBGImage = rOption.GetString();
4295 : 0 : break;
4296 : : case HTML_O_STYLE:
4297 [ # # ]: 0 : aStyle = rOption.GetString();
4298 : 0 : break;
4299 : : case HTML_O_CLASS:
4300 [ # # ]: 0 : aClass= rOption.GetString();
4301 : 0 : break;
4302 : : }
4303 : : }
4304 : : }
4305 : :
4306 [ # # ]: 0 : if( aId.Len() )
4307 [ # # ]: 0 : InsertBookmark( aId );
4308 : :
4309 : : SvxBrushItem *pBrushItem =
4310 : : CreateBrushItem( bBGColor ? &aBGColor : 0, aBGImage, aStyle,
4311 [ # # ][ # # ]: 0 : aId, aClass );
4312 [ # # ]: 0 : pCurTable->OpenRow( eAdjust, eVertOri, pBrushItem );
4313 : : // ist beim ersten GetNextToken schon pending, muss bei
4314 : : // wiederaufsetzen auf jedenfall neu gelesen werden!
4315 [ # # ][ # # ]: 0 : SaveState( 0 );
[ # # ][ # # ]
[ # # ]
4316 : : }
4317 : :
4318 [ # # ]: 0 : if( !nToken )
4319 : 0 : nToken = GetNextToken(); // naechstes Token
4320 : :
4321 : 0 : sal_Bool bDone = sal_False;
4322 [ # # ][ # # ]: 0 : while( (IsParserWorking() && !bDone) || bPending )
[ # # ][ # # ]
4323 : : {
4324 : 0 : SaveState( nToken );
4325 : :
4326 : 0 : nToken = FilterToken( nToken );
4327 : :
4328 : : OSL_ENSURE( pPendStack || !bCallNextToken ||
4329 : : pCurTable->GetContext() || pCurTable->HasParentSection(),
4330 : : "Wo ist die Section gebieben?" );
4331 [ # # # # : 0 : if( !pPendStack && bCallNextToken &&
# # ][ # # ]
[ # # ]
4332 : 0 : (pCurTable->GetContext() || pCurTable->HasParentSection()) )
4333 : : {
4334 : : // NextToken direkt aufrufen (z.B. um den Inhalt von
4335 : : // Floating-Frames oder Applets zu ignorieren)
4336 : 0 : NextToken( nToken );
4337 : : }
4338 [ # # # # : 0 : else switch( nToken )
# # # # #
# # # # ]
4339 : : {
4340 : : case HTML_TABLE_ON:
4341 [ # # ]: 0 : if( !pCurTable->GetContext() )
4342 : : {
4343 : 0 : SkipToken( -1 );
4344 : 0 : bDone = sal_True;
4345 : : }
4346 : :
4347 : 0 : break;
4348 : : case HTML_TABLEROW_ON:
4349 : : case HTML_THEAD_ON:
4350 : : case HTML_THEAD_OFF:
4351 : : case HTML_TBODY_ON:
4352 : : case HTML_TBODY_OFF:
4353 : : case HTML_TFOOT_ON:
4354 : : case HTML_TFOOT_OFF:
4355 : : case HTML_TABLE_OFF:
4356 : 0 : SkipToken( -1 );
4357 : : case HTML_TABLEROW_OFF:
4358 : 0 : bDone = sal_True;
4359 : 0 : break;
4360 : : case HTML_TABLEHEADER_ON:
4361 : : case HTML_TABLEDATA_ON:
4362 : 0 : BuildTableCell( pCurTable, sal_True, HTML_TABLEHEADER_ON==nToken );
4363 [ # # ]: 0 : if( SVPAR_PENDING != GetStatus() )
4364 : : {
4365 : 0 : pSaveStruct->bHasCells = sal_True;
4366 : 0 : bDone = pTable->IsOverflowing();
4367 : : }
4368 : 0 : break;
4369 : : case HTML_CAPTION_ON:
4370 : 0 : BuildTableCaption( pCurTable );
4371 : 0 : bDone = pTable->IsOverflowing();
4372 : 0 : break;
4373 : : case HTML_CAPTION_OFF:
4374 : : case HTML_TABLEHEADER_OFF:
4375 : : case HTML_TABLEDATA_OFF:
4376 : : case HTML_COLGROUP_ON:
4377 : : case HTML_COLGROUP_OFF:
4378 : : case HTML_COL_ON:
4379 : : case HTML_COL_OFF:
4380 : : // wo keine Zelle anfing kann auch keine aufhoehren, oder?
4381 : : // und die ganzen anderen Tokens haben hier auch nicht zu
4382 : : // suchen und machen nur die Tabelle kaputt
4383 : 0 : break;
4384 : : case HTML_MULTICOL_ON:
4385 : : // spaltige Rahmen koennen wir hier leider nicht einguegen
4386 : 0 : break;
4387 : : case HTML_FORM_ON:
4388 : 0 : NewForm( sal_False ); // keinen neuen Absatz aufmachen!
4389 : 0 : break;
4390 : : case HTML_FORM_OFF:
4391 : 0 : EndForm( sal_False ); // keinen neuen Absatz aufmachen!
4392 : 0 : break;
4393 : : case HTML_COMMENT:
4394 : 0 : NextToken( nToken );
4395 : 0 : break;
4396 : : case HTML_MAP_ON:
4397 : : // eine Image-Map fuegt nichts ein, deshalb koennen wir sie
4398 : : // problemlos auch ohne Zelle parsen
4399 : 0 : NextToken( nToken );
4400 : 0 : break;
4401 : : case HTML_TEXTTOKEN:
4402 [ # # # # : 0 : if( (pCurTable->GetContext() ||
# # # # ]
[ # # ]
4403 : 0 : !pCurTable->HasParentSection()) &&
4404 : 0 : 1==aToken.Len() && ' '==aToken.GetChar(0) )
4405 : 0 : break;
4406 : : default:
4407 : 0 : pCurTable->MakeParentContents();
4408 : 0 : NextToken( nToken );
4409 : 0 : break;
4410 : : }
4411 : :
4412 : : OSL_ENSURE( !bPending || !pPendStack,
4413 : : "SwHTMLParser::BuildTableRow: Es gibt wieder einen Pend-Stack" );
4414 : 0 : bPending = sal_False;
4415 [ # # ]: 0 : if( IsParserWorking() )
4416 : 0 : SaveState( 0 );
4417 : :
4418 [ # # ]: 0 : if( !bDone )
4419 : 0 : nToken = GetNextToken();
4420 : : }
4421 : :
4422 [ # # ]: 0 : if( SVPAR_PENDING == GetStatus() )
4423 : : {
4424 : 0 : pPendStack = new SwPendingStack( HTML_TABLEROW_ON, pPendStack );
4425 : 0 : pPendStack->pData = pSaveStruct;
4426 : : }
4427 : : else
4428 : : {
4429 : 0 : pCurTable->CloseRow( !pSaveStruct->bHasCells );
4430 [ # # ]: 0 : delete pSaveStruct;
4431 : : }
4432 : :
4433 : : // wir stehen jetzt (wahrscheinlich) vor <TR> oder </TABLE>
4434 : : }
4435 : :
4436 : 0 : void SwHTMLParser::BuildTableSection( HTMLTable *pCurTable,
4437 : : sal_Bool bReadOptions,
4438 : : sal_Bool bHead )
4439 : : {
4440 : : // <THEAD>, <TBODY> bzw. <TFOOT> wurde bereits gelesen
4441 [ # # ][ # # ]: 0 : if( !IsParserWorking() && !pPendStack )
[ # # ]
4442 : 0 : return;
4443 : :
4444 : 0 : int nToken = 0;
4445 : 0 : sal_Bool bPending = sal_False;
4446 : : _RowSaveStruct* pSaveStruct;
4447 : :
4448 [ # # ]: 0 : if( pPendStack )
4449 : : {
4450 : 0 : pSaveStruct = (_RowSaveStruct*)pPendStack->pData;
4451 : :
4452 : 0 : SwPendingStack* pTmp = pPendStack->pNext;
4453 : 0 : delete pPendStack;
4454 : 0 : pPendStack = pTmp;
4455 [ # # ]: 0 : nToken = pPendStack ? pPendStack->nToken : GetSaveToken();
4456 [ # # ][ # # ]: 0 : bPending = SVPAR_ERROR == eState && pPendStack != 0;
4457 : :
4458 : 0 : SaveState( nToken );
4459 : : }
4460 : : else
4461 : : {
4462 : 0 : pSaveStruct = new _RowSaveStruct;
4463 : :
4464 [ # # ]: 0 : if( bReadOptions )
4465 : : {
4466 : 0 : const HTMLOptions& rHTMLOptions = GetOptions();
4467 [ # # ]: 0 : for (size_t i = rHTMLOptions.size(); i; )
4468 : : {
4469 : 0 : const HTMLOption& rOption = rHTMLOptions[--i];
4470 [ # # # # ]: 0 : switch( rOption.GetToken() )
4471 : : {
4472 : : case HTML_O_ID:
4473 : 0 : InsertBookmark( rOption.GetString() );
4474 : 0 : break;
4475 : : case HTML_O_ALIGN:
4476 : : pSaveStruct->eAdjust =
4477 : : (SvxAdjust)rOption.GetEnum( aHTMLPAlignTable,
4478 : 0 : static_cast< sal_uInt16 >(pSaveStruct->eAdjust) );
4479 : 0 : break;
4480 : : case HTML_O_VALIGN:
4481 : : pSaveStruct->eVertOri =
4482 : : rOption.GetEnum( aHTMLTblVAlignTable,
4483 : 0 : pSaveStruct->eVertOri );
4484 : 0 : break;
4485 : : }
4486 : : }
4487 : : }
4488 : :
4489 : : // ist beim ersten GetNextToken schon pending, muss bei
4490 : : // wiederaufsetzen auf jedenfall neu gelesen werden!
4491 : 0 : SaveState( 0 );
4492 : : }
4493 : :
4494 [ # # ]: 0 : if( !nToken )
4495 : 0 : nToken = GetNextToken(); // naechstes Token
4496 : :
4497 : 0 : sal_Bool bDone = sal_False;
4498 [ # # ][ # # ]: 0 : while( (IsParserWorking() && !bDone) || bPending )
[ # # ][ # # ]
4499 : : {
4500 : 0 : SaveState( nToken );
4501 : :
4502 : 0 : nToken = FilterToken( nToken );
4503 : :
4504 : : OSL_ENSURE( pPendStack || !bCallNextToken ||
4505 : : pCurTable->GetContext() || pCurTable->HasParentSection(),
4506 : : "Wo ist die Section gebieben?" );
4507 [ # # # # : 0 : if( !pPendStack && bCallNextToken &&
# # ][ # # ]
[ # # ]
4508 : 0 : (pCurTable->GetContext() || pCurTable->HasParentSection()) )
4509 : : {
4510 : : // NextToken direkt aufrufen (z.B. um den Inhalt von
4511 : : // Floating-Frames oder Applets zu ignorieren)
4512 : 0 : NextToken( nToken );
4513 : : }
4514 [ # # # # : 0 : else switch( nToken )
# # # # #
# # # ]
4515 : : {
4516 : : case HTML_TABLE_ON:
4517 [ # # ]: 0 : if( !pCurTable->GetContext() )
4518 : : {
4519 : 0 : SkipToken( -1 );
4520 : 0 : bDone = sal_True;
4521 : : }
4522 : :
4523 : 0 : break;
4524 : : case HTML_THEAD_ON:
4525 : : case HTML_TFOOT_ON:
4526 : : case HTML_TBODY_ON:
4527 : : case HTML_TABLE_OFF:
4528 : 0 : SkipToken( -1 );
4529 : : case HTML_THEAD_OFF:
4530 : : case HTML_TBODY_OFF:
4531 : : case HTML_TFOOT_OFF:
4532 : 0 : bDone = sal_True;
4533 : 0 : break;
4534 : : case HTML_CAPTION_ON:
4535 : 0 : BuildTableCaption( pCurTable );
4536 : 0 : bDone = pTable->IsOverflowing();
4537 : 0 : break;
4538 : : case HTML_CAPTION_OFF:
4539 : 0 : break;
4540 : : case HTML_TABLEHEADER_ON:
4541 : : case HTML_TABLEDATA_ON:
4542 : 0 : SkipToken( -1 );
4543 : : BuildTableRow( pCurTable, sal_False, pSaveStruct->eAdjust,
4544 : 0 : pSaveStruct->eVertOri );
4545 : 0 : bDone = pTable->IsOverflowing();
4546 : 0 : break;
4547 : : case HTML_TABLEROW_ON:
4548 : : BuildTableRow( pCurTable, sal_True, pSaveStruct->eAdjust,
4549 : 0 : pSaveStruct->eVertOri );
4550 : 0 : bDone = pTable->IsOverflowing();
4551 : 0 : break;
4552 : : case HTML_MULTICOL_ON:
4553 : : // spaltige Rahmen koennen wir hier leider nicht einguegen
4554 : 0 : break;
4555 : : case HTML_FORM_ON:
4556 : 0 : NewForm( sal_False ); // keinen neuen Absatz aufmachen!
4557 : 0 : break;
4558 : : case HTML_FORM_OFF:
4559 : 0 : EndForm( sal_False ); // keinen neuen Absatz aufmachen!
4560 : 0 : break;
4561 : : case HTML_TEXTTOKEN:
4562 : : // Blank-Strings sind Folge von CR+LF und kein Text
4563 [ # # # # : 0 : if( (pCurTable->GetContext() ||
# # # # ]
[ # # ]
4564 : 0 : !pCurTable->HasParentSection()) &&
4565 : 0 : 1==aToken.Len() && ' '==aToken.GetChar(0) )
4566 : 0 : break;
4567 : : default:
4568 : 0 : pCurTable->MakeParentContents();
4569 : 0 : NextToken( nToken );
4570 : : }
4571 : :
4572 : : OSL_ENSURE( !bPending || !pPendStack,
4573 : : "SwHTMLParser::BuildTableSection: Es gibt wieder einen Pend-Stack" );
4574 : 0 : bPending = sal_False;
4575 [ # # ]: 0 : if( IsParserWorking() )
4576 : 0 : SaveState( 0 );
4577 : :
4578 [ # # ]: 0 : if( !bDone )
4579 : 0 : nToken = GetNextToken();
4580 : : }
4581 : :
4582 [ # # ]: 0 : if( SVPAR_PENDING == GetStatus() )
4583 : : {
4584 : : pPendStack = new SwPendingStack( bHead ? HTML_THEAD_ON
4585 [ # # ]: 0 : : HTML_TBODY_ON, pPendStack );
4586 : 0 : pPendStack->pData = pSaveStruct;
4587 : : }
4588 : : else
4589 : : {
4590 : 0 : pCurTable->CloseSection( bHead );
4591 [ # # ]: 0 : delete pSaveStruct;
4592 : : }
4593 : :
4594 : : // now we stand (perhaps) in front of <TBODY>,... or </TABLE>
4595 : : }
4596 : :
4597 [ # # ]: 0 : struct _TblColGrpSaveStruct : public SwPendingStackData
4598 : : {
4599 : : sal_uInt16 nColGrpSpan;
4600 : : sal_uInt16 nColGrpWidth;
4601 : : sal_Bool bRelColGrpWidth;
4602 : : SvxAdjust eColGrpAdjust;
4603 : : sal_Int16 eColGrpVertOri;
4604 : :
4605 : : inline _TblColGrpSaveStruct();
4606 : :
4607 : :
4608 : : inline void CloseColGroup( HTMLTable *pTable );
4609 : : };
4610 : :
4611 : 0 : inline _TblColGrpSaveStruct::_TblColGrpSaveStruct() :
4612 : : nColGrpSpan( 1 ), nColGrpWidth( 0 ),
4613 : : bRelColGrpWidth( sal_False ), eColGrpAdjust( SVX_ADJUST_END ),
4614 : 0 : eColGrpVertOri( text::VertOrientation::TOP )
4615 : 0 : {}
4616 : :
4617 : :
4618 : 0 : inline void _TblColGrpSaveStruct::CloseColGroup( HTMLTable *pTable )
4619 : : {
4620 : : pTable->CloseColGroup( nColGrpSpan, nColGrpWidth,
4621 : 0 : bRelColGrpWidth, eColGrpAdjust, eColGrpVertOri );
4622 : 0 : }
4623 : :
4624 : 0 : void SwHTMLParser::BuildTableColGroup( HTMLTable *pCurTable,
4625 : : sal_Bool bReadOptions )
4626 : : {
4627 : : // <COLGROUP> wurde bereits gelesen, wenn bReadOptions
4628 : :
4629 [ # # ][ # # ]: 0 : if( !IsParserWorking() && !pPendStack )
[ # # ]
4630 : 0 : return;
4631 : :
4632 : 0 : int nToken = 0;
4633 : 0 : sal_Bool bPending = sal_False;
4634 : : _TblColGrpSaveStruct* pSaveStruct;
4635 : :
4636 [ # # ]: 0 : if( pPendStack )
4637 : : {
4638 : 0 : pSaveStruct = (_TblColGrpSaveStruct*)pPendStack->pData;
4639 : :
4640 : 0 : SwPendingStack* pTmp = pPendStack->pNext;
4641 : 0 : delete pPendStack;
4642 : 0 : pPendStack = pTmp;
4643 [ # # ]: 0 : nToken = pPendStack ? pPendStack->nToken : GetSaveToken();
4644 [ # # ][ # # ]: 0 : bPending = SVPAR_ERROR == eState && pPendStack != 0;
4645 : :
4646 : 0 : SaveState( nToken );
4647 : : }
4648 : : else
4649 : : {
4650 : :
4651 : 0 : pSaveStruct = new _TblColGrpSaveStruct;
4652 [ # # ]: 0 : if( bReadOptions )
4653 : : {
4654 : 0 : const HTMLOptions& rColGrpOptions = GetOptions();
4655 [ # # ]: 0 : for (size_t i = rColGrpOptions.size(); i; )
4656 : : {
4657 : 0 : const HTMLOption& rOption = rColGrpOptions[--i];
4658 [ # # # # : 0 : switch( rOption.GetToken() )
# # ]
4659 : : {
4660 : : case HTML_O_ID:
4661 : 0 : InsertBookmark( rOption.GetString() );
4662 : 0 : break;
4663 : : case HTML_O_SPAN:
4664 : 0 : pSaveStruct->nColGrpSpan = (sal_uInt16)rOption.GetNumber();
4665 : 0 : break;
4666 : : case HTML_O_WIDTH:
4667 : 0 : pSaveStruct->nColGrpWidth = (sal_uInt16)rOption.GetNumber();
4668 : : pSaveStruct->bRelColGrpWidth =
4669 : 0 : (rOption.GetString().Search('*') != STRING_NOTFOUND);
4670 : 0 : break;
4671 : : case HTML_O_ALIGN:
4672 : : pSaveStruct->eColGrpAdjust =
4673 : : (SvxAdjust)rOption.GetEnum( aHTMLPAlignTable,
4674 : 0 : static_cast< sal_uInt16 >(pSaveStruct->eColGrpAdjust) );
4675 : 0 : break;
4676 : : case HTML_O_VALIGN:
4677 : : pSaveStruct->eColGrpVertOri =
4678 : : rOption.GetEnum( aHTMLTblVAlignTable,
4679 : 0 : pSaveStruct->eColGrpVertOri );
4680 : 0 : break;
4681 : : }
4682 : : }
4683 : : }
4684 : : // ist beim ersten GetNextToken schon pending, muss bei
4685 : : // wiederaufsetzen auf jedenfall neu gelesen werden!
4686 : 0 : SaveState( 0 );
4687 : : }
4688 : :
4689 [ # # ]: 0 : if( !nToken )
4690 : 0 : nToken = GetNextToken(); // naechstes Token
4691 : :
4692 : 0 : sal_Bool bDone = sal_False;
4693 [ # # ][ # # ]: 0 : while( (IsParserWorking() && !bDone) || bPending )
[ # # ][ # # ]
4694 : : {
4695 : 0 : SaveState( nToken );
4696 : :
4697 : 0 : nToken = FilterToken( nToken );
4698 : :
4699 : : OSL_ENSURE( pPendStack || !bCallNextToken ||
4700 : : pCurTable->GetContext() || pCurTable->HasParentSection(),
4701 : : "Wo ist die Section gebieben?" );
4702 [ # # # # : 0 : if( !pPendStack && bCallNextToken &&
# # ][ # # ]
[ # # ]
4703 : 0 : (pCurTable->GetContext() || pCurTable->HasParentSection()) )
4704 : : {
4705 : : // NextToken direkt aufrufen (z.B. um den Inhalt von
4706 : : // Floating-Frames oder Applets zu ignorieren)
4707 : 0 : NextToken( nToken );
4708 : : }
4709 [ # # # # : 0 : else switch( nToken )
# # # # ]
4710 : : {
4711 : : case HTML_TABLE_ON:
4712 [ # # ]: 0 : if( !pCurTable->GetContext() )
4713 : : {
4714 : 0 : SkipToken( -1 );
4715 : 0 : bDone = sal_True;
4716 : : }
4717 : :
4718 : 0 : break;
4719 : : case HTML_COLGROUP_ON:
4720 : : case HTML_THEAD_ON:
4721 : : case HTML_TFOOT_ON:
4722 : : case HTML_TBODY_ON:
4723 : : case HTML_TABLEROW_ON:
4724 : : case HTML_TABLE_OFF:
4725 : 0 : SkipToken( -1 );
4726 : : case HTML_COLGROUP_OFF:
4727 : 0 : bDone = sal_True;
4728 : 0 : break;
4729 : : case HTML_COL_ON:
4730 : : {
4731 : 0 : sal_uInt16 nColSpan = 1;
4732 : 0 : sal_uInt16 nColWidth = pSaveStruct->nColGrpWidth;
4733 : 0 : sal_Bool bRelColWidth = pSaveStruct->bRelColGrpWidth;
4734 : 0 : SvxAdjust eColAdjust = pSaveStruct->eColGrpAdjust;
4735 : 0 : sal_Int16 eColVertOri = pSaveStruct->eColGrpVertOri;
4736 : :
4737 : 0 : const HTMLOptions& rColOptions = GetOptions();
4738 [ # # ]: 0 : for (size_t i = rColOptions.size(); i; )
4739 : : {
4740 : 0 : const HTMLOption& rOption = rColOptions[--i];
4741 [ # # # # : 0 : switch( rOption.GetToken() )
# # ]
4742 : : {
4743 : : case HTML_O_ID:
4744 : 0 : InsertBookmark( rOption.GetString() );
4745 : 0 : break;
4746 : : case HTML_O_SPAN:
4747 : 0 : nColSpan = (sal_uInt16)rOption.GetNumber();
4748 : 0 : break;
4749 : : case HTML_O_WIDTH:
4750 : 0 : nColWidth = (sal_uInt16)rOption.GetNumber();
4751 : : bRelColWidth =
4752 : 0 : (rOption.GetString().Search('*') != STRING_NOTFOUND);
4753 : 0 : break;
4754 : : case HTML_O_ALIGN:
4755 : : eColAdjust =
4756 : : (SvxAdjust)rOption.GetEnum( aHTMLPAlignTable,
4757 : 0 : static_cast< sal_uInt16 >(eColAdjust) );
4758 : 0 : break;
4759 : : case HTML_O_VALIGN:
4760 : : eColVertOri =
4761 : : rOption.GetEnum( aHTMLTblVAlignTable,
4762 : 0 : eColVertOri );
4763 : 0 : break;
4764 : : }
4765 : : }
4766 : : pCurTable->InsertCol( nColSpan, nColWidth, bRelColWidth,
4767 : 0 : eColAdjust, eColVertOri );
4768 : :
4769 : : // die Angaben in <COLGRP> sollen ignoriert werden, wenn
4770 : : // <COL>-Elemente existieren
4771 : 0 : pSaveStruct->nColGrpSpan = 0;
4772 : : }
4773 : 0 : break;
4774 : : case HTML_COL_OFF:
4775 : 0 : break; // Ignorieren
4776 : : case HTML_MULTICOL_ON:
4777 : : // spaltige Rahmen koennen wir hier leider nicht einguegen
4778 : 0 : break;
4779 : : case HTML_TEXTTOKEN:
4780 [ # # # # : 0 : if( (pCurTable->GetContext() ||
# # # # ]
[ # # ]
4781 : 0 : !pCurTable->HasParentSection()) &&
4782 : 0 : 1==aToken.Len() && ' '==aToken.GetChar(0) )
4783 : 0 : break;
4784 : : default:
4785 : 0 : pCurTable->MakeParentContents();
4786 : 0 : NextToken( nToken );
4787 : : }
4788 : :
4789 : : OSL_ENSURE( !bPending || !pPendStack,
4790 : : "SwHTMLParser::BuildTableColGrp: Es gibt wieder einen Pend-Stack" );
4791 : 0 : bPending = sal_False;
4792 [ # # ]: 0 : if( IsParserWorking() )
4793 : 0 : SaveState( 0 );
4794 : :
4795 [ # # ]: 0 : if( !bDone )
4796 : 0 : nToken = GetNextToken();
4797 : : }
4798 : :
4799 [ # # ]: 0 : if( SVPAR_PENDING == GetStatus() )
4800 : : {
4801 : 0 : pPendStack = new SwPendingStack( HTML_COL_ON, pPendStack );
4802 : 0 : pPendStack->pData = pSaveStruct;
4803 : : }
4804 : : else
4805 : : {
4806 : 0 : pSaveStruct->CloseColGroup( pCurTable );
4807 [ # # ]: 0 : delete pSaveStruct;
4808 : : }
4809 : : }
4810 : :
4811 : : class _CaptionSaveStruct : public _SectionSaveStruct
4812 : : {
4813 : : SwPosition aSavePos;
4814 : : SwHTMLNumRuleInfo aNumRuleInfo; // gueltige Numerierung
4815 : :
4816 : : public:
4817 : :
4818 : : _HTMLAttrTable aAttrTab; // und die Attribute
4819 : :
4820 : 0 : _CaptionSaveStruct( SwHTMLParser& rParser, const SwPosition& rPos ) :
4821 [ # # ]: 0 : _SectionSaveStruct( rParser ), aSavePos( rPos )
4822 : : {
4823 [ # # ]: 0 : rParser.SaveAttrTab( aAttrTab );
4824 : :
4825 : : // Die aktuelle Numerierung wurde gerettet und muss nur
4826 : : // noch beendet werden.
4827 : 0 : aNumRuleInfo.Set( rParser.GetNumInfo() );
4828 : 0 : rParser.GetNumInfo().Clear();
4829 : 0 : }
4830 : :
4831 : 0 : const SwPosition& GetPos() const { return aSavePos; }
4832 : :
4833 : 0 : void RestoreAll( SwHTMLParser& rParser )
4834 : : {
4835 : : // Die alten Stack wiederherstellen
4836 : 0 : Restore( rParser );
4837 : :
4838 : : // Die alte Attribut-Tabelle wiederherstellen
4839 : 0 : rParser.RestoreAttrTab( aAttrTab );
4840 : :
4841 : : // Die alte Numerierung wieder aufspannen
4842 : 0 : rParser.GetNumInfo().Set( aNumRuleInfo );
4843 : 0 : }
4844 : :
4845 : : virtual ~_CaptionSaveStruct();
4846 : : };
4847 : :
4848 [ # # ]: 0 : _CaptionSaveStruct::~_CaptionSaveStruct()
4849 [ # # ]: 0 : {}
4850 : :
4851 : 0 : void SwHTMLParser::BuildTableCaption( HTMLTable *pCurTable )
4852 : : {
4853 : : // <CAPTION> wurde bereits gelesen
4854 : :
4855 [ # # ][ # # ]: 0 : if( !IsParserWorking() && !pPendStack )
[ # # ]
4856 : 0 : return;
4857 : :
4858 : 0 : int nToken = 0;
4859 : : _CaptionSaveStruct* pSaveStruct;
4860 : :
4861 [ # # ]: 0 : if( pPendStack )
4862 : : {
4863 : 0 : pSaveStruct = (_CaptionSaveStruct*)pPendStack->pData;
4864 : :
4865 : 0 : SwPendingStack* pTmp = pPendStack->pNext;
4866 : 0 : delete pPendStack;
4867 : 0 : pPendStack = pTmp;
4868 [ # # ]: 0 : nToken = pPendStack ? pPendStack->nToken : GetSaveToken();
4869 : : OSL_ENSURE( !pPendStack, "Wo kommt hier ein Pending-Stack her?" );
4870 : :
4871 : 0 : SaveState( nToken );
4872 : : }
4873 : : else
4874 : : {
4875 [ # # ]: 0 : if( pTable->IsOverflowing() )
4876 : : {
4877 : 0 : SaveState( 0 );
4878 : 0 : return;
4879 : : }
4880 : :
4881 : 0 : sal_Bool bTop = sal_True;
4882 : 0 : const HTMLOptions& rHTMLOptions = GetOptions();
4883 [ # # ]: 0 : for ( size_t i = rHTMLOptions.size(); i; )
4884 : : {
4885 : 0 : const HTMLOption& rOption = rHTMLOptions[--i];
4886 [ # # ]: 0 : if( HTML_O_ALIGN == rOption.GetToken() )
4887 : : {
4888 [ # # ]: 0 : if( rOption.GetString().EqualsIgnoreCaseAscii(OOO_STRING_SVTOOLS_HTML_VA_bottom))
4889 : 0 : bTop = sal_False;
4890 : : }
4891 : : }
4892 : :
4893 : : // Alte PaM-Position retten.
4894 [ # # ]: 0 : pSaveStruct = new _CaptionSaveStruct( *this, *pPam->GetPoint() );
4895 : :
4896 : : // Eine Text-Section im Icons-Bereich als Container fuer die
4897 : : // Ueberschrift anlegen und PaM dort reinstellen.
4898 : : const SwStartNode *pStNd;
4899 [ # # ]: 0 : if( pTable == pCurTable )
4900 : 0 : pStNd = InsertTempTableCaptionSection();
4901 : : else
4902 : 0 : pStNd = InsertTableSection( RES_POOLCOLL_TEXT );
4903 : :
4904 [ # # ]: 0 : _HTMLAttrContext *pCntxt = new _HTMLAttrContext( HTML_CAPTION_ON );
4905 : :
4906 : : // Tabellen-Ueberschriften sind immer zentriert.
4907 [ # # ]: 0 : NewAttr( &aAttrTab.pAdjust, SvxAdjustItem(SVX_ADJUST_CENTER, RES_PARATR_ADJUST) );
4908 : :
4909 : 0 : _HTMLAttrs &rAttrs = pCntxt->GetAttrs();
4910 : 0 : rAttrs.push_back( aAttrTab.pAdjust );
4911 : :
4912 : 0 : PushContext( pCntxt );
4913 : :
4914 : : // StartNode der Section an der Tabelle merken.
4915 : 0 : pCurTable->SetCaption( pStNd, bTop );
4916 : :
4917 : : // ist beim ersten GetNextToken schon pending, muss bei
4918 : : // wiederaufsetzen auf jedenfall neu gelesen werden!
4919 : 0 : SaveState( 0 );
4920 : : }
4921 : :
4922 [ # # ]: 0 : if( !nToken )
4923 : 0 : nToken = GetNextToken(); // naechstes Token
4924 : :
4925 : : // </CAPTION> wird laut DTD benoetigt
4926 : 0 : sal_Bool bDone = sal_False;
4927 [ # # ][ # # ]: 0 : while( IsParserWorking() && !bDone )
[ # # ]
4928 : : {
4929 : 0 : SaveState( nToken );
4930 : :
4931 : 0 : nToken = FilterToken( nToken );
4932 : :
4933 [ # # # # ]: 0 : switch( nToken )
4934 : : {
4935 : : case HTML_TABLE_ON:
4936 [ # # ]: 0 : if( !pPendStack )
4937 : : {
4938 : 0 : pSaveStruct->pTable = pTable;
4939 : 0 : sal_Bool bHasToFly = pSaveStruct->pTable!=pCurTable;
4940 : : BuildTable( pCurTable->GetTableAdjust( sal_True ),
4941 : 0 : sal_False, sal_True, sal_True, bHasToFly );
4942 : : }
4943 : : else
4944 : : {
4945 : 0 : BuildTable( SVX_ADJUST_END );
4946 : : }
4947 [ # # ]: 0 : if( SVPAR_PENDING != GetStatus() )
4948 : : {
4949 : 0 : pTable = pSaveStruct->pTable;
4950 : : }
4951 : 0 : break;
4952 : : case HTML_TABLE_OFF:
4953 : : case HTML_COLGROUP_ON:
4954 : : case HTML_THEAD_ON:
4955 : : case HTML_TFOOT_ON:
4956 : : case HTML_TBODY_ON:
4957 : : case HTML_TABLEROW_ON:
4958 : 0 : SkipToken( -1 );
4959 : 0 : bDone = sal_True;
4960 : 0 : break;
4961 : :
4962 : : case HTML_CAPTION_OFF:
4963 : 0 : bDone = sal_True;
4964 : 0 : break;
4965 : : default:
4966 [ # # ]: 0 : if( pPendStack )
4967 : : {
4968 : 0 : SwPendingStack* pTmp = pPendStack->pNext;
4969 : 0 : delete pPendStack;
4970 : 0 : pPendStack = pTmp;
4971 : :
4972 : : OSL_ENSURE( !pTmp, "weiter kann es nicht gehen!" );
4973 : : }
4974 : :
4975 [ # # ]: 0 : if( IsParserWorking() )
4976 : 0 : NextToken( nToken );
4977 : 0 : break;
4978 : : }
4979 : :
4980 [ # # ]: 0 : if( IsParserWorking() )
4981 : 0 : SaveState( 0 );
4982 : :
4983 [ # # ]: 0 : if( !bDone )
4984 : 0 : nToken = GetNextToken();
4985 : : }
4986 : :
4987 [ # # ]: 0 : if( SVPAR_PENDING==GetStatus() )
4988 : : {
4989 : 0 : pPendStack = new SwPendingStack( HTML_CAPTION_ON, pPendStack );
4990 : 0 : pPendStack->pData = pSaveStruct;
4991 : 0 : return;
4992 : : }
4993 : :
4994 : : // Alle noch offenen Kontexte beenden
4995 [ # # ]: 0 : while( (sal_uInt16)aContexts.size() > nContextStAttrMin+1 )
4996 : : {
4997 : 0 : _HTMLAttrContext *pCntxt = PopContext();
4998 : 0 : EndContext( pCntxt );
4999 [ # # ]: 0 : delete pCntxt;
5000 : : }
5001 : :
5002 : : // LF am Absatz-Ende entfernen
5003 : 0 : sal_Bool bLFStripped = StripTrailingLF() > 0;
5004 : :
5005 [ # # ]: 0 : if( pTable==pCurTable )
5006 : : {
5007 : : // Beim spaeteren verschieben der Beschriftung vor oder hinter
5008 : : // die Tabelle wird der letzte Absatz nicht mitverschoben.
5009 : : // Deshalb muss sich am Ende der Section immer ein leerer
5010 : : // Absatz befinden.
5011 [ # # ][ # # ]: 0 : if( pPam->GetPoint()->nContent.GetIndex() || bLFStripped )
[ # # ]
5012 : 0 : AppendTxtNode( AM_NOSPACE );
5013 : : }
5014 : : else
5015 : : {
5016 : : // LFs am Absatz-Ende entfernen
5017 [ # # ][ # # ]: 0 : if( !pPam->GetPoint()->nContent.GetIndex() && !bLFStripped )
[ # # ]
5018 : 0 : StripTrailingPara();
5019 : : }
5020 : :
5021 : : // falls fuer die Zelle eine Ausrichtung gesetzt wurde, muessen
5022 : : // wir die beenden
5023 : 0 : _HTMLAttrContext *pCntxt = PopContext();
5024 : 0 : EndContext( pCntxt );
5025 [ # # ]: 0 : delete pCntxt;
5026 : :
5027 : 0 : SetAttr( sal_False );
5028 : :
5029 : : // Stacks und Attribut-Tabelle wiederherstellen
5030 : 0 : pSaveStruct->RestoreAll( *this );
5031 : :
5032 : : // PaM wiederherstellen.
5033 : 0 : *pPam->GetPoint() = pSaveStruct->GetPos();
5034 : :
5035 [ # # ]: 0 : delete pSaveStruct;
5036 : : }
5037 : :
5038 : : class _TblSaveStruct : public SwPendingStackData
5039 : : {
5040 : : public:
5041 : : HTMLTable *pCurTable;
5042 : :
5043 : 0 : _TblSaveStruct( HTMLTable *pCurTbl ) :
5044 : 0 : pCurTable( pCurTbl )
5045 : 0 : {}
5046 : :
5047 : : virtual ~_TblSaveStruct();
5048 : :
5049 : : // Aufbau der Tabelle anstossen und die Tabelle ggf. in einen
5050 : : // Rahmen packen. Wenn sal_True zurueckgegeben wird muss noch ein
5051 : : // Absatz eingefuegt werden!
5052 : : void MakeTable( sal_uInt16 nWidth, SwPosition& rPos, SwDoc *pDoc );
5053 : : };
5054 : :
5055 : 0 : _TblSaveStruct::~_TblSaveStruct()
5056 [ # # ]: 0 : {}
5057 : :
5058 : :
5059 : 0 : void _TblSaveStruct::MakeTable( sal_uInt16 nWidth, SwPosition& rPos, SwDoc *pDoc )
5060 : : {
5061 : 0 : pCurTable->MakeTable( 0, nWidth );
5062 : :
5063 : 0 : _HTMLTableContext *pTCntxt = pCurTable->GetContext();
5064 : : OSL_ENSURE( pTCntxt, "Wo ist der Tabellen-Kontext" );
5065 : :
5066 : 0 : SwTableNode *pTblNd = pTCntxt->GetTableNode();
5067 : : OSL_ENSURE( pTblNd, "Wo ist der Tabellen-Node" );
5068 : :
5069 [ # # ][ # # ]: 0 : if( pDoc->GetCurrentViewShell() && pTblNd ) //swmod 071108//swmod 071225
[ # # ]
5070 : : {
5071 : : // Existiert schon ein Layout, dann muss an dieser Tabelle die
5072 : : // BoxFrames neu erzeugt werden.
5073 : :
5074 [ # # ]: 0 : if( pTCntxt->GetFrmFmt() )
5075 : : {
5076 : 0 : pTCntxt->GetFrmFmt()->DelFrms();
5077 : 0 : pTblNd->DelFrms();
5078 : 0 : pTCntxt->GetFrmFmt()->MakeFrms();
5079 : : }
5080 : : else
5081 : : {
5082 [ # # ]: 0 : pTblNd->DelFrms();
5083 [ # # ]: 0 : SwNodeIndex aIdx( *pTblNd->EndOfSectionNode(), 1 );
5084 : : OSL_ENSURE( aIdx.GetIndex() <= pTCntxt->GetPos()->nNode.GetIndex(),
5085 : : "unerwarteter Node fuer das Tabellen-Layout" );
5086 [ # # ][ # # ]: 0 : pTblNd->MakeFrms( &aIdx );
5087 : : }
5088 : : }
5089 : :
5090 : 0 : rPos = *pTCntxt->GetPos();
5091 : 0 : }
5092 : :
5093 : :
5094 : 0 : HTMLTableOptions::HTMLTableOptions( const HTMLOptions& rOptions,
5095 : : SvxAdjust eParentAdjust ) :
5096 : : nCols( 0 ),
5097 : : nWidth( 0 ), nHeight( 0 ),
5098 : : nCellPadding( USHRT_MAX ), nCellSpacing( USHRT_MAX ),
5099 : : nBorder( USHRT_MAX ),
5100 : : nHSpace( 0 ), nVSpace( 0 ),
5101 : : eAdjust( eParentAdjust ), eVertOri( text::VertOrientation::CENTER ),
5102 : : eFrame( HTML_TF_VOID ), eRules( HTML_TR_NONE ),
5103 : : bPrcWidth( sal_False ),
5104 : : bTableAdjust( sal_False ),
5105 : : bBGColor( sal_False ),
5106 [ # # ][ # # ]: 0 : aBorderColor( COL_GRAY )
[ # # ][ # # ]
5107 : : {
5108 : 0 : sal_Bool bBorderColor = sal_False;
5109 : 0 : sal_Bool bHasFrame = sal_False, bHasRules = sal_False;
5110 : :
5111 [ # # ]: 0 : for (size_t i = rOptions.size(); i; )
5112 : : {
5113 [ # # ]: 0 : const HTMLOption& rOption = rOptions[--i];
5114 [ # # # # : 0 : switch( rOption.GetToken() )
# # # # #
# # # # #
# # # # #
# # ]
5115 : : {
5116 : : case HTML_O_ID:
5117 [ # # ]: 0 : aId = rOption.GetString();
5118 : 0 : break;
5119 : : case HTML_O_COLS:
5120 [ # # ]: 0 : nCols = (sal_uInt16)rOption.GetNumber();
5121 : 0 : break;
5122 : : case HTML_O_WIDTH:
5123 [ # # ]: 0 : nWidth = (sal_uInt16)rOption.GetNumber();
5124 [ # # ]: 0 : bPrcWidth = (rOption.GetString().Search('%') != STRING_NOTFOUND);
5125 [ # # ][ # # ]: 0 : if( bPrcWidth && nWidth>100 )
5126 : 0 : nWidth = 100;
5127 : 0 : break;
5128 : : case HTML_O_HEIGHT:
5129 [ # # ]: 0 : nHeight = (sal_uInt16)rOption.GetNumber();
5130 [ # # ][ # # ]: 0 : if( rOption.GetString().Search('%') != STRING_NOTFOUND )
5131 : 0 : nHeight = 0; // keine %-Anagben benutzen!!!
5132 : 0 : break;
5133 : : case HTML_O_CELLPADDING:
5134 [ # # ]: 0 : nCellPadding = (sal_uInt16)rOption.GetNumber();
5135 : 0 : break;
5136 : : case HTML_O_CELLSPACING:
5137 [ # # ]: 0 : nCellSpacing = (sal_uInt16)rOption.GetNumber();
5138 : 0 : break;
5139 : : case HTML_O_ALIGN:
5140 : : {
5141 : 0 : sal_uInt16 nAdjust = static_cast< sal_uInt16 >(eAdjust);
5142 [ # # ][ # # ]: 0 : if( rOption.GetEnum( nAdjust, aHTMLPAlignTable ) )
5143 : : {
5144 : 0 : eAdjust = (SvxAdjust)nAdjust;
5145 : 0 : bTableAdjust = sal_True;
5146 : : }
5147 : : }
5148 : 0 : break;
5149 : : case HTML_O_VALIGN:
5150 [ # # ]: 0 : eVertOri = rOption.GetEnum( aHTMLTblVAlignTable, eVertOri );
5151 : 0 : break;
5152 : : case HTML_O_BORDER:
5153 : : // BORDER und BORDER=BORDER wie BORDER=1 behandeln
5154 [ # # ][ # # ]: 0 : if( rOption.GetString().Len() &&
[ # # ]
5155 [ # # ]: 0 : !rOption.GetString().EqualsIgnoreCaseAscii(OOO_STRING_SVTOOLS_HTML_O_border) )
5156 [ # # ]: 0 : nBorder = (sal_uInt16)rOption.GetNumber();
5157 : : else
5158 : 0 : nBorder = 1;
5159 : :
5160 [ # # ]: 0 : if( !bHasFrame )
5161 [ # # ]: 0 : eFrame = ( nBorder ? HTML_TF_BOX : HTML_TF_VOID );
5162 [ # # ]: 0 : if( !bHasRules )
5163 [ # # ]: 0 : eRules = ( nBorder ? HTML_TR_ALL : HTML_TR_NONE );
5164 : 0 : break;
5165 : : case HTML_O_FRAME:
5166 [ # # ]: 0 : eFrame = rOption.GetTableFrame();
5167 : 0 : bHasFrame = sal_True;
5168 : 0 : break;
5169 : : case HTML_O_RULES:
5170 [ # # ]: 0 : eRules = rOption.GetTableRules();
5171 : 0 : bHasRules = sal_True;
5172 : 0 : break;
5173 : : case HTML_O_BGCOLOR:
5174 : : // Leere BGCOLOR bei <TABLE>, <TR> und <TD>/<TH> wie Netscape
5175 : : // ignorieren, bei allen anderen Tags *wirklich* nicht.
5176 [ # # ]: 0 : if( rOption.GetString().Len() )
5177 : : {
5178 [ # # ]: 0 : rOption.GetColor( aBGColor );
5179 : 0 : bBGColor = sal_True;
5180 : : }
5181 : 0 : break;
5182 : : case HTML_O_BACKGROUND:
5183 [ # # ]: 0 : aBGImage = rOption.GetString();
5184 : 0 : break;
5185 : : case HTML_O_BORDERCOLOR:
5186 [ # # ]: 0 : rOption.GetColor( aBorderColor );
5187 : 0 : bBorderColor = sal_True;
5188 : 0 : break;
5189 : : case HTML_O_BORDERCOLORDARK:
5190 [ # # ]: 0 : if( !bBorderColor )
5191 [ # # ]: 0 : rOption.GetColor( aBorderColor );
5192 : 0 : break;
5193 : : case HTML_O_STYLE:
5194 [ # # ]: 0 : aStyle = rOption.GetString();
5195 : 0 : break;
5196 : : case HTML_O_CLASS:
5197 [ # # ]: 0 : aClass = rOption.GetString();
5198 : 0 : break;
5199 : : case HTML_O_DIR:
5200 [ # # ]: 0 : aDir = rOption.GetString();
5201 : 0 : break;
5202 : : case HTML_O_HSPACE:
5203 [ # # ]: 0 : nHSpace = (sal_uInt16)rOption.GetNumber();
5204 : 0 : break;
5205 : : case HTML_O_VSPACE:
5206 [ # # ]: 0 : nVSpace = (sal_uInt16)rOption.GetNumber();
5207 : 0 : break;
5208 : : }
5209 : : }
5210 : :
5211 [ # # ][ # # ]: 0 : if( nCols && !nWidth )
5212 : : {
5213 : 0 : nWidth = 100;
5214 : 0 : bPrcWidth = sal_True;
5215 : : }
5216 : :
5217 : : // Wenn BORDER=0 oder kein BORDER gegeben ist, daan darf es auch
5218 : : // keine Umrandung geben
5219 [ # # ][ # # ]: 0 : if( 0==nBorder || USHRT_MAX==nBorder )
5220 : : {
5221 : 0 : eFrame = HTML_TF_VOID;
5222 : 0 : eRules = HTML_TR_NONE;
5223 : : }
5224 : 0 : }
5225 : :
5226 : :
5227 : 0 : HTMLTable *SwHTMLParser::BuildTable( SvxAdjust eParentAdjust,
5228 : : sal_Bool bIsParentHead,
5229 : : sal_Bool bHasParentSection,
5230 : : sal_Bool bMakeTopSubTable,
5231 : : sal_Bool bHasToFly )
5232 : : {
5233 [ # # ][ # # ]: 0 : if( !IsParserWorking() && !pPendStack )
[ # # ]
5234 : 0 : return 0;
5235 : :
5236 : 0 : int nToken = 0;
5237 : 0 : sal_Bool bPending = sal_False;
5238 : : _TblSaveStruct* pSaveStruct;
5239 : :
5240 [ # # ]: 0 : if( pPendStack )
5241 : : {
5242 : 0 : pSaveStruct = (_TblSaveStruct*)pPendStack->pData;
5243 : :
5244 : 0 : SwPendingStack* pTmp = pPendStack->pNext;
5245 : 0 : delete pPendStack;
5246 : 0 : pPendStack = pTmp;
5247 [ # # ]: 0 : nToken = pPendStack ? pPendStack->nToken : GetSaveToken();
5248 [ # # ][ # # ]: 0 : bPending = SVPAR_ERROR == eState && pPendStack != 0;
5249 : :
5250 : 0 : SaveState( nToken );
5251 : : }
5252 : : else
5253 : : {
5254 : 0 : pTable = 0;
5255 : : HTMLTableOptions *pTblOptions =
5256 [ # # ]: 0 : new HTMLTableOptions( GetOptions(), eParentAdjust );
5257 : :
5258 [ # # ]: 0 : if( pTblOptions->aId.Len() )
5259 : 0 : InsertBookmark( pTblOptions->aId );
5260 : :
5261 : : HTMLTable *pCurTable = new HTMLTable( this, pTable,
5262 : : bIsParentHead,
5263 : : bHasParentSection,
5264 : : bMakeTopSubTable,
5265 : : bHasToFly,
5266 [ # # ]: 0 : pTblOptions );
5267 [ # # ]: 0 : if( !pTable )
5268 : 0 : pTable = pCurTable;
5269 : :
5270 : 0 : pSaveStruct = new _TblSaveStruct( pCurTable );
5271 : :
5272 [ # # ]: 0 : delete pTblOptions;
5273 : :
5274 : : // ist beim ersten GetNextToken schon pending, muss bei
5275 : : // wiederaufsetzen auf jedenfall neu gelesen werden!
5276 : 0 : SaveState( 0 );
5277 : : }
5278 : :
5279 : 0 : HTMLTable *pCurTable = pSaveStruct->pCurTable;
5280 : :
5281 : : // </TABLE> wird laut DTD benoetigt
5282 [ # # ]: 0 : if( !nToken )
5283 : 0 : nToken = GetNextToken(); // naechstes Token
5284 : :
5285 : 0 : sal_Bool bDone = sal_False;
5286 [ # # ][ # # ]: 0 : while( (IsParserWorking() && !bDone) || bPending )
[ # # ][ # # ]
5287 : : {
5288 : 0 : SaveState( nToken );
5289 : :
5290 : 0 : nToken = FilterToken( nToken );
5291 : :
5292 : : OSL_ENSURE( pPendStack || !bCallNextToken ||
5293 : : pCurTable->GetContext() || pCurTable->HasParentSection(),
5294 : : "Wo ist die Section gebieben?" );
5295 [ # # # # : 0 : if( !pPendStack && bCallNextToken &&
# # ][ # # ]
[ # # ]
5296 : 0 : (pCurTable->GetContext() || pCurTable->HasParentSection()) )
5297 : : {
5298 : : // NextToken direkt aufrufen (z.B. um den Inhalt von
5299 : : // Floating-Frames oder Applets zu ignorieren)
5300 : 0 : NextToken( nToken );
5301 : : }
5302 [ # # # # : 0 : else switch( nToken )
# # # # #
# # # ]
5303 : : {
5304 : : case HTML_TABLE_ON:
5305 [ # # ]: 0 : if( !pCurTable->GetContext() )
5306 : : {
5307 : : // Wenn noch keine Tabelle eingefuegt wurde,
5308 : : // die naechste Tabelle lesen
5309 : 0 : SkipToken( -1 );
5310 : 0 : bDone = sal_True;
5311 : : }
5312 : :
5313 : 0 : break;
5314 : : case HTML_TABLE_OFF:
5315 : 0 : bDone = sal_True;
5316 : 0 : break;
5317 : : case HTML_CAPTION_ON:
5318 : 0 : BuildTableCaption( pCurTable );
5319 : 0 : bDone = pTable->IsOverflowing();
5320 : 0 : break;
5321 : : case HTML_COL_ON:
5322 : 0 : SkipToken( -1 );
5323 : 0 : BuildTableColGroup( pCurTable, sal_False );
5324 : 0 : break;
5325 : : case HTML_COLGROUP_ON:
5326 : 0 : BuildTableColGroup( pCurTable, sal_True );
5327 : 0 : break;
5328 : : case HTML_TABLEROW_ON:
5329 : : case HTML_TABLEHEADER_ON:
5330 : : case HTML_TABLEDATA_ON:
5331 : 0 : SkipToken( -1 );
5332 : 0 : BuildTableSection( pCurTable, sal_False, sal_False );
5333 : 0 : bDone = pTable->IsOverflowing();
5334 : 0 : break;
5335 : : case HTML_THEAD_ON:
5336 : : case HTML_TFOOT_ON:
5337 : : case HTML_TBODY_ON:
5338 : 0 : BuildTableSection( pCurTable, sal_True, HTML_THEAD_ON==nToken );
5339 : 0 : bDone = pTable->IsOverflowing();
5340 : 0 : break;
5341 : : case HTML_MULTICOL_ON:
5342 : : // spaltige Rahmen koennen wir hier leider nicht einguegen
5343 : 0 : break;
5344 : : case HTML_FORM_ON:
5345 : 0 : NewForm( sal_False ); // keinen neuen Absatz aufmachen!
5346 : 0 : break;
5347 : : case HTML_FORM_OFF:
5348 : 0 : EndForm( sal_False ); // keinen neuen Absatz aufmachen!
5349 : 0 : break;
5350 : : case HTML_TEXTTOKEN:
5351 : : // Blank-Strings sind u. U. eine Folge von CR+LF und kein Text
5352 [ # # # # : 0 : if( (pCurTable->GetContext() ||
# # # # ]
[ # # ]
5353 : 0 : !pCurTable->HasParentSection()) &&
5354 : 0 : 1==aToken.Len() && ' '==aToken.GetChar(0) )
5355 : 0 : break;
5356 : : default:
5357 : 0 : pCurTable->MakeParentContents();
5358 : 0 : NextToken( nToken );
5359 : 0 : break;
5360 : : }
5361 : :
5362 : : OSL_ENSURE( !bPending || !pPendStack,
5363 : : "SwHTMLParser::BuildTable: Es gibt wieder einen Pend-Stack" );
5364 : 0 : bPending = sal_False;
5365 [ # # ]: 0 : if( IsParserWorking() )
5366 : 0 : SaveState( 0 );
5367 : :
5368 [ # # ]: 0 : if( !bDone )
5369 : 0 : nToken = GetNextToken();
5370 : : }
5371 : :
5372 [ # # ]: 0 : if( SVPAR_PENDING == GetStatus() )
5373 : : {
5374 : 0 : pPendStack = new SwPendingStack( HTML_TABLE_ON, pPendStack );
5375 : 0 : pPendStack->pData = pSaveStruct;
5376 : 0 : return 0;
5377 : : }
5378 : :
5379 : 0 : _HTMLTableContext *pTCntxt = pCurTable->GetContext();
5380 [ # # ]: 0 : if( pTCntxt )
5381 : : {
5382 : : // Die Tabelle wurde auch angelegt
5383 : :
5384 : : // Tabellen-Struktur anpassen
5385 : 0 : pCurTable->CloseTable();
5386 : :
5387 : : // ausserhalb von Zellen begonnene Kontexte beenden
5388 : : // muss vor(!) dem Umsetzten der Attribut Tabelle existieren,
5389 : : // weil die aktuelle danach nicht mehr existiert
5390 [ # # ]: 0 : while( aContexts.size() > nContextStAttrMin )
5391 : : {
5392 : 0 : _HTMLAttrContext *pCntxt = PopContext();
5393 : 0 : ClearContext( pCntxt );
5394 [ # # ]: 0 : delete pCntxt;
5395 : : }
5396 : :
5397 : 0 : nContextStMin = pTCntxt->GetContextStMin();
5398 : 0 : nContextStAttrMin = pTCntxt->GetContextStAttrMin();
5399 : :
5400 [ # # ]: 0 : if( pTable==pCurTable )
5401 : : {
5402 : : // Tabellen-Beschriftung setzen
5403 : 0 : const SwStartNode *pCapStNd = pTable->GetCaptionStartNode();
5404 [ # # ]: 0 : if( pCapStNd )
5405 : : {
5406 : : // Der letzte Absatz der Section wird nie mitkopiert. Deshalb
5407 : : // muss die Section mindestens zwei Absaetze enthalten.
5408 : :
5409 [ # # ]: 0 : if( pCapStNd->EndOfSectionIndex() - pCapStNd->GetIndex() > 2 )
5410 : : {
5411 : : // Start-Node und letzten Absatz nicht mitkopieren.
5412 : : SwNodeRange aSrcRg( *pCapStNd, 1,
5413 [ # # ]: 0 : *pCapStNd->EndOfSectionNode(), -1 );
5414 : :
5415 : 0 : sal_Bool bTop = pTable->IsTopCaption();
5416 : 0 : SwStartNode *pTblStNd = pTCntxt->GetTableNode();
5417 : :
5418 : : OSL_ENSURE( pTblStNd, "Wo ist der Tabellen-Node" );
5419 : : OSL_ENSURE( pTblStNd==pPam->GetNode()->FindTableNode(),
5420 : : "Stehen wir in der falschen Tabelle?" );
5421 : :
5422 : : SwNode* pNd;
5423 [ # # ]: 0 : if( bTop )
5424 : 0 : pNd = pTblStNd;
5425 : : else
5426 : 0 : pNd = pTblStNd->EndOfSectionNode();
5427 [ # # ]: 0 : SwNodeIndex aDstIdx( *pNd, bTop ? 0 : 1 );
5428 : :
5429 : : pDoc->MoveNodeRange( aSrcRg, aDstIdx,
5430 [ # # ]: 0 : IDocumentContentOperations::DOC_MOVEDEFAULT );
5431 : :
5432 : : // Wenn die Caption vor der Tabelle eingefuegt wurde muss
5433 : : // eine an der Tabelle gestzte Seitenvorlage noch in den
5434 : : // ersten Absatz der Ueberschrift verschoben werden.
5435 : : // Ausserdem muessen alle gemerkten Indizes, die auf den
5436 : : // Tabellen-Node zeigen noch verschoben werden.
5437 [ # # ]: 0 : if( bTop )
5438 : : {
5439 : : MovePageDescAttrs( pTblStNd, aSrcRg.aStart.GetIndex(),
5440 [ # # ]: 0 : sal_False );
5441 [ # # ][ # # ]: 0 : }
5442 : : }
5443 : :
5444 : : // Die Section wird jetzt nicht mehr gebraucht.
5445 : 0 : pPam->SetMark();
5446 : 0 : pPam->DeleteMark();
5447 : 0 : pDoc->DeleteSection( (SwStartNode *)pCapStNd );
5448 : 0 : pTable->SetCaption( 0, sal_False );
5449 : : }
5450 : :
5451 : : // SwTable aufbereiten
5452 : 0 : sal_uInt16 nBrowseWidth = (sal_uInt16)GetCurrentBrowseWidth();
5453 : 0 : pSaveStruct->MakeTable( nBrowseWidth, *pPam->GetPoint(), pDoc );
5454 : : }
5455 : :
5456 : 0 : GetNumInfo().Set( pTCntxt->GetNumInfo() );
5457 : 0 : pTCntxt->RestorePREListingXMP( *this );
5458 : 0 : RestoreAttrTab( pTCntxt->aAttrTab );
5459 : :
5460 [ # # ]: 0 : if( pTable==pCurTable )
5461 : : {
5462 : : // oberen Absatz-Abstand einstellen
5463 : 0 : bUpperSpace = sal_True;
5464 : 0 : SetTxtCollAttrs();
5465 : :
5466 : 0 : nParaCnt = nParaCnt - Min(nParaCnt, (sal_uInt16)pTCntxt->GetTableNode()->GetTable().GetTabSortBoxes().size());
5467 : :
5468 : : // ggfs. eine Tabelle anspringen
5469 [ # # # # ]: 0 : if( JUMPTO_TABLE == eJumpTo && pTable->GetSwTable() &&
[ # # ][ # # ]
5470 : 0 : pTable->GetSwTable()->GetFrmFmt()->GetName() == sJmpMark )
5471 : : {
5472 : 0 : bChkJumpMark = sal_True;
5473 : 0 : eJumpTo = JUMPTO_NONE;
5474 : : }
5475 : :
5476 : : // Wenn Import abgebrochen wurde kein erneutes Show
5477 : : // aufrufen, weil die ViewShell schon geloescht wurde!
5478 : : // Genuegt nicht. Auch im ACCEPTING_STATE darf
5479 : : // kein Show aufgerufen werden, weil sonst waehrend des
5480 : : // Reschedules der Parser zerstoert wird, wenn noch ein
5481 : : // DataAvailable-Link kommt. Deshalb: Nur im WORKING-State.
5482 [ # # ][ # # ]: 0 : if( !nParaCnt && SVPAR_WORKING == GetStatus() )
[ # # ]
5483 : 0 : Show();
5484 : : }
5485 : : }
5486 [ # # ]: 0 : else if( pTable==pCurTable )
5487 : : {
5488 : : // Es wurde gar keine Tabelle gelesen.
5489 : :
5490 : : // Dann muss eine evtl gelesene Beschriftung noch geloescht werden.
5491 : 0 : const SwStartNode *pCapStNd = pCurTable->GetCaptionStartNode();
5492 [ # # ]: 0 : if( pCapStNd )
5493 : : {
5494 : 0 : pPam->SetMark();
5495 : 0 : pPam->DeleteMark();
5496 : 0 : pDoc->DeleteSection( (SwStartNode *)pCapStNd );
5497 : 0 : pCurTable->SetCaption( 0, sal_False );
5498 : : }
5499 : : }
5500 : :
5501 [ # # ]: 0 : if( pTable == pCurTable )
5502 : : {
5503 [ # # ]: 0 : delete pSaveStruct->pCurTable;
5504 : 0 : pSaveStruct->pCurTable = 0;
5505 : 0 : pTable = 0;
5506 : : }
5507 : :
5508 : 0 : HTMLTable* pRetTbl = pSaveStruct->pCurTable;
5509 [ # # ]: 0 : delete pSaveStruct;
5510 : :
5511 : 0 : return pRetTbl;
5512 : : }
5513 : :
5514 : :
5515 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|