LCOV - code coverage report
Current view: top level - sw/source/core/unocore - unorefmk.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 467 579 80.7 %
Date: 2014-04-11 Functions: 84 113 74.3 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10