blob: 8c02d9ada2591a9ddc5ff8fb11024df72b36499e [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sw.hxx"
#include <vos/mutex.hxx>
#include <vcl/svapp.hxx>
#include <unomid.h>
#include <unotextrange.hxx>
#include <unorefmark.hxx>
#include <unotextcursor.hxx>
#include <unomap.hxx>
#include <unocrsr.hxx>
#include <unoevtlstnr.hxx>
#include <unocrsrhelper.hxx>
#include <doc.hxx>
#include <ndtxt.hxx>
#include <fmtrfmrk.hxx>
#include <txtrfmrk.hxx>
#include <hints.hxx>
using namespace ::com::sun::star;
using ::rtl::OUString;
/******************************************************************
* SwXReferenceMark
******************************************************************/
class SwXReferenceMark::Impl
: public SwClient
{
public:
SwEventListenerContainer m_ListenerContainer;
bool m_bIsDescriptor;
SwDoc * m_pDoc;
const SwFmtRefMark * m_pMarkFmt;
::rtl::OUString m_sMarkName;
Impl( SwXReferenceMark & rThis,
SwDoc *const pDoc, SwFmtRefMark const*const pRefMark)
: SwClient((pDoc) ? pDoc->GetUnoCallBack() : 0)
, m_ListenerContainer(static_cast< ::cppu::OWeakObject* >(&rThis))
// #i111177# unxsols4 (Sun C++ 5.9 SunOS_sparc) may generate wrong code
, m_bIsDescriptor((0 == pRefMark) ? true : false)
, m_pDoc(pDoc)
, m_pMarkFmt(pRefMark)
{
if (pRefMark)
{
m_sMarkName = pRefMark->GetRefName();
}
}
bool IsValid() const { return 0 != GetRegisteredIn(); }
void InsertRefMark( SwPaM & rPam, SwXTextCursor const*const pCursor );
void Invalidate();
protected:
// SwClient
virtual void Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew);
};
/* -----------------------------07.01.00 12:51--------------------------------
---------------------------------------------------------------------------*/
void SwXReferenceMark::Impl::Invalidate()
{
if (IsValid())
{
const_cast<SwModify*>(GetRegisteredIn())->Remove(this);
}
m_ListenerContainer.Disposing();
m_pDoc = 0;
m_pMarkFmt = 0;
}
/*-- 11.12.98 10:28:37---------------------------------------------------
-----------------------------------------------------------------------*/
void SwXReferenceMark::Impl::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew)
{
ClientModify(this, pOld, pNew);
if (!GetRegisteredIn()) // removed => dispose
{
Invalidate();
}
else if (pOld)
{
switch (pOld->Which())
{
case RES_REFMARK_DELETED:
if (static_cast<const void*>(m_pMarkFmt) ==
static_cast<const SwPtrMsgPoolItem *>(pOld)->pObject)
{
Invalidate();
}
break;
}
}
}
/*-- 11.12.98 10:28:32---------------------------------------------------
-----------------------------------------------------------------------*/
SwXReferenceMark::SwXReferenceMark(
SwDoc *const pDoc, SwFmtRefMark const*const pRefMark)
: m_pImpl( new SwXReferenceMark::Impl(*this, pDoc, pRefMark) )
{
}
/*-- 11.12.98 10:28:33---------------------------------------------------
-----------------------------------------------------------------------*/
SwXReferenceMark::~SwXReferenceMark()
{
}
SwXReferenceMark *
SwXReferenceMark::GetReferenceMark(
SwModify const& /*rUnoCB*/, SwFmtRefMark const& /*rMarkFmt*/)
{
// #i105557#: do not iterate over the registered clients: race condition
// to do this properly requires the SwXReferenceMark to register at the
// SwFmtRefMark directly, not at the unocallback
return 0;
}
SwXReferenceMark *
SwXReferenceMark::CreateXReferenceMark(
SwDoc & rDoc, SwFmtRefMark const& rMarkFmt)
{
SwXReferenceMark *const pXMark(
GetReferenceMark(*rDoc.GetUnoCallBack(), rMarkFmt) );
return (pXMark)
? pXMark
: new SwXReferenceMark(&rDoc, &rMarkFmt);
}
/* -----------------------------13.03.00 12:15--------------------------------
---------------------------------------------------------------------------*/
const uno::Sequence< sal_Int8 > & SwXReferenceMark::getUnoTunnelId()
{
static uno::Sequence< sal_Int8 > aSeq = ::CreateUnoTunnelId();
return aSeq;
}
/* -----------------------------10.03.00 18:04--------------------------------
---------------------------------------------------------------------------*/
sal_Int64 SAL_CALL
SwXReferenceMark::getSomething(const uno::Sequence< sal_Int8 >& rId)
throw (uno::RuntimeException)
{
return ::sw::UnoTunnelImpl<SwXReferenceMark>(rId, this);
}
/* -----------------------------06.04.00 16:41--------------------------------
---------------------------------------------------------------------------*/
OUString SAL_CALL SwXReferenceMark::getImplementationName()
throw (uno::RuntimeException)
{
return C2U("SwXReferenceMark");
}
/* -----------------------------06.04.00 16:41--------------------------------
---------------------------------------------------------------------------*/
static char const*const g_ServicesReferenceMark[] =
{
"com.sun.star.text.TextContent",
"com.sun.star.text.ReferenceMark",
};
static const size_t g_nServicesReferenceMark(
sizeof(g_ServicesReferenceMark)/sizeof(g_ServicesReferenceMark[0]));
sal_Bool SAL_CALL
SwXReferenceMark::supportsService(const OUString& rServiceName)
throw (uno::RuntimeException)
{
return ::sw::SupportsServiceImpl(
g_nServicesReferenceMark, g_ServicesReferenceMark, rServiceName);
}
/* -----------------------------06.04.00 16:41--------------------------------
---------------------------------------------------------------------------*/
uno::Sequence< OUString > SAL_CALL
SwXReferenceMark::getSupportedServiceNames()
throw (uno::RuntimeException)
{
return ::sw::GetSupportedServiceNamesImpl(
g_nServicesReferenceMark, g_ServicesReferenceMark);
}
/* -----------------03.11.99 14:14-------------------
--------------------------------------------------*/
template<typename T> struct NotContainedIn
{
::std::vector<T> const& m_rVector;
explicit NotContainedIn(::std::vector<T> const& rVector)
: m_rVector(rVector) { }
bool operator() (T const& rT) {
return ::std::find(m_rVector.begin(), m_rVector.end(), rT)
== m_rVector.end();
}
};
void SwXReferenceMark::Impl::InsertRefMark(SwPaM& rPam,
SwXTextCursor const*const pCursor)
{
//! in some cases when this function is called the pDoc pointer member may have become
//! invalid/deleted thus we obtain the document pointer from rPaM where it should always
//! be valid.
SwDoc *pDoc2 = rPam.GetDoc();
UnoActionContext aCont(pDoc2);
SwFmtRefMark aRefMark(m_sMarkName);
sal_Bool bMark = *rPam.GetPoint() != *rPam.GetMark();
const bool bForceExpandHints( (!bMark && pCursor)
? pCursor->IsAtEndOfMeta() : false );
const SetAttrMode nInsertFlags = (bForceExpandHints)
? ( nsSetAttrMode::SETATTR_FORCEHINTEXPAND
| nsSetAttrMode::SETATTR_DONTEXPAND)
: nsSetAttrMode::SETATTR_DONTEXPAND;
::std::vector<SwTxtAttr *> oldMarks;
if (bMark)
{
oldMarks = rPam.GetNode()->GetTxtNode()->GetTxtAttrsAt(
rPam.GetPoint()->nContent.GetIndex(), RES_TXTATR_REFMARK);
}
pDoc2->InsertPoolItem( rPam, aRefMark, nInsertFlags );
if( bMark && *rPam.GetPoint() > *rPam.GetMark())
{
rPam.Exchange();
}
// aRefMark was copied into the document pool; now retrieve real format...
SwTxtAttr * pTxtAttr(0);
if (bMark)
{
// #i107672#
// ensure that we do not retrieve a different mark at the same position
::std::vector<SwTxtAttr *> const newMarks(
rPam.GetNode()->GetTxtNode()->GetTxtAttrsAt(
rPam.GetPoint()->nContent.GetIndex(), RES_TXTATR_REFMARK));
::std::vector<SwTxtAttr *>::const_iterator const iter(
::std::find_if(newMarks.begin(), newMarks.end(),
NotContainedIn<SwTxtAttr *>(oldMarks)));
OSL_ASSERT(newMarks.end() != iter);
if (newMarks.end() != iter)
{
pTxtAttr = *iter;
}
}
else
{
pTxtAttr = rPam.GetNode()->GetTxtNode()->GetTxtAttrForCharAt(
rPam.GetPoint()->nContent.GetIndex() - 1, RES_TXTATR_REFMARK);
}
if (!pTxtAttr)
{
throw uno::RuntimeException(::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
"SwXReferenceMark::InsertRefMark(): cannot insert attribute")), 0);
}
m_pMarkFmt = &pTxtAttr->GetRefMark();
pDoc2->GetUnoCallBack()->Add(this);
}
/*-- 11.12.98 10:28:34---------------------------------------------------
-----------------------------------------------------------------------*/
void SAL_CALL
SwXReferenceMark::attach(const uno::Reference< text::XTextRange > & xTextRange)
throw (lang::IllegalArgumentException, uno::RuntimeException)
{
vos::OGuard aGuard(Application::GetSolarMutex());
if (!m_pImpl->m_bIsDescriptor)
{
throw uno::RuntimeException();
}
uno::Reference<lang::XUnoTunnel> xRangeTunnel( xTextRange, uno::UNO_QUERY);
SwXTextRange* pRange = 0;
OTextCursorHelper* pCursor = 0;
if(xRangeTunnel.is())
{
pRange = ::sw::UnoTunnelGetImplementation<SwXTextRange>(xRangeTunnel);
pCursor =
::sw::UnoTunnelGetImplementation<OTextCursorHelper>(xRangeTunnel);
}
SwDoc *const pDocument =
(pRange) ? pRange->GetDoc() : ((pCursor) ? pCursor->GetDoc() : 0);
if (!pDocument)
{
throw lang::IllegalArgumentException();
}
SwUnoInternalPaM aPam(*pDocument);
//das muss jetzt sal_True liefern
::sw::XTextRangeToSwPaM(aPam, xTextRange);
m_pImpl->InsertRefMark(aPam, dynamic_cast<SwXTextCursor*>(pCursor));
m_pImpl->m_bIsDescriptor = sal_False;
m_pImpl->m_pDoc = pDocument;
}
/*-- 11.12.98 10:28:34---------------------------------------------------
-----------------------------------------------------------------------*/
uno::Reference< text::XTextRange > SAL_CALL
SwXReferenceMark::getAnchor() throw (uno::RuntimeException)
{
vos::OGuard aGuard(Application::GetSolarMutex());
if (m_pImpl->IsValid())
{
SwFmtRefMark const*const pNewMark =
m_pImpl->m_pDoc->GetRefMark(m_pImpl->m_sMarkName);
if (pNewMark && (pNewMark == m_pImpl->m_pMarkFmt))
{
SwTxtRefMark const*const pTxtMark =
m_pImpl->m_pMarkFmt->GetTxtRefMark();
if (pTxtMark &&
(&pTxtMark->GetTxtNode().GetNodes() ==
&m_pImpl->m_pDoc->GetNodes()))
{
SwTxtNode const& rTxtNode = pTxtMark->GetTxtNode();
const ::std::auto_ptr<SwPaM> pPam( (pTxtMark->End())
? new SwPaM( rTxtNode, *pTxtMark->End(),
rTxtNode, *pTxtMark->GetStart())
: new SwPaM( rTxtNode, *pTxtMark->GetStart()) );
return SwXTextRange::CreateXTextRange(
*m_pImpl->m_pDoc, *pPam->Start(), pPam->End());
}
}
}
return 0;
}
/*-- 11.12.98 10:28:35---------------------------------------------------
-----------------------------------------------------------------------*/
void SAL_CALL SwXReferenceMark::dispose() throw (uno::RuntimeException)
{
vos::OGuard aGuard(Application::GetSolarMutex());
if (m_pImpl->IsValid())
{
SwFmtRefMark const*const pNewMark =
m_pImpl->m_pDoc->GetRefMark(m_pImpl->m_sMarkName);
if (pNewMark && (pNewMark == m_pImpl->m_pMarkFmt))
{
SwTxtRefMark const*const pTxtMark =
m_pImpl->m_pMarkFmt->GetTxtRefMark();
if (pTxtMark &&
(&pTxtMark->GetTxtNode().GetNodes() ==
&m_pImpl->m_pDoc->GetNodes()))
{
SwTxtNode const& rTxtNode = pTxtMark->GetTxtNode();
const xub_StrLen nStt = *pTxtMark->GetStart();
const xub_StrLen nEnd = pTxtMark->End()
? *pTxtMark->End()
: nStt + 1;
SwPaM aPam( rTxtNode, nStt, rTxtNode, nEnd );
m_pImpl->m_pDoc->DeleteAndJoin( aPam );
}
}
}
else if (m_pImpl->m_bIsDescriptor)
{
m_pImpl->Invalidate();
}
}
/*-- 11.12.98 10:28:35---------------------------------------------------
-----------------------------------------------------------------------*/
void SAL_CALL SwXReferenceMark::addEventListener(
const uno::Reference< lang::XEventListener > & xListener)
throw (uno::RuntimeException)
{
vos::OGuard g(Application::GetSolarMutex());
if (!m_pImpl->IsValid())
{
throw uno::RuntimeException();
}
m_pImpl->m_ListenerContainer.AddListener(xListener);
}
/*-- 11.12.98 10:28:35---------------------------------------------------
-----------------------------------------------------------------------*/
void SAL_CALL SwXReferenceMark::removeEventListener(
const uno::Reference< lang::XEventListener > & xListener)
throw (uno::RuntimeException)
{
vos::OGuard g(Application::GetSolarMutex());
if (!m_pImpl->IsValid() ||
!m_pImpl->m_ListenerContainer.RemoveListener(xListener))
{
throw uno::RuntimeException();
}
}
/*-- 11.12.98 10:28:36---------------------------------------------------
-----------------------------------------------------------------------*/
OUString SAL_CALL SwXReferenceMark::getName()
throw (uno::RuntimeException)
{
vos::OGuard aGuard(Application::GetSolarMutex());
if (!m_pImpl->IsValid() ||
!m_pImpl->m_pDoc->GetRefMark(m_pImpl->m_sMarkName))
{
throw uno::RuntimeException();
}
return m_pImpl->m_sMarkName;
}
/*-- 11.12.98 10:28:36---------------------------------------------------
-----------------------------------------------------------------------*/
void SAL_CALL SwXReferenceMark::setName(const OUString& rName)
throw (uno::RuntimeException)
{
vos::OGuard aGuard(Application::GetSolarMutex());
if (m_pImpl->m_bIsDescriptor)
{
m_pImpl->m_sMarkName = rName;
}
else
{
if (!m_pImpl->IsValid()
|| !m_pImpl->m_pDoc->GetRefMark(m_pImpl->m_sMarkName)
|| m_pImpl->m_pDoc->GetRefMark(rName))
{
throw uno::RuntimeException();
}
SwFmtRefMark const*const pCurMark =
m_pImpl->m_pDoc->GetRefMark(m_pImpl->m_sMarkName);
if ((rName != m_pImpl->m_sMarkName)
&& pCurMark && (pCurMark == m_pImpl->m_pMarkFmt))
{
const UnoActionContext aCont(m_pImpl->m_pDoc);
SwTxtRefMark const*const pTxtMark =
m_pImpl->m_pMarkFmt->GetTxtRefMark();
if (pTxtMark &&
(&pTxtMark->GetTxtNode().GetNodes() ==
&m_pImpl->m_pDoc->GetNodes()))
{
SwTxtNode const& rTxtNode = pTxtMark->GetTxtNode();
const xub_StrLen nStt = *pTxtMark->GetStart();
const xub_StrLen nEnd = pTxtMark->End()
? *pTxtMark->End()
: nStt + 1;
SwPaM aPam( rTxtNode, nStt, rTxtNode, nEnd );
// deletes the m_pImpl->m_pDoc member in the SwXReferenceMark!
m_pImpl->m_pDoc->DeleteAndJoin( aPam );
// The aPam will keep the correct and functional doc though
m_pImpl->m_sMarkName = rName;
//create a new one
m_pImpl->InsertRefMark( aPam, 0 );
m_pImpl->m_pDoc = aPam.GetDoc();
}
}
}
}
/*-- 12.09.00 12:58:20---------------------------------------------------
-----------------------------------------------------------------------*/
uno::Reference< beans::XPropertySetInfo > SAL_CALL
SwXReferenceMark::getPropertySetInfo() throw (uno::RuntimeException)
{
vos::OGuard g(Application::GetSolarMutex());
static uno::Reference< beans::XPropertySetInfo > xRef =
aSwMapProvider.GetPropertySet(PROPERTY_MAP_PARAGRAPH_EXTENSIONS)
->getPropertySetInfo();
return xRef;
}
/*-- 12.09.00 12:58:20---------------------------------------------------
-----------------------------------------------------------------------*/
void SAL_CALL SwXReferenceMark::setPropertyValue(
const OUString& /*rPropertyName*/, const uno::Any& /*rValue*/ )
throw (beans::UnknownPropertyException, beans::PropertyVetoException,
lang::IllegalArgumentException, lang::WrappedTargetException,
uno::RuntimeException)
{
throw lang::IllegalArgumentException();
}
/*-- 12.09.00 12:58:20---------------------------------------------------
-----------------------------------------------------------------------*/
uno::Any SAL_CALL
SwXReferenceMark::getPropertyValue(const OUString& rPropertyName)
throw (beans::UnknownPropertyException, lang::WrappedTargetException,
uno::RuntimeException)
{
// does not seem to need SolarMutex
uno::Any aRet;
if (! ::sw::GetDefaultTextContentValue(aRet, rPropertyName))
{
throw beans::UnknownPropertyException();
}
return aRet;
}
/*-- 12.09.00 12:58:20---------------------------------------------------
-----------------------------------------------------------------------*/
void SAL_CALL SwXReferenceMark::addPropertyChangeListener(
const OUString& /*rPropertyName*/,
const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
throw (beans::UnknownPropertyException, lang::WrappedTargetException,
uno::RuntimeException)
{
OSL_ENSURE(false,
"SwXReferenceMark::addPropertyChangeListener(): not implemented");
}
/*-- 12.09.00 12:58:20---------------------------------------------------
-----------------------------------------------------------------------*/
void SAL_CALL SwXReferenceMark::removePropertyChangeListener(
const OUString& /*rPropertyName*/,
const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
throw (beans::UnknownPropertyException, lang::WrappedTargetException,
uno::RuntimeException)
{
OSL_ENSURE(false,
"SwXReferenceMark::removePropertyChangeListener(): not implemented");
}
/*-- 12.09.00 12:58:20---------------------------------------------------
-----------------------------------------------------------------------*/
void SAL_CALL SwXReferenceMark::addVetoableChangeListener(
const OUString& /*rPropertyName*/,
const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
throw (beans::UnknownPropertyException, lang::WrappedTargetException,
uno::RuntimeException)
{
OSL_ENSURE(false,
"SwXReferenceMark::addVetoableChangeListener(): not implemented");
}
/*-- 12.09.00 12:58:21---------------------------------------------------
-----------------------------------------------------------------------*/
void SAL_CALL SwXReferenceMark::removeVetoableChangeListener(
const OUString& /*rPropertyName*/,
const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
throw (beans::UnknownPropertyException, lang::WrappedTargetException,
uno::RuntimeException)
{
OSL_ENSURE(false,
"SwXReferenceMark::removeVetoableChangeListener(): not implemented");
}
#include <com/sun/star/lang/DisposedException.hpp>
#include <unometa.hxx>
#include <unotext.hxx>
#include <unoport.hxx>
#include <txtatr.hxx>
#include <fmtmeta.hxx>
#include <docsh.hxx>
//=============================================================================
/******************************************************************
* SwXMetaText
******************************************************************/
class SwXMetaText
: public SwXText
{
private:
SwXMeta & m_rMeta;
virtual void PrepareForAttach(uno::Reference< text::XTextRange > & xRange,
const SwPaM & rPam);
virtual bool CheckForOwnMemberMeta(const SwPaM & rPam, const bool bAbsorb)
throw (lang::IllegalArgumentException, uno::RuntimeException);
protected:
virtual const SwStartNode *GetStartNode() const;
virtual uno::Reference< text::XTextCursor >
CreateCursor() throw (uno::RuntimeException);
public:
SwXMetaText(SwDoc & rDoc, SwXMeta & rMeta);
/// make available for SwXMeta
void Invalidate() { SwXText::Invalidate(); };
// XInterface
virtual void SAL_CALL acquire() throw()
{ OSL_ENSURE(false, "ERROR: SwXMetaText::acquire"); }
virtual void SAL_CALL release() throw()
{ OSL_ENSURE(false, "ERROR: SwXMetaText::release"); }
// XTypeProvider
virtual uno::Sequence< sal_Int8 > SAL_CALL
getImplementationId() throw (uno::RuntimeException);
// XText
virtual uno::Reference< text::XTextCursor > SAL_CALL
createTextCursor() throw (uno::RuntimeException);
virtual uno::Reference< text::XTextCursor > SAL_CALL
createTextCursorByRange(
const uno::Reference< text::XTextRange > & xTextPosition)
throw (uno::RuntimeException);
SwXMeta & GetXMeta() { return m_rMeta; }
};
SwXMetaText::SwXMetaText(SwDoc & rDoc, SwXMeta & rMeta)
: SwXText(&rDoc, CURSOR_META)
, m_rMeta(rMeta)
{
}
const SwStartNode *SwXMetaText::GetStartNode() const
{
SwXText const * const pParent(
dynamic_cast<SwXText*>(m_rMeta.GetParentText().get()));
return (pParent) ? pParent->GetStartNode() : 0;
}
void SwXMetaText::PrepareForAttach( uno::Reference<text::XTextRange> & xRange,
const SwPaM & rPam)
{
// create a new cursor to prevent modifying SwXTextRange
xRange = static_cast<text::XWordCursor*>(
new SwXTextCursor(*GetDoc(), &m_rMeta, CURSOR_META, *rPam.GetPoint(),
(rPam.HasMark()) ? rPam.GetMark() : 0));
}
bool SwXMetaText::CheckForOwnMemberMeta(const SwPaM & rPam, const bool bAbsorb)
throw (lang::IllegalArgumentException, uno::RuntimeException)
{
return m_rMeta.CheckForOwnMemberMeta(rPam, bAbsorb);
}
uno::Reference< text::XTextCursor > SwXMetaText::CreateCursor()
throw (uno::RuntimeException)
{
uno::Reference< text::XTextCursor > xRet;
if (IsValid())
{
SwTxtNode * pTxtNode;
xub_StrLen nMetaStart;
xub_StrLen nMetaEnd;
const bool bSuccess(
m_rMeta.SetContentRange(pTxtNode, nMetaStart, nMetaEnd) );
if (bSuccess)
{
SwPosition aPos(*pTxtNode, nMetaStart);
xRet = static_cast<text::XWordCursor*>(
new SwXTextCursor(*GetDoc(), &m_rMeta, CURSOR_META, aPos));
}
}
return xRet;
}
uno::Sequence<sal_Int8> SAL_CALL
SwXMetaText::getImplementationId() throw (uno::RuntimeException)
{
return m_rMeta.getImplementationId();
}
// XText
uno::Reference< text::XTextCursor > SAL_CALL
SwXMetaText::createTextCursor() throw (uno::RuntimeException)
{
return CreateCursor();
}
uno::Reference< text::XTextCursor > SAL_CALL
SwXMetaText::createTextCursorByRange(
const uno::Reference<text::XTextRange> & xTextPosition)
throw (uno::RuntimeException)
{
const uno::Reference<text::XTextCursor> xCursor( CreateCursor() );
xCursor->gotoRange(xTextPosition, sal_False);
return xCursor;
}
/******************************************************************
* SwXMeta
******************************************************************/
// the Meta has a cached list of text portions for its contents
// this list is created by SwXTextPortionEnumeration
// the Meta listens at the SwTxtNode and throws away the cache when it changes
class SwXMeta::Impl
: public SwClient
{
public:
SwEventListenerContainer m_ListenerContainer;
::std::auto_ptr<const TextRangeList_t> m_pTextPortions;
// 3 possible states: not attached, attached, disposed
bool m_bIsDisposed;
bool m_bIsDescriptor;
uno::Reference<text::XText> m_xParentText;
SwXMetaText m_Text;
Impl( SwXMeta & rThis, SwDoc & rDoc,
::sw::Meta * const pMeta,
uno::Reference<text::XText> const& xParentText,
TextRangeList_t const * const pPortions)
: SwClient(pMeta)
, m_ListenerContainer(static_cast< ::cppu::OWeakObject* >(&rThis))
, m_pTextPortions( pPortions )
, m_bIsDisposed( false )
// #i111177# unxsols4 (Sun C++ 5.9 SunOS_sparc) may generate wrong code
, m_bIsDescriptor((0 == pMeta) ? true : false)
, m_xParentText(xParentText)
, m_Text(rDoc, rThis)
{
}
inline const ::sw::Meta * GetMeta() const;
// only for SwXMetaField!
inline const ::sw::MetaField * GetMetaField() const;
protected:
// SwClient
virtual void Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew);
};
inline const ::sw::Meta * SwXMeta::Impl::GetMeta() const
{
return static_cast< const ::sw::Meta * >(GetRegisteredIn());
}
// SwModify
void SwXMeta::Impl::Modify( const SfxPoolItem* pOld, const SfxPoolItem *pNew )
{
m_pTextPortions.reset(); // throw away cache (SwTxtNode changed)
ClientModify(this, pOld, pNew);
if (!GetRegisteredIn()) // removed => dispose
{
m_ListenerContainer.Disposing();
m_bIsDisposed = true;
m_Text.Invalidate();
}
}
uno::Reference<text::XText> SwXMeta::GetParentText() const
{
return m_pImpl->m_xParentText;
}
SwXMeta::SwXMeta(SwDoc *const pDoc, ::sw::Meta *const pMeta,
uno::Reference<text::XText> const& xParentText,
TextRangeList_t const*const pPortions)
: m_pImpl( new SwXMeta::Impl(*this, *pDoc, pMeta, xParentText, pPortions) )
{
}
SwXMeta::SwXMeta(SwDoc *const pDoc)
: m_pImpl( new SwXMeta::Impl(*this, *pDoc, 0, 0, 0) )
{
}
SwXMeta::~SwXMeta()
{
}
uno::Reference<rdf::XMetadatable>
SwXMeta::CreateXMeta(::sw::Meta & rMeta,
uno::Reference<text::XText> const& i_xParent,
::std::auto_ptr<TextRangeList_t const> pPortions)
{
// re-use existing SwXMeta
// #i105557#: do not iterate over the registered clients: race condition
uno::Reference<rdf::XMetadatable> xMeta(rMeta.GetXMeta());
if (xMeta.is())
{
if (pPortions.get()) // set cache in the XMeta to the given portions
{
const uno::Reference<lang::XUnoTunnel> xUT(xMeta, uno::UNO_QUERY);
SwXMeta *const pXMeta(
::sw::UnoTunnelGetImplementation<SwXMeta>(xUT));
OSL_ENSURE(pXMeta, "no pXMeta?");
// NB: the meta must always be created with the complete content
// if SwXTextPortionEnumeration is created for a selection,
// it must be checked that the Meta is contained in the selection!
pXMeta->m_pImpl->m_pTextPortions = pPortions;
// ??? is this necessary?
if (pXMeta->m_pImpl->m_xParentText.get() != i_xParent.get())
{
OSL_ENSURE(false, "SwXMeta with different parent?");
pXMeta->m_pImpl->m_xParentText.set(i_xParent);
}
}
return xMeta;
}
// create new SwXMeta
SwTxtNode * const pTxtNode( rMeta.GetTxtNode() );
OSL_ENSURE(pTxtNode, "CreateXMeta: no text node?");
if (!pTxtNode) { return 0; }
uno::Reference<text::XText> xParentText(i_xParent);
if (!xParentText.is())
{
SwTxtMeta * const pTxtAttr( rMeta.GetTxtAttr() );
OSL_ENSURE(pTxtAttr, "CreateXMeta: no text attr?");
if (!pTxtAttr) { return 0; }
const SwPosition aPos(*pTxtNode, *pTxtAttr->GetStart());
xParentText.set( ::sw::CreateParentXText(*pTxtNode->GetDoc(), aPos) );
}
if (!xParentText.is()) { return 0; }
SwXMeta *const pXMeta( (RES_TXTATR_META == rMeta.GetFmtMeta()->Which())
? new SwXMeta (pTxtNode->GetDoc(), &rMeta, xParentText,
pPortions.release()) // temporarily un-auto_ptr :-(
: new SwXMetaField(pTxtNode->GetDoc(), &rMeta, xParentText,
pPortions.release()));
// this is why the constructor is private: need to acquire pXMeta here
xMeta.set(pXMeta);
// in order to initialize the weak pointer cache in the core object
rMeta.SetXMeta(xMeta);
return xMeta;
}
bool SwXMeta::SetContentRange(
SwTxtNode *& rpNode, xub_StrLen & rStart, xub_StrLen & rEnd ) const
{
::sw::Meta const * const pMeta( m_pImpl->GetMeta() );
if (pMeta)
{
SwTxtMeta const * const pTxtAttr( pMeta->GetTxtAttr() );
if (pTxtAttr)
{
rpNode = pMeta->GetTxtNode();
if (rpNode)
{
// rStart points at the first position _within_ the meta!
rStart = *pTxtAttr->GetStart() + 1;
rEnd = *pTxtAttr->End();
return true;
}
}
}
return false;
}
bool SwXMeta::CheckForOwnMemberMeta(const SwPaM & rPam, const bool bAbsorb)
throw (lang::IllegalArgumentException, uno::RuntimeException)
{
SwTxtNode * pTxtNode;
xub_StrLen nMetaStart;
xub_StrLen nMetaEnd;
const bool bSuccess( SetContentRange(pTxtNode, nMetaStart, nMetaEnd) );
ASSERT(bSuccess, "no pam?");
if (!bSuccess)
throw lang::DisposedException();
SwPosition const * const pStartPos( rPam.Start() );
if (&pStartPos->nNode.GetNode() != pTxtNode)
{
throw lang::IllegalArgumentException(
C2U("trying to insert into a nesting text content, but start "
"of text range not in same paragraph as text content"),
0, 0);
}
bool bForceExpandHints(false);
const xub_StrLen nStartPos(pStartPos->nContent.GetIndex());
// not <= but < because nMetaStart is behind dummy char!
// not >= but > because == means insert at end!
if ((nStartPos < nMetaStart) || (nStartPos > nMetaEnd))
{
throw lang::IllegalArgumentException(
C2U("trying to insert into a nesting text content, but start "
"of text range not inside text content"),
0, 0);
}
else if (nStartPos == nMetaEnd)
{
bForceExpandHints = true;
}
if (rPam.HasMark() && bAbsorb)
{
SwPosition const * const pEndPos( rPam.End() );
if (&pEndPos->nNode.GetNode() != pTxtNode)
{
throw lang::IllegalArgumentException(
C2U("trying to insert into a nesting text content, but end "
"of text range not in same paragraph as text content"),
0, 0);
}
const xub_StrLen nEndPos(pEndPos->nContent.GetIndex());
// not <= but < because nMetaStart is behind dummy char!
// not >= but > because == means insert at end!
if ((nEndPos < nMetaStart) || (nEndPos > nMetaEnd))
{
throw lang::IllegalArgumentException(
C2U("trying to insert into a nesting text content, but end "
"of text range not inside text content"),
0, 0);
}
else if (nEndPos == nMetaEnd)
{
bForceExpandHints = true;
}
}
return bForceExpandHints;
}
const uno::Sequence< sal_Int8 > & SwXMeta::getUnoTunnelId()
{
static uno::Sequence< sal_Int8 > aSeq( ::CreateUnoTunnelId() );
return aSeq;
}
// XUnoTunnel
sal_Int64 SAL_CALL
SwXMeta::getSomething( const uno::Sequence< sal_Int8 > & i_rId )
throw (uno::RuntimeException)
{
return ::sw::UnoTunnelImpl<SwXMeta>(i_rId, this);
}
// XServiceInfo
::rtl::OUString SAL_CALL
SwXMeta::getImplementationName() throw (uno::RuntimeException)
{
return C2U("SwXMeta");
}
static char const*const g_ServicesMeta[] =
{
"com.sun.star.text.TextContent",
"com.sun.star.text.InContentMetadata",
};
static const size_t g_nServicesMeta(
sizeof(g_ServicesMeta)/sizeof(g_ServicesMeta[0]));
sal_Bool SAL_CALL
SwXMeta::supportsService(const ::rtl::OUString& rServiceName)
throw (uno::RuntimeException)
{
return ::sw::SupportsServiceImpl(
g_nServicesMeta, g_ServicesMeta, rServiceName);
}
uno::Sequence< ::rtl::OUString > SAL_CALL
SwXMeta::getSupportedServiceNames() throw (uno::RuntimeException)
{
return ::sw::GetSupportedServiceNamesImpl(g_nServicesMeta, g_ServicesMeta);
}
// XComponent
void SAL_CALL
SwXMeta::addEventListener(
uno::Reference< lang::XEventListener> const & xListener )
throw (uno::RuntimeException)
{
vos::OGuard g(Application::GetSolarMutex());
m_pImpl->m_ListenerContainer.AddListener(xListener);
if (m_pImpl->m_bIsDisposed)
{
m_pImpl->m_ListenerContainer.Disposing();
}
}
void SAL_CALL
SwXMeta::removeEventListener(
uno::Reference< lang::XEventListener> const & xListener )
throw (uno::RuntimeException)
{
vos::OGuard g(Application::GetSolarMutex());
if (!m_pImpl->m_bIsDisposed)
{
m_pImpl->m_ListenerContainer.RemoveListener(xListener);
}
}
void SAL_CALL
SwXMeta::dispose() throw (uno::RuntimeException)
{
vos::OGuard g(Application::GetSolarMutex());
if (m_pImpl->m_bIsDescriptor)
{
m_pImpl->m_pTextPortions.reset();
m_pImpl->m_ListenerContainer.Disposing();
m_pImpl->m_bIsDisposed = true;
m_pImpl->m_Text.Invalidate();
}
else if (!m_pImpl->m_bIsDisposed)
{
SwTxtNode * pTxtNode;
xub_StrLen nMetaStart;
xub_StrLen nMetaEnd;
const bool bSuccess(SetContentRange(pTxtNode, nMetaStart, nMetaEnd));
ASSERT(bSuccess, "no pam?");
if (bSuccess)
{
// -1 because of CH_TXTATR
SwPaM aPam( *pTxtNode, nMetaStart - 1, *pTxtNode, nMetaEnd );
SwDoc * const pDoc( pTxtNode->GetDoc() );
pDoc->DeleteAndJoin( aPam );
// removal should call Modify and do the dispose
OSL_ENSURE(m_pImpl->m_bIsDisposed, "zombie meta");
}
}
}
void SAL_CALL
SwXMeta::AttachImpl(const uno::Reference< text::XTextRange > & i_xTextRange,
const sal_uInt16 i_nWhich)
throw (lang::IllegalArgumentException, uno::RuntimeException)
{
vos::OGuard g(Application::GetSolarMutex());
if (m_pImpl->m_bIsDisposed)
{
throw lang::DisposedException();
}
if (!m_pImpl->m_bIsDescriptor)
{
throw uno::RuntimeException(
C2S("SwXMeta::attach(): already attached"),
static_cast< ::cppu::OWeakObject* >(this));
}
uno::Reference<lang::XUnoTunnel> xRangeTunnel(i_xTextRange, uno::UNO_QUERY);
if (!xRangeTunnel.is())
{
throw lang::IllegalArgumentException(
C2S("SwXMeta::attach(): argument is no XUnoTunnel"),
static_cast< ::cppu::OWeakObject* >(this), 0);
}
SwXTextRange *const pRange(
::sw::UnoTunnelGetImplementation<SwXTextRange>(xRangeTunnel));
OTextCursorHelper *const pCursor( (pRange) ? 0 :
::sw::UnoTunnelGetImplementation<OTextCursorHelper>(xRangeTunnel));
if (!pRange && !pCursor)
{
throw lang::IllegalArgumentException(
C2S("SwXMeta::attach(): argument not supported type"),
static_cast< ::cppu::OWeakObject* >(this), 0);
}
SwDoc * const pDoc(
pRange ? pRange->GetDoc() : pCursor ? pCursor->GetDoc() : 0 );
if (!pDoc)
{
throw lang::IllegalArgumentException(
C2S("SwXMeta::attach(): argument has no SwDoc"),
static_cast< ::cppu::OWeakObject* >(this), 0);
}
SwUnoInternalPaM aPam(*pDoc);
::sw::XTextRangeToSwPaM(aPam, i_xTextRange);
UnoActionContext aContext(pDoc);
SwXTextCursor const*const pTextCursor(
dynamic_cast<SwXTextCursor*>(pCursor));
const bool bForceExpandHints((pTextCursor)
? pTextCursor->IsAtEndOfMeta() : false);
const SetAttrMode nInsertFlags( (bForceExpandHints)
? ( nsSetAttrMode::SETATTR_FORCEHINTEXPAND
| nsSetAttrMode::SETATTR_DONTEXPAND)
: nsSetAttrMode::SETATTR_DONTEXPAND );
const ::boost::shared_ptr< ::sw::Meta> pMeta( (RES_TXTATR_META == i_nWhich)
? ::boost::shared_ptr< ::sw::Meta>( new ::sw::Meta() )
: ::boost::shared_ptr< ::sw::Meta>(
pDoc->GetMetaFieldManager().makeMetaField()) );
SwFmtMeta meta(pMeta, i_nWhich); // this is cloned by Insert!
const bool bSuccess( pDoc->InsertPoolItem( aPam, meta, nInsertFlags ) );
SwTxtAttr * const pTxtAttr( pMeta->GetTxtAttr() );
if (!bSuccess)
{
throw lang::IllegalArgumentException(
C2S("SwXMeta::attach(): cannot create meta: range invalid?"),
static_cast< ::cppu::OWeakObject* >(this), 1);
}
if (!pTxtAttr)
{
ASSERT(false, "meta inserted, but has no text attribute?");
throw uno::RuntimeException(
C2S("SwXMeta::attach(): cannot create meta"),
static_cast< ::cppu::OWeakObject* >(this));
}
pMeta->Add(m_pImpl.get());
pMeta->SetXMeta(uno::Reference<rdf::XMetadatable>(this));
m_pImpl->m_xParentText = ::sw::CreateParentXText(*pDoc, *aPam.GetPoint());
m_pImpl->m_bIsDescriptor = false;
}
// XTextContent
void SAL_CALL
SwXMeta::attach(const uno::Reference< text::XTextRange > & i_xTextRange)
throw (lang::IllegalArgumentException, uno::RuntimeException)
{
return SwXMeta::AttachImpl(i_xTextRange, RES_TXTATR_META);
}
uno::Reference< text::XTextRange > SAL_CALL
SwXMeta::getAnchor() throw (uno::RuntimeException)
{
vos::OGuard g(Application::GetSolarMutex());
if (m_pImpl->m_bIsDisposed)
{
throw lang::DisposedException();
}
if (m_pImpl->m_bIsDescriptor)
{
throw uno::RuntimeException(
C2S("SwXMeta::getAnchor(): not inserted"),
static_cast< ::cppu::OWeakObject* >(this));
}
SwTxtNode * pTxtNode;
xub_StrLen nMetaStart;
xub_StrLen nMetaEnd;
const bool bSuccess(SetContentRange(pTxtNode, nMetaStart, nMetaEnd));
ASSERT(bSuccess, "no pam?");
if (!bSuccess)
{
throw lang::DisposedException(
C2S("SwXMeta::getAnchor(): not attached"),
static_cast< ::cppu::OWeakObject* >(this));
}
const SwPosition start(*pTxtNode, nMetaStart - 1); // -1 due to CH_TXTATR
const SwPosition end(*pTxtNode, nMetaEnd);
return SwXTextRange::CreateXTextRange(*pTxtNode->GetDoc(), start, &end);
}
// XTextRange
uno::Reference< text::XText > SAL_CALL
SwXMeta::getText() throw (uno::RuntimeException)
{
vos::OGuard g(Application::GetSolarMutex());
return this;
}
uno::Reference< text::XTextRange > SAL_CALL
SwXMeta::getStart() throw (uno::RuntimeException)
{
vos::OGuard g(Application::GetSolarMutex());
return m_pImpl->m_Text.getStart();
}
uno::Reference< text::XTextRange > SAL_CALL
SwXMeta::getEnd() throw (uno::RuntimeException)
{
vos::OGuard g(Application::GetSolarMutex());
return m_pImpl->m_Text.getEnd();
}
rtl::OUString SAL_CALL
SwXMeta::getString() throw (uno::RuntimeException)
{
vos::OGuard g(Application::GetSolarMutex());
return m_pImpl->m_Text.getString();
}
void SAL_CALL
SwXMeta::setString(const rtl::OUString& rString) throw (uno::RuntimeException)
{
vos::OGuard g(Application::GetSolarMutex());
return m_pImpl->m_Text.setString(rString);
}
// XSimpleText
uno::Reference< text::XTextCursor > SAL_CALL
SwXMeta::createTextCursor() throw (uno::RuntimeException)
{
vos::OGuard g(Application::GetSolarMutex());
return m_pImpl->m_Text.createTextCursor();
}
uno::Reference< text::XTextCursor > SAL_CALL
SwXMeta::createTextCursorByRange(
const uno::Reference<text::XTextRange> & xTextPosition)
throw (uno::RuntimeException)
{
vos::OGuard g(Application::GetSolarMutex());
return m_pImpl->m_Text.createTextCursorByRange(xTextPosition);
}
void SAL_CALL
SwXMeta::insertString(const uno::Reference<text::XTextRange> & xRange,
const rtl::OUString& rString, sal_Bool bAbsorb)
throw (uno::RuntimeException)
{
vos::OGuard g(Application::GetSolarMutex());
return m_pImpl->m_Text.insertString(xRange, rString, bAbsorb);
}
void SAL_CALL
SwXMeta::insertControlCharacter(const uno::Reference<text::XTextRange> & xRange,
sal_Int16 nControlCharacter, sal_Bool bAbsorb)
throw (lang::IllegalArgumentException, uno::RuntimeException)
{
vos::OGuard g(Application::GetSolarMutex());
return m_pImpl->m_Text.insertControlCharacter(xRange, nControlCharacter,
bAbsorb);
}
// XText
void SAL_CALL
SwXMeta::insertTextContent( const uno::Reference<text::XTextRange> & xRange,
const uno::Reference<text::XTextContent> & xContent, sal_Bool bAbsorb)
throw (lang::IllegalArgumentException, uno::RuntimeException)
{
vos::OGuard g(Application::GetSolarMutex());
return m_pImpl->m_Text.insertTextContent(xRange, xContent, bAbsorb);
}
void SAL_CALL
SwXMeta::removeTextContent(
const uno::Reference< text::XTextContent > & xContent)
throw (container::NoSuchElementException, uno::RuntimeException)
{
vos::OGuard g(Application::GetSolarMutex());
return m_pImpl->m_Text.removeTextContent(xContent);
}
// XChild
uno::Reference< uno::XInterface > SAL_CALL
SwXMeta::getParent() throw (uno::RuntimeException)
{
vos::OGuard g(Application::GetSolarMutex());
SwTxtNode * pTxtNode;
xub_StrLen nMetaStart;
xub_StrLen nMetaEnd;
bool const bSuccess( SetContentRange(pTxtNode, nMetaStart, nMetaEnd) );
OSL_ENSURE(bSuccess, "no pam?");
if (!bSuccess) { throw lang::DisposedException(); }
// in order to prevent getting this meta, subtract 1 from nMetaStart;
// so we get the index of the dummy character, and we exclude it
// by calling GetTxtAttrAt(_, _, PARENT) in GetNestedTextContent
uno::Reference<text::XTextContent> const xRet(
SwUnoCursorHelper::GetNestedTextContent(*pTxtNode, nMetaStart - 1,
true) );
return xRet;
}
void SAL_CALL
SwXMeta::setParent(uno::Reference< uno::XInterface > const& /*xParent*/)
throw (uno::RuntimeException, lang::NoSupportException)
{
throw lang::NoSupportException(C2S("setting parent not supported"), *this);
}
// XElementAccess
uno::Type SAL_CALL
SwXMeta::getElementType() throw (uno::RuntimeException)
{
return text::XTextRange::static_type();
}
sal_Bool SAL_CALL
SwXMeta::hasElements() throw (uno::RuntimeException)
{
vos::OGuard g(Application::GetSolarMutex());
return m_pImpl->GetRegisteredIn() ? sal_True : sal_False;
}
// XEnumerationAccess
uno::Reference< container::XEnumeration > SAL_CALL
SwXMeta::createEnumeration() throw (uno::RuntimeException)
{
vos::OGuard g(Application::GetSolarMutex());
if (m_pImpl->m_bIsDisposed)
{
throw lang::DisposedException();
}
if (m_pImpl->m_bIsDescriptor)
{
throw uno::RuntimeException(
C2S("createEnumeration(): not inserted"),
static_cast< ::cppu::OWeakObject* >(this));
}
SwTxtNode * pTxtNode;
xub_StrLen nMetaStart;
xub_StrLen nMetaEnd;
const bool bSuccess(SetContentRange(pTxtNode, nMetaStart, nMetaEnd));
ASSERT(bSuccess, "no pam?");
if (!bSuccess)
throw lang::DisposedException();
SwPaM aPam(*pTxtNode, nMetaStart);
if (!m_pImpl->m_pTextPortions.get())
{
return new SwXTextPortionEnumeration(
aPam, GetParentText(), nMetaStart, nMetaEnd);
}
else // cached!
{
return new SwXTextPortionEnumeration(aPam, *m_pImpl->m_pTextPortions);
}
}
// MetadatableMixin
::sfx2::Metadatable* SwXMeta::GetCoreObject()
{
return const_cast< ::sw::Meta * >(m_pImpl->GetMeta());
}
uno::Reference<frame::XModel> SwXMeta::GetModel()
{
::sw::Meta const * const pMeta( m_pImpl->GetMeta() );
if (pMeta)
{
SwTxtNode const * const pTxtNode( pMeta->GetTxtNode() );
if (pTxtNode)
{
SwDocShell const * const pShell(pTxtNode->GetDoc()->GetDocShell());
return (pShell) ? pShell->GetModel() : 0;
}
}
return 0;
}
/******************************************************************
* SwXMetaField
******************************************************************/
inline const ::sw::MetaField * SwXMeta::Impl::GetMetaField() const
{
return static_cast< const ::sw::MetaField * >(GetRegisteredIn());
}
SwXMetaField::SwXMetaField(SwDoc *const pDoc, ::sw::Meta *const pMeta,
uno::Reference<text::XText> const& xParentText,
TextRangeList_t const*const pPortions)
: SwXMetaField_Base(pDoc, pMeta, xParentText, pPortions)
{
ASSERT(pMeta && dynamic_cast< ::sw::MetaField* >(pMeta),
"SwXMetaField created for wrong hint!");
}
SwXMetaField::SwXMetaField(SwDoc *const pDoc)
: SwXMetaField_Base(pDoc)
{
}
SwXMetaField::~SwXMetaField()
{
}
// XServiceInfo
::rtl::OUString SAL_CALL
SwXMetaField::getImplementationName() throw (uno::RuntimeException)
{
return C2U("SwXMetaField");
}
static char const*const g_ServicesMetaField[] =
{
"com.sun.star.text.TextContent",
"com.sun.star.text.TextField",
"com.sun.star.text.textfield.MetadataField",
};
static const size_t g_nServicesMetaField(
sizeof(g_ServicesMetaField)/sizeof(g_ServicesMetaField[0]));
sal_Bool SAL_CALL
SwXMetaField::supportsService(const ::rtl::OUString& rServiceName)
throw (uno::RuntimeException)
{
return ::sw::SupportsServiceImpl(
g_nServicesMetaField, g_ServicesMetaField, rServiceName);
}
uno::Sequence< ::rtl::OUString > SAL_CALL
SwXMetaField::getSupportedServiceNames() throw (uno::RuntimeException)
{
return ::sw::GetSupportedServiceNamesImpl(
g_nServicesMetaField, g_ServicesMetaField);
}
// XComponent
void SAL_CALL
SwXMetaField::addEventListener(
uno::Reference< lang::XEventListener> const & xListener )
throw (uno::RuntimeException)
{
return SwXMeta::addEventListener(xListener);
}
void SAL_CALL
SwXMetaField::removeEventListener(
uno::Reference< lang::XEventListener> const & xListener )
throw (uno::RuntimeException)
{
return SwXMeta::removeEventListener(xListener);
}
void SAL_CALL
SwXMetaField::dispose() throw (uno::RuntimeException)
{
return SwXMeta::dispose();
}
// XTextContent
void SAL_CALL
SwXMetaField::attach(const uno::Reference< text::XTextRange > & i_xTextRange)
throw (lang::IllegalArgumentException, uno::RuntimeException)
{
return SwXMeta::AttachImpl(i_xTextRange, RES_TXTATR_METAFIELD);
}
uno::Reference< text::XTextRange > SAL_CALL
SwXMetaField::getAnchor() throw (uno::RuntimeException)
{
return SwXMeta::getAnchor();
}
// XPropertySet
uno::Reference< beans::XPropertySetInfo > SAL_CALL
SwXMetaField::getPropertySetInfo() throw (uno::RuntimeException)
{
vos::OGuard g(Application::GetSolarMutex());
static uno::Reference< beans::XPropertySetInfo > xRef(
aSwMapProvider.GetPropertySet(PROPERTY_MAP_METAFIELD)
->getPropertySetInfo() );
return xRef;
}
void SAL_CALL
SwXMetaField::setPropertyValue(
const ::rtl::OUString& rPropertyName, const uno::Any& rValue)
throw (beans::UnknownPropertyException, beans::PropertyVetoException,
lang::IllegalArgumentException, lang::WrappedTargetException,
uno::RuntimeException)
{
vos::OGuard g(Application::GetSolarMutex());
::sw::MetaField * const pMeta(
const_cast< ::sw::MetaField * >(m_pImpl->GetMetaField()) );
if (!pMeta)
throw lang::DisposedException();
if (rPropertyName.equalsAscii("NumberFormat"))
{
sal_Int32 nNumberFormat(0);
if (rValue >>= nNumberFormat)
{
pMeta->SetNumberFormat(static_cast<sal_uInt32>(nNumberFormat));
}
}
else if (rPropertyName.equalsAscii("IsFixedLanguage"))
{
bool b(false);
if (rValue >>= b)
{
pMeta->SetIsFixedLanguage(b);
}
}
else
{
throw beans::UnknownPropertyException();
}
}
uno::Any SAL_CALL
SwXMetaField::getPropertyValue(const ::rtl::OUString& rPropertyName)
throw (beans::UnknownPropertyException, lang::WrappedTargetException,
uno::RuntimeException)
{
vos::OGuard g(Application::GetSolarMutex());
::sw::MetaField const * const pMeta( m_pImpl->GetMetaField() );
if (!pMeta)
throw lang::DisposedException();
uno::Any any;
if (rPropertyName.equalsAscii("NumberFormat"))
{
const ::rtl::OUString text( getPresentation(sal_False) );
any <<= static_cast<sal_Int32>(pMeta->GetNumberFormat(text));
}
else if (rPropertyName.equalsAscii("IsFixedLanguage"))
{
any <<= pMeta->IsFixedLanguage();
}
else
{
throw beans::UnknownPropertyException();
}
return any;
}
void SAL_CALL
SwXMetaField::addPropertyChangeListener(
const ::rtl::OUString& /*rPropertyName*/,
const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
throw (beans::UnknownPropertyException, lang::WrappedTargetException,
uno::RuntimeException)
{
OSL_ENSURE(false,
"SwXMetaField::addPropertyChangeListener(): not implemented");
}
void SAL_CALL
SwXMetaField::removePropertyChangeListener(
const ::rtl::OUString& /*rPropertyName*/,
const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
throw (beans::UnknownPropertyException, lang::WrappedTargetException,
uno::RuntimeException)
{
OSL_ENSURE(false,
"SwXMetaField::removePropertyChangeListener(): not implemented");
}
void SAL_CALL
SwXMetaField::addVetoableChangeListener(
const ::rtl::OUString& /*rPropertyName*/,
const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
throw (beans::UnknownPropertyException, lang::WrappedTargetException,
uno::RuntimeException)
{
OSL_ENSURE(false,
"SwXMetaField::addVetoableChangeListener(): not implemented");
}
void SAL_CALL
SwXMetaField::removeVetoableChangeListener(
const ::rtl::OUString& /*rPropertyName*/,
const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
throw (beans::UnknownPropertyException, lang::WrappedTargetException,
uno::RuntimeException)
{
OSL_ENSURE(false,
"SwXMetaField::removeVetoableChangeListener(): not implemented");
}
#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
#include <com/sun/star/rdf/Statement.hpp>
#include <com/sun/star/rdf/URI.hpp>
#include <com/sun/star/rdf/URIs.hpp>
#include <com/sun/star/rdf/XLiteral.hpp>
#include <com/sun/star/rdf/XRepositorySupplier.hpp>
#include <comphelper/processfactory.hxx>
static uno::Reference<rdf::XURI> const&
lcl_getURI(const bool bPrefix)
{
static uno::Reference< uno::XComponentContext > xContext(
::comphelper::getProcessComponentContext());
static uno::Reference< rdf::XURI > xOdfPrefix(
rdf::URI::createKnown(xContext, rdf::URIs::ODF_PREFIX),
uno::UNO_SET_THROW);
static uno::Reference< rdf::XURI > xOdfSuffix(
rdf::URI::createKnown(xContext, rdf::URIs::ODF_SUFFIX),
uno::UNO_SET_THROW);
return (bPrefix) ? xOdfPrefix : xOdfSuffix;
}
static ::rtl::OUString
lcl_getPrefixOrSuffix(
uno::Reference<rdf::XRepository> const & xRepository,
uno::Reference<rdf::XResource> const & xMetaField,
uno::Reference<rdf::XURI> const & xPredicate)
{
const uno::Reference<container::XEnumeration> xEnum(
xRepository->getStatements(xMetaField, xPredicate, 0),
uno::UNO_SET_THROW);
while (xEnum->hasMoreElements()) {
rdf::Statement stmt;
if (!(xEnum->nextElement() >>= stmt)) {
throw uno::RuntimeException();
}
const uno::Reference<rdf::XLiteral> xObject(stmt.Object,
uno::UNO_QUERY);
if (!xObject.is()) continue;
if (xEnum->hasMoreElements()) {
OSL_TRACE("ignoring other odf:Prefix/odf:Suffix statements");
}
return xObject->getValue();
}
return ::rtl::OUString();
}
void
getPrefixAndSuffix(
const uno::Reference<frame::XModel>& xModel,
const uno::Reference<rdf::XMetadatable>& xMetaField,
::rtl::OUString *const o_pPrefix, ::rtl::OUString *const o_pSuffix)
{
try {
const uno::Reference<rdf::XRepositorySupplier> xRS(
xModel, uno::UNO_QUERY_THROW);
const uno::Reference<rdf::XRepository> xRepo(
xRS->getRDFRepository(), uno::UNO_SET_THROW);
const uno::Reference<rdf::XResource> xMeta(
xMetaField, uno::UNO_QUERY_THROW);
if (o_pPrefix)
{
*o_pPrefix = lcl_getPrefixOrSuffix(xRepo, xMeta, lcl_getURI(true));
}
if (o_pSuffix)
{
*o_pSuffix = lcl_getPrefixOrSuffix(xRepo, xMeta, lcl_getURI(false));
}
} catch (uno::RuntimeException &) {
throw;
} catch (uno::Exception & e) {
throw lang::WrappedTargetRuntimeException(
::rtl::OUString::createFromAscii("getPrefixAndSuffix: exception"),
0, uno::makeAny(e));
}
}
// XTextField
::rtl::OUString SAL_CALL
SwXMetaField::getPresentation(sal_Bool bShowCommand)
throw (uno::RuntimeException)
{
vos::OGuard g(Application::GetSolarMutex());
if (bShowCommand)
{
//FIXME ?
return ::rtl::OUString();
}
else
{
// getString should check if this is invalid
const ::rtl::OUString content( this->getString() );
::rtl::OUString prefix;
::rtl::OUString suffix;
getPrefixAndSuffix(GetModel(), this, &prefix, &suffix);
return prefix + content + suffix;
}
}