bump product version to 4.1.6.2
[LibreOffice.git] / sw / source / ui / uno / unoatxt.cxx
blobd495848fd42a726713b6c7bf4cd4e1cbb618242c
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <com/sun/star/beans/PropertyAttribute.hpp>
21 #include <osl/mutex.hxx>
22 #include <osl/diagnose.h>
23 #include <vcl/svapp.hxx>
24 #include <svtools/unoevent.hxx>
25 #include <svl/urihelper.hxx>
26 #include <sfx2/event.hxx>
27 #include <swtypes.hxx>
28 #include <glosdoc.hxx>
29 #include <shellio.hxx>
30 #include <initui.hxx>
31 #include <gloslst.hxx>
32 #include <unoatxt.hxx>
33 #include <unomap.hxx>
34 #include <unomid.h>
35 #include <unotextbodyhf.hxx>
36 #include <unotextrange.hxx>
37 #include <TextCursorHelper.hxx>
38 #include <swevent.hxx>
39 #include <doc.hxx>
40 #include <unocrsr.hxx>
41 #include <IMark.hxx>
42 #include <unoprnms.hxx>
43 #include <docsh.hxx>
44 #include <swmodule.hxx>
45 #include <svl/smplhint.hxx>
46 #include <svl/macitem.hxx>
47 #include <editeng/acorrcfg.hxx>
48 #include <comphelper/servicehelper.hxx>
49 #include <comphelper/string.hxx>
50 #include <memory>
53 SV_IMPL_REF ( SwDocShell )
54 using namespace ::com::sun::star;
56 uno::Reference< uno::XInterface > SAL_CALL SwXAutoTextContainer_createInstance(
57 const uno::Reference< lang::XMultiServiceFactory > & ) throw( uno::Exception )
59 //the module may not be loaded
60 SolarMutexGuard aGuard;
61 SwGlobals::ensure();
62 static uno::Reference< uno::XInterface > xAText = (cppu::OWeakObject*)new SwXAutoTextContainer();
63 return xAText;
66 uno::Sequence< OUString > SAL_CALL SwXAutoTextContainer_getSupportedServiceNames() throw()
68 OUString sService("com.sun.star.text.AutoTextContainer");
69 const uno::Sequence< OUString > aSeq( &sService, 1 );
70 return aSeq;
73 OUString SAL_CALL SwXAutoTextContainer_getImplementationName() throw()
75 return OUString("SwXAutoTextContainer" );
78 SwXAutoTextContainer::SwXAutoTextContainer()
80 pGlossaries = ::GetGlossaries();
84 SwXAutoTextContainer::~SwXAutoTextContainer()
89 sal_Int32 SwXAutoTextContainer::getCount(void) throw( uno::RuntimeException )
91 return pGlossaries->GetGroupCnt();
94 uno::Any SwXAutoTextContainer::getByIndex(sal_Int32 nIndex)
95 throw( lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException )
97 SolarMutexGuard aGuard;
98 uno::Any aRet;
99 sal_uInt16 nCount = pGlossaries->GetGroupCnt();
100 if ( 0 <= nIndex && nIndex < nCount )
101 aRet = getByName(pGlossaries->GetGroupName( static_cast< sal_uInt16 >(nIndex) ));
102 else
103 throw lang::IndexOutOfBoundsException();
104 return aRet;
107 uno::Type SwXAutoTextContainer::getElementType(void) throw( uno::RuntimeException )
109 return ::getCppuType((const uno::Reference<text::XAutoTextGroup>*)0);
113 sal_Bool SwXAutoTextContainer::hasElements(void) throw( uno::RuntimeException )
115 //zumindest Standard sollte es immer geben!
116 return sal_True;
119 uno::Any SwXAutoTextContainer::getByName(const OUString& GroupName)
120 throw( container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException )
122 SolarMutexGuard aGuard;
124 uno::Reference< text::XAutoTextGroup > xGroup;
125 if ( pGlossaries && hasByName( GroupName ) ) // group name already known?
126 // sal_True = create group if not already available
127 xGroup = pGlossaries->GetAutoTextGroup( GroupName, sal_True );
129 if ( !xGroup.is() )
130 throw container::NoSuchElementException();
132 return makeAny( xGroup );
135 uno::Sequence< OUString > SwXAutoTextContainer::getElementNames(void) throw( uno::RuntimeException )
137 SolarMutexGuard aGuard;
138 sal_uInt16 nCount = pGlossaries->GetGroupCnt();
140 uno::Sequence< OUString > aGroupNames(nCount);
141 OUString *pArr = aGroupNames.getArray();
143 for ( sal_uInt16 i = 0; i < nCount; i++ )
145 // Die Namen werden ohne Pfad-Extension weitergegeben
146 String sGroupName(pGlossaries->GetGroupName(i));
147 pArr[i] = sGroupName.GetToken(0, GLOS_DELIM);
149 return aGroupNames;
151 /*-----------------------------------------------------------------------
152 findet Gruppennamen mit und ohne Pfadindex
153 -----------------------------------------------------------------------*/
154 sal_Bool SwXAutoTextContainer::hasByName(const OUString& Name)
155 throw( uno::RuntimeException )
157 SolarMutexGuard aGuard;
158 String sGroupName( pGlossaries->GetCompleteGroupName( Name ) );
159 if(sGroupName.Len())
160 return sal_True;
161 return sal_False;
164 uno::Reference< text::XAutoTextGroup > SwXAutoTextContainer::insertNewByName(
165 const OUString& aGroupName)
166 throw( lang::IllegalArgumentException, container::ElementExistException, uno::RuntimeException )
168 SolarMutexGuard aGuard;
169 if(hasByName(aGroupName))
170 throw container::ElementExistException();
171 //check for non-ASCII characters
172 if(aGroupName.isEmpty())
174 lang::IllegalArgumentException aIllegal;
175 aIllegal.Message = "group name must not be empty";
176 throw aIllegal;
178 for(sal_Int32 nPos = 0; nPos < aGroupName.getLength(); nPos++)
180 sal_Unicode cChar = aGroupName[nPos];
181 if (comphelper::string::isalnumAscii(cChar) ||
182 (cChar == '_') ||
183 (cChar == 0x20) ||
184 (cChar == GLOS_DELIM) )
186 continue;
188 lang::IllegalArgumentException aIllegal;
189 aIllegal.Message = "group name must contain a-z, A-z, '_', ' ' only";
190 throw aIllegal;
192 String sGroup(aGroupName);
193 if(STRING_NOTFOUND == sGroup.Search(GLOS_DELIM))
195 sGroup += GLOS_DELIM;
196 sGroup += "0";
198 pGlossaries->NewGroupDoc(sGroup, sGroup.GetToken(0, GLOS_DELIM));
200 uno::Reference< text::XAutoTextGroup > xGroup = pGlossaries->GetAutoTextGroup( sGroup, true );
201 OSL_ENSURE( xGroup.is(), "SwXAutoTextContainer::insertNewByName: no UNO object created? How this?" );
202 // we just inserted the group into the glossaries, so why doesn't it exist?
204 return xGroup;
207 void SwXAutoTextContainer::removeByName(const OUString& aGroupName)
208 throw( container::NoSuchElementException, uno::RuntimeException )
210 SolarMutexGuard aGuard;
211 //zunaechst den Namen mit Pfad-Extension finden
212 String sGroupName = pGlossaries->GetCompleteGroupName( aGroupName );
213 if(!sGroupName.Len())
214 throw container::NoSuchElementException();
215 pGlossaries->DelGroupDoc(sGroupName);
218 OUString SwXAutoTextContainer::getImplementationName(void) throw( uno::RuntimeException )
220 return SwXAutoTextContainer_getImplementationName();
223 sal_Bool SwXAutoTextContainer::supportsService(const OUString& rServiceName) throw( uno::RuntimeException )
225 const uno::Sequence< OUString > aNames = SwXAutoTextContainer_getSupportedServiceNames();
226 for(sal_Int32 nService = 0; nService < aNames.getLength(); nService++)
228 if(aNames.getConstArray()[nService] == rServiceName)
229 return sal_True;
231 return sal_False;
234 uno::Sequence< OUString > SwXAutoTextContainer::getSupportedServiceNames(void) throw( uno::RuntimeException )
236 return SwXAutoTextContainer_getSupportedServiceNames();
239 namespace
241 class theSwXAutoTextGroupUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSwXAutoTextGroupUnoTunnelId > {};
244 const uno::Sequence< sal_Int8 > & SwXAutoTextGroup::getUnoTunnelId()
246 return theSwXAutoTextGroupUnoTunnelId::get().getSeq();
249 sal_Int64 SAL_CALL SwXAutoTextGroup::getSomething( const uno::Sequence< sal_Int8 >& rId )
250 throw(uno::RuntimeException)
252 if( rId.getLength() == 16
253 && 0 == memcmp( getUnoTunnelId().getConstArray(),
254 rId.getConstArray(), 16 ) )
256 return sal::static_int_cast< sal_Int64 >( reinterpret_cast< sal_IntPtr >( this ));
258 return 0;
261 SwXAutoTextGroup::SwXAutoTextGroup(const OUString& rName,
262 SwGlossaries* pGlos) :
263 pPropSet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_AUTO_TEXT_GROUP)),
264 pGlossaries(pGlos),
265 sName(rName),
266 m_sGroupName(rName)
268 OSL_ENSURE( -1 != rName.indexOf( GLOS_DELIM ),
269 "SwXAutoTextGroup::SwXAutoTextGroup: to be constructed with a complete name only!" );
272 SwXAutoTextGroup::~SwXAutoTextGroup()
276 uno::Sequence< OUString > SwXAutoTextGroup::getTitles(void) throw( uno::RuntimeException )
278 SolarMutexGuard aGuard;
279 sal_uInt16 nCount = 0;
280 SwTextBlocks* pGlosGroup = pGlossaries ? pGlossaries->GetGroupDoc(m_sGroupName, sal_False) : 0;
281 if(pGlosGroup && !pGlosGroup->GetError())
282 nCount = pGlosGroup->GetCount();
283 else
284 throw uno::RuntimeException();
286 uno::Sequence< OUString > aEntryTitles(nCount);
287 OUString *pArr = aEntryTitles.getArray();
289 for ( sal_uInt16 i = 0; i < nCount; i++ )
290 pArr[i] = pGlosGroup->GetLongName(i);
291 delete pGlosGroup;
292 return aEntryTitles;
295 void SwXAutoTextGroup::renameByName(const OUString& aElementName,
296 const OUString& aNewElementName, const OUString& aNewElementTitle)
297 throw( lang::IllegalArgumentException, container::ElementExistException, io::IOException,
298 uno::RuntimeException)
300 SolarMutexGuard aGuard;
301 // throw exception only if the programmatic name is to be changed into an existing name
302 if(aNewElementName != aElementName && hasByName(aNewElementName))
303 throw container::ElementExistException();
304 SwTextBlocks* pGlosGroup = pGlossaries ? pGlossaries->GetGroupDoc(m_sGroupName, sal_False) : 0;
305 if(pGlosGroup && !pGlosGroup->GetError())
307 sal_uInt16 nIdx = pGlosGroup->GetIndex( aElementName);
308 if(USHRT_MAX == nIdx)
309 throw lang::IllegalArgumentException();
310 String aNewShort( aNewElementName);
311 String aNewName( aNewElementTitle);
312 sal_uInt16 nOldLongIdx = pGlosGroup->GetLongIndex( aNewShort );
313 sal_uInt16 nOldIdx = pGlosGroup->GetIndex( aNewName );
315 if( nIdx != USHRT_MAX &&
316 (nOldLongIdx == USHRT_MAX || nOldLongIdx == nIdx )&&
317 (nOldIdx == USHRT_MAX || nOldIdx == nIdx ))
319 pGlosGroup->Rename( nIdx, &aNewShort, &aNewName );
320 if(pGlosGroup->GetError() != 0)
321 throw io::IOException();
323 delete pGlosGroup;
325 else
326 throw uno::RuntimeException();
329 static bool lcl_CopySelToDoc( SwDoc* pInsDoc, OTextCursorHelper* pxCursor, SwXTextRange* pxRange)
331 OSL_ENSURE( pInsDoc, "no InsDoc");
333 SwNodes& rNds = pInsDoc->GetNodes();
335 SwNodeIndex aIdx( rNds.GetEndOfContent(), -1 );
336 SwCntntNode * pNd = aIdx.GetNode().GetCntntNode();
337 SwPosition aPos( aIdx, SwIndex( pNd, pNd->Len() ));
339 bool bRet = false;
340 pInsDoc->LockExpFlds();
342 SwDoc *const pDoc((pxCursor) ? pxCursor->GetDoc() : pxRange->GetDoc());
343 SwPaM aPam(pDoc->GetNodes());
344 SwPaM * pPam(0);
345 if(pxCursor)
347 pPam = pxCursor->GetPaM();
349 else
351 if (pxRange->GetPositions(aPam))
353 pPam = & aPam;
356 if (!pPam) { return false; }
357 bRet = pDoc->CopyRange( *pPam, aPos, false ) || bRet;
360 pInsDoc->UnlockExpFlds();
361 if( !pInsDoc->IsExpFldsLocked() )
362 pInsDoc->UpdateExpFlds(NULL, true);
364 return bRet;
367 uno::Reference< text::XAutoTextEntry > SwXAutoTextGroup::insertNewByName(const OUString& aName,
368 const OUString& aTitle, const uno::Reference< text::XTextRange > & xTextRange)
369 throw( container::ElementExistException, uno::RuntimeException )
371 SolarMutexGuard aGuard;
372 if(hasByName(aName))
373 throw container::ElementExistException();
374 if(!xTextRange.is())
375 throw uno::RuntimeException();
377 SwTextBlocks* pGlosGroup = pGlossaries ? pGlossaries->GetGroupDoc(m_sGroupName, sal_False) : 0;
378 String sShortName(aName);
379 String sLongName(aTitle);
380 if(pGlosGroup && !pGlosGroup->GetError())
382 uno::Reference<lang::XUnoTunnel> xRangeTunnel( xTextRange, uno::UNO_QUERY);
383 SwXTextRange* pxRange = 0;
384 OTextCursorHelper* pxCursor = 0;
385 if(xRangeTunnel.is())
387 pxRange = reinterpret_cast<SwXTextRange*>(xRangeTunnel->getSomething(
388 SwXTextRange::getUnoTunnelId()));
389 pxCursor = reinterpret_cast<OTextCursorHelper*>(xRangeTunnel->getSomething(
390 OTextCursorHelper::getUnoTunnelId()));
393 String sOnlyTxt;
394 String* pOnlyTxt = 0;
395 bool bNoAttr = !pxCursor && !pxRange;
396 if(bNoAttr)
398 sOnlyTxt = OUString(xTextRange->getString());
399 pOnlyTxt = &sOnlyTxt;
402 const SvxAutoCorrCfg& rCfg = SvxAutoCorrCfg::Get();
404 SwDoc* pGDoc = pGlosGroup->GetDoc();
406 // Bis es eine Option dafuer gibt, base util::URL loeschen
407 if(rCfg.IsSaveRelFile())
409 INetURLObject aTemp(pGlosGroup->GetFileName());
410 pGlosGroup->SetBaseURL( aTemp.GetMainURL(INetURLObject::NO_DECODE));
412 else
413 pGlosGroup->SetBaseURL( aEmptyStr );
415 sal_uInt16 nRet;
416 if( pOnlyTxt )
417 nRet = pGlosGroup->PutText( sShortName, sLongName, *pOnlyTxt );
418 else
420 pGlosGroup->ClearDoc();
421 if( pGlosGroup->BeginPutDoc( sShortName, sLongName ) )
423 pGDoc->SetRedlineMode_intern( nsRedlineMode_t::REDLINE_DELETE_REDLINES );
424 lcl_CopySelToDoc( pGDoc, pxCursor, pxRange );
425 pGDoc->SetRedlineMode_intern((RedlineMode_t)( 0 ));
426 nRet = pGlosGroup->PutDoc();
428 else
429 nRet = (sal_uInt16) -1;
432 if(nRet == (sal_uInt16) -1 )
434 throw uno::RuntimeException();
436 pGlossaries->PutGroupDoc( pGlosGroup );
439 uno::Reference< text::XAutoTextEntry > xEntry = pGlossaries->GetAutoTextEntry( m_sGroupName, sName, sShortName, true );
440 OSL_ENSURE( xEntry.is(), "SwXAutoTextGroup::insertNewByName: no UNO object created? How this?" );
441 // we just inserted the entry into the group, so why doesn't it exist?
443 return xEntry;
446 void SwXAutoTextGroup::removeByName(const OUString& aEntryName) throw( container::NoSuchElementException, uno::RuntimeException )
448 SolarMutexGuard aGuard;
449 SwTextBlocks* pGlosGroup = pGlossaries ? pGlossaries->GetGroupDoc(m_sGroupName, sal_False) : 0;
450 if(pGlosGroup && !pGlosGroup->GetError())
452 sal_uInt16 nIdx = pGlosGroup->GetIndex(aEntryName);
453 if ( nIdx != USHRT_MAX )
454 pGlosGroup->Delete(nIdx);
455 delete pGlosGroup;
457 else
458 throw container::NoSuchElementException();
461 OUString SwXAutoTextGroup::getName(void) throw( uno::RuntimeException )
463 SolarMutexGuard aGuard;
464 return sName;
467 void SwXAutoTextGroup::setName(const OUString& rName) throw( uno::RuntimeException )
469 SolarMutexGuard aGuard;
470 if( !pGlossaries )
471 throw uno::RuntimeException();
473 sal_Int32 nNewDelimPos = rName.lastIndexOf( GLOS_DELIM );
474 sal_Int32 nOldDelimPos = sName.lastIndexOf( GLOS_DELIM );
476 OUString aNewSuffix;
477 if (nNewDelimPos > -1)
478 aNewSuffix = rName.copy( nNewDelimPos + 1 );
479 OUString aOldSuffix;
480 if (nOldDelimPos > -1)
481 aOldSuffix = sName.copy( nOldDelimPos + 1 );
483 sal_Int32 nNewNumeric = aNewSuffix.toInt32();
484 sal_Int32 nOldNumeric = aOldSuffix.toInt32();
486 OUString aNewPrefix( (nNewDelimPos > 1) ? rName.copy( 0, nNewDelimPos ) : rName );
487 OUString aOldPrefix( (nOldDelimPos > 1) ? sName.copy( 0, nOldDelimPos ) : sName );
489 if ( sName == rName ||
490 ( nNewNumeric == nOldNumeric && aNewPrefix == aOldPrefix ) )
491 return;
492 String sNewGroup(rName);
493 if(STRING_NOTFOUND == sNewGroup.Search(GLOS_DELIM))
495 sNewGroup += GLOS_DELIM;
496 sNewGroup += "0";
499 //the name must be saved, the group may be invalidated while in RenameGroupDoc()
500 SwGlossaries* pTempGlossaries = pGlossaries;
502 String sPreserveTitle( pGlossaries->GetGroupTitle( sName ) );
503 if ( !pGlossaries->RenameGroupDoc( sName, sNewGroup, sPreserveTitle ) )
504 throw uno::RuntimeException();
505 else
507 sName = rName;
508 m_sGroupName = sNewGroup;
509 pGlossaries = pTempGlossaries;
513 sal_Int32 SwXAutoTextGroup::getCount(void) throw( uno::RuntimeException )
515 SolarMutexGuard aGuard;
516 int nCount = 0;
517 SwTextBlocks* pGlosGroup = pGlossaries ? pGlossaries->GetGroupDoc(m_sGroupName, sal_False) : 0;
518 if(pGlosGroup && !pGlosGroup->GetError())
519 nCount = pGlosGroup->GetCount();
520 else
521 throw uno::RuntimeException();
522 delete pGlosGroup;
523 return nCount;
526 uno::Any SwXAutoTextGroup::getByIndex(sal_Int32 nIndex)
527 throw( lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException )
529 SolarMutexGuard aGuard;
530 uno::Any aRet;
531 sal_uInt16 nCount = 0;
532 SwTextBlocks* pGlosGroup = pGlossaries ? pGlossaries->GetGroupDoc(m_sGroupName, sal_False) : 0;
533 if(pGlosGroup && !pGlosGroup->GetError())
534 nCount = pGlosGroup->GetCount();
535 else
536 throw uno::RuntimeException();
537 if(0 <= nIndex && nIndex < nCount)
538 aRet = getByName(pGlosGroup->GetShortName((sal_uInt16) nIndex));
539 else
540 throw lang::IndexOutOfBoundsException();
541 delete pGlosGroup;
542 return aRet;
545 uno::Type SwXAutoTextGroup::getElementType(void) throw( uno::RuntimeException )
547 return ::getCppuType((uno::Reference<text::XAutoTextEntry>*)0);
551 sal_Bool SwXAutoTextGroup::hasElements(void) throw( uno::RuntimeException )
553 SolarMutexGuard aGuard;
554 SwTextBlocks* pGlosGroup = pGlossaries ? pGlossaries->GetGroupDoc(m_sGroupName, sal_False) : 0;
555 sal_uInt16 nCount = 0;
556 if(pGlosGroup && !pGlosGroup->GetError())
557 nCount = pGlosGroup->GetCount();
558 else
559 throw uno::RuntimeException();
560 delete pGlosGroup;
561 return nCount > 0;
565 uno::Any SwXAutoTextGroup::getByName(const OUString& _rName)
566 throw( container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException )
568 SolarMutexGuard aGuard;
569 uno::Reference< text::XAutoTextEntry > xEntry = pGlossaries->GetAutoTextEntry( m_sGroupName, sName, _rName, true );
570 OSL_ENSURE( xEntry.is(), "SwXAutoTextGroup::getByName: GetAutoTextEntry is fractious!" );
571 // we told it to create the object, so why didn't it?
572 return makeAny( xEntry );
575 uno::Sequence< OUString > SwXAutoTextGroup::getElementNames(void)
576 throw( uno::RuntimeException )
578 SolarMutexGuard aGuard;
579 sal_uInt16 nCount = 0;
580 SwTextBlocks* pGlosGroup = pGlossaries ? pGlossaries->GetGroupDoc(m_sGroupName, sal_False) : 0;
581 if(pGlosGroup && !pGlosGroup->GetError())
582 nCount = pGlosGroup->GetCount();
583 else
584 throw uno::RuntimeException();
586 uno::Sequence< OUString > aEntryNames(nCount);
587 OUString *pArr = aEntryNames.getArray();
589 for ( sal_uInt16 i = 0; i < nCount; i++ )
590 pArr[i] = pGlosGroup->GetShortName(i);
591 delete pGlosGroup;
592 return aEntryNames;
595 sal_Bool SwXAutoTextGroup::hasByName(const OUString& rName)
596 throw( uno::RuntimeException )
598 SolarMutexGuard aGuard;
599 sal_Bool bRet = sal_False;
600 sal_uInt16 nCount = 0;
601 SwTextBlocks* pGlosGroup = pGlossaries ? pGlossaries->GetGroupDoc(m_sGroupName, sal_False) : 0;
602 if(pGlosGroup && !pGlosGroup->GetError())
603 nCount = pGlosGroup->GetCount();
604 else
605 throw uno::RuntimeException();
607 for( sal_uInt16 i = 0; i < nCount; i++ )
609 String sCompare(pGlosGroup->GetShortName(i));
610 if(COMPARE_EQUAL == sCompare.CompareIgnoreCaseToAscii(String(rName)))
612 bRet = sal_True;
613 break;
616 delete pGlosGroup;
617 return bRet;
620 uno::Reference< beans::XPropertySetInfo > SwXAutoTextGroup::getPropertySetInfo(void)
621 throw( uno::RuntimeException )
623 static uno::Reference< beans::XPropertySetInfo > xRet = pPropSet->getPropertySetInfo();
624 return xRet;
627 void SwXAutoTextGroup::setPropertyValue(
628 const OUString& rPropertyName, const uno::Any& aValue)
629 throw( beans::UnknownPropertyException, beans::PropertyVetoException,
630 lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException)
632 SolarMutexGuard aGuard;
633 const SfxItemPropertySimpleEntry* pEntry = pPropSet->getPropertyMap().getByName( rPropertyName );
635 if(!pEntry)
636 throw beans::UnknownPropertyException();
638 SwTextBlocks* pGlosGroup = pGlossaries ? pGlossaries->GetGroupDoc(m_sGroupName, sal_False) : 0;
639 if(!pGlosGroup || pGlosGroup->GetError())
640 throw uno::RuntimeException();
641 switch(pEntry->nWID)
643 case WID_GROUP_TITLE:
645 OUString sNewTitle;
646 aValue >>= sNewTitle;
647 if(sNewTitle.isEmpty())
648 throw lang::IllegalArgumentException();
649 bool bChanged = !sNewTitle.equals(pGlosGroup->GetName());
650 pGlosGroup->SetName(sNewTitle);
651 if(bChanged && HasGlossaryList())
652 GetGlossaryList()->ClearGroups();
654 break;
656 delete pGlosGroup;
659 uno::Any SwXAutoTextGroup::getPropertyValue(const OUString& rPropertyName)
660 throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
662 SolarMutexGuard aGuard;
663 const SfxItemPropertySimpleEntry* pEntry = pPropSet->getPropertyMap().getByName( rPropertyName);
665 if(!pEntry)
666 throw beans::UnknownPropertyException();
667 SwTextBlocks* pGlosGroup = pGlossaries ? pGlossaries->GetGroupDoc(m_sGroupName, sal_False) : 0;
668 if(!pGlosGroup || pGlosGroup->GetError())
669 throw uno::RuntimeException();
671 uno::Any aAny;
672 switch(pEntry->nWID)
674 case WID_GROUP_PATH:
675 aAny <<= OUString(pGlosGroup->GetFileName());
676 break;
677 case WID_GROUP_TITLE:
678 aAny <<= OUString(pGlosGroup->GetName());
679 break;
681 delete pGlosGroup;
682 return aAny;
685 void SwXAutoTextGroup::addPropertyChangeListener(
686 const OUString& /*PropertyName*/, const uno::Reference< beans::XPropertyChangeListener > & /*aListener*/)
687 throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
691 void SwXAutoTextGroup::removePropertyChangeListener(
692 const OUString& /*PropertyName*/, const uno::Reference< beans::XPropertyChangeListener > & /*aListener*/)
693 throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
697 void SwXAutoTextGroup::addVetoableChangeListener(
698 const OUString& /*PropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*aListener*/)
699 throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
703 void SwXAutoTextGroup::removeVetoableChangeListener(
704 const OUString& /*PropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*aListener*/)
705 throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
709 void SwXAutoTextGroup::Invalidate()
711 pGlossaries = 0;
712 sName = aEmptyStr;
713 m_sGroupName = aEmptyStr;
716 OUString SwXAutoTextGroup::getImplementationName(void) throw( uno::RuntimeException )
718 return OUString("SwXAutoTextGroup");
721 sal_Bool SwXAutoTextGroup::supportsService(const OUString& rServiceName) throw( uno::RuntimeException )
723 return OUString("com.sun.star.text.AutoTextGroup") == rServiceName;
726 uno::Sequence< OUString > SwXAutoTextGroup::getSupportedServiceNames(void) throw( uno::RuntimeException )
728 uno::Sequence< OUString > aRet(1);
729 OUString* pArray = aRet.getArray();
730 pArray[0] = OUString("com.sun.star.text.AutoTextGroup");
731 return aRet;
734 namespace
736 class theSwXAutoTextEntryUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSwXAutoTextEntryUnoTunnelId > {};
739 const uno::Sequence< sal_Int8 > & SwXAutoTextEntry::getUnoTunnelId()
741 return theSwXAutoTextEntryUnoTunnelId::get().getSeq();
744 sal_Int64 SAL_CALL SwXAutoTextEntry::getSomething( const uno::Sequence< sal_Int8 >& rId )
745 throw(uno::RuntimeException)
747 if( rId.getLength() == 16
748 && 0 == memcmp( getUnoTunnelId().getConstArray(),
749 rId.getConstArray(), 16 ) )
751 return sal::static_int_cast< sal_Int64 >( reinterpret_cast< sal_IntPtr >( this ));
753 return 0;
756 SwXAutoTextEntry::SwXAutoTextEntry(SwGlossaries* pGlss, const String& rGroupName,
757 const String& rEntryName) :
758 pGlossaries(pGlss),
759 sGroupName(rGroupName),
760 sEntryName(rEntryName),
761 pBodyText ( NULL )
765 SwXAutoTextEntry::~SwXAutoTextEntry()
768 SolarMutexGuard aGuard;
770 // ensure that any pending modifications are written
771 implFlushDocument( true );
773 //! Bug #96559
774 // DocShell must be cleared before mutex is lost.
775 // Needs to be done explicitly since xDocSh is a class member.
776 // Thus, an own block here, guarded by the SolarMutex
780 void SwXAutoTextEntry::implFlushDocument( bool _bCloseDoc )
782 if ( xDocSh.Is() )
784 if ( xDocSh->GetDoc()->IsModified () )
785 xDocSh->Save();
787 if ( _bCloseDoc )
789 // stop listening at the document
790 EndListening( *&xDocSh );
792 xDocSh->DoClose();
793 xDocSh.Clear();
798 void SwXAutoTextEntry::Notify( SfxBroadcaster& _rBC, const SfxHint& _rHint )
800 if ( &_rBC == &xDocSh )
801 { // it's our document
802 if ( _rHint.ISA( SfxSimpleHint ) )
804 if ( SFX_HINT_DEINITIALIZING == static_cast< const SfxSimpleHint& >( _rHint ).GetId() )
806 // our document is dying (possibly because we're shuting down, and the document was notified
807 // earlier than we are?)
808 // stop listening at the docu
809 EndListening( *&xDocSh );
810 // and release our reference
811 xDocSh.Clear();
814 else if(_rHint.ISA(SfxEventHint))
816 if(SFX_EVENT_PREPARECLOSEDOC == static_cast< const SfxEventHint& >( _rHint ).GetEventId())
818 implFlushDocument( sal_False );
819 xBodyText = 0;
820 xDocSh.Clear();
826 void SwXAutoTextEntry::GetBodyText ()
828 SolarMutexGuard aGuard;
830 xDocSh = pGlossaries->EditGroupDoc ( sGroupName, sEntryName, sal_False );
831 OSL_ENSURE( xDocSh.Is(), "SwXAutoTextEntry::GetBodyText: unexpected: no doc returned by EditGroupDoc!" );
833 // start listening at the document
834 StartListening( *&xDocSh );
836 pBodyText = new SwXBodyText ( xDocSh->GetDoc() );
837 xBodyText = uno::Reference < lang::XServiceInfo > ( *pBodyText, uno::UNO_QUERY);
840 uno::Reference< text::XTextCursor > SwXAutoTextEntry::createTextCursor(void) throw( uno::RuntimeException )
842 SolarMutexGuard aGuard;
843 EnsureBodyText();
844 return pBodyText->createTextCursor();
847 uno::Reference< text::XTextCursor > SwXAutoTextEntry::createTextCursorByRange(
848 const uno::Reference< text::XTextRange > & aTextPosition) throw( uno::RuntimeException )
850 SolarMutexGuard aGuard;
851 EnsureBodyText();
852 return pBodyText->createTextCursorByRange ( aTextPosition );
855 void SwXAutoTextEntry::insertString(const uno::Reference< text::XTextRange > & xRange, const OUString& aString, sal_Bool bAbsorb) throw( uno::RuntimeException )
857 SolarMutexGuard aGuard;
858 EnsureBodyText();
859 pBodyText->insertString ( xRange, aString, bAbsorb );
862 void SwXAutoTextEntry::insertControlCharacter(const uno::Reference< text::XTextRange > & xRange,
863 sal_Int16 nControlCharacter, sal_Bool bAbsorb)
864 throw( lang::IllegalArgumentException, uno::RuntimeException )
866 SolarMutexGuard aGuard;
867 EnsureBodyText();
868 pBodyText->insertControlCharacter ( xRange, nControlCharacter, bAbsorb );
871 void SwXAutoTextEntry::insertTextContent(
872 const uno::Reference< text::XTextRange > & xRange,
873 const uno::Reference< text::XTextContent > & xContent, sal_Bool bAbsorb)
874 throw( lang::IllegalArgumentException, uno::RuntimeException )
876 SolarMutexGuard aGuard;
877 EnsureBodyText();
878 pBodyText->insertTextContent ( xRange, xContent, bAbsorb );
881 void SwXAutoTextEntry::removeTextContent(
882 const uno::Reference< text::XTextContent > & xContent)
883 throw( container::NoSuchElementException, uno::RuntimeException )
885 SolarMutexGuard aGuard;
886 EnsureBodyText();
887 pBodyText->removeTextContent ( xContent );
890 uno::Reference< text::XText > SwXAutoTextEntry::getText(void) throw( uno::RuntimeException )
892 SolarMutexGuard aGuard;
893 uno::Reference< text::XText > xRet = (text::XText*)this;
894 return xRet;
897 uno::Reference< text::XTextRange > SwXAutoTextEntry::getStart(void) throw( uno::RuntimeException )
899 SolarMutexGuard aGuard;
900 EnsureBodyText();
901 return pBodyText->getStart();
904 uno::Reference< text::XTextRange > SwXAutoTextEntry::getEnd(void) throw( uno::RuntimeException )
906 SolarMutexGuard aGuard;
907 EnsureBodyText();
908 return pBodyText->getEnd();
911 OUString SwXAutoTextEntry::getString(void) throw( uno::RuntimeException )
913 SolarMutexGuard aGuard;
914 EnsureBodyText();
915 return pBodyText->getString();
918 void SwXAutoTextEntry::setString(const OUString& aString) throw( uno::RuntimeException )
920 SolarMutexGuard aGuard;
921 EnsureBodyText();
922 pBodyText->setString( aString );
925 void SwXAutoTextEntry::applyTo(const uno::Reference< text::XTextRange > & xTextRange)throw( uno::RuntimeException )
927 SolarMutexGuard aGuard;
929 // ensure that any pending modifications are written
930 // reason is that we're holding the _copy_ of the auto text, while the real auto text
931 // is stored somewhere. And below, we're not working with our copy, but only tell the target
932 // TextRange to work with the stored version.
933 // #96380# - 2003-03-03 - fs@openoffice.org
934 implFlushDocument( false );
935 // TODO: think about if we should pass "true" here
936 // The difference would be that when the next modification is made to this instance here, then
937 // we would be forced to open the document again, instead of working on our current copy.
938 // This means that we would reflect any changes which were done to the AutoText by foreign instances
939 // in the meantime
941 uno::Reference<lang::XUnoTunnel> xTunnel( xTextRange, uno::UNO_QUERY);
942 SwXTextRange* pRange = 0;
943 OTextCursorHelper* pCursor = 0;
944 SwXText *pText = 0;
946 if(xTunnel.is())
948 pRange = reinterpret_cast < SwXTextRange* >
949 ( xTunnel->getSomething( SwXTextRange::getUnoTunnelId() ) );
950 pCursor = reinterpret_cast < OTextCursorHelper*>
951 ( xTunnel->getSomething( OTextCursorHelper::getUnoTunnelId() ) );
952 pText = reinterpret_cast < SwXText* >
953 ( xTunnel->getSomething( SwXText::getUnoTunnelId() ) );
956 SwDoc* pDoc = 0;
957 if (pRange)
958 pDoc = pRange->GetDoc();
959 else if ( pCursor )
960 pDoc = pCursor->GetDoc();
961 else if ( pText && pText->GetDoc() )
963 xTunnel = uno::Reference < lang::XUnoTunnel > (pText->getStart(), uno::UNO_QUERY);
964 if (xTunnel.is())
966 pCursor = reinterpret_cast < OTextCursorHelper* >
967 ( xTunnel->getSomething( OTextCursorHelper::getUnoTunnelId() ) );
968 if (pCursor)
969 pDoc = pText->GetDoc();
973 if(!pDoc)
974 throw uno::RuntimeException();
976 SwPaM InsertPaM(pDoc->GetNodes());
977 if (pRange)
979 if (!pRange->GetPositions(InsertPaM))
981 throw uno::RuntimeException();
984 else
986 InsertPaM = *pCursor->GetPaM();
989 ::std::auto_ptr<SwTextBlocks> pBlock(pGlossaries->GetGroupDoc(sGroupName));
990 const bool bResult = pBlock.get() && !pBlock->GetError()
991 && pDoc->InsertGlossary( *pBlock, sEntryName, InsertPaM);
993 if(!bResult)
994 throw uno::RuntimeException();
997 OUString SwXAutoTextEntry::getImplementationName(void) throw( uno::RuntimeException )
999 return OUString("SwXAutoTextEntry");
1002 sal_Bool SwXAutoTextEntry::supportsService(const OUString& rServiceName) throw( uno::RuntimeException )
1004 return rServiceName == "com.sun.star.text.AutoTextEntry";
1007 uno::Sequence< OUString > SwXAutoTextEntry::getSupportedServiceNames(void) throw( uno::RuntimeException )
1009 uno::Sequence< OUString > aRet(1);
1010 OUString* pArray = aRet.getArray();
1011 pArray[0] = "com.sun.star.text.AutoTextEntry";
1012 return aRet;
1015 uno::Reference< container::XNameReplace > SwXAutoTextEntry::getEvents()
1016 throw( uno::RuntimeException )
1018 return new SwAutoTextEventDescriptor( *this );
1021 const struct SvEventDescription aAutotextEvents[] =
1023 { SW_EVENT_START_INS_GLOSSARY, "OnInsertStart" },
1024 { SW_EVENT_END_INS_GLOSSARY, "OnInsertDone" },
1025 { 0, NULL }
1028 SwAutoTextEventDescriptor::SwAutoTextEventDescriptor(
1029 SwXAutoTextEntry& rAutoText ) :
1030 SvBaseEventDescriptor(aAutotextEvents),
1031 sSwAutoTextEventDescriptor(
1032 "SwAutoTextEventDescriptor"),
1033 rAutoTextEntry(rAutoText)
1037 SwAutoTextEventDescriptor::~SwAutoTextEventDescriptor()
1041 OUString SwAutoTextEventDescriptor::getImplementationName()
1042 throw( uno::RuntimeException )
1044 return sSwAutoTextEventDescriptor;
1047 void SwAutoTextEventDescriptor::replaceByName(
1048 const sal_uInt16 nEvent,
1049 const SvxMacro& rMacro)
1050 throw(
1051 lang::IllegalArgumentException,
1052 container::NoSuchElementException,
1053 lang::WrappedTargetException,
1054 uno::RuntimeException)
1056 OSL_ENSURE( NULL != rAutoTextEntry.GetGlossaries(),
1057 "Strangely enough, the AutoText vanished!" );
1058 OSL_ENSURE( (nEvent == SW_EVENT_END_INS_GLOSSARY) ||
1059 (nEvent == SW_EVENT_START_INS_GLOSSARY) ,
1060 "Unknown event ID" );
1062 SwGlossaries *const pGlossaries =
1063 const_cast<SwGlossaries*>(rAutoTextEntry.GetGlossaries());
1064 SwTextBlocks* pBlocks =
1065 pGlossaries->GetGroupDoc( rAutoTextEntry.GetGroupName() );
1066 OSL_ENSURE( NULL != pBlocks,
1067 "can't get autotext group; SwAutoTextEntry has illegal name?");
1069 if( pBlocks && !pBlocks->GetError())
1071 sal_uInt16 nIndex = pBlocks->GetIndex( rAutoTextEntry.GetEntryName() );
1072 if( nIndex != USHRT_MAX )
1074 SvxMacroTableDtor aMacroTable;
1075 if( pBlocks->GetMacroTable( nIndex, aMacroTable ) )
1077 aMacroTable.Insert( nEvent, rMacro );
1078 pBlocks->SetMacroTable( nIndex, aMacroTable );
1082 delete pBlocks;
1084 // else: ignore
1087 void SwAutoTextEventDescriptor::getByName(
1088 SvxMacro& rMacro,
1089 const sal_uInt16 nEvent )
1090 throw(
1091 container::NoSuchElementException,
1092 lang::WrappedTargetException,
1093 uno::RuntimeException)
1095 OSL_ENSURE( NULL != rAutoTextEntry.GetGlossaries(), "no AutoText" );
1096 OSL_ENSURE( (nEvent == SW_EVENT_END_INS_GLOSSARY) ||
1097 (nEvent == SW_EVENT_START_INS_GLOSSARY) ,
1098 "Unknown event ID" );
1100 SwGlossaries *const pGlossaries =
1101 const_cast<SwGlossaries*>(rAutoTextEntry.GetGlossaries());
1102 SwTextBlocks* pBlocks =
1103 pGlossaries->GetGroupDoc( rAutoTextEntry.GetGroupName() );
1104 OSL_ENSURE( NULL != pBlocks,
1105 "can't get autotext group; SwAutoTextEntry has illegal name?");
1107 // return empty macro, unless macro is found
1108 OUString sEmptyStr;
1109 SvxMacro aEmptyMacro(sEmptyStr, sEmptyStr);
1110 rMacro = aEmptyMacro;
1112 if ( pBlocks && !pBlocks->GetError())
1114 sal_uInt16 nIndex = pBlocks->GetIndex( rAutoTextEntry.GetEntryName() );
1115 if( nIndex != USHRT_MAX )
1117 SvxMacroTableDtor aMacroTable;
1118 if( pBlocks->GetMacroTable( nIndex, aMacroTable ) )
1120 SvxMacro *pMacro = aMacroTable.Get( nEvent );
1121 if( pMacro )
1122 rMacro = *pMacro;
1126 delete pBlocks;
1133 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */