Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include "hintids.hxx"
21 : #include <svl/itemiter.hxx>
22 : #include <svl/whiter.hxx>
23 : #include <svl/urihelper.hxx>
24 : #include <i18nlangtag/languagetag.hxx>
25 : #include <sfx2/docfile.hxx>
26 : #include <vcl/svapp.hxx>
27 : #include <editeng/fhgtitem.hxx>
28 : #include <editeng/brushitem.hxx>
29 : #include <editeng/lrspitem.hxx>
30 : #include <editeng/ulspitem.hxx>
31 : #include <editeng/boxitem.hxx>
32 : #include <editeng/flstitem.hxx>
33 : #include <editeng/formatbreakitem.hxx>
34 : #include <editeng/keepitem.hxx>
35 : #include <editeng/fontitem.hxx>
36 : #include <editeng/langitem.hxx>
37 : #include <editeng/frmdiritem.hxx>
38 : #include <svtools/htmltokn.h>
39 : #include <svtools/htmlkywd.hxx>
40 : #include <fmtpdsc.hxx>
41 : #include <fmtanchr.hxx>
42 : #include <fmtornt.hxx>
43 : #include <fmtsrnd.hxx>
44 : #include <fmtfsize.hxx>
45 : #include "frmatr.hxx"
46 : #include <charfmt.hxx>
47 : #include <docary.hxx>
48 : #include <svx/svxids.hrc>
49 :
50 : #include "doc.hxx"
51 : #include "pam.hxx"
52 : #include "ndtxt.hxx"
53 : #include "poolfmt.hxx"
54 : #include "docsh.hxx"
55 : #include "paratr.hxx"
56 : #include "pagedesc.hxx"
57 : #include "css1kywd.hxx"
58 : #include "swcss1.hxx"
59 : #include "htmlnum.hxx"
60 : #include "swhtml.hxx"
61 : #include <numrule.hxx>
62 :
63 : using namespace ::com::sun::star;
64 :
65 : // Wie viele Zeilen/Zeichen sind fuer DropCaps erlaubt?
66 : // (Gibt es vielleicht woanders entsprechende Werte?)
67 : #define MAX_DROPCAP_LINES 9
68 : #define MAX_DROPCAP_CHARS 9
69 :
70 : static void lcl_swcss1_setEncoding( SwFmt& rFmt, rtl_TextEncoding eEnc );
71 :
72 : // Implementierung des SwCSS1Parsers (eigentlich swcss1.cxx)
73 : static struct SwCSS1ItemIds
74 : {
75 : sal_uInt16 nFmtBreak;
76 : sal_uInt16 nFmtPageDesc;
77 : sal_uInt16 nFmtKeep;
78 :
79 0 : SwCSS1ItemIds() :
80 : nFmtBreak( RES_BREAK ),
81 : nFmtPageDesc( RES_PAGEDESC ),
82 0 : nFmtKeep( RES_KEEP )
83 0 : {}
84 :
85 0 : } aItemIds;
86 :
87 0 : void SwCSS1Parser::ChgPageDesc( const SwPageDesc *pPageDesc,
88 : const SwPageDesc& rNewPageDesc )
89 : {
90 0 : sal_uInt16 nPageDescs = pDoc->GetPageDescCnt();
91 : sal_uInt16 i;
92 0 : for( i=0; i<nPageDescs; i++ )
93 0 : if( pPageDesc == &pDoc->GetPageDesc(i) )
94 : {
95 0 : pDoc->ChgPageDesc( i, rNewPageDesc );
96 0 : return;
97 : }
98 :
99 : OSL_ENSURE( i<nPageDescs, "Seitenvorlage nicht gefunden" );
100 : }
101 :
102 0 : SwCSS1Parser::SwCSS1Parser( SwDoc *pD, sal_uInt32 aFHeights[7], const OUString& rBaseURL, sal_Bool bNewDoc ) :
103 0 : SvxCSS1Parser( pD->GetAttrPool(), rBaseURL, MM50/2,
104 0 : (sal_uInt16*)&aItemIds, sizeof(aItemIds) / sizeof(sal_uInt16) ),
105 : pDoc( pD ),
106 : nDropCapCnt( 0 ),
107 : bIsNewDoc( bNewDoc ),
108 : bBodyBGColorSet( sal_False ),
109 : bBodyBackgroundSet( sal_False ),
110 : bBodyTextSet( sal_False ),
111 : bBodyLinkSet( sal_False ),
112 : bBodyVLinkSet( sal_False ),
113 : bSetFirstPageDesc( sal_False ),
114 : bSetRightPageDesc( sal_False ),
115 : bTableHeaderTxtCollSet( sal_False ),
116 : bTableTxtCollSet( sal_False ),
117 0 : bLinkCharFmtsSet( sal_False )
118 : {
119 0 : aFontHeights[0] = aFHeights[0];
120 0 : aFontHeights[1] = aFHeights[1];
121 0 : aFontHeights[2] = aFHeights[2];
122 0 : aFontHeights[3] = aFHeights[3];
123 0 : aFontHeights[4] = aFHeights[4];
124 0 : aFontHeights[5] = aFHeights[5];
125 0 : aFontHeights[6] = aFHeights[6];
126 0 : }
127 :
128 0 : SwCSS1Parser::~SwCSS1Parser()
129 : {
130 0 : }
131 :
132 : // Feature: PrintExt
133 0 : sal_Bool SwCSS1Parser::SetFmtBreak( SfxItemSet& rItemSet,
134 : const SvxCSS1PropertyInfo& rPropInfo )
135 : {
136 0 : SvxBreak eBreak = SVX_BREAK_NONE;
137 0 : sal_Bool bKeep = sal_False;
138 0 : sal_Bool bSetKeep = sal_False, bSetBreak = sal_False, bSetPageDesc = sal_False;
139 0 : const SwPageDesc *pPageDesc = 0;
140 0 : switch( rPropInfo.ePageBreakBefore )
141 : {
142 : case SVX_CSS1_PBREAK_ALWAYS:
143 0 : eBreak = SVX_BREAK_PAGE_BEFORE;
144 0 : bSetBreak = sal_True;
145 0 : break;
146 : case SVX_CSS1_PBREAK_LEFT:
147 0 : pPageDesc = GetLeftPageDesc( sal_True );
148 0 : bSetPageDesc = sal_True;
149 0 : break;
150 : case SVX_CSS1_PBREAK_RIGHT:
151 0 : pPageDesc = GetRightPageDesc( sal_True );
152 0 : bSetPageDesc = sal_True;
153 0 : break;
154 : case SVX_CSS1_PBREAK_AUTO:
155 0 : bSetBreak = bSetPageDesc = sal_True;
156 0 : break;
157 : default:
158 : ;
159 : }
160 0 : switch( rPropInfo.ePageBreakAfter )
161 : {
162 : case SVX_CSS1_PBREAK_ALWAYS:
163 : case SVX_CSS1_PBREAK_LEFT:
164 : case SVX_CSS1_PBREAK_RIGHT:
165 : // LEFT/RIGHT koennte man auch am Absatz davor setzen
166 0 : eBreak = SVX_BREAK_PAGE_AFTER;
167 0 : bSetBreak = sal_True;
168 0 : break;
169 : case SVX_CSS1_PBREAK_AUTO:
170 0 : bSetBreak = bSetKeep = bSetPageDesc = sal_True;
171 0 : break;
172 : case SVX_CSS1_PBREAK_AVOID:
173 0 : bKeep = bSetKeep = sal_True;
174 0 : break;
175 : default:
176 : ;
177 : }
178 :
179 0 : if( bSetBreak )
180 0 : rItemSet.Put( SvxFmtBreakItem( eBreak, RES_BREAK ) );
181 0 : if( bSetPageDesc )
182 0 : rItemSet.Put( SwFmtPageDesc( pPageDesc ) );
183 0 : if( bSetKeep )
184 0 : rItemSet.Put( SvxFmtKeepItem( bKeep, RES_KEEP ) );
185 :
186 0 : return bSetBreak;
187 : }
188 : // /Feature: PrintExt
189 :
190 0 : static void SetCharFmtAttrs( SwCharFmt *pCharFmt, SfxItemSet& rItemSet )
191 : {
192 : const SfxPoolItem *pItem;
193 : static const sal_uInt16 aWhichIds[3] = { RES_CHRATR_FONTSIZE,RES_CHRATR_CJK_FONTSIZE,
194 : RES_CHRATR_CTL_FONTSIZE };
195 0 : for( sal_uInt16 i=0; i<3; i++ )
196 : {
197 0 : if( SFX_ITEM_SET == rItemSet.GetItemState( aWhichIds[i], false,
198 0 : &pItem ) &&
199 0 : ((const SvxFontHeightItem *)pItem)->GetProp() != 100)
200 : {
201 : // %-Angaben beim FontHeight-Item werden nicht unterstuetzt
202 0 : rItemSet.ClearItem( aWhichIds[i] );
203 : }
204 : }
205 :
206 0 : pCharFmt->SetFmtAttr( rItemSet );
207 :
208 0 : if( SFX_ITEM_SET == rItemSet.GetItemState( RES_BACKGROUND, false, &pItem ) )
209 : {
210 : // Ein Brush-Item mit RES_BACKGROUND muss noch in eines mit
211 : // RES_CHRATR_BACKGROUND gewandelt werden
212 :
213 0 : SvxBrushItem aBrushItem( *(const SvxBrushItem *)pItem );
214 0 : aBrushItem.SetWhich( RES_CHRATR_BACKGROUND );
215 0 : pCharFmt->SetFmtAttr( aBrushItem );
216 : }
217 :
218 0 : if( SFX_ITEM_SET == rItemSet.GetItemState( RES_BOX, false, &pItem ) )
219 : {
220 0 : SvxBoxItem aBoxItem( *(const SvxBoxItem *)pItem );
221 0 : aBoxItem.SetWhich( RES_CHRATR_BOX );
222 0 : pCharFmt->SetFmtAttr( aBoxItem );
223 : }
224 0 : }
225 :
226 0 : void SwCSS1Parser::SetLinkCharFmts()
227 : {
228 : OSL_ENSURE( !bLinkCharFmtsSet, "Aufruf von SetLinkCharFmts unnoetig" );
229 :
230 : SvxCSS1MapEntry *pStyleEntry =
231 0 : GetTag( OUString(OOO_STRING_SVTOOLS_HTML_anchor) );
232 0 : SwCharFmt *pUnvisited = 0, *pVisited = 0;
233 0 : if( pStyleEntry )
234 : {
235 0 : SfxItemSet& rItemSet = pStyleEntry->GetItemSet();
236 0 : sal_Bool bColorSet = (SFX_ITEM_SET==rItemSet.GetItemState(RES_CHRATR_COLOR,
237 0 : false));
238 0 : pUnvisited = GetCharFmtFromPool( RES_POOLCHR_INET_NORMAL );
239 0 : SetCharFmtAttrs( pUnvisited, rItemSet );
240 0 : bBodyLinkSet |= bColorSet;
241 :
242 0 : pVisited = GetCharFmtFromPool( RES_POOLCHR_INET_VISIT );
243 0 : SetCharFmtAttrs( pVisited, rItemSet );
244 0 : bBodyVLinkSet |= bColorSet;
245 : }
246 :
247 0 : OUString sTmp = OOO_STRING_SVTOOLS_HTML_anchor ":link";
248 :
249 0 : pStyleEntry = GetTag( sTmp );
250 0 : if( pStyleEntry )
251 : {
252 0 : SfxItemSet& rItemSet = pStyleEntry->GetItemSet();
253 0 : sal_Bool bColorSet = (SFX_ITEM_SET==rItemSet.GetItemState(RES_CHRATR_COLOR,
254 0 : false));
255 0 : if( !pUnvisited )
256 0 : pUnvisited = GetCharFmtFromPool( RES_POOLCHR_INET_NORMAL );
257 0 : SetCharFmtAttrs( pUnvisited, rItemSet );
258 0 : bBodyLinkSet |= bColorSet;
259 : }
260 :
261 0 : sTmp = OOO_STRING_SVTOOLS_HTML_anchor ":visited";
262 :
263 0 : pStyleEntry = GetTag( sTmp );
264 0 : if( pStyleEntry )
265 : {
266 0 : SfxItemSet& rItemSet = pStyleEntry->GetItemSet();
267 0 : sal_Bool bColorSet = (SFX_ITEM_SET==rItemSet.GetItemState(RES_CHRATR_COLOR,
268 0 : false));
269 0 : if( !pVisited )
270 0 : pVisited = GetCharFmtFromPool( RES_POOLCHR_INET_VISIT );
271 0 : SetCharFmtAttrs( pVisited, rItemSet );
272 0 : bBodyVLinkSet |= bColorSet;
273 : }
274 :
275 0 : bLinkCharFmtsSet = sal_True;
276 0 : }
277 :
278 0 : static void SetTxtCollAttrs( SwTxtFmtColl *pColl, SfxItemSet& rItemSet,
279 : SvxCSS1PropertyInfo& rPropInfo,
280 : SwCSS1Parser *pCSS1Parser )
281 : {
282 0 : const SfxItemSet& rCollItemSet = pColl->GetAttrSet();
283 : const SfxPoolItem *pCollItem, *pItem;
284 :
285 : // linker, rechter Rand und Erstzeilen-Einzug
286 0 : if( (rPropInfo.bLeftMargin || rPropInfo.bRightMargin ||
287 0 : rPropInfo.bTextIndent) &&
288 0 : (!rPropInfo.bLeftMargin || !rPropInfo.bRightMargin ||
289 0 : !rPropInfo.bTextIndent) &&
290 0 : SFX_ITEM_SET == rCollItemSet.GetItemState(RES_LR_SPACE,true,&pCollItem) &&
291 0 : SFX_ITEM_SET == rItemSet.GetItemState(RES_LR_SPACE,false,&pItem) )
292 : {
293 0 : const SvxLRSpaceItem *pLRItem = (const SvxLRSpaceItem *)pItem;
294 :
295 0 : SvxLRSpaceItem aLRItem( *((const SvxLRSpaceItem *)pCollItem) );
296 0 : if( rPropInfo.bLeftMargin )
297 0 : aLRItem.SetTxtLeft( pLRItem->GetTxtLeft() );
298 0 : if( rPropInfo.bRightMargin )
299 0 : aLRItem.SetRight( pLRItem->GetRight() );
300 0 : if( rPropInfo.bTextIndent )
301 0 : aLRItem.SetTxtFirstLineOfst( pLRItem->GetTxtFirstLineOfst() );
302 :
303 0 : rItemSet.Put( aLRItem );
304 : }
305 :
306 : // oberer und unterer Rand
307 0 : if( (rPropInfo.bTopMargin || rPropInfo.bBottomMargin) &&
308 0 : (!rPropInfo.bTopMargin || !rPropInfo.bBottomMargin) &&
309 : SFX_ITEM_SET == rCollItemSet.GetItemState(RES_UL_SPACE,true,
310 0 : &pCollItem) &&
311 0 : SFX_ITEM_SET == rItemSet.GetItemState(RES_UL_SPACE,false,&pItem) )
312 : {
313 0 : const SvxULSpaceItem *pULItem = (const SvxULSpaceItem *)pItem;
314 :
315 0 : SvxULSpaceItem aULItem( *((const SvxULSpaceItem *)pCollItem) );
316 0 : if( rPropInfo.bTopMargin )
317 0 : aULItem.SetUpper( pULItem->GetUpper() );
318 0 : if( rPropInfo.bBottomMargin )
319 0 : aULItem.SetLower( pULItem->GetLower() );
320 :
321 0 : rItemSet.Put( aULItem );
322 : }
323 :
324 : static const sal_uInt16 aWhichIds[3] = { RES_CHRATR_FONTSIZE,RES_CHRATR_CJK_FONTSIZE,
325 : RES_CHRATR_CTL_FONTSIZE };
326 0 : for( sal_uInt16 i=0; i<3; i++ )
327 : {
328 0 : if( SFX_ITEM_SET == rItemSet.GetItemState( aWhichIds[i], false,
329 0 : &pItem ) &&
330 0 : ((const SvxFontHeightItem *)pItem)->GetProp() != 100)
331 : {
332 : // %-Angaben beim FontHeight-Item werden nicht unterstuetzt
333 0 : rItemSet.ClearItem( aWhichIds[i] );
334 : }
335 : }
336 :
337 : // Feature: PrintExt
338 0 : pCSS1Parser->SetFmtBreak( rItemSet, rPropInfo );
339 : // /Feature: PrintExt
340 :
341 0 : pColl->SetFmtAttr( rItemSet );
342 0 : }
343 :
344 0 : void SwCSS1Parser::SetTableTxtColl( sal_Bool bHeader )
345 : {
346 : OSL_ENSURE( !(bHeader ? bTableHeaderTxtCollSet : bTableTxtCollSet),
347 : "Aufruf von SetTableTxtColl unnoetig" );
348 :
349 : sal_uInt16 nPoolId;
350 0 : OUString sTag;
351 0 : if( bHeader )
352 : {
353 0 : nPoolId = RES_POOLCOLL_TABLE_HDLN;
354 0 : sTag = OOO_STRING_SVTOOLS_HTML_tableheader;
355 : }
356 : else
357 : {
358 0 : nPoolId = RES_POOLCOLL_TABLE;
359 0 : sTag = OOO_STRING_SVTOOLS_HTML_tabledata;
360 : }
361 :
362 0 : SwTxtFmtColl *pColl = 0;
363 :
364 : // The following entries will never be used again and may be changed.
365 0 : SvxCSS1MapEntry *pStyleEntry = GetTag( sTag );
366 0 : if( pStyleEntry )
367 : {
368 0 : pColl = GetTxtFmtColl( nPoolId, aEmptyOUStr );
369 0 : SetTxtCollAttrs( pColl, pStyleEntry->GetItemSet(),
370 0 : pStyleEntry->GetPropertyInfo(), this );
371 : }
372 :
373 0 : OUString sTmp = sTag + " " + OOO_STRING_SVTOOLS_HTML_parabreak;
374 0 : pStyleEntry = GetTag( sTmp );
375 0 : if( pStyleEntry )
376 : {
377 0 : if( !pColl )
378 0 : pColl = GetTxtFmtColl( nPoolId, aEmptyOUStr );
379 0 : SetTxtCollAttrs( pColl, pStyleEntry->GetItemSet(),
380 0 : pStyleEntry->GetPropertyInfo(), this );
381 : }
382 :
383 0 : if( bHeader )
384 0 : bTableHeaderTxtCollSet = sal_True;
385 : else
386 0 : bTableTxtCollSet = sal_True;
387 0 : }
388 :
389 0 : void SwCSS1Parser::SetPageDescAttrs( const SvxBrushItem *pBrush,
390 : SfxItemSet *pItemSet2 )
391 : {
392 0 : SvxBrushItem aBrushItem( RES_BACKGROUND );
393 0 : SvxBoxItem aBoxItem( RES_BOX );
394 0 : SvxFrameDirectionItem aFrmDirItem(FRMDIR_ENVIRONMENT, RES_FRAMEDIR);
395 0 : sal_Bool bSetBrush = pBrush!=0, bSetBox = sal_False, bSetFrmDir = sal_False;
396 0 : if( pBrush )
397 0 : aBrushItem = *pBrush;
398 :
399 0 : if( pItemSet2 )
400 : {
401 0 : const SfxPoolItem *pItem = 0;
402 0 : if( SFX_ITEM_SET == pItemSet2->GetItemState( RES_BACKGROUND, false,
403 0 : &pItem ) )
404 : {
405 : // ein Hintergrund wird gesetzt
406 0 : aBrushItem = *((const SvxBrushItem *)pItem);
407 0 : pItemSet2->ClearItem( RES_BACKGROUND );
408 0 : bSetBrush = sal_True;
409 : }
410 :
411 0 : if( SFX_ITEM_SET == pItemSet2->GetItemState( RES_BOX, false, &pItem ) )
412 : {
413 : // eine Umrandung wird gesetzt
414 0 : aBoxItem = *((const SvxBoxItem *)pItem);
415 0 : pItemSet2->ClearItem( RES_BOX );
416 0 : bSetBox = sal_True;
417 : }
418 :
419 0 : if( SFX_ITEM_SET == pItemSet2->GetItemState( RES_FRAMEDIR, false, &pItem ) )
420 : {
421 : // eine Umrandung wird gesetzt
422 0 : aFrmDirItem = *static_cast< const SvxFrameDirectionItem *>( pItem );
423 0 : pItemSet2->ClearItem( RES_FRAMEDIR );
424 0 : bSetFrmDir = sal_True;
425 : }
426 : }
427 :
428 0 : if( bSetBrush || bSetBox || bSetFrmDir )
429 : {
430 : static sal_uInt16 aPoolIds[] = { RES_POOLPAGE_HTML, RES_POOLPAGE_FIRST,
431 : RES_POOLPAGE_LEFT, RES_POOLPAGE_RIGHT };
432 0 : for( sal_uInt16 i=0; i<4; i++ )
433 : {
434 0 : const SwPageDesc *pPageDesc = GetPageDesc( aPoolIds[i], sal_False );
435 0 : if( pPageDesc )
436 : {
437 0 : SwPageDesc aNewPageDesc( *pPageDesc );
438 0 : SwFrmFmt &rMaster = aNewPageDesc.GetMaster();
439 0 : if( bSetBrush )
440 0 : rMaster.SetFmtAttr( aBrushItem );
441 0 : if( bSetBox )
442 0 : rMaster.SetFmtAttr( aBoxItem );
443 0 : if( bSetFrmDir )
444 0 : rMaster.SetFmtAttr( aFrmDirItem );
445 :
446 0 : ChgPageDesc( pPageDesc, aNewPageDesc );
447 : }
448 : }
449 0 : }
450 0 : }
451 :
452 : // Feature: PrintExt
453 0 : void SwCSS1Parser::SetPageDescAttrs( const SwPageDesc *pPageDesc,
454 : SfxItemSet& rItemSet,
455 : const SvxCSS1PropertyInfo& rPropInfo )
456 : {
457 0 : if( !pPageDesc )
458 0 : return;
459 :
460 0 : SwPageDesc aNewPageDesc( *pPageDesc );
461 0 : SwFrmFmt &rMaster = aNewPageDesc.GetMaster();
462 0 : const SfxItemSet& rPageItemSet = rMaster.GetAttrSet();
463 : const SfxPoolItem *pPageItem, *pItem;
464 0 : sal_Bool bChanged = sal_False;
465 :
466 : // linker, rechter Rand und Erstzeilen-Einzug
467 0 : if( (rPropInfo.bLeftMargin || rPropInfo.bRightMargin) &&
468 0 : SFX_ITEM_SET == rItemSet.GetItemState(RES_LR_SPACE,false,&pItem) )
469 : {
470 0 : if( (!rPropInfo.bLeftMargin || !rPropInfo.bRightMargin) &&
471 : SFX_ITEM_SET == rPageItemSet.GetItemState(RES_LR_SPACE,
472 0 : true,&pPageItem) )
473 : {
474 0 : const SvxLRSpaceItem *pLRItem = (const SvxLRSpaceItem *)pItem;
475 :
476 0 : SvxLRSpaceItem aLRItem( *((const SvxLRSpaceItem *)pPageItem) );
477 0 : if( rPropInfo.bLeftMargin )
478 0 : aLRItem.SetLeft( pLRItem->GetLeft() );
479 0 : if( rPropInfo.bRightMargin )
480 0 : aLRItem.SetRight( pLRItem->GetRight() );
481 :
482 0 : rMaster.SetFmtAttr( aLRItem );
483 : }
484 : else
485 : {
486 0 : rMaster.SetFmtAttr( *pItem );
487 : }
488 0 : bChanged = sal_True;
489 : }
490 :
491 : // oberer und unterer Rand
492 0 : if( (rPropInfo.bTopMargin || rPropInfo.bBottomMargin) &&
493 0 : SFX_ITEM_SET == rItemSet.GetItemState(RES_UL_SPACE,false,&pItem) )
494 : {
495 0 : if( (!rPropInfo.bTopMargin || !rPropInfo.bBottomMargin) &&
496 : SFX_ITEM_SET == rPageItemSet.GetItemState(RES_UL_SPACE,
497 0 : true,&pPageItem) )
498 : {
499 0 : const SvxULSpaceItem *pULItem = (const SvxULSpaceItem *)pItem;
500 :
501 0 : SvxULSpaceItem aULItem( *((const SvxULSpaceItem *)pPageItem) );
502 0 : if( rPropInfo.bTopMargin )
503 0 : aULItem.SetUpper( pULItem->GetUpper() );
504 0 : if( rPropInfo.bBottomMargin )
505 0 : aULItem.SetLower( pULItem->GetLower() );
506 :
507 0 : rMaster.SetFmtAttr( aULItem );
508 : }
509 : else
510 : {
511 0 : rMaster.SetFmtAttr( *pItem );
512 : }
513 0 : bChanged = sal_True;
514 : }
515 :
516 : // die Groesse
517 0 : if( rPropInfo.eSizeType != SVX_CSS1_STYPE_NONE )
518 : {
519 0 : if( rPropInfo.eSizeType == SVX_CSS1_STYPE_TWIP )
520 : {
521 : rMaster.SetFmtAttr( SwFmtFrmSize( ATT_FIX_SIZE, rPropInfo.nWidth,
522 0 : rPropInfo.nHeight ) );
523 0 : bChanged = sal_True;
524 : }
525 : else
526 : {
527 : // Bei "size: auto|portrait|landscape" bleibt die bisherige
528 : // Groesse der Vorlage erhalten. Bei "landscape" und "portrait"
529 : // wird das Landscape-Flag gesetzt und evtl. die Breite/Hoehe
530 : // vertauscht.
531 0 : SwFmtFrmSize aFrmSz( rMaster.GetFrmSize() );
532 0 : sal_Bool bLandscape = aNewPageDesc.GetLandscape();
533 0 : if( ( bLandscape &&
534 0 : rPropInfo.eSizeType == SVX_CSS1_STYPE_PORTRAIT ) ||
535 0 : ( !bLandscape &&
536 0 : rPropInfo.eSizeType == SVX_CSS1_STYPE_LANDSCAPE ) )
537 : {
538 0 : SwTwips nTmp = aFrmSz.GetHeight();
539 0 : aFrmSz.SetHeight( aFrmSz.GetWidth() );
540 0 : aFrmSz.SetWidth( nTmp );
541 0 : rMaster.SetFmtAttr( aFrmSz );
542 0 : aNewPageDesc.SetLandscape( !bLandscape );
543 0 : bChanged = sal_True;
544 0 : }
545 : }
546 : }
547 :
548 : // Geht das wirklich?
549 0 : if( SFX_ITEM_SET == rItemSet.GetItemState( RES_BACKGROUND, false, &pItem ) )
550 : {
551 : // eine Umrandung wird gesetzt
552 0 : rMaster.SetFmtAttr( *pItem );
553 0 : rItemSet.ClearItem( RES_BACKGROUND );
554 0 : bChanged = sal_True;
555 : }
556 :
557 0 : if( bChanged )
558 0 : ChgPageDesc( pPageDesc, aNewPageDesc );
559 : }
560 : // /Feature: PrintExt
561 :
562 0 : const SvxBrushItem& SwCSS1Parser::GetPageDescBackground() const
563 : {
564 0 : return pDoc->GetPageDescFromPool( RES_POOLPAGE_HTML, false )
565 0 : ->GetMaster().GetBackground();
566 : }
567 :
568 0 : sal_uInt16 SwCSS1Parser::GetScriptFromClass( OUString& rClass,
569 : sal_Bool bSubClassOnly )
570 : {
571 0 : sal_uInt16 nScriptFlags = CSS1_SCRIPT_ALL;
572 0 : sal_Int32 nLen = rClass.getLength();
573 0 : sal_Int32 nPos = nLen > 4 ? rClass.lastIndexOf( '-' ) : -1;
574 :
575 0 : if( nPos == -1 )
576 : {
577 0 : if( bSubClassOnly )
578 0 : return nScriptFlags;
579 0 : nPos = 0;
580 : }
581 : else
582 : {
583 0 : nPos++;
584 0 : nLen = nLen - nPos;
585 : }
586 :
587 0 : switch( nLen )
588 : {
589 : case 3:
590 0 : if( rClass.matchIgnoreAsciiCaseAsciiL( "cjk", 3, nPos ) )
591 : {
592 0 : nScriptFlags = CSS1_SCRIPT_CJK;
593 : }
594 0 : else if( rClass.matchIgnoreAsciiCaseAsciiL( "ctl", 3, nPos ) )
595 : {
596 0 : nScriptFlags = CSS1_SCRIPT_CTL;
597 : }
598 0 : break;
599 : case 7:
600 0 : if( rClass.matchIgnoreAsciiCaseAsciiL( "western", 7, nPos ) )
601 : {
602 0 : nScriptFlags = CSS1_SCRIPT_WESTERN;
603 : }
604 0 : break;
605 : }
606 0 : if( CSS1_SCRIPT_ALL != nScriptFlags )
607 : {
608 0 : if( nPos )
609 : {
610 0 : rClass = rClass.copy( 0, nPos-1 );
611 : }
612 : else
613 : {
614 0 : rClass = "";
615 : }
616 : }
617 :
618 0 : return nScriptFlags;
619 : }
620 :
621 0 : static CSS1SelectorType GetTokenAndClass( const CSS1Selector *pSelector,
622 : OUString& rToken, OUString& rClass,
623 : sal_uInt16& rScriptFlags )
624 : {
625 0 : rToken = pSelector->GetString();
626 0 : rClass = "";
627 0 : rScriptFlags = CSS1_SCRIPT_ALL;
628 :
629 0 : CSS1SelectorType eType = pSelector->GetType();
630 0 : if( CSS1_SELTYPE_ELEM_CLASS==eType )
631 : {
632 0 : sal_Int32 nPos = rToken.indexOf( '.' );
633 : OSL_ENSURE( nPos >= 0, "kein Punkt in Class-Selektor???" );
634 0 : if( nPos >= 0 )
635 : {
636 0 : rClass = rToken.copy( nPos+1 );
637 0 : rToken = rToken.copy( 0, nPos );
638 :
639 0 : rScriptFlags = SwCSS1Parser::GetScriptFromClass( rClass, sal_False );
640 0 : if( rClass.isEmpty() )
641 0 : eType = CSS1_SELTYPE_ELEMENT;
642 : }
643 : }
644 :
645 0 : rToken = rToken.toAsciiLowerCase();
646 0 : return eType;
647 : }
648 :
649 : extern bool swhtml_css1atr_equalFontItems( const SfxPoolItem& r1, const SfxPoolItem& r2 );
650 :
651 0 : static void RemoveScriptItems( SfxItemSet& rItemSet, sal_uInt16 nScript,
652 : const SfxItemSet *pParentItemSet = 0 )
653 : {
654 : static const sal_uInt16 aWhichIds[3][5] =
655 : {
656 : { RES_CHRATR_FONT, RES_CHRATR_FONTSIZE, RES_CHRATR_LANGUAGE,
657 : RES_CHRATR_POSTURE, RES_CHRATR_WEIGHT },
658 : { RES_CHRATR_CJK_FONT, RES_CHRATR_CJK_FONTSIZE, RES_CHRATR_CJK_LANGUAGE,
659 : RES_CHRATR_CJK_POSTURE, RES_CHRATR_CJK_WEIGHT },
660 : { RES_CHRATR_CTL_FONT, RES_CHRATR_CTL_FONTSIZE, RES_CHRATR_CTL_LANGUAGE,
661 : RES_CHRATR_CTL_POSTURE, RES_CHRATR_CTL_WEIGHT }
662 : };
663 :
664 0 : sal_uInt16 aClearItems[3] = { sal_False, sal_False, sal_False };
665 0 : switch( nScript )
666 : {
667 : case CSS1_SCRIPT_WESTERN:
668 0 : aClearItems[1] = aClearItems[2] = sal_True;
669 0 : break;
670 : case CSS1_SCRIPT_CJK:
671 0 : aClearItems[0] = aClearItems[2] = sal_True;
672 0 : break;
673 : case CSS1_SCRIPT_CTL:
674 0 : aClearItems[0] = aClearItems[1] = sal_True;
675 0 : break;
676 : case CSS1_SCRIPT_ALL:
677 0 : break;
678 : default:
679 : OSL_ENSURE( aClearItems[0], "unknown script type" );
680 0 : break;
681 : }
682 :
683 0 : for( sal_uInt16 j=0; j < 3; j++ )
684 : {
685 0 : for( sal_uInt16 i=0; i < 5; i++ )
686 : {
687 0 : sal_uInt16 nWhich = aWhichIds[j][i];
688 : const SfxPoolItem *pItem;
689 0 : if( aClearItems[j] ||
690 0 : (pParentItemSet &&
691 0 : SFX_ITEM_SET == rItemSet.GetItemState( nWhich, false, &pItem ) &&
692 0 : (0==i ? swhtml_css1atr_equalFontItems( *pItem, pParentItemSet->Get(nWhich, true ) )
693 0 : : *pItem == pParentItemSet->Get(nWhich, true ) ) ) )
694 : {
695 0 : rItemSet.ClearItem( nWhich );
696 : }
697 : }
698 : }
699 0 : }
700 :
701 0 : sal_Bool SwCSS1Parser::StyleParsed( const CSS1Selector *pSelector,
702 : SfxItemSet& rItemSet,
703 : SvxCSS1PropertyInfo& rPropInfo )
704 : {
705 0 : if( !bIsNewDoc )
706 0 : return sal_True;
707 :
708 0 : CSS1SelectorType eSelType = pSelector->GetType();
709 0 : const CSS1Selector *pNext = pSelector->GetNext();
710 :
711 0 : if( CSS1_SELTYPE_ID==eSelType && !pNext )
712 : {
713 0 : InsertId( pSelector->GetString(), rItemSet, rPropInfo );
714 : }
715 0 : else if( CSS1_SELTYPE_CLASS==eSelType && !pNext )
716 : {
717 0 : OUString aClass( pSelector->GetString() );
718 0 : sal_uInt16 nScript = GetScriptFromClass( aClass );
719 0 : if( CSS1_SCRIPT_ALL != nScript )
720 : {
721 0 : SfxItemSet aScriptItemSet( rItemSet );
722 0 : RemoveScriptItems( aScriptItemSet, nScript );
723 0 : InsertClass( aClass, aScriptItemSet, rPropInfo );
724 : }
725 : else
726 : {
727 0 : InsertClass( aClass, rItemSet, rPropInfo );
728 0 : }
729 : }
730 0 : else if( CSS1_SELTYPE_PAGE==eSelType )
731 : {
732 0 : if( !pNext ||
733 0 : (CSS1_SELTYPE_PSEUDO == pNext->GetType() &&
734 0 : (pNext->GetString().equalsIgnoreAsciiCase( "left" ) ||
735 0 : pNext->GetString().equalsIgnoreAsciiCase( "right" ) ||
736 0 : pNext->GetString().equalsIgnoreAsciiCase( "first" ) ) ) )
737 : {
738 0 : OUString aName;
739 0 : if( pNext )
740 0 : aName = pNext->GetString();
741 : InsertPage( aName,
742 : pNext != 0,
743 0 : rItemSet, rPropInfo );
744 : }
745 : }
746 :
747 0 : if( CSS1_SELTYPE_ELEMENT != eSelType &&
748 : CSS1_SELTYPE_ELEM_CLASS != eSelType)
749 0 : return sal_True;
750 :
751 : // Token und Class zu dem Selektor holen
752 0 : OUString aToken2;
753 0 : OUString aClass;
754 : sal_uInt16 nScript;
755 0 : eSelType = GetTokenAndClass( pSelector, aToken2, aClass, nScript );
756 0 : int nToken2 = GetHTMLToken( aToken2 );
757 :
758 : // und noch ein ganz par Infos zum naechsten Element
759 : CSS1SelectorType eNextType = pNext ? pNext->GetType()
760 0 : : CSS1_SELTYPE_ELEMENT;
761 :
762 : // Erstmal ein par Spezialfaelle
763 0 : if( CSS1_SELTYPE_ELEMENT==eSelType )
764 : {
765 0 : switch( nToken2 )
766 : {
767 : case HTML_ANCHOR_ON:
768 0 : if( !pNext )
769 : {
770 0 : InsertTag( aToken2, rItemSet, rPropInfo );
771 0 : return sal_False;
772 : }
773 0 : else if( pNext && CSS1_SELTYPE_PSEUDO == eNextType )
774 : {
775 : // vielleicht A:visited oder A:link
776 :
777 0 : OUString aPseudo( pNext->GetString() );
778 0 : aPseudo = aPseudo.toAsciiLowerCase();
779 0 : sal_Bool bInsert = sal_False;
780 0 : switch( aPseudo[0] )
781 : {
782 : case 'l':
783 0 : if( aPseudo == "link" )
784 : {
785 0 : bInsert = sal_True;
786 : }
787 0 : break;
788 : case 'v':
789 0 : if( aPseudo == "visited" )
790 : {
791 0 : bInsert = sal_True;
792 : }
793 0 : break;
794 : }
795 0 : if( bInsert )
796 : {
797 0 : OUString sTmp = aToken2 + ":" + aPseudo;
798 0 : if( CSS1_SCRIPT_ALL != nScript )
799 : {
800 0 : SfxItemSet aScriptItemSet( rItemSet );
801 0 : RemoveScriptItems( aScriptItemSet, nScript );
802 0 : InsertTag( sTmp, aScriptItemSet, rPropInfo );
803 : }
804 : else
805 : {
806 0 : InsertTag( sTmp, rItemSet, rPropInfo );
807 : }
808 0 : return sal_False;
809 0 : }
810 : }
811 0 : break;
812 : case HTML_BODY_ON:
813 0 : if( !pNext )
814 : {
815 : // BODY
816 :
817 : // Den Hintergrund muessen wir vor dem Setzen abfragen,
818 : // denn in SetPageDescAttrs wird er geloescht.
819 : const SfxPoolItem *pItem;
820 0 : if( SFX_ITEM_SET==rItemSet.GetItemState(RES_BACKGROUND,false,&pItem) )
821 : {
822 : const SvxBrushItem *pBrushItem =
823 0 : (const SvxBrushItem *)pItem;
824 :
825 : /// Body has a background color, if it is not "no fill"/"auto fill"
826 0 : if( pBrushItem->GetColor() != COL_TRANSPARENT )
827 0 : bBodyBGColorSet = sal_True;
828 0 : if( GPOS_NONE != pBrushItem->GetGraphicPos() )
829 0 : bBodyBackgroundSet = sal_True;
830 : }
831 :
832 : // Border and Padding
833 0 : rPropInfo.SetBoxItem( rItemSet, MIN_BORDER_DIST );
834 :
835 : // Ein par Attribute muessen an der Seitenvorlage gesetzt werden,
836 : // und zwar die, die nicht vererbt werden
837 0 : SetPageDescAttrs( 0, &rItemSet );
838 :
839 : // alle noch uebrigen Optionen koennen an der Standard-Vorlage
840 : // gesetzt werden und gelten dann automatisch als defaults
841 0 : if( SFX_ITEM_SET==rItemSet.GetItemState(RES_CHRATR_COLOR,false) )
842 0 : bBodyTextSet = sal_True;
843 : SetTxtCollAttrs(
844 : GetTxtCollFromPool( RES_POOLCOLL_STANDARD ),
845 0 : rItemSet, rPropInfo, this );
846 :
847 0 : return sal_False;
848 : }
849 0 : break;
850 : }
851 : }
852 0 : else if( CSS1_SELTYPE_ELEM_CLASS==eSelType && HTML_ANCHOR_ON==nToken2 &&
853 0 : !pNext && aClass.getLength() >= 9 &&
854 0 : ('s' == aClass[0] || 'S' == aClass[0]) )
855 : {
856 0 : sal_uInt16 nPoolFmtId = 0;
857 0 : if( aClass.equalsIgnoreAsciiCase(OOO_STRING_SVTOOLS_HTML_sdendnote_sym) )
858 0 : nPoolFmtId = RES_POOLCHR_ENDNOTE;
859 0 : else if( aClass.equalsIgnoreAsciiCase(OOO_STRING_SVTOOLS_HTML_sdfootnote_sym) )
860 0 : nPoolFmtId = RES_POOLCHR_FOOTNOTE;
861 0 : if( nPoolFmtId )
862 : {
863 0 : if( CSS1_SCRIPT_ALL == nScript )
864 : {
865 0 : SetCharFmtAttrs( GetCharFmtFromPool(nPoolFmtId), rItemSet );
866 : }
867 : else
868 : {
869 0 : SfxItemSet aScriptItemSet( rItemSet );
870 0 : RemoveScriptItems( aScriptItemSet, nScript );
871 : SetCharFmtAttrs( GetCharFmtFromPool(nPoolFmtId),
872 0 : aScriptItemSet);
873 : }
874 0 : return sal_False;
875 : }
876 : }
877 :
878 : // Jetzt werden die Selektoren verarbeitet, die zu einer Absatz-Vorlage
879 : // gehoehren
880 0 : sal_uInt16 nPoolCollId = 0;
881 0 : switch( nToken2 )
882 : {
883 : case HTML_HEAD1_ON:
884 0 : nPoolCollId = RES_POOLCOLL_HEADLINE1;
885 0 : break;
886 : case HTML_HEAD2_ON:
887 0 : nPoolCollId = RES_POOLCOLL_HEADLINE2;
888 0 : break;
889 : case HTML_HEAD3_ON:
890 0 : nPoolCollId = RES_POOLCOLL_HEADLINE3;
891 0 : break;
892 : case HTML_HEAD4_ON:
893 0 : nPoolCollId = RES_POOLCOLL_HEADLINE4;
894 0 : break;
895 : case HTML_HEAD5_ON:
896 0 : nPoolCollId = RES_POOLCOLL_HEADLINE5;
897 0 : break;
898 : case HTML_HEAD6_ON:
899 0 : nPoolCollId = RES_POOLCOLL_HEADLINE6;
900 0 : break;
901 : case HTML_PARABREAK_ON:
902 0 : if( aClass.getLength() >= 9 &&
903 0 : ('s' == aClass[0] || 'S' == aClass[0]) )
904 : {
905 0 : if( aClass.equalsIgnoreAsciiCase(OOO_STRING_SVTOOLS_HTML_sdendnote) )
906 0 : nPoolCollId = RES_POOLCOLL_ENDNOTE;
907 0 : else if( aClass.equalsIgnoreAsciiCase(OOO_STRING_SVTOOLS_HTML_sdfootnote) )
908 0 : nPoolCollId = RES_POOLCOLL_FOOTNOTE;
909 :
910 0 : if( nPoolCollId )
911 0 : aClass = aEmptyOUStr;
912 : else
913 0 : nPoolCollId = RES_POOLCOLL_TEXT;
914 : }
915 : else
916 : {
917 0 : nPoolCollId = RES_POOLCOLL_TEXT;
918 : }
919 0 : break;
920 : case HTML_ADDRESS_ON:
921 0 : nPoolCollId = RES_POOLCOLL_SENDADRESS;
922 0 : break;
923 : case HTML_BLOCKQUOTE_ON:
924 0 : nPoolCollId = RES_POOLCOLL_HTML_BLOCKQUOTE;
925 0 : break;
926 : case HTML_DT_ON:
927 0 : nPoolCollId = RES_POOLCOLL_HTML_DT;
928 0 : break;
929 : case HTML_DD_ON:
930 0 : nPoolCollId = RES_POOLCOLL_HTML_DD;
931 0 : break;
932 : case HTML_PREFORMTXT_ON:
933 0 : nPoolCollId = RES_POOLCOLL_HTML_PRE;
934 0 : break;
935 : case HTML_TABLEHEADER_ON:
936 : case HTML_TABLEDATA_ON:
937 0 : if( CSS1_SELTYPE_ELEMENT==eSelType && !pNext )
938 : {
939 0 : InsertTag( aToken2, rItemSet, rPropInfo );
940 0 : return sal_False;
941 : }
942 0 : else if( CSS1_SELTYPE_ELEMENT==eSelType && pNext &&
943 0 : (CSS1_SELTYPE_ELEMENT==eNextType ||
944 : CSS1_SELTYPE_ELEM_CLASS==eNextType) )
945 : {
946 : // nicht TH und TD, aber TH P und TD P
947 0 : OUString aSubToken, aSubClass;
948 0 : GetTokenAndClass( pNext, aSubToken, aSubClass, nScript );
949 0 : if( HTML_PARABREAK_ON == GetHTMLToken( aSubToken ) )
950 : {
951 0 : aClass = aSubClass;
952 0 : pNext = pNext->GetNext();
953 0 : eNextType = pNext ? pNext->GetType() : CSS1_SELTYPE_ELEMENT;
954 :
955 0 : if( !aClass.isEmpty() || pNext )
956 : {
957 : nPoolCollId = static_cast< sal_uInt16 >(
958 : HTML_TABLEHEADER_ON == nToken2 ? RES_POOLCOLL_TABLE_HDLN
959 0 : : RES_POOLCOLL_TABLE );
960 : }
961 : else
962 : {
963 0 : OUString sTmp = aToken2 + " " + OOO_STRING_SVTOOLS_HTML_parabreak;
964 :
965 0 : if( CSS1_SCRIPT_ALL == nScript )
966 : {
967 0 : InsertTag( sTmp, rItemSet, rPropInfo );
968 : }
969 : else
970 : {
971 0 : SfxItemSet aScriptItemSet( rItemSet );
972 0 : RemoveScriptItems( aScriptItemSet, nScript );
973 0 : InsertTag( sTmp, aScriptItemSet, rPropInfo );
974 : }
975 :
976 0 : return sal_False;
977 : }
978 0 : }
979 : }
980 0 : break;
981 :
982 : default:
983 : ;
984 : }
985 :
986 0 : if( nPoolCollId )
987 : {
988 0 : if( !pNext ||
989 0 : (CSS1_SELTYPE_PSEUDO==eNextType &&
990 0 : pNext->GetString().equalsIgnoreAsciiCase( "first-letter" ) &&
991 0 : SVX_ADJUST_LEFT == rPropInfo.eFloat) )
992 : {
993 : // Entweder kein zusammengesetzter Selektor oder
994 : // ein X:first-line { float: left; ... }
995 :
996 : // Die Vorlage Suchen bzw. Anlegen
997 0 : SwTxtFmtColl *pColl = GetTxtFmtColl( nPoolCollId, aEmptyOUStr );
998 0 : SwTxtFmtColl* pParentColl = 0;
999 0 : if( !aClass.isEmpty() )
1000 : {
1001 0 : OUString aName( pColl->GetName() );
1002 0 : AddClassName( aName, aClass );
1003 :
1004 0 : pParentColl = pColl;
1005 0 : pColl = pDoc->FindTxtFmtCollByName( aName );
1006 0 : if( !pColl )
1007 0 : pColl = pDoc->MakeTxtFmtColl( aName, pParentColl );
1008 : }
1009 0 : if( !pNext )
1010 : {
1011 : // nur die Attribute an der Vorlage setzen
1012 : const SfxPoolItem *pItem;
1013 0 : const SvxBoxItem *pBoxItem = 0;
1014 0 : if( SFX_ITEM_SET ==
1015 0 : pColl->GetAttrSet().GetItemState(RES_BOX,true,&pItem) )
1016 0 : pBoxItem = (const SvxBoxItem *)pItem;
1017 0 : rPropInfo.SetBoxItem( rItemSet, MIN_BORDER_DIST, pBoxItem );
1018 0 : if( CSS1_SCRIPT_ALL == nScript && !pParentColl )
1019 : {
1020 0 : SetTxtCollAttrs( pColl, rItemSet, rPropInfo, this );
1021 : }
1022 : else
1023 : {
1024 0 : SfxItemSet aScriptItemSet( rItemSet );
1025 : RemoveScriptItems( aScriptItemSet, nScript,
1026 0 : pParentColl ? &pParentColl->GetAttrSet() : 0 );
1027 0 : SetTxtCollAttrs( pColl, aScriptItemSet, rPropInfo, this );
1028 : }
1029 : }
1030 : else
1031 : {
1032 : // ein Drop-Cap-Attribut basteln
1033 0 : SwFmtDrop aDrop( pColl->GetDrop() );
1034 0 : aDrop.GetChars() = 1;
1035 :
1036 : // die Attribute in das DropCap-Attribut einfuegen
1037 0 : if( CSS1_SCRIPT_ALL == nScript )
1038 : {
1039 0 : OUString sName(pColl->GetName());
1040 0 : FillDropCap( aDrop, rItemSet, &sName );
1041 : }
1042 : else
1043 : {
1044 0 : SfxItemSet aScriptItemSet( rItemSet );
1045 0 : if( CSS1_SCRIPT_WESTERN != nScript )
1046 : {
1047 0 : aScriptItemSet.ClearItem( RES_CHRATR_FONT );
1048 0 : aScriptItemSet.ClearItem( RES_CHRATR_LANGUAGE );
1049 0 : aScriptItemSet.ClearItem( RES_CHRATR_POSTURE );
1050 0 : aScriptItemSet.ClearItem( RES_CHRATR_WEIGHT );
1051 : }
1052 0 : if( CSS1_SCRIPT_CJK != nScript )
1053 : {
1054 0 : aScriptItemSet.ClearItem( RES_CHRATR_CJK_FONT );
1055 0 : aScriptItemSet.ClearItem( RES_CHRATR_CJK_LANGUAGE );
1056 0 : aScriptItemSet.ClearItem( RES_CHRATR_CJK_POSTURE );
1057 0 : aScriptItemSet.ClearItem( RES_CHRATR_CJK_WEIGHT );
1058 : }
1059 0 : if( CSS1_SCRIPT_CTL != nScript )
1060 : {
1061 0 : aScriptItemSet.ClearItem( RES_CHRATR_CTL_FONT );
1062 0 : aScriptItemSet.ClearItem( RES_CHRATR_CTL_LANGUAGE );
1063 0 : aScriptItemSet.ClearItem( RES_CHRATR_CTL_POSTURE );
1064 0 : aScriptItemSet.ClearItem( RES_CHRATR_CTL_WEIGHT );
1065 : }
1066 0 : OUString sName(pColl->GetName());
1067 0 : FillDropCap( aDrop, aScriptItemSet, &sName );
1068 : }
1069 :
1070 : // Das Attribut nur setzen, wenn float: left angegeben wurde
1071 : // und das Initial ueber mehrere Zeilen geht. Sonst wird die
1072 : // ggf. angelegte Zeichen-Vorlage spaeter ueber den Namen
1073 : // gesucht und gesetzt.
1074 0 : if( aDrop.GetLines() > 1 &&
1075 0 : (SVX_ADJUST_LEFT == rPropInfo.eFloat ||
1076 0 : CSS1_SCRIPT_ALL == nScript) )
1077 : {
1078 0 : pColl->SetFmtAttr( aDrop );
1079 0 : }
1080 : }
1081 :
1082 0 : return sal_False;
1083 : }
1084 :
1085 0 : return sal_True;
1086 : }
1087 :
1088 : // Jetzt werden die Selektoten verarbeitet, die zu einer Zechenvorlage
1089 : // gehoehren. Zusammengesetzte gibt es hier allerdings nich nicht.
1090 0 : if( pNext )
1091 0 : return sal_True;
1092 :
1093 0 : SwCharFmt *pCFmt = GetChrFmt( static_cast< sal_uInt16 >(nToken2), aEmptyOUStr );
1094 0 : if( pCFmt )
1095 : {
1096 0 : SwCharFmt *pParentCFmt = 0;
1097 0 : if( !aClass.isEmpty() )
1098 : {
1099 0 : OUString aName( pCFmt->GetName() );
1100 0 : AddClassName( aName, aClass );
1101 0 : pParentCFmt = pCFmt;
1102 :
1103 0 : pCFmt = pDoc->FindCharFmtByName( aName );
1104 0 : if( !pCFmt )
1105 : {
1106 0 : pCFmt = pDoc->MakeCharFmt( aName, pParentCFmt );
1107 0 : pCFmt->SetAuto( false );
1108 0 : }
1109 : }
1110 :
1111 0 : if( CSS1_SCRIPT_ALL == nScript && !pParentCFmt )
1112 : {
1113 0 : SetCharFmtAttrs( pCFmt, rItemSet );
1114 : }
1115 : else
1116 : {
1117 0 : SfxItemSet aScriptItemSet( rItemSet );
1118 : RemoveScriptItems( aScriptItemSet, nScript,
1119 0 : pParentCFmt ? &pParentCFmt->GetAttrSet() : 0 );
1120 0 : SetCharFmtAttrs( pCFmt, aScriptItemSet );
1121 : }
1122 0 : return sal_False;
1123 : }
1124 :
1125 0 : return sal_True;
1126 : }
1127 :
1128 0 : sal_uInt32 SwCSS1Parser::GetFontHeight( sal_uInt16 nSize ) const
1129 : {
1130 0 : return aFontHeights[ nSize>6 ? 6 : nSize ];
1131 : }
1132 :
1133 0 : const FontList *SwCSS1Parser::GetFontList() const
1134 : {
1135 0 : const FontList *pFList = 0;
1136 0 : SwDocShell *pDocSh = pDoc->GetDocShell();
1137 0 : if( pDocSh )
1138 : {
1139 : const SvxFontListItem *pFListItem =
1140 0 : (const SvxFontListItem *)pDocSh->GetItem(SID_ATTR_CHAR_FONTLIST);
1141 0 : if( pFListItem )
1142 0 : pFList = pFListItem->GetFontList();
1143 : }
1144 :
1145 0 : return pFList;
1146 : }
1147 :
1148 0 : SwCharFmt* SwCSS1Parser::GetChrFmt( sal_uInt16 nToken2, const OUString& rClass ) const
1149 : {
1150 : // die entsprechende Vorlage suchen
1151 0 : sal_uInt16 nPoolId = 0;
1152 0 : const sal_Char* sName = 0;
1153 0 : switch( nToken2 )
1154 : {
1155 0 : case HTML_EMPHASIS_ON: nPoolId = RES_POOLCHR_HTML_EMPHASIS; break;
1156 0 : case HTML_CITIATION_ON: nPoolId = RES_POOLCHR_HTML_CITIATION; break;
1157 0 : case HTML_STRONG_ON: nPoolId = RES_POOLCHR_HTML_STRONG; break;
1158 0 : case HTML_CODE_ON: nPoolId = RES_POOLCHR_HTML_CODE; break;
1159 0 : case HTML_SAMPLE_ON: nPoolId = RES_POOLCHR_HTML_SAMPLE; break;
1160 0 : case HTML_KEYBOARD_ON: nPoolId = RES_POOLCHR_HTML_KEYBOARD; break;
1161 0 : case HTML_VARIABLE_ON: nPoolId = RES_POOLCHR_HTML_VARIABLE; break;
1162 0 : case HTML_DEFINSTANCE_ON: nPoolId = RES_POOLCHR_HTML_DEFINSTANCE; break;
1163 0 : case HTML_TELETYPE_ON: nPoolId = RES_POOLCHR_HTML_TELETYPE; break;
1164 :
1165 0 : case HTML_SHORTQUOTE_ON: sName = OOO_STRING_SVTOOLS_HTML_shortquote; break;
1166 0 : case HTML_LANGUAGE_ON: sName = OOO_STRING_SVTOOLS_HTML_language; break;
1167 0 : case HTML_AUTHOR_ON: sName = OOO_STRING_SVTOOLS_HTML_author; break;
1168 0 : case HTML_PERSON_ON: sName = OOO_STRING_SVTOOLS_HTML_person; break;
1169 0 : case HTML_ACRONYM_ON: sName = OOO_STRING_SVTOOLS_HTML_acronym; break;
1170 0 : case HTML_ABBREVIATION_ON: sName = OOO_STRING_SVTOOLS_HTML_abbreviation; break;
1171 0 : case HTML_INSERTEDTEXT_ON: sName = OOO_STRING_SVTOOLS_HTML_insertedtext; break;
1172 0 : case HTML_DELETEDTEXT_ON: sName = OOO_STRING_SVTOOLS_HTML_deletedtext; break;
1173 : }
1174 :
1175 : // die Vorlage suchen oder anlegen (geht nur mit Namen)
1176 0 : if( !nPoolId && !sName )
1177 0 : return 0;
1178 :
1179 : // Die Vorlage (ohne Class) suchen oder anlegen
1180 0 : SwCharFmt *pCFmt = 0;
1181 0 : if( nPoolId )
1182 : {
1183 0 : pCFmt = GetCharFmtFromPool( nPoolId );
1184 : }
1185 : else
1186 : {
1187 0 : OUString sCName( OUString::createFromAscii(sName) );
1188 0 : pCFmt = pDoc->FindCharFmtByName( sCName );
1189 0 : if( !pCFmt )
1190 : {
1191 0 : pCFmt = pDoc->MakeCharFmt( sCName, pDoc->GetDfltCharFmt() );
1192 0 : pCFmt->SetAuto( false );
1193 0 : }
1194 : }
1195 :
1196 : OSL_ENSURE( pCFmt, "Keine Zeichen-Vorlage???" );
1197 :
1198 : // Wenn es eine Klasse gibt, die Klassen-Vorlage suchen aber nicht
1199 : // neu anlegen.
1200 0 : OUString aClass( rClass );
1201 0 : GetScriptFromClass( aClass, sal_False );
1202 0 : if( !aClass.isEmpty() )
1203 : {
1204 0 : OUString aTmp( pCFmt->GetName() );
1205 0 : AddClassName( aTmp, aClass );
1206 0 : SwCharFmt *pClassCFmt = pDoc->FindCharFmtByName( aTmp );
1207 0 : if( pClassCFmt )
1208 : {
1209 0 : pCFmt = pClassCFmt;
1210 : }
1211 : else
1212 : {
1213 0 : const SvxCSS1MapEntry *pClass = GetClass( aClass );
1214 0 : if( pClass )
1215 : {
1216 0 : pCFmt = pDoc->MakeCharFmt( aTmp, pCFmt );
1217 0 : pCFmt->SetAuto( false );
1218 0 : SfxItemSet aItemSet( pClass->GetItemSet() );
1219 0 : SetCharFmtAttrs( pCFmt, aItemSet );
1220 : }
1221 0 : }
1222 : }
1223 :
1224 0 : return pCFmt;
1225 : }
1226 :
1227 0 : SwTxtFmtColl *SwCSS1Parser::GetTxtCollFromPool( sal_uInt16 nPoolId ) const
1228 : {
1229 0 : sal_uInt16 nOldArrLen = pDoc->GetTxtFmtColls()->size();
1230 :
1231 0 : SwTxtFmtColl *pColl = pDoc->GetTxtCollFromPool( nPoolId, false );
1232 :
1233 0 : if( bIsNewDoc )
1234 : {
1235 0 : sal_uInt16 nArrLen = pDoc->GetTxtFmtColls()->size();
1236 0 : for( sal_uInt16 i=nOldArrLen; i<nArrLen; i++ )
1237 0 : lcl_swcss1_setEncoding( *(*pDoc->GetTxtFmtColls())[i],
1238 0 : GetDfltEncoding() );
1239 : }
1240 :
1241 0 : return pColl;
1242 : }
1243 :
1244 0 : SwCharFmt *SwCSS1Parser::GetCharFmtFromPool( sal_uInt16 nPoolId ) const
1245 : {
1246 0 : sal_uInt16 nOldArrLen = pDoc->GetCharFmts()->size();
1247 :
1248 0 : SwCharFmt *pCharFmt = pDoc->GetCharFmtFromPool( nPoolId );
1249 :
1250 0 : if( bIsNewDoc )
1251 : {
1252 0 : sal_uInt16 nArrLen = pDoc->GetCharFmts()->size();
1253 :
1254 0 : for( sal_uInt16 i=nOldArrLen; i<nArrLen; i++ )
1255 0 : lcl_swcss1_setEncoding( *(*pDoc->GetCharFmts())[i],
1256 0 : GetDfltEncoding() );
1257 : }
1258 :
1259 0 : return pCharFmt;
1260 : }
1261 :
1262 0 : SwTxtFmtColl *SwCSS1Parser::GetTxtFmtColl( sal_uInt16 nTxtColl,
1263 : const OUString& rClass )
1264 : {
1265 0 : SwTxtFmtColl* pColl = 0;
1266 :
1267 0 : OUString aClass( rClass );
1268 0 : GetScriptFromClass( aClass, sal_False );
1269 0 : if( RES_POOLCOLL_TEXT == nTxtColl && aClass.getLength() >= 9 &&
1270 0 : ('s' == aClass[0] || 'S' == aClass[0] ) )
1271 : {
1272 0 : if( aClass.equalsIgnoreAsciiCase(OOO_STRING_SVTOOLS_HTML_sdendnote) )
1273 : {
1274 0 : nTxtColl = RES_POOLCOLL_ENDNOTE;
1275 0 : aClass = aEmptyOUStr;
1276 : }
1277 0 : else if( aClass.equalsIgnoreAsciiCase(OOO_STRING_SVTOOLS_HTML_sdfootnote) )
1278 : {
1279 0 : nTxtColl = RES_POOLCOLL_FOOTNOTE;
1280 0 : aClass = aEmptyOUStr;
1281 : }
1282 : }
1283 :
1284 0 : if( USER_FMT & nTxtColl ) // eine vom Reader angelegte
1285 : {
1286 : OSL_ENSURE( !this, "Wo kommt die Benutzer-Vorlage her?" );
1287 0 : pColl = GetTxtCollFromPool( RES_POOLCOLL_STANDARD );
1288 : }
1289 : else
1290 : {
1291 0 : pColl = GetTxtCollFromPool( nTxtColl );
1292 : }
1293 :
1294 : OSL_ENSURE( pColl, "Keine Absatz-Vorlage???" );
1295 0 : if( !aClass.isEmpty() )
1296 : {
1297 0 : OUString aTmp( pColl->GetName() );
1298 0 : AddClassName( aTmp, aClass );
1299 0 : SwTxtFmtColl* pClassColl = pDoc->FindTxtFmtCollByName( aTmp );
1300 :
1301 0 : if( !pClassColl &&
1302 0 : (nTxtColl==RES_POOLCOLL_TABLE ||
1303 : nTxtColl==RES_POOLCOLL_TABLE_HDLN) )
1304 : {
1305 : // Wenn dieser Fall eintritt, dann wurde ein <TD><P CLASS=foo>
1306 : // gelesen, aber die TD.foo Vorlage nicht gefunden. Dann muessen
1307 : // wir P.foo nehmen, wenn es sie gibt.
1308 : SwTxtFmtColl* pCollText =
1309 0 : GetTxtCollFromPool( RES_POOLCOLL_TEXT );
1310 0 : aTmp = pCollText->GetName();
1311 0 : AddClassName( aTmp, aClass );
1312 0 : pClassColl = pDoc->FindTxtFmtCollByName( aTmp );
1313 : }
1314 :
1315 0 : if( pClassColl )
1316 : {
1317 0 : pColl = pClassColl;
1318 : }
1319 : else
1320 : {
1321 0 : const SvxCSS1MapEntry *pClass = GetClass( aClass );
1322 0 : if( pClass )
1323 : {
1324 0 : pColl = pDoc->MakeTxtFmtColl( aTmp, pColl );
1325 0 : SfxItemSet aItemSet( pClass->GetItemSet() );
1326 0 : SvxCSS1PropertyInfo aPropInfo( pClass->GetPropertyInfo() );
1327 0 : aPropInfo.SetBoxItem( aItemSet, MIN_BORDER_DIST );
1328 0 : sal_Bool bPositioned = MayBePositioned( pClass->GetPropertyInfo() );
1329 0 : if( bPositioned )
1330 0 : aItemSet.ClearItem( RES_BACKGROUND );
1331 : SetTxtCollAttrs( pColl, aItemSet, aPropInfo,
1332 0 : this );
1333 : }
1334 0 : }
1335 :
1336 : }
1337 :
1338 0 : if( pColl )
1339 0 : lcl_swcss1_setEncoding( *pColl, GetDfltEncoding() );
1340 :
1341 0 : return pColl;
1342 : }
1343 :
1344 0 : SwPageDesc *SwCSS1Parser::GetMasterPageDesc()
1345 : {
1346 0 : return pDoc->GetPageDescFromPool( RES_POOLPAGE_HTML, false );
1347 : }
1348 :
1349 0 : static SwPageDesc *FindPageDesc( SwDoc *pDoc, sal_uInt16 nPoolId, sal_uInt16& rPage )
1350 : {
1351 0 : sal_uInt16 nPageDescs = pDoc->GetPageDescCnt();
1352 0 : for( rPage=0; rPage < nPageDescs &&
1353 0 : pDoc->GetPageDesc(rPage).GetPoolFmtId() != nPoolId; rPage++ )
1354 : ;
1355 :
1356 0 : return rPage < nPageDescs ? &pDoc->GetPageDesc( rPage ) : 0;
1357 : }
1358 :
1359 0 : const SwPageDesc *SwCSS1Parser::GetPageDesc( sal_uInt16 nPoolId, sal_Bool bCreate )
1360 : {
1361 0 : if( RES_POOLPAGE_HTML == nPoolId )
1362 0 : return pDoc->GetPageDescFromPool( RES_POOLPAGE_HTML, false );
1363 :
1364 : sal_uInt16 nPage;
1365 0 : const SwPageDesc *pPageDesc = FindPageDesc( pDoc, nPoolId, nPage );
1366 0 : if( !pPageDesc && bCreate )
1367 : {
1368 : // Die erste Seite wird aus der rechten Seite erzeugt, wenn es die
1369 : // gibt.
1370 0 : SwPageDesc *pMasterPageDesc = 0;
1371 0 : if( RES_POOLPAGE_FIRST == nPoolId )
1372 0 : pMasterPageDesc = FindPageDesc( pDoc, RES_POOLPAGE_RIGHT, nPage );
1373 0 : if( !pMasterPageDesc )
1374 0 : pMasterPageDesc = pDoc->GetPageDescFromPool( RES_POOLPAGE_HTML, false );
1375 :
1376 : // Die neue Seitenvorlage entsteht aus dem Master durch kopieren.
1377 : SwPageDesc *pNewPageDesc = pDoc->
1378 0 : GetPageDescFromPool( nPoolId, false );
1379 :
1380 : // dazu brauchen wir auch die Nummer der neuen Vorlage
1381 0 : pPageDesc = FindPageDesc( pDoc, nPoolId, nPage );
1382 : OSL_ENSURE( pPageDesc==pNewPageDesc, "Seitenvorlage nicht gefunden" );
1383 :
1384 0 : pDoc->CopyPageDesc( *pMasterPageDesc, *pNewPageDesc, false );
1385 :
1386 : // Die Vorlagen an ihren neuen Zweck anpassen.
1387 0 : const SwPageDesc *pFollow = 0;
1388 0 : sal_Bool bSetFollowFollow = sal_False;
1389 0 : switch( nPoolId )
1390 : {
1391 : case RES_POOLPAGE_FIRST:
1392 : // Wenn es schon eine linke Seite gibt, dann ist das die
1393 : // Folge-Vorlage, sonst ist es die HTML-Vorlage.
1394 0 : pFollow = GetLeftPageDesc();
1395 0 : if( !pFollow )
1396 0 : pFollow = pMasterPageDesc;
1397 0 : break;
1398 :
1399 : case RES_POOLPAGE_RIGHT:
1400 : // Wenn die linke Vorlage schon angelegt ist, passiert hier gar
1401 : // nichts. Sonst wird die linke Vorlage angelegt und sorgt auch
1402 : // fuer die richtige Verkettung mit der rechten Voralge.
1403 0 : GetLeftPageDesc( sal_True );
1404 0 : break;
1405 :
1406 : case RES_POOLPAGE_LEFT:
1407 : // Die rechte Vorlage wird angelegt, wenn sie noch nicht existiert.
1408 : // Es findet aber keine Verkettung statt.
1409 : // Wenn schon eine erste Seitenvorlage existiert, wird die linke
1410 : // Vorlage die Folge-Vorlage der ersten Seite.
1411 0 : pFollow = GetRightPageDesc( sal_True );
1412 0 : bSetFollowFollow = sal_True;
1413 : {
1414 0 : const SwPageDesc *pFirstPageDesc = GetFirstPageDesc();
1415 0 : if( pFirstPageDesc )
1416 : {
1417 0 : SwPageDesc aNewFirstPageDesc( *pFirstPageDesc );
1418 0 : aNewFirstPageDesc.SetFollow( pNewPageDesc );
1419 0 : ChgPageDesc( pFirstPageDesc, aNewFirstPageDesc );
1420 : }
1421 : }
1422 0 : break;
1423 : }
1424 :
1425 0 : if( pFollow )
1426 : {
1427 0 : SwPageDesc aNewPageDesc( *pNewPageDesc );
1428 0 : aNewPageDesc.SetFollow( pFollow );
1429 0 : ChgPageDesc( pNewPageDesc, aNewPageDesc );
1430 :
1431 0 : if( bSetFollowFollow )
1432 : {
1433 0 : SwPageDesc aNewFollowPageDesc( *pFollow );
1434 0 : aNewFollowPageDesc.SetFollow( pNewPageDesc );
1435 0 : ChgPageDesc( pFollow, aNewFollowPageDesc );
1436 0 : }
1437 : }
1438 0 : pPageDesc = pNewPageDesc;
1439 : }
1440 :
1441 0 : return pPageDesc;
1442 : }
1443 :
1444 0 : sal_Bool SwCSS1Parser::MayBePositioned( const SvxCSS1PropertyInfo& rPropInfo,
1445 : sal_Bool bAutoWidth )
1446 : {
1447 : // abs-pos
1448 : // left/top none auto twip perc
1449 :
1450 : // none Z Z - -
1451 : // auto Z Z - -
1452 : // twip Z Z S/R -
1453 : // perc - - - -
1454 :
1455 : // - das Tag wird absolut positioniert und left/top sind beide
1456 : // gegeben und enthalten auch keine %-Angabe, oder
1457 : // - das Tag soll fliessen, und
1458 : // - es wurde eine Breite angegeben (in beiden Faellen noetig)
1459 0 : return ( ( SVX_CSS1_POS_ABSOLUTE == rPropInfo.ePosition &&
1460 0 : SVX_CSS1_LTYPE_PERCENTAGE != rPropInfo.eLeftType &&
1461 0 : SVX_CSS1_LTYPE_PERCENTAGE != rPropInfo.eTopType &&
1462 0 : (SVX_CSS1_LTYPE_TWIP == rPropInfo.eLeftType ||
1463 0 : SVX_CSS1_LTYPE_TWIP != rPropInfo.eTopType) ) ||
1464 0 : ( SVX_ADJUST_END != rPropInfo.eFloat ) ) &&
1465 0 : ( bAutoWidth ||
1466 0 : SVX_CSS1_LTYPE_TWIP == rPropInfo.eWidthType ||
1467 0 : SVX_CSS1_LTYPE_PERCENTAGE == rPropInfo.eWidthType );
1468 : }
1469 :
1470 0 : void SwCSS1Parser::AddClassName( OUString& rFmtName, const OUString& rClass )
1471 : {
1472 : OSL_ENSURE( !rClass.isEmpty(), "Style-Klasse ohne Laenge?" );
1473 :
1474 0 : rFmtName += "." + rClass;
1475 0 : }
1476 :
1477 0 : void SwCSS1Parser::FillDropCap( SwFmtDrop& rDrop,
1478 : SfxItemSet& rItemSet,
1479 : const OUString *pName )
1480 : {
1481 : // die Anzahl der Zeilen entspricht in etwa einer %-Angabe
1482 : // fuer die Hoehe (was passiert mit absoluten Hoehen???)
1483 0 : sal_uInt8 nLines = rDrop.GetLines();
1484 : const SfxPoolItem *pItem;
1485 0 : if( SFX_ITEM_SET == rItemSet.GetItemState( RES_CHRATR_FONTSIZE, false, &pItem ) )
1486 : {
1487 0 : sal_uInt16 nProp = ((const SvxFontHeightItem *)pItem)->GetProp();
1488 0 : nLines = (sal_uInt8)((nProp + 50) / 100);
1489 0 : if( nLines < 1 )
1490 0 : nLines = 1;
1491 0 : else if( nLines > MAX_DROPCAP_LINES )
1492 0 : nLines = MAX_DROPCAP_LINES;
1493 :
1494 : // Nur wenn nLines>1 ist, wird das Attribut auch gesetzt. Dann
1495 : // brauchen wir die Font-Hoehe aber auch nicht in der Zeichen-Vorlage.
1496 0 : if( nLines > 1 )
1497 : {
1498 0 : rItemSet.ClearItem( RES_CHRATR_FONTSIZE );
1499 0 : rItemSet.ClearItem( RES_CHRATR_CJK_FONTSIZE );
1500 0 : rItemSet.ClearItem( RES_CHRATR_CTL_FONTSIZE );
1501 : }
1502 : }
1503 :
1504 : // Bei harter Attributierung (pName==0) koennen wir aufhoehren, wenn
1505 : // das Initial nur ueber eine Zeile geht.
1506 0 : if( nLines<=1 )
1507 0 : return;
1508 :
1509 0 : rDrop.GetLines() = nLines;
1510 :
1511 : // ein rechter Rand wird der Abstand zum Text!
1512 0 : if( SFX_ITEM_SET == rItemSet.GetItemState( RES_LR_SPACE, false, &pItem ) )
1513 : {
1514 0 : rDrop.GetDistance() = static_cast< sal_uInt16 >(
1515 0 : ((const SvxLRSpaceItem *)pItem)->GetRight() );
1516 0 : rItemSet.ClearItem( RES_LR_SPACE );
1517 : }
1518 :
1519 : // Fuer alle anderen Attribute eine Zeichen-Vorlage anlegen
1520 0 : if( rItemSet.Count() )
1521 : {
1522 0 : SwCharFmt *pCFmt = 0;
1523 0 : OUString aName;
1524 0 : if( pName )
1525 : {
1526 0 : aName = *pName;
1527 0 : AddFirstLetterExt( aName );
1528 0 : pCFmt = pDoc->FindCharFmtByName( aName );
1529 : }
1530 : else
1531 : {
1532 0 : do
1533 : {
1534 0 : aName = "first-letter " + OUString::number( (sal_Int32)(++nDropCapCnt) );
1535 : }
1536 0 : while( pDoc->FindCharFmtByName(aName) );
1537 : }
1538 :
1539 0 : if( !pCFmt )
1540 : {
1541 0 : pCFmt = pDoc->MakeCharFmt( aName, pDoc->GetDfltCharFmt() );
1542 0 : pCFmt->SetAuto( false );
1543 : }
1544 0 : SetCharFmtAttrs( pCFmt, rItemSet );
1545 :
1546 : // Die Zeichenvorlage braucht nur im Attribut gesetzt werden, wenn
1547 : // auch das Attribut gesetzt wird.
1548 0 : if( nLines > 1 )
1549 0 : rDrop.SetCharFmt( pCFmt );
1550 : }
1551 : }
1552 :
1553 : // CSS1-sezifisches des SwHTMLParsers
1554 :
1555 0 : _HTMLAttr **SwHTMLParser::GetAttrTabEntry( sal_uInt16 nWhich )
1556 : {
1557 : // den zu dem Item gehoehrenden Tabellen-Eintrag ermitteln ...
1558 0 : _HTMLAttr **ppAttr = 0;
1559 0 : switch( nWhich )
1560 : {
1561 : case RES_CHRATR_BLINK:
1562 0 : ppAttr = &aAttrTab.pBlink;
1563 0 : break;
1564 : case RES_CHRATR_CASEMAP:
1565 0 : ppAttr = &aAttrTab.pCaseMap;
1566 0 : break;
1567 : case RES_CHRATR_COLOR:
1568 0 : ppAttr = &aAttrTab.pFontColor;
1569 0 : break;
1570 : case RES_CHRATR_CROSSEDOUT:
1571 0 : ppAttr = &aAttrTab.pStrike;
1572 0 : break;
1573 : case RES_CHRATR_ESCAPEMENT:
1574 0 : ppAttr = &aAttrTab.pEscapement;
1575 0 : break;
1576 : case RES_CHRATR_FONT:
1577 0 : ppAttr = &aAttrTab.pFont;
1578 0 : break;
1579 : case RES_CHRATR_CJK_FONT:
1580 0 : ppAttr = &aAttrTab.pFontCJK;
1581 0 : break;
1582 : case RES_CHRATR_CTL_FONT:
1583 0 : ppAttr = &aAttrTab.pFontCTL;
1584 0 : break;
1585 : case RES_CHRATR_FONTSIZE:
1586 0 : ppAttr = &aAttrTab.pFontHeight;
1587 0 : break;
1588 : case RES_CHRATR_CJK_FONTSIZE:
1589 0 : ppAttr = &aAttrTab.pFontHeightCJK;
1590 0 : break;
1591 : case RES_CHRATR_CTL_FONTSIZE:
1592 0 : ppAttr = &aAttrTab.pFontHeightCTL;
1593 0 : break;
1594 : case RES_CHRATR_KERNING:
1595 0 : ppAttr = &aAttrTab.pKerning;
1596 0 : break;
1597 : case RES_CHRATR_POSTURE:
1598 0 : ppAttr = &aAttrTab.pItalic;
1599 0 : break;
1600 : case RES_CHRATR_CJK_POSTURE:
1601 0 : ppAttr = &aAttrTab.pItalicCJK;
1602 0 : break;
1603 : case RES_CHRATR_CTL_POSTURE:
1604 0 : ppAttr = &aAttrTab.pItalicCTL;
1605 0 : break;
1606 : case RES_CHRATR_UNDERLINE:
1607 0 : ppAttr = &aAttrTab.pUnderline;
1608 0 : break;
1609 : case RES_CHRATR_WEIGHT:
1610 0 : ppAttr = &aAttrTab.pBold;
1611 0 : break;
1612 : case RES_CHRATR_CJK_WEIGHT:
1613 0 : ppAttr = &aAttrTab.pBoldCJK;
1614 0 : break;
1615 : case RES_CHRATR_CTL_WEIGHT:
1616 0 : ppAttr = &aAttrTab.pBoldCTL;
1617 0 : break;
1618 : case RES_CHRATR_BACKGROUND:
1619 0 : ppAttr = &aAttrTab.pCharBrush;
1620 0 : break;
1621 : case RES_CHRATR_BOX:
1622 0 : ppAttr = &aAttrTab.pCharBox;
1623 0 : break;
1624 :
1625 : case RES_PARATR_LINESPACING:
1626 0 : ppAttr = &aAttrTab.pLineSpacing;
1627 0 : break;
1628 : case RES_PARATR_ADJUST:
1629 0 : ppAttr = &aAttrTab.pAdjust;
1630 0 : break;
1631 :
1632 : case RES_LR_SPACE:
1633 0 : ppAttr = &aAttrTab.pLRSpace;
1634 0 : break;
1635 : case RES_UL_SPACE:
1636 0 : ppAttr = &aAttrTab.pULSpace;
1637 0 : break;
1638 : case RES_BOX:
1639 0 : ppAttr = &aAttrTab.pBox;
1640 0 : break;
1641 : case RES_BACKGROUND:
1642 0 : ppAttr = &aAttrTab.pBrush;
1643 0 : break;
1644 : case RES_BREAK:
1645 0 : ppAttr = &aAttrTab.pBreak;
1646 0 : break;
1647 : case RES_PAGEDESC:
1648 0 : ppAttr = &aAttrTab.pPageDesc;
1649 0 : break;
1650 : case RES_PARATR_SPLIT:
1651 0 : ppAttr = &aAttrTab.pSplit;
1652 0 : break;
1653 : case RES_PARATR_WIDOWS:
1654 0 : ppAttr = &aAttrTab.pWidows;
1655 0 : break;
1656 : case RES_PARATR_ORPHANS:
1657 0 : ppAttr = &aAttrTab.pOrphans;
1658 0 : break;
1659 : case RES_KEEP:
1660 0 : ppAttr = &aAttrTab.pKeep;
1661 0 : break;
1662 :
1663 : case RES_CHRATR_LANGUAGE:
1664 0 : ppAttr = &aAttrTab.pLanguage;
1665 0 : break;
1666 : case RES_CHRATR_CJK_LANGUAGE:
1667 0 : ppAttr = &aAttrTab.pLanguageCJK;
1668 0 : break;
1669 : case RES_CHRATR_CTL_LANGUAGE:
1670 0 : ppAttr = &aAttrTab.pLanguageCTL;
1671 0 : break;
1672 :
1673 : case RES_FRAMEDIR:
1674 0 : ppAttr = &aAttrTab.pDirection;
1675 0 : break;
1676 : }
1677 :
1678 0 : return ppAttr;
1679 : }
1680 :
1681 0 : void SwHTMLParser::NewStyle()
1682 : {
1683 0 : OUString sType;
1684 :
1685 0 : const HTMLOptions& rOptions2 = GetOptions();
1686 0 : for (size_t i = rOptions2.size(); i; )
1687 : {
1688 0 : const HTMLOption& rOption = rOptions2[--i];
1689 0 : if( HTML_O_TYPE == rOption.GetToken() )
1690 0 : sType = rOption.GetString();
1691 : }
1692 :
1693 0 : bIgnoreRawData = !sType.getLength() &&
1694 0 : !sType.getToken(0,';').equalsAscii(sCSS_mimetype);
1695 0 : }
1696 :
1697 0 : void SwHTMLParser::EndStyle()
1698 : {
1699 0 : bIgnoreRawData = false;
1700 :
1701 0 : if( !aStyleSource.isEmpty() )
1702 : {
1703 0 : pCSS1Parser->ParseStyleSheet( aStyleSource );
1704 0 : aStyleSource = "";
1705 : }
1706 0 : }
1707 :
1708 0 : sal_Bool SwHTMLParser::FileDownload( const OUString& rURL,
1709 : OUString& rStr )
1710 : {
1711 : // View wegschmeissen (wegen Reschedule)
1712 0 : SwViewShell *pOldVSh = CallEndAction();
1713 :
1714 : // Ein Medium anlegen
1715 0 : SfxMedium aDLMedium( rURL, STREAM_READ | STREAM_SHARE_DENYWRITE );
1716 :
1717 0 : SvStream* pStream = aDLMedium.GetInStream();
1718 0 : if( pStream )
1719 : {
1720 0 : SvMemoryStream aStream;
1721 0 : aStream.WriteStream( *pStream );
1722 :
1723 0 : aStream.Seek( STREAM_SEEK_TO_END );
1724 0 : rStr = OUString((const sal_Char *)aStream.GetData(), aStream.Tell(),
1725 0 : GetSrcEncoding());
1726 : }
1727 :
1728 : // wurde abgebrochen?
1729 0 : if( ( pDoc->GetDocShell() && pDoc->GetDocShell()->IsAbortingImport() )
1730 0 : || 1 == pDoc->getReferenceCount() )
1731 : {
1732 : // wurde der Import vom SFX abgebrochen?
1733 0 : eState = SVPAR_ERROR;
1734 0 : pStream = 0;
1735 : }
1736 :
1737 : // recreate View
1738 0 : SwViewShell *const pVSh = CallStartAction( pOldVSh );
1739 : OSL_ENSURE( pOldVSh == pVSh, "FileDownload: SwViewShell changed on us" );
1740 : (void) pVSh;
1741 :
1742 0 : return pStream!=0;
1743 : }
1744 :
1745 0 : void SwHTMLParser::InsertLink()
1746 : {
1747 0 : sal_Bool bFinishDownload = sal_False;
1748 0 : if( pPendStack )
1749 : {
1750 : OSL_ENSURE( ShouldFinishFileDownload(),
1751 : "Pending-Stack ohne File-Download?" );
1752 :
1753 0 : SwPendingStack* pTmp = pPendStack->pNext;
1754 0 : delete pPendStack;
1755 0 : pPendStack = pTmp;
1756 : OSL_ENSURE( !pPendStack, "Wo kommt der Pending-Stack her?" );
1757 :
1758 0 : bFinishDownload = sal_True;
1759 : }
1760 : else
1761 : {
1762 0 : OUString sRel, sHRef, sType;
1763 :
1764 0 : const HTMLOptions& rOptions2 = GetOptions();
1765 0 : for (size_t i = rOptions2.size(); i; )
1766 : {
1767 0 : const HTMLOption& rOption = rOptions2[--i];
1768 0 : switch( rOption.GetToken() )
1769 : {
1770 : case HTML_O_REL:
1771 0 : sRel = rOption.GetString();
1772 0 : break;
1773 : case HTML_O_HREF:
1774 0 : sHRef = URIHelper::SmartRel2Abs( INetURLObject( sBaseURL ), rOption.GetString(), Link(), false );
1775 0 : break;
1776 : case HTML_O_TYPE:
1777 0 : sType = rOption.GetString();
1778 0 : break;
1779 : }
1780 : }
1781 :
1782 0 : if( !sHRef.isEmpty() && sRel.equalsIgnoreAsciiCase( "STYLESHEET" ) &&
1783 0 : ( sType.isEmpty() ||
1784 0 : sType.getToken(0,';').equalsAscii(sCSS_mimetype) ) )
1785 : {
1786 0 : if( GetMedium() )
1787 : {
1788 : // Download des Style-Source starten
1789 0 : StartFileDownload(sHRef);
1790 0 : if( IsParserWorking() )
1791 : {
1792 : // Der Style wurde synchron geladen und wir koennen
1793 : // es direkt aufrufen.
1794 0 : bFinishDownload = sal_True;
1795 : }
1796 : else
1797 : {
1798 : // Der Style wird asynchron geladen und ist erst beim
1799 : // naechsten Continue-Aufruf da. Wir muessen deshalb einen
1800 : // Pending-Stack anlegen, damit wir hierher zurueckkehren
1801 0 : pPendStack = new SwPendingStack( HTML_LINK, pPendStack );
1802 : }
1803 : }
1804 : else
1805 : {
1806 : // File synchron holen
1807 0 : OUString sSource;
1808 0 : if( FileDownload( sHRef, sSource ) )
1809 0 : pCSS1Parser->ParseStyleSheet( sSource );
1810 : }
1811 0 : }
1812 : }
1813 :
1814 0 : if( bFinishDownload )
1815 : {
1816 0 : OUString sSource;
1817 0 : if( FinishFileDownload( sSource ) && !sSource.isEmpty() )
1818 0 : pCSS1Parser->ParseStyleSheet( sSource );
1819 : }
1820 0 : }
1821 :
1822 0 : sal_Bool SwCSS1Parser::ParseStyleSheet( const OUString& rIn )
1823 : {
1824 0 : if( !SvxCSS1Parser::ParseStyleSheet( rIn ) )
1825 0 : return sal_False;
1826 :
1827 : SwPageDesc *pMasterPageDesc =
1828 0 : pDoc->GetPageDescFromPool( RES_POOLPAGE_HTML, false );
1829 :
1830 0 : SvxCSS1MapEntry *pPageEntry = GetPage( aEmptyOUStr, false );
1831 0 : if( pPageEntry )
1832 : {
1833 : // @page (wirkt auf alle Seiten, die es schon gibt
1834 :
1835 0 : SetPageDescAttrs( pMasterPageDesc, pPageEntry->GetItemSet(),
1836 0 : pPageEntry->GetPropertyInfo() );
1837 :
1838 : // Fuer alle anderen Seiten-Vorlagen, die es schon gibt,
1839 : // muessen die Attribute auch noch gesetzt werden
1840 :
1841 0 : SetPageDescAttrs( GetFirstPageDesc(), pPageEntry->GetItemSet(),
1842 0 : pPageEntry->GetPropertyInfo() );
1843 0 : SetPageDescAttrs( GetLeftPageDesc(), pPageEntry->GetItemSet(),
1844 0 : pPageEntry->GetPropertyInfo() );
1845 0 : SetPageDescAttrs( GetRightPageDesc(), pPageEntry->GetItemSet(),
1846 0 : pPageEntry->GetPropertyInfo() );
1847 :
1848 : }
1849 :
1850 0 : pPageEntry = GetPage( "first", true );
1851 0 : if( pPageEntry )
1852 : {
1853 0 : SetPageDescAttrs( GetFirstPageDesc(sal_True), pPageEntry->GetItemSet(),
1854 0 : pPageEntry->GetPropertyInfo() );
1855 0 : bSetFirstPageDesc = sal_True;
1856 : }
1857 :
1858 0 : pPageEntry = GetPage( "right", true );
1859 0 : if( pPageEntry )
1860 : {
1861 0 : SetPageDescAttrs( GetRightPageDesc(sal_True), pPageEntry->GetItemSet(),
1862 0 : pPageEntry->GetPropertyInfo() );
1863 0 : bSetRightPageDesc = sal_True;
1864 : }
1865 :
1866 0 : pPageEntry = GetPage( "left", true );
1867 0 : if( pPageEntry )
1868 0 : SetPageDescAttrs( GetLeftPageDesc(sal_True), pPageEntry->GetItemSet(),
1869 0 : pPageEntry->GetPropertyInfo() );
1870 :
1871 0 : return sal_True;
1872 : }
1873 :
1874 0 : sal_Bool SwHTMLParser::ParseStyleOptions( const OUString &rStyle,
1875 : const OUString &rId,
1876 : const OUString &rClass,
1877 : SfxItemSet &rItemSet,
1878 : SvxCSS1PropertyInfo &rPropInfo,
1879 : const OUString *pLang,
1880 : const OUString *pDir )
1881 : {
1882 0 : sal_Bool bRet = sal_False;
1883 :
1884 0 : if( !rClass.isEmpty() )
1885 : {
1886 0 : OUString aClass( rClass );
1887 0 : SwCSS1Parser::GetScriptFromClass( aClass );
1888 0 : const SvxCSS1MapEntry *pClass = pCSS1Parser->GetClass( aClass );
1889 0 : if( pClass )
1890 : {
1891 0 : pCSS1Parser->MergeStyles( pClass->GetItemSet(),
1892 0 : pClass->GetPropertyInfo(),
1893 0 : rItemSet, rPropInfo, sal_False );
1894 0 : bRet = sal_True;
1895 0 : }
1896 : }
1897 :
1898 0 : if( !rId.isEmpty() )
1899 : {
1900 0 : const SvxCSS1MapEntry *pId = pCSS1Parser->GetId( rId );
1901 0 : if( pId )
1902 0 : pCSS1Parser->MergeStyles( pId->GetItemSet(),
1903 0 : pId->GetPropertyInfo(),
1904 0 : rItemSet, rPropInfo, !rClass.isEmpty() );
1905 0 : rPropInfo.aId = rId;
1906 0 : bRet = sal_True;
1907 : }
1908 :
1909 0 : if( !rStyle.isEmpty() )
1910 : {
1911 0 : pCSS1Parser->ParseStyleOption( rStyle, rItemSet, rPropInfo );
1912 0 : bRet = sal_True;
1913 : }
1914 :
1915 0 : if( bRet )
1916 0 : rPropInfo.SetBoxItem( rItemSet, MIN_BORDER_DIST );
1917 :
1918 0 : if( pLang && !pLang->isEmpty() )
1919 : {
1920 0 : LanguageType eLang = LanguageTag::convertToLanguageTypeWithFallback( *pLang );
1921 0 : if( LANGUAGE_DONTKNOW != eLang )
1922 : {
1923 0 : SvxLanguageItem aLang( eLang, RES_CHRATR_LANGUAGE );
1924 0 : rItemSet.Put( aLang );
1925 0 : aLang.SetWhich( RES_CHRATR_CJK_LANGUAGE );
1926 0 : rItemSet.Put( aLang );
1927 0 : aLang.SetWhich( RES_CHRATR_CTL_LANGUAGE );
1928 0 : rItemSet.Put( aLang );
1929 :
1930 0 : bRet = sal_True;
1931 : }
1932 : }
1933 0 : if( pDir && !pDir->isEmpty() )
1934 : {
1935 0 : OUString aValue( *pDir );
1936 0 : SvxFrameDirection eDir = FRMDIR_ENVIRONMENT;
1937 0 : if (aValue.equalsIgnoreAsciiCase("LTR"))
1938 0 : eDir = FRMDIR_HORI_LEFT_TOP;
1939 0 : else if (aValue.equalsIgnoreAsciiCase("RTL"))
1940 0 : eDir = FRMDIR_HORI_RIGHT_TOP;
1941 :
1942 0 : if( FRMDIR_ENVIRONMENT != eDir )
1943 : {
1944 0 : SvxFrameDirectionItem aDir( eDir, RES_FRAMEDIR );
1945 0 : rItemSet.Put( aDir );
1946 :
1947 0 : bRet = sal_True;
1948 0 : }
1949 : }
1950 :
1951 0 : return bRet;
1952 : }
1953 :
1954 0 : void SwHTMLParser::SetAnchorAndAdjustment( const SfxItemSet & /*rItemSet*/,
1955 : const SvxCSS1PropertyInfo &rPropInfo,
1956 : SfxItemSet &rFrmItemSet )
1957 : {
1958 0 : SwFmtAnchor aAnchor;
1959 :
1960 0 : sal_Int16 eHoriOri = text::HoriOrientation::NONE;
1961 0 : sal_Int16 eVertOri = text::VertOrientation::NONE;
1962 0 : sal_Int16 eHoriRel = text::RelOrientation::FRAME;
1963 0 : sal_Int16 eVertRel = text::RelOrientation::FRAME;
1964 0 : SwTwips nHoriPos = 0, nVertPos = 0;
1965 0 : SwSurround eSurround = SURROUND_THROUGHT;
1966 0 : if( SVX_CSS1_POS_ABSOLUTE == rPropInfo.ePosition )
1967 : {
1968 0 : if( SVX_CSS1_LTYPE_TWIP == rPropInfo.eLeftType &&
1969 0 : SVX_CSS1_LTYPE_TWIP == rPropInfo.eTopType )
1970 : {
1971 : // Absolut positionierte Objekte sind seitengebunden, wenn
1972 : // sie nicht schon in einem Rahmen stehen und sonst
1973 : // Rahmengebunden.
1974 : const SwStartNode *pFlySttNd =
1975 0 : pPam->GetPoint()->nNode.GetNode().FindFlyStartNode();
1976 0 : if( pFlySttNd )
1977 : {
1978 0 : aAnchor.SetType( FLY_AT_FLY );
1979 0 : SwPosition aPos( *pFlySttNd );
1980 0 : aAnchor.SetAnchor( &aPos );
1981 : }
1982 : else
1983 : {
1984 0 : aAnchor.SetType( FLY_AT_PAGE );
1985 0 : aAnchor.SetPageNum( 1 );
1986 : }
1987 0 : nHoriPos = rPropInfo.nLeft;
1988 0 : nVertPos = rPropInfo.nTop;
1989 : }
1990 : else
1991 : {
1992 0 : aAnchor.SetType( FLY_AT_PARA );
1993 0 : aAnchor.SetAnchor( pPam->GetPoint() );
1994 0 : eVertOri = text::VertOrientation::TOP;
1995 0 : eVertRel = text::RelOrientation::CHAR;
1996 0 : if( SVX_CSS1_LTYPE_TWIP == rPropInfo.eLeftType )
1997 : {
1998 0 : eHoriOri = text::HoriOrientation::NONE;
1999 0 : eHoriRel = text::RelOrientation::PAGE_FRAME;
2000 0 : nHoriPos = rPropInfo.nLeft;
2001 : }
2002 : else
2003 : {
2004 0 : eHoriOri = text::HoriOrientation::LEFT;
2005 0 : eHoriRel = text::RelOrientation::FRAME; // wird noch umgeschossen
2006 : }
2007 : }
2008 : }
2009 : else
2010 : {
2011 : // fliessende Objekte werden Absatzgebunden eingefuegt, wenn
2012 : // der Absatz noch leer ist und sonst auto-gebunden.
2013 : // Auto-gebundene Rahmen werden zunaechst an der Position davor
2014 : // eingefuegt und erst spaeter verschoben.
2015 0 : const sal_Int32 nCntnt = pPam->GetPoint()->nContent.GetIndex();
2016 0 : if( nCntnt )
2017 : {
2018 0 : aAnchor.SetType( FLY_AT_CHAR );
2019 0 : pPam->Move( fnMoveBackward );
2020 0 : eVertOri = text::VertOrientation::CHAR_BOTTOM;
2021 0 : eVertRel = text::RelOrientation::CHAR;
2022 : }
2023 : else
2024 : {
2025 0 : aAnchor.SetType( FLY_AT_PARA );
2026 0 : eVertOri = text::VertOrientation::TOP;
2027 0 : eVertRel = text::RelOrientation::PRINT_AREA;
2028 : }
2029 :
2030 0 : aAnchor.SetAnchor( pPam->GetPoint() );
2031 :
2032 0 : if( nCntnt )
2033 0 : pPam->Move( fnMoveForward );
2034 :
2035 0 : sal_uInt16 nLeftSpace = 0, nRightSpace = 0;
2036 0 : short nIndent = 0;
2037 0 : GetMarginsFromContextWithNumBul( nLeftSpace, nRightSpace, nIndent );
2038 :
2039 0 : if( SVX_ADJUST_RIGHT==rPropInfo.eFloat )
2040 : {
2041 0 : eHoriOri = text::HoriOrientation::RIGHT;
2042 0 : eHoriRel = nRightSpace ? text::RelOrientation::PRINT_AREA : text::RelOrientation::FRAME;
2043 0 : eSurround = SURROUND_LEFT;
2044 : }
2045 : else
2046 : {
2047 0 : eHoriOri = text::HoriOrientation::LEFT;
2048 0 : eHoriRel = nLeftSpace ? text::RelOrientation::PRINT_AREA : text::RelOrientation::FRAME;
2049 0 : eSurround = SURROUND_RIGHT;
2050 : }
2051 : }
2052 0 : rFrmItemSet.Put( aAnchor );
2053 :
2054 : // Absolut Positioniert mit Durchlauf
2055 0 : rFrmItemSet.Put( SwFmtHoriOrient( nHoriPos, eHoriOri, eHoriRel ) );
2056 0 : rFrmItemSet.Put( SwFmtVertOrient( nVertPos, eVertOri, eVertRel ) );
2057 0 : rFrmItemSet.Put( SwFmtSurround( eSurround ) );
2058 0 : }
2059 :
2060 0 : void SwHTMLParser::SetVarSize( SfxItemSet & /*rItemSet*/,
2061 : SvxCSS1PropertyInfo &rPropInfo,
2062 : SfxItemSet &rFrmItemSet,
2063 : SwTwips nDfltWidth, sal_uInt8 nDfltPrcWidth )
2064 : {
2065 0 : SwFrmSize eSize = ATT_MIN_SIZE;
2066 0 : SwTwips nWidth = nDfltWidth, nHeight = MINFLY;
2067 0 : sal_uInt8 nPrcWidth = nDfltPrcWidth, nPrcHeight = 0;
2068 0 : switch( rPropInfo.eWidthType )
2069 : {
2070 : case SVX_CSS1_LTYPE_PERCENTAGE:
2071 0 : nPrcWidth = rPropInfo.nWidth > 0 ? (sal_uInt8)rPropInfo.nWidth : 1;
2072 0 : nWidth = MINFLY;
2073 0 : break;
2074 : case SVX_CSS1_LTYPE_TWIP:
2075 0 : nWidth = rPropInfo.nWidth > MINFLY ? rPropInfo.nWidth : MINFLY;
2076 0 : nPrcWidth = 0;
2077 0 : break;
2078 : default:
2079 : ;
2080 : }
2081 0 : switch( rPropInfo.eHeightType )
2082 : {
2083 : case SVX_CSS1_LTYPE_PERCENTAGE:
2084 0 : nPrcHeight = rPropInfo.nHeight > 0 ? (sal_uInt8)rPropInfo.nHeight : 1;
2085 0 : break;
2086 : case SVX_CSS1_LTYPE_TWIP:
2087 : // Netscape und MS-IE interpretieren die Hoehe regelwiedrig
2088 : // als Mindest-Hoehe, also machwn wir das auch so.
2089 0 : nHeight = rPropInfo.nHeight > MINFLY ? rPropInfo.nHeight : MINFLY;
2090 0 : break;
2091 : default:
2092 : ;
2093 : }
2094 :
2095 0 : SwFmtFrmSize aFrmSize( eSize, nWidth, nHeight );
2096 0 : aFrmSize.SetWidthPercent( nPrcWidth );
2097 0 : aFrmSize.SetHeightPercent( nPrcHeight );
2098 0 : rFrmItemSet.Put( aFrmSize );
2099 0 : }
2100 :
2101 0 : void SwHTMLParser::SetFrmFmtAttrs( SfxItemSet &rItemSet,
2102 : SvxCSS1PropertyInfo & /*rPropInfo*/,
2103 : sal_uInt16 nFlags,
2104 : SfxItemSet &rFrmItemSet )
2105 : {
2106 : const SfxPoolItem *pItem;
2107 0 : if( (nFlags & HTML_FF_BOX) != 0 &&
2108 0 : SFX_ITEM_SET==rItemSet.GetItemState( RES_BOX, true, &pItem ) )
2109 : {
2110 0 : if( (nFlags & HTML_FF_PADDING) == 0 )
2111 : {
2112 0 : SvxBoxItem aBoxItem( *(const SvxBoxItem *)pItem );
2113 : // Alle 4 Seiten gleichzeitig auf 0 setzen
2114 0 : aBoxItem.SetDistance( 0 );
2115 0 : rFrmItemSet.Put( aBoxItem );
2116 : }
2117 : else
2118 : {
2119 0 : rFrmItemSet.Put( *pItem );
2120 : }
2121 0 : rItemSet.ClearItem( RES_BOX );
2122 : }
2123 :
2124 0 : if( (nFlags & HTML_FF_BACKGROUND) != 0 &&
2125 0 : SFX_ITEM_SET==rItemSet.GetItemState( RES_BACKGROUND, true, &pItem ) )
2126 : {
2127 0 : rFrmItemSet.Put( *pItem );
2128 0 : rItemSet.ClearItem( RES_BACKGROUND );
2129 : }
2130 :
2131 0 : if( (nFlags & HTML_FF_DIRECTION) != 0 &&
2132 0 : SFX_ITEM_SET==rItemSet.GetItemState( RES_FRAMEDIR, true, &pItem ) )
2133 : {
2134 0 : rFrmItemSet.Put( *pItem );
2135 0 : rItemSet.ClearItem( RES_FRAMEDIR );
2136 : }
2137 0 : }
2138 :
2139 0 : _HTMLAttrContext *SwHTMLParser::PopContext( sal_uInt16 nToken, sal_uInt16 nLimit,
2140 : sal_Bool bRemove )
2141 : {
2142 0 : sal_uInt16 nPos = aContexts.size();
2143 0 : if( nPos <= nContextStMin )
2144 0 : return 0;
2145 :
2146 0 : sal_Bool bFound = 0==nToken;
2147 0 : if( nToken )
2148 : {
2149 : // Stack-Eintrag zu dem Token suchen
2150 0 : while( nPos > nContextStMin )
2151 : {
2152 0 : sal_uInt16 nCntxtToken = aContexts[--nPos]->GetToken();
2153 0 : if( nCntxtToken == nToken )
2154 : {
2155 0 : bFound = sal_True;
2156 0 : break;
2157 : }
2158 0 : else if( nCntxtToken == nLimit ) // 0 als Token kommt nicht vor
2159 : {
2160 0 : break;
2161 : }
2162 : }
2163 : }
2164 : else
2165 : {
2166 0 : nPos--;
2167 : }
2168 :
2169 0 : _HTMLAttrContext *pCntxt = 0;
2170 0 : if( bFound )
2171 : {
2172 0 : pCntxt = aContexts[nPos];
2173 0 : if( bRemove )
2174 0 : aContexts.erase( aContexts.begin() + nPos );
2175 : }
2176 :
2177 0 : return pCntxt;
2178 : }
2179 :
2180 0 : sal_Bool SwHTMLParser::GetMarginsFromContext( sal_uInt16& nLeft,
2181 : sal_uInt16& nRight,
2182 : short& nIndent,
2183 : sal_Bool bIgnoreTopContext ) const
2184 : {
2185 0 : sal_uInt16 nPos = aContexts.size();
2186 0 : if( bIgnoreTopContext )
2187 : {
2188 0 : if( !nPos )
2189 0 : return sal_False;
2190 : else
2191 0 : nPos--;
2192 : }
2193 :
2194 0 : while( nPos > nContextStAttrMin )
2195 : {
2196 0 : const _HTMLAttrContext *pCntxt = aContexts[--nPos];
2197 0 : if( pCntxt->IsLRSpaceChanged() )
2198 : {
2199 0 : pCntxt->GetMargins( nLeft, nRight, nIndent );
2200 0 : return sal_True;
2201 : }
2202 : }
2203 :
2204 0 : return sal_False;
2205 : }
2206 :
2207 0 : sal_Bool SwHTMLParser::GetMarginsFromContextWithNumBul( sal_uInt16& nLeft,
2208 : sal_uInt16& nRight,
2209 : short& nIndent ) const
2210 : {
2211 0 : sal_Bool bRet = GetMarginsFromContext( nLeft, nRight, nIndent );
2212 0 : const SwHTMLNumRuleInfo& rInfo = ((SwHTMLParser*)this)->GetNumInfo();
2213 0 : if( rInfo.GetDepth() )
2214 : {
2215 0 : sal_uInt8 nLevel = (sal_uInt8)( (rInfo.GetDepth() <= MAXLEVEL ? rInfo.GetDepth()
2216 0 : : MAXLEVEL) - 1 );
2217 0 : const SwNumFmt& rNumFmt = rInfo.GetNumRule()->Get(nLevel);
2218 0 : nLeft = nLeft + rNumFmt.GetAbsLSpace();
2219 0 : nIndent = rNumFmt.GetFirstLineOffset();
2220 : }
2221 :
2222 0 : return bRet;
2223 : }
2224 :
2225 0 : void SwHTMLParser::GetULSpaceFromContext( sal_uInt16& nUpper,
2226 : sal_uInt16& nLower ) const
2227 : {
2228 0 : sal_uInt16 nDfltColl = 0;
2229 0 : OUString aDfltClass;
2230 :
2231 0 : sal_uInt16 nPos = aContexts.size();
2232 0 : while( nPos > nContextStAttrMin )
2233 : {
2234 0 : const _HTMLAttrContext *pCntxt = aContexts[--nPos];
2235 0 : if( pCntxt->IsULSpaceChanged() )
2236 : {
2237 0 : pCntxt->GetULSpace( nUpper, nLower );
2238 0 : return;
2239 : }
2240 0 : else if( !nDfltColl )
2241 : {
2242 0 : nDfltColl = pCntxt->GetDfltTxtFmtColl();
2243 0 : if( nDfltColl )
2244 0 : aDfltClass = pCntxt->GetClass();
2245 : }
2246 : }
2247 :
2248 0 : if( !nDfltColl )
2249 0 : nDfltColl = RES_POOLCOLL_TEXT;
2250 :
2251 : const SwTxtFmtColl *pColl =
2252 0 : pCSS1Parser->GetTxtFmtColl( nDfltColl, aDfltClass );
2253 0 : const SvxULSpaceItem& rULSpace = pColl->GetULSpace();
2254 0 : nUpper = rULSpace.GetUpper();
2255 0 : nLower = rULSpace.GetLower();
2256 : }
2257 :
2258 0 : void SwHTMLParser::EndContextAttrs( _HTMLAttrContext *pContext, sal_Bool bRemove )
2259 : {
2260 0 : _HTMLAttrs &rAttrs = pContext->GetAttrs();
2261 0 : for( sal_uInt16 i=0; i<rAttrs.size(); i++ )
2262 : {
2263 0 : _HTMLAttr *pAttr = rAttrs[i];
2264 :
2265 0 : if( RES_PARATR_DROP==pAttr->GetItem().Which() )
2266 : {
2267 : // Fuer DropCaps noch die Anzahl der Zeichen anpassen. Wenn
2268 : // es am Ende 0 sind, wird das Attribut invalidiert und dann
2269 : // von _SetAttr gar nicht erst gesetzt.
2270 0 : sal_Int32 nChars = pPam->GetPoint()->nContent.GetIndex();
2271 0 : if( nChars < 1 )
2272 0 : pAttr->Invalidate();
2273 0 : else if( nChars > MAX_DROPCAP_CHARS )
2274 0 : nChars = MAX_DROPCAP_CHARS;
2275 0 : ((SwFmtDrop&)pAttr->GetItem()).GetChars() = (sal_uInt8)nChars;
2276 : }
2277 :
2278 0 : EndAttr( pAttr );
2279 : }
2280 :
2281 0 : if( bRemove && !rAttrs.empty() )
2282 0 : rAttrs.clear();
2283 0 : }
2284 :
2285 0 : void SwHTMLParser::InsertParaAttrs( const SfxItemSet& rItemSet )
2286 : {
2287 0 : SfxItemIter aIter( rItemSet );
2288 :
2289 0 : const SfxPoolItem *pItem = aIter.FirstItem();
2290 0 : while( pItem )
2291 : {
2292 : // den zu dem Item gehoehrenden Tabellen-Eintrag ermitteln ...
2293 0 : sal_uInt16 nWhich = pItem->Which();
2294 0 : _HTMLAttr **ppAttr = GetAttrTabEntry( nWhich );
2295 :
2296 0 : if( ppAttr )
2297 : {
2298 0 : NewAttr( ppAttr, *pItem );
2299 0 : if( RES_PARATR_BEGIN > nWhich )
2300 0 : (*ppAttr)->SetLikePara();
2301 0 : aParaAttrs.push_back( *ppAttr );
2302 0 : EndAttr( *ppAttr, 0, sal_False );
2303 : }
2304 :
2305 0 : pItem = aIter.NextItem();
2306 0 : }
2307 0 : }
2308 :
2309 0 : static void lcl_swcss1_setEncoding( SwFmt& rFmt, rtl_TextEncoding eEnc )
2310 : {
2311 0 : if( RTL_TEXTENCODING_DONTKNOW == eEnc )
2312 0 : return;
2313 :
2314 0 : const SfxItemSet& rItemSet = rFmt.GetAttrSet();
2315 : static const sal_uInt16 aWhichIds[3] = { RES_CHRATR_FONT, RES_CHRATR_CJK_FONT,
2316 : RES_CHRATR_CTL_FONT };
2317 : const SfxPoolItem *pItem;
2318 0 : for( sal_uInt16 i=0; i<3; i++ )
2319 : {
2320 0 : if( SFX_ITEM_SET == rItemSet.GetItemState( aWhichIds[i], false,&pItem ) )
2321 : {
2322 0 : const SvxFontItem& rFont = *(const SvxFontItem *)pItem;
2323 0 : if( RTL_TEXTENCODING_SYMBOL != rFont.GetCharSet() )
2324 : {
2325 0 : SvxFontItem aFont( rFont.GetFamily(), rFont.GetFamilyName(),
2326 0 : rFont.GetStyleName(), rFont.GetPitch(),
2327 0 : eEnc, aWhichIds[i]);
2328 0 : rFmt.SetFmtAttr( aFont );
2329 : }
2330 : }
2331 : }
2332 : }
2333 :
2334 0 : void SwCSS1Parser::SetDfltEncoding( rtl_TextEncoding eEnc )
2335 : {
2336 0 : if( eEnc != GetDfltEncoding() )
2337 : {
2338 0 : if( bIsNewDoc )
2339 : {
2340 : // Set new encoding as pool default
2341 : static const sal_uInt16 aWhichIds[3] = { RES_CHRATR_FONT, RES_CHRATR_CJK_FONT,
2342 : RES_CHRATR_CTL_FONT };
2343 : sal_uInt16 i;
2344 0 : for( i=0; i<3; i++ )
2345 : {
2346 : const SvxFontItem& rDfltFont =
2347 0 : (const SvxFontItem&)pDoc->GetDefault( aWhichIds[i]);
2348 : SvxFontItem aFont( rDfltFont.GetFamily(),
2349 0 : rDfltFont.GetFamilyName(),
2350 0 : rDfltFont.GetStyleName(),
2351 : rDfltFont.GetPitch(),
2352 0 : eEnc, aWhichIds[i] );
2353 0 : pDoc->SetDefault( aFont );
2354 0 : }
2355 :
2356 : // Change all paragraph styles that do specify a font.
2357 0 : sal_uInt16 nArrLen = pDoc->GetTxtFmtColls()->size();
2358 0 : for( i=1; i<nArrLen; i++ )
2359 0 : lcl_swcss1_setEncoding( *(*pDoc->GetTxtFmtColls())[i], eEnc );
2360 :
2361 : // Change all character styles that do specify a font.
2362 0 : nArrLen = pDoc->GetCharFmts()->size();
2363 0 : for( i=1; i<nArrLen; i++ )
2364 0 : lcl_swcss1_setEncoding( *(*pDoc->GetCharFmts())[i], eEnc );
2365 : }
2366 :
2367 0 : SvxCSS1Parser::SetDfltEncoding( eEnc );
2368 : }
2369 0 : }
2370 :
2371 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|