1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
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>
46 #include <charfmt.hxx>
48 #include <svx/svxids.hrc>
51 #include <IDocumentStylePoolAccess.hxx>
54 #include "poolfmt.hxx"
57 #include "pagedesc.hxx"
58 #include "css1kywd.hxx"
60 #include "htmlnum.hxx"
62 #include <numrule.hxx>
63 #include <css1atr.hxx>
65 using namespace ::com::sun::star
;
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
72 static void lcl_swcss1_setEncoding( SwFormat
& rFormat
, rtl_TextEncoding eEnc
);
74 // Implementierung des SwCSS1Parsers (eigentlich swcss1.cxx)
75 static struct SwCSS1ItemIds
77 sal_uInt16 nFormatBreak
;
78 sal_uInt16 nFormatPageDesc
;
79 sal_uInt16 nFormatKeep
;
82 nFormatBreak( RES_BREAK
),
83 nFormatPageDesc( RES_PAGEDESC
),
84 nFormatKeep( RES_KEEP
)
89 void SwCSS1Parser::ChgPageDesc( const SwPageDesc
*pPageDesc
,
90 const SwPageDesc
& rNewPageDesc
)
93 bool found
= pDoc
->ContainsPageDesc( pPageDesc
, &pos
);
94 OSL_ENSURE( found
, "Seitenvorlage nicht gefunden" );
96 pDoc
->ChgPageDesc( pos
, rNewPageDesc
);
99 SwCSS1Parser::SwCSS1Parser( SwDoc
*pD
, sal_uInt32 aFHeights
[7], const OUString
& rBaseURL
, bool bNewDoc
) :
100 SvxCSS1Parser( pD
->GetAttrPool(), rBaseURL
,
101 reinterpret_cast<sal_uInt16
*>(&aItemIds
), sizeof(aItemIds
) / sizeof(sal_uInt16
) ),
104 bIsNewDoc( bNewDoc
),
105 bBodyBGColorSet( false ),
106 bBodyBackgroundSet( false ),
107 bBodyTextSet( false ),
108 bBodyLinkSet( false ),
109 bBodyVLinkSet( false ),
110 bSetFirstPageDesc( false ),
111 bSetRightPageDesc( false ),
112 bTableHeaderTextCollSet( false ),
113 bTableTextCollSet( false ),
114 bLinkCharFormatsSet( false )
116 aFontHeights
[0] = aFHeights
[0];
117 aFontHeights
[1] = aFHeights
[1];
118 aFontHeights
[2] = aFHeights
[2];
119 aFontHeights
[3] = aFHeights
[3];
120 aFontHeights
[4] = aFHeights
[4];
121 aFontHeights
[5] = aFHeights
[5];
122 aFontHeights
[6] = aFHeights
[6];
125 SwCSS1Parser::~SwCSS1Parser()
130 bool SwCSS1Parser::SetFormatBreak( SfxItemSet
& rItemSet
,
131 const SvxCSS1PropertyInfo
& rPropInfo
)
133 SvxBreak eBreak
= SvxBreak::NONE
;
135 bool bSetKeep
= false, bSetBreak
= false, bSetPageDesc
= false;
136 const SwPageDesc
*pPageDesc
= nullptr;
137 switch( rPropInfo
.m_ePageBreakBefore
)
139 case SVX_CSS1_PBREAK_ALWAYS
:
140 eBreak
= SvxBreak::PageBefore
;
143 case SVX_CSS1_PBREAK_LEFT
:
144 pPageDesc
= GetLeftPageDesc( true );
147 case SVX_CSS1_PBREAK_RIGHT
:
148 pPageDesc
= GetRightPageDesc( true );
151 case SVX_CSS1_PBREAK_AUTO
:
152 bSetBreak
= bSetPageDesc
= true;
157 switch( rPropInfo
.m_ePageBreakAfter
)
159 case SVX_CSS1_PBREAK_ALWAYS
:
160 case SVX_CSS1_PBREAK_LEFT
:
161 case SVX_CSS1_PBREAK_RIGHT
:
162 // LEFT/RIGHT koennte man auch am Absatz davor setzen
163 eBreak
= SvxBreak::PageAfter
;
166 case SVX_CSS1_PBREAK_AUTO
:
167 bSetBreak
= bSetKeep
= bSetPageDesc
= true;
169 case SVX_CSS1_PBREAK_AVOID
:
170 bKeep
= bSetKeep
= true;
177 rItemSet
.Put( SvxFormatBreakItem( eBreak
, RES_BREAK
) );
179 rItemSet
.Put( SwFormatPageDesc( pPageDesc
) );
181 rItemSet
.Put( SvxFormatKeepItem( bKeep
, RES_KEEP
) );
186 static void SetCharFormatAttrs( SwCharFormat
*pCharFormat
, SfxItemSet
& rItemSet
)
188 const SfxPoolItem
*pItem
;
189 static const sal_uInt16 aWhichIds
[3] = { RES_CHRATR_FONTSIZE
,RES_CHRATR_CJK_FONTSIZE
,
190 RES_CHRATR_CTL_FONTSIZE
};
191 for(sal_uInt16 i
: aWhichIds
)
193 if( SfxItemState::SET
== rItemSet
.GetItemState( i
, false,
195 static_cast<const SvxFontHeightItem
*>(pItem
)->GetProp() != 100)
197 // %-Angaben beim FontHeight-Item werden nicht unterstuetzt
198 rItemSet
.ClearItem( i
);
202 pCharFormat
->SetFormatAttr( rItemSet
);
204 if( SfxItemState::SET
== rItemSet
.GetItemState( RES_BACKGROUND
, false, &pItem
) )
206 // Ein Brush-Item mit RES_BACKGROUND muss noch in eines mit
207 // RES_CHRATR_BACKGROUND gewandelt werden
209 SvxBrushItem
aBrushItem( *static_cast<const SvxBrushItem
*>(pItem
) );
210 aBrushItem
.SetWhich( RES_CHRATR_BACKGROUND
);
211 pCharFormat
->SetFormatAttr( aBrushItem
);
214 if( SfxItemState::SET
== rItemSet
.GetItemState( RES_BOX
, false, &pItem
) )
216 SvxBoxItem
aBoxItem( *static_cast<const SvxBoxItem
*>(pItem
) );
217 aBoxItem
.SetWhich( RES_CHRATR_BOX
);
218 pCharFormat
->SetFormatAttr( aBoxItem
);
222 void SwCSS1Parser::SetLinkCharFormats()
224 OSL_ENSURE( !bLinkCharFormatsSet
, "Aufruf von SetLinkCharFormats unnoetig" );
226 SvxCSS1MapEntry
*pStyleEntry
=
227 GetTag( OOO_STRING_SVTOOLS_HTML_anchor
);
228 SwCharFormat
*pUnvisited
= nullptr, *pVisited
= nullptr;
231 SfxItemSet
& rItemSet
= pStyleEntry
->GetItemSet();
232 bool bColorSet
= (SfxItemState::SET
==rItemSet
.GetItemState(RES_CHRATR_COLOR
,
234 pUnvisited
= GetCharFormatFromPool( RES_POOLCHR_INET_NORMAL
);
235 SetCharFormatAttrs( pUnvisited
, rItemSet
);
236 bBodyLinkSet
|= bColorSet
;
238 pVisited
= GetCharFormatFromPool( RES_POOLCHR_INET_VISIT
);
239 SetCharFormatAttrs( pVisited
, rItemSet
);
240 bBodyVLinkSet
|= bColorSet
;
243 OUString sTmp
= OOO_STRING_SVTOOLS_HTML_anchor
":link";
245 pStyleEntry
= GetTag( sTmp
);
248 SfxItemSet
& rItemSet
= pStyleEntry
->GetItemSet();
249 bool bColorSet
= (SfxItemState::SET
==rItemSet
.GetItemState(RES_CHRATR_COLOR
,
252 pUnvisited
= GetCharFormatFromPool( RES_POOLCHR_INET_NORMAL
);
253 SetCharFormatAttrs( pUnvisited
, rItemSet
);
254 bBodyLinkSet
|= bColorSet
;
257 sTmp
= OOO_STRING_SVTOOLS_HTML_anchor
":visited";
259 pStyleEntry
= GetTag( sTmp
);
262 SfxItemSet
& rItemSet
= pStyleEntry
->GetItemSet();
263 bool bColorSet
= (SfxItemState::SET
==rItemSet
.GetItemState(RES_CHRATR_COLOR
,
266 pVisited
= GetCharFormatFromPool( RES_POOLCHR_INET_VISIT
);
267 SetCharFormatAttrs( pVisited
, rItemSet
);
268 bBodyVLinkSet
|= bColorSet
;
271 bLinkCharFormatsSet
= true;
274 static void SetTextCollAttrs( SwTextFormatColl
*pColl
, SfxItemSet
& rItemSet
,
275 SvxCSS1PropertyInfo
& rPropInfo
,
276 SwCSS1Parser
*pCSS1Parser
)
278 const SfxItemSet
& rCollItemSet
= pColl
->GetAttrSet();
279 const SfxPoolItem
*pCollItem
, *pItem
;
281 // linker, rechter Rand und Erstzeilen-Einzug
282 if( (rPropInfo
.m_bLeftMargin
|| rPropInfo
.m_bRightMargin
||
283 rPropInfo
.m_bTextIndent
) &&
284 (!rPropInfo
.m_bLeftMargin
|| !rPropInfo
.m_bRightMargin
||
285 !rPropInfo
.m_bTextIndent
) &&
286 SfxItemState::SET
== rCollItemSet
.GetItemState(RES_LR_SPACE
,true,&pCollItem
) &&
287 SfxItemState::SET
== rItemSet
.GetItemState(RES_LR_SPACE
,false,&pItem
) )
289 const SvxLRSpaceItem
*pLRItem
= static_cast<const SvxLRSpaceItem
*>(pItem
);
291 SvxLRSpaceItem
aLRItem( *static_cast<const SvxLRSpaceItem
*>(pCollItem
) );
292 if( rPropInfo
.m_bLeftMargin
)
293 aLRItem
.SetTextLeft( pLRItem
->GetTextLeft() );
294 if( rPropInfo
.m_bRightMargin
)
295 aLRItem
.SetRight( pLRItem
->GetRight() );
296 if( rPropInfo
.m_bTextIndent
)
297 aLRItem
.SetTextFirstLineOfst( pLRItem
->GetTextFirstLineOfst() );
299 rItemSet
.Put( aLRItem
);
302 // oberer und unterer Rand
303 if( (rPropInfo
.m_bTopMargin
|| rPropInfo
.m_bBottomMargin
) &&
304 (!rPropInfo
.m_bTopMargin
|| !rPropInfo
.m_bBottomMargin
) &&
305 SfxItemState::SET
== rCollItemSet
.GetItemState(RES_UL_SPACE
,true,
307 SfxItemState::SET
== rItemSet
.GetItemState(RES_UL_SPACE
,false,&pItem
) )
309 const SvxULSpaceItem
*pULItem
= static_cast<const SvxULSpaceItem
*>(pItem
);
311 SvxULSpaceItem
aULItem( *static_cast<const SvxULSpaceItem
*>(pCollItem
) );
312 if( rPropInfo
.m_bTopMargin
)
313 aULItem
.SetUpper( pULItem
->GetUpper() );
314 if( rPropInfo
.m_bBottomMargin
)
315 aULItem
.SetLower( pULItem
->GetLower() );
317 rItemSet
.Put( aULItem
);
320 static const sal_uInt16 aWhichIds
[3] = { RES_CHRATR_FONTSIZE
,RES_CHRATR_CJK_FONTSIZE
,
321 RES_CHRATR_CTL_FONTSIZE
};
322 for(sal_uInt16 i
: aWhichIds
)
324 if( SfxItemState::SET
== rItemSet
.GetItemState( i
, false,
326 static_cast<const SvxFontHeightItem
*>(pItem
)->GetProp() != 100)
328 // %-Angaben beim FontHeight-Item werden nicht unterstuetzt
329 rItemSet
.ClearItem( i
);
333 pCSS1Parser
->SetFormatBreak( rItemSet
, rPropInfo
);
335 pColl
->SetFormatAttr( rItemSet
);
338 void SwCSS1Parser::SetTableTextColl( bool bHeader
)
340 OSL_ENSURE( !(bHeader
? bTableHeaderTextCollSet
: bTableTextCollSet
),
341 "Aufruf von SetTableTextColl unnoetig" );
347 nPoolId
= RES_POOLCOLL_TABLE_HDLN
;
348 sTag
= OOO_STRING_SVTOOLS_HTML_tableheader
;
352 nPoolId
= RES_POOLCOLL_TABLE
;
353 sTag
= OOO_STRING_SVTOOLS_HTML_tabledata
;
356 SwTextFormatColl
*pColl
= nullptr;
358 // The following entries will never be used again and may be changed.
359 SvxCSS1MapEntry
*pStyleEntry
= GetTag( sTag
);
362 pColl
= GetTextFormatColl( nPoolId
, aEmptyOUStr
);
363 SetTextCollAttrs( pColl
, pStyleEntry
->GetItemSet(),
364 pStyleEntry
->GetPropertyInfo(), this );
367 OUString sTmp
= sTag
+ " " OOO_STRING_SVTOOLS_HTML_parabreak
;
368 pStyleEntry
= GetTag( sTmp
);
372 pColl
= GetTextFormatColl( nPoolId
, aEmptyOUStr
);
373 SetTextCollAttrs( pColl
, pStyleEntry
->GetItemSet(),
374 pStyleEntry
->GetPropertyInfo(), this );
378 bTableHeaderTextCollSet
= true;
380 bTableTextCollSet
= true;
383 void SwCSS1Parser::SetPageDescAttrs( const SvxBrushItem
*pBrush
,
384 SfxItemSet
*pItemSet2
)
386 SvxBrushItem
aBrushItem( RES_BACKGROUND
);
387 SvxBoxItem
aBoxItem( RES_BOX
);
388 SvxFrameDirectionItem
aFrameDirItem(FRMDIR_ENVIRONMENT
, RES_FRAMEDIR
);
389 bool bSetBrush
= pBrush
!=nullptr, bSetBox
= false, bSetFrameDir
= false;
391 aBrushItem
= *pBrush
;
395 const SfxPoolItem
*pItem
= nullptr;
396 if( SfxItemState::SET
== pItemSet2
->GetItemState( RES_BACKGROUND
, false,
399 // ein Hintergrund wird gesetzt
400 aBrushItem
= *static_cast<const SvxBrushItem
*>(pItem
);
401 pItemSet2
->ClearItem( RES_BACKGROUND
);
405 if( SfxItemState::SET
== pItemSet2
->GetItemState( RES_BOX
, false, &pItem
) )
407 // eine Umrandung wird gesetzt
408 aBoxItem
= *static_cast<const SvxBoxItem
*>(pItem
);
409 pItemSet2
->ClearItem( RES_BOX
);
413 if( SfxItemState::SET
== pItemSet2
->GetItemState( RES_FRAMEDIR
, false, &pItem
) )
415 // eine Umrandung wird gesetzt
416 aFrameDirItem
= *static_cast< const SvxFrameDirectionItem
*>( pItem
);
417 pItemSet2
->ClearItem( RES_FRAMEDIR
);
422 if( bSetBrush
|| bSetBox
|| bSetFrameDir
)
424 static sal_uInt16 aPoolIds
[] = { RES_POOLPAGE_HTML
, RES_POOLPAGE_FIRST
,
425 RES_POOLPAGE_LEFT
, RES_POOLPAGE_RIGHT
};
426 for(sal_uInt16 i
: aPoolIds
)
428 const SwPageDesc
*pPageDesc
= GetPageDesc( i
, false );
431 SwPageDesc
aNewPageDesc( *pPageDesc
);
432 SwFrameFormat
&rMaster
= aNewPageDesc
.GetMaster();
434 rMaster
.SetFormatAttr( aBrushItem
);
436 rMaster
.SetFormatAttr( aBoxItem
);
438 rMaster
.SetFormatAttr( aFrameDirItem
);
440 ChgPageDesc( pPageDesc
, aNewPageDesc
);
447 void SwCSS1Parser::SetPageDescAttrs( const SwPageDesc
*pPageDesc
,
448 SfxItemSet
& rItemSet
,
449 const SvxCSS1PropertyInfo
& rPropInfo
)
454 SwPageDesc
aNewPageDesc( *pPageDesc
);
455 SwFrameFormat
&rMaster
= aNewPageDesc
.GetMaster();
456 const SfxItemSet
& rPageItemSet
= rMaster
.GetAttrSet();
457 const SfxPoolItem
*pPageItem
, *pItem
;
458 bool bChanged
= false;
460 // linker, rechter Rand und Erstzeilen-Einzug
461 if( (rPropInfo
.m_bLeftMargin
|| rPropInfo
.m_bRightMargin
) &&
462 SfxItemState::SET
== rItemSet
.GetItemState(RES_LR_SPACE
,false,&pItem
) )
464 if( (!rPropInfo
.m_bLeftMargin
|| !rPropInfo
.m_bRightMargin
) &&
465 SfxItemState::SET
== rPageItemSet
.GetItemState(RES_LR_SPACE
,
468 const SvxLRSpaceItem
*pLRItem
= static_cast<const SvxLRSpaceItem
*>(pItem
);
470 SvxLRSpaceItem
aLRItem( *static_cast<const SvxLRSpaceItem
*>(pPageItem
) );
471 if( rPropInfo
.m_bLeftMargin
)
472 aLRItem
.SetLeft( pLRItem
->GetLeft() );
473 if( rPropInfo
.m_bRightMargin
)
474 aLRItem
.SetRight( pLRItem
->GetRight() );
476 rMaster
.SetFormatAttr( aLRItem
);
480 rMaster
.SetFormatAttr( *pItem
);
485 // oberer und unterer Rand
486 if( (rPropInfo
.m_bTopMargin
|| rPropInfo
.m_bBottomMargin
) &&
487 SfxItemState::SET
== rItemSet
.GetItemState(RES_UL_SPACE
,false,&pItem
) )
489 if( (!rPropInfo
.m_bTopMargin
|| !rPropInfo
.m_bBottomMargin
) &&
490 SfxItemState::SET
== rPageItemSet
.GetItemState(RES_UL_SPACE
,
493 const SvxULSpaceItem
*pULItem
= static_cast<const SvxULSpaceItem
*>(pItem
);
495 SvxULSpaceItem
aULItem( *static_cast<const SvxULSpaceItem
*>(pPageItem
) );
496 if( rPropInfo
.m_bTopMargin
)
497 aULItem
.SetUpper( pULItem
->GetUpper() );
498 if( rPropInfo
.m_bBottomMargin
)
499 aULItem
.SetLower( pULItem
->GetLower() );
501 rMaster
.SetFormatAttr( aULItem
);
505 rMaster
.SetFormatAttr( *pItem
);
511 if( rPropInfo
.m_eSizeType
!= SVX_CSS1_STYPE_NONE
)
513 if( rPropInfo
.m_eSizeType
== SVX_CSS1_STYPE_TWIP
)
515 rMaster
.SetFormatAttr( SwFormatFrameSize( ATT_FIX_SIZE
, rPropInfo
.m_nWidth
,
516 rPropInfo
.m_nHeight
) );
521 // Bei "size: auto|portrait|landscape" bleibt die bisherige
522 // Groesse der Vorlage erhalten. Bei "landscape" und "portrait"
523 // wird das Landscape-Flag gesetzt und evtl. die Breite/Hoehe
525 SwFormatFrameSize
aFrameSz( rMaster
.GetFrameSize() );
526 bool bLandscape
= aNewPageDesc
.GetLandscape();
528 rPropInfo
.m_eSizeType
== SVX_CSS1_STYPE_PORTRAIT
) ||
530 rPropInfo
.m_eSizeType
== SVX_CSS1_STYPE_LANDSCAPE
) )
532 SwTwips nTmp
= aFrameSz
.GetHeight();
533 aFrameSz
.SetHeight( aFrameSz
.GetWidth() );
534 aFrameSz
.SetWidth( nTmp
);
535 rMaster
.SetFormatAttr( aFrameSz
);
536 aNewPageDesc
.SetLandscape( !bLandscape
);
542 // Geht das wirklich?
543 if( SfxItemState::SET
== rItemSet
.GetItemState( RES_BACKGROUND
, false, &pItem
) )
545 // eine Umrandung wird gesetzt
546 rMaster
.SetFormatAttr( *pItem
);
547 rItemSet
.ClearItem( RES_BACKGROUND
);
552 ChgPageDesc( pPageDesc
, aNewPageDesc
);
555 SvxBrushItem
SwCSS1Parser::makePageDescBackground() const
557 return pDoc
->getIDocumentStylePoolAccess().GetPageDescFromPool( RES_POOLPAGE_HTML
, false )
558 ->GetMaster().makeBackgroundBrushItem();
561 sal_uInt16
SwCSS1Parser::GetScriptFromClass( OUString
& rClass
,
564 sal_uInt16 nScriptFlags
= CSS1_SCRIPT_ALL
;
565 sal_Int32 nLen
= rClass
.getLength();
566 sal_Int32 nPos
= nLen
> 4 ? rClass
.lastIndexOf( '-' ) : -1;
583 if( rClass
.matchIgnoreAsciiCase( "cjk", nPos
) )
585 nScriptFlags
= CSS1_SCRIPT_CJK
;
587 else if( rClass
.matchIgnoreAsciiCase( "ctl", nPos
) )
589 nScriptFlags
= CSS1_SCRIPT_CTL
;
593 if( rClass
.matchIgnoreAsciiCase( "western", nPos
) )
595 nScriptFlags
= CSS1_SCRIPT_WESTERN
;
599 if( CSS1_SCRIPT_ALL
!= nScriptFlags
)
603 rClass
= rClass
.copy( 0, nPos
-1 );
614 static CSS1SelectorType
GetTokenAndClass( const CSS1Selector
*pSelector
,
615 OUString
& rToken
, OUString
& rClass
,
616 sal_uInt16
& rScriptFlags
)
618 rToken
= pSelector
->GetString();
620 rScriptFlags
= CSS1_SCRIPT_ALL
;
622 CSS1SelectorType eType
= pSelector
->GetType();
623 if( CSS1_SELTYPE_ELEM_CLASS
==eType
)
625 sal_Int32 nPos
= rToken
.indexOf( '.' );
626 OSL_ENSURE( nPos
>= 0, "kein Punkt in Class-Selektor???" );
629 rClass
= rToken
.copy( nPos
+1 );
630 rToken
= rToken
.copy( 0, nPos
);
632 rScriptFlags
= SwCSS1Parser::GetScriptFromClass( rClass
, false );
633 if( rClass
.isEmpty() )
634 eType
= CSS1_SELTYPE_ELEMENT
;
638 rToken
= rToken
.toAsciiLowerCase();
642 static void RemoveScriptItems( SfxItemSet
& rItemSet
, sal_uInt16 nScript
,
643 const SfxItemSet
*pParentItemSet
= nullptr )
645 static const sal_uInt16 aWhichIds
[3][5] =
647 { RES_CHRATR_FONT
, RES_CHRATR_FONTSIZE
, RES_CHRATR_LANGUAGE
,
648 RES_CHRATR_POSTURE
, RES_CHRATR_WEIGHT
},
649 { RES_CHRATR_CJK_FONT
, RES_CHRATR_CJK_FONTSIZE
, RES_CHRATR_CJK_LANGUAGE
,
650 RES_CHRATR_CJK_POSTURE
, RES_CHRATR_CJK_WEIGHT
},
651 { RES_CHRATR_CTL_FONT
, RES_CHRATR_CTL_FONTSIZE
, RES_CHRATR_CTL_LANGUAGE
,
652 RES_CHRATR_CTL_POSTURE
, RES_CHRATR_CTL_WEIGHT
}
655 bool aClearItems
[3] = { false, false, false };
658 case CSS1_SCRIPT_WESTERN
:
659 aClearItems
[1] = aClearItems
[2] = true;
661 case CSS1_SCRIPT_CJK
:
662 aClearItems
[0] = aClearItems
[2] = true;
664 case CSS1_SCRIPT_CTL
:
665 aClearItems
[0] = aClearItems
[1] = true;
667 case CSS1_SCRIPT_ALL
:
670 OSL_ENSURE( aClearItems
[0], "unknown script type" );
674 for( size_t j
=0; j
< SAL_N_ELEMENTS(aWhichIds
); ++j
)
676 for( size_t i
=0; i
< SAL_N_ELEMENTS(aWhichIds
[0]); ++i
)
678 sal_uInt16 nWhich
= aWhichIds
[j
][i
];
679 const SfxPoolItem
*pItem
;
680 if( aClearItems
[j
] ||
682 SfxItemState::SET
== rItemSet
.GetItemState( nWhich
, false, &pItem
) &&
683 (0==i
? swhtml_css1atr_equalFontItems( *pItem
, pParentItemSet
->Get(nWhich
) )
684 : *pItem
== pParentItemSet
->Get(nWhich
) ) ) )
686 rItemSet
.ClearItem( nWhich
);
692 void SwCSS1Parser::StyleParsed( const CSS1Selector
*pSelector
,
693 SfxItemSet
& rItemSet
,
694 SvxCSS1PropertyInfo
& rPropInfo
)
699 CSS1SelectorType eSelType
= pSelector
->GetType();
700 const CSS1Selector
*pNext
= pSelector
->GetNext();
702 if( CSS1_SELTYPE_ID
==eSelType
&& !pNext
)
704 InsertId( pSelector
->GetString(), rItemSet
, rPropInfo
);
706 else if( CSS1_SELTYPE_CLASS
==eSelType
&& !pNext
)
708 OUString
aClass( pSelector
->GetString() );
709 sal_uInt16 nScript
= GetScriptFromClass( aClass
);
710 if( CSS1_SCRIPT_ALL
!= nScript
)
712 SfxItemSet
aScriptItemSet( rItemSet
);
713 RemoveScriptItems( aScriptItemSet
, nScript
);
714 InsertClass( aClass
, aScriptItemSet
, rPropInfo
);
718 InsertClass( aClass
, rItemSet
, rPropInfo
);
721 else if( CSS1_SELTYPE_PAGE
==eSelType
)
724 (CSS1_SELTYPE_PSEUDO
== pNext
->GetType() &&
725 (pNext
->GetString().equalsIgnoreAsciiCase( "left" ) ||
726 pNext
->GetString().equalsIgnoreAsciiCase( "right" ) ||
727 pNext
->GetString().equalsIgnoreAsciiCase( "first" ) ) ) )
731 aName
= pNext
->GetString();
734 rItemSet
, rPropInfo
);
738 if( CSS1_SELTYPE_ELEMENT
!= eSelType
&&
739 CSS1_SELTYPE_ELEM_CLASS
!= eSelType
)
742 // Token und Class zu dem Selektor holen
746 eSelType
= GetTokenAndClass( pSelector
, aToken2
, aClass
, nScript
);
747 int nToken2
= GetHTMLToken( aToken2
);
749 // und noch ein ganz par Infos zum naechsten Element
750 CSS1SelectorType eNextType
= pNext
? pNext
->GetType()
751 : CSS1_SELTYPE_ELEMENT
;
753 // Erstmal ein par Spezialfaelle
754 if( CSS1_SELTYPE_ELEMENT
==eSelType
)
761 InsertTag( aToken2
, rItemSet
, rPropInfo
);
764 else if( pNext
&& CSS1_SELTYPE_PSEUDO
== eNextType
)
766 // vielleicht A:visited oder A:link
768 OUString
aPseudo( pNext
->GetString() );
769 aPseudo
= aPseudo
.toAsciiLowerCase();
770 bool bInsert
= false;
774 if( aPseudo
== "link" )
780 if( aPseudo
== "visited" )
788 OUString sTmp
= aToken2
+ ":" + aPseudo
;
789 if( CSS1_SCRIPT_ALL
!= nScript
)
791 SfxItemSet
aScriptItemSet( rItemSet
);
792 RemoveScriptItems( aScriptItemSet
, nScript
);
793 InsertTag( sTmp
, aScriptItemSet
, rPropInfo
);
797 InsertTag( sTmp
, rItemSet
, rPropInfo
);
808 // Den Hintergrund muessen wir vor dem Setzen abfragen,
809 // denn in SetPageDescAttrs wird er geloescht.
810 const SfxPoolItem
*pItem
;
811 if( SfxItemState::SET
==rItemSet
.GetItemState(RES_BACKGROUND
,false,&pItem
) )
813 const SvxBrushItem
*pBrushItem
=
814 static_cast<const SvxBrushItem
*>(pItem
);
816 /// Body has a background color, if it is not "no fill"/"auto fill"
817 if( pBrushItem
->GetColor() != COL_TRANSPARENT
)
818 bBodyBGColorSet
= true;
819 if( GPOS_NONE
!= pBrushItem
->GetGraphicPos() )
820 bBodyBackgroundSet
= true;
823 // Border and Padding
824 rPropInfo
.SetBoxItem( rItemSet
, MIN_BORDER_DIST
);
826 // Ein par Attribute muessen an der Seitenvorlage gesetzt werden,
827 // und zwar die, die nicht vererbt werden
828 SetPageDescAttrs( nullptr, &rItemSet
);
830 // alle noch uebrigen Optionen koennen an der Standard-Vorlage
831 // gesetzt werden und gelten dann automatisch als defaults
832 if( SfxItemState::SET
==rItemSet
.GetItemState(RES_CHRATR_COLOR
,false) )
835 GetTextCollFromPool( RES_POOLCOLL_STANDARD
),
836 rItemSet
, rPropInfo
, this );
843 else if( CSS1_SELTYPE_ELEM_CLASS
==eSelType
&& HTML_ANCHOR_ON
==nToken2
&&
844 !pNext
&& aClass
.getLength() >= 9 &&
845 ('s' == aClass
[0] || 'S' == aClass
[0]) )
847 sal_uInt16 nPoolFormatId
= 0;
848 if( aClass
.equalsIgnoreAsciiCase(OOO_STRING_SVTOOLS_HTML_sdendnote_sym
) )
849 nPoolFormatId
= RES_POOLCHR_ENDNOTE
;
850 else if( aClass
.equalsIgnoreAsciiCase(OOO_STRING_SVTOOLS_HTML_sdfootnote_sym
) )
851 nPoolFormatId
= RES_POOLCHR_FOOTNOTE
;
854 if( CSS1_SCRIPT_ALL
== nScript
)
856 SetCharFormatAttrs( GetCharFormatFromPool(nPoolFormatId
), rItemSet
);
860 SfxItemSet
aScriptItemSet( rItemSet
);
861 RemoveScriptItems( aScriptItemSet
, nScript
);
862 SetCharFormatAttrs( GetCharFormatFromPool(nPoolFormatId
),
869 // Jetzt werden die Selektoren verarbeitet, die zu einer Absatz-Vorlage
871 sal_uInt16 nPoolCollId
= 0;
875 nPoolCollId
= RES_POOLCOLL_HEADLINE1
;
878 nPoolCollId
= RES_POOLCOLL_HEADLINE2
;
881 nPoolCollId
= RES_POOLCOLL_HEADLINE3
;
884 nPoolCollId
= RES_POOLCOLL_HEADLINE4
;
887 nPoolCollId
= RES_POOLCOLL_HEADLINE5
;
890 nPoolCollId
= RES_POOLCOLL_HEADLINE6
;
892 case HTML_PARABREAK_ON
:
893 if( aClass
.getLength() >= 9 &&
894 ('s' == aClass
[0] || 'S' == aClass
[0]) )
896 if( aClass
.equalsIgnoreAsciiCase(OOO_STRING_SVTOOLS_HTML_sdendnote
) )
897 nPoolCollId
= RES_POOLCOLL_ENDNOTE
;
898 else if( aClass
.equalsIgnoreAsciiCase(OOO_STRING_SVTOOLS_HTML_sdfootnote
) )
899 nPoolCollId
= RES_POOLCOLL_FOOTNOTE
;
902 aClass
= aEmptyOUStr
;
904 nPoolCollId
= RES_POOLCOLL_TEXT
;
908 nPoolCollId
= RES_POOLCOLL_TEXT
;
911 case HTML_ADDRESS_ON
:
912 nPoolCollId
= RES_POOLCOLL_SENDADRESS
;
914 case HTML_BLOCKQUOTE_ON
:
915 nPoolCollId
= RES_POOLCOLL_HTML_BLOCKQUOTE
;
918 nPoolCollId
= RES_POOLCOLL_HTML_DT
;
921 nPoolCollId
= RES_POOLCOLL_HTML_DD
;
923 case HTML_PREFORMTXT_ON
:
924 nPoolCollId
= RES_POOLCOLL_HTML_PRE
;
926 case HTML_TABLEHEADER_ON
:
927 case HTML_TABLEDATA_ON
:
928 if( CSS1_SELTYPE_ELEMENT
==eSelType
&& !pNext
)
930 InsertTag( aToken2
, rItemSet
, rPropInfo
);
933 else if( CSS1_SELTYPE_ELEMENT
==eSelType
&& pNext
&&
934 (CSS1_SELTYPE_ELEMENT
==eNextType
||
935 CSS1_SELTYPE_ELEM_CLASS
==eNextType
) )
937 // nicht TH und TD, aber TH P und TD P
938 OUString aSubToken
, aSubClass
;
939 GetTokenAndClass( pNext
, aSubToken
, aSubClass
, nScript
);
940 if( HTML_PARABREAK_ON
== GetHTMLToken( aSubToken
) )
943 pNext
= pNext
->GetNext();
944 eNextType
= pNext
? pNext
->GetType() : CSS1_SELTYPE_ELEMENT
;
946 if( !aClass
.isEmpty() || pNext
)
948 nPoolCollId
= static_cast< sal_uInt16
>(
949 HTML_TABLEHEADER_ON
== nToken2
? RES_POOLCOLL_TABLE_HDLN
950 : RES_POOLCOLL_TABLE
);
954 OUString sTmp
= aToken2
+ " " OOO_STRING_SVTOOLS_HTML_parabreak
;
956 if( CSS1_SCRIPT_ALL
== nScript
)
958 InsertTag( sTmp
, rItemSet
, rPropInfo
);
962 SfxItemSet
aScriptItemSet( rItemSet
);
963 RemoveScriptItems( aScriptItemSet
, nScript
);
964 InsertTag( sTmp
, aScriptItemSet
, rPropInfo
);
980 (CSS1_SELTYPE_PSEUDO
==eNextType
&&
981 pNext
->GetString().equalsIgnoreAsciiCase( "first-letter" ) &&
982 SVX_ADJUST_LEFT
== rPropInfo
.m_eFloat
) )
984 // Entweder kein zusammengesetzter Selektor oder
985 // ein X:first-line { float: left; ... }
987 // Die Vorlage Suchen bzw. Anlegen
988 SwTextFormatColl
*pColl
= GetTextFormatColl( nPoolCollId
, aEmptyOUStr
);
989 SwTextFormatColl
* pParentColl
= nullptr;
990 if( !aClass
.isEmpty() )
992 OUString
aName( pColl
->GetName() );
993 AddClassName( aName
, aClass
);
996 pColl
= pDoc
->FindTextFormatCollByName( aName
);
998 pColl
= pDoc
->MakeTextFormatColl( aName
, pParentColl
);
1002 // nur die Attribute an der Vorlage setzen
1003 const SfxPoolItem
*pItem
;
1004 const SvxBoxItem
*pBoxItem
= nullptr;
1005 if( SfxItemState::SET
==
1006 pColl
->GetAttrSet().GetItemState(RES_BOX
,true,&pItem
) )
1007 pBoxItem
= static_cast<const SvxBoxItem
*>(pItem
);
1008 rPropInfo
.SetBoxItem( rItemSet
, MIN_BORDER_DIST
, pBoxItem
);
1009 if( CSS1_SCRIPT_ALL
== nScript
&& !pParentColl
)
1011 SetTextCollAttrs( pColl
, rItemSet
, rPropInfo
, this );
1015 SfxItemSet
aScriptItemSet( rItemSet
);
1016 RemoveScriptItems( aScriptItemSet
, nScript
,
1017 pParentColl
? &pParentColl
->GetAttrSet() : nullptr );
1018 SetTextCollAttrs( pColl
, aScriptItemSet
, rPropInfo
, this );
1023 // ein Drop-Cap-Attribut basteln
1024 SwFormatDrop
aDrop( pColl
->GetDrop() );
1025 aDrop
.GetChars() = 1;
1027 // die Attribute in das DropCap-Attribut einfuegen
1028 if( CSS1_SCRIPT_ALL
== nScript
)
1030 OUString
sName(pColl
->GetName());
1031 FillDropCap( aDrop
, rItemSet
, &sName
);
1035 SfxItemSet
aScriptItemSet( rItemSet
);
1036 if( CSS1_SCRIPT_WESTERN
!= nScript
)
1038 aScriptItemSet
.ClearItem( RES_CHRATR_FONT
);
1039 aScriptItemSet
.ClearItem( RES_CHRATR_LANGUAGE
);
1040 aScriptItemSet
.ClearItem( RES_CHRATR_POSTURE
);
1041 aScriptItemSet
.ClearItem( RES_CHRATR_WEIGHT
);
1043 if( CSS1_SCRIPT_CJK
!= nScript
)
1045 aScriptItemSet
.ClearItem( RES_CHRATR_CJK_FONT
);
1046 aScriptItemSet
.ClearItem( RES_CHRATR_CJK_LANGUAGE
);
1047 aScriptItemSet
.ClearItem( RES_CHRATR_CJK_POSTURE
);
1048 aScriptItemSet
.ClearItem( RES_CHRATR_CJK_WEIGHT
);
1050 if( CSS1_SCRIPT_CTL
!= nScript
)
1052 aScriptItemSet
.ClearItem( RES_CHRATR_CTL_FONT
);
1053 aScriptItemSet
.ClearItem( RES_CHRATR_CTL_LANGUAGE
);
1054 aScriptItemSet
.ClearItem( RES_CHRATR_CTL_POSTURE
);
1055 aScriptItemSet
.ClearItem( RES_CHRATR_CTL_WEIGHT
);
1057 OUString
sName(pColl
->GetName());
1058 FillDropCap( aDrop
, aScriptItemSet
, &sName
);
1061 // Das Attribut nur setzen, wenn float: left angegeben wurde
1062 // und das Initial ueber mehrere Zeilen geht. Sonst wird die
1063 // ggf. angelegte Zeichen-Vorlage spaeter ueber den Namen
1064 // gesucht und gesetzt.
1065 if( aDrop
.GetLines() > 1 &&
1066 (SVX_ADJUST_LEFT
== rPropInfo
.m_eFloat
||
1067 CSS1_SCRIPT_ALL
== nScript
) )
1069 pColl
->SetFormatAttr( aDrop
);
1077 // Jetzt werden die Selektoten verarbeitet, die zu einer Zechenvorlage
1078 // gehoehren. Zusammengesetzte gibt es hier allerdings nich nicht.
1082 SwCharFormat
*pCFormat
= GetChrFormat( static_cast< sal_uInt16
>(nToken2
), aEmptyOUStr
);
1085 SwCharFormat
*pParentCFormat
= nullptr;
1086 if( !aClass
.isEmpty() )
1088 OUString
aName( pCFormat
->GetName() );
1089 AddClassName( aName
, aClass
);
1090 pParentCFormat
= pCFormat
;
1092 pCFormat
= pDoc
->FindCharFormatByName( aName
);
1095 pCFormat
= pDoc
->MakeCharFormat( aName
, pParentCFormat
);
1096 pCFormat
->SetAuto(false);
1100 if( CSS1_SCRIPT_ALL
== nScript
&& !pParentCFormat
)
1102 SetCharFormatAttrs( pCFormat
, rItemSet
);
1106 SfxItemSet
aScriptItemSet( rItemSet
);
1107 RemoveScriptItems( aScriptItemSet
, nScript
,
1108 pParentCFormat
? &pParentCFormat
->GetAttrSet() : nullptr );
1109 SetCharFormatAttrs( pCFormat
, aScriptItemSet
);
1114 sal_uInt32
SwCSS1Parser::GetFontHeight( sal_uInt16 nSize
) const
1116 return aFontHeights
[ nSize
>6 ? 6 : nSize
];
1119 const FontList
*SwCSS1Parser::GetFontList() const
1121 const FontList
*pFList
= nullptr;
1122 SwDocShell
*pDocSh
= pDoc
->GetDocShell();
1125 const SvxFontListItem
*pFListItem
=
1126 static_cast<const SvxFontListItem
*>(pDocSh
->GetItem(SID_ATTR_CHAR_FONTLIST
));
1128 pFList
= pFListItem
->GetFontList();
1134 SwCharFormat
* SwCSS1Parser::GetChrFormat( sal_uInt16 nToken2
, const OUString
& rClass
) const
1136 // die entsprechende Vorlage suchen
1137 sal_uInt16 nPoolId
= 0;
1138 const sal_Char
* sName
= nullptr;
1141 case HTML_EMPHASIS_ON
: nPoolId
= RES_POOLCHR_HTML_EMPHASIS
; break;
1142 case HTML_CITIATION_ON
: nPoolId
= RES_POOLCHR_HTML_CITIATION
; break;
1143 case HTML_STRONG_ON
: nPoolId
= RES_POOLCHR_HTML_STRONG
; break;
1144 case HTML_CODE_ON
: nPoolId
= RES_POOLCHR_HTML_CODE
; break;
1145 case HTML_SAMPLE_ON
: nPoolId
= RES_POOLCHR_HTML_SAMPLE
; break;
1146 case HTML_KEYBOARD_ON
: nPoolId
= RES_POOLCHR_HTML_KEYBOARD
; break;
1147 case HTML_VARIABLE_ON
: nPoolId
= RES_POOLCHR_HTML_VARIABLE
; break;
1148 case HTML_DEFINSTANCE_ON
: nPoolId
= RES_POOLCHR_HTML_DEFINSTANCE
; break;
1149 case HTML_TELETYPE_ON
: nPoolId
= RES_POOLCHR_HTML_TELETYPE
; break;
1151 case HTML_SHORTQUOTE_ON
: sName
= OOO_STRING_SVTOOLS_HTML_shortquote
; break;
1152 case HTML_LANGUAGE_ON
: sName
= OOO_STRING_SVTOOLS_HTML_language
; break;
1153 case HTML_AUTHOR_ON
: sName
= OOO_STRING_SVTOOLS_HTML_author
; break;
1154 case HTML_PERSON_ON
: sName
= OOO_STRING_SVTOOLS_HTML_person
; break;
1155 case HTML_ACRONYM_ON
: sName
= OOO_STRING_SVTOOLS_HTML_acronym
; break;
1156 case HTML_ABBREVIATION_ON
: sName
= OOO_STRING_SVTOOLS_HTML_abbreviation
; break;
1157 case HTML_INSERTEDTEXT_ON
: sName
= OOO_STRING_SVTOOLS_HTML_insertedtext
; break;
1158 case HTML_DELETEDTEXT_ON
: sName
= OOO_STRING_SVTOOLS_HTML_deletedtext
; break;
1161 // die Vorlage suchen oder anlegen (geht nur mit Namen)
1162 if( !nPoolId
&& !sName
)
1165 // Die Vorlage (ohne Class) suchen oder anlegen
1166 SwCharFormat
*pCFormat
= nullptr;
1169 pCFormat
= GetCharFormatFromPool( nPoolId
);
1173 OUString
sCName( OUString::createFromAscii(sName
) );
1174 pCFormat
= pDoc
->FindCharFormatByName( sCName
);
1177 pCFormat
= pDoc
->MakeCharFormat( sCName
, pDoc
->GetDfltCharFormat() );
1178 pCFormat
->SetAuto(false);
1182 OSL_ENSURE( pCFormat
, "Keine Zeichen-Vorlage???" );
1184 // Wenn es eine Klasse gibt, die Klassen-Vorlage suchen aber nicht
1186 OUString
aClass( rClass
);
1187 GetScriptFromClass( aClass
, false );
1188 if( !aClass
.isEmpty() )
1190 OUString
aTmp( pCFormat
->GetName() );
1191 AddClassName( aTmp
, aClass
);
1192 SwCharFormat
*pClassCFormat
= pDoc
->FindCharFormatByName( aTmp
);
1195 pCFormat
= pClassCFormat
;
1199 const SvxCSS1MapEntry
*pClass
= GetClass( aClass
);
1202 pCFormat
= pDoc
->MakeCharFormat( aTmp
, pCFormat
);
1203 pCFormat
->SetAuto(false);
1204 SfxItemSet
aItemSet( pClass
->GetItemSet() );
1205 SetCharFormatAttrs( pCFormat
, aItemSet
);
1213 SwTextFormatColl
*SwCSS1Parser::GetTextCollFromPool( sal_uInt16 nPoolId
) const
1215 const SwTextFormatColls::size_type nOldArrLen
= pDoc
->GetTextFormatColls()->size();
1217 SwTextFormatColl
*pColl
= pDoc
->getIDocumentStylePoolAccess().GetTextCollFromPool( nPoolId
, false );
1221 const SwTextFormatColls::size_type nArrLen
= pDoc
->GetTextFormatColls()->size();
1222 for( SwTextFormatColls::size_type i
=nOldArrLen
; i
<nArrLen
; ++i
)
1223 lcl_swcss1_setEncoding( *(*pDoc
->GetTextFormatColls())[i
],
1224 GetDfltEncoding() );
1230 SwCharFormat
*SwCSS1Parser::GetCharFormatFromPool( sal_uInt16 nPoolId
) const
1232 const SwCharFormats::size_type nOldArrLen
= pDoc
->GetCharFormats()->size();
1234 SwCharFormat
*pCharFormat
= pDoc
->getIDocumentStylePoolAccess().GetCharFormatFromPool( nPoolId
);
1238 const SwCharFormats::size_type nArrLen
= pDoc
->GetCharFormats()->size();
1240 for( SwCharFormats::size_type i
=nOldArrLen
; i
<nArrLen
; i
++ )
1241 lcl_swcss1_setEncoding( *(*pDoc
->GetCharFormats())[i
],
1242 GetDfltEncoding() );
1248 SwTextFormatColl
*SwCSS1Parser::GetTextFormatColl( sal_uInt16 nTextColl
,
1249 const OUString
& rClass
)
1251 SwTextFormatColl
* pColl
= nullptr;
1253 OUString
aClass( rClass
);
1254 GetScriptFromClass( aClass
, false );
1255 if( RES_POOLCOLL_TEXT
== nTextColl
&& aClass
.getLength() >= 9 &&
1256 ('s' == aClass
[0] || 'S' == aClass
[0] ) )
1258 if( aClass
.equalsIgnoreAsciiCase(OOO_STRING_SVTOOLS_HTML_sdendnote
) )
1260 nTextColl
= RES_POOLCOLL_ENDNOTE
;
1261 aClass
= aEmptyOUStr
;
1263 else if( aClass
.equalsIgnoreAsciiCase(OOO_STRING_SVTOOLS_HTML_sdfootnote
) )
1265 nTextColl
= RES_POOLCOLL_FOOTNOTE
;
1266 aClass
= aEmptyOUStr
;
1270 if( USER_FMT
& nTextColl
) // eine vom Reader angelegte
1272 OSL_ENSURE( false, "Wo kommt die Benutzer-Vorlage her?" );
1273 pColl
= GetTextCollFromPool( RES_POOLCOLL_STANDARD
);
1277 pColl
= GetTextCollFromPool( nTextColl
);
1280 OSL_ENSURE( pColl
, "Keine Absatz-Vorlage???" );
1281 if( !aClass
.isEmpty() )
1283 OUString
aTmp( pColl
->GetName() );
1284 AddClassName( aTmp
, aClass
);
1285 SwTextFormatColl
* pClassColl
= pDoc
->FindTextFormatCollByName( aTmp
);
1288 (nTextColl
==RES_POOLCOLL_TABLE
||
1289 nTextColl
==RES_POOLCOLL_TABLE_HDLN
) )
1291 // Wenn dieser Fall eintritt, dann wurde ein <TD><P CLASS=foo>
1292 // gelesen, aber die TD.foo Vorlage nicht gefunden. Dann muessen
1293 // wir P.foo nehmen, wenn es sie gibt.
1294 SwTextFormatColl
* pCollText
=
1295 GetTextCollFromPool( RES_POOLCOLL_TEXT
);
1296 aTmp
= pCollText
->GetName();
1297 AddClassName( aTmp
, aClass
);
1298 pClassColl
= pDoc
->FindTextFormatCollByName( aTmp
);
1307 const SvxCSS1MapEntry
*pClass
= GetClass( aClass
);
1310 pColl
= pDoc
->MakeTextFormatColl( aTmp
, pColl
);
1311 SfxItemSet
aItemSet( pClass
->GetItemSet() );
1312 SvxCSS1PropertyInfo
aPropInfo( pClass
->GetPropertyInfo() );
1313 aPropInfo
.SetBoxItem( aItemSet
, MIN_BORDER_DIST
);
1314 bool bPositioned
= MayBePositioned( pClass
->GetPropertyInfo() );
1316 aItemSet
.ClearItem( RES_BACKGROUND
);
1317 SetTextCollAttrs( pColl
, aItemSet
, aPropInfo
,
1325 lcl_swcss1_setEncoding( *pColl
, GetDfltEncoding() );
1330 SwPageDesc
*SwCSS1Parser::GetMasterPageDesc()
1332 return pDoc
->getIDocumentStylePoolAccess().GetPageDescFromPool( RES_POOLPAGE_HTML
, false );
1335 static SwPageDesc
*FindPageDesc(SwDoc
*pDoc
, sal_uInt16 nPoolId
)
1337 size_t nPageDescs
= pDoc
->GetPageDescCnt();
1339 for (nPage
=0; nPage
< nPageDescs
&&
1340 pDoc
->GetPageDesc(nPage
).GetPoolFormatId() != nPoolId
; ++nPage
)
1343 return nPage
< nPageDescs
? &pDoc
->GetPageDesc(nPage
) : nullptr;
1346 const SwPageDesc
*SwCSS1Parser::GetPageDesc( sal_uInt16 nPoolId
, bool bCreate
)
1348 if( RES_POOLPAGE_HTML
== nPoolId
)
1349 return pDoc
->getIDocumentStylePoolAccess().GetPageDescFromPool( RES_POOLPAGE_HTML
, false );
1351 const SwPageDesc
*pPageDesc
= FindPageDesc(pDoc
, nPoolId
);
1352 if( !pPageDesc
&& bCreate
)
1354 // Die erste Seite wird aus der rechten Seite erzeugt, wenn es die
1356 SwPageDesc
*pMasterPageDesc
= nullptr;
1357 if( RES_POOLPAGE_FIRST
== nPoolId
)
1358 pMasterPageDesc
= FindPageDesc(pDoc
, RES_POOLPAGE_RIGHT
);
1359 if( !pMasterPageDesc
)
1360 pMasterPageDesc
= pDoc
->getIDocumentStylePoolAccess().GetPageDescFromPool( RES_POOLPAGE_HTML
, false );
1362 // Die neue Seitenvorlage entsteht aus dem Master durch kopieren.
1363 SwPageDesc
*pNewPageDesc
= pDoc
->
1364 getIDocumentStylePoolAccess().GetPageDescFromPool( nPoolId
, false );
1366 // dazu brauchen wir auch die Nummer der neuen Vorlage
1367 OSL_ENSURE(pNewPageDesc
== FindPageDesc(pDoc
, nPoolId
), "Seitenvorlage nicht gefunden");
1369 pDoc
->CopyPageDesc( *pMasterPageDesc
, *pNewPageDesc
, false );
1371 // Die Vorlagen an ihren neuen Zweck anpassen.
1372 const SwPageDesc
*pFollow
= nullptr;
1373 bool bSetFollowFollow
= false;
1376 case RES_POOLPAGE_FIRST
:
1377 // Wenn es schon eine linke Seite gibt, dann ist das die
1378 // Folge-Vorlage, sonst ist es die HTML-Vorlage.
1379 pFollow
= GetLeftPageDesc();
1381 pFollow
= pMasterPageDesc
;
1384 case RES_POOLPAGE_RIGHT
:
1385 // Wenn die linke Vorlage schon angelegt ist, passiert hier gar
1386 // nichts. Sonst wird die linke Vorlage angelegt und sorgt auch
1387 // fuer die richtige Verkettung mit der rechten Voralge.
1388 GetLeftPageDesc( true );
1391 case RES_POOLPAGE_LEFT
:
1392 // Die rechte Vorlage wird angelegt, wenn sie noch nicht existiert.
1393 // Es findet aber keine Verkettung statt.
1394 // Wenn schon eine erste Seitenvorlage existiert, wird die linke
1395 // Vorlage die Folge-Vorlage der ersten Seite.
1396 pFollow
= GetRightPageDesc( true );
1397 bSetFollowFollow
= true;
1399 const SwPageDesc
*pFirstPageDesc
= GetFirstPageDesc();
1400 if( pFirstPageDesc
)
1402 SwPageDesc
aNewFirstPageDesc( *pFirstPageDesc
);
1403 aNewFirstPageDesc
.SetFollow( pNewPageDesc
);
1404 ChgPageDesc( pFirstPageDesc
, aNewFirstPageDesc
);
1412 SwPageDesc
aNewPageDesc( *pNewPageDesc
);
1413 aNewPageDesc
.SetFollow( pFollow
);
1414 ChgPageDesc( pNewPageDesc
, aNewPageDesc
);
1416 if( bSetFollowFollow
)
1418 SwPageDesc
aNewFollowPageDesc( *pFollow
);
1419 aNewFollowPageDesc
.SetFollow( pNewPageDesc
);
1420 ChgPageDesc( pFollow
, aNewFollowPageDesc
);
1423 pPageDesc
= pNewPageDesc
;
1429 bool SwCSS1Parser::MayBePositioned( const SvxCSS1PropertyInfo
& rPropInfo
,
1433 // left/top none auto twip perc
1440 // - das Tag wird absolut positioniert und left/top sind beide
1441 // gegeben und enthalten auch keine %-Angabe, oder
1442 // - das Tag soll fliessen, und
1443 // - es wurde eine Breite angegeben (in beiden Faellen noetig)
1444 return ( ( SVX_CSS1_POS_ABSOLUTE
== rPropInfo
.m_ePosition
&&
1445 SVX_CSS1_LTYPE_PERCENTAGE
!= rPropInfo
.m_eLeftType
&&
1446 SVX_CSS1_LTYPE_PERCENTAGE
!= rPropInfo
.m_eTopType
&&
1447 (SVX_CSS1_LTYPE_TWIP
== rPropInfo
.m_eLeftType
||
1448 SVX_CSS1_LTYPE_TWIP
!= rPropInfo
.m_eTopType
) ) ||
1449 ( SVX_ADJUST_END
!= rPropInfo
.m_eFloat
) ) &&
1451 SVX_CSS1_LTYPE_TWIP
== rPropInfo
.m_eWidthType
||
1452 SVX_CSS1_LTYPE_PERCENTAGE
== rPropInfo
.m_eWidthType
);
1455 void SwCSS1Parser::AddClassName( OUString
& rFormatName
, const OUString
& rClass
)
1457 OSL_ENSURE( !rClass
.isEmpty(), "Style-Klasse ohne Laenge?" );
1459 rFormatName
+= "." + rClass
;
1462 void SwCSS1Parser::FillDropCap( SwFormatDrop
& rDrop
,
1463 SfxItemSet
& rItemSet
,
1464 const OUString
*pName
)
1466 // die Anzahl der Zeilen entspricht in etwa einer %-Angabe
1467 // fuer die Hoehe (was passiert mit absoluten Hoehen???)
1468 sal_uInt8 nLines
= rDrop
.GetLines();
1469 const SfxPoolItem
*pItem
;
1470 if( SfxItemState::SET
== rItemSet
.GetItemState( RES_CHRATR_FONTSIZE
, false, &pItem
) )
1472 sal_uInt16 nProp
= static_cast<const SvxFontHeightItem
*>(pItem
)->GetProp();
1473 nLines
= (sal_uInt8
)((nProp
+ 50) / 100);
1476 else if( nLines
> MAX_DROPCAP_LINES
)
1477 nLines
= MAX_DROPCAP_LINES
;
1479 // Nur wenn nLines>1 ist, wird das Attribut auch gesetzt. Dann
1480 // brauchen wir die Font-Hoehe aber auch nicht in der Zeichen-Vorlage.
1483 rItemSet
.ClearItem( RES_CHRATR_FONTSIZE
);
1484 rItemSet
.ClearItem( RES_CHRATR_CJK_FONTSIZE
);
1485 rItemSet
.ClearItem( RES_CHRATR_CTL_FONTSIZE
);
1489 // Bei harter Attributierung (pName==0) koennen wir aufhoehren, wenn
1490 // das Initial nur ueber eine Zeile geht.
1494 rDrop
.GetLines() = nLines
;
1496 // ein rechter Rand wird der Abstand zum Text!
1497 if( SfxItemState::SET
== rItemSet
.GetItemState( RES_LR_SPACE
, false, &pItem
) )
1499 rDrop
.GetDistance() = static_cast< sal_uInt16
>(
1500 static_cast<const SvxLRSpaceItem
*>(pItem
)->GetRight() );
1501 rItemSet
.ClearItem( RES_LR_SPACE
);
1504 // Fuer alle anderen Attribute eine Zeichen-Vorlage anlegen
1505 if( rItemSet
.Count() )
1507 SwCharFormat
*pCFormat
= nullptr;
1512 aName
+= ".FL"; // first letter
1513 pCFormat
= pDoc
->FindCharFormatByName( aName
);
1519 aName
= "first-letter " + OUString::number( (sal_Int32
)(++nDropCapCnt
) );
1521 while( pDoc
->FindCharFormatByName(aName
) );
1526 pCFormat
= pDoc
->MakeCharFormat( aName
, pDoc
->GetDfltCharFormat() );
1527 pCFormat
->SetAuto(false);
1529 SetCharFormatAttrs( pCFormat
, rItemSet
);
1531 // Die Zeichenvorlage braucht nur im Attribut gesetzt werden, wenn
1532 // auch das Attribut gesetzt wird.
1534 rDrop
.SetCharFormat( pCFormat
);
1538 // CSS1-sezifisches des SwHTMLParsers
1540 HTMLAttr
**SwHTMLParser::GetAttrTabEntry( sal_uInt16 nWhich
)
1542 // den zu dem Item gehoehrenden Tabellen-Eintrag ermitteln ...
1543 HTMLAttr
**ppAttr
= nullptr;
1546 case RES_CHRATR_BLINK
:
1547 ppAttr
= &m_aAttrTab
.pBlink
;
1549 case RES_CHRATR_CASEMAP
:
1550 ppAttr
= &m_aAttrTab
.pCaseMap
;
1552 case RES_CHRATR_COLOR
:
1553 ppAttr
= &m_aAttrTab
.pFontColor
;
1555 case RES_CHRATR_CROSSEDOUT
:
1556 ppAttr
= &m_aAttrTab
.pStrike
;
1558 case RES_CHRATR_ESCAPEMENT
:
1559 ppAttr
= &m_aAttrTab
.pEscapement
;
1561 case RES_CHRATR_FONT
:
1562 ppAttr
= &m_aAttrTab
.pFont
;
1564 case RES_CHRATR_CJK_FONT
:
1565 ppAttr
= &m_aAttrTab
.pFontCJK
;
1567 case RES_CHRATR_CTL_FONT
:
1568 ppAttr
= &m_aAttrTab
.pFontCTL
;
1570 case RES_CHRATR_FONTSIZE
:
1571 ppAttr
= &m_aAttrTab
.pFontHeight
;
1573 case RES_CHRATR_CJK_FONTSIZE
:
1574 ppAttr
= &m_aAttrTab
.pFontHeightCJK
;
1576 case RES_CHRATR_CTL_FONTSIZE
:
1577 ppAttr
= &m_aAttrTab
.pFontHeightCTL
;
1579 case RES_CHRATR_KERNING
:
1580 ppAttr
= &m_aAttrTab
.pKerning
;
1582 case RES_CHRATR_POSTURE
:
1583 ppAttr
= &m_aAttrTab
.pItalic
;
1585 case RES_CHRATR_CJK_POSTURE
:
1586 ppAttr
= &m_aAttrTab
.pItalicCJK
;
1588 case RES_CHRATR_CTL_POSTURE
:
1589 ppAttr
= &m_aAttrTab
.pItalicCTL
;
1591 case RES_CHRATR_UNDERLINE
:
1592 ppAttr
= &m_aAttrTab
.pUnderline
;
1594 case RES_CHRATR_WEIGHT
:
1595 ppAttr
= &m_aAttrTab
.pBold
;
1597 case RES_CHRATR_CJK_WEIGHT
:
1598 ppAttr
= &m_aAttrTab
.pBoldCJK
;
1600 case RES_CHRATR_CTL_WEIGHT
:
1601 ppAttr
= &m_aAttrTab
.pBoldCTL
;
1603 case RES_CHRATR_BACKGROUND
:
1604 ppAttr
= &m_aAttrTab
.pCharBrush
;
1606 case RES_CHRATR_BOX
:
1607 ppAttr
= &m_aAttrTab
.pCharBox
;
1610 case RES_PARATR_LINESPACING
:
1611 ppAttr
= &m_aAttrTab
.pLineSpacing
;
1613 case RES_PARATR_ADJUST
:
1614 ppAttr
= &m_aAttrTab
.pAdjust
;
1618 ppAttr
= &m_aAttrTab
.pLRSpace
;
1621 ppAttr
= &m_aAttrTab
.pULSpace
;
1624 ppAttr
= &m_aAttrTab
.pBox
;
1626 case RES_BACKGROUND
:
1627 ppAttr
= &m_aAttrTab
.pBrush
;
1630 ppAttr
= &m_aAttrTab
.pBreak
;
1633 ppAttr
= &m_aAttrTab
.pPageDesc
;
1635 case RES_PARATR_SPLIT
:
1636 ppAttr
= &m_aAttrTab
.pSplit
;
1638 case RES_PARATR_WIDOWS
:
1639 ppAttr
= &m_aAttrTab
.pWidows
;
1641 case RES_PARATR_ORPHANS
:
1642 ppAttr
= &m_aAttrTab
.pOrphans
;
1645 ppAttr
= &m_aAttrTab
.pKeep
;
1648 case RES_CHRATR_LANGUAGE
:
1649 ppAttr
= &m_aAttrTab
.pLanguage
;
1651 case RES_CHRATR_CJK_LANGUAGE
:
1652 ppAttr
= &m_aAttrTab
.pLanguageCJK
;
1654 case RES_CHRATR_CTL_LANGUAGE
:
1655 ppAttr
= &m_aAttrTab
.pLanguageCTL
;
1659 ppAttr
= &m_aAttrTab
.pDirection
;
1666 void SwHTMLParser::NewStyle()
1670 const HTMLOptions
& rOptions2
= GetOptions();
1671 for (size_t i
= rOptions2
.size(); i
; )
1673 const HTMLOption
& rOption
= rOptions2
[--i
];
1674 if( HTML_O_TYPE
== rOption
.GetToken() )
1675 sType
= rOption
.GetString();
1678 m_bIgnoreRawData
= sType
.getLength() &&
1679 !sType
.getToken(0,';').equalsAscii(sCSS_mimetype
);
1682 void SwHTMLParser::EndStyle()
1684 m_bIgnoreRawData
= false;
1686 if( !m_aStyleSource
.isEmpty() )
1688 m_pCSS1Parser
->ParseStyleSheet( m_aStyleSource
);
1689 m_aStyleSource
.clear();
1693 bool SwHTMLParser::FileDownload( const OUString
& rURL
,
1696 // View wegschmeissen (wegen Reschedule)
1697 SwViewShell
*pOldVSh
= CallEndAction();
1699 // Ein Medium anlegen
1700 SfxMedium
aDLMedium( rURL
, StreamMode::READ
| StreamMode::SHARE_DENYWRITE
);
1702 SvStream
* pStream
= aDLMedium
.GetInStream();
1705 SvMemoryStream aStream
;
1706 aStream
.WriteStream( *pStream
);
1708 aStream
.Seek( STREAM_SEEK_TO_END
);
1709 rStr
= OUString(static_cast<const sal_Char
*>(aStream
.GetData()), aStream
.Tell(),
1713 // wurde abgebrochen?
1714 if( ( m_pDoc
->GetDocShell() && m_pDoc
->GetDocShell()->IsAbortingImport() )
1715 || 1 == m_pDoc
->getReferenceCount() )
1717 // wurde der Import vom SFX abgebrochen?
1718 eState
= SVPAR_ERROR
;
1723 SwViewShell
*const pVSh
= CallStartAction( pOldVSh
);
1724 OSL_ENSURE( pOldVSh
== pVSh
, "FileDownload: SwViewShell changed on us" );
1727 return pStream
!=nullptr;
1730 void SwHTMLParser::InsertLink()
1732 bool bFinishDownload
= false;
1735 OSL_ENSURE( ShouldFinishFileDownload(),
1736 "Pending-Stack ohne File-Download?" );
1738 SwPendingStack
* pTmp
= m_pPendStack
->pNext
;
1739 delete m_pPendStack
;
1740 m_pPendStack
= pTmp
;
1741 OSL_ENSURE( !m_pPendStack
, "Wo kommt der Pending-Stack her?" );
1743 bFinishDownload
= true;
1747 OUString sRel
, sHRef
, sType
;
1749 const HTMLOptions
& rOptions2
= GetOptions();
1750 for (size_t i
= rOptions2
.size(); i
; )
1752 const HTMLOption
& rOption
= rOptions2
[--i
];
1753 switch( rOption
.GetToken() )
1756 sRel
= rOption
.GetString();
1759 sHRef
= URIHelper::SmartRel2Abs( INetURLObject( m_sBaseURL
), rOption
.GetString(), Link
<OUString
*, bool>(), false );
1762 sType
= rOption
.GetString();
1767 if( !sHRef
.isEmpty() && sRel
.equalsIgnoreAsciiCase( "STYLESHEET" ) &&
1768 ( sType
.isEmpty() ||
1769 sType
.getToken(0,';').equalsAscii(sCSS_mimetype
) ) )
1773 // Download des Style-Source starten
1774 StartFileDownload(sHRef
);
1775 if( IsParserWorking() )
1777 // Der Style wurde synchron geladen und wir koennen
1778 // es direkt aufrufen.
1779 bFinishDownload
= true;
1783 // Der Style wird asynchron geladen und ist erst beim
1784 // naechsten Continue-Aufruf da. Wir muessen deshalb einen
1785 // Pending-Stack anlegen, damit wir hierher zurueckkehren
1786 m_pPendStack
= new SwPendingStack( HTML_LINK
, m_pPendStack
);
1791 // File synchron holen
1793 if( FileDownload( sHRef
, sSource
) )
1794 m_pCSS1Parser
->ParseStyleSheet( sSource
);
1799 if( bFinishDownload
)
1802 if( FinishFileDownload( sSource
) && !sSource
.isEmpty() )
1803 m_pCSS1Parser
->ParseStyleSheet( sSource
);
1807 bool SwCSS1Parser::ParseStyleSheet( const OUString
& rIn
)
1809 if( !SvxCSS1Parser::ParseStyleSheet( rIn
) )
1812 SwPageDesc
*pMasterPageDesc
=
1813 pDoc
->getIDocumentStylePoolAccess().GetPageDescFromPool( RES_POOLPAGE_HTML
, false );
1815 SvxCSS1MapEntry
*pPageEntry
= GetPage( aEmptyOUStr
, false );
1818 // @page (wirkt auf alle Seiten, die es schon gibt
1820 SetPageDescAttrs( pMasterPageDesc
, pPageEntry
->GetItemSet(),
1821 pPageEntry
->GetPropertyInfo() );
1823 // Fuer alle anderen Seiten-Vorlagen, die es schon gibt,
1824 // muessen die Attribute auch noch gesetzt werden
1826 SetPageDescAttrs( GetFirstPageDesc(), pPageEntry
->GetItemSet(),
1827 pPageEntry
->GetPropertyInfo() );
1828 SetPageDescAttrs( GetLeftPageDesc(), pPageEntry
->GetItemSet(),
1829 pPageEntry
->GetPropertyInfo() );
1830 SetPageDescAttrs( GetRightPageDesc(), pPageEntry
->GetItemSet(),
1831 pPageEntry
->GetPropertyInfo() );
1835 pPageEntry
= GetPage( "first", true );
1838 SetPageDescAttrs( GetFirstPageDesc(true), pPageEntry
->GetItemSet(),
1839 pPageEntry
->GetPropertyInfo() );
1840 bSetFirstPageDesc
= true;
1843 pPageEntry
= GetPage( "right", true );
1846 SetPageDescAttrs( GetRightPageDesc(true), pPageEntry
->GetItemSet(),
1847 pPageEntry
->GetPropertyInfo() );
1848 bSetRightPageDesc
= true;
1851 pPageEntry
= GetPage( "left", true );
1853 SetPageDescAttrs( GetLeftPageDesc(true), pPageEntry
->GetItemSet(),
1854 pPageEntry
->GetPropertyInfo() );
1859 bool SwHTMLParser::ParseStyleOptions( const OUString
&rStyle
,
1860 const OUString
&rId
,
1861 const OUString
&rClass
,
1862 SfxItemSet
&rItemSet
,
1863 SvxCSS1PropertyInfo
&rPropInfo
,
1864 const OUString
*pLang
,
1865 const OUString
*pDir
)
1869 if( !rClass
.isEmpty() )
1871 OUString
aClass( rClass
);
1872 SwCSS1Parser::GetScriptFromClass( aClass
);
1873 const SvxCSS1MapEntry
*pClass
= m_pCSS1Parser
->GetClass( aClass
);
1876 SvxCSS1Parser::MergeStyles( pClass
->GetItemSet(),
1877 pClass
->GetPropertyInfo(),
1878 rItemSet
, rPropInfo
, false );
1883 if( !rId
.isEmpty() )
1885 const SvxCSS1MapEntry
*pId
= m_pCSS1Parser
->GetId( rId
);
1887 SvxCSS1Parser::MergeStyles( pId
->GetItemSet(),
1888 pId
->GetPropertyInfo(),
1889 rItemSet
, rPropInfo
, !rClass
.isEmpty() );
1890 rPropInfo
.m_aId
= rId
;
1894 if( !rStyle
.isEmpty() )
1896 m_pCSS1Parser
->ParseStyleOption( rStyle
, rItemSet
, rPropInfo
);
1901 rPropInfo
.SetBoxItem( rItemSet
, MIN_BORDER_DIST
);
1903 if( pLang
&& !pLang
->isEmpty() )
1905 LanguageType eLang
= LanguageTag::convertToLanguageTypeWithFallback( *pLang
);
1906 if( LANGUAGE_DONTKNOW
!= eLang
)
1908 SvxLanguageItem
aLang( eLang
, RES_CHRATR_LANGUAGE
);
1909 rItemSet
.Put( aLang
);
1910 aLang
.SetWhich( RES_CHRATR_CJK_LANGUAGE
);
1911 rItemSet
.Put( aLang
);
1912 aLang
.SetWhich( RES_CHRATR_CTL_LANGUAGE
);
1913 rItemSet
.Put( aLang
);
1918 if( pDir
&& !pDir
->isEmpty() )
1920 OUString
aValue( *pDir
);
1921 SvxFrameDirection eDir
= FRMDIR_ENVIRONMENT
;
1922 if (aValue
.equalsIgnoreAsciiCase("LTR"))
1923 eDir
= FRMDIR_HORI_LEFT_TOP
;
1924 else if (aValue
.equalsIgnoreAsciiCase("RTL"))
1925 eDir
= FRMDIR_HORI_RIGHT_TOP
;
1927 if( FRMDIR_ENVIRONMENT
!= eDir
)
1929 SvxFrameDirectionItem
aDir( eDir
, RES_FRAMEDIR
);
1930 rItemSet
.Put( aDir
);
1939 void SwHTMLParser::SetAnchorAndAdjustment( const SfxItemSet
& /*rItemSet*/,
1940 const SvxCSS1PropertyInfo
&rPropInfo
,
1941 SfxItemSet
&rFrameItemSet
)
1943 SwFormatAnchor aAnchor
;
1945 sal_Int16 eHoriOri
= text::HoriOrientation::NONE
;
1946 sal_Int16 eVertOri
= text::VertOrientation::NONE
;
1947 sal_Int16 eHoriRel
= text::RelOrientation::FRAME
;
1948 sal_Int16 eVertRel
= text::RelOrientation::FRAME
;
1949 SwTwips nHoriPos
= 0, nVertPos
= 0;
1950 SwSurround eSurround
= SURROUND_THROUGHT
;
1951 if( SVX_CSS1_POS_ABSOLUTE
== rPropInfo
.m_ePosition
)
1953 if( SVX_CSS1_LTYPE_TWIP
== rPropInfo
.m_eLeftType
&&
1954 SVX_CSS1_LTYPE_TWIP
== rPropInfo
.m_eTopType
)
1956 // Absolut positionierte Objekte sind seitengebunden, wenn
1957 // sie nicht schon in einem Rahmen stehen und sonst
1959 const SwStartNode
*pFlySttNd
=
1960 m_pPam
->GetPoint()->nNode
.GetNode().FindFlyStartNode();
1963 aAnchor
.SetType( FLY_AT_FLY
);
1964 SwPosition
aPos( *pFlySttNd
);
1965 aAnchor
.SetAnchor( &aPos
);
1969 aAnchor
.SetType( FLY_AT_PAGE
);
1970 aAnchor
.SetPageNum( 1 );
1972 nHoriPos
= rPropInfo
.m_nLeft
;
1973 nVertPos
= rPropInfo
.m_nTop
;
1977 aAnchor
.SetType( FLY_AT_PARA
);
1978 aAnchor
.SetAnchor( m_pPam
->GetPoint() );
1979 eVertOri
= text::VertOrientation::TOP
;
1980 eVertRel
= text::RelOrientation::CHAR
;
1981 if( SVX_CSS1_LTYPE_TWIP
== rPropInfo
.m_eLeftType
)
1983 eHoriOri
= text::HoriOrientation::NONE
;
1984 eHoriRel
= text::RelOrientation::PAGE_FRAME
;
1985 nHoriPos
= rPropInfo
.m_nLeft
;
1989 eHoriOri
= text::HoriOrientation::LEFT
;
1990 eHoriRel
= text::RelOrientation::FRAME
; // wird noch umgeschossen
1996 // fliessende Objekte werden Absatzgebunden eingefuegt, wenn
1997 // der Absatz noch leer ist und sonst auto-gebunden.
1998 // Auto-gebundene Rahmen werden zunaechst an der Position davor
1999 // eingefuegt und erst spaeter verschoben.
2000 const sal_Int32 nContent
= m_pPam
->GetPoint()->nContent
.GetIndex();
2003 aAnchor
.SetType( FLY_AT_CHAR
);
2004 m_pPam
->Move( fnMoveBackward
);
2005 eVertOri
= text::VertOrientation::CHAR_BOTTOM
;
2006 eVertRel
= text::RelOrientation::CHAR
;
2010 aAnchor
.SetType( FLY_AT_PARA
);
2011 eVertOri
= text::VertOrientation::TOP
;
2012 eVertRel
= text::RelOrientation::PRINT_AREA
;
2015 aAnchor
.SetAnchor( m_pPam
->GetPoint() );
2018 m_pPam
->Move( fnMoveForward
);
2020 sal_uInt16 nLeftSpace
= 0, nRightSpace
= 0;
2022 GetMarginsFromContextWithNumBul( nLeftSpace
, nRightSpace
, nIndent
);
2024 if( SVX_ADJUST_RIGHT
==rPropInfo
.m_eFloat
)
2026 eHoriOri
= text::HoriOrientation::RIGHT
;
2027 eHoriRel
= nRightSpace
? text::RelOrientation::PRINT_AREA
: text::RelOrientation::FRAME
;
2028 eSurround
= SURROUND_LEFT
;
2032 eHoriOri
= text::HoriOrientation::LEFT
;
2033 eHoriRel
= nLeftSpace
? text::RelOrientation::PRINT_AREA
: text::RelOrientation::FRAME
;
2034 eSurround
= SURROUND_RIGHT
;
2037 rFrameItemSet
.Put( aAnchor
);
2039 // Absolut Positioniert mit Durchlauf
2040 rFrameItemSet
.Put( SwFormatHoriOrient( nHoriPos
, eHoriOri
, eHoriRel
) );
2041 rFrameItemSet
.Put( SwFormatVertOrient( nVertPos
, eVertOri
, eVertRel
) );
2042 rFrameItemSet
.Put( SwFormatSurround( eSurround
) );
2045 void SwHTMLParser::SetVarSize( SfxItemSet
& /*rItemSet*/,
2046 SvxCSS1PropertyInfo
&rPropInfo
,
2047 SfxItemSet
&rFrameItemSet
,
2048 SwTwips nDfltWidth
, sal_uInt8 nDfltPrcWidth
)
2050 SwFrameSize eSize
= ATT_MIN_SIZE
;
2051 SwTwips nWidth
= nDfltWidth
, nHeight
= MINFLY
;
2052 sal_uInt8 nPrcWidth
= nDfltPrcWidth
, nPrcHeight
= 0;
2053 switch( rPropInfo
.m_eWidthType
)
2055 case SVX_CSS1_LTYPE_PERCENTAGE
:
2056 nPrcWidth
= rPropInfo
.m_nWidth
> 0 ? (sal_uInt8
)rPropInfo
.m_nWidth
: 1;
2059 case SVX_CSS1_LTYPE_TWIP
:
2060 nWidth
= rPropInfo
.m_nWidth
> MINFLY
? rPropInfo
.m_nWidth
: MINFLY
;
2066 switch( rPropInfo
.m_eHeightType
)
2068 case SVX_CSS1_LTYPE_PERCENTAGE
:
2069 nPrcHeight
= rPropInfo
.m_nHeight
> 0 ? (sal_uInt8
)rPropInfo
.m_nHeight
: 1;
2071 case SVX_CSS1_LTYPE_TWIP
:
2072 // Netscape und MS-IE interpretieren die Hoehe regelwiedrig
2073 // als Mindest-Hoehe, also machwn wir das auch so.
2074 nHeight
= rPropInfo
.m_nHeight
> MINFLY
? rPropInfo
.m_nHeight
: MINFLY
;
2080 SwFormatFrameSize
aFrameSize( eSize
, nWidth
, nHeight
);
2081 aFrameSize
.SetWidthPercent( nPrcWidth
);
2082 aFrameSize
.SetHeightPercent( nPrcHeight
);
2083 rFrameItemSet
.Put( aFrameSize
);
2086 void SwHTMLParser::SetFrameFormatAttrs( SfxItemSet
&rItemSet
,
2087 SvxCSS1PropertyInfo
& /*rPropInfo*/,
2088 HtmlFrameFormatFlags nFlags
,
2089 SfxItemSet
&rFrameItemSet
)
2091 const SfxPoolItem
*pItem
;
2092 if( (nFlags
& HtmlFrameFormatFlags::Box
) &&
2093 SfxItemState::SET
==rItemSet
.GetItemState( RES_BOX
, true, &pItem
) )
2095 if( nFlags
& HtmlFrameFormatFlags::Padding
)
2097 SvxBoxItem
aBoxItem( *static_cast<const SvxBoxItem
*>(pItem
) );
2098 // reset all 4 sides to 0
2099 aBoxItem
.SetAllDistances(0);
2100 rFrameItemSet
.Put( aBoxItem
);
2104 rFrameItemSet
.Put( *pItem
);
2106 rItemSet
.ClearItem( RES_BOX
);
2109 if( (nFlags
& HtmlFrameFormatFlags::Background
) &&
2110 SfxItemState::SET
==rItemSet
.GetItemState( RES_BACKGROUND
, true, &pItem
) )
2112 rFrameItemSet
.Put( *pItem
);
2113 rItemSet
.ClearItem( RES_BACKGROUND
);
2116 if( (nFlags
& HtmlFrameFormatFlags::Direction
) &&
2117 SfxItemState::SET
==rItemSet
.GetItemState( RES_FRAMEDIR
, true, &pItem
) )
2119 rFrameItemSet
.Put( *pItem
);
2120 rItemSet
.ClearItem( RES_FRAMEDIR
);
2124 HTMLAttrContext
*SwHTMLParser::PopContext( sal_uInt16 nToken
)
2126 HTMLAttrContexts::size_type nPos
= m_aContexts
.size();
2127 if( nPos
<= m_nContextStMin
)
2130 bool bFound
= 0==nToken
;
2133 // Stack-Eintrag zu dem Token suchen
2134 while( nPos
> m_nContextStMin
)
2136 sal_uInt16 nCntxtToken
= m_aContexts
[--nPos
]->GetToken();
2137 if( nCntxtToken
== nToken
)
2142 else if( nCntxtToken
== 0 ) // 0 als Token kommt nicht vor
2153 HTMLAttrContext
*pCntxt
= nullptr;
2156 pCntxt
= m_aContexts
[nPos
];
2157 m_aContexts
.erase( m_aContexts
.begin() + nPos
);
2163 bool SwHTMLParser::GetMarginsFromContext( sal_uInt16
& nLeft
,
2166 bool bIgnoreTopContext
) const
2168 HTMLAttrContexts::size_type nPos
= m_aContexts
.size();
2169 if( bIgnoreTopContext
)
2177 while( nPos
> m_nContextStAttrMin
)
2179 const HTMLAttrContext
*pCntxt
= m_aContexts
[--nPos
];
2180 if( pCntxt
->IsLRSpaceChanged() )
2182 pCntxt
->GetMargins( nLeft
, nRight
, nIndent
);
2190 void SwHTMLParser::GetMarginsFromContextWithNumBul( sal_uInt16
& nLeft
,
2192 short& nIndent
) const
2194 GetMarginsFromContext( nLeft
, nRight
, nIndent
);
2195 const SwHTMLNumRuleInfo
& rInfo
= const_cast<SwHTMLParser
*>(this)->GetNumInfo();
2196 if( rInfo
.GetDepth() )
2198 sal_uInt8 nLevel
= (sal_uInt8
)( (rInfo
.GetDepth() <= MAXLEVEL
? rInfo
.GetDepth()
2200 const SwNumFormat
& rNumFormat
= rInfo
.GetNumRule()->Get(nLevel
);
2201 nLeft
= nLeft
+ rNumFormat
.GetAbsLSpace();
2202 nIndent
= rNumFormat
.GetFirstLineOffset();
2206 void SwHTMLParser::GetULSpaceFromContext( sal_uInt16
& nUpper
,
2207 sal_uInt16
& nLower
) const
2209 sal_uInt16 nDfltColl
= 0;
2210 OUString aDfltClass
;
2212 HTMLAttrContexts::size_type nPos
= m_aContexts
.size();
2213 while( nPos
> m_nContextStAttrMin
)
2215 const HTMLAttrContext
*pCntxt
= m_aContexts
[--nPos
];
2216 if( pCntxt
->IsULSpaceChanged() )
2218 pCntxt
->GetULSpace( nUpper
, nLower
);
2221 else if( !nDfltColl
)
2223 nDfltColl
= pCntxt
->GetDfltTextFormatColl();
2225 aDfltClass
= pCntxt
->GetClass();
2230 nDfltColl
= RES_POOLCOLL_TEXT
;
2232 const SwTextFormatColl
*pColl
=
2233 m_pCSS1Parser
->GetTextFormatColl( nDfltColl
, aDfltClass
);
2234 const SvxULSpaceItem
& rULSpace
= pColl
->GetULSpace();
2235 nUpper
= rULSpace
.GetUpper();
2236 nLower
= rULSpace
.GetLower();
2239 void SwHTMLParser::EndContextAttrs( HTMLAttrContext
*pContext
)
2241 HTMLAttrs
&rAttrs
= pContext
->GetAttrs();
2242 for( auto pAttr
: rAttrs
)
2244 if( RES_PARATR_DROP
==pAttr
->GetItem().Which() )
2246 // Fuer DropCaps noch die Anzahl der Zeichen anpassen. Wenn
2247 // es am Ende 0 sind, wird das Attribut invalidiert und dann
2248 // von SetAttr_ gar nicht erst gesetzt.
2249 sal_Int32 nChars
= m_pPam
->GetPoint()->nContent
.GetIndex();
2251 pAttr
->Invalidate();
2252 else if( nChars
> MAX_DROPCAP_CHARS
)
2253 nChars
= MAX_DROPCAP_CHARS
;
2254 static_cast<SwFormatDrop
&>(pAttr
->GetItem()).GetChars() = (sal_uInt8
)nChars
;
2261 void SwHTMLParser::InsertParaAttrs( const SfxItemSet
& rItemSet
)
2263 SfxItemIter
aIter( rItemSet
);
2265 const SfxPoolItem
*pItem
= aIter
.FirstItem();
2268 // den zu dem Item gehoehrenden Tabellen-Eintrag ermitteln ...
2269 sal_uInt16 nWhich
= pItem
->Which();
2270 HTMLAttr
**ppAttr
= GetAttrTabEntry( nWhich
);
2274 NewAttr( ppAttr
, *pItem
);
2275 if( RES_PARATR_BEGIN
> nWhich
)
2276 (*ppAttr
)->SetLikePara();
2277 m_aParaAttrs
.push_back( *ppAttr
);
2278 bool bSuccess
= EndAttr( *ppAttr
, false );
2280 m_aParaAttrs
.pop_back();
2283 pItem
= aIter
.NextItem();
2287 static void lcl_swcss1_setEncoding( SwFormat
& rFormat
, rtl_TextEncoding eEnc
)
2289 if( RTL_TEXTENCODING_DONTKNOW
== eEnc
)
2292 const SfxItemSet
& rItemSet
= rFormat
.GetAttrSet();
2293 static const sal_uInt16 aWhichIds
[3] = { RES_CHRATR_FONT
, RES_CHRATR_CJK_FONT
,
2294 RES_CHRATR_CTL_FONT
};
2295 const SfxPoolItem
*pItem
;
2296 for(sal_uInt16 i
: aWhichIds
)
2298 if( SfxItemState::SET
== rItemSet
.GetItemState( i
, false,&pItem
) )
2300 const SvxFontItem
& rFont
= *static_cast<const SvxFontItem
*>(pItem
);
2301 if( RTL_TEXTENCODING_SYMBOL
!= rFont
.GetCharSet() )
2303 SvxFontItem
aFont( rFont
.GetFamily(), rFont
.GetFamilyName(),
2304 rFont
.GetStyleName(), rFont
.GetPitch(),
2306 rFormat
.SetFormatAttr( aFont
);
2312 void SwCSS1Parser::SetDfltEncoding( rtl_TextEncoding eEnc
)
2314 if( eEnc
!= GetDfltEncoding() )
2318 // Set new encoding as pool default
2319 static const sal_uInt16 aWhichIds
[3] = { RES_CHRATR_FONT
, RES_CHRATR_CJK_FONT
,
2320 RES_CHRATR_CTL_FONT
};
2321 for(sal_uInt16 i
: aWhichIds
)
2323 const SvxFontItem
& rDfltFont
=
2324 static_cast<const SvxFontItem
&>(pDoc
->GetDefault( i
));
2325 SvxFontItem
aFont( rDfltFont
.GetFamily(),
2326 rDfltFont
.GetFamilyName(),
2327 rDfltFont
.GetStyleName(),
2328 rDfltFont
.GetPitch(),
2330 pDoc
->SetDefault( aFont
);
2333 // Change all paragraph styles that do specify a font.
2334 for( auto pTextFormatColl
: *pDoc
->GetTextFormatColls() )
2335 lcl_swcss1_setEncoding( *pTextFormatColl
, eEnc
);
2337 // Change all character styles that do specify a font.
2338 for( auto pCharFormat
: *pDoc
->GetCharFormats() )
2339 lcl_swcss1_setEncoding( *pCharFormat
, eEnc
);
2342 SvxCSS1Parser::SetDfltEncoding( eEnc
);
2346 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */