blob: aff7d25f1851c3d6f11f724d6415d66e2f4c8657 [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 <hintids.hxx>
#include <poolfmt.hxx>
#include "unomid.h"
#include <basic/sbxvar.hxx>
#include <svl/macitem.hxx>
#include <svl/stritem.hxx>
#include <svl/stylepool.hxx>
#include <fmtautofmt.hxx>
#include <fchrfmt.hxx>
#include <fmtinfmt.hxx>
#include <txtatr.hxx>
#include <fmtruby.hxx>
#include <charfmt.hxx>
#include <hints.hxx> // SwUpdateAttr
#include <unostyle.hxx>
#include <unoevent.hxx> // SwHyperlinkEventDescriptor
#include <com/sun/star/text/RubyAdjust.hdl>
#include <cmdid.h>
#include <com/sun/star/uno/Any.h>
#include <SwStyleNameMapper.hxx>
#include <fmtmeta.hxx>
#include <ndtxt.hxx> // for meta
#include <doc.hxx> // for meta
#include <unometa.hxx>
#include <docsh.hxx>
#include <svl/zforlist.hxx> // GetNumberFormat
#include <boost/bind.hpp>
#include <algorithm>
using namespace ::com::sun::star;
using ::rtl::OUString;
TYPEINIT1_AUTOFACTORY(SwFmtINetFmt, SfxPoolItem);
TYPEINIT1_AUTOFACTORY(SwFmtAutoFmt, SfxPoolItem);
/*************************************************************************
|*
|* class SwFmtCharFmt
|* Beschreibung
|* Ersterstellung JP 23.11.90
|* Letzte Aenderung JP 09.08.94
|*
*************************************************************************/
SwFmtCharFmt::SwFmtCharFmt( SwCharFmt *pFmt )
: SfxPoolItem( RES_TXTATR_CHARFMT ),
SwClient(pFmt),
pTxtAttr( 0 )
{
}
SwFmtCharFmt::SwFmtCharFmt( const SwFmtCharFmt& rAttr )
: SfxPoolItem( RES_TXTATR_CHARFMT ),
SwClient( rAttr.GetCharFmt() ),
pTxtAttr( 0 )
{
}
SwFmtCharFmt::~SwFmtCharFmt() {}
int SwFmtCharFmt::operator==( const SfxPoolItem& rAttr ) const
{
ASSERT( SfxPoolItem::operator==( rAttr ), "keine gleichen Attribute" );
return GetCharFmt() == ((SwFmtCharFmt&)rAttr).GetCharFmt();
}
SfxPoolItem* SwFmtCharFmt::Clone( SfxItemPool* ) const
{
return new SwFmtCharFmt( *this );
}
// weiterleiten an das TextAttribut
void SwFmtCharFmt::Modify( const SfxPoolItem* pOld, const SfxPoolItem* pNew )
{
if( pTxtAttr )
pTxtAttr->ModifyNotification( pOld, pNew );
}
// weiterleiten an das TextAttribut
sal_Bool SwFmtCharFmt::GetInfo( SfxPoolItem& rInfo ) const
{
return pTxtAttr ? pTxtAttr->GetInfo( rInfo ) : sal_False;
}
sal_Bool SwFmtCharFmt::QueryValue( uno::Any& rVal, sal_uInt8 ) const
{
String sCharFmtName;
if(GetCharFmt())
SwStyleNameMapper::FillProgName(GetCharFmt()->GetName(), sCharFmtName, nsSwGetPoolIdFromName::GET_POOLID_CHRFMT, sal_True );
rVal <<= OUString( sCharFmtName );
return sal_True;
}
sal_Bool SwFmtCharFmt::PutValue( const uno::Any& , sal_uInt8 )
{
DBG_ERROR("Zeichenvorlage kann mit PutValue nicht gesetzt werden!");
return sal_False;
}
/*************************************************************************
|*
|* class SwFmtAutoFmt
|* Beschreibung
|* Ersterstellung AMA 12.05.06
|* Letzte Aenderung AMA 12.05.06
|*
*************************************************************************/
SwFmtAutoFmt::SwFmtAutoFmt( sal_uInt16 nInitWhich )
: SfxPoolItem( nInitWhich )
{
}
SwFmtAutoFmt::SwFmtAutoFmt( const SwFmtAutoFmt& rAttr )
: SfxPoolItem( rAttr.Which() ), mpHandle( rAttr.mpHandle )
{
}
SwFmtAutoFmt::~SwFmtAutoFmt()
{
}
int SwFmtAutoFmt::operator==( const SfxPoolItem& rAttr ) const
{
ASSERT( SfxPoolItem::operator==( rAttr ), "different attributes" );
return mpHandle == ((SwFmtAutoFmt&)rAttr).mpHandle;
}
SfxPoolItem* SwFmtAutoFmt::Clone( SfxItemPool* ) const
{
return new SwFmtAutoFmt( *this );
}
sal_Bool SwFmtAutoFmt::QueryValue( uno::Any& rVal, sal_uInt8 ) const
{
String sCharFmtName = StylePool::nameOf( mpHandle );
rVal <<= OUString( sCharFmtName );
return sal_True;
}
sal_Bool SwFmtAutoFmt::PutValue( const uno::Any& , sal_uInt8 )
{
//the format is not renameable via API
return sal_False;
}
/*************************************************************************
|*
|* class SwFmtINetFmt
|* Beschreibung
|* Ersterstellung AMA 02.08.96
|* Letzte Aenderung AMA 02.08.96
|*
*************************************************************************/
SwFmtINetFmt::SwFmtINetFmt()
: SfxPoolItem( RES_TXTATR_INETFMT )
, msURL()
, msTargetFrame()
, msINetFmtName()
, msVisitedFmtName()
, msHyperlinkName()
, mpMacroTbl( 0 )
, mpTxtAttr( 0 )
, mnINetFmtId( 0 )
, mnVisitedFmtId( 0 )
{}
SwFmtINetFmt::SwFmtINetFmt( const XubString& rURL, const XubString& rTarget )
: SfxPoolItem( RES_TXTATR_INETFMT )
, msURL( rURL )
, msTargetFrame( rTarget )
, msINetFmtName()
, msVisitedFmtName()
, msHyperlinkName()
, mpMacroTbl( 0 )
, mpTxtAttr( 0 )
, mnINetFmtId( RES_POOLCHR_INET_NORMAL )
, mnVisitedFmtId( RES_POOLCHR_INET_VISIT )
{
SwStyleNameMapper::FillUIName( mnINetFmtId, msINetFmtName );
SwStyleNameMapper::FillUIName( mnVisitedFmtId, msVisitedFmtName );
}
SwFmtINetFmt::SwFmtINetFmt( const SwFmtINetFmt& rAttr )
: SfxPoolItem( RES_TXTATR_INETFMT )
, msURL( rAttr.GetValue() )
, msTargetFrame( rAttr.msTargetFrame )
, msINetFmtName( rAttr.msINetFmtName )
, msVisitedFmtName( rAttr.msVisitedFmtName )
, msHyperlinkName( rAttr.msHyperlinkName )
, mpMacroTbl( 0 )
, mpTxtAttr( 0 )
, mnINetFmtId( rAttr.mnINetFmtId )
, mnVisitedFmtId( rAttr.mnVisitedFmtId )
{
if ( rAttr.GetMacroTbl() )
mpMacroTbl = new SvxMacroTableDtor( *rAttr.GetMacroTbl() );
}
SwFmtINetFmt::~SwFmtINetFmt()
{
delete mpMacroTbl;
}
int SwFmtINetFmt::operator==( const SfxPoolItem& rAttr ) const
{
ASSERT( SfxPoolItem::operator==( rAttr ), "keine gleichen Attribute" );
sal_Bool bRet = SfxPoolItem::operator==( (SfxPoolItem&) rAttr )
&& msURL == ((SwFmtINetFmt&)rAttr).msURL
&& msHyperlinkName == ((SwFmtINetFmt&)rAttr).msHyperlinkName
&& msTargetFrame == ((SwFmtINetFmt&)rAttr).msTargetFrame
&& msINetFmtName == ((SwFmtINetFmt&)rAttr).msINetFmtName
&& msVisitedFmtName == ((SwFmtINetFmt&)rAttr).msVisitedFmtName
&& mnINetFmtId == ((SwFmtINetFmt&)rAttr).mnINetFmtId
&& mnVisitedFmtId == ((SwFmtINetFmt&)rAttr).mnVisitedFmtId;
if( !bRet )
return sal_False;
const SvxMacroTableDtor* pOther = ((SwFmtINetFmt&)rAttr).mpMacroTbl;
if( !mpMacroTbl )
return ( !pOther || !pOther->Count() );
if( !pOther )
return 0 == mpMacroTbl->Count();
const SvxMacroTableDtor& rOwn = *mpMacroTbl;
const SvxMacroTableDtor& rOther = *pOther;
// Anzahl unterschiedlich => auf jeden Fall ungleich
if( rOwn.Count() != rOther.Count() )
return sal_False;
// einzeln vergleichen; wegen Performance ist die Reihenfolge wichtig
for( sal_uInt16 nNo = 0; nNo < rOwn.Count(); ++nNo )
{
const SvxMacro *pOwnMac = rOwn.GetObject(nNo);
const SvxMacro *pOtherMac = rOther.GetObject(nNo);
if ( rOwn.GetKey(pOwnMac) != rOther.GetKey(pOtherMac) ||
pOwnMac->GetLibName() != pOtherMac->GetLibName() ||
pOwnMac->GetMacName() != pOtherMac->GetMacName() )
return sal_False;
}
return sal_True;
}
SfxPoolItem* SwFmtINetFmt::Clone( SfxItemPool* ) const
{
return new SwFmtINetFmt( *this );
}
void SwFmtINetFmt::SetMacroTbl( const SvxMacroTableDtor* pNewTbl )
{
if( pNewTbl )
{
if( mpMacroTbl )
*mpMacroTbl = *pNewTbl;
else
mpMacroTbl = new SvxMacroTableDtor( *pNewTbl );
}
else if( mpMacroTbl )
delete mpMacroTbl, mpMacroTbl = 0;
}
void SwFmtINetFmt::SetMacro( sal_uInt16 nEvent, const SvxMacro& rMacro )
{
if( !mpMacroTbl )
mpMacroTbl = new SvxMacroTableDtor;
SvxMacro *pOldMacro;
if( 0 != ( pOldMacro = mpMacroTbl->Get( nEvent )) )
{
delete pOldMacro;
mpMacroTbl->Replace( nEvent, new SvxMacro( rMacro ) );
}
else
mpMacroTbl->Insert( nEvent, new SvxMacro( rMacro ) );
}
const SvxMacro* SwFmtINetFmt::GetMacro( sal_uInt16 nEvent ) const
{
const SvxMacro* pRet = 0;
if( mpMacroTbl && mpMacroTbl->IsKeyValid( nEvent ) )
pRet = mpMacroTbl->Get( nEvent );
return pRet;
}
sal_Bool SwFmtINetFmt::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const
{
sal_Bool bRet = sal_True;
XubString sVal;
nMemberId &= ~CONVERT_TWIPS;
switch(nMemberId)
{
case MID_URL_URL:
sVal = msURL;
break;
case MID_URL_TARGET:
sVal = msTargetFrame;
break;
case MID_URL_HYPERLINKNAME:
sVal = msHyperlinkName;
break;
case MID_URL_VISITED_FMT:
sVal = msVisitedFmtName;
if( !sVal.Len() && mnVisitedFmtId != 0 )
SwStyleNameMapper::FillUIName( mnVisitedFmtId, sVal );
if( sVal.Len() )
SwStyleNameMapper::FillProgName( sVal, sVal, nsSwGetPoolIdFromName::GET_POOLID_CHRFMT, sal_True );
break;
case MID_URL_UNVISITED_FMT:
sVal = msINetFmtName;
if( !sVal.Len() && mnINetFmtId != 0 )
SwStyleNameMapper::FillUIName( mnINetFmtId, sVal );
if( sVal.Len() )
SwStyleNameMapper::FillProgName( sVal, sVal, nsSwGetPoolIdFromName::GET_POOLID_CHRFMT, sal_True );
break;
case MID_URL_HYPERLINKEVENTS:
{
// create (and return) event descriptor
SwHyperlinkEventDescriptor* pEvents =
new SwHyperlinkEventDescriptor();
pEvents->copyMacrosFromINetFmt(*this);
uno::Reference<container::XNameReplace> xNameReplace(pEvents);
// all others return a string; so we just set rVal here and exit
rVal <<= xNameReplace;
return bRet;
}
default:
break;
}
rVal <<= OUString(sVal);
return bRet;
}
sal_Bool SwFmtINetFmt::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId )
{
sal_Bool bRet = sal_True;
nMemberId &= ~CONVERT_TWIPS;
// all properties except HyperlinkEvents are of type string, hence
// we treat HyperlinkEvents specially
if (MID_URL_HYPERLINKEVENTS == nMemberId)
{
uno::Reference<container::XNameReplace> xReplace;
rVal >>= xReplace;
if (xReplace.is())
{
// Create hyperlink event descriptor. Then copy events
// from argument into descriptor. Then copy events from
// the descriptor into the format.
SwHyperlinkEventDescriptor* pEvents = new SwHyperlinkEventDescriptor();
uno::Reference< lang::XServiceInfo> xHold = pEvents;
pEvents->copyMacrosFromNameReplace(xReplace);
pEvents->copyMacrosIntoINetFmt(*this);
}
else
{
// wrong type!
bRet = sal_False;
}
}
else
{
// all string properties:
if(rVal.getValueType() != ::getCppuType((rtl::OUString*)0))
return sal_False;
XubString sVal = *(rtl::OUString*)rVal.getValue();
switch(nMemberId)
{
case MID_URL_URL:
msURL = sVal;
break;
case MID_URL_TARGET:
msTargetFrame = sVal;
break;
case MID_URL_HYPERLINKNAME:
msHyperlinkName = sVal;
break;
case MID_URL_VISITED_FMT:
{
String aString;
SwStyleNameMapper::FillUIName( sVal, aString, nsSwGetPoolIdFromName::GET_POOLID_CHRFMT, sal_True );
msVisitedFmtName = OUString ( aString );
mnVisitedFmtId = SwStyleNameMapper::GetPoolIdFromUIName( msVisitedFmtName,
nsSwGetPoolIdFromName::GET_POOLID_CHRFMT );
}
break;
case MID_URL_UNVISITED_FMT:
{
String aString;
SwStyleNameMapper::FillUIName( sVal, aString, nsSwGetPoolIdFromName::GET_POOLID_CHRFMT, sal_True );
msINetFmtName = OUString ( aString );
mnINetFmtId = SwStyleNameMapper::GetPoolIdFromUIName( msINetFmtName, nsSwGetPoolIdFromName::GET_POOLID_CHRFMT );
}
break;
default:
bRet = sal_False;
}
}
return bRet;
}
/*************************************************************************
|* class SwFmtRuby
*************************************************************************/
SwFmtRuby::SwFmtRuby( const String& rRubyTxt )
: SfxPoolItem( RES_TXTATR_CJK_RUBY ),
sRubyTxt( rRubyTxt ),
pTxtAttr( 0 ),
nCharFmtId( 0 ),
nPosition( 0 ),
nAdjustment( 0 )
{
}
SwFmtRuby::SwFmtRuby( const SwFmtRuby& rAttr )
: SfxPoolItem( RES_TXTATR_CJK_RUBY ),
sRubyTxt( rAttr.sRubyTxt ),
sCharFmtName( rAttr.sCharFmtName ),
pTxtAttr( 0 ),
nCharFmtId( rAttr.nCharFmtId),
nPosition( rAttr.nPosition ),
nAdjustment( rAttr.nAdjustment )
{
}
SwFmtRuby::~SwFmtRuby()
{
}
SwFmtRuby& SwFmtRuby::operator=( const SwFmtRuby& rAttr )
{
sRubyTxt = rAttr.sRubyTxt;
sCharFmtName = rAttr.sCharFmtName;
nCharFmtId = rAttr.nCharFmtId;
nPosition = rAttr.nPosition;
nAdjustment = rAttr.nAdjustment;
pTxtAttr = 0;
return *this;
}
int SwFmtRuby::operator==( const SfxPoolItem& rAttr ) const
{
ASSERT( SfxPoolItem::operator==( rAttr ), "keine gleichen Attribute" );
return sRubyTxt == ((SwFmtRuby&)rAttr).sRubyTxt &&
sCharFmtName == ((SwFmtRuby&)rAttr).sCharFmtName &&
nCharFmtId == ((SwFmtRuby&)rAttr).nCharFmtId &&
nPosition == ((SwFmtRuby&)rAttr).nPosition &&
nAdjustment == ((SwFmtRuby&)rAttr).nAdjustment;
}
SfxPoolItem* SwFmtRuby::Clone( SfxItemPool* ) const
{
return new SwFmtRuby( *this );
}
sal_Bool SwFmtRuby::QueryValue( uno::Any& rVal,
sal_uInt8 nMemberId ) const
{
sal_Bool bRet = sal_True;
nMemberId &= ~CONVERT_TWIPS;
switch( nMemberId )
{
case MID_RUBY_TEXT: rVal <<= (OUString)sRubyTxt; break;
case MID_RUBY_ADJUST: rVal <<= (sal_Int16)nAdjustment; break;
case MID_RUBY_CHARSTYLE:
{
String aString;
SwStyleNameMapper::FillProgName(sCharFmtName, aString, nsSwGetPoolIdFromName::GET_POOLID_CHRFMT, sal_True );
rVal <<= OUString ( aString );
}
break;
case MID_RUBY_ABOVE:
{
sal_Bool bAbove = !nPosition;
rVal.setValue(&bAbove, ::getBooleanCppuType());
}
break;
default:
bRet = sal_False;
}
return bRet;
}
sal_Bool SwFmtRuby::PutValue( const uno::Any& rVal,
sal_uInt8 nMemberId )
{
sal_Bool bRet = sal_True;
nMemberId &= ~CONVERT_TWIPS;
switch( nMemberId )
{
case MID_RUBY_TEXT:
{
OUString sTmp;
bRet = rVal >>= sTmp;
sRubyTxt = sTmp;
}
break;
case MID_RUBY_ADJUST:
{
sal_Int16 nSet = 0;
rVal >>= nSet;
if(nSet >= 0 && nSet <= text::RubyAdjust_INDENT_BLOCK)
nAdjustment = nSet;
else
bRet = sal_False;
}
break;
case MID_RUBY_ABOVE:
{
const uno::Type& rType = ::getBooleanCppuType();
if(rVal.hasValue() && rVal.getValueType() == rType)
{
sal_Bool bAbove = *(sal_Bool*)rVal.getValue();
nPosition = bAbove ? 0 : 1;
}
}
break;
case MID_RUBY_CHARSTYLE:
{
OUString sTmp;
bRet = rVal >>= sTmp;
if(bRet)
sCharFmtName = SwStyleNameMapper::GetUIName(sTmp, nsSwGetPoolIdFromName::GET_POOLID_CHRFMT );
}
break;
default:
bRet = sal_False;
}
return bRet;
}
/*************************************************************************
class SwFmtMeta
************************************************************************/
SwFmtMeta * SwFmtMeta::CreatePoolDefault(const sal_uInt16 i_nWhich)
{
return new SwFmtMeta(i_nWhich);
}
SwFmtMeta::SwFmtMeta(const sal_uInt16 i_nWhich)
: SfxPoolItem( i_nWhich )
, m_pMeta()
, m_pTxtAttr( 0 )
{
ASSERT((RES_TXTATR_META == i_nWhich) || (RES_TXTATR_METAFIELD == i_nWhich),
"ERROR: SwFmtMeta: invalid which id!");
}
SwFmtMeta::SwFmtMeta( ::boost::shared_ptr< ::sw::Meta > const & i_pMeta,
const sal_uInt16 i_nWhich )
: SfxPoolItem( i_nWhich )
, m_pMeta( i_pMeta )
, m_pTxtAttr( 0 )
{
ASSERT((RES_TXTATR_META == i_nWhich) || (RES_TXTATR_METAFIELD == i_nWhich),
"ERROR: SwFmtMeta: invalid which id!");
ASSERT(m_pMeta, "SwFmtMeta: no Meta ?");
// DO NOT call m_pMeta->SetFmtMeta(this) here; only from SetTxtAttr!
}
SwFmtMeta::~SwFmtMeta()
{
if (m_pMeta && (m_pMeta->GetFmtMeta() == this))
{
NotifyChangeTxtNode(0);
m_pMeta->SetFmtMeta(0);
}
}
int SwFmtMeta::operator==( const SfxPoolItem & i_rOther ) const
{
ASSERT( SfxPoolItem::operator==( i_rOther ), "i just copied this assert" );
return SfxPoolItem::operator==( i_rOther )
&& (m_pMeta == static_cast<SwFmtMeta const &>( i_rOther ).m_pMeta);
}
SfxPoolItem * SwFmtMeta::Clone( SfxItemPool * /*pPool*/ ) const
{
// if this is indeed a copy, then DoCopy must be called later!
return (m_pMeta) // #i105148# pool default may be cloned also!
? new SwFmtMeta( m_pMeta, Which() ) : new SwFmtMeta( Which() );
}
void SwFmtMeta::SetTxtAttr(SwTxtMeta * const i_pTxtAttr)
{
OSL_ENSURE(!(m_pTxtAttr && i_pTxtAttr),
"SwFmtMeta::SetTxtAttr: already has text attribute?");
OSL_ENSURE( m_pTxtAttr || i_pTxtAttr ,
"SwFmtMeta::SetTxtAttr: no attribute to remove?");
m_pTxtAttr = i_pTxtAttr;
OSL_ENSURE(m_pMeta, "inserted SwFmtMeta has no sw::Meta?");
// the sw::Meta must be able to find the current text attribute!
if (m_pMeta)
{
if (i_pTxtAttr)
{
m_pMeta->SetFmtMeta(this);
}
else if (m_pMeta->GetFmtMeta() == this)
{ // text attribute gone => de-register from text node!
NotifyChangeTxtNode(0);
m_pMeta->SetFmtMeta(0);
}
}
}
void SwFmtMeta::NotifyChangeTxtNode(SwTxtNode *const pTxtNode)
{
// N.B.: do not reset m_pTxtAttr here: see call in nodes.cxx,
// where the hint is not deleted!
OSL_ENSURE(m_pMeta, "SwFmtMeta::NotifyChangeTxtNode: no Meta?");
if (m_pMeta && (m_pMeta->GetFmtMeta() == this))
{ // do not call Modify, that would call SwXMeta::Modify!
m_pMeta->NotifyChangeTxtNode(pTxtNode);
}
}
// this SwFmtMeta has been cloned and points at the same sw::Meta as the source
// this method copies the sw::Meta
void SwFmtMeta::DoCopy(::sw::MetaFieldManager & i_rTargetDocManager,
SwTxtNode & i_rTargetTxtNode)
{
OSL_ENSURE(m_pMeta, "DoCopy called for SwFmtMeta with no sw::Meta?");
if (m_pMeta)
{
const ::boost::shared_ptr< ::sw::Meta> pOriginal( m_pMeta );
if (RES_TXTATR_META == Which())
{
m_pMeta.reset( new ::sw::Meta(this) );
}
else
{
::sw::MetaField *const pMetaField(
static_cast< ::sw::MetaField* >(pOriginal.get()));
m_pMeta = i_rTargetDocManager.makeMetaField( this,
pMetaField->m_nNumberFormat, pMetaField->IsFixedLanguage() );
}
// Meta must have a text node before calling RegisterAsCopyOf
m_pMeta->NotifyChangeTxtNode(& i_rTargetTxtNode);
// this cannot be done in Clone: a Clone is not necessarily a copy!
m_pMeta->RegisterAsCopyOf(*pOriginal);
}
}
namespace sw {
/*************************************************************************
class sw::Meta
************************************************************************/
Meta::Meta(SwFmtMeta * const i_pFmt)
: ::sfx2::Metadatable()
, SwModify()
, m_pFmt( i_pFmt )
{
}
Meta::~Meta()
{
}
SwTxtMeta * Meta::GetTxtAttr() const
{
return (m_pFmt) ? m_pFmt->GetTxtAttr() : 0;
}
SwTxtNode * Meta::GetTxtNode() const
{
return m_pTxtNode;
}
void Meta::NotifyChangeTxtNodeImpl()
{
if (m_pTxtNode && (GetRegisteredIn() != m_pTxtNode))
{
m_pTxtNode->Add(this);
}
else if (!m_pTxtNode && GetRegisteredIn())
{
GetRegisteredInNonConst()->Remove(this);
}
}
void Meta::NotifyChangeTxtNode(SwTxtNode *const pTxtNode)
{
m_pTxtNode = pTxtNode;
NotifyChangeTxtNodeImpl();
if (!pTxtNode) // text node gone? invalidate UNO object!
{
SwPtrMsgPoolItem aMsgHint( RES_REMOVE_UNO_OBJECT,
&static_cast<SwModify&>(*this) ); // cast to base class!
this->Modify(&aMsgHint, &aMsgHint);
}
}
// SwClient
void Meta::Modify( const SfxPoolItem *pOld, const SfxPoolItem *pNew )
{
NotifyClients(pOld, pNew);
if (pOld && (RES_REMOVE_UNO_OBJECT == pOld->Which()))
{ // invalidate cached uno object
SetXMeta(uno::Reference<rdf::XMetadatable>(0));
}
}
// sfx2::Metadatable
::sfx2::IXmlIdRegistry& Meta::GetRegistry()
{
SwTxtNode * const pTxtNode( GetTxtNode() );
// GetRegistry may only be called on a meta that is actually in the
// document, which means it has a pointer to its text node
OSL_ENSURE(pTxtNode, "ERROR: GetRegistry: no text node?");
if (!pTxtNode)
throw uno::RuntimeException();
return pTxtNode->GetRegistry();
}
bool Meta::IsInClipboard() const
{
const SwTxtNode * const pTxtNode( GetTxtNode() );
// no text node: in UNDO OSL_ENSURE(pTxtNode, "IsInClipboard: no text node?");
return (pTxtNode) ? pTxtNode->IsInClipboard() : false;
}
bool Meta::IsInUndo() const
{
const SwTxtNode * const pTxtNode( GetTxtNode() );
// no text node: in UNDO OSL_ENSURE(pTxtNode, "IsInUndo: no text node?");
return (pTxtNode) ? pTxtNode->IsInUndo() : true;
}
bool Meta::IsInContent() const
{
const SwTxtNode * const pTxtNode( GetTxtNode() );
OSL_ENSURE(pTxtNode, "IsInContent: no text node?");
return (pTxtNode) ? pTxtNode->IsInContent() : true;
}
::com::sun::star::uno::Reference< ::com::sun::star::rdf::XMetadatable >
Meta::MakeUnoObject()
{
return SwXMeta::CreateXMeta(*this);
}
/*************************************************************************
class sw::MetaField
************************************************************************/
MetaField::MetaField(SwFmtMeta * const i_pFmt,
const sal_uInt32 nNumberFormat, const bool bIsFixedLanguage)
: Meta(i_pFmt)
, m_nNumberFormat( nNumberFormat )
, m_bIsFixedLanguage( bIsFixedLanguage )
{
}
void MetaField::GetPrefixAndSuffix(
::rtl::OUString *const o_pPrefix, ::rtl::OUString *const o_pSuffix)
{
try
{
const uno::Reference<rdf::XMetadatable> xMetaField( MakeUnoObject() );
OSL_ENSURE(dynamic_cast<SwXMetaField*>(xMetaField.get()),
"GetPrefixAndSuffix: no SwXMetaField?");
if (xMetaField.is())
{
SwTxtNode * const pTxtNode( GetTxtNode() );
SwDocShell const * const pShell(pTxtNode->GetDoc()->GetDocShell());
const uno::Reference<frame::XModel> xModel(
(pShell) ? pShell->GetModel() : 0, uno::UNO_SET_THROW);
getPrefixAndSuffix(xModel, xMetaField, o_pPrefix, o_pSuffix);
}
} catch (uno::Exception) {
OSL_ENSURE(false, "exception?");
}
}
sal_uInt32 MetaField::GetNumberFormat(::rtl::OUString const & rContent) const
{
//TODO: this probably lacks treatment for some special cases
sal_uInt32 nNumberFormat( m_nNumberFormat );
SwTxtNode * const pTxtNode( GetTxtNode() );
if (pTxtNode)
{
SvNumberFormatter *const pNumberFormatter(
pTxtNode->GetDoc()->GetNumberFormatter() );
double number;
(void) pNumberFormatter->IsNumberFormat(
rContent, nNumberFormat, number );
}
return nNumberFormat;
}
void MetaField::SetNumberFormat(sal_uInt32 nNumberFormat)
{
// effectively, the member is only a default:
// GetNumberFormat checks if the text actually conforms
m_nNumberFormat = nNumberFormat;
}
/*************************************************************************
class sw::MetaFieldManager
************************************************************************/
MetaFieldManager::MetaFieldManager()
{
}
::boost::shared_ptr<MetaField>
MetaFieldManager::makeMetaField(SwFmtMeta * const i_pFmt,
const sal_uInt32 nNumberFormat, const bool bIsFixedLanguage)
{
const ::boost::shared_ptr<MetaField> pMetaField(
new MetaField(i_pFmt, nNumberFormat, bIsFixedLanguage) );
m_MetaFields.push_back(pMetaField);
return pMetaField;
}
struct IsInUndo
{
bool operator()(::boost::weak_ptr<MetaField> const & pMetaField) {
return pMetaField.lock()->IsInUndo();
}
};
struct MakeUnoObject
{
uno::Reference<text::XTextField>
operator()(::boost::weak_ptr<MetaField> const & pMetaField) {
return uno::Reference<text::XTextField>(
pMetaField.lock()->MakeUnoObject(), uno::UNO_QUERY);
}
};
::std::vector< uno::Reference<text::XTextField> >
MetaFieldManager::getMetaFields()
{
// erase deleted fields
const MetaFieldList_t::iterator iter(
::std::remove_if(m_MetaFields.begin(), m_MetaFields.end(),
::boost::bind(&::boost::weak_ptr<MetaField>::expired, _1)));
m_MetaFields.erase(iter, m_MetaFields.end());
// filter out fields in UNDO
MetaFieldList_t filtered(m_MetaFields.size());
const MetaFieldList_t::iterator iter2(
::std::remove_copy_if(m_MetaFields.begin(), m_MetaFields.end(),
filtered.begin(), IsInUndo()));
filtered.erase(iter2, filtered.end());
// create uno objects
::std::vector< uno::Reference<text::XTextField> > ret(filtered.size());
::std::transform(filtered.begin(), filtered.end(), ret.begin(),
MakeUnoObject());
return ret;
}
} // namespace sw