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 throw lang::IllegalArgumentException(u
"group name must not be empty"_ustr
, nullptr, 0);
153 for(sal_Int32 nPos
= 0; nPos
< aGroupName
.getLength(); nPos
++)
155 sal_Unicode cChar
= aGroupName
[nPos
];
156 if (rtl::isAsciiAlphanumeric(cChar
) ||
159 (cChar
== GLOS_DELIM
) )
163 throw lang::IllegalArgumentException(u
"group name must contain a-z, A-z, '_', ' ' only"_ustr
, nullptr, 0);
165 OUString
sGroup(aGroupName
);
166 if (sGroup
.indexOf(GLOS_DELIM
)<0)
168 sGroup
+= OUStringChar(GLOS_DELIM
) + "0";
170 m_pGlossaries
->NewGroupDoc(sGroup
, sGroup
.getToken(0, GLOS_DELIM
));
172 uno::Reference
< text::XAutoTextGroup
> xGroup
= m_pGlossaries
->GetAutoTextGroup( sGroup
);
173 OSL_ENSURE( xGroup
.is(), "SwXAutoTextContainer::insertNewByName: no UNO object created? How this?" );
174 // We just inserted the group into the glossaries, so why doesn't it exist?
179 void SwXAutoTextContainer::removeByName(const OUString
& aGroupName
)
181 SolarMutexGuard aGuard
;
182 // At first find the name with path extension
183 OUString sGroupName
= m_pGlossaries
->GetCompleteGroupName( aGroupName
);
184 if(sGroupName
.isEmpty())
185 throw container::NoSuchElementException();
186 m_pGlossaries
->DelGroupDoc(sGroupName
);
189 OUString
SwXAutoTextContainer::getImplementationName()
191 return u
"SwXAutoTextContainer"_ustr
;
194 sal_Bool
SwXAutoTextContainer::supportsService(const OUString
& rServiceName
)
196 return cppu::supportsService(this, rServiceName
);
199 uno::Sequence
< OUString
> SwXAutoTextContainer::getSupportedServiceNames()
201 return { u
"com.sun.star.text.AutoTextContainer"_ustr
};
204 SwXAutoTextGroup::SwXAutoTextGroup(const OUString
& rName
,
205 SwGlossaries
* pGlos
) :
206 m_pPropSet(aSwMapProvider
.GetPropertySet(PROPERTY_MAP_AUTO_TEXT_GROUP
)),
207 m_pGlossaries(pGlos
),
211 OSL_ENSURE( -1 != rName
.indexOf( GLOS_DELIM
),
212 "SwXAutoTextGroup::SwXAutoTextGroup: to be constructed with a complete name only!" );
215 SwXAutoTextGroup::~SwXAutoTextGroup()
219 uno::Sequence
< OUString
> SwXAutoTextGroup::getTitles()
221 SolarMutexGuard aGuard
;
222 std::unique_ptr
<SwTextBlocks
> pGlosGroup(m_pGlossaries
? m_pGlossaries
->GetGroupDoc(m_sGroupName
) : nullptr);
223 if (!pGlosGroup
|| pGlosGroup
->GetError())
224 throw uno::RuntimeException();
225 const sal_uInt16 nCount
= pGlosGroup
->GetCount();
227 uno::Sequence
< OUString
> aEntryTitles(nCount
);
228 OUString
*pArr
= aEntryTitles
.getArray();
230 for ( sal_uInt16 i
= 0; i
< nCount
; i
++ )
231 pArr
[i
] = pGlosGroup
->GetLongName(i
);
235 void SwXAutoTextGroup::renameByName(const OUString
& aElementName
,
236 const OUString
& aNewElementName
, const OUString
& aNewElementTitle
)
238 SolarMutexGuard aGuard
;
239 // throw exception only if the programmatic name is to be changed into an existing name
240 if(aNewElementName
!= aElementName
&& hasByName(aNewElementName
))
241 throw container::ElementExistException();
242 std::unique_ptr
<SwTextBlocks
> pGlosGroup(m_pGlossaries
? m_pGlossaries
->GetGroupDoc(m_sGroupName
) : nullptr);
243 if(!pGlosGroup
|| pGlosGroup
->GetError())
244 throw uno::RuntimeException();
246 const sal_uInt16 nIdx
= pGlosGroup
->GetIndex( aElementName
);
247 if(USHRT_MAX
== nIdx
)
248 throw lang::IllegalArgumentException();
249 const OUString
& aNewShort(aNewElementName
);
250 const OUString
& aNewName(aNewElementTitle
);
251 sal_uInt16 nOldLongIdx
= pGlosGroup
->GetLongIndex( aNewShort
);
252 sal_uInt16 nOldIdx
= pGlosGroup
->GetIndex( aNewName
);
254 if ((nOldLongIdx
== USHRT_MAX
|| nOldLongIdx
== nIdx
)
255 && (nOldIdx
== USHRT_MAX
|| nOldIdx
== nIdx
))
257 pGlosGroup
->Rename( nIdx
, &aNewShort
, &aNewName
);
258 if(pGlosGroup
->GetError() != ERRCODE_NONE
)
259 throw io::IOException();
264 static bool lcl_CopySelToDoc(SwDoc
& rInsDoc
, OTextCursorHelper
* pxCursor
, SwXTextRange
* pxRange
)
266 SwNodes
& rNds
= rInsDoc
.GetNodes();
268 SwNodeIndex
aIdx( rNds
.GetEndOfContent(), -1 );
269 SwContentNode
* pNd
= aIdx
.GetNode().GetContentNode();
270 SwPosition
aPos(aIdx
, pNd
, pNd
? pNd
->Len() : 0);
273 rInsDoc
.getIDocumentFieldsAccess().LockExpFields();
275 SwDoc
*const pDoc(pxCursor
? pxCursor
->GetDoc() : &pxRange
->GetDoc());
276 SwPaM
aPam(pDoc
->GetNodes());
277 SwPaM
* pPam(nullptr);
280 pPam
= pxCursor
->GetPaM();
284 if (pxRange
->GetPositions(aPam
))
289 if (!pPam
) { return false; }
290 bRet
= pDoc
->getIDocumentContentOperations().CopyRange(*pPam
, aPos
, SwCopyFlags::CheckPosInFly
)
294 rInsDoc
.getIDocumentFieldsAccess().UnlockExpFields();
295 if( !rInsDoc
.getIDocumentFieldsAccess().IsExpFieldsLocked() )
296 rInsDoc
.getIDocumentFieldsAccess().UpdateExpFields(nullptr, true);
301 uno::Reference
< text::XAutoTextEntry
> SwXAutoTextGroup::insertNewByName(const OUString
& aName
,
302 const OUString
& aTitle
, const uno::Reference
< text::XTextRange
> & xTextRange
)
304 SolarMutexGuard aGuard
;
306 throw container::ElementExistException();
308 throw uno::RuntimeException();
310 std::unique_ptr
<SwTextBlocks
> pGlosGroup
;
312 pGlosGroup
= m_pGlossaries
->GetGroupDoc(m_sGroupName
);
313 const OUString
& sShortName(aName
);
314 const OUString
& sLongName(aTitle
);
315 if (pGlosGroup
&& !pGlosGroup
->GetError())
317 SwXTextRange
* pxRange
= dynamic_cast<SwXTextRange
*>(xTextRange
.get());
318 OTextCursorHelper
* pxCursor
= dynamic_cast<OTextCursorHelper
*>(xTextRange
.get());
321 OUString
* pOnlyText
= nullptr;
322 bool bNoAttr
= !pxCursor
&& !pxRange
;
325 sOnlyText
= xTextRange
->getString();
326 pOnlyText
= &sOnlyText
;
329 const SvxAutoCorrCfg
& rCfg
= SvxAutoCorrCfg::Get();
331 SwDoc
* pGDoc
= pGlosGroup
->GetDoc();
333 // Until there is an option for that, delete base util::URL
334 if(rCfg
.IsSaveRelFile())
336 INetURLObject
aTemp(pGlosGroup
->GetFileName());
337 pGlosGroup
->SetBaseURL( aTemp
.GetMainURL(INetURLObject::DecodeMechanism::NONE
));
340 pGlosGroup
->SetBaseURL( OUString() );
342 sal_uInt16 nRet
= USHRT_MAX
;
344 nRet
= pGlosGroup
->PutText( sShortName
, sLongName
, *pOnlyText
);
347 pGlosGroup
->ClearDoc();
348 if( pGlosGroup
->BeginPutDoc( sShortName
, sLongName
) )
350 pGDoc
->getIDocumentRedlineAccess().SetRedlineFlags_intern( RedlineFlags::DeleteRedlines
);
351 lcl_CopySelToDoc(*pGDoc
, pxCursor
, pxRange
);
352 pGDoc
->getIDocumentRedlineAccess().SetRedlineFlags_intern(RedlineFlags::NONE
);
353 nRet
= pGlosGroup
->PutDoc();
357 if (nRet
== USHRT_MAX
)
359 throw uno::RuntimeException();
364 uno::Reference
< text::XAutoTextEntry
> xEntry
;
368 xEntry
= m_pGlossaries
?
369 m_pGlossaries
->GetAutoTextEntry( m_sGroupName
, m_sName
, sShortName
) :
370 uno::Reference
< text::XAutoTextEntry
>();
371 OSL_ENSURE( xEntry
.is(), "SwXAutoTextGroup::insertNewByName: no UNO object created? How this?" );
372 // we just inserted the entry into the group, so why doesn't it exist?
374 catch (const container::ElementExistException
&)
378 catch (const uno::RuntimeException
&)
382 catch (const uno::Exception
&)
384 css::uno::Any anyEx
= cppu::getCaughtException();
385 throw css::lang::WrappedTargetRuntimeException(
386 u
"Error Getting AutoText!"_ustr
,
394 void SwXAutoTextGroup::removeByName(const OUString
& aEntryName
)
396 SolarMutexGuard aGuard
;
397 std::unique_ptr
<SwTextBlocks
> pGlosGroup(m_pGlossaries
? m_pGlossaries
->GetGroupDoc(m_sGroupName
) : nullptr);
398 if(!pGlosGroup
|| pGlosGroup
->GetError())
399 throw container::NoSuchElementException();
401 sal_uInt16 nIdx
= pGlosGroup
->GetIndex(aEntryName
);
402 if ( nIdx
== USHRT_MAX
)
403 throw container::NoSuchElementException();
405 pGlosGroup
->Delete(nIdx
);
408 OUString
SwXAutoTextGroup::getName()
410 SolarMutexGuard aGuard
;
414 void SwXAutoTextGroup::setName(const OUString
& rName
)
416 SolarMutexGuard aGuard
;
418 throw uno::RuntimeException();
420 sal_Int32 nNewDelimPos
= rName
.lastIndexOf( GLOS_DELIM
);
421 sal_Int32 nOldDelimPos
= m_sName
.lastIndexOf( GLOS_DELIM
);
424 if (nNewDelimPos
> -1)
425 aNewSuffix
= rName
.copy( nNewDelimPos
+ 1 );
427 if (nOldDelimPos
> -1)
428 aOldSuffix
= m_sName
.copy( nOldDelimPos
+ 1 );
430 sal_Int32 nNewNumeric
= aNewSuffix
.toInt32();
431 sal_Int32 nOldNumeric
= aOldSuffix
.toInt32();
433 OUString
aNewPrefix( (nNewDelimPos
> 1) ? rName
.copy( 0, nNewDelimPos
) : rName
);
434 OUString
aOldPrefix( (nOldDelimPos
> 1) ? m_sName
.copy( 0, nOldDelimPos
) : m_sName
);
436 if ( m_sName
== rName
||
437 ( nNewNumeric
== nOldNumeric
&& aNewPrefix
== aOldPrefix
) )
439 OUString
sNewGroup(rName
);
440 if (sNewGroup
.indexOf(GLOS_DELIM
)<0)
442 sNewGroup
+= OUStringChar(GLOS_DELIM
) + "0";
445 //the name must be saved, the group may be invalidated while in RenameGroupDoc()
446 SwGlossaries
* pTempGlossaries
= m_pGlossaries
;
448 OUString
sPreserveTitle( m_pGlossaries
->GetGroupTitle( m_sName
) );
449 if ( !m_pGlossaries
->RenameGroupDoc( m_sName
, sNewGroup
, sPreserveTitle
) )
450 throw uno::RuntimeException();
452 m_sGroupName
= sNewGroup
;
453 m_pGlossaries
= pTempGlossaries
;
456 sal_Int32
SwXAutoTextGroup::getCount()
458 SolarMutexGuard aGuard
;
459 std::unique_ptr
<SwTextBlocks
> pGlosGroup(m_pGlossaries
? m_pGlossaries
->GetGroupDoc(m_sGroupName
) : nullptr);
460 if (!pGlosGroup
|| pGlosGroup
->GetError())
461 throw uno::RuntimeException();
462 return static_cast<sal_Int32
>(pGlosGroup
->GetCount());
465 uno::Any
SwXAutoTextGroup::getByIndex(sal_Int32 nIndex
)
467 SolarMutexGuard aGuard
;
469 throw uno::RuntimeException();
470 std::unique_ptr
<SwTextBlocks
> pGlosGroup(m_pGlossaries
->GetGroupDoc(m_sGroupName
));
471 if (!pGlosGroup
|| pGlosGroup
->GetError())
472 throw uno::RuntimeException();
473 const sal_uInt16 nCount
= pGlosGroup
->GetCount();
474 if (nIndex
< 0 || o3tl::make_unsigned(nIndex
) >= nCount
)
475 throw lang::IndexOutOfBoundsException();
476 return getByName(pGlosGroup
->GetShortName(o3tl::narrowing
<sal_uInt16
>(nIndex
)));
479 uno::Type
SwXAutoTextGroup::getElementType()
481 return cppu::UnoType
<text::XAutoTextEntry
>::get();
485 sal_Bool
SwXAutoTextGroup::hasElements()
487 SolarMutexGuard aGuard
;
488 std::unique_ptr
<SwTextBlocks
> pGlosGroup(m_pGlossaries
? m_pGlossaries
->GetGroupDoc(m_sGroupName
) : nullptr);
489 if (!pGlosGroup
|| pGlosGroup
->GetError())
490 throw uno::RuntimeException();
491 return pGlosGroup
->GetCount() > 0;
495 uno::Any
SwXAutoTextGroup::getByName(const OUString
& _rName
)
497 SolarMutexGuard aGuard
;
498 uno::Reference
< text::XAutoTextEntry
> xEntry
= m_pGlossaries
->GetAutoTextEntry( m_sGroupName
, m_sName
, _rName
);
499 OSL_ENSURE( xEntry
.is(), "SwXAutoTextGroup::getByName: GetAutoTextEntry is fractious!" );
500 // we told it to create the object, so why didn't it?
501 return css::uno::Any( xEntry
);
504 uno::Sequence
< OUString
> SwXAutoTextGroup::getElementNames()
506 SolarMutexGuard aGuard
;
507 std::unique_ptr
<SwTextBlocks
> pGlosGroup(m_pGlossaries
? m_pGlossaries
->GetGroupDoc(m_sGroupName
) : nullptr);
508 if (!pGlosGroup
|| pGlosGroup
->GetError())
509 throw uno::RuntimeException();
511 const sal_uInt16 nCount
= pGlosGroup
->GetCount();
512 uno::Sequence
< OUString
> aEntryNames(nCount
);
513 OUString
*pArr
= aEntryNames
.getArray();
515 for ( sal_uInt16 i
= 0; i
< nCount
; i
++ )
516 pArr
[i
] = pGlosGroup
->GetShortName(i
);
520 sal_Bool
SwXAutoTextGroup::hasByName(const OUString
& rName
)
522 SolarMutexGuard aGuard
;
524 std::unique_ptr
<SwTextBlocks
> pGlosGroup(m_pGlossaries
? m_pGlossaries
->GetGroupDoc(m_sGroupName
) : nullptr);
525 if (!pGlosGroup
|| pGlosGroup
->GetError())
526 throw uno::RuntimeException();
528 const sal_uInt16 nCount
= pGlosGroup
->GetCount();
529 for( sal_uInt16 i
= 0; i
< nCount
; ++i
)
531 OUString
sCompare(pGlosGroup
->GetShortName(i
));
532 if(sCompare
.equalsIgnoreAsciiCase(rName
))
541 uno::Reference
< beans::XPropertySetInfo
> SwXAutoTextGroup::getPropertySetInfo()
543 static uno::Reference
< beans::XPropertySetInfo
> xRet
= m_pPropSet
->getPropertySetInfo();
547 void SwXAutoTextGroup::setPropertyValue(
548 const OUString
& rPropertyName
, const uno::Any
& aValue
)
550 SolarMutexGuard aGuard
;
551 const SfxItemPropertyMapEntry
* pEntry
= m_pPropSet
->getPropertyMap().getByName( rPropertyName
);
554 throw beans::UnknownPropertyException(rPropertyName
);
556 std::unique_ptr
<SwTextBlocks
> pGlosGroup(m_pGlossaries
? m_pGlossaries
->GetGroupDoc(m_sGroupName
) : nullptr);
557 if(!pGlosGroup
|| pGlosGroup
->GetError())
558 throw uno::RuntimeException();
561 case WID_GROUP_TITLE
:
564 aValue
>>= sNewTitle
;
565 if(sNewTitle
.isEmpty())
566 throw lang::IllegalArgumentException();
567 bool bChanged
= sNewTitle
!= pGlosGroup
->GetName();
568 pGlosGroup
->SetName(sNewTitle
);
569 if(bChanged
&& HasGlossaryList())
570 GetGlossaryList()->ClearGroups();
576 uno::Any
SwXAutoTextGroup::getPropertyValue(const OUString
& rPropertyName
)
578 SolarMutexGuard aGuard
;
579 const SfxItemPropertyMapEntry
* pEntry
= m_pPropSet
->getPropertyMap().getByName( rPropertyName
);
582 throw beans::UnknownPropertyException(rPropertyName
);
583 std::unique_ptr
<SwTextBlocks
> pGlosGroup(m_pGlossaries
? m_pGlossaries
->GetGroupDoc(m_sGroupName
) : nullptr);
584 if(!pGlosGroup
|| pGlosGroup
->GetError())
585 throw uno::RuntimeException();
591 aAny
<<= pGlosGroup
->GetFileName();
593 case WID_GROUP_TITLE
:
594 aAny
<<= pGlosGroup
->GetName();
600 void SwXAutoTextGroup::addPropertyChangeListener(
601 const OUString
& /*PropertyName*/, const uno::Reference
< beans::XPropertyChangeListener
> & /*aListener*/)
605 void SwXAutoTextGroup::removePropertyChangeListener(
606 const OUString
& /*PropertyName*/, const uno::Reference
< beans::XPropertyChangeListener
> & /*aListener*/)
610 void SwXAutoTextGroup::addVetoableChangeListener(
611 const OUString
& /*PropertyName*/, const uno::Reference
< beans::XVetoableChangeListener
> & /*aListener*/)
615 void SwXAutoTextGroup::removeVetoableChangeListener(
616 const OUString
& /*PropertyName*/, const uno::Reference
< beans::XVetoableChangeListener
> & /*aListener*/)
620 void SwXAutoTextGroup::Invalidate()
622 m_pGlossaries
= nullptr;
624 m_sGroupName
.clear();
627 OUString
SwXAutoTextGroup::getImplementationName()
629 return u
"SwXAutoTextGroup"_ustr
;
632 sal_Bool
SwXAutoTextGroup::supportsService(const OUString
& rServiceName
)
634 return cppu::supportsService(this, rServiceName
);
637 uno::Sequence
< OUString
> SwXAutoTextGroup::getSupportedServiceNames()
639 uno::Sequence
<OUString
> aRet
{ u
"com.sun.star.text.AutoTextGroup"_ustr
};
643 SwXAutoTextEntry::SwXAutoTextEntry(SwGlossaries
* pGlss
, OUString aGroupName
,
644 OUString aEntryName
) :
645 m_pGlossaries(pGlss
),
646 m_sGroupName(std::move(aGroupName
)),
647 m_sEntryName(std::move(aEntryName
))
651 SwXAutoTextEntry::~SwXAutoTextEntry()
653 SolarMutexGuard aGuard
;
655 // ensure that any pending modifications are written
656 implFlushDocument( true );
659 void SwXAutoTextEntry::implFlushDocument( bool _bCloseDoc
)
661 if ( !m_xDocSh
.is() )
664 if ( m_xDocSh
->GetDoc()->getIDocumentState().IsModified () )
669 // stop listening at the document
670 EndListening( *m_xDocSh
);
677 void SwXAutoTextEntry::Notify( SfxBroadcaster
& _rBC
, const SfxHint
& _rHint
)
679 if ( &_rBC
!= m_xDocSh
.get() )
683 if (_rHint
.GetId() == SfxHintId::ThisIsAnSfxEventHint
)
685 const SfxEventHint
& rEventHint
= static_cast<const SfxEventHint
&>(_rHint
);
686 if (SfxEventHintId::PrepareCloseDoc
== rEventHint
.GetEventId())
690 EndListening( *m_xDocSh
);
696 if ( SfxHintId::Deinitializing
== _rHint
.GetId() )
698 // our document is dying (possibly because we're shutting down, and the document was notified
699 // earlier than we are?)
700 // stop listening at the docu
701 EndListening( *m_xDocSh
);
702 // and release our reference
708 void SwXAutoTextEntry::GetBodyText ()
710 SolarMutexGuard aGuard
;
712 m_xDocSh
= m_pGlossaries
->EditGroupDoc ( m_sGroupName
, m_sEntryName
, false );
713 OSL_ENSURE( m_xDocSh
.is(), "SwXAutoTextEntry::GetBodyText: unexpected: no doc returned by EditGroupDoc!" );
715 // start listening at the document
716 StartListening( *m_xDocSh
);
718 mxBodyText
= new SwXBodyText ( m_xDocSh
->GetDoc() );
721 void SwXAutoTextEntry::disposing(std::unique_lock
<std::mutex
>&)
724 implFlushDocument(true);
727 uno::Reference
< text::XTextCursor
> SwXAutoTextEntry::createTextCursor()
729 SolarMutexGuard aGuard
;
731 return mxBodyText
->createTextCursor();
734 uno::Reference
< text::XTextCursor
> SwXAutoTextEntry::createTextCursorByRange(
735 const uno::Reference
< text::XTextRange
> & aTextPosition
)
737 SolarMutexGuard aGuard
;
739 return mxBodyText
->createTextCursorByRange ( aTextPosition
);
742 void SwXAutoTextEntry::insertString(const uno::Reference
< text::XTextRange
> & xRange
, const OUString
& aString
, sal_Bool bAbsorb
)
744 SolarMutexGuard aGuard
;
746 mxBodyText
->insertString ( xRange
, aString
, bAbsorb
);
749 void SwXAutoTextEntry::insertControlCharacter(const uno::Reference
< text::XTextRange
> & xRange
,
750 sal_Int16 nControlCharacter
, sal_Bool bAbsorb
)
752 SolarMutexGuard aGuard
;
754 mxBodyText
->insertControlCharacter ( xRange
, nControlCharacter
, bAbsorb
);
757 void SwXAutoTextEntry::insertTextContent(
758 const uno::Reference
< text::XTextRange
> & xRange
,
759 const uno::Reference
< text::XTextContent
> & xContent
, sal_Bool bAbsorb
)
761 SolarMutexGuard aGuard
;
763 mxBodyText
->insertTextContent ( xRange
, xContent
, bAbsorb
);
766 void SwXAutoTextEntry::removeTextContent(
767 const uno::Reference
< text::XTextContent
> & xContent
)
769 SolarMutexGuard aGuard
;
771 mxBodyText
->removeTextContent ( xContent
);
774 uno::Reference
< text::XText
> SwXAutoTextEntry::getText()
776 SolarMutexGuard aGuard
;
777 uno::Reference
< text::XText
> xRet
= static_cast<text::XText
*>(this);
781 uno::Reference
< text::XTextRange
> SwXAutoTextEntry::getStart()
783 SolarMutexGuard aGuard
;
785 return mxBodyText
->getStart();
788 uno::Reference
< text::XTextRange
> SwXAutoTextEntry::getEnd()
790 SolarMutexGuard aGuard
;
792 return mxBodyText
->getEnd();
795 OUString
SwXAutoTextEntry::getString()
797 SolarMutexGuard aGuard
;
799 return mxBodyText
->getString();
802 void SwXAutoTextEntry::setString(const OUString
& aString
)
804 SolarMutexGuard aGuard
;
806 mxBodyText
->setString( aString
);
809 void SwXAutoTextEntry::applyTo(const uno::Reference
< text::XTextRange
> & xTextRange
)
811 SolarMutexGuard aGuard
;
813 // ensure that any pending modifications are written
814 // reason is that we're holding the _copy_ of the auto text, while the real auto text
815 // is stored somewhere. And below, we're not working with our copy, but only tell the target
816 // TextRange to work with the stored version.
817 // #96380# - 2003-03-03 - fs@openoffice.org
819 // TODO: think about if we should pass "true" here
820 // The difference would be that when the next modification is made to this instance here, then
821 // we would be forced to open the document again, instead of working on our current copy.
822 // This means that we would reflect any changes which were done to the AutoText by foreign instances
825 // The reference to xKeepAlive is needed during the whole call, likely because it could be a
826 // different object, not xTextRange itself, and the reference guards it from preliminary death
827 auto xKeepAlive( xTextRange
);
828 SwXTextRange
* pRange
= dynamic_cast<SwXTextRange
*>(xTextRange
.get());
829 OTextCursorHelper
* pCursor
= dynamic_cast<OTextCursorHelper
*>(xTextRange
.get());
830 SwXText
*pText
= dynamic_cast<SwXText
*>(xTextRange
.get());
832 SwDoc
* pDoc
= nullptr;
834 pDoc
= &pRange
->GetDoc();
836 pDoc
= pCursor
->GetDoc();
837 else if ( pText
&& pText
->GetDoc() )
839 xKeepAlive
= pText
->getStart();
840 pCursor
= dynamic_cast<OTextCursorHelper
*>(xKeepAlive
.get());
842 pDoc
= pText
->GetDoc();
846 throw uno::RuntimeException();
848 SwPaM
InsertPaM(pDoc
->GetNodes());
851 if (!pRange
->GetPositions(InsertPaM
))
853 throw uno::RuntimeException();
858 InsertPaM
= *pCursor
->GetPaM();
861 std::unique_ptr
<SwTextBlocks
> pBlock(m_pGlossaries
->GetGroupDoc(m_sGroupName
));
862 const bool bResult
= pBlock
&& !pBlock
->GetError()
863 && pDoc
->InsertGlossary( *pBlock
, m_sEntryName
, InsertPaM
);
866 throw uno::RuntimeException();
869 OUString
SwXAutoTextEntry::getImplementationName()
871 return u
"SwXAutoTextEntry"_ustr
;
874 sal_Bool
SwXAutoTextEntry::supportsService(const OUString
& rServiceName
)
876 return cppu::supportsService(this, rServiceName
);
879 uno::Sequence
< OUString
> SwXAutoTextEntry::getSupportedServiceNames()
881 uno::Sequence
<OUString
> aRet
{ u
"com.sun.star.text.AutoTextEntry"_ustr
};
885 uno::Reference
< container::XNameReplace
> SwXAutoTextEntry::getEvents()
887 return new SwAutoTextEventDescriptor( *this );
890 const struct SvEventDescription aAutotextEvents
[] =
892 { SvMacroItemId::SwStartInsGlossary
, "OnInsertStart" },
893 { SvMacroItemId::SwEndInsGlossary
, "OnInsertDone" },
894 { SvMacroItemId::NONE
, nullptr }
897 SwAutoTextEventDescriptor::SwAutoTextEventDescriptor(
898 SwXAutoTextEntry
& rAutoText
) :
899 SvBaseEventDescriptor(aAutotextEvents
),
900 m_rAutoTextEntry(rAutoText
)
904 SwAutoTextEventDescriptor::~SwAutoTextEventDescriptor()
908 OUString
SwAutoTextEventDescriptor::getImplementationName()
910 return u
"SwAutoTextEventDescriptor"_ustr
;
913 void SwAutoTextEventDescriptor::replaceByName(
914 const SvMacroItemId nEvent
,
915 const SvxMacro
& rMacro
)
917 OSL_ENSURE( nullptr != m_rAutoTextEntry
.GetGlossaries(),
918 "Strangely enough, the AutoText vanished!" );
919 OSL_ENSURE( (nEvent
== SvMacroItemId::SwEndInsGlossary
) ||
920 (nEvent
== SvMacroItemId::SwStartInsGlossary
) ,
921 "Unknown event ID" );
923 SwGlossaries
*const pGlossaries
=
924 const_cast<SwGlossaries
*>(m_rAutoTextEntry
.GetGlossaries());
925 std::unique_ptr
<SwTextBlocks
> pBlocks(
926 pGlossaries
->GetGroupDoc( m_rAutoTextEntry
.GetGroupName() ));
928 "can't get autotext group; SwAutoTextEntry has illegal name?");
930 if( !pBlocks
|| pBlocks
->GetError())
933 sal_uInt16 nIndex
= pBlocks
->GetIndex( m_rAutoTextEntry
.GetEntryName() );
934 if( nIndex
!= USHRT_MAX
)
936 SvxMacroTableDtor aMacroTable
;
937 if( pBlocks
->GetMacroTable( nIndex
, aMacroTable
) )
939 aMacroTable
.Insert( nEvent
, rMacro
);
940 pBlocks
->SetMacroTable( nIndex
, aMacroTable
);
946 void SwAutoTextEventDescriptor::getByName(
948 const SvMacroItemId nEvent
)
950 OSL_ENSURE( nullptr != m_rAutoTextEntry
.GetGlossaries(), "no AutoText" );
951 OSL_ENSURE( (nEvent
== SvMacroItemId::SwEndInsGlossary
) ||
952 (nEvent
== SvMacroItemId::SwStartInsGlossary
) ,
953 "Unknown event ID" );
955 SwGlossaries
*const pGlossaries
=
956 const_cast<SwGlossaries
*>(m_rAutoTextEntry
.GetGlossaries());
957 std::unique_ptr
<SwTextBlocks
> pBlocks(
958 pGlossaries
->GetGroupDoc( m_rAutoTextEntry
.GetGroupName() ));
960 "can't get autotext group; SwAutoTextEntry has illegal name?");
962 // return empty macro, unless macro is found
964 rMacro
= SvxMacro(sEmptyStr
, sEmptyStr
);
966 if ( !pBlocks
|| pBlocks
->GetError())
969 sal_uInt16 nIndex
= pBlocks
->GetIndex( m_rAutoTextEntry
.GetEntryName() );
970 if( nIndex
!= USHRT_MAX
)
972 SvxMacroTableDtor aMacroTable
;
973 if( pBlocks
->GetMacroTable( nIndex
, aMacroTable
) )
975 SvxMacro
*pMacro
= aMacroTable
.Get( nEvent
);
982 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
983 SwXAutoTextContainer_get_implementation(css::uno::XComponentContext
*,
984 css::uno::Sequence
<css::uno::Any
> const &)
986 //the module may not be loaded
987 SolarMutexGuard aGuard
;
989 return cppu::acquire(new SwXAutoTextContainer());
992 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */