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