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