/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ #include #include #include #include #include #include #include #if OSL_DEBUG_LEVEL > 0 #include #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // ...Percent() #include #include #include #include // fuer SwBookmark ... #include #include // fuer Start/EndAction #include #include #include #include #include #include #include #include #include #include #include #include // ResId fuer Statusleiste #include #define FONTSIZE_MASK 7 #define HTML_ESC_PROP 80 #define HTML_ESC_SUPER DFLT_ESC_SUPER #define HTML_ESC_SUB DFLT_ESC_SUB #define HTML_SPTYPE_NONE 0 #define HTML_SPTYPE_BLOCK 1 #define HTML_SPTYPE_HORI 2 #define HTML_SPTYPE_VERT 3 using editeng::SvxBorderLine; using namespace ::com::sun::star; //

, , usw. HTMLOptionEnum aHTMLPAlignTable[] = { { OOO_STRING_SVTOOLS_HTML_AL_left, SVX_ADJUST_LEFT }, { OOO_STRING_SVTOOLS_HTML_AL_center, SVX_ADJUST_CENTER }, { OOO_STRING_SVTOOLS_HTML_AL_middle, SVX_ADJUST_CENTER }, // Netscape { OOO_STRING_SVTOOLS_HTML_AL_right, SVX_ADJUST_RIGHT }, { OOO_STRING_SVTOOLS_HTML_AL_justify, SVX_ADJUST_BLOCK }, { OOO_STRING_SVTOOLS_HTML_AL_char, SVX_ADJUST_LEFT }, { 0, 0 } }; // static HTMLOptionEnum aHTMLSpacerTypeTable[] = { { OOO_STRING_SVTOOLS_HTML_SPTYPE_block, HTML_SPTYPE_BLOCK }, { OOO_STRING_SVTOOLS_HTML_SPTYPE_horizontal, HTML_SPTYPE_HORI }, { OOO_STRING_SVTOOLS_HTML_SPTYPE_vertical, HTML_SPTYPE_VERT }, { 0, 0 } }; HTMLReader::HTMLReader() { bTmplBrowseMode = sal_True; } String HTMLReader::GetTemplateName() const { String sTemplate("internal"); sTemplate += INET_PATH_TOKEN; sTemplate.Append(String("html")); String sTemplateWithoutExt( sTemplate ); // first search for OpenDocument Writer/Web template sTemplate.Append(String(".oth")); SvtPathOptions aPathOpt; // OpenDocument Writer/Web template (extension .oth) sal_Bool bSet = aPathOpt.SearchFile( sTemplate, SvtPathOptions::PATH_TEMPLATE ); if( !bSet ) { // no OpenDocument Writer/Web template found. // search for OpenOffice.org Writer/Web template sTemplate = sTemplateWithoutExt; sTemplate.Append(String(".stw")); bSet = aPathOpt.SearchFile( sTemplate, SvtPathOptions::PATH_TEMPLATE ); } if( !bSet ) { sTemplate = ""; OSL_ENSURE( !this, "The default HTML template cannot be found in the defined template directories!"); } return sTemplate; } int HTMLReader::SetStrmStgPtr() { OSL_ENSURE( pMedium, "Wo ist das Medium??" ); if( pMedium->IsRemote() || !pMedium->IsStorage() ) { pStrm = pMedium->GetInStream(); return sal_True; } return sal_False; } // Aufruf fuer die allg. Reader-Schnittstelle sal_uLong HTMLReader::Read( SwDoc &rDoc, const String& rBaseURL, SwPaM &rPam, const String & rName ) { if( !pStrm ) { OSL_ENSURE( pStrm, "HTML-Read ohne Stream" ); return ERR_SWG_READ_ERROR; } if( !bInsertMode ) { Reader::ResetFrmFmts( rDoc ); // Die HTML-Seitenvorlage setzen, wenn des kein HTML-Dokument ist, // sonst ist sie schon gesetzt. if( !rDoc.get(IDocumentSettingAccess::HTML_MODE) ) { rDoc.InsertPoolItem( rPam, SwFmtPageDesc( rDoc.GetPageDescFromPool( RES_POOLPAGE_HTML, false )), 0 ); } } // damit keiner das Doc klaut! rDoc.acquire(); sal_uLong nRet = 0; SvParserRef xParser = new SwHTMLParser( &rDoc, rPam, *pStrm, rName, rBaseURL, !bInsertMode, pMedium, IsReadUTF8(), bIgnoreHTMLComments ); SvParserState eState = xParser->CallParser(); if( SVPAR_PENDING == eState ) pStrm->ResetError(); else if( SVPAR_ACCEPTED != eState ) { String sErr( OUString::number((sal_Int32)xParser->GetLineNr())); sErr += ','; sErr += OUString::number((sal_Int32)xParser->GetLinePos()); // den Stream als Fehlernummer Transporter benutzen nRet = *new StringErrorInfo( ERR_FORMAT_ROWCOL, sErr, ERRCODE_BUTTON_OK | ERRCODE_MSG_ERROR ); } return nRet; } SwHTMLParser::SwHTMLParser( SwDoc* pD, const SwPaM& rCrsr, SvStream& rIn, const String& rPath, const String& rBaseURL, int bReadNewDoc, SfxMedium* pMed, sal_Bool bReadUTF8, sal_Bool bNoHTMLComments ) : SfxHTMLParser( rIn, static_cast< sal_Bool >(bReadNewDoc), pMed ), SwClient( 0 ), aPathToFile( rPath ), sBaseURL( rBaseURL ), pAppletImpl( 0 ), pCSS1Parser( 0 ), pNumRuleInfo( new SwHTMLNumRuleInfo ), pPendStack( 0 ), pDoc( pD ), pActionViewShell( 0 ), pSttNdIdx( 0 ), pTable(0), pFormImpl( 0 ), pMarquee( 0 ), pField( 0 ), pImageMap( 0 ), pImageMaps( 0 ), pFootEndNoteImpl( 0 ), nScriptStartLineNr( 0 ), nBaseFontStMin( 0 ), nFontStMin( 0 ), nDefListDeep( 0 ), nFontStHeadStart( 0 ), nSBModuleCnt( 0 ), nMissingImgMaps( 0 ), nParaCnt( 5 ), // #i83625# nContextStMin( 0 ), nContextStAttrMin( 0 ), nOpenParaToken( 0 ), eJumpTo( JUMPTO_NONE ), #ifdef DBG_UTIL m_nContinue( 0 ), #endif eParaAdjust( SVX_ADJUST_END ), bDocInitalized( sal_False ), bSetModEnabled( sal_False ), bInFloatingFrame( sal_False ), bInField( sal_False ), bCallNextToken( sal_False ), bIgnoreRawData( sal_False ), bNoParSpace( sal_False ), bInNoEmbed( sal_False ), bInTitle( sal_False ), bUpdateDocStat( sal_False ), bFixSelectWidth( sal_False ), bFixSelectHeight( sal_False ), bTextArea( sal_False ), bSelect( sal_False ), bInFootEndNoteAnchor( sal_False ), bInFootEndNoteSymbol( sal_False ), bIgnoreHTMLComments( bNoHTMLComments ), bRemoveHidden( sal_False ), pTempViewFrame(0) { nEventId = 0; bUpperSpace = bViewCreated = bChkJumpMark = bSetCrsr = sal_False; eScriptLang = HTML_SL_UNKNOWN; bAnyStarBasic = sal_True; pPam = new SwPaM( *rCrsr.GetPoint() ); memset( &aAttrTab, 0, sizeof( _HTMLAttrTable )); // Die Font-Groessen 1-7 aus der INI-Datei lesen SvxHtmlOptions& rHtmlOptions = SvxHtmlOptions::Get(); aFontHeights[0] = rHtmlOptions.GetFontSize( 0 ) * 20; aFontHeights[1] = rHtmlOptions.GetFontSize( 1 ) * 20; aFontHeights[2] = rHtmlOptions.GetFontSize( 2 ) * 20; aFontHeights[3] = rHtmlOptions.GetFontSize( 3 ) * 20; aFontHeights[4] = rHtmlOptions.GetFontSize( 4 ) * 20; aFontHeights[5] = rHtmlOptions.GetFontSize( 5 ) * 20; aFontHeights[6] = rHtmlOptions.GetFontSize( 6 ) * 20; bKeepUnknown = rHtmlOptions.IsImportUnknown(); if(bReadNewDoc) { //CJK has different defaults, so a different object should be used for this //RES_CHARTR_CJK_FONTSIZE is a valid value SvxFontHeightItem aFontHeight(aFontHeights[2], 100, RES_CHRATR_FONTSIZE); pDoc->SetDefault( aFontHeight ); SvxFontHeightItem aFontHeightCJK(aFontHeights[2], 100, RES_CHRATR_CJK_FONTSIZE); pDoc->SetDefault( aFontHeightCJK ); SvxFontHeightItem aFontHeightCTL(aFontHeights[2], 100, RES_CHRATR_CTL_FONTSIZE); pDoc->SetDefault( aFontHeightCTL ); } // Waehrend des Imports in den HTML-Modus schalten, damit die // richrigen Vorlagen angelegt werden bOldIsHTMLMode = pDoc->get(IDocumentSettingAccess::HTML_MODE); pDoc->set(IDocumentSettingAccess::HTML_MODE, true); pCSS1Parser = new SwCSS1Parser( pDoc, aFontHeights, sBaseURL, IsNewDoc() ); pCSS1Parser->SetIgnoreFontFamily( rHtmlOptions.IsIgnoreFontFamily() ); if( bReadUTF8 ) { SetSrcEncoding( RTL_TEXTENCODING_UTF8 ); } else { SwDocShell *pDocSh = pDoc->GetDocShell(); SvKeyValueIterator *pHeaderAttrs = pDocSh->GetHeaderAttributes(); if( pHeaderAttrs ) SetEncodingByHTTPHeader( pHeaderAttrs ); } pCSS1Parser->SetDfltEncoding( osl_getThreadTextEncoding() ); // Timer nur bei ganz normalen Dokumenten aufsetzen! SwDocShell* pDocSh = pDoc->GetDocShell(); if( pDocSh ) { bViewCreated = sal_True; // nicht, synchron laden // es ist ein Sprungziel vorgegeben. if( pMed ) { sJmpMark = pMed->GetURLObject().GetMark(); if( sJmpMark.Len() ) { eJumpTo = JUMPTO_MARK; xub_StrLen nLastPos, nPos = 0; while( STRING_NOTFOUND != ( nLastPos = sJmpMark.Search( cMarkSeperator, nPos + 1 )) ) nPos = nLastPos; String sCmp; if (nPos) { sCmp = comphelper::string::remove( sJmpMark.Copy(nPos + 1), ' '); } if( sCmp.Len() ) { sCmp.ToLowerAscii(); if( sCmp.EqualsAscii( pMarkToRegion ) ) eJumpTo = JUMPTO_REGION; else if( sCmp.EqualsAscii( pMarkToTable ) ) eJumpTo = JUMPTO_TABLE; else if( sCmp.EqualsAscii( pMarkToGraphic ) ) eJumpTo = JUMPTO_GRAPHIC; else if( sCmp.EqualsAscii( pMarkToOutline ) || sCmp.EqualsAscii( pMarkToText ) || sCmp.EqualsAscii( pMarkToFrame ) ) eJumpTo = JUMPTO_NONE; // das ist nichts gueltiges! else // ansonsten ist das ein normaler (Book)Mark nPos = STRING_LEN; } else nPos = STRING_LEN; sJmpMark.Erase( nPos ); if( !sJmpMark.Len() ) eJumpTo = JUMPTO_NONE; } } } } SwHTMLParser::~SwHTMLParser() { #ifdef DBG_UTIL OSL_ENSURE( !m_nContinue, "DTOR im Continue!" ); #endif sal_Bool bAsync = pDoc->IsInLoadAsynchron(); pDoc->SetInLoadAsynchron( sal_False ); pDoc->set(IDocumentSettingAccess::HTML_MODE, bOldIsHTMLMode); if( pDoc->GetDocShell() && nEventId ) Application::RemoveUserEvent( nEventId ); // das DocumentDetected kann ggfs. die DocShells loeschen, darum nochmals // abfragen if( pDoc->GetDocShell() ) { // Gelinkte Bereiche updaten sal_uInt16 nLinkMode = pDoc->getLinkUpdateMode( true ); if( nLinkMode != NEVER && bAsync && SFX_CREATE_MODE_INTERNAL!=pDoc->GetDocShell()->GetCreateMode() ) pDoc->GetLinkManager().UpdateAllLinks( nLinkMode == MANUAL, true, false ); if ( pDoc->GetDocShell()->IsLoading() ) { // #i59688# pDoc->GetDocShell()->LoadingFinished(); } } delete pSttNdIdx; if( !aSetAttrTab.empty() ) { OSL_ENSURE( aSetAttrTab.empty(),"Es stehen noch Attribute auf dem Stack" ); for ( _HTMLAttrs::const_iterator it = aSetAttrTab.begin(); it != aSetAttrTab.end(); ++it ) delete *it; aSetAttrTab.clear(); } delete pPam; delete pCSS1Parser; delete pNumRuleInfo; DeleteFormImpl(); DeleteFootEndNoteImpl(); OSL_ENSURE( !pTable, "Es existiert noch eine offene Tabelle" ); delete pImageMaps; OSL_ENSURE( !pPendStack, "SwHTMLParser::~SwHTMLParser: Hier sollte es keinen Pending-Stack mehr geben" ); while( pPendStack ) { SwPendingStack* pTmp = pPendStack; pPendStack = pPendStack->pNext; delete pTmp->pData; delete pTmp; } if( !pDoc->release() ) { // keiner will mehr das Doc haben, also weg damit delete pDoc; pDoc = NULL; } if ( pTempViewFrame ) { pTempViewFrame->DoClose(); // the temporary view frame is hidden, so the hidden flag might need to be removed if ( bRemoveHidden && pDoc && pDoc->GetDocShell() && pDoc->GetDocShell()->GetMedium() ) pDoc->GetDocShell()->GetMedium()->GetItemSet()->ClearItem( SID_HIDDEN ); } } IMPL_LINK( SwHTMLParser, AsyncCallback, void*, /*pVoid*/ ) { nEventId=0; // #i47907# - If the document has already been destructed, // the parser should be aware of this: if( ( pDoc->GetDocShell() && pDoc->GetDocShell()->IsAbortingImport() ) || 1 == pDoc->getReferenceCount() ) { // wurde der Import vom SFX abgebrochen? eState = SVPAR_ERROR; } GetAsynchCallLink().Call(0); return 0; } SvParserState SwHTMLParser::CallParser() { // einen temporaeren Index anlegen, auf Pos 0 so wird er nicht bewegt! pSttNdIdx = new SwNodeIndex( pDoc->GetNodes() ); if( !IsNewDoc() ) // in ein Dokument einfuegen ? { const SwPosition* pPos = pPam->GetPoint(); pDoc->SplitNode( *pPos, false ); *pSttNdIdx = pPos->nNode.GetIndex()-1; pDoc->SplitNode( *pPos, false ); SwPaM aInsertionRangePam( *pPos ); pPam->Move( fnMoveBackward ); // split any redline over the insertion point aInsertionRangePam.SetMark(); *aInsertionRangePam.GetPoint() = *pPam->GetPoint(); aInsertionRangePam.Move( fnMoveBackward ); pDoc->SplitRedline( aInsertionRangePam ); pDoc->SetTxtFmtColl( *pPam, pCSS1Parser->GetTxtCollFromPool( RES_POOLCOLL_STANDARD )); } if( GetMedium() ) { if( !bViewCreated ) { nEventId = Application::PostUserEvent( LINK( this, SwHTMLParser, AsyncCallback ), 0 ); } else { bViewCreated = sal_True; nEventId = 0; } } // Laufbalken anzeigen else if( !GetMedium() || !GetMedium()->IsRemote() ) { rInput.Seek(STREAM_SEEK_TO_END); rInput.ResetError(); ::StartProgress( STR_STATSTR_W4WREAD, 0, rInput.Tell(), pDoc->GetDocShell() ); rInput.Seek(STREAM_SEEK_TO_BEGIN); rInput.ResetError(); } pDoc->GetPageDesc( 0 ).Add( this ); SvParserState eRet = HTMLParser::CallParser(); return eRet; } void SwHTMLParser::Continue( int nToken ) { #ifdef DBG_UTIL OSL_ENSURE(!m_nContinue, "Continue im Continue - not supposed to happen"); m_nContinue++; #endif // Wenn der Import (vom SFX) abgebrochen wurde, wird ein Fehler // gesetzt aber trotzdem noch weiter gemacht, damit vernuenftig // aufgeraeumt wird. OSL_ENSURE( SVPAR_ERROR!=eState, "SwHTMLParser::Continue: bereits ein Fehler gesetzt" ); if( pDoc->GetDocShell() && pDoc->GetDocShell()->IsAbortingImport() ) eState = SVPAR_ERROR; // Die ViewShell vom Dokument holen, merken und als aktuelle setzen. ViewShell *pInitVSh = CallStartAction(); if( SVPAR_ERROR != eState && GetMedium() && !bViewCreated ) { // Beim ersten Aufruf erstmal returnen, Doc anzeigen // und auf Timer Callback warten. // An dieser Stelle wurde im CallParser gerade mal ein Zeichen // gelesen und ein SaveState(0) gerufen. eState = SVPAR_PENDING; bViewCreated = sal_True; pDoc->SetInLoadAsynchron( sal_True ); #ifdef DBG_UTIL m_nContinue--; #endif return; } bSetModEnabled = sal_False; if( pDoc->GetDocShell() && 0 != (bSetModEnabled = pDoc->GetDocShell()->IsEnableSetModified()) ) { pDoc->GetDocShell()->EnableSetModified( sal_False ); } // waehrend des einlesens kein OLE-Modified rufen Link aOLELink( pDoc->GetOle2Link() ); pDoc->SetOle2Link( Link() ); sal_Bool bModified = pDoc->IsModified(); bool const bWasUndo = pDoc->GetIDocumentUndoRedo().DoesUndo(); pDoc->GetIDocumentUndoRedo().DoUndo(false); // Wenn der Import abgebrochen wird, kein Continue mehr rufen. // Falls ein Pending-Stack existiert aber durch einen Aufruf // von NextToken dafuer sorgen, dass der Pending-Stack noch // beendet wird. if( SVPAR_ERROR == eState ) { OSL_ENSURE( !pPendStack || pPendStack->nToken, "SwHTMLParser::Continue: Pending-Stack ohne Token" ); if( pPendStack && pPendStack->nToken ) NextToken( pPendStack->nToken ); OSL_ENSURE( !pPendStack, "SwHTMLParser::Continue: Es gibt wieder einen Pend-Stack" ); } else { HTMLParser::Continue( pPendStack ? pPendStack->nToken : nToken ); } // Laufbalken wieder abschalten EndProgress( pDoc->GetDocShell() ); sal_Bool bLFStripped = sal_False; if( SVPAR_PENDING != GetStatus() ) { // noch die letzten Attribute setzen { if( aScriptSource.Len() ) { SwScriptFieldType *pType = (SwScriptFieldType*)pDoc->GetSysFldType( RES_SCRIPTFLD ); SwScriptField aFld( pType, aScriptType, aScriptSource, sal_False ); InsertAttr( SwFmtFld( aFld ) ); } if( pAppletImpl ) { if( pAppletImpl->GetApplet().is() ) EndApplet(); else EndObject(); } // ggf. ein noch vorhandes LF hinter dem letzen Absatz entfernen if( IsNewDoc() ) bLFStripped = StripTrailingLF() > 0; // noch offene Nummerierungen beenden. while( GetNumInfo().GetNumRule() ) EndNumBulList(); OSL_ENSURE( !nContextStMin, "Es gibt geschuetzte Kontexte" ); nContextStMin = 0; while( aContexts.size() ) { _HTMLAttrContext *pCntxt = PopContext(); if( pCntxt ) { EndContext( pCntxt ); delete pCntxt; } } if( !aParaAttrs.empty() ) aParaAttrs.clear(); SetAttr( sal_False ); // Noch die erst verzoegert gesetzten Styles setzen pCSS1Parser->SetDelayedStyles(); } // den Start wieder korrigieren if( !IsNewDoc() && pSttNdIdx->GetIndex() ) { SwTxtNode* pTxtNode = pSttNdIdx->GetNode().GetTxtNode(); SwNodeIndex aNxtIdx( *pSttNdIdx ); if( pTxtNode && pTxtNode->CanJoinNext( &aNxtIdx )) { xub_StrLen nStt = pTxtNode->GetTxt().getLength(); // wenn der Cursor noch in dem Node steht, dann setze in an das Ende if( pPam->GetPoint()->nNode == aNxtIdx ) { pPam->GetPoint()->nNode = *pSttNdIdx; pPam->GetPoint()->nContent.Assign( pTxtNode, nStt ); } #if OSL_DEBUG_LEVEL > 0 // !!! sollte nicht moeglich sein, oder ?? OSL_ENSURE( pSttNdIdx->GetIndex()+1 != pPam->GetBound( sal_True ).nNode.GetIndex(), "Pam.Bound1 steht noch im Node" ); OSL_ENSURE( pSttNdIdx->GetIndex()+1 != pPam->GetBound( sal_False ).nNode.GetIndex(), "Pam.Bound2 steht noch im Node" ); if( pSttNdIdx->GetIndex()+1 == pPam->GetBound( sal_True ).nNode.GetIndex() ) { xub_StrLen nCntPos = pPam->GetBound( sal_True ).nContent.GetIndex(); pPam->GetBound( sal_True ).nContent.Assign( pTxtNode, pTxtNode->GetTxt().getLength() + nCntPos ); } if( pSttNdIdx->GetIndex()+1 == pPam->GetBound( sal_False ).nNode.GetIndex() ) { xub_StrLen nCntPos = pPam->GetBound( sal_False ).nContent.GetIndex(); pPam->GetBound( sal_False ).nContent.Assign( pTxtNode, pTxtNode->GetTxt().getLength() + nCntPos ); } #endif // Zeichen Attribute beibehalten! SwTxtNode* pDelNd = aNxtIdx.GetNode().GetTxtNode(); if (pTxtNode->GetTxt().getLength()) pDelNd->FmtToTxtAttr( pTxtNode ); else pTxtNode->ChgFmtColl( pDelNd->GetTxtColl() ); pTxtNode->JoinNext(); } } } if( SVPAR_ACCEPTED == eState ) { if( nMissingImgMaps ) { // es fehlen noch ein paar Image-Map zuordungen. // vielleicht sind die Image-Maps ja jetzt da? ConnectImageMaps(); } // jetzt noch den letzten ueberfluessigen Absatz loeschen SwPosition* pPos = pPam->GetPoint(); if( !pPos->nContent.GetIndex() && !bLFStripped ) { SwTxtNode* pAktNd; sal_uLong nNodeIdx = pPos->nNode.GetIndex(); sal_Bool bHasFlysOrMarks = HasCurrentParaFlys() || HasCurrentParaBookmarks( sal_True ); if( IsNewDoc() ) { const SwNode *pPrev = pDoc->GetNodes()[nNodeIdx -1]; if( !pPam->GetPoint()->nContent.GetIndex() && ( pPrev->IsCntntNode() || (pPrev->IsEndNode() && pPrev->StartOfSectionNode()->IsSectionNode()) ) ) { SwCntntNode* pCNd = pPam->GetCntntNode(); if( pCNd && pCNd->StartOfSectionIndex()+2 < pCNd->EndOfSectionIndex() && !bHasFlysOrMarks ) { ViewShell *pVSh = CheckActionViewShell(); SwCrsrShell *pCrsrSh = pVSh && pVSh->ISA(SwCrsrShell) ? static_cast < SwCrsrShell * >( pVSh ) : 0; if( pCrsrSh && pCrsrSh->GetCrsr()->GetPoint() ->nNode.GetIndex() == nNodeIdx ) { pCrsrSh->MovePara(fnParaPrev, fnParaEnd ); pCrsrSh->SetMark(); pCrsrSh->ClearMark(); } pPam->GetBound(sal_True).nContent.Assign( 0, 0 ); pPam->GetBound(sal_False).nContent.Assign( 0, 0 ); pDoc->GetNodes().Delete( pPam->GetPoint()->nNode ); } } } else if( 0 != ( pAktNd = pDoc->GetNodes()[ nNodeIdx ]->GetTxtNode()) && !bHasFlysOrMarks ) { if( pAktNd->CanJoinNext( &pPos->nNode )) { SwTxtNode* pNextNd = pPos->nNode.GetNode().GetTxtNode(); pPos->nContent.Assign( pNextNd, 0 ); pPam->SetMark(); pPam->DeleteMark(); pNextNd->JoinPrev(); } else if (pAktNd->GetTxt().isEmpty()) { pPos->nContent.Assign( 0, 0 ); pPam->SetMark(); pPam->DeleteMark(); pDoc->GetNodes().Delete( pPos->nNode, 1 ); pPam->Move( fnMoveBackward ); } } } // nun noch das SplitNode vom Anfang aufheben else if( !IsNewDoc() ) { if( pPos->nContent.GetIndex() ) // dann gabs am Ende kein

, pPam->Move( fnMoveForward, fnGoNode ); // als zum naechsten Node SwTxtNode* pTxtNode = pPos->nNode.GetNode().GetTxtNode(); SwNodeIndex aPrvIdx( pPos->nNode ); if( pTxtNode && pTxtNode->CanJoinPrev( &aPrvIdx ) && *pSttNdIdx <= aPrvIdx ) { // eigentlich muss hier ein JoinNext erfolgen, aber alle Cursor // usw. sind im pTxtNode angemeldet, so dass der bestehen // bleiben MUSS. // Absatz in Zeichen-Attribute umwandeln, aus dem Prev die // Absatzattribute und die Vorlage uebernehmen! SwTxtNode* pPrev = aPrvIdx.GetNode().GetTxtNode(); pTxtNode->ChgFmtColl( pPrev->GetTxtColl() ); pTxtNode->FmtToTxtAttr( pPrev ); pTxtNode->ResetAllAttr(); if( pPrev->HasSwAttrSet() ) pTxtNode->SetAttr( *pPrev->GetpSwAttrSet() ); if( &pPam->GetBound(sal_True).nNode.GetNode() == pPrev ) pPam->GetBound(sal_True).nContent.Assign( pTxtNode, 0 ); if( &pPam->GetBound(sal_False).nNode.GetNode() == pPrev ) pPam->GetBound(sal_False).nContent.Assign( pTxtNode, 0 ); pTxtNode->JoinPrev(); } } // adjust AutoLoad in DocumentProperties if( IsNewDoc() ) { SwDocShell *pDocShell(pDoc->GetDocShell()); OSL_ENSURE(pDocShell, "no SwDocShell"); if (pDocShell) { uno::Reference xDPS( pDocShell->GetModel(), uno::UNO_QUERY_THROW); uno::Reference xDocProps( xDPS->getDocumentProperties()); OSL_ENSURE(xDocProps.is(), "DocumentProperties is null"); if ( xDocProps.is() && (xDocProps->getAutoloadSecs() > 0) && (xDocProps->getAutoloadURL().isEmpty()) ) { xDocProps->setAutoloadURL(aPathToFile); } } } if( bUpdateDocStat ) { pDoc->UpdateDocStat(); } } if( SVPAR_PENDING != GetStatus() ) delete pSttNdIdx, pSttNdIdx = 0; // sollte der Parser der Letzte sein, der das Doc haelt, dann braucht // man hier auch nichts mehr tun, Doc wird gleich zerstoert! if( 1 < pDoc->getReferenceCount() ) { if( bWasUndo ) { pDoc->GetIDocumentUndoRedo().DelAllUndoObj(); pDoc->GetIDocumentUndoRedo().DoUndo(true); } else if( !pInitVSh ) { // Wenn zu Beginn des Continue keine Shell vorhanden war, // kann trotzdem mitlerweile eine angelegt worden sein. // In dieses Fall stimmt das bWasUndo-Flag nicht und // wir muessen das Undo noch anschalten. ViewShell *pTmpVSh = CheckActionViewShell(); if( pTmpVSh ) { pDoc->GetIDocumentUndoRedo().DoUndo(true); } } pDoc->SetOle2Link( aOLELink ); if( !bModified ) pDoc->ResetModified(); if( bSetModEnabled && pDoc->GetDocShell() ) { pDoc->GetDocShell()->EnableSetModified( sal_True ); bSetModEnabled = sal_False; // this is unnecessary here } } // Wenn die Dokuemnt-ViewShell noch existiert und eine Action // offen ist (muss bei Abbruch nicht sein), die Action beenden, // uns von der Shell abmelden und schliesslich die alte Shell // wieder rekonstruieren. CallEndAction( sal_True ); #ifdef DBG_UTIL m_nContinue--; #endif } void SwHTMLParser::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew ) { switch( pOld ? pOld->Which() : pNew ? pNew->Which() : 0 ) { case RES_OBJECTDYING: if( ((SwPtrMsgPoolItem *)pOld)->pObject == GetRegisteredIn() ) { // dann uns selbst beenden GetRegisteredInNonConst()->Remove( this ); ReleaseRef(); // ansonsten sind wir fertig! } break; } } void SwHTMLParser::DocumentDetected() { OSL_ENSURE( !bDocInitalized, "DocumentDetected mehrfach aufgerufen" ); bDocInitalized = sal_True; if( IsNewDoc() ) { if( IsInHeader() ) FinishHeader( sal_True ); CallEndAction( sal_True, sal_True ); pDoc->GetIDocumentUndoRedo().DoUndo(false); // Durch das DocumentDetected wurde im allgemeinen eine // ViewShell angelegt. Es kann aber auch sein, dass sie // erst spaeter angelegt wird, naemlich dann, wenn die UI // gecaptured ist. CallStartAction(); } } // is called for every token that is recognised in CallParser void SwHTMLParser::NextToken( int nToken ) { if( ( pDoc->GetDocShell() && pDoc->GetDocShell()->IsAbortingImport() ) || 1 == pDoc->getReferenceCount() ) { // Was the import cancelled by SFX? If a pending stack // exists, clean it. eState = SVPAR_ERROR; OSL_ENSURE( !pPendStack || pPendStack->nToken, "SwHTMLParser::NextToken: Pending-Stack without token" ); if( 1 == pDoc->getReferenceCount() || !pPendStack ) return ; } #if OSL_DEBUG_LEVEL > 0 if( pPendStack ) { switch( nToken ) { // tables are read by recursive method calls case HTML_TABLE_ON: // For CSS declarations we might have to wait // for a file download to finish case HTML_LINK: // For controls we might have to set the size. case HTML_INPUT: case HTML_TEXTAREA_ON: case HTML_SELECT_ON: case HTML_SELECT_OFF: break; default: OSL_ENSURE( !pPendStack, "Unbekanntes Token fuer Pending-Stack" ); break; } } #endif // The following special cases have to be treated before the // filter detection, because Netscape doesn't reference the content // of the title for filter detection either. if( !pPendStack ) { if( bInTitle ) { switch( nToken ) { case HTML_TITLE_OFF: if( IsNewDoc() && sTitle.Len() ) { if( pDoc->GetDocShell() ) { uno::Reference xDPS(pDoc->GetDocShell()->GetModel(), uno::UNO_QUERY_THROW); uno::Reference xDocProps( xDPS->getDocumentProperties()); OSL_ENSURE(xDocProps.is(), "no DocumentProperties"); if (xDocProps.is()) { xDocProps->setTitle(sTitle); } pDoc->GetDocShell()->SetTitle( sTitle ); } } bInTitle = sal_False; sTitle.Erase(); break; case HTML_NONBREAKSPACE: sTitle += ' '; break; case HTML_SOFTHYPH: sTitle += '-'; break; case HTML_TEXTTOKEN: sTitle += aToken; break; default: sTitle += '<'; if( (HTML_TOKEN_ONOFF & nToken) && (1 & nToken) ) sTitle += '/'; sTitle += sSaveToken; if( aToken.Len() ) { sTitle += ' '; sTitle += aToken; } sTitle += '>'; break; } return; } } // Find out what type of document it is if we don't know already. // For Controls this has to be finished before the control is inserted // because for inserting a View is needed. if( !bDocInitalized ) DocumentDetected(); sal_Bool bGetIDOption = sal_False, bInsertUnknown = sal_False; sal_Bool bUpperSpaceSave = bUpperSpace; bUpperSpace = sal_False; // The following special cases may or have to be treated after the // filter detection if( !pPendStack ) { if( bInFloatingFrame ) { //