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