xref: /aoo4110/main/sw/source/core/unocore/unorefmk.cxx (revision b1cdbd2c)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sw.hxx"
26 
27 #include <vos/mutex.hxx>
28 #include <vcl/svapp.hxx>
29 
30 #include <unomid.h>
31 #include <unotextrange.hxx>
32 #include <unorefmark.hxx>
33 #include <unotextcursor.hxx>
34 #include <unomap.hxx>
35 #include <unocrsr.hxx>
36 #include <unoevtlstnr.hxx>
37 #include <unocrsrhelper.hxx>
38 #include <doc.hxx>
39 #include <ndtxt.hxx>
40 #include <fmtrfmrk.hxx>
41 #include <txtrfmrk.hxx>
42 #include <hints.hxx>
43 
44 
45 using namespace ::com::sun::star;
46 using ::rtl::OUString;
47 
48 /******************************************************************
49  * SwXReferenceMark
50  ******************************************************************/
51 
52 class SwXReferenceMark::Impl
53     : public SwClient
54 {
55 
56 public:
57     SwEventListenerContainer    m_ListenerContainer;
58     bool                        m_bIsDescriptor;
59     SwDoc *                     m_pDoc;
60     const SwFmtRefMark *        m_pMarkFmt;
61     ::rtl::OUString             m_sMarkName;
62 
Impl(SwXReferenceMark & rThis,SwDoc * const pDoc,SwFmtRefMark const * const pRefMark)63     Impl(   SwXReferenceMark & rThis,
64             SwDoc *const pDoc, SwFmtRefMark const*const pRefMark)
65         : SwClient((pDoc) ? pDoc->GetUnoCallBack() : 0)
66         , m_ListenerContainer(static_cast< ::cppu::OWeakObject* >(&rThis))
67         // #i111177# unxsols4 (Sun C++ 5.9 SunOS_sparc) may generate wrong code
68         , m_bIsDescriptor((0 == pRefMark) ? true : false)
69         , m_pDoc(pDoc)
70         , m_pMarkFmt(pRefMark)
71     {
72         if (pRefMark)
73         {
74             m_sMarkName = pRefMark->GetRefName();
75         }
76     }
77 
IsValid() const78     bool    IsValid() const { return 0 != GetRegisteredIn(); }
79     void    InsertRefMark( SwPaM & rPam, SwXTextCursor const*const pCursor );
80     void    Invalidate();
81 protected:
82     // SwClient
83     virtual void    Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew);
84 
85 };
86 
87 /* -----------------------------07.01.00 12:51--------------------------------
88 
89  ---------------------------------------------------------------------------*/
Invalidate()90 void SwXReferenceMark::Impl::Invalidate()
91 {
92     if (IsValid())
93     {
94         const_cast<SwModify*>(GetRegisteredIn())->Remove(this);
95     }
96     m_ListenerContainer.Disposing();
97     m_pDoc = 0;
98     m_pMarkFmt = 0;
99 }
100 
101 /*-- 11.12.98 10:28:37---------------------------------------------------
102 
103   -----------------------------------------------------------------------*/
Modify(const SfxPoolItem * pOld,const SfxPoolItem * pNew)104 void SwXReferenceMark::Impl::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew)
105 {
106     ClientModify(this, pOld, pNew);
107 
108     if (!GetRegisteredIn()) // removed => dispose
109     {
110         Invalidate();
111     }
112     else if (pOld)
113     {
114         switch (pOld->Which())
115         {
116             case RES_REFMARK_DELETED:
117                 if (static_cast<const void*>(m_pMarkFmt) ==
118                         static_cast<const SwPtrMsgPoolItem *>(pOld)->pObject)
119                 {
120                     Invalidate();
121                 }
122                 break;
123         }
124     }
125 }
126 
127 
128 /*-- 11.12.98 10:28:32---------------------------------------------------
129 
130   -----------------------------------------------------------------------*/
SwXReferenceMark(SwDoc * const pDoc,SwFmtRefMark const * const pRefMark)131 SwXReferenceMark::SwXReferenceMark(
132         SwDoc *const pDoc, SwFmtRefMark const*const pRefMark)
133     : m_pImpl( new SwXReferenceMark::Impl(*this, pDoc, pRefMark) )
134 {
135 }
136 
137 /*-- 11.12.98 10:28:33---------------------------------------------------
138 
139   -----------------------------------------------------------------------*/
~SwXReferenceMark()140 SwXReferenceMark::~SwXReferenceMark()
141 {
142 }
143 
144 SwXReferenceMark *
GetReferenceMark(SwModify const &,SwFmtRefMark const &)145 SwXReferenceMark::GetReferenceMark(
146         SwModify const& /*rUnoCB*/, SwFmtRefMark const& /*rMarkFmt*/)
147 {
148     // #i105557#: do not iterate over the registered clients: race condition
149     // to do this properly requires the SwXReferenceMark to register at the
150     // SwFmtRefMark directly, not at the unocallback
151     return 0;
152 }
153 
154 SwXReferenceMark *
CreateXReferenceMark(SwDoc & rDoc,SwFmtRefMark const & rMarkFmt)155 SwXReferenceMark::CreateXReferenceMark(
156         SwDoc & rDoc, SwFmtRefMark const& rMarkFmt)
157 {
158     SwXReferenceMark *const pXMark(
159         GetReferenceMark(*rDoc.GetUnoCallBack(), rMarkFmt) );
160     return (pXMark)
161         ?   pXMark
162         :   new SwXReferenceMark(&rDoc, &rMarkFmt);
163 }
164 
165 /* -----------------------------13.03.00 12:15--------------------------------
166 
167  ---------------------------------------------------------------------------*/
getUnoTunnelId()168 const uno::Sequence< sal_Int8 > & SwXReferenceMark::getUnoTunnelId()
169 {
170     static uno::Sequence< sal_Int8 > aSeq = ::CreateUnoTunnelId();
171 	return aSeq;
172 }
173 /* -----------------------------10.03.00 18:04--------------------------------
174 
175  ---------------------------------------------------------------------------*/
176 sal_Int64 SAL_CALL
getSomething(const uno::Sequence<sal_Int8> & rId)177 SwXReferenceMark::getSomething(const uno::Sequence< sal_Int8 >& rId)
178 throw (uno::RuntimeException)
179 {
180     return ::sw::UnoTunnelImpl<SwXReferenceMark>(rId, this);
181 }
182 /* -----------------------------06.04.00 16:41--------------------------------
183 
184  ---------------------------------------------------------------------------*/
getImplementationName()185 OUString SAL_CALL SwXReferenceMark::getImplementationName()
186 throw (uno::RuntimeException)
187 {
188 	return C2U("SwXReferenceMark");
189 }
190 /* -----------------------------06.04.00 16:41--------------------------------
191 
192  ---------------------------------------------------------------------------*/
193 static char const*const g_ServicesReferenceMark[] =
194 {
195     "com.sun.star.text.TextContent",
196     "com.sun.star.text.ReferenceMark",
197 };
198 static const size_t g_nServicesReferenceMark(
199     sizeof(g_ServicesReferenceMark)/sizeof(g_ServicesReferenceMark[0]));
200 
201 sal_Bool SAL_CALL
supportsService(const OUString & rServiceName)202 SwXReferenceMark::supportsService(const OUString& rServiceName)
203 throw (uno::RuntimeException)
204 {
205     return ::sw::SupportsServiceImpl(
206             g_nServicesReferenceMark, g_ServicesReferenceMark, rServiceName);
207 }
208 /* -----------------------------06.04.00 16:41--------------------------------
209 
210  ---------------------------------------------------------------------------*/
211 uno::Sequence< OUString > SAL_CALL
getSupportedServiceNames()212 SwXReferenceMark::getSupportedServiceNames()
213 throw (uno::RuntimeException)
214 {
215     return ::sw::GetSupportedServiceNamesImpl(
216             g_nServicesReferenceMark, g_ServicesReferenceMark);
217 }
218 
219 /* -----------------03.11.99 14:14-------------------
220 
221  --------------------------------------------------*/
222 template<typename T> struct NotContainedIn
223 {
224     ::std::vector<T> const& m_rVector;
NotContainedInNotContainedIn225     explicit NotContainedIn(::std::vector<T> const& rVector)
226         : m_rVector(rVector) { }
operator ()NotContainedIn227     bool operator() (T const& rT) {
228         return ::std::find(m_rVector.begin(), m_rVector.end(), rT)
229                     == m_rVector.end();
230     }
231 };
232 
InsertRefMark(SwPaM & rPam,SwXTextCursor const * const pCursor)233 void SwXReferenceMark::Impl::InsertRefMark(SwPaM& rPam,
234         SwXTextCursor const*const pCursor)
235 {
236 	//! in some cases when this function is called the pDoc pointer member may have become
237 	//! invalid/deleted thus we obtain the document pointer from rPaM where it should always
238 	//! be valid.
239 	SwDoc *pDoc2 = rPam.GetDoc();
240 
241 	UnoActionContext aCont(pDoc2);
242     SwFmtRefMark aRefMark(m_sMarkName);
243 	sal_Bool bMark = *rPam.GetPoint() != *rPam.GetMark();
244 
245     const bool bForceExpandHints( (!bMark && pCursor)
246             ? pCursor->IsAtEndOfMeta() : false );
247     const SetAttrMode nInsertFlags = (bForceExpandHints)
248         ?   ( nsSetAttrMode::SETATTR_FORCEHINTEXPAND
249             | nsSetAttrMode::SETATTR_DONTEXPAND)
250         : nsSetAttrMode::SETATTR_DONTEXPAND;
251 
252     ::std::vector<SwTxtAttr *> oldMarks;
253     if (bMark)
254     {
255         oldMarks = rPam.GetNode()->GetTxtNode()->GetTxtAttrsAt(
256             rPam.GetPoint()->nContent.GetIndex(), RES_TXTATR_REFMARK);
257     }
258 
259     pDoc2->InsertPoolItem( rPam, aRefMark, nInsertFlags );
260 
261 	if( bMark && *rPam.GetPoint() > *rPam.GetMark())
262     {
263 		rPam.Exchange();
264     }
265 
266     // aRefMark was copied into the document pool; now retrieve real format...
267     SwTxtAttr * pTxtAttr(0);
268     if (bMark)
269     {
270         // #i107672#
271         // ensure that we do not retrieve a different mark at the same position
272         ::std::vector<SwTxtAttr *> const newMarks(
273             rPam.GetNode()->GetTxtNode()->GetTxtAttrsAt(
274                 rPam.GetPoint()->nContent.GetIndex(), RES_TXTATR_REFMARK));
275         ::std::vector<SwTxtAttr *>::const_iterator const iter(
276             ::std::find_if(newMarks.begin(), newMarks.end(),
277                 NotContainedIn<SwTxtAttr *>(oldMarks)));
278         OSL_ASSERT(newMarks.end() != iter);
279         if (newMarks.end() != iter)
280         {
281             pTxtAttr = *iter;
282         }
283     }
284     else
285     {
286         pTxtAttr = rPam.GetNode()->GetTxtNode()->GetTxtAttrForCharAt(
287                 rPam.GetPoint()->nContent.GetIndex() - 1, RES_TXTATR_REFMARK);
288     }
289 
290     if (!pTxtAttr)
291     {
292         throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
293             "SwXReferenceMark::InsertRefMark(): cannot insert attribute")), 0);
294     }
295 
296     m_pMarkFmt = &pTxtAttr->GetRefMark();
297 
298 	pDoc2->GetUnoCallBack()->Add(this);
299 }
300 
301 /*-- 11.12.98 10:28:34---------------------------------------------------
302 
303   -----------------------------------------------------------------------*/
304 void SAL_CALL
attach(const uno::Reference<text::XTextRange> & xTextRange)305 SwXReferenceMark::attach(const uno::Reference< text::XTextRange > & xTextRange)
306 throw (lang::IllegalArgumentException, uno::RuntimeException)
307 {
308 	vos::OGuard aGuard(Application::GetSolarMutex());
309 
310     if (!m_pImpl->m_bIsDescriptor)
311     {
312 		throw uno::RuntimeException();
313     }
314 	uno::Reference<lang::XUnoTunnel> xRangeTunnel( xTextRange, uno::UNO_QUERY);
315 	SwXTextRange* pRange = 0;
316 	OTextCursorHelper* pCursor = 0;
317 	if(xRangeTunnel.is())
318     {
319         pRange = ::sw::UnoTunnelGetImplementation<SwXTextRange>(xRangeTunnel);
320         pCursor =
321             ::sw::UnoTunnelGetImplementation<OTextCursorHelper>(xRangeTunnel);
322     }
323     SwDoc *const pDocument =
324         (pRange) ? pRange->GetDoc() : ((pCursor) ? pCursor->GetDoc() : 0);
325 	if (!pDocument)
326 	{
327 		throw lang::IllegalArgumentException();
328 	}
329 
330     SwUnoInternalPaM aPam(*pDocument);
331     //das muss jetzt sal_True liefern
332     ::sw::XTextRangeToSwPaM(aPam, xTextRange);
333     m_pImpl->InsertRefMark(aPam, dynamic_cast<SwXTextCursor*>(pCursor));
334     m_pImpl->m_bIsDescriptor = sal_False;
335     m_pImpl->m_pDoc = pDocument;
336 }
337 
338 /*-- 11.12.98 10:28:34---------------------------------------------------
339 
340   -----------------------------------------------------------------------*/
341 uno::Reference< text::XTextRange > SAL_CALL
getAnchor()342 SwXReferenceMark::getAnchor() throw (uno::RuntimeException)
343 {
344 	vos::OGuard aGuard(Application::GetSolarMutex());
345 
346     if (m_pImpl->IsValid())
347     {
348         SwFmtRefMark const*const pNewMark =
349             m_pImpl->m_pDoc->GetRefMark(m_pImpl->m_sMarkName);
350         if (pNewMark && (pNewMark == m_pImpl->m_pMarkFmt))
351         {
352             SwTxtRefMark const*const pTxtMark =
353                 m_pImpl->m_pMarkFmt->GetTxtRefMark();
354             if (pTxtMark &&
355                 (&pTxtMark->GetTxtNode().GetNodes() ==
356                     &m_pImpl->m_pDoc->GetNodes()))
357             {
358                 SwTxtNode const& rTxtNode = pTxtMark->GetTxtNode();
359                 const ::std::auto_ptr<SwPaM> pPam( (pTxtMark->End())
360                     ?   new SwPaM( rTxtNode, *pTxtMark->End(),
361                                    rTxtNode, *pTxtMark->GetStart())
362                     :   new SwPaM( rTxtNode, *pTxtMark->GetStart()) );
363 
364                 return SwXTextRange::CreateXTextRange(
365                             *m_pImpl->m_pDoc, *pPam->Start(), pPam->End());
366             }
367         }
368     }
369     return 0;
370 }
371 /*-- 11.12.98 10:28:35---------------------------------------------------
372 
373   -----------------------------------------------------------------------*/
dispose()374 void SAL_CALL SwXReferenceMark::dispose() throw (uno::RuntimeException)
375 {
376 	vos::OGuard aGuard(Application::GetSolarMutex());
377     if (m_pImpl->IsValid())
378     {
379         SwFmtRefMark const*const pNewMark =
380             m_pImpl->m_pDoc->GetRefMark(m_pImpl->m_sMarkName);
381         if (pNewMark && (pNewMark == m_pImpl->m_pMarkFmt))
382         {
383             SwTxtRefMark const*const pTxtMark =
384                 m_pImpl->m_pMarkFmt->GetTxtRefMark();
385             if (pTxtMark &&
386                 (&pTxtMark->GetTxtNode().GetNodes() ==
387                     &m_pImpl->m_pDoc->GetNodes()))
388             {
389                 SwTxtNode const& rTxtNode = pTxtMark->GetTxtNode();
390                 const xub_StrLen nStt = *pTxtMark->GetStart();
391                 const xub_StrLen nEnd = pTxtMark->End()
392                                   ? *pTxtMark->End()
393                                   : nStt + 1;
394 
395 				SwPaM aPam( rTxtNode, nStt, rTxtNode, nEnd );
396                 m_pImpl->m_pDoc->DeleteAndJoin( aPam );
397             }
398         }
399     }
400     else if (m_pImpl->m_bIsDescriptor)
401     {
402         m_pImpl->Invalidate();
403     }
404 }
405 /*-- 11.12.98 10:28:35---------------------------------------------------
406 
407   -----------------------------------------------------------------------*/
addEventListener(const uno::Reference<lang::XEventListener> & xListener)408 void SAL_CALL SwXReferenceMark::addEventListener(
409         const uno::Reference< lang::XEventListener > & xListener)
410 throw (uno::RuntimeException)
411 {
412     vos::OGuard g(Application::GetSolarMutex());
413 
414     if (!m_pImpl->IsValid())
415     {
416 		throw uno::RuntimeException();
417     }
418     m_pImpl->m_ListenerContainer.AddListener(xListener);
419 }
420 /*-- 11.12.98 10:28:35---------------------------------------------------
421 
422   -----------------------------------------------------------------------*/
removeEventListener(const uno::Reference<lang::XEventListener> & xListener)423 void SAL_CALL SwXReferenceMark::removeEventListener(
424         const uno::Reference< lang::XEventListener > & xListener)
425 throw (uno::RuntimeException)
426 {
427     vos::OGuard g(Application::GetSolarMutex());
428 
429     if (!m_pImpl->IsValid() ||
430         !m_pImpl->m_ListenerContainer.RemoveListener(xListener))
431     {
432 		throw uno::RuntimeException();
433     }
434 }
435 /*-- 11.12.98 10:28:36---------------------------------------------------
436 
437   -----------------------------------------------------------------------*/
getName()438 OUString SAL_CALL SwXReferenceMark::getName()
439 throw (uno::RuntimeException)
440 {
441 	vos::OGuard aGuard(Application::GetSolarMutex());
442     if (!m_pImpl->IsValid() ||
443         !m_pImpl->m_pDoc->GetRefMark(m_pImpl->m_sMarkName))
444     {
445 		throw uno::RuntimeException();
446     }
447     return m_pImpl->m_sMarkName;
448 }
449 /*-- 11.12.98 10:28:36---------------------------------------------------
450 
451   -----------------------------------------------------------------------*/
setName(const OUString & rName)452 void SAL_CALL SwXReferenceMark::setName(const OUString& rName)
453 throw (uno::RuntimeException)
454 {
455 	vos::OGuard aGuard(Application::GetSolarMutex());
456     if (m_pImpl->m_bIsDescriptor)
457     {
458         m_pImpl->m_sMarkName = rName;
459     }
460     else
461     {
462         if (!m_pImpl->IsValid()
463             || !m_pImpl->m_pDoc->GetRefMark(m_pImpl->m_sMarkName)
464             || m_pImpl->m_pDoc->GetRefMark(rName))
465         {
466 			throw uno::RuntimeException();
467         }
468         SwFmtRefMark const*const pCurMark =
469             m_pImpl->m_pDoc->GetRefMark(m_pImpl->m_sMarkName);
470         if ((rName != m_pImpl->m_sMarkName)
471             && pCurMark && (pCurMark == m_pImpl->m_pMarkFmt))
472         {
473             const UnoActionContext aCont(m_pImpl->m_pDoc);
474             SwTxtRefMark const*const pTxtMark =
475                 m_pImpl->m_pMarkFmt->GetTxtRefMark();
476             if (pTxtMark &&
477                 (&pTxtMark->GetTxtNode().GetNodes() ==
478                      &m_pImpl->m_pDoc->GetNodes()))
479             {
480                 SwTxtNode const& rTxtNode = pTxtMark->GetTxtNode();
481                 const xub_StrLen nStt = *pTxtMark->GetStart();
482                 const xub_StrLen nEnd = pTxtMark->End()
483                                         ? *pTxtMark->End()
484                                         : nStt + 1;
485 
486                 SwPaM aPam( rTxtNode, nStt, rTxtNode, nEnd );
487                 // deletes the m_pImpl->m_pDoc member in the SwXReferenceMark!
488                 m_pImpl->m_pDoc->DeleteAndJoin( aPam );
489                 // The aPam will keep the correct and functional doc though
490 
491                 m_pImpl->m_sMarkName = rName;
492                 //create a new one
493                 m_pImpl->InsertRefMark( aPam, 0 );
494                 m_pImpl->m_pDoc = aPam.GetDoc();
495             }
496         }
497     }
498 }
499 
500 /*-- 12.09.00 12:58:20---------------------------------------------------
501 
502   -----------------------------------------------------------------------*/
503 uno::Reference< beans::XPropertySetInfo > SAL_CALL
getPropertySetInfo()504 SwXReferenceMark::getPropertySetInfo() throw (uno::RuntimeException)
505 {
506     vos::OGuard g(Application::GetSolarMutex());
507 
508 	static uno::Reference< beans::XPropertySetInfo >  xRef =
509         aSwMapProvider.GetPropertySet(PROPERTY_MAP_PARAGRAPH_EXTENSIONS)
510             ->getPropertySetInfo();
511 	return xRef;
512 }
513 /*-- 12.09.00 12:58:20---------------------------------------------------
514 
515   -----------------------------------------------------------------------*/
setPropertyValue(const OUString &,const uno::Any &)516 void SAL_CALL SwXReferenceMark::setPropertyValue(
517     const OUString& /*rPropertyName*/, const uno::Any& /*rValue*/ )
518 throw (beans::UnknownPropertyException, beans::PropertyVetoException,
519     lang::IllegalArgumentException, lang::WrappedTargetException,
520     uno::RuntimeException)
521 {
522 	throw lang::IllegalArgumentException();
523 }
524 /*-- 12.09.00 12:58:20---------------------------------------------------
525 
526   -----------------------------------------------------------------------*/
527 uno::Any SAL_CALL
getPropertyValue(const OUString & rPropertyName)528 SwXReferenceMark::getPropertyValue(const OUString& rPropertyName)
529 throw (beans::UnknownPropertyException, lang::WrappedTargetException,
530     uno::RuntimeException)
531 {
532     // does not seem to need SolarMutex
533 	uno::Any aRet;
534     if (! ::sw::GetDefaultTextContentValue(aRet, rPropertyName))
535     {
536 		throw beans::UnknownPropertyException();
537     }
538 	return aRet;
539 }
540 /*-- 12.09.00 12:58:20---------------------------------------------------
541 
542   -----------------------------------------------------------------------*/
addPropertyChangeListener(const OUString &,const uno::Reference<beans::XPropertyChangeListener> &)543 void SAL_CALL SwXReferenceMark::addPropertyChangeListener(
544         const OUString& /*rPropertyName*/,
545         const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
546 throw (beans::UnknownPropertyException, lang::WrappedTargetException,
547     uno::RuntimeException)
548 {
549     OSL_ENSURE(false,
550         "SwXReferenceMark::addPropertyChangeListener(): not implemented");
551 }
552 /*-- 12.09.00 12:58:20---------------------------------------------------
553 
554   -----------------------------------------------------------------------*/
removePropertyChangeListener(const OUString &,const uno::Reference<beans::XPropertyChangeListener> &)555 void SAL_CALL SwXReferenceMark::removePropertyChangeListener(
556         const OUString& /*rPropertyName*/,
557         const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
558 throw (beans::UnknownPropertyException, lang::WrappedTargetException,
559         uno::RuntimeException)
560 {
561     OSL_ENSURE(false,
562         "SwXReferenceMark::removePropertyChangeListener(): not implemented");
563 }
564 /*-- 12.09.00 12:58:20---------------------------------------------------
565 
566   -----------------------------------------------------------------------*/
addVetoableChangeListener(const OUString &,const uno::Reference<beans::XVetoableChangeListener> &)567 void SAL_CALL SwXReferenceMark::addVetoableChangeListener(
568         const OUString& /*rPropertyName*/,
569         const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
570 throw (beans::UnknownPropertyException, lang::WrappedTargetException,
571         uno::RuntimeException)
572 {
573     OSL_ENSURE(false,
574         "SwXReferenceMark::addVetoableChangeListener(): not implemented");
575 }
576 /*-- 12.09.00 12:58:21---------------------------------------------------
577 
578   -----------------------------------------------------------------------*/
removeVetoableChangeListener(const OUString &,const uno::Reference<beans::XVetoableChangeListener> &)579 void SAL_CALL SwXReferenceMark::removeVetoableChangeListener(
580     const OUString& /*rPropertyName*/,
581     const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
582 throw (beans::UnknownPropertyException, lang::WrappedTargetException,
583         uno::RuntimeException)
584 {
585     OSL_ENSURE(false,
586         "SwXReferenceMark::removeVetoableChangeListener(): not implemented");
587 }
588 
589 #include <com/sun/star/lang/DisposedException.hpp>
590 #include <unometa.hxx>
591 #include <unotext.hxx>
592 #include <unoport.hxx>
593 #include <txtatr.hxx>
594 #include <fmtmeta.hxx>
595 #include <docsh.hxx>
596 
597 //=============================================================================
598 
599 /******************************************************************
600  * SwXMetaText
601  ******************************************************************/
602 
603 class SwXMetaText
604     : public SwXText
605 {
606 private:
607     SwXMeta & m_rMeta;
608 
609     virtual void PrepareForAttach(uno::Reference< text::XTextRange > & xRange,
610             const SwPaM & rPam);
611 
612     virtual bool CheckForOwnMemberMeta(const SwPaM & rPam, const bool bAbsorb)
613         throw (lang::IllegalArgumentException, uno::RuntimeException);
614 
615 protected:
616     virtual const SwStartNode *GetStartNode() const;
617     virtual uno::Reference< text::XTextCursor >
618         CreateCursor() throw (uno::RuntimeException);
619 
620 public:
621     SwXMetaText(SwDoc & rDoc, SwXMeta & rMeta);
622 
623     /// make available for SwXMeta
Invalidate()624     void Invalidate() { SwXText::Invalidate(); };
625 
626     // XInterface
acquire()627     virtual void SAL_CALL acquire() throw()
628         { OSL_ENSURE(false, "ERROR: SwXMetaText::acquire"); }
release()629     virtual void SAL_CALL release() throw()
630         { OSL_ENSURE(false, "ERROR: SwXMetaText::release"); }
631 
632     // XTypeProvider
633     virtual uno::Sequence< sal_Int8 > SAL_CALL
634         getImplementationId() throw (uno::RuntimeException);
635 
636     // XText
637     virtual uno::Reference< text::XTextCursor >  SAL_CALL
638         createTextCursor() throw (uno::RuntimeException);
639     virtual uno::Reference< text::XTextCursor >  SAL_CALL
640         createTextCursorByRange(
641             const uno::Reference< text::XTextRange > & xTextPosition)
642         throw (uno::RuntimeException);
643 
GetXMeta()644     SwXMeta & GetXMeta() { return m_rMeta; }
645 
646 };
647 
SwXMetaText(SwDoc & rDoc,SwXMeta & rMeta)648 SwXMetaText::SwXMetaText(SwDoc & rDoc, SwXMeta & rMeta)
649     : SwXText(&rDoc, CURSOR_META)
650     , m_rMeta(rMeta)
651 {
652 }
653 
GetStartNode() const654 const SwStartNode *SwXMetaText::GetStartNode() const
655 {
656     SwXText const * const pParent(
657             dynamic_cast<SwXText*>(m_rMeta.GetParentText().get()));
658     return (pParent) ? pParent->GetStartNode() : 0;
659 }
660 
PrepareForAttach(uno::Reference<text::XTextRange> & xRange,const SwPaM & rPam)661 void SwXMetaText::PrepareForAttach( uno::Reference<text::XTextRange> & xRange,
662         const SwPaM & rPam)
663 {
664     // create a new cursor to prevent modifying SwXTextRange
665     xRange = static_cast<text::XWordCursor*>(
666         new SwXTextCursor(*GetDoc(), &m_rMeta, CURSOR_META, *rPam.GetPoint(),
667                 (rPam.HasMark()) ? rPam.GetMark() : 0));
668 }
669 
CheckForOwnMemberMeta(const SwPaM & rPam,const bool bAbsorb)670 bool SwXMetaText::CheckForOwnMemberMeta(const SwPaM & rPam, const bool bAbsorb)
671     throw (lang::IllegalArgumentException, uno::RuntimeException)
672 {
673     return m_rMeta.CheckForOwnMemberMeta(rPam, bAbsorb);
674 }
675 
CreateCursor()676 uno::Reference< text::XTextCursor > SwXMetaText::CreateCursor()
677 throw (uno::RuntimeException)
678 {
679     uno::Reference< text::XTextCursor > xRet;
680     if (IsValid())
681     {
682         SwTxtNode * pTxtNode;
683         xub_StrLen nMetaStart;
684         xub_StrLen nMetaEnd;
685         const bool bSuccess(
686                 m_rMeta.SetContentRange(pTxtNode, nMetaStart, nMetaEnd) );
687         if (bSuccess)
688         {
689             SwPosition aPos(*pTxtNode, nMetaStart);
690             xRet = static_cast<text::XWordCursor*>(
691                     new SwXTextCursor(*GetDoc(), &m_rMeta, CURSOR_META, aPos));
692         }
693     }
694     return xRet;
695 }
696 
697 uno::Sequence<sal_Int8> SAL_CALL
getImplementationId()698 SwXMetaText::getImplementationId() throw (uno::RuntimeException)
699 {
700     return m_rMeta.getImplementationId();
701 }
702 
703 // XText
704 uno::Reference< text::XTextCursor > SAL_CALL
createTextCursor()705 SwXMetaText::createTextCursor() throw (uno::RuntimeException)
706 {
707     return CreateCursor();
708 }
709 
710 uno::Reference< text::XTextCursor > SAL_CALL
createTextCursorByRange(const uno::Reference<text::XTextRange> & xTextPosition)711 SwXMetaText::createTextCursorByRange(
712         const uno::Reference<text::XTextRange> & xTextPosition)
713     throw (uno::RuntimeException)
714 {
715     const uno::Reference<text::XTextCursor> xCursor( CreateCursor() );
716     xCursor->gotoRange(xTextPosition, sal_False);
717     return xCursor;
718 }
719 
720 /******************************************************************
721  * SwXMeta
722  ******************************************************************/
723 
724 // the Meta has a cached list of text portions for its contents
725 // this list is created by SwXTextPortionEnumeration
726 // the Meta listens at the SwTxtNode and throws away the cache when it changes
727 
728 class SwXMeta::Impl
729     : public SwClient
730 {
731 
732 public:
733 
734     SwEventListenerContainer m_ListenerContainer;
735     ::std::auto_ptr<const TextRangeList_t> m_pTextPortions;
736     // 3 possible states: not attached, attached, disposed
737     bool m_bIsDisposed;
738     bool m_bIsDescriptor;
739     uno::Reference<text::XText> m_xParentText;
740     SwXMetaText m_Text;
741 
Impl(SwXMeta & rThis,SwDoc & rDoc,::sw::Meta * const pMeta,uno::Reference<text::XText> const & xParentText,TextRangeList_t const * const pPortions)742     Impl(   SwXMeta & rThis, SwDoc & rDoc,
743             ::sw::Meta * const pMeta,
744             uno::Reference<text::XText> const& xParentText,
745             TextRangeList_t const * const pPortions)
746         : SwClient(pMeta)
747         , m_ListenerContainer(static_cast< ::cppu::OWeakObject* >(&rThis))
748         , m_pTextPortions( pPortions )
749         , m_bIsDisposed( false )
750         // #i111177# unxsols4 (Sun C++ 5.9 SunOS_sparc) may generate wrong code
751         , m_bIsDescriptor((0 == pMeta) ? true : false)
752         , m_xParentText(xParentText)
753         , m_Text(rDoc, rThis)
754     {
755     }
756 
757     inline const ::sw::Meta * GetMeta() const;
758     // only for SwXMetaField!
759     inline const ::sw::MetaField * GetMetaField() const;
760 protected:
761     // SwClient
762     virtual void Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew);
763 
764 };
765 
GetMeta() const766 inline const ::sw::Meta * SwXMeta::Impl::GetMeta() const
767 {
768     return static_cast< const ::sw::Meta * >(GetRegisteredIn());
769 }
770 
771 // SwModify
Modify(const SfxPoolItem * pOld,const SfxPoolItem * pNew)772 void SwXMeta::Impl::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew )
773 {
774     m_pTextPortions.reset(); // throw away cache (SwTxtNode changed)
775 
776     ClientModify(this, pOld, pNew);
777 
778     if (!GetRegisteredIn()) // removed => dispose
779     {
780         m_ListenerContainer.Disposing();
781         m_bIsDisposed = true;
782         m_Text.Invalidate();
783     }
784 }
785 
GetParentText() const786 uno::Reference<text::XText> SwXMeta::GetParentText() const
787 {
788     return m_pImpl->m_xParentText;
789 }
790 
SwXMeta(SwDoc * const pDoc,::sw::Meta * const pMeta,uno::Reference<text::XText> const & xParentText,TextRangeList_t const * const pPortions)791 SwXMeta::SwXMeta(SwDoc *const pDoc, ::sw::Meta *const pMeta,
792         uno::Reference<text::XText> const& xParentText,
793         TextRangeList_t const*const pPortions)
794     : m_pImpl( new SwXMeta::Impl(*this, *pDoc, pMeta, xParentText, pPortions) )
795 {
796 }
797 
SwXMeta(SwDoc * const pDoc)798 SwXMeta::SwXMeta(SwDoc *const pDoc)
799     : m_pImpl( new SwXMeta::Impl(*this, *pDoc, 0, 0, 0) )
800 {
801 }
802 
~SwXMeta()803 SwXMeta::~SwXMeta()
804 {
805 }
806 
807 uno::Reference<rdf::XMetadatable>
CreateXMeta(::sw::Meta & rMeta,uno::Reference<text::XText> const & i_xParent,::std::auto_ptr<TextRangeList_t const> pPortions)808 SwXMeta::CreateXMeta(::sw::Meta & rMeta,
809             uno::Reference<text::XText> const& i_xParent,
810             ::std::auto_ptr<TextRangeList_t const> pPortions)
811 {
812     // re-use existing SwXMeta
813     // #i105557#: do not iterate over the registered clients: race condition
814     uno::Reference<rdf::XMetadatable> xMeta(rMeta.GetXMeta());
815     if (xMeta.is())
816     {
817         if (pPortions.get()) // set cache in the XMeta to the given portions
818         {
819             const uno::Reference<lang::XUnoTunnel> xUT(xMeta, uno::UNO_QUERY);
820             SwXMeta *const pXMeta(
821                 ::sw::UnoTunnelGetImplementation<SwXMeta>(xUT));
822             OSL_ENSURE(pXMeta, "no pXMeta?");
823             // NB: the meta must always be created with the complete content
824             // if SwXTextPortionEnumeration is created for a selection,
825             // it must be checked that the Meta is contained in the selection!
826             pXMeta->m_pImpl->m_pTextPortions = pPortions;
827             // ??? is this necessary?
828             if (pXMeta->m_pImpl->m_xParentText.get() != i_xParent.get())
829             {
830                 OSL_ENSURE(false, "SwXMeta with different parent?");
831                 pXMeta->m_pImpl->m_xParentText.set(i_xParent);
832             }
833         }
834         return xMeta;
835     }
836 
837     // create new SwXMeta
838     SwTxtNode * const pTxtNode( rMeta.GetTxtNode() );
839     OSL_ENSURE(pTxtNode, "CreateXMeta: no text node?");
840     if (!pTxtNode) { return 0; }
841     uno::Reference<text::XText> xParentText(i_xParent);
842     if (!xParentText.is())
843     {
844         SwTxtMeta * const pTxtAttr( rMeta.GetTxtAttr() );
845         OSL_ENSURE(pTxtAttr, "CreateXMeta: no text attr?");
846         if (!pTxtAttr) { return 0; }
847         const SwPosition aPos(*pTxtNode, *pTxtAttr->GetStart());
848         xParentText.set( ::sw::CreateParentXText(*pTxtNode->GetDoc(), aPos) );
849     }
850     if (!xParentText.is()) { return 0; }
851     SwXMeta *const pXMeta( (RES_TXTATR_META == rMeta.GetFmtMeta()->Which())
852         ? new SwXMeta     (pTxtNode->GetDoc(), &rMeta, xParentText,
853                             pPortions.release()) // temporarily un-auto_ptr :-(
854         : new SwXMetaField(pTxtNode->GetDoc(), &rMeta, xParentText,
855                             pPortions.release()));
856     // this is why the constructor is private: need to acquire pXMeta here
857     xMeta.set(pXMeta);
858     // in order to initialize the weak pointer cache in the core object
859     rMeta.SetXMeta(xMeta);
860     return xMeta;
861 }
862 
863 
SetContentRange(SwTxtNode * & rpNode,xub_StrLen & rStart,xub_StrLen & rEnd) const864 bool SwXMeta::SetContentRange(
865         SwTxtNode *& rpNode, xub_StrLen & rStart, xub_StrLen & rEnd ) const
866 {
867     ::sw::Meta const * const pMeta( m_pImpl->GetMeta() );
868     if (pMeta)
869     {
870         SwTxtMeta const * const pTxtAttr( pMeta->GetTxtAttr() );
871         if (pTxtAttr)
872         {
873             rpNode = pMeta->GetTxtNode();
874             if (rpNode)
875             {
876                 // rStart points at the first position _within_ the meta!
877                 rStart = *pTxtAttr->GetStart() + 1;
878                 rEnd = *pTxtAttr->End();
879                 return true;
880             }
881         }
882     }
883     return false;
884 }
885 
CheckForOwnMemberMeta(const SwPaM & rPam,const bool bAbsorb)886 bool SwXMeta::CheckForOwnMemberMeta(const SwPaM & rPam, const bool bAbsorb)
887     throw (lang::IllegalArgumentException, uno::RuntimeException)
888 {
889     SwTxtNode * pTxtNode;
890     xub_StrLen nMetaStart;
891     xub_StrLen nMetaEnd;
892     const bool bSuccess( SetContentRange(pTxtNode, nMetaStart, nMetaEnd) );
893     ASSERT(bSuccess, "no pam?");
894     if (!bSuccess)
895         throw lang::DisposedException();
896 
897     SwPosition const * const pStartPos( rPam.Start() );
898     if (&pStartPos->nNode.GetNode() != pTxtNode)
899     {
900         throw lang::IllegalArgumentException(
901             C2U("trying to insert into a nesting text content, but start "
902                 "of text range not in same paragraph as text content"),
903                 0, 0);
904     }
905     bool bForceExpandHints(false);
906     const xub_StrLen nStartPos(pStartPos->nContent.GetIndex());
907     // not <= but < because nMetaStart is behind dummy char!
908     // not >= but > because == means insert at end!
909     if ((nStartPos < nMetaStart) || (nStartPos > nMetaEnd))
910     {
911         throw lang::IllegalArgumentException(
912             C2U("trying to insert into a nesting text content, but start "
913                 "of text range not inside text content"),
914                 0, 0);
915     }
916     else if (nStartPos == nMetaEnd)
917     {
918         bForceExpandHints = true;
919     }
920     if (rPam.HasMark() && bAbsorb)
921     {
922         SwPosition const * const pEndPos( rPam.End() );
923         if (&pEndPos->nNode.GetNode() != pTxtNode)
924         {
925             throw lang::IllegalArgumentException(
926                 C2U("trying to insert into a nesting text content, but end "
927                     "of text range not in same paragraph as text content"),
928                     0, 0);
929         }
930         const xub_StrLen nEndPos(pEndPos->nContent.GetIndex());
931         // not <= but < because nMetaStart is behind dummy char!
932         // not >= but > because == means insert at end!
933         if ((nEndPos < nMetaStart) || (nEndPos > nMetaEnd))
934         {
935             throw lang::IllegalArgumentException(
936                 C2U("trying to insert into a nesting text content, but end "
937                     "of text range not inside text content"),
938                     0, 0);
939         }
940         else if (nEndPos == nMetaEnd)
941         {
942             bForceExpandHints = true;
943         }
944     }
945     return bForceExpandHints;
946 }
947 
getUnoTunnelId()948 const uno::Sequence< sal_Int8 > & SwXMeta::getUnoTunnelId()
949 {
950     static uno::Sequence< sal_Int8 > aSeq( ::CreateUnoTunnelId() );
951     return aSeq;
952 }
953 
954 // XUnoTunnel
955 sal_Int64 SAL_CALL
getSomething(const uno::Sequence<sal_Int8> & i_rId)956 SwXMeta::getSomething( const uno::Sequence< sal_Int8 > & i_rId )
957 throw (uno::RuntimeException)
958 {
959     return ::sw::UnoTunnelImpl<SwXMeta>(i_rId, this);
960 }
961 
962 // XServiceInfo
963 ::rtl::OUString SAL_CALL
getImplementationName()964 SwXMeta::getImplementationName() throw (uno::RuntimeException)
965 {
966     return C2U("SwXMeta");
967 }
968 
969 static char const*const g_ServicesMeta[] =
970 {
971     "com.sun.star.text.TextContent",
972     "com.sun.star.text.InContentMetadata",
973 };
974 static const size_t g_nServicesMeta(
975     sizeof(g_ServicesMeta)/sizeof(g_ServicesMeta[0]));
976 
977 sal_Bool SAL_CALL
supportsService(const::rtl::OUString & rServiceName)978 SwXMeta::supportsService(const ::rtl::OUString& rServiceName)
979 throw (uno::RuntimeException)
980 {
981     return ::sw::SupportsServiceImpl(
982             g_nServicesMeta, g_ServicesMeta, rServiceName);
983 }
984 
985 uno::Sequence< ::rtl::OUString > SAL_CALL
getSupportedServiceNames()986 SwXMeta::getSupportedServiceNames() throw (uno::RuntimeException)
987 {
988     return ::sw::GetSupportedServiceNamesImpl(g_nServicesMeta, g_ServicesMeta);
989 }
990 
991 
992 // XComponent
993 void SAL_CALL
addEventListener(uno::Reference<lang::XEventListener> const & xListener)994 SwXMeta::addEventListener(
995         uno::Reference< lang::XEventListener> const & xListener )
996 throw (uno::RuntimeException)
997 {
998     vos::OGuard g(Application::GetSolarMutex());
999 
1000     m_pImpl->m_ListenerContainer.AddListener(xListener);
1001     if (m_pImpl->m_bIsDisposed)
1002     {
1003         m_pImpl->m_ListenerContainer.Disposing();
1004     }
1005 }
1006 
1007 void SAL_CALL
removeEventListener(uno::Reference<lang::XEventListener> const & xListener)1008 SwXMeta::removeEventListener(
1009         uno::Reference< lang::XEventListener> const & xListener )
1010 throw (uno::RuntimeException)
1011 {
1012     vos::OGuard g(Application::GetSolarMutex());
1013 
1014     if (!m_pImpl->m_bIsDisposed)
1015     {
1016         m_pImpl->m_ListenerContainer.RemoveListener(xListener);
1017     }
1018 }
1019 
1020 void SAL_CALL
dispose()1021 SwXMeta::dispose() throw (uno::RuntimeException)
1022 {
1023     vos::OGuard g(Application::GetSolarMutex());
1024 
1025     if (m_pImpl->m_bIsDescriptor)
1026     {
1027         m_pImpl->m_pTextPortions.reset();
1028         m_pImpl->m_ListenerContainer.Disposing();
1029         m_pImpl->m_bIsDisposed = true;
1030         m_pImpl->m_Text.Invalidate();
1031     }
1032     else if (!m_pImpl->m_bIsDisposed)
1033     {
1034         SwTxtNode * pTxtNode;
1035         xub_StrLen nMetaStart;
1036         xub_StrLen nMetaEnd;
1037         const bool bSuccess(SetContentRange(pTxtNode, nMetaStart, nMetaEnd));
1038         ASSERT(bSuccess, "no pam?");
1039         if (bSuccess)
1040         {
1041             // -1 because of CH_TXTATR
1042             SwPaM aPam( *pTxtNode, nMetaStart - 1, *pTxtNode, nMetaEnd );
1043             SwDoc * const pDoc( pTxtNode->GetDoc() );
1044             pDoc->DeleteAndJoin( aPam );
1045 
1046             // removal should call Modify and do the dispose
1047             OSL_ENSURE(m_pImpl->m_bIsDisposed, "zombie meta");
1048         }
1049     }
1050 }
1051 
1052 
1053 void SAL_CALL
AttachImpl(const uno::Reference<text::XTextRange> & i_xTextRange,const sal_uInt16 i_nWhich)1054 SwXMeta::AttachImpl(const uno::Reference< text::XTextRange > & i_xTextRange,
1055         const sal_uInt16 i_nWhich)
1056 throw (lang::IllegalArgumentException, uno::RuntimeException)
1057 {
1058     vos::OGuard g(Application::GetSolarMutex());
1059 
1060     if (m_pImpl->m_bIsDisposed)
1061     {
1062         throw lang::DisposedException();
1063     }
1064     if (!m_pImpl->m_bIsDescriptor)
1065     {
1066         throw uno::RuntimeException(
1067             C2S("SwXMeta::attach(): already attached"),
1068                 static_cast< ::cppu::OWeakObject* >(this));
1069     }
1070 
1071     uno::Reference<lang::XUnoTunnel> xRangeTunnel(i_xTextRange, uno::UNO_QUERY);
1072     if (!xRangeTunnel.is())
1073     {
1074         throw lang::IllegalArgumentException(
1075             C2S("SwXMeta::attach(): argument is no XUnoTunnel"),
1076                 static_cast< ::cppu::OWeakObject* >(this), 0);
1077     }
1078     SwXTextRange *const pRange(
1079             ::sw::UnoTunnelGetImplementation<SwXTextRange>(xRangeTunnel));
1080     OTextCursorHelper *const pCursor( (pRange) ? 0 :
1081             ::sw::UnoTunnelGetImplementation<OTextCursorHelper>(xRangeTunnel));
1082     if (!pRange && !pCursor)
1083     {
1084         throw lang::IllegalArgumentException(
1085             C2S("SwXMeta::attach(): argument not supported type"),
1086                 static_cast< ::cppu::OWeakObject* >(this), 0);
1087     }
1088 
1089     SwDoc * const pDoc(
1090             pRange ? pRange->GetDoc() : pCursor ? pCursor->GetDoc() : 0 );
1091     if (!pDoc)
1092     {
1093         throw lang::IllegalArgumentException(
1094             C2S("SwXMeta::attach(): argument has no SwDoc"),
1095                 static_cast< ::cppu::OWeakObject* >(this), 0);
1096     }
1097 
1098     SwUnoInternalPaM aPam(*pDoc);
1099     ::sw::XTextRangeToSwPaM(aPam, i_xTextRange);
1100 
1101     UnoActionContext aContext(pDoc);
1102 
1103     SwXTextCursor const*const pTextCursor(
1104             dynamic_cast<SwXTextCursor*>(pCursor));
1105     const bool bForceExpandHints((pTextCursor)
1106             ? pTextCursor->IsAtEndOfMeta() : false);
1107     const SetAttrMode nInsertFlags( (bForceExpandHints)
1108         ?   ( nsSetAttrMode::SETATTR_FORCEHINTEXPAND
1109             | nsSetAttrMode::SETATTR_DONTEXPAND)
1110         : nsSetAttrMode::SETATTR_DONTEXPAND );
1111 
1112     const ::boost::shared_ptr< ::sw::Meta> pMeta( (RES_TXTATR_META == i_nWhich)
1113         ? ::boost::shared_ptr< ::sw::Meta>( new ::sw::Meta() )
1114         : ::boost::shared_ptr< ::sw::Meta>(
1115             pDoc->GetMetaFieldManager().makeMetaField()) );
1116     SwFmtMeta meta(pMeta, i_nWhich); // this is cloned by Insert!
1117     const bool bSuccess( pDoc->InsertPoolItem( aPam, meta, nInsertFlags ) );
1118     SwTxtAttr * const pTxtAttr( pMeta->GetTxtAttr() );
1119     if (!bSuccess)
1120     {
1121         throw lang::IllegalArgumentException(
1122             C2S("SwXMeta::attach(): cannot create meta: range invalid?"),
1123                 static_cast< ::cppu::OWeakObject* >(this), 1);
1124     }
1125     if (!pTxtAttr)
1126     {
1127         ASSERT(false, "meta inserted, but has no text attribute?");
1128         throw uno::RuntimeException(
1129             C2S("SwXMeta::attach(): cannot create meta"),
1130                 static_cast< ::cppu::OWeakObject* >(this));
1131     }
1132 
1133     pMeta->Add(m_pImpl.get());
1134     pMeta->SetXMeta(uno::Reference<rdf::XMetadatable>(this));
1135 
1136     m_pImpl->m_xParentText = ::sw::CreateParentXText(*pDoc, *aPam.GetPoint());
1137 
1138     m_pImpl->m_bIsDescriptor = false;
1139 }
1140 
1141 // XTextContent
1142 void SAL_CALL
attach(const uno::Reference<text::XTextRange> & i_xTextRange)1143 SwXMeta::attach(const uno::Reference< text::XTextRange > & i_xTextRange)
1144 throw (lang::IllegalArgumentException, uno::RuntimeException)
1145 {
1146     return SwXMeta::AttachImpl(i_xTextRange, RES_TXTATR_META);
1147 }
1148 
1149 uno::Reference< text::XTextRange > SAL_CALL
getAnchor()1150 SwXMeta::getAnchor() throw (uno::RuntimeException)
1151 {
1152     vos::OGuard g(Application::GetSolarMutex());
1153 
1154     if (m_pImpl->m_bIsDisposed)
1155     {
1156         throw lang::DisposedException();
1157     }
1158     if (m_pImpl->m_bIsDescriptor)
1159     {
1160         throw uno::RuntimeException(
1161                 C2S("SwXMeta::getAnchor(): not inserted"),
1162                 static_cast< ::cppu::OWeakObject* >(this));
1163     }
1164 
1165     SwTxtNode * pTxtNode;
1166     xub_StrLen nMetaStart;
1167     xub_StrLen nMetaEnd;
1168     const bool bSuccess(SetContentRange(pTxtNode, nMetaStart, nMetaEnd));
1169     ASSERT(bSuccess, "no pam?");
1170     if (!bSuccess)
1171     {
1172         throw lang::DisposedException(
1173                 C2S("SwXMeta::getAnchor(): not attached"),
1174                 static_cast< ::cppu::OWeakObject* >(this));
1175     }
1176 
1177     const SwPosition start(*pTxtNode, nMetaStart - 1); // -1 due to CH_TXTATR
1178     const SwPosition end(*pTxtNode, nMetaEnd);
1179     return SwXTextRange::CreateXTextRange(*pTxtNode->GetDoc(), start, &end);
1180 }
1181 
1182 // XTextRange
1183 uno::Reference< text::XText > SAL_CALL
getText()1184 SwXMeta::getText() throw (uno::RuntimeException)
1185 {
1186     vos::OGuard g(Application::GetSolarMutex());
1187     return this;
1188 }
1189 
1190 uno::Reference< text::XTextRange > SAL_CALL
getStart()1191 SwXMeta::getStart() throw (uno::RuntimeException)
1192 {
1193     vos::OGuard g(Application::GetSolarMutex());
1194     return m_pImpl->m_Text.getStart();
1195 }
1196 
1197 uno::Reference< text::XTextRange > SAL_CALL
getEnd()1198 SwXMeta::getEnd() throw (uno::RuntimeException)
1199 {
1200     vos::OGuard g(Application::GetSolarMutex());
1201     return m_pImpl->m_Text.getEnd();
1202 }
1203 
1204 rtl::OUString SAL_CALL
getString()1205 SwXMeta::getString() throw (uno::RuntimeException)
1206 {
1207     vos::OGuard g(Application::GetSolarMutex());
1208     return m_pImpl->m_Text.getString();
1209 }
1210 
1211 void SAL_CALL
setString(const rtl::OUString & rString)1212 SwXMeta::setString(const rtl::OUString& rString) throw (uno::RuntimeException)
1213 {
1214     vos::OGuard g(Application::GetSolarMutex());
1215     return m_pImpl->m_Text.setString(rString);
1216 }
1217 
1218 // XSimpleText
1219 uno::Reference< text::XTextCursor > SAL_CALL
createTextCursor()1220 SwXMeta::createTextCursor() throw (uno::RuntimeException)
1221 {
1222     vos::OGuard g(Application::GetSolarMutex());
1223     return m_pImpl->m_Text.createTextCursor();
1224 }
1225 
1226 uno::Reference< text::XTextCursor > SAL_CALL
createTextCursorByRange(const uno::Reference<text::XTextRange> & xTextPosition)1227 SwXMeta::createTextCursorByRange(
1228         const uno::Reference<text::XTextRange> & xTextPosition)
1229     throw (uno::RuntimeException)
1230 {
1231     vos::OGuard g(Application::GetSolarMutex());
1232     return m_pImpl->m_Text.createTextCursorByRange(xTextPosition);
1233 }
1234 
1235 void SAL_CALL
insertString(const uno::Reference<text::XTextRange> & xRange,const rtl::OUString & rString,sal_Bool bAbsorb)1236 SwXMeta::insertString(const uno::Reference<text::XTextRange> & xRange,
1237         const rtl::OUString& rString, sal_Bool bAbsorb)
1238 throw (uno::RuntimeException)
1239 {
1240     vos::OGuard g(Application::GetSolarMutex());
1241     return m_pImpl->m_Text.insertString(xRange, rString, bAbsorb);
1242 }
1243 
1244 void SAL_CALL
insertControlCharacter(const uno::Reference<text::XTextRange> & xRange,sal_Int16 nControlCharacter,sal_Bool bAbsorb)1245 SwXMeta::insertControlCharacter(const uno::Reference<text::XTextRange> & xRange,
1246         sal_Int16 nControlCharacter, sal_Bool bAbsorb)
1247 throw (lang::IllegalArgumentException, uno::RuntimeException)
1248 {
1249     vos::OGuard g(Application::GetSolarMutex());
1250     return m_pImpl->m_Text.insertControlCharacter(xRange, nControlCharacter,
1251                 bAbsorb);
1252 }
1253 
1254 // XText
1255 void SAL_CALL
insertTextContent(const uno::Reference<text::XTextRange> & xRange,const uno::Reference<text::XTextContent> & xContent,sal_Bool bAbsorb)1256 SwXMeta::insertTextContent( const uno::Reference<text::XTextRange> & xRange,
1257         const uno::Reference<text::XTextContent> & xContent, sal_Bool bAbsorb)
1258 throw (lang::IllegalArgumentException, uno::RuntimeException)
1259 {
1260     vos::OGuard g(Application::GetSolarMutex());
1261     return m_pImpl->m_Text.insertTextContent(xRange, xContent, bAbsorb);
1262 }
1263 
1264 void SAL_CALL
removeTextContent(const uno::Reference<text::XTextContent> & xContent)1265 SwXMeta::removeTextContent(
1266         const uno::Reference< text::XTextContent > & xContent)
1267     throw (container::NoSuchElementException, uno::RuntimeException)
1268 {
1269     vos::OGuard g(Application::GetSolarMutex());
1270     return m_pImpl->m_Text.removeTextContent(xContent);
1271 }
1272 
1273 // XChild
1274 uno::Reference< uno::XInterface > SAL_CALL
getParent()1275 SwXMeta::getParent() throw (uno::RuntimeException)
1276 {
1277     vos::OGuard g(Application::GetSolarMutex());
1278     SwTxtNode * pTxtNode;
1279     xub_StrLen nMetaStart;
1280     xub_StrLen nMetaEnd;
1281     bool const bSuccess( SetContentRange(pTxtNode, nMetaStart, nMetaEnd) );
1282     OSL_ENSURE(bSuccess, "no pam?");
1283     if (!bSuccess) { throw lang::DisposedException(); }
1284     // in order to prevent getting this meta, subtract 1 from nMetaStart;
1285     // so we get the index of the dummy character, and we exclude it
1286     // by calling GetTxtAttrAt(_, _, PARENT) in GetNestedTextContent
1287     uno::Reference<text::XTextContent> const xRet(
1288         SwUnoCursorHelper::GetNestedTextContent(*pTxtNode, nMetaStart - 1,
1289             true) );
1290     return xRet;
1291 }
1292 
1293 void SAL_CALL
setParent(uno::Reference<uno::XInterface> const &)1294 SwXMeta::setParent(uno::Reference< uno::XInterface > const& /*xParent*/)
1295     throw (uno::RuntimeException, lang::NoSupportException)
1296 {
1297     throw lang::NoSupportException(C2S("setting parent not supported"), *this);
1298 }
1299 
1300 // XElementAccess
1301 uno::Type SAL_CALL
getElementType()1302 SwXMeta::getElementType() throw (uno::RuntimeException)
1303 {
1304     return text::XTextRange::static_type();
1305 }
1306 
1307 sal_Bool SAL_CALL
hasElements()1308 SwXMeta::hasElements() throw (uno::RuntimeException)
1309 {
1310     vos::OGuard g(Application::GetSolarMutex());
1311 
1312     return m_pImpl->GetRegisteredIn() ? sal_True : sal_False;
1313 }
1314 
1315 // XEnumerationAccess
1316 uno::Reference< container::XEnumeration > SAL_CALL
createEnumeration()1317 SwXMeta::createEnumeration() throw (uno::RuntimeException)
1318 {
1319     vos::OGuard g(Application::GetSolarMutex());
1320 
1321     if (m_pImpl->m_bIsDisposed)
1322     {
1323         throw lang::DisposedException();
1324     }
1325     if (m_pImpl->m_bIsDescriptor)
1326     {
1327         throw uno::RuntimeException(
1328                 C2S("createEnumeration(): not inserted"),
1329                 static_cast< ::cppu::OWeakObject* >(this));
1330     }
1331 
1332     SwTxtNode * pTxtNode;
1333     xub_StrLen nMetaStart;
1334     xub_StrLen nMetaEnd;
1335     const bool bSuccess(SetContentRange(pTxtNode, nMetaStart, nMetaEnd));
1336     ASSERT(bSuccess, "no pam?");
1337     if (!bSuccess)
1338         throw lang::DisposedException();
1339 
1340     SwPaM aPam(*pTxtNode, nMetaStart);
1341 
1342     if (!m_pImpl->m_pTextPortions.get())
1343     {
1344         return new SwXTextPortionEnumeration(
1345                     aPam, GetParentText(), nMetaStart, nMetaEnd);
1346     }
1347     else // cached!
1348     {
1349         return new SwXTextPortionEnumeration(aPam, *m_pImpl->m_pTextPortions);
1350     }
1351 }
1352 
1353 
1354 // MetadatableMixin
GetCoreObject()1355 ::sfx2::Metadatable* SwXMeta::GetCoreObject()
1356 {
1357     return const_cast< ::sw::Meta * >(m_pImpl->GetMeta());
1358 }
1359 
GetModel()1360 uno::Reference<frame::XModel> SwXMeta::GetModel()
1361 {
1362     ::sw::Meta const * const pMeta( m_pImpl->GetMeta() );
1363     if (pMeta)
1364     {
1365         SwTxtNode const * const pTxtNode( pMeta->GetTxtNode() );
1366         if (pTxtNode)
1367         {
1368             SwDocShell const * const pShell(pTxtNode->GetDoc()->GetDocShell());
1369             return (pShell) ? pShell->GetModel() : 0;
1370         }
1371     }
1372     return 0;
1373 }
1374 
1375 
1376 /******************************************************************
1377  * SwXMetaField
1378  ******************************************************************/
1379 
GetMetaField() const1380 inline const ::sw::MetaField * SwXMeta::Impl::GetMetaField() const
1381 {
1382     return static_cast< const ::sw::MetaField * >(GetRegisteredIn());
1383 }
1384 
SwXMetaField(SwDoc * const pDoc,::sw::Meta * const pMeta,uno::Reference<text::XText> const & xParentText,TextRangeList_t const * const pPortions)1385 SwXMetaField::SwXMetaField(SwDoc *const pDoc, ::sw::Meta *const pMeta,
1386         uno::Reference<text::XText> const& xParentText,
1387         TextRangeList_t const*const pPortions)
1388     : SwXMetaField_Base(pDoc, pMeta, xParentText, pPortions)
1389 {
1390     ASSERT(pMeta && dynamic_cast< ::sw::MetaField* >(pMeta),
1391         "SwXMetaField created for wrong hint!");
1392 }
1393 
SwXMetaField(SwDoc * const pDoc)1394 SwXMetaField::SwXMetaField(SwDoc *const pDoc)
1395     :  SwXMetaField_Base(pDoc)
1396 {
1397 }
1398 
~SwXMetaField()1399 SwXMetaField::~SwXMetaField()
1400 {
1401 }
1402 
1403 // XServiceInfo
1404 ::rtl::OUString SAL_CALL
getImplementationName()1405 SwXMetaField::getImplementationName() throw (uno::RuntimeException)
1406 {
1407     return C2U("SwXMetaField");
1408 }
1409 
1410 static char const*const g_ServicesMetaField[] =
1411 {
1412     "com.sun.star.text.TextContent",
1413     "com.sun.star.text.TextField",
1414     "com.sun.star.text.textfield.MetadataField",
1415 };
1416 static const size_t g_nServicesMetaField(
1417     sizeof(g_ServicesMetaField)/sizeof(g_ServicesMetaField[0]));
1418 
1419 sal_Bool SAL_CALL
supportsService(const::rtl::OUString & rServiceName)1420 SwXMetaField::supportsService(const ::rtl::OUString& rServiceName)
1421 throw (uno::RuntimeException)
1422 {
1423     return ::sw::SupportsServiceImpl(
1424             g_nServicesMetaField, g_ServicesMetaField, rServiceName);
1425 }
1426 
1427 uno::Sequence< ::rtl::OUString > SAL_CALL
getSupportedServiceNames()1428 SwXMetaField::getSupportedServiceNames() throw (uno::RuntimeException)
1429 {
1430     return ::sw::GetSupportedServiceNamesImpl(
1431             g_nServicesMetaField, g_ServicesMetaField);
1432 }
1433 
1434 // XComponent
1435 void SAL_CALL
addEventListener(uno::Reference<lang::XEventListener> const & xListener)1436 SwXMetaField::addEventListener(
1437         uno::Reference< lang::XEventListener> const & xListener )
1438 throw (uno::RuntimeException)
1439 {
1440     return SwXMeta::addEventListener(xListener);
1441 }
1442 
1443 void SAL_CALL
removeEventListener(uno::Reference<lang::XEventListener> const & xListener)1444 SwXMetaField::removeEventListener(
1445         uno::Reference< lang::XEventListener> const & xListener )
1446 throw (uno::RuntimeException)
1447 {
1448     return SwXMeta::removeEventListener(xListener);
1449 }
1450 
1451 void SAL_CALL
dispose()1452 SwXMetaField::dispose() throw (uno::RuntimeException)
1453 {
1454     return SwXMeta::dispose();
1455 }
1456 
1457 // XTextContent
1458 void SAL_CALL
attach(const uno::Reference<text::XTextRange> & i_xTextRange)1459 SwXMetaField::attach(const uno::Reference< text::XTextRange > & i_xTextRange)
1460 throw (lang::IllegalArgumentException, uno::RuntimeException)
1461 {
1462     return SwXMeta::AttachImpl(i_xTextRange, RES_TXTATR_METAFIELD);
1463 }
1464 
1465 uno::Reference< text::XTextRange > SAL_CALL
getAnchor()1466 SwXMetaField::getAnchor() throw (uno::RuntimeException)
1467 {
1468     return SwXMeta::getAnchor();
1469 }
1470 
1471 // XPropertySet
1472 uno::Reference< beans::XPropertySetInfo > SAL_CALL
getPropertySetInfo()1473 SwXMetaField::getPropertySetInfo() throw (uno::RuntimeException)
1474 {
1475     vos::OGuard g(Application::GetSolarMutex());
1476 
1477     static uno::Reference< beans::XPropertySetInfo > xRef(
1478         aSwMapProvider.GetPropertySet(PROPERTY_MAP_METAFIELD)
1479             ->getPropertySetInfo() );
1480     return xRef;
1481 }
1482 
1483 void SAL_CALL
setPropertyValue(const::rtl::OUString & rPropertyName,const uno::Any & rValue)1484 SwXMetaField::setPropertyValue(
1485         const ::rtl::OUString& rPropertyName, const uno::Any& rValue)
1486 throw (beans::UnknownPropertyException, beans::PropertyVetoException,
1487     lang::IllegalArgumentException, lang::WrappedTargetException,
1488     uno::RuntimeException)
1489 {
1490     vos::OGuard g(Application::GetSolarMutex());
1491 
1492     ::sw::MetaField * const pMeta(
1493             const_cast< ::sw::MetaField * >(m_pImpl->GetMetaField()) );
1494     if (!pMeta)
1495         throw lang::DisposedException();
1496 
1497     if (rPropertyName.equalsAscii("NumberFormat"))
1498     {
1499         sal_Int32 nNumberFormat(0);
1500         if (rValue >>= nNumberFormat)
1501         {
1502             pMeta->SetNumberFormat(static_cast<sal_uInt32>(nNumberFormat));
1503         }
1504     }
1505     else if (rPropertyName.equalsAscii("IsFixedLanguage"))
1506     {
1507         bool b(false);
1508         if (rValue >>= b)
1509         {
1510             pMeta->SetIsFixedLanguage(b);
1511         }
1512     }
1513     else
1514     {
1515         throw beans::UnknownPropertyException();
1516     }
1517 }
1518 
1519 uno::Any SAL_CALL
getPropertyValue(const::rtl::OUString & rPropertyName)1520 SwXMetaField::getPropertyValue(const ::rtl::OUString& rPropertyName)
1521 throw (beans::UnknownPropertyException, lang::WrappedTargetException,
1522     uno::RuntimeException)
1523 {
1524     vos::OGuard g(Application::GetSolarMutex());
1525 
1526     ::sw::MetaField const * const pMeta( m_pImpl->GetMetaField() );
1527     if (!pMeta)
1528         throw lang::DisposedException();
1529 
1530     uno::Any any;
1531 
1532     if (rPropertyName.equalsAscii("NumberFormat"))
1533     {
1534         const ::rtl::OUString text( getPresentation(sal_False) );
1535         any <<= static_cast<sal_Int32>(pMeta->GetNumberFormat(text));
1536     }
1537     else if (rPropertyName.equalsAscii("IsFixedLanguage"))
1538     {
1539         any <<= pMeta->IsFixedLanguage();
1540     }
1541     else
1542     {
1543         throw beans::UnknownPropertyException();
1544     }
1545 
1546     return any;
1547 }
1548 
1549 void SAL_CALL
addPropertyChangeListener(const::rtl::OUString &,const uno::Reference<beans::XPropertyChangeListener> &)1550 SwXMetaField::addPropertyChangeListener(
1551         const ::rtl::OUString& /*rPropertyName*/,
1552         const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
1553 throw (beans::UnknownPropertyException, lang::WrappedTargetException,
1554     uno::RuntimeException)
1555 {
1556     OSL_ENSURE(false,
1557         "SwXMetaField::addPropertyChangeListener(): not implemented");
1558 }
1559 
1560 void SAL_CALL
removePropertyChangeListener(const::rtl::OUString &,const uno::Reference<beans::XPropertyChangeListener> &)1561 SwXMetaField::removePropertyChangeListener(
1562         const ::rtl::OUString& /*rPropertyName*/,
1563         const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
1564 throw (beans::UnknownPropertyException, lang::WrappedTargetException,
1565     uno::RuntimeException)
1566 {
1567     OSL_ENSURE(false,
1568         "SwXMetaField::removePropertyChangeListener(): not implemented");
1569 }
1570 
1571 void SAL_CALL
addVetoableChangeListener(const::rtl::OUString &,const uno::Reference<beans::XVetoableChangeListener> &)1572 SwXMetaField::addVetoableChangeListener(
1573         const ::rtl::OUString& /*rPropertyName*/,
1574         const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
1575 throw (beans::UnknownPropertyException, lang::WrappedTargetException,
1576     uno::RuntimeException)
1577 {
1578     OSL_ENSURE(false,
1579         "SwXMetaField::addVetoableChangeListener(): not implemented");
1580 }
1581 
1582 void SAL_CALL
removeVetoableChangeListener(const::rtl::OUString &,const uno::Reference<beans::XVetoableChangeListener> &)1583 SwXMetaField::removeVetoableChangeListener(
1584         const ::rtl::OUString& /*rPropertyName*/,
1585         const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
1586 throw (beans::UnknownPropertyException, lang::WrappedTargetException,
1587         uno::RuntimeException)
1588 {
1589     OSL_ENSURE(false,
1590         "SwXMetaField::removeVetoableChangeListener(): not implemented");
1591 }
1592 
1593 #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
1594 #include <com/sun/star/rdf/Statement.hpp>
1595 #include <com/sun/star/rdf/URI.hpp>
1596 #include <com/sun/star/rdf/URIs.hpp>
1597 #include <com/sun/star/rdf/XLiteral.hpp>
1598 #include <com/sun/star/rdf/XRepositorySupplier.hpp>
1599 #include <comphelper/processfactory.hxx>
1600 
1601 static uno::Reference<rdf::XURI> const&
lcl_getURI(const bool bPrefix)1602 lcl_getURI(const bool bPrefix)
1603 {
1604     static uno::Reference< uno::XComponentContext > xContext(
1605         ::comphelper::getProcessComponentContext());
1606     static uno::Reference< rdf::XURI > xOdfPrefix(
1607         rdf::URI::createKnown(xContext, rdf::URIs::ODF_PREFIX),
1608         uno::UNO_SET_THROW);
1609     static uno::Reference< rdf::XURI > xOdfSuffix(
1610         rdf::URI::createKnown(xContext, rdf::URIs::ODF_SUFFIX),
1611         uno::UNO_SET_THROW);
1612     return (bPrefix) ? xOdfPrefix : xOdfSuffix;
1613 }
1614 
1615 static ::rtl::OUString
lcl_getPrefixOrSuffix(uno::Reference<rdf::XRepository> const & xRepository,uno::Reference<rdf::XResource> const & xMetaField,uno::Reference<rdf::XURI> const & xPredicate)1616 lcl_getPrefixOrSuffix(
1617     uno::Reference<rdf::XRepository> const & xRepository,
1618     uno::Reference<rdf::XResource> const & xMetaField,
1619     uno::Reference<rdf::XURI> const & xPredicate)
1620 {
1621     const uno::Reference<container::XEnumeration> xEnum(
1622         xRepository->getStatements(xMetaField, xPredicate, 0),
1623         uno::UNO_SET_THROW);
1624     while (xEnum->hasMoreElements()) {
1625         rdf::Statement stmt;
1626         if (!(xEnum->nextElement() >>= stmt)) {
1627             throw uno::RuntimeException();
1628         }
1629         const uno::Reference<rdf::XLiteral> xObject(stmt.Object,
1630             uno::UNO_QUERY);
1631         if (!xObject.is()) continue;
1632         if (xEnum->hasMoreElements()) {
1633             OSL_TRACE("ignoring other odf:Prefix/odf:Suffix statements");
1634         }
1635         return xObject->getValue();
1636     }
1637     return ::rtl::OUString();
1638 }
1639 
1640 void
getPrefixAndSuffix(const uno::Reference<frame::XModel> & xModel,const uno::Reference<rdf::XMetadatable> & xMetaField,::rtl::OUString * const o_pPrefix,::rtl::OUString * const o_pSuffix)1641 getPrefixAndSuffix(
1642         const uno::Reference<frame::XModel>& xModel,
1643         const uno::Reference<rdf::XMetadatable>& xMetaField,
1644         ::rtl::OUString *const o_pPrefix, ::rtl::OUString *const o_pSuffix)
1645 {
1646     try {
1647         const uno::Reference<rdf::XRepositorySupplier> xRS(
1648                 xModel, uno::UNO_QUERY_THROW);
1649         const uno::Reference<rdf::XRepository> xRepo(
1650                 xRS->getRDFRepository(), uno::UNO_SET_THROW);
1651         const uno::Reference<rdf::XResource> xMeta(
1652                 xMetaField, uno::UNO_QUERY_THROW);
1653         if (o_pPrefix)
1654         {
1655             *o_pPrefix = lcl_getPrefixOrSuffix(xRepo, xMeta, lcl_getURI(true));
1656         }
1657         if (o_pSuffix)
1658         {
1659             *o_pSuffix = lcl_getPrefixOrSuffix(xRepo, xMeta, lcl_getURI(false));
1660         }
1661     } catch (uno::RuntimeException &) {
1662         throw;
1663     } catch (uno::Exception & e) {
1664         throw lang::WrappedTargetRuntimeException(
1665             ::rtl::OUString::createFromAscii("getPrefixAndSuffix: exception"),
1666             0, uno::makeAny(e));
1667     }
1668 }
1669 
1670 // XTextField
1671 ::rtl::OUString SAL_CALL
getPresentation(sal_Bool bShowCommand)1672 SwXMetaField::getPresentation(sal_Bool bShowCommand)
1673 throw (uno::RuntimeException)
1674 {
1675     vos::OGuard g(Application::GetSolarMutex());
1676 
1677     if (bShowCommand)
1678     {
1679 //FIXME ?
1680         return ::rtl::OUString();
1681     }
1682     else
1683     {
1684         // getString should check if this is invalid
1685         const ::rtl::OUString content( this->getString() );
1686         ::rtl::OUString prefix;
1687         ::rtl::OUString suffix;
1688         getPrefixAndSuffix(GetModel(), this, &prefix, &suffix);
1689         return prefix + content + suffix;
1690     }
1691 }
1692 
1693