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

Generated by: LCOV version 1.10