Line data Source code
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 : #include <osl/mutex.hxx>
22 : #include <cppuhelper/interfacecontainer.h>
23 : #include <cppuhelper/supportsservice.hxx>
24 : #include <vcl/svapp.hxx>
25 :
26 : #include <TextCursorHelper.hxx>
27 : #include <unotextrange.hxx>
28 : #include <unomap.hxx>
29 : #include <unoprnms.hxx>
30 : #include <IMark.hxx>
31 : #include <crossrefbookmark.hxx>
32 : #include <doc.hxx>
33 : #include <IDocumentState.hxx>
34 : #include <docary.hxx>
35 : #include <swundo.hxx>
36 : #include <docsh.hxx>
37 : #include <xmloff/odffields.hxx>
38 : #include <comphelper/servicehelper.hxx>
39 :
40 : using namespace ::sw::mark;
41 : using namespace ::com::sun::star;
42 :
43 13178 : class SwXBookmark::Impl
44 : : public SwClient
45 : {
46 : private:
47 : ::osl::Mutex m_Mutex; // just for OInterfaceContainerHelper
48 :
49 : public:
50 : uno::WeakReference<uno::XInterface> m_wThis;
51 : ::cppu::OInterfaceContainerHelper m_EventListeners;
52 : SwDoc * m_pDoc;
53 : ::sw::mark::IMark * m_pRegisteredBookmark;
54 : OUString m_sMarkName;
55 :
56 6589 : Impl( SwDoc *const pDoc, ::sw::mark::IMark *const /*pBookmark*/)
57 : : SwClient()
58 : , m_EventListeners(m_Mutex)
59 : , m_pDoc(pDoc)
60 6589 : , m_pRegisteredBookmark(0)
61 : {
62 : // DO NOT registerInMark here! (because SetXBookmark would delete rThis)
63 6589 : }
64 :
65 : void registerInMark(SwXBookmark & rThis, ::sw::mark::IMark *const pBkmk);
66 : protected:
67 : // SwClient
68 : virtual void Modify( const SfxPoolItem *pOld, const SfxPoolItem *pNew) SAL_OVERRIDE;
69 :
70 : };
71 :
72 1986 : void SwXBookmark::Impl::Modify(const SfxPoolItem *pOld, const SfxPoolItem *pNew)
73 : {
74 1986 : ClientModify(this, pOld, pNew);
75 1986 : if (GetRegisteredIn())
76 : {
77 0 : return; // core object still alive
78 : }
79 :
80 1986 : m_pRegisteredBookmark = 0;
81 1986 : m_pDoc = 0;
82 1986 : uno::Reference<uno::XInterface> const xThis(m_wThis);
83 1986 : if (!xThis.is())
84 : { // fdo#72695: if UNO object is already dead, don't revive it with event
85 0 : return;
86 : }
87 3972 : lang::EventObject const ev(xThis);
88 3972 : m_EventListeners.disposeAndClear(ev);
89 : }
90 :
91 11498 : void SwXBookmark::Impl::registerInMark(SwXBookmark & rThis,
92 : ::sw::mark::IMark *const pBkmk)
93 : {
94 11498 : const uno::Reference<text::XTextContent> xBookmark(& rThis);
95 11498 : if (pBkmk)
96 : {
97 6159 : pBkmk->Add(this);
98 6159 : ::sw::mark::MarkBase *const pMarkBase(dynamic_cast< ::sw::mark::MarkBase * >(pBkmk));
99 : OSL_ENSURE(pMarkBase, "registerInMark: no MarkBase?");
100 6159 : if (pMarkBase)
101 : {
102 6159 : pMarkBase->SetXBookmark(xBookmark);
103 : }
104 : }
105 5339 : else if (m_pRegisteredBookmark)
106 : {
107 0 : m_sMarkName = m_pRegisteredBookmark->GetName();
108 0 : m_pRegisteredBookmark->Remove(this);
109 : }
110 11498 : m_pRegisteredBookmark = pBkmk;
111 : // need a permanent Reference to initialize m_wThis
112 11498 : m_wThis = xBookmark;
113 11498 : }
114 :
115 133 : void SwXBookmark::registerInMark(SwXBookmark & rThis,
116 : ::sw::mark::IMark *const pBkmk)
117 : {
118 133 : m_pImpl->registerInMark( rThis, pBkmk );
119 133 : }
120 :
121 223 : const ::sw::mark::IMark* SwXBookmark::GetBookmark() const
122 : {
123 223 : return m_pImpl->m_pRegisteredBookmark;
124 : }
125 :
126 1804 : SwXBookmark::SwXBookmark(
127 : ::sw::mark::IMark *const pBkmk,
128 : SwDoc *const pDoc)
129 1804 : : m_pImpl( new SwXBookmark::Impl(pDoc, pBkmk) )
130 : {
131 1804 : }
132 :
133 4785 : SwXBookmark::SwXBookmark()
134 4785 : : m_pImpl( new SwXBookmark::Impl(0, 0) )
135 : {
136 4785 : }
137 :
138 13045 : SwXBookmark::~SwXBookmark()
139 : {
140 13045 : }
141 :
142 11991 : uno::Reference<text::XTextContent> SwXBookmark::CreateXBookmark(
143 : SwDoc & rDoc,
144 : ::sw::mark::IMark *const pBookmark)
145 : {
146 : // #i105557#: do not iterate over the registered clients: race condition
147 11991 : ::sw::mark::MarkBase *const pMarkBase(dynamic_cast< ::sw::mark::MarkBase * >(pBookmark));
148 : OSL_ENSURE(!pBookmark || pMarkBase, "CreateXBookmark: no MarkBase?");
149 11991 : uno::Reference<text::XTextContent> xBookmark;
150 11991 : if (pMarkBase)
151 : {
152 7206 : xBookmark = pMarkBase->GetXBookmark();
153 : }
154 11991 : if (!xBookmark.is())
155 : {
156 : OSL_ENSURE(!pBookmark ||
157 : dynamic_cast< ::sw::mark::IBookmark* >(pBookmark) ||
158 : IDocumentMarkAccess::GetType(*pBookmark) == IDocumentMarkAccess::MarkType::ANNOTATIONMARK,
159 : "<SwXBookmark::GetObject(..)>"
160 : "SwXBookmark requested for non-bookmark mark and non-annotation mark.");
161 : SwXBookmark *const pXBookmark =
162 6456 : (pBookmark) ? new SwXBookmark(pBookmark, &rDoc) : new SwXBookmark;
163 6456 : xBookmark.set(pXBookmark);
164 6456 : pXBookmark->m_pImpl->registerInMark(*pXBookmark, pMarkBase);
165 : }
166 11991 : return xBookmark;
167 : }
168 :
169 0 : ::sw::mark::IMark const* SwXBookmark::GetBookmarkInDoc(SwDoc const*const pDoc,
170 : const uno::Reference< lang::XUnoTunnel> & xUT)
171 : {
172 : SwXBookmark *const pXBkm(
173 0 : ::sw::UnoTunnelGetImplementation<SwXBookmark>(xUT));
174 0 : if (pXBkm && (pDoc == pXBkm->m_pImpl->m_pDoc))
175 : {
176 0 : return pXBkm->m_pImpl->m_pRegisteredBookmark;
177 : }
178 0 : return 0;
179 : }
180 :
181 : namespace
182 : {
183 : class theSwXBookmarkUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSwXBookmarkUnoTunnelId > {};
184 : }
185 :
186 39581 : const uno::Sequence< sal_Int8 > & SwXBookmark::getUnoTunnelId()
187 : {
188 39581 : return theSwXBookmarkUnoTunnelId::get().getSeq();
189 : }
190 :
191 29088 : sal_Int64 SAL_CALL SwXBookmark::getSomething( const uno::Sequence< sal_Int8 >& rId )
192 : throw (uno::RuntimeException, std::exception)
193 : {
194 29088 : return ::sw::UnoTunnelImpl<SwXBookmark>(rId, this);
195 : }
196 :
197 4909 : void SwXBookmark::attachToRangeEx(
198 : const uno::Reference< text::XTextRange > & xTextRange,
199 : IDocumentMarkAccess::MarkType eType)
200 : throw (lang::IllegalArgumentException, uno::RuntimeException)
201 : {
202 4909 : if (m_pImpl->m_pRegisteredBookmark)
203 : {
204 0 : throw uno::RuntimeException();
205 : }
206 :
207 : const uno::Reference<lang::XUnoTunnel> xRangeTunnel(
208 4909 : xTextRange, uno::UNO_QUERY);
209 4909 : SwXTextRange* pRange = 0;
210 4909 : OTextCursorHelper* pCursor = 0;
211 4909 : if(xRangeTunnel.is())
212 : {
213 4909 : pRange = ::sw::UnoTunnelGetImplementation<SwXTextRange>(xRangeTunnel);
214 : pCursor =
215 4909 : ::sw::UnoTunnelGetImplementation<OTextCursorHelper>(xRangeTunnel);
216 : }
217 :
218 : SwDoc *const pDoc =
219 4909 : (pRange) ? pRange->GetDoc() : ((pCursor) ? pCursor->GetDoc() : 0);
220 4909 : if (!pDoc)
221 : {
222 0 : throw lang::IllegalArgumentException();
223 : }
224 :
225 4909 : m_pImpl->m_pDoc = pDoc;
226 9818 : SwUnoInternalPaM aPam(*m_pImpl->m_pDoc);
227 4909 : ::sw::XTextRangeToSwPaM(aPam, xTextRange);
228 9818 : UnoActionContext aCont(m_pImpl->m_pDoc);
229 4909 : if (m_pImpl->m_sMarkName.isEmpty())
230 : {
231 122 : m_pImpl->m_sMarkName = "Bookmark";
232 : }
233 9691 : if ((eType == IDocumentMarkAccess::MarkType::BOOKMARK) &&
234 4782 : ::sw::mark::CrossRefNumItemBookmark::IsLegalName(m_pImpl->m_sMarkName))
235 : {
236 9 : eType = IDocumentMarkAccess::MarkType::CROSSREF_NUMITEM_BOOKMARK;
237 : }
238 9673 : else if ((eType == IDocumentMarkAccess::MarkType::BOOKMARK) &&
239 5405 : ::sw::mark::CrossRefHeadingBookmark::IsLegalName(m_pImpl->m_sMarkName) &&
240 505 : IDocumentMarkAccess::IsLegalPaMForCrossRefHeadingBookmark( aPam ) )
241 : {
242 505 : eType = IDocumentMarkAccess::MarkType::CROSSREF_HEADING_BOOKMARK;
243 : }
244 : m_pImpl->registerInMark(*this,
245 4909 : m_pImpl->m_pDoc->getIDocumentMarkAccess()->makeMark(
246 4909 : aPam, m_pImpl->m_sMarkName, eType));
247 : // #i81002#
248 : // Check, if bookmark has been created.
249 : // E.g., the creation of a cross-reference bookmark is suppress,
250 : // if the PaM isn't a valid one for cross-reference bookmarks.
251 4909 : if (!m_pImpl->m_pRegisteredBookmark)
252 : {
253 : OSL_FAIL("<SwXBookmark::attachToRange(..)>"
254 : " - could not create Mark.");
255 427 : throw lang::IllegalArgumentException();
256 4909 : }
257 4482 : }
258 :
259 4782 : void SwXBookmark::attachToRange( const uno::Reference< text::XTextRange > & xTextRange )
260 : throw (lang::IllegalArgumentException, uno::RuntimeException)
261 : {
262 4782 : attachToRangeEx(xTextRange, IDocumentMarkAccess::MarkType::BOOKMARK);
263 4355 : }
264 :
265 4909 : void SAL_CALL SwXBookmark::attach( const uno::Reference< text::XTextRange > & xTextRange )
266 : throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception)
267 : {
268 4909 : SolarMutexGuard aGuard;
269 5336 : attachToRange( xTextRange );
270 4482 : }
271 :
272 4844 : uno::Reference< text::XTextRange > SAL_CALL SwXBookmark::getAnchor()
273 : throw (uno::RuntimeException, std::exception)
274 : {
275 4844 : SolarMutexGuard aGuard;
276 :
277 4844 : if (!m_pImpl->m_pRegisteredBookmark)
278 : {
279 0 : throw uno::RuntimeException();
280 : }
281 : return SwXTextRange::CreateXTextRange(
282 4844 : *m_pImpl->m_pDoc,
283 9688 : m_pImpl->m_pRegisteredBookmark->GetMarkPos(),
284 4844 : (m_pImpl->m_pRegisteredBookmark->IsExpanded())
285 14532 : ? &m_pImpl->m_pRegisteredBookmark->GetOtherMarkPos() : NULL);
286 : }
287 :
288 1 : void SAL_CALL SwXBookmark::dispose()
289 : throw (uno::RuntimeException, std::exception)
290 : {
291 1 : SolarMutexGuard aGuard;
292 1 : if (m_pImpl->m_pRegisteredBookmark)
293 : {
294 1 : m_pImpl->m_pDoc->getIDocumentMarkAccess()->deleteMark( m_pImpl->m_pRegisteredBookmark );
295 1 : }
296 1 : }
297 :
298 2 : void SAL_CALL SwXBookmark::addEventListener(
299 : const uno::Reference< lang::XEventListener > & xListener)
300 : throw (uno::RuntimeException, std::exception)
301 : {
302 : // no need to lock here as m_pImpl is const and container threadsafe
303 2 : m_pImpl->m_EventListeners.addInterface(xListener);
304 2 : }
305 :
306 1 : void SAL_CALL SwXBookmark::removeEventListener(
307 : const uno::Reference< lang::XEventListener > & xListener)
308 : throw (uno::RuntimeException, std::exception)
309 : {
310 : // no need to lock here as m_pImpl is const and container threadsafe
311 1 : m_pImpl->m_EventListeners.removeInterface(xListener);
312 1 : }
313 :
314 2057 : OUString SAL_CALL SwXBookmark::getName()
315 : throw (uno::RuntimeException, std::exception)
316 : {
317 2057 : SolarMutexGuard aGuard;
318 :
319 2057 : return (m_pImpl->m_pRegisteredBookmark)
320 2057 : ? m_pImpl->m_pRegisteredBookmark->GetName()
321 4114 : : m_pImpl->m_sMarkName;
322 : }
323 :
324 4792 : void SAL_CALL SwXBookmark::setName(const OUString& rName)
325 : throw (uno::RuntimeException, std::exception)
326 : {
327 4792 : SolarMutexGuard aGuard;
328 :
329 4792 : if (!m_pImpl->m_pRegisteredBookmark)
330 : {
331 4789 : m_pImpl->m_sMarkName = rName;
332 : }
333 4792 : if (!m_pImpl->m_pRegisteredBookmark || (getName() == rName))
334 : {
335 9581 : return;
336 : }
337 : IDocumentMarkAccess *const pMarkAccess =
338 3 : m_pImpl->m_pDoc->getIDocumentMarkAccess();
339 3 : if(pMarkAccess->findMark(rName) != pMarkAccess->getAllMarksEnd())
340 : {
341 0 : throw uno::RuntimeException();
342 : }
343 :
344 6 : SwPaM aPam(m_pImpl->m_pRegisteredBookmark->GetMarkPos());
345 3 : if (m_pImpl->m_pRegisteredBookmark->IsExpanded())
346 : {
347 1 : aPam.SetMark();
348 1 : *aPam.GetMark() = m_pImpl->m_pRegisteredBookmark->GetOtherMarkPos();
349 : }
350 :
351 6 : pMarkAccess->renameMark(m_pImpl->m_pRegisteredBookmark, rName);
352 : }
353 :
354 : OUString SAL_CALL
355 0 : SwXBookmark::getImplementationName() throw (uno::RuntimeException, std::exception)
356 : {
357 0 : return OUString("SwXBookmark");
358 : }
359 :
360 : static char const*const g_ServicesBookmark[] =
361 : {
362 : "com.sun.star.text.TextContent",
363 : "com.sun.star.text.Bookmark",
364 : "com.sun.star.document.LinkTarget",
365 : };
366 : static const size_t g_nServicesBookmark(
367 : sizeof(g_ServicesBookmark)/sizeof(g_ServicesBookmark[0]));
368 :
369 17 : sal_Bool SAL_CALL SwXBookmark::supportsService(const OUString& rServiceName)
370 : throw (uno::RuntimeException, std::exception)
371 : {
372 17 : return cppu::supportsService(this, rServiceName);
373 : }
374 :
375 : uno::Sequence< OUString > SAL_CALL
376 17 : SwXBookmark::getSupportedServiceNames() throw (uno::RuntimeException, std::exception)
377 : {
378 : return ::sw::GetSupportedServiceNamesImpl(
379 17 : g_nServicesBookmark, g_ServicesBookmark);
380 : }
381 :
382 : // MetadatableMixin
383 2110 : ::sfx2::Metadatable* SwXBookmark::GetCoreObject()
384 : {
385 2110 : return dynamic_cast< ::sfx2::Metadatable* >(m_pImpl->m_pRegisteredBookmark);
386 : }
387 :
388 0 : uno::Reference<frame::XModel> SwXBookmark::GetModel()
389 : {
390 0 : if (m_pImpl->m_pDoc)
391 : {
392 0 : SwDocShell const * const pShell( m_pImpl->m_pDoc->GetDocShell() );
393 0 : return (pShell) ? pShell->GetModel() : 0;
394 : }
395 0 : return 0;
396 : }
397 :
398 : uno::Reference< beans::XPropertySetInfo > SAL_CALL
399 6 : SwXBookmark::getPropertySetInfo() throw (uno::RuntimeException, std::exception)
400 : {
401 6 : SolarMutexGuard g;
402 :
403 : static uno::Reference< beans::XPropertySetInfo > xRef(
404 : aSwMapProvider.GetPropertySet(PROPERTY_MAP_BOOKMARK)
405 6 : ->getPropertySetInfo() );
406 6 : return xRef;
407 : }
408 :
409 : void SAL_CALL
410 3 : SwXBookmark::setPropertyValue(const OUString& PropertyName,
411 : const uno::Any& /*rValue*/)
412 : throw (beans::UnknownPropertyException, beans::PropertyVetoException,
413 : lang::IllegalArgumentException, lang::WrappedTargetException,
414 : uno::RuntimeException, std::exception)
415 : {
416 : // nothing to set here
417 : throw lang::IllegalArgumentException("Property is read-only: "
418 3 : + PropertyName, static_cast< cppu::OWeakObject * >(this), 0 );
419 : }
420 :
421 8 : uno::Any SAL_CALL SwXBookmark::getPropertyValue(const OUString& rPropertyName)
422 : throw (beans::UnknownPropertyException, lang::WrappedTargetException,
423 : uno::RuntimeException, std::exception)
424 : {
425 8 : SolarMutexGuard g;
426 :
427 8 : uno::Any aRet;
428 8 : if (! ::sw::GetDefaultTextContentValue(aRet, rPropertyName))
429 : {
430 2 : if(rPropertyName == UNO_LINK_DISPLAY_NAME)
431 : {
432 0 : aRet <<= getName();
433 : }
434 : }
435 8 : return aRet;
436 : }
437 :
438 : void SAL_CALL
439 0 : SwXBookmark::addPropertyChangeListener(
440 : const OUString& /*rPropertyName*/,
441 : const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
442 : throw (beans::UnknownPropertyException, lang::WrappedTargetException,
443 : uno::RuntimeException, std::exception)
444 : {
445 : OSL_FAIL("SwXBookmark::addPropertyChangeListener(): not implemented");
446 0 : }
447 :
448 : void SAL_CALL
449 0 : SwXBookmark::removePropertyChangeListener(
450 : const OUString& /*rPropertyName*/,
451 : const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
452 : throw (beans::UnknownPropertyException, lang::WrappedTargetException,
453 : uno::RuntimeException, std::exception)
454 : {
455 : OSL_FAIL("SwXBookmark::removePropertyChangeListener(): not implemented");
456 0 : }
457 :
458 : void SAL_CALL
459 0 : SwXBookmark::addVetoableChangeListener(
460 : const OUString& /*rPropertyName*/,
461 : const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
462 : throw (beans::UnknownPropertyException, lang::WrappedTargetException,
463 : uno::RuntimeException, std::exception)
464 : {
465 : OSL_FAIL("SwXBookmark::addVetoableChangeListener(): not implemented");
466 0 : }
467 :
468 : void SAL_CALL
469 0 : SwXBookmark::removeVetoableChangeListener(
470 : const OUString& /*rPropertyName*/,
471 : const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
472 : throw (beans::UnknownPropertyException, lang::WrappedTargetException,
473 : uno::RuntimeException, std::exception)
474 : {
475 : OSL_FAIL("SwXBookmark::removeVetoableChangeListener(): not implemented");
476 0 : }
477 :
478 133 : SwXFieldmark::SwXFieldmark(bool _isReplacementObject, ::sw::mark::IMark* pBkm, SwDoc* pDc)
479 : : SwXFieldmark_Base(pBkm, pDc)
480 133 : , isReplacementObject(_isReplacementObject)
481 133 : { }
482 :
483 0 : void SwXFieldmarkParameters::insertByName(const OUString& aName, const uno::Any& aElement)
484 : throw (lang::IllegalArgumentException, container::ElementExistException, lang::WrappedTargetException, uno::RuntimeException, std::exception)
485 : {
486 0 : SolarMutexGuard aGuard;
487 0 : IFieldmark::parameter_map_t* pParameters = getCoreParameters();
488 0 : if(pParameters->find(aName) != pParameters->end())
489 0 : throw container::ElementExistException();
490 0 : (*pParameters)[aName] = aElement;
491 0 : }
492 :
493 0 : void SwXFieldmarkParameters::removeByName(const OUString& aName)
494 : throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException, std::exception)
495 : {
496 0 : SolarMutexGuard aGuard;
497 0 : if(!getCoreParameters()->erase(aName))
498 0 : throw container::NoSuchElementException();
499 0 : }
500 :
501 0 : void SwXFieldmarkParameters::replaceByName(const OUString& aName, const uno::Any& aElement)
502 : throw (lang::IllegalArgumentException, container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException, std::exception)
503 : {
504 0 : SolarMutexGuard aGuard;
505 0 : IFieldmark::parameter_map_t* pParameters = getCoreParameters();
506 0 : IFieldmark::parameter_map_t::iterator pEntry = pParameters->find(aName);
507 0 : if(pEntry == pParameters->end())
508 0 : throw container::NoSuchElementException();
509 0 : pEntry->second = aElement;
510 0 : }
511 :
512 2 : uno::Any SwXFieldmarkParameters::getByName(const OUString& aName)
513 : throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException, std::exception)
514 : {
515 2 : SolarMutexGuard aGuard;
516 2 : IFieldmark::parameter_map_t* pParameters = getCoreParameters();
517 2 : IFieldmark::parameter_map_t::iterator pEntry = pParameters->find(aName);
518 2 : if(pEntry == pParameters->end())
519 0 : throw container::NoSuchElementException();
520 2 : return pEntry->second;
521 : }
522 :
523 1 : uno::Sequence<OUString> SwXFieldmarkParameters::getElementNames()
524 : throw (uno::RuntimeException, std::exception)
525 : {
526 1 : SolarMutexGuard aGuard;
527 1 : IFieldmark::parameter_map_t* pParameters = getCoreParameters();
528 1 : uno::Sequence<OUString> vResult(pParameters->size());
529 1 : OUString* pOutEntry = vResult.getArray();
530 2 : for(IFieldmark::parameter_map_t::iterator pEntry = pParameters->begin(); pEntry!=pParameters->end(); ++pEntry, ++pOutEntry)
531 1 : *pOutEntry = pEntry->first;
532 1 : return vResult;
533 : }
534 :
535 0 : sal_Bool SwXFieldmarkParameters::hasByName(const OUString& aName)
536 : throw (uno::RuntimeException, std::exception)
537 : {
538 0 : SolarMutexGuard aGuard;
539 0 : IFieldmark::parameter_map_t* pParameters = getCoreParameters();
540 0 : return (pParameters->find(aName) != pParameters->end());
541 : }
542 :
543 0 : uno::Type SwXFieldmarkParameters::getElementType()
544 : throw (uno::RuntimeException, std::exception)
545 : {
546 0 : return ::cppu::UnoType<void>::get();
547 : }
548 :
549 0 : sal_Bool SwXFieldmarkParameters::hasElements()
550 : throw (uno::RuntimeException, std::exception)
551 : {
552 0 : SolarMutexGuard aGuard;
553 0 : return !getCoreParameters()->empty();
554 : }
555 :
556 0 : void SwXFieldmarkParameters::Modify(const SfxPoolItem *pOld, const SfxPoolItem *pNew)
557 : {
558 0 : ClientModify(this, pOld, pNew);
559 0 : }
560 :
561 3 : IFieldmark::parameter_map_t* SwXFieldmarkParameters::getCoreParameters()
562 : throw (uno::RuntimeException)
563 : {
564 3 : const IFieldmark* pFieldmark = dynamic_cast< const IFieldmark* >(GetRegisteredIn());
565 3 : if(!pFieldmark)
566 0 : throw uno::RuntimeException();
567 3 : return const_cast< IFieldmark* >(pFieldmark)->GetParameters();
568 : }
569 :
570 127 : void SwXFieldmark::attachToRange( const uno::Reference < text::XTextRange >& xTextRange )
571 : throw(lang::IllegalArgumentException, uno::RuntimeException)
572 : {
573 :
574 : attachToRangeEx( xTextRange,
575 127 : ( isReplacementObject ? IDocumentMarkAccess::MarkType::CHECKBOX_FIELDMARK : IDocumentMarkAccess::MarkType::TEXT_FIELDMARK ) );
576 127 : }
577 :
578 30 : OUString SwXFieldmark::getFieldType()
579 : throw(uno::RuntimeException, std::exception)
580 : {
581 30 : SolarMutexGuard aGuard;
582 30 : const IFieldmark *pBkm = dynamic_cast<const IFieldmark*>(GetBookmark());
583 30 : if(!pBkm)
584 0 : throw uno::RuntimeException();
585 30 : return pBkm->GetFieldname();
586 : }
587 :
588 127 : void SwXFieldmark::setFieldType(const OUString & fieldType)
589 : throw(uno::RuntimeException, std::exception)
590 : {
591 127 : SolarMutexGuard aGuard;
592 : IFieldmark *pBkm = const_cast<IFieldmark*>(
593 127 : dynamic_cast<const IFieldmark*>(GetBookmark()));
594 127 : if(!pBkm)
595 0 : throw uno::RuntimeException();
596 127 : pBkm->SetFieldname(fieldType);
597 127 : }
598 :
599 36 : uno::Reference<container::XNameContainer> SwXFieldmark::getParameters()
600 : throw (uno::RuntimeException, std::exception)
601 : {
602 36 : SolarMutexGuard aGuard;
603 : IFieldmark *pBkm = const_cast<IFieldmark*>(
604 36 : dynamic_cast<const IFieldmark*>(GetBookmark()));
605 36 : if(!pBkm)
606 0 : throw uno::RuntimeException();
607 36 : return uno::Reference<container::XNameContainer>(new SwXFieldmarkParameters(pBkm));
608 : }
609 :
610 : uno::Reference<text::XTextContent>
611 137 : SwXFieldmark::CreateXFieldmark(SwDoc & rDoc, ::sw::mark::IMark *const pMark,
612 : bool const isReplacementObject)
613 : {
614 : // #i105557#: do not iterate over the registered clients: race condition
615 : ::sw::mark::MarkBase *const pMarkBase(
616 137 : dynamic_cast< ::sw::mark::MarkBase * >(pMark));
617 : assert(!pMark || pMarkBase);
618 137 : uno::Reference<text::XTextContent> xMark;
619 137 : if (pMarkBase)
620 : {
621 10 : xMark = pMarkBase->GetXBookmark();
622 : }
623 137 : if (!xMark.is())
624 : {
625 : // FIXME: These belong in XTextFieldsSupplier
626 133 : SwXFieldmark* pXBkmk = NULL;
627 133 : if (dynamic_cast< ::sw::mark::TextFieldmark* >(pMark))
628 4 : pXBkmk = new SwXFieldmark(false, pMark, &rDoc);
629 129 : else if (dynamic_cast< ::sw::mark::CheckboxFieldmark* >(pMark))
630 2 : pXBkmk = new SwXFieldmark(true, pMark, &rDoc);
631 : else
632 127 : pXBkmk = new SwXFieldmark(isReplacementObject, 0, &rDoc);
633 :
634 133 : xMark.set(pXBkmk);
635 133 : pXBkmk->registerInMark(*pXBkmk, pMarkBase);
636 : }
637 137 : return xMark;
638 : }
639 :
640 : ::sw::mark::ICheckboxFieldmark*
641 30 : SwXFieldmark::getCheckboxFieldmark()
642 : {
643 30 : ::sw::mark::ICheckboxFieldmark* pCheckboxFm = NULL;
644 30 : if ( getFieldType() == ODF_FORMCHECKBOX )
645 : {
646 : // evil #TODO #FIXME casting away the const-ness
647 30 : pCheckboxFm = const_cast<sw::mark::ICheckboxFieldmark*>(dynamic_cast< const ::sw::mark::ICheckboxFieldmark* >( GetBookmark()));
648 : OSL_ASSERT( GetBookmark() == 0 || pCheckboxFm != 0 );
649 : // unclear to me whether GetBookmark() can be null here
650 : }
651 30 : return pCheckboxFm;
652 :
653 : }
654 :
655 : // support 'hidden' "Checked" property ( note: this property is just for convenience to support
656 : // docx import filter thus not published via PropertySet info )
657 :
658 : void SAL_CALL
659 30 : SwXFieldmark::setPropertyValue(const OUString& PropertyName,
660 : const uno::Any& rValue)
661 : throw (beans::UnknownPropertyException, beans::PropertyVetoException,
662 : lang::IllegalArgumentException, lang::WrappedTargetException,
663 : uno::RuntimeException, std::exception)
664 : {
665 30 : SolarMutexGuard g;
666 30 : if ( PropertyName == "Checked" )
667 : {
668 30 : ::sw::mark::ICheckboxFieldmark* pCheckboxFm = getCheckboxFieldmark();
669 30 : bool bChecked( false );
670 30 : if ( pCheckboxFm && ( rValue >>= bChecked ) )
671 30 : pCheckboxFm->SetChecked( bChecked );
672 : else
673 0 : throw uno::RuntimeException();
674 :
675 : }
676 : else
677 0 : SwXFieldmark_Base::setPropertyValue( PropertyName, rValue );
678 30 : }
679 :
680 : // support 'hidden' "Checked" property ( note: this property is just for convenience to support
681 : // docx import filter thus not published via PropertySet info )
682 :
683 0 : uno::Any SAL_CALL SwXFieldmark::getPropertyValue(const OUString& rPropertyName)
684 : throw (beans::UnknownPropertyException, lang::WrappedTargetException,
685 : uno::RuntimeException, std::exception)
686 : {
687 0 : SolarMutexGuard g;
688 0 : if ( rPropertyName == "Checked" )
689 : {
690 0 : ::sw::mark::ICheckboxFieldmark* pCheckboxFm = getCheckboxFieldmark();
691 0 : if ( pCheckboxFm )
692 0 : return uno::makeAny( pCheckboxFm->IsChecked() );
693 : else
694 0 : throw uno::RuntimeException();
695 : }
696 0 : return SwXFieldmark_Base::getPropertyValue( rPropertyName );
697 177 : }
698 :
699 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|