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