LibreOffice Module sw (master) 1
unorefmk.cxx
Go to the documentation of this file.
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 <memory>
21#include <utility>
22
28#include <cppuhelper/weak.hxx>
29#include <sal/config.h>
30#include <svl/listener.hxx>
31#include <vcl/svapp.hxx>
32#include <sal/log.hxx>
33
34#include <unotextrange.hxx>
35#include <unorefmark.hxx>
36#include <unotextcursor.hxx>
37#include <unomap.hxx>
38#include <unocrsrhelper.hxx>
39#include <doc.hxx>
40#include <ndtxt.hxx>
41#include <fmtrfmrk.hxx>
42#include <txtrfmrk.hxx>
43#include <unometa.hxx>
44#include <unotext.hxx>
45#include <unoport.hxx>
46#include <txtatr.hxx>
47#include <fmtmeta.hxx>
48#include <docsh.hxx>
49
50#include <com/sun/star/frame/XModel.hpp>
51#include <com/sun/star/lang/NoSupportException.hpp>
52#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
53#include <com/sun/star/rdf/Statement.hpp>
54#include <com/sun/star/rdf/URI.hpp>
55#include <com/sun/star/rdf/URIs.hpp>
56#include <com/sun/star/rdf/XLiteral.hpp>
57#include <com/sun/star/rdf/XRepositorySupplier.hpp>
58#include <com/sun/star/lang/DisposedException.hpp>
59
60using namespace ::com::sun::star;
61
63 : public SvtListener
64{
65public:
67 std::mutex m_Mutex; // just for OInterfaceContainerHelper4
72 OUString m_sMarkName;
73
74 Impl(SwDoc* const pDoc, SwFormatRefMark* const pRefMark)
75 : m_bIsDescriptor(nullptr == pRefMark)
76 , m_pDoc(pDoc)
77 , m_pMarkFormat(pRefMark)
78 {
79 if (pRefMark)
80 {
81 StartListening(pRefMark->GetNotifier());
82 m_sMarkName = pRefMark->GetRefName();
83 }
84 }
85
86 bool IsValid() const { return m_pMarkFormat; }
87 void InsertRefMark( SwPaM & rPam, SwXTextCursor const*const pCursor );
88 void Invalidate();
89protected:
90 virtual void Notify(const SfxHint&) override;
91
92};
93
95{
97 m_pDoc = nullptr;
98 m_pMarkFormat = nullptr;
99 uno::Reference<uno::XInterface> const xThis(m_wThis);
100 if (!xThis.is())
101 { // fdo#72695: if UNO object is already dead, don't revive it with event
102 return;
103 }
104 lang::EventObject const ev(xThis);
105 std::unique_lock aGuard(m_Mutex);
107}
108
110{
111 if(rHint.GetId() == SfxHintId::Dying)
112 Invalidate();
113}
114
116 SwDoc *const pDoc, SwFormatRefMark *const pRefMark)
117 : m_pImpl( new SwXReferenceMark::Impl(pDoc, pRefMark) )
118{
119}
120
122{
123}
124
127 SwDoc & rDoc, SwFormatRefMark *const pMarkFormat)
128{
129 // i#105557: do not iterate over the registered clients: race condition
131 if (pMarkFormat)
132 {
133 xMark = pMarkFormat->GetXRefMark();
134 }
135 if (!xMark.is())
136 {
137 xMark = new SwXReferenceMark(&rDoc, pMarkFormat);
138 if (pMarkFormat)
139 {
140 pMarkFormat->SetXRefMark(xMark);
141 }
142 // need a permanent Reference to initialize m_wThis
143 xMark->m_pImpl->m_wThis = xMark.get();
144 }
145 return xMark;
146}
147
149{
150 return "SwXReferenceMark";
151}
152
153sal_Bool SAL_CALL
154SwXReferenceMark::supportsService(const OUString& rServiceName)
155{
156 return cppu::supportsService(this, rServiceName);
157}
158
159uno::Sequence< OUString > SAL_CALL
161{
162 return {
163 "com.sun.star.text.TextContent",
164 "com.sun.star.text.ReferenceMark"
165 };
166}
167
168namespace {
169
170template<typename T> struct NotContainedIn
171{
172 std::vector<T> const& m_rVector;
173 explicit NotContainedIn(std::vector<T> const& rVector)
174 : m_rVector(rVector) { }
175 bool operator() (T const& rT) {
176 return std::find(m_rVector.begin(), m_rVector.end(), rT)
177 == m_rVector.end();
178 }
179};
180
181}
182
184 SwXTextCursor const*const pCursor)
185{
189 SwDoc& rDoc2 = rPam.GetDoc();
190
191 UnoActionContext aCont(&rDoc2);
193 bool bMark = *rPam.GetPoint() != *rPam.GetMark();
194
195 const bool bForceExpandHints( !bMark && pCursor && pCursor->IsAtEndOfMeta() );
196 const SetAttrMode nInsertFlags = bForceExpandHints
200
201 std::vector<SwTextAttr *> oldMarks;
202 if (bMark)
203 {
204 oldMarks = rPam.GetPointNode().GetTextNode()->GetTextAttrsAt(
206 }
207
208 rDoc2.getIDocumentContentOperations().InsertPoolItem( rPam, aRefMark, nInsertFlags );
209
210 if( bMark && *rPam.GetPoint() > *rPam.GetMark())
211 {
212 rPam.Exchange();
213 }
214
215 // aRefMark was copied into the document pool; now retrieve real format...
216 SwTextAttr * pTextAttr(nullptr);
217 if (bMark)
218 {
219 // #i107672#
220 // ensure that we do not retrieve a different mark at the same position
221 std::vector<SwTextAttr *> const newMarks(
224 std::vector<SwTextAttr *>::const_iterator const iter(
225 std::find_if(newMarks.begin(), newMarks.end(),
226 NotContainedIn<SwTextAttr *>(oldMarks)));
227 assert(newMarks.end() != iter);
228 if (newMarks.end() != iter)
229 {
230 pTextAttr = *iter;
231 }
232 }
233 else
234 {
235 SwTextNode *pTextNd = rPam.GetPointNode().GetTextNode();
236 assert(pTextNd);
237 pTextAttr = pTextNd ? rPam.GetPointNode().GetTextNode()->GetTextAttrForCharAt(
238 rPam.GetPoint()->GetContentIndex() - 1, RES_TXTATR_REFMARK) : nullptr;
239 }
240
241 if (!pTextAttr)
242 {
243 throw uno::RuntimeException(
244 "SwXReferenceMark::InsertRefMark(): cannot insert attribute", nullptr);
245 }
246
247 m_pMarkFormat = &pTextAttr->GetRefMark();
249 StartListening(const_cast<SwFormatRefMark*>(m_pMarkFormat)->GetNotifier());
250}
251
252void SAL_CALL
253SwXReferenceMark::attach(const uno::Reference< text::XTextRange > & xTextRange)
254{
255 SolarMutexGuard aGuard;
256
257 if (!m_pImpl->m_bIsDescriptor)
258 {
259 throw uno::RuntimeException();
260 }
261 SwXTextRange* pRange = dynamic_cast<SwXTextRange*>(xTextRange.get());
262 OTextCursorHelper* pCursor = dynamic_cast<OTextCursorHelper*>(xTextRange.get());
263 SwDoc *const pDocument =
264 pRange ? &pRange->GetDoc() : (pCursor ? pCursor->GetDoc() : nullptr);
265 if (!pDocument)
266 {
267 throw lang::IllegalArgumentException();
268 }
269
270 SwUnoInternalPaM aPam(*pDocument);
271 // this now needs to return TRUE
272 ::sw::XTextRangeToSwPaM(aPam, xTextRange);
273 m_pImpl->InsertRefMark(aPam, dynamic_cast<SwXTextCursor*>(pCursor));
274 m_pImpl->m_bIsDescriptor = false;
275 m_pImpl->m_pDoc = pDocument;
276}
277
278uno::Reference< text::XTextRange > SAL_CALL
280{
281 SolarMutexGuard aGuard;
282
283 if (m_pImpl->IsValid())
284 {
285 SwFormatRefMark const*const pNewMark =
286 m_pImpl->m_pDoc->GetRefMark(m_pImpl->m_sMarkName);
287 if (pNewMark && (pNewMark == m_pImpl->m_pMarkFormat))
288 {
289 SwTextRefMark const*const pTextMark =
290 m_pImpl->m_pMarkFormat->GetTextRefMark();
291 if (pTextMark &&
292 (&pTextMark->GetTextNode().GetNodes() ==
293 &m_pImpl->m_pDoc->GetNodes()))
294 {
295 SwTextNode const& rTextNode = pTextMark->GetTextNode();
296 std::optional<SwPaM> pPam;
297 if ( pTextMark->End() )
298 pPam.emplace( rTextNode, *pTextMark->End(),
299 rTextNode, pTextMark->GetStart());
300 else
301 pPam.emplace( rTextNode, pTextMark->GetStart());
302
304 *m_pImpl->m_pDoc, *pPam->Start(), pPam->End());
305 }
306 }
307 }
308 return nullptr;
309}
310
312{
313 SolarMutexGuard aGuard;
314 if (m_pImpl->IsValid())
315 {
316 SwFormatRefMark const*const pNewMark =
317 m_pImpl->m_pDoc->GetRefMark(m_pImpl->m_sMarkName);
318 if (pNewMark && (pNewMark == m_pImpl->m_pMarkFormat))
319 {
320 SwTextRefMark const*const pTextMark =
321 m_pImpl->m_pMarkFormat->GetTextRefMark();
322 if (pTextMark &&
323 (&pTextMark->GetTextNode().GetNodes() ==
324 &m_pImpl->m_pDoc->GetNodes()))
325 {
326 SwTextNode const& rTextNode = pTextMark->GetTextNode();
327 const sal_Int32 nStt = pTextMark->GetStart();
328 const sal_Int32 nEnd = pTextMark->End()
329 ? *pTextMark->End()
330 : nStt + 1;
331
332 SwPaM aPam( rTextNode, nStt, rTextNode, nEnd );
333 m_pImpl->m_pDoc->getIDocumentContentOperations().DeleteAndJoin( aPam );
334 }
335 }
336 }
337 else if (m_pImpl->m_bIsDescriptor)
338 {
339 m_pImpl->Invalidate();
340 }
341}
342
344 const uno::Reference< lang::XEventListener > & xListener)
345{
346 // no need to lock here as m_pImpl is const and container threadsafe
347 std::unique_lock aGuard(m_pImpl->m_Mutex);
348 m_pImpl->m_EventListeners.addInterface(aGuard, xListener);
349}
350
352 const uno::Reference< lang::XEventListener > & xListener)
353{
354 // no need to lock here as m_pImpl is const and container threadsafe
355 std::unique_lock aGuard(m_pImpl->m_Mutex);
356 m_pImpl->m_EventListeners.removeInterface(aGuard, xListener);
357}
358
359OUString SAL_CALL SwXReferenceMark::getName()
360{
361 SolarMutexGuard aGuard;
362 if (!m_pImpl->IsValid() ||
363 !m_pImpl->m_pDoc->GetRefMark(m_pImpl->m_sMarkName))
364 {
365 throw uno::RuntimeException();
366 }
367 return m_pImpl->m_sMarkName;
368}
369
370void SAL_CALL SwXReferenceMark::setName(const OUString& rName)
371{
372 SolarMutexGuard aGuard;
373 if (m_pImpl->m_bIsDescriptor)
374 {
375 m_pImpl->m_sMarkName = rName;
376 }
377 else
378 {
379 if (!m_pImpl->IsValid()
380 || !m_pImpl->m_pDoc->GetRefMark(m_pImpl->m_sMarkName)
381 || m_pImpl->m_pDoc->GetRefMark(rName))
382 {
383 throw uno::RuntimeException();
384 }
385 SwFormatRefMark const*const pCurMark =
386 m_pImpl->m_pDoc->GetRefMark(m_pImpl->m_sMarkName);
387 if ((rName != m_pImpl->m_sMarkName)
388 && pCurMark && (pCurMark == m_pImpl->m_pMarkFormat))
389 {
390 const UnoActionContext aCont(m_pImpl->m_pDoc);
391 SwTextRefMark const*const pTextMark =
392 m_pImpl->m_pMarkFormat->GetTextRefMark();
393 if (pTextMark &&
394 (&pTextMark->GetTextNode().GetNodes() ==
395 &m_pImpl->m_pDoc->GetNodes()))
396 {
397 SwTextNode const& rTextNode = pTextMark->GetTextNode();
398 const sal_Int32 nStt = pTextMark->GetStart();
399 const sal_Int32 nEnd = pTextMark->End()
400 ? *pTextMark->End()
401 : nStt + 1;
402
403 SwPaM aPam( rTextNode, nStt, rTextNode, nEnd );
404 // deletes the m_pImpl->m_pDoc member in the SwXReferenceMark!
405 m_pImpl->m_pDoc->getIDocumentContentOperations().DeleteAndJoin( aPam );
406 // The aPam will keep the correct and functional doc though
407
408 m_pImpl->m_sMarkName = rName;
409 //create a new one
410 m_pImpl->InsertRefMark( aPam, nullptr );
411 m_pImpl->m_pDoc = &aPam.GetDoc();
412 }
413 }
414 }
415}
416
417uno::Reference< beans::XPropertySetInfo > SAL_CALL
419{
421
422 static uno::Reference< beans::XPropertySetInfo > xRef =
425 return xRef;
426}
427
429 const OUString& /*rPropertyName*/, const uno::Any& /*rValue*/ )
430{
431 throw lang::IllegalArgumentException();
432}
433
434uno::Any SAL_CALL
435SwXReferenceMark::getPropertyValue(const OUString& rPropertyName)
436{
437 // does not seem to need SolarMutex
438 uno::Any aRet;
439 if (! ::sw::GetDefaultTextContentValue(aRet, rPropertyName))
440 {
441 throw beans::UnknownPropertyException(rPropertyName);
442 }
443 return aRet;
444}
445
447 const OUString& /*rPropertyName*/,
448 const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
449{
450 OSL_FAIL("SwXReferenceMark::addPropertyChangeListener(): not implemented");
451}
452
454 const OUString& /*rPropertyName*/,
455 const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
456{
457 OSL_FAIL("SwXReferenceMark::removePropertyChangeListener(): not implemented");
458}
459
461 const OUString& /*rPropertyName*/,
462 const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
463{
464 OSL_FAIL("SwXReferenceMark::addVetoableChangeListener(): not implemented");
465}
466
468 const OUString& /*rPropertyName*/,
469 const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
470{
471 OSL_FAIL("SwXReferenceMark::removeVetoableChangeListener(): not implemented");
472}
473
474namespace {
475
476class SwXMetaText : public cppu::OWeakObject, public SwXText
477{
478private:
479 SwXMeta & m_rMeta;
480
481 virtual void PrepareForAttach(uno::Reference< text::XTextRange > & xRange,
482 const SwPaM & rPam) override;
483
484 virtual bool CheckForOwnMemberMeta(const SwPaM & rPam, const bool bAbsorb) override;
485
486protected:
487 virtual const SwStartNode *GetStartNode() const override;
488
489public:
490 SwXMetaText(SwDoc & rDoc, SwXMeta & rMeta);
491
494
495 // XInterface
496 virtual void SAL_CALL acquire() noexcept override { cppu::OWeakObject::acquire(); }
497 virtual void SAL_CALL release() noexcept override { cppu::OWeakObject::release(); }
498
499 // XTypeProvider
500 virtual uno::Sequence< sal_Int8 > SAL_CALL
501 getImplementationId() override;
502
503 // XText
504 virtual rtl::Reference< SwXTextCursor > createXTextCursor() override;
505 virtual rtl::Reference< SwXTextCursor > createXTextCursorByRange(
506 const ::css::uno::Reference< ::css::text::XTextRange >& aTextPosition ) override;
507};
508
509}
510
511SwXMetaText::SwXMetaText(SwDoc & rDoc, SwXMeta & rMeta)
512 : SwXText(&rDoc, CursorType::Meta)
513 , m_rMeta(rMeta)
514{
515}
516
518{
519 SwXText const * const pParent(
520 dynamic_cast<SwXText*>(m_rMeta.GetParentText().get()));
521 return pParent ? pParent->GetStartNode() : nullptr;
522}
523
524void SwXMetaText::PrepareForAttach( uno::Reference<text::XTextRange> & xRange,
525 const SwPaM & rPam)
526{
527 // create a new cursor to prevent modifying SwXTextRange
528 xRange = static_cast<text::XWordCursor*>(
529 new SwXTextCursor(*GetDoc(), &m_rMeta, CursorType::Meta, *rPam.GetPoint(),
530 (rPam.HasMark()) ? rPam.GetMark() : nullptr));
531}
532
533bool SwXMetaText::CheckForOwnMemberMeta(const SwPaM & rPam, const bool bAbsorb)
534{
535 return m_rMeta.CheckForOwnMemberMeta(rPam, bAbsorb);
536}
537
538rtl::Reference< SwXTextCursor > SwXMetaText::createXTextCursor()
539{
541 if (IsValid())
542 {
543 SwTextNode * pTextNode;
544 sal_Int32 nMetaStart;
545 sal_Int32 nMetaEnd;
546 const bool bSuccess(
547 m_rMeta.SetContentRange(pTextNode, nMetaStart, nMetaEnd) );
548 if (bSuccess)
549 {
550 SwPosition aPos(*pTextNode, nMetaStart);
551 xRet = new SwXTextCursor(*GetDoc(), &m_rMeta, CursorType::Meta, aPos);
552 }
553 }
554 return xRet;
555}
556
557uno::Sequence<sal_Int8> SAL_CALL
558SwXMetaText::getImplementationId()
559{
560 return css::uno::Sequence<sal_Int8>();
561}
562
563// XText
564
566SwXMetaText::createXTextCursorByRange(
567 const uno::Reference<text::XTextRange> & xTextPosition)
568{
569 const rtl::Reference< SwXTextCursor > xCursor( createXTextCursor() );
570 xCursor->gotoRange(xTextPosition, false);
571 return xCursor;
572}
573
582{
583public:
585 std::mutex m_Mutex; // just for OInterfaceContainerHelper4
587 std::unique_ptr<const TextRangeList_t> m_pTextPortions;
588 // 3 possible states: not attached, attached, disposed
591 uno::Reference<text::XText> m_xParentText;
594
595 Impl(SwXMeta& rThis, SwDoc& rDoc,
596 ::sw::Meta* const pMeta,
597 uno::Reference<text::XText> xParentText,
598 std::unique_ptr<TextRangeList_t const> pPortions)
599 : m_pTextPortions(std::move(pPortions))
600 , m_bIsDisposed(false)
601 , m_bIsDescriptor(nullptr == pMeta)
602 , m_xParentText(std::move(xParentText))
603 , m_xText(new SwXMetaText(rDoc, rThis))
604 , m_pMeta(pMeta)
605 {
606 !m_bIsDescriptor && StartListening(m_pMeta->GetNotifier());
607 }
608
609 inline const ::sw::Meta* GetMeta() const;
610 // only for SwXMetaField!
611 inline const ::sw::MetaField* GetMetaField() const;
612protected:
613 virtual void Notify(const SfxHint& rHint) override;
614
615};
616
617inline const ::sw::Meta* SwXMeta::Impl::GetMeta() const
618{
619 return m_pMeta;
620}
621
622// sw::BroadcastingModify
624{
625 m_pTextPortions.reset(); // throw away cache (SwTextNode changed)
626 if(rHint.GetId() != SfxHintId::Dying && rHint.GetId() != SfxHintId::Deinitializing)
627 return;
628
629 m_bIsDisposed = true;
630 m_pMeta = nullptr;
631 m_xText->Invalidate();
632 uno::Reference<uno::XInterface> const xThis(m_wThis);
633 if (!xThis.is())
634 { // fdo#72695: if UNO object is already dead, don't revive it with event
635 return;
636 }
637 lang::EventObject const ev(xThis);
638 std::unique_lock aGuard(m_Mutex);
639 m_EventListeners.disposeAndClear(aGuard, ev);
640}
641
642uno::Reference<text::XText> const & SwXMeta::GetParentText() const
643{
644 return m_pImpl->m_xParentText;
645}
646
647SwXMeta::SwXMeta(SwDoc *const pDoc, ::sw::Meta *const pMeta,
648 uno::Reference<text::XText> const& xParentText,
649 std::unique_ptr<TextRangeList_t const> pPortions)
650 : m_pImpl( new SwXMeta::Impl(*this, *pDoc, pMeta, xParentText, std::move(pPortions)) )
651{
652}
653
655 : m_pImpl( new SwXMeta::Impl(*this, *pDoc, nullptr, nullptr, nullptr) )
656{
657}
658
660{
661}
662
664SwXMeta::CreateXMeta(SwDoc & rDoc, bool const isField)
665{
666 // this is why the constructor is private: need to acquire pXMeta here
667 rtl::Reference<SwXMeta> xMeta(isField
668 ? new SwXMetaField(& rDoc) : new SwXMeta(& rDoc));
669 // need a permanent Reference to initialize m_wThis
670 xMeta->m_pImpl->m_wThis = xMeta.get();
671 return xMeta;
672}
673
676 uno::Reference<text::XText> const& i_xParent,
677 std::unique_ptr<TextRangeList_t const> && pPortions)
678{
679 // re-use existing SwXMeta
680 // #i105557#: do not iterate over the registered clients: race condition
681 rtl::Reference<SwXMeta> xMeta(rMeta.GetXMeta());
682 if (xMeta.is())
683 {
684 if (pPortions) // set cache in the XMeta to the given portions
685 {
686 // NB: the meta must always be created with the complete content
687 // if SwXTextPortionEnumeration is created for a selection,
688 // it must be checked that the Meta is contained in the selection!
689 xMeta->m_pImpl->m_pTextPortions = std::move(pPortions);
690 // ??? is this necessary?
691 if (xMeta->m_pImpl->m_xParentText.get() != i_xParent.get())
692 {
693 SAL_WARN("sw.uno", "SwXMeta with different parent?");
694 xMeta->m_pImpl->m_xParentText.set(i_xParent);
695 }
696 }
697 return xMeta;
698 }
699
700 // create new SwXMeta
701 SwTextNode * const pTextNode( rMeta.GetTextNode() );
702 SAL_WARN_IF(!pTextNode, "sw.uno", "CreateXMeta: no text node?");
703 if (!pTextNode) { return nullptr; }
704 uno::Reference<text::XText> xParentText(i_xParent);
705 if (!xParentText.is())
706 {
707 SwTextMeta * const pTextAttr( rMeta.GetTextAttr() );
708 SAL_WARN_IF(!pTextAttr, "sw.uno", "CreateXMeta: no text attr?");
709 if (!pTextAttr) { return nullptr; }
710 const SwPosition aPos(*pTextNode, pTextAttr->GetStart());
711 xParentText.set( ::sw::CreateParentXText(pTextNode->GetDoc(), aPos) );
712 }
713 if (!xParentText.is()) { return nullptr; }
714 // this is why the constructor is private: need to acquire pXMeta here
715 xMeta = (RES_TXTATR_META == rMeta.GetFormatMeta()->Which())
716 ? new SwXMeta (&pTextNode->GetDoc(), &rMeta, xParentText,
717 std::move(pPortions))
718 : new SwXMetaField(&pTextNode->GetDoc(), &rMeta, xParentText,
719 std::move(pPortions));
720 // in order to initialize the weak pointer cache in the core object
721 rMeta.SetXMeta(xMeta);
722 // need a permanent Reference to initialize m_wThis
723 xMeta->m_pImpl->m_wThis = xMeta.get();
724 return xMeta;
725}
726
728 SwTextNode *& rpNode, sal_Int32 & rStart, sal_Int32 & rEnd ) const
729{
730 ::sw::Meta const * const pMeta( m_pImpl->GetMeta() );
731 if (pMeta)
732 {
733 SwTextMeta const * const pTextAttr( pMeta->GetTextAttr() );
734 if (pTextAttr)
735 {
736 rpNode = pMeta->GetTextNode();
737 if (rpNode)
738 {
739 // rStart points at the first position _within_ the meta!
740 rStart = pTextAttr->GetStart() + 1;
741 rEnd = *pTextAttr->End();
742 return true;
743 }
744 }
745 }
746 return false;
747}
748
749bool SwXMeta::CheckForOwnMemberMeta(const SwPaM & rPam, const bool bAbsorb)
750{
751 SwTextNode * pTextNode;
752 sal_Int32 nMetaStart;
753 sal_Int32 nMetaEnd;
754 const bool bSuccess( SetContentRange(pTextNode, nMetaStart, nMetaEnd) );
755 OSL_ENSURE(bSuccess, "no pam?");
756 if (!bSuccess)
757 throw lang::DisposedException();
758
759 SwPosition const * const pStartPos( rPam.Start() );
760 if (&pStartPos->GetNode() != pTextNode)
761 {
762 throw lang::IllegalArgumentException(
763 "trying to insert into a nesting text content, but start "
764 "of text range not in same paragraph as text content",
765 nullptr, 0);
766 }
767 bool bForceExpandHints(false);
768 const sal_Int32 nStartPos(pStartPos->GetContentIndex());
769 // not <= but < because nMetaStart is behind dummy char!
770 // not >= but > because == means insert at end!
771 if ((nStartPos < nMetaStart) || (nStartPos > nMetaEnd))
772 {
773 throw lang::IllegalArgumentException(
774 "trying to insert into a nesting text content, but start "
775 "of text range not inside text content",
776 nullptr, 0);
777 }
778 else if (nStartPos == nMetaEnd)
779 {
780 bForceExpandHints = true;
781 }
782 if (rPam.HasMark() && bAbsorb)
783 {
784 SwPosition const * const pEndPos( rPam.End() );
785 if (&pEndPos->GetNode() != pTextNode)
786 {
787 throw lang::IllegalArgumentException(
788 "trying to insert into a nesting text content, but end "
789 "of text range not in same paragraph as text content",
790 nullptr, 0);
791 }
792 const sal_Int32 nEndPos(pEndPos->GetContentIndex());
793 // not <= but < because nMetaStart is behind dummy char!
794 // not >= but > because == means insert at end!
795 if ((nEndPos < nMetaStart) || (nEndPos > nMetaEnd))
796 {
797 throw lang::IllegalArgumentException(
798 "trying to insert into a nesting text content, but end "
799 "of text range not inside text content",
800 nullptr, 0);
801 }
802 else if (nEndPos == nMetaEnd)
803 {
804 bForceExpandHints = true;
805 }
806 }
807 return bForceExpandHints;
808}
809
810// XServiceInfo
811OUString SAL_CALL
813{
814 return "SwXMeta";
815}
816
817sal_Bool SAL_CALL
818SwXMeta::supportsService(const OUString& rServiceName)
819{
820 return cppu::supportsService(this, rServiceName);
821}
822
823uno::Sequence< OUString > SAL_CALL
825{
826 return {
827 "com.sun.star.text.TextContent",
828 "com.sun.star.text.InContentMetadata"
829 };
830}
831
832// XComponent
833void SAL_CALL
835 uno::Reference< lang::XEventListener> const & xListener )
836{
837 // no need to lock here as m_pImpl is const and container threadsafe
838 std::unique_lock aGuard(m_pImpl->m_Mutex);
839 m_pImpl->m_EventListeners.addInterface(aGuard, xListener);
840}
841
842void SAL_CALL
844 uno::Reference< lang::XEventListener> const & xListener )
845{
846 // no need to lock here as m_pImpl is const and container threadsafe
847 std::unique_lock aGuard(m_pImpl->m_Mutex);
848 m_pImpl->m_EventListeners.removeInterface(aGuard, xListener);
849}
850
851void SAL_CALL
853{
855
856 if (m_pImpl->m_bIsDescriptor)
857 {
858 m_pImpl->m_pTextPortions.reset();
859 lang::EventObject const ev(static_cast< ::cppu::OWeakObject&>(*this));
860 std::unique_lock aGuard(m_pImpl->m_Mutex);
861 m_pImpl->m_EventListeners.disposeAndClear(aGuard, ev);
862 m_pImpl->m_bIsDisposed = true;
863 m_pImpl->m_xText->Invalidate();
864 }
865 else if (!m_pImpl->m_bIsDisposed)
866 {
867 SwTextNode * pTextNode;
868 sal_Int32 nMetaStart;
869 sal_Int32 nMetaEnd;
870 const bool bSuccess(SetContentRange(pTextNode, nMetaStart, nMetaEnd));
871 OSL_ENSURE(bSuccess, "no pam?");
872 if (bSuccess)
873 {
874 // -1 because of CH_TXTATR
875 SwPaM aPam( *pTextNode, nMetaStart - 1, *pTextNode, nMetaEnd );
876 SwDoc& rDoc( pTextNode->GetDoc() );
878
879 // removal should call Modify and do the dispose
880 assert(m_pImpl->m_bIsDisposed);
881 }
882 }
883}
884
885void
886SwXMeta::AttachImpl(const uno::Reference< text::XTextRange > & i_xTextRange,
887 const sal_uInt16 i_nWhich)
888{
890
891 if (m_pImpl->m_bIsDisposed)
892 {
893 throw lang::DisposedException();
894 }
895 if (!m_pImpl->m_bIsDescriptor)
896 {
897 throw uno::RuntimeException(
898 "SwXMeta::attach(): already attached",
899 static_cast< ::cppu::OWeakObject* >(this));
900 }
901
902 SwXTextRange *const pRange(dynamic_cast<SwXTextRange*>(i_xTextRange.get()));
903 OTextCursorHelper *const pCursor(dynamic_cast<OTextCursorHelper*>(i_xTextRange.get()));
904 if (!pRange && !pCursor)
905 {
906 throw lang::IllegalArgumentException(
907 "SwXMeta::attach(): argument not supported type",
908 static_cast< ::cppu::OWeakObject* >(this), 0);
909 }
910
911 SwDoc * const pDoc(
912 pRange ? &pRange->GetDoc() : pCursor->GetDoc());
913 if (!pDoc)
914 {
915 throw lang::IllegalArgumentException(
916 "SwXMeta::attach(): argument has no SwDoc",
917 static_cast< ::cppu::OWeakObject* >(this), 0);
918 }
919
920 SwUnoInternalPaM aPam(*pDoc);
921 ::sw::XTextRangeToSwPaM(aPam, i_xTextRange);
922
923 UnoActionContext aContext(pDoc);
924
925 SwXTextCursor const*const pTextCursor(
926 dynamic_cast<SwXTextCursor*>(pCursor));
927 const bool bForceExpandHints(pTextCursor && pTextCursor->IsAtEndOfMeta());
928 const SetAttrMode nInsertFlags( bForceExpandHints
932
933 const std::shared_ptr< ::sw::Meta> pMeta( (RES_TXTATR_META == i_nWhich)
934 ? std::make_shared< ::sw::Meta>( nullptr )
935 : std::shared_ptr< ::sw::Meta>(
937 SwFormatMeta meta(pMeta, i_nWhich); // this is cloned by Insert!
938 const bool bSuccess( pDoc->getIDocumentContentOperations().InsertPoolItem( aPam, meta, nInsertFlags ) );
939 SwTextAttr * const pTextAttr( pMeta->GetTextAttr() );
940 if (!bSuccess)
941 {
942 throw lang::IllegalArgumentException(
943 "SwXMeta::attach(): cannot create meta: range invalid?",
944 static_cast< ::cppu::OWeakObject* >(this), 1);
945 }
946 if (!pTextAttr)
947 {
948 OSL_FAIL("meta inserted, but has no text attribute?");
949 throw uno::RuntimeException(
950 "SwXMeta::attach(): cannot create meta",
951 static_cast< ::cppu::OWeakObject* >(this));
952 }
953
954 m_pImpl->EndListeningAll();
955 m_pImpl->m_pMeta = pMeta.get();
956 m_pImpl->StartListening(pMeta->GetNotifier());
957 pMeta->SetXMeta(this);
958
959 m_pImpl->m_xParentText = ::sw::CreateParentXText(*pDoc, *aPam.GetPoint());
960
961 m_pImpl->m_bIsDescriptor = false;
962}
963
964// XTextContent
965void SAL_CALL
966SwXMeta::attach(const uno::Reference< text::XTextRange > & i_xTextRange)
967{
968 return SwXMeta::AttachImpl(i_xTextRange, RES_TXTATR_META);
969}
970
971uno::Reference< text::XTextRange > SAL_CALL
973{
975
976 if (m_pImpl->m_bIsDisposed)
977 {
978 throw lang::DisposedException();
979 }
980 if (m_pImpl->m_bIsDescriptor)
981 {
982 throw uno::RuntimeException(
983 "SwXMeta::getAnchor(): not inserted",
984 static_cast< ::cppu::OWeakObject* >(this));
985 }
986
987 SwTextNode * pTextNode;
988 sal_Int32 nMetaStart;
989 sal_Int32 nMetaEnd;
990 const bool bSuccess(SetContentRange(pTextNode, nMetaStart, nMetaEnd));
991 OSL_ENSURE(bSuccess, "no pam?");
992 if (!bSuccess)
993 {
994 throw lang::DisposedException(
995 "SwXMeta::getAnchor(): not attached",
996 static_cast< ::cppu::OWeakObject* >(this));
997 }
998
999 const SwPosition start(*pTextNode, nMetaStart - 1); // -1 due to CH_TXTATR
1000 const SwPosition end(*pTextNode, nMetaEnd);
1001 return SwXTextRange::CreateXTextRange(pTextNode->GetDoc(), start, &end);
1002}
1003
1004// XTextRange
1005uno::Reference< text::XText > SAL_CALL
1007{
1008 return this;
1009}
1010
1011uno::Reference< text::XTextRange > SAL_CALL
1013{
1015 return m_pImpl->m_xText->getStart();
1016}
1017
1018uno::Reference< text::XTextRange > SAL_CALL
1020{
1022 return m_pImpl->m_xText->getEnd();
1023}
1024
1025OUString SAL_CALL
1027{
1029 return m_pImpl->m_xText->getString();
1030}
1031
1032void SAL_CALL
1033SwXMeta::setString(const OUString& rString)
1034{
1036 return m_pImpl->m_xText->setString(rString);
1037}
1038
1039// XSimpleText
1040uno::Reference< text::XTextCursor > SAL_CALL
1042{
1044 return m_pImpl->m_xText->createTextCursor();
1045}
1046
1047uno::Reference< text::XTextCursor > SAL_CALL
1049 const uno::Reference<text::XTextRange> & xTextPosition)
1050{
1052 return m_pImpl->m_xText->createTextCursorByRange(xTextPosition);
1053}
1054
1055void SAL_CALL
1056SwXMeta::insertString(const uno::Reference<text::XTextRange> & xRange,
1057 const OUString& rString, sal_Bool bAbsorb)
1058{
1060 return m_pImpl->m_xText->insertString(xRange, rString, bAbsorb);
1061}
1062
1063void SAL_CALL
1064SwXMeta::insertControlCharacter(const uno::Reference<text::XTextRange> & xRange,
1065 sal_Int16 nControlCharacter, sal_Bool bAbsorb)
1066{
1068 return m_pImpl->m_xText->insertControlCharacter(xRange, nControlCharacter,
1069 bAbsorb);
1070}
1071
1072// XText
1073void SAL_CALL
1074SwXMeta::insertTextContent( const uno::Reference<text::XTextRange> & xRange,
1075 const uno::Reference<text::XTextContent> & xContent, sal_Bool bAbsorb)
1076{
1078 return m_pImpl->m_xText->insertTextContent(xRange, xContent, bAbsorb);
1079}
1080
1081void SAL_CALL
1083 const uno::Reference< text::XTextContent > & xContent)
1084{
1086 return m_pImpl->m_xText->removeTextContent(xContent);
1087}
1088
1089// XChild
1090uno::Reference< uno::XInterface > SAL_CALL
1092{
1094 SwTextNode * pTextNode;
1095 sal_Int32 nMetaStart;
1096 sal_Int32 nMetaEnd;
1097 bool const bSuccess( SetContentRange(pTextNode, nMetaStart, nMetaEnd) );
1098 OSL_ENSURE(bSuccess, "no pam?");
1099 if (!bSuccess) { throw lang::DisposedException(); }
1100 // in order to prevent getting this meta, subtract 1 from nMetaStart;
1101 // so we get the index of the dummy character, and we exclude it
1102 // by calling GetTextAttrAt(_, _, PARENT) in GetNestedTextContent
1103 uno::Reference<text::XTextContent> const xRet(
1104 SwUnoCursorHelper::GetNestedTextContent(*pTextNode, nMetaStart - 1,
1105 true) );
1106 return xRet;
1107}
1108
1109void SAL_CALL
1110SwXMeta::setParent(uno::Reference< uno::XInterface > const& /*xParent*/)
1111{
1112 throw lang::NoSupportException("setting parent not supported", *this);
1113}
1114
1115// XElementAccess
1116uno::Type SAL_CALL
1118{
1120}
1121
1123{
1125 return m_pImpl->m_pMeta != nullptr;
1126}
1127
1128// XEnumerationAccess
1129uno::Reference< container::XEnumeration > SAL_CALL
1131{
1133
1134 if (m_pImpl->m_bIsDisposed)
1135 {
1136 throw lang::DisposedException();
1137 }
1138 if (m_pImpl->m_bIsDescriptor)
1139 {
1140 throw uno::RuntimeException(
1141 "createEnumeration(): not inserted",
1142 static_cast< ::cppu::OWeakObject* >(this));
1143 }
1144
1145 SwTextNode * pTextNode;
1146 sal_Int32 nMetaStart;
1147 sal_Int32 nMetaEnd;
1148 const bool bSuccess(SetContentRange(pTextNode, nMetaStart, nMetaEnd));
1149 OSL_ENSURE(bSuccess, "no pam?");
1150 if (!bSuccess)
1151 throw lang::DisposedException();
1152
1153 SwPaM aPam(*pTextNode, nMetaStart);
1154
1155 if (!m_pImpl->m_pTextPortions)
1156 {
1157 return new SwXTextPortionEnumeration(
1158 aPam, GetParentText(), nMetaStart, nMetaEnd);
1159 }
1160 else // cached!
1161 {
1162 return new SwXTextPortionEnumeration(aPam, std::deque(*m_pImpl->m_pTextPortions));
1163 }
1164}
1165
1166// MetadatableMixin
1167::sfx2::Metadatable* SwXMeta::GetCoreObject()
1168{
1169 return const_cast< ::sw::Meta * >(m_pImpl->GetMeta());
1170}
1171
1172uno::Reference<frame::XModel> SwXMeta::GetModel()
1173{
1174 ::sw::Meta const * const pMeta( m_pImpl->GetMeta() );
1175 if (pMeta)
1176 {
1177 SwTextNode const * const pTextNode( pMeta->GetTextNode() );
1178 if (pTextNode)
1179 {
1180 SwDocShell const * const pShell(pTextNode->GetDoc().GetDocShell());
1181 return pShell ? pShell->GetModel() : nullptr;
1182 }
1183 }
1184 return nullptr;
1185}
1186
1187inline const ::sw::MetaField* SwXMeta::Impl::GetMetaField() const
1188{
1189 return dynamic_cast<sw::MetaField*>(m_pMeta);
1190}
1191
1192SwXMetaField::SwXMetaField(SwDoc *const pDoc, ::sw::Meta *const pMeta,
1193 uno::Reference<text::XText> const& xParentText,
1194 std::unique_ptr<TextRangeList_t const> pPortions)
1195 : SwXMetaField_Base(pDoc, pMeta, xParentText, std::move(pPortions))
1196{
1197 assert(dynamic_cast< ::sw::MetaField* >(pMeta) && "SwXMetaField created for wrong hint!");
1198}
1199
1201 : SwXMetaField_Base(pDoc)
1202{
1203}
1204
1206{
1207}
1208
1209// XServiceInfo
1210OUString SAL_CALL
1212{
1213 return "SwXMetaField";
1214}
1215
1216sal_Bool SAL_CALL
1217SwXMetaField::supportsService(const OUString& rServiceName)
1218{
1219 return cppu::supportsService(this, rServiceName);
1220}
1221
1222uno::Sequence< OUString > SAL_CALL
1224{
1225 return {
1226 "com.sun.star.text.TextContent",
1227 "com.sun.star.text.TextField",
1228 "com.sun.star.text.textfield.MetadataField"
1229 };
1230}
1231
1232// XComponent
1233void SAL_CALL
1235 uno::Reference< lang::XEventListener> const & xListener )
1236{
1237 return SwXMeta::addEventListener(xListener);
1238}
1239
1240void SAL_CALL
1242 uno::Reference< lang::XEventListener> const & xListener )
1243{
1244 return SwXMeta::removeEventListener(xListener);
1245}
1246
1247void SAL_CALL
1249{
1250 return SwXMeta::dispose();
1251}
1252
1253// XTextContent
1254void SAL_CALL
1255SwXMetaField::attach(const uno::Reference< text::XTextRange > & i_xTextRange)
1256{
1257 return SwXMeta::AttachImpl(i_xTextRange, RES_TXTATR_METAFIELD);
1258}
1259
1260uno::Reference< text::XTextRange > SAL_CALL
1262{
1263 return SwXMeta::getAnchor();
1264}
1265
1266// XPropertySet
1267uno::Reference< beans::XPropertySetInfo > SAL_CALL
1269{
1271
1272 static uno::Reference< beans::XPropertySetInfo > xRef(
1274 ->getPropertySetInfo() );
1275 return xRef;
1276}
1277
1278void SAL_CALL
1280 const OUString& rPropertyName, const uno::Any& rValue)
1281{
1283
1284 ::sw::MetaField * const pMeta(
1285 const_cast< ::sw::MetaField * >(m_pImpl->GetMetaField()) );
1286 if (!pMeta)
1287 throw lang::DisposedException();
1288
1289 if ( rPropertyName == "NumberFormat" )
1290 {
1291 sal_Int32 nNumberFormat(0);
1292 if (rValue >>= nNumberFormat)
1293 {
1294 pMeta->SetNumberFormat(static_cast<sal_uInt32>(nNumberFormat));
1295 }
1296 }
1297 else if ( rPropertyName == "IsFixedLanguage" )
1298 {
1299 bool b(false);
1300 if (rValue >>= b)
1301 {
1302 pMeta->SetIsFixedLanguage(b);
1303 }
1304 }
1305 else
1306 {
1307 throw beans::UnknownPropertyException(rPropertyName);
1308 }
1309}
1310
1311uno::Any SAL_CALL
1312SwXMetaField::getPropertyValue(const OUString& rPropertyName)
1313{
1315
1316 ::sw::MetaField const * const pMeta( m_pImpl->GetMetaField() );
1317 if (!pMeta)
1318 throw lang::DisposedException();
1319
1320 uno::Any any;
1321
1322 if ( rPropertyName == "NumberFormat" )
1323 {
1324 const OUString text( getPresentation(false) );
1325 any <<= static_cast<sal_Int32>(pMeta->GetNumberFormat(text));
1326 }
1327 else if ( rPropertyName == "IsFixedLanguage" )
1328 {
1329 any <<= pMeta->IsFixedLanguage();
1330 }
1331 else
1332 {
1333 throw beans::UnknownPropertyException(rPropertyName);
1334 }
1335
1336 return any;
1337}
1338
1339void SAL_CALL
1341 const OUString& /*rPropertyName*/,
1342 const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
1343{
1344 OSL_FAIL("SwXMetaField::addPropertyChangeListener(): not implemented");
1345}
1346
1347void SAL_CALL
1349 const OUString& /*rPropertyName*/,
1350 const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
1351{
1352 OSL_FAIL("SwXMetaField::removePropertyChangeListener(): not implemented");
1353}
1354
1355void SAL_CALL
1357 const OUString& /*rPropertyName*/,
1358 const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
1359{
1360 OSL_FAIL("SwXMetaField::addVetoableChangeListener(): not implemented");
1361}
1362
1363void SAL_CALL
1365 const OUString& /*rPropertyName*/,
1366 const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
1367{
1368 OSL_FAIL("SwXMetaField::removeVetoableChangeListener(): not implemented");
1369}
1370
1371static uno::Reference<rdf::XURI> const&
1372lcl_getURI(const sal_Int16 eKnown)
1373{
1374 static uno::Reference< uno::XComponentContext > xContext(
1375 ::comphelper::getProcessComponentContext());
1376 static uno::Reference< rdf::XURI > xOdfPrefix(
1377 rdf::URI::createKnown(xContext, rdf::URIs::ODF_PREFIX),
1378 uno::UNO_SET_THROW);
1379 static uno::Reference< rdf::XURI > xOdfSuffix(
1380 rdf::URI::createKnown(xContext, rdf::URIs::ODF_SUFFIX),
1381 uno::UNO_SET_THROW);
1382 static uno::Reference< rdf::XURI > xOdfShading(
1383 rdf::URI::createKnown(xContext, rdf::URIs::LO_EXT_SHADING),
1384 uno::UNO_SET_THROW);
1385 switch (eKnown)
1386 {
1387 case rdf::URIs::ODF_PREFIX:
1388 return xOdfPrefix;
1389 case rdf::URIs::ODF_SUFFIX:
1390 return xOdfSuffix;
1391 default:
1392 return xOdfShading;
1393 }
1394}
1395
1396static OUString
1398 uno::Reference<rdf::XRepository> const & xRepository,
1399 uno::Reference<rdf::XResource> const & xMetaField,
1400 uno::Reference<rdf::XURI> const & xPredicate)
1401{
1402 const uno::Reference<container::XEnumeration> xEnum(
1403 xRepository->getStatements(xMetaField, xPredicate, nullptr),
1404 uno::UNO_SET_THROW);
1405 while (xEnum->hasMoreElements()) {
1406 rdf::Statement stmt;
1407 if (!(xEnum->nextElement() >>= stmt)) {
1408 throw uno::RuntimeException();
1409 }
1410 const uno::Reference<rdf::XLiteral> xObject(stmt.Object,
1411 uno::UNO_QUERY);
1412 if (!xObject.is()) continue;
1413 if (xEnum->hasMoreElements()) {
1414 SAL_INFO("sw.uno", "ignoring other odf:Prefix/odf:Suffix statements");
1415 }
1416 return xObject->getValue();
1417 }
1418 return OUString();
1419}
1420
1421void
1423 const uno::Reference<frame::XModel>& xModel,
1424 const uno::Reference<rdf::XMetadatable>& xMetaField,
1425 OUString *const o_pPrefix, OUString *const o_pSuffix, OUString *const o_pShadingColor)
1426{
1427 try {
1428 const uno::Reference<rdf::XRepositorySupplier> xRS(
1429 xModel, uno::UNO_QUERY_THROW);
1430 const uno::Reference<rdf::XRepository> xRepo(
1431 xRS->getRDFRepository(), uno::UNO_SET_THROW);
1432 const uno::Reference<rdf::XResource> xMeta(
1433 xMetaField, uno::UNO_QUERY_THROW);
1434 if (o_pPrefix)
1435 {
1436 *o_pPrefix = lcl_getPrefixOrSuffix(xRepo, xMeta, lcl_getURI(rdf::URIs::ODF_PREFIX));
1437 }
1438 if (o_pSuffix)
1439 {
1440 *o_pSuffix = lcl_getPrefixOrSuffix(xRepo, xMeta, lcl_getURI(rdf::URIs::ODF_SUFFIX));
1441 }
1442 if (o_pShadingColor)
1443 {
1444 *o_pShadingColor = lcl_getPrefixOrSuffix(xRepo, xMeta, lcl_getURI(rdf::URIs::LO_EXT_SHADING));
1445 }
1446 } catch (uno::RuntimeException &) {
1447 throw;
1448 } catch (const uno::Exception &) {
1449 css::uno::Any anyEx = cppu::getCaughtException();
1450 throw lang::WrappedTargetRuntimeException("getPrefixAndSuffix: exception", nullptr, anyEx);
1451 }
1452}
1453
1454// XTextField
1455OUString SAL_CALL
1457{
1459
1460 if (bShowCommand)
1461 {
1462//FIXME ?
1463 return OUString();
1464 }
1465 else
1466 {
1467 // getString should check if this is invalid
1468 const OUString content( getString() );
1469 OUString prefix;
1470 OUString suffix;
1471 getPrefixAndSuffix(GetModel(), this, &prefix, &suffix, nullptr);
1472 return prefix + content + suffix;
1473 }
1474}
1475
1476/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
::std::unique_ptr< XmlIdRegistry_Impl > m_pImpl
const Any & any
virtual bool DeleteAndJoin(SwPaM &, SwDeleteFlags flags=SwDeleteFlags::Default)=0
complete delete of a given PaM
virtual bool InsertPoolItem(const SwPaM &rRg, const SfxPoolItem &, const SetAttrMode nFlags=SetAttrMode::DEFAULT, SwRootFrame const *pLayout=nullptr, SwTextAttr **ppNewTextAttr=nullptr)=0
Insert an attribute.
SfxHintId GetId() const
css::uno::Reference< css::beans::XPropertySetInfo > const & getPropertySetInfo() const
css::uno::Reference< css::frame::XModel3 > GetModel() const
sal_uInt16 Which() const
void EndListeningAll()
bool StartListening(SvtBroadcaster &rBroadcaster)
Definition: doc.hxx:197
IDocumentContentOperations const & getIDocumentContentOperations() const
Definition: doc.cxx:329
::sw::MetaFieldManager & GetMetaFieldManager()
Definition: doc.cxx:137
SwDocShell * GetDocShell()
Definition: doc.hxx:1370
SwFormatMeta is a pool item subclass that owns a Meta.
Definition: fmtmeta.hxx:93
void SetXRefMark(rtl::Reference< SwXReferenceMark > const &xMark)
Definition: atrref.cxx:59
unotools::WeakReference< SwXReferenceMark > const & GetXRefMark() const
Definition: fmtrfmrk.hxx:66
OUString & GetRefName()
Definition: fmtrfmrk.hxx:63
SwTextNode * GetTextNode()
Inline methods from Node.hxx.
Definition: ndtxt.hxx:901
SwNodes & GetNodes()
Node is in which nodes-array/doc?
Definition: node.hxx:706
SwDoc & GetDoc()
Definition: node.hxx:233
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:188
const SwPosition * GetMark() const
Definition: pam.hxx:255
SwNode & GetPointNode() const
Definition: pam.hxx:275
void Exchange()
Definition: pam.hxx:242
const SwPosition * End() const
Definition: pam.hxx:263
SwDoc & GetDoc() const
Definition: pam.hxx:291
const SwPosition * GetPoint() const
Definition: pam.hxx:253
const SwPosition * Start() const
Definition: pam.hxx:258
bool HasMark() const
A PaM marks a selection if Point and Mark are distinct positions.
Definition: pam.hxx:251
Starts a section of nodes in the document model.
Definition: node.hxx:348
A wrapper around SfxPoolItem to store the start position of (usually) a text portion,...
Definition: txatbase.hxx:44
const SwFormatRefMark & GetRefMark() const
Definition: txatbase.hxx:238
const sal_Int32 * End() const
Definition: txatbase.hxx:156
sal_Int32 GetStart() const
Definition: txatbase.hxx:88
SwTextNode is a paragraph in the document model.
Definition: ndtxt.hxx:112
std::vector< SwTextAttr * > GetTextAttrsAt(sal_Int32 const nIndex, sal_uInt16 const nWhich) const
get the innermost text attributes covering position nIndex.
Definition: ndtxt.cxx:1795
SwTextAttr * GetTextAttrForCharAt(const sal_Int32 nIndex, const sal_uInt16 nWhich=RES_TXTATR_END) const
get the text attribute at position nIndex which owns the dummy character CH_TXTATR_* at that position...
Definition: ndtxt.cxx:3155
const SwTextNode & GetTextNode() const
Definition: txtrfmrk.hxx:50
const SfxItemPropertySet * GetPropertySet(sal_uInt16 PropertyId)
Definition: unomap1.cxx:1111
virtual css::uno::Reference< css::text::XTextRange > SAL_CALL getAnchor() override
Definition: unorefmk.cxx:1261
virtual void SAL_CALL dispose() override
Definition: unorefmk.cxx:1248
virtual void SAL_CALL setPropertyValue(const OUString &rPropertyName, const css::uno::Any &rValue) override
Definition: unorefmk.cxx:1279
virtual void SAL_CALL addPropertyChangeListener(const OUString &rPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener > &xListener) override
Definition: unorefmk.cxx:1340
SwXMetaField(SwDoc *const pDoc, ::sw::Meta *const pMeta, css::uno::Reference< css::text::XText > const &xParentText, std::unique_ptr< TextRangeList_t const > pPortions)
virtual void SAL_CALL addVetoableChangeListener(const OUString &rPropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener > &xListener) override
Definition: unorefmk.cxx:1356
virtual ~SwXMetaField() override
Definition: unorefmk.cxx:1205
virtual OUString SAL_CALL getPresentation(sal_Bool bShowCommand) override
Definition: unorefmk.cxx:1456
virtual void SAL_CALL removePropertyChangeListener(const OUString &rPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener > &xListener) override
Definition: unorefmk.cxx:1348
virtual void SAL_CALL removeVetoableChangeListener(const OUString &rPropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener > &xListener) override
Definition: unorefmk.cxx:1364
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
Definition: unorefmk.cxx:1223
virtual sal_Bool SAL_CALL supportsService(const OUString &ServiceName) override
Definition: unorefmk.cxx:1217
virtual void SAL_CALL addEventListener(const css::uno::Reference< css::lang::XEventListener > &xListener) override
Definition: unorefmk.cxx:1234
virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() override
Definition: unorefmk.cxx:1268
virtual OUString SAL_CALL getImplementationName() override
Definition: unorefmk.cxx:1211
virtual void SAL_CALL attach(const css::uno::Reference< css::text::XTextRange > &xTextRange) override
Definition: unorefmk.cxx:1255
virtual void SAL_CALL removeEventListener(const css::uno::Reference< css::lang::XEventListener > &xListener) override
Definition: unorefmk.cxx:1241
virtual css::uno::Any SAL_CALL getPropertyValue(const OUString &rPropertyName) override
Definition: unorefmk.cxx:1312
the Meta has a cached list of text portions for its contents this list is created by SwXTextPortionEn...
Definition: unorefmk.cxx:582
::comphelper::OInterfaceContainerHelper4< css::lang::XEventListener > m_EventListeners
Definition: unorefmk.cxx:586
rtl::Reference< SwXMetaText > m_xText
Definition: unorefmk.cxx:592
uno::Reference< text::XText > m_xParentText
Definition: unorefmk.cxx:591
const ::sw::Meta * GetMeta() const
Definition: unorefmk.cxx:617
bool m_bIsDescriptor
Definition: unorefmk.cxx:590
const ::sw::MetaField * GetMetaField() const
Definition: unorefmk.cxx:1187
unotools::WeakReference< SwXMeta > m_wThis
Definition: unorefmk.cxx:584
sw::Meta * m_pMeta
Definition: unorefmk.cxx:593
std::mutex m_Mutex
Definition: unorefmk.cxx:585
std::unique_ptr< const TextRangeList_t > m_pTextPortions
Definition: unorefmk.cxx:587
bool m_bIsDisposed
Definition: unorefmk.cxx:589
virtual void Notify(const SfxHint &rHint) override
Definition: unorefmk.cxx:623
Impl(SwXMeta &rThis, SwDoc &rDoc, ::sw::Meta *const pMeta, uno::Reference< text::XText > xParentText, std::unique_ptr< TextRangeList_t const > pPortions)
Definition: unorefmk.cxx:595
virtual css::uno::Reference< css::text::XTextRange > SAL_CALL getStart() override
Definition: unorefmk.cxx:1012
virtual void SAL_CALL insertTextContent(const css::uno::Reference< css::text::XTextRange > &xRange, const css::uno::Reference< css::text::XTextContent > &xContent, sal_Bool bAbsorb) override
Definition: unorefmk.cxx:1074
static rtl::Reference< SwXMeta > CreateXMeta(::sw::Meta &rMeta, css::uno::Reference< css::text::XText > const &xParentText=nullptr, std::unique_ptr< TextRangeList_t const > &&pPortions=std::unique_ptr< TextRangeList_t const >())
virtual OUString SAL_CALL getImplementationName() override
Definition: unorefmk.cxx:812
SwXMeta(SwXMeta const &)=delete
bool CheckForOwnMemberMeta(const SwPaM &rPam, const bool bAbsorb)
Definition: unorefmk.cxx:749
virtual ~SwXMeta() override
Definition: unorefmk.cxx:659
virtual void SAL_CALL insertString(const css::uno::Reference< css::text::XTextRange > &xRange, const OUString &aString, sal_Bool bAbsorb) override
Definition: unorefmk.cxx:1056
virtual css::uno::Reference< css::text::XTextRange > SAL_CALL getAnchor() override
Definition: unorefmk.cxx:972
virtual void SAL_CALL insertControlCharacter(const css::uno::Reference< css::text::XTextRange > &xRange, sal_Int16 nControlCharacter, sal_Bool bAbsorb) override
Definition: unorefmk.cxx:1064
virtual void SAL_CALL addEventListener(const css::uno::Reference< css::lang::XEventListener > &xListener) override
Definition: unorefmk.cxx:834
void AttachImpl(const css::uno::Reference< css::text::XTextRange > &xTextRange, const sal_uInt16 nWhich)
Definition: unorefmk.cxx:886
::sw::UnoImplPtr< Impl > m_pImpl
Definition: unometa.hxx:65
virtual css::uno::Reference< css::text::XTextCursor > SAL_CALL createTextCursorByRange(const css::uno::Reference< css::text::XTextRange > &xTextPosition) override
Definition: unorefmk.cxx:1048
virtual css::uno::Reference< css::text::XText > SAL_CALL getText() override
Definition: unorefmk.cxx:1006
virtual css::uno::Reference< css::frame::XModel > GetModel() override
Definition: unorefmk.cxx:1172
virtual css::uno::Reference< css::uno::XInterface > SAL_CALL getParent() override
Definition: unorefmk.cxx:1091
css::uno::Reference< css::text::XText > const & GetParentText() const
Definition: unorefmk.cxx:642
virtual void SAL_CALL removeTextContent(const css::uno::Reference< css::text::XTextContent > &xContent) override
Definition: unorefmk.cxx:1082
virtual ::sfx2::Metadatable * GetCoreObject() override
Definition: unorefmk.cxx:1167
virtual void SAL_CALL setParent(css::uno::Reference< css::uno::XInterface > const &xParent) override
Definition: unorefmk.cxx:1110
virtual void SAL_CALL dispose() override
Definition: unorefmk.cxx:852
virtual OUString SAL_CALL getString() override
Definition: unorefmk.cxx:1026
virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override
Definition: unorefmk.cxx:1130
virtual sal_Bool SAL_CALL hasElements() override
Definition: unorefmk.cxx:1122
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
Definition: unorefmk.cxx:824
bool SetContentRange(SwTextNode *&rpNode, sal_Int32 &rStart, sal_Int32 &rEnd) const
init params with position of the attribute content (w/out CH_TXTATR)
Definition: unorefmk.cxx:727
virtual css::uno::Reference< css::text::XTextRange > SAL_CALL getEnd() override
Definition: unorefmk.cxx:1019
virtual sal_Bool SAL_CALL supportsService(const OUString &rServiceName) override
Definition: unorefmk.cxx:818
virtual css::uno::Type SAL_CALL getElementType() override
Definition: unorefmk.cxx:1117
virtual void SAL_CALL removeEventListener(const css::uno::Reference< css::lang::XEventListener > &xListener) override
Definition: unorefmk.cxx:843
virtual css::uno::Reference< css::text::XTextCursor > SAL_CALL createTextCursor() override
Definition: unorefmk.cxx:1041
virtual void SAL_CALL attach(const css::uno::Reference< css::text::XTextRange > &xTextRange) override
Definition: unorefmk.cxx:966
virtual void SAL_CALL setString(const OUString &rString) override
Definition: unorefmk.cxx:1033
unotools::WeakReference< SwXReferenceMark > m_wThis
Definition: unorefmk.cxx:66
void InsertRefMark(SwPaM &rPam, SwXTextCursor const *const pCursor)
Definition: unorefmk.cxx:183
Impl(SwDoc *const pDoc, SwFormatRefMark *const pRefMark)
Definition: unorefmk.cxx:74
bool IsValid() const
Definition: unorefmk.cxx:86
virtual void Notify(const SfxHint &) override
Definition: unorefmk.cxx:109
const SwFormatRefMark * m_pMarkFormat
Definition: unorefmk.cxx:71
::comphelper::OInterfaceContainerHelper4< css::lang::XEventListener > m_EventListeners
Definition: unorefmk.cxx:68
virtual OUString SAL_CALL getName() override
Definition: unorefmk.cxx:359
virtual css::uno::Reference< css::text::XTextRange > SAL_CALL getAnchor() override
Definition: unorefmk.cxx:279
virtual ~SwXReferenceMark() override
Definition: unorefmk.cxx:121
virtual void SAL_CALL setName(const OUString &rName) override
Definition: unorefmk.cxx:370
virtual void SAL_CALL setPropertyValue(const OUString &rPropertyName, const css::uno::Any &rValue) override
Definition: unorefmk.cxx:428
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
Definition: unorefmk.cxx:160
virtual void SAL_CALL dispose() override
Definition: unorefmk.cxx:311
static rtl::Reference< SwXReferenceMark > CreateXReferenceMark(SwDoc &rDoc, SwFormatRefMark *pMarkFormat)
Definition: unorefmk.cxx:126
virtual void SAL_CALL removePropertyChangeListener(const OUString &rPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener > &xListener) override
Definition: unorefmk.cxx:453
::sw::UnoImplPtr< Impl > m_pImpl
Definition: unorefmark.hxx:48
virtual void SAL_CALL removeEventListener(const css::uno::Reference< css::lang::XEventListener > &xListener) override
Definition: unorefmk.cxx:351
virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() override
Definition: unorefmk.cxx:418
SwXReferenceMark(SwDoc *const pDoc, SwFormatRefMark *const pMark)
Definition: unorefmk.cxx:115
virtual void SAL_CALL removeVetoableChangeListener(const OUString &rPropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener > &xListener) override
Definition: unorefmk.cxx:467
virtual void SAL_CALL addEventListener(const css::uno::Reference< css::lang::XEventListener > &xListener) override
Definition: unorefmk.cxx:343
virtual void SAL_CALL attach(const css::uno::Reference< css::text::XTextRange > &xTextRange) override
Definition: unorefmk.cxx:253
virtual void SAL_CALL addPropertyChangeListener(const OUString &rPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener > &xListener) override
Definition: unorefmk.cxx:446
virtual sal_Bool SAL_CALL supportsService(const OUString &rServiceName) override
Definition: unorefmk.cxx:154
virtual css::uno::Any SAL_CALL getPropertyValue(const OUString &rPropertyName) override
Definition: unorefmk.cxx:435
virtual OUString SAL_CALL getImplementationName() override
Definition: unorefmk.cxx:148
virtual void SAL_CALL addVetoableChangeListener(const OUString &rPropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener > &xListener) override
Definition: unorefmk.cxx:460
bool IsAtEndOfMeta() const
Definition: unoobj.cxx:876
const SwDoc & GetDoc() const
Definition: unoobj2.cxx:762
static rtl::Reference< SwXTextRange > CreateXTextRange(SwDoc &rDoc, const SwPosition &rPos, const SwPosition *const pMark)
Definition: unoobj2.cxx:1221
void Invalidate()
Definition: unotext.cxx:149
void disposeAndClear(::std::unique_lock<::std::mutex > &rGuard, const css::lang::EventObject &rEvt)
virtual void SAL_CALL acquire() SAL_NOEXCEPT SAL_OVERRIDE
virtual void SAL_CALL release() SAL_NOEXCEPT SAL_OVERRIDE
css::uno::Type const & get()
std::shared_ptr< MetaField > makeMetaField(SwFormatMeta *const i_pFormat=nullptr, const sal_uInt32 nNumberFormat=SAL_MAX_UINT32, const bool bIsFixedLanguage=false)
Definition: fmtatr2.cxx:795
void SetIsFixedLanguage(bool b)
Definition: fmtmeta.hxx:188
bool IsFixedLanguage() const
Definition: fmtmeta.hxx:187
sal_uInt32 GetNumberFormat(const OUString &aContent) const
Definition: fmtatr2.cxx:770
void SetNumberFormat(sal_uInt32 nNumberFormat)
Definition: fmtatr2.cxx:783
Meta is an annotation on a range of text.
Definition: fmtmeta.hxx:137
SwTextNode * GetTextNode() const
Definition: fmtmeta.hxx:149
SwFormatMeta * GetFormatMeta() const
Definition: fmtmeta.hxx:151
SwTextMeta * GetTextAttr() const
Definition: fmtatr2.cxx:663
unotools::WeakReference< SwXMeta > const & GetXMeta() const
Definition: fmtmeta.hxx:156
void SetXMeta(rtl::Reference< SwXMeta > const &xMeta)
Definition: fmtatr2.cxx:668
static SwNode * GetStartNode(SwOutlineNodes const *pOutlNds, int nOutlineLevel, SwOutlineNodes::size_type *nOutl)
Definition: docglbl.cxx:89
constexpr TypedWhichId< SwFormatMeta > RES_TXTATR_METAFIELD(49)
constexpr TypedWhichId< SwFormatRefMark > RES_TXTATR_REFMARK(RES_TXTATR_WITHEND_BEGIN)
constexpr TypedWhichId< SwFormatMeta > RES_TXTATR_META(48)
#define SAL_WARN_IF(condition, area, stream)
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
def text(shape, orig_st)
uno::Reference< text::XTextContent > GetNestedTextContent(SwTextNode const &rTextNode, sal_Int32 const nIndex, bool const bParent)
OUString getString(const Any &_rAny)
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
Any SAL_CALL getCaughtException()
end
uno::Reference< text::XText > CreateParentXText(SwDoc &rDoc, const SwPosition &rPos)
Definition: unoobj2.cxx:1240
bool XTextRangeToSwPaM(SwUnoInternalPaM &rToFill, const uno::Reference< text::XTextRange > &xTextRange, ::sw::TextRangeMode const eMode)
Definition: unoobj2.cxx:1108
bool GetDefaultTextContentValue(css::uno::Any &rAny, std::u16string_view rPropertyName, sal_uInt16 nWID=0)
Marks a position in the document model.
Definition: pam.hxx:38
SwNode & GetNode() const
Definition: pam.hxx:81
sal_Int32 GetContentIndex() const
Definition: pam.hxx:85
Reference< XModel > xModel
SetAttrMode
Definition: swtypes.hxx:133
@ FORCEHINTEXPAND
Force hint expand (only matters for hints with CH_TXTATR).
unsigned char sal_Bool
CursorType
SwUnoPropertyMapProvider aSwMapProvider
Definition: unomap1.cxx:88
#define PROPERTY_MAP_PARAGRAPH_EXTENSIONS
Definition: unomap.hxx:52
#define PROPERTY_MAP_METAFIELD
Definition: unomap.hxx:124
::cppu::ImplInheritanceHelper< SwXMeta, css::beans::XPropertySet, css::text::XTextField > SwXMetaField_Base
Definition: unometa.hxx:183
static OUString lcl_getPrefixOrSuffix(uno::Reference< rdf::XRepository > const &xRepository, uno::Reference< rdf::XResource > const &xMetaField, uno::Reference< rdf::XURI > const &xPredicate)
Definition: unorefmk.cxx:1397
void getPrefixAndSuffix(const uno::Reference< frame::XModel > &xModel, const uno::Reference< rdf::XMetadatable > &xMetaField, OUString *const o_pPrefix, OUString *const o_pSuffix, OUString *const o_pShadingColor)
Definition: unorefmk.cxx:1422
static uno::Reference< rdf::XURI > const & lcl_getURI(const sal_Int16 eKnown)
Definition: unorefmk.cxx:1372