LibreOffice Module sw (master)  1
unobkm.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 <unobookmark.hxx>
21 
23 #include <comphelper/sequence.hxx>
26 #include <svl/itemprop.hxx>
27 #include <svl/listener.hxx>
28 #include <vcl/svapp.hxx>
29 #include <xmloff/odffields.hxx>
30 
31 #include <TextCursorHelper.hxx>
32 #include <unotextrange.hxx>
33 #include <unomap.hxx>
34 #include <unoprnms.hxx>
35 #include <IMark.hxx>
36 #include <crossrefbookmark.hxx>
37 #include <doc.hxx>
38 #include <docsh.hxx>
39 
40 using namespace ::sw::mark;
41 using namespace ::com::sun::star;
42 
44  : public SvtListener
45 {
46 public:
47  uno::WeakReference<uno::XInterface> m_wThis;
48  std::mutex m_Mutex; // just for OInterfaceContainerHelper3
52  OUString m_sMarkName;
53  bool m_bHidden;
54  OUString m_HideCondition;
55 
56  Impl( SwDoc *const pDoc )
57  : m_pDoc(pDoc)
58  , m_pRegisteredBookmark(nullptr)
59  , m_bHidden(false)
60  {
61  // DO NOT registerInMark here! (because SetXBookmark would delete rThis)
62  }
63 
64  void registerInMark(SwXBookmark & rThis, ::sw::mark::IMark *const pBkmk);
65 protected:
66  virtual void Notify(const SfxHint&) override;
67 
68 };
69 
71 {
72  if(rHint.GetId() == SfxHintId::Dying)
73  {
74  m_pRegisteredBookmark = nullptr;
75  m_pDoc = nullptr;
76  uno::Reference<uno::XInterface> const xThis(m_wThis);
77  if (!xThis.is())
78  { // fdo#72695: if UNO object is already dead, don't revive it with event
79  return;
80  }
81  lang::EventObject const ev(xThis);
82  std::unique_lock aGuard(m_Mutex);
84  }
85 }
86 
88  ::sw::mark::IMark* const pBkmk)
89 {
90  const uno::Reference<text::XTextContent> xBookmark(&rThis);
91  if (pBkmk)
92  {
93  EndListeningAll();
94  StartListening(pBkmk->GetNotifier());
95  ::sw::mark::MarkBase *const pMarkBase(dynamic_cast< ::sw::mark::MarkBase * >(pBkmk));
96  OSL_ENSURE(pMarkBase, "registerInMark: no MarkBase?");
97  if (pMarkBase)
98  {
99  pMarkBase->SetXBookmark(xBookmark);
100  }
101  assert(m_pDoc == nullptr || m_pDoc == &pBkmk->GetMarkPos().GetDoc());
102  m_pDoc = &pBkmk->GetMarkPos().GetDoc();
103  }
104  else if (m_pRegisteredBookmark)
105  {
106  m_sMarkName = m_pRegisteredBookmark->GetName();
107 
108  // the following applies only to bookmarks (not to fieldmarks)
109  IBookmark* pBookmark = dynamic_cast<IBookmark*>(m_pRegisteredBookmark);
110  if (pBookmark)
111  {
112  m_bHidden = pBookmark->IsHidden();
113  m_HideCondition = pBookmark->GetHideCondition();
114  }
115  EndListeningAll();
116  }
117  m_pRegisteredBookmark = pBkmk;
118  // need a permanent Reference to initialize m_wThis
119  m_wThis = xBookmark;
120 }
121 
123  ::sw::mark::IMark *const pBkmk)
124 {
125  m_pImpl->registerInMark( rThis, pBkmk );
126 }
127 
129 {
130  return m_pImpl->m_pRegisteredBookmark;
131 }
132 
134 {
135  return m_pImpl->m_pDoc->getIDocumentMarkAccess();
136 }
137 
139 {
140  return m_pImpl->m_pDoc;
141 }
142 
144  : m_pImpl( new SwXBookmark::Impl(pDoc) )
145 {
146 }
147 
149  : m_pImpl( new SwXBookmark::Impl(nullptr) )
150 {
151 }
152 
154 {
155 }
156 
157 uno::Reference<text::XTextContent> SwXBookmark::CreateXBookmark(
158  SwDoc & rDoc,
159  ::sw::mark::IMark *const pBookmark)
160 {
161  // #i105557#: do not iterate over the registered clients: race condition
162  ::sw::mark::MarkBase *const pMarkBase(dynamic_cast< ::sw::mark::MarkBase * >(pBookmark));
163  OSL_ENSURE(!pBookmark || pMarkBase, "CreateXBookmark: no MarkBase?");
164  uno::Reference<text::XTextContent> xBookmark;
165  if (pMarkBase)
166  {
167  xBookmark = pMarkBase->GetXBookmark();
168  }
169  if (!xBookmark.is())
170  {
171  OSL_ENSURE(!pBookmark ||
172  dynamic_cast< ::sw::mark::IBookmark* >(pBookmark) ||
174  "<SwXBookmark::GetObject(..)>"
175  "SwXBookmark requested for non-bookmark mark and non-annotation mark.");
176  SwXBookmark *const pXBookmark =
177  pBookmark ? new SwXBookmark(&rDoc) : new SwXBookmark;
178  xBookmark.set(pXBookmark);
179  pXBookmark->m_pImpl->registerInMark(*pXBookmark, pMarkBase);
180  }
181  return xBookmark;
182 }
183 
185  const uno::Reference< lang::XUnoTunnel> & xUT)
186 {
187  SwXBookmark *const pXBkm(
188  comphelper::getFromUnoTunnel<SwXBookmark>(xUT));
189  if (pXBkm && (pDoc == pXBkm->m_pImpl->m_pDoc))
190  {
191  return pXBkm->m_pImpl->m_pRegisteredBookmark;
192  }
193  return nullptr;
194 }
195 
196 const uno::Sequence< sal_Int8 > & SwXBookmark::getUnoTunnelId()
197 {
198  static const comphelper::UnoIdInit theSwXBookmarkUnoTunnelId;
199  return theSwXBookmarkUnoTunnelId.getSeq();
200 }
201 
202 sal_Int64 SAL_CALL SwXBookmark::getSomething( const uno::Sequence< sal_Int8 >& rId )
203 {
204  return comphelper::getSomethingImpl<SwXBookmark>(rId, this);
205 }
206 
208  const uno::Reference< text::XTextRange > & xTextRange,
210 {
211  if (m_pImpl->m_pRegisteredBookmark)
212  {
213  throw uno::RuntimeException();
214  }
215 
216  const uno::Reference<lang::XUnoTunnel> xRangeTunnel(
217  xTextRange, uno::UNO_QUERY);
218  SwXTextRange* pRange = comphelper::getFromUnoTunnel<SwXTextRange>(xRangeTunnel);
219  OTextCursorHelper* pCursor =
220  comphelper::getFromUnoTunnel<OTextCursorHelper>(xRangeTunnel);
221 
222  SwDoc *const pDoc =
223  pRange ? &pRange->GetDoc() : (pCursor ? pCursor->GetDoc() : nullptr);
224  if (!pDoc)
225  {
226  throw lang::IllegalArgumentException();
227  }
228 
229  m_pImpl->m_pDoc = pDoc;
230  SwUnoInternalPaM aPam(*m_pImpl->m_pDoc);
231  ::sw::XTextRangeToSwPaM(aPam, xTextRange);
232  UnoActionContext aCont(m_pImpl->m_pDoc);
233  if (m_pImpl->m_sMarkName.isEmpty())
234  {
235  m_pImpl->m_sMarkName = "Bookmark";
236  }
239  {
241  }
242  else if ((eType == IDocumentMarkAccess::MarkType::BOOKMARK) &&
245  {
247  }
248  m_pImpl->registerInMark(*this,
249  m_pImpl->m_pDoc->getIDocumentMarkAccess()->makeMark(
250  aPam, m_pImpl->m_sMarkName, eType, ::sw::mark::InsertMode::New));
251  // #i81002#
252  // Check, if bookmark has been created.
253  // E.g., the creation of a cross-reference bookmark is suppress,
254  // if the PaM isn't a valid one for cross-reference bookmarks.
255  if (!m_pImpl->m_pRegisteredBookmark)
256  {
257  OSL_FAIL("<SwXBookmark::attachToRange(..)>"
258  " - could not create Mark.");
259  throw lang::IllegalArgumentException();
260  }
261 }
262 
263 void SwXBookmark::attachToRange( const uno::Reference< text::XTextRange > & xTextRange )
264 {
266 }
267 
268 void SAL_CALL SwXBookmark::attach( const uno::Reference< text::XTextRange > & xTextRange )
269 {
270  SolarMutexGuard aGuard;
271  attachToRange( xTextRange );
272 }
273 
274 uno::Reference< text::XTextRange > SAL_CALL SwXBookmark::getAnchor()
275 {
276  SolarMutexGuard aGuard;
277 
278  if (!m_pImpl->m_pRegisteredBookmark)
279  {
280  throw uno::RuntimeException();
281  }
283  *m_pImpl->m_pDoc,
284  m_pImpl->m_pRegisteredBookmark->GetMarkPos(),
285  (m_pImpl->m_pRegisteredBookmark->IsExpanded())
286  ? &m_pImpl->m_pRegisteredBookmark->GetOtherMarkPos() : nullptr);
287 }
288 
289 void SAL_CALL SwXBookmark::dispose()
290 {
291  SolarMutexGuard aGuard;
292  if (m_pImpl->m_pRegisteredBookmark)
293  {
294  m_pImpl->m_pDoc->getIDocumentMarkAccess()->deleteMark( m_pImpl->m_pRegisteredBookmark );
295  }
296 }
297 
299  const uno::Reference< lang::XEventListener > & xListener)
300 {
301  // no need to lock here as m_pImpl is const and container threadsafe
302  std::unique_lock aGuard(m_pImpl->m_Mutex);
303  m_pImpl->m_EventListeners.addInterface(aGuard, xListener);
304 }
305 
307  const uno::Reference< lang::XEventListener > & xListener)
308 {
309  // no need to lock here as m_pImpl is const and container threadsafe
310  std::unique_lock aGuard(m_pImpl->m_Mutex);
311  m_pImpl->m_EventListeners.removeInterface(aGuard, xListener);
312 }
313 
314 OUString SAL_CALL SwXBookmark::getName()
315 {
316  SolarMutexGuard aGuard;
317 
318  return (m_pImpl->m_pRegisteredBookmark)
319  ? m_pImpl->m_pRegisteredBookmark->GetName()
320  : m_pImpl->m_sMarkName;
321 }
322 
323 void SAL_CALL SwXBookmark::setName(const OUString& rName)
324 {
325  SolarMutexGuard aGuard;
326 
327  if (!m_pImpl->m_pRegisteredBookmark)
328  {
329  m_pImpl->m_sMarkName = rName;
330  }
331  if (!m_pImpl->m_pRegisteredBookmark || (getName() == rName))
332  {
333  return;
334  }
335  IDocumentMarkAccess *const pMarkAccess =
336  m_pImpl->m_pDoc->getIDocumentMarkAccess();
337  if(pMarkAccess->findMark(rName) != pMarkAccess->getAllMarksEnd())
338  {
339  throw uno::RuntimeException("setName(): name already in use",
340  static_cast<::cppu::OWeakObject*>(this));
341  }
342 
343  SwPaM aPam(m_pImpl->m_pRegisteredBookmark->GetMarkPos());
344  if (m_pImpl->m_pRegisteredBookmark->IsExpanded())
345  {
346  aPam.SetMark();
347  *aPam.GetMark() = m_pImpl->m_pRegisteredBookmark->GetOtherMarkPos();
348  }
349 
350  pMarkAccess->renameMark(m_pImpl->m_pRegisteredBookmark, rName);
351 }
352 
353 OUString SAL_CALL
355 {
356  return "SwXBookmark";
357 }
358 
359 sal_Bool SAL_CALL SwXBookmark::supportsService(const OUString& rServiceName)
360 {
361  return cppu::supportsService(this, rServiceName);
362 }
363 
364 uno::Sequence< OUString > SAL_CALL
366 {
367  return {
368  "com.sun.star.text.TextContent",
369  "com.sun.star.text.Bookmark",
370  "com.sun.star.document.LinkTarget"
371  };
372 }
373 
374 // MetadatableMixin
376 {
377  return dynamic_cast< ::sfx2::Metadatable* >(m_pImpl->m_pRegisteredBookmark);
378 }
379 
380 uno::Reference<frame::XModel> SwXBookmark::GetModel()
381 {
382  if (m_pImpl->m_pDoc)
383  {
384  SwDocShell const * const pShell( m_pImpl->m_pDoc->GetDocShell() );
385  return pShell ? pShell->GetModel() : nullptr;
386  }
387  return nullptr;
388 }
389 
390 uno::Reference< beans::XPropertySetInfo > SAL_CALL
392 {
393  SolarMutexGuard g;
394 
395  static uno::Reference< beans::XPropertySetInfo > xRef(
397  ->getPropertySetInfo() );
398  return xRef;
399 }
400 
401 void SAL_CALL
402 SwXBookmark::setPropertyValue(const OUString& PropertyName,
403  const uno::Any& rValue)
404 {
405  if (PropertyName == UNO_NAME_BOOKMARK_HIDDEN)
406  {
407  bool bNewValue = false;
408  if (!(rValue >>= bNewValue))
409  throw lang::IllegalArgumentException("Property BookmarkHidden requires value of type boolean", nullptr, 0);
410 
411  IBookmark* pBookmark = dynamic_cast<IBookmark*>(m_pImpl->m_pRegisteredBookmark);
412  if (pBookmark)
413  {
414  pBookmark->Hide(bNewValue);
415  }
416  else
417  {
418  m_pImpl->m_bHidden = bNewValue;
419  }
420  return;
421  }
422  else if (PropertyName == UNO_NAME_BOOKMARK_CONDITION)
423  {
424  OUString newValue;
425  if (!(rValue >>= newValue))
426  throw lang::IllegalArgumentException("Property BookmarkCondition requires value of type string", nullptr, 0);
427 
428  IBookmark* pBookmark = dynamic_cast<IBookmark*>(m_pImpl->m_pRegisteredBookmark);
429  if (pBookmark)
430  {
431  pBookmark->SetHideCondition(newValue);
432  }
433  else
434  {
435  m_pImpl->m_HideCondition = newValue;
436  }
437  return;
438  }
439 
440  // nothing to set here
441  throw lang::IllegalArgumentException("Property is read-only: "
442  + PropertyName, static_cast< cppu::OWeakObject * >(this), 0 );
443 }
444 
445 uno::Any SAL_CALL SwXBookmark::getPropertyValue(const OUString& rPropertyName)
446 {
447  SolarMutexGuard g;
448 
449  uno::Any aRet;
450  if (! ::sw::GetDefaultTextContentValue(aRet, rPropertyName))
451  {
452  if(rPropertyName == UNO_LINK_DISPLAY_NAME)
453  {
454  aRet <<= getName();
455  }
456  else if (rPropertyName == UNO_NAME_BOOKMARK_HIDDEN)
457  {
458  IBookmark* pBookmark = dynamic_cast<IBookmark*>(m_pImpl->m_pRegisteredBookmark);
459  if (pBookmark)
460  {
461  aRet <<= pBookmark->IsHidden();
462  }
463  else
464  {
465  aRet <<= m_pImpl->m_bHidden;
466  }
467  }
468  else if (rPropertyName == UNO_NAME_BOOKMARK_CONDITION)
469  {
470  IBookmark* pBookmark = dynamic_cast<IBookmark*>(m_pImpl->m_pRegisteredBookmark);
471  if (pBookmark)
472  {
473  aRet <<= pBookmark->GetHideCondition();
474  }
475  else
476  {
477  aRet <<= m_pImpl->m_HideCondition;
478  }
479  }
480  }
481  return aRet;
482 }
483 
484 void SAL_CALL
486  const OUString& /*rPropertyName*/,
487  const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
488 {
489  OSL_FAIL("SwXBookmark::addPropertyChangeListener(): not implemented");
490 }
491 
492 void SAL_CALL
494  const OUString& /*rPropertyName*/,
495  const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
496 {
497  OSL_FAIL("SwXBookmark::removePropertyChangeListener(): not implemented");
498 }
499 
500 void SAL_CALL
502  const OUString& /*rPropertyName*/,
503  const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
504 {
505  OSL_FAIL("SwXBookmark::addVetoableChangeListener(): not implemented");
506 }
507 
508 void SAL_CALL
510  const OUString& /*rPropertyName*/,
511  const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
512 {
513  OSL_FAIL("SwXBookmark::removeVetoableChangeListener(): not implemented");
514 }
515 
516 
517 void SwXFieldmarkParameters::insertByName(const OUString& aName, const uno::Any& aElement)
518 {
519  SolarMutexGuard aGuard;
520  IFieldmark::parameter_map_t* pParameters = getCoreParameters();
521  if(pParameters->find(aName) != pParameters->end())
522  throw container::ElementExistException();
523  (*pParameters)[aName] = aElement;
524 }
525 
526 void SwXFieldmarkParameters::removeByName(const OUString& aName)
527 {
528  SolarMutexGuard aGuard;
529  if(!getCoreParameters()->erase(aName))
530  throw container::NoSuchElementException();
531 }
532 
533 void SwXFieldmarkParameters::replaceByName(const OUString& aName, const uno::Any& aElement)
534 {
535  SolarMutexGuard aGuard;
536  IFieldmark::parameter_map_t* pParameters = getCoreParameters();
537  IFieldmark::parameter_map_t::iterator pEntry = pParameters->find(aName);
538  if(pEntry == pParameters->end())
539  throw container::NoSuchElementException();
540  pEntry->second = aElement;
541 }
542 
544 {
545  SolarMutexGuard aGuard;
546  IFieldmark::parameter_map_t* pParameters = getCoreParameters();
547  IFieldmark::parameter_map_t::iterator pEntry = pParameters->find(aName);
548  if(pEntry == pParameters->end())
549  throw container::NoSuchElementException();
550  return pEntry->second;
551 }
552 
554 {
555  SolarMutexGuard aGuard;
556  IFieldmark::parameter_map_t* pParameters = getCoreParameters();
557  return comphelper::mapKeysToSequence(*pParameters);
558 }
559 
561 {
562  SolarMutexGuard aGuard;
563  IFieldmark::parameter_map_t* pParameters = getCoreParameters();
564  return (pParameters->find(aName) != pParameters->end());
565 }
566 
568 {
570 }
571 
573 {
574  SolarMutexGuard aGuard;
575  return !getCoreParameters()->empty();
576 }
577 
579 {
580  if(rHint.GetId() == SfxHintId::Dying)
581  m_pFieldmark = nullptr;
582 }
583 
584 IFieldmark::parameter_map_t* SwXFieldmarkParameters::getCoreParameters()
585 {
586  if(!m_pFieldmark)
587  throw uno::RuntimeException();
588  return m_pFieldmark->GetParameters();
589 }
590 
591 SwXFieldmark::SwXFieldmark(bool const isReplacementObject, SwDoc *const pDoc)
592  : SwXFieldmark_Base(pDoc)
593  , m_bReplacementObject(isReplacementObject)
594 {
595 }
596 
597 OUString SAL_CALL
599 {
600  return "SwXFieldmark";
601 }
602 
603 uno::Sequence<OUString> SAL_CALL
605 {
606  // is const, no lock needed
608  {
609  return {"com.sun.star.text.TextContent",
610  "com.sun.star.text.Bookmark",
611  "com.sun.star.text.FormFieldmark"};
612  }
613  else
614  {
615  return {"com.sun.star.text.TextContent",
616  "com.sun.star.text.Bookmark",
617  "com.sun.star.text.Fieldmark"};
618  }
619 }
620 
621 void SwXFieldmark::attachToRange( const uno::Reference < text::XTextRange >& xTextRange )
622 {
623 
624  attachToRangeEx( xTextRange,
626 }
627 
629 {
630  SolarMutexGuard aGuard;
631  const IFieldmark *pBkm = dynamic_cast<const IFieldmark*>(GetBookmark());
632  if(!pBkm)
633  throw uno::RuntimeException();
634  return pBkm->GetFieldname();
635 }
636 
637 void SwXFieldmark::setFieldType(const OUString & fieldType)
638 {
639  SolarMutexGuard aGuard;
640  IFieldmark *pBkm = dynamic_cast<IFieldmark*>(GetBookmark());
641  if(!pBkm)
642  throw uno::RuntimeException();
643 
644  OUString const oldFieldType(getFieldType());
645  if (fieldType == oldFieldType)
646  return;
647 
648  // note: this must not change between point-fieldmarks and range-fieldmarks
649  if(fieldType == ODF_FORMDROPDOWN || fieldType == ODF_FORMCHECKBOX || fieldType == ODF_FORMDATE)
650  {
651  ::sw::mark::IFieldmark* pNewFieldmark = GetIDocumentMarkAccess()->changeFormFieldmarkType(pBkm, fieldType);
652  if (pNewFieldmark)
653  {
654  registerInMark(*this, pNewFieldmark);
655  return;
656  }
657  }
658 
659  if ((!m_bReplacementObject && (fieldType == ODF_UNHANDLED
660  || fieldType == ODF_FORMDATE
661  || fieldType == ODF_FORMTEXT))
662  || (m_bReplacementObject && (fieldType == ODF_FORMCHECKBOX
663  || fieldType == ODF_FORMDROPDOWN)))
664  {
665  pBkm->SetFieldname(fieldType);
666  return;
667  }
668 
669  throw uno::RuntimeException("changing to that type isn't implemented");
670 }
671 
672 uno::Reference<container::XNameContainer> SwXFieldmark::getParameters()
673 {
674  SolarMutexGuard aGuard;
675  IFieldmark *pBkm = dynamic_cast<IFieldmark*>(GetBookmark());
676  if(!pBkm)
677  throw uno::RuntimeException();
678  return uno::Reference<container::XNameContainer>(new SwXFieldmarkParameters(pBkm));
679 }
680 
681 uno::Reference<text::XTextContent>
683  bool const isReplacementObject)
684 {
685  // #i105557#: do not iterate over the registered clients: race condition
686  ::sw::mark::MarkBase *const pMarkBase(
687  dynamic_cast< ::sw::mark::MarkBase * >(pMark));
688  assert(!pMark || pMarkBase);
689  uno::Reference<text::XTextContent> xMark;
690  if (pMarkBase)
691  {
692  xMark = pMarkBase->GetXBookmark();
693  }
694  if (!xMark.is())
695  {
696  // FIXME: These belong in XTextFieldsSupplier
698  if (dynamic_cast< ::sw::mark::TextFieldmark* >(pMark))
699  pXBkmk = new SwXFieldmark(false, &rDoc);
700  else if (dynamic_cast< ::sw::mark::CheckboxFieldmark* >(pMark))
701  pXBkmk = new SwXFieldmark(true, &rDoc);
702  else if (dynamic_cast< ::sw::mark::DropDownFieldmark* >(pMark))
703  pXBkmk = new SwXFieldmark(true, &rDoc);
704  else if (dynamic_cast< ::sw::mark::DateFieldmark* >(pMark))
705  pXBkmk = new SwXFieldmark(false, &rDoc);
706  else
707  pXBkmk = new SwXFieldmark(isReplacementObject, &rDoc);
708 
709  xMark.set(static_cast<::cppu::OWeakObject*>(pXBkmk.get()), uno::UNO_QUERY); // work around ambiguous base
710  pXBkmk->registerInMark(*pXBkmk, pMarkBase);
711  }
712  return xMark;
713 }
714 
717 {
718  ::sw::mark::ICheckboxFieldmark* pCheckboxFm = nullptr;
719  if ( getFieldType() == ODF_FORMCHECKBOX )
720  {
721  pCheckboxFm = dynamic_cast< ::sw::mark::ICheckboxFieldmark* >( GetBookmark());
722  assert( GetBookmark() == nullptr || pCheckboxFm != nullptr );
723  // unclear to me whether GetBookmark() can be null here
724  }
725  return pCheckboxFm;
726 
727 }
728 
729 // support 'hidden' "Checked" property ( note: this property is just for convenience to support
730 // docx import filter thus not published via PropertySet info )
731 
732 void SAL_CALL
733 SwXFieldmark::setPropertyValue(const OUString& PropertyName,
734  const uno::Any& rValue)
735 {
736  SolarMutexGuard g;
737  if ( PropertyName == "Checked" )
738  {
740  bool bChecked( false );
741  if ( !(pCheckboxFm && ( rValue >>= bChecked )) )
742  throw uno::RuntimeException();
743 
744  pCheckboxFm->SetChecked( bChecked );
745  }
746  // this doesn't support any SwXBookmark property
747 }
748 
749 // support 'hidden' "Checked" property ( note: this property is just for convenience to support
750 // docx import filter thus not published via PropertySet info )
751 
752 uno::Any SAL_CALL SwXFieldmark::getPropertyValue(const OUString& rPropertyName)
753 {
754  SolarMutexGuard g;
755  if ( rPropertyName == "Checked" )
756  {
758  if ( !pCheckboxFm )
759  throw uno::RuntimeException();
760 
761  return uno::Any( pCheckboxFm->IsChecked() );
762  }
763  return uno::Any(); // this doesn't support any SwXBookmark property
764 }
765 
766 uno::Reference<beans::XPropertySetInfo> SAL_CALL
768 {
769  SolarMutexGuard g;
770 
771  static uno::Reference<beans::XPropertySetInfo> const xRef(
773  ->getPropertySetInfo() );
774  return xRef;
775 }
776 
777 // XComponent
778 void SAL_CALL SwXFieldmark::dispose()
779 {
780  return SwXBookmark::dispose();
781 }
783  uno::Reference<lang::XEventListener> const& xListener)
784 {
785  return SwXBookmark::addEventListener(xListener);
786 }
788  uno::Reference<lang::XEventListener> const& xListener)
789 {
790  return SwXBookmark::removeEventListener(xListener);
791 }
792 
793 // XTextContent
794 void SAL_CALL SwXFieldmark::attach(
795  uno::Reference<text::XTextRange> const& xTextRange)
796 {
797  return SwXBookmark::attach(xTextRange);
798 }
799 
800 uno::Reference<text::XTextRange> SAL_CALL SwXFieldmark::getAnchor()
801 {
802  return SwXBookmark::getAnchor();
803 }
804 
805 uno::Reference<text::XTextRange>
806 SwXFieldmark::GetCommand(IFieldmark const& rMark)
807 {
808  SwPosition const sepPos(sw::mark::FindFieldSep(rMark));
809  SwPosition start(rMark.GetMarkStart());
810  ++start.nContent;
811  return SwXTextRange::CreateXTextRange(*GetDoc(), start, &sepPos);
812 }
813 
814 uno::Reference<text::XTextRange>
815 SwXFieldmark::GetResult(IFieldmark const& rMark)
816 {
817  SwPosition sepPos(sw::mark::FindFieldSep(rMark));
818  ++sepPos.nContent;
819  SwPosition const& rEnd(rMark.GetMarkEnd());
820  return SwXTextRange::CreateXTextRange(*GetDoc(), sepPos, &rEnd);
821 }
822 
823 // XTextField
824 OUString SAL_CALL
826 {
827  SolarMutexGuard g;
828 
829  IFieldmark const*const pMark(dynamic_cast<IFieldmark*>(GetBookmark()));
830  if (!pMark)
831  {
832  throw lang::DisposedException();
833  }
834 
835  if (bShowCommand)
836  {
838  {
839  return OUString();
840  }
841  else
842  { // also for ODF_FORMDATE, which shouldn't be a fieldmark...
843  uno::Reference<text::XTextRange> const xCommand(GetCommand(*pMark));
844  return xCommand->getString();
845  }
846  }
847  else
848  {
849  OUString const type(getFieldType());
850  if (type == ODF_FORMCHECKBOX || type == ODF_FORMDROPDOWN)
851  {
852  return sw::mark::ExpandFieldmark(const_cast<IFieldmark *>(pMark));
853  }
854  else
855  {
856  assert(!m_bReplacementObject);
857  uno::Reference<text::XTextRange> const xResult(GetResult(*pMark));
858  return xResult->getString();
859  }
860  }
861 }
862 
863 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void disposeAndClear(::std::unique_lock<::std::mutex > &rGuard, const css::lang::EventObject &rEvt)
css::uno::Reference< css::linguistic2::XProofreadingIterator > get(css::uno::Reference< css::uno::XComponentContext > const &context)
static bool IsLegalName(std::u16string_view rName)
virtual void SAL_CALL addEventListener(const css::uno::Reference< css::lang::XEventListener > &xListener) override
Definition: unobkm.cxx:782
Marks a position in the document model.
Definition: pam.hxx:36
static const css::uno::Sequence< sal_Int8 > & getUnoTunnelId()
Definition: unobkm.cxx:196
virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() override
Definition: unobkm.cxx:767
SwDoc * m_pDoc
Definition: unobkm.cxx:50
SwXFieldmark(bool isReplacementObject, SwDoc *pDoc)
Definition: unobkm.cxx:591
SwDoc * GetDoc()
Definition: unobkm.cxx:138
virtual css::uno::Type SAL_CALL getElementType() override
Definition: unobkm.cxx:567
static SW_DLLPUBLIC MarkType GetType(const ::sw::mark::IMark &rMark)
Returns the MarkType used to create the mark.
Definition: docbm.cxx:474
virtual css::uno::Any SAL_CALL getPropertyValue(const OUString &rPropertyName) override
Definition: unobkm.cxx:445
virtual void SAL_CALL removeEventListener(const css::uno::Reference< css::lang::XEventListener > &xListener) override
Definition: unobkm.cxx:787
IDocumentMarkAccess * GetIDocumentMarkAccess()
Definition: unobkm.cxx:133
Provides access to the marks of a document.
css::uno::Reference< css::frame::XModel3 > GetModel() const
const SfxItemPropertySet * GetPropertySet(sal_uInt16 PropertyId)
Definition: unomap1.cxx:1090
Definition: doc.hxx:187
#define PROPERTY_MAP_BOOKMARK
Definition: unomap.hxx:50
::sw::mark::IMark * m_pRegisteredBookmark
Definition: unobkm.cxx:51
virtual const SwPosition & GetMarkPos() const =0
constexpr OUStringLiteral ODF_FORMDATE
SwPosition FindFieldSep(IFieldmark const &rMark)
return position of the CH_TXT_ATR_FIELDSEP for rMark
virtual void SAL_CALL addVetoableChangeListener(const OUString &rPropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener > &xListener) override
Definition: unobkm.cxx:501
virtual css::uno::Reference< css::frame::XModel > GetModel() override
Definition: unobkm.cxx:380
OUString m_sMarkName
Definition: unobkm.cxx:52
OUString ExpandFieldmark(IFieldmark *pBM)
Definition: itrform2.cxx:902
virtual ::sfx2::Metadatable * GetCoreObject() override
Definition: unobkm.cxx:375
::sw::mark::IFieldmark::parameter_map_t * getCoreParameters()
Definition: unobkm.cxx:584
css::uno::Reference< css::beans::XPropertySetInfo > const & getPropertySetInfo() const
SfxHintId GetId() const
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
Definition: unobkm.cxx:604
virtual css::uno::Reference< css::text::XTextRange > SAL_CALL getAnchor() override
Definition: unobkm.cxx:274
virtual css::uno::Sequence< OUString > SAL_CALL getElementNames() override
Definition: unobkm.cxx:553
virtual void SAL_CALL dispose() override
Definition: unobkm.cxx:778
css::uno::Reference< css::text::XTextRange > GetCommand(::sw::mark::IFieldmark const &rMark)
Definition: unobkm.cxx:806
void registerInMark(SwXBookmark &rThis,::sw::mark::IMark *const pBkmk)
Definition: unobkm.cxx:87
const SwDoc & GetDoc() const
Definition: unoobj2.cxx:767
static SW_DLLPUBLIC bool IsLegalPaMForCrossRefHeadingBookmark(const SwPaM &rPaM)
Definition: docbm.cxx:513
virtual const_iterator_t findMark(const OUString &rMark) const =0
Finds a mark by name.
virtual void SAL_CALL removeByName(const OUString &Name) override
Definition: unobkm.cxx:526
SwIndex nContent
Definition: pam.hxx:39
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
static css::uno::Reference< css::text::XTextContent > CreateXFieldmark(SwDoc &rDoc,::sw::mark::IMark *pMark, bool isReplacementObject=false)
Definition: unobkm.cxx:682
virtual OUString SAL_CALL getPresentation(sal_Bool bShowCommand) override
Definition: unobkm.cxx:825
virtual void SAL_CALL removePropertyChangeListener(const OUString &rPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener > &xListener) override
Definition: unobkm.cxx:493
virtual parameter_map_t * GetParameters()=0
#define UNO_NAME_BOOKMARK_HIDDEN
Definition: unoprnms.hxx:346
virtual css::uno::Any SAL_CALL getPropertyValue(const OUString &rPropertyName) override
Definition: unobkm.cxx:752
virtual sal_Bool SAL_CALL hasByName(const OUString &aName) override
Definition: unobkm.cxx:560
SwXBookmark()
descriptor
Definition: unobkm.cxx:148
const css::uno::Sequence< sal_Int8 > & getSeq() const
virtual void SAL_CALL attach(const css::uno::Reference< css::text::XTextRange > &xTextRange) override
Definition: unobkm.cxx:268
PaM is Point and Mark: a selection of the document model.
Definition: pam.hxx:137
static css::uno::Reference< css::text::XTextContent > CreateXBookmark(SwDoc &rDoc,::sw::mark::IMark *pBookmark)
Definition: unobkm.cxx:157
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
Definition: unobkm.cxx:365
bool GetDefaultTextContentValue(css::uno::Any &rAny, std::u16string_view rPropertyName, sal_uInt16 nWID=0)
virtual bool IsChecked() const =0
virtual const_iterator_t getAllMarksEnd() const =0
returns a STL-like random access iterator to the end of the sequence of marks.
virtual OUString SAL_CALL getImplementationName() override
Definition: unobkm.cxx:598
virtual css::uno::Reference< css::text::XTextRange > SAL_CALL getAnchor() override
Definition: unobkm.cxx:800
virtual void SAL_CALL addPropertyChangeListener(const OUString &rPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener > &xListener) override
Definition: unobkm.cxx:485
constexpr OUStringLiteral ODF_FORMTEXT
unsigned char sal_Bool
virtual void SAL_CALL removeEventListener(const css::uno::Reference< css::lang::XEventListener > &xListener) override
Definition: unobkm.cxx:306
::comphelper::OInterfaceContainerHelper4< css::lang::XEventListener > m_EventListeners
Definition: unobkm.cxx:49
virtual void SAL_CALL addEventListener(const css::uno::Reference< css::lang::XEventListener > &xListener) override
Definition: unobkm.cxx:298
virtual void SAL_CALL setFieldType(const OUString &description) override
Definition: unobkm.cxx:637
virtual void SAL_CALL replaceByName(const OUString &aName, const css::uno::Any &aElement) override
Definition: unobkm.cxx:533
bool XTextRangeToSwPaM(SwUnoInternalPaM &rToFill, const uno::Reference< text::XTextRange > &xTextRange,::sw::TextRangeMode const eMode)
Definition: unoobj2.cxx:1107
::sw::mark::IMark * GetBookmark() const
Definition: unobkm.cxx:128
virtual void SAL_CALL setPropertyValue(const OUString &rPropertyName, const css::uno::Any &rValue) override
Definition: unobkm.cxx:733
uno::WeakReference< uno::XInterface > m_wThis
Definition: unobkm.cxx:47
css::uno::Reference< css::text::XTextRange > GetResult(::sw::mark::IFieldmark const &rMark)
Definition: unobkm.cxx:815
SvtBroadcaster & GetNotifier()
Definition: calbck.hxx:101
UNO API wrapper around an internal sw::mark::IMark.
Definition: unobookmark.hxx:50
virtual void SAL_CALL attach(const css::uno::Reference< css::text::XTextRange > &xTextRange) override
Definition: unobkm.cxx:794
virtual void Notify(const SfxHint &rHint) override
Definition: unobkm.cxx:578
virtual void SAL_CALL insertByName(const OUString &aName, const css::uno::Any &aElement) override
Definition: unobkm.cxx:517
Impl(SwDoc *const pDoc)
Definition: unobkm.cxx:56
virtual void SAL_CALL removeVetoableChangeListener(const OUString &rPropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener > &xListener) override
Definition: unobkm.cxx:509
virtual sal_Bool SAL_CALL hasElements() override
Definition: unobkm.cxx:572
void registerInMark(SwXBookmark &rXMark,::sw::mark::IMark *const pMarkBase)
Definition: unobkm.cxx:122
virtual OUString SAL_CALL getFieldType() override
Definition: unobkm.cxx:628
virtual void SAL_CALL setName(const OUString &rName) override
Definition: unobkm.cxx:323
virtual css::uno::Reference< css::container::XNameContainer > SAL_CALL getParameters() override
Definition: unobkm.cxx:672
static bool IsLegalName(std::u16string_view rName)
SwDoc & GetDoc() const
Returns the document this position is in.
Definition: pam.cxx:179
constexpr OUStringLiteral ODF_UNHANDLED
virtual ~SwXBookmark() override
Definition: unobkm.cxx:153
::sw::mark::ICheckboxFieldmark * getCheckboxFieldmark()
Definition: unobkm.cxx:716
SwUnoPropertyMapProvider aSwMapProvider
Definition: unomap1.cxx:87
::sw::mark::IMark const * GetBookmarkInDoc(SwDoc const *const pDoc, const css::uno::Reference< css::lang::XUnoTunnel > &xUT)
Definition: unobkm.cxx:184
#define UNO_LINK_DISPLAY_NAME
Definition: unoprnms.hxx:458
virtual OUString SAL_CALL getImplementationName() override
Definition: unobkm.cxx:354
#define UNO_NAME_BOOKMARK_CONDITION
Definition: unoprnms.hxx:347
virtual void attachToRange(const css::uno::Reference< css::text::XTextRange > &xTextRange) override
Definition: unobkm.cxx:621
void attachToRangeEx(const css::uno::Reference< css::text::XTextRange > &xTextRange, IDocumentMarkAccess::MarkType eType)
Definition: unobkm.cxx:207
virtual sal_Int64 SAL_CALL getSomething(const css::uno::Sequence< sal_Int8 > &rIdentifier) override
Definition: unobkm.cxx:202
virtual bool renameMark(::sw::mark::IMark *io_pMark, const OUString &rNewName)=0
Renames an existing Mark, if possible.
ResultType type
bool const m_bReplacementObject
constexpr OUStringLiteral ODF_FORMCHECKBOX
virtual OUString SAL_CALL getName() override
Definition: unobkm.cxx:314
virtual void attachToRange(const css::uno::Reference< css::text::XTextRange > &xTextRange)
Definition: unobkm.cxx:263
OUString m_HideCondition
Definition: unobkm.cxx:54
const css::uno::WeakReference< css::text::XTextContent > & GetXBookmark() const
virtual void SetMark()
Unless this is called, the getter method of Mark will return Point.
Definition: pam.cxx:476
static css::uno::Reference< css::text::XTextRange > CreateXTextRange(SwDoc &rDoc, const SwPosition &rPos, const SwPosition *const pMark)
Definition: unoobj2.cxx:1214
virtual void SAL_CALL dispose() override
Definition: unobkm.cxx:289
#define PROPERTY_MAP_FIELDMARK
Definition: unomap.hxx:127
virtual void SetChecked(bool checked)=0
::std::unique_ptr< XmlIdRegistry_Impl > m_pImpl
std::mutex m_Mutex
Definition: unobkm.cxx:48
virtual css::uno::Any SAL_CALL getByName(const OUString &aName) override
Definition: unobkm.cxx:543
::sw::UnoImplPtr< Impl > m_pImpl
Definition: unobookmark.hxx:56
constexpr OUStringLiteral ODF_FORMDROPDOWN
virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() override
Definition: unobkm.cxx:391
::sw::mark::IFieldmark * m_pFieldmark
cppu::ImplInheritanceHelper< SwXBookmark, css::text::XFormField, css::text::XTextField > SwXFieldmark_Base
virtual void Notify(const SfxHint &) override
Definition: unobkm.cxx:70
virtual void SAL_CALL setPropertyValue(const OUString &rPropertyName, const css::uno::Any &rValue) override
Definition: unobkm.cxx:402
css::uno::Sequence< typename M::key_type > mapKeysToSequence(M const &map)
virtual sal_Bool SAL_CALL supportsService(const OUString &rServiceName) override
Definition: unobkm.cxx:359
bool m_bDetectedRangeSegmentation false