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