Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 :
21 : #include <memory>
22 :
23 : #include <com/sun/star/container/XNamed.hpp>
24 :
25 : #include <unotools/transliterationwrapper.hxx>
26 :
27 :
28 : #ifndef __RSC //autogen
29 : #include <tools/errinf.hxx>
30 : #endif
31 : #include <osl/diagnose.h>
32 : #include <svl/urihelper.hxx>
33 : #include <svl/fstathelper.hxx>
34 : #include <unotools/pathoptions.hxx>
35 : #include <unotools/tempfile.hxx>
36 : #include <comphelper/string.hxx>
37 : #include <swtypes.hxx>
38 : #include <uitool.hxx>
39 : #include <glosdoc.hxx>
40 : #include <shellio.hxx>
41 : #include <swunohelper.hxx>
42 :
43 : #include <unoatxt.hxx>
44 : #include <swerror.h>
45 : #include <globals.hrc>
46 :
47 : using namespace ::com::sun::star;
48 : using namespace ::com::sun::star::uno;
49 :
50 : // PUBLIC METHODES -------------------------------------------------------
51 0 : static String lcl_CheckFileName( const String& rNewFilePath,
52 : const String& rNewGroupName )
53 : {
54 0 : String sRet;
55 : //group name should contain only A-Z and a-z and spaces
56 0 : for( xub_StrLen i = 0; i < rNewGroupName.Len(); i++ )
57 : {
58 0 : sal_Unicode cChar = rNewGroupName.GetChar(i);
59 0 : if (comphelper::string::isalnumAscii(cChar) ||
60 : cChar == '_' || cChar == 0x20)
61 : {
62 0 : sRet += cChar;
63 : }
64 : }
65 0 : sRet = comphelper::string::strip(sRet, ' ');
66 :
67 0 : sal_Bool bOk = sal_False;
68 0 : if( sRet.Len() )
69 : {
70 0 : String sTmpDir(rNewFilePath);
71 0 : sTmpDir += INET_PATH_TOKEN;
72 0 : sTmpDir += sRet;
73 0 : sTmpDir += SwGlossaries::GetExtension();
74 0 : bOk = !FStatHelper::IsDocument( sTmpDir );
75 : }
76 :
77 0 : if( !bOk )
78 : {
79 0 : String rSG = SwGlossaries::GetExtension();
80 : //generate generic name
81 : utl::TempFile aTemp(rtl::OUString("group"),
82 0 : &rSG, &rNewFilePath );
83 0 : aTemp.EnableKillingFile();
84 :
85 0 : INetURLObject aTempURL( aTemp.GetURL() );
86 0 : sRet = aTempURL.GetBase();
87 : }
88 0 : return sRet;
89 : }
90 :
91 : /*------------------------------------------------------------------------
92 : Description: supplies the default group's name
93 : ------------------------------------------------------------------------*/
94 0 : String SwGlossaries::GetDefName()
95 : {
96 0 : return rtl::OUString("standard");
97 :
98 : }
99 :
100 : /*------------------------------------------------------------------------
101 : Description: supplies the number of text block groups
102 : ------------------------------------------------------------------------*/
103 0 : sal_uInt16 SwGlossaries::GetGroupCnt()
104 : {
105 0 : return static_cast<sal_uInt16>(GetNameList().size());
106 : }
107 :
108 : /*------------------------------------------------------------------------
109 : Description: supplies the group's name
110 : ------------------------------------------------------------------------*/
111 0 : sal_Bool SwGlossaries::FindGroupName(String & rGroup)
112 : {
113 : // if the group name doesn't contain a path, a suitable group entry
114 : // can the searched for here;
115 0 : sal_uInt16 nCount = GetGroupCnt();
116 : sal_uInt16 i;
117 0 : for(i= 0; i < nCount; i++)
118 : {
119 0 : String sTemp(GetGroupName(i));
120 0 : if(rGroup.Equals( sTemp.GetToken(0, GLOS_DELIM)))
121 : {
122 0 : rGroup = sTemp;
123 0 : return sal_True;
124 : }
125 0 : }
126 : // you can search two times because for more directories the case sensitive
127 : // name could occur multiple times
128 0 : const ::utl::TransliterationWrapper& rSCmp = GetAppCmpStrIgnore();
129 0 : for(i = 0; i < nCount; i++)
130 : {
131 0 : String sTemp( GetGroupName( i ));
132 0 : sal_uInt16 nPath = (sal_uInt16)sTemp.GetToken(1, GLOS_DELIM).ToInt32();
133 :
134 0 : if (!SWUnoHelper::UCB_IsCaseSensitiveFileName( m_PathArr[nPath] )
135 0 : && rSCmp.isEqual( rGroup, sTemp.GetToken( 0, GLOS_DELIM) ) )
136 : {
137 0 : rGroup = sTemp;
138 0 : return sal_True;
139 : }
140 0 : }
141 0 : return sal_False;
142 : }
143 :
144 0 : String SwGlossaries::GetGroupName(sal_uInt16 nGroupId)
145 : {
146 : OSL_ENSURE(static_cast<size_t>(nGroupId) < m_GlosArr.size(),
147 : "SwGlossaries::GetGroupName: index out of bounds");
148 0 : return m_GlosArr[nGroupId];
149 : }
150 :
151 0 : String SwGlossaries::GetGroupTitle( const String& rGroupName )
152 : {
153 0 : String sRet;
154 0 : String sGroup(rGroupName);
155 0 : if(STRING_NOTFOUND == sGroup.Search(GLOS_DELIM))
156 0 : FindGroupName(sGroup);
157 0 : SwTextBlocks* pGroup = GetGroupDoc(sGroup, sal_False);
158 0 : if(pGroup)
159 : {
160 0 : sRet = pGroup->GetName();
161 0 : PutGroupDoc( pGroup );
162 : }
163 0 : return sRet;
164 : }
165 :
166 : /*------------------------------------------------------------------------
167 : Description: supplies the group rName's text block document
168 : ------------------------------------------------------------------------*/
169 0 : SwTextBlocks* SwGlossaries::GetGroupDoc(const String &rName,
170 : sal_Bool bCreate)
171 : {
172 : // insert to the list of text blocks if applicable
173 0 : if(bCreate && !m_GlosArr.empty())
174 : {
175 0 : std::vector<String>::const_iterator it(m_GlosArr.begin());
176 0 : for (; it != m_GlosArr.end(); ++it)
177 : {
178 0 : if (*it == rName)
179 0 : break;
180 : }
181 0 : if (it == m_GlosArr.end())
182 : { // block not in the list
183 0 : m_GlosArr.push_back(rName);
184 : }
185 : }
186 0 : return GetGlosDoc( rName, bCreate );
187 : }
188 :
189 : /*------------------------------------------------------------------------
190 : Description: delete a text block
191 : ------------------------------------------------------------------------*/
192 0 : void SwGlossaries::PutGroupDoc(SwTextBlocks *pBlock) {
193 0 : delete pBlock;
194 0 : }
195 :
196 : /*------------------------------------------------------------------------
197 : Description: Creates a new document with the group name. temporarly
198 : also created as file so that groups remain there later
199 : (without access).
200 : ------------------------------------------------------------------------*/
201 0 : sal_Bool SwGlossaries::NewGroupDoc(String& rGroupName, const String& rTitle)
202 : {
203 0 : sal_uInt16 nNewPath = (sal_uInt16)rGroupName.GetToken(1, GLOS_DELIM).ToInt32();
204 0 : if (static_cast<size_t>(nNewPath) >= m_PathArr.size())
205 0 : return sal_False;
206 0 : String sNewFilePath(m_PathArr[nNewPath]);
207 0 : String sNewGroup = lcl_CheckFileName(sNewFilePath, rGroupName.GetToken(0, GLOS_DELIM));
208 0 : sNewGroup += GLOS_DELIM;
209 0 : sNewGroup += rGroupName.GetToken(1, GLOS_DELIM);
210 0 : SwTextBlocks *pBlock = GetGlosDoc( sNewGroup );
211 0 : if(pBlock)
212 : {
213 0 : GetNameList().push_back(sNewGroup);
214 0 : pBlock->SetName(rTitle);
215 0 : PutGroupDoc(pBlock);
216 0 : rGroupName = sNewGroup;
217 0 : return sal_True;
218 : }
219 0 : return sal_False;
220 : }
221 :
222 0 : sal_Bool SwGlossaries::RenameGroupDoc(
223 : const String& rOldGroup, String& rNewGroup, const String& rNewTitle )
224 : {
225 0 : sal_Bool bRet = sal_False;
226 0 : sal_uInt16 nOldPath = (sal_uInt16)rOldGroup.GetToken(1, GLOS_DELIM).ToInt32();
227 0 : if (static_cast<size_t>(nOldPath) < m_PathArr.size())
228 : {
229 0 : String sOldFileURL(m_PathArr[nOldPath]);
230 0 : sOldFileURL += INET_PATH_TOKEN;
231 0 : sOldFileURL += rOldGroup.GetToken(0, GLOS_DELIM);
232 0 : sOldFileURL += SwGlossaries::GetExtension();
233 0 : sal_Bool bExist = FStatHelper::IsDocument( sOldFileURL );
234 : OSL_ENSURE(bExist, "group doesn't exist!");
235 0 : if(bExist)
236 : {
237 0 : sal_uInt16 nNewPath = (sal_uInt16)rNewGroup.GetToken(1, GLOS_DELIM).ToInt32();
238 0 : if (static_cast<size_t>(nNewPath) < m_PathArr.size())
239 : {
240 0 : String sNewFilePath(m_PathArr[nNewPath]);
241 : String sNewFileName = lcl_CheckFileName(
242 0 : sNewFilePath, rNewGroup.GetToken(0, GLOS_DELIM));
243 0 : const sal_uInt16 nFileNameLen = sNewFileName.Len();
244 0 : sNewFileName += SwGlossaries::GetExtension();
245 0 : String sTempNewFilePath(sNewFilePath);
246 0 : sTempNewFilePath += INET_PATH_TOKEN;
247 0 : sTempNewFilePath += sNewFileName ;
248 0 : bExist = FStatHelper::IsDocument( sTempNewFilePath );
249 : OSL_ENSURE(!bExist, "group already exists!");
250 0 : if(!bExist)
251 : {
252 : sal_Bool bCopyCompleted = SWUnoHelper::UCB_CopyFile(
253 0 : sOldFileURL, sTempNewFilePath, sal_True );
254 0 : if(bCopyCompleted)
255 : {
256 0 : bRet = sal_True;
257 0 : RemoveFileFromList( rOldGroup );
258 :
259 0 : rNewGroup = sNewFileName.Copy(0, nFileNameLen);
260 0 : rNewGroup += GLOS_DELIM;
261 0 : rNewGroup += String::CreateFromInt32(nNewPath);
262 0 : if (m_GlosArr.empty())
263 : {
264 0 : GetNameList();
265 : }
266 : else
267 : {
268 0 : m_GlosArr.push_back(rNewGroup);
269 : }
270 :
271 0 : sNewFilePath += INET_PATH_TOKEN;
272 0 : sNewFilePath += sNewFileName ;
273 0 : SwTextBlocks* pNewBlock = new SwTextBlocks( sNewFilePath );
274 0 : pNewBlock->SetName(rNewTitle);
275 0 : delete pNewBlock;
276 : }
277 0 : }
278 : }
279 0 : }
280 : }
281 0 : return bRet;
282 : }
283 :
284 : /*------------------------------------------------------------------------
285 : Description: Deletes a text block group
286 : ------------------------------------------------------------------------*/
287 0 : sal_Bool SwGlossaries::DelGroupDoc(const String &rName)
288 : {
289 0 : sal_uInt16 nPath = (sal_uInt16)rName.GetToken(1, GLOS_DELIM).ToInt32();
290 0 : if (static_cast<size_t>(nPath) >= m_PathArr.size())
291 0 : return sal_False;
292 0 : String sFileURL(m_PathArr[nPath]);
293 0 : String aTmp( rName.GetToken(0, GLOS_DELIM));
294 0 : String aName(aTmp);
295 0 : aName += GLOS_DELIM;
296 0 : aName += String::CreateFromInt32(nPath);
297 :
298 0 : aTmp += SwGlossaries::GetExtension();
299 0 : sFileURL += INET_PATH_TOKEN;
300 0 : sFileURL += aTmp;
301 : // Even if the file doesn't exist it hast to be deleted from
302 : // the list of text block regions
303 : // no && because of CFfront
304 0 : sal_Bool bRemoved = SWUnoHelper::UCB_DeleteFile( sFileURL );
305 : OSL_ENSURE(bRemoved, "file has not been removed");
306 0 : RemoveFileFromList( aName );
307 0 : return bRemoved;
308 : }
309 :
310 0 : SwGlossaries::~SwGlossaries()
311 : {
312 0 : InvalidateUNOOjects();
313 0 : }
314 :
315 : /*------------------------------------------------------------------------
316 : Description: read a block document
317 : ------------------------------------------------------------------------*/
318 0 : SwTextBlocks* SwGlossaries::GetGlosDoc( const String &rName, sal_Bool bCreate ) const
319 : {
320 0 : sal_uInt16 nPath = (sal_uInt16)rName.GetToken(1, GLOS_DELIM).ToInt32();
321 0 : SwTextBlocks *pTmp = 0;
322 0 : if (static_cast<size_t>(nPath) < m_PathArr.size())
323 : {
324 0 : String sFileURL(m_PathArr[nPath]);
325 0 : String aTmp( rName.GetToken(0, GLOS_DELIM));
326 0 : aTmp += SwGlossaries::GetExtension();
327 0 : sFileURL += INET_PATH_TOKEN;
328 0 : sFileURL += aTmp;
329 :
330 0 : sal_Bool bExist = sal_False;
331 0 : if(!bCreate)
332 0 : bExist = FStatHelper::IsDocument( sFileURL );
333 :
334 0 : if (bCreate || bExist)
335 : {
336 0 : pTmp = new SwTextBlocks( sFileURL );
337 0 : sal_Bool bOk = sal_True;
338 0 : if( pTmp->GetError() )
339 : {
340 0 : ErrorHandler::HandleError( pTmp->GetError() );
341 0 : bOk = !IsError( pTmp->GetError() );
342 : }
343 :
344 0 : if( bOk && !pTmp->GetName().Len() )
345 0 : pTmp->SetName( rName );
346 0 : }
347 : }
348 :
349 0 : return pTmp;
350 : }
351 :
352 : /*------------------------------------------------------------------------
353 : Description: access to the list of names; read in if applicable
354 : ------------------------------------------------------------------------*/
355 0 : std::vector<String> & SwGlossaries::GetNameList()
356 : {
357 0 : if (m_GlosArr.empty())
358 : {
359 0 : String sExt( SwGlossaries::GetExtension() );
360 0 : for (size_t i = 0; i < m_PathArr.size(); ++i)
361 : {
362 0 : std::vector<String*> aFiles;
363 :
364 0 : SWUnoHelper::UCB_GetFileListOfFolder(m_PathArr[i], aFiles, &sExt);
365 0 : for( std::vector<String*>::const_iterator filesIt(aFiles.begin());
366 0 : filesIt != aFiles.end(); ++filesIt)
367 : {
368 0 : String *pTitle = *filesIt;
369 0 : String sName( pTitle->Copy( 0, pTitle->Len() - sExt.Len() ));
370 0 : sName += GLOS_DELIM;
371 0 : sName += String::CreateFromInt32( static_cast<sal_Int16>(i) );
372 0 : m_GlosArr.push_back(sName);
373 :
374 : // don't need any more these pointers
375 0 : delete pTitle;
376 0 : }
377 0 : }
378 0 : if (m_GlosArr.empty())
379 : {
380 : // the standard block is inside of the path's first part
381 0 : String tmp( SwGlossaries::GetDefName() );
382 0 : tmp += GLOS_DELIM;
383 0 : tmp += '0';
384 0 : m_GlosArr.push_back( tmp );
385 0 : }
386 : }
387 0 : return m_GlosArr;
388 : }
389 :
390 0 : SwGlossaries::SwGlossaries()
391 : {
392 0 : UpdateGlosPath(sal_True);
393 0 : }
394 :
395 : /*------------------------------------------------------------------------
396 : Description: set new path and recreate internal array
397 : ------------------------------------------------------------------------*/
398 :
399 : /* --------------------------------------------------
400 : * #61050# double paths cause irritation - get rid of it
401 : * --------------------------------------------------*/
402 0 : static sal_Bool lcl_FindSameEntry(const std::vector<String*>& rDirArr, const String& rEntryURL)
403 : {
404 0 : for(std::vector<String*>::const_iterator it(rDirArr.begin()); it != rDirArr.end(); ++it)
405 0 : if( **it == rEntryURL )
406 0 : return sal_True;
407 0 : return sal_False;
408 : }
409 :
410 0 : void SwGlossaries::UpdateGlosPath(sal_Bool bFull)
411 : {
412 0 : SvtPathOptions aPathOpt;
413 0 : String aNewPath( aPathOpt.GetAutoTextPath() );
414 0 : sal_Bool bPathChanged = m_aPath != aNewPath;
415 0 : if (bFull || bPathChanged)
416 : {
417 0 : m_aPath = aNewPath;
418 :
419 0 : m_PathArr.clear();
420 :
421 0 : sal_uInt16 nTokenCount = comphelper::string::getTokenCount(m_aPath, SVT_SEARCHPATH_DELIMITER);
422 0 : std::vector<String*> aDirArr;
423 0 : for( sal_uInt16 i = 0; i < nTokenCount; i++ )
424 : {
425 0 : String sPth(m_aPath.GetToken(i, SVT_SEARCHPATH_DELIMITER));
426 : sPth = URIHelper::SmartRel2Abs(
427 0 : INetURLObject(), sPth, URIHelper::GetMaybeFileHdl());
428 :
429 0 : if(i && lcl_FindSameEntry(aDirArr, sPth))
430 : {
431 0 : continue;
432 : }
433 0 : aDirArr.push_back(new String(sPth));
434 0 : if( !FStatHelper::IsFolder( sPth ) )
435 : {
436 0 : if( m_sErrPath.Len() )
437 0 : m_sErrPath += SVT_SEARCHPATH_DELIMITER;
438 0 : INetURLObject aTemp( sPth );
439 0 : m_sErrPath += String(aTemp.GetFull());
440 : }
441 : else
442 0 : m_PathArr.push_back(sPth);
443 0 : }
444 0 : for(std::vector<String*>::const_iterator it(aDirArr.begin()); it != aDirArr.end(); ++it)
445 0 : delete *it;
446 :
447 0 : if(!nTokenCount ||
448 0 : (m_sErrPath.Len() && (bPathChanged || m_sOldErrPath != m_sErrPath)) )
449 : {
450 0 : m_sOldErrPath = m_sErrPath;
451 : // wrong path, that means AutoText directory doesn't exist
452 :
453 : ErrorHandler::HandleError( *new StringErrorInfo(
454 : ERR_AUTOPATH_ERROR, m_sErrPath,
455 0 : ERRCODE_BUTTON_OK | ERRCODE_MSG_ERROR ));
456 0 : m_bError = sal_True;
457 : }
458 : else
459 0 : m_bError = sal_False;
460 :
461 0 : if (!m_GlosArr.empty())
462 : {
463 0 : m_GlosArr.clear();
464 0 : GetNameList();
465 0 : }
466 0 : }
467 0 : }
468 :
469 0 : void SwGlossaries::ShowError()
470 : {
471 : sal_uInt32 nPathError = *new StringErrorInfo(ERR_AUTOPATH_ERROR,
472 0 : m_sErrPath, ERRCODE_BUTTON_OK );
473 0 : ErrorHandler::HandleError( nPathError );
474 0 : }
475 :
476 0 : String SwGlossaries::GetExtension()
477 : {
478 0 : return rtl::OUString(".bau");
479 : }
480 :
481 0 : void SwGlossaries::RemoveFileFromList( const String& rGroup )
482 : {
483 0 : if (!m_GlosArr.empty())
484 : {
485 0 : for (std::vector<String>::iterator it(m_GlosArr.begin());
486 0 : it != m_GlosArr.end(); ++it)
487 : {
488 0 : if (*it == rGroup)
489 : {
490 0 : rtl::OUString aUName = rGroup;
491 : {
492 : // tell the UNO AutoTextGroup object that it's not valid anymore
493 0 : for ( UnoAutoTextGroups::iterator aLoop = m_aGlossaryGroups.begin();
494 0 : aLoop != m_aGlossaryGroups.end();
495 : ++aLoop
496 : )
497 : {
498 0 : Reference< container::XNamed > xNamed( aLoop->get(), UNO_QUERY );
499 0 : if ( xNamed.is() && ( xNamed->getName() == aUName ) )
500 : {
501 0 : static_cast< SwXAutoTextGroup* >( xNamed.get() )->Invalidate();
502 : // note that this static_cast works because we know that the array only
503 : // contains SwXAutoTextGroup implementation
504 0 : m_aGlossaryGroups.erase( aLoop );
505 : break;
506 : }
507 0 : }
508 : }
509 :
510 : {
511 : // tell all our UNO AutoTextEntry objects that they're not valid anymore
512 0 : for ( UnoAutoTextEntries::iterator aLoop = m_aGlossaryEntries.begin();
513 0 : aLoop != m_aGlossaryEntries.end();
514 : )
515 : {
516 0 : Reference< lang::XUnoTunnel > xEntryTunnel( aLoop->get(), UNO_QUERY );
517 :
518 0 : SwXAutoTextEntry* pEntry = NULL;
519 0 : if ( xEntryTunnel.is() )
520 : pEntry = reinterpret_cast< SwXAutoTextEntry* >(
521 0 : xEntryTunnel->getSomething( SwXAutoTextEntry::getUnoTunnelId() ) );
522 :
523 0 : if ( pEntry && ( pEntry->GetGroupName() == rGroup ) )
524 : {
525 0 : pEntry->Invalidate();
526 0 : aLoop = m_aGlossaryEntries.erase( aLoop );
527 : }
528 : else
529 0 : ++aLoop;
530 0 : }
531 : }
532 :
533 0 : m_GlosArr.erase(it);
534 0 : break;
535 : }
536 : }
537 : }
538 0 : }
539 :
540 0 : String SwGlossaries::GetCompleteGroupName( const rtl::OUString& GroupName )
541 : {
542 0 : sal_uInt16 nCount = GetGroupCnt();
543 : // when the group name was created internally the path is here as well
544 0 : String sGroup(GroupName);
545 0 : String sGroupName(sGroup.GetToken(0, GLOS_DELIM));
546 0 : String sPath = sGroup.GetToken(1, GLOS_DELIM);
547 0 : sal_Bool bPathLen = sPath.Len() > 0;
548 0 : for ( sal_uInt16 i = 0; i < nCount; i++ )
549 : {
550 0 : String sGrpName = GetGroupName(i);
551 0 : if(bPathLen ? sGroup == sGrpName : sGroupName == sGrpName.GetToken(0, GLOS_DELIM))
552 : {
553 0 : return sGrpName;
554 : }
555 0 : }
556 0 : return aEmptyStr;
557 : }
558 :
559 0 : void SwGlossaries::InvalidateUNOOjects()
560 : {
561 : // invalidate all the AutoTextGroup-objects
562 0 : for ( UnoAutoTextGroups::iterator aGroupLoop = m_aGlossaryGroups.begin();
563 0 : aGroupLoop != m_aGlossaryGroups.end();
564 : ++aGroupLoop
565 : )
566 : {
567 0 : Reference< text::XAutoTextGroup > xGroup( aGroupLoop->get(), UNO_QUERY );
568 0 : if ( xGroup.is() )
569 0 : static_cast< SwXAutoTextGroup* >( xGroup.get() )->Invalidate();
570 0 : }
571 0 : UnoAutoTextGroups aTmpg = UnoAutoTextGroups();
572 0 : m_aGlossaryGroups.swap( aTmpg );
573 :
574 : // invalidate all the AutoTextEntry-objects
575 0 : for ( UnoAutoTextEntries::const_iterator aEntryLoop = m_aGlossaryEntries.begin();
576 0 : aEntryLoop != m_aGlossaryEntries.end();
577 : ++aEntryLoop
578 : )
579 : {
580 0 : Reference< lang::XUnoTunnel > xEntryTunnel( aEntryLoop->get(), UNO_QUERY );
581 0 : SwXAutoTextEntry* pEntry = NULL;
582 0 : if ( xEntryTunnel.is() )
583 : pEntry = reinterpret_cast< SwXAutoTextEntry* >(
584 0 : xEntryTunnel->getSomething( SwXAutoTextEntry::getUnoTunnelId() ) );
585 :
586 0 : if ( pEntry )
587 0 : pEntry->Invalidate();
588 0 : }
589 0 : UnoAutoTextEntries aTmpe = UnoAutoTextEntries();
590 0 : m_aGlossaryEntries.swap( aTmpe );
591 0 : }
592 :
593 0 : Reference< text::XAutoTextGroup > SwGlossaries::GetAutoTextGroup( const ::rtl::OUString& _rGroupName, bool _bCreate )
594 : {
595 : // first, find the name with path-extension
596 0 : String sCompleteGroupName = GetCompleteGroupName( _rGroupName );
597 :
598 0 : Reference< text::XAutoTextGroup > xGroup;
599 :
600 : // look up the group in the cache
601 0 : UnoAutoTextGroups::iterator aSearch = m_aGlossaryGroups.begin();
602 0 : for ( ; aSearch != m_aGlossaryGroups.end(); )
603 : {
604 0 : Reference< lang::XUnoTunnel > xGroupTunnel( aSearch->get(), UNO_QUERY );
605 :
606 0 : SwXAutoTextGroup* pSwGroup = 0;
607 0 : if ( xGroupTunnel.is() )
608 0 : pSwGroup = reinterpret_cast< SwXAutoTextGroup* >( xGroupTunnel->getSomething( SwXAutoTextGroup::getUnoTunnelId() ) );
609 :
610 0 : if ( !pSwGroup )
611 : {
612 : // the object is dead in the meantime -> remove from cache
613 0 : aSearch = m_aGlossaryGroups.erase( aSearch );
614 0 : continue;
615 : }
616 :
617 0 : if ( _rGroupName == pSwGroup->getName() )
618 : { // the group is already cached
619 0 : if ( sCompleteGroupName.Len() )
620 : { // the group still exists -> return it
621 0 : xGroup = pSwGroup;
622 : break;
623 : }
624 : else
625 : {
626 : // this group does not exist (anymore) -> release the cached UNO object for it
627 0 : aSearch = m_aGlossaryGroups.erase( aSearch );
628 : // so it won't be created below
629 0 : _bCreate = sal_False;
630 : break;
631 : }
632 : }
633 :
634 0 : ++aSearch;
635 0 : }
636 :
637 0 : if ( !xGroup.is() && _bCreate )
638 : {
639 0 : xGroup = new SwXAutoTextGroup( sCompleteGroupName, this );
640 : // cache it
641 0 : m_aGlossaryGroups.push_back( AutoTextGroupRef( xGroup ) );
642 : }
643 :
644 0 : return xGroup;
645 : }
646 :
647 0 : Reference< text::XAutoTextEntry > SwGlossaries::GetAutoTextEntry( const String& _rCompleteGroupName, const ::rtl::OUString& _rGroupName, const ::rtl::OUString& _rEntryName,
648 : bool _bCreate )
649 : {
650 : //standard must be created
651 0 : sal_Bool bCreate = ( _rCompleteGroupName == GetDefName() );
652 0 : ::std::auto_ptr< SwTextBlocks > pGlosGroup( GetGroupDoc( _rCompleteGroupName, bCreate ) );
653 :
654 0 : if ( pGlosGroup.get() && !pGlosGroup->GetError() )
655 : {
656 0 : sal_uInt16 nIdx = pGlosGroup->GetIndex( _rEntryName );
657 0 : if ( USHRT_MAX == nIdx )
658 0 : throw container::NoSuchElementException();
659 : }
660 : else
661 0 : throw lang::WrappedTargetException();
662 :
663 0 : Reference< text::XAutoTextEntry > xReturn;
664 0 : String sGroupName( _rGroupName );
665 0 : String sEntryName( _rEntryName );
666 :
667 0 : UnoAutoTextEntries::iterator aSearch( m_aGlossaryEntries.begin() );
668 0 : for ( ; aSearch != m_aGlossaryEntries.end(); )
669 : {
670 0 : Reference< lang::XUnoTunnel > xEntryTunnel( aSearch->get(), UNO_QUERY );
671 :
672 0 : SwXAutoTextEntry* pEntry = NULL;
673 0 : if ( xEntryTunnel.is() )
674 0 : pEntry = reinterpret_cast< SwXAutoTextEntry* >( xEntryTunnel->getSomething( SwXAutoTextEntry::getUnoTunnelId() ) );
675 : else
676 : {
677 : // the object is dead in the meantime -> remove from cache
678 0 : aSearch = m_aGlossaryEntries.erase( aSearch );
679 0 : continue;
680 : }
681 :
682 0 : if ( pEntry
683 0 : && ( COMPARE_EQUAL == pEntry->GetGroupName().CompareTo( sGroupName ) )
684 0 : && ( COMPARE_EQUAL == pEntry->GetEntryName().CompareTo( sEntryName ) )
685 : )
686 : {
687 0 : xReturn = pEntry;
688 : break;
689 : }
690 :
691 0 : ++aSearch;
692 0 : }
693 :
694 0 : if ( !xReturn.is() && _bCreate )
695 : {
696 0 : xReturn = new SwXAutoTextEntry( this, sGroupName, sEntryName );
697 : // cache it
698 0 : m_aGlossaryEntries.push_back( AutoTextEntryRef( xReturn ) );
699 : }
700 :
701 0 : return xReturn;
702 : }
703 :
704 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|