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( SwFmt& rFmt, rtl_TextEncoding eEnc );
73 :
74 : // Implementierung des SwCSS1Parsers (eigentlich swcss1.cxx)
75 : static struct SwCSS1ItemIds
76 : {
77 : sal_uInt16 nFmtBreak;
78 : sal_uInt16 nFmtPageDesc;
79 : sal_uInt16 nFmtKeep;
80 :
81 90 : SwCSS1ItemIds() :
82 : nFmtBreak( RES_BREAK ),
83 : nFmtPageDesc( RES_PAGEDESC ),
84 90 : nFmtKeep( RES_KEEP )
85 90 : {}
86 :
87 90 : } aItemIds;
88 :
89 20 : void SwCSS1Parser::ChgPageDesc( const SwPageDesc *pPageDesc,
90 : const SwPageDesc& rNewPageDesc )
91 : {
92 20 : sal_uInt16 nPageDescs = pDoc->GetPageDescCnt();
93 : sal_uInt16 i;
94 44 : for( i=0; i<nPageDescs; i++ )
95 44 : if( pPageDesc == &pDoc->GetPageDesc(i) )
96 : {
97 20 : pDoc->ChgPageDesc( i, rNewPageDesc );
98 40 : return;
99 : }
100 :
101 : OSL_ENSURE( i<nPageDescs, "Seitenvorlage nicht gefunden" );
102 : }
103 :
104 22 : SwCSS1Parser::SwCSS1Parser( SwDoc *pD, sal_uInt32 aFHeights[7], const OUString& rBaseURL, bool bNewDoc ) :
105 22 : SvxCSS1Parser( pD->GetAttrPool(), rBaseURL, MM50/2,
106 22 : (sal_uInt16*)&aItemIds, sizeof(aItemIds) / sizeof(sal_uInt16) ),
107 : pDoc( pD ),
108 : nDropCapCnt( 0 ),
109 : bIsNewDoc( bNewDoc ),
110 : bBodyBGColorSet( false ),
111 : bBodyBackgroundSet( false ),
112 : bBodyTextSet( false ),
113 : bBodyLinkSet( false ),
114 : bBodyVLinkSet( false ),
115 : bSetFirstPageDesc( false ),
116 : bSetRightPageDesc( false ),
117 : bTableHeaderTxtCollSet( false ),
118 : bTableTxtCollSet( false ),
119 44 : bLinkCharFmtsSet( false )
120 : {
121 22 : aFontHeights[0] = aFHeights[0];
122 22 : aFontHeights[1] = aFHeights[1];
123 22 : aFontHeights[2] = aFHeights[2];
124 22 : aFontHeights[3] = aFHeights[3];
125 22 : aFontHeights[4] = aFHeights[4];
126 22 : aFontHeights[5] = aFHeights[5];
127 22 : aFontHeights[6] = aFHeights[6];
128 22 : }
129 :
130 44 : SwCSS1Parser::~SwCSS1Parser()
131 : {
132 44 : }
133 :
134 : // Feature: PrintExt
135 1048 : bool SwCSS1Parser::SetFmtBreak( SfxItemSet& rItemSet,
136 : const SvxCSS1PropertyInfo& rPropInfo )
137 : {
138 1048 : SvxBreak eBreak = SVX_BREAK_NONE;
139 1048 : bool bKeep = false;
140 1048 : bool bSetKeep = false, bSetBreak = false, bSetPageDesc = false;
141 1048 : const SwPageDesc *pPageDesc = 0;
142 1048 : switch( rPropInfo.ePageBreakBefore )
143 : {
144 : case SVX_CSS1_PBREAK_ALWAYS:
145 2 : eBreak = SVX_BREAK_PAGE_BEFORE;
146 2 : bSetBreak = true;
147 2 : break;
148 : case SVX_CSS1_PBREAK_LEFT:
149 0 : pPageDesc = GetLeftPageDesc( true );
150 0 : bSetPageDesc = true;
151 0 : break;
152 : case SVX_CSS1_PBREAK_RIGHT:
153 0 : pPageDesc = GetRightPageDesc( true );
154 0 : bSetPageDesc = true;
155 0 : break;
156 : case SVX_CSS1_PBREAK_AUTO:
157 0 : bSetBreak = bSetPageDesc = true;
158 0 : break;
159 : default:
160 : ;
161 : }
162 1048 : switch( rPropInfo.ePageBreakAfter )
163 : {
164 : case SVX_CSS1_PBREAK_ALWAYS:
165 : case SVX_CSS1_PBREAK_LEFT:
166 : case SVX_CSS1_PBREAK_RIGHT:
167 : // LEFT/RIGHT koennte man auch am Absatz davor setzen
168 0 : eBreak = SVX_BREAK_PAGE_AFTER;
169 0 : bSetBreak = true;
170 0 : break;
171 : case SVX_CSS1_PBREAK_AUTO:
172 0 : bSetBreak = bSetKeep = bSetPageDesc = true;
173 0 : break;
174 : case SVX_CSS1_PBREAK_AVOID:
175 0 : bKeep = bSetKeep = true;
176 0 : break;
177 : default:
178 : ;
179 : }
180 :
181 1048 : if( bSetBreak )
182 2 : rItemSet.Put( SvxFmtBreakItem( eBreak, RES_BREAK ) );
183 1048 : if( bSetPageDesc )
184 0 : rItemSet.Put( SwFmtPageDesc( pPageDesc ) );
185 1048 : if( bSetKeep )
186 0 : rItemSet.Put( SvxFmtKeepItem( bKeep, RES_KEEP ) );
187 :
188 1048 : return bSetBreak;
189 : }
190 : // /Feature: PrintExt
191 :
192 2 : static void SetCharFmtAttrs( SwCharFmt *pCharFmt, SfxItemSet& rItemSet )
193 : {
194 : const SfxPoolItem *pItem;
195 : static const sal_uInt16 aWhichIds[3] = { RES_CHRATR_FONTSIZE,RES_CHRATR_CJK_FONTSIZE,
196 : RES_CHRATR_CTL_FONTSIZE };
197 8 : for( sal_uInt16 i=0; i<3; i++ )
198 : {
199 12 : if( SfxItemState::SET == rItemSet.GetItemState( aWhichIds[i], false,
200 6 : &pItem ) &&
201 0 : ((const SvxFontHeightItem *)pItem)->GetProp() != 100)
202 : {
203 : // %-Angaben beim FontHeight-Item werden nicht unterstuetzt
204 0 : rItemSet.ClearItem( aWhichIds[i] );
205 : }
206 : }
207 :
208 2 : pCharFmt->SetFmtAttr( rItemSet );
209 :
210 2 : if( SfxItemState::SET == rItemSet.GetItemState( RES_BACKGROUND, false, &pItem ) )
211 : {
212 : // Ein Brush-Item mit RES_BACKGROUND muss noch in eines mit
213 : // RES_CHRATR_BACKGROUND gewandelt werden
214 :
215 0 : SvxBrushItem aBrushItem( *(const SvxBrushItem *)pItem );
216 0 : aBrushItem.SetWhich( RES_CHRATR_BACKGROUND );
217 0 : pCharFmt->SetFmtAttr( aBrushItem );
218 : }
219 :
220 2 : if( SfxItemState::SET == rItemSet.GetItemState( RES_BOX, false, &pItem ) )
221 : {
222 0 : SvxBoxItem aBoxItem( *(const SvxBoxItem *)pItem );
223 0 : aBoxItem.SetWhich( RES_CHRATR_BOX );
224 0 : pCharFmt->SetFmtAttr( aBoxItem );
225 : }
226 2 : }
227 :
228 22 : void SwCSS1Parser::SetLinkCharFmts()
229 : {
230 : OSL_ENSURE( !bLinkCharFmtsSet, "Aufruf von SetLinkCharFmts unnoetig" );
231 :
232 : SvxCSS1MapEntry *pStyleEntry =
233 22 : GetTag( OUString(OOO_STRING_SVTOOLS_HTML_anchor) );
234 22 : SwCharFmt *pUnvisited = 0, *pVisited = 0;
235 22 : if( pStyleEntry )
236 : {
237 0 : SfxItemSet& rItemSet = pStyleEntry->GetItemSet();
238 : bool bColorSet = (SfxItemState::SET==rItemSet.GetItemState(RES_CHRATR_COLOR,
239 0 : false));
240 0 : pUnvisited = GetCharFmtFromPool( RES_POOLCHR_INET_NORMAL );
241 0 : SetCharFmtAttrs( pUnvisited, rItemSet );
242 0 : bBodyLinkSet |= bColorSet;
243 :
244 0 : pVisited = GetCharFmtFromPool( RES_POOLCHR_INET_VISIT );
245 0 : SetCharFmtAttrs( pVisited, rItemSet );
246 0 : bBodyVLinkSet |= bColorSet;
247 : }
248 :
249 22 : OUString sTmp = OOO_STRING_SVTOOLS_HTML_anchor ":link";
250 :
251 22 : pStyleEntry = GetTag( sTmp );
252 22 : if( pStyleEntry )
253 : {
254 2 : SfxItemSet& rItemSet = pStyleEntry->GetItemSet();
255 : bool bColorSet = (SfxItemState::SET==rItemSet.GetItemState(RES_CHRATR_COLOR,
256 2 : false));
257 2 : if( !pUnvisited )
258 2 : pUnvisited = GetCharFmtFromPool( RES_POOLCHR_INET_NORMAL );
259 2 : SetCharFmtAttrs( pUnvisited, rItemSet );
260 2 : bBodyLinkSet |= bColorSet;
261 : }
262 :
263 22 : sTmp = OOO_STRING_SVTOOLS_HTML_anchor ":visited";
264 :
265 22 : pStyleEntry = GetTag( sTmp );
266 22 : if( pStyleEntry )
267 : {
268 0 : SfxItemSet& rItemSet = pStyleEntry->GetItemSet();
269 : bool bColorSet = (SfxItemState::SET==rItemSet.GetItemState(RES_CHRATR_COLOR,
270 0 : false));
271 0 : if( !pVisited )
272 0 : pVisited = GetCharFmtFromPool( RES_POOLCHR_INET_VISIT );
273 0 : SetCharFmtAttrs( pVisited, rItemSet );
274 0 : bBodyVLinkSet |= bColorSet;
275 : }
276 :
277 22 : bLinkCharFmtsSet = true;
278 22 : }
279 :
280 12 : static void SetTxtCollAttrs( SwTxtFmtColl *pColl, SfxItemSet& rItemSet,
281 : SvxCSS1PropertyInfo& rPropInfo,
282 : SwCSS1Parser *pCSS1Parser )
283 : {
284 12 : const SfxItemSet& rCollItemSet = pColl->GetAttrSet();
285 : const SfxPoolItem *pCollItem, *pItem;
286 :
287 : // linker, rechter Rand und Erstzeilen-Einzug
288 24 : if( (rPropInfo.bLeftMargin || rPropInfo.bRightMargin ||
289 0 : rPropInfo.bTextIndent) &&
290 0 : (!rPropInfo.bLeftMargin || !rPropInfo.bRightMargin ||
291 0 : !rPropInfo.bTextIndent) &&
292 12 : SfxItemState::SET == rCollItemSet.GetItemState(RES_LR_SPACE,true,&pCollItem) &&
293 0 : SfxItemState::SET == rItemSet.GetItemState(RES_LR_SPACE,false,&pItem) )
294 : {
295 0 : const SvxLRSpaceItem *pLRItem = (const SvxLRSpaceItem *)pItem;
296 :
297 0 : SvxLRSpaceItem aLRItem( *((const SvxLRSpaceItem *)pCollItem) );
298 0 : if( rPropInfo.bLeftMargin )
299 0 : aLRItem.SetTxtLeft( pLRItem->GetTxtLeft() );
300 0 : if( rPropInfo.bRightMargin )
301 0 : aLRItem.SetRight( pLRItem->GetRight() );
302 0 : if( rPropInfo.bTextIndent )
303 0 : aLRItem.SetTxtFirstLineOfst( pLRItem->GetTxtFirstLineOfst() );
304 :
305 0 : rItemSet.Put( aLRItem );
306 : }
307 :
308 : // oberer und unterer Rand
309 26 : if( (rPropInfo.bTopMargin || rPropInfo.bBottomMargin) &&
310 4 : (!rPropInfo.bTopMargin || !rPropInfo.bBottomMargin) &&
311 : SfxItemState::SET == rCollItemSet.GetItemState(RES_UL_SPACE,true,
312 16 : &pCollItem) &&
313 2 : SfxItemState::SET == rItemSet.GetItemState(RES_UL_SPACE,false,&pItem) )
314 : {
315 2 : const SvxULSpaceItem *pULItem = (const SvxULSpaceItem *)pItem;
316 :
317 2 : SvxULSpaceItem aULItem( *((const SvxULSpaceItem *)pCollItem) );
318 2 : if( rPropInfo.bTopMargin )
319 0 : aULItem.SetUpper( pULItem->GetUpper() );
320 2 : if( rPropInfo.bBottomMargin )
321 2 : aULItem.SetLower( pULItem->GetLower() );
322 :
323 2 : rItemSet.Put( aULItem );
324 : }
325 :
326 : static const sal_uInt16 aWhichIds[3] = { RES_CHRATR_FONTSIZE,RES_CHRATR_CJK_FONTSIZE,
327 : RES_CHRATR_CTL_FONTSIZE };
328 48 : for( sal_uInt16 i=0; i<3; i++ )
329 : {
330 72 : if( SfxItemState::SET == rItemSet.GetItemState( aWhichIds[i], false,
331 42 : &pItem ) &&
332 6 : ((const SvxFontHeightItem *)pItem)->GetProp() != 100)
333 : {
334 : // %-Angaben beim FontHeight-Item werden nicht unterstuetzt
335 0 : rItemSet.ClearItem( aWhichIds[i] );
336 : }
337 : }
338 :
339 : // Feature: PrintExt
340 12 : pCSS1Parser->SetFmtBreak( rItemSet, rPropInfo );
341 : // /Feature: PrintExt
342 :
343 12 : pColl->SetFmtAttr( rItemSet );
344 12 : }
345 :
346 44 : void SwCSS1Parser::SetTableTxtColl( bool bHeader )
347 : {
348 : OSL_ENSURE( !(bHeader ? bTableHeaderTxtCollSet : bTableTxtCollSet),
349 : "Aufruf von SetTableTxtColl unnoetig" );
350 :
351 : sal_uInt16 nPoolId;
352 44 : OUString sTag;
353 44 : if( bHeader )
354 : {
355 22 : nPoolId = RES_POOLCOLL_TABLE_HDLN;
356 22 : sTag = OOO_STRING_SVTOOLS_HTML_tableheader;
357 : }
358 : else
359 : {
360 22 : nPoolId = RES_POOLCOLL_TABLE;
361 22 : sTag = OOO_STRING_SVTOOLS_HTML_tabledata;
362 : }
363 :
364 44 : SwTxtFmtColl *pColl = 0;
365 :
366 : // The following entries will never be used again and may be changed.
367 44 : SvxCSS1MapEntry *pStyleEntry = GetTag( sTag );
368 44 : if( pStyleEntry )
369 : {
370 0 : pColl = GetTxtFmtColl( nPoolId, aEmptyOUStr );
371 0 : SetTxtCollAttrs( pColl, pStyleEntry->GetItemSet(),
372 0 : pStyleEntry->GetPropertyInfo(), this );
373 : }
374 :
375 88 : OUString sTmp = sTag + " " OOO_STRING_SVTOOLS_HTML_parabreak;
376 44 : pStyleEntry = GetTag( sTmp );
377 44 : if( pStyleEntry )
378 : {
379 0 : if( !pColl )
380 0 : pColl = GetTxtFmtColl( nPoolId, aEmptyOUStr );
381 0 : SetTxtCollAttrs( pColl, pStyleEntry->GetItemSet(),
382 0 : pStyleEntry->GetPropertyInfo(), this );
383 : }
384 :
385 44 : if( bHeader )
386 22 : bTableHeaderTxtCollSet = true;
387 : else
388 66 : bTableTxtCollSet = true;
389 44 : }
390 :
391 10 : void SwCSS1Parser::SetPageDescAttrs( const SvxBrushItem *pBrush,
392 : SfxItemSet *pItemSet2 )
393 : {
394 10 : SvxBrushItem aBrushItem( RES_BACKGROUND );
395 20 : SvxBoxItem aBoxItem( RES_BOX );
396 20 : SvxFrameDirectionItem aFrmDirItem(FRMDIR_ENVIRONMENT, RES_FRAMEDIR);
397 10 : bool bSetBrush = pBrush!=0, bSetBox = false, bSetFrmDir = false;
398 10 : if( pBrush )
399 0 : aBrushItem = *pBrush;
400 :
401 10 : if( pItemSet2 )
402 : {
403 10 : const SfxPoolItem *pItem = 0;
404 10 : if( SfxItemState::SET == pItemSet2->GetItemState( RES_BACKGROUND, false,
405 10 : &pItem ) )
406 : {
407 : // ein Hintergrund wird gesetzt
408 0 : aBrushItem = *((const SvxBrushItem *)pItem);
409 0 : pItemSet2->ClearItem( RES_BACKGROUND );
410 0 : bSetBrush = true;
411 : }
412 :
413 10 : if( SfxItemState::SET == pItemSet2->GetItemState( RES_BOX, false, &pItem ) )
414 : {
415 : // eine Umrandung wird gesetzt
416 0 : aBoxItem = *((const SvxBoxItem *)pItem);
417 0 : pItemSet2->ClearItem( RES_BOX );
418 0 : bSetBox = true;
419 : }
420 :
421 10 : if( SfxItemState::SET == pItemSet2->GetItemState( RES_FRAMEDIR, false, &pItem ) )
422 : {
423 : // eine Umrandung wird gesetzt
424 10 : aFrmDirItem = *static_cast< const SvxFrameDirectionItem *>( pItem );
425 10 : pItemSet2->ClearItem( RES_FRAMEDIR );
426 10 : bSetFrmDir = true;
427 : }
428 : }
429 :
430 10 : if( bSetBrush || bSetBox || bSetFrmDir )
431 : {
432 : static sal_uInt16 aPoolIds[] = { RES_POOLPAGE_HTML, RES_POOLPAGE_FIRST,
433 : RES_POOLPAGE_LEFT, RES_POOLPAGE_RIGHT };
434 50 : for( sal_uInt16 i=0; i<4; i++ )
435 : {
436 40 : const SwPageDesc *pPageDesc = GetPageDesc( aPoolIds[i], false );
437 40 : if( pPageDesc )
438 : {
439 10 : SwPageDesc aNewPageDesc( *pPageDesc );
440 10 : SwFrmFmt &rMaster = aNewPageDesc.GetMaster();
441 10 : if( bSetBrush )
442 0 : rMaster.SetFmtAttr( aBrushItem );
443 10 : if( bSetBox )
444 0 : rMaster.SetFmtAttr( aBoxItem );
445 10 : if( bSetFrmDir )
446 10 : rMaster.SetFmtAttr( aFrmDirItem );
447 :
448 10 : ChgPageDesc( pPageDesc, aNewPageDesc );
449 : }
450 : }
451 10 : }
452 10 : }
453 :
454 : // Feature: PrintExt
455 40 : void SwCSS1Parser::SetPageDescAttrs( const SwPageDesc *pPageDesc,
456 : SfxItemSet& rItemSet,
457 : const SvxCSS1PropertyInfo& rPropInfo )
458 : {
459 40 : if( !pPageDesc )
460 70 : return;
461 :
462 10 : SwPageDesc aNewPageDesc( *pPageDesc );
463 10 : SwFrmFmt &rMaster = aNewPageDesc.GetMaster();
464 10 : const SfxItemSet& rPageItemSet = rMaster.GetAttrSet();
465 : const SfxPoolItem *pPageItem, *pItem;
466 10 : bool bChanged = false;
467 :
468 : // linker, rechter Rand und Erstzeilen-Einzug
469 20 : if( (rPropInfo.bLeftMargin || rPropInfo.bRightMargin) &&
470 10 : SfxItemState::SET == rItemSet.GetItemState(RES_LR_SPACE,false,&pItem) )
471 : {
472 10 : if( (!rPropInfo.bLeftMargin || !rPropInfo.bRightMargin) &&
473 : SfxItemState::SET == rPageItemSet.GetItemState(RES_LR_SPACE,
474 0 : true,&pPageItem) )
475 : {
476 0 : const SvxLRSpaceItem *pLRItem = (const SvxLRSpaceItem *)pItem;
477 :
478 0 : SvxLRSpaceItem aLRItem( *((const SvxLRSpaceItem *)pPageItem) );
479 0 : if( rPropInfo.bLeftMargin )
480 0 : aLRItem.SetLeft( pLRItem->GetLeft() );
481 0 : if( rPropInfo.bRightMargin )
482 0 : aLRItem.SetRight( pLRItem->GetRight() );
483 :
484 0 : rMaster.SetFmtAttr( aLRItem );
485 : }
486 : else
487 : {
488 10 : rMaster.SetFmtAttr( *pItem );
489 : }
490 10 : bChanged = true;
491 : }
492 :
493 : // oberer und unterer Rand
494 20 : if( (rPropInfo.bTopMargin || rPropInfo.bBottomMargin) &&
495 10 : SfxItemState::SET == rItemSet.GetItemState(RES_UL_SPACE,false,&pItem) )
496 : {
497 10 : if( (!rPropInfo.bTopMargin || !rPropInfo.bBottomMargin) &&
498 : SfxItemState::SET == rPageItemSet.GetItemState(RES_UL_SPACE,
499 0 : true,&pPageItem) )
500 : {
501 0 : const SvxULSpaceItem *pULItem = (const SvxULSpaceItem *)pItem;
502 :
503 0 : SvxULSpaceItem aULItem( *((const SvxULSpaceItem *)pPageItem) );
504 0 : if( rPropInfo.bTopMargin )
505 0 : aULItem.SetUpper( pULItem->GetUpper() );
506 0 : if( rPropInfo.bBottomMargin )
507 0 : aULItem.SetLower( pULItem->GetLower() );
508 :
509 0 : rMaster.SetFmtAttr( aULItem );
510 : }
511 : else
512 : {
513 10 : rMaster.SetFmtAttr( *pItem );
514 : }
515 10 : bChanged = true;
516 : }
517 :
518 : // die Groesse
519 10 : if( rPropInfo.eSizeType != SVX_CSS1_STYPE_NONE )
520 : {
521 10 : if( rPropInfo.eSizeType == SVX_CSS1_STYPE_TWIP )
522 : {
523 : rMaster.SetFmtAttr( SwFmtFrmSize( ATT_FIX_SIZE, rPropInfo.nWidth,
524 10 : rPropInfo.nHeight ) );
525 10 : bChanged = true;
526 : }
527 : else
528 : {
529 : // Bei "size: auto|portrait|landscape" bleibt die bisherige
530 : // Groesse der Vorlage erhalten. Bei "landscape" und "portrait"
531 : // wird das Landscape-Flag gesetzt und evtl. die Breite/Hoehe
532 : // vertauscht.
533 0 : SwFmtFrmSize aFrmSz( rMaster.GetFrmSize() );
534 0 : bool bLandscape = aNewPageDesc.GetLandscape();
535 0 : if( ( bLandscape &&
536 0 : rPropInfo.eSizeType == SVX_CSS1_STYPE_PORTRAIT ) ||
537 0 : ( !bLandscape &&
538 0 : rPropInfo.eSizeType == SVX_CSS1_STYPE_LANDSCAPE ) )
539 : {
540 0 : SwTwips nTmp = aFrmSz.GetHeight();
541 0 : aFrmSz.SetHeight( aFrmSz.GetWidth() );
542 0 : aFrmSz.SetWidth( nTmp );
543 0 : rMaster.SetFmtAttr( aFrmSz );
544 0 : aNewPageDesc.SetLandscape( !bLandscape );
545 0 : bChanged = true;
546 0 : }
547 : }
548 : }
549 :
550 : // Geht das wirklich?
551 10 : if( SfxItemState::SET == rItemSet.GetItemState( RES_BACKGROUND, false, &pItem ) )
552 : {
553 : // eine Umrandung wird gesetzt
554 0 : rMaster.SetFmtAttr( *pItem );
555 0 : rItemSet.ClearItem( RES_BACKGROUND );
556 0 : bChanged = true;
557 : }
558 :
559 10 : if( bChanged )
560 10 : ChgPageDesc( pPageDesc, aNewPageDesc );
561 : }
562 : // /Feature: PrintExt
563 :
564 20 : SvxBrushItem SwCSS1Parser::makePageDescBackground() const
565 : {
566 20 : return pDoc->getIDocumentStylePoolAccess().GetPageDescFromPool( RES_POOLPAGE_HTML, false )
567 20 : ->GetMaster().makeBackgroundBrushItem();
568 : }
569 :
570 270 : sal_uInt16 SwCSS1Parser::GetScriptFromClass( OUString& rClass,
571 : bool bSubClassOnly )
572 : {
573 270 : sal_uInt16 nScriptFlags = CSS1_SCRIPT_ALL;
574 270 : sal_Int32 nLen = rClass.getLength();
575 270 : sal_Int32 nPos = nLen > 4 ? rClass.lastIndexOf( '-' ) : -1;
576 :
577 270 : if( nPos == -1 )
578 : {
579 254 : if( bSubClassOnly )
580 4 : return nScriptFlags;
581 250 : nPos = 0;
582 : }
583 : else
584 : {
585 16 : nPos++;
586 16 : nLen = nLen - nPos;
587 : }
588 :
589 266 : switch( nLen )
590 : {
591 : case 3:
592 8 : if( rClass.matchIgnoreAsciiCaseAsciiL( "cjk", 3, nPos ) )
593 : {
594 4 : nScriptFlags = CSS1_SCRIPT_CJK;
595 : }
596 4 : else if( rClass.matchIgnoreAsciiCaseAsciiL( "ctl", 3, nPos ) )
597 : {
598 4 : nScriptFlags = CSS1_SCRIPT_CTL;
599 : }
600 8 : break;
601 : case 7:
602 214 : if( rClass.matchIgnoreAsciiCaseAsciiL( "western", 7, nPos ) )
603 : {
604 212 : nScriptFlags = CSS1_SCRIPT_WESTERN;
605 : }
606 214 : break;
607 : }
608 266 : if( CSS1_SCRIPT_ALL != nScriptFlags )
609 : {
610 220 : if( nPos )
611 : {
612 0 : rClass = rClass.copy( 0, nPos-1 );
613 : }
614 : else
615 : {
616 220 : rClass = "";
617 : }
618 : }
619 :
620 266 : return nScriptFlags;
621 : }
622 :
623 20 : static CSS1SelectorType GetTokenAndClass( const CSS1Selector *pSelector,
624 : OUString& rToken, OUString& rClass,
625 : sal_uInt16& rScriptFlags )
626 : {
627 20 : rToken = pSelector->GetString();
628 20 : rClass = "";
629 20 : rScriptFlags = CSS1_SCRIPT_ALL;
630 :
631 20 : CSS1SelectorType eType = pSelector->GetType();
632 20 : if( CSS1_SELTYPE_ELEM_CLASS==eType )
633 : {
634 12 : sal_Int32 nPos = rToken.indexOf( '.' );
635 : OSL_ENSURE( nPos >= 0, "kein Punkt in Class-Selektor???" );
636 12 : if( nPos >= 0 )
637 : {
638 12 : rClass = rToken.copy( nPos+1 );
639 12 : rToken = rToken.copy( 0, nPos );
640 :
641 12 : rScriptFlags = SwCSS1Parser::GetScriptFromClass( rClass, false );
642 12 : if( rClass.isEmpty() )
643 12 : eType = CSS1_SELTYPE_ELEMENT;
644 : }
645 : }
646 :
647 20 : rToken = rToken.toAsciiLowerCase();
648 20 : return eType;
649 : }
650 :
651 12 : 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 12 : sal_uInt16 aClearItems[3] = { sal_False, sal_False, sal_False };
665 12 : switch( nScript )
666 : {
667 : case CSS1_SCRIPT_WESTERN:
668 4 : aClearItems[1] = aClearItems[2] = sal_True;
669 4 : break;
670 : case CSS1_SCRIPT_CJK:
671 4 : aClearItems[0] = aClearItems[2] = sal_True;
672 4 : break;
673 : case CSS1_SCRIPT_CTL:
674 4 : aClearItems[0] = aClearItems[1] = sal_True;
675 4 : 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 48 : for( sal_uInt16 j=0; j < 3; j++ )
684 : {
685 216 : for( sal_uInt16 i=0; i < 5; i++ )
686 : {
687 180 : sal_uInt16 nWhich = aWhichIds[j][i];
688 : const SfxPoolItem *pItem;
689 300 : if( aClearItems[j] ||
690 0 : (pParentItemSet &&
691 0 : SfxItemState::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 120 : rItemSet.ClearItem( nWhich );
696 : }
697 : }
698 : }
699 12 : }
700 :
701 30 : bool SwCSS1Parser::StyleParsed( const CSS1Selector *pSelector,
702 : SfxItemSet& rItemSet,
703 : SvxCSS1PropertyInfo& rPropInfo )
704 : {
705 30 : if( !bIsNewDoc )
706 0 : return true;
707 :
708 30 : CSS1SelectorType eSelType = pSelector->GetType();
709 30 : const CSS1Selector *pNext = pSelector->GetNext();
710 :
711 30 : if( CSS1_SELTYPE_ID==eSelType && !pNext )
712 : {
713 0 : InsertId( pSelector->GetString(), rItemSet, rPropInfo );
714 : }
715 30 : 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 30 : else if( CSS1_SELTYPE_PAGE==eSelType )
731 : {
732 20 : 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 10 : OUString aName;
739 10 : if( pNext )
740 0 : aName = pNext->GetString();
741 : InsertPage( aName,
742 : pNext != 0,
743 10 : rItemSet, rPropInfo );
744 : }
745 : }
746 :
747 30 : if( CSS1_SELTYPE_ELEMENT != eSelType &&
748 : CSS1_SELTYPE_ELEM_CLASS != eSelType)
749 10 : return true;
750 :
751 : // Token und Class zu dem Selektor holen
752 20 : OUString aToken2;
753 40 : OUString aClass;
754 : sal_uInt16 nScript;
755 20 : eSelType = GetTokenAndClass( pSelector, aToken2, aClass, nScript );
756 20 : int nToken2 = GetHTMLToken( aToken2 );
757 :
758 : // und noch ein ganz par Infos zum naechsten Element
759 : CSS1SelectorType eNextType = pNext ? pNext->GetType()
760 20 : : CSS1_SELTYPE_ELEMENT;
761 :
762 : // Erstmal ein par Spezialfaelle
763 20 : if( CSS1_SELTYPE_ELEMENT==eSelType )
764 : {
765 20 : switch( nToken2 )
766 : {
767 : case HTML_ANCHOR_ON:
768 8 : if( !pNext )
769 : {
770 0 : InsertTag( aToken2, rItemSet, rPropInfo );
771 0 : return false;
772 : }
773 8 : else if( pNext && CSS1_SELTYPE_PSEUDO == eNextType )
774 : {
775 : // vielleicht A:visited oder A:link
776 :
777 8 : OUString aPseudo( pNext->GetString() );
778 8 : aPseudo = aPseudo.toAsciiLowerCase();
779 8 : bool bInsert = false;
780 8 : switch( aPseudo[0] )
781 : {
782 : case 'l':
783 8 : if( aPseudo == "link" )
784 : {
785 8 : bInsert = true;
786 : }
787 8 : break;
788 : case 'v':
789 0 : if( aPseudo == "visited" )
790 : {
791 0 : bInsert = true;
792 : }
793 0 : break;
794 : }
795 8 : if( bInsert )
796 : {
797 8 : OUString sTmp = aToken2 + ":" + aPseudo;
798 8 : if( CSS1_SCRIPT_ALL != nScript )
799 : {
800 6 : SfxItemSet aScriptItemSet( rItemSet );
801 6 : RemoveScriptItems( aScriptItemSet, nScript );
802 6 : InsertTag( sTmp, aScriptItemSet, rPropInfo );
803 : }
804 : else
805 : {
806 2 : InsertTag( sTmp, rItemSet, rPropInfo );
807 : }
808 8 : return 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( SfxItemState::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 = true;
828 0 : if( GPOS_NONE != pBrushItem->GetGraphicPos() )
829 0 : bBodyBackgroundSet = 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( SfxItemState::SET==rItemSet.GetItemState(RES_CHRATR_COLOR,false) )
842 0 : bBodyTextSet = true;
843 : SetTxtCollAttrs(
844 : GetTxtCollFromPool( RES_POOLCOLL_STANDARD ),
845 0 : rItemSet, rPropInfo, this );
846 :
847 0 : return 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 false;
875 : }
876 : }
877 :
878 : // Jetzt werden die Selektoren verarbeitet, die zu einer Absatz-Vorlage
879 : // gehoehren
880 12 : sal_uInt16 nPoolCollId = 0;
881 12 : 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 12 : 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 12 : nPoolCollId = RES_POOLCOLL_TEXT;
918 : }
919 12 : 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 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 false;
977 : }
978 0 : }
979 : }
980 0 : break;
981 :
982 : default:
983 : ;
984 : }
985 :
986 12 : if( nPoolCollId )
987 : {
988 24 : 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 12 : SwTxtFmtColl *pColl = GetTxtFmtColl( nPoolCollId, aEmptyOUStr );
998 12 : SwTxtFmtColl* pParentColl = 0;
999 12 : 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 12 : if( !pNext )
1010 : {
1011 : // nur die Attribute an der Vorlage setzen
1012 : const SfxPoolItem *pItem;
1013 12 : const SvxBoxItem *pBoxItem = 0;
1014 12 : if( SfxItemState::SET ==
1015 12 : pColl->GetAttrSet().GetItemState(RES_BOX,true,&pItem) )
1016 0 : pBoxItem = (const SvxBoxItem *)pItem;
1017 12 : rPropInfo.SetBoxItem( rItemSet, MIN_BORDER_DIST, pBoxItem );
1018 12 : if( CSS1_SCRIPT_ALL == nScript && !pParentColl )
1019 : {
1020 6 : SetTxtCollAttrs( pColl, rItemSet, rPropInfo, this );
1021 : }
1022 : else
1023 : {
1024 6 : SfxItemSet aScriptItemSet( rItemSet );
1025 : RemoveScriptItems( aScriptItemSet, nScript,
1026 6 : pParentColl ? &pParentColl->GetAttrSet() : 0 );
1027 6 : 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 12 : return false;
1083 : }
1084 :
1085 0 : return 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 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 false;
1123 : }
1124 :
1125 20 : return 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 4 : const FontList *SwCSS1Parser::GetFontList() const
1134 : {
1135 4 : const FontList *pFList = 0;
1136 4 : SwDocShell *pDocSh = pDoc->GetDocShell();
1137 4 : if( pDocSh )
1138 : {
1139 : const SvxFontListItem *pFListItem =
1140 4 : (const SvxFontListItem *)pDocSh->GetItem(SID_ATTR_CHAR_FONTLIST);
1141 4 : if( pFListItem )
1142 4 : pFList = pFListItem->GetFontList();
1143 : }
1144 :
1145 4 : 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, 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 1772 : SwTxtFmtColl *SwCSS1Parser::GetTxtCollFromPool( sal_uInt16 nPoolId ) const
1228 : {
1229 1772 : sal_uInt16 nOldArrLen = pDoc->GetTxtFmtColls()->size();
1230 :
1231 1772 : SwTxtFmtColl *pColl = pDoc->getIDocumentStylePoolAccess().GetTxtCollFromPool( nPoolId, false );
1232 :
1233 1772 : if( bIsNewDoc )
1234 : {
1235 1772 : sal_uInt16 nArrLen = pDoc->GetTxtFmtColls()->size();
1236 1772 : for( sal_uInt16 i=nOldArrLen; i<nArrLen; i++ )
1237 0 : lcl_swcss1_setEncoding( *(*pDoc->GetTxtFmtColls())[i],
1238 0 : GetDfltEncoding() );
1239 : }
1240 :
1241 1772 : return pColl;
1242 : }
1243 :
1244 10 : SwCharFmt *SwCSS1Parser::GetCharFmtFromPool( sal_uInt16 nPoolId ) const
1245 : {
1246 10 : sal_uInt16 nOldArrLen = pDoc->GetCharFmts()->size();
1247 :
1248 10 : SwCharFmt *pCharFmt = pDoc->getIDocumentStylePoolAccess().GetCharFmtFromPool( nPoolId );
1249 :
1250 10 : if( bIsNewDoc )
1251 : {
1252 10 : sal_uInt16 nArrLen = pDoc->GetCharFmts()->size();
1253 :
1254 12 : for( sal_uInt16 i=nOldArrLen; i<nArrLen; i++ )
1255 2 : lcl_swcss1_setEncoding( *(*pDoc->GetCharFmts())[i],
1256 4 : GetDfltEncoding() );
1257 : }
1258 :
1259 10 : return pCharFmt;
1260 : }
1261 :
1262 234 : SwTxtFmtColl *SwCSS1Parser::GetTxtFmtColl( sal_uInt16 nTxtColl,
1263 : const OUString& rClass )
1264 : {
1265 234 : SwTxtFmtColl* pColl = 0;
1266 :
1267 234 : OUString aClass( rClass );
1268 234 : GetScriptFromClass( aClass, false );
1269 238 : if( RES_POOLCOLL_TEXT == nTxtColl && aClass.getLength() >= 9 &&
1270 8 : ('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 234 : if( USER_FMT & nTxtColl ) // eine vom Reader angelegte
1285 : {
1286 : OSL_ENSURE( false, "Wo kommt die Benutzer-Vorlage her?" );
1287 0 : pColl = GetTxtCollFromPool( RES_POOLCOLL_STANDARD );
1288 : }
1289 : else
1290 : {
1291 234 : pColl = GetTxtCollFromPool( nTxtColl );
1292 : }
1293 :
1294 : OSL_ENSURE( pColl, "Keine Absatz-Vorlage???" );
1295 234 : if( !aClass.isEmpty() )
1296 : {
1297 8 : OUString aTmp( pColl->GetName() );
1298 8 : AddClassName( aTmp, aClass );
1299 8 : SwTxtFmtColl* pClassColl = pDoc->FindTxtFmtCollByName( aTmp );
1300 :
1301 8 : if( !pClassColl &&
1302 8 : (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 8 : if( pClassColl )
1316 : {
1317 0 : pColl = pClassColl;
1318 : }
1319 : else
1320 : {
1321 8 : const SvxCSS1MapEntry *pClass = GetClass( aClass );
1322 8 : 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 : 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 8 : }
1335 :
1336 : }
1337 :
1338 234 : if( pColl )
1339 234 : lcl_swcss1_setEncoding( *pColl, GetDfltEncoding() );
1340 :
1341 234 : return pColl;
1342 : }
1343 :
1344 2 : SwPageDesc *SwCSS1Parser::GetMasterPageDesc()
1345 : {
1346 2 : return pDoc->getIDocumentStylePoolAccess().GetPageDescFromPool( RES_POOLPAGE_HTML, false );
1347 : }
1348 :
1349 60 : static SwPageDesc *FindPageDesc(SwDoc *pDoc, sal_uInt16 nPoolId)
1350 : {
1351 60 : sal_uInt16 nPageDescs = pDoc->GetPageDescCnt();
1352 : sal_uInt16 nPage;
1353 192 : for (nPage=0; nPage < nPageDescs &&
1354 132 : pDoc->GetPageDesc(nPage).GetPoolFmtId() != nPoolId; ++nPage)
1355 : ;
1356 :
1357 60 : return nPage < nPageDescs ? &pDoc->GetPageDesc(nPage) : 0;
1358 : }
1359 :
1360 70 : const SwPageDesc *SwCSS1Parser::GetPageDesc( sal_uInt16 nPoolId, bool bCreate )
1361 : {
1362 70 : if( RES_POOLPAGE_HTML == nPoolId )
1363 10 : return pDoc->getIDocumentStylePoolAccess().GetPageDescFromPool( RES_POOLPAGE_HTML, false );
1364 :
1365 60 : const SwPageDesc *pPageDesc = FindPageDesc(pDoc, nPoolId);
1366 60 : 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);
1373 0 : if( !pMasterPageDesc )
1374 0 : pMasterPageDesc = pDoc->getIDocumentStylePoolAccess().GetPageDescFromPool( RES_POOLPAGE_HTML, false );
1375 :
1376 : // Die neue Seitenvorlage entsteht aus dem Master durch kopieren.
1377 : SwPageDesc *pNewPageDesc = pDoc->
1378 0 : getIDocumentStylePoolAccess().GetPageDescFromPool( nPoolId, false );
1379 :
1380 : // dazu brauchen wir auch die Nummer der neuen Vorlage
1381 : OSL_ENSURE(pNewPageDesc == FindPageDesc(pDoc, nPoolId), "Seitenvorlage nicht gefunden");
1382 :
1383 0 : pDoc->CopyPageDesc( *pMasterPageDesc, *pNewPageDesc, false );
1384 :
1385 : // Die Vorlagen an ihren neuen Zweck anpassen.
1386 0 : const SwPageDesc *pFollow = 0;
1387 0 : bool bSetFollowFollow = false;
1388 0 : switch( nPoolId )
1389 : {
1390 : case RES_POOLPAGE_FIRST:
1391 : // Wenn es schon eine linke Seite gibt, dann ist das die
1392 : // Folge-Vorlage, sonst ist es die HTML-Vorlage.
1393 0 : pFollow = GetLeftPageDesc();
1394 0 : if( !pFollow )
1395 0 : pFollow = pMasterPageDesc;
1396 0 : break;
1397 :
1398 : case RES_POOLPAGE_RIGHT:
1399 : // Wenn die linke Vorlage schon angelegt ist, passiert hier gar
1400 : // nichts. Sonst wird die linke Vorlage angelegt und sorgt auch
1401 : // fuer die richtige Verkettung mit der rechten Voralge.
1402 0 : GetLeftPageDesc( true );
1403 0 : break;
1404 :
1405 : case RES_POOLPAGE_LEFT:
1406 : // Die rechte Vorlage wird angelegt, wenn sie noch nicht existiert.
1407 : // Es findet aber keine Verkettung statt.
1408 : // Wenn schon eine erste Seitenvorlage existiert, wird die linke
1409 : // Vorlage die Folge-Vorlage der ersten Seite.
1410 0 : pFollow = GetRightPageDesc( true );
1411 0 : bSetFollowFollow = true;
1412 : {
1413 0 : const SwPageDesc *pFirstPageDesc = GetFirstPageDesc();
1414 0 : if( pFirstPageDesc )
1415 : {
1416 0 : SwPageDesc aNewFirstPageDesc( *pFirstPageDesc );
1417 0 : aNewFirstPageDesc.SetFollow( pNewPageDesc );
1418 0 : ChgPageDesc( pFirstPageDesc, aNewFirstPageDesc );
1419 : }
1420 : }
1421 0 : break;
1422 : }
1423 :
1424 0 : if( pFollow )
1425 : {
1426 0 : SwPageDesc aNewPageDesc( *pNewPageDesc );
1427 0 : aNewPageDesc.SetFollow( pFollow );
1428 0 : ChgPageDesc( pNewPageDesc, aNewPageDesc );
1429 :
1430 0 : if( bSetFollowFollow )
1431 : {
1432 0 : SwPageDesc aNewFollowPageDesc( *pFollow );
1433 0 : aNewFollowPageDesc.SetFollow( pNewPageDesc );
1434 0 : ChgPageDesc( pFollow, aNewFollowPageDesc );
1435 0 : }
1436 : }
1437 0 : pPageDesc = pNewPageDesc;
1438 : }
1439 :
1440 60 : return pPageDesc;
1441 : }
1442 :
1443 576 : bool SwCSS1Parser::MayBePositioned( const SvxCSS1PropertyInfo& rPropInfo,
1444 : bool bAutoWidth )
1445 : {
1446 : // abs-pos
1447 : // left/top none auto twip perc
1448 :
1449 : // none Z Z - -
1450 : // auto Z Z - -
1451 : // twip Z Z S/R -
1452 : // perc - - - -
1453 :
1454 : // - das Tag wird absolut positioniert und left/top sind beide
1455 : // gegeben und enthalten auch keine %-Angabe, oder
1456 : // - das Tag soll fliessen, und
1457 : // - es wurde eine Breite angegeben (in beiden Faellen noetig)
1458 582 : return ( ( SVX_CSS1_POS_ABSOLUTE == rPropInfo.ePosition &&
1459 12 : SVX_CSS1_LTYPE_PERCENTAGE != rPropInfo.eLeftType &&
1460 12 : SVX_CSS1_LTYPE_PERCENTAGE != rPropInfo.eTopType &&
1461 6 : (SVX_CSS1_LTYPE_TWIP == rPropInfo.eLeftType ||
1462 570 : SVX_CSS1_LTYPE_TWIP != rPropInfo.eTopType) ) ||
1463 1156 : ( SVX_ADJUST_END != rPropInfo.eFloat ) ) &&
1464 4 : ( bAutoWidth ||
1465 6 : SVX_CSS1_LTYPE_TWIP == rPropInfo.eWidthType ||
1466 578 : SVX_CSS1_LTYPE_PERCENTAGE == rPropInfo.eWidthType );
1467 : }
1468 :
1469 8 : void SwCSS1Parser::AddClassName( OUString& rFmtName, const OUString& rClass )
1470 : {
1471 : OSL_ENSURE( !rClass.isEmpty(), "Style-Klasse ohne Laenge?" );
1472 :
1473 8 : rFmtName += "." + rClass;
1474 8 : }
1475 :
1476 0 : void SwCSS1Parser::FillDropCap( SwFmtDrop& rDrop,
1477 : SfxItemSet& rItemSet,
1478 : const OUString *pName )
1479 : {
1480 : // die Anzahl der Zeilen entspricht in etwa einer %-Angabe
1481 : // fuer die Hoehe (was passiert mit absoluten Hoehen???)
1482 0 : sal_uInt8 nLines = rDrop.GetLines();
1483 : const SfxPoolItem *pItem;
1484 0 : if( SfxItemState::SET == rItemSet.GetItemState( RES_CHRATR_FONTSIZE, false, &pItem ) )
1485 : {
1486 0 : sal_uInt16 nProp = ((const SvxFontHeightItem *)pItem)->GetProp();
1487 0 : nLines = (sal_uInt8)((nProp + 50) / 100);
1488 0 : if( nLines < 1 )
1489 0 : nLines = 1;
1490 0 : else if( nLines > MAX_DROPCAP_LINES )
1491 0 : nLines = MAX_DROPCAP_LINES;
1492 :
1493 : // Nur wenn nLines>1 ist, wird das Attribut auch gesetzt. Dann
1494 : // brauchen wir die Font-Hoehe aber auch nicht in der Zeichen-Vorlage.
1495 0 : if( nLines > 1 )
1496 : {
1497 0 : rItemSet.ClearItem( RES_CHRATR_FONTSIZE );
1498 0 : rItemSet.ClearItem( RES_CHRATR_CJK_FONTSIZE );
1499 0 : rItemSet.ClearItem( RES_CHRATR_CTL_FONTSIZE );
1500 : }
1501 : }
1502 :
1503 : // Bei harter Attributierung (pName==0) koennen wir aufhoehren, wenn
1504 : // das Initial nur ueber eine Zeile geht.
1505 0 : if( nLines<=1 )
1506 0 : return;
1507 :
1508 0 : rDrop.GetLines() = nLines;
1509 :
1510 : // ein rechter Rand wird der Abstand zum Text!
1511 0 : if( SfxItemState::SET == rItemSet.GetItemState( RES_LR_SPACE, false, &pItem ) )
1512 : {
1513 0 : rDrop.GetDistance() = static_cast< sal_uInt16 >(
1514 0 : ((const SvxLRSpaceItem *)pItem)->GetRight() );
1515 0 : rItemSet.ClearItem( RES_LR_SPACE );
1516 : }
1517 :
1518 : // Fuer alle anderen Attribute eine Zeichen-Vorlage anlegen
1519 0 : if( rItemSet.Count() )
1520 : {
1521 0 : SwCharFmt *pCFmt = 0;
1522 0 : OUString aName;
1523 0 : if( pName )
1524 : {
1525 0 : aName = *pName;
1526 0 : AddFirstLetterExt( aName );
1527 0 : pCFmt = pDoc->FindCharFmtByName( aName );
1528 : }
1529 : else
1530 : {
1531 0 : do
1532 : {
1533 0 : aName = "first-letter " + OUString::number( (sal_Int32)(++nDropCapCnt) );
1534 : }
1535 0 : while( pDoc->FindCharFmtByName(aName) );
1536 : }
1537 :
1538 0 : if( !pCFmt )
1539 : {
1540 0 : pCFmt = pDoc->MakeCharFmt( aName, pDoc->GetDfltCharFmt() );
1541 0 : pCFmt->SetAuto( false );
1542 : }
1543 0 : SetCharFmtAttrs( pCFmt, rItemSet );
1544 :
1545 : // Die Zeichenvorlage braucht nur im Attribut gesetzt werden, wenn
1546 : // auch das Attribut gesetzt wird.
1547 0 : if( nLines > 1 )
1548 0 : rDrop.SetCharFmt( pCFmt );
1549 : }
1550 : }
1551 :
1552 : // CSS1-sezifisches des SwHTMLParsers
1553 :
1554 1556 : _HTMLAttr **SwHTMLParser::GetAttrTabEntry( sal_uInt16 nWhich )
1555 : {
1556 : // den zu dem Item gehoehrenden Tabellen-Eintrag ermitteln ...
1557 1556 : _HTMLAttr **ppAttr = 0;
1558 1556 : switch( nWhich )
1559 : {
1560 : case RES_CHRATR_BLINK:
1561 0 : ppAttr = &aAttrTab.pBlink;
1562 0 : break;
1563 : case RES_CHRATR_CASEMAP:
1564 12 : ppAttr = &aAttrTab.pCaseMap;
1565 12 : break;
1566 : case RES_CHRATR_COLOR:
1567 0 : ppAttr = &aAttrTab.pFontColor;
1568 0 : break;
1569 : case RES_CHRATR_CROSSEDOUT:
1570 0 : ppAttr = &aAttrTab.pStrike;
1571 0 : break;
1572 : case RES_CHRATR_ESCAPEMENT:
1573 0 : ppAttr = &aAttrTab.pEscapement;
1574 0 : break;
1575 : case RES_CHRATR_FONT:
1576 2 : ppAttr = &aAttrTab.pFont;
1577 2 : break;
1578 : case RES_CHRATR_CJK_FONT:
1579 2 : ppAttr = &aAttrTab.pFontCJK;
1580 2 : break;
1581 : case RES_CHRATR_CTL_FONT:
1582 2 : ppAttr = &aAttrTab.pFontCTL;
1583 2 : break;
1584 : case RES_CHRATR_FONTSIZE:
1585 0 : ppAttr = &aAttrTab.pFontHeight;
1586 0 : break;
1587 : case RES_CHRATR_CJK_FONTSIZE:
1588 0 : ppAttr = &aAttrTab.pFontHeightCJK;
1589 0 : break;
1590 : case RES_CHRATR_CTL_FONTSIZE:
1591 0 : ppAttr = &aAttrTab.pFontHeightCTL;
1592 0 : break;
1593 : case RES_CHRATR_KERNING:
1594 0 : ppAttr = &aAttrTab.pKerning;
1595 0 : break;
1596 : case RES_CHRATR_POSTURE:
1597 0 : ppAttr = &aAttrTab.pItalic;
1598 0 : break;
1599 : case RES_CHRATR_CJK_POSTURE:
1600 0 : ppAttr = &aAttrTab.pItalicCJK;
1601 0 : break;
1602 : case RES_CHRATR_CTL_POSTURE:
1603 0 : ppAttr = &aAttrTab.pItalicCTL;
1604 0 : break;
1605 : case RES_CHRATR_UNDERLINE:
1606 0 : ppAttr = &aAttrTab.pUnderline;
1607 0 : break;
1608 : case RES_CHRATR_WEIGHT:
1609 0 : ppAttr = &aAttrTab.pBold;
1610 0 : break;
1611 : case RES_CHRATR_CJK_WEIGHT:
1612 0 : ppAttr = &aAttrTab.pBoldCJK;
1613 0 : break;
1614 : case RES_CHRATR_CTL_WEIGHT:
1615 0 : ppAttr = &aAttrTab.pBoldCTL;
1616 0 : break;
1617 : case RES_CHRATR_BACKGROUND:
1618 0 : ppAttr = &aAttrTab.pCharBrush;
1619 0 : break;
1620 : case RES_CHRATR_BOX:
1621 0 : ppAttr = &aAttrTab.pCharBox;
1622 0 : break;
1623 :
1624 : case RES_PARATR_LINESPACING:
1625 2 : ppAttr = &aAttrTab.pLineSpacing;
1626 2 : break;
1627 : case RES_PARATR_ADJUST:
1628 0 : ppAttr = &aAttrTab.pAdjust;
1629 0 : break;
1630 :
1631 : case RES_LR_SPACE:
1632 0 : ppAttr = &aAttrTab.pLRSpace;
1633 0 : break;
1634 : case RES_UL_SPACE:
1635 0 : ppAttr = &aAttrTab.pULSpace;
1636 0 : break;
1637 : case RES_BOX:
1638 0 : ppAttr = &aAttrTab.pBox;
1639 0 : break;
1640 : case RES_BACKGROUND:
1641 0 : ppAttr = &aAttrTab.pBrush;
1642 0 : break;
1643 : case RES_BREAK:
1644 0 : ppAttr = &aAttrTab.pBreak;
1645 0 : break;
1646 : case RES_PAGEDESC:
1647 0 : ppAttr = &aAttrTab.pPageDesc;
1648 0 : break;
1649 : case RES_PARATR_SPLIT:
1650 0 : ppAttr = &aAttrTab.pSplit;
1651 0 : break;
1652 : case RES_PARATR_WIDOWS:
1653 0 : ppAttr = &aAttrTab.pWidows;
1654 0 : break;
1655 : case RES_PARATR_ORPHANS:
1656 0 : ppAttr = &aAttrTab.pOrphans;
1657 0 : break;
1658 : case RES_KEEP:
1659 0 : ppAttr = &aAttrTab.pKeep;
1660 0 : break;
1661 :
1662 : case RES_CHRATR_LANGUAGE:
1663 512 : ppAttr = &aAttrTab.pLanguage;
1664 512 : break;
1665 : case RES_CHRATR_CJK_LANGUAGE:
1666 512 : ppAttr = &aAttrTab.pLanguageCJK;
1667 512 : break;
1668 : case RES_CHRATR_CTL_LANGUAGE:
1669 512 : ppAttr = &aAttrTab.pLanguageCTL;
1670 512 : break;
1671 :
1672 : case RES_FRAMEDIR:
1673 0 : ppAttr = &aAttrTab.pDirection;
1674 0 : break;
1675 : }
1676 :
1677 1556 : return ppAttr;
1678 : }
1679 :
1680 12 : void SwHTMLParser::NewStyle()
1681 : {
1682 12 : OUString sType;
1683 :
1684 12 : const HTMLOptions& rOptions2 = GetOptions();
1685 32 : for (size_t i = rOptions2.size(); i; )
1686 : {
1687 8 : const HTMLOption& rOption = rOptions2[--i];
1688 8 : if( HTML_O_TYPE == rOption.GetToken() )
1689 8 : sType = rOption.GetString();
1690 : }
1691 :
1692 28 : bIgnoreRawData = sType.getLength() &&
1693 28 : !sType.getToken(0,';').equalsAscii(sCSS_mimetype);
1694 12 : }
1695 :
1696 12 : void SwHTMLParser::EndStyle()
1697 : {
1698 12 : bIgnoreRawData = false;
1699 :
1700 12 : if( !aStyleSource.isEmpty() )
1701 : {
1702 12 : pCSS1Parser->ParseStyleSheet( aStyleSource );
1703 12 : aStyleSource = "";
1704 : }
1705 12 : }
1706 :
1707 0 : bool SwHTMLParser::FileDownload( const OUString& rURL,
1708 : OUString& rStr )
1709 : {
1710 : // View wegschmeissen (wegen Reschedule)
1711 0 : SwViewShell *pOldVSh = CallEndAction();
1712 :
1713 : // Ein Medium anlegen
1714 0 : SfxMedium aDLMedium( rURL, STREAM_READ | STREAM_SHARE_DENYWRITE );
1715 :
1716 0 : SvStream* pStream = aDLMedium.GetInStream();
1717 0 : if( pStream )
1718 : {
1719 0 : SvMemoryStream aStream;
1720 0 : aStream.WriteStream( *pStream );
1721 :
1722 0 : aStream.Seek( STREAM_SEEK_TO_END );
1723 0 : rStr = OUString((const sal_Char *)aStream.GetData(), aStream.Tell(),
1724 0 : GetSrcEncoding());
1725 : }
1726 :
1727 : // wurde abgebrochen?
1728 0 : if( ( pDoc->GetDocShell() && pDoc->GetDocShell()->IsAbortingImport() )
1729 0 : || 1 == pDoc->getReferenceCount() )
1730 : {
1731 : // wurde der Import vom SFX abgebrochen?
1732 0 : eState = SVPAR_ERROR;
1733 0 : pStream = 0;
1734 : }
1735 :
1736 : // recreate View
1737 0 : SwViewShell *const pVSh = CallStartAction( pOldVSh );
1738 : OSL_ENSURE( pOldVSh == pVSh, "FileDownload: SwViewShell changed on us" );
1739 : (void) pVSh;
1740 :
1741 0 : return pStream!=0;
1742 : }
1743 :
1744 0 : void SwHTMLParser::InsertLink()
1745 : {
1746 0 : bool bFinishDownload = false;
1747 0 : if( pPendStack )
1748 : {
1749 : OSL_ENSURE( ShouldFinishFileDownload(),
1750 : "Pending-Stack ohne File-Download?" );
1751 :
1752 0 : SwPendingStack* pTmp = pPendStack->pNext;
1753 0 : delete pPendStack;
1754 0 : pPendStack = pTmp;
1755 : OSL_ENSURE( !pPendStack, "Wo kommt der Pending-Stack her?" );
1756 :
1757 0 : bFinishDownload = true;
1758 : }
1759 : else
1760 : {
1761 0 : OUString sRel, sHRef, sType;
1762 :
1763 0 : const HTMLOptions& rOptions2 = GetOptions();
1764 0 : for (size_t i = rOptions2.size(); i; )
1765 : {
1766 0 : const HTMLOption& rOption = rOptions2[--i];
1767 0 : switch( rOption.GetToken() )
1768 : {
1769 : case HTML_O_REL:
1770 0 : sRel = rOption.GetString();
1771 0 : break;
1772 : case HTML_O_HREF:
1773 0 : sHRef = URIHelper::SmartRel2Abs( INetURLObject( sBaseURL ), rOption.GetString(), Link(), false );
1774 0 : break;
1775 : case HTML_O_TYPE:
1776 0 : sType = rOption.GetString();
1777 0 : break;
1778 : }
1779 : }
1780 :
1781 0 : if( !sHRef.isEmpty() && sRel.equalsIgnoreAsciiCase( "STYLESHEET" ) &&
1782 0 : ( sType.isEmpty() ||
1783 0 : sType.getToken(0,';').equalsAscii(sCSS_mimetype) ) )
1784 : {
1785 0 : if( GetMedium() )
1786 : {
1787 : // Download des Style-Source starten
1788 0 : StartFileDownload(sHRef);
1789 0 : if( IsParserWorking() )
1790 : {
1791 : // Der Style wurde synchron geladen und wir koennen
1792 : // es direkt aufrufen.
1793 0 : bFinishDownload = true;
1794 : }
1795 : else
1796 : {
1797 : // Der Style wird asynchron geladen und ist erst beim
1798 : // naechsten Continue-Aufruf da. Wir muessen deshalb einen
1799 : // Pending-Stack anlegen, damit wir hierher zurueckkehren
1800 0 : pPendStack = new SwPendingStack( HTML_LINK, pPendStack );
1801 : }
1802 : }
1803 : else
1804 : {
1805 : // File synchron holen
1806 0 : OUString sSource;
1807 0 : if( FileDownload( sHRef, sSource ) )
1808 0 : pCSS1Parser->ParseStyleSheet( sSource );
1809 : }
1810 0 : }
1811 : }
1812 :
1813 0 : if( bFinishDownload )
1814 : {
1815 0 : OUString sSource;
1816 0 : if( FinishFileDownload( sSource ) && !sSource.isEmpty() )
1817 0 : pCSS1Parser->ParseStyleSheet( sSource );
1818 : }
1819 0 : }
1820 :
1821 12 : bool SwCSS1Parser::ParseStyleSheet( const OUString& rIn )
1822 : {
1823 12 : if( !SvxCSS1Parser::ParseStyleSheet( rIn ) )
1824 0 : return false;
1825 :
1826 : SwPageDesc *pMasterPageDesc =
1827 12 : pDoc->getIDocumentStylePoolAccess().GetPageDescFromPool( RES_POOLPAGE_HTML, false );
1828 :
1829 12 : SvxCSS1MapEntry *pPageEntry = GetPage( aEmptyOUStr, false );
1830 12 : if( pPageEntry )
1831 : {
1832 : // @page (wirkt auf alle Seiten, die es schon gibt
1833 :
1834 10 : SetPageDescAttrs( pMasterPageDesc, pPageEntry->GetItemSet(),
1835 20 : pPageEntry->GetPropertyInfo() );
1836 :
1837 : // Fuer alle anderen Seiten-Vorlagen, die es schon gibt,
1838 : // muessen die Attribute auch noch gesetzt werden
1839 :
1840 10 : SetPageDescAttrs( GetFirstPageDesc(), pPageEntry->GetItemSet(),
1841 20 : pPageEntry->GetPropertyInfo() );
1842 10 : SetPageDescAttrs( GetLeftPageDesc(), pPageEntry->GetItemSet(),
1843 20 : pPageEntry->GetPropertyInfo() );
1844 10 : SetPageDescAttrs( GetRightPageDesc(), pPageEntry->GetItemSet(),
1845 20 : pPageEntry->GetPropertyInfo() );
1846 :
1847 : }
1848 :
1849 12 : pPageEntry = GetPage( "first", true );
1850 12 : if( pPageEntry )
1851 : {
1852 0 : SetPageDescAttrs( GetFirstPageDesc(true), pPageEntry->GetItemSet(),
1853 0 : pPageEntry->GetPropertyInfo() );
1854 0 : bSetFirstPageDesc = true;
1855 : }
1856 :
1857 12 : pPageEntry = GetPage( "right", true );
1858 12 : if( pPageEntry )
1859 : {
1860 0 : SetPageDescAttrs( GetRightPageDesc(true), pPageEntry->GetItemSet(),
1861 0 : pPageEntry->GetPropertyInfo() );
1862 0 : bSetRightPageDesc = true;
1863 : }
1864 :
1865 12 : pPageEntry = GetPage( "left", true );
1866 12 : if( pPageEntry )
1867 0 : SetPageDescAttrs( GetLeftPageDesc(true), pPageEntry->GetItemSet(),
1868 0 : pPageEntry->GetPropertyInfo() );
1869 :
1870 12 : return true;
1871 : }
1872 :
1873 1106 : bool SwHTMLParser::ParseStyleOptions( const OUString &rStyle,
1874 : const OUString &rId,
1875 : const OUString &rClass,
1876 : SfxItemSet &rItemSet,
1877 : SvxCSS1PropertyInfo &rPropInfo,
1878 : const OUString *pLang,
1879 : const OUString *pDir )
1880 : {
1881 1106 : bool bRet = false;
1882 :
1883 1106 : if( !rClass.isEmpty() )
1884 : {
1885 14 : OUString aClass( rClass );
1886 14 : SwCSS1Parser::GetScriptFromClass( aClass );
1887 14 : const SvxCSS1MapEntry *pClass = pCSS1Parser->GetClass( aClass );
1888 14 : if( pClass )
1889 : {
1890 0 : pCSS1Parser->MergeStyles( pClass->GetItemSet(),
1891 0 : pClass->GetPropertyInfo(),
1892 0 : rItemSet, rPropInfo, false );
1893 0 : bRet = true;
1894 14 : }
1895 : }
1896 :
1897 1106 : if( !rId.isEmpty() )
1898 : {
1899 28 : const SvxCSS1MapEntry *pId = pCSS1Parser->GetId( rId );
1900 28 : if( pId )
1901 0 : pCSS1Parser->MergeStyles( pId->GetItemSet(),
1902 0 : pId->GetPropertyInfo(),
1903 0 : rItemSet, rPropInfo, !rClass.isEmpty() );
1904 28 : rPropInfo.aId = rId;
1905 28 : bRet = true;
1906 : }
1907 :
1908 1106 : if( !rStyle.isEmpty() )
1909 : {
1910 568 : pCSS1Parser->ParseStyleOption( rStyle, rItemSet, rPropInfo );
1911 568 : bRet = true;
1912 : }
1913 :
1914 1106 : if( bRet )
1915 584 : rPropInfo.SetBoxItem( rItemSet, MIN_BORDER_DIST );
1916 :
1917 1106 : if( pLang && !pLang->isEmpty() )
1918 : {
1919 512 : LanguageType eLang = LanguageTag::convertToLanguageTypeWithFallback( *pLang );
1920 512 : if( LANGUAGE_DONTKNOW != eLang )
1921 : {
1922 512 : SvxLanguageItem aLang( eLang, RES_CHRATR_LANGUAGE );
1923 512 : rItemSet.Put( aLang );
1924 512 : aLang.SetWhich( RES_CHRATR_CJK_LANGUAGE );
1925 512 : rItemSet.Put( aLang );
1926 512 : aLang.SetWhich( RES_CHRATR_CTL_LANGUAGE );
1927 512 : rItemSet.Put( aLang );
1928 :
1929 512 : bRet = true;
1930 : }
1931 : }
1932 1106 : if( pDir && !pDir->isEmpty() )
1933 : {
1934 10 : OUString aValue( *pDir );
1935 10 : SvxFrameDirection eDir = FRMDIR_ENVIRONMENT;
1936 10 : if (aValue.equalsIgnoreAsciiCase("LTR"))
1937 10 : eDir = FRMDIR_HORI_LEFT_TOP;
1938 0 : else if (aValue.equalsIgnoreAsciiCase("RTL"))
1939 0 : eDir = FRMDIR_HORI_RIGHT_TOP;
1940 :
1941 10 : if( FRMDIR_ENVIRONMENT != eDir )
1942 : {
1943 10 : SvxFrameDirectionItem aDir( eDir, RES_FRAMEDIR );
1944 10 : rItemSet.Put( aDir );
1945 :
1946 10 : bRet = true;
1947 10 : }
1948 : }
1949 :
1950 1106 : return bRet;
1951 : }
1952 :
1953 2 : void SwHTMLParser::SetAnchorAndAdjustment( const SfxItemSet & /*rItemSet*/,
1954 : const SvxCSS1PropertyInfo &rPropInfo,
1955 : SfxItemSet &rFrmItemSet )
1956 : {
1957 2 : SwFmtAnchor aAnchor;
1958 :
1959 2 : sal_Int16 eHoriOri = text::HoriOrientation::NONE;
1960 2 : sal_Int16 eVertOri = text::VertOrientation::NONE;
1961 2 : sal_Int16 eHoriRel = text::RelOrientation::FRAME;
1962 2 : sal_Int16 eVertRel = text::RelOrientation::FRAME;
1963 2 : SwTwips nHoriPos = 0, nVertPos = 0;
1964 2 : SwSurround eSurround = SURROUND_THROUGHT;
1965 2 : if( SVX_CSS1_POS_ABSOLUTE == rPropInfo.ePosition )
1966 : {
1967 4 : if( SVX_CSS1_LTYPE_TWIP == rPropInfo.eLeftType &&
1968 2 : SVX_CSS1_LTYPE_TWIP == rPropInfo.eTopType )
1969 : {
1970 : // Absolut positionierte Objekte sind seitengebunden, wenn
1971 : // sie nicht schon in einem Rahmen stehen und sonst
1972 : // Rahmengebunden.
1973 : const SwStartNode *pFlySttNd =
1974 2 : pPam->GetPoint()->nNode.GetNode().FindFlyStartNode();
1975 2 : if( pFlySttNd )
1976 : {
1977 0 : aAnchor.SetType( FLY_AT_FLY );
1978 0 : SwPosition aPos( *pFlySttNd );
1979 0 : aAnchor.SetAnchor( &aPos );
1980 : }
1981 : else
1982 : {
1983 2 : aAnchor.SetType( FLY_AT_PAGE );
1984 2 : aAnchor.SetPageNum( 1 );
1985 : }
1986 2 : nHoriPos = rPropInfo.nLeft;
1987 2 : nVertPos = rPropInfo.nTop;
1988 : }
1989 : else
1990 : {
1991 0 : aAnchor.SetType( FLY_AT_PARA );
1992 0 : aAnchor.SetAnchor( pPam->GetPoint() );
1993 0 : eVertOri = text::VertOrientation::TOP;
1994 0 : eVertRel = text::RelOrientation::CHAR;
1995 0 : if( SVX_CSS1_LTYPE_TWIP == rPropInfo.eLeftType )
1996 : {
1997 0 : eHoriOri = text::HoriOrientation::NONE;
1998 0 : eHoriRel = text::RelOrientation::PAGE_FRAME;
1999 0 : nHoriPos = rPropInfo.nLeft;
2000 : }
2001 : else
2002 : {
2003 0 : eHoriOri = text::HoriOrientation::LEFT;
2004 0 : eHoriRel = text::RelOrientation::FRAME; // wird noch umgeschossen
2005 : }
2006 : }
2007 : }
2008 : else
2009 : {
2010 : // fliessende Objekte werden Absatzgebunden eingefuegt, wenn
2011 : // der Absatz noch leer ist und sonst auto-gebunden.
2012 : // Auto-gebundene Rahmen werden zunaechst an der Position davor
2013 : // eingefuegt und erst spaeter verschoben.
2014 0 : const sal_Int32 nCntnt = pPam->GetPoint()->nContent.GetIndex();
2015 0 : if( nCntnt )
2016 : {
2017 0 : aAnchor.SetType( FLY_AT_CHAR );
2018 0 : pPam->Move( fnMoveBackward );
2019 0 : eVertOri = text::VertOrientation::CHAR_BOTTOM;
2020 0 : eVertRel = text::RelOrientation::CHAR;
2021 : }
2022 : else
2023 : {
2024 0 : aAnchor.SetType( FLY_AT_PARA );
2025 0 : eVertOri = text::VertOrientation::TOP;
2026 0 : eVertRel = text::RelOrientation::PRINT_AREA;
2027 : }
2028 :
2029 0 : aAnchor.SetAnchor( pPam->GetPoint() );
2030 :
2031 0 : if( nCntnt )
2032 0 : pPam->Move( fnMoveForward );
2033 :
2034 0 : sal_uInt16 nLeftSpace = 0, nRightSpace = 0;
2035 0 : short nIndent = 0;
2036 0 : GetMarginsFromContextWithNumBul( nLeftSpace, nRightSpace, nIndent );
2037 :
2038 0 : if( SVX_ADJUST_RIGHT==rPropInfo.eFloat )
2039 : {
2040 0 : eHoriOri = text::HoriOrientation::RIGHT;
2041 0 : eHoriRel = nRightSpace ? text::RelOrientation::PRINT_AREA : text::RelOrientation::FRAME;
2042 0 : eSurround = SURROUND_LEFT;
2043 : }
2044 : else
2045 : {
2046 0 : eHoriOri = text::HoriOrientation::LEFT;
2047 0 : eHoriRel = nLeftSpace ? text::RelOrientation::PRINT_AREA : text::RelOrientation::FRAME;
2048 0 : eSurround = SURROUND_RIGHT;
2049 : }
2050 : }
2051 2 : rFrmItemSet.Put( aAnchor );
2052 :
2053 : // Absolut Positioniert mit Durchlauf
2054 2 : rFrmItemSet.Put( SwFmtHoriOrient( nHoriPos, eHoriOri, eHoriRel ) );
2055 2 : rFrmItemSet.Put( SwFmtVertOrient( nVertPos, eVertOri, eVertRel ) );
2056 2 : rFrmItemSet.Put( SwFmtSurround( eSurround ) );
2057 2 : }
2058 :
2059 2 : void SwHTMLParser::SetVarSize( SfxItemSet & /*rItemSet*/,
2060 : SvxCSS1PropertyInfo &rPropInfo,
2061 : SfxItemSet &rFrmItemSet,
2062 : SwTwips nDfltWidth, sal_uInt8 nDfltPrcWidth )
2063 : {
2064 2 : SwFrmSize eSize = ATT_MIN_SIZE;
2065 2 : SwTwips nWidth = nDfltWidth, nHeight = MINFLY;
2066 2 : sal_uInt8 nPrcWidth = nDfltPrcWidth, nPrcHeight = 0;
2067 2 : switch( rPropInfo.eWidthType )
2068 : {
2069 : case SVX_CSS1_LTYPE_PERCENTAGE:
2070 0 : nPrcWidth = rPropInfo.nWidth > 0 ? (sal_uInt8)rPropInfo.nWidth : 1;
2071 0 : nWidth = MINFLY;
2072 0 : break;
2073 : case SVX_CSS1_LTYPE_TWIP:
2074 2 : nWidth = rPropInfo.nWidth > MINFLY ? rPropInfo.nWidth : MINFLY;
2075 2 : nPrcWidth = 0;
2076 2 : break;
2077 : default:
2078 : ;
2079 : }
2080 2 : switch( rPropInfo.eHeightType )
2081 : {
2082 : case SVX_CSS1_LTYPE_PERCENTAGE:
2083 0 : nPrcHeight = rPropInfo.nHeight > 0 ? (sal_uInt8)rPropInfo.nHeight : 1;
2084 0 : break;
2085 : case SVX_CSS1_LTYPE_TWIP:
2086 : // Netscape und MS-IE interpretieren die Hoehe regelwiedrig
2087 : // als Mindest-Hoehe, also machwn wir das auch so.
2088 2 : nHeight = rPropInfo.nHeight > MINFLY ? rPropInfo.nHeight : MINFLY;
2089 2 : break;
2090 : default:
2091 : ;
2092 : }
2093 :
2094 2 : SwFmtFrmSize aFrmSize( eSize, nWidth, nHeight );
2095 2 : aFrmSize.SetWidthPercent( nPrcWidth );
2096 2 : aFrmSize.SetHeightPercent( nPrcHeight );
2097 2 : rFrmItemSet.Put( aFrmSize );
2098 2 : }
2099 :
2100 10 : void SwHTMLParser::SetFrmFmtAttrs( SfxItemSet &rItemSet,
2101 : SvxCSS1PropertyInfo & /*rPropInfo*/,
2102 : sal_uInt16 nFlags,
2103 : SfxItemSet &rFrmItemSet )
2104 : {
2105 : const SfxPoolItem *pItem;
2106 20 : if( (nFlags & HTML_FF_BOX) != 0 &&
2107 10 : SfxItemState::SET==rItemSet.GetItemState( RES_BOX, true, &pItem ) )
2108 : {
2109 0 : if( (nFlags & HTML_FF_PADDING) == 0 )
2110 : {
2111 0 : SvxBoxItem aBoxItem( *(const SvxBoxItem *)pItem );
2112 : // Alle 4 Seiten gleichzeitig auf 0 setzen
2113 0 : aBoxItem.SetDistance( 0 );
2114 0 : rFrmItemSet.Put( aBoxItem );
2115 : }
2116 : else
2117 : {
2118 0 : rFrmItemSet.Put( *pItem );
2119 : }
2120 0 : rItemSet.ClearItem( RES_BOX );
2121 : }
2122 :
2123 12 : if( (nFlags & HTML_FF_BACKGROUND) != 0 &&
2124 2 : SfxItemState::SET==rItemSet.GetItemState( RES_BACKGROUND, true, &pItem ) )
2125 : {
2126 0 : rFrmItemSet.Put( *pItem );
2127 0 : rItemSet.ClearItem( RES_BACKGROUND );
2128 : }
2129 :
2130 12 : if( (nFlags & HTML_FF_DIRECTION) != 0 &&
2131 2 : SfxItemState::SET==rItemSet.GetItemState( RES_FRAMEDIR, true, &pItem ) )
2132 : {
2133 0 : rFrmItemSet.Put( *pItem );
2134 0 : rItemSet.ClearItem( RES_FRAMEDIR );
2135 : }
2136 10 : }
2137 :
2138 1136 : _HTMLAttrContext *SwHTMLParser::PopContext( sal_uInt16 nToken, sal_uInt16 nLimit,
2139 : bool bRemove )
2140 : {
2141 1136 : sal_uInt16 nPos = aContexts.size();
2142 1136 : if( nPos <= nContextStMin )
2143 0 : return 0;
2144 :
2145 1136 : bool bFound = 0==nToken;
2146 1136 : if( nToken )
2147 : {
2148 : // Stack-Eintrag zu dem Token suchen
2149 1260 : while( nPos > nContextStMin )
2150 : {
2151 636 : sal_uInt16 nCntxtToken = aContexts[--nPos]->GetToken();
2152 636 : if( nCntxtToken == nToken )
2153 : {
2154 604 : bFound = true;
2155 604 : break;
2156 : }
2157 32 : else if( nCntxtToken == nLimit ) // 0 als Token kommt nicht vor
2158 : {
2159 0 : break;
2160 : }
2161 : }
2162 : }
2163 : else
2164 : {
2165 522 : nPos--;
2166 : }
2167 :
2168 1136 : _HTMLAttrContext *pCntxt = 0;
2169 1136 : if( bFound )
2170 : {
2171 1126 : pCntxt = aContexts[nPos];
2172 1126 : if( bRemove )
2173 1126 : aContexts.erase( aContexts.begin() + nPos );
2174 : }
2175 :
2176 1136 : return pCntxt;
2177 : }
2178 :
2179 4 : bool SwHTMLParser::GetMarginsFromContext( sal_uInt16& nLeft,
2180 : sal_uInt16& nRight,
2181 : short& nIndent,
2182 : bool bIgnoreTopContext ) const
2183 : {
2184 4 : sal_uInt16 nPos = aContexts.size();
2185 4 : if( bIgnoreTopContext )
2186 : {
2187 0 : if( !nPos )
2188 0 : return false;
2189 : else
2190 0 : nPos--;
2191 : }
2192 :
2193 8 : while( nPos > nContextStAttrMin )
2194 : {
2195 0 : const _HTMLAttrContext *pCntxt = aContexts[--nPos];
2196 0 : if( pCntxt->IsLRSpaceChanged() )
2197 : {
2198 0 : pCntxt->GetMargins( nLeft, nRight, nIndent );
2199 0 : return true;
2200 : }
2201 : }
2202 :
2203 4 : return false;
2204 : }
2205 :
2206 2 : bool SwHTMLParser::GetMarginsFromContextWithNumBul( sal_uInt16& nLeft,
2207 : sal_uInt16& nRight,
2208 : short& nIndent ) const
2209 : {
2210 2 : bool bRet = GetMarginsFromContext( nLeft, nRight, nIndent );
2211 2 : const SwHTMLNumRuleInfo& rInfo = ((SwHTMLParser*)this)->GetNumInfo();
2212 2 : if( rInfo.GetDepth() )
2213 : {
2214 0 : sal_uInt8 nLevel = (sal_uInt8)( (rInfo.GetDepth() <= MAXLEVEL ? rInfo.GetDepth()
2215 0 : : MAXLEVEL) - 1 );
2216 0 : const SwNumFmt& rNumFmt = rInfo.GetNumRule()->Get(nLevel);
2217 0 : nLeft = nLeft + rNumFmt.GetAbsLSpace();
2218 0 : nIndent = rNumFmt.GetFirstLineOffset();
2219 : }
2220 :
2221 2 : return bRet;
2222 : }
2223 :
2224 6 : void SwHTMLParser::GetULSpaceFromContext( sal_uInt16& nUpper,
2225 : sal_uInt16& nLower ) const
2226 : {
2227 6 : sal_uInt16 nDfltColl = 0;
2228 6 : OUString aDfltClass;
2229 :
2230 6 : sal_uInt16 nPos = aContexts.size();
2231 14 : while( nPos > nContextStAttrMin )
2232 : {
2233 2 : const _HTMLAttrContext *pCntxt = aContexts[--nPos];
2234 2 : if( pCntxt->IsULSpaceChanged() )
2235 : {
2236 0 : pCntxt->GetULSpace( nUpper, nLower );
2237 6 : return;
2238 : }
2239 2 : else if( !nDfltColl )
2240 : {
2241 2 : nDfltColl = pCntxt->GetDfltTxtFmtColl();
2242 2 : if( nDfltColl )
2243 2 : aDfltClass = pCntxt->GetClass();
2244 : }
2245 : }
2246 :
2247 6 : if( !nDfltColl )
2248 4 : nDfltColl = RES_POOLCOLL_TEXT;
2249 :
2250 : const SwTxtFmtColl *pColl =
2251 6 : pCSS1Parser->GetTxtFmtColl( nDfltColl, aDfltClass );
2252 6 : const SvxULSpaceItem& rULSpace = pColl->GetULSpace();
2253 6 : nUpper = rULSpace.GetUpper();
2254 6 : nLower = rULSpace.GetLower();
2255 : }
2256 :
2257 572 : void SwHTMLParser::EndContextAttrs( _HTMLAttrContext *pContext, bool bRemove )
2258 : {
2259 572 : _HTMLAttrs &rAttrs = pContext->GetAttrs();
2260 2224 : for( sal_uInt16 i=0; i<rAttrs.size(); i++ )
2261 : {
2262 1652 : _HTMLAttr *pAttr = rAttrs[i];
2263 :
2264 1652 : if( RES_PARATR_DROP==pAttr->GetItem().Which() )
2265 : {
2266 : // Fuer DropCaps noch die Anzahl der Zeichen anpassen. Wenn
2267 : // es am Ende 0 sind, wird das Attribut invalidiert und dann
2268 : // von _SetAttr gar nicht erst gesetzt.
2269 0 : sal_Int32 nChars = pPam->GetPoint()->nContent.GetIndex();
2270 0 : if( nChars < 1 )
2271 0 : pAttr->Invalidate();
2272 0 : else if( nChars > MAX_DROPCAP_CHARS )
2273 0 : nChars = MAX_DROPCAP_CHARS;
2274 0 : ((SwFmtDrop&)pAttr->GetItem()).GetChars() = (sal_uInt8)nChars;
2275 : }
2276 :
2277 1652 : EndAttr( pAttr );
2278 : }
2279 :
2280 572 : if( bRemove && !rAttrs.empty() )
2281 0 : rAttrs.clear();
2282 572 : }
2283 :
2284 0 : void SwHTMLParser::InsertParaAttrs( const SfxItemSet& rItemSet )
2285 : {
2286 0 : SfxItemIter aIter( rItemSet );
2287 :
2288 0 : const SfxPoolItem *pItem = aIter.FirstItem();
2289 0 : while( pItem )
2290 : {
2291 : // den zu dem Item gehoehrenden Tabellen-Eintrag ermitteln ...
2292 0 : sal_uInt16 nWhich = pItem->Which();
2293 0 : _HTMLAttr **ppAttr = GetAttrTabEntry( nWhich );
2294 :
2295 0 : if( ppAttr )
2296 : {
2297 0 : NewAttr( ppAttr, *pItem );
2298 0 : if( RES_PARATR_BEGIN > nWhich )
2299 0 : (*ppAttr)->SetLikePara();
2300 0 : aParaAttrs.push_back( *ppAttr );
2301 0 : EndAttr( *ppAttr, 0, false );
2302 : }
2303 :
2304 0 : pItem = aIter.NextItem();
2305 0 : }
2306 0 : }
2307 :
2308 476 : static void lcl_swcss1_setEncoding( SwFmt& rFmt, rtl_TextEncoding eEnc )
2309 : {
2310 476 : if( RTL_TEXTENCODING_DONTKNOW == eEnc )
2311 476 : return;
2312 :
2313 476 : const SfxItemSet& rItemSet = rFmt.GetAttrSet();
2314 : static const sal_uInt16 aWhichIds[3] = { RES_CHRATR_FONT, RES_CHRATR_CJK_FONT,
2315 : RES_CHRATR_CTL_FONT };
2316 : const SfxPoolItem *pItem;
2317 1904 : for( sal_uInt16 i=0; i<3; i++ )
2318 : {
2319 1428 : if( SfxItemState::SET == rItemSet.GetItemState( aWhichIds[i], false,&pItem ) )
2320 : {
2321 60 : const SvxFontItem& rFont = *(const SvxFontItem *)pItem;
2322 60 : if( RTL_TEXTENCODING_SYMBOL != rFont.GetCharSet() )
2323 : {
2324 60 : SvxFontItem aFont( rFont.GetFamily(), rFont.GetFamilyName(),
2325 60 : rFont.GetStyleName(), rFont.GetPitch(),
2326 120 : eEnc, aWhichIds[i]);
2327 60 : rFmt.SetFmtAttr( aFont );
2328 : }
2329 : }
2330 : }
2331 : }
2332 :
2333 22 : void SwCSS1Parser::SetDfltEncoding( rtl_TextEncoding eEnc )
2334 : {
2335 22 : if( eEnc != GetDfltEncoding() )
2336 : {
2337 22 : if( bIsNewDoc )
2338 : {
2339 : // Set new encoding as pool default
2340 : static const sal_uInt16 aWhichIds[3] = { RES_CHRATR_FONT, RES_CHRATR_CJK_FONT,
2341 : RES_CHRATR_CTL_FONT };
2342 : sal_uInt16 i;
2343 88 : for( i=0; i<3; i++ )
2344 : {
2345 : const SvxFontItem& rDfltFont =
2346 66 : (const SvxFontItem&)pDoc->GetDefault( aWhichIds[i]);
2347 : SvxFontItem aFont( rDfltFont.GetFamily(),
2348 66 : rDfltFont.GetFamilyName(),
2349 66 : rDfltFont.GetStyleName(),
2350 : rDfltFont.GetPitch(),
2351 132 : eEnc, aWhichIds[i] );
2352 66 : pDoc->SetDefault( aFont );
2353 66 : }
2354 :
2355 : // Change all paragraph styles that do specify a font.
2356 22 : sal_uInt16 nArrLen = pDoc->GetTxtFmtColls()->size();
2357 226 : for( i=1; i<nArrLen; i++ )
2358 204 : lcl_swcss1_setEncoding( *(*pDoc->GetTxtFmtColls())[i], eEnc );
2359 :
2360 : // Change all character styles that do specify a font.
2361 22 : nArrLen = pDoc->GetCharFmts()->size();
2362 58 : for( i=1; i<nArrLen; i++ )
2363 36 : lcl_swcss1_setEncoding( *(*pDoc->GetCharFmts())[i], eEnc );
2364 : }
2365 :
2366 22 : SvxCSS1Parser::SetDfltEncoding( eEnc );
2367 : }
2368 292 : }
2369 :
2370 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|