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