/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
*
* - GNU Lesser General Public License Version 2.1
* - Sun Industry Standards Source License Version 1.1
*
* Sun Microsystems Inc., October, 2000
*
* GNU Lesser General Public License Version 2.1
* =============================================
* Copyright 2000 by Sun Microsystems, Inc.
* 901 San Antonio Road, Palo Alto, CA 94303, USA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1, as published by the Free Software Foundation.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
*
* Sun Industry Standards Source License Version 1.1
* =================================================
* The contents of this file are subject to the Sun Industry Standards
* Source License Version 1.1 (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.openoffice.org/license.html.
*
* Software provided under this License is provided on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
* WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
* MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
* See the License for the specific provisions governing your rights and
* obligations concerning the Software.
*
* The Initial Developer of the Original Code is: IBM Corporation
*
* Copyright: 2008 by IBM Corporation
*
* All Rights Reserved.
*
* Contributor(s): _______________________________________
*
*
************************************************************************/
/*************************************************************************
* @file
* For LWP filter architecture prototype
************************************************************************/
#include <memory>
#include <boost/cast.hpp>
#include "lwppara.hxx"
#include <lwpglobalmgr.hxx>
#include <lwpfilehdr.hxx>
#include "lwpparaproperty.hxx"
#include <lwptools.hxx>
#include "lwpparastyle.hxx"
#include <xfilter/xffont.hxx>
#include <xfilter/xftextstyle.hxx>
#include <xfilter/xfstylemanager.hxx>
#include <xfilter/xfparagraph.hxx>
#include <xfilter/xftextcontent.hxx>
#include <xfilter/xftextspan.hxx>
#include <xfilter/xfmargins.hxx>
#include <xfilter/xftabstop.hxx>
#include <xfilter/xflinebreak.hxx>
#include <xfilter/xfsection.hxx>
#include <xfilter/xfsectionstyle.hxx>
#include <xfilter/xfcolor.hxx>
#include <xfilter/xfhyperlink.hxx>
#include "lwpcharsetmgr.hxx"
#include "lwpsection.hxx"
#include "lwplayout.hxx"
#include "lwpusewhen.hxx"
#include "lwpbulletstylemgr.hxx"
#include "lwpstory.hxx"
#include "lwpsilverbullet.hxx"
#include <xfilter/xflist.hxx>
#include <xfilter/xfframe.hxx>
#include "lwpdivinfo.hxx"
#include "lwpdoc.hxx"
#include "lwpholder.hxx"
#include "lwppagehint.hxx"
#include <lwpdropcapmgr.hxx>
#include "lwptable.hxx"
#include "lwpcelllayout.hxx"
#include "lwpframelayout.hxx"
#include <set>
// boost::polymorphic_downcast checks and reports (using assert), if the
// cast is incorrect (in debug builds).
using boost::polymorphic_downcast;
/**
* @short get text of paragraph
*/
OUString const & LwpPara::GetContentText(bool bAllText)
{
// rFont = m_FontID;
if (bAllText)
{
m_Fribs.SetPara(this);
m_Fribs.GatherAllText();
return m_AllText;
}
else
return m_Content;
}
/**
* @short set text of paragraph
*/
void LwpPara::SetAllText(const OUString& sText)
{
m_AllText+=sText;
}
/**
* @short set first frib content
*/
void LwpPara::SetFirstFrib(const OUString& Content,sal_uInt32 FontID)
{
m_FontID= FontID;
m_Content=Content;
}
/**
* @short get paragraph xfstyle
*/
XFParaStyle* LwpPara::GetXFParaStyle()
{
XFStyleManager* pXFStyleManager = LwpGlobalMgr::GetInstance()->GetXFStyleManager();
return pXFStyleManager->FindParaStyle(m_StyleName);
}
/**
* @short get drop cap info
*/
void LwpPara::GatherDropcapInfo()
{
m_nLines = m_pDropcapLayout->GetLines();
m_nChars = m_pDropcapLayout->GetChars();
}
/**
* @short get parent paragraph
*/
LwpPara* LwpPara::GetParent()
{
LwpPara* pPara;
sal_uInt16 otherlevel;
sal_uInt16 level = GetLevel();
if (level != 1)
{
pPara = dynamic_cast<LwpPara*>(GetPrevious().obj().get());
std::set<LwpPara*> aSeen;
while (pPara)
{
aSeen.insert(pPara);
otherlevel = pPara->GetLevel();
if ((otherlevel < level) || (otherlevel && (level == 0)))
return pPara;
pPara = dynamic_cast<LwpPara*>(pPara->GetPrevious().obj().get());
if (aSeen.find(pPara) != aSeen.end())
throw std::runtime_error("loop in conversion");
}
}
return nullptr;
}
/**
* @short: Offer prefix, paranumber and suffix according to position.
* @param: nPosition index of wanted paranumbering in the style-list.
* @param: pParaNumbering a pointer to the structure which contains prefix, paranumber and
* suffix.
*/
void LwpPara::GetParaNumber(sal_uInt16 nPosition, ParaNumbering* pParaNumbering)
{
if (nPosition > 9)
{
return;
}
sal_uInt16 nCurrentPos = 0;
LwpFrib* pPreFrib = nullptr;
LwpFrib* pFrib = m_Fribs.GetFribs();
if (!pFrib)
{
return;
}
while (pFrib)
{
sal_uInt8 nFribType = pFrib->GetType();
if (nFribType == FRIB_TAG_PARANUMBER)
{
nCurrentPos++;
ModifierInfo* pModInfo = pFrib->GetModifiers();
if (pModInfo)
{
sal_uInt16 nHideLevels = pModInfo->aTxtAttrOverride.GetHideLevels();
if (nCurrentPos == nPosition)
{
//get prefix text frib
if (pPreFrib)
{
if ((pPreFrib->GetType() == FRIB_TAG_TEXT) &&
(pPreFrib->GetModifiers() && pPreFrib->GetModifiers()->aTxtAttrOverride.GetHideLevels() == nHideLevels))
{
pParaNumbering->pPrefix = static_cast<LwpFribText*>(pPreFrib);
}
}
//get para numbering
pParaNumbering->pParaNumber = static_cast<LwpFribParaNumber*>(pFrib);
pParaNumbering->nNumLevel = nHideLevels;
//get suffix text frib
pFrib = pFrib->GetNext();
if ( pFrib )
{
if( pFrib->GetType() == FRIB_TAG_TEXT )
{
if (
(pFrib->GetNext() && pFrib->GetNext()->GetType() == FRIB_TAG_TEXT) ||
(pFrib->GetModifiers() && pFrib->GetModifiers()->aTxtAttrOverride.GetHideLevels() == nHideLevels)
)
{
pParaNumbering->pSuffix = static_cast<LwpFribText*>(pFrib);
}
}
}
break;
}
}
else
{
if (nCurrentPos == nPosition)
{
//get prefix text frib
if (pPreFrib)
{
if (pPreFrib->GetType() == FRIB_TAG_TEXT)
{
pParaNumbering->pPrefix = static_cast<LwpFribText*>(pPreFrib);
}
}
//get para numbering
pParaNumbering->pParaNumber = static_cast<LwpFribParaNumber*>(pFrib);
//get suffix text frib
pFrib = pFrib->GetNext();
if ( pFrib )
{
if (pFrib->GetType() == FRIB_TAG_TEXT)
{
pParaNumbering->pSuffix = static_cast<LwpFribText*>(pFrib);
}
}
}
}
}
pPreFrib = pFrib;
if (pFrib)
{
pFrib = pFrib->GetNext();
}
}
}
/**
* @short override alignment
*/
void LwpPara::OverrideAlignment(LwpAlignmentOverride* base,LwpAlignmentOverride* over,XFParaStyle* pOverStyle)
{
if (base)//the latter two parameter never be null
{
over->Override(base);
LwpParaStyle::ApplyAlignment(pOverStyle,base);
}
else
LwpParaStyle::ApplyAlignment(pOverStyle,over);
}
/**
* @short override indent attribute
*/
void LwpPara::OverrideIndent(LwpIndentOverride* base,LwpIndentOverride* over,XFParaStyle* pOverStyle)
{
if (base)//the latter two parameter never be null
{
over->Override(base);
LwpParaStyle::ApplyIndent(this,pOverStyle,base);
}
else
{
LwpParaStyle::ApplyIndent(this,pOverStyle,over);
}
}
/**
* @short override spacing
*/
void LwpPara::OverrideSpacing(LwpSpacingOverride* base,LwpSpacingOverride* over,XFParaStyle* pOverStyle)
{
if (base)//the latter two parameter never be null
{
if (over)
over->Override(base);
LwpParaStyle::ApplySpacing(this,pOverStyle,base);
}
else
LwpParaStyle::ApplySpacing(this,pOverStyle,over);
}
/**
* @short: Get parastyle object according to the objID.
* @return: pointer to the parastyle.
*/
LwpParaStyle* LwpPara::GetParaStyle()
{
return dynamic_cast<LwpParaStyle*>(m_ParaStyle.obj(VO_PARASTYLE).get());
}
/**
* @short: Override paraborder style.
* @param: pProps pointer to the LwpParaProperty and we can get local breaks through it.
* @param: pOverStyle pointer to XFParaStyle which contains the parastyle for XFilter.
*/
void LwpPara::OverrideParaBorder(LwpParaProperty* pProps, XFParaStyle* pOverStyle)
{
// get paraborder in parastyle
LwpParaStyle* pParaStyle = GetParaStyle();
if (!pParaStyle)
{
return;
}
LwpOverride* pBorder = pParaStyle->GetParaBorder();
std::unique_ptr<LwpParaBorderOverride> pFinalBorder(
pBorder
? polymorphic_downcast<LwpParaBorderOverride*>(pBorder->clone())
: new LwpParaBorderOverride)
;
// get local border
pBorder = static_cast<LwpParaBorderProperty*>(pProps)->GetLocalParaBorder();
if (pBorder)
{
std::unique_ptr<LwpParaBorderOverride> pLocalBorder(
polymorphic_downcast<LwpParaBorderOverride*>(pBorder->clone()));
pLocalBorder->Override(pFinalBorder.get());
}
LwpParaStyle::ApplyParaBorder(pOverStyle, pFinalBorder.get());
}
/**
* @short: Override parabreaks style.
* @param: pProps pointer to the LwpParaProperty and we can get local breaks through it.
* @param: pOverStyle pointer to XFParaStyle which contains the parastyle for XFilter.
*/
void LwpPara::OverrideParaBreaks(LwpParaProperty* pProps, XFParaStyle* pOverStyle)
{
// get breaks in parastyle
LwpParaStyle* pParaStyle = GetParaStyle();
if (!pParaStyle)
{
return;
}
LwpOverride* pBreaks = pParaStyle->GetBreaks();
std::unique_ptr<LwpBreaksOverride> pFinalBreaks(
pBreaks
? polymorphic_downcast<LwpBreaksOverride*>(pBreaks->clone())
: new LwpBreaksOverride)
;
// get local breaks
pBreaks = static_cast<LwpParaBreaksProperty*>(pProps)->GetLocalParaBreaks();
if (pBreaks)
{
std::unique_ptr<LwpBreaksOverride> const pLocalBreaks(
polymorphic_downcast<LwpBreaksOverride*>(pBreaks->clone()));
pLocalBreaks->Override(pFinalBreaks.get());
}
// save the breaks
m_pBreaks.reset( pFinalBreaks.release() );
XFStyleManager* pXFStyleManager = LwpGlobalMgr::GetInstance()->GetXFStyleManager();
if (m_pBreaks->IsKeepWithNext())
{
pOverStyle->SetBreaks(enumXFBreakKeepWithNext);
}
if (m_pBreaks->IsPageBreakBefore())
{
std::unique_ptr<XFParaStyle> pStyle(new XFParaStyle());
pStyle->SetBreaks(enumXFBreakAftPage);
m_BefPageBreakName = pXFStyleManager->AddStyle(std::move(pStyle)).m_pStyle->GetStyleName();
}
if (m_pBreaks->IsPageBreakAfter())
{
std::unique_ptr<XFParaStyle> pStyle(new XFParaStyle());
pStyle->SetBreaks(enumXFBreakAftPage);
m_AftPageBreakName = pXFStyleManager->AddStyle(std::move(pStyle)).m_pStyle->GetStyleName();
}
if (m_pBreaks->IsColumnBreakBefore())
{
std::unique_ptr<XFParaStyle> pStyle(new XFParaStyle());
pStyle->SetBreaks(enumXFBreakAftColumn);//tmp after, should change when layout read
m_BefColumnBreakName = pXFStyleManager->AddStyle(std::move(pStyle)).m_pStyle->GetStyleName();
}
if (m_pBreaks->IsColumnBreakAfter())
{
std::unique_ptr<XFParaStyle> pStyle(new XFParaStyle());
pStyle->SetBreaks(enumXFBreakAftColumn);
m_AftColumnBreakName = pXFStyleManager->AddStyle(std::move(pStyle)).m_pStyle->GetStyleName();
}
// pParaStyle->ApplyBreaks(pOverStyle, &aFinalBreaks);
}
/**
* @short: Override bullet styles.
* @param: pProps pointer to the LwpParaProperty and we can get local bullet through it.
*/
void LwpPara::OverrideParaBullet(LwpParaProperty* pProps)
{
// get bulletoverride in parastyle
LwpParaStyle* pParaStyle = GetParaStyle();
if (!pParaStyle)
{
return;
}
if (pProps)
{
m_xBullOver.reset(new LwpBulletOverride);
// get local bulletoverride
LwpBulletOverride* pLocalBullet = static_cast<LwpParaBulletProperty*>(pProps)->GetLocalParaBullet();
if (!pLocalBullet)
{
return;
}
LwpObjectID aSilverBulletID = pLocalBullet->GetSilverBullet();
if (aSilverBulletID.IsNull())
{
return;
}
else
{
m_bHasBullet = true;
const LwpOverride* pBullet= pParaStyle->GetBulletOverride();
std::unique_ptr<LwpBulletOverride> xFinalBullet(
pBullet
? polymorphic_downcast<LwpBulletOverride*>(pBullet->clone())
: new LwpBulletOverride)
;
std::unique_ptr<LwpBulletOverride> const pLocalBullet2(pLocalBullet->clone());
pLocalBullet2->Override(xFinalBullet.get());
aSilverBulletID = xFinalBullet->GetSilverBullet();
m_xBullOver = std::move(xFinalBullet);
if (!aSilverBulletID.IsNull())
{
m_pSilverBullet = dynamic_cast<LwpSilverBullet*>(aSilverBulletID.obj(VO_SILVERBULLET).get());
if (m_pSilverBullet)
m_pSilverBullet->SetFoundry(m_pFoundry);
}
m_aSilverBulletID = aSilverBulletID;
}
}
else
{
const LwpBulletOverride* pBullOver = pParaStyle->GetBulletOverride();
if (pBullOver)
{
m_aSilverBulletID = pBullOver->GetSilverBullet();
if (!m_aSilverBulletID.IsNull())
{
m_bHasBullet = true;
m_pSilverBullet = dynamic_cast<LwpSilverBullet*>(m_aSilverBulletID.obj(VO_SILVERBULLET).get());
if (m_pSilverBullet)
m_pSilverBullet->SetFoundry(m_pFoundry);
}
m_xBullOver.reset(pBullOver->clone());
}
}
}
/**
* @short: Override paranumbering properties.
* @param: pProps pointer to the LwpParaProperty and we can get local paranumbering through it.
*/
void LwpPara::OverrideParaNumbering(LwpParaProperty const * pProps)
{
// get numbering override in parastyle
LwpParaStyle* pParaStyle = GetParaStyle();
if (!pParaStyle)
{
return;
}
LwpNumberingOverride* pParaNumbering = pParaStyle->GetNumberingOverride();
std::unique_ptr<LwpNumberingOverride> pOver(new LwpNumberingOverride);
//Override with the local numbering, if any
if (pProps)
{
LwpNumberingOverride* pPropNumbering = static_cast<LwpParaNumberingProperty const *>(pProps)->GetLocalNumbering();
if (pPropNumbering)
{
pOver.reset(pPropNumbering->clone());
}
}
else
{
if (pParaNumbering)
{
pOver.reset(pParaNumbering->clone());
}
}
if (m_nFlags & VALID_LEVEL)
{
pOver->OverrideLevel(m_nLevel);
}
m_xParaNumbering = std::move(pOver);
}
/**************************************************************************
* @descr: Get property according to the property type
**************************************************************************/
LwpParaProperty* LwpPara::GetProperty(sal_uInt32 nPropType)
{
for (auto & i : m_vProps)
if(i->GetType() == nPropType)
{
return i.get();
}
return nullptr;
}
/**************************************************************************
* @descr: Get local tab rack
**************************************************************************/
LwpTabOverride* LwpPara::GetLocalTabOverride()
{
LwpParaProperty* pProp = GetProperty(PP_LOCAL_TABRACK);
if(pProp)
{
return static_cast<LwpParaTabRackProperty*>(pProp)->GetTab();
}
return nullptr;
}
/**
* @descr: Determined which para is earlier in position
*
*/
bool LwpPara::operator< (LwpPara const & Other)
{
return m_nOrdinal < Other.m_nOrdinal;
}
/**
* @descr: If the two layouts in the same para, compare which layout is earlied according to frib order
*
*/
bool LwpPara::ComparePagePosition(LwpVirtualLayout const * pPreLayout, LwpVirtualLayout const * pNextLayout)
{
m_Fribs.SetPara(this);
return m_Fribs.ComparePagePosition(pPreLayout, pNextLayout);
}
/**
* @short check paragraph in cell or not
*/
bool LwpPara::IsInCell()
{
LwpStory *pStory = GetStory();
if (!pStory)
return false;
rtl::Reference<LwpVirtualLayout> xLayout(pStory->GetLayout(nullptr));
return xLayout.is() && xLayout->IsCell();
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
↑ V547 Expression 'pBullet' is always true.
↑ V547 Expression 'pBullOver' is always true.