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