1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 <sal/config.h>
22 #include <com/sun/star/io/IOException.hpp>
23 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
24 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
25 #include <com/sun/star/container/ElementExistException.hpp>
26 #include <o3tl/safeint.hxx>
27 #include <osl/diagnose.h>
28 #include <rtl/character.hxx>
30 #include <vcl/svapp.hxx>
31 #include <svtools/unoevent.hxx>
32 #include <sfx2/event.hxx>
33 #include <glosdoc.hxx>
34 #include <shellio.hxx>
36 #include <gloslst.hxx>
37 #include <unoatxt.hxx>
39 #include <unotextbodyhf.hxx>
40 #include <unotextrange.hxx>
41 #include <TextCursorHelper.hxx>
43 #include <IDocumentContentOperations.hxx>
44 #include <IDocumentRedlineAccess.hxx>
45 #include <IDocumentFieldsAccess.hxx>
46 #include <IDocumentState.hxx>
49 #include <svl/hint.hxx>
50 #include <tools/urlobj.hxx>
51 #include <svl/macitem.hxx>
52 #include <editeng/acorrcfg.hxx>
53 #include <comphelper/servicehelper.hxx>
54 #include <cppuhelper/exc_hlp.hxx>
55 #include <cppuhelper/supportsservice.hxx>
59 using namespace ::com::sun::star
;
61 SwXAutoTextContainer::SwXAutoTextContainer()
63 m_pGlossaries
= ::GetGlossaries();
67 SwXAutoTextContainer::~SwXAutoTextContainer()
72 sal_Int32
SwXAutoTextContainer::getCount()
74 OSL_ENSURE(m_pGlossaries
->GetGroupCnt() < o3tl::make_unsigned(SAL_MAX_INT32
),
75 "SwXAutoTextContainer::getCount: too many items");
76 return static_cast<sal_Int32
>(m_pGlossaries
->GetGroupCnt());
79 uno::Any
SwXAutoTextContainer::getByIndex(sal_Int32 nIndex
)
81 SolarMutexGuard aGuard
;
82 const size_t nCount
= m_pGlossaries
->GetGroupCnt();
83 if ( nIndex
< 0 || o3tl::make_unsigned(nIndex
) >= nCount
)
84 throw lang::IndexOutOfBoundsException();
85 return getByName(m_pGlossaries
->GetGroupName( static_cast<size_t>(nIndex
) ));
88 uno::Type
SwXAutoTextContainer::getElementType()
90 return cppu::UnoType
<text::XAutoTextGroup
>::get();
94 sal_Bool
SwXAutoTextContainer::hasElements()
96 // At least standard should always exists!
100 uno::Any
SwXAutoTextContainer::getByName(const OUString
& GroupName
)
102 SolarMutexGuard aGuard
;
104 uno::Reference
< text::XAutoTextGroup
> xGroup
;
105 if ( m_pGlossaries
&& hasByName( GroupName
) ) // group name already known?
106 // true = create group if not already available
107 xGroup
= m_pGlossaries
->GetAutoTextGroup( GroupName
);
110 throw container::NoSuchElementException();
112 return css::uno::Any( xGroup
);
115 uno::Sequence
< OUString
> SwXAutoTextContainer::getElementNames()
117 SolarMutexGuard aGuard
;
118 const size_t nCount
= m_pGlossaries
->GetGroupCnt();
119 OSL_ENSURE(nCount
< o3tl::make_unsigned(SAL_MAX_INT32
),
120 "SwXAutoTextContainer::getElementNames: too many groups");
122 uno::Sequence
< OUString
> aGroupNames(static_cast<sal_Int32
>(nCount
));
123 OUString
*pArr
= aGroupNames
.getArray();
125 for ( size_t i
= 0; i
< nCount
; ++i
)
127 // The names will be passed without a path extension.
128 pArr
[i
] = m_pGlossaries
->GetGroupName(i
).getToken(0, GLOS_DELIM
);
132 // Finds group names with or without path index.
133 sal_Bool
SwXAutoTextContainer::hasByName(const OUString
& Name
)
135 SolarMutexGuard aGuard
;
136 OUString
sGroupName( m_pGlossaries
->GetCompleteGroupName( Name
) );
137 if(!sGroupName
.isEmpty())
142 uno::Reference
< text::XAutoTextGroup
> SwXAutoTextContainer::insertNewByName(
143 const OUString
& aGroupName
)
145 SolarMutexGuard aGuard
;
146 if(hasByName(aGroupName
))
147 throw container::ElementExistException();
148 //check for non-ASCII characters
149 if(aGroupName
.isEmpty())
151 lang::IllegalArgumentException aIllegal
;
152 aIllegal
.Message
= "group name must not be empty";
155 for(sal_Int32 nPos
= 0; nPos
< aGroupName
.getLength(); nPos
++)
157 sal_Unicode cChar
= aGroupName
[nPos
];
158 if (rtl::isAsciiAlphanumeric(cChar
) ||
161 (cChar
== GLOS_DELIM
) )
165 lang::IllegalArgumentException aIllegal
;
166 aIllegal
.Message
= "group name must contain a-z, A-z, '_', ' ' only";
169 OUString
sGroup(aGroupName
);
170 if (sGroup
.indexOf(GLOS_DELIM
)<0)
172 sGroup
+= OUStringChar(GLOS_DELIM
) + "0";
174 m_pGlossaries
->NewGroupDoc(sGroup
, sGroup
.getToken(0, GLOS_DELIM
));
176 uno::Reference
< text::XAutoTextGroup
> xGroup
= m_pGlossaries
->GetAutoTextGroup( sGroup
);
177 OSL_ENSURE( xGroup
.is(), "SwXAutoTextContainer::insertNewByName: no UNO object created? How this?" );
178 // We just inserted the group into the glossaries, so why doesn't it exist?
183 void SwXAutoTextContainer::removeByName(const OUString
& aGroupName
)
185 SolarMutexGuard aGuard
;
186 // At first find the name with path extension
187 OUString sGroupName
= m_pGlossaries
->GetCompleteGroupName( aGroupName
);
188 if(sGroupName
.isEmpty())
189 throw container::NoSuchElementException();
190 m_pGlossaries
->DelGroupDoc(sGroupName
);
193 OUString
SwXAutoTextContainer::getImplementationName()
195 return "SwXAutoTextContainer";
198 sal_Bool
SwXAutoTextContainer::supportsService(const OUString
& rServiceName
)
200 return cppu::supportsService(this, rServiceName
);
203 uno::Sequence
< OUString
> SwXAutoTextContainer::getSupportedServiceNames()
205 return { "com.sun.star.text.AutoTextContainer" };
208 SwXAutoTextGroup::SwXAutoTextGroup(const OUString
& rName
,
209 SwGlossaries
* pGlos
) :
210 m_pPropSet(aSwMapProvider
.GetPropertySet(PROPERTY_MAP_AUTO_TEXT_GROUP
)),
211 m_pGlossaries(pGlos
),
215 OSL_ENSURE( -1 != rName
.indexOf( GLOS_DELIM
),
216 "SwXAutoTextGroup::SwXAutoTextGroup: to be constructed with a complete name only!" );
219 SwXAutoTextGroup::~SwXAutoTextGroup()
223 uno::Sequence
< OUString
> SwXAutoTextGroup::getTitles()
225 SolarMutexGuard aGuard
;
226 std::unique_ptr
<SwTextBlocks
> pGlosGroup(m_pGlossaries
? m_pGlossaries
->GetGroupDoc(m_sGroupName
) : nullptr);
227 if (!pGlosGroup
|| pGlosGroup
->GetError())
228 throw uno::RuntimeException();
229 const sal_uInt16 nCount
= pGlosGroup
->GetCount();
231 uno::Sequence
< OUString
> aEntryTitles(nCount
);
232 OUString
*pArr
= aEntryTitles
.getArray();
234 for ( sal_uInt16 i
= 0; i
< nCount
; i
++ )
235 pArr
[i
] = pGlosGroup
->GetLongName(i
);
239 void SwXAutoTextGroup::renameByName(const OUString
& aElementName
,
240 const OUString
& aNewElementName
, const OUString
& aNewElementTitle
)
242 SolarMutexGuard aGuard
;
243 // throw exception only if the programmatic name is to be changed into an existing name
244 if(aNewElementName
!= aElementName
&& hasByName(aNewElementName
))
245 throw container::ElementExistException();
246 std::unique_ptr
<SwTextBlocks
> pGlosGroup(m_pGlossaries
? m_pGlossaries
->GetGroupDoc(m_sGroupName
) : nullptr);
247 if(!pGlosGroup
|| pGlosGroup
->GetError())
248 throw uno::RuntimeException();
250 const sal_uInt16 nIdx
= pGlosGroup
->GetIndex( aElementName
);
251 if(USHRT_MAX
== nIdx
)
252 throw lang::IllegalArgumentException();
253 OUString
aNewShort(aNewElementName
);
254 OUString
aNewName(aNewElementTitle
);
255 sal_uInt16 nOldLongIdx
= pGlosGroup
->GetLongIndex( aNewShort
);
256 sal_uInt16 nOldIdx
= pGlosGroup
->GetIndex( aNewName
);
258 if ((nOldLongIdx
== USHRT_MAX
|| nOldLongIdx
== nIdx
)
259 && (nOldIdx
== USHRT_MAX
|| nOldIdx
== nIdx
))
261 pGlosGroup
->Rename( nIdx
, &aNewShort
, &aNewName
);
262 if(pGlosGroup
->GetError() != ERRCODE_NONE
)
263 throw io::IOException();
268 static bool lcl_CopySelToDoc(SwDoc
& rInsDoc
, OTextCursorHelper
* pxCursor
, SwXTextRange
* pxRange
)
270 SwNodes
& rNds
= rInsDoc
.GetNodes();
272 SwNodeIndex
aIdx( rNds
.GetEndOfContent(), -1 );
273 SwContentNode
* pNd
= aIdx
.GetNode().GetContentNode();
274 SwPosition
aPos(aIdx
, pNd
, pNd
? pNd
->Len() : 0);
277 rInsDoc
.getIDocumentFieldsAccess().LockExpFields();
279 SwDoc
*const pDoc(pxCursor
? pxCursor
->GetDoc() : &pxRange
->GetDoc());
280 SwPaM
aPam(pDoc
->GetNodes());
281 SwPaM
* pPam(nullptr);
284 pPam
= pxCursor
->GetPaM();
288 if (pxRange
->GetPositions(aPam
))
293 if (!pPam
) { return false; }
294 bRet
= pDoc
->getIDocumentContentOperations().CopyRange(*pPam
, aPos
, SwCopyFlags::CheckPosInFly
)
298 rInsDoc
.getIDocumentFieldsAccess().UnlockExpFields();
299 if( !rInsDoc
.getIDocumentFieldsAccess().IsExpFieldsLocked() )
300 rInsDoc
.getIDocumentFieldsAccess().UpdateExpFields(nullptr, true);
305 uno::Reference
< text::XAutoTextEntry
> SwXAutoTextGroup::insertNewByName(const OUString
& aName
,
306 const OUString
& aTitle
, const uno::Reference
< text::XTextRange
> & xTextRange
)
308 SolarMutexGuard aGuard
;
310 throw container::ElementExistException();
312 throw uno::RuntimeException();
314 std::unique_ptr
<SwTextBlocks
> pGlosGroup
;
316 pGlosGroup
= m_pGlossaries
->GetGroupDoc(m_sGroupName
);
317 const OUString
& sShortName(aName
);
318 const OUString
& sLongName(aTitle
);
319 if (pGlosGroup
&& !pGlosGroup
->GetError())
321 SwXTextRange
* pxRange
= dynamic_cast<SwXTextRange
*>(xTextRange
.get());
322 OTextCursorHelper
* pxCursor
= dynamic_cast<OTextCursorHelper
*>(xTextRange
.get());
325 OUString
* pOnlyText
= nullptr;
326 bool bNoAttr
= !pxCursor
&& !pxRange
;
329 sOnlyText
= xTextRange
->getString();
330 pOnlyText
= &sOnlyText
;
333 const SvxAutoCorrCfg
& rCfg
= SvxAutoCorrCfg::Get();
335 SwDoc
* pGDoc
= pGlosGroup
->GetDoc();
337 // Until there is an option for that, delete base util::URL
338 if(rCfg
.IsSaveRelFile())
340 INetURLObject
aTemp(pGlosGroup
->GetFileName());
341 pGlosGroup
->SetBaseURL( aTemp
.GetMainURL(INetURLObject::DecodeMechanism::NONE
));
344 pGlosGroup
->SetBaseURL( OUString() );
346 sal_uInt16 nRet
= USHRT_MAX
;
348 nRet
= pGlosGroup
->PutText( sShortName
, sLongName
, *pOnlyText
);
351 pGlosGroup
->ClearDoc();
352 if( pGlosGroup
->BeginPutDoc( sShortName
, sLongName
) )
354 pGDoc
->getIDocumentRedlineAccess().SetRedlineFlags_intern( RedlineFlags::DeleteRedlines
);
355 lcl_CopySelToDoc(*pGDoc
, pxCursor
, pxRange
);
356 pGDoc
->getIDocumentRedlineAccess().SetRedlineFlags_intern(RedlineFlags::NONE
);
357 nRet
= pGlosGroup
->PutDoc();
361 if (nRet
== USHRT_MAX
)
363 throw uno::RuntimeException();
368 uno::Reference
< text::XAutoTextEntry
> xEntry
;
372 xEntry
= m_pGlossaries
?
373 m_pGlossaries
->GetAutoTextEntry( m_sGroupName
, m_sName
, sShortName
) :
374 uno::Reference
< text::XAutoTextEntry
>();
375 OSL_ENSURE( xEntry
.is(), "SwXAutoTextGroup::insertNewByName: no UNO object created? How this?" );
376 // we just inserted the entry into the group, so why doesn't it exist?
378 catch (const container::ElementExistException
&)
382 catch (const uno::RuntimeException
&)
386 catch (const uno::Exception
&)
388 css::uno::Any anyEx
= cppu::getCaughtException();
389 throw css::lang::WrappedTargetRuntimeException(
390 "Error Getting AutoText!",
391 static_cast < OWeakObject
* > ( this ),
398 void SwXAutoTextGroup::removeByName(const OUString
& aEntryName
)
400 SolarMutexGuard aGuard
;
401 std::unique_ptr
<SwTextBlocks
> pGlosGroup(m_pGlossaries
? m_pGlossaries
->GetGroupDoc(m_sGroupName
) : nullptr);
402 if(!pGlosGroup
|| pGlosGroup
->GetError())
403 throw container::NoSuchElementException();
405 sal_uInt16 nIdx
= pGlosGroup
->GetIndex(aEntryName
);
406 if ( nIdx
== USHRT_MAX
)
407 throw container::NoSuchElementException();
409 pGlosGroup
->Delete(nIdx
);
412 OUString
SwXAutoTextGroup::getName()
414 SolarMutexGuard aGuard
;
418 void SwXAutoTextGroup::setName(const OUString
& rName
)
420 SolarMutexGuard aGuard
;
422 throw uno::RuntimeException();
424 sal_Int32 nNewDelimPos
= rName
.lastIndexOf( GLOS_DELIM
);
425 sal_Int32 nOldDelimPos
= m_sName
.lastIndexOf( GLOS_DELIM
);
428 if (nNewDelimPos
> -1)
429 aNewSuffix
= rName
.copy( nNewDelimPos
+ 1 );
431 if (nOldDelimPos
> -1)
432 aOldSuffix
= m_sName
.copy( nOldDelimPos
+ 1 );
434 sal_Int32 nNewNumeric
= aNewSuffix
.toInt32();
435 sal_Int32 nOldNumeric
= aOldSuffix
.toInt32();
437 OUString
aNewPrefix( (nNewDelimPos
> 1) ? rName
.copy( 0, nNewDelimPos
) : rName
);
438 OUString
aOldPrefix( (nOldDelimPos
> 1) ? m_sName
.copy( 0, nOldDelimPos
) : m_sName
);
440 if ( m_sName
== rName
||
441 ( nNewNumeric
== nOldNumeric
&& aNewPrefix
== aOldPrefix
) )
443 OUString
sNewGroup(rName
);
444 if (sNewGroup
.indexOf(GLOS_DELIM
)<0)
446 sNewGroup
+= OUStringChar(GLOS_DELIM
) + "0";
449 //the name must be saved, the group may be invalidated while in RenameGroupDoc()
450 SwGlossaries
* pTempGlossaries
= m_pGlossaries
;
452 OUString
sPreserveTitle( m_pGlossaries
->GetGroupTitle( m_sName
) );
453 if ( !m_pGlossaries
->RenameGroupDoc( m_sName
, sNewGroup
, sPreserveTitle
) )
454 throw uno::RuntimeException();
456 m_sGroupName
= sNewGroup
;
457 m_pGlossaries
= pTempGlossaries
;
460 sal_Int32
SwXAutoTextGroup::getCount()
462 SolarMutexGuard aGuard
;
463 std::unique_ptr
<SwTextBlocks
> pGlosGroup(m_pGlossaries
? m_pGlossaries
->GetGroupDoc(m_sGroupName
) : nullptr);
464 if (!pGlosGroup
|| pGlosGroup
->GetError())
465 throw uno::RuntimeException();
466 return static_cast<sal_Int32
>(pGlosGroup
->GetCount());
469 uno::Any
SwXAutoTextGroup::getByIndex(sal_Int32 nIndex
)
471 SolarMutexGuard aGuard
;
473 throw uno::RuntimeException();
474 std::unique_ptr
<SwTextBlocks
> pGlosGroup(m_pGlossaries
->GetGroupDoc(m_sGroupName
));
475 if (!pGlosGroup
|| pGlosGroup
->GetError())
476 throw uno::RuntimeException();
477 const sal_uInt16 nCount
= pGlosGroup
->GetCount();
478 if (nIndex
< 0 || o3tl::make_unsigned(nIndex
) >= nCount
)
479 throw lang::IndexOutOfBoundsException();
480 return getByName(pGlosGroup
->GetShortName(o3tl::narrowing
<sal_uInt16
>(nIndex
)));
483 uno::Type
SwXAutoTextGroup::getElementType()
485 return cppu::UnoType
<text::XAutoTextEntry
>::get();
489 sal_Bool
SwXAutoTextGroup::hasElements()
491 SolarMutexGuard aGuard
;
492 std::unique_ptr
<SwTextBlocks
> pGlosGroup(m_pGlossaries
? m_pGlossaries
->GetGroupDoc(m_sGroupName
) : nullptr);
493 if (!pGlosGroup
|| pGlosGroup
->GetError())
494 throw uno::RuntimeException();
495 return pGlosGroup
->GetCount() > 0;
499 uno::Any
SwXAutoTextGroup::getByName(const OUString
& _rName
)
501 SolarMutexGuard aGuard
;
502 uno::Reference
< text::XAutoTextEntry
> xEntry
= m_pGlossaries
->GetAutoTextEntry( m_sGroupName
, m_sName
, _rName
);
503 OSL_ENSURE( xEntry
.is(), "SwXAutoTextGroup::getByName: GetAutoTextEntry is fractious!" );
504 // we told it to create the object, so why didn't it?
505 return css::uno::Any( xEntry
);
508 uno::Sequence
< OUString
> SwXAutoTextGroup::getElementNames()
510 SolarMutexGuard aGuard
;
511 std::unique_ptr
<SwTextBlocks
> pGlosGroup(m_pGlossaries
? m_pGlossaries
->GetGroupDoc(m_sGroupName
) : nullptr);
512 if (!pGlosGroup
|| pGlosGroup
->GetError())
513 throw uno::RuntimeException();
515 const sal_uInt16 nCount
= pGlosGroup
->GetCount();
516 uno::Sequence
< OUString
> aEntryNames(nCount
);
517 OUString
*pArr
= aEntryNames
.getArray();
519 for ( sal_uInt16 i
= 0; i
< nCount
; i
++ )
520 pArr
[i
] = pGlosGroup
->GetShortName(i
);
524 sal_Bool
SwXAutoTextGroup::hasByName(const OUString
& rName
)
526 SolarMutexGuard aGuard
;
528 std::unique_ptr
<SwTextBlocks
> pGlosGroup(m_pGlossaries
? m_pGlossaries
->GetGroupDoc(m_sGroupName
) : nullptr);
529 if (!pGlosGroup
|| pGlosGroup
->GetError())
530 throw uno::RuntimeException();
532 const sal_uInt16 nCount
= pGlosGroup
->GetCount();
533 for( sal_uInt16 i
= 0; i
< nCount
; ++i
)
535 OUString
sCompare(pGlosGroup
->GetShortName(i
));
536 if(sCompare
.equalsIgnoreAsciiCase(rName
))
545 uno::Reference
< beans::XPropertySetInfo
> SwXAutoTextGroup::getPropertySetInfo()
547 static uno::Reference
< beans::XPropertySetInfo
> xRet
= m_pPropSet
->getPropertySetInfo();
551 void SwXAutoTextGroup::setPropertyValue(
552 const OUString
& rPropertyName
, const uno::Any
& aValue
)
554 SolarMutexGuard aGuard
;
555 const SfxItemPropertyMapEntry
* pEntry
= m_pPropSet
->getPropertyMap().getByName( rPropertyName
);
558 throw beans::UnknownPropertyException(rPropertyName
);
560 std::unique_ptr
<SwTextBlocks
> pGlosGroup(m_pGlossaries
? m_pGlossaries
->GetGroupDoc(m_sGroupName
) : nullptr);
561 if(!pGlosGroup
|| pGlosGroup
->GetError())
562 throw uno::RuntimeException();
565 case WID_GROUP_TITLE
:
568 aValue
>>= sNewTitle
;
569 if(sNewTitle
.isEmpty())
570 throw lang::IllegalArgumentException();
571 bool bChanged
= sNewTitle
!= pGlosGroup
->GetName();
572 pGlosGroup
->SetName(sNewTitle
);
573 if(bChanged
&& HasGlossaryList())
574 GetGlossaryList()->ClearGroups();
580 uno::Any
SwXAutoTextGroup::getPropertyValue(const OUString
& rPropertyName
)
582 SolarMutexGuard aGuard
;
583 const SfxItemPropertyMapEntry
* pEntry
= m_pPropSet
->getPropertyMap().getByName( rPropertyName
);
586 throw beans::UnknownPropertyException(rPropertyName
);
587 std::unique_ptr
<SwTextBlocks
> pGlosGroup(m_pGlossaries
? m_pGlossaries
->GetGroupDoc(m_sGroupName
) : nullptr);
588 if(!pGlosGroup
|| pGlosGroup
->GetError())
589 throw uno::RuntimeException();
595 aAny
<<= pGlosGroup
->GetFileName();
597 case WID_GROUP_TITLE
:
598 aAny
<<= pGlosGroup
->GetName();
604 void SwXAutoTextGroup::addPropertyChangeListener(
605 const OUString
& /*PropertyName*/, const uno::Reference
< beans::XPropertyChangeListener
> & /*aListener*/)
609 void SwXAutoTextGroup::removePropertyChangeListener(
610 const OUString
& /*PropertyName*/, const uno::Reference
< beans::XPropertyChangeListener
> & /*aListener*/)
614 void SwXAutoTextGroup::addVetoableChangeListener(
615 const OUString
& /*PropertyName*/, const uno::Reference
< beans::XVetoableChangeListener
> & /*aListener*/)
619 void SwXAutoTextGroup::removeVetoableChangeListener(
620 const OUString
& /*PropertyName*/, const uno::Reference
< beans::XVetoableChangeListener
> & /*aListener*/)
624 void SwXAutoTextGroup::Invalidate()
626 m_pGlossaries
= nullptr;
628 m_sGroupName
.clear();
631 OUString
SwXAutoTextGroup::getImplementationName()
633 return "SwXAutoTextGroup";
636 sal_Bool
SwXAutoTextGroup::supportsService(const OUString
& rServiceName
)
638 return cppu::supportsService(this, rServiceName
);
641 uno::Sequence
< OUString
> SwXAutoTextGroup::getSupportedServiceNames()
643 uno::Sequence
<OUString
> aRet
{ "com.sun.star.text.AutoTextGroup" };
647 SwXAutoTextEntry::SwXAutoTextEntry(SwGlossaries
* pGlss
, OUString aGroupName
,
648 OUString aEntryName
) :
649 m_pGlossaries(pGlss
),
650 m_sGroupName(std::move(aGroupName
)),
651 m_sEntryName(std::move(aEntryName
))
655 SwXAutoTextEntry::~SwXAutoTextEntry()
657 SolarMutexGuard aGuard
;
659 // ensure that any pending modifications are written
660 implFlushDocument( true );
663 void SwXAutoTextEntry::implFlushDocument( bool _bCloseDoc
)
665 if ( !m_xDocSh
.is() )
668 if ( m_xDocSh
->GetDoc()->getIDocumentState().IsModified () )
673 // stop listening at the document
674 EndListening( *m_xDocSh
);
681 void SwXAutoTextEntry::Notify( SfxBroadcaster
& _rBC
, const SfxHint
& _rHint
)
683 if ( &_rBC
!= m_xDocSh
.get() )
687 if (const SfxEventHint
* pEventHint
= dynamic_cast<const SfxEventHint
*>(&_rHint
))
689 if (SfxEventHintId::PrepareCloseDoc
== pEventHint
->GetEventId())
693 EndListening( *m_xDocSh
);
699 if ( SfxHintId::Deinitializing
== _rHint
.GetId() )
701 // our document is dying (possibly because we're shutting down, and the document was notified
702 // earlier than we are?)
703 // stop listening at the docu
704 EndListening( *m_xDocSh
);
705 // and release our reference
711 void SwXAutoTextEntry::GetBodyText ()
713 SolarMutexGuard aGuard
;
715 m_xDocSh
= m_pGlossaries
->EditGroupDoc ( m_sGroupName
, m_sEntryName
, false );
716 OSL_ENSURE( m_xDocSh
.is(), "SwXAutoTextEntry::GetBodyText: unexpected: no doc returned by EditGroupDoc!" );
718 // start listening at the document
719 StartListening( *m_xDocSh
);
721 mxBodyText
= new SwXBodyText ( m_xDocSh
->GetDoc() );
724 void SwXAutoTextEntry::disposing(std::unique_lock
<std::mutex
>&)
727 implFlushDocument(true);
730 uno::Reference
< text::XTextCursor
> SwXAutoTextEntry::createTextCursor()
732 SolarMutexGuard aGuard
;
734 return mxBodyText
->createTextCursor();
737 uno::Reference
< text::XTextCursor
> SwXAutoTextEntry::createTextCursorByRange(
738 const uno::Reference
< text::XTextRange
> & aTextPosition
)
740 SolarMutexGuard aGuard
;
742 return mxBodyText
->createTextCursorByRange ( aTextPosition
);
745 void SwXAutoTextEntry::insertString(const uno::Reference
< text::XTextRange
> & xRange
, const OUString
& aString
, sal_Bool bAbsorb
)
747 SolarMutexGuard aGuard
;
749 mxBodyText
->insertString ( xRange
, aString
, bAbsorb
);
752 void SwXAutoTextEntry::insertControlCharacter(const uno::Reference
< text::XTextRange
> & xRange
,
753 sal_Int16 nControlCharacter
, sal_Bool bAbsorb
)
755 SolarMutexGuard aGuard
;
757 mxBodyText
->insertControlCharacter ( xRange
, nControlCharacter
, bAbsorb
);
760 void SwXAutoTextEntry::insertTextContent(
761 const uno::Reference
< text::XTextRange
> & xRange
,
762 const uno::Reference
< text::XTextContent
> & xContent
, sal_Bool bAbsorb
)
764 SolarMutexGuard aGuard
;
766 mxBodyText
->insertTextContent ( xRange
, xContent
, bAbsorb
);
769 void SwXAutoTextEntry::removeTextContent(
770 const uno::Reference
< text::XTextContent
> & xContent
)
772 SolarMutexGuard aGuard
;
774 mxBodyText
->removeTextContent ( xContent
);
777 uno::Reference
< text::XText
> SwXAutoTextEntry::getText()
779 SolarMutexGuard aGuard
;
780 uno::Reference
< text::XText
> xRet
= static_cast<text::XText
*>(this);
784 uno::Reference
< text::XTextRange
> SwXAutoTextEntry::getStart()
786 SolarMutexGuard aGuard
;
788 return mxBodyText
->getStart();
791 uno::Reference
< text::XTextRange
> SwXAutoTextEntry::getEnd()
793 SolarMutexGuard aGuard
;
795 return mxBodyText
->getEnd();
798 OUString
SwXAutoTextEntry::getString()
800 SolarMutexGuard aGuard
;
802 return mxBodyText
->getString();
805 void SwXAutoTextEntry::setString(const OUString
& aString
)
807 SolarMutexGuard aGuard
;
809 mxBodyText
->setString( aString
);
812 void SwXAutoTextEntry::applyTo(const uno::Reference
< text::XTextRange
> & xTextRange
)
814 SolarMutexGuard aGuard
;
816 // ensure that any pending modifications are written
817 // reason is that we're holding the _copy_ of the auto text, while the real auto text
818 // is stored somewhere. And below, we're not working with our copy, but only tell the target
819 // TextRange to work with the stored version.
820 // #96380# - 2003-03-03 - fs@openoffice.org
822 // TODO: think about if we should pass "true" here
823 // The difference would be that when the next modification is made to this instance here, then
824 // we would be forced to open the document again, instead of working on our current copy.
825 // This means that we would reflect any changes which were done to the AutoText by foreign instances
828 // The reference to xKeepAlive is needed during the whole call, likely because it could be a
829 // different object, not xTextRange itself, and the reference guards it from preliminary death
830 auto xKeepAlive( xTextRange
);
831 SwXTextRange
* pRange
= dynamic_cast<SwXTextRange
*>(xTextRange
.get());
832 OTextCursorHelper
* pCursor
= dynamic_cast<OTextCursorHelper
*>(xTextRange
.get());
833 SwXText
*pText
= dynamic_cast<SwXText
*>(xTextRange
.get());
835 SwDoc
* pDoc
= nullptr;
837 pDoc
= &pRange
->GetDoc();
839 pDoc
= pCursor
->GetDoc();
840 else if ( pText
&& pText
->GetDoc() )
842 xKeepAlive
= pText
->getStart();
843 pCursor
= dynamic_cast<OTextCursorHelper
*>(xKeepAlive
.get());
845 pDoc
= pText
->GetDoc();
849 throw uno::RuntimeException();
851 SwPaM
InsertPaM(pDoc
->GetNodes());
854 if (!pRange
->GetPositions(InsertPaM
))
856 throw uno::RuntimeException();
861 InsertPaM
= *pCursor
->GetPaM();
864 std::unique_ptr
<SwTextBlocks
> pBlock(m_pGlossaries
->GetGroupDoc(m_sGroupName
));
865 const bool bResult
= pBlock
&& !pBlock
->GetError()
866 && pDoc
->InsertGlossary( *pBlock
, m_sEntryName
, InsertPaM
);
869 throw uno::RuntimeException();
872 OUString
SwXAutoTextEntry::getImplementationName()
874 return "SwXAutoTextEntry";
877 sal_Bool
SwXAutoTextEntry::supportsService(const OUString
& rServiceName
)
879 return cppu::supportsService(this, rServiceName
);
882 uno::Sequence
< OUString
> SwXAutoTextEntry::getSupportedServiceNames()
884 uno::Sequence
<OUString
> aRet
{ "com.sun.star.text.AutoTextEntry" };
888 uno::Reference
< container::XNameReplace
> SwXAutoTextEntry::getEvents()
890 return new SwAutoTextEventDescriptor( *this );
893 const struct SvEventDescription aAutotextEvents
[] =
895 { SvMacroItemId::SwStartInsGlossary
, "OnInsertStart" },
896 { SvMacroItemId::SwEndInsGlossary
, "OnInsertDone" },
897 { SvMacroItemId::NONE
, nullptr }
900 SwAutoTextEventDescriptor::SwAutoTextEventDescriptor(
901 SwXAutoTextEntry
& rAutoText
) :
902 SvBaseEventDescriptor(aAutotextEvents
),
903 m_rAutoTextEntry(rAutoText
)
907 SwAutoTextEventDescriptor::~SwAutoTextEventDescriptor()
911 OUString
SwAutoTextEventDescriptor::getImplementationName()
913 return "SwAutoTextEventDescriptor";
916 void SwAutoTextEventDescriptor::replaceByName(
917 const SvMacroItemId nEvent
,
918 const SvxMacro
& rMacro
)
920 OSL_ENSURE( nullptr != m_rAutoTextEntry
.GetGlossaries(),
921 "Strangely enough, the AutoText vanished!" );
922 OSL_ENSURE( (nEvent
== SvMacroItemId::SwEndInsGlossary
) ||
923 (nEvent
== SvMacroItemId::SwStartInsGlossary
) ,
924 "Unknown event ID" );
926 SwGlossaries
*const pGlossaries
=
927 const_cast<SwGlossaries
*>(m_rAutoTextEntry
.GetGlossaries());
928 std::unique_ptr
<SwTextBlocks
> pBlocks(
929 pGlossaries
->GetGroupDoc( m_rAutoTextEntry
.GetGroupName() ));
931 "can't get autotext group; SwAutoTextEntry has illegal name?");
933 if( !pBlocks
|| pBlocks
->GetError())
936 sal_uInt16 nIndex
= pBlocks
->GetIndex( m_rAutoTextEntry
.GetEntryName() );
937 if( nIndex
!= USHRT_MAX
)
939 SvxMacroTableDtor aMacroTable
;
940 if( pBlocks
->GetMacroTable( nIndex
, aMacroTable
) )
942 aMacroTable
.Insert( nEvent
, rMacro
);
943 pBlocks
->SetMacroTable( nIndex
, aMacroTable
);
949 void SwAutoTextEventDescriptor::getByName(
951 const SvMacroItemId nEvent
)
953 OSL_ENSURE( nullptr != m_rAutoTextEntry
.GetGlossaries(), "no AutoText" );
954 OSL_ENSURE( (nEvent
== SvMacroItemId::SwEndInsGlossary
) ||
955 (nEvent
== SvMacroItemId::SwStartInsGlossary
) ,
956 "Unknown event ID" );
958 SwGlossaries
*const pGlossaries
=
959 const_cast<SwGlossaries
*>(m_rAutoTextEntry
.GetGlossaries());
960 std::unique_ptr
<SwTextBlocks
> pBlocks(
961 pGlossaries
->GetGroupDoc( m_rAutoTextEntry
.GetGroupName() ));
963 "can't get autotext group; SwAutoTextEntry has illegal name?");
965 // return empty macro, unless macro is found
967 SvxMacro
aEmptyMacro(sEmptyStr
, sEmptyStr
);
968 rMacro
= aEmptyMacro
;
970 if ( !pBlocks
|| pBlocks
->GetError())
973 sal_uInt16 nIndex
= pBlocks
->GetIndex( m_rAutoTextEntry
.GetEntryName() );
974 if( nIndex
!= USHRT_MAX
)
976 SvxMacroTableDtor aMacroTable
;
977 if( pBlocks
->GetMacroTable( nIndex
, aMacroTable
) )
979 SvxMacro
*pMacro
= aMacroTable
.Get( nEvent
);
986 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
987 SwXAutoTextContainer_get_implementation(css::uno::XComponentContext
*,
988 css::uno::Sequence
<css::uno::Any
> const &)
990 //the module may not be loaded
991 SolarMutexGuard aGuard
;
993 return cppu::acquire(new SwXAutoTextContainer());
996 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */