/************************************************************** * * 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 #define _SVSTDARR_STRINGS #include #include #ifndef __RSC //autogen #include #endif #include #include #ifndef SVTOOLS_FSTATHELPER_HXX #include #endif #include #include #include #include // ASSERT #include #include #include #include #include #include #ifndef _GLOBALS_HRC #include #endif using namespace ::com::sun::star; using namespace ::com::sun::star::uno; // PUBLIC METHODES ------------------------------------------------------- /* -----------------------------08.02.00 15:54-------------------------------- ---------------------------------------------------------------------------*/ String lcl_CheckFileName( const String& rNewFilePath, const String& rNewGroupName ) { String sRet; //group name should contain only A-Z and a-z and spaces for( xub_StrLen i = 0; i < rNewGroupName.Len(); i++ ) { sal_Unicode cChar = rNewGroupName.GetChar(i); if( (cChar >= 'A' && cChar <= 'Z') || (cChar >= 'a' && cChar <= 'z') || (cChar >= '0' && cChar <= '9') || cChar == '_' || cChar == 0x20 ) { sRet += cChar; } } sRet.EraseLeadingChars(); sRet.EraseTrailingChars(); sal_Bool bOk = sal_False; if( sRet.Len() ) { String sTmpDir(rNewFilePath); sTmpDir += INET_PATH_TOKEN; sTmpDir += sRet; sTmpDir += SwGlossaries::GetExtension(); bOk = !FStatHelper::IsDocument( sTmpDir ); } if( !bOk ) { String rSG = SwGlossaries::GetExtension(); //generate generic name utl::TempFile aTemp( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "group" )), &rSG, &rNewFilePath ); aTemp.EnableKillingFile(); INetURLObject aTempURL( aTemp.GetURL() ); sRet = aTempURL.GetBase(); } return sRet; } /*------------------------------------------------------------------------ Beschreibung: Liefert den Namen der Default-Gruppe ------------------------------------------------------------------------*/ String SwGlossaries::GetDefName() { return String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "standard" )); } /*------------------------------------------------------------------------ Beschreibung: Liefert die Anzahl der Textbausteingruppen ------------------------------------------------------------------------*/ sal_uInt16 SwGlossaries::GetGroupCnt() { return GetNameList()->Count(); } /*------------------------------------------------------------------------ Beschreibung: Liefert den Gruppennamen ------------------------------------------------------------------------*/ sal_Bool SwGlossaries::FindGroupName(String & rGroup) { // enthaelt der Gruppenname keinen Pfad, kann hier ein passender // Gruppeneintrag gesucht werden; sal_uInt16 nCount = GetGroupCnt(); sal_uInt16 i; for(i= 0; i < nCount; i++) { String sTemp(GetGroupName(i)); if(rGroup.Equals( sTemp.GetToken(0, GLOS_DELIM))) { rGroup = sTemp; return sal_True; } } //man darf zweimal suchen, denn bei mehreren Verzeichnissen koennte //der caseinsensitive Name mehrfach auftreten const ::utl::TransliterationWrapper& rSCmp = GetAppCmpStrIgnore(); for(i = 0; i < nCount; i++) { String sTemp( GetGroupName( i )); sal_uInt16 nPath = (sal_uInt16)sTemp.GetToken(1, GLOS_DELIM).ToInt32(); if( !SWUnoHelper::UCB_IsCaseSensitiveFileName( *(*m_pPathArr)[nPath] ) && rSCmp.isEqual( rGroup, sTemp.GetToken( 0, GLOS_DELIM) ) ) { rGroup = sTemp; return sal_True; } } return sal_False; } /* --------------------------------------------------------------------------- ---------------------------------------------------------------------------*/ String SwGlossaries::GetGroupName(sal_uInt16 nGroupId) { ASSERT(nGroupId < m_pGlosArr->Count(), Textbausteinarray ueberindiziert); return *(*m_pGlosArr)[nGroupId]; } /* -----------------------------08.02.00 13:04-------------------------------- ---------------------------------------------------------------------------*/ String SwGlossaries::GetGroupTitle( const String& rGroupName ) { String sRet; String sGroup(rGroupName); if(STRING_NOTFOUND == sGroup.Search(GLOS_DELIM)) FindGroupName(sGroup); SwTextBlocks* pGroup = GetGroupDoc(sGroup, sal_False); if(pGroup) { sRet = pGroup->GetName(); PutGroupDoc( pGroup ); } return sRet; } /*------------------------------------------------------------------------ Beschreibung: Liefert das Textbaustein-Dokument der Gruppe rName ------------------------------------------------------------------------*/ SwTextBlocks* SwGlossaries::GetGroupDoc(const String &rName, sal_Bool bCreate) const { // gfs. in die Liste der Textbausteine eintragen if(bCreate && m_pGlosArr) { const String aName(rName); const sal_uInt16 nCount = m_pGlosArr->Count(); sal_uInt16 i; for( i = 0; i < nCount; ++i) { const String *pName = (*m_pGlosArr)[i]; if(*pName == aName) break; } if(i == nCount) { // Baustein nicht in der Liste String *pTmp = new String(aName); m_pGlosArr->Insert(pTmp, m_pGlosArr->Count()); } } return GetGlosDoc( rName, bCreate ); } /*------------------------------------------------------------------------ Beschreibung: Loeschen Textblock ------------------------------------------------------------------------*/ void SwGlossaries::PutGroupDoc(SwTextBlocks *pBlock) { delete pBlock; } /*------------------------------------------------------------------------ Beschreibung: Erzeugt ein neues Dokument mit dem Gruppenname Wird temp. auch als File angelegt, damit die Gruppen auch spaeter (ohne Zugriff) vorhanden sind. ------------------------------------------------------------------------*/ sal_Bool SwGlossaries::NewGroupDoc(String& rGroupName, const String& rTitle) { sal_uInt16 nNewPath = (sal_uInt16)rGroupName.GetToken(1, GLOS_DELIM).ToInt32(); String sNewFilePath(*(*m_pPathArr)[nNewPath]); String sNewGroup = lcl_CheckFileName(sNewFilePath, rGroupName.GetToken(0, GLOS_DELIM)); sNewGroup += GLOS_DELIM; sNewGroup += rGroupName.GetToken(1, GLOS_DELIM); SwTextBlocks *pBlock = GetGlosDoc( sNewGroup ); if(pBlock) { String *pTmp = new String(sNewGroup); SvStrings* pList = GetNameList(); pList->Insert(pTmp, pList->Count()); pBlock->SetName(rTitle); PutGroupDoc(pBlock); rGroupName = sNewGroup; return sal_True; } return sal_False; } /* -----------------23.11.98 13:13------------------- * * --------------------------------------------------*/ sal_Bool SwGlossaries::RenameGroupDoc( const String& rOldGroup, String& rNewGroup, const String& rNewTitle ) { sal_Bool bRet = sal_False; sal_uInt16 nOldPath = (sal_uInt16)rOldGroup.GetToken(1, GLOS_DELIM).ToInt32(); if(nOldPath < m_pPathArr->Count()) { String sOldFileURL(*(*m_pPathArr)[nOldPath]); sOldFileURL += INET_PATH_TOKEN; sOldFileURL += rOldGroup.GetToken(0, GLOS_DELIM); sOldFileURL += SwGlossaries::GetExtension(); sal_Bool bExist = FStatHelper::IsDocument( sOldFileURL ); DBG_ASSERT(bExist, "Gruppe existiert nicht!"); if(bExist) { sal_uInt16 nNewPath = (sal_uInt16)rNewGroup.GetToken(1, GLOS_DELIM).ToInt32(); if( nNewPath < m_pPathArr->Count()) { String sNewFilePath(*(*m_pPathArr)[nNewPath]); String sNewFileName = lcl_CheckFileName( sNewFilePath, rNewGroup.GetToken(0, GLOS_DELIM)); //String aTmp( rNewGroup.GetToken(0, GLOS_DELIM)); const sal_uInt16 nFileNameLen = sNewFileName.Len(); sNewFileName += SwGlossaries::GetExtension(); String sTempNewFilePath(sNewFilePath); sTempNewFilePath += INET_PATH_TOKEN; sTempNewFilePath += sNewFileName ; bExist = FStatHelper::IsDocument( sTempNewFilePath ); DBG_ASSERT(!bExist, "Gruppe existiert bereits!"); if(!bExist) { sal_Bool bCopyCompleted = SWUnoHelper::UCB_CopyFile( sOldFileURL, sTempNewFilePath, sal_True ); if(bCopyCompleted) { bRet = sal_True; RemoveFileFromList( rOldGroup ); rNewGroup = sNewFileName.Copy(0, nFileNameLen); rNewGroup += GLOS_DELIM; rNewGroup += String::CreateFromInt32(nNewPath); String *pTmp = new String(rNewGroup); if(!m_pGlosArr) GetNameList(); else m_pGlosArr->Insert(pTmp, m_pGlosArr->Count()); sNewFilePath += INET_PATH_TOKEN; sNewFilePath += sNewFileName ; SwTextBlocks* pNewBlock = new SwTextBlocks( sNewFilePath ); pNewBlock->SetName(rNewTitle); delete pNewBlock; } } } } } return bRet; } /*------------------------------------------------------------------------ Beschreibung: Loescht eine Textbausteingruppe ------------------------------------------------------------------------*/ sal_Bool SwGlossaries::DelGroupDoc(const String &rName) { sal_uInt16 nPath = (sal_uInt16)rName.GetToken(1, GLOS_DELIM).ToInt32(); if(nPath >= m_pPathArr->Count()) return sal_False; String sFileURL(*(*m_pPathArr)[nPath]); String aTmp( rName.GetToken(0, GLOS_DELIM)); String aName(aTmp); aName += GLOS_DELIM; aName += String::CreateFromInt32(nPath); aTmp += SwGlossaries::GetExtension(); sFileURL += INET_PATH_TOKEN; sFileURL += aTmp; // Auch, wenn das File nicht existiert, muss es aus der Liste // der Textbausteinbereiche entfernt werden // Kein && wegen CFfront sal_Bool bRemoved = SWUnoHelper::UCB_DeleteFile( sFileURL ); DBG_ASSERT(bRemoved, "file has not been removed"); RemoveFileFromList( aName ); return bRemoved; } /*------------------------------------------------------------------------ Beschreibung: DTOR ------------------------------------------------------------------------*/ SwGlossaries::~SwGlossaries() { sal_uInt16 nCount = m_pGlosArr? m_pGlosArr->Count() : 0; sal_uInt16 i; for( i = 0; i < nCount; ++i) { String *pTmp = (*m_pGlosArr)[i]; delete pTmp; } nCount = m_pPathArr? m_pPathArr->Count() : 0; for(i = 0; i < nCount; ++i) { String *pTmp = (*m_pPathArr)[i]; delete pTmp; } delete m_pGlosArr; delete m_pPathArr; InvalidateUNOOjects(); } /*------------------------------------------------------------------------ Beschreibung: Bausteindokument einlesen ------------------------------------------------------------------------*/ SwTextBlocks* SwGlossaries::GetGlosDoc( const String &rName, sal_Bool bCreate ) const { sal_uInt16 nPath = (sal_uInt16)rName.GetToken(1, GLOS_DELIM).ToInt32(); SwTextBlocks *pTmp = 0; if(nPath < m_pPathArr->Count()) { String sFileURL(*(*m_pPathArr)[nPath]); String aTmp( rName.GetToken(0, GLOS_DELIM)); aTmp += SwGlossaries::GetExtension(); sFileURL += INET_PATH_TOKEN; sFileURL += aTmp; sal_Bool bExist = sal_False; if(!bCreate) bExist = FStatHelper::IsDocument( sFileURL ); if (bCreate || bExist) { pTmp = new SwTextBlocks( sFileURL ); sal_Bool bOk = sal_True; if( pTmp->GetError() ) { ErrorHandler::HandleError( pTmp->GetError() ); bOk = !IsError( pTmp->GetError() ); } if( bOk && !pTmp->GetName().Len() ) pTmp->SetName( rName ); } } return pTmp; } /*------------------------------------------------------------------------ Beschreibung: Zugriff auf die Liste der Name; diese wird gfs. eingelesen ------------------------------------------------------------------------*/ SvStrings* SwGlossaries::GetNameList() { if( !m_pGlosArr ) { m_pGlosArr = new SvStrings; String sExt( SwGlossaries::GetExtension() ); for( sal_uInt16 i = 0; i < m_pPathArr->Count(); i++ ) { SvStrings aFiles( 16, 16 ); SWUnoHelper::UCB_GetFileListOfFolder( *(*m_pPathArr)[i], aFiles, &sExt ); for( sal_uInt16 nFiles = 0, nFEnd = aFiles.Count(); nFiles < nFEnd; ++nFiles ) { String* pTitle = aFiles[ nFiles ]; String sName( pTitle->Copy( 0, pTitle->Len() - sExt.Len() )); sName += GLOS_DELIM; sName += String::CreateFromInt32( i ); m_pGlosArr->Insert( new String(sName), m_pGlosArr->Count() ); // don't need any more these pointers delete pTitle; } } if(!m_pGlosArr->Count()) { // Der Standard-Baustein steht im ersten Teil des Pfades String *pTmp = new String( SwGlossaries::GetDefName() ); (*pTmp) += GLOS_DELIM; (*pTmp) += '0'; m_pGlosArr->Insert(pTmp, m_pGlosArr->Count()); } } return m_pGlosArr; } /*------------------------------------------------------------------------ Beschreibung: CTOR ------------------------------------------------------------------------*/ SwGlossaries::SwGlossaries() : m_pPathArr(0), m_pGlosArr(0) { m_pPathArr = new SvStrings; UpdateGlosPath(sal_True); } /*------------------------------------------------------------------------ Beschreibung: Neuen Pfad einstellen und internes Array neu aufbauen ------------------------------------------------------------------------*/ /* -----------------21.01.99 15:36------------------- * #61050# Doppelte Pfade fuehren zu Verwirrung - als raus damit * --------------------------------------------------*/ sal_Bool lcl_FindSameEntry(const SvStrings& rDirArr, const String& rEntryURL) { for(sal_uInt16 i = 0; i < rDirArr.Count(); i++) if(rEntryURL == (*rDirArr.GetObject(i))) return sal_True; return sal_False; } void SwGlossaries::UpdateGlosPath(sal_Bool bFull) { SvtPathOptions aPathOpt; String aNewPath( aPathOpt.GetAutoTextPath() ); sal_Bool bPathChanged = m_aPath != aNewPath; if (bFull || bPathChanged) { m_aPath = aNewPath; sal_uInt16 nCount = m_pPathArr? m_pPathArr->Count() : 0; sal_uInt16 i; for( i = nCount; i; --i) { String *pTmp = (*m_pPathArr)[i - 1]; m_pPathArr->Remove(i - 1); delete pTmp; } sal_uInt16 nTokenCount = m_aPath.GetTokenCount(SVT_SEARCHPATH_DELIMITER); SvStrings aDirArr; for( i = 0; i < nTokenCount; i++ ) { String sPth(m_aPath.GetToken(i, SVT_SEARCHPATH_DELIMITER)); sPth = URIHelper::SmartRel2Abs( INetURLObject(), sPth, URIHelper::GetMaybeFileHdl()); if(i && lcl_FindSameEntry(aDirArr, sPth)) { continue; } aDirArr.Insert(new String(sPth), aDirArr.Count()); if( !FStatHelper::IsFolder( sPth ) ) { if( m_sErrPath.Len() ) m_sErrPath += SVT_SEARCHPATH_DELIMITER; INetURLObject aTemp( sPth ); m_sErrPath += String(aTemp.GetFull()); } else m_pPathArr->Insert(new String(sPth), m_pPathArr->Count()); } aDirArr.DeleteAndDestroy(0, aDirArr.Count()); if(!nTokenCount || (m_sErrPath.Len() && (bPathChanged || m_sOldErrPath != m_sErrPath)) ) { m_sOldErrPath = m_sErrPath; // Falscher Pfad, d.h. AutoText-Verzeichnis existiert nicht ErrorHandler::HandleError( *new StringErrorInfo( ERR_AUTOPATH_ERROR, m_sErrPath, ERRCODE_BUTTON_OK | ERRCODE_MSG_ERROR )); m_bError = sal_True; } else m_bError = sal_False; if(m_pGlosArr) { for(i = 0; i < m_pGlosArr->Count(); ++i) { delete (String *)(*m_pGlosArr)[i]; } DELETEZ(m_pGlosArr); GetNameList(); } } } /*------------------------------------------------------------------------ Beschreibung: ------------------------------------------------------------------------*/ void SwGlossaries::ShowError() { sal_uInt32 nPathError = *new StringErrorInfo(ERR_AUTOPATH_ERROR, m_sErrPath, ERRCODE_BUTTON_OK ); ErrorHandler::HandleError( nPathError ); } /* -----------------------------09.02.00 11:37-------------------------------- ---------------------------------------------------------------------------*/ String SwGlossaries::GetExtension() { return String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( ".bau" )); } void SwGlossaries::RemoveFileFromList( const String& rGroup ) { if(m_pGlosArr) { const sal_uInt16 nCount = m_pGlosArr->Count(); for(sal_uInt16 i = 0; i < nCount; ++i) { String *pTmp = (*m_pGlosArr)[i]; if(*pTmp == rGroup) { rtl::OUString aUName = rGroup; { // tell the UNO AutoTextGroup object that it's not valid anymore for ( UnoAutoTextGroups::iterator aLoop = m_aGlossaryGroups.begin(); aLoop != m_aGlossaryGroups.end(); ++aLoop ) { Reference< container::XNamed > xNamed( aLoop->get(), UNO_QUERY ); if ( xNamed.is() && ( xNamed->getName() == aUName ) ) { static_cast< SwXAutoTextGroup* >( xNamed.get() )->Invalidate(); // note that this static_cast works because we know that the array only // contains SwXAutoTextGroup implementation m_aGlossaryGroups.erase( aLoop ); break; } } } { // tell all our UNO AutoTextEntry objects that they're not valid anymore for ( UnoAutoTextEntries::iterator aLoop = m_aGlossaryEntries.begin(); aLoop != m_aGlossaryEntries.end(); ) { Reference< lang::XUnoTunnel > xEntryTunnel( aLoop->get(), UNO_QUERY ); SwXAutoTextEntry* pEntry = NULL; if ( xEntryTunnel.is() ) pEntry = reinterpret_cast< SwXAutoTextEntry* >( xEntryTunnel->getSomething( SwXAutoTextEntry::getUnoTunnelId() ) ); if ( pEntry && ( pEntry->GetGroupName() == rGroup ) ) { pEntry->Invalidate(); aLoop = m_aGlossaryEntries.erase( aLoop ); } else ++aLoop; } } m_pGlosArr->Remove(i); delete pTmp; break; } } } } String SwGlossaries::GetCompleteGroupName( const rtl::OUString& GroupName ) { sal_uInt16 nCount = GetGroupCnt(); //wenn der Gruppenname intern erzeugt wurde, dann steht auch hier der Pfad drin String sGroup(GroupName); String sGroupName(sGroup.GetToken(0, GLOS_DELIM)); String sPath = sGroup.GetToken(1, GLOS_DELIM); sal_Bool bPathLen = sPath.Len() > 0; for ( sal_uInt16 i = 0; i < nCount; i++ ) { String sGrpName = GetGroupName(i); if(bPathLen ? sGroup == sGrpName : sGroupName == sGrpName.GetToken(0, GLOS_DELIM)) { return sGrpName; } } return aEmptyStr; } void SwGlossaries::InvalidateUNOOjects() { // invalidate all the AutoTextGroup-objects for ( UnoAutoTextGroups::iterator aGroupLoop = m_aGlossaryGroups.begin(); aGroupLoop != m_aGlossaryGroups.end(); ++aGroupLoop ) { Reference< text::XAutoTextGroup > xGroup( aGroupLoop->get(), UNO_QUERY ); if ( xGroup.is() ) static_cast< SwXAutoTextGroup* >( xGroup.get() )->Invalidate(); } UnoAutoTextGroups aTmpg = UnoAutoTextGroups(); m_aGlossaryGroups.swap( aTmpg ); // invalidate all the AutoTextEntry-objects for ( UnoAutoTextEntries::const_iterator aEntryLoop = m_aGlossaryEntries.begin(); aEntryLoop != m_aGlossaryEntries.end(); ++aEntryLoop ) { Reference< lang::XUnoTunnel > xEntryTunnel( aEntryLoop->get(), UNO_QUERY ); SwXAutoTextEntry* pEntry = NULL; if ( xEntryTunnel.is() ) pEntry = reinterpret_cast< SwXAutoTextEntry* >( xEntryTunnel->getSomething( SwXAutoTextEntry::getUnoTunnelId() ) ); if ( pEntry ) pEntry->Invalidate(); } UnoAutoTextEntries aTmpe = UnoAutoTextEntries(); m_aGlossaryEntries.swap( aTmpe ); } //----------------------------------------------------------------------- //--- 03.03.2003 14:15:32 ----------------------------------------------- Reference< text::XAutoTextGroup > SwGlossaries::GetAutoTextGroup( const ::rtl::OUString& _rGroupName, bool _bCreate ) { // first, find the name with path-extension String sCompleteGroupName = GetCompleteGroupName( _rGroupName ); Reference< text::XAutoTextGroup > xGroup; // look up the group in the cache UnoAutoTextGroups::iterator aSearch = m_aGlossaryGroups.begin(); for ( ; aSearch != m_aGlossaryGroups.end(); ) { Reference< lang::XUnoTunnel > xGroupTunnel( aSearch->get(), UNO_QUERY ); SwXAutoTextGroup* pSwGroup = 0; if ( xGroupTunnel.is() ) pSwGroup = reinterpret_cast< SwXAutoTextGroup* >( xGroupTunnel->getSomething( SwXAutoTextGroup::getUnoTunnelId() ) ); if ( !pSwGroup ) { // the object is dead in the meantime -> remove from cache aSearch = m_aGlossaryGroups.erase( aSearch ); continue; } if ( _rGroupName == pSwGroup->getName() ) { // the group is already cached if ( sCompleteGroupName.Len() ) { // the group still exists -> return it xGroup = pSwGroup; break; } else { // this group does not exist (anymore) -> release the cached UNO object for it aSearch = m_aGlossaryGroups.erase( aSearch ); // so it won't be created below _bCreate = sal_False; break; } } ++aSearch; } if ( !xGroup.is() && _bCreate ) { xGroup = new SwXAutoTextGroup( sCompleteGroupName, this ); // cache it m_aGlossaryGroups.push_back( AutoTextGroupRef( xGroup ) ); } return xGroup; } //----------------------------------------------------------------------- //--- 03.03.2003 13:46:06 ----------------------------------------------- Reference< text::XAutoTextEntry > SwGlossaries::GetAutoTextEntry( const String& _rCompleteGroupName, const ::rtl::OUString& _rGroupName, const ::rtl::OUString& _rEntryName, bool _bCreate ) { //standard must be created sal_Bool bCreate = ( _rCompleteGroupName == GetDefName() ); ::std::auto_ptr< SwTextBlocks > pGlosGroup( GetGroupDoc( _rCompleteGroupName, bCreate ) ); if ( pGlosGroup.get() && !pGlosGroup->GetError() ) { sal_uInt16 nIdx = pGlosGroup->GetIndex( _rEntryName ); if ( USHRT_MAX == nIdx ) throw container::NoSuchElementException(); } else throw lang::WrappedTargetException(); Reference< text::XAutoTextEntry > xReturn; String sGroupName( _rGroupName ); String sEntryName( _rEntryName ); UnoAutoTextEntries::iterator aSearch( m_aGlossaryEntries.begin() ); for ( ; aSearch != m_aGlossaryEntries.end(); ) { Reference< lang::XUnoTunnel > xEntryTunnel( aSearch->get(), UNO_QUERY ); SwXAutoTextEntry* pEntry = NULL; if ( xEntryTunnel.is() ) pEntry = reinterpret_cast< SwXAutoTextEntry* >( xEntryTunnel->getSomething( SwXAutoTextEntry::getUnoTunnelId() ) ); else { // the object is dead in the meantime -> remove from cache aSearch = m_aGlossaryEntries.erase( aSearch ); continue; } if ( pEntry && ( COMPARE_EQUAL == pEntry->GetGroupName().CompareTo( sGroupName ) ) && ( COMPARE_EQUAL == pEntry->GetEntryName().CompareTo( sEntryName ) ) ) { xReturn = pEntry; break; } ++aSearch; } if ( !xReturn.is() && _bCreate ) { xReturn = new SwXAutoTextEntry( this, sGroupName, sEntryName ); // cache it m_aGlossaryEntries.push_back( AutoTextEntryRef( xReturn ) ); } return xReturn; }