/* -*- 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 #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 #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 #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_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 = true; } OUString HTMLReader::GetTemplateName() const { const OUString sTemplateWithoutExt("internal/html"); SvtPathOptions aPathOpt; // first search for OpenDocument Writer/Web template // OpenDocument Writer/Web template (extension .oth) OUString sTemplate( sTemplateWithoutExt + ".oth" ); if (aPathOpt.SearchFile( sTemplate, SvtPathOptions::PATH_TEMPLATE )) return sTemplate; // no OpenDocument Writer/Web template found. // search for OpenOffice.org Writer/Web template sTemplate = sTemplateWithoutExt + ".stw"; if (aPathOpt.SearchFile( sTemplate, SvtPathOptions::PATH_TEMPLATE )) return sTemplate; OSL_ENSURE( false, "The default HTML template cannot be found in the defined template directories!"); return OUString(); } bool HTMLReader::SetStrmStgPtr() { OSL_ENSURE( pMedium, "Wo ist das Medium??" ); if( pMedium->IsRemote() || !pMedium->IsStorage() ) { pStrm = pMedium->GetInStream(); return true; } return false; } // Aufruf fuer die allg. Reader-Schnittstelle sal_uLong HTMLReader::Read( SwDoc &rDoc, const OUString& rBaseURL, SwPaM &rPam, const OUString & rName ) { if( !pStrm ) { OSL_ENSURE( pStrm, "HTML-Read ohne Stream" ); return ERR_SWG_READ_ERROR; } if( !bInsertMode ) { Reader::ResetFrameFormats( rDoc ); // Die HTML-Seitenvorlage setzen, wenn des kein HTML-Dokument ist, // sonst ist sie schon gesetzt. if( !rDoc.getIDocumentSettingAccess().get(DocumentSettingId::HTML_MODE) ) { rDoc.getIDocumentContentOperations().InsertPoolItem( rPam, SwFormatPageDesc( rDoc.getIDocumentStylePoolAccess().GetPageDescFromPool( RES_POOLPAGE_HTML, false )) ); } } // damit keiner das Doc klaut! rDoc.acquire(); sal_uLong nRet = 0; tools::SvRef 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 ) { const OUString sErr(OUString::number((sal_Int32)xParser->GetLineNr()) + "," + 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, SwPaM& rCrsr, SvStream& rIn, const OUString& rPath, const OUString& rBaseURL, bool bReadNewDoc, SfxMedium* pMed, bool bReadUTF8, bool bNoHTMLComments ) : SfxHTMLParser( rIn, 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 ), nSelectEntryCnt( 0 ), nOpenParaToken( 0 ), eJumpTo( JUMPTO_NONE ), #ifdef DBG_UTIL m_nContinue( 0 ), #endif eParaAdjust( SVX_ADJUST_END ), bDocInitalized( false ), bSetModEnabled( false ), bInFloatingFrame( false ), bInField( false ), bCallNextToken( false ), bIgnoreRawData( false ), bLBEntrySelected ( false ), bTAIgnoreNewPara ( false ), bFixMarqueeWidth ( false ), bFixMarqueeHeight ( false ), bNoParSpace( false ), bInNoEmbed( false ), bInTitle( false ), bUpdateDocStat( false ), bFixSelectWidth( false ), bFixSelectHeight( false ), bTextArea( false ), bSelect( false ), bInFootEndNoteAnchor( false ), bInFootEndNoteSymbol( false ), bIgnoreHTMLComments( bNoHTMLComments ), bRemoveHidden( false ), pTempViewFrame(0) { nEventId = 0; bUpperSpace = bViewCreated = bChkJumpMark = bSetCrsr = false; eScriptLang = HTML_SL_UNKNOWN; bAnyStarBasic = true; rCrsr.DeleteMark(); pPam = &rCrsr; // re-use existing cursor: avoids spurious ~SwIndexReg assert 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 ); // #i18732# - adjust default of option 'FollowTextFlow' // TODO: not sure what the appropriate default for HTML should be? pDoc->SetDefault( SwFormatFollowTextFlow(true) ); } // Waehrend des Imports in den HTML-Modus schalten, damit die // richrigen Vorlagen angelegt werden bOldIsHTMLMode = pDoc->getIDocumentSettingAccess().get(DocumentSettingId::HTML_MODE); pDoc->getIDocumentSettingAccess().set(DocumentSettingId::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 = true; // nicht, synchron laden // es ist ein Sprungziel vorgegeben. if( pMed ) { sJmpMark = pMed->GetURLObject().GetMark(); if( !sJmpMark.isEmpty() ) { eJumpTo = JUMPTO_MARK; sal_Int32 nLastPos = sJmpMark.lastIndexOf( cMarkSeparator ); sal_Int32 nPos = nLastPos != -1 ? nLastPos : 0; OUString sCmp; if (nPos) { sCmp = comphelper::string::remove( sJmpMark.copy(nPos + 1), ' '); } if( !sCmp.isEmpty() ) { sCmp = sCmp.toAsciiLowerCase(); if( sCmp == "region" ) eJumpTo = JUMPTO_REGION; else if( sCmp == "table" ) eJumpTo = JUMPTO_TABLE; else if( sCmp == "graphic" ) eJumpTo = JUMPTO_GRAPHIC; else if( sCmp == "outline" || sCmp == "text" || sCmp == "frame" ) eJumpTo = JUMPTO_NONE; // das ist nichts gueltiges! else // ansonsten ist das ein normaler (Book)Mark nPos = -1; } else nPos = -1; if( nPos != -1 ) sJmpMark = sJmpMark.copy( 0, nPos ); if( sJmpMark.isEmpty() ) eJumpTo = JUMPTO_NONE; } } } } SwHTMLParser::~SwHTMLParser() { #ifdef DBG_UTIL OSL_ENSURE( !m_nContinue, "DTOR im Continue!" ); #endif bool bAsync = pDoc->IsInLoadAsynchron(); pDoc->SetInLoadAsynchron( false ); pDoc->getIDocumentSettingAccess().set(DocumentSettingId::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->getIDocumentSettingAccess().getLinkUpdateMode( true ); if( nLinkMode != NEVER && bAsync && SfxObjectCreateMode::INTERNAL!=pDoc->GetDocShell()->GetCreateMode() ) pDoc->getIDocumentLinksAdministration().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 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_NOARG_TYPED( SwHTMLParser, AsyncCallback, void*, void ) { 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); } 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->getIDocumentContentOperations().SplitNode( *pPos, false ); *pSttNdIdx = pPos->nNode.GetIndex()-1; pDoc->getIDocumentContentOperations().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->getIDocumentRedlineAccess().SplitRedline( aInsertionRangePam ); pDoc->SetTextFormatColl( *pPam, pCSS1Parser->GetTextCollFromPool( RES_POOLCOLL_STANDARD )); } if( GetMedium() ) { if( !bViewCreated ) { nEventId = Application::PostUserEvent( LINK( this, SwHTMLParser, AsyncCallback ), 0 ); } else { bViewCreated = 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 SwViewShell vom Dokument holen, merken und als aktuelle setzen. SwViewShell *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 = true; pDoc->SetInLoadAsynchron( true ); #ifdef DBG_UTIL m_nContinue--; #endif return; } bSetModEnabled = false; if( pDoc->GetDocShell() && (bSetModEnabled = pDoc->GetDocShell()->IsEnableSetModified()) ) { pDoc->GetDocShell()->EnableSetModified( false ); } // waehrend des einlesens kein OLE-Modified rufen Link aOLELink( pDoc->GetOle2Link() ); pDoc->SetOle2Link( Link() ); bool bModified = pDoc->getIDocumentState().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() ); bool bLFStripped = false; if( SVPAR_PENDING != GetStatus() ) { // noch die letzten Attribute setzen { if( !aScriptSource.isEmpty() ) { SwScriptFieldType *pType = static_cast(pDoc->getIDocumentFieldsAccess().GetSysFieldType( RES_SCRIPTFLD )); SwScriptField aField( pType, aScriptType, aScriptSource, false ); InsertAttr( SwFormatField( aField ) ); } 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( false ); // Noch die erst verzoegert gesetzten Styles setzen pCSS1Parser->SetDelayedStyles(); } // den Start wieder korrigieren if( !IsNewDoc() && pSttNdIdx->GetIndex() ) { SwTextNode* pTextNode = pSttNdIdx->GetNode().GetTextNode(); SwNodeIndex aNxtIdx( *pSttNdIdx ); if( pTextNode && pTextNode->CanJoinNext( &aNxtIdx )) { const sal_Int32 nStt = pTextNode->GetText().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( pTextNode, nStt ); } #if OSL_DEBUG_LEVEL > 0 // !!! sollte nicht moeglich sein, oder ?? OSL_ENSURE( pSttNdIdx->GetIndex()+1 != pPam->GetBound().nNode.GetIndex(), "Pam.Bound1 steht noch im Node" ); OSL_ENSURE( pSttNdIdx->GetIndex()+1 != pPam->GetBound( false ).nNode.GetIndex(), "Pam.Bound2 steht noch im Node" ); if( pSttNdIdx->GetIndex()+1 == pPam->GetBound().nNode.GetIndex() ) { const sal_Int32 nCntPos = pPam->GetBound().nContent.GetIndex(); pPam->GetBound().nContent.Assign( pTextNode, pTextNode->GetText().getLength() + nCntPos ); } if( pSttNdIdx->GetIndex()+1 == pPam->GetBound( false ).nNode.GetIndex() ) { const sal_Int32 nCntPos = pPam->GetBound( false ).nContent.GetIndex(); pPam->GetBound( false ).nContent.Assign( pTextNode, pTextNode->GetText().getLength() + nCntPos ); } #endif // Zeichen Attribute beibehalten! SwTextNode* pDelNd = aNxtIdx.GetNode().GetTextNode(); if (pTextNode->GetText().getLength()) pDelNd->FormatToTextAttr( pTextNode ); else pTextNode->ChgFormatColl( pDelNd->GetTextColl() ); pTextNode->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 ) { SwTextNode* pAktNd; sal_uLong nNodeIdx = pPos->nNode.GetIndex(); bool bHasFlysOrMarks = HasCurrentParaFlys() || HasCurrentParaBookmarks( true ); if( IsNewDoc() ) { const SwNode *pPrev = pDoc->GetNodes()[nNodeIdx -1]; if( !pPam->GetPoint()->nContent.GetIndex() && ( pPrev->IsContentNode() || (pPrev->IsEndNode() && pPrev->StartOfSectionNode()->IsSectionNode()) ) ) { SwContentNode* pCNd = pPam->GetContentNode(); if( pCNd && pCNd->StartOfSectionIndex()+2 < pCNd->EndOfSectionIndex() && !bHasFlysOrMarks ) { SwViewShell *pVSh = CheckActionViewShell(); SwCrsrShell *pCrsrSh = pVSh && dynamic_cast< const SwCrsrShell *>( pVSh ) != nullptr ? static_cast < SwCrsrShell * >( pVSh ) : 0; if( pCrsrSh && pCrsrSh->GetCrsr()->GetPoint() ->nNode.GetIndex() == nNodeIdx ) { pCrsrSh->MovePara(fnParaPrev, fnParaEnd ); pCrsrSh->SetMark(); pCrsrSh->ClearMark(); } pPam->GetBound().nContent.Assign( 0, 0 ); pPam->GetBound(false).nContent.Assign( 0, 0 ); pDoc->GetNodes().Delete( pPam->GetPoint()->nNode ); } } } else if( 0 != ( pAktNd = pDoc->GetNodes()[ nNodeIdx ]->GetTextNode()) && !bHasFlysOrMarks ) { if( pAktNd->CanJoinNext( &pPos->nNode )) { SwTextNode* pNextNd = pPos->nNode.GetNode().GetTextNode(); pPos->nContent.Assign( pNextNd, 0 ); pPam->SetMark(); pPam->DeleteMark(); pNextNd->JoinPrev(); } else if (pAktNd->GetText().isEmpty()) { pPos->nContent.Assign( 0, 0 ); pPam->SetMark(); pPam->DeleteMark(); pDoc->GetNodes().Delete( pPos->nNode ); 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 SwTextNode* pTextNode = pPos->nNode.GetNode().GetTextNode(); SwNodeIndex aPrvIdx( pPos->nNode ); if( pTextNode && pTextNode->CanJoinPrev( &aPrvIdx ) && *pSttNdIdx <= aPrvIdx ) { // eigentlich muss hier ein JoinNext erfolgen, aber alle Cursor // usw. sind im pTextNode angemeldet, so dass der bestehen // bleiben MUSS. // Absatz in Zeichen-Attribute umwandeln, aus dem Prev die // Absatzattribute und die Vorlage uebernehmen! SwTextNode* pPrev = aPrvIdx.GetNode().GetTextNode(); pTextNode->ChgFormatColl( pPrev->GetTextColl() ); pTextNode->FormatToTextAttr( pPrev ); pTextNode->ResetAllAttr(); if( pPrev->HasSwAttrSet() ) pTextNode->SetAttr( *pPrev->GetpSwAttrSet() ); if( &pPam->GetBound().nNode.GetNode() == pPrev ) pPam->GetBound().nContent.Assign( pTextNode, 0 ); if( &pPam->GetBound(false).nNode.GetNode() == pPrev ) pPam->GetBound(false).nContent.Assign( pTextNode, 0 ); pTextNode->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->getIDocumentStatistics().UpdateDocStat( false, true ); } } 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. SwViewShell *pTmpVSh = CheckActionViewShell(); if( pTmpVSh ) { pDoc->GetIDocumentUndoRedo().DoUndo(true); } } pDoc->SetOle2Link( aOLELink ); if( !bModified ) pDoc->getIDocumentState().ResetModified(); if( bSetModEnabled && pDoc->GetDocShell() ) { pDoc->GetDocShell()->EnableSetModified(); bSetModEnabled = false; // this is unnecessary here } } // Wenn die Dokuemnt-SwViewShell 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( 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 (pOld && static_cast(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 = true; if( IsNewDoc() ) { if( IsInHeader() ) FinishHeader( true ); CallEndAction( true ); pDoc->GetIDocumentUndoRedo().DoUndo(false); // Durch das DocumentDetected wurde im allgemeinen eine // SwViewShell 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.isEmpty() ) { 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 = false; sTitle.clear(); 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.isEmpty() ) { 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(); bool bGetIDOption = false, bInsertUnknown = false; bool bUpperSpaceSave = bUpperSpace; bUpperSpace = false; // The following special cases may or have to be treated after the // filter detection if( !pPendStack ) { if( bInFloatingFrame ) { //