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