Files
libreoffice/sw/source/core/text/xmldump.cxx
Caolán McNamara afe5672fbc cppcheck: noExplicitConstructor
Change-Id: I27c24d3284a8e0678fc5c041426b4a7e71cbd363
2015-05-27 13:54:54 +01:00

467 lines
16 KiB
C++

/* -*- 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/.
*/
#include "frame.hxx"
#include "frmfmt.hxx"
#include "sectfrm.hxx"
#include "tabfrm.hxx"
#include "txtfrm.hxx"
#include "hffrm.hxx"
#include "rootfrm.hxx"
#include "editsh.hxx"
#include "porlin.hxx"
#include "porlay.hxx"
#include "portxt.hxx"
#include "sortedobjs.hxx"
#include <anchoredobject.hxx>
#include <libxml/xmlwriter.h>
#include <SwPortionHandler.hxx>
class XmlPortionDumper:public SwPortionHandler
{
private:
xmlTextWriterPtr writer;
sal_Int32 ofs;
static const char* getTypeName( sal_uInt16 nType )
{
switch ( nType )
{
case POR_LIN: return "POR_LIN";
case POR_FLYCNT: return "POR_FLYCNT";
case POR_HOLE: return "POR_HOLE";
case POR_TMPEND: return "POR_TMPEND";
case POR_BRK: return "POR_BRK";
case POR_KERN: return "POR_KERN";
case POR_ARROW: return "POR_ARROW";
case POR_MULTI: return "POR_MULTI";
case POR_HIDDEN_TXT: return "POR_HIDDEN_TXT";
case POR_CONTROLCHAR: return "POR_CONTROLCHAR";
case POR_TXT: return "POR_TXT";
case POR_LAY: return "POR_LAY";
case POR_PARA: return "POR_PARA";
case POR_URL: return "POR_URL";
case POR_HNG: return "POR_HNG";
case POR_DROP: return "POR_DROP";
case POR_TOX: return "POR_TOX";
case POR_ISOTOX: return "POR_ISOTOX";
case POR_REF: return "POR_REF";
case POR_ISOREF: return "POR_ISOREF";
case POR_META: return "POR_META";
case POR_EXP: return "POR_EXP";
case POR_BLANK: return "POR_BLANK";
case POR_POSTITS: return "POR_POSTITS";
case POR_HYPH: return "POR_HYPH";
case POR_HYPHSTR: return "POR_HYPHSTR";
case POR_SOFTHYPH: return "POR_SOFTHYPH";
case POR_SOFTHYPHSTR: return "POR_SOFTHYPHSTR";
case POR_SOFTHYPH_COMP: return "POR_SOFTHYPH_COMP";
case POR_FLD: return "POR_FLD";
case POR_HIDDEN: return "POR_HIDDEN";
case POR_QUOVADIS: return "POR_QUOVADIS";
case POR_ERGOSUM: return "POR_ERGOSUM";
case POR_COMBINED: return "POR_COMBINED";
case POR_FTN: return "POR_FTN";
case POR_FTNNUM: return "POR_FTNNUM";
case POR_NUMBER: return "POR_NUMBER";
case POR_BULLET: return "POR_BULLET";
case POR_GRFNUM: return "POR_GRFNUM";
case POR_GLUE: return "POR_GLUE";
case POR_MARGIN: return "POR_MARGIN";
case POR_FIX: return "POR_FIX";
case POR_FLY: return "POR_FLY";
case POR_TAB: return "POR_TAB";
case POR_TABRIGHT: return "POR_TABRIGHT";
case POR_TABCENTER: return "POR_TABCENTER";
case POR_TABDECIMAL: return "POR_TABDECIMAL";
case POR_TABLEFT: return "POR_TABLEFT";
default:
return "Unknown";
}
}
public:
explicit XmlPortionDumper( xmlTextWriterPtr some_writer ):writer( some_writer ), ofs( 0 )
{
}
virtual ~ XmlPortionDumper( )
{
}
/**
@param nLength
length of this portion in the model string
@param rText
text which is painted on-screen
*/
virtual void Text( sal_Int32 nLength,
sal_uInt16 nType,
sal_Int32 nHeight,
sal_Int32 nWidth) SAL_OVERRIDE
{
ofs += nLength;
xmlTextWriterStartElement( writer, BAD_CAST( "Text" ) );
xmlTextWriterWriteFormatAttribute( writer,
BAD_CAST( "nLength" ),
"%i", ( int ) nLength );
xmlTextWriterWriteFormatAttribute( writer,
BAD_CAST( "nType" ),
"%s", getTypeName( nType ) );
if (nHeight > 0)
xmlTextWriterWriteFormatAttribute(writer, BAD_CAST("nHeight"), "%i", (int)nHeight);
if (nWidth > 0)
xmlTextWriterWriteFormatAttribute(writer, BAD_CAST("nWidth"), "%i", (int)nWidth);
xmlTextWriterEndElement( writer );
}
/**
@param nLength
length of this portion in the model string
@param rText
text which is painted on-screen
@param nType
type of this portion
@param nHeight
font size of the painted text
*/
virtual void Special( sal_Int32 nLength,
const OUString & rText,
sal_uInt16 nType,
sal_Int32 nHeight,
sal_Int32 nWidth,
const SwFont* pFont ) SAL_OVERRIDE
{
xmlTextWriterStartElement( writer, BAD_CAST( "Special" ) );
xmlTextWriterWriteFormatAttribute( writer,
BAD_CAST( "nLength" ),
"%i", ( int ) nLength );
xmlTextWriterWriteFormatAttribute( writer,
BAD_CAST( "nType" ),
"%s", getTypeName( nType ) );
OUString sText( rText );
OString sText8 =OUStringToOString( sText,
RTL_TEXTENCODING_UTF8 );
xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "rText" ),
"%s", sText8.getStr( ) );
if (nHeight > 0)
xmlTextWriterWriteFormatAttribute(writer, BAD_CAST("nHeight"), "%i", (int)nHeight);
if (nWidth > 0)
xmlTextWriterWriteFormatAttribute(writer, BAD_CAST("nWidth"), "%i", (int)nWidth);
if (pFont)
pFont->dumpAsXml(writer);
xmlTextWriterEndElement( writer );
ofs += nLength;
}
virtual void LineBreak( sal_Int32 nWidth ) SAL_OVERRIDE
{
xmlTextWriterStartElement( writer, BAD_CAST( "LineBreak" ) );
if (nWidth > 0)
xmlTextWriterWriteFormatAttribute( writer,
BAD_CAST( "nWidth" ),
"%i", ( int ) nWidth );
xmlTextWriterEndElement( writer );
}
/**
* @param nLength
* number of 'model string' characters to be skipped
*/
virtual void Skip( sal_Int32 nLength ) SAL_OVERRIDE
{
xmlTextWriterStartElement( writer, BAD_CAST( "Skip" ) );
xmlTextWriterWriteFormatAttribute( writer,
BAD_CAST( "nLength" ),
"%i", ( int ) nLength );
xmlTextWriterEndElement( writer );
ofs += nLength;
}
virtual void Finish( ) SAL_OVERRIDE
{
xmlTextWriterStartElement( writer, BAD_CAST( "Finish" ) );
xmlTextWriterEndElement( writer );
}
};
namespace
{
xmlTextWriterPtr lcl_createDefaultWriter()
{
xmlTextWriterPtr writer = xmlNewTextWriterFilename( "layout.xml", 0 );
xmlTextWriterStartDocument( writer, NULL, NULL, NULL );
return writer;
}
void lcl_freeWriter( xmlTextWriterPtr writer )
{
xmlTextWriterEndDocument( writer );
xmlFreeTextWriter( writer );
}
}
void SwFrm::dumpAsXml( xmlTextWriterPtr writer ) const
{
bool bCreateWriter = ( NULL == writer );
if ( bCreateWriter )
writer = lcl_createDefaultWriter();
const char *name = NULL;
switch ( GetType( ) )
{
case FRM_ROOT:
name = "root";
break;
case FRM_PAGE:
name = "page";
break;
case FRM_COLUMN:
name = "column";
break;
case FRM_HEADER:
name = "header";
break;
case FRM_FOOTER:
name = "footer";
break;
case FRM_FTNCONT:
name = "ftncont";
break;
case FRM_FTN:
name = "ftn";
break;
case FRM_BODY:
name = "body";
break;
case FRM_FLY:
name = "fly";
break;
case FRM_SECTION:
name = "section";
break;
case FRM_UNUSED:
name = "unused";
break;
case FRM_TAB:
name = "tab";
break;
case FRM_ROW:
name = "row";
break;
case FRM_CELL:
name = "cell";
break;
case FRM_TXT:
name = "txt";
break;
case FRM_NOTXT:
name = "notxt";
break;
};
if ( name != NULL )
{
xmlTextWriterStartElement( writer, reinterpret_cast<const xmlChar *>(name) );
dumpAsXmlAttributes( writer );
if (IsRootFrm())
{
// Root frame has access to the edit shell, so dump the current selection ranges here.
const SwRootFrm* const pRootFrm = static_cast<const SwRootFrm* const>(this);
SwEditShell* pEditShell = pRootFrm->GetCurrShell()->GetDoc()->GetEditShell();
xmlTextWriterStartElement(writer, BAD_CAST("shellCrsr"));
for (SwPaM& rPaM : pEditShell->getShellCrsr(false)->GetRingContainer())
rPaM.dumpAsXml(writer);
xmlTextWriterEndElement(writer);
}
xmlTextWriterStartElement( writer, BAD_CAST( "infos" ) );
dumpInfosAsXml( writer );
xmlTextWriterEndElement( writer );
// Dump Anchored objects if any
const SwSortedObjs* pAnchored = GetDrawObjs();
if ( pAnchored && pAnchored->size() > 0 )
{
xmlTextWriterStartElement( writer, BAD_CAST( "anchored" ) );
for ( size_t i = 0, len = pAnchored->size(); i < len; ++i )
{
SwAnchoredObject* pObject = (*pAnchored)[i];
pObject->dumpAsXml( writer );
}
xmlTextWriterEndElement( writer );
}
// Dump the children
if ( IsTextFrm( ) )
{
const SwTextFrm *pTextFrm = static_cast<const SwTextFrm *>(this);
OUString aText = pTextFrm->GetText( );
for ( int i = 0; i < 32; i++ )
{
aText = aText.replace( i, '*' );
}
OString aText8 =OUStringToOString( aText,
RTL_TEXTENCODING_UTF8 );
xmlTextWriterWriteString( writer,
reinterpret_cast<const xmlChar *>(aText8.getStr( )) );
XmlPortionDumper pdumper( writer );
pTextFrm->VisitPortions( pdumper );
}
else
{
dumpChildrenAsXml( writer );
}
xmlTextWriterEndElement( writer );
}
if ( bCreateWriter )
lcl_freeWriter( writer );
}
void SwFrm::dumpInfosAsXml( xmlTextWriterPtr writer ) const
{
// output the Frm
xmlTextWriterStartElement( writer, BAD_CAST( "bounds" ) );
xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "left" ), "%ld", Frm().Left() );
xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "top" ), "%ld", Frm().Top() );
xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "width" ), "%ld", Frm().Width() );
xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "height" ), "%ld", Frm().Height() );
xmlTextWriterEndElement( writer );
}
// Hack: somehow conversion from "..." to va_list does
// bomb on two string litterals in the format.
static const char* TMP_FORMAT = "%" SAL_PRIuUINTPTR;
void SwFrm::dumpAsXmlAttributes( xmlTextWriterPtr writer ) const
{
xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "ptr" ), "%p", this );
xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "id" ), "%" SAL_PRIuUINT32, GetFrmId() );
xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "symbol" ), "%s", BAD_CAST( typeid( *this ).name( ) ) );
if ( GetNext( ) )
xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "next" ), "%" SAL_PRIuUINT32, GetNext()->GetFrmId() );
if ( GetPrev( ) )
xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "prev" ), "%" SAL_PRIuUINT32, GetPrev()->GetFrmId() );
if ( GetUpper( ) )
xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "upper" ), "%" SAL_PRIuUINT32, GetUpper()->GetFrmId() );
if ( GetLower( ) )
xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "lower" ), "%" SAL_PRIuUINT32, GetLower()->GetFrmId() );
if ( IsTextFrm( ) )
{
const SwTextFrm *pTextFrm = static_cast<const SwTextFrm *>(this);
const SwTextNode *pTextNode = pTextFrm->GetTextNode();
xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "txtNodeIndex" ), TMP_FORMAT, pTextNode->GetIndex() );
}
if (IsHeaderFrm() || IsFooterFrm())
{
const SwHeadFootFrm *pHeadFootFrm = static_cast<const SwHeadFootFrm*>(this);
OUString aFormatName = pHeadFootFrm->GetFormat()->GetName();
xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "fmtName" ), "%s", BAD_CAST(OUStringToOString(aFormatName, RTL_TEXTENCODING_UTF8).getStr()));
xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "fmtPtr" ), "%p", pHeadFootFrm->GetFormat());
}
}
void SwFrm::dumpChildrenAsXml( xmlTextWriterPtr writer ) const
{
const SwFrm *pFrm = GetLower( );
for ( ; pFrm != NULL; pFrm = pFrm->GetNext( ) )
{
pFrm->dumpAsXml( writer );
}
}
void SwAnchoredObject::dumpAsXml( xmlTextWriterPtr writer ) const
{
bool bCreateWriter = ( NULL == writer );
if ( bCreateWriter )
writer = lcl_createDefaultWriter();
xmlTextWriterStartElement( writer, BAD_CAST( getElementName() ) );
xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "ptr" ), "%p", this );
xmlTextWriterStartElement( writer, BAD_CAST( "bounds" ) );
xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "left" ), "%ld", GetObjBoundRect().Left() );
xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "top" ), "%ld", GetObjBoundRect().Top() );
xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "width" ), "%ld", GetObjBoundRect().Width() );
xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "height" ), "%ld", GetObjBoundRect().Height() );
xmlTextWriterEndElement( writer );
xmlTextWriterEndElement( writer );
if ( bCreateWriter )
lcl_freeWriter( writer );
}
void SwFont::dumpAsXml(xmlTextWriterPtr writer) const
{
xmlTextWriterStartElement(writer, BAD_CAST("pFont"));
xmlTextWriterWriteFormatAttribute(writer, BAD_CAST("ptr"), "%p", this);
xmlTextWriterWriteFormatAttribute(writer, BAD_CAST("color"), "%s", GetColor().AsRGBHexString().toUtf8().getStr());
xmlTextWriterEndElement(writer);
}
void SwTextFrm::dumpAsXmlAttributes( xmlTextWriterPtr writer ) const
{
SwFrm::dumpAsXmlAttributes( writer );
if ( HasFollow() )
xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "follow" ), "%" SAL_PRIuUINT32, GetFollow()->GetFrmId() );
if (m_pPrecede != NULL)
xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "precede" ), "%" SAL_PRIuUINT32, static_cast<SwTextFrm*>(m_pPrecede)->GetFrmId() );
}
void SwSectionFrm::dumpAsXmlAttributes( xmlTextWriterPtr writer ) const
{
SwFrm::dumpAsXmlAttributes( writer );
if ( HasFollow() )
xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "follow" ), "%" SAL_PRIuUINT32, GetFollow()->GetFrmId() );
if (m_pPrecede != NULL)
xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "precede" ), "%" SAL_PRIuUINT32, static_cast<SwSectionFrm*>( m_pPrecede )->GetFrmId() );
}
void SwTabFrm::dumpAsXmlAttributes( xmlTextWriterPtr writer ) const
{
SwFrm::dumpAsXmlAttributes( writer );
if ( HasFollow() )
xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "follow" ), "%" SAL_PRIuUINT32, GetFollow()->GetFrmId() );
if (m_pPrecede != NULL)
xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "precede" ), "%" SAL_PRIuUINT32, static_cast<SwTabFrm*>( m_pPrecede )->GetFrmId() );
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */