Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include "hintids.hxx"
30 : : #include <svl/itemiter.hxx>
31 : : #include <editeng/lrspitem.hxx>
32 : : #include <editeng/ulspitem.hxx>
33 : : #include <editeng/brshitem.hxx>
34 : : #include <editeng/fhgtitem.hxx>
35 : : #include <svtools/htmltokn.h>
36 : :
37 : : #include "doc.hxx"
38 : : #include "pam.hxx"
39 : : #include "ndtxt.hxx"
40 : : #include "shellio.hxx"
41 : : #include "paratr.hxx"
42 : : #include "htmlnum.hxx"
43 : : #include "css1kywd.hxx"
44 : : #include "swcss1.hxx"
45 : : #include "swhtml.hxx"
46 : :
47 : : using namespace ::com::sun::star;
48 : :
49 : :
50 : :
51 : :
52 : : class _HTMLAttrContext_SaveDoc
53 : : {
54 : : SwHTMLNumRuleInfo aNumRuleInfo; // In Umgebung gueltige Numerierung
55 : : SwPosition *pPos; // hierhin beim verlassen den
56 : : // Kontexts zurueckgesprungen
57 : : _HTMLAttrTable *pAttrTab; // In Umgebung gueltige Attribute,
58 : : // wenn Attributierung nicht
59 : : // beibehalten werden soll.
60 : :
61 : : sal_uInt16 nContextStMin; // In Umgebung gueltige Stack-
62 : : // Untergrenze, wenn der Stack
63 : : // geschuetzt werden soll.
64 : : sal_uInt16 nContextStAttrMin; // In Umgebung gueltige Stack-
65 : : // Untergrenze, wenn die Attribute
66 : : // nicht beibehalten werden sollen.
67 : :
68 : : sal_Bool bStripTrailingPara : 1; // letzen Absatz entfernen?
69 : : sal_Bool bKeepNumRules : 1; // Numerierung beibehalten?
70 : : sal_Bool bPopStack : 1; // Stack-Elemente oberhalb des
71 : : // zu schliessenden entfernen?
72 : : sal_Bool bFixHeaderDist : 1;
73 : : sal_Bool bFixFooterDist : 1;
74 : :
75 : : public:
76 : :
77 : 0 : _HTMLAttrContext_SaveDoc() :
78 : : pPos( 0 ), pAttrTab( 0 ),
79 : : nContextStMin( USHRT_MAX ), nContextStAttrMin( USHRT_MAX ),
80 : : bStripTrailingPara( sal_False ), bKeepNumRules( sal_False ),
81 : : bPopStack( sal_False ),
82 : 0 : bFixHeaderDist( sal_False ), bFixFooterDist( sal_False )
83 : 0 : {}
84 : :
85 [ # # ]: 0 : ~_HTMLAttrContext_SaveDoc() { delete pPos; delete pAttrTab; }
86 : :
87 : : // Die Position gehoert uns, muss also angelegt und zerstoert werden
88 [ # # ]: 0 : void SetPos( const SwPosition& rPos ) { pPos = new SwPosition(rPos); }
89 : 0 : const SwPosition *GetPos() const { return pPos; }
90 : :
91 : : // Der Index gehoert uns nicht. Kein Anlgen und Zerstoeren.
92 : 0 : void SetNumInfo( const SwHTMLNumRuleInfo& rInf ) { aNumRuleInfo.Set(rInf); }
93 : 0 : const SwHTMLNumRuleInfo& GetNumInfo() const { return aNumRuleInfo; }
94 : :
95 : : _HTMLAttrTable *GetAttrTab( sal_Bool bCreate= sal_False );
96 : :
97 : 0 : void SetContextStMin( sal_uInt16 nMin ) { nContextStMin = nMin; }
98 : 0 : sal_uInt16 GetContextStMin() const { return nContextStMin; }
99 : :
100 : 0 : void SetContextStAttrMin( sal_uInt16 nMin ) { nContextStAttrMin = nMin; }
101 : 0 : sal_uInt16 GetContextStAttrMin() const { return nContextStAttrMin; }
102 : :
103 : 0 : void SetStripTrailingPara( sal_Bool bSet ) { bStripTrailingPara = bSet; }
104 : 0 : sal_Bool GetStripTrailingPara() const { return bStripTrailingPara; }
105 : :
106 : 0 : void SetKeepNumRules( sal_Bool bSet ) { bKeepNumRules = bSet; }
107 : 0 : sal_Bool GetKeepNumRules() const { return bKeepNumRules; }
108 : :
109 : 0 : void SetFixHeaderDist( sal_Bool bSet ) { bFixHeaderDist = bSet; }
110 : 0 : sal_Bool GetFixHeaderDist() const { return bFixHeaderDist; }
111 : :
112 : 0 : void SetFixFooterDist( sal_Bool bSet ) { bFixFooterDist = bSet; }
113 : 0 : sal_Bool GetFixFooterDist() const { return bFixFooterDist; }
114 : : };
115 : :
116 : 0 : _HTMLAttrTable *_HTMLAttrContext_SaveDoc::GetAttrTab( sal_Bool bCreate )
117 : : {
118 [ # # ][ # # ]: 0 : if( !pAttrTab && bCreate )
119 : : {
120 : 0 : pAttrTab = new _HTMLAttrTable;
121 : 0 : memset( pAttrTab, 0, sizeof( _HTMLAttrTable ));
122 : : }
123 : 0 : return pAttrTab;
124 : : }
125 : :
126 : :
127 : 0 : _HTMLAttrContext_SaveDoc *_HTMLAttrContext::GetSaveDocContext( sal_Bool bCreate )
128 : : {
129 [ # # ][ # # ]: 0 : if( !pSaveDocContext && bCreate )
130 : 0 : pSaveDocContext = new _HTMLAttrContext_SaveDoc;
131 : :
132 : 0 : return pSaveDocContext;
133 : : }
134 : :
135 : 2 : void _HTMLAttrContext::ClearSaveDocContext()
136 : : {
137 [ - + ]: 2 : delete pSaveDocContext;
138 : 2 : pSaveDocContext = 0;
139 : 2 : }
140 : :
141 : :
142 : 0 : void SwHTMLParser::SplitAttrTab( const SwPosition& rNewPos )
143 : : {
144 : : // preliminary paragraph attributes are not allowed here, they could
145 : : // be set here and then the pointers become invalid!
146 : : OSL_ENSURE(aParaAttrs.empty(),
147 : : "Danger: there are non-final paragraph attributes");
148 [ # # ]: 0 : if( !aParaAttrs.empty() )
149 : 0 : aParaAttrs.clear();
150 : :
151 : 0 : const SwNodeIndex* pOldEndPara = &pPam->GetPoint()->nNode;
152 : 0 : xub_StrLen nOldEndCnt = pPam->GetPoint()->nContent.GetIndex();
153 : :
154 : 0 : const SwNodeIndex& rNewSttPara = rNewPos.nNode;
155 : 0 : xub_StrLen nNewSttCnt = rNewPos.nContent.GetIndex();
156 : :
157 : 0 : sal_Bool bMoveBack = sal_False;
158 : :
159 : : // alle noch offenen Attribute beenden und hinter der Tabelle
160 : : // neu aufspannen
161 : 0 : _HTMLAttr** pTbl = (_HTMLAttr**)&aAttrTab;
162 [ # # ]: 0 : for( sal_uInt16 nCnt = sizeof( _HTMLAttrTable ) / sizeof( _HTMLAttr* );
163 : : nCnt--; ++pTbl )
164 : : {
165 : 0 : _HTMLAttr *pAttr = *pTbl;
166 [ # # ]: 0 : while( pAttr )
167 : : {
168 : 0 : _HTMLAttr *pNext = pAttr->GetNext();
169 : 0 : _HTMLAttr *pPrev = pAttr->GetPrev();
170 : :
171 : 0 : sal_uInt16 nWhich = pAttr->pItem->Which();
172 [ # # # # ]: 0 : if( !nOldEndCnt && RES_PARATR_BEGIN <= nWhich &&
[ # # ][ # # ]
173 : 0 : pAttr->GetSttParaIdx() < pOldEndPara->GetIndex() )
174 : : {
175 : : // Das Attribut muss eine Content-Position weiter vorne
176 : : // beendet werden
177 [ # # ]: 0 : if( !bMoveBack )
178 : : {
179 [ # # ]: 0 : bMoveBack = pPam->Move( fnMoveBackward );
180 : 0 : nOldEndCnt = pPam->GetPoint()->nContent.GetIndex();
181 : : }
182 : : }
183 [ # # ]: 0 : else if( bMoveBack )
184 : : {
185 [ # # ]: 0 : pPam->Move( fnMoveForward );
186 : 0 : nOldEndCnt = pPam->GetPoint()->nContent.GetIndex();
187 : : }
188 : :
189 [ # # ][ # # : 0 : if( (RES_PARATR_BEGIN <= nWhich && bMoveBack) ||
# # # # #
# ][ # # ]
190 : 0 : pAttr->GetSttParaIdx() < pOldEndPara->GetIndex() ||
191 : 0 : (pAttr->GetSttPara() == *pOldEndPara &&
192 : 0 : pAttr->GetSttCnt() != nOldEndCnt) )
193 : : {
194 : : // Das Attribut muss gesetzt werden. Da wir
195 : : // das Original noch brauchen, weil Zeiger auf das Attribut
196 : : // noch in den Kontexten existieren, muessen wir es clonen.
197 : : // Die Next-Liste geht dabei verloren, aber die
198 : : // Previous-Liste bleibt erhalten
199 [ # # ]: 0 : _HTMLAttr *pSetAttr = pAttr->Clone( *pOldEndPara, nOldEndCnt );
200 : :
201 [ # # ]: 0 : if( pNext )
202 [ # # ]: 0 : pNext->InsertPrev( pSetAttr );
203 : : else
204 : : {
205 [ # # ]: 0 : if (pSetAttr->bInsAtStart)
206 [ # # ]: 0 : aSetAttrTab.push_front( pSetAttr );
207 : : else
208 [ # # ]: 0 : aSetAttrTab.push_back( pSetAttr );
209 : : }
210 : : }
211 [ # # ]: 0 : else if( pPrev )
212 : : {
213 : : // Wenn das Attribut nicht gesetzt vor der Tabelle
214 : : // gesetzt werden muss, muessen der Previous-Attribute
215 : : // trotzdem gesetzt werden.
216 [ # # ]: 0 : if( pNext )
217 [ # # ]: 0 : pNext->InsertPrev( pPrev );
218 : : else
219 : : {
220 [ # # ]: 0 : if (pPrev->bInsAtStart)
221 [ # # ]: 0 : aSetAttrTab.push_front( pPrev );
222 : : else
223 [ # # ]: 0 : aSetAttrTab.push_back( pPrev );
224 : : }
225 : : }
226 : :
227 : : // den Start des Attributs neu setzen
228 [ # # ]: 0 : pAttr->nSttPara = rNewSttPara;
229 [ # # ]: 0 : pAttr->nEndPara = rNewSttPara;
230 : 0 : pAttr->nSttCntnt = nNewSttCnt;
231 : 0 : pAttr->nEndCntnt = nNewSttCnt;
232 : 0 : pAttr->pPrev = 0;
233 : :
234 : 0 : pAttr = pNext;
235 : : }
236 : : }
237 : :
238 [ # # ]: 0 : if( bMoveBack )
239 : 0 : pPam->Move( fnMoveForward );
240 : :
241 : 0 : }
242 : :
243 : 0 : void SwHTMLParser::SaveDocContext( _HTMLAttrContext *pCntxt,
244 : : sal_uInt16 nFlags,
245 : : const SwPosition *pNewPos )
246 : : {
247 : 0 : _HTMLAttrContext_SaveDoc *pSave = pCntxt->GetSaveDocContext( sal_True );
248 : 0 : pSave->SetStripTrailingPara( (HTML_CNTXT_STRIP_PARA & nFlags) != 0 );
249 : 0 : pSave->SetKeepNumRules( (HTML_CNTXT_KEEP_NUMRULE & nFlags) != 0 );
250 : 0 : pSave->SetFixHeaderDist( (HTML_CNTXT_HEADER_DIST & nFlags) != 0 );
251 : 0 : pSave->SetFixFooterDist( (HTML_CNTXT_FOOTER_DIST & nFlags) != 0 );
252 : :
253 [ # # ]: 0 : if( pNewPos )
254 : : {
255 : : // Wenn der PaM an eine andere Position gesetzt wird, muss
256 : : // die Numerierung gerettet werden..
257 [ # # ]: 0 : if( !pSave->GetKeepNumRules() )
258 : : {
259 : : // Die Numerierung soll nicht beibehalten werden. Also muss
260 : : // der aktuelle Zustand gerettet und die Numerierung
261 : : // anschliessend ausgeschaltet werden.
262 : 0 : pSave->SetNumInfo( GetNumInfo() );
263 : 0 : GetNumInfo().Clear();
264 : : }
265 : :
266 [ # # ]: 0 : if( (HTML_CNTXT_KEEP_ATTRS & nFlags) != 0 )
267 : : {
268 : : // Attribute an aktueller Position beenden und an neuer neu anfangen
269 : 0 : SplitAttrTab( *pNewPos );
270 : : }
271 : : else
272 : : {
273 : 0 : _HTMLAttrTable *pSaveAttrTab = pSave->GetAttrTab( sal_True );
274 : 0 : SaveAttrTab( *pSaveAttrTab );
275 : : }
276 : :
277 : :
278 : 0 : pSave->SetPos( *pPam->GetPoint() );
279 : 0 : *pPam->GetPoint() = *pNewPos;
280 : : }
281 : :
282 : : // Mit dem Setzen von nContextStMin koennen automatisch auch
283 : : // keine gerade offenen Listen (DL/OL/UL) mehr beendet werden.
284 [ # # ]: 0 : if( (HTML_CNTXT_PROTECT_STACK & nFlags) != 0 )
285 : : {
286 : 0 : pSave->SetContextStMin( nContextStMin );
287 : 0 : nContextStMin = aContexts.size();
288 : :
289 [ # # ]: 0 : if( (HTML_CNTXT_KEEP_ATTRS & nFlags) == 0 )
290 : : {
291 : 0 : pSave->SetContextStAttrMin( nContextStAttrMin );
292 : 0 : nContextStAttrMin = aContexts.size();
293 : : }
294 : : }
295 : 0 : }
296 : :
297 : 0 : void SwHTMLParser::RestoreDocContext( _HTMLAttrContext *pCntxt )
298 : : {
299 : 0 : _HTMLAttrContext_SaveDoc *pSave = pCntxt->GetSaveDocContext();
300 [ # # ]: 0 : if( !pSave )
301 : 0 : return;
302 : :
303 [ # # ]: 0 : if( pSave->GetStripTrailingPara() )
304 : 0 : StripTrailingPara();
305 : :
306 [ # # ]: 0 : if( pSave->GetPos() )
307 : : {
308 [ # # ][ # # ]: 0 : if( pSave->GetFixHeaderDist() || pSave->GetFixFooterDist() )
[ # # ]
309 : 0 : FixHeaderFooterDistance( pSave->GetFixHeaderDist(),
310 : 0 : pSave->GetPos() );
311 : :
312 : 0 : _HTMLAttrTable *pSaveAttrTab = pSave->GetAttrTab();
313 [ # # ]: 0 : if( !pSaveAttrTab )
314 : : {
315 : : // Attribute an aktueller Position beenden und an alter neu
316 : : // anfangen.
317 : 0 : SplitAttrTab( *pSave->GetPos() );
318 : : }
319 : : else
320 : : {
321 : 0 : RestoreAttrTab( *pSaveAttrTab );
322 : : }
323 : :
324 : 0 : *pPam->GetPoint() = *pSave->GetPos();
325 : :
326 : : // Die bisherigen Attribute koennen wir schonmal setzen.
327 : 0 : SetAttr();
328 : : }
329 : :
330 [ # # ]: 0 : if( USHRT_MAX != pSave->GetContextStMin() )
331 : : {
332 : 0 : nContextStMin = pSave->GetContextStMin();
333 [ # # ]: 0 : if( USHRT_MAX != pSave->GetContextStAttrMin() )
334 : 0 : nContextStAttrMin = pSave->GetContextStAttrMin();
335 : : }
336 : :
337 [ # # ]: 0 : if( !pSave->GetKeepNumRules() )
338 : : {
339 : : // Die bisherige gemerkte Numerierung wieder setzen
340 : 0 : GetNumInfo().Set( pSave->GetNumInfo() );
341 : : }
342 : :
343 : 0 : pCntxt->ClearSaveDocContext();
344 : : }
345 : :
346 : :
347 : 2 : void SwHTMLParser::EndContext( _HTMLAttrContext *pContext )
348 : : {
349 [ - + ]: 2 : if( pContext->GetPopStack() )
350 : : {
351 : : // Alle noch offenen Kontexte beenden. Der eigene
352 : : // Kontext muss bereits geloscht sein!
353 [ # # ]: 0 : while( aContexts.size() > nContextStMin )
354 : : {
355 : 0 : _HTMLAttrContext *pCntxt = PopContext();
356 : : OSL_ENSURE( pCntxt != pContext,
357 : : "Kontext noch im Stack" );
358 [ # # ]: 0 : if( pCntxt == pContext )
359 : 0 : break;
360 : :
361 : 0 : EndContext( pCntxt );
362 [ # # ]: 0 : delete pCntxt;
363 : : }
364 : : }
365 : :
366 : : // Alle noch offenen Attribute beenden
367 [ - + ]: 2 : if( pContext->HasAttrs() )
368 : 0 : EndContextAttrs( pContext );
369 : :
370 : : // Falls ein Bereich geoeffnet wurde, den verlassen. Da Bereiche
371 : : // auch innerhalb von absolut positionierten Objekten angelegt werden,
372 : : // muss das passieren, bever ein alter Dokument-Kontext restauriert wird.
373 [ - + ]: 2 : if( pContext->GetSpansSection() )
374 : 0 : EndSection();
375 : :
376 : : // Rahmen und sonstige Sonderbereiche verlassen.
377 [ - + ]: 2 : if( pContext->HasSaveDocContext() )
378 : 0 : RestoreDocContext( pContext );
379 : :
380 : : // Ggf. noch einen Ansatz-Umbruch einfuegen
381 [ - + # # ]: 2 : if( AM_NONE != pContext->GetAppendMode() &&
[ - + ]
382 : 0 : pPam->GetPoint()->nContent.GetIndex() )
383 : 0 : AppendTxtNode( pContext->GetAppendMode() );
384 : :
385 : : // PRE-/LISTING- und XMP-Umgebungen wieder starten
386 [ - + ]: 2 : if( pContext->IsFinishPREListingXMP() )
387 : 0 : FinishPREListingXMP();
388 : :
389 [ - + ]: 2 : if( pContext->IsRestartPRE() )
390 : 0 : StartPRE();
391 : :
392 [ - + ]: 2 : if( pContext->IsRestartXMP() )
393 : 0 : StartXMP();
394 : :
395 [ - + ]: 2 : if( pContext->IsRestartListing() )
396 : 0 : StartListing();
397 : 2 : }
398 : :
399 : 0 : void SwHTMLParser::ClearContext( _HTMLAttrContext *pContext )
400 : : {
401 : 0 : _HTMLAttrs &rAttrs = pContext->GetAttrs();
402 [ # # ]: 0 : for( sal_uInt16 i=0; i<rAttrs.size(); i++ )
403 : : {
404 : : // einfaches Loeschen reicht hier nicht, weil das
405 : : // Attribut auch aus seiner Liste ausgetragen werden
406 : : // muss. Theoretisch koennt man natuerlich auch die Liste
407 : : // und die Attribute getrennt loeschen, aber wenn man
408 : : // dann was falsch gemacht hat, sieht es uebel aus.
409 : 0 : DeleteAttr( rAttrs[i] );
410 : : }
411 : :
412 : : OSL_ENSURE( !pContext->GetSpansSection(),
413 : : "Bereich kann nicht mehr verlassen werden" );
414 : :
415 : : OSL_ENSURE( !pContext->HasSaveDocContext(),
416 : : "Rahmen kann nicht mehr verlassen werden" );
417 : :
418 : : // PRE-/LISTING- und XMP-Umgebungen wieder starten
419 [ # # ]: 0 : if( pContext->IsFinishPREListingXMP() )
420 : 0 : FinishPREListingXMP();
421 : :
422 [ # # ]: 0 : if( pContext->IsRestartPRE() )
423 : 0 : StartPRE();
424 : :
425 [ # # ]: 0 : if( pContext->IsRestartXMP() )
426 : 0 : StartXMP();
427 : :
428 [ # # ]: 0 : if( pContext->IsRestartListing() )
429 : 0 : StartListing();
430 : 0 : }
431 : :
432 : :
433 : 0 : sal_Bool SwHTMLParser::DoPositioning( SfxItemSet &rItemSet,
434 : : SvxCSS1PropertyInfo &rPropInfo,
435 : : _HTMLAttrContext *pContext )
436 : : {
437 : 0 : sal_Bool bRet = sal_False;
438 : :
439 : : // Unter folgenden Umstaenden wird jetzt ein Rahmen aufgemacht:
440 : : // - das Tag wird absolut positioniert und left/top sind beide
441 : : // gegeben und enthalten auch keine %-Angabe, oder
442 : : // - das Tag soll fliessen, und
443 : : // - es wurde eine Breite angegeben (in beiden Faellen noetig)
444 [ # # ]: 0 : if( SwCSS1Parser::MayBePositioned( rPropInfo ) )
445 : : {
446 : 0 : SfxItemSet aFrmItemSet( pDoc->GetAttrPool(),
447 [ # # ]: 0 : RES_FRMATR_BEGIN, RES_FRMATR_END-1 );
448 [ # # ]: 0 : if( !IsNewDoc() )
449 [ # # ]: 0 : Reader::ResetFrmFmtAttrs(aFrmItemSet );
450 : :
451 : : // Ausrichtung setzen
452 : : SetAnchorAndAdjustment( text::VertOrientation::NONE, text::HoriOrientation::NONE, rItemSet, rPropInfo,
453 [ # # ]: 0 : aFrmItemSet );
454 : :
455 : : // Groesse setzen
456 [ # # ]: 0 : SetVarSize( rItemSet, rPropInfo, aFrmItemSet );
457 : :
458 : : // Abstaende setzen
459 [ # # ]: 0 : SetSpace( Size(0,0), rItemSet, rPropInfo, aFrmItemSet );
460 : :
461 : : // Sonstige CSS1-Attribute Setzen
462 : : SetFrmFmtAttrs( rItemSet, rPropInfo,
463 : : HTML_FF_BOX|HTML_FF_PADDING|HTML_FF_BACKGROUND|HTML_FF_DIRECTION,
464 [ # # ]: 0 : aFrmItemSet );
465 : :
466 : : InsertFlyFrame( aFrmItemSet, pContext, rPropInfo.aId,
467 [ # # ]: 0 : CONTEXT_FLAGS_ABSPOS );
468 : 0 : pContext->SetPopStack( sal_True );
469 [ # # ]: 0 : rPropInfo.aId.Erase();
470 [ # # ]: 0 : bRet = sal_True;
471 : : }
472 : :
473 : 0 : return bRet;
474 : : }
475 : :
476 : 0 : sal_Bool SwHTMLParser::CreateContainer( const String& rClass,
477 : : SfxItemSet &rItemSet,
478 : : SvxCSS1PropertyInfo &rPropInfo,
479 : : _HTMLAttrContext *pContext )
480 : : {
481 : 0 : sal_Bool bRet = sal_False;
482 [ # # # # ]: 0 : if( rClass.EqualsIgnoreCaseAscii(sCSS1_class_abs_pos) &&
[ # # ]
483 : 0 : pCSS1Parser->MayBePositioned( rPropInfo ) )
484 : : {
485 : : // Container-Klasse
486 [ # # ]: 0 : SfxItemSet *pFrmItemSet = pContext->GetFrmItemSet( pDoc );
487 [ # # ]: 0 : if( !IsNewDoc() )
488 [ # # ]: 0 : Reader::ResetFrmFmtAttrs( *pFrmItemSet );
489 : :
490 : : SetAnchorAndAdjustment( text::VertOrientation::NONE, text::HoriOrientation::NONE,
491 [ # # ]: 0 : rItemSet, rPropInfo, *pFrmItemSet );
492 : 0 : Size aDummy(0,0);
493 : : SetFixSize( aDummy, aDummy, sal_False, sal_False, rItemSet, rPropInfo,
494 [ # # ]: 0 : *pFrmItemSet );
495 [ # # ]: 0 : SetSpace( aDummy, rItemSet, rPropInfo, *pFrmItemSet );
496 : : SetFrmFmtAttrs( rItemSet, rPropInfo, HTML_FF_BOX|HTML_FF_BACKGROUND|HTML_FF_DIRECTION,
497 [ # # ]: 0 : *pFrmItemSet );
498 : :
499 : 0 : bRet = sal_True;
500 : : }
501 : :
502 : 0 : return bRet;
503 : : }
504 : :
505 : :
506 : 0 : void SwHTMLParser::InsertAttrs( SfxItemSet &rItemSet,
507 : : SvxCSS1PropertyInfo &rPropInfo,
508 : : _HTMLAttrContext *pContext,
509 : : sal_Bool bCharLvl )
510 : : {
511 : : // Ein DropCap-Attribut basteln, wenn auf Zeichen-Ebene vor dem
512 : : // ersten Zeichen ein float: left vorkommt
513 [ # # ][ # # ]: 0 : if( bCharLvl && !pPam->GetPoint()->nContent.GetIndex() &&
[ # # ][ # # ]
514 : : SVX_ADJUST_LEFT == rPropInfo.eFloat )
515 : : {
516 [ # # ]: 0 : SwFmtDrop aDrop;
517 : 0 : aDrop.GetChars() = 1;
518 : :
519 [ # # ]: 0 : pCSS1Parser->FillDropCap( aDrop, rItemSet );
520 : :
521 : : // Nur wenn das Initial auch ueber mehrere Zeilen geht, wird das
522 : : // DropCap-Attribut gesetzt. Sonst setzten wir die Attribute hart.
523 [ # # ]: 0 : if( aDrop.GetLines() > 1 )
524 : : {
525 [ # # ]: 0 : NewAttr( &aAttrTab.pDropCap, aDrop );
526 : :
527 : 0 : _HTMLAttrs &rAttrs = pContext->GetAttrs();
528 [ # # ]: 0 : rAttrs.push_back( aAttrTab.pDropCap );
529 : :
530 : 0 : return;
531 [ # # ][ # # ]: 0 : }
532 : : }
533 : :
534 : : // Feature: PrintExt
535 [ # # ]: 0 : if( !bCharLvl )
536 [ # # ]: 0 : pCSS1Parser->SetFmtBreak( rItemSet, rPropInfo );
537 : : // /Feature: PrintExt
538 : :
539 : : OSL_ENSURE(aContexts.size() <= nContextStAttrMin ||
540 : : aContexts.back() != pContext,
541 : : "SwHTMLParser::InsertAttrs: Context already on the Stack");
542 : :
543 [ # # ]: 0 : SfxItemIter aIter( rItemSet );
544 : :
545 : 0 : const SfxPoolItem *pItem = aIter.FirstItem();
546 [ # # ]: 0 : while( pItem )
547 : : {
548 : 0 : _HTMLAttr **ppAttr = 0;
549 : :
550 [ # # # # : 0 : switch( pItem->Which() )
# # # ]
551 : : {
552 : : case RES_LR_SPACE:
553 : : {
554 : : // Absatz-Einzuege muessen addiert werden und werden immer
555 : : // nur absatzweise gesetzt (fuer den ersten Absatz hier,
556 : : // fuer alle folgenden in SetTxtCollAttrs)
557 : :
558 : : const SvxLRSpaceItem *pLRItem =
559 : 0 : (const SvxLRSpaceItem *)pItem;
560 : :
561 : : // die bisherigen Absatz-Abstaende holen (ohne die vom
562 : : // obersten Kontext, denn den veraendern wir ja gerade) ...
563 : 0 : sal_uInt16 nOldLeft = 0, nOldRight = 0;
564 : 0 : short nOldIndent = 0;
565 : 0 : sal_Bool bIgnoreTop = aContexts.size() > nContextStMin &&
566 [ # # ][ # # ]: 0 : aContexts.back() == pContext;
[ # # ]
567 : : GetMarginsFromContext( nOldLeft, nOldRight, nOldIndent,
568 [ # # ]: 0 : bIgnoreTop );
569 : :
570 : :
571 : : // und noch die aktuell gueltigen
572 : 0 : sal_uInt16 nLeft = nOldLeft, nRight = nOldRight;
573 : 0 : short nIndent = nOldIndent;
574 : 0 : pContext->GetMargins( nLeft, nRight, nIndent );
575 : :
576 : : // ... und die neuen Abstaende zu den alten addieren
577 : : // Hier werden nicht die aus dem Item genommen, sondern die
578 : : // extra gemerkten, weil die auch negativ sein koennen. Die
579 : : // Abfrage ueber das Item funktioniert aber trotzdem, denn
580 : : // fuer negative Werte wird das Item (mit Wert 0) auch
581 : : // eingefuegt.
582 [ # # ]: 0 : if( rPropInfo.bLeftMargin )
583 : : {
584 : : OSL_ENSURE( rPropInfo.nLeftMargin < 0 ||
585 : : rPropInfo.nLeftMargin == pLRItem->GetTxtLeft(),
586 : : "linker Abstand stimmt nicht mit Item ueberein" );
587 [ # # ][ # # ]: 0 : if( rPropInfo.nLeftMargin < 0 &&
588 : : -rPropInfo.nLeftMargin > nOldLeft )
589 : 0 : nLeft = 0;
590 : : else
591 : 0 : nLeft = nOldLeft + static_cast< sal_uInt16 >(rPropInfo.nLeftMargin);
592 : : }
593 [ # # ]: 0 : if( rPropInfo.bRightMargin )
594 : : {
595 : : OSL_ENSURE( rPropInfo.nRightMargin < 0 ||
596 : : rPropInfo.nRightMargin == pLRItem->GetRight(),
597 : : "rechter Abstand stimmt nicht mit Item ueberein" );
598 [ # # ][ # # ]: 0 : if( rPropInfo.nRightMargin < 0 &&
599 : : -rPropInfo.nRightMargin > nOldRight )
600 : 0 : nRight = 0;
601 : : else
602 : 0 : nRight = nOldRight + static_cast< sal_uInt16 >(rPropInfo.nRightMargin);
603 : : }
604 [ # # ]: 0 : if( rPropInfo.bTextIndent )
605 : 0 : nIndent = pLRItem->GetTxtFirstLineOfst();
606 : :
607 : : // und die Werte fuer nachfolgende Absaetze merken
608 : 0 : pContext->SetMargins( nLeft, nRight, nIndent );
609 : :
610 : : // das Attribut noch am aktuellen Absatz setzen
611 [ # # ]: 0 : SvxLRSpaceItem aLRItem( *pLRItem );
612 [ # # ]: 0 : aLRItem.SetTxtFirstLineOfst( nIndent );
613 [ # # ]: 0 : aLRItem.SetTxtLeft( nLeft );
614 : 0 : aLRItem.SetRight( nRight );
615 [ # # ]: 0 : NewAttr( &aAttrTab.pLRSpace, aLRItem );
616 [ # # ][ # # ]: 0 : EndAttr( aAttrTab.pLRSpace, 0, sal_False );
617 : : }
618 : 0 : break;
619 : :
620 : : case RES_UL_SPACE:
621 [ # # ][ # # ]: 0 : if( !rPropInfo.bTopMargin || !rPropInfo.bBottomMargin )
622 : : {
623 : 0 : sal_uInt16 nUpper = 0, nLower = 0;
624 [ # # ]: 0 : GetULSpaceFromContext( nUpper, nLower );
625 [ # # ]: 0 : SvxULSpaceItem aULSpace( *((const SvxULSpaceItem *)pItem) );
626 [ # # ]: 0 : if( !rPropInfo.bTopMargin )
627 : 0 : aULSpace.SetUpper( nUpper );
628 [ # # ]: 0 : if( !rPropInfo.bBottomMargin )
629 : 0 : aULSpace.SetLower( nLower );
630 : :
631 [ # # ]: 0 : NewAttr( &aAttrTab.pULSpace, aULSpace );
632 : :
633 : : // ... und noch die Kontext-Information speichern
634 : 0 : _HTMLAttrs &rAttrs = pContext->GetAttrs();
635 [ # # ]: 0 : rAttrs.push_back( aAttrTab.pULSpace );
636 : :
637 [ # # ]: 0 : pContext->SetULSpace( aULSpace.GetUpper(), aULSpace.GetLower() );
638 : : }
639 : : else
640 : : {
641 : 0 : ppAttr = &aAttrTab.pULSpace;
642 : : }
643 : 0 : break;
644 : : case RES_CHRATR_FONTSIZE:
645 : : // es werden keine Attribute mit %-Angaben gesetzt
646 [ # # ]: 0 : if( ((const SvxFontHeightItem *)pItem)->GetProp() == 100 )
647 : 0 : ppAttr = &aAttrTab.pFontHeight;
648 : 0 : break;
649 : : case RES_CHRATR_CJK_FONTSIZE:
650 : : // es werden keine Attribute mit %-Angaben gesetzt
651 [ # # ]: 0 : if( ((const SvxFontHeightItem *)pItem)->GetProp() == 100 )
652 : 0 : ppAttr = &aAttrTab.pFontHeightCJK;
653 : 0 : break;
654 : : case RES_CHRATR_CTL_FONTSIZE:
655 : : // es werden keine Attribute mit %-Angaben gesetzt
656 [ # # ]: 0 : if( ((const SvxFontHeightItem *)pItem)->GetProp() == 100 )
657 : 0 : ppAttr = &aAttrTab.pFontHeightCTL;
658 : 0 : break;
659 : :
660 : : case RES_BACKGROUND:
661 [ # # ]: 0 : if( bCharLvl )
662 : : {
663 : : // das Frame-Attr ggf. in ein Char-Attr umwandeln
664 [ # # ]: 0 : SvxBrushItem aBrushItem( *(const SvxBrushItem *)pItem );
665 : 0 : aBrushItem.SetWhich( RES_CHRATR_BACKGROUND );
666 : :
667 : : // Das Attribut setzen ...
668 [ # # ]: 0 : NewAttr( &aAttrTab.pCharBrush, aBrushItem );
669 : :
670 : : // ... und noch die Kontext-Information speichern
671 : 0 : _HTMLAttrs &rAttrs = pContext->GetAttrs();
672 [ # # ][ # # ]: 0 : rAttrs.push_back( aAttrTab.pCharBrush );
673 : : }
674 [ # # # # ]: 0 : else if( pContext->GetToken() != HTML_TABLEHEADER_ON &&
[ # # ]
675 : 0 : pContext->GetToken() != HTML_TABLEDATA_ON )
676 : : {
677 : 0 : ppAttr = &aAttrTab.pBrush;
678 : : }
679 : 0 : break;
680 : :
681 : : default:
682 : : // den zu dem Item gehoehrenden Tabellen-Eintrag ermitteln ...
683 [ # # ]: 0 : ppAttr = GetAttrTabEntry( pItem->Which() );
684 : 0 : break;
685 : : }
686 : :
687 [ # # ]: 0 : if( ppAttr )
688 : : {
689 : : // Das Attribut setzen ...
690 [ # # ]: 0 : NewAttr( ppAttr, *pItem );
691 : :
692 : : // ... und noch die Kontext-Information speichern
693 : 0 : _HTMLAttrs &rAttrs = pContext->GetAttrs();
694 [ # # ]: 0 : rAttrs.push_back( *ppAttr );
695 : : }
696 : :
697 : : // auf zum naechsten Item
698 [ # # ]: 0 : pItem = aIter.NextItem();
699 : : }
700 : :
701 [ # # ]: 0 : if( rPropInfo.aId.Len() )
702 [ # # ][ # # ]: 0 : InsertBookmark( rPropInfo.aId );
703 : : }
704 : :
705 : 0 : void SwHTMLParser::InsertAttr( _HTMLAttr **ppAttr, const SfxPoolItem & rItem,
706 : : _HTMLAttrContext *pCntxt )
707 : : {
708 [ # # ]: 0 : if( !ppAttr )
709 : : {
710 : 0 : ppAttr = GetAttrTabEntry( rItem.Which() );
711 [ # # ]: 0 : if( !ppAttr )
712 : 0 : return;
713 : : }
714 : :
715 : : // das Attribut setzen
716 : 0 : NewAttr( ppAttr, rItem );
717 : :
718 : : // und im Kontext merken
719 : 0 : _HTMLAttrs &rAttrs = pCntxt->GetAttrs();
720 : 0 : rAttrs.push_back( *ppAttr );
721 : : }
722 : :
723 : 0 : void SwHTMLParser::SplitPREListingXMP( _HTMLAttrContext *pCntxt )
724 : : {
725 : : // PRE/Listing/XMP soll beim beenden des Kontexts beendet werden.
726 : 0 : pCntxt->SetFinishPREListingXMP( sal_True );
727 : :
728 : : // Und die jetzt gueltigen Flags sollen wieder gesetzt werden.
729 [ # # ]: 0 : if( IsReadPRE() )
730 : 0 : pCntxt->SetRestartPRE( sal_True );
731 [ # # ]: 0 : if( IsReadXMP() )
732 : 0 : pCntxt->SetRestartXMP( sal_True );
733 [ # # ]: 0 : if( IsReadListing() )
734 : 0 : pCntxt->SetRestartListing( sal_True );
735 : :
736 : : // PRE/Listing/XMP wird auuserdem sofort beendet
737 : 0 : FinishPREListingXMP();
738 : 0 : }
739 : :
740 : 0 : SfxItemSet *_HTMLAttrContext::GetFrmItemSet( SwDoc *pCreateDoc )
741 : : {
742 [ # # ][ # # ]: 0 : if( !pFrmItemSet && pCreateDoc )
743 : 0 : pFrmItemSet = new SfxItemSet( pCreateDoc->GetAttrPool(),
744 [ # # ]: 0 : RES_FRMATR_BEGIN, RES_FRMATR_END-1 );
745 : 0 : return pFrmItemSet;
746 : : }
747 : :
748 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|