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