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