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 virtual uno::Reference< text::XTextCursor >
489 CreateCursor() override;
490
491public:
492 SwXMetaText(SwDoc & rDoc, SwXMeta & rMeta);
493
496
497 // XInterface
498 virtual void SAL_CALL acquire() noexcept override { cppu::OWeakObject::acquire(); }
499 virtual void SAL_CALL release() noexcept override { cppu::OWeakObject::release(); }
500
501 // XTypeProvider
502 virtual uno::Sequence< sal_Int8 > SAL_CALL
503 getImplementationId() override;
504
505 // XText
506 virtual uno::Reference< text::XTextCursor > SAL_CALL
507 createTextCursor() override;
508 virtual uno::Reference< text::XTextCursor > SAL_CALL
509 createTextCursorByRange(
510 const uno::Reference< text::XTextRange > & xTextPosition) override;
511
512};
513
514}
515
516SwXMetaText::SwXMetaText(SwDoc & rDoc, SwXMeta & rMeta)
517 : SwXText(&rDoc, CursorType::Meta)
518 , m_rMeta(rMeta)
519{
520}
521
523{
524 SwXText const * const pParent(
525 dynamic_cast<SwXText*>(m_rMeta.GetParentText().get()));
526 return pParent ? pParent->GetStartNode() : nullptr;
527}
528
529void SwXMetaText::PrepareForAttach( uno::Reference<text::XTextRange> & xRange,
530 const SwPaM & rPam)
531{
532 // create a new cursor to prevent modifying SwXTextRange
533 xRange = static_cast<text::XWordCursor*>(
534 new SwXTextCursor(*GetDoc(), &m_rMeta, CursorType::Meta, *rPam.GetPoint(),
535 (rPam.HasMark()) ? rPam.GetMark() : nullptr));
536}
537
538bool SwXMetaText::CheckForOwnMemberMeta(const SwPaM & rPam, const bool bAbsorb)
539{
540 return m_rMeta.CheckForOwnMemberMeta(rPam, bAbsorb);
541}
542
543uno::Reference< text::XTextCursor > SwXMetaText::CreateCursor()
544{
545 uno::Reference< text::XTextCursor > xRet;
546 if (IsValid())
547 {
548 SwTextNode * pTextNode;
549 sal_Int32 nMetaStart;
550 sal_Int32 nMetaEnd;
551 const bool bSuccess(
552 m_rMeta.SetContentRange(pTextNode, nMetaStart, nMetaEnd) );
553 if (bSuccess)
554 {
555 SwPosition aPos(*pTextNode, nMetaStart);
556 xRet = static_cast<text::XWordCursor*>(
557 new SwXTextCursor(*GetDoc(), &m_rMeta, CursorType::Meta, aPos));
558 }
559 }
560 return xRet;
561}
562
563uno::Sequence<sal_Int8> SAL_CALL
564SwXMetaText::getImplementationId()
565{
566 return css::uno::Sequence<sal_Int8>();
567}
568
569// XText
570uno::Reference< text::XTextCursor > SAL_CALL
571SwXMetaText::createTextCursor()
572{
573 return CreateCursor();
574}
575
576uno::Reference< text::XTextCursor > SAL_CALL
577SwXMetaText::createTextCursorByRange(
578 const uno::Reference<text::XTextRange> & xTextPosition)
579{
580 const uno::Reference<text::XTextCursor> xCursor( CreateCursor() );
581 xCursor->gotoRange(xTextPosition, false);
582 return xCursor;
583}
584
593{
594public:
596 std::mutex m_Mutex; // just for OInterfaceContainerHelper4
598 std::unique_ptr<const TextRangeList_t> m_pTextPortions;
599 // 3 possible states: not attached, attached, disposed
602 uno::Reference<text::XText> m_xParentText;
605
606 Impl(SwXMeta& rThis, SwDoc& rDoc,
607 ::sw::Meta* const pMeta,
608 uno::Reference<text::XText> xParentText,
609 std::unique_ptr<TextRangeList_t const> pPortions)
610 : m_pTextPortions(std::move(pPortions))
611 , m_bIsDisposed(false)
612 , m_bIsDescriptor(nullptr == pMeta)
613 , m_xParentText(std::move(xParentText))
614 , m_xText(new SwXMetaText(rDoc, rThis))
615 , m_pMeta(pMeta)
616 {
617 !m_bIsDescriptor && StartListening(m_pMeta->GetNotifier());
618 }
619
620 inline const ::sw::Meta* GetMeta() const;
621 // only for SwXMetaField!
622 inline const ::sw::MetaField* GetMetaField() const;
623protected:
624 virtual void Notify(const SfxHint& rHint) override;
625
626};
627
628inline const ::sw::Meta* SwXMeta::Impl::GetMeta() const
629{
630 return m_pMeta;
631}
632
633// sw::BroadcastingModify
635{
636 m_pTextPortions.reset(); // throw away cache (SwTextNode changed)
637 if(rHint.GetId() != SfxHintId::Dying && rHint.GetId() != SfxHintId::Deinitializing)
638 return;
639
640 m_bIsDisposed = true;
641 m_pMeta = nullptr;
642 m_xText->Invalidate();
643 uno::Reference<uno::XInterface> const xThis(m_wThis);
644 if (!xThis.is())
645 { // fdo#72695: if UNO object is already dead, don't revive it with event
646 return;
647 }
648 lang::EventObject const ev(xThis);
649 std::unique_lock aGuard(m_Mutex);
650 m_EventListeners.disposeAndClear(aGuard, ev);
651}
652
653uno::Reference<text::XText> const & SwXMeta::GetParentText() const
654{
655 return m_pImpl->m_xParentText;
656}
657
658SwXMeta::SwXMeta(SwDoc *const pDoc, ::sw::Meta *const pMeta,
659 uno::Reference<text::XText> const& xParentText,
660 std::unique_ptr<TextRangeList_t const> pPortions)
661 : m_pImpl( new SwXMeta::Impl(*this, *pDoc, pMeta, xParentText, std::move(pPortions)) )
662{
663}
664
666 : m_pImpl( new SwXMeta::Impl(*this, *pDoc, nullptr, nullptr, nullptr) )
667{
668}
669
671{
672}
673
675SwXMeta::CreateXMeta(SwDoc & rDoc, bool const isField)
676{
677 // this is why the constructor is private: need to acquire pXMeta here
678 rtl::Reference<SwXMeta> xMeta(isField
679 ? new SwXMetaField(& rDoc) : new SwXMeta(& rDoc));
680 // need a permanent Reference to initialize m_wThis
681 xMeta->m_pImpl->m_wThis = xMeta.get();
682 return xMeta;
683}
684
687 uno::Reference<text::XText> const& i_xParent,
688 std::unique_ptr<TextRangeList_t const> && pPortions)
689{
690 // re-use existing SwXMeta
691 // #i105557#: do not iterate over the registered clients: race condition
692 rtl::Reference<SwXMeta> xMeta(rMeta.GetXMeta());
693 if (xMeta.is())
694 {
695 if (pPortions) // set cache in the XMeta to the given portions
696 {
697 // NB: the meta must always be created with the complete content
698 // if SwXTextPortionEnumeration is created for a selection,
699 // it must be checked that the Meta is contained in the selection!
700 xMeta->m_pImpl->m_pTextPortions = std::move(pPortions);
701 // ??? is this necessary?
702 if (xMeta->m_pImpl->m_xParentText.get() != i_xParent.get())
703 {
704 SAL_WARN("sw.uno", "SwXMeta with different parent?");
705 xMeta->m_pImpl->m_xParentText.set(i_xParent);
706 }
707 }
708 return xMeta;
709 }
710
711 // create new SwXMeta
712 SwTextNode * const pTextNode( rMeta.GetTextNode() );
713 SAL_WARN_IF(!pTextNode, "sw.uno", "CreateXMeta: no text node?");
714 if (!pTextNode) { return nullptr; }
715 uno::Reference<text::XText> xParentText(i_xParent);
716 if (!xParentText.is())
717 {
718 SwTextMeta * const pTextAttr( rMeta.GetTextAttr() );
719 SAL_WARN_IF(!pTextAttr, "sw.uno", "CreateXMeta: no text attr?");
720 if (!pTextAttr) { return nullptr; }
721 const SwPosition aPos(*pTextNode, pTextAttr->GetStart());
722 xParentText.set( ::sw::CreateParentXText(pTextNode->GetDoc(), aPos) );
723 }
724 if (!xParentText.is()) { return nullptr; }
725 // this is why the constructor is private: need to acquire pXMeta here
726 xMeta = (RES_TXTATR_META == rMeta.GetFormatMeta()->Which())
727 ? new SwXMeta (&pTextNode->GetDoc(), &rMeta, xParentText,
728 std::move(pPortions))
729 : new SwXMetaField(&pTextNode->GetDoc(), &rMeta, xParentText,
730 std::move(pPortions));
731 // in order to initialize the weak pointer cache in the core object
732 rMeta.SetXMeta(xMeta);
733 // need a permanent Reference to initialize m_wThis
734 xMeta->m_pImpl->m_wThis = xMeta.get();
735 return xMeta;
736}
737
739 SwTextNode *& rpNode, sal_Int32 & rStart, sal_Int32 & rEnd ) const
740{
741 ::sw::Meta const * const pMeta( m_pImpl->GetMeta() );
742 if (pMeta)
743 {
744 SwTextMeta const * const pTextAttr( pMeta->GetTextAttr() );
745 if (pTextAttr)
746 {
747 rpNode = pMeta->GetTextNode();
748 if (rpNode)
749 {
750 // rStart points at the first position _within_ the meta!
751 rStart = pTextAttr->GetStart() + 1;
752 rEnd = *pTextAttr->End();
753 return true;
754 }
755 }
756 }
757 return false;
758}
759
760bool SwXMeta::CheckForOwnMemberMeta(const SwPaM & rPam, const bool bAbsorb)
761{
762 SwTextNode * pTextNode;
763 sal_Int32 nMetaStart;
764 sal_Int32 nMetaEnd;
765 const bool bSuccess( SetContentRange(pTextNode, nMetaStart, nMetaEnd) );
766 OSL_ENSURE(bSuccess, "no pam?");
767 if (!bSuccess)
768 throw lang::DisposedException();
769
770 SwPosition const * const pStartPos( rPam.Start() );
771 if (&pStartPos->GetNode() != pTextNode)
772 {
773 throw lang::IllegalArgumentException(
774 "trying to insert into a nesting text content, but start "
775 "of text range not in same paragraph as text content",
776 nullptr, 0);
777 }
778 bool bForceExpandHints(false);
779 const sal_Int32 nStartPos(pStartPos->GetContentIndex());
780 // not <= but < because nMetaStart is behind dummy char!
781 // not >= but > because == means insert at end!
782 if ((nStartPos < nMetaStart) || (nStartPos > nMetaEnd))
783 {
784 throw lang::IllegalArgumentException(
785 "trying to insert into a nesting text content, but start "
786 "of text range not inside text content",
787 nullptr, 0);
788 }
789 else if (nStartPos == nMetaEnd)
790 {
791 bForceExpandHints = true;
792 }
793 if (rPam.HasMark() && bAbsorb)
794 {
795 SwPosition const * const pEndPos( rPam.End() );
796 if (&pEndPos->GetNode() != pTextNode)
797 {
798 throw lang::IllegalArgumentException(
799 "trying to insert into a nesting text content, but end "
800 "of text range not in same paragraph as text content",
801 nullptr, 0);
802 }
803 const sal_Int32 nEndPos(pEndPos->GetContentIndex());
804 // not <= but < because nMetaStart is behind dummy char!
805 // not >= but > because == means insert at end!
806 if ((nEndPos < nMetaStart) || (nEndPos > nMetaEnd))
807 {
808 throw lang::IllegalArgumentException(
809 "trying to insert into a nesting text content, but end "
810 "of text range not inside text content",
811 nullptr, 0);
812 }
813 else if (nEndPos == nMetaEnd)
814 {
815 bForceExpandHints = true;
816 }
817 }
818 return bForceExpandHints;
819}
820
821// XServiceInfo
822OUString SAL_CALL
824{
825 return "SwXMeta";
826}
827
828sal_Bool SAL_CALL
829SwXMeta::supportsService(const OUString& rServiceName)
830{
831 return cppu::supportsService(this, rServiceName);
832}
833
834uno::Sequence< OUString > SAL_CALL
836{
837 return {
838 "com.sun.star.text.TextContent",
839 "com.sun.star.text.InContentMetadata"
840 };
841}
842
843// XComponent
844void SAL_CALL
846 uno::Reference< lang::XEventListener> const & xListener )
847{
848 // no need to lock here as m_pImpl is const and container threadsafe
849 std::unique_lock aGuard(m_pImpl->m_Mutex);
850 m_pImpl->m_EventListeners.addInterface(aGuard, xListener);
851}
852
853void SAL_CALL
855 uno::Reference< lang::XEventListener> const & xListener )
856{
857 // no need to lock here as m_pImpl is const and container threadsafe
858 std::unique_lock aGuard(m_pImpl->m_Mutex);
859 m_pImpl->m_EventListeners.removeInterface(aGuard, xListener);
860}
861
862void SAL_CALL
864{
866
867 if (m_pImpl->m_bIsDescriptor)
868 {
869 m_pImpl->m_pTextPortions.reset();
870 lang::EventObject const ev(static_cast< ::cppu::OWeakObject&>(*this));
871 std::unique_lock aGuard(m_pImpl->m_Mutex);
872 m_pImpl->m_EventListeners.disposeAndClear(aGuard, ev);
873 m_pImpl->m_bIsDisposed = true;
874 m_pImpl->m_xText->Invalidate();
875 }
876 else if (!m_pImpl->m_bIsDisposed)
877 {
878 SwTextNode * pTextNode;
879 sal_Int32 nMetaStart;
880 sal_Int32 nMetaEnd;
881 const bool bSuccess(SetContentRange(pTextNode, nMetaStart, nMetaEnd));
882 OSL_ENSURE(bSuccess, "no pam?");
883 if (bSuccess)
884 {
885 // -1 because of CH_TXTATR
886 SwPaM aPam( *pTextNode, nMetaStart - 1, *pTextNode, nMetaEnd );
887 SwDoc& rDoc( pTextNode->GetDoc() );
889
890 // removal should call Modify and do the dispose
891 assert(m_pImpl->m_bIsDisposed);
892 }
893 }
894}
895
896void
897SwXMeta::AttachImpl(const uno::Reference< text::XTextRange > & i_xTextRange,
898 const sal_uInt16 i_nWhich)
899{
901
902 if (m_pImpl->m_bIsDisposed)
903 {
904 throw lang::DisposedException();
905 }
906 if (!m_pImpl->m_bIsDescriptor)
907 {
908 throw uno::RuntimeException(
909 "SwXMeta::attach(): already attached",
910 static_cast< ::cppu::OWeakObject* >(this));
911 }
912
913 SwXTextRange *const pRange(dynamic_cast<SwXTextRange*>(i_xTextRange.get()));
914 OTextCursorHelper *const pCursor(dynamic_cast<OTextCursorHelper*>(i_xTextRange.get()));
915 if (!pRange && !pCursor)
916 {
917 throw lang::IllegalArgumentException(
918 "SwXMeta::attach(): argument not supported type",
919 static_cast< ::cppu::OWeakObject* >(this), 0);
920 }
921
922 SwDoc * const pDoc(
923 pRange ? &pRange->GetDoc() : pCursor->GetDoc());
924 if (!pDoc)
925 {
926 throw lang::IllegalArgumentException(
927 "SwXMeta::attach(): argument has no SwDoc",
928 static_cast< ::cppu::OWeakObject* >(this), 0);
929 }
930
931 SwUnoInternalPaM aPam(*pDoc);
932 ::sw::XTextRangeToSwPaM(aPam, i_xTextRange);
933
934 UnoActionContext aContext(pDoc);
935
936 SwXTextCursor const*const pTextCursor(
937 dynamic_cast<SwXTextCursor*>(pCursor));
938 const bool bForceExpandHints(pTextCursor && pTextCursor->IsAtEndOfMeta());
939 const SetAttrMode nInsertFlags( bForceExpandHints
943
944 const std::shared_ptr< ::sw::Meta> pMeta( (RES_TXTATR_META == i_nWhich)
945 ? std::make_shared< ::sw::Meta>( nullptr )
946 : std::shared_ptr< ::sw::Meta>(
948 SwFormatMeta meta(pMeta, i_nWhich); // this is cloned by Insert!
949 const bool bSuccess( pDoc->getIDocumentContentOperations().InsertPoolItem( aPam, meta, nInsertFlags ) );
950 SwTextAttr * const pTextAttr( pMeta->GetTextAttr() );
951 if (!bSuccess)
952 {
953 throw lang::IllegalArgumentException(
954 "SwXMeta::attach(): cannot create meta: range invalid?",
955 static_cast< ::cppu::OWeakObject* >(this), 1);
956 }
957 if (!pTextAttr)
958 {
959 OSL_FAIL("meta inserted, but has no text attribute?");
960 throw uno::RuntimeException(
961 "SwXMeta::attach(): cannot create meta",
962 static_cast< ::cppu::OWeakObject* >(this));
963 }
964
965 m_pImpl->EndListeningAll();
966 m_pImpl->m_pMeta = pMeta.get();
967 m_pImpl->StartListening(pMeta->GetNotifier());
968 pMeta->SetXMeta(this);
969
970 m_pImpl->m_xParentText = ::sw::CreateParentXText(*pDoc, *aPam.GetPoint());
971
972 m_pImpl->m_bIsDescriptor = false;
973}
974
975// XTextContent
976void SAL_CALL
977SwXMeta::attach(const uno::Reference< text::XTextRange > & i_xTextRange)
978{
979 return SwXMeta::AttachImpl(i_xTextRange, RES_TXTATR_META);
980}
981
982uno::Reference< text::XTextRange > SAL_CALL
984{
986
987 if (m_pImpl->m_bIsDisposed)
988 {
989 throw lang::DisposedException();
990 }
991 if (m_pImpl->m_bIsDescriptor)
992 {
993 throw uno::RuntimeException(
994 "SwXMeta::getAnchor(): not inserted",
995 static_cast< ::cppu::OWeakObject* >(this));
996 }
997
998 SwTextNode * pTextNode;
999 sal_Int32 nMetaStart;
1000 sal_Int32 nMetaEnd;
1001 const bool bSuccess(SetContentRange(pTextNode, nMetaStart, nMetaEnd));
1002 OSL_ENSURE(bSuccess, "no pam?");
1003 if (!bSuccess)
1004 {
1005 throw lang::DisposedException(
1006 "SwXMeta::getAnchor(): not attached",
1007 static_cast< ::cppu::OWeakObject* >(this));
1008 }
1009
1010 const SwPosition start(*pTextNode, nMetaStart - 1); // -1 due to CH_TXTATR
1011 const SwPosition end(*pTextNode, nMetaEnd);
1012 return SwXTextRange::CreateXTextRange(pTextNode->GetDoc(), start, &end);
1013}
1014
1015// XTextRange
1016uno::Reference< text::XText > SAL_CALL
1018{
1019 return this;
1020}
1021
1022uno::Reference< text::XTextRange > SAL_CALL
1024{
1026 return m_pImpl->m_xText->getStart();
1027}
1028
1029uno::Reference< text::XTextRange > SAL_CALL
1031{
1033 return m_pImpl->m_xText->getEnd();
1034}
1035
1036OUString SAL_CALL
1038{
1040 return m_pImpl->m_xText->getString();
1041}
1042
1043void SAL_CALL
1044SwXMeta::setString(const OUString& rString)
1045{
1047 return m_pImpl->m_xText->setString(rString);
1048}
1049
1050// XSimpleText
1051uno::Reference< text::XTextCursor > SAL_CALL
1053{
1055 return m_pImpl->m_xText->createTextCursor();
1056}
1057
1058uno::Reference< text::XTextCursor > SAL_CALL
1060 const uno::Reference<text::XTextRange> & xTextPosition)
1061{
1063 return m_pImpl->m_xText->createTextCursorByRange(xTextPosition);
1064}
1065
1066void SAL_CALL
1067SwXMeta::insertString(const uno::Reference<text::XTextRange> & xRange,
1068 const OUString& rString, sal_Bool bAbsorb)
1069{
1071 return m_pImpl->m_xText->insertString(xRange, rString, bAbsorb);
1072}
1073
1074void SAL_CALL
1075SwXMeta::insertControlCharacter(const uno::Reference<text::XTextRange> & xRange,
1076 sal_Int16 nControlCharacter, sal_Bool bAbsorb)
1077{
1079 return m_pImpl->m_xText->insertControlCharacter(xRange, nControlCharacter,
1080 bAbsorb);
1081}
1082
1083// XText
1084void SAL_CALL
1085SwXMeta::insertTextContent( const uno::Reference<text::XTextRange> & xRange,
1086 const uno::Reference<text::XTextContent> & xContent, sal_Bool bAbsorb)
1087{
1089 return m_pImpl->m_xText->insertTextContent(xRange, xContent, bAbsorb);
1090}
1091
1092void SAL_CALL
1094 const uno::Reference< text::XTextContent > & xContent)
1095{
1097 return m_pImpl->m_xText->removeTextContent(xContent);
1098}
1099
1100// XChild
1101uno::Reference< uno::XInterface > SAL_CALL
1103{
1105 SwTextNode * pTextNode;
1106 sal_Int32 nMetaStart;
1107 sal_Int32 nMetaEnd;
1108 bool const bSuccess( SetContentRange(pTextNode, nMetaStart, nMetaEnd) );
1109 OSL_ENSURE(bSuccess, "no pam?");
1110 if (!bSuccess) { throw lang::DisposedException(); }
1111 // in order to prevent getting this meta, subtract 1 from nMetaStart;
1112 // so we get the index of the dummy character, and we exclude it
1113 // by calling GetTextAttrAt(_, _, PARENT) in GetNestedTextContent
1114 uno::Reference<text::XTextContent> const xRet(
1115 SwUnoCursorHelper::GetNestedTextContent(*pTextNode, nMetaStart - 1,
1116 true) );
1117 return xRet;
1118}
1119
1120void SAL_CALL
1121SwXMeta::setParent(uno::Reference< uno::XInterface > const& /*xParent*/)
1122{
1123 throw lang::NoSupportException("setting parent not supported", *this);
1124}
1125
1126// XElementAccess
1127uno::Type SAL_CALL
1129{
1131}
1132
1134{
1136 return m_pImpl->m_pMeta != nullptr;
1137}
1138
1139// XEnumerationAccess
1140uno::Reference< container::XEnumeration > SAL_CALL
1142{
1144
1145 if (m_pImpl->m_bIsDisposed)
1146 {
1147 throw lang::DisposedException();
1148 }
1149 if (m_pImpl->m_bIsDescriptor)
1150 {
1151 throw uno::RuntimeException(
1152 "createEnumeration(): not inserted",
1153 static_cast< ::cppu::OWeakObject* >(this));
1154 }
1155
1156 SwTextNode * pTextNode;
1157 sal_Int32 nMetaStart;
1158 sal_Int32 nMetaEnd;
1159 const bool bSuccess(SetContentRange(pTextNode, nMetaStart, nMetaEnd));
1160 OSL_ENSURE(bSuccess, "no pam?");
1161 if (!bSuccess)
1162 throw lang::DisposedException();
1163
1164 SwPaM aPam(*pTextNode, nMetaStart);
1165
1166 if (!m_pImpl->m_pTextPortions)
1167 {
1168 return new SwXTextPortionEnumeration(
1169 aPam, GetParentText(), nMetaStart, nMetaEnd);
1170 }
1171 else // cached!
1172 {
1173 return new SwXTextPortionEnumeration(aPam, std::deque(*m_pImpl->m_pTextPortions));
1174 }
1175}
1176
1177// MetadatableMixin
1178::sfx2::Metadatable* SwXMeta::GetCoreObject()
1179{
1180 return const_cast< ::sw::Meta * >(m_pImpl->GetMeta());
1181}
1182
1183uno::Reference<frame::XModel> SwXMeta::GetModel()
1184{
1185 ::sw::Meta const * const pMeta( m_pImpl->GetMeta() );
1186 if (pMeta)
1187 {
1188 SwTextNode const * const pTextNode( pMeta->GetTextNode() );
1189 if (pTextNode)
1190 {
1191 SwDocShell const * const pShell(pTextNode->GetDoc().GetDocShell());
1192 return pShell ? pShell->GetModel() : nullptr;
1193 }
1194 }
1195 return nullptr;
1196}
1197
1198inline const ::sw::MetaField* SwXMeta::Impl::GetMetaField() const
1199{
1200 return dynamic_cast<sw::MetaField*>(m_pMeta);
1201}
1202
1203SwXMetaField::SwXMetaField(SwDoc *const pDoc, ::sw::Meta *const pMeta,
1204 uno::Reference<text::XText> const& xParentText,
1205 std::unique_ptr<TextRangeList_t const> pPortions)
1206 : SwXMetaField_Base(pDoc, pMeta, xParentText, std::move(pPortions))
1207{
1208 assert(dynamic_cast< ::sw::MetaField* >(pMeta) && "SwXMetaField created for wrong hint!");
1209}
1210
1212 : SwXMetaField_Base(pDoc)
1213{
1214}
1215
1217{
1218}
1219
1220// XServiceInfo
1221OUString SAL_CALL
1223{
1224 return "SwXMetaField";
1225}
1226
1227sal_Bool SAL_CALL
1228SwXMetaField::supportsService(const OUString& rServiceName)
1229{
1230 return cppu::supportsService(this, rServiceName);
1231}
1232
1233uno::Sequence< OUString > SAL_CALL
1235{
1236 return {
1237 "com.sun.star.text.TextContent",
1238 "com.sun.star.text.TextField",
1239 "com.sun.star.text.textfield.MetadataField"
1240 };
1241}
1242
1243// XComponent
1244void SAL_CALL
1246 uno::Reference< lang::XEventListener> const & xListener )
1247{
1248 return SwXMeta::addEventListener(xListener);
1249}
1250
1251void SAL_CALL
1253 uno::Reference< lang::XEventListener> const & xListener )
1254{
1255 return SwXMeta::removeEventListener(xListener);
1256}
1257
1258void SAL_CALL
1260{
1261 return SwXMeta::dispose();
1262}
1263
1264// XTextContent
1265void SAL_CALL
1266SwXMetaField::attach(const uno::Reference< text::XTextRange > & i_xTextRange)
1267{
1268 return SwXMeta::AttachImpl(i_xTextRange, RES_TXTATR_METAFIELD);
1269}
1270
1271uno::Reference< text::XTextRange > SAL_CALL
1273{
1274 return SwXMeta::getAnchor();
1275}
1276
1277// XPropertySet
1278uno::Reference< beans::XPropertySetInfo > SAL_CALL
1280{
1282
1283 static uno::Reference< beans::XPropertySetInfo > xRef(
1285 ->getPropertySetInfo() );
1286 return xRef;
1287}
1288
1289void SAL_CALL
1291 const OUString& rPropertyName, const uno::Any& rValue)
1292{
1294
1295 ::sw::MetaField * const pMeta(
1296 const_cast< ::sw::MetaField * >(m_pImpl->GetMetaField()) );
1297 if (!pMeta)
1298 throw lang::DisposedException();
1299
1300 if ( rPropertyName == "NumberFormat" )
1301 {
1302 sal_Int32 nNumberFormat(0);
1303 if (rValue >>= nNumberFormat)
1304 {
1305 pMeta->SetNumberFormat(static_cast<sal_uInt32>(nNumberFormat));
1306 }
1307 }
1308 else if ( rPropertyName == "IsFixedLanguage" )
1309 {
1310 bool b(false);
1311 if (rValue >>= b)
1312 {
1313 pMeta->SetIsFixedLanguage(b);
1314 }
1315 }
1316 else
1317 {
1318 throw beans::UnknownPropertyException(rPropertyName);
1319 }
1320}
1321
1322uno::Any SAL_CALL
1323SwXMetaField::getPropertyValue(const OUString& rPropertyName)
1324{
1326
1327 ::sw::MetaField const * const pMeta( m_pImpl->GetMetaField() );
1328 if (!pMeta)
1329 throw lang::DisposedException();
1330
1331 uno::Any any;
1332
1333 if ( rPropertyName == "NumberFormat" )
1334 {
1335 const OUString text( getPresentation(false) );
1336 any <<= static_cast<sal_Int32>(pMeta->GetNumberFormat(text));
1337 }
1338 else if ( rPropertyName == "IsFixedLanguage" )
1339 {
1340 any <<= pMeta->IsFixedLanguage();
1341 }
1342 else
1343 {
1344 throw beans::UnknownPropertyException(rPropertyName);
1345 }
1346
1347 return any;
1348}
1349
1350void SAL_CALL
1352 const OUString& /*rPropertyName*/,
1353 const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
1354{
1355 OSL_FAIL("SwXMetaField::addPropertyChangeListener(): not implemented");
1356}
1357
1358void SAL_CALL
1360 const OUString& /*rPropertyName*/,
1361 const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
1362{
1363 OSL_FAIL("SwXMetaField::removePropertyChangeListener(): not implemented");
1364}
1365
1366void SAL_CALL
1368 const OUString& /*rPropertyName*/,
1369 const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
1370{
1371 OSL_FAIL("SwXMetaField::addVetoableChangeListener(): not implemented");
1372}
1373
1374void SAL_CALL
1376 const OUString& /*rPropertyName*/,
1377 const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
1378{
1379 OSL_FAIL("SwXMetaField::removeVetoableChangeListener(): not implemented");
1380}
1381
1382static uno::Reference<rdf::XURI> const&
1383lcl_getURI(const sal_Int16 eKnown)
1384{
1385 static uno::Reference< uno::XComponentContext > xContext(
1386 ::comphelper::getProcessComponentContext());
1387 static uno::Reference< rdf::XURI > xOdfPrefix(
1388 rdf::URI::createKnown(xContext, rdf::URIs::ODF_PREFIX),
1389 uno::UNO_SET_THROW);
1390 static uno::Reference< rdf::XURI > xOdfSuffix(
1391 rdf::URI::createKnown(xContext, rdf::URIs::ODF_SUFFIX),
1392 uno::UNO_SET_THROW);
1393 static uno::Reference< rdf::XURI > xOdfShading(
1394 rdf::URI::createKnown(xContext, rdf::URIs::LO_EXT_SHADING),
1395 uno::UNO_SET_THROW);
1396 switch (eKnown)
1397 {
1398 case rdf::URIs::ODF_PREFIX:
1399 return xOdfPrefix;
1400 case rdf::URIs::ODF_SUFFIX:
1401 return xOdfSuffix;
1402 default:
1403 return xOdfShading;
1404 }
1405}
1406
1407static OUString
1409 uno::Reference<rdf::XRepository> const & xRepository,
1410 uno::Reference<rdf::XResource> const & xMetaField,
1411 uno::Reference<rdf::XURI> const & xPredicate)
1412{
1413 const uno::Reference<container::XEnumeration> xEnum(
1414 xRepository->getStatements(xMetaField, xPredicate, nullptr),
1415 uno::UNO_SET_THROW);
1416 while (xEnum->hasMoreElements()) {
1417 rdf::Statement stmt;
1418 if (!(xEnum->nextElement() >>= stmt)) {
1419 throw uno::RuntimeException();
1420 }
1421 const uno::Reference<rdf::XLiteral> xObject(stmt.Object,
1422 uno::UNO_QUERY);
1423 if (!xObject.is()) continue;
1424 if (xEnum->hasMoreElements()) {
1425 SAL_INFO("sw.uno", "ignoring other odf:Prefix/odf:Suffix statements");
1426 }
1427 return xObject->getValue();
1428 }
1429 return OUString();
1430}
1431
1432void
1434 const uno::Reference<frame::XModel>& xModel,
1435 const uno::Reference<rdf::XMetadatable>& xMetaField,
1436 OUString *const o_pPrefix, OUString *const o_pSuffix, OUString *const o_pShadingColor)
1437{
1438 try {
1439 const uno::Reference<rdf::XRepositorySupplier> xRS(
1440 xModel, uno::UNO_QUERY_THROW);
1441 const uno::Reference<rdf::XRepository> xRepo(
1442 xRS->getRDFRepository(), uno::UNO_SET_THROW);
1443 const uno::Reference<rdf::XResource> xMeta(
1444 xMetaField, uno::UNO_QUERY_THROW);
1445 if (o_pPrefix)
1446 {
1447 *o_pPrefix = lcl_getPrefixOrSuffix(xRepo, xMeta, lcl_getURI(rdf::URIs::ODF_PREFIX));
1448 }
1449 if (o_pSuffix)
1450 {
1451 *o_pSuffix = lcl_getPrefixOrSuffix(xRepo, xMeta, lcl_getURI(rdf::URIs::ODF_SUFFIX));
1452 }
1453 if (o_pShadingColor)
1454 {
1455 *o_pShadingColor = lcl_getPrefixOrSuffix(xRepo, xMeta, lcl_getURI(rdf::URIs::LO_EXT_SHADING));
1456 }
1457 } catch (uno::RuntimeException &) {
1458 throw;
1459 } catch (const uno::Exception &) {
1460 css::uno::Any anyEx = cppu::getCaughtException();
1461 throw lang::WrappedTargetRuntimeException("getPrefixAndSuffix: exception", nullptr, anyEx);
1462 }
1463}
1464
1465// XTextField
1466OUString SAL_CALL
1468{
1470
1471 if (bShowCommand)
1472 {
1473//FIXME ?
1474 return OUString();
1475 }
1476 else
1477 {
1478 // getString should check if this is invalid
1479 const OUString content( getString() );
1480 OUString prefix;
1481 OUString suffix;
1482 getPrefixAndSuffix(GetModel(), this, &prefix, &suffix, nullptr);
1483 return prefix + content + suffix;
1484 }
1485}
1486
1487/* 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:195
IDocumentContentOperations const & getIDocumentContentOperations() const
Definition: doc.cxx:323
::sw::MetaFieldManager & GetMetaFieldManager()
Definition: doc.cxx:131
SwDocShell * GetDocShell()
Definition: doc.hxx:1364
void SetXRefMark(rtl::Reference< SwXReferenceMark > const &xMark)
Definition: atrref.cxx:56
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:903
SwNodes & GetNodes()
Node is in which nodes-array/doc?
Definition: node.hxx:744
SwDoc & GetDoc()
Definition: node.hxx:233
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:187
const SwPosition * GetMark() const
Definition: pam.hxx:263
SwNode & GetPointNode() const
Definition: pam.hxx:283
void Exchange()
Definition: pam.cxx:656
const SwPosition * End() const
Definition: pam.hxx:271
SwDoc & GetDoc() const
Definition: pam.hxx:299
const SwPosition * GetPoint() const
Definition: pam.hxx:261
const SwPosition * Start() const
Definition: pam.hxx:266
bool HasMark() const
A PaM marks a selection if Point and Mark are distinct positions.
Definition: pam.hxx:259
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:1793
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:3153
const SwTextNode & GetTextNode() const
Definition: txtrfmrk.hxx:47
const SfxItemPropertySet * GetPropertySet(sal_uInt16 PropertyId)
Definition: unomap1.cxx:1082
virtual css::uno::Reference< css::text::XTextRange > SAL_CALL getAnchor() override
Definition: unorefmk.cxx:1272
virtual void SAL_CALL dispose() override
Definition: unorefmk.cxx:1259
virtual void SAL_CALL setPropertyValue(const OUString &rPropertyName, const css::uno::Any &rValue) override
Definition: unorefmk.cxx:1290
virtual void SAL_CALL addPropertyChangeListener(const OUString &rPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener > &xListener) override
Definition: unorefmk.cxx:1351
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:1367
virtual ~SwXMetaField() override
Definition: unorefmk.cxx:1216
virtual OUString SAL_CALL getPresentation(sal_Bool bShowCommand) override
Definition: unorefmk.cxx:1467
virtual void SAL_CALL removePropertyChangeListener(const OUString &rPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener > &xListener) override
Definition: unorefmk.cxx:1359
virtual void SAL_CALL removeVetoableChangeListener(const OUString &rPropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener > &xListener) override
Definition: unorefmk.cxx:1375
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
Definition: unorefmk.cxx:1234
virtual sal_Bool SAL_CALL supportsService(const OUString &ServiceName) override
Definition: unorefmk.cxx:1228
virtual void SAL_CALL addEventListener(const css::uno::Reference< css::lang::XEventListener > &xListener) override
Definition: unorefmk.cxx:1245
virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() override
Definition: unorefmk.cxx:1279
virtual OUString SAL_CALL getImplementationName() override
Definition: unorefmk.cxx:1222
virtual void SAL_CALL attach(const css::uno::Reference< css::text::XTextRange > &xTextRange) override
Definition: unorefmk.cxx:1266
virtual void SAL_CALL removeEventListener(const css::uno::Reference< css::lang::XEventListener > &xListener) override
Definition: unorefmk.cxx:1252
virtual css::uno::Any SAL_CALL getPropertyValue(const OUString &rPropertyName) override
Definition: unorefmk.cxx:1323
the Meta has a cached list of text portions for its contents this list is created by SwXTextPortionEn...
Definition: unorefmk.cxx:593
::comphelper::OInterfaceContainerHelper4< css::lang::XEventListener > m_EventListeners
Definition: unorefmk.cxx:597
rtl::Reference< SwXMetaText > m_xText
Definition: unorefmk.cxx:603
uno::Reference< text::XText > m_xParentText
Definition: unorefmk.cxx:602
const ::sw::Meta * GetMeta() const
Definition: unorefmk.cxx:628
bool m_bIsDescriptor
Definition: unorefmk.cxx:601
const ::sw::MetaField * GetMetaField() const
Definition: unorefmk.cxx:1198
unotools::WeakReference< SwXMeta > m_wThis
Definition: unorefmk.cxx:595
sw::Meta * m_pMeta
Definition: unorefmk.cxx:604
std::mutex m_Mutex
Definition: unorefmk.cxx:596
std::unique_ptr< const TextRangeList_t > m_pTextPortions
Definition: unorefmk.cxx:598
bool m_bIsDisposed
Definition: unorefmk.cxx:600
virtual void Notify(const SfxHint &rHint) override
Definition: unorefmk.cxx:634
Impl(SwXMeta &rThis, SwDoc &rDoc, ::sw::Meta *const pMeta, uno::Reference< text::XText > xParentText, std::unique_ptr< TextRangeList_t const > pPortions)
Definition: unorefmk.cxx:606
virtual css::uno::Reference< css::text::XTextRange > SAL_CALL getStart() override
Definition: unorefmk.cxx:1023
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:1085
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:823
SwXMeta(SwXMeta const &)=delete
bool CheckForOwnMemberMeta(const SwPaM &rPam, const bool bAbsorb)
Definition: unorefmk.cxx:760
virtual ~SwXMeta() override
Definition: unorefmk.cxx:670
virtual void SAL_CALL insertString(const css::uno::Reference< css::text::XTextRange > &xRange, const OUString &aString, sal_Bool bAbsorb) override
Definition: unorefmk.cxx:1067
virtual css::uno::Reference< css::text::XTextRange > SAL_CALL getAnchor() override
Definition: unorefmk.cxx:983
virtual void SAL_CALL insertControlCharacter(const css::uno::Reference< css::text::XTextRange > &xRange, sal_Int16 nControlCharacter, sal_Bool bAbsorb) override
Definition: unorefmk.cxx:1075
virtual void SAL_CALL addEventListener(const css::uno::Reference< css::lang::XEventListener > &xListener) override
Definition: unorefmk.cxx:845
void AttachImpl(const css::uno::Reference< css::text::XTextRange > &xTextRange, const sal_uInt16 nWhich)
Definition: unorefmk.cxx:897
::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:1059
virtual css::uno::Reference< css::text::XText > SAL_CALL getText() override
Definition: unorefmk.cxx:1017
virtual css::uno::Reference< css::frame::XModel > GetModel() override
Definition: unorefmk.cxx:1183
virtual css::uno::Reference< css::uno::XInterface > SAL_CALL getParent() override
Definition: unorefmk.cxx:1102
css::uno::Reference< css::text::XText > const & GetParentText() const
Definition: unorefmk.cxx:653
virtual void SAL_CALL removeTextContent(const css::uno::Reference< css::text::XTextContent > &xContent) override
Definition: unorefmk.cxx:1093
virtual ::sfx2::Metadatable * GetCoreObject() override
Definition: unorefmk.cxx:1178
virtual void SAL_CALL setParent(css::uno::Reference< css::uno::XInterface > const &xParent) override
Definition: unorefmk.cxx:1121
virtual void SAL_CALL dispose() override
Definition: unorefmk.cxx:863
virtual OUString SAL_CALL getString() override
Definition: unorefmk.cxx:1037
virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() override
Definition: unorefmk.cxx:1141
virtual sal_Bool SAL_CALL hasElements() override
Definition: unorefmk.cxx:1133
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
Definition: unorefmk.cxx:835
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:738
virtual css::uno::Reference< css::text::XTextRange > SAL_CALL getEnd() override
Definition: unorefmk.cxx:1030
virtual sal_Bool SAL_CALL supportsService(const OUString &rServiceName) override
Definition: unorefmk.cxx:829
virtual css::uno::Type SAL_CALL getElementType() override
Definition: unorefmk.cxx:1128
virtual void SAL_CALL removeEventListener(const css::uno::Reference< css::lang::XEventListener > &xListener) override
Definition: unorefmk.cxx:854
virtual css::uno::Reference< css::text::XTextCursor > SAL_CALL createTextCursor() override
Definition: unorefmk.cxx:1052
virtual void SAL_CALL attach(const css::uno::Reference< css::text::XTextRange > &xTextRange) override
Definition: unorefmk.cxx:977
virtual void SAL_CALL setString(const OUString &rString) override
Definition: unorefmk.cxx:1044
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:916
const SwDoc & GetDoc() const
Definition: unoobj2.cxx:764
static rtl::Reference< SwXTextRange > CreateXTextRange(SwDoc &rDoc, const SwPosition &rPos, const SwPosition *const pMark)
Definition: unoobj2.cxx:1199
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
sal_uInt32 GetNumberFormat(std::u16string_view aContent) const
Definition: fmtatr2.cxx:770
void SetIsFixedLanguage(bool b)
Definition: fmtmeta.hxx:181
bool IsFixedLanguage() const
Definition: fmtmeta.hxx:180
void SetNumberFormat(sal_uInt32 nNumberFormat)
Definition: fmtatr2.cxx:783
SwTextNode * GetTextNode() const
Definition: fmtmeta.hxx:142
SwFormatMeta * GetFormatMeta() const
Definition: fmtmeta.hxx:144
SwTextMeta * GetTextAttr() const
Definition: fmtatr2.cxx:663
unotools::WeakReference< SwXMeta > const & GetXMeta() const
Definition: fmtmeta.hxx:149
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:1218
bool XTextRangeToSwPaM(SwUnoInternalPaM &rToFill, const uno::Reference< text::XTextRange > &xTextRange, ::sw::TextRangeMode const eMode)
Definition: unoobj2.cxx:1090
bool GetDefaultTextContentValue(css::uno::Any &rAny, std::u16string_view rPropertyName, sal_uInt16 nWID=0)
Marks a position in the document model.
Definition: pam.hxx:37
SwNode & GetNode() const
Definition: pam.hxx:80
sal_Int32 GetContentIndex() const
Definition: pam.hxx:84
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:87
#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:1408
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:1433
static uno::Reference< rdf::XURI > const & lcl_getURI(const sal_Int16 eKnown)
Definition: unorefmk.cxx:1383