/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* 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 .
*/
#include <hintids.hxx>
#include <hints.hxx>
#include <osl/diagnose.h>
#include <txtinet.hxx>
#include <txtatr.hxx>
#include <fchrfmt.hxx>
#include <fmtinfmt.hxx>
#include <charfmt.hxx>
#include <ndtxt.hxx>
#include <poolfmt.hxx>
#include <doc.hxx>
#include <fmtruby.hxx>
#include <fmtmeta.hxx>
#include <IDocumentState.hxx>
#include <IDocumentStylePoolAccess.hxx>
namespace {
bool lcl_CheckAutoFormatHint(
const SfxHint& rHint)
{
if (rHint.GetId() != SfxHintId::SwAutoFormatUsedHint)
return false ;
auto & rAutoFormatUsed =
static_cast <
const sw::AutoFormatUsedHint&>(rHint);
rAutoFormatUsed.SetUsed();
return true ;
}
bool lcl_CheckAutoFormatHint(
const SfxHint& rHint,
const SwTextNode* pTextNode)
{
if (rHint.GetId() != SfxHintId::SwAutoFormatUsedHint)
return false ;
auto & rAutoFormatUsed =
static_cast <
const sw::AutoFormatUsedHint&>(rHint);
rAutoFormatUsed.CheckNode(pTextNode);
return true ;
}
}
SwTextCharFormat::SwTextCharFormat(
const SfxPoolItemHolder& rAttr,
sal_Int32 nStt,
sal_Int32 nEnd )
: SwTextAttr( rAttr, nStt )
, SwTextAttrEnd( rAttr, nStt, nEnd )
, m_pTextNode( nullptr )
, m_nSortNumber( 0 )
{
SwFormatCharFormat& rSwFormatCharFormat(
static_cast <SwFormatCharFormat&>(GetA
ttr()));
rSwFormatCharFormat.m_pTextAttribute = this ;
SetCharFormatAttr( true );
}
SwTextCharFormat::~SwTextCharFormat( )
{
}
void SwTextCharFormat::TriggerNodeUpdate(const sw::LegacyModifyHint& rHint)
{
const auto nWhich = rHint.GetWhich();
assert( isCHRATR(nWhich) && "SwTextCharFormat::TriggerNodeUpdate: unknown hint type" );
if (m_pTextNode)
{
SwUpdateAttr aUpdateAttr(
GetStart(),
*GetEnd(),
nWhich);
m_pTextNode->TriggerNodeUpdate(sw::UpdateAttrHint(&aUpdateAttr, &aUpdateAttr));
}
}
void SwTextCharFormat::TriggerNodeUpdate(const sw::ObjectDyingHint& /*rHint*/)
{
if (m_pTextNode)
{
SwUpdateAttr aUpdateAttr(
GetStart(),
*GetEnd(),
RES_UPDATEATTR_OBJECTDYING);
m_pTextNode->TriggerNodeUpdate(sw::UpdateAttrHint(&aUpdateAttr, &aUpdateAttr));
}
}
void SwTextCharFormat::TriggerNodeUpdate(const sw::AttrSetChangeHint& /*rHint*/)
{
if (m_pTextNode)
{
SwUpdateAttr aUpdateAttr(
GetStart(),
*GetEnd(),
RES_UPDATEATTR_ATTRSET_CHG);
m_pTextNode->TriggerNodeUpdate(sw::UpdateAttrHint(&aUpdateAttr, &aUpdateAttr));
}
}
void SwTextCharFormat::TriggerNodeUpdate(const SwFormatChangeHint&)
{
if (m_pTextNode)
{
SwUpdateAttr aUpdateAttr(
GetStart(),
*GetEnd(),
RES_UPDATEATTR_FMT_CHG);
m_pTextNode->TriggerNodeUpdate(sw::UpdateAttrHint(&aUpdateAttr, &aUpdateAttr));
}
}
void SwTextCharFormat::HandleAutoFormatUsedHint(const sw::AutoFormatUsedHint& rHint)
{
rHint.CheckNode(m_pTextNode);
}
SwTextAttrNesting::SwTextAttrNesting(
const SfxPoolItemHolder& i_rAttr,
const sal_Int32 i_nStart,
const sal_Int32 i_nEnd )
: SwTextAttr( i_rAttr, i_nStart )
, SwTextAttrEnd( i_rAttr, i_nStart, i_nEnd )
{
SetDontExpand( true ); // never expand this attribute
// lock the expand flag: simple guarantee that nesting will not be
// invalidated by expand operations
SetLockExpandFlag( true );
SetDontExpandStartAttr( true );
SetNesting( true );
}
SwTextAttrNesting::~SwTextAttrNesting()
{
}
SwTextINetFormat::SwTextINetFormat(
const SfxPoolItemHolder& rAttr,
sal_Int32 nStart,
sal_Int32 nEnd )
: SwTextAttr( rAttr, nStart )
, SwTextAttrNesting( rAttr, nStart, nEnd )
, SwClient( nullptr )
, m_pTextNode( nullptr )
, m_bVisited( false )
, m_bVisitedValid( false )
{
SwFormatINetFormat& rSwFormatINetFormat(static_cast <SwFormatINetFormat&>(GetAttr()));
rSwFormatINetFormat.mpTextAttr = this ;
SetCharFormatAttr( true );
}
SwTextINetFormat::~SwTextINetFormat( )
{
}
SwCharFormat* SwTextINetFormat::GetCharFormat()
{
const SwFormatINetFormat& rFormat = SwTextAttrEnd::GetINetFormat();
SwCharFormat* pRet = nullptr;
if (!rFormat.GetValue().isEmpty())
{
SwDoc& rDoc = GetTextNode().GetDoc();
if ( !IsVisitedValid() )
{
SetVisited( rDoc.IsVisitedURL( rFormat.GetValue() ) );
SetVisitedValid( true );
}
const sal_uInt16 nId = IsVisited() ? rFormat.GetVisitedFormatId() : rFormat.GetINetFormatId();
const UIName& rStr = IsVisited() ? rFormat.GetVisitedFormat() : rFormat.GetINetFormat();
if (rStr.isEmpty())
{
OSL_ENSURE( false , " - missing character format at hyperlink attribute" );
}
// JP 10.02.2000, Bug 72806: don't modify the doc for getting the
// correct charstyle.
bool bModifiedEnabled = rDoc.getIDocumentState().IsEnableSetModified();
rDoc.getIDocumentState().SetEnableSetModified(false );
pRet = IsPoolUserFormat( nId )
? rDoc.FindCharFormatByName( rStr )
: rDoc.getIDocumentStylePoolAccess().GetCharFormatFromPool( nId );
rDoc.getIDocumentState().SetEnableSetModified(bModifiedEnabled);
}
if ( pRet )
pRet->Add(*this );
else
EndListeningAll();
return pRet;
}
void SwTextINetFormat::SwClientNotify(const SwModify&, const SfxHint& rHint)
{
if (lcl_CheckAutoFormatHint(rHint))
return ;
if (rHint.GetId() == SfxHintId::SwFormatChange)
{
if (!m_pTextNode)
return ;
const SwUpdateAttr aUpdateAttr(GetStart(), *GetEnd(), RES_UPDATEATTR_FMT_CHG);
m_pTextNode->TriggerNodeUpdate(sw::UpdateAttrHint(&aUpdateAttr, &aUpdateAttr));
}
else if (rHint.GetId() == SfxHintId::SwAttrSetChange)
{
if (!m_pTextNode)
return ;
const SwUpdateAttr aUpdateAttr(GetStart(), *GetEnd(), RES_UPDATEATTR_ATTRSET_CHG);
m_pTextNode->TriggerNodeUpdate(sw::UpdateAttrHint(&aUpdateAttr, &aUpdateAttr));
}
else if (rHint.GetId() == SfxHintId::SwObjectDying)
{
if (!m_pTextNode)
return ;
const SwUpdateAttr aUpdateAttr(GetStart(), *GetEnd(), RES_UPDATEATTR_OBJECTDYING);
m_pTextNode->TriggerNodeUpdate(sw::UpdateAttrHint(&aUpdateAttr, &aUpdateAttr));
}
else if (rHint.GetId() == SfxHintId::SwLegacyModify)
{
auto pLegacy = static_cast <const sw::LegacyModifyHint*>(&rHint);
const auto nWhich = pLegacy->GetWhich();
assert(isCHRATR(nWhich) && "SwTextINetFormat::SwClientNotify: unknown hint." );
if (!m_pTextNode)
return ;
const SwUpdateAttr aUpdateAttr(GetStart(), *GetEnd(), nWhich);
m_pTextNode->TriggerNodeUpdate(sw::UpdateAttrHint(&aUpdateAttr, &aUpdateAttr));
}
}
bool SwTextINetFormat::IsProtect( ) const
{
return m_pTextNode && m_pTextNode->IsProtect();
}
SwTextRuby::SwTextRuby(
const SfxPoolItemHolder& rAttr,
sal_Int32 nStart,
sal_Int32 nEnd )
: SwTextAttr( rAttr, nStart )
, SwTextAttrNesting( rAttr, nStart, nEnd )
, m_pTextNode( nullptr )
{
SwFormatRuby& rSwFormatRuby(static_cast <SwFormatRuby&>(GetAttr()));
rSwFormatRuby.m_pTextAttr = this ;
}
SwTextRuby::~SwTextRuby()
{
}
void SwTextRuby::Notify(const SfxHint& rHint)
{
if (lcl_CheckAutoFormatHint(rHint, m_pTextNode))
return ;
sal_uInt16 nWhich = 0;
switch (rHint.GetId())
{
case SfxHintId::SwAttrSetChange: nWhich = RES_UPDATEATTR_ATTRSET_CHG; break ;
case SfxHintId::SwFormatChange: nWhich = RES_UPDATEATTR_FMT_CHG; break ;
case SfxHintId::SwObjectDying: nWhich = RES_UPDATEATTR_OBJECTDYING; break ;
case SfxHintId::SwLegacyModify:
{
auto pLegacy = static_cast <const sw::LegacyModifyHint*>(&rHint);
nWhich = pLegacy->GetWhich();
assert( isCHRATR(nWhich) && "SwTextRuby::SwClientNotify(): unknown legacy hint" );
break ;
}
default : break ;
}
if (!m_pTextNode || !nWhich)
return ;
SwUpdateAttr aUpdateAttr(GetStart(), *GetEnd(), nWhich);
m_pTextNode->TriggerNodeUpdate(sw::UpdateAttrHint(&aUpdateAttr, &aUpdateAttr));
}
SwCharFormat* SwTextRuby::GetCharFormat()
{
const SwFormatRuby& rFormat = SwTextAttrEnd::GetRuby();
SwCharFormat* pRet = nullptr;
if ( !rFormat.GetText().isEmpty() )
{
const SwDoc& rDoc = GetTextNode().GetDoc();
const UIName& rStr = rFormat.GetCharFormatName();
const sal_uInt16 nId = rStr.isEmpty()
? o3tl::narrowing<sal_uInt16>(RES_POOLCHR_RUBYTEXT)
: rFormat.GetCharFormatId();
// JP 10.02.2000, Bug 72806: don't modify the doc for getting the
// correct charstyle.
const bool bResetMod = !rDoc.getIDocumentState().IsModified();
Link<bool ,void > aOle2Lnk;
if ( bResetMod )
{
aOle2Lnk = rDoc.GetOle2Link();
const_cast <SwDoc&>(rDoc).SetOle2Link( Link<bool ,void >() );
}
pRet = IsPoolUserFormat( nId )
? rDoc.FindCharFormatByName( rStr )
: const_cast <SwDoc&>(rDoc).getIDocumentStylePoolAccess().GetCharFormatFromPool( nId );
if ( bResetMod )
{
const_cast <SwDoc&>(rDoc).getIDocumentState().ResetModified();
const_cast <SwDoc&>(rDoc).SetOle2Link( aOle2Lnk );
}
}
EndListeningAll();
if (pRet)
StartListening(pRet->GetNotifier());
return pRet;
}
SwTextMeta *
SwTextMeta::CreateTextMeta(
::sw::MetaFieldManager & i_rTargetDocManager,
SwTextNode *const i_pTargetTextNode,
const SfxPoolItemHolder& i_rAttr,
sal_Int32 const i_nStart,
sal_Int32 const i_nEnd,
bool const i_bIsCopy)
{
if (i_bIsCopy)
{ // i_rAttr is already cloned, now call DoCopy to copy the sw::Meta
assert(i_pTargetTextNode && "cannot copy Meta without target node" );
SwFormatMeta* pSwFormatMeta(static_cast <SwFormatMeta*>(const_cast <SfxPoolItem*>(i_rAttr.getItem())));
pSwFormatMeta->DoCopy(i_rTargetDocManager, *i_pTargetTextNode);
}
SwTextMeta *const pTextMeta(new SwTextMeta(i_rAttr, i_nStart, i_nEnd));
return pTextMeta;
}
SwTextMeta::SwTextMeta(
const SfxPoolItemHolder& i_rAttr,
const sal_Int32 i_nStart,
const sal_Int32 i_nEnd )
: SwTextAttr( i_rAttr, i_nStart )
, SwTextAttrNesting( i_rAttr, i_nStart, i_nEnd )
{
SwFormatMeta& rSwFormatMeta(static_cast <SwFormatMeta&>(GetAttr()));
rSwFormatMeta.SetTextAttr( this );
SetHasDummyChar(true );
}
SwTextMeta::~SwTextMeta()
{
SwFormatMeta & rFormatMeta( static_cast <SwFormatMeta &>(GetAttr()) );
if (rFormatMeta.GetTextAttr() == this )
{
rFormatMeta.SetTextAttr(nullptr);
}
}
void SwTextMeta::ChgTextNode(SwTextNode * const pNode)
{
SwFormatMeta & rFormatMeta( static_cast <SwFormatMeta &>(GetAttr()) );
if (rFormatMeta.GetTextAttr() == this )
{
rFormatMeta.NotifyChangeTextNode(pNode);
}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Messung V0.5 C=93 H=94 G=93
¤ Dauer der Verarbeitung: 0.14 Sekunden
(vorverarbeitet)
¤
*© Formatika GbR, Deutschland