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 <rtl/uri.hxx>
31 : :
32 : : #include <svl/urihelper.hxx>
33 : : #include <vcl/svapp.hxx>
34 : : #include <vcl/wrkwin.hxx>
35 : : #include <editeng/adjitem.hxx>
36 : : #include <editeng/ulspitem.hxx>
37 : : #include <editeng/brkitem.hxx>
38 : : #include <svtools/htmltokn.h>
39 : : #include <svtools/htmlkywd.hxx>
40 : : #include <sfx2/linkmgr.hxx>
41 : :
42 : : #include "hintids.hxx"
43 : : #include <fmtornt.hxx>
44 : : #include <fmthdft.hxx>
45 : : #include <fmtcntnt.hxx>
46 : : #include <fmtfsize.hxx>
47 : : #include <fmtclds.hxx>
48 : : #include <fmtanchr.hxx>
49 : : #include <fmtpdsc.hxx>
50 : : #include <fmtsrnd.hxx>
51 : : #include <fmtflcnt.hxx>
52 : : #include "frmatr.hxx"
53 : : #include "doc.hxx"
54 : : #include "pam.hxx"
55 : : #include "ndtxt.hxx"
56 : : #include "shellio.hxx"
57 : : #include "section.hxx"
58 : : #include "poolfmt.hxx"
59 : : #include "pagedesc.hxx"
60 : : #include "swtable.hxx"
61 : : #include "viewsh.hxx"
62 : : #include "swcss1.hxx"
63 : : #include "swhtml.hxx"
64 : :
65 : : #define CONTEXT_FLAGS_MULTICOL (HTML_CNTXT_STRIP_PARA | \
66 : : HTML_CNTXT_KEEP_NUMRULE | \
67 : : HTML_CNTXT_KEEP_ATTRS)
68 : : #define CONTEXT_FLAGS_HDRFTR (CONTEXT_FLAGS_MULTICOL)
69 : : #define CONTEXT_FLAGS_FTN (CONTEXT_FLAGS_MULTICOL)
70 : :
71 : :
72 : : using namespace ::com::sun::star;
73 : :
74 : 0 : void SwHTMLParser::NewDivision( int nToken )
75 : : {
76 [ # # ][ # # ]: 0 : String aId, aHRef, aStyle, aClass, aLang, aDir;
[ # # ][ # # ]
[ # # ][ # # ]
77 : : SvxAdjust eAdjust = HTML_CENTER_ON==nToken ? SVX_ADJUST_CENTER
78 [ # # ]: 0 : : SVX_ADJUST_END;
79 : :
80 : 0 : sal_Bool bHeader=sal_False, bFooter=sal_False;
81 [ # # ]: 0 : const HTMLOptions& rHTMLOptions = GetOptions();
82 [ # # ]: 0 : for (size_t i = rHTMLOptions.size(); i; )
83 : : {
84 [ # # ]: 0 : const HTMLOption& rOption = rHTMLOptions[--i];
85 [ # # # # : 0 : switch( rOption.GetToken() )
# # # #
# ]
86 : : {
87 : : case HTML_O_ID:
88 [ # # ]: 0 : aId = rOption.GetString();
89 : 0 : break;
90 : : case HTML_O_ALIGN:
91 [ # # ]: 0 : if( HTML_DIVISION_ON==nToken )
92 : : eAdjust = (SvxAdjust)rOption.GetEnum( aHTMLPAlignTable,
93 [ # # ]: 0 : static_cast< sal_uInt16 >(eAdjust) );
94 : 0 : break;
95 : : case HTML_O_STYLE:
96 [ # # ]: 0 : aStyle = rOption.GetString();
97 : 0 : break;
98 : : case HTML_O_CLASS:
99 [ # # ]: 0 : aClass = rOption.GetString();
100 : 0 : break;
101 : : case HTML_O_LANG:
102 [ # # ]: 0 : aLang = rOption.GetString();
103 : 0 : break;
104 : : case HTML_O_DIR:
105 [ # # ]: 0 : aDir = rOption.GetString();
106 : 0 : break;
107 : : case HTML_O_HREF:
108 [ # # ]: 0 : aHRef = rOption.GetString();
109 : 0 : break;
110 : : case HTML_O_TYPE:
111 : : {
112 : 0 : const String& rType = rOption.GetString();
113 [ # # ][ # # ]: 0 : if( rType.EqualsIgnoreCaseAscii( "HEADER" ) )
114 : 0 : bHeader = sal_True;
115 [ # # ][ # # ]: 0 : else if( rType.EqualsIgnoreCaseAscii( "FOOTER" ) )
116 : 0 : bFooter = sal_True;
117 : : }
118 : : }
119 : : }
120 : :
121 : 0 : sal_Bool bAppended = sal_False;
122 [ # # ]: 0 : if( pPam->GetPoint()->nContent.GetIndex() )
123 : : {
124 : 0 : AppendTxtNode( bHeader||bFooter||aId.Len()||aHRef.Len() ? AM_NORMAL
125 [ # # ][ # # : 0 : : AM_NOSPACE );
# # # # ]
[ # # ]
126 : 0 : bAppended = sal_True;
127 : : }
128 : :
129 [ # # ][ # # ]: 0 : _HTMLAttrContext *pCntxt = new _HTMLAttrContext( static_cast< sal_uInt16 >(nToken) );
130 : :
131 : 0 : sal_Bool bStyleParsed = sal_False, bPositioned = sal_False;
132 [ # # ][ # # ]: 0 : SfxItemSet aItemSet( pDoc->GetAttrPool(), pCSS1Parser->GetWhichMap() );
133 [ # # ]: 0 : SvxCSS1PropertyInfo aPropInfo;
134 [ # # ]: 0 : if( HasStyleOptions( aStyle, aId, aClass, &aLang, &aDir ) )
135 : : {
136 : : bStyleParsed = ParseStyleOptions( aStyle, aId, aClass,
137 [ # # ]: 0 : aItemSet, aPropInfo, &aLang, &aDir );
138 [ # # ]: 0 : if( bStyleParsed )
139 : : {
140 : 0 : bPositioned = HTML_DIVISION_ON == nToken && aClass.Len() &&
141 : : CreateContainer( aClass, aItemSet, aPropInfo,
142 [ # # # # ]: 0 : pCntxt );
[ # # ][ # # ]
143 [ # # ]: 0 : if( !bPositioned )
144 [ # # ]: 0 : bPositioned = DoPositioning( aItemSet, aPropInfo, pCntxt );
145 : : }
146 : : }
147 : :
148 [ # # ][ # # ]: 0 : if( !bPositioned && (bHeader || bFooter) && IsNewDoc() )
[ # # ][ # # ]
[ # # ]
149 : : {
150 [ # # ]: 0 : SwPageDesc *pPageDesc = pCSS1Parser->GetMasterPageDesc();
151 : 0 : SwFrmFmt& rPageFmt = pPageDesc->GetMaster();
152 : :
153 : : SwFrmFmt *pHdFtFmt;
154 : 0 : sal_Bool bNew = sal_False;
155 : 0 : sal_uInt16 nFlags = CONTEXT_FLAGS_HDRFTR;
156 [ # # ]: 0 : if( bHeader )
157 : : {
158 [ # # ]: 0 : pHdFtFmt = (SwFrmFmt*)rPageFmt.GetHeader().GetHeaderFmt();
159 [ # # ]: 0 : if( !pHdFtFmt )
160 : : {
161 : : // noch keine Header, dann erzeuge einen.
162 [ # # ][ # # ]: 0 : rPageFmt.SetFmtAttr( SwFmtHeader( sal_True ));
[ # # ]
163 [ # # ]: 0 : pHdFtFmt = (SwFrmFmt*)rPageFmt.GetHeader().GetHeaderFmt();
164 : 0 : bNew = sal_True;
165 : : }
166 : 0 : nFlags |= HTML_CNTXT_HEADER_DIST;
167 : : }
168 : : else
169 : : {
170 [ # # ]: 0 : pHdFtFmt = (SwFrmFmt*)rPageFmt.GetFooter().GetFooterFmt();
171 [ # # ]: 0 : if( !pHdFtFmt )
172 : : {
173 : : // noch keine Footer, dann erzeuge einen.
174 [ # # ][ # # ]: 0 : rPageFmt.SetFmtAttr( SwFmtFooter( sal_True ));
[ # # ]
175 [ # # ]: 0 : pHdFtFmt = (SwFrmFmt*)rPageFmt.GetFooter().GetFooterFmt();
176 : 0 : bNew = sal_True;
177 : : }
178 : 0 : nFlags |= HTML_CNTXT_FOOTER_DIST;
179 : : }
180 : :
181 [ # # ]: 0 : const SwFmtCntnt& rFlyCntnt = pHdFtFmt->GetCntnt();
182 : 0 : const SwNodeIndex& rCntntStIdx = *rFlyCntnt.GetCntntIdx();
183 : : SwCntntNode *pCNd;
184 : :
185 [ # # ]: 0 : if( bNew )
186 : : {
187 [ # # ]: 0 : pCNd = pDoc->GetNodes()[rCntntStIdx.GetIndex()+1]
188 [ # # ]: 0 : ->GetCntntNode();
189 : : }
190 : : else
191 : : {
192 : : // Einen neuen Node zu Beginn der Section anlegen
193 [ # # ]: 0 : SwNodeIndex aSttIdx( rCntntStIdx, 1 );
194 [ # # ]: 0 : pCNd = pDoc->GetNodes().MakeTxtNode( aSttIdx,
195 [ # # ][ # # ]: 0 : pCSS1Parser->GetTxtCollFromPool(RES_POOLCOLL_TEXT));
196 : :
197 : : // Den bisherigen Inhalt der Section loeschen
198 [ # # ]: 0 : SwPaM aDelPam( aSttIdx );
199 [ # # ]: 0 : aDelPam.SetMark();
200 : :
201 : : const SwStartNode *pStNd =
202 : 0 : (const SwStartNode *) &rCntntStIdx.GetNode();
203 [ # # ]: 0 : aDelPam.GetPoint()->nNode = pStNd->EndOfSectionIndex() - 1;
204 : :
205 [ # # ]: 0 : pDoc->DelFullPara( aDelPam );
206 : :
207 : : // Die Seitenvorlage aktualisieren
208 [ # # ]: 0 : for( sal_uInt16 i=0; i < pDoc->GetPageDescCnt(); i++ )
209 : : {
210 [ # # ][ # # ]: 0 : if( RES_POOLPAGE_HTML == pDoc->GetPageDesc(i).GetPoolFmtId() )
211 : : {
212 [ # # ]: 0 : pDoc->ChgPageDesc( i, *pPageDesc );
213 : 0 : break;
214 : : }
215 [ # # ][ # # ]: 0 : }
216 : : }
217 : :
218 [ # # ][ # # ]: 0 : SwPosition aNewPos( SwNodeIndex( rCntntStIdx, 1 ), SwIndex( pCNd, 0 ) );
[ # # ][ # # ]
[ # # ][ # # ]
219 [ # # ][ # # ]: 0 : SaveDocContext( pCntxt, nFlags, &aNewPos );
220 : : }
221 [ # # ][ # # : 0 : else if( !bPositioned && aId.Len() > 9 &&
# # # # #
# # # ]
[ # # ]
222 : 0 : ('s' == aId.GetChar(0) || 'S' == aId.GetChar(0) ) &&
223 : 0 : ('d' == aId.GetChar(1) || 'D' == aId.GetChar(1) ) )
224 : : {
225 : 0 : sal_Bool bEndNote = sal_False, bFootNote = sal_False;
226 [ # # ][ # # ]: 0 : if( aId.CompareIgnoreCaseToAscii( OOO_STRING_SVTOOLS_HTML_sdendnote, 9 ) == COMPARE_EQUAL )
227 : 0 : bEndNote = sal_True;
228 [ # # ][ # # ]: 0 : else if( aId.CompareIgnoreCaseToAscii( OOO_STRING_SVTOOLS_HTML_sdfootnote, 10 ) == COMPARE_EQUAL )
229 : 0 : bFootNote = sal_True;
230 [ # # ][ # # ]: 0 : if( bFootNote || bEndNote )
231 : : {
232 [ # # ]: 0 : SwNodeIndex *pStartNdIdx = GetFootEndNoteSection( aId );
233 [ # # ]: 0 : if( pStartNdIdx )
234 : : {
235 : : SwCntntNode *pCNd =
236 [ # # ][ # # ]: 0 : pDoc->GetNodes()[pStartNdIdx->GetIndex()+1]->GetCntntNode();
237 [ # # ]: 0 : SwNodeIndex aTmpSwNodeIndex = SwNodeIndex(*pCNd);
238 [ # # ][ # # ]: 0 : SwPosition aNewPos( aTmpSwNodeIndex, SwIndex( pCNd, 0 ) );
[ # # ][ # # ]
239 [ # # ]: 0 : SaveDocContext( pCntxt, CONTEXT_FLAGS_FTN, &aNewPos );
240 [ # # ][ # # ]: 0 : aId = aPropInfo.aId = aEmptyStr;
[ # # ][ # # ]
241 : : }
242 : : }
243 : : }
244 : :
245 : : // Bereiche fuegen wir in Rahmen nur dann ein, wenn der Bereich gelinkt ist.
246 [ # # ][ # # ]: 0 : if( (aId.Len() && !bPositioned) || aHRef.Len() )
[ # # ][ # # ]
247 : : {
248 : : // Bereich einfuegen (muss vor dem Setzten von Attributen erfolgen,
249 : : // weil die Section vor der PaM-Position eingefuegt.
250 : :
251 : : // wenn wir im ersten Node einer Section stehen, wir die neue
252 : : // Section nicht in der aktuellen, sondern vor der aktuellen
253 : : // Section eingefuegt. Deshalb muessen wir dann einen Node
254 : : // einfuegen. UND IN LOESCHEN!!!
255 [ # # ]: 0 : if( !bAppended )
256 : : {
257 [ # # ]: 0 : SwNodeIndex aPrvNdIdx( pPam->GetPoint()->nNode, -1 );
258 [ # # ]: 0 : if (aPrvNdIdx.GetNode().IsSectionNode())
259 : : {
260 [ # # ]: 0 : AppendTxtNode();
261 : 0 : bAppended = sal_True;
262 [ # # ]: 0 : }
263 : : }
264 [ # # ][ # # ]: 0 : _HTMLAttrs *pPostIts = bAppended ? 0 : new _HTMLAttrs;
[ # # ]
265 [ # # ]: 0 : SetAttr( sal_True, sal_True, pPostIts );
266 : :
267 : : // Namen der Section eindeutig machen
268 [ # # ][ # # ]: 0 : String aName( pDoc->GetUniqueSectionName( aId.Len() ? &aId : 0 ) );
269 : :
270 [ # # ]: 0 : if( aHRef.Len() )
271 : : {
272 : 0 : sal_Unicode cDelim = 255U;
273 [ # # ]: 0 : String aURL;
274 [ # # ]: 0 : xub_StrLen nPos = aHRef.SearchBackward( cDelim );
275 : 0 : xub_StrLen nPos2 = STRING_NOTFOUND;
276 [ # # ]: 0 : if( STRING_NOTFOUND != nPos )
277 : : {
278 [ # # ]: 0 : nPos2 = aHRef.SearchBackward( cDelim, nPos );
279 [ # # ]: 0 : if( STRING_NOTFOUND != nPos2 )
280 : : {
281 : 0 : xub_StrLen nTmp = nPos;
282 : 0 : nPos = nPos2;
283 : 0 : nPos2 = nTmp;
284 : : }
285 : : }
286 [ # # ]: 0 : if( STRING_NOTFOUND == nPos )
287 : : {
288 [ # # ][ # # ]: 0 : aURL = URIHelper::SmartRel2Abs(INetURLObject( sBaseURL ), aHRef, Link(), false);
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
289 : : }
290 : : else
291 : : {
292 [ # # ][ # # ]: 0 : aURL = URIHelper::SmartRel2Abs(INetURLObject( sBaseURL ), aHRef.Copy( 0, nPos ), Link(), false );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
293 [ # # ]: 0 : aURL += sfx2::cTokenSeperator;
294 [ # # ]: 0 : if( STRING_NOTFOUND == nPos2 )
295 : : {
296 [ # # ][ # # ]: 0 : aURL += aHRef.Copy( nPos+1 );
[ # # ]
297 : : }
298 : : else
299 : : {
300 [ # # ][ # # ]: 0 : aURL += aHRef.Copy( nPos+1, nPos2 - (nPos+1) );
[ # # ]
301 [ # # ]: 0 : aURL += sfx2::cTokenSeperator;
302 : : aURL += String(rtl::Uri::decode( aHRef.Copy( nPos2+1 ),
303 : : rtl_UriDecodeWithCharset,
304 [ # # ][ # # ]: 0 : RTL_TEXTENCODING_ISO_8859_1 ));
[ # # ][ # # ]
[ # # ][ # # ]
305 : : }
306 : : }
307 [ # # ][ # # ]: 0 : aHRef = aURL;
308 : : }
309 : :
310 : 0 : SwSectionData aSection( (aHRef.Len()) ? FILE_LINK_SECTION
311 [ # # ][ # # ]: 0 : : CONTENT_SECTION, aName );
312 [ # # ]: 0 : if( aHRef.Len() )
313 : : {
314 [ # # ]: 0 : aSection.SetLinkFileName( aHRef );
315 : 0 : aSection.SetProtectFlag(true);
316 : : }
317 : :
318 : 0 : SfxItemSet aFrmItemSet( pDoc->GetAttrPool(),
319 [ # # ]: 0 : RES_FRMATR_BEGIN, RES_FRMATR_END-1 );
320 [ # # ]: 0 : if( !IsNewDoc() )
321 [ # # ]: 0 : Reader::ResetFrmFmtAttrs(aFrmItemSet );
322 : :
323 : : const SfxPoolItem *pItem;
324 [ # # ]: 0 : if( SFX_ITEM_SET == aItemSet.GetItemState( RES_BACKGROUND, sal_False,
325 [ # # ]: 0 : &pItem ) )
326 : : {
327 [ # # ]: 0 : aFrmItemSet.Put( *pItem );
328 [ # # ]: 0 : aItemSet.ClearItem( RES_BACKGROUND );
329 : : }
330 [ # # ]: 0 : if( SFX_ITEM_SET == aItemSet.GetItemState( RES_FRAMEDIR, sal_False,
331 [ # # ]: 0 : &pItem ) )
332 : : {
333 [ # # ]: 0 : aFrmItemSet.Put( *pItem );
334 [ # # ]: 0 : aItemSet.ClearItem( RES_FRAMEDIR );
335 : : }
336 : :
337 [ # # ]: 0 : pDoc->InsertSwSection( *pPam, aSection, 0, &aFrmItemSet, false );
338 : :
339 : : // ggfs. einen Bereich anspringen
340 [ # # ][ # # ]: 0 : if( JUMPTO_REGION == eJumpTo && aName == sJmpMark )
[ # # ][ # # ]
341 : : {
342 : 0 : bChkJumpMark = sal_True;
343 : 0 : eJumpTo = JUMPTO_NONE;
344 : : }
345 : :
346 : : SwTxtNode* pOldTxtNd =
347 [ # # ]: 0 : (bAppended) ? 0 : pPam->GetPoint()->nNode.GetNode().GetTxtNode();
348 : :
349 [ # # ]: 0 : pPam->Move( fnMoveBackward );
350 : :
351 : : // PageDesc- und SwFmtBreak Attribute vom aktuellen Node in den
352 : : // (ersten) Node des Bereich verschieben.
353 [ # # ]: 0 : if( pOldTxtNd )
354 : 0 : MovePageDescAttrs( pOldTxtNd, pPam->GetPoint()->nNode.GetIndex(),
355 [ # # ][ # # ]: 0 : sal_True );
356 : :
357 [ # # ]: 0 : if( pPostIts )
358 : : {
359 : : // noch vorhandene PostIts in den ersten Absatz
360 : : // der Tabelle setzen
361 [ # # ]: 0 : InsertAttrs( *pPostIts );
362 [ # # ]: 0 : delete pPostIts;
363 : 0 : pPostIts = 0;
364 : : }
365 : :
366 : 0 : pCntxt->SetSpansSection( sal_True );
367 : :
368 : : // keine text::Bookmarks mit dem gleichen Namen wie Bereiche einfuegen
369 [ # # ][ # # ]: 0 : if( aPropInfo.aId.Len() && aPropInfo.aId==aName )
[ # # ][ # # ]
370 [ # # ][ # # ]: 0 : aPropInfo.aId.Erase();
[ # # ][ # # ]
371 : : }
372 : : else
373 : : {
374 : 0 : pCntxt->SetAppendMode( AM_NOSPACE );
375 : : }
376 : :
377 [ # # ]: 0 : if( SVX_ADJUST_END != eAdjust )
378 : : {
379 [ # # ][ # # ]: 0 : InsertAttr( &aAttrTab.pAdjust, SvxAdjustItem(eAdjust, RES_PARATR_ADJUST), pCntxt );
[ # # ]
380 : : }
381 : :
382 : : // Style parsen
383 [ # # ]: 0 : if( bStyleParsed )
384 [ # # ]: 0 : InsertAttrs( aItemSet, aPropInfo, pCntxt, sal_True );
385 : :
386 [ # # ][ # # ]: 0 : PushContext( pCntxt );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
387 : 0 : }
388 : :
389 : 0 : void SwHTMLParser::EndDivision( int /*nToken*/ )
390 : : {
391 : : // Stack-Eintrag zu dem Token suchen (weil wir noch den Div-Stack
392 : : // haben unterscheiden wir erst einmal nicht zwischen DIV und CENTER
393 : 0 : _HTMLAttrContext *pCntxt = 0;
394 : 0 : sal_uInt16 nPos = aContexts.size();
395 [ # # ][ # # ]: 0 : while( !pCntxt && nPos>nContextStMin )
[ # # ]
396 : : {
397 [ # # ]: 0 : switch( aContexts[--nPos]->GetToken() )
398 : : {
399 : : case HTML_CENTER_ON:
400 : : case HTML_DIVISION_ON:
401 : 0 : pCntxt = aContexts[nPos];
402 [ # # ][ # # ]: 0 : aContexts.erase( aContexts.begin() + nPos );
403 : 0 : break;
404 : : }
405 : : }
406 : :
407 [ # # ]: 0 : if( pCntxt )
408 : : {
409 : : // Attribute beenden
410 : 0 : EndContext( pCntxt );
411 : 0 : SetAttr(); // Absatz-Atts wegen JavaScript moeglichst schnell setzen
412 : :
413 [ # # ]: 0 : delete pCntxt;
414 : : }
415 : 0 : }
416 : :
417 : 0 : void SwHTMLParser::FixHeaderFooterDistance( sal_Bool bHeader,
418 : : const SwPosition *pOldPos )
419 : : {
420 [ # # ]: 0 : SwPageDesc *pPageDesc = pCSS1Parser->GetMasterPageDesc();
421 : 0 : SwFrmFmt& rPageFmt = pPageDesc->GetMaster();
422 : :
423 : : SwFrmFmt *pHdFtFmt =
424 [ # # ]: 0 : bHeader ? (SwFrmFmt*)rPageFmt.GetHeader().GetHeaderFmt()
425 [ # # ][ # # ]: 0 : : (SwFrmFmt*)rPageFmt.GetFooter().GetFooterFmt();
426 : : OSL_ENSURE( pHdFtFmt, "Doch keine Kopf- oder Fusszeile" );
427 : :
428 [ # # ]: 0 : const SwFmtCntnt& rFlyCntnt = pHdFtFmt->GetCntnt();
429 : 0 : const SwNodeIndex& rCntntStIdx = *rFlyCntnt.GetCntntIdx();
430 : :
431 : : sal_uLong nPrvNxtIdx;
432 [ # # ]: 0 : if( bHeader )
433 : : {
434 : 0 : nPrvNxtIdx = rCntntStIdx.GetNode().EndOfSectionIndex()-1;
435 : : }
436 : : else
437 : : {
438 : 0 : nPrvNxtIdx = pOldPos->nNode.GetIndex() - 1;
439 : : }
440 : :
441 : 0 : sal_uInt16 nSpace = 0;
442 [ # # ][ # # ]: 0 : SwTxtNode *pTxtNode = pDoc->GetNodes()[nPrvNxtIdx]->GetTxtNode();
443 [ # # ]: 0 : if( pTxtNode )
444 : : {
445 : : const SvxULSpaceItem& rULSpace =
446 : : ((const SvxULSpaceItem&)pTxtNode
447 [ # # ]: 0 : ->SwCntntNode::GetAttr( RES_UL_SPACE ));
448 : :
449 : : // Der untere Absatz-Abstand wird zum Abstand zur
450 : : // Kopf- oder Fusszeile
451 : 0 : nSpace = rULSpace.GetLower();
452 : :
453 : : // und anschliessend auf einen vernuenftigen Wert
454 : : // gesetzt
455 : : const SvxULSpaceItem& rCollULSpace =
456 [ # # ]: 0 : pTxtNode->GetAnyFmtColl().GetULSpace();
457 [ # # ]: 0 : if( rCollULSpace.GetUpper() == rULSpace.GetUpper() )
458 [ # # ]: 0 : pTxtNode->ResetAttr( RES_UL_SPACE );
459 : : else
460 : : pTxtNode->SetAttr(
461 : 0 : SvxULSpaceItem( rULSpace.GetUpper(),
462 [ # # ][ # # ]: 0 : rCollULSpace.GetLower(), RES_UL_SPACE ) );
[ # # ]
463 : : }
464 : :
465 [ # # ]: 0 : if( bHeader )
466 : : {
467 : 0 : nPrvNxtIdx = pOldPos->nNode.GetIndex();
468 : : }
469 : : else
470 : : {
471 : 0 : nPrvNxtIdx = rCntntStIdx.GetIndex() + 1;
472 : : }
473 : :
474 [ # # ]: 0 : pTxtNode = pDoc->GetNodes()[nPrvNxtIdx]
475 [ # # ]: 0 : ->GetTxtNode();
476 [ # # ]: 0 : if( pTxtNode )
477 : : {
478 : : const SvxULSpaceItem& rULSpace =
479 : : ((const SvxULSpaceItem&)pTxtNode
480 [ # # ]: 0 : ->SwCntntNode::GetAttr( RES_UL_SPACE ));
481 : :
482 : : // Der obere Absatz-Abstand wird zum Abstand zur
483 : : // Kopf- oder Fusszeile, wenn er groesser ist als
484 : : // der untere vom Absatz davor
485 [ # # ]: 0 : if( rULSpace.GetUpper() > nSpace )
486 : 0 : nSpace = rULSpace.GetUpper();
487 : :
488 : : // und anschliessend auf einen vernuenftigen Wert gesetzt
489 : : const SvxULSpaceItem& rCollULSpace =
490 [ # # ]: 0 : pTxtNode->GetAnyFmtColl().GetULSpace();
491 [ # # ]: 0 : if( rCollULSpace.GetLower() == rULSpace.GetLower() )
492 [ # # ]: 0 : pTxtNode->ResetAttr( RES_UL_SPACE );
493 : : else
494 : : pTxtNode->SetAttr(
495 : 0 : SvxULSpaceItem( rCollULSpace.GetUpper(),
496 [ # # ][ # # ]: 0 : rULSpace.GetLower(), RES_UL_SPACE ) );
[ # # ]
497 : : }
498 : :
499 [ # # ]: 0 : SvxULSpaceItem aULSpace( RES_UL_SPACE );
500 [ # # ]: 0 : if( bHeader )
501 : 0 : aULSpace.SetLower( nSpace );
502 : : else
503 : 0 : aULSpace.SetUpper( nSpace );
504 : :
505 [ # # ][ # # ]: 0 : pHdFtFmt->SetFmtAttr( aULSpace );
506 : 0 : }
507 : :
508 : 0 : sal_Bool SwHTMLParser::EndSection( sal_Bool bLFStripped )
509 : : {
510 : 0 : SwEndNode *pEndNd = pDoc->GetNodes()[pPam->GetPoint()->nNode.GetIndex()+1]
511 : 0 : ->GetEndNode();
512 [ # # ][ # # ]: 0 : if( pEndNd && pEndNd->StartOfSectionNode()->IsSectionNode() )
[ # # ]
513 : : {
514 : : // den Bereich beenden
515 [ # # ]: 0 : if( !bLFStripped )
516 : 0 : StripTrailingPara();
517 : 0 : pPam->Move( fnMoveForward );
518 : 0 : return sal_True;
519 : : }
520 : :
521 : : OSL_ENSURE( !this, "Falsche PaM Position Beenden eines Bereichs" );
522 : :
523 : 0 : return sal_False;
524 : : }
525 : :
526 : 0 : sal_Bool SwHTMLParser::EndSections( sal_Bool bLFStripped )
527 : : {
528 : 0 : sal_Bool bSectionClosed = sal_False;
529 : 0 : sal_uInt16 nPos = aContexts.size();
530 [ # # ]: 0 : while( nPos>nContextStMin )
531 : : {
532 : 0 : _HTMLAttrContext *pCntxt = aContexts[--nPos];
533 [ # # ][ # # ]: 0 : if( pCntxt->GetSpansSection() && EndSection( bLFStripped ) )
[ # # ]
534 : : {
535 : 0 : bSectionClosed = sal_True;
536 : 0 : pCntxt->SetSpansSection( sal_False );
537 : 0 : bLFStripped = sal_False;
538 : : }
539 : : }
540 : :
541 : 0 : return bSectionClosed;
542 : : }
543 : :
544 : 0 : void SwHTMLParser::NewMultiCol()
545 : : {
546 [ # # ][ # # ]: 0 : String aId, aStyle, aClass, aLang, aDir;
[ # # ][ # # ]
[ # # ]
547 : 0 : long nWidth = 100;
548 : 0 : sal_uInt16 nCols = 0, nGutter = 10;
549 : 0 : sal_Bool bPrcWidth = sal_True;
550 : :
551 [ # # ]: 0 : const HTMLOptions& rHTMLOptions = GetOptions();
552 [ # # ]: 0 : for (size_t i = rHTMLOptions.size(); i; )
553 : : {
554 [ # # ]: 0 : const HTMLOption& rOption = rHTMLOptions[--i];
555 [ # # # # : 0 : switch( rOption.GetToken() )
# # # #
# ]
556 : : {
557 : : case HTML_O_ID:
558 [ # # ]: 0 : aId = rOption.GetString();
559 : 0 : break;
560 : : case HTML_O_STYLE:
561 [ # # ]: 0 : aStyle = rOption.GetString();
562 : 0 : break;
563 : : case HTML_O_CLASS:
564 [ # # ]: 0 : aClass = rOption.GetString();
565 : 0 : break;
566 : : case HTML_O_LANG:
567 [ # # ]: 0 : aLang = rOption.GetString();
568 : 0 : break;
569 : : case HTML_O_DIR:
570 [ # # ]: 0 : aDir = rOption.GetString();
571 : 0 : break;
572 : : case HTML_O_COLS:
573 [ # # ]: 0 : nCols = (sal_uInt16)rOption.GetNumber();
574 : 0 : break;
575 : : case HTML_O_WIDTH:
576 [ # # ]: 0 : nWidth = rOption.GetNumber();
577 [ # # ]: 0 : bPrcWidth = (rOption.GetString().Search('%') != STRING_NOTFOUND);
578 [ # # ][ # # ]: 0 : if( bPrcWidth && nWidth>100 )
579 : 0 : nWidth = 100;
580 : 0 : break;
581 : : case HTML_O_GUTTER:
582 [ # # ]: 0 : nGutter = (sal_uInt16)rOption.GetNumber();
583 : 0 : break;
584 : :
585 : : }
586 : : }
587 : :
588 [ # # ][ # # ]: 0 : _HTMLAttrContext *pCntxt = new _HTMLAttrContext( HTML_MULTICOL_ON );
589 : :
590 : : //.is the multicol elememt contained in a container? That may be the
591 : : // case for 5.0 documents.
592 : 0 : sal_Bool bInCntnr = sal_False;
593 : 0 : sal_uInt16 i = aContexts.size();
594 [ # # ][ # # ]: 0 : while( !bInCntnr && i > nContextStMin )
[ # # ]
595 : 0 : bInCntnr = 0 != aContexts[--i]->GetFrmItemSet();
596 : :
597 : : // Parse style sheets, but don't position anything by now.
598 : 0 : sal_Bool bStyleParsed = sal_False;
599 [ # # ][ # # ]: 0 : SfxItemSet aItemSet( pDoc->GetAttrPool(), pCSS1Parser->GetWhichMap() );
600 [ # # ]: 0 : SvxCSS1PropertyInfo aPropInfo;
601 [ # # ]: 0 : if( HasStyleOptions( aStyle, aId, aClass, &aLang, &aDir ) )
602 : : bStyleParsed = ParseStyleOptions( aStyle, aId, aClass,
603 [ # # ]: 0 : aItemSet, aPropInfo, &aLang, &aDir );
604 : :
605 : : // Calculate width.
606 [ # # ]: 0 : sal_uInt8 nPrcWidth = bPrcWidth ? (sal_uInt8)nWidth : 0;
607 : 0 : sal_uInt16 nTwipWidth = 0;
608 [ # # ][ # # ]: 0 : if( !bPrcWidth && nWidth && Application::GetDefaultDevice() )
[ # # ][ # # ]
[ # # ]
609 : : {
610 : : nTwipWidth = (sal_uInt16)Application::GetDefaultDevice()
611 : : ->PixelToLogic( Size(nWidth, 0),
612 [ # # ][ # # ]: 0 : MapMode(MAP_TWIP) ).Width();
[ # # ][ # # ]
613 : : }
614 : :
615 [ # # ][ # # ]: 0 : if( !nPrcWidth && nTwipWidth < MINFLY )
616 : 0 : nTwipWidth = MINFLY;
617 : :
618 : : // Do positioning.
619 : 0 : sal_Bool bPositioned = sal_False;
620 [ # # ][ # # ]: 0 : if( bInCntnr || pCSS1Parser->MayBePositioned( aPropInfo, sal_True ) )
[ # # ][ # # ]
621 : : {
622 : 0 : SfxItemSet aFrmItemSet( pDoc->GetAttrPool(),
623 [ # # ]: 0 : RES_FRMATR_BEGIN, RES_FRMATR_END-1 );
624 [ # # ]: 0 : if( !IsNewDoc() )
625 [ # # ]: 0 : Reader::ResetFrmFmtAttrs(aFrmItemSet );
626 : :
627 : : SetAnchorAndAdjustment( text::VertOrientation::NONE, text::HoriOrientation::NONE, aItemSet, aPropInfo,
628 [ # # ]: 0 : aFrmItemSet );
629 : :
630 : : // The width is either the WIDTH attribute's value or contained
631 : : // in some style option.
632 [ # # ]: 0 : SetVarSize( aItemSet, aPropInfo, aFrmItemSet, nTwipWidth, nPrcWidth );
633 : :
634 [ # # ]: 0 : SetSpace( Size(0,0), aItemSet, aPropInfo, aFrmItemSet );
635 : :
636 : : // Set some other frame attributes. If the background is set, its
637 : : // it will be cleared here. That for, it won't be set at the section,
638 : : // too.
639 : : SetFrmFmtAttrs( aItemSet, aPropInfo,
640 : : HTML_FF_BOX|HTML_FF_BACKGROUND|HTML_FF_PADDING|HTML_FF_DIRECTION,
641 [ # # ]: 0 : aFrmItemSet );
642 : :
643 : : // Insert fly frame. If the are columns, the fly frame's name is not
644 : : // the sections name but a generated one.
645 [ # # ]: 0 : String aFlyName( aEmptyStr );
646 [ # # ]: 0 : if( nCols < 2 )
647 : : {
648 [ # # ]: 0 : aFlyName = aId;
649 [ # # ]: 0 : aPropInfo.aId.Erase();
650 : : }
651 : :
652 [ # # ]: 0 : InsertFlyFrame( aFrmItemSet, pCntxt, aFlyName, CONTEXT_FLAGS_ABSPOS );
653 : :
654 : 0 : pCntxt->SetPopStack( sal_True );
655 [ # # ][ # # ]: 0 : bPositioned = sal_True;
656 : : }
657 : :
658 : 0 : sal_Bool bAppended = sal_False;
659 [ # # ]: 0 : if( !bPositioned )
660 : : {
661 [ # # ]: 0 : if( pPam->GetPoint()->nContent.GetIndex() )
662 : : {
663 [ # # ]: 0 : AppendTxtNode( AM_SPACE );
664 : 0 : bAppended = sal_True;
665 : : }
666 : : else
667 : : {
668 [ # # ]: 0 : AddParSpace();
669 : : }
670 : : }
671 : :
672 : : // If there are less then 2 columns, no section is inserted.
673 [ # # ]: 0 : if( nCols >= 2 )
674 : : {
675 [ # # ]: 0 : if( !bAppended )
676 : : {
677 : : // If the pam is at the start of a section, a additional text
678 : : // node must be inserted. Otherwise, the new section will be
679 : : // inserted in front of the old one.
680 [ # # ]: 0 : SwNodeIndex aPrvNdIdx( pPam->GetPoint()->nNode, -1 );
681 [ # # ]: 0 : if (aPrvNdIdx.GetNode().IsSectionNode())
682 : : {
683 [ # # ]: 0 : AppendTxtNode();
684 : 0 : bAppended = sal_True;
685 [ # # ]: 0 : }
686 : : }
687 [ # # ][ # # ]: 0 : _HTMLAttrs *pPostIts = bAppended ? 0 : new _HTMLAttrs;
[ # # ]
688 [ # # ]: 0 : SetAttr( sal_True, sal_True, pPostIts );
689 : :
690 : : // Make section name unique.
691 [ # # ][ # # ]: 0 : String aName( pDoc->GetUniqueSectionName( aId.Len() ? &aId : 0 ) );
692 [ # # ]: 0 : SwSectionData aSection( CONTENT_SECTION, aName );
693 : :
694 : 0 : SfxItemSet aFrmItemSet( pDoc->GetAttrPool(),
695 [ # # ]: 0 : RES_FRMATR_BEGIN, RES_FRMATR_END-1 );
696 [ # # ]: 0 : if( !IsNewDoc() )
697 [ # # ]: 0 : Reader::ResetFrmFmtAttrs(aFrmItemSet );
698 : :
699 [ # # ][ # # ]: 0 : if( nGutter && Application::GetDefaultDevice() )
[ # # ][ # # ]
700 : : {
701 : : nGutter = (sal_uInt16)Application::GetDefaultDevice()
702 : : ->PixelToLogic( Size(nGutter, 0),
703 [ # # ][ # # ]: 0 : MapMode(MAP_TWIP) ).Width();
[ # # ][ # # ]
704 : : }
705 : :
706 [ # # ]: 0 : SwFmtCol aFmtCol;
707 : : #ifndef WIDTH_SUPPORTED_BY_SECTIONS
708 : 0 : nPrcWidth = 100;
709 : : #endif
710 : :
711 [ # # ][ # # ]: 0 : aFmtCol.Init( nCols, nGutter, nPrcWidth ? USHRT_MAX : nTwipWidth );
712 [ # # ]: 0 : aFrmItemSet.Put( aFmtCol );
713 : :
714 : : const SfxPoolItem *pItem;
715 [ # # ]: 0 : if( SFX_ITEM_SET == aItemSet.GetItemState( RES_BACKGROUND, sal_False,
716 [ # # ]: 0 : &pItem ) )
717 : : {
718 [ # # ]: 0 : aFrmItemSet.Put( *pItem );
719 [ # # ]: 0 : aItemSet.ClearItem( RES_BACKGROUND );
720 : : }
721 [ # # ]: 0 : if( SFX_ITEM_SET == aItemSet.GetItemState( RES_FRAMEDIR, sal_False,
722 [ # # ]: 0 : &pItem ) )
723 : : {
724 [ # # ]: 0 : aFrmItemSet.Put( *pItem );
725 [ # # ]: 0 : aItemSet.ClearItem( RES_FRAMEDIR );
726 : : }
727 [ # # ]: 0 : pDoc->InsertSwSection( *pPam, aSection, 0, &aFrmItemSet, false );
728 : :
729 : : // Jump to section, if this is requested.
730 [ # # ][ # # ]: 0 : if( JUMPTO_REGION == eJumpTo && aName == sJmpMark )
[ # # ][ # # ]
731 : : {
732 : 0 : bChkJumpMark = sal_True;
733 : 0 : eJumpTo = JUMPTO_NONE;
734 : : }
735 : :
736 : : SwTxtNode* pOldTxtNd =
737 [ # # ]: 0 : (bAppended) ? 0 : pPam->GetPoint()->nNode.GetNode().GetTxtNode();
738 : :
739 [ # # ]: 0 : pPam->Move( fnMoveBackward );
740 : :
741 : : // Move PageDesc and SwFmtBreak attributes of the current node
742 : : // to the section's first node.
743 [ # # ]: 0 : if( pOldTxtNd )
744 : 0 : MovePageDescAttrs( pOldTxtNd, pPam->GetPoint()->nNode.GetIndex(),
745 [ # # ][ # # ]: 0 : sal_True );
746 : :
747 [ # # ]: 0 : if( pPostIts )
748 : : {
749 : : // Move pending PostIts into the section.
750 [ # # ]: 0 : InsertAttrs( *pPostIts );
751 [ # # ]: 0 : delete pPostIts;
752 : 0 : pPostIts = 0;
753 : : }
754 : :
755 : 0 : pCntxt->SetSpansSection( sal_True );
756 : :
757 : : // Insert a bookmark if its name differs from the section's name only.
758 [ # # ][ # # ]: 0 : if( aPropInfo.aId.Len() && aPropInfo.aId==aName )
[ # # ][ # # ]
759 [ # # ][ # # ]: 0 : aPropInfo.aId.Erase();
[ # # ][ # # ]
[ # # ]
760 : : }
761 : :
762 : : // Additional attributes must be set as hard ones.
763 [ # # ]: 0 : if( bStyleParsed )
764 [ # # ]: 0 : InsertAttrs( aItemSet, aPropInfo, pCntxt, sal_True );
765 : :
766 [ # # ][ # # ]: 0 : PushContext( pCntxt );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ][ # # ]
767 : 0 : }
768 : :
769 : :
770 : 0 : void SwHTMLParser::InsertFlyFrame( const SfxItemSet& rItemSet,
771 : : _HTMLAttrContext *pCntxt,
772 : : const String& rName,
773 : : sal_uInt16 nFlags )
774 : : {
775 : : RndStdIds eAnchorId =
776 [ # # ]: 0 : ((const SwFmtAnchor&)rItemSet.Get( RES_ANCHOR )).GetAnchorId();
777 : :
778 : : // Den Rahmen anlegen
779 : 0 : SwFlyFrmFmt* pFlyFmt = pDoc->MakeFlySection( eAnchorId, pPam->GetPoint(),
780 [ # # ]: 0 : &rItemSet );
781 : : // Ggf. den Namen setzen
782 [ # # ]: 0 : if( rName.Len() )
783 [ # # ]: 0 : pFlyFmt->SetName( rName );
784 : :
785 [ # # ]: 0 : RegisterFlyFrm( pFlyFmt );
786 : :
787 [ # # ]: 0 : const SwFmtCntnt& rFlyCntnt = pFlyFmt->GetCntnt();
788 : 0 : const SwNodeIndex& rFlyCntIdx = *rFlyCntnt.GetCntntIdx();
789 [ # # ]: 0 : SwCntntNode *pCNd = pDoc->GetNodes()[rFlyCntIdx.GetIndex()+1]
790 [ # # ]: 0 : ->GetCntntNode();
791 : :
792 [ # # ][ # # ]: 0 : SwPosition aNewPos( SwNodeIndex( rFlyCntIdx, 1 ), SwIndex( pCNd, 0 ) );
[ # # ][ # # ]
[ # # ][ # # ]
793 [ # # ][ # # ]: 0 : SaveDocContext( pCntxt, nFlags, &aNewPos );
794 : 0 : }
795 : :
796 : :
797 : :
798 : 0 : void SwHTMLParser::MovePageDescAttrs( SwNode *pSrcNd,
799 : : sal_uLong nDestIdx,
800 : : sal_Bool bFmtBreak )
801 : : {
802 : : SwCntntNode* pDestCntntNd =
803 : 0 : pDoc->GetNodes()[nDestIdx]->GetCntntNode();
804 : :
805 : : OSL_ENSURE( pDestCntntNd, "Wieso ist das Ziel kein Content-Node?" );
806 : :
807 [ # # ]: 0 : if( pSrcNd->IsCntntNode() )
808 : : {
809 : 0 : SwCntntNode* pSrcCntntNd = pSrcNd->GetCntntNode();
810 : :
811 : : const SfxPoolItem* pItem;
812 [ # # # # ]: 0 : if( SFX_ITEM_SET == pSrcCntntNd->GetSwAttrSet()
[ # # ][ # # ]
813 [ # # ]: 0 : .GetItemState( RES_PAGEDESC, sal_False, &pItem ) &&
814 : 0 : ((SwFmtPageDesc *)pItem)->GetPageDesc() )
815 : : {
816 [ # # ]: 0 : pDestCntntNd->SetAttr( *pItem );
817 [ # # ]: 0 : pSrcCntntNd->ResetAttr( RES_PAGEDESC );
818 : : }
819 [ # # ][ # # ]: 0 : if( SFX_ITEM_SET == pSrcCntntNd->GetSwAttrSet()
820 [ # # ]: 0 : .GetItemState( RES_BREAK, sal_False, &pItem ) )
821 : : {
822 [ # # ]: 0 : switch( ((SvxFmtBreakItem *)pItem)->GetBreak() )
823 : : {
824 : : case SVX_BREAK_PAGE_BEFORE:
825 : : case SVX_BREAK_PAGE_AFTER:
826 : : case SVX_BREAK_PAGE_BOTH:
827 [ # # ]: 0 : if( bFmtBreak )
828 [ # # ]: 0 : pDestCntntNd->SetAttr( *pItem );
829 [ # # ]: 0 : pSrcCntntNd->ResetAttr( RES_BREAK );
830 : : default:
831 : : ;
832 : : }
833 : : }
834 : : }
835 [ # # ]: 0 : else if( pSrcNd->IsTableNode() )
836 : : {
837 : 0 : SwFrmFmt *pFrmFmt = pSrcNd->GetTableNode()->GetTable().GetFrmFmt();
838 : :
839 : : const SfxPoolItem* pItem;
840 [ # # ]: 0 : if( SFX_ITEM_SET == pFrmFmt->GetAttrSet().
841 [ # # ]: 0 : GetItemState( RES_PAGEDESC, sal_False, &pItem ) )
842 : : {
843 [ # # ]: 0 : pDestCntntNd->SetAttr( *pItem );
844 [ # # ]: 0 : pFrmFmt->ResetFmtAttr( RES_PAGEDESC );
845 : : }
846 : : }
847 : 0 : }
848 : :
849 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|