/************************************************************** * * 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 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sw.hxx" #include #include #include #include #include #ifdef DBG_UTIL #include #endif #include #define _SVSTDARR_STRINGS #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 FONTCOLOR_MASK (1<<15) #define FONT_MASK (1<<14) #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 #ifndef TOOLS_CONSTASCII_STRINGPARAM #define TOOLS_CONSTASCII_STRINGPARAM( constAsciiStr ) constAsciiStr, sizeof( constAsciiStr )-1 #endif using namespace ::com::sun::star; //

, , usw. HTMLOptionEnum __FAR_DATA 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 __FAR_DATA 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 } }; SV_IMPL_PTRARR( _HTMLAttrs, _HTMLAttrPtr ) HTMLReader::HTMLReader() { bTmplBrowseMode = sal_True; } String HTMLReader::GetTemplateName() const { String sTemplate( String::CreateFromAscii(TOOLS_CONSTASCII_STRINGPARAM("internal")) ); sTemplate += INET_PATH_TOKEN; sTemplate.AppendAscii( TOOLS_CONSTASCII_STRINGPARAM("html") ); String sTemplateWithoutExt( sTemplate ); #ifndef MAC_WITHOUT_EXT // --> OD 2005-01-26 - first search for OpenDocument Writer/Web template sTemplate.AppendAscii( TOOLS_CONSTASCII_STRINGPARAM(".oth") ); // <-- #endif SvtPathOptions aPathOpt; // OpenDocument Writer/Web template (extension .oth) sal_Bool bSet = aPathOpt.SearchFile( sTemplate, SvtPathOptions::PATH_TEMPLATE ); #ifndef MAC_WITHOUT_EXT if( !bSet ) { // 6.0 (extension .stw) sTemplate = sTemplateWithoutExt; // --> OD 2005-01-26 - no OpenDocument Writer/Web template found. // search for OpenOffice.org Writer/Web template sTemplate.AppendAscii( TOOLS_CONSTASCII_STRINGPARAM(".stw") ); // <-- bSet = aPathOpt.SearchFile( sTemplate, SvtPathOptions::PATH_TEMPLATE ); } #endif if( !bSet ) { sTemplate.Erase(); ASSERT( !this, "Die html.vor befindet sich nicht mehr im definierten Directory!"); } return sTemplate; } int HTMLReader::SetStrmStgPtr() { ASSERT( 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 ) { ASSERT( pStrm, "HTML-Read ohne Stream" ); return ERR_SWG_READ_ERROR; } if( !bInsertMode ) { Reader::SetNoOutlineNum( rDoc ); 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( String::CreateFromInt32((sal_Int32)xParser->GetLineNr())); sErr += ','; sErr += String::CreateFromInt32((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 ), // --> OD 2007-10-26 #i83625# nContextStMin( 0 ), nContextStAttrMin( 0 ), // <-- nOpenParaToken( 0 ), eJumpTo( JUMPTO_NONE ), #ifdef DBG_UTIL 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 ) 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* pHtmlOptions = SvxHtmlOptions::Get(); aFontHeights[0] = pHtmlOptions->GetFontSize( 0 ) * 20; aFontHeights[1] = pHtmlOptions->GetFontSize( 1 ) * 20; aFontHeights[2] = pHtmlOptions->GetFontSize( 2 ) * 20; aFontHeights[3] = pHtmlOptions->GetFontSize( 3 ) * 20; aFontHeights[4] = pHtmlOptions->GetFontSize( 4 ) * 20; aFontHeights[5] = pHtmlOptions->GetFontSize( 5 ) * 20; aFontHeights[6] = pHtmlOptions->GetFontSize( 6 ) * 20; bKeepUnknown = pHtmlOptions->IsImportUnknown(); if(bReadNewDoc) { SvxFontHeightItem aFontHeight(aFontHeights[2], 100, RES_CHRATR_FONTSIZE); pDoc->SetDefault( aFontHeight ); aFontHeight.SetWhich( RES_CHRATR_CJK_FONTSIZE ); pDoc->SetDefault( aFontHeight ); aFontHeight.SetWhich( RES_CHRATR_CTL_FONTSIZE ); pDoc->SetDefault( aFontHeight ); } // 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( pHtmlOptions->IsIgnoreFontFamily() ); if( bReadUTF8 ) { SetSrcEncoding( RTL_TEXTENCODING_UTF8 ); } else { SwDocShell *pDocSh = pDoc->GetDocShell(); SvKeyValueIterator *pHeaderAttrs = pDocSh->GetHeaderAttributes(); if( pHeaderAttrs ) SetEncodingByHTTPHeader( pHeaderAttrs ); } pCSS1Parser->SetDfltEncoding( gsl_getSystemTextEncoding() ); // 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; String sCmp; xub_StrLen nLastPos, nPos = 0; while( STRING_NOTFOUND != ( nLastPos = sJmpMark.Search( cMarkSeperator, nPos + 1 )) ) nPos = nLastPos; if( nPos && ( sCmp = sJmpMark.Copy( nPos + 1 ) ). EraseAllChars().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; } } } } __EXPORT SwHTMLParser::~SwHTMLParser() { #ifdef DBG_UTIL ASSERT( !nContinue, "DTOR im Continue - Das geht schief!!!" ); #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, sal_True, sal_False ); if ( pDoc->GetDocShell()->IsLoading() ) { // --> OD 2006-11-07 #i59688# pDoc->GetDocShell()->LoadingFinished(); } } delete pSttNdIdx; if( aSetAttrTab.Count() ) { ASSERT( !aSetAttrTab.Count(),"Es stehen noch Attribute auf dem Stack" ); aSetAttrTab.DeleteAndDestroy( 0, aSetAttrTab.Count() ); } delete pPam; delete pCSS1Parser; delete pNumRuleInfo; DeleteFormImpl(); DeleteFootEndNoteImpl(); ASSERT( !pTable, "Es existiert noch eine offene Tabelle" ); delete pImageMaps; //delete pTable; ASSERT( !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; // --> FME 2005-08-18 #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 __EXPORT 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 ); // #106634# 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(); } SwPageDesc& rDesc = pDoc->_GetPageDesc( 0 ); rDesc.Add( this ); SvParserState eRet = HTMLParser::CallParser(); return eRet; } void __EXPORT SwHTMLParser::Continue( int nToken ) { #ifdef DBG_UTIL ASSERT( !nContinue, "Continue im Continue - Das sollte doch nicht sein, oder?" ); nContinue++; #endif // Wenn der Import (vom SFX) abgebrochen wurde, wird ein Fehler // gesetzt aber trotzdem noch weiter gemacht, damit vernuenftig // aufgeraeumt wird. ASSERT( 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 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 ) { ASSERT( !pPendStack || pPendStack->nToken, "SwHTMLParser::Continue: Pending-Stack ohne Token" ); if( pPendStack && pPendStack->nToken ) NextToken( pPendStack->nToken ); ASSERT( !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(); ASSERT( !nContextStMin, "Es gibt geschuetzte Kontexte" ); nContextStMin = 0; while( aContexts.Count() ) { _HTMLAttrContext *pCntxt = PopContext(); if( pCntxt ) { EndContext( pCntxt ); delete pCntxt; } } if( aParaAttrs.Count() ) aParaAttrs.Remove( 0, aParaAttrs.Count() ); 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().Len(); // 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 ); } #ifdef DBG_UTIL // !!! sollte nicht moeglich sein, oder ?? ASSERT( pSttNdIdx->GetIndex()+1 != pPam->GetBound( sal_True ).nNode.GetIndex(), "Pam.Bound1 steht noch im Node" ); ASSERT( 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().Len() + 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().Len() + nCntPos ); } #endif // Zeichen Attribute beibehalten! SwTxtNode* pDelNd = aNxtIdx.GetNode().GetTxtNode(); if( pTxtNode->GetTxt().Len() ) 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().Len() ) { 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(); } } // und noch die DocumentInfo aufbereiten if( IsNewDoc() ) { SwDocShell *pDocShell(pDoc->GetDocShell()); DBG_ASSERT(pDocShell, "no SwDocShell"); if (pDocShell) { uno::Reference xDPS( pDocShell->GetModel(), uno::UNO_QUERY_THROW); uno::Reference xDocProps( xDPS->getDocumentProperties()); DBG_ASSERT(xDocProps.is(), "DocumentProperties is null"); if ( xDocProps.is() && (xDocProps->getAutoloadSecs() > 0) && xDocProps->getAutoloadURL().equalsAscii("") ) { xDocProps->setAutoloadURL(aPathToFile); } } } if( bUpdateDocStat ) { SwDocStat aStat( pDoc->GetDocStat() ); pDoc->UpdateDocStat( aStat ); } } 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 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() { ASSERT( !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(); } } // wird fuer jedes Token gerufen, das in CallParser erkannt wird void __EXPORT SwHTMLParser::NextToken( int nToken ) { if( ( pDoc->GetDocShell() && pDoc->GetDocShell()->IsAbortingImport() ) || 1 == pDoc->getReferenceCount() ) { // wurde der Import vom SFX abgebrochen? Wenn ein Pending-Stack // existiert den noch aufraumen eState = SVPAR_ERROR; ASSERT( !pPendStack || pPendStack->nToken, "SwHTMLParser::NextToken: Pending-Stack ohne Token" ); if( 1 == pDoc->getReferenceCount() || !pPendStack ) return ; } #ifdef DBG_UTIL if( pPendStack ) { switch( nToken ) { // Tabellen werden ueber rekusive Methodenaufrufe gelesen case HTML_TABLE_ON: // Bei CSS-Deklarationen muss evtl. noch auf das // Ende eines File-Downloads gewartet werden. case HTML_LINK: // Bei Controls muss evtl. noch die Groesse gesetzt werden. case HTML_INPUT: case HTML_TEXTAREA_ON: case HTML_SELECT_ON: case HTML_SELECT_OFF: break; default: ASSERT( !pPendStack, "Unbekanntes Token fuer Pending-Stack" ); break; } } #endif // Die folgeneden Spezialfaelle muessen vor der Filter-Detection behandelt // werden, denn der Inhalt des Titels, etc. wird auch in Netcape nicht // zur Filter-Detection herangezogen. 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()); DBG_ASSERT(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; } } // Wenn wir noch nicht wissen, was fuer ein Dokument wir vor uns haben, // versuchen wir das erstmal rauszufinden. Das muss fuer Controls in // Fall vor dem Einfuegen des Controls passieren, weil beim Einfuegen // bereits eine View benoetigt wird. if( !bDocInitalized ) DocumentDetected(); sal_Bool bGetIDOption = sal_False, bInsertUnknown = sal_False; sal_Bool bUpperSpaceSave = bUpperSpace; bUpperSpace = sal_False; // Die folgenden Speziallfaelle muessen oder koennen nach der // Filter-Detection erfolgen. if( !pPendStack ) { if( bInFloatingFrame ) { //