1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: swhtml.cxx,v $
10 * $Revision: 1.51.98.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
35 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
36 #include <com/sun/star/document/XDocumentProperties.hpp>
37 #include <com/sun/star/i18n/ScriptType.hpp>
42 #include <hintids.hxx>
44 #define _SVSTDARR_STRINGS
45 #include <svtools/svstdarr.hxx>
46 #include <svtools/stritem.hxx>
47 #include <svtools/imap.hxx>
48 #include <svtools/htmltokn.h>
49 #include <svtools/htmlkywd.hxx>
50 #include <svtools/ctrltool.hxx>
51 #include <svtools/pathoptions.hxx>
52 #include <vcl/svapp.hxx>
53 #include <vcl/wrkwin.hxx>
54 #include <sfx2/fcontnr.hxx>
55 #include <sfx2/docfile.hxx>
57 #include <svx/htmlcfg.hxx>
58 #include <svx/linkmgr.hxx>
59 #include <svx/kernitem.hxx>
60 #include <svx/boxitem.hxx>
61 #include <svx/fhgtitem.hxx>
62 #include <svx/brkitem.hxx>
63 #include <svx/postitem.hxx>
64 #include <svx/wghtitem.hxx>
65 #include <svx/crsditem.hxx>
66 #include <svx/udlnitem.hxx>
67 #include <svx/escpitem.hxx>
68 #include <svx/blnkitem.hxx>
69 #include <svx/ulspitem.hxx>
70 #include <svx/colritem.hxx>
71 #include <svx/fontitem.hxx>
72 #include <svx/adjitem.hxx>
73 #include <svx/lrspitem.hxx>
74 #include <svx/protitem.hxx>
75 #include <svx/flstitem.hxx>
79 #include <charatr.hxx>
81 #include <fmtpdsc.hxx>
82 #include <fmthbsh.hxx>
84 #include <fmtanchr.hxx>
85 #include <fmtsrnd.hxx>
86 #include <fmtfsize.hxx>
87 #include <fmtclds.hxx>
88 #include <fchrfmt.hxx>
89 #include <fmtinfmt.hxx>
91 #include <docstat.hxx>
95 #include <mdiexp.hxx> // ...Percent()
97 #include <poolfmt.hxx>
98 #include <pagedesc.hxx>
99 #include <IMark.hxx> // fuer SwBookmark ...
101 #include <editsh.hxx> // fuer Start/EndAction
102 #include <docufld.hxx>
103 #include <swcss1.hxx>
104 #include <htmlvsh.hxx>
105 #include <fltini.hxx>
106 #include <htmltbl.hxx>
107 #include <htmlnum.hxx>
108 #include <swhtml.hxx>
109 #include <linkenum.hxx>
110 #include <breakit.hxx>
111 #include <SwAppletImpl.hxx>
113 #include <sfx2/viewfrm.hxx>
116 #include <statstr.hrc> // ResId fuer Statusleiste
120 #define FONTSIZE_MASK 7
121 #define FONTCOLOR_MASK (1<<15)
122 #define FONT_MASK (1<<14)
124 #define HTML_ESC_PROP 80
125 #define HTML_ESC_SUPER DFLT_ESC_SUPER
126 #define HTML_ESC_SUB DFLT_ESC_SUB
128 #define HTML_SPTYPE_NONE 0
129 #define HTML_SPTYPE_BLOCK 1
130 #define HTML_SPTYPE_HORI 2
131 #define HTML_SPTYPE_VERT 3
133 #ifndef TOOLS_CONSTASCII_STRINGPARAM
134 #define TOOLS_CONSTASCII_STRINGPARAM( constAsciiStr ) constAsciiStr, sizeof( constAsciiStr )-1
137 using namespace ::com::sun::star
;
139 // <P ALIGN=xxx>, <Hn ALIGN=xxx>, <TD ALIGN=xxx> usw.
140 HTMLOptionEnum __FAR_DATA aHTMLPAlignTable
[] =
142 { OOO_STRING_SVTOOLS_HTML_AL_left
, SVX_ADJUST_LEFT
},
143 { OOO_STRING_SVTOOLS_HTML_AL_center
, SVX_ADJUST_CENTER
},
144 { OOO_STRING_SVTOOLS_HTML_AL_middle
, SVX_ADJUST_CENTER
}, // Netscape
145 { OOO_STRING_SVTOOLS_HTML_AL_right
, SVX_ADJUST_RIGHT
},
146 { OOO_STRING_SVTOOLS_HTML_AL_justify
, SVX_ADJUST_BLOCK
},
147 { OOO_STRING_SVTOOLS_HTML_AL_char
, SVX_ADJUST_LEFT
},
152 static HTMLOptionEnum __FAR_DATA aHTMLSpacerTypeTable
[] =
154 { OOO_STRING_SVTOOLS_HTML_SPTYPE_block
, HTML_SPTYPE_BLOCK
},
155 { OOO_STRING_SVTOOLS_HTML_SPTYPE_horizontal
, HTML_SPTYPE_HORI
},
156 { OOO_STRING_SVTOOLS_HTML_SPTYPE_vertical
, HTML_SPTYPE_VERT
},
160 SV_IMPL_PTRARR( _HTMLAttrs
, _HTMLAttrPtr
)
162 HTMLReader::HTMLReader()
164 bTmplBrowseMode
= TRUE
;
167 String
HTMLReader::GetTemplateName() const
170 String::CreateFromAscii(TOOLS_CONSTASCII_STRINGPARAM("internal")) );
171 sTemplate
+= INET_PATH_TOKEN
;
172 sTemplate
.AppendAscii( TOOLS_CONSTASCII_STRINGPARAM("html") );
173 String
sTemplateWithoutExt( sTemplate
);
174 #ifndef MAC_WITHOUT_EXT
175 // --> OD 2005-01-26 - first search for OpenDocument Writer/Web template
176 sTemplate
.AppendAscii( TOOLS_CONSTASCII_STRINGPARAM(".oth") );
180 SvtPathOptions aPathOpt
;
181 // OpenDocument Writer/Web template (extension .oth)
182 BOOL bSet
= aPathOpt
.SearchFile( sTemplate
, SvtPathOptions::PATH_TEMPLATE
);
184 #ifndef MAC_WITHOUT_EXT
187 // 6.0 (extension .stw)
188 sTemplate
= sTemplateWithoutExt
;
189 // --> OD 2005-01-26 - no OpenDocument Writer/Web template found.
190 // search for OpenOffice.org Writer/Web template
191 sTemplate
.AppendAscii( TOOLS_CONSTASCII_STRINGPARAM(".stw") );
193 bSet
= aPathOpt
.SearchFile( sTemplate
, SvtPathOptions::PATH_TEMPLATE
);
201 "Die html.vor befindet sich nicht mehr im definierten Directory!");
207 int HTMLReader::SetStrmStgPtr()
209 ASSERT( pMedium
, "Wo ist das Medium??" );
211 if( pMedium
->IsRemote() || !pMedium
->IsStorage() )
213 pStrm
= pMedium
->GetInStream();
220 // Aufruf fuer die allg. Reader-Schnittstelle
221 ULONG
HTMLReader::Read( SwDoc
&rDoc
, const String
& rBaseURL
, SwPaM
&rPam
, const String
& rName
)
225 ASSERT( pStrm
, "HTML-Read ohne Stream" );
226 return ERR_SWG_READ_ERROR
;
231 Reader::SetNoOutlineNum( rDoc
);
232 Reader::ResetFrmFmts( rDoc
);
234 // Die HTML-Seitenvorlage setzen, wenn des kein HTML-Dokument ist,
235 // sonst ist sie schon gesetzt.
236 if( !rDoc
.get(IDocumentSettingAccess::HTML_MODE
) )
238 rDoc
.Insert( rPam
, SwFmtPageDesc(
239 rDoc
.GetPageDescFromPool( RES_POOLPAGE_HTML
, false )), 0 );
243 // damit keiner das Doc klaut!
246 SvParserRef xParser
= new SwHTMLParser( &rDoc
, rPam
, *pStrm
,
247 rName
, rBaseURL
, !bInsertMode
, pMedium
,
249 bIgnoreHTMLComments
);
251 SvParserState eState
= xParser
->CallParser();
253 if( SVPAR_PENDING
== eState
)
255 else if( SVPAR_ACCEPTED
!= eState
)
257 String
sErr( String::CreateFromInt32((sal_Int32
)xParser
->GetLineNr()));
259 sErr
+= String::CreateFromInt32((sal_Int32
)xParser
->GetLinePos());
261 // den Stream als Fehlernummer Transporter benutzen
262 nRet
= *new StringErrorInfo( ERR_FORMAT_ROWCOL
, sErr
,
263 ERRCODE_BUTTON_OK
| ERRCODE_MSG_ERROR
);
273 SwHTMLParser::SwHTMLParser( SwDoc
* pD
, const SwPaM
& rCrsr
, SvStream
& rIn
,
275 const String
& rBaseURL
,
277 SfxMedium
* pMed
, BOOL bReadUTF8
,
278 sal_Bool bNoHTMLComments
)
279 : SfxHTMLParser( rIn
, static_cast< BOOL
>(bReadNewDoc
), pMed
),
281 aPathToFile( rPath
),
282 sBaseURL( rBaseURL
),
285 pNumRuleInfo( new SwHTMLNumRuleInfo
),
288 pActionViewShell( 0 ),
296 pFootEndNoteImpl( 0 ),
297 nScriptStartLineNr( 0 ),
301 nFontStHeadStart( 0 ),
303 nMissingImgMaps( 0 ),
305 // --> OD 2007-10-26 #i83625#
307 nContextStAttrMin( 0 ),
310 eJumpTo( JUMPTO_NONE
),
314 eParaAdjust( SVX_ADJUST_END
),
315 bDocInitalized( FALSE
),
316 bSetModEnabled( FALSE
),
317 bInFloatingFrame( FALSE
),
319 bCallNextToken( FALSE
),
320 bIgnoreRawData( FALSE
),
321 bNoParSpace( FALSE
),
324 bUpdateDocStat( FALSE
),
325 bFixSelectWidth( FALSE
),
326 bFixSelectHeight( FALSE
),
329 bInFootEndNoteAnchor( FALSE
),
330 bInFootEndNoteSymbol( FALSE
),
331 // bIgnoreHTMLComments( bNoHTMLComments )
332 bIgnoreHTMLComments( bNoHTMLComments
),
333 bRemoveHidden( FALSE
),
337 bUpperSpace
= bViewCreated
= bChkJumpMark
=
340 eScriptLang
= HTML_SL_UNKNOWN
;
341 bAnyStarBasic
= TRUE
;
343 pPam
= new SwPaM( *rCrsr
.GetPoint() );
344 memset( &aAttrTab
, 0, sizeof( _HTMLAttrTable
));
346 // Die Font-Groessen 1-7 aus der INI-Datei lesen
347 SvxHtmlOptions
* pHtmlOptions
= SvxHtmlOptions::Get();
348 aFontHeights
[0] = pHtmlOptions
->GetFontSize( 0 ) * 20;
349 aFontHeights
[1] = pHtmlOptions
->GetFontSize( 1 ) * 20;
350 aFontHeights
[2] = pHtmlOptions
->GetFontSize( 2 ) * 20;
351 aFontHeights
[3] = pHtmlOptions
->GetFontSize( 3 ) * 20;
352 aFontHeights
[4] = pHtmlOptions
->GetFontSize( 4 ) * 20;
353 aFontHeights
[5] = pHtmlOptions
->GetFontSize( 5 ) * 20;
354 aFontHeights
[6] = pHtmlOptions
->GetFontSize( 6 ) * 20;
356 bKeepUnknown
= pHtmlOptions
->IsImportUnknown();
360 SvxFontHeightItem
aFontHeight(aFontHeights
[2], 100, RES_CHRATR_FONTSIZE
);
361 pDoc
->SetDefault( aFontHeight
);
362 aFontHeight
.SetWhich( RES_CHRATR_CJK_FONTSIZE
);
363 pDoc
->SetDefault( aFontHeight
);
364 aFontHeight
.SetWhich( RES_CHRATR_CTL_FONTSIZE
);
365 pDoc
->SetDefault( aFontHeight
);
368 // Waehrend des Imports in den HTML-Modus schalten, damit die
369 // richrigen Vorlagen angelegt werden
370 bOldIsHTMLMode
= pDoc
->get(IDocumentSettingAccess::HTML_MODE
);
371 pDoc
->set(IDocumentSettingAccess::HTML_MODE
, true);
373 pCSS1Parser
= new SwCSS1Parser( pDoc
, aFontHeights
, sBaseURL
, IsNewDoc() );
374 pCSS1Parser
->SetIgnoreFontFamily( pHtmlOptions
->IsIgnoreFontFamily() );
378 SetSrcEncoding( RTL_TEXTENCODING_UTF8
);
382 SwDocShell
*pDocSh
= pDoc
->GetDocShell();
383 SvKeyValueIterator
*pHeaderAttrs
=
384 pDocSh
->GetHeaderAttributes();
386 SetEncodingByHTTPHeader( pHeaderAttrs
);
388 pCSS1Parser
->SetDfltEncoding( gsl_getSystemTextEncoding() );
390 // Timer nur bei ganz normalen Dokumenten aufsetzen!
391 SwDocShell
* pDocSh
= pDoc
->GetDocShell();
394 bViewCreated
= TRUE
; // nicht, synchron laden
396 // es ist ein Sprungziel vorgegeben.
400 sJmpMark
= pMed
->GetURLObject().GetMark();
403 eJumpTo
= JUMPTO_MARK
;
405 xub_StrLen nLastPos
, nPos
= 0;
406 while( STRING_NOTFOUND
!= ( nLastPos
=
407 sJmpMark
.Search( cMarkSeperator
, nPos
+ 1 )) )
410 if( nPos
&& ( sCmp
= sJmpMark
.Copy( nPos
+ 1 ) ).
411 EraseAllChars().Len() )
414 if( sCmp
.EqualsAscii( pMarkToRegion
) )
415 eJumpTo
= JUMPTO_REGION
;
416 else if( sCmp
.EqualsAscii( pMarkToTable
) )
417 eJumpTo
= JUMPTO_TABLE
;
418 else if( sCmp
.EqualsAscii( pMarkToGraphic
) )
419 eJumpTo
= JUMPTO_GRAPHIC
;
420 else if( sCmp
.EqualsAscii( pMarkToOutline
) ||
421 sCmp
.EqualsAscii( pMarkToText
) ||
422 sCmp
.EqualsAscii( pMarkToFrame
) )
423 eJumpTo
= JUMPTO_NONE
; // das ist nichts gueltiges!
425 // ansonsten ist das ein normaler (Book)Mark
431 sJmpMark
.Erase( nPos
);
432 if( !sJmpMark
.Len() )
433 eJumpTo
= JUMPTO_NONE
;
439 __EXPORT
SwHTMLParser::~SwHTMLParser()
442 ASSERT( !nContinue
, "DTOR im Continue - Das geht schief!!!" );
444 BOOL bAsync
= pDoc
->IsInLoadAsynchron();
445 pDoc
->SetInLoadAsynchron( FALSE
);
446 pDoc
->set(IDocumentSettingAccess::HTML_MODE
, bOldIsHTMLMode
);
448 if( pDoc
->GetDocShell() && nEventId
)
449 Application::RemoveUserEvent( nEventId
);
451 // das DocumentDetected kann ggfs. die DocShells loeschen, darum nochmals
453 if( pDoc
->GetDocShell() )
455 // Gelinkte Bereiche updaten
456 USHORT nLinkMode
= pDoc
->getLinkUpdateMode( true );
457 if( nLinkMode
!= NEVER
&& bAsync
&&
458 SFX_CREATE_MODE_INTERNAL
!=pDoc
->GetDocShell()->GetCreateMode() )
459 pDoc
->GetLinkManager().UpdateAllLinks( nLinkMode
== MANUAL
,
462 if ( pDoc
->GetDocShell()->IsLoading() )
464 // --> OD 2006-11-07 #i59688#
465 pDoc
->GetDocShell()->LoadingFinished();
471 if( aSetAttrTab
.Count() )
473 ASSERT( !aSetAttrTab
.Count(),"Es stehen noch Attribute auf dem Stack" );
474 aSetAttrTab
.DeleteAndDestroy( 0, aSetAttrTab
.Count() );
481 DeleteFootEndNoteImpl();
483 ASSERT( !pTable
, "Es existiert noch eine offene Tabelle" );
488 "SwHTMLParser::~SwHTMLParser: Hier sollte es keinen Pending-Stack mehr geben" );
491 SwPendingStack
* pTmp
= pPendStack
;
492 pPendStack
= pPendStack
->pNext
;
497 if( !pDoc
->release() )
499 // keiner will mehr das Doc haben, also weg damit
504 if ( pTempViewFrame
)
506 pTempViewFrame
->DoClose();
508 // the temporary view frame is hidden, so the hidden flag might need to be removed
509 if ( bRemoveHidden
&& pDoc
&& pDoc
->GetDocShell() && pDoc
->GetDocShell()->GetMedium() )
510 pDoc
->GetDocShell()->GetMedium()->GetItemSet()->ClearItem( SID_HIDDEN
);
514 IMPL_LINK( SwHTMLParser
, AsyncCallback
, void*, /*pVoid*/ )
518 // --> FME 2005-08-18 #i47907# If the document has already been destructed,
519 // the parser should be aware of this:
520 if( ( pDoc
->GetDocShell() && pDoc
->GetDocShell()->IsAbortingImport() )
521 || 1 == pDoc
->getReferenceCount() )
523 // wurde der Import vom SFX abgebrochen?
524 eState
= SVPAR_ERROR
;
528 GetAsynchCallLink().Call(0);
532 SvParserState __EXPORT
SwHTMLParser::CallParser()
534 // einen temporaeren Index anlegen, auf Pos 0 so wird er nicht bewegt!
535 pSttNdIdx
= new SwNodeIndex( pDoc
->GetNodes() );
536 if( !IsNewDoc() ) // in ein Dokument einfuegen ?
538 const SwPosition
* pPos
= pPam
->GetPoint();
540 pDoc
->SplitNode( *pPos
, false );
542 *pSttNdIdx
= pPos
->nNode
.GetIndex()-1;
543 pDoc
->SplitNode( *pPos
, false );
545 SwPaM
aInsertionRangePam( *pPos
);
547 pPam
->Move( fnMoveBackward
);
549 // #106634# split any redline over the insertion point
550 aInsertionRangePam
.SetMark();
551 *aInsertionRangePam
.GetPoint() = *pPam
->GetPoint();
552 aInsertionRangePam
.Move( fnMoveBackward
);
553 pDoc
->SplitRedline( aInsertionRangePam
);
555 pDoc
->SetTxtFmtColl( *pPam
,
556 pCSS1Parser
->GetTxtCollFromPool( RES_POOLCOLL_STANDARD
));
563 nEventId
= Application::PostUserEvent( LINK( this, SwHTMLParser
, AsyncCallback
), 0 );
572 // Laufbalken anzeigen
573 else if( !GetMedium() || !GetMedium()->IsRemote() )
575 rInput
.Seek(STREAM_SEEK_TO_END
);
577 ::StartProgress( STR_STATSTR_W4WREAD
, 0, rInput
.Tell(),
578 pDoc
->GetDocShell() );
579 rInput
.Seek(STREAM_SEEK_TO_BEGIN
);
583 SwPageDesc
& rDesc
= pDoc
->_GetPageDesc( 0 );
586 SvParserState eRet
= HTMLParser::CallParser();
590 void __EXPORT
SwHTMLParser::Continue( int nToken
)
593 ASSERT( !nContinue
, "Continue im Continue - Das sollte doch nicht sein, oder?" );
597 // Wenn der Import (vom SFX) abgebrochen wurde, wird ein Fehler
598 // gesetzt aber trotzdem noch weiter gemacht, damit vernuenftig
600 ASSERT( SVPAR_ERROR
!=eState
,
601 "SwHTMLParser::Continue: bereits ein Fehler gesetzt" );
602 if( pDoc
->GetDocShell() && pDoc
->GetDocShell()->IsAbortingImport() )
603 eState
= SVPAR_ERROR
;
605 // Die ViewShell vom Dokument holen, merken und als aktuelle setzen.
606 ViewShell
*pInitVSh
= CallStartAction();
608 if( SVPAR_ERROR
!= eState
&& GetMedium() && !bViewCreated
)
610 // Beim ersten Aufruf erstmal returnen, Doc anzeigen
611 // und auf Timer Callback warten.
612 // An dieser Stelle wurde im CallParser gerade mal ein Zeichen
613 // gelesen und ein SaveState(0) gerufen.
614 eState
= SVPAR_PENDING
;
616 pDoc
->SetInLoadAsynchron( TRUE
);
625 bSetModEnabled
= FALSE
;
626 if( pDoc
->GetDocShell() &&
627 0 != (bSetModEnabled
= pDoc
->GetDocShell()->IsEnableSetModified()) )
629 pDoc
->GetDocShell()->EnableSetModified( FALSE
);
632 // waehrend des einlesens kein OLE-Modified rufen
633 Link
aOLELink( pDoc
->GetOle2Link() );
634 pDoc
->SetOle2Link( Link() );
636 BOOL bModified
= pDoc
->IsModified();
637 BOOL bWasUndo
= pDoc
->DoesUndo();
638 pDoc
->DoUndo( FALSE
);
640 // Wenn der Import abgebrochen wird, kein Continue mehr rufen.
641 // Falls ein Pending-Stack existiert aber durch einen Aufruf
642 // von NextToken dafuer sorgen, dass der Pending-Stack noch
644 if( SVPAR_ERROR
== eState
)
646 ASSERT( !pPendStack
|| pPendStack
->nToken
,
647 "SwHTMLParser::Continue: Pending-Stack ohne Token" );
648 if( pPendStack
&& pPendStack
->nToken
)
649 NextToken( pPendStack
->nToken
);
651 "SwHTMLParser::Continue: Es gibt wieder einen Pend-Stack" );
655 HTMLParser::Continue( pPendStack
? pPendStack
->nToken
: nToken
);
658 // Laufbalken wieder abschalten
659 EndProgress( pDoc
->GetDocShell() );
661 BOOL bLFStripped
= FALSE
;
662 if( SVPAR_PENDING
!= GetStatus() )
664 // noch die letzten Attribute setzen
666 if( aScriptSource
.Len() )
668 SwScriptFieldType
*pType
=
669 (SwScriptFieldType
*)pDoc
->GetSysFldType( RES_SCRIPTFLD
);
671 SwScriptField
aFld( pType
, aScriptType
, aScriptSource
,
673 InsertAttr( SwFmtFld( aFld
) );
678 if( pAppletImpl
->GetApplet().is() )
684 // ggf. ein noch vorhandes LF hinter dem letzen Absatz entfernen
686 bLFStripped
= StripTrailingLF() > 0;
688 // noch offene Nummerierungen beenden.
689 while( GetNumInfo().GetNumRule() )
692 ASSERT( !nContextStMin
, "Es gibt geschuetzte Kontexte" );
694 while( aContexts
.Count() )
696 _HTMLAttrContext
*pCntxt
= PopContext();
699 EndContext( pCntxt
);
704 if( aParaAttrs
.Count() )
705 aParaAttrs
.Remove( 0, aParaAttrs
.Count() );
709 // Noch die erst verzoegert gesetzten Styles setzen
710 pCSS1Parser
->SetDelayedStyles();
713 // den Start wieder korrigieren
714 if( !IsNewDoc() && pSttNdIdx
->GetIndex() )
716 SwTxtNode
* pTxtNode
= pSttNdIdx
->GetNode().GetTxtNode();
717 SwNodeIndex
aNxtIdx( *pSttNdIdx
);
718 if( pTxtNode
&& pTxtNode
->CanJoinNext( &aNxtIdx
))
720 xub_StrLen nStt
= pTxtNode
->GetTxt().Len();
721 // wenn der Cursor noch in dem Node steht, dann setze in an das Ende
722 if( pPam
->GetPoint()->nNode
== aNxtIdx
)
724 pPam
->GetPoint()->nNode
= *pSttNdIdx
;
725 pPam
->GetPoint()->nContent
.Assign( pTxtNode
, nStt
);
729 // !!! sollte nicht moeglich sein, oder ??
730 ASSERT( pSttNdIdx
->GetIndex()+1 != pPam
->GetBound( TRUE
).nNode
.GetIndex(),
731 "Pam.Bound1 steht noch im Node" );
732 ASSERT( pSttNdIdx
->GetIndex()+1 != pPam
->GetBound( FALSE
).nNode
.GetIndex(),
733 "Pam.Bound2 steht noch im Node" );
735 if( pSttNdIdx
->GetIndex()+1 == pPam
->GetBound( TRUE
).nNode
.GetIndex() )
737 xub_StrLen nCntPos
= pPam
->GetBound( TRUE
).nContent
.GetIndex();
738 pPam
->GetBound( TRUE
).nContent
.Assign( pTxtNode
,
739 pTxtNode
->GetTxt().Len() + nCntPos
);
741 if( pSttNdIdx
->GetIndex()+1 == pPam
->GetBound( FALSE
).nNode
.GetIndex() )
743 xub_StrLen nCntPos
= pPam
->GetBound( FALSE
).nContent
.GetIndex();
744 pPam
->GetBound( FALSE
).nContent
.Assign( pTxtNode
,
745 pTxtNode
->GetTxt().Len() + nCntPos
);
748 // Zeichen Attribute beibehalten!
749 SwTxtNode
* pDelNd
= aNxtIdx
.GetNode().GetTxtNode();
750 if( pTxtNode
->GetTxt().Len() )
751 pDelNd
->FmtToTxtAttr( pTxtNode
);
753 pTxtNode
->ChgFmtColl( pDelNd
->GetTxtColl() );
754 pTxtNode
->JoinNext();
759 if( SVPAR_ACCEPTED
== eState
)
761 if( nMissingImgMaps
)
763 // es fehlen noch ein paar Image-Map zuordungen.
764 // vielleicht sind die Image-Maps ja jetzt da?
768 // jetzt noch den letzten ueberfluessigen Absatz loeschen
769 SwPosition
* pPos
= pPam
->GetPoint();
770 if( !pPos
->nContent
.GetIndex() && !bLFStripped
)
773 ULONG nNodeIdx
= pPos
->nNode
.GetIndex();
775 BOOL bHasFlysOrMarks
=
776 HasCurrentParaFlys() || HasCurrentParaBookmarks( TRUE
);
780 const SwNode
*pPrev
= pDoc
->GetNodes()[nNodeIdx
-1];
781 if( !pPam
->GetPoint()->nContent
.GetIndex() &&
782 ( pPrev
->IsCntntNode() ||
783 (pPrev
->IsEndNode() &&
784 pPrev
->StartOfSectionNode()->IsSectionNode()) ) )
786 SwCntntNode
* pCNd
= pPam
->GetCntntNode();
787 if( pCNd
&& pCNd
->StartOfSectionIndex()+2 <
788 pCNd
->EndOfSectionIndex() && !bHasFlysOrMarks
)
790 ViewShell
*pVSh
= CheckActionViewShell();
791 SwCrsrShell
*pCrsrSh
= pVSh
&& pVSh
->ISA(SwCrsrShell
)
792 ? static_cast < SwCrsrShell
* >( pVSh
)
795 pCrsrSh
->GetCrsr()->GetPoint()
796 ->nNode
.GetIndex() == nNodeIdx
)
798 pCrsrSh
->MovePara(fnParaPrev
, fnParaEnd
);
800 pCrsrSh
->ClearMark();
802 pPam
->GetBound(TRUE
).nContent
.Assign( 0, 0 );
803 pPam
->GetBound(FALSE
).nContent
.Assign( 0, 0 );
804 pDoc
->GetNodes().Delete( pPam
->GetPoint()->nNode
);
808 else if( 0 != ( pAktNd
= pDoc
->GetNodes()[ nNodeIdx
]->GetTxtNode()) && !bHasFlysOrMarks
)
810 if( pAktNd
->CanJoinNext( &pPos
->nNode
))
812 SwTxtNode
* pNextNd
= pPos
->nNode
.GetNode().GetTxtNode();
813 pPos
->nContent
.Assign( pNextNd
, 0 );
814 pPam
->SetMark(); pPam
->DeleteMark();
817 else if( !pAktNd
->GetTxt().Len() )
819 pPos
->nContent
.Assign( 0, 0 );
820 pPam
->SetMark(); pPam
->DeleteMark();
821 pDoc
->GetNodes().Delete( pPos
->nNode
, 1 );
822 pPam
->Move( fnMoveBackward
);
827 // nun noch das SplitNode vom Anfang aufheben
828 else if( !IsNewDoc() )
830 if( pPos
->nContent
.GetIndex() ) // dann gabs am Ende kein <P>,
831 pPam
->Move( fnMoveForward
, fnGoNode
); // als zum naechsten Node
832 SwTxtNode
* pTxtNode
= pPos
->nNode
.GetNode().GetTxtNode();
833 SwNodeIndex
aPrvIdx( pPos
->nNode
);
834 if( pTxtNode
&& pTxtNode
->CanJoinPrev( &aPrvIdx
) &&
835 *pSttNdIdx
<= aPrvIdx
)
837 // eigentlich muss hier ein JoinNext erfolgen, aber alle Cursor
838 // usw. sind im pTxtNode angemeldet, so dass der bestehen
841 // Absatz in Zeichen-Attribute umwandeln, aus dem Prev die
842 // Absatzattribute und die Vorlage uebernehmen!
843 SwTxtNode
* pPrev
= aPrvIdx
.GetNode().GetTxtNode();
844 pTxtNode
->ChgFmtColl( pPrev
->GetTxtColl() );
845 pTxtNode
->FmtToTxtAttr( pPrev
);
846 pTxtNode
->ResetAllAttr();
848 if( pPrev
->HasSwAttrSet() )
849 pTxtNode
->SetAttr( *pPrev
->GetpSwAttrSet() );
851 if( &pPam
->GetBound(TRUE
).nNode
.GetNode() == pPrev
)
852 pPam
->GetBound(TRUE
).nContent
.Assign( pTxtNode
, 0 );
853 if( &pPam
->GetBound(FALSE
).nNode
.GetNode() == pPrev
)
854 pPam
->GetBound(FALSE
).nContent
.Assign( pTxtNode
, 0 );
856 pTxtNode
->JoinPrev();
860 // und noch die DocumentInfo aufbereiten
863 SwDocShell
*pDocShell(pDoc
->GetDocShell());
864 DBG_ASSERT(pDocShell
, "no SwDocShell");
866 uno::Reference
<document::XDocumentPropertiesSupplier
> xDPS(
867 pDocShell
->GetModel(), uno::UNO_QUERY_THROW
);
868 uno::Reference
<document::XDocumentProperties
> xDocProps(
869 xDPS
->getDocumentProperties());
870 DBG_ASSERT(xDocProps
.is(), "DocumentProperties is null");
871 if ( xDocProps
.is() && (xDocProps
->getAutoloadSecs() > 0) &&
872 xDocProps
->getAutoloadURL().equalsAscii("") )
874 xDocProps
->setAutoloadURL(aPathToFile
);
881 SwDocStat
aStat( pDoc
->GetDocStat() );
882 pDoc
->UpdateDocStat( aStat
);
886 if( SVPAR_PENDING
!= GetStatus() )
887 delete pSttNdIdx
, pSttNdIdx
= 0;
889 // sollte der Parser der Letzte sein, der das Doc haelt, dann braucht
890 // man hier auch nichts mehr tun, Doc wird gleich zerstoert!
891 if( 1 < pDoc
->getReferenceCount() )
895 pDoc
->DelAllUndoObj();
896 pDoc
->DoUndo( TRUE
);
900 // Wenn zu Beginn des Continue keine Shell vorhanden war,
901 // kann trotzdem mitlerweile eine angelegt worden sein.
902 // In dieses Fall stimmt das bWasUndo-Flag nicht und
903 // wir muessen das Undo noch anschalten.
904 ViewShell
*pTmpVSh
= CheckActionViewShell();
906 pDoc
->DoUndo( TRUE
);
909 pDoc
->SetOle2Link( aOLELink
);
911 pDoc
->ResetModified();
912 if( bSetModEnabled
&& pDoc
->GetDocShell() )
914 pDoc
->GetDocShell()->EnableSetModified( TRUE
);
915 bSetModEnabled
= FALSE
; // this is unnecessary here
920 // Wenn die Dokuemnt-ViewShell noch existiert und eine Action
921 // offen ist (muss bei Abbruch nicht sein), die Action beenden,
922 // uns von der Shell abmelden und schliesslich die alte Shell
923 // wieder rekonstruieren.
924 CallEndAction( TRUE
);
931 void SwHTMLParser::Modify( SfxPoolItem
*pOld
, SfxPoolItem
*pNew
)
933 switch( pOld
? pOld
->Which() : pNew
? pNew
->Which() : 0 )
935 case RES_OBJECTDYING
:
936 if( ((SwPtrMsgPoolItem
*)pOld
)->pObject
== pRegisteredIn
)
938 // dann uns selbst beenden
939 pRegisteredIn
->Remove( this );
940 ReleaseRef(); // ansonsten sind wir fertig!
946 void SwHTMLParser::DocumentDetected()
948 ASSERT( !bDocInitalized
, "DocumentDetected mehrfach aufgerufen" );
949 bDocInitalized
= TRUE
;
953 FinishHeader( TRUE
);
955 CallEndAction( TRUE
, TRUE
);
957 pDoc
->DoUndo( FALSE
);
958 // Durch das DocumentDetected wurde im allgemeinen eine
959 // ViewShell angelegt. Es kann aber auch sein, dass sie
960 // erst spaeter angelegt wird, naemlich dann, wenn die UI
966 // wird fuer jedes Token gerufen, das in CallParser erkannt wird
967 void __EXPORT
SwHTMLParser::NextToken( int nToken
)
969 if( ( pDoc
->GetDocShell() && pDoc
->GetDocShell()->IsAbortingImport() )
970 || 1 == pDoc
->getReferenceCount() )
972 // wurde der Import vom SFX abgebrochen? Wenn ein Pending-Stack
973 // existiert den noch aufraumen
974 eState
= SVPAR_ERROR
;
975 ASSERT( !pPendStack
|| pPendStack
->nToken
,
976 "SwHTMLParser::NextToken: Pending-Stack ohne Token" );
977 if( 1 == pDoc
->getReferenceCount() || !pPendStack
)
986 // Tabellen werden ueber rekusive Methodenaufrufe gelesen
988 // Bei CSS-Deklarationen muss evtl. noch auf das
989 // Ende eines File-Downloads gewartet werden.
991 // Bei Controls muss evtl. noch die Groesse gesetzt werden.
993 case HTML_TEXTAREA_ON
:
995 case HTML_SELECT_OFF
:
998 ASSERT( !pPendStack
, "Unbekanntes Token fuer Pending-Stack" );
1004 // Die folgeneden Spezialfaelle muessen vor der Filter-Detection behandelt
1005 // werden, denn der Inhalt des Titels, etc. wird auch in Netcape nicht
1006 // zur Filter-Detection herangezogen.
1013 case HTML_TITLE_OFF
:
1014 if( IsNewDoc() && sTitle
.Len() )
1016 if( pDoc
->GetDocShell() ) {
1017 uno::Reference
<document::XDocumentPropertiesSupplier
>
1018 xDPS(pDoc
->GetDocShell()->GetModel(),
1019 uno::UNO_QUERY_THROW
);
1020 uno::Reference
<document::XDocumentProperties
> xDocProps(
1021 xDPS
->getDocumentProperties());
1022 DBG_ASSERT(xDocProps
.is(), "no DocumentProperties");
1023 if (xDocProps
.is()) {
1024 xDocProps
->setTitle(sTitle
);
1027 pDoc
->GetDocShell()->SetTitle( sTitle
);
1034 case HTML_NONBREAKSPACE
:
1042 case HTML_TEXTTOKEN
:
1048 if( (HTML_TOKEN_ONOFF
& nToken
) && (1 & nToken
) )
1050 sTitle
+= sSaveToken
;
1064 // Wenn wir noch nicht wissen, was fuer ein Dokument wir vor uns haben,
1065 // versuchen wir das erstmal rauszufinden. Das muss fuer Controls in
1066 // Fall vor dem Einfuegen des Controls passieren, weil beim Einfuegen
1067 // bereits eine View benoetigt wird.
1068 if( !bDocInitalized
)
1071 BOOL bGetIDOption
= FALSE
, bInsertUnknown
= FALSE
;
1072 BOOL bUpperSpaceSave
= bUpperSpace
;
1073 bUpperSpace
= FALSE
;
1075 // Die folgenden Speziallfaelle muessen oder koennen nach der
1076 // Filter-Detection erfolgen.
1079 if( bInFloatingFrame
)
1081 // <SCRIPT> wird hier (von uns) ignoriert, weil es auch in
1082 // Applets ignoriert wird!
1083 if( HTML_IFRAME_OFF
== nToken
)
1085 bCallNextToken
= FALSE
;
1091 else if( bInNoEmbed
)
1095 case HTML_NOEMBED_OFF
:
1096 aContents
.ConvertLineEnd();
1097 InsertComment( aContents
, OOO_STRING_SVTOOLS_HTML_noembed
);
1099 bCallNextToken
= FALSE
;
1104 InsertCommentText( OOO_STRING_SVTOOLS_HTML_noembed
);
1108 ASSERT( !this, "SwHTMLParser::NextToken: ungueltiges Tag" );
1114 else if( pAppletImpl
)
1116 // in einem Applet interessieren uns (erstmal) nur <PARAM>-Tags
1117 // und das </APPLET>.
1118 // <SCRIPT> wird hier (von Netscape) ignoriert!
1122 case HTML_APPLET_OFF
:
1123 bCallNextToken
= FALSE
;
1126 case HTML_OBJECT_OFF
:
1127 bCallNextToken
= FALSE
;
1138 else if( bTextArea
)
1140 // in einer TextArea wird alles bis zum </TEXTAREA> als Text
1142 // <SCRIPT> wird hier (von Netscape) ignoriert!
1146 case HTML_TEXTAREA_OFF
:
1147 bCallNextToken
= FALSE
;
1152 InsertTextAreaText( static_cast< sal_uInt16
>(nToken
) );
1160 // MUSS nach bNoScript kommen!
1163 case HTML_SELECT_OFF
:
1164 bCallNextToken
= FALSE
;
1169 InsertSelectOption();
1172 case HTML_TEXTTOKEN
:
1177 case HTML_SCRIPT_ON
:
1178 case HTML_SCRIPT_OFF
:
1179 case HTML_NOSCRIPT_ON
:
1180 case HTML_NOSCRIPT_OFF
:
1182 // im normalen switch bahandeln
1192 // in einer TextArea wird alles bis zum </TEXTAREA> als Text
1194 // Die <SCRIPT>-Tags werden vom MS-IE ignoriert, von uns das
1198 case HTML_MARQUEE_OFF
:
1199 bCallNextToken
= FALSE
;
1203 case HTML_TEXTTOKEN
:
1204 InsertMarqueeText();
1214 case HTML_SDFIELD_OFF
:
1215 bCallNextToken
= FALSE
;
1219 case HTML_TEXTTOKEN
:
1226 else if( bInFootEndNoteAnchor
|| bInFootEndNoteSymbol
)
1230 case HTML_ANCHOR_OFF
:
1232 bCallNextToken
= FALSE
;
1235 case HTML_TEXTTOKEN
:
1236 InsertFootEndNoteText();
1241 else if( aUnknownToken
.Len() )
1243 // Fix i#59064 : Paste content of unknown tags.
1244 if (aToken
.Len() > 0)
1246 if( !bDocInitalized
)
1248 pDoc
->Insert( *pPam
, aToken
, true );
1250 // wenn es noch vorlaefige Absatz-Attribute gibt, der Absatz aber
1251 // nicht leer ist, dann sind die Absatz-Attribute entgueltig.
1252 if( aParaAttrs
.Count() )
1253 aParaAttrs
.Remove( 0, aParaAttrs
.Count() );
1258 // Unbekannte Token im Header werden nur durch ein passendes
1259 // End-Token, </HEAD> oder <BODY> wieder beendet. Darin wird Text
1263 case HTML_UNKNOWNCONTROL_OFF
:
1264 if( aUnknownToken
.CompareTo(sSaveToken
) != COMPARE_EQUAL
)
1266 case HTML_FRAMESET_ON
:
1269 case HTML_IMAGE
: // Warum auch immer Netscape das tut.
1270 aUnknownToken
.Erase();
1272 case HTML_TEXTTOKEN
:
1275 aUnknownToken
.Erase();
1284 if( aStyleSource
.Len() )
1286 pCSS1Parser
->ParseStyleSheet( aStyleSource
);
1287 aStyleSource
.Erase();
1291 InsertBodyOptions();
1292 // Falls es eine Vorlage fuer die erste oder rechte Seite gibt,
1293 // setzen wir die hier.
1294 const SwPageDesc
*pPageDesc
= 0;
1295 if( pCSS1Parser
->IsSetFirstPageDesc() )
1296 pPageDesc
= pCSS1Parser
->GetFirstPageDesc();
1297 else if( pCSS1Parser
->IsSetRightPageDesc() )
1298 pPageDesc
= pCSS1Parser
->GetRightPageDesc();
1301 pDoc
->Insert( *pPam
, SwFmtPageDesc( pPageDesc
), 0 );
1311 const HTMLOptions
*pHTMLOptions
= GetOptions();
1312 for( USHORT i
= pHTMLOptions
->Count(); i
; )
1314 const HTMLOption
*pOption
= (*pHTMLOptions
)[ --i
];
1315 switch( pOption
->GetToken() )
1318 sBaseURL
= pOption
->GetString();
1323 SwDocShell
*pDocShell(pDoc
->GetDocShell());
1324 DBG_ASSERT(pDocShell
, "no SwDocShell");
1326 uno::Reference
<document::XDocumentPropertiesSupplier
> xDPS(
1327 pDocShell
->GetModel(), uno::UNO_QUERY_THROW
);
1328 uno::Reference
<document::XDocumentProperties
>
1329 xDocProps(xDPS
->getDocumentProperties());
1330 DBG_ASSERT(xDocProps
.is(),"no DocumentProperties");
1331 if (xDocProps
.is()) {
1332 xDocProps
->setDefaultTarget(
1333 pOption
->GetString());
1345 SvKeyValueIterator
*pHTTPHeader
= 0;
1348 SwDocShell
*pDocSh
= pDoc
->GetDocShell();
1350 pHTTPHeader
= pDocSh
->GetHeaderAttributes();
1352 SwDocShell
*pDocShell(pDoc
->GetDocShell());
1353 DBG_ASSERT(pDocShell
, "no SwDocShell");
1356 uno::Reference
<document::XDocumentProperties
> xDocProps
;
1359 const uno::Reference
<document::XDocumentPropertiesSupplier
>
1360 xDPS( pDocShell
->GetModel(), uno::UNO_QUERY_THROW
);
1361 xDocProps
= xDPS
->getDocumentProperties();
1362 DBG_ASSERT(xDocProps
.is(), "DocumentProperties is null");
1364 ParseMetaOptions( xDocProps
, pHTTPHeader
);
1373 case HTML_SCRIPT_ON
:
1377 case HTML_SCRIPT_OFF
:
1381 case HTML_NOSCRIPT_ON
:
1382 case HTML_NOSCRIPT_OFF
:
1383 bInsertUnknown
= TRUE
;
1390 case HTML_STYLE_OFF
:
1395 if( !bIgnoreRawData
)
1397 if( IsReadScript() )
1401 else if( IsReadStyle() )
1403 if( aStyleSource
.Len() )
1404 aStyleSource
+= '\n';
1405 aStyleSource
+= aToken
;
1410 case HTML_OBJECT_ON
:
1413 bCallNextToken
= pAppletImpl
!=0 && pTable
!=0;
1417 case HTML_APPLET_ON
:
1420 bCallNextToken
= pAppletImpl
!=0 && pTable
!=0;
1424 case HTML_IFRAME_ON
:
1425 InsertFloatingFrame();
1426 bCallNextToken
= bInFloatingFrame
&& pTable
!=0;
1429 case HTML_LINEBREAK
:
1436 bGetIDOption
= TRUE
;
1437 // <BR>s in <PRE> aehneln echten LFs, deshalb kein break
1440 // CR in PRE/LISTING/XMP
1442 if( HTML_NEWPARA
==nToken
||
1443 pPam
->GetPoint()->nContent
.GetIndex() )
1445 AppendTxtNode(); // lf gibts hier nicht, deshalb unkritisch
1448 // Laufbalkenanzeige
1449 if( !GetMedium() || !GetMedium()->IsRemote() )
1450 ::SetProgressState( rInput
.Tell(), pDoc
->GetDocShell() );
1454 case HTML_NONBREAKSPACE
:
1455 pDoc
->Insert( *pPam
, CHAR_HARDBLANK
);
1459 pDoc
->Insert( *pPam
, CHAR_SOFTHYPHEN
);
1462 case HTML_LINEFEEDCHAR
:
1463 if( pPam
->GetPoint()->nContent
.GetIndex() )
1465 if( !pTable
&& !pDoc
->IsInHeaderFooter( pPam
->GetPoint()->nNode
) )
1467 NewAttr( &aAttrTab
.pBreak
, SvxFmtBreakItem(SVX_BREAK_PAGE_BEFORE
, RES_BREAK
) );
1468 EndAttr( aAttrTab
.pBreak
, 0, FALSE
);
1472 case HTML_TEXTTOKEN
:
1473 // dann fuege den String ein, ohne das Attribute am Ende
1474 // aufgespannt werden.
1475 if( aToken
.Len() && ' '==aToken
.GetChar(0) && !IsReadPRE() )
1477 xub_StrLen nPos
= pPam
->GetPoint()->nContent
.GetIndex();
1480 const String
& rText
=
1481 pDoc
->GetNodes()[ pPam
->GetPoint()->nNode
]->GetTxtNode()
1483 sal_Unicode cLast
= rText
.GetChar(--nPos
);
1484 if( ' ' == cLast
|| '\x0a' == cLast
)
1492 bUpperSpace
= bUpperSpaceSave
;
1499 if( !bDocInitalized
)
1501 pDoc
->Insert( *pPam
, aToken
, true );
1503 // wenn es noch vorlaefige Absatz-Attribute gibt, der Absatz aber
1504 // nicht leer ist, dann sind die Absatz-Attribute entgueltig.
1505 if( aParaAttrs
.Count() )
1506 aParaAttrs
.Remove( 0, aParaAttrs
.Count() );
1518 // sollte der Parser der Letzte sein, der das Doc haelt, dann kann
1519 // man hier abbrechen und einen Fehler setzen.
1520 if( 1 == pDoc
->getReferenceCount() )
1522 eState
= SVPAR_ERROR
;
1534 case HTML_NOEMBED_ON
:
1536 bCallNextToken
= pTable
!=0;
1537 ReadRawData( OOO_STRING_SVTOOLS_HTML_noembed
);
1540 case HTML_DEFLIST_ON
:
1541 if( nOpenParaToken
)
1545 case HTML_DEFLIST_OFF
:
1546 if( nOpenParaToken
)
1548 EndDefListItem( 0, FALSE
, 1==nDefListDeep
);
1554 if( nOpenParaToken
)
1556 EndDefListItem( 0, FALSE
);// <DD>/<DT> beenden und keine Vorl. setzen
1557 NewDefListItem( nToken
);
1562 // siehe HTML_LI_OFF
1563 // eigentlich muesste man ein DD/DT jetzt beenden. Da aber sowhl
1564 // Netscape als auch Microsoft das nicht tun, machen wir das eben
1566 EndDefListItem( nToken
, FALSE
);
1570 case HTML_DIVISION_ON
:
1571 case HTML_CENTER_ON
:
1572 if( nOpenParaToken
)
1579 NewDivision( nToken
);
1582 case HTML_DIVISION_OFF
:
1583 case HTML_CENTER_OFF
:
1584 if( nOpenParaToken
)
1591 EndDivision( nToken
);
1594 case HTML_MULTICOL_ON
:
1595 if( nOpenParaToken
)
1600 case HTML_MULTICOL_OFF
:
1601 if( nOpenParaToken
)
1603 EndTag( HTML_MULTICOL_ON
);
1606 case HTML_MARQUEE_ON
:
1608 bCallNextToken
= pMarquee
!=0 && pTable
!=0;
1619 case HTML_PARABREAK_ON
:
1620 if( nOpenParaToken
)
1625 case HTML_PARABREAK_OFF
:
1629 case HTML_ADDRESS_ON
:
1630 if( nOpenParaToken
)
1632 NewTxtFmtColl( HTML_ADDRESS_ON
, RES_POOLCOLL_SENDADRESS
);
1635 case HTML_ADDRESS_OFF
:
1636 if( nOpenParaToken
)
1638 EndTxtFmtColl( HTML_ADDRESS_OFF
);
1641 case HTML_BLOCKQUOTE_ON
:
1642 case HTML_BLOCKQUOTE30_ON
:
1643 if( nOpenParaToken
)
1645 NewTxtFmtColl( HTML_BLOCKQUOTE_ON
, RES_POOLCOLL_HTML_BLOCKQUOTE
);
1648 case HTML_BLOCKQUOTE_OFF
:
1649 case HTML_BLOCKQUOTE30_OFF
:
1650 if( nOpenParaToken
)
1652 EndTxtFmtColl( HTML_BLOCKQUOTE_ON
);
1655 case HTML_PREFORMTXT_ON
:
1656 case HTML_LISTING_ON
:
1658 if( nOpenParaToken
)
1660 NewTxtFmtColl( nToken
, RES_POOLCOLL_HTML_PRE
);
1663 case HTML_PREFORMTXT_OFF
:
1664 bNoParSpace
= TRUE
; // der letzte PRE-Absatz muss einen Zeilenabstand bekommen
1665 EndTxtFmtColl( HTML_PREFORMTXT_OFF
);
1668 case HTML_LISTING_OFF
:
1670 EndTxtFmtColl( nToken
);
1679 if( nOpenParaToken
)
1686 NewHeading( nToken
);
1689 case HTML_HEAD1_OFF
:
1690 case HTML_HEAD2_OFF
:
1691 case HTML_HEAD3_OFF
:
1692 case HTML_HEAD4_OFF
:
1693 case HTML_HEAD5_OFF
:
1694 case HTML_HEAD6_OFF
:
1700 BuildTable( SVX_ADJUST_END
);
1703 if( nOpenParaToken
)
1705 ASSERT( !pTable
, "Tabelle in Tabelle darf hier nicht vorkommen" );
1706 if( !pTable
&& (IsNewDoc() || !pPam
->GetNode()->FindTableNode()) &&
1707 (pPam
->GetPoint()->nNode
.GetIndex() >
1708 pDoc
->GetNodes().GetEndOfExtras().GetIndex() ||
1709 !pPam
->GetNode()->FindFootnoteStartNode() ) )
1712 Show(); // bis hierhin schon mal anzeigen
1714 SvxAdjust eAdjust
= aAttrTab
.pAdjust
1715 ? ((const SvxAdjustItem
&)aAttrTab
.pAdjust
->GetItem()).
1718 BuildTable( eAdjust
);
1721 bInsertUnknown
= bKeepUnknown
;
1726 case HTML_DIRLIST_ON
:
1727 case HTML_MENULIST_ON
:
1728 case HTML_ORDERLIST_ON
:
1729 case HTML_UNORDERLIST_ON
:
1730 if( nOpenParaToken
)
1732 NewNumBulList( nToken
);
1735 case HTML_DIRLIST_OFF
:
1736 case HTML_MENULIST_OFF
:
1737 case HTML_ORDERLIST_OFF
:
1738 case HTML_UNORDERLIST_OFF
:
1739 if( nOpenParaToken
)
1741 EndNumBulListItem( 0, TRUE
, GetNumInfo().GetDepth()==1 );
1742 EndNumBulList( nToken
);
1746 case HTML_LISTHEADER_ON
:
1747 if( nOpenParaToken
&&
1748 (pPam
->GetPoint()->nContent
.GetIndex()
1749 || HTML_PARABREAK_ON
==nOpenParaToken
) )
1751 // nure bei <P><LI> den Absatz beenden, aber nicht bei <DD><LI>
1755 EndNumBulListItem( 0, FALSE
);// <LI>/<LH> beenden und keine Vorl. setzen
1756 NewNumBulListItem( nToken
);
1760 case HTML_LISTHEADER_OFF
:
1761 EndNumBulListItem( nToken
, FALSE
);
1765 case HTML_ITALIC_ON
:
1767 SvxPostureItem
aPosture( ITALIC_NORMAL
, RES_CHRATR_POSTURE
);
1768 SvxPostureItem
aPostureCJK( ITALIC_NORMAL
, RES_CHRATR_CJK_POSTURE
);
1769 SvxPostureItem
aPostureCTL( ITALIC_NORMAL
, RES_CHRATR_CTL_POSTURE
);
1770 NewStdAttr( HTML_ITALIC_ON
,
1771 &aAttrTab
.pItalic
, aPosture
,
1772 &aAttrTab
.pItalicCJK
, &aPostureCJK
,
1773 &aAttrTab
.pItalicCTL
, &aPostureCTL
);
1779 SvxWeightItem
aWeight( WEIGHT_BOLD
, RES_CHRATR_WEIGHT
);
1780 SvxWeightItem
aWeightCJK( WEIGHT_BOLD
, RES_CHRATR_CJK_WEIGHT
);
1781 SvxWeightItem
aWeightCTL( WEIGHT_BOLD
, RES_CHRATR_CTL_WEIGHT
);
1782 NewStdAttr( HTML_BOLD_ON
,
1783 &aAttrTab
.pBold
, aWeight
,
1784 &aAttrTab
.pBoldCJK
, &aWeightCJK
,
1785 &aAttrTab
.pBoldCTL
, &aWeightCTL
);
1790 case HTML_STRIKE_ON
:
1791 case HTML_STRIKETHROUGH_ON
:
1793 NewStdAttr( HTML_STRIKE_ON
, &aAttrTab
.pStrike
,
1794 SvxCrossedOutItem(STRIKEOUT_SINGLE
, RES_CHRATR_CROSSEDOUT
) );
1798 case HTML_UNDERLINE_ON
:
1800 NewStdAttr( HTML_UNDERLINE_ON
, &aAttrTab
.pUnderline
,
1801 SvxUnderlineItem(UNDERLINE_SINGLE
, RES_CHRATR_UNDERLINE
) );
1805 case HTML_SUPERSCRIPT_ON
:
1807 NewStdAttr( HTML_SUPERSCRIPT_ON
, &aAttrTab
.pEscapement
,
1808 SvxEscapementItem(HTML_ESC_SUPER
,HTML_ESC_PROP
, RES_CHRATR_ESCAPEMENT
) );
1812 case HTML_SUBSCRIPT_ON
:
1814 NewStdAttr( HTML_SUBSCRIPT_ON
, &aAttrTab
.pEscapement
,
1815 SvxEscapementItem(HTML_ESC_SUB
,HTML_ESC_PROP
, RES_CHRATR_ESCAPEMENT
) );
1821 NewStdAttr( HTML_BLINK_ON
, &aAttrTab
.pBlink
,
1822 SvxBlinkItem( TRUE
, RES_CHRATR_BLINK
) );
1827 NewStdAttr( HTML_SPAN_ON
);
1831 case HTML_ITALIC_OFF
:
1833 case HTML_STRIKE_OFF
:
1834 case HTML_UNDERLINE_OFF
:
1835 case HTML_SUPERSCRIPT_OFF
:
1836 case HTML_SUBSCRIPT_OFF
:
1837 case HTML_BLINK_OFF
:
1842 case HTML_STRIKETHROUGH_OFF
:
1843 EndTag( HTML_STRIKE_OFF
);
1846 case HTML_BASEFONT_ON
:
1849 case HTML_BASEFONT_OFF
:
1853 case HTML_BIGPRINT_ON
:
1854 case HTML_SMALLPRINT_ON
:
1855 NewFontAttr( nToken
);
1858 case HTML_BIGPRINT_OFF
:
1859 case HTML_SMALLPRINT_OFF
:
1860 EndFontAttr( nToken
);
1863 case HTML_EMPHASIS_ON
:
1864 case HTML_CITIATION_ON
:
1865 case HTML_STRONG_ON
:
1867 case HTML_SAMPLE_ON
:
1868 case HTML_KEYBOARD_ON
:
1869 case HTML_VARIABLE_ON
:
1870 case HTML_DEFINSTANCE_ON
:
1871 case HTML_SHORTQUOTE_ON
:
1872 case HTML_LANGUAGE_ON
:
1873 case HTML_AUTHOR_ON
:
1874 case HTML_PERSON_ON
:
1875 case HTML_ACRONYM_ON
:
1876 case HTML_ABBREVIATION_ON
:
1877 case HTML_INSERTEDTEXT_ON
:
1878 case HTML_DELETEDTEXT_ON
:
1880 case HTML_TELETYPE_ON
:
1881 NewCharFmt( nToken
);
1884 case HTML_SDFIELD_ON
:
1886 bCallNextToken
= bInField
&& pTable
!=0;
1889 case HTML_EMPHASIS_OFF
:
1890 case HTML_CITIATION_OFF
:
1891 case HTML_STRONG_OFF
:
1893 case HTML_SAMPLE_OFF
:
1894 case HTML_KEYBOARD_OFF
:
1895 case HTML_VARIABLE_OFF
:
1896 case HTML_DEFINSTANCE_OFF
:
1897 case HTML_SHORTQUOTE_OFF
:
1898 case HTML_LANGUAGE_OFF
:
1899 case HTML_AUTHOR_OFF
:
1900 case HTML_PERSON_OFF
:
1901 case HTML_ACRONYM_OFF
:
1902 case HTML_ABBREVIATION_OFF
:
1903 case HTML_INSERTEDTEXT_OFF
:
1904 case HTML_DELETEDTEXT_OFF
:
1906 case HTML_TELETYPE_OFF
:
1911 if( aStyleSource
.Len() )
1913 pCSS1Parser
->ParseStyleSheet( aStyleSource
);
1914 aStyleSource
.Erase();
1922 case HTML_TITLE_OFF
:
1923 break; // nicht weiter auswerten, oder???
1926 const HTMLOptions
*pHTMLOptions
= GetOptions();
1927 for( USHORT i
= pHTMLOptions
->Count(); i
; )
1929 const HTMLOption
*pOption
= (*pHTMLOptions
)[ --i
];
1930 if( HTML_O_DIR
== pOption
->GetToken() )
1932 const String
& rDir
= pOption
->GetString();
1933 SfxItemSet
aItemSet( pDoc
->GetAttrPool(),
1934 pCSS1Parser
->GetWhichMap() );
1935 SvxCSS1PropertyInfo aPropInfo
;
1937 ParseStyleOptions( aDummy
, aDummy
, aDummy
, aItemSet
,
1938 aPropInfo
, 0, &rDir
);
1940 pCSS1Parser
->SetPageDescAttrs( 0, &aItemSet
);
1951 case HTML_TEXTAREA_ON
:
1953 bCallNextToken
= bTextArea
&& pTable
!=0;
1956 case HTML_SELECT_ON
:
1958 bCallNextToken
= bSelect
&& pTable
!=0;
1961 case HTML_ANCHOR_ON
:
1965 case HTML_ANCHOR_OFF
:
1970 if( ( aToken
.Len() > 5 ) && ( ! bIgnoreHTMLComments
) )
1972 // als Post-It einfuegen
1973 // MIB 8.12.2000: If there are no space characters right behind
1974 // the <!-- and on front of the -->, leave the comment untouched.
1975 if( ' ' == aToken
.GetChar( 3 ) &&
1976 ' ' == aToken
.GetChar( aToken
.Len()-3 ) )
1978 String
aComment( aToken
.Copy( 3, aToken
.Len()-5 ) );
1979 aComment
.EraseLeadingChars().EraseTrailingChars();
1980 InsertComment( aComment
);
1984 String
aComment( '<' );
1985 (aComment
+= aToken
) += '>';
1986 InsertComment( aComment
);
1992 // Image Maps werden asynchron gelesen: Zunaechst wird nur eine
1993 // ImageMap angelegt. Die Bereiche kommen spaeter. Trozdem wird
1994 // die ImageMap schon in das IMap-Array eingetragen, denn sie
1995 // koennte ja schon verwendet werden.
1996 pImageMap
= new ImageMap
;
1997 if( ParseMapOptions( pImageMap
) )
2000 pImageMaps
= new ImageMaps
;
2001 pImageMaps
->Insert( pImageMap
, pImageMaps
->Count() );
2011 // jetzt gibt es keine ImageMap mehr (IMap nicht Loeschen, denn
2012 // die stckt ja schon in dem Array!)
2018 ParseAreaOptions( pImageMap
, sBaseURL
, SFX_EVENT_MOUSEOVER_OBJECT
,
2019 SFX_EVENT_MOUSEOUT_OBJECT
);
2022 case HTML_FRAMESET_ON
:
2023 bInsertUnknown
= bKeepUnknown
;
2026 case HTML_NOFRAMES_ON
:
2028 FinishHeader( TRUE
);
2029 bInsertUnknown
= bKeepUnknown
;
2032 case HTML_UNKNOWNCONTROL_ON
:
2033 // Im Header muss der Inhalt von unbekannten Token ignoriert werden,
2034 // es sei denn, das Token faengt mit einem '!' an.
2035 if( IsInHeader() && !IsReadPRE() && !aUnknownToken
.Len() &&
2036 sSaveToken
.Len() && '!' != sSaveToken
.GetChar(0) &&
2037 '%' != sSaveToken
.GetChar(0) )
2038 aUnknownToken
= sSaveToken
;
2042 bInsertUnknown
= bKeepUnknown
;
2049 if( bInsertUnknown
)
2052 String::CreateFromAscii(TOOLS_CONSTASCII_STRINGPARAM("HTML: <")) );
2053 if( (HTML_TOKEN_ONOFF
& nToken
) != 0 && (1 & nToken
) != 0 )
2055 aComment
+= sSaveToken
;
2059 (aComment
+= ' ') += aToken
;
2062 InsertComment( aComment
);
2065 // wenn es noch vorlaefige Absatz-Attribute gibt, der Absatz aber
2066 // nicht leer ist, dann sind die Absatz-Attribute entgueltig.
2067 if( aParaAttrs
.Count() && pPam
->GetPoint()->nContent
.GetIndex() )
2068 aParaAttrs
.Remove( 0, aParaAttrs
.Count() );
2073 extern BOOL
lcl_css1atr_equalFontItems( const SfxPoolItem
& r1
, const SfxPoolItem
& r2
);
2075 void lcl_swhtml_getItemInfo( const _HTMLAttr
& rAttr
,
2076 sal_Bool
& rScriptDependent
, sal_Bool
& rFont
,
2077 sal_uInt16
& rScriptType
)
2079 sal_uInt16 nWhich
= rAttr
.GetItem().Which();
2082 case RES_CHRATR_FONT
:
2084 case RES_CHRATR_FONTSIZE
:
2085 case RES_CHRATR_LANGUAGE
:
2086 case RES_CHRATR_POSTURE
:
2087 case RES_CHRATR_WEIGHT
:
2088 rScriptType
= i18n::ScriptType::LATIN
;
2089 rScriptDependent
= sal_True
;
2091 case RES_CHRATR_CJK_FONT
:
2093 case RES_CHRATR_CJK_FONTSIZE
:
2094 case RES_CHRATR_CJK_LANGUAGE
:
2095 case RES_CHRATR_CJK_POSTURE
:
2096 case RES_CHRATR_CJK_WEIGHT
:
2097 rScriptType
= i18n::ScriptType::ASIAN
;
2098 rScriptDependent
= sal_True
;
2100 case RES_CHRATR_CTL_FONT
:
2102 case RES_CHRATR_CTL_FONTSIZE
:
2103 case RES_CHRATR_CTL_LANGUAGE
:
2104 case RES_CHRATR_CTL_POSTURE
:
2105 case RES_CHRATR_CTL_WEIGHT
:
2106 rScriptType
= i18n::ScriptType::COMPLEX
;
2107 rScriptDependent
= sal_True
;
2110 rScriptDependent
= sal_False
;
2116 BOOL
SwHTMLParser::AppendTxtNode( SwHTMLAppendMode eMode
, BOOL bUpdateNum
)
2118 // Ein harter Zeilen-Umbruch am Ende muss immer entfernt werden.
2119 // Einen zweiten ersetzen wir durch einen Absatz-Abstand.
2120 xub_StrLen nLFStripped
= StripTrailingLF();
2121 if( (AM_NOSPACE
==eMode
|| AM_SOFTNOSPACE
==eMode
) && nLFStripped
> 1 )
2124 // die harten Attribute an diesem Absatz werden nie mehr ungueltig
2125 if( aParaAttrs
.Count() )
2126 aParaAttrs
.Remove( 0, aParaAttrs
.Count() );
2128 if( AM_SPACE
==eMode
|| AM_NOSPACE
==eMode
)
2130 SwTxtNode
*pTxtNode
=
2131 pDoc
->GetNodes()[pPam
->GetPoint()->nNode
]->GetTxtNode();
2133 const SvxULSpaceItem
& rULSpace
=
2134 (const SvxULSpaceItem
&)pTxtNode
->SwCntntNode::GetAttr( RES_UL_SPACE
);
2136 BOOL bChange
= AM_NOSPACE
==eMode
? rULSpace
.GetLower() > 0
2137 : rULSpace
.GetLower() == 0;
2141 const SvxULSpaceItem
& rCollULSpace
=
2142 pTxtNode
->GetAnyFmtColl().GetULSpace();
2144 BOOL bMayReset
= AM_NOSPACE
==eMode
? rCollULSpace
.GetLower() == 0
2145 : rCollULSpace
.GetLower() > 0;
2148 rCollULSpace
.GetUpper() == rULSpace
.GetUpper() )
2150 pTxtNode
->ResetAttr( RES_UL_SPACE
);
2155 SvxULSpaceItem( rULSpace
.GetUpper(),
2156 AM_NOSPACE
==eMode
? 0 : HTML_PARSPACE
, RES_UL_SPACE
) );
2160 bNoParSpace
= AM_NOSPACE
==eMode
|| AM_SOFTNOSPACE
==eMode
;
2162 SwPosition
aOldPos( *pPam
->GetPoint() );
2164 BOOL bRet
= pDoc
->AppendTxtNode( *pPam
->GetPoint() );
2166 // Zeichen-Attribute aufspalten und ggf keine setzen, die ueber den
2167 // ganzen Absatz gesetzt sind
2168 const SwNodeIndex
& rEndIdx
= aOldPos
.nNode
;
2169 xub_StrLen nEndCnt
= aOldPos
.nContent
.GetIndex();
2170 const SwPosition
& rPos
= *pPam
->GetPoint();
2172 _HTMLAttr
** pTbl
= (_HTMLAttr
**)&aAttrTab
;
2173 for( USHORT nCnt
= sizeof( _HTMLAttrTable
) / sizeof( _HTMLAttr
* );
2176 _HTMLAttr
*pAttr
= *pTbl
;
2177 if( pAttr
&& pAttr
->GetItem().Which() < RES_PARATR_BEGIN
)
2179 BOOL bWholePara
= FALSE
;
2183 _HTMLAttr
*pNext
= pAttr
->GetNext();
2184 if( pAttr
->GetSttParaIdx() < rEndIdx
.GetIndex() ||
2186 pAttr
->GetSttPara() == rEndIdx
&&
2187 pAttr
->GetSttCnt() != nEndCnt
) )
2190 pAttr
->GetSttPara() == rEndIdx
&&
2191 pAttr
->GetSttCnt() == 0;
2193 xub_StrLen nStt
= pAttr
->nSttCntnt
;
2194 sal_Bool bScript
= sal_False
, bFont
= sal_False
;
2195 sal_uInt16 nScriptItem
;
2196 sal_Bool bInsert
= sal_True
;
2197 lcl_swhtml_getItemInfo( *pAttr
, bScript
, bFont
,
2199 // den besehrigen Teil setzen
2200 if( bInsert
&& bScript
)
2202 const SwTxtNode
*pTxtNd
=
2203 pAttr
->GetSttPara().GetNode().GetTxtNode();
2204 ASSERT( pTxtNd
, "No text node" );
2207 const String
& rText
= pTxtNd
->GetTxt();
2208 sal_uInt16 nScriptTxt
=
2209 pBreakIt
->GetBreakIter()->getScriptType(
2210 rText
, pAttr
->GetSttCnt() );
2211 xub_StrLen nScriptEnd
= (xub_StrLen
)pBreakIt
->GetBreakIter()
2212 ->endOfScript( rText
, nStt
, nScriptTxt
);
2213 while( nScriptEnd
< nEndCnt
)
2215 if( nScriptItem
== nScriptTxt
)
2217 _HTMLAttr
*pSetAttr
=
2218 pAttr
->Clone( rEndIdx
, nScriptEnd
);
2219 pSetAttr
->nSttCntnt
= nStt
;
2220 pSetAttr
->ClearPrev();
2221 if( !pNext
|| bWholePara
)
2223 USHORT nTmp
= pSetAttr
->bInsAtStart
? 0
2224 : aSetAttrTab
.Count();
2225 aSetAttrTab
.Insert( pSetAttr
, nTmp
);
2228 pNext
->InsertPrev( pSetAttr
);
2231 nScriptTxt
= pBreakIt
->GetBreakIter()->getScriptType(
2233 nScriptEnd
= (xub_StrLen
)pBreakIt
->GetBreakIter()
2234 ->endOfScript( rText
, nStt
, nScriptTxt
);
2236 bInsert
= nScriptItem
== nScriptTxt
;
2241 _HTMLAttr
*pSetAttr
=
2242 pAttr
->Clone( rEndIdx
, nEndCnt
);
2243 pSetAttr
->nSttCntnt
= nStt
;
2245 // Wenn das Attribut den gesamten Absatz umspannt, werden
2246 // alle auesseren Attribute nicht mehr beachtet. Deshalb
2247 // darf es auch nicht in die Prev-Liste eines ausseren
2248 // Attributs eingetragen werden, denn dieses wird ja
2249 // erstmal nicht gesetzt. Das fuehrt zu verschiebenungen,
2250 // wenn Felder ins Rennen kommen (siehe #51020#)
2251 if( !pNext
|| bWholePara
)
2253 USHORT nTmp
= pSetAttr
->bInsAtStart
? 0
2254 : aSetAttrTab
.Count();
2255 aSetAttrTab
.Insert( pSetAttr
, nTmp
);
2258 pNext
->InsertPrev( pSetAttr
);
2262 _HTMLAttr
*pPrev
= pAttr
->GetPrev();
2265 // Die Previous-Attribute muessen trotzdem gesetzt werden.
2266 if( !pNext
|| bWholePara
)
2268 USHORT nTmp
= pPrev
->bInsAtStart
? 0 : aSetAttrTab
.Count();
2269 aSetAttrTab
.Insert( pPrev
, nTmp
);
2272 pNext
->InsertPrev( pPrev
);
2278 pAttr
->SetStart( rPos
);
2286 if( GetNumInfo().GetDepth() )
2288 BYTE nLvl
= GetNumInfo().GetLevel();
2289 // --> OD 2008-04-02 #refactorlists#
2290 // SetNoNum (&nLvl, TRUE);
2291 // SetNodeNum( nLvl);
2292 SetNodeNum( nLvl
, false );
2296 pPam
->GetNode()->GetTxtNode()->ResetAttr( RES_PARATR_NUMRULE
);
2299 // Attrubute im Absatz davor sollte man jetzt setzen (wegen JavaScript)
2302 // Now it is time to get rid of all script dependent hints that are
2303 // equal to the settings in the style
2304 SwTxtNode
*pTxtNd
= rEndIdx
.GetNode().GetTxtNode();
2305 ASSERT( pTxtNd
, "There is the txt node" );
2306 sal_uInt16 nCntAttr
= (pTxtNd
&& pTxtNd
->GetpSwpHints())
2307 ? pTxtNd
->GetSwpHints().Count() : 0;
2310 // These are the end position of all script depenent hints.
2311 // If we find a hint that starts before the current end position,
2312 // we have to set it. If we finf a hint that start behind or at
2313 // that position, we have to take the hint's value into account.
2314 // If it is equal to the style, or in fact the paragarph's value
2315 // for that hint, the hint is removed. Otherwise it's end position
2317 xub_StrLen aEndPos
[15] =
2318 { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
2319 SwpHints
& rHints
= pTxtNd
->GetSwpHints();
2320 for( sal_uInt16 i
=0; i
< nCntAttr
; i
++ )
2322 SwTxtAttr
*pHt
= rHints
.GetTextHint( i
);
2323 sal_uInt16 nWhich
= pHt
->Which();
2324 sal_Int16 nIdx
= -1;
2325 if( RES_CHRATR_CJK_FONT
<= nWhich
&&
2326 nWhich
<= RES_CHRATR_CTL_WEIGHT
)
2328 nIdx
= static_cast< USHORT
>(nWhich
- RES_CHRATR_CJK_FONT
+ 5);
2330 else switch( nWhich
)
2332 case RES_CHRATR_FONT
: nIdx
= 0; break;
2333 case RES_CHRATR_FONTSIZE
: nIdx
= 1; break;
2334 case RES_CHRATR_LANGUAGE
: nIdx
= 2; break;
2335 case RES_CHRATR_POSTURE
: nIdx
= 3; break;
2336 case RES_CHRATR_WEIGHT
: nIdx
= 4; break;
2340 xub_StrLen nStt
= *pHt
->GetStart();
2341 if( nStt
>= aEndPos
[nIdx
] )
2343 sal_Bool bFont
= (nIdx
% 5) == 0;
2344 const SfxPoolItem
& rItem
=
2345 ((const SwCntntNode
*)pTxtNd
)->GetAttr( nWhich
);
2346 if( bFont
? lcl_css1atr_equalFontItems(rItem
,pHt
->GetAttr())
2347 : rItem
== pHt
->GetAttr() )
2349 // The hint is the same as set in the paragraph and
2350 // therfor, it can be deleted
2351 // CAUTION!!! This WILL delete the hint and it MAY
2352 // also delete the SwpHints!!! To avoid any trouble
2353 // we leave the loop immediately if this is the last
2355 pTxtNd
->Delete( pHt
, sal_True
);
2363 // The hint is deifferent. Therfor all hints within that
2364 // hint have to be ignored.
2365 aEndPos
[nIdx
] = pHt
->GetEnd() ? *pHt
->GetEnd() : nStt
;
2370 // The hint starts before another one ends.
2371 // The hint in this case is not deleted
2372 ASSERT( pHt
->GetEnd() && *pHt
->GetEnd() <= aEndPos
[nIdx
],
2373 "hints aren't nested properly!" );
2380 if( !pTable
&& !--nParaCnt
)
2386 void SwHTMLParser::AddParSpace()
2391 bNoParSpace
= FALSE
;
2393 ULONG nNdIdx
= pPam
->GetPoint()->nNode
.GetIndex() - 1;
2395 SwTxtNode
*pTxtNode
= pDoc
->GetNodes()[nNdIdx
]->GetTxtNode();
2399 SvxULSpaceItem rULSpace
=
2400 (const SvxULSpaceItem
&)pTxtNode
->SwCntntNode::GetAttr( RES_UL_SPACE
);
2401 if( !rULSpace
.GetLower() )
2403 const SvxULSpaceItem
& rCollULSpace
=
2404 pTxtNode
->GetAnyFmtColl().GetULSpace();
2405 if( rCollULSpace
.GetLower() &&
2406 rCollULSpace
.GetUpper() == rULSpace
.GetUpper() )
2408 pTxtNode
->ResetAttr( RES_UL_SPACE
);
2413 SvxULSpaceItem( rULSpace
.GetUpper(), HTML_PARSPACE
, RES_UL_SPACE
) );
2419 void SwHTMLParser::Show()
2422 // - ein EndAction gerufen, damit formatiert wird
2423 // - ein Reschedule gerufen,
2424 // - die eiegen View-Shell wieder gesetzt
2425 // - und Start-Action gerufen
2427 ASSERT( SVPAR_WORKING
==eState
, "Show nicht im Working-State - Das kann ins Auge gehen" );
2428 ViewShell
*pOldVSh
= CallEndAction();
2430 GetpApp()->Reschedule();
2432 if( ( pDoc
->GetDocShell() && pDoc
->GetDocShell()->IsAbortingImport() )
2433 || 1 == pDoc
->getReferenceCount() )
2435 // wurde der Import vom SFX abgebrochen?
2436 eState
= SVPAR_ERROR
;
2439 // Die ViewShell nochmal holen, denn sie koennte im Reschedule
2440 // zerstoert wirden sein.
2441 ViewShell
*pVSh
= CallStartAction( pOldVSh
);
2443 // ist der aktuelle Node nicht mehr sichtbar, dann benutzen wir
2444 // eine groessere Schrittweite
2446 nParaCnt
= pDoc
->GetNodes()[pPam
->GetPoint()->nNode
]
2447 ->IsInVisibleArea(pVSh
) ? 5 : 50;
2450 void SwHTMLParser::ShowStatline()
2453 // - ein Reschedule gerufen, damit gescrollt werden kann
2454 // - die eiegen View-Shell wieder gesetzt
2455 // - ein Start/End-Action gerufen, wenn gescrollt wurde.
2457 ASSERT( SVPAR_WORKING
==eState
, "ShowStatLine nicht im Working-State - Das kann ins Auge gehen" );
2459 // Laufbalkenanzeige
2460 if( !GetMedium() || !GetMedium()->IsRemote() )
2462 ::SetProgressState( rInput
.Tell(), pDoc
->GetDocShell() );
2463 CheckActionViewShell();
2467 GetpApp()->Reschedule();
2469 if( ( pDoc
->GetDocShell() && pDoc
->GetDocShell()->IsAbortingImport() )
2470 || 1 == pDoc
->getReferenceCount() )
2471 // wurde der Import vom SFX abgebrochen?
2472 eState
= SVPAR_ERROR
;
2474 ViewShell
*pVSh
= CheckActionViewShell();
2475 if( pVSh
&& pVSh
->HasInvalidRect() )
2477 CallEndAction( FALSE
, FALSE
);
2478 CallStartAction( pVSh
, FALSE
);
2483 ViewShell
*SwHTMLParser::CallStartAction( ViewShell
*pVSh
, BOOL bChkPtr
)
2485 ASSERT( !pActionViewShell
, "CallStartAction: ViewShell schon gesetzt" );
2487 if( !pVSh
|| bChkPtr
)
2490 ViewShell
*pOldVSh
= pVSh
;
2492 pDoc
->GetEditShell( &pVSh
);
2493 ASSERT( !pVSh
|| !pOldVSh
|| pOldVSh
== pVSh
, "CallStartAction: Wer hat die ViewShell ausgetauscht?" );
2495 if( pOldVSh
&& !pVSh
)
2499 pActionViewShell
= pVSh
;
2501 if( pActionViewShell
)
2503 if( pActionViewShell
->ISA( SwEditShell
) )
2504 ((SwEditShell
*)pActionViewShell
)->StartAction();
2506 pActionViewShell
->StartAction();
2509 return pActionViewShell
;
2512 ViewShell
*SwHTMLParser::CallEndAction( BOOL bChkAction
, BOOL bChkPtr
)
2516 ViewShell
*pVSh
= 0;
2517 pDoc
->GetEditShell( &pVSh
);
2518 ASSERT( !pVSh
|| pActionViewShell
== pVSh
,
2519 "CallEndAction: Wer hat die ViewShell ausgetauscht?" );
2520 #if OSL_DEBUG_LEVEL > 1
2521 if( pActionViewShell
&& !pVSh
)
2524 if( pVSh
!= pActionViewShell
)
2525 pActionViewShell
= 0;
2528 if( !pActionViewShell
|| (bChkAction
&& !pActionViewShell
->ActionPend()) )
2529 return pActionViewShell
;
2533 // an allen CrsrEditShells die Cursor auf den Doc-Anfang setzen
2534 ViewShell
*pSh
= pActionViewShell
;
2536 if( pSh
->IsA( TYPE( SwCrsrShell
) ) )
2537 ((SwCrsrShell
*)pSh
)->SttEndDoc(TRUE
);
2538 pSh
= (ViewShell
*)pSh
->GetNext();
2539 } while( pSh
!= pActionViewShell
);
2543 if( pActionViewShell
->ISA( SwEditShell
) )
2545 //Schon gescrollt?, dann dafuer sorgen, dass die View sich nicht bewegt!
2546 const BOOL bOldLock
= pActionViewShell
->IsViewLocked();
2547 pActionViewShell
->LockView( TRUE
);
2548 const BOOL bOldEndActionByVirDev
= pActionViewShell
->IsEndActionByVirDev();
2549 pActionViewShell
->SetEndActionByVirDev( TRUE
);;
2550 ((SwEditShell
*)pActionViewShell
)->EndAction();
2551 pActionViewShell
->SetEndActionByVirDev( bOldEndActionByVirDev
);
2552 pActionViewShell
->LockView( bOldLock
);
2554 // bChkJumpMark ist nur gesetzt, wenn das Object auch gefunden wurde
2557 const Point
aVisSttPos( DOCUMENTBORDER
, DOCUMENTBORDER
);
2558 if( GetMedium() && aVisSttPos
== pActionViewShell
->VisArea().Pos() )
2559 ::JumpToSwMark( pActionViewShell
,
2560 GetMedium()->GetURLObject().GetMark() );
2561 bChkJumpMark
= FALSE
;
2565 pActionViewShell
->EndAction();
2567 // sollte der Parser der Letzte sein, der das Doc haelt, dann kann
2568 // man hier abbrechen und einen Fehler setzen.
2569 if( 1 == pDoc
->getReferenceCount() )
2571 eState
= SVPAR_ERROR
;
2574 ViewShell
*pVSh
= pActionViewShell
;
2575 pActionViewShell
= 0;
2580 ViewShell
*SwHTMLParser::CheckActionViewShell()
2582 ViewShell
*pVSh
= 0;
2583 pDoc
->GetEditShell( &pVSh
);
2584 ASSERT( !pVSh
|| pActionViewShell
== pVSh
,
2585 "CheckActionViewShell: Wer hat die ViewShell ausgetauscht?" );
2586 #if OSL_DEBUG_LEVEL > 1
2587 if( pActionViewShell
&& !pVSh
)
2590 if( pVSh
!= pActionViewShell
)
2591 pActionViewShell
= 0;
2593 return pActionViewShell
;
2598 void SwHTMLParser::_SetAttr( BOOL bChkEnd
, BOOL bBeforeTable
,
2599 _HTMLAttrs
*pPostIts
)
2601 SwPaM
* pAttrPam
= new SwPaM( *pPam
->GetPoint() );
2602 const SwNodeIndex
& rEndIdx
= pPam
->GetPoint()->nNode
;
2603 xub_StrLen nEndCnt
= pPam
->GetPoint()->nContent
.GetIndex();
2608 _HTMLAttrs
aFields( 5, 5 );
2610 for( n
= aSetAttrTab
.Count(); n
; )
2612 pAttr
= aSetAttrTab
[ --n
];
2613 USHORT nWhich
= pAttr
->pItem
->Which();
2615 ULONG nEndParaIdx
= pAttr
->GetEndParaIdx();
2619 // fix #42192#: Zechen-Attribute mit Ende moeglich frueh,
2620 // also noch im aktuellen Absatz setzen (wegen JavaScript
2621 // und diversen Chats). das darf man aber nicht fuer Attribute,
2622 // die ueber den ganzen Absatz aufgspannt werden sollen, weil
2623 // sie aus Absatzvorlgen stammen, die nicht gesetzt werden
2624 // koennen. Weil die Attribute mit SETATTR_DONTREPLACE
2625 // eingefuegt werden, sollte man sie auch anchtraeglich
2626 // noch setzen koennen.
2627 bSetAttr
= ( nEndParaIdx
< rEndIdx
.GetIndex() &&
2628 (RES_LR_SPACE
!= nWhich
|| !GetNumInfo().GetNumRule()) ) ||
2629 ( !pAttr
->IsLikePara() &&
2630 nEndParaIdx
== rEndIdx
.GetIndex() &&
2631 pAttr
->GetEndCnt() < nEndCnt
&&
2632 (isCHRATR(nWhich
) || isTXTATR_WITHEND(nWhich
)) ) ||
2634 nEndParaIdx
== rEndIdx
.GetIndex() &&
2635 !pAttr
->GetEndCnt() );
2639 // Attribiute im Content-Bereich duerfen nicht gesetzt
2640 // werden, wenn wir in einem Sonderbereich stehen, aber
2641 // umgekekehrt schon.
2642 ULONG nEndOfIcons
= pDoc
->GetNodes().GetEndOfExtras().GetIndex();
2643 bSetAttr
= nEndParaIdx
< rEndIdx
.GetIndex() ||
2644 rEndIdx
.GetIndex() > nEndOfIcons
||
2645 nEndParaIdx
<= nEndOfIcons
;
2650 // Das Attribute darf nicht in der liste der vorlaeufigen
2651 // Absatz-Attribute stehen, weil es sonst geloescht wurde.
2652 USHORT ii
= aParaAttrs
.Count();
2655 ASSERT( pAttr
!= aParaAttrs
[ii
],
2656 "SetAttr: Attribut duerfte noch nicht gesetzt werden" );
2657 aParaAttrs
.Remove( ii
);
2662 aSetAttrTab
.Remove( n
, 1 );
2666 _HTMLAttr
*pPrev
= pAttr
->GetPrev();
2667 if( !pAttr
->bValid
)
2669 // ungueltige Attribute koennen gloescht werden
2676 pCNd
= pDoc
->GetNodes()[ pAttr
->nSttPara
]->GetCntntNode();
2679 // durch die elende Loescherei von Nodes kann auch mal
2680 // ein Index auf einen End-Node zeigen :-(
2681 if ( (pAttr
->GetSttPara() == pAttr
->GetEndPara()) &&
2682 !isTXTATR_NOEND(nWhich
) )
2684 // wenn der End-Index auch auf den Node zeigt
2685 // brauchen wir auch kein Attribut mehr zu setzen,
2686 // es sei denn, es ist ein Text-Attribut.
2691 pCNd
= pDoc
->GetNodes().GoNext( &(pAttr
->nSttPara
) );
2693 pAttr
->nSttCntnt
= 0;
2696 ASSERT( !this, "SetAttr: GoNext() failed!" );
2702 pAttrPam
->GetPoint()->nNode
= pAttr
->nSttPara
;
2706 // durch das Loeschen von BRs kann der Start-Index
2707 // auch mal hinter das Ende des Textes zeigen
2708 if( pAttr
->nSttCntnt
> pCNd
->Len() )
2709 pAttr
->nSttCntnt
= pCNd
->Len();
2710 pAttrPam
->GetPoint()->nContent
.Assign( pCNd
, pAttr
->nSttCntnt
);
2712 pAttrPam
->SetMark();
2713 if ( (pAttr
->GetSttPara() != pAttr
->GetEndPara()) &&
2714 !isTXTATR_NOEND(nWhich
) )
2716 pCNd
= pDoc
->GetNodes()[ pAttr
->nEndPara
]->GetCntntNode();
2719 pCNd
= pDoc
->GetNodes().GoPrevious( &(pAttr
->nEndPara
) );
2721 pAttr
->nEndCntnt
= pCNd
->Len();
2724 ASSERT( !this, "SetAttr: GoPrevious() failed!" );
2725 pAttrPam
->DeleteMark();
2732 pAttrPam
->GetPoint()->nNode
= pAttr
->nEndPara
;
2734 else if( pAttr
->IsLikePara() )
2736 pAttr
->nEndCntnt
= pCNd
->Len();
2739 // durch das Loeschen von BRs kann der End-Index
2740 // auch mal hinter das Ende des Textes zeigen
2741 if( pAttr
->nEndCntnt
> pCNd
->Len() )
2742 pAttr
->nEndCntnt
= pCNd
->Len();
2744 pAttrPam
->GetPoint()->nContent
.Assign( pCNd
, pAttr
->nEndCntnt
);
2746 pAttrPam
->GetPoint()->nNode
.GetIndex() ==
2747 rEndIdx
.GetIndex() )
2749 // wenn wir vor dem Einfuegen einer Tabelle stehen
2750 // und das Attribut im aktuellen Node beendet wird,
2751 // muessen wir es im Node davor beenden oder wegschmeissen,
2752 // wenn es erst in dem Node beginnt
2753 if( nWhich
!= RES_BREAK
&& nWhich
!= RES_PAGEDESC
&&
2754 !isTXTATR_NOEND(nWhich
) )
2756 if( pAttrPam
->GetMark()->nNode
.GetIndex() !=
2757 rEndIdx
.GetIndex() )
2759 ASSERT( !pAttrPam
->GetPoint()->nContent
.GetIndex(),
2760 "Content-Position vor Tabelle nicht 0???" );
2761 pAttrPam
->Move( fnMoveBackward
);
2765 pAttrPam
->DeleteMark();
2775 case RES_FLTR_BOOKMARK
: // insert bookmark
2777 const String
sName( ((SfxStringItem
*)pAttr
->pItem
)->GetValue() );
2778 IDocumentMarkAccess
* const pMarkAccess
= pDoc
->getIDocumentMarkAccess();
2779 IDocumentMarkAccess::const_iterator_t ppBkmk
= pMarkAccess
->findMark( sName
);
2780 if( ppBkmk
!= pMarkAccess
->getMarksEnd() &&
2781 ppBkmk
->get()->GetMarkStart() == *pAttrPam
->GetPoint() )
2782 break; // do not generate duplicates on this position
2783 pAttrPam
->DeleteMark();
2784 const ::sw::mark::IMark
* const pNewMark
= pMarkAccess
->makeMark(
2787 IDocumentMarkAccess::BOOKMARK
);
2790 if( JUMPTO_MARK
== eJumpTo
&& pNewMark
->GetName() == ::rtl::OUString(sJmpMark
) )
2792 bChkJumpMark
= TRUE
;
2793 eJumpTo
= JUMPTO_NONE
;
2797 case RES_TXTATR_FIELD
:
2800 pPostIts
? ((const SwFmtFld
*)pAttr
->pItem
)
2801 ->GetFld()->GetTyp()->Which() : 0;
2802 if( pPostIts
&& (RES_POSTITFLD
== nFldWhich
||
2803 RES_SCRIPTFLD
== nFldWhich
) )
2805 pPostIts
->Insert( pAttr
, 0 );
2809 aFields
.Insert( pAttr
, aFields
.Count() );
2812 pAttrPam
->DeleteMark();
2817 if( pAttrPam
->GetPoint()->nNode
.GetIndex() ==
2818 pAttrPam
->GetMark()->nNode
.GetIndex() &&
2821 // wegen Numerierungen dieses Attribut direkt
2823 pCNd
->SetAttr( *pAttr
->pItem
);
2827 "LRSpace ueber mehrere Absaetze gesetzt!" );
2828 // kein break (hier sollen wir trotzdem nie hinkommen;
2831 // ggfs. ein Bookmark anspringen
2832 if( RES_TXTATR_INETFMT
== nWhich
&&
2833 JUMPTO_MARK
== eJumpTo
&&
2834 sJmpMark
== ((SwFmtINetFmt
*)pAttr
->pItem
)->GetName() )
2836 bChkJumpMark
= TRUE
;
2837 eJumpTo
= JUMPTO_NONE
;
2840 pDoc
->Insert( *pAttrPam
, *pAttr
->pItem
, nsSetAttrMode::SETATTR_DONTREPLACE
);
2842 pAttrPam
->DeleteMark();
2850 for( n
= aMoveFlyFrms
.Count(); n
; )
2852 SwFrmFmt
*pFrmFmt
= aMoveFlyFrms
[ --n
];
2854 const SwFmtAnchor
& rAnchor
= pFrmFmt
->GetAnchor();
2855 ASSERT( FLY_AT_CNTNT
==rAnchor
.GetAnchorId(),
2856 "Nur Auto-Rahmen brauchen eine Spezialbehandlung" );
2857 const SwPosition
*pFlyPos
= rAnchor
.GetCntntAnchor();
2858 ULONG nFlyParaIdx
= pFlyPos
->nNode
.GetIndex();
2862 bMoveFly
= nFlyParaIdx
< rEndIdx
.GetIndex() ||
2863 ( nFlyParaIdx
== rEndIdx
.GetIndex() &&
2864 aMoveFlyCnts
[n
] < nEndCnt
);
2868 ULONG nEndOfIcons
= pDoc
->GetNodes().GetEndOfExtras().GetIndex();
2869 bMoveFly
= nFlyParaIdx
< rEndIdx
.GetIndex() ||
2870 rEndIdx
.GetIndex() > nEndOfIcons
||
2871 nFlyParaIdx
<= nEndOfIcons
;
2876 *pAttrPam
->GetPoint() = *pFlyPos
;
2877 pAttrPam
->GetPoint()->nContent
.Assign( pAttrPam
->GetCntntNode(),
2879 SwFmtAnchor
aAnchor( rAnchor
);
2880 aAnchor
.SetType( FLY_AUTO_CNTNT
);
2881 aAnchor
.SetAnchor( pAttrPam
->GetPoint() );
2882 pFrmFmt
->SetFmtAttr( aAnchor
);
2884 const SwFmtHoriOrient
& rHoriOri
= pFrmFmt
->GetHoriOrient();
2885 if( text::HoriOrientation::LEFT
== rHoriOri
.GetHoriOrient() )
2887 SwFmtHoriOrient
aHoriOri( rHoriOri
);
2888 aHoriOri
.SetRelationOrient( text::RelOrientation::CHAR
);
2889 pFrmFmt
->SetFmtAttr( aHoriOri
);
2891 const SwFmtVertOrient
& rVertOri
= pFrmFmt
->GetVertOrient();
2892 if( text::VertOrientation::TOP
== rVertOri
.GetVertOrient() )
2894 SwFmtVertOrient
aVertOri( rVertOri
);
2895 aVertOri
.SetRelationOrient( text::RelOrientation::CHAR
);
2896 pFrmFmt
->SetFmtAttr( aVertOri
);
2899 pFrmFmt
->MakeFrms();
2900 aMoveFlyFrms
.Remove( n
, 1 );
2901 aMoveFlyCnts
.Remove( n
, 1 );
2904 while( aFields
.Count() )
2908 pCNd
= pDoc
->GetNodes()[ pAttr
->nSttPara
]->GetCntntNode();
2909 pAttrPam
->GetPoint()->nNode
= pAttr
->nSttPara
;
2910 pAttrPam
->GetPoint()->nContent
.Assign( pCNd
, pAttr
->nSttCntnt
);
2913 pAttrPam
->GetPoint()->nNode
.GetIndex() == rEndIdx
.GetIndex() )
2915 ASSERT( !bBeforeTable
, "Aha, der Fall tritt also doch ein" );
2916 ASSERT( !pAttrPam
->GetPoint()->nContent
.GetIndex(),
2917 "Content-Position vor Tabelle nicht 0???" );
2919 pAttrPam
->Move( fnMoveBackward
);
2922 pDoc
->Insert( *pAttrPam
, *pAttr
->pItem
, 0 );
2924 aFields
.Remove( 0, 1 );
2931 void SwHTMLParser::NewAttr( _HTMLAttr
**ppAttr
, const SfxPoolItem
& rItem
)
2933 // Font-Hoehen und -Farben- sowie Escapement-Attribute duerfen nicht
2934 // zusammengefasst werden. Sie werden deshalb in einer Liste gespeichert,
2935 // in der das zuletzt aufgespannte Attribut vorne steht und der Count
2936 // immer 1 ist. Fuer alle anderen Attribute wird der Count einfach
2940 _HTMLAttr
*pAttr
= new _HTMLAttr( *pPam
->GetPoint(), rItem
,
2942 pAttr
->InsertNext( *ppAttr
);
2946 (*ppAttr
) = new _HTMLAttr( *pPam
->GetPoint(), rItem
, ppAttr
);
2950 void SwHTMLParser::EndAttr( _HTMLAttr
* pAttr
, _HTMLAttr
**ppDepAttr
,
2953 ASSERT( !ppDepAttr
, "SwHTMLParser::EndAttr: ppDepAttr-Feature ungetestet?" );
2954 // Der Listenkopf ist im Attribut gespeichert
2955 _HTMLAttr
**ppHead
= pAttr
->ppHead
;
2957 ASSERT( ppHead
, "keinen Attributs-Listenkopf gefunden!" );
2959 // die aktuelle Psoition als Ende-Position merken
2960 const SwNodeIndex
* pEndIdx
= &pPam
->GetPoint()->nNode
;
2961 xub_StrLen nEndCnt
= pPam
->GetPoint()->nContent
.GetIndex();
2963 // WIrd das zueltzt gestartete oder ein frueher gestartetes Attribut
2965 _HTMLAttr
*pLast
= 0;
2966 if( ppHead
&& pAttr
!= *ppHead
)
2968 // Es wird nicht das zuletzt gestartete Attribut beendet
2970 // Dann suche wir das unmittelbar danach gestartete Attribut, das
2971 // ja ebenfalls noch nicht beendet wurde (sonst stuende es nicht
2972 // mehr in der Liste
2974 while( pLast
&& pLast
->GetNext() != pAttr
)
2975 pLast
= pLast
->GetNext();
2977 ASSERT( pLast
, "Attribut nicht in eigener Liste gefunden!" );
2979 // das Attribut nicht an der PaM-Psoition beenden, sondern da,
2980 // wo das danch gestartete Attribut anfing???
2981 //pEndIdx = &pPrev->GetSttPara();
2982 //nEndCnt = pPrev->GetSttCnt();
2985 BOOL bMoveBack
= FALSE
;
2986 USHORT nWhich
= pAttr
->pItem
->Which();
2987 if( /*!pLast &&*/ !nEndCnt
&& RES_PARATR_BEGIN
<= nWhich
&&
2988 *pEndIdx
!= pAttr
->GetSttPara() )
2990 // dann eine Cntntnt Position zurueck!
2991 bMoveBack
= pPam
->Move( fnMoveBackward
);
2992 nEndCnt
= pPam
->GetPoint()->nContent
.GetIndex();
2995 // nun das Attrubut beenden
2996 _HTMLAttr
*pNext
= pAttr
->GetNext();
3000 sal_uInt16 nScriptItem
= 0;
3001 sal_Bool bScript
= sal_False
, bFont
= sal_False
;
3003 if( !bChkEmpty
|| (RES_PARATR_BEGIN
<= nWhich
&& bMoveBack
) ||
3004 RES_PAGEDESC
== nWhich
|| RES_BREAK
== nWhich
||
3005 *pEndIdx
!= pAttr
->GetSttPara() ||
3006 nEndCnt
!= pAttr
->GetSttCnt() )
3009 // We do some optimization for script depenedent attribtes here.
3010 if( *pEndIdx
== pAttr
->GetSttPara() )
3012 lcl_swhtml_getItemInfo( *pAttr
, bScript
, bFont
, nScriptItem
);
3017 bInsert
= sal_False
;
3020 if( bInsert
&& bScript
)
3022 const SwTxtNode
*pTxtNd
= pAttr
->GetSttPara().GetNode()
3024 ASSERT( pTxtNd
, "No text node" );
3025 const String
& rText
= pTxtNd
->GetTxt();
3026 sal_uInt16 nScriptTxt
= pBreakIt
->GetBreakIter()->getScriptType(
3027 rText
, pAttr
->GetSttCnt() );
3028 xub_StrLen nScriptEnd
= (xub_StrLen
)pBreakIt
->GetBreakIter()
3029 ->endOfScript( rText
, pAttr
->GetSttCnt(), nScriptTxt
);
3030 while( nScriptEnd
< nEndCnt
)
3032 if( nScriptItem
== nScriptTxt
)
3034 _HTMLAttr
*pSetAttr
= pAttr
->Clone( *pEndIdx
, nScriptEnd
);
3035 pSetAttr
->ClearPrev();
3037 pNext
->InsertPrev( pSetAttr
);
3040 USHORT nTmp
= pSetAttr
->bInsAtStart
? 0
3041 : aSetAttrTab
.Count();
3042 aSetAttrTab
.Insert( pSetAttr
, nTmp
);
3045 pAttr
->nSttCntnt
= nScriptEnd
;
3046 nScriptTxt
= pBreakIt
->GetBreakIter()->getScriptType(
3047 rText
, nScriptEnd
);
3048 nScriptEnd
= (xub_StrLen
)pBreakIt
->GetBreakIter()
3049 ->endOfScript( rText
, nScriptEnd
, nScriptTxt
);
3051 bInsert
= nScriptItem
== nScriptTxt
;
3055 pAttr
->nEndPara
= *pEndIdx
;
3056 pAttr
->nEndCntnt
= nEndCnt
;
3057 pAttr
->bInsAtStart
= RES_TXTATR_INETFMT
!= nWhich
&&
3058 RES_TXTATR_CHARFMT
!= nWhich
;
3062 // keine offenen Attribute dieses Typs mehr da,
3063 // dann koennen alle gesetzt werden, es sei denn
3064 // sie haengen noch von einem anderen Attribut ab,
3065 // dann werden sie dort angehaengt
3066 if( ppDepAttr
&& *ppDepAttr
)
3067 (*ppDepAttr
)->InsertPrev( pAttr
);
3070 USHORT nTmp
= pAttr
->bInsAtStart
? 0 : aSetAttrTab
.Count();
3071 aSetAttrTab
.Insert( pAttr
, nTmp
);
3076 // es gibt noch andere offene Attribute des Typs,
3077 // daher muss das Setzen zurueckgestellt werden.
3078 // das aktuelle Attribut wird deshalb hinten an die
3079 // Previous-Liste des Nachfolgers angehaengt
3080 pNext
->InsertPrev( pAttr
);
3085 // dann nicht einfuegen, sondern Loeschen. Durch das "tuerken" von
3086 // Vorlagen durch harte Attributierung koennen sich auch mal andere
3087 // leere Attribute in der Prev-Liste befinden, die dann trotzdem
3088 // gesetzt werden muessen
3089 _HTMLAttr
*pPrev
= pAttr
->GetPrev();
3094 // Die Previous-Attribute muessen trotzdem gesetzt werden.
3096 pNext
->InsertPrev( pPrev
);
3099 USHORT nTmp
= pPrev
->bInsAtStart
? 0 : aSetAttrTab
.Count();
3100 aSetAttrTab
.Insert( pPrev
, nTmp
);
3106 // wenn das erste Attribut der Liste gesetzt wurde muss noch der
3107 // Listenkopf korrigiert werden.
3109 pLast
->pNext
= pNext
;
3114 pPam
->Move( fnMoveForward
);
3117 void SwHTMLParser::DeleteAttr( _HTMLAttr
* pAttr
)
3119 // Hier darf es keine vorlauefigen Absatz-Attribute geben, den die
3120 // koennten jetzt gesetzt werden und dann sind die Zeiger ungueltig!!!
3121 ASSERT( !aParaAttrs
.Count(),
3122 "Hoechste Gefahr: Es gibt noch nicht-endgueltige Absatz-Attribute" );
3123 if( aParaAttrs
.Count() )
3124 aParaAttrs
.Remove( 0, aParaAttrs
.Count() );
3126 // Der Listenkopf ist im Attribut gespeichert
3127 _HTMLAttr
**ppHead
= pAttr
->ppHead
;
3129 ASSERT( ppHead
, "keinen Attributs-Listenkopf gefunden!" );
3131 // Wird das zueltzt gestartete oder ein frueher gestartetes Attribut
3133 _HTMLAttr
*pLast
= 0;
3134 if( ppHead
&& pAttr
!= *ppHead
)
3136 // Es wird nicht das zuletzt gestartete Attribut beendet
3138 // Dann suche wir das unmittelbar danach gestartete Attribut, das
3139 // ja ebenfalls noch nicht beendet wurde (sonst stuende es nicht
3140 // mehr in der Liste
3142 while( pLast
&& pLast
->GetNext() != pAttr
)
3143 pLast
= pLast
->GetNext();
3145 ASSERT( pLast
, "Attribut nicht in eigener Liste gefunden!" );
3148 // nun das Attrubut entfernen
3149 _HTMLAttr
*pNext
= pAttr
->GetNext();
3150 _HTMLAttr
*pPrev
= pAttr
->GetPrev();
3155 // Die Previous-Attribute muessen trotzdem gesetzt werden.
3157 pNext
->InsertPrev( pPrev
);
3160 USHORT nTmp
= pPrev
->bInsAtStart
? 0 : aSetAttrTab
.Count();
3161 aSetAttrTab
.Insert( pPrev
, nTmp
);
3165 // wenn das erste Attribut der Liste entfernt wurde muss noch der
3166 // Listenkopf korrigiert werden.
3168 pLast
->pNext
= pNext
;
3173 void SwHTMLParser::SaveAttrTab( _HTMLAttrTable
& rNewAttrTab
)
3175 // Hier darf es keine vorlauefigen Absatz-Attribute geben, den die
3176 // koennten jetzt gesetzt werden und dann sind die Zeiger ungueltig!!!
3177 ASSERT( !aParaAttrs
.Count(),
3178 "Hoechste Gefahr: Es gibt noch nicht-endgueltige Absatz-Attribute" );
3179 if( aParaAttrs
.Count() )
3180 aParaAttrs
.Remove( 0, aParaAttrs
.Count() );
3182 _HTMLAttr
** pTbl
= (_HTMLAttr
**)&aAttrTab
;
3183 _HTMLAttr
** pSaveTbl
= (_HTMLAttr
**)&rNewAttrTab
;
3185 for( USHORT nCnt
= sizeof( _HTMLAttrTable
) / sizeof( _HTMLAttr
* );
3186 nCnt
--; (++pTbl
, ++pSaveTbl
) )
3190 _HTMLAttr
*pAttr
= *pSaveTbl
;
3193 pAttr
->SetHead( pSaveTbl
);
3194 pAttr
= pAttr
->GetNext();
3201 void SwHTMLParser::SplitAttrTab( _HTMLAttrTable
& rNewAttrTab
,
3204 // Hier darf es keine vorlauefigen Absatz-Attribute geben, den die
3205 // koennten jetzt gesetzt werden und dann sind die Zeiger ungueltig!!!
3206 ASSERT( !aParaAttrs
.Count(),
3207 "Hoechste Gefahr: Es gibt noch nicht-endgueltige Absatz-Attribute" );
3208 if( aParaAttrs
.Count() )
3209 aParaAttrs
.Remove( 0, aParaAttrs
.Count() );
3211 const SwNodeIndex
& nSttIdx
= pPam
->GetPoint()->nNode
;
3212 SwNodeIndex
nEndIdx( nSttIdx
);
3214 // alle noch offenen Attribute beenden und hinter der Tabelle
3216 _HTMLAttr
** pTbl
= (_HTMLAttr
**)&aAttrTab
;
3217 _HTMLAttr
** pSaveTbl
= (_HTMLAttr
**)&rNewAttrTab
;
3218 BOOL bSetAttr
= TRUE
;
3219 xub_StrLen nSttCnt
= pPam
->GetPoint()->nContent
.GetIndex();
3220 xub_StrLen nEndCnt
= nSttCnt
;
3224 ULONG nOldEnd
= nEndIdx
.GetIndex();
3226 if( ( nTmpIdx
= pDoc
->GetNodes().GetEndOfExtras().GetIndex()) >= nOldEnd
||
3227 ( nTmpIdx
= pDoc
->GetNodes().GetEndOfAutotext().GetIndex()) >= nOldEnd
)
3229 nTmpIdx
= pDoc
->GetNodes().GetEndOfInserts().GetIndex();
3231 SwCntntNode
* pCNd
= pDoc
->GetNodes().GoPrevious(&nEndIdx
);
3233 // keine Attribute setzen, wenn der PaM aus dem Content-Bereich
3234 // herausgeschoben wurde.
3235 bSetAttr
= pCNd
&& nTmpIdx
< nEndIdx
.GetIndex();
3237 nEndCnt
= (bSetAttr
? pCNd
->Len() : 0);
3239 for( USHORT nCnt
= sizeof( _HTMLAttrTable
) / sizeof( _HTMLAttr
* );
3240 nCnt
--; (++pTbl
, ++pSaveTbl
) )
3242 _HTMLAttr
*pAttr
= *pTbl
;
3246 _HTMLAttr
*pNext
= pAttr
->GetNext();
3247 _HTMLAttr
*pPrev
= pAttr
->GetPrev();
3250 ( pAttr
->GetSttParaIdx() < nEndIdx
.GetIndex() ||
3251 (pAttr
->GetSttPara() == nEndIdx
&&
3252 pAttr
->GetSttCnt() != nEndCnt
) ) )
3254 // das Attribut muss vor der Liste gesetzt werden. Da wir
3255 // das Original noch brauchen, weil Zeiger auf das Attribut
3256 // noch in den Kontexten existieren, muessen wir es clonen.
3257 // Die Next-Liste geht dabei verloren, aber die
3258 // Previous-Liste bleibt erhalten
3259 _HTMLAttr
*pSetAttr
= pAttr
->Clone( nEndIdx
, nEndCnt
);
3262 pNext
->InsertPrev( pSetAttr
);
3265 USHORT nTmp
= pSetAttr
->bInsAtStart
? 0
3266 : aSetAttrTab
.Count();
3267 aSetAttrTab
.Insert( pSetAttr
, nTmp
);
3272 // Wenn das Attribut nicht gesetzt vor der Tabelle
3273 // gesetzt werden muss, muessen der Previous-Attribute
3274 // trotzdem gesetzt werden.
3276 pNext
->InsertPrev( pPrev
);
3279 USHORT nTmp
= pPrev
->bInsAtStart
? 0 : aSetAttrTab
.Count();
3280 aSetAttrTab
.Insert( pPrev
, nTmp
);
3284 // den Start des Attributs neu setzen und die Verkettungen
3286 pAttr
->Reset( nSttIdx
, nSttCnt
, pSaveTbl
);
3290 _HTMLAttr
*pSAttr
= *pSaveTbl
;
3291 while( pSAttr
->GetNext() )
3292 pSAttr
= pSAttr
->GetNext();
3293 pSAttr
->InsertNext( pAttr
);
3305 void SwHTMLParser::RestoreAttrTab( const _HTMLAttrTable
& rNewAttrTab
,
3308 // Hier darf es keine vorlauefigen Absatz-Attribute geben, den die
3309 // koennten jetzt gesetzt werden und dann sind die Zeiger ungueltig!!!
3310 ASSERT( !aParaAttrs
.Count(),
3311 "Hoechste Gefahr: Es gibt noch nicht-endgueltige Absatz-Attribute" );
3312 if( aParaAttrs
.Count() )
3313 aParaAttrs
.Remove( 0, aParaAttrs
.Count() );
3315 _HTMLAttr
** pTbl
= (_HTMLAttr
**)&aAttrTab
;
3316 _HTMLAttr
** pSaveTbl
= (_HTMLAttr
**)&rNewAttrTab
;
3318 for( USHORT nCnt
= sizeof( _HTMLAttrTable
) / sizeof( _HTMLAttr
* );
3319 nCnt
--; (++pTbl
, ++pSaveTbl
) )
3321 ASSERT( !*pTbl
, "Die Attribut-Tabelle ist nicht leer!" );
3323 const SwPosition
*pPos
= pPam
->GetPoint();
3324 const SwNodeIndex
& rSttPara
= pPos
->nNode
;
3325 xub_StrLen nSttCnt
= pPos
->nContent
.GetIndex();
3329 _HTMLAttr
*pAttr
= *pTbl
;
3332 ASSERT( !pAttr
->GetPrev() || !pAttr
->GetPrev()->ppHead
,
3333 "Previous-Attribut hat noch einen Header" );
3334 pAttr
->SetHead( pTbl
);
3337 pAttr
->nSttPara
= rSttPara
;
3338 pAttr
->nEndPara
= rSttPara
;
3339 pAttr
->nSttCntnt
= nSttCnt
;
3340 pAttr
->nEndCntnt
= nSttCnt
;
3342 pAttr
= pAttr
->GetNext();
3349 void SwHTMLParser::InsertAttr( const SfxPoolItem
& rItem
, BOOL bLikePara
,
3352 _HTMLAttr
* pTmp
= new _HTMLAttr( *pPam
->GetPoint(),
3355 pTmp
->SetLikePara();
3356 USHORT nTmp
= bInsAtStart
? 0 : aSetAttrTab
.Count();
3357 aSetAttrTab
.Insert( pTmp
, nTmp
);
3360 void SwHTMLParser::InsertAttrs( _HTMLAttrs
& rAttrs
)
3362 while( rAttrs
.Count() )
3364 _HTMLAttr
*pAttr
= rAttrs
[0];
3365 InsertAttr( pAttr
->GetItem() );
3366 rAttrs
.Remove( 0, 1 );
3373 void SwHTMLParser::NewStdAttr( int nToken
)
3375 String aId
, aStyle
, aClass
, aLang
, aDir
;
3377 const HTMLOptions
*pHTMLOptions
= GetOptions();
3378 for( USHORT i
= pHTMLOptions
->Count(); i
; )
3380 const HTMLOption
*pOption
= (*pHTMLOptions
)[--i
];
3381 switch( pOption
->GetToken() )
3384 aId
= pOption
->GetString();
3387 aStyle
= pOption
->GetString();
3390 aClass
= pOption
->GetString();
3393 aLang
= pOption
->GetString();
3396 aDir
= pOption
->GetString();
3401 // einen neuen Kontext anlegen
3402 _HTMLAttrContext
*pCntxt
= new _HTMLAttrContext( static_cast< sal_uInt16
>(nToken
) );
3405 if( HasStyleOptions( aStyle
, aId
, aClass
, &aLang
, &aDir
) )
3407 SfxItemSet
aItemSet( pDoc
->GetAttrPool(), pCSS1Parser
->GetWhichMap() );
3408 SvxCSS1PropertyInfo aPropInfo
;
3410 if( ParseStyleOptions( aStyle
, aId
, aClass
, aItemSet
, aPropInfo
, &aLang
, &aDir
) )
3412 if( HTML_SPAN_ON
!= nToken
|| !aClass
.Len() ||
3413 !CreateContainer( aClass
, aItemSet
, aPropInfo
, pCntxt
) )
3414 DoPositioning( aItemSet
, aPropInfo
, pCntxt
);
3415 InsertAttrs( aItemSet
, aPropInfo
, pCntxt
, TRUE
);
3419 // den Kontext merken
3420 PushContext( pCntxt
);
3423 void SwHTMLParser::NewStdAttr( int nToken
,
3424 _HTMLAttr
**ppAttr
, const SfxPoolItem
& rItem
,
3425 _HTMLAttr
**ppAttr2
, const SfxPoolItem
*pItem2
,
3426 _HTMLAttr
**ppAttr3
, const SfxPoolItem
*pItem3
)
3428 String aId
, aStyle
, aClass
, aLang
, aDir
;
3430 const HTMLOptions
*pHTMLOptions
= GetOptions();
3431 for( USHORT i
= pHTMLOptions
->Count(); i
; )
3433 const HTMLOption
*pOption
= (*pHTMLOptions
)[--i
];
3434 switch( pOption
->GetToken() )
3437 aId
= pOption
->GetString();
3440 aStyle
= pOption
->GetString();
3443 aClass
= pOption
->GetString();
3446 aLang
= pOption
->GetString();
3449 aDir
= pOption
->GetString();
3454 // einen neuen Kontext anlegen
3455 _HTMLAttrContext
*pCntxt
= new _HTMLAttrContext( static_cast< sal_uInt16
>(nToken
) );
3458 if( HasStyleOptions( aStyle
, aId
, aClass
, &aLang
, &aDir
) )
3460 SfxItemSet
aItemSet( pDoc
->GetAttrPool(), pCSS1Parser
->GetWhichMap() );
3461 SvxCSS1PropertyInfo aPropInfo
;
3463 aItemSet
.Put( rItem
);
3465 aItemSet
.Put( *pItem2
);
3467 aItemSet
.Put( *pItem3
);
3469 if( ParseStyleOptions( aStyle
, aId
, aClass
, aItemSet
, aPropInfo
, &aLang
, &aDir
) )
3470 DoPositioning( aItemSet
, aPropInfo
, pCntxt
);
3472 InsertAttrs( aItemSet
, aPropInfo
, pCntxt
, TRUE
);
3476 InsertAttr( ppAttr
,rItem
, pCntxt
);
3479 ASSERT( ppAttr2
, "missing table entry for item2" );
3480 InsertAttr( ppAttr2
, *pItem2
, pCntxt
);
3484 ASSERT( ppAttr3
, "missing table entry for item3" );
3485 InsertAttr( ppAttr3
, *pItem3
, pCntxt
);
3489 // den Kontext merken
3490 PushContext( pCntxt
);
3493 void SwHTMLParser::EndTag( int nToken
)
3495 // den Kontext holen
3496 _HTMLAttrContext
*pCntxt
= PopContext( static_cast< sal_uInt16
>(nToken
& ~1) );
3499 // und ggf. die Attribute beenden
3500 EndContext( pCntxt
);
3506 void SwHTMLParser::NewBasefontAttr()
3508 String aId
, aStyle
, aClass
, aLang
, aDir
;
3511 const HTMLOptions
*pHTMLOptions
= GetOptions();
3512 for( USHORT i
= pHTMLOptions
->Count(); i
; )
3514 const HTMLOption
*pOption
= (*pHTMLOptions
)[--i
];
3515 switch( pOption
->GetToken() )
3518 nSize
= (USHORT
)pOption
->GetNumber();
3521 aId
= pOption
->GetString();
3524 aStyle
= pOption
->GetString();
3527 aClass
= pOption
->GetString();
3530 aLang
= pOption
->GetString();
3533 aDir
= pOption
->GetString();
3544 // einen neuen Kontext anlegen
3545 _HTMLAttrContext
*pCntxt
= new _HTMLAttrContext( HTML_BASEFONT_ON
);
3548 if( HasStyleOptions( aStyle
, aId
, aClass
, &aLang
, &aDir
) )
3550 SfxItemSet
aItemSet( pDoc
->GetAttrPool(), pCSS1Parser
->GetWhichMap() );
3551 SvxCSS1PropertyInfo aPropInfo
;
3553 SvxFontHeightItem
aFontHeight( aFontHeights
[nSize
-1], 100, RES_CHRATR_FONTSIZE
);
3554 aItemSet
.Put( aFontHeight
);
3555 aFontHeight
.SetWhich( RES_CHRATR_CJK_FONTSIZE
);
3556 aItemSet
.Put( aFontHeight
);
3557 aFontHeight
.SetWhich( RES_CHRATR_CTL_FONTSIZE
);
3558 aItemSet
.Put( aFontHeight
);
3560 if( ParseStyleOptions( aStyle
, aId
, aClass
, aItemSet
, aPropInfo
, &aLang
, &aDir
) )
3561 DoPositioning( aItemSet
, aPropInfo
, pCntxt
);
3563 InsertAttrs( aItemSet
, aPropInfo
, pCntxt
, TRUE
);
3567 SvxFontHeightItem
aFontHeight( aFontHeights
[nSize
-1], 100, RES_CHRATR_FONTSIZE
);
3568 InsertAttr( &aAttrTab
.pFontHeight
, aFontHeight
, pCntxt
);
3569 aFontHeight
.SetWhich( RES_CHRATR_CJK_FONTSIZE
);
3570 InsertAttr( &aAttrTab
.pFontHeightCJK
, aFontHeight
, pCntxt
);
3571 aFontHeight
.SetWhich( RES_CHRATR_CTL_FONTSIZE
);
3572 InsertAttr( &aAttrTab
.pFontHeightCTL
, aFontHeight
, pCntxt
);
3575 // den Kontext merken
3576 PushContext( pCntxt
);
3578 // die Font-Size merken
3579 aBaseFontStack
.Insert( nSize
, aBaseFontStack
.Count() );
3582 void SwHTMLParser::EndBasefontAttr()
3584 EndTag( HTML_BASEFONT_ON
);
3586 // Stack-Unterlauf in Tabellen vermeiden
3587 if( aBaseFontStack
.Count() > nBaseFontStMin
)
3588 aBaseFontStack
.Remove( aBaseFontStack
.Count()-1, 1 );
3591 void SwHTMLParser::NewFontAttr( int nToken
)
3594 ( aBaseFontStack
.Count() > nBaseFontStMin
3595 ? (aBaseFontStack
[aBaseFontStack
.Count()-1] & FONTSIZE_MASK
)
3598 ( aFontStack
.Count() > nFontStMin
3599 ? (aFontStack
[aFontStack
.Count()-1] & FONTSIZE_MASK
)
3602 String aFace
, aId
, aStyle
, aClass
, aLang
, aDir
;
3604 ULONG nFontHeight
= 0; // tatsaechlich einzustellende Font-Hoehe
3605 USHORT nSize
= 0; // Fontgroesse in Netscape-Notation (1-7)
3606 BOOL bColor
= FALSE
;
3608 const HTMLOptions
*pHTMLOptions
= GetOptions();
3609 for( USHORT i
= pHTMLOptions
->Count(); i
; )
3611 const HTMLOption
*pOption
= (*pHTMLOptions
)[--i
];
3612 switch( pOption
->GetToken() )
3615 if( HTML_FONT_ON
==nToken
&& pOption
->GetString().Len() )
3618 if( '+' == pOption
->GetString().GetChar(0) ||
3619 '-' == pOption
->GetString().GetChar(0) )
3620 nSSize
= nBaseSize
+ pOption
->GetSNumber();
3622 nSSize
= (INT32
)pOption
->GetNumber();
3626 else if( nSSize
> 7 )
3629 nSize
= (USHORT
)nSSize
;
3630 nFontHeight
= aFontHeights
[nSize
-1];
3634 if( HTML_FONT_ON
==nToken
)
3636 pOption
->GetColor( aColor
);
3641 if( HTML_FONT_ON
==nToken
)
3642 aFace
= pOption
->GetString();
3645 aId
= pOption
->GetString();
3648 aStyle
= pOption
->GetString();
3651 aClass
= pOption
->GetString();
3654 aLang
= pOption
->GetString();
3657 aDir
= pOption
->GetString();
3662 if( HTML_FONT_ON
!= nToken
)
3664 // HTML_BIGPRINT_ON oder HTML_SMALLPRINT_ON
3666 // in Ueberschriften bestimmt die aktuelle Ueberschrift
3667 // die Font-Hoehe und nicht BASEFONT
3668 USHORT nPoolId
= GetCurrFmtColl()->GetPoolFmtId();
3669 if( (nPoolId
>=RES_POOLCOLL_HEADLINE1
&&
3670 nPoolId
<=RES_POOLCOLL_HEADLINE6
) )
3672 // wenn die Schriftgroesse in der Ueberschrift noch
3673 // nicht veraendert ist, die aus der Vorlage nehmen
3674 if( nFontStHeadStart
==aFontStack
.Count() )
3675 nFontSize
= static_cast< USHORT
>(6 - (nPoolId
- RES_POOLCOLL_HEADLINE1
));
3680 if( HTML_BIGPRINT_ON
== nToken
)
3681 nSize
= ( nFontSize
<7 ? nFontSize
+1 : 7 );
3683 nSize
= ( nFontSize
>1 ? nFontSize
-1 : 1 );
3685 // in Ueberschriften wird die neue Fonthoehe wenn moeglich aus
3686 // den Vorlagen geholt.
3687 if( nPoolId
&& nSize
>=1 && nSize
<=6 )
3689 pCSS1Parser
->GetTxtCollFromPool(
3690 RES_POOLCOLL_HEADLINE1
+6-nSize
)->GetSize().GetHeight();
3692 nFontHeight
= aFontHeights
[nSize
-1];
3695 ASSERT( !nSize
== !nFontHeight
, "HTML-Font-Size != Font-Height" );
3697 String aFontName
, aStyleName
;
3698 FontFamily eFamily
= FAMILY_DONTKNOW
; // Family und Pitch,
3699 FontPitch ePitch
= PITCH_DONTKNOW
; // falls nicht gefunden
3700 rtl_TextEncoding eEnc
= gsl_getSystemTextEncoding();
3702 if( aFace
.Len() && !pCSS1Parser
->IsIgnoreFontFamily() )
3704 const FontList
*pFList
= 0;
3705 SwDocShell
*pDocSh
= pDoc
->GetDocShell();
3708 const SvxFontListItem
*pFListItem
=
3709 (const SvxFontListItem
*)pDocSh
->GetItem(SID_ATTR_CHAR_FONTLIST
);
3711 pFList
= pFListItem
->GetFontList();
3714 BOOL bFound
= FALSE
;
3715 xub_StrLen nStrPos
= 0;
3716 while( nStrPos
!=STRING_NOTFOUND
)
3718 String aFName
= aFace
.GetToken( 0, ',', nStrPos
);
3719 aFName
.EraseTrailingChars().EraseLeadingChars();
3722 if( !bFound
&& pFList
)
3724 sal_Handle hFont
= pFList
->GetFirstFontInfo( aFName
);
3727 const FontInfo
& rFInfo
= pFList
->GetFontInfo( hFont
);
3728 if( RTL_TEXTENCODING_DONTKNOW
!= rFInfo
.GetCharSet() )
3731 if( RTL_TEXTENCODING_SYMBOL
== rFInfo
.GetCharSet() )
3732 eEnc
= RTL_TEXTENCODING_SYMBOL
;
3736 if( aFontName
.Len() )
3738 aFontName
+= aFName
;
3744 // einen neuen Kontext anlegen
3745 _HTMLAttrContext
*pCntxt
= new _HTMLAttrContext( static_cast< sal_uInt16
>(nToken
) );
3748 if( HasStyleOptions( aStyle
, aId
, aClass
, &aLang
, &aDir
) )
3750 SfxItemSet
aItemSet( pDoc
->GetAttrPool(), pCSS1Parser
->GetWhichMap() );
3751 SvxCSS1PropertyInfo aPropInfo
;
3755 SvxFontHeightItem
aFontHeight( nFontHeight
, 100, RES_CHRATR_FONTSIZE
);
3756 aItemSet
.Put( aFontHeight
);
3757 aFontHeight
.SetWhich( RES_CHRATR_CJK_FONTSIZE
);
3758 aItemSet
.Put( aFontHeight
);
3759 aFontHeight
.SetWhich( RES_CHRATR_CTL_FONTSIZE
);
3760 aItemSet
.Put( aFontHeight
);
3763 aItemSet
.Put( SvxColorItem(aColor
, RES_CHRATR_COLOR
) );
3764 if( aFontName
.Len() )
3766 SvxFontItem
aFont( eFamily
, aFontName
, aStyleName
, ePitch
, eEnc
, RES_CHRATR_FONT
);
3767 aItemSet
.Put( aFont
);
3768 aFont
.SetWhich( RES_CHRATR_CJK_FONT
);
3769 aItemSet
.Put( aFont
);
3770 aFont
.SetWhich( RES_CHRATR_CTL_FONT
);
3771 aItemSet
.Put( aFont
);
3775 if( ParseStyleOptions( aStyle
, aId
, aClass
, aItemSet
, aPropInfo
, &aLang
, &aDir
) )
3776 DoPositioning( aItemSet
, aPropInfo
, pCntxt
);
3778 InsertAttrs( aItemSet
, aPropInfo
, pCntxt
, TRUE
);
3784 SvxFontHeightItem
aFontHeight( nFontHeight
, 100, RES_CHRATR_FONTSIZE
);
3785 InsertAttr( &aAttrTab
.pFontHeight
, aFontHeight
, pCntxt
);
3786 aFontHeight
.SetWhich( RES_CHRATR_CJK_FONTSIZE
);
3787 InsertAttr( &aAttrTab
.pFontHeightCJK
, aFontHeight
, pCntxt
);
3788 aFontHeight
.SetWhich( RES_CHRATR_CTL_FONTSIZE
);
3789 InsertAttr( &aAttrTab
.pFontHeightCTL
, aFontHeight
, pCntxt
);
3792 InsertAttr( &aAttrTab
.pFontColor
, SvxColorItem(aColor
, RES_CHRATR_COLOR
), pCntxt
);
3793 if( aFontName
.Len() )
3795 SvxFontItem
aFont( eFamily
, aFontName
, aStyleName
, ePitch
, eEnc
, RES_CHRATR_FONT
);
3796 InsertAttr( &aAttrTab
.pFont
, aFont
, pCntxt
);
3797 aFont
.SetWhich( RES_CHRATR_CJK_FONT
);
3798 InsertAttr( &aAttrTab
.pFontCJK
, aFont
, pCntxt
);
3799 aFont
.SetWhich( RES_CHRATR_CTL_FONT
);
3800 InsertAttr( &aAttrTab
.pFontCTL
, aFont
, pCntxt
);
3804 // den Kontext merken
3805 PushContext( pCntxt
);
3807 aFontStack
.Insert( nSize
, aFontStack
.Count() );
3810 void SwHTMLParser::EndFontAttr( int nToken
)
3814 // Stack-Unterlauf in Tabellen vermeiden
3815 if( aFontStack
.Count() > nFontStMin
)
3816 aFontStack
.Remove( aFontStack
.Count()-1, 1 );
3821 void SwHTMLParser::NewPara()
3823 if( pPam
->GetPoint()->nContent
.GetIndex() )
3824 AppendTxtNode( AM_SPACE
);
3828 eParaAdjust
= SVX_ADJUST_END
;
3829 String aId
, aStyle
, aClass
, aLang
, aDir
;
3831 const HTMLOptions
*pHTMLOptions
= GetOptions();
3832 for( USHORT i
= pHTMLOptions
->Count(); i
; )
3834 const HTMLOption
*pOption
= (*pHTMLOptions
)[--i
];
3835 switch( pOption
->GetToken() )
3838 aId
= pOption
->GetString();
3841 eParaAdjust
= (SvxAdjust
)pOption
->GetEnum( aHTMLPAlignTable
, static_cast< sal_uInt16
>(eParaAdjust
) );
3844 aStyle
= pOption
->GetString();
3847 aClass
= pOption
->GetString();
3850 aLang
= pOption
->GetString();
3853 aDir
= pOption
->GetString();
3858 // einen neuen Kontext anlegen
3859 _HTMLAttrContext
*pCntxt
=
3860 aClass
.Len() ? new _HTMLAttrContext( HTML_PARABREAK_ON
,
3861 RES_POOLCOLL_TEXT
, aClass
)
3862 : new _HTMLAttrContext( HTML_PARABREAK_ON
);
3864 // Styles parsen (Class nicht beruecksichtigen. Das geht nur, solange
3865 // keine der CSS1-Properties der Klasse hart formatiert werden muss!!!)
3866 if( HasStyleOptions( aStyle
, aId
, aEmptyStr
, &aLang
, &aDir
) )
3868 SfxItemSet
aItemSet( pDoc
->GetAttrPool(), pCSS1Parser
->GetWhichMap() );
3869 SvxCSS1PropertyInfo aPropInfo
;
3871 if( ParseStyleOptions( aStyle
, aId
, aEmptyStr
, aItemSet
, aPropInfo
, &aLang
, &aDir
) )
3873 ASSERT( !aClass
.Len() || !pCSS1Parser
->GetClass( aClass
),
3874 "Class wird nicht beruecksichtigt" );
3875 DoPositioning( aItemSet
, aPropInfo
, pCntxt
);
3876 InsertAttrs( aItemSet
, aPropInfo
, pCntxt
);
3880 if( SVX_ADJUST_END
!= eParaAdjust
)
3881 InsertAttr( &aAttrTab
.pAdjust
, SvxAdjustItem(eParaAdjust
, RES_PARATR_ADJUST
), pCntxt
);
3883 // und auf den Stack packen
3884 PushContext( pCntxt
);
3886 // die aktuelle Vorlage oder deren Attribute setzen
3887 SetTxtCollAttrs( aClass
.Len() ? pCntxt
: 0 );
3889 // Laufbalkenanzeige
3892 ASSERT( !nOpenParaToken
, "Jetzt geht ein offenes Absatz-Element verloren" );
3893 nOpenParaToken
= HTML_PARABREAK_ON
;
3896 void SwHTMLParser::EndPara( BOOL bReal
)
3898 if( HTML_LI_ON
==nOpenParaToken
&& pTable
)
3901 const SwNumRule
*pNumRule
= pPam
->GetNode()->GetTxtNode()->GetNumRule();
3903 ASSERT( pNumRule
, "Wo ist die Numrule geblieben" );
3906 // leere Absaetze werden von Netscape uebersprungen, von uns jetzt auch
3909 if( pPam
->GetPoint()->nContent
.GetIndex() )
3910 AppendTxtNode( AM_SPACE
);
3915 // wenn ein DD oder DT offen war, handelt es sich um eine
3916 // implizite Def-Liste, die jetzt beendet werden muss
3917 if( (nOpenParaToken
==HTML_DT_ON
|| nOpenParaToken
==HTML_DD_ON
) &&
3923 // den Kontext vom Stack holen. Er kann auch von einer implizit
3924 // geoeffneten Definitionsliste kommen
3925 _HTMLAttrContext
*pCntxt
=
3926 PopContext( static_cast< sal_uInt16
>(nOpenParaToken
? (nOpenParaToken
& ~1)
3927 : HTML_PARABREAK_ON
) );
3929 // Attribute beenden
3932 EndContext( pCntxt
);
3933 SetAttr(); // Absatz-Atts wegen JavaScript moeglichst schnell setzen
3937 // und die bisherige Vorlage neu setzen
3945 void SwHTMLParser::NewHeading( int nToken
)
3947 eParaAdjust
= SVX_ADJUST_END
;
3949 String aId
, aStyle
, aClass
, aLang
, aDir
;
3951 const HTMLOptions
*pHTMLOptions
= GetOptions();
3952 for( USHORT i
= pHTMLOptions
->Count(); i
; )
3954 const HTMLOption
*pOption
= (*pHTMLOptions
)[--i
];
3955 switch( pOption
->GetToken() )
3958 aId
= pOption
->GetString();
3961 eParaAdjust
= (SvxAdjust
)pOption
->GetEnum( aHTMLPAlignTable
, static_cast< sal_uInt16
>(eParaAdjust
) );
3964 aStyle
= pOption
->GetString();
3967 aClass
= pOption
->GetString();
3970 aLang
= pOption
->GetString();
3973 aDir
= pOption
->GetString();
3978 // einen neuen Absatz aufmachen
3979 if( pPam
->GetPoint()->nContent
.GetIndex() )
3980 AppendTxtNode( AM_SPACE
);
3984 // die passende Vorlage suchen
3988 case HTML_HEAD1_ON
: nTxtColl
= RES_POOLCOLL_HEADLINE1
; break;
3989 case HTML_HEAD2_ON
: nTxtColl
= RES_POOLCOLL_HEADLINE2
; break;
3990 case HTML_HEAD3_ON
: nTxtColl
= RES_POOLCOLL_HEADLINE3
; break;
3991 case HTML_HEAD4_ON
: nTxtColl
= RES_POOLCOLL_HEADLINE4
; break;
3992 case HTML_HEAD5_ON
: nTxtColl
= RES_POOLCOLL_HEADLINE5
; break;
3993 case HTML_HEAD6_ON
: nTxtColl
= RES_POOLCOLL_HEADLINE6
; break;
3994 default: nTxtColl
= RES_POOLCOLL_STANDARD
; break;
3997 // den Kontext anlegen
3998 _HTMLAttrContext
*pCntxt
= new _HTMLAttrContext( static_cast< sal_uInt16
>(nToken
), nTxtColl
, aClass
);
4000 // Styles parsen (zu Class siehe auch NewPara)
4001 if( HasStyleOptions( aStyle
, aId
, aEmptyStr
, &aLang
, &aDir
) )
4003 SfxItemSet
aItemSet( pDoc
->GetAttrPool(), pCSS1Parser
->GetWhichMap() );
4004 SvxCSS1PropertyInfo aPropInfo
;
4006 if( ParseStyleOptions( aStyle
, aId
, aEmptyStr
, aItemSet
, aPropInfo
, &aLang
, &aDir
) )
4008 ASSERT( !aClass
.Len() || !pCSS1Parser
->GetClass( aClass
),
4009 "Class wird nicht beruecksichtigt" );
4010 DoPositioning( aItemSet
, aPropInfo
, pCntxt
);
4011 InsertAttrs( aItemSet
, aPropInfo
, pCntxt
);
4015 if( SVX_ADJUST_END
!= eParaAdjust
)
4016 InsertAttr( &aAttrTab
.pAdjust
, SvxAdjustItem(eParaAdjust
, RES_PARATR_ADJUST
), pCntxt
);
4018 // udn auf den Stack packen
4019 PushContext( pCntxt
);
4021 // und die Vorlage oder deren Attribute setzen
4022 SetTxtCollAttrs( pCntxt
);
4024 nFontStHeadStart
= aFontStack
.Count();
4026 // Laufbalkenanzeige
4030 void SwHTMLParser::EndHeading()
4032 // einen neuen Absatz aufmachen
4033 if( pPam
->GetPoint()->nContent
.GetIndex() )
4034 AppendTxtNode( AM_SPACE
);
4038 // Kontext zu dem Token suchen und vom Stack holen
4039 _HTMLAttrContext
*pCntxt
= 0;
4040 USHORT nPos
= aContexts
.Count();
4041 while( !pCntxt
&& nPos
>nContextStMin
)
4043 switch( aContexts
[--nPos
]->GetToken() )
4051 pCntxt
= aContexts
[nPos
];
4052 aContexts
.Remove( nPos
, 1 );
4057 // und noch Attribute beenden
4060 EndContext( pCntxt
);
4061 SetAttr(); // Absatz-Atts wegen JavaScript moeglichst schnell setzen
4065 // die bisherige Vorlage neu setzen
4068 nFontStHeadStart
= nFontStMin
;
4073 void SwHTMLParser::NewTxtFmtColl( int nToken
, USHORT nColl
)
4075 String aId
, aStyle
, aClass
, aLang
, aDir
;
4077 const HTMLOptions
*pHTMLOptions
= GetOptions();
4078 for( USHORT i
= pHTMLOptions
->Count(); i
; )
4080 const HTMLOption
*pOption
= (*pHTMLOptions
)[--i
];
4081 switch( pOption
->GetToken() )
4084 aId
= pOption
->GetString();
4087 aStyle
= pOption
->GetString();
4090 aClass
= pOption
->GetString();
4093 aLang
= pOption
->GetString();
4096 aDir
= pOption
->GetString();
4101 // einen neuen Absatz aufmachen
4102 SwHTMLAppendMode eMode
= AM_NORMAL
;
4105 case HTML_LISTING_ON
:
4107 // Diese beiden Tags werden jetzt auf die PRE-Vorlage gemappt.
4108 // Fuer dem Fall, dass ein CLASS angegeben ist, loeschen wir
4109 // es damit wir nicht die CLASS der PRE-Vorlage bekommen.
4111 case HTML_BLOCKQUOTE_ON
:
4112 case HTML_BLOCKQUOTE30_ON
:
4113 case HTML_PREFORMTXT_ON
:
4116 case HTML_ADDRESS_ON
:
4117 eMode
= AM_NOSPACE
; // ADDRESS kann auf einen <P> ohne </P> folgen
4121 eMode
= AM_SOFTNOSPACE
;
4124 ASSERT( !this, "unbekannte Vorlage" );
4127 if( pPam
->GetPoint()->nContent
.GetIndex() )
4128 AppendTxtNode( eMode
);
4129 else if( AM_SPACE
==eMode
)
4132 // ... und in einem Kontext merken
4133 _HTMLAttrContext
*pCntxt
= new _HTMLAttrContext( static_cast< sal_uInt16
>(nToken
), nColl
, aClass
);
4135 // Styles parsen (zu Class siehe auch NewPara)
4136 if( HasStyleOptions( aStyle
, aId
, aEmptyStr
, &aLang
, &aDir
) )
4138 SfxItemSet
aItemSet( pDoc
->GetAttrPool(), pCSS1Parser
->GetWhichMap() );
4139 SvxCSS1PropertyInfo aPropInfo
;
4141 if( ParseStyleOptions( aStyle
, aId
, aEmptyStr
, aItemSet
, aPropInfo
, &aLang
, &aDir
) )
4143 ASSERT( !aClass
.Len() || !pCSS1Parser
->GetClass( aClass
),
4144 "Class wird nicht beruecksichtigt" );
4145 DoPositioning( aItemSet
, aPropInfo
, pCntxt
);
4146 InsertAttrs( aItemSet
, aPropInfo
, pCntxt
);
4150 PushContext( pCntxt
);
4152 // die neue Vorlage setzen
4153 SetTxtCollAttrs( pCntxt
);
4155 // Laufbalkenanzeige aktualisieren
4159 void SwHTMLParser::EndTxtFmtColl( int nToken
)
4161 SwHTMLAppendMode eMode
= AM_NORMAL
;
4162 switch( nToken
& ~1 )
4164 case HTML_BLOCKQUOTE_ON
:
4165 case HTML_BLOCKQUOTE30_ON
:
4166 case HTML_PREFORMTXT_ON
:
4167 case HTML_LISTING_ON
:
4171 case HTML_ADDRESS_ON
:
4174 eMode
= AM_SOFTNOSPACE
;
4177 ASSERT( !this, "unbekannte Vorlage" );
4180 if( pPam
->GetPoint()->nContent
.GetIndex() )
4181 AppendTxtNode( eMode
);
4182 else if( AM_SPACE
==eMode
)
4185 // den aktuellen Kontext vom Stack holen
4186 _HTMLAttrContext
*pCntxt
= PopContext( static_cast< sal_uInt16
>(nToken
& ~1) );
4188 // und noch Attribute beenden
4191 EndContext( pCntxt
);
4192 SetAttr(); // Absatz-Atts wegen JavaScript moeglichst schnell setzen
4196 // und die bisherige Vorlage setzen
4202 void SwHTMLParser::NewDefList()
4204 String aId
, aStyle
, aClass
, aLang
, aDir
;
4206 const HTMLOptions
*pHTMLOptions
= GetOptions();
4207 for( USHORT i
= pHTMLOptions
->Count(); i
; )
4209 const HTMLOption
*pOption
= (*pHTMLOptions
)[--i
];
4210 switch( pOption
->GetToken() )
4213 aId
= pOption
->GetString();
4216 aStyle
= pOption
->GetString();
4219 aClass
= pOption
->GetString();
4222 aLang
= pOption
->GetString();
4225 aDir
= pOption
->GetString();
4230 // einen neuen Absatz aufmachen
4231 BOOL bSpace
= (GetNumInfo().GetDepth() + nDefListDeep
) == 0;
4232 if( pPam
->GetPoint()->nContent
.GetIndex() )
4233 AppendTxtNode( bSpace
? AM_SPACE
: AM_SOFTNOSPACE
);
4241 BOOL bInDD
= FALSE
, bNotInDD
= FALSE
;
4242 USHORT nPos
= aContexts
.Count();
4243 while( !bInDD
&& !bNotInDD
&& nPos
>nContextStMin
)
4245 USHORT nCntxtToken
= aContexts
[--nPos
]->GetToken();
4246 switch( nCntxtToken
)
4248 case HTML_DEFLIST_ON
:
4249 case HTML_DIRLIST_ON
:
4250 case HTML_MENULIST_ON
:
4251 case HTML_ORDERLIST_ON
:
4252 case HTML_UNORDERLIST_ON
:
4262 // ... und in einem Kontext merken
4263 _HTMLAttrContext
*pCntxt
= new _HTMLAttrContext( HTML_DEFLIST_ON
);
4265 // darin auch die Raender merken
4266 sal_uInt16 nLeft
=0, nRight
=0;
4268 GetMarginsFromContext( nLeft
, nRight
, nIndent
);
4270 // Die Einrueckung, die sich schon aus einem DL-ergibt, entspricht der
4271 // eines DT auf dem aktuellen Level, und die entspricht der eines
4272 // DD auf dem Level davor. Fue einen Level >=2 muss also ein DD-Abstand
4273 // hinzugefuegt werden
4274 if( !bInDD
&& nDefListDeep
> 1 )
4277 // und den der DT-Vorlage des aktuellen Levels
4278 SvxLRSpaceItem rLRSpace
=
4279 pCSS1Parser
->GetTxtFmtColl( RES_POOLCOLL_HTML_DD
, aEmptyStr
)
4281 nLeft
= nLeft
+ static_cast< sal_uInt16
>(rLRSpace
.GetTxtLeft());
4284 pCntxt
->SetMargins( nLeft
, nRight
, nIndent
);
4287 if( HasStyleOptions( aStyle
, aId
, aClass
, &aLang
, &aDir
) )
4289 SfxItemSet
aItemSet( pDoc
->GetAttrPool(), pCSS1Parser
->GetWhichMap() );
4290 SvxCSS1PropertyInfo aPropInfo
;
4292 if( ParseStyleOptions( aStyle
, aId
, aClass
, aItemSet
, aPropInfo
, &aLang
, &aDir
) )
4294 DoPositioning( aItemSet
, aPropInfo
, pCntxt
);
4295 InsertAttrs( aItemSet
, aPropInfo
, pCntxt
);
4299 PushContext( pCntxt
);
4301 // die Attribute der neuen Vorlage setzen
4302 if( nDefListDeep
> 1 )
4303 SetTxtCollAttrs( pCntxt
);
4306 void SwHTMLParser::EndDefList()
4308 BOOL bSpace
= (GetNumInfo().GetDepth() + nDefListDeep
) == 1;
4309 if( pPam
->GetPoint()->nContent
.GetIndex() )
4310 AppendTxtNode( bSpace
? AM_SPACE
: AM_SOFTNOSPACE
);
4314 // ein Level weniger
4315 if( nDefListDeep
> 0 )
4318 // den aktuellen Kontext vom Stack holen
4319 _HTMLAttrContext
*pCntxt
= PopContext( HTML_DEFLIST_ON
);
4321 // und noch Attribute beenden
4324 EndContext( pCntxt
);
4325 SetAttr(); // Absatz-Atts wegen JavaScript moeglichst schnell setzen
4329 // und Vorlage setzen
4333 void SwHTMLParser::NewDefListItem( int nToken
)
4335 // festellen, ob das DD/DT in einer DL vorkommt
4336 BOOL bInDefList
= FALSE
, bNotInDefList
= FALSE
;
4337 USHORT nPos
= aContexts
.Count();
4338 while( !bInDefList
&& !bNotInDefList
&& nPos
>nContextStMin
)
4340 USHORT nCntxtToken
= aContexts
[--nPos
]->GetToken();
4341 switch( nCntxtToken
)
4343 case HTML_DEFLIST_ON
:
4346 case HTML_DIRLIST_ON
:
4347 case HTML_MENULIST_ON
:
4348 case HTML_ORDERLIST_ON
:
4349 case HTML_UNORDERLIST_ON
:
4350 bNotInDefList
= TRUE
;
4355 // wenn nicht, implizit eine neue DL aufmachen
4359 ASSERT( !nOpenParaToken
,
4360 "Jetzt geht ein offenes Absatz-Element verloren" );
4361 nOpenParaToken
= static_cast< sal_uInt16
>(nToken
);
4364 NewTxtFmtColl( nToken
, static_cast< USHORT
>(nToken
==HTML_DD_ON
? RES_POOLCOLL_HTML_DD
4365 : RES_POOLCOLL_HTML_DT
) );
4368 void SwHTMLParser::EndDefListItem( int nToken
, BOOL bSetColl
,
4369 BOOL
/*bLastPara*/ )
4371 // einen neuen Absatz aufmachen
4372 if( !nToken
&& pPam
->GetPoint()->nContent
.GetIndex() )
4373 AppendTxtNode( AM_SOFTNOSPACE
);
4375 // Kontext zu dem Token suchen und vom Stack holen
4377 _HTMLAttrContext
*pCntxt
= 0;
4378 USHORT nPos
= aContexts
.Count();
4379 while( !pCntxt
&& nPos
>nContextStMin
)
4381 USHORT nCntxtToken
= aContexts
[--nPos
]->GetToken();
4382 switch( nCntxtToken
)
4386 if( !nToken
|| nToken
== nCntxtToken
)
4388 pCntxt
= aContexts
[nPos
];
4389 aContexts
.Remove( nPos
, 1 );
4392 case HTML_DEFLIST_ON
:
4393 // keine DD/DT ausserhalb der aktuelen DefListe betrachten
4394 case HTML_DIRLIST_ON
:
4395 case HTML_MENULIST_ON
:
4396 case HTML_ORDERLIST_ON
:
4397 case HTML_UNORDERLIST_ON
:
4398 // und auch nicht ausserhalb einer anderen Liste
4399 nPos
= nContextStMin
;
4404 // und noch Attribute beenden
4407 EndContext( pCntxt
);
4408 SetAttr(); // Absatz-Atts wegen JavaScript moeglichst schnell setzen
4412 // und die bisherige Vorlage setzen
4419 BOOL
SwHTMLParser::HasCurrentParaFlys( BOOL bNoSurroundOnly
,
4420 BOOL bSurroundOnly
) const
4422 // bNoSurroundOnly: Der Absatz enthaelt mindestens einen Rahmen
4424 // bSurroundOnly: Der Absatz enthaelt mindestens einen Rahmen
4425 // mit Umlauf aber keinen ohne Umlauf
4426 // sonst: Der Absatz enthaelt irgendeinen Rahmen
4427 SwNodeIndex
& rNodeIdx
= pPam
->GetPoint()->nNode
;
4430 const SwFmtAnchor
* pAnchor
;
4431 const SwPosition
* pAPos
;
4432 const SwSpzFrmFmts
& rFrmFmtTbl
= *pDoc
->GetSpzFrmFmts();
4435 BOOL bFound
= FALSE
;
4436 for( i
=0; i
<rFrmFmtTbl
.Count(); i
++ )
4438 pFmt
= rFrmFmtTbl
[i
];
4439 pAnchor
= &pFmt
->GetAnchor();
4440 // Ein Rahmen wurde gefunden, wenn
4441 // - er absatzgebunden ist, und
4442 // - im aktuellen Absatz verankert ist, und
4443 // - jeder absatzgebunene Rahmen zaehlt, oder
4444 // - (nur Rahmen oder umlauf zaehlen und ) der Rahmen keinen
4447 if( 0 != ( pAPos
= pAnchor
->GetCntntAnchor()) &&
4448 (FLY_AT_CNTNT
== pAnchor
->GetAnchorId() ||
4449 FLY_AUTO_CNTNT
== pAnchor
->GetAnchorId()) &&
4450 pAPos
->nNode
== rNodeIdx
)
4452 if( !(bNoSurroundOnly
|| bSurroundOnly
) )
4459 // fix #42282#: Wenn Rahmen mit Umlauf gesucht sind,
4460 // auch keine mit Durchlauf beachten. Dabei handelt es
4461 // sich (noch) um HIDDEN-Controls, und denen weicht man
4462 // besser auch nicht aus.
4463 SwSurround eSurround
= pFmt
->GetSurround().GetSurround();
4464 if( bNoSurroundOnly
)
4466 if( SURROUND_NONE
==eSurround
)
4474 if( SURROUND_NONE
==eSurround
)
4479 else if( SURROUND_THROUGHT
!=eSurround
)
4482 // weitersuchen: Es koennten ja noch welche ohne
4483 // Umlauf kommen ...
4495 // die speziellen Methoden zum Einfuegen von Objecten
4497 const SwFmtColl
*SwHTMLParser::GetCurrFmtColl() const
4499 const SwCntntNode
* pCNd
= pPam
->GetCntntNode();
4500 return &pCNd
->GetAnyFmtColl();
4504 void SwHTMLParser::SetTxtCollAttrs( _HTMLAttrContext
*pContext
)
4506 SwTxtFmtColl
*pCollToSet
= 0; // die zu setzende Vorlage
4507 SfxItemSet
*pItemSet
= 0; // der Set fuer harte Attrs
4508 USHORT nTopColl
= pContext
? pContext
->GetTxtFmtColl() : 0;
4509 const String
& rTopClass
= pContext
? pContext
->GetClass() : (const String
&) aEmptyStr
;
4510 USHORT nDfltColl
= RES_POOLCOLL_TEXT
;
4512 BOOL bInPRE
=FALSE
; // etwas Kontext Info
4514 USHORT nLeftMargin
= 0, nRightMargin
= 0; // die Einzuege und
4515 short nFirstLineIndent
= 0; // Abstaende
4518 for( i
= nContextStAttrMin
; i
< aContexts
.Count(); i
++ )
4520 const _HTMLAttrContext
*pCntxt
= aContexts
[i
];
4522 USHORT nColl
= pCntxt
->GetTxtFmtColl();
4525 // Es gibt eine Vorlage, die zu setzen ist. Dann
4526 // muss zunaechst einmal entschieden werden,
4527 // ob die Vorlage auch gesetzt werden kann
4528 BOOL bSetThis
= TRUE
;
4531 case USHORT(RES_POOLCOLL_HTML_PRE
):
4534 case USHORT(RES_POOLCOLL_TEXT
):
4535 // <TD><P CLASS=xxx> muss TD.xxx werden
4536 if( nDfltColl
==RES_POOLCOLL_TABLE
||
4537 nDfltColl
==RES_POOLCOLL_TABLE_HDLN
)
4540 case USHORT(RES_POOLCOLL_HTML_HR
):
4541 // <HR> auch in <PRE> als Vorlage setzen, sonst kann man sie
4542 // nicht mehr exportieren
4550 SwTxtFmtColl
*pNewColl
=
4551 pCSS1Parser
->GetTxtFmtColl( nColl
, pCntxt
->GetClass() );
4555 // wenn jetzt eine andere Vorlage gesetzt werden soll als
4556 // bisher, muss die bishere Vorlage durch harte Attributierung
4561 // die Attribute, die die bisherige Vorlage setzt
4564 pItemSet
= new SfxItemSet( pCollToSet
->GetAttrSet() );
4567 const SfxItemSet
& rCollSet
= pCollToSet
->GetAttrSet();
4568 SfxItemSet
aItemSet( *rCollSet
.GetPool(),
4569 rCollSet
.GetRanges() );
4570 aItemSet
.Set( rCollSet
);
4571 pItemSet
->Put( aItemSet
);
4573 // aber die Attribute, die aktuelle Vorlage setzt
4574 // entfernen, weil sie sonst spaeter ueberschrieben
4576 pItemSet
->Differentiate( pNewColl
->GetAttrSet() );
4579 pCollToSet
= pNewColl
;
4583 // hart Attributieren
4585 pItemSet
= new SfxItemSet( pNewColl
->GetAttrSet() );
4588 const SfxItemSet
& rCollSet
= pNewColl
->GetAttrSet();
4589 SfxItemSet
aItemSet( *rCollSet
.GetPool(),
4590 rCollSet
.GetRanges() );
4591 aItemSet
.Set( rCollSet
);
4592 pItemSet
->Put( aItemSet
);
4598 // vielliecht gibt es ja eine Default-Vorlage?
4599 nColl
= pCntxt
->GetDfltTxtFmtColl();
4604 // ggf. neue Absatz-Einzuege holen
4605 if( pCntxt
->IsLRSpaceChanged() )
4607 USHORT nLeft
=0, nRight
=0;
4609 pCntxt
->GetMargins( nLeft
, nRight
, nFirstLineIndent
);
4610 nLeftMargin
= nLeft
;
4611 nRightMargin
= nRight
;
4615 // wenn im aktuellen Kontext eine neue Vorlage gesetzt werden soll,
4616 // muessen deren Absatz-Abstaende noch in den Kontext eingetragen werden
4617 if( pContext
&& nTopColl
)
4619 // <TD><P CLASS=xxx> muss TD.xxx werden
4620 if( nTopColl
==RES_POOLCOLL_TEXT
&&
4621 (nDfltColl
==RES_POOLCOLL_TABLE
||
4622 nDfltColl
==RES_POOLCOLL_TABLE_HDLN
) )
4623 nTopColl
= nDfltColl
;
4625 const SwTxtFmtColl
*pTopColl
=
4626 pCSS1Parser
->GetTxtFmtColl( nTopColl
, rTopClass
);
4627 const SfxItemSet
& rItemSet
= pTopColl
->GetAttrSet();
4628 const SfxPoolItem
*pItem
;
4629 if( SFX_ITEM_SET
== rItemSet
.GetItemState(RES_LR_SPACE
,TRUE
, &pItem
) )
4631 const SvxLRSpaceItem
*pLRItem
=
4632 (const SvxLRSpaceItem
*)pItem
;
4634 sal_Int32 nLeft
= pLRItem
->GetTxtLeft();
4635 sal_Int32 nRight
= pLRItem
->GetRight();
4636 nFirstLineIndent
= pLRItem
->GetTxtFirstLineOfst();
4638 // In Definitions-Listen enthalten die Abstaende auch die der
4639 // vorhergehenden Level
4640 if( RES_POOLCOLL_HTML_DD
== nTopColl
)
4642 const SvxLRSpaceItem
& rDTLRSpace
= pCSS1Parser
4643 ->GetTxtFmtColl( RES_POOLCOLL_HTML_DT
, aEmptyStr
)
4645 nLeft
-= rDTLRSpace
.GetTxtLeft();
4646 nRight
-= rDTLRSpace
.GetRight();
4648 else if( RES_POOLCOLL_HTML_DT
== nTopColl
)
4654 // die Absatz-Abstaende addieren sich
4655 nLeftMargin
= nLeftMargin
+ static_cast< sal_uInt16
>(nLeft
);
4656 nRightMargin
= nRightMargin
+ static_cast< sal_uInt16
>(nRight
);
4658 pContext
->SetMargins( nLeftMargin
, nRightMargin
,
4661 if( SFX_ITEM_SET
== rItemSet
.GetItemState(RES_UL_SPACE
,TRUE
, &pItem
) )
4663 const SvxULSpaceItem
*pULItem
=
4664 (const SvxULSpaceItem
*)pItem
;
4665 pContext
->SetULSpace( pULItem
->GetUpper(), pULItem
->GetLower() );
4669 // wenn gar keine Vorlage im Kontext gesetzt ist, Textkoerper nehmen
4672 pCollToSet
= pCSS1Parser
->GetTxtCollFromPool( nDfltColl
);
4673 const SvxLRSpaceItem
& rLRItem
= pCollToSet
->GetLRSpace();
4675 nLeftMargin
= static_cast< sal_uInt16
>(rLRItem
.GetTxtLeft());
4677 nRightMargin
= static_cast< sal_uInt16
>(rLRItem
.GetRight());
4678 if( !nFirstLineIndent
)
4679 nFirstLineIndent
= rLRItem
.GetTxtFirstLineOfst();
4682 // bisherige harte Attributierung des Absatzes entfernen
4683 if( aParaAttrs
.Count() )
4685 for( i
=0; i
<aParaAttrs
.Count(); i
++ )
4686 aParaAttrs
[i
]->Invalidate();
4688 aParaAttrs
.Remove( 0, aParaAttrs
.Count() );
4691 // Die Vorlage setzen
4692 pDoc
->SetTxtFmtColl( *pPam
, pCollToSet
);
4694 // ggf. noch den Absatz-Einzug korrigieren
4695 const SvxLRSpaceItem
& rLRItem
= pCollToSet
->GetLRSpace();
4698 bSetLRSpace
= nLeftMargin
!= rLRItem
.GetTxtLeft() ||
4699 nFirstLineIndent
!= rLRItem
.GetTxtFirstLineOfst() ||
4700 nRightMargin
!= rLRItem
.GetRight();
4704 SvxLRSpaceItem
aLRItem( rLRItem
);
4705 aLRItem
.SetTxtLeft( nLeftMargin
);
4706 aLRItem
.SetRight( nRightMargin
);
4707 aLRItem
.SetTxtFirstLineOfst( nFirstLineIndent
);
4709 pItemSet
->Put( aLRItem
);
4712 NewAttr( &aAttrTab
.pLRSpace
, aLRItem
);
4713 aAttrTab
.pLRSpace
->SetLikePara();
4714 aParaAttrs
.Insert( aAttrTab
.pLRSpace
, aParaAttrs
.Count() );
4715 EndAttr( aAttrTab
.pLRSpace
, 0, FALSE
);
4719 // und nun noch die Attribute setzen
4722 InsertParaAttrs( *pItemSet
);
4729 void SwHTMLParser::NewCharFmt( int nToken
)
4731 String aId
, aStyle
, aClass
, aLang
, aDir
;
4733 const HTMLOptions
*pHTMLOptions
= GetOptions();
4734 for( USHORT i
= pHTMLOptions
->Count(); i
; )
4736 const HTMLOption
*pOption
= (*pHTMLOptions
)[--i
];
4737 switch( pOption
->GetToken() )
4740 aId
= pOption
->GetString();
4743 aStyle
= pOption
->GetString();
4746 aClass
= pOption
->GetString();
4749 aLang
= pOption
->GetString();
4752 aDir
= pOption
->GetString();
4757 // einen neuen Kontext anlegen
4758 _HTMLAttrContext
*pCntxt
= new _HTMLAttrContext( static_cast< sal_uInt16
>(nToken
) );
4760 // die Vorlage setzen und im Kontext merken
4761 SwCharFmt
* pCFmt
= pCSS1Parser
->GetChrFmt( static_cast< sal_uInt16
>(nToken
), aClass
);
4762 ASSERT( pCFmt
, "keine Zeichenvorlage zu Token gefunden" );
4765 // Styles parsen (zu Class siehe auch NewPara)
4766 if( HasStyleOptions( aStyle
, aId
, aEmptyStr
, &aLang
, &aDir
) )
4768 SfxItemSet
aItemSet( pDoc
->GetAttrPool(), pCSS1Parser
->GetWhichMap() );
4769 SvxCSS1PropertyInfo aPropInfo
;
4771 if( ParseStyleOptions( aStyle
, aId
, aEmptyStr
, aItemSet
, aPropInfo
, &aLang
, &aDir
) )
4773 ASSERT( !aClass
.Len() || !pCSS1Parser
->GetClass( aClass
),
4774 "Class wird nicht beruecksichtigt" );
4775 DoPositioning( aItemSet
, aPropInfo
, pCntxt
);
4776 InsertAttrs( aItemSet
, aPropInfo
, pCntxt
, TRUE
);
4780 // Zeichen-Vorlagen werden in einem eigenen Stack gehalten und
4781 // koennen nie durch Styles eingefuegt werden. Das Attribut ist deshalb
4782 // auch gar nicht im CSS1-Which-Range enthalten
4784 InsertAttr( &aAttrTab
.pCharFmts
, SwFmtCharFmt( pCFmt
), pCntxt
);
4786 // den Kontext merken
4787 PushContext( pCntxt
);
4793 void SwHTMLParser::InsertSpacer()
4795 // und es ggf. durch die Optionen veraendern
4797 sal_Int16 eVertOri
= text::VertOrientation::TOP
;
4798 sal_Int16 eHoriOri
= text::HoriOrientation::NONE
;
4801 BOOL bPrcWidth
= FALSE
;
4802 BOOL bPrcHeight
= FALSE
;
4803 USHORT nType
= HTML_SPTYPE_HORI
;
4805 const HTMLOptions
*pHTMLOptions
= GetOptions();
4806 for( USHORT i
= pHTMLOptions
->Count(); i
; )
4808 const HTMLOption
*pOption
= (*pHTMLOptions
)[--i
];
4809 switch( pOption
->GetToken() )
4812 aId
= pOption
->GetString();
4815 pOption
->GetEnum( nType
, aHTMLSpacerTypeTable
);
4819 pOption
->GetEnum( aHTMLImgVAlignTable
,
4822 pOption
->GetEnum( aHTMLImgHAlignTable
,
4826 // erstmal nur als Pixelwerte merken!
4827 bPrcWidth
= (pOption
->GetString().Search('%') != STRING_NOTFOUND
);
4828 aSize
.Width() = (long)pOption
->GetNumber();
4831 // erstmal nur als Pixelwerte merken!
4832 bPrcHeight
= (pOption
->GetString().Search('%') != STRING_NOTFOUND
);
4833 aSize
.Height() = (long)pOption
->GetNumber();
4836 // erstmal nur als Pixelwerte merken!
4837 nSize
= pOption
->GetNumber();
4844 case HTML_SPTYPE_BLOCK
:
4846 // einen leeren Textrahmen anlegen
4848 // den Itemset holen
4849 SfxItemSet
aFrmSet( pDoc
->GetAttrPool(),
4850 RES_FRMATR_BEGIN
, RES_FRMATR_END
-1 );
4852 Reader::ResetFrmFmtAttrs( aFrmSet
);
4854 // den Anker und die Ausrichtung setzen
4855 SetAnchorAndAdjustment( eVertOri
, eHoriOri
, aFrmSet
);
4857 // und noch die Groesse des Rahmens
4858 Size
aDfltSz( MINFLY
, MINFLY
);
4859 Size
aSpace( 0, 0 );
4860 SfxItemSet
aDummyItemSet( pDoc
->GetAttrPool(),
4861 pCSS1Parser
->GetWhichMap() );
4862 SvxCSS1PropertyInfo aDummyPropInfo
;
4864 SetFixSize( aSize
, aDfltSz
, bPrcWidth
, bPrcHeight
,
4865 aDummyItemSet
, aDummyPropInfo
, aFrmSet
);
4866 SetSpace( aSpace
, aDummyItemSet
, aDummyPropInfo
, aFrmSet
);
4868 // den Inhalt schuetzen
4869 SvxProtectItem
aProtectItem( RES_PROTECT
) ;
4870 aProtectItem
.SetCntntProtect( TRUE
);
4871 aFrmSet
.Put( aProtectItem
);
4873 // der Rahmen anlegen
4874 RndStdIds eAnchorId
=
4875 ((const SwFmtAnchor
&)aFrmSet
.Get(RES_ANCHOR
)).GetAnchorId();
4876 SwFrmFmt
*pFlyFmt
= pDoc
->MakeFlySection( eAnchorId
,
4877 pPam
->GetPoint(), &aFrmSet
);
4878 // Ggf Frames anlegen und auto-geb. Rahmen registrieren
4879 RegisterFlyFrm( pFlyFmt
);
4882 case HTML_SPTYPE_VERT
:
4885 if( nSize
&& Application::GetDefaultDevice() )
4887 nSize
= Application::GetDefaultDevice()
4888 ->PixelToLogic( Size(0,nSize
),
4889 MapMode(MAP_TWIP
) ).Height();
4892 // einen Absatz-Abstand setzen
4893 SwTxtNode
*pTxtNode
= 0;
4894 if( !pPam
->GetPoint()->nContent
.GetIndex() )
4896 // den unteren Absatz-Abstand des vorherigen Nodes aendern,
4899 SetAttr(); // noch offene Absatz-Attribute setzen
4901 pTxtNode
= pDoc
->GetNodes()[pPam
->GetPoint()->nNode
.GetIndex()-1]
4904 // Wenn der Abstz davor kein Txtenode ist, dann wird jetzt
4905 // ein leere Absatz angelegt, der eh schon eine Zeilenhoehe
4908 nSize
= nSize
>HTML_PARSPACE
? nSize
-HTML_PARSPACE
: 0;
4913 SvxULSpaceItem
aULSpace( (const SvxULSpaceItem
&)pTxtNode
4914 ->SwCntntNode::GetAttr( RES_UL_SPACE
) );
4915 aULSpace
.SetLower( aULSpace
.GetLower() + (USHORT
)nSize
);
4916 pTxtNode
->SetAttr( aULSpace
);
4920 NewAttr( &aAttrTab
.pULSpace
, SvxULSpaceItem( 0, (USHORT
)nSize
, RES_UL_SPACE
) );
4921 EndAttr( aAttrTab
.pULSpace
, 0, FALSE
);
4923 AppendTxtNode(); // nicht am Abstand drehen!
4927 case HTML_SPTYPE_HORI
:
4930 // wenn der Absatz noch leer ist, einen Erstzeilen-Einzug
4931 // setzen, sondern Sperrschrift ueber einem Space aufspannen
4933 if( nSize
&& Application::GetDefaultDevice() )
4935 nSize
= Application::GetDefaultDevice()
4936 ->PixelToLogic( Size(nSize
,0),
4937 MapMode(MAP_TWIP
) ).Width();
4940 if( !pPam
->GetPoint()->nContent
.GetIndex() )
4942 USHORT nLeft
=0, nRight
=0;
4945 GetMarginsFromContextWithNumBul( nLeft
, nRight
, nIndent
);
4946 nIndent
= nIndent
+ (short)nSize
;
4948 SvxLRSpaceItem
aLRItem( RES_LR_SPACE
);
4949 aLRItem
.SetTxtLeft( nLeft
);
4950 aLRItem
.SetRight( nRight
);
4951 aLRItem
.SetTxtFirstLineOfst( nIndent
);
4953 NewAttr( &aAttrTab
.pLRSpace
, aLRItem
);
4954 EndAttr( aAttrTab
.pLRSpace
, 0, FALSE
);
4958 NewAttr( &aAttrTab
.pKerning
, SvxKerningItem( (short)nSize
, RES_CHRATR_KERNING
) );
4960 pDoc
->Insert( *pPam
, aTmp
/*, CHARSET_ANSI*/, true );
4961 EndAttr( aAttrTab
.pKerning
);
4967 USHORT
SwHTMLParser::ToTwips( USHORT nPixel
) const
4969 if( nPixel
&& Application::GetDefaultDevice() )
4971 long nTwips
= Application::GetDefaultDevice()->PixelToLogic(
4972 Size( nPixel
, nPixel
), MapMode( MAP_TWIP
) ).Width();
4973 return nTwips
<= USHRT_MAX
? (USHORT
)nTwips
: USHRT_MAX
;
4979 SwTwips
SwHTMLParser::GetCurrentBrowseWidth()
4981 SwTwips nWidth
= SwHTMLTableLayout::GetBrowseWidth( *pDoc
);
4985 if( !aHTMLPageSize
.Width() )
4987 const SwFrmFmt
& rPgFmt
= pCSS1Parser
->GetMasterPageDesc()->GetMaster();
4989 const SwFmtFrmSize
& rSz
= rPgFmt
.GetFrmSize();
4990 const SvxLRSpaceItem
& rLR
= rPgFmt
.GetLRSpace();
4991 const SvxULSpaceItem
& rUL
= rPgFmt
.GetULSpace();
4992 const SwFmtCol
& rCol
= rPgFmt
.GetCol();
4994 aHTMLPageSize
.Width() = rSz
.GetWidth() - rLR
.GetLeft() - rLR
.GetRight();
4995 aHTMLPageSize
.Height() = rSz
.GetHeight() - rUL
.GetUpper() - rUL
.GetLower();
4997 if( 1 < rCol
.GetNumCols() )
4998 aHTMLPageSize
.Width() /= rCol
.GetNumCols();
5001 return aHTMLPageSize
.Width();
5007 void SwHTMLParser::InsertIDOption()
5010 const HTMLOptions
*pHTMLOptions
= GetOptions();
5011 for( USHORT i
= pHTMLOptions
->Count(); i
; )
5013 const HTMLOption
*pOption
= (*pHTMLOptions
)[--i
];
5014 if( HTML_O_ID
==pOption
->GetToken() )
5016 aId
= pOption
->GetString();
5022 InsertBookmark( aId
);
5029 void SwHTMLParser::InsertLineBreak()
5031 // <BR CLEAR=xxx> wird wie folgt behandelt:
5032 // 1.) Es werden nur nur absatzgebundene Rahmen betrachtet, die
5033 // im aktuellen Absatz verankert sind.
5034 // 2.) Fuer linksbuendig ausgerichtete Rahmen wird bei CLEAR=LEFT
5035 // oder ALL und auf rechtsbuendige ausgerichtete Rahmen bei
5036 // CLEAR=RIGHT oder ALL der Durchlauf wie folgt geaendert:
5037 // 3.) Wenn der Absatz keinen Text enthaelt, bekommt der Rahmen keinen
5039 // 4.) sonst erhaelt ein links ausgerichteter Rahmen eine rechten
5040 // "nur Anker" Umlauf und recht rechst ausg. Rahmen einen linken
5041 // "nur Anker" Umlauf.
5042 // 5.) wenn in einem nicht-leeren Absatz der Umlauf eines Rahmens
5043 // geaendert wird, wird ein neuer Absatz aufgemacht
5044 // 6.) Wenn von keinem Rahmen der Umlauf geaendert wird, wird ein
5045 // harter Zeilenumbruch eingefuegt
5047 String aId
, aStyle
, aClass
; // die ID der Bookmark
5048 BOOL bClearLeft
= FALSE
, bClearRight
= FALSE
;
5049 BOOL bCleared
= FALSE
; // wurde ein CLEAR ausgefuehrt?
5051 // dann holen wir mal die Optionen
5052 const HTMLOptions
*pHTMLOptions
= GetOptions();
5053 for( USHORT i
= pHTMLOptions
->Count(); i
; )
5055 const HTMLOption
*pOption
= (*pHTMLOptions
)[--i
];
5056 switch( pOption
->GetToken() )
5060 const String
&aClear
= pOption
->GetString();
5061 if( aClear
.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_AL_all
) )
5066 else if( aClear
.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_AL_left
) )
5068 else if( aClear
.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_AL_right
) )
5073 aId
= pOption
->GetString();
5076 aStyle
= pOption
->GetString();
5079 aClass
= pOption
->GetString();
5084 // CLEAR wird nur fuer den aktuellen Absaetz unterstuetzt
5085 if( bClearLeft
|| bClearRight
)
5087 SwNodeIndex
& rNodeIdx
= pPam
->GetPoint()->nNode
;
5088 SwTxtNode
* pTxtNd
= rNodeIdx
.GetNode().GetTxtNode();
5092 const SwFmtAnchor
* pAnchor
;
5093 const SwPosition
* pAPos
;
5094 const SwSpzFrmFmts
& rFrmFmtTbl
= *pDoc
->GetSpzFrmFmts();
5096 for( USHORT i
=0; i
<rFrmFmtTbl
.Count(); i
++ )
5098 pFmt
= rFrmFmtTbl
[i
];
5099 pAnchor
= &pFmt
->GetAnchor();
5100 if( 0 != ( pAPos
= pAnchor
->GetCntntAnchor()) &&
5101 (FLY_AT_CNTNT
== pAnchor
->GetAnchorId() ||
5102 FLY_AUTO_CNTNT
== pAnchor
->GetAnchorId()) &&
5103 pAPos
->nNode
== rNodeIdx
&&
5104 pFmt
->GetSurround().GetSurround() != SURROUND_NONE
)
5106 sal_Int16 eHori
= RES_DRAWFRMFMT
== pFmt
->Which()
5107 ? text::HoriOrientation::LEFT
5108 : pFmt
->GetHoriOrient().GetHoriOrient();
5110 SwSurround eSurround
= SURROUND_PARALLEL
;
5111 if( pPam
->GetPoint()->nContent
.GetIndex() )
5113 if( bClearLeft
&& text::HoriOrientation::LEFT
==eHori
)
5114 eSurround
= SURROUND_RIGHT
;
5115 else if( bClearRight
&& text::HoriOrientation::RIGHT
==eHori
)
5116 eSurround
= SURROUND_LEFT
;
5118 else if( (bClearLeft
&& text::HoriOrientation::LEFT
==eHori
) ||
5119 (bClearRight
&& text::HoriOrientation::RIGHT
==eHori
) )
5121 eSurround
= SURROUND_NONE
;
5124 if( SURROUND_PARALLEL
!= eSurround
)
5126 SwFmtSurround
aSurround( eSurround
);
5127 if( SURROUND_NONE
!= eSurround
)
5128 aSurround
.SetAnchorOnly( TRUE
);
5129 pFmt
->SetFmtAttr( aSurround
);
5132 } // Anker ist nicht im Node
5133 } // Schleife ueber Fly-Frames
5138 SvxFmtBreakItem
aBreakItem( SVX_BREAK_NONE
, RES_BREAK
);
5139 BOOL bBreakItem
= FALSE
;
5140 if( HasStyleOptions( aStyle
, aId
, aClass
) )
5142 SfxItemSet
aItemSet( pDoc
->GetAttrPool(), pCSS1Parser
->GetWhichMap() );
5143 SvxCSS1PropertyInfo aPropInfo
;
5145 if( ParseStyleOptions( aStyle
, aId
, aClass
, aItemSet
, aPropInfo
) )
5147 if( pCSS1Parser
->SetFmtBreak( aItemSet
, aPropInfo
) )
5149 aBreakItem
= (const SvxFmtBreakItem
&)aItemSet
.Get( RES_BREAK
);
5152 if( aPropInfo
.aId
.Len() )
5153 InsertBookmark( aPropInfo
.aId
);
5157 if( bBreakItem
&& SVX_BREAK_PAGE_AFTER
==aBreakItem
.GetBreak() )
5159 NewAttr( &aAttrTab
.pBreak
, aBreakItem
);
5160 EndAttr( aAttrTab
.pBreak
, 0, FALSE
);
5163 if( !bCleared
&& !bBreakItem
)
5165 // wenn kein CLEAR ausgefuehrt werden sollte oder konnte, wird
5166 // ein Zeilenumbruch eingef?gt
5167 String
sTmp( (sal_Unicode
)0x0a ); // make the Mac happy :-)
5168 pDoc
->Insert( *pPam
, sTmp
, true );
5170 else if( pPam
->GetPoint()->nContent
.GetIndex() )
5172 // wenn ein Claer in einem nicht-leeren Absatz ausgefuehrt wurde,
5173 // muss anschliessen ein neuer Absatz aufgemacht werden
5174 // MIB 21.02.97: Eigentlich muesste man hier den unteren Absatz-
5175 // Absatnd auf 0 drehen. Das geht aber bei sowas wie <BR ..><P>
5176 // schief (>Netacpe). Deshalb lassen wir das erstmal.
5177 AppendTxtNode( AM_NOSPACE
);
5179 if( bBreakItem
&& SVX_BREAK_PAGE_BEFORE
==aBreakItem
.GetBreak() )
5181 NewAttr( &aAttrTab
.pBreak
, aBreakItem
);
5182 EndAttr( aAttrTab
.pBreak
, 0, FALSE
);
5186 void SwHTMLParser::InsertHorzRule()
5191 SvxAdjust eAdjust
= SVX_ADJUST_END
;
5193 BOOL bPrcWidth
= FALSE
;
5194 BOOL bNoShade
= FALSE
;
5195 BOOL bColor
= FALSE
;
5200 // dann holen wir mal die Optionen
5201 const HTMLOptions
*pHTMLOptions
= GetOptions();
5202 for( USHORT i
= pHTMLOptions
->Count(); i
; )
5204 const HTMLOption
*pOption
= (*pHTMLOptions
)[--i
];
5205 switch( pOption
->GetToken() )
5208 aId
= pOption
->GetString();
5211 nSize
= (USHORT
)pOption
->GetNumber();
5214 bPrcWidth
= (pOption
->GetString().Search('%') != STRING_NOTFOUND
);
5215 nWidth
= (USHORT
)pOption
->GetNumber();
5216 if( bPrcWidth
&& nWidth
>=100 )
5218 // 100%-Linien sind der default-Fall (keine Attrs neotig)
5225 (SvxAdjust
)pOption
->GetEnum( aHTMLPAlignTable
, static_cast< sal_uInt16
>(eAdjust
) );
5227 case HTML_O_NOSHADE
:
5231 pOption
->GetColor( aColor
);
5237 if( pPam
->GetPoint()->nContent
.GetIndex() )
5238 AppendTxtNode( AM_NOSPACE
);
5239 if( nOpenParaToken
)
5242 pPam
->Move( fnMoveBackward
);
5244 // ... und in einem Kontext merken
5245 _HTMLAttrContext
*pCntxt
=
5246 new _HTMLAttrContext( HTML_HORZRULE
, RES_POOLCOLL_HTML_HR
, aEmptyStr
);
5248 PushContext( pCntxt
);
5250 // die neue Vorlage setzen
5251 SetTxtCollAttrs( pCntxt
);
5253 // die harten Attribute an diesem Absatz werden nie mehr ungueltig
5254 if( aParaAttrs
.Count() )
5255 aParaAttrs
.Remove( 0, aParaAttrs
.Count() );
5257 if( nSize
>0 || bColor
|| bNoShade
)
5259 // Farbe und/oder Breite der Linie setzen
5261 aColor
.SetColor( COL_GRAY
);
5263 SvxBorderLine
aBorderLine( &aColor
);
5267 long nPHeight
= (long)nSize
;
5268 SvxCSS1Parser::PixelToTwip( nPWidth
, nPHeight
);
5269 SvxCSS1Parser::SetBorderWidth( aBorderLine
, (USHORT
)nPHeight
,
5274 aBorderLine
.SetOutWidth( DEF_LINE_WIDTH_2
);
5278 aBorderLine
.SetOutWidth( DEF_DOUBLE_LINE0_OUT
);
5279 aBorderLine
.SetInWidth( DEF_DOUBLE_LINE0_IN
);
5280 aBorderLine
.SetDistance( DEF_DOUBLE_LINE0_DIST
);
5283 SvxBoxItem
aBoxItem(RES_BOX
);
5284 aBoxItem
.SetLine( &aBorderLine
, BOX_LINE_BOTTOM
);
5285 _HTMLAttr
* pTmp
= new _HTMLAttr( *pPam
->GetPoint(), aBoxItem
);
5286 aSetAttrTab
.Insert( pTmp
, aSetAttrTab
.Count() );
5290 // Wenn wir in keiner Tabelle sind, wird die Breitenangabe durch
5291 // Absatz-Einzuege "getuerkt". In einer Tabelle macht das wenig
5292 // Sinn. Um zu Vermeiden, dass die Linie bei der Breitenberechnung
5293 // beruecksichtigt wird, bekommt sie aber trotzdem entsprechendes
5294 // LRSpace-Item verpasst.
5296 const SwFmtColl
*pColl
= GetCurrFmtColl();
5297 SvxLRSpaceItem
aLRItem( pColl
->GetLRSpace() );
5301 // Laenge und Ausrichtung der Linie ueber Absatz-Einzuege "tuerken"
5302 long nBrowseWidth
= GetCurrentBrowseWidth();
5303 nWidth
= bPrcWidth
? (USHORT
)((nWidth
*nBrowseWidth
) / 100)
5304 : ToTwips( (USHORT
)nBrowseWidth
);
5305 if( nWidth
< MINLAY
)
5308 if( (long)nWidth
< nBrowseWidth
)
5311 const SwFmtColl
*pColl
= GetCurrFmtColl();
5312 SvxLRSpaceItem
aLRItem( pColl
->GetLRSpace() );
5314 long nDist
= nBrowseWidth
- nWidth
;
5318 case SVX_ADJUST_RIGHT
:
5319 aLRItem
.SetTxtLeft( (USHORT
)nDist
);
5321 case SVX_ADJUST_LEFT
:
5322 aLRItem
.SetRight( (USHORT
)nDist
);
5324 case SVX_ADJUST_CENTER
:
5327 aLRItem
.SetTxtLeft( (USHORT
)nDist
);
5328 aLRItem
.SetRight( (USHORT
)nDist
);
5333 _HTMLAttr
* pTmp
= new _HTMLAttr( *pPam
->GetPoint(), aLRItem
);
5334 aSetAttrTab
.Insert( pTmp
, aSetAttrTab
.Count() );
5340 _HTMLAttr
* pTmp
= new _HTMLAttr( *pPam
->GetPoint(), aLRItem
);
5341 aSetAttrTab
.Insert( pTmp
, aSetAttrTab
.Count() );
5345 // Bookmarks koennen nicht in Hyperlinks eingefueht werden
5347 InsertBookmark( aId
);
5349 // den aktuellen Kontext vom Stack holen
5350 _HTMLAttrContext
*pPoppedContext
= PopContext( HTML_HORZRULE
);
5351 ASSERT( pPoppedContext
==pCntxt
, "wo kommt denn da ein HR-Kontext her?" );
5352 delete pPoppedContext
;
5354 pPam
->Move( fnMoveForward
);
5356 // und im Absatz danach die dort aktuelle Vorlage setzen
5360 void SwHTMLParser::ParseMoreMetaOptions()
5362 String aName
, aContent
;
5363 BOOL bHTTPEquiv
= FALSE
;
5365 const HTMLOptions
*pHTMLOptions
= GetOptions();
5366 for( USHORT i
= pHTMLOptions
->Count(); i
; )
5368 const HTMLOption
*pOption
= (*pHTMLOptions
)[ --i
];
5369 switch( pOption
->GetToken() )
5372 aName
= pOption
->GetString();
5375 case HTML_O_HTTPEQUIV
:
5376 aName
= pOption
->GetString();
5379 case HTML_O_CONTENT
:
5380 aContent
= pOption
->GetString();
5385 // Hier wird es etwas tricky: Wir wissen genau, da? die Dok-Info
5386 // nicht geaendert wurde. Deshalb genuegt es, auf Generator und
5387 // auf refresh abzufragen, um noch nicht verarbeitete Token zu finden,
5388 // denn das sind die einzigen, die die Dok-Info nicht modifizieren.
5389 if( aName
.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_META_generator
) ||
5390 aName
.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_META_refresh
) ||
5391 aName
.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_META_content_type
) ||
5392 aName
.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_META_content_script_type
) )
5395 aContent
.EraseAllChars( _CR
);
5396 aContent
.EraseAllChars( _LF
);
5398 if( aName
.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_META_sdendnote
) )
5400 FillEndNoteInfo( aContent
);
5404 if( aName
.EqualsIgnoreCaseAscii( OOO_STRING_SVTOOLS_HTML_META_sdfootnote
) )
5406 FillFootNoteInfo( aContent
);
5411 String::CreateFromAscii(TOOLS_CONSTASCII_STRINGPARAM("HTML: <")) );
5412 sText
.AppendAscii( TOOLS_CONSTASCII_STRINGPARAM(OOO_STRING_SVTOOLS_HTML_meta
) );
5413 sText
.Append( ' ' );
5415 sText
.AppendAscii( TOOLS_CONSTASCII_STRINGPARAM(OOO_STRING_SVTOOLS_HTML_O_httpequiv
) );
5417 sText
.AppendAscii( TOOLS_CONSTASCII_STRINGPARAM(OOO_STRING_SVTOOLS_HTML_O_name
) );
5418 sText
.AppendAscii( TOOLS_CONSTASCII_STRINGPARAM("=\"") );
5419 sText
.Append( aName
);
5420 sText
.AppendAscii( TOOLS_CONSTASCII_STRINGPARAM("\" ") );
5421 sText
.AppendAscii( TOOLS_CONSTASCII_STRINGPARAM(OOO_STRING_SVTOOLS_HTML_O_content
) );
5422 sText
.AppendAscii( TOOLS_CONSTASCII_STRINGPARAM("=\"") );
5423 sText
.Append( aContent
);
5424 sText
.AppendAscii( TOOLS_CONSTASCII_STRINGPARAM("\">") );
5426 SwPostItField
aPostItFld(
5427 (SwPostItFieldType
*)pDoc
->GetSysFldType( RES_POSTITFLD
),
5428 aEmptyStr
, sText
, DateTime() );
5429 SwFmtFld
aFmtFld( aPostItFld
);
5430 InsertAttr( aFmtFld
);
5435 _HTMLAttr::_HTMLAttr( const SwPosition
& rPos
, const SfxPoolItem
& rItem
,
5436 _HTMLAttr
**ppHd
) :
5437 nSttPara( rPos
.nNode
),
5438 nEndPara( rPos
.nNode
),
5439 nSttCntnt( rPos
.nContent
.GetIndex() ),
5440 nEndCntnt(rPos
.nContent
.GetIndex() ),
5441 bInsAtStart( TRUE
),
5449 pItem
= rItem
.Clone();
5452 _HTMLAttr::_HTMLAttr( const _HTMLAttr
&rAttr
, const SwNodeIndex
&rEndPara
,
5453 USHORT nEndCnt
, _HTMLAttr
**ppHd
) :
5454 nSttPara( rAttr
.nSttPara
),
5455 nEndPara( rEndPara
),
5456 nSttCntnt( rAttr
.nSttCntnt
),
5457 nEndCntnt( nEndCnt
),
5458 bInsAtStart( rAttr
.bInsAtStart
),
5459 bLikePara( rAttr
.bLikePara
),
5460 bValid( rAttr
.bValid
),
5461 nCount( rAttr
.nCount
),
5466 pItem
= rAttr
.pItem
->Clone();
5469 _HTMLAttr::~_HTMLAttr()
5474 _HTMLAttr
*_HTMLAttr::Clone( const SwNodeIndex
& rEndPara
, USHORT nEndCnt
) const
5476 // das Attribut mit der alten Start-Position neu anlegen
5477 _HTMLAttr
*pNew
= new _HTMLAttr( *this, rEndPara
, nEndCnt
, ppHead
);
5479 // die Previous-Liste muss uebernommen werden, die Next-Liste nicht!
5480 pNew
->pPrev
= pPrev
;
5485 void _HTMLAttr::Reset( const SwNodeIndex
& rSttPara
, USHORT nSttCnt
,
5488 // den Anfang (und das Ende) neu setzen
5489 nSttPara
= rSttPara
;
5490 nSttCntnt
= nSttCnt
;
5491 nEndPara
= rSttPara
;
5492 nEndCntnt
= nSttCnt
;
5494 // den Head korrigieren und die Verkettungen aufheben
5500 void _HTMLAttr::InsertPrev( _HTMLAttr
*pPrv
)
5502 ASSERT( !pPrv
->pNext
|| pPrv
->pNext
== this,
5503 "_HTMLAttr::InsertPrev: pNext falsch" );
5506 ASSERT( 0 == pPrv
->ppHead
|| ppHead
== pPrv
->ppHead
,
5507 "_HTMLAttr::InsertPrev: ppHead falsch" );
5510 _HTMLAttr
*pAttr
= this;
5511 while( pAttr
->GetPrev() )
5512 pAttr
= pAttr
->GetPrev();
5514 pAttr
->pPrev
= pPrv
;
5517 bool SwHTMLParser::ParseMetaOptions(
5518 const uno::Reference
<document::XDocumentProperties
> & i_xDocProps
,
5519 SvKeyValueIterator
*i_pHeader
)
5521 // always call base ParseMetaOptions, it sets the encoding (#i96700#)
5522 bool ret( HTMLParser::ParseMetaOptions(i_xDocProps
, i_pHeader
) );
5523 if (!ret
&& IsNewDoc())
5525 ParseMoreMetaOptions();
5530 // override so we can parse DOCINFO field subtypes INFO[1-4]
5531 void SwHTMLParser::AddMetaUserDefined( ::rtl::OUString
const & i_rMetaName
)
5533 // unless we already have 4 names, append the argument to m_InfoNames
5534 ::rtl::OUString
* pName
// the first empty string in m_InfoNames
5535 (!m_InfoNames
[0].getLength() ? &m_InfoNames
[0] :
5536 (!m_InfoNames
[1].getLength() ? &m_InfoNames
[1] :
5537 (!m_InfoNames
[2].getLength() ? &m_InfoNames
[2] :
5538 (!m_InfoNames
[3].getLength() ? &m_InfoNames
[3] : 0 ))));
5541 (*pName
) = i_rMetaName
;