1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_sw.hxx" 30 31 #include <memory> 32 33 #include <com/sun/star/container/XNamed.hpp> 34 35 #define _SVSTDARR_STRINGS 36 #include <unotools/transliterationwrapper.hxx> 37 38 #include <svl/svstdarr.hxx> 39 40 #ifndef __RSC //autogen 41 #include <tools/errinf.hxx> 42 #endif 43 #include <tools/debug.hxx> 44 #include <svl/urihelper.hxx> 45 #ifndef SVTOOLS_FSTATHELPER_HXX 46 #include <svl/fstathelper.hxx> 47 #endif 48 #include <unotools/pathoptions.hxx> 49 #include <unotools/tempfile.hxx> 50 #include <swtypes.hxx> 51 #include <errhdl.hxx> // ASSERT 52 #include <uitool.hxx> 53 #include <glosdoc.hxx> 54 #include <shellio.hxx> 55 #include <swunohelper.hxx> 56 57 #include <unoatxt.hxx> 58 #include <swerror.h> 59 #ifndef _GLOBALS_HRC 60 #include <globals.hrc> 61 #endif 62 63 using namespace ::com::sun::star; 64 using namespace ::com::sun::star::uno; 65 66 67 // PUBLIC METHODES ------------------------------------------------------- 68 /* -----------------------------08.02.00 15:54-------------------------------- 69 70 ---------------------------------------------------------------------------*/ 71 String lcl_CheckFileName( const String& rNewFilePath, 72 const String& rNewGroupName ) 73 { 74 String sRet; 75 //group name should contain only A-Z and a-z and spaces 76 for( xub_StrLen i = 0; i < rNewGroupName.Len(); i++ ) 77 { 78 sal_Unicode cChar = rNewGroupName.GetChar(i); 79 if( (cChar >= 'A' && cChar <= 'Z') || 80 (cChar >= 'a' && cChar <= 'z') || 81 (cChar >= '0' && cChar <= '9') || 82 cChar == '_' || cChar == 0x20 ) 83 { 84 sRet += cChar; 85 } 86 } 87 sRet.EraseLeadingChars(); 88 sRet.EraseTrailingChars(); 89 90 sal_Bool bOk = sal_False; 91 if( sRet.Len() ) 92 { 93 String sTmpDir(rNewFilePath); 94 sTmpDir += INET_PATH_TOKEN; 95 sTmpDir += sRet; 96 sTmpDir += SwGlossaries::GetExtension(); 97 bOk = !FStatHelper::IsDocument( sTmpDir ); 98 } 99 100 if( !bOk ) 101 { 102 String rSG = SwGlossaries::GetExtension(); 103 //generate generic name 104 utl::TempFile aTemp( 105 String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "group" )), 106 &rSG, &rNewFilePath ); 107 aTemp.EnableKillingFile(); 108 109 INetURLObject aTempURL( aTemp.GetURL() ); 110 sRet = aTempURL.GetBase(); 111 } 112 return sRet; 113 } 114 /*------------------------------------------------------------------------ 115 Beschreibung: Liefert den Namen der Default-Gruppe 116 ------------------------------------------------------------------------*/ 117 118 119 String SwGlossaries::GetDefName() 120 { 121 return String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "standard" )); 122 123 } 124 /*------------------------------------------------------------------------ 125 Beschreibung: Liefert die Anzahl der Textbausteingruppen 126 ------------------------------------------------------------------------*/ 127 128 129 sal_uInt16 SwGlossaries::GetGroupCnt() 130 { 131 return GetNameList()->Count(); 132 } 133 /*------------------------------------------------------------------------ 134 Beschreibung: Liefert den Gruppennamen 135 ------------------------------------------------------------------------*/ 136 sal_Bool SwGlossaries::FindGroupName(String & rGroup) 137 { 138 // enthaelt der Gruppenname keinen Pfad, kann hier ein passender 139 // Gruppeneintrag gesucht werden; 140 sal_uInt16 nCount = GetGroupCnt(); 141 sal_uInt16 i; 142 for(i= 0; i < nCount; i++) 143 { 144 String sTemp(GetGroupName(i)); 145 if(rGroup.Equals( sTemp.GetToken(0, GLOS_DELIM))) 146 { 147 rGroup = sTemp; 148 return sal_True; 149 } 150 } 151 //man darf zweimal suchen, denn bei mehreren Verzeichnissen koennte 152 //der caseinsensitive Name mehrfach auftreten 153 const ::utl::TransliterationWrapper& rSCmp = GetAppCmpStrIgnore(); 154 for(i = 0; i < nCount; i++) 155 { 156 String sTemp( GetGroupName( i )); 157 sal_uInt16 nPath = (sal_uInt16)sTemp.GetToken(1, GLOS_DELIM).ToInt32(); 158 159 if( !SWUnoHelper::UCB_IsCaseSensitiveFileName( *(*m_pPathArr)[nPath] ) 160 && rSCmp.isEqual( rGroup, sTemp.GetToken( 0, GLOS_DELIM) ) ) 161 { 162 rGroup = sTemp; 163 return sal_True; 164 } 165 } 166 return sal_False; 167 } 168 /* --------------------------------------------------------------------------- 169 170 ---------------------------------------------------------------------------*/ 171 172 String SwGlossaries::GetGroupName(sal_uInt16 nGroupId) 173 { 174 ASSERT(nGroupId < m_pGlosArr->Count(), Textbausteinarray ueberindiziert); 175 return *(*m_pGlosArr)[nGroupId]; 176 } 177 /* -----------------------------08.02.00 13:04-------------------------------- 178 179 ---------------------------------------------------------------------------*/ 180 String SwGlossaries::GetGroupTitle( const String& rGroupName ) 181 { 182 String sRet; 183 String sGroup(rGroupName); 184 if(STRING_NOTFOUND == sGroup.Search(GLOS_DELIM)) 185 FindGroupName(sGroup); 186 SwTextBlocks* pGroup = GetGroupDoc(sGroup, sal_False); 187 if(pGroup) 188 { 189 sRet = pGroup->GetName(); 190 PutGroupDoc( pGroup ); 191 } 192 return sRet; 193 } 194 195 /*------------------------------------------------------------------------ 196 Beschreibung: Liefert das Textbaustein-Dokument der Gruppe rName 197 ------------------------------------------------------------------------*/ 198 199 SwTextBlocks* SwGlossaries::GetGroupDoc(const String &rName, 200 sal_Bool bCreate) const 201 { 202 // gfs. in die Liste der Textbausteine eintragen 203 if(bCreate && m_pGlosArr) 204 { 205 const String aName(rName); 206 const sal_uInt16 nCount = m_pGlosArr->Count(); 207 sal_uInt16 i; 208 209 for( i = 0; i < nCount; ++i) 210 { 211 const String *pName = (*m_pGlosArr)[i]; 212 if(*pName == aName) 213 break; 214 } 215 if(i == nCount) 216 { // Baustein nicht in der Liste 217 String *pTmp = new String(aName); 218 m_pGlosArr->Insert(pTmp, m_pGlosArr->Count()); 219 } 220 } 221 return GetGlosDoc( rName, bCreate ); 222 } 223 224 /*------------------------------------------------------------------------ 225 Beschreibung: Loeschen Textblock 226 ------------------------------------------------------------------------*/ 227 228 void SwGlossaries::PutGroupDoc(SwTextBlocks *pBlock) { 229 delete pBlock; 230 } 231 /*------------------------------------------------------------------------ 232 Beschreibung: Erzeugt ein neues Dokument mit dem Gruppenname 233 Wird temp. auch als File angelegt, damit die 234 Gruppen auch spaeter (ohne Zugriff) vorhanden sind. 235 ------------------------------------------------------------------------*/ 236 237 238 sal_Bool SwGlossaries::NewGroupDoc(String& rGroupName, const String& rTitle) 239 { 240 sal_uInt16 nNewPath = (sal_uInt16)rGroupName.GetToken(1, GLOS_DELIM).ToInt32(); 241 String sNewFilePath(*(*m_pPathArr)[nNewPath]); 242 String sNewGroup = lcl_CheckFileName(sNewFilePath, rGroupName.GetToken(0, GLOS_DELIM)); 243 sNewGroup += GLOS_DELIM; 244 sNewGroup += rGroupName.GetToken(1, GLOS_DELIM); 245 SwTextBlocks *pBlock = GetGlosDoc( sNewGroup ); 246 if(pBlock) 247 { 248 String *pTmp = 249 new String(sNewGroup); 250 SvStrings* pList = GetNameList(); 251 pList->Insert(pTmp, pList->Count()); 252 pBlock->SetName(rTitle); 253 PutGroupDoc(pBlock); 254 rGroupName = sNewGroup; 255 return sal_True; 256 } 257 return sal_False; 258 } 259 /* -----------------23.11.98 13:13------------------- 260 * 261 * --------------------------------------------------*/ 262 sal_Bool SwGlossaries::RenameGroupDoc( 263 const String& rOldGroup, String& rNewGroup, const String& rNewTitle ) 264 { 265 sal_Bool bRet = sal_False; 266 sal_uInt16 nOldPath = (sal_uInt16)rOldGroup.GetToken(1, GLOS_DELIM).ToInt32(); 267 if(nOldPath < m_pPathArr->Count()) 268 { 269 String sOldFileURL(*(*m_pPathArr)[nOldPath]); 270 sOldFileURL += INET_PATH_TOKEN; 271 sOldFileURL += rOldGroup.GetToken(0, GLOS_DELIM); 272 sOldFileURL += SwGlossaries::GetExtension(); 273 sal_Bool bExist = FStatHelper::IsDocument( sOldFileURL ); 274 DBG_ASSERT(bExist, "Gruppe existiert nicht!"); 275 if(bExist) 276 { 277 sal_uInt16 nNewPath = (sal_uInt16)rNewGroup.GetToken(1, GLOS_DELIM).ToInt32(); 278 if( nNewPath < m_pPathArr->Count()) 279 { 280 String sNewFilePath(*(*m_pPathArr)[nNewPath]); 281 String sNewFileName = lcl_CheckFileName( 282 sNewFilePath, rNewGroup.GetToken(0, GLOS_DELIM)); 283 //String aTmp( rNewGroup.GetToken(0, GLOS_DELIM)); 284 const sal_uInt16 nFileNameLen = sNewFileName.Len(); 285 sNewFileName += SwGlossaries::GetExtension(); 286 String sTempNewFilePath(sNewFilePath); 287 sTempNewFilePath += INET_PATH_TOKEN; 288 sTempNewFilePath += sNewFileName ; 289 bExist = FStatHelper::IsDocument( sTempNewFilePath ); 290 DBG_ASSERT(!bExist, "Gruppe existiert bereits!"); 291 if(!bExist) 292 { 293 sal_Bool bCopyCompleted = SWUnoHelper::UCB_CopyFile( 294 sOldFileURL, sTempNewFilePath, sal_True ); 295 if(bCopyCompleted) 296 { 297 bRet = sal_True; 298 RemoveFileFromList( rOldGroup ); 299 300 rNewGroup = sNewFileName.Copy(0, nFileNameLen); 301 rNewGroup += GLOS_DELIM; 302 rNewGroup += String::CreateFromInt32(nNewPath); 303 String *pTmp = new String(rNewGroup); 304 if(!m_pGlosArr) 305 GetNameList(); 306 else 307 m_pGlosArr->Insert(pTmp, m_pGlosArr->Count()); 308 309 sNewFilePath += INET_PATH_TOKEN; 310 sNewFilePath += sNewFileName ; 311 SwTextBlocks* pNewBlock = new SwTextBlocks( sNewFilePath ); 312 pNewBlock->SetName(rNewTitle); 313 delete pNewBlock; 314 } 315 } 316 } 317 } 318 } 319 return bRet; 320 } 321 322 /*------------------------------------------------------------------------ 323 Beschreibung: Loescht eine Textbausteingruppe 324 ------------------------------------------------------------------------*/ 325 326 327 sal_Bool SwGlossaries::DelGroupDoc(const String &rName) 328 { 329 sal_uInt16 nPath = (sal_uInt16)rName.GetToken(1, GLOS_DELIM).ToInt32(); 330 if(nPath >= m_pPathArr->Count()) 331 return sal_False; 332 String sFileURL(*(*m_pPathArr)[nPath]); 333 String aTmp( rName.GetToken(0, GLOS_DELIM)); 334 String aName(aTmp); 335 aName += GLOS_DELIM; 336 aName += String::CreateFromInt32(nPath); 337 338 aTmp += SwGlossaries::GetExtension(); 339 sFileURL += INET_PATH_TOKEN; 340 sFileURL += aTmp; 341 // Auch, wenn das File nicht existiert, muss es aus der Liste 342 // der Textbausteinbereiche entfernt werden 343 // Kein && wegen CFfront 344 sal_Bool bRemoved = SWUnoHelper::UCB_DeleteFile( sFileURL ); 345 DBG_ASSERT(bRemoved, "file has not been removed"); 346 RemoveFileFromList( aName ); 347 return bRemoved; 348 } 349 /*------------------------------------------------------------------------ 350 Beschreibung: DTOR 351 ------------------------------------------------------------------------*/ 352 353 354 SwGlossaries::~SwGlossaries() 355 { 356 sal_uInt16 nCount = m_pGlosArr? m_pGlosArr->Count() : 0; 357 sal_uInt16 i; 358 359 for( i = 0; i < nCount; ++i) 360 { 361 String *pTmp = (*m_pGlosArr)[i]; 362 delete pTmp; 363 } 364 nCount = m_pPathArr? m_pPathArr->Count() : 0; 365 for(i = 0; i < nCount; ++i) 366 { 367 String *pTmp = (*m_pPathArr)[i]; 368 delete pTmp; 369 } 370 delete m_pGlosArr; 371 delete m_pPathArr; 372 373 InvalidateUNOOjects(); 374 } 375 /*------------------------------------------------------------------------ 376 Beschreibung: Bausteindokument einlesen 377 ------------------------------------------------------------------------*/ 378 379 380 SwTextBlocks* SwGlossaries::GetGlosDoc( const String &rName, sal_Bool bCreate ) const 381 { 382 sal_uInt16 nPath = (sal_uInt16)rName.GetToken(1, GLOS_DELIM).ToInt32(); 383 SwTextBlocks *pTmp = 0; 384 if(nPath < m_pPathArr->Count()) 385 { 386 String sFileURL(*(*m_pPathArr)[nPath]); 387 String aTmp( rName.GetToken(0, GLOS_DELIM)); 388 aTmp += SwGlossaries::GetExtension(); 389 sFileURL += INET_PATH_TOKEN; 390 sFileURL += aTmp; 391 392 sal_Bool bExist = sal_False; 393 if(!bCreate) 394 bExist = FStatHelper::IsDocument( sFileURL ); 395 396 if (bCreate || bExist) 397 { 398 pTmp = new SwTextBlocks( sFileURL ); 399 sal_Bool bOk = sal_True; 400 if( pTmp->GetError() ) 401 { 402 ErrorHandler::HandleError( pTmp->GetError() ); 403 bOk = !IsError( pTmp->GetError() ); 404 } 405 406 if( bOk && !pTmp->GetName().Len() ) 407 pTmp->SetName( rName ); 408 } 409 } 410 411 return pTmp; 412 } 413 414 /*------------------------------------------------------------------------ 415 Beschreibung: Zugriff auf die Liste der Name; diese wird gfs. eingelesen 416 ------------------------------------------------------------------------*/ 417 418 SvStrings* SwGlossaries::GetNameList() 419 { 420 if( !m_pGlosArr ) 421 { 422 m_pGlosArr = new SvStrings; 423 String sExt( SwGlossaries::GetExtension() ); 424 for( sal_uInt16 i = 0; i < m_pPathArr->Count(); i++ ) 425 { 426 SvStrings aFiles( 16, 16 ); 427 428 SWUnoHelper::UCB_GetFileListOfFolder( *(*m_pPathArr)[i], aFiles, 429 &sExt ); 430 for( sal_uInt16 nFiles = 0, nFEnd = aFiles.Count(); 431 nFiles < nFEnd; ++nFiles ) 432 { 433 String* pTitle = aFiles[ nFiles ]; 434 String sName( pTitle->Copy( 0, pTitle->Len() - sExt.Len() )); 435 sName += GLOS_DELIM; 436 sName += String::CreateFromInt32( i ); 437 m_pGlosArr->Insert( new String(sName), m_pGlosArr->Count() ); 438 439 // don't need any more these pointers 440 delete pTitle; 441 } 442 } 443 if(!m_pGlosArr->Count()) 444 { 445 // Der Standard-Baustein steht im ersten Teil des Pfades 446 String *pTmp = new String( SwGlossaries::GetDefName() ); 447 (*pTmp) += GLOS_DELIM; 448 (*pTmp) += '0'; 449 m_pGlosArr->Insert(pTmp, m_pGlosArr->Count()); 450 } 451 } 452 return m_pGlosArr; 453 } 454 455 /*------------------------------------------------------------------------ 456 Beschreibung: CTOR 457 ------------------------------------------------------------------------*/ 458 459 460 SwGlossaries::SwGlossaries() : 461 m_pPathArr(0), 462 m_pGlosArr(0) 463 { 464 m_pPathArr = new SvStrings; 465 UpdateGlosPath(sal_True); 466 } 467 468 /*------------------------------------------------------------------------ 469 Beschreibung: Neuen Pfad einstellen und internes Array neu aufbauen 470 ------------------------------------------------------------------------*/ 471 472 /* -----------------21.01.99 15:36------------------- 473 * #61050# Doppelte Pfade fuehren zu Verwirrung - als raus damit 474 * --------------------------------------------------*/ 475 sal_Bool lcl_FindSameEntry(const SvStrings& rDirArr, const String& rEntryURL) 476 { 477 for(sal_uInt16 i = 0; i < rDirArr.Count(); i++) 478 if(rEntryURL == (*rDirArr.GetObject(i))) 479 return sal_True; 480 return sal_False; 481 } 482 483 void SwGlossaries::UpdateGlosPath(sal_Bool bFull) 484 { 485 SvtPathOptions aPathOpt; 486 String aNewPath( aPathOpt.GetAutoTextPath() ); 487 sal_Bool bPathChanged = m_aPath != aNewPath; 488 if (bFull || bPathChanged) 489 { 490 m_aPath = aNewPath; 491 sal_uInt16 nCount = m_pPathArr? m_pPathArr->Count() : 0; 492 sal_uInt16 i; 493 494 for( i = nCount; i; --i) 495 { 496 String *pTmp = (*m_pPathArr)[i - 1]; 497 m_pPathArr->Remove(i - 1); 498 delete pTmp; 499 } 500 sal_uInt16 nTokenCount = m_aPath.GetTokenCount(SVT_SEARCHPATH_DELIMITER); 501 SvStrings aDirArr; 502 for( i = 0; i < nTokenCount; i++ ) 503 { 504 String sPth(m_aPath.GetToken(i, SVT_SEARCHPATH_DELIMITER)); 505 sPth = URIHelper::SmartRel2Abs( 506 INetURLObject(), sPth, URIHelper::GetMaybeFileHdl()); 507 508 if(i && lcl_FindSameEntry(aDirArr, sPth)) 509 { 510 continue; 511 } 512 aDirArr.Insert(new String(sPth), aDirArr.Count()); 513 if( !FStatHelper::IsFolder( sPth ) ) 514 { 515 if( m_sErrPath.Len() ) 516 m_sErrPath += SVT_SEARCHPATH_DELIMITER; 517 INetURLObject aTemp( sPth ); 518 m_sErrPath += String(aTemp.GetFull()); 519 } 520 else 521 m_pPathArr->Insert(new String(sPth), m_pPathArr->Count()); 522 } 523 aDirArr.DeleteAndDestroy(0, aDirArr.Count()); 524 525 if(!nTokenCount || 526 (m_sErrPath.Len() && (bPathChanged || m_sOldErrPath != m_sErrPath)) ) 527 { 528 m_sOldErrPath = m_sErrPath; 529 // Falscher Pfad, d.h. AutoText-Verzeichnis existiert nicht 530 531 ErrorHandler::HandleError( *new StringErrorInfo( 532 ERR_AUTOPATH_ERROR, m_sErrPath, 533 ERRCODE_BUTTON_OK | ERRCODE_MSG_ERROR )); 534 m_bError = sal_True; 535 } 536 else 537 m_bError = sal_False; 538 539 if(m_pGlosArr) 540 { 541 for(i = 0; i < m_pGlosArr->Count(); ++i) 542 { 543 delete (String *)(*m_pGlosArr)[i]; 544 } 545 DELETEZ(m_pGlosArr); 546 GetNameList(); 547 } 548 } 549 } 550 551 /*------------------------------------------------------------------------ 552 Beschreibung: 553 ------------------------------------------------------------------------*/ 554 555 556 void SwGlossaries::ShowError() 557 { 558 sal_uInt32 nPathError = *new StringErrorInfo(ERR_AUTOPATH_ERROR, 559 m_sErrPath, ERRCODE_BUTTON_OK ); 560 ErrorHandler::HandleError( nPathError ); 561 } 562 /* -----------------------------09.02.00 11:37-------------------------------- 563 564 ---------------------------------------------------------------------------*/ 565 String SwGlossaries::GetExtension() 566 { 567 return String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( ".bau" )); 568 } 569 570 571 572 void SwGlossaries::RemoveFileFromList( const String& rGroup ) 573 { 574 if(m_pGlosArr) 575 { 576 const sal_uInt16 nCount = m_pGlosArr->Count(); 577 for(sal_uInt16 i = 0; i < nCount; ++i) 578 { 579 String *pTmp = (*m_pGlosArr)[i]; 580 if(*pTmp == rGroup) 581 { 582 rtl::OUString aUName = rGroup; 583 { 584 // tell the UNO AutoTextGroup object that it's not valid anymore 585 for ( UnoAutoTextGroups::iterator aLoop = m_aGlossaryGroups.begin(); 586 aLoop != m_aGlossaryGroups.end(); 587 ++aLoop 588 ) 589 { 590 Reference< container::XNamed > xNamed( aLoop->get(), UNO_QUERY ); 591 if ( xNamed.is() && ( xNamed->getName() == aUName ) ) 592 { 593 static_cast< SwXAutoTextGroup* >( xNamed.get() )->Invalidate(); 594 // note that this static_cast works because we know that the array only 595 // contains SwXAutoTextGroup implementation 596 m_aGlossaryGroups.erase( aLoop ); 597 break; 598 } 599 } 600 } 601 602 { 603 // tell all our UNO AutoTextEntry objects that they're not valid anymore 604 for ( UnoAutoTextEntries::iterator aLoop = m_aGlossaryEntries.begin(); 605 aLoop != m_aGlossaryEntries.end(); 606 ) 607 { 608 Reference< lang::XUnoTunnel > xEntryTunnel( aLoop->get(), UNO_QUERY ); 609 610 SwXAutoTextEntry* pEntry = NULL; 611 if ( xEntryTunnel.is() ) 612 pEntry = reinterpret_cast< SwXAutoTextEntry* >( 613 xEntryTunnel->getSomething( SwXAutoTextEntry::getUnoTunnelId() ) ); 614 615 if ( pEntry && ( pEntry->GetGroupName() == rGroup ) ) 616 { 617 pEntry->Invalidate(); 618 aLoop = m_aGlossaryEntries.erase( aLoop ); 619 } 620 else 621 ++aLoop; 622 } 623 } 624 625 m_pGlosArr->Remove(i); 626 delete pTmp; 627 break; 628 } 629 } 630 } 631 } 632 633 634 String SwGlossaries::GetCompleteGroupName( const rtl::OUString& GroupName ) 635 { 636 sal_uInt16 nCount = GetGroupCnt(); 637 //wenn der Gruppenname intern erzeugt wurde, dann steht auch hier der Pfad drin 638 String sGroup(GroupName); 639 String sGroupName(sGroup.GetToken(0, GLOS_DELIM)); 640 String sPath = sGroup.GetToken(1, GLOS_DELIM); 641 sal_Bool bPathLen = sPath.Len() > 0; 642 for ( sal_uInt16 i = 0; i < nCount; i++ ) 643 { 644 String sGrpName = GetGroupName(i); 645 if(bPathLen ? sGroup == sGrpName : sGroupName == sGrpName.GetToken(0, GLOS_DELIM)) 646 { 647 return sGrpName; 648 } 649 } 650 return aEmptyStr; 651 } 652 653 654 void SwGlossaries::InvalidateUNOOjects() 655 { 656 // invalidate all the AutoTextGroup-objects 657 for ( UnoAutoTextGroups::iterator aGroupLoop = m_aGlossaryGroups.begin(); 658 aGroupLoop != m_aGlossaryGroups.end(); 659 ++aGroupLoop 660 ) 661 { 662 Reference< text::XAutoTextGroup > xGroup( aGroupLoop->get(), UNO_QUERY ); 663 if ( xGroup.is() ) 664 static_cast< SwXAutoTextGroup* >( xGroup.get() )->Invalidate(); 665 } 666 UnoAutoTextGroups aTmpg = UnoAutoTextGroups(); 667 m_aGlossaryGroups.swap( aTmpg ); 668 669 // invalidate all the AutoTextEntry-objects 670 for ( UnoAutoTextEntries::const_iterator aEntryLoop = m_aGlossaryEntries.begin(); 671 aEntryLoop != m_aGlossaryEntries.end(); 672 ++aEntryLoop 673 ) 674 { 675 Reference< lang::XUnoTunnel > xEntryTunnel( aEntryLoop->get(), UNO_QUERY ); 676 SwXAutoTextEntry* pEntry = NULL; 677 if ( xEntryTunnel.is() ) 678 pEntry = reinterpret_cast< SwXAutoTextEntry* >( 679 xEntryTunnel->getSomething( SwXAutoTextEntry::getUnoTunnelId() ) ); 680 681 if ( pEntry ) 682 pEntry->Invalidate(); 683 } 684 UnoAutoTextEntries aTmpe = UnoAutoTextEntries(); 685 m_aGlossaryEntries.swap( aTmpe ); 686 } 687 688 //----------------------------------------------------------------------- 689 //--- 03.03.2003 14:15:32 ----------------------------------------------- 690 691 Reference< text::XAutoTextGroup > SwGlossaries::GetAutoTextGroup( const ::rtl::OUString& _rGroupName, bool _bCreate ) 692 { 693 // first, find the name with path-extension 694 String sCompleteGroupName = GetCompleteGroupName( _rGroupName ); 695 696 Reference< text::XAutoTextGroup > xGroup; 697 698 // look up the group in the cache 699 UnoAutoTextGroups::iterator aSearch = m_aGlossaryGroups.begin(); 700 for ( ; aSearch != m_aGlossaryGroups.end(); ) 701 { 702 Reference< lang::XUnoTunnel > xGroupTunnel( aSearch->get(), UNO_QUERY ); 703 704 SwXAutoTextGroup* pSwGroup = 0; 705 if ( xGroupTunnel.is() ) 706 pSwGroup = reinterpret_cast< SwXAutoTextGroup* >( xGroupTunnel->getSomething( SwXAutoTextGroup::getUnoTunnelId() ) ); 707 708 if ( !pSwGroup ) 709 { 710 // the object is dead in the meantime -> remove from cache 711 aSearch = m_aGlossaryGroups.erase( aSearch ); 712 continue; 713 } 714 715 if ( _rGroupName == pSwGroup->getName() ) 716 { // the group is already cached 717 if ( sCompleteGroupName.Len() ) 718 { // the group still exists -> return it 719 xGroup = pSwGroup; 720 break; 721 } 722 else 723 { 724 // this group does not exist (anymore) -> release the cached UNO object for it 725 aSearch = m_aGlossaryGroups.erase( aSearch ); 726 // so it won't be created below 727 _bCreate = sal_False; 728 break; 729 } 730 } 731 732 ++aSearch; 733 } 734 735 if ( !xGroup.is() && _bCreate ) 736 { 737 xGroup = new SwXAutoTextGroup( sCompleteGroupName, this ); 738 // cache it 739 m_aGlossaryGroups.push_back( AutoTextGroupRef( xGroup ) ); 740 } 741 742 return xGroup; 743 } 744 745 //----------------------------------------------------------------------- 746 //--- 03.03.2003 13:46:06 ----------------------------------------------- 747 748 Reference< text::XAutoTextEntry > SwGlossaries::GetAutoTextEntry( const String& _rCompleteGroupName, const ::rtl::OUString& _rGroupName, const ::rtl::OUString& _rEntryName, 749 bool _bCreate ) 750 { 751 //standard must be created 752 sal_Bool bCreate = ( _rCompleteGroupName == GetDefName() ); 753 ::std::auto_ptr< SwTextBlocks > pGlosGroup( GetGroupDoc( _rCompleteGroupName, bCreate ) ); 754 755 if ( pGlosGroup.get() && !pGlosGroup->GetError() ) 756 { 757 sal_uInt16 nIdx = pGlosGroup->GetIndex( _rEntryName ); 758 if ( USHRT_MAX == nIdx ) 759 throw container::NoSuchElementException(); 760 } 761 else 762 throw lang::WrappedTargetException(); 763 764 Reference< text::XAutoTextEntry > xReturn; 765 String sGroupName( _rGroupName ); 766 String sEntryName( _rEntryName ); 767 768 UnoAutoTextEntries::iterator aSearch( m_aGlossaryEntries.begin() ); 769 for ( ; aSearch != m_aGlossaryEntries.end(); ) 770 { 771 Reference< lang::XUnoTunnel > xEntryTunnel( aSearch->get(), UNO_QUERY ); 772 773 SwXAutoTextEntry* pEntry = NULL; 774 if ( xEntryTunnel.is() ) 775 pEntry = reinterpret_cast< SwXAutoTextEntry* >( xEntryTunnel->getSomething( SwXAutoTextEntry::getUnoTunnelId() ) ); 776 else 777 { 778 // the object is dead in the meantime -> remove from cache 779 aSearch = m_aGlossaryEntries.erase( aSearch ); 780 continue; 781 } 782 783 if ( pEntry 784 && ( COMPARE_EQUAL == pEntry->GetGroupName().CompareTo( sGroupName ) ) 785 && ( COMPARE_EQUAL == pEntry->GetEntryName().CompareTo( sEntryName ) ) 786 ) 787 { 788 xReturn = pEntry; 789 break; 790 } 791 792 ++aSearch; 793 } 794 795 if ( !xReturn.is() && _bCreate ) 796 { 797 xReturn = new SwXAutoTextEntry( this, sGroupName, sEntryName ); 798 // cache it 799 m_aGlossaryEntries.push_back( AutoTextEntryRef( xReturn ) ); 800 } 801 802 return xReturn; 803 } 804 805 806 807