Files
libreoffice/xmloff/source/text/XMLFootnoteConfigurationImportContext.cxx
Stephan Bergmann 314f15bff0 Extend loplugin:external to warn about enums
To mitigate the dangers of silently breaking ADL when moving enums into unnamed
namespaces (see the commit message of 206b5b2661
"New loplugin:external"), note all functions that are affected.  (The plan is to
extend loplugin:external further to also warn about classes and class templates,
and the code to identify affected functions already takes that into account, so
some parts of that code are not actually relevant for enums.)

But it appears that none of the functions that are actually affected by the
changes in this commit relied on being found through ADL, so no adaptions were
necessary for them.

(clang::DeclContext::collectAllContexts is non-const, which recursively means
that External's Visit... functions must take non-const Decl*.  Which required
compilerplugins/clang/sharedvisitor/analyzer.cxx to be generalized to support
such Visit... functions with non-const Decl* parameters.)

Change-Id: Ia215291402bf850d43defdab3cff4db5b270d1bd
Reviewed-on: https://gerrit.libreoffice.org/83001
Tested-by: Jenkins
Reviewed-by: Stephan Bergmann <sbergman@redhat.com>
2019-11-17 00:28:17 +01:00

423 lines
14 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/.
*
* 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 <XMLFootnoteConfigurationImportContext.hxx>
#include <rtl/ustring.hxx>
#include <rtl/ustrbuf.hxx>
#include <sax/tools/converter.hxx>
#include <xmloff/nmspmap.hxx>
#include <xmloff/xmlnmspe.hxx>
#include <xmloff/xmltoken.hxx>
#include <xmloff/xmlement.hxx>
#include <xmloff/families.hxx>
#include <xmloff/xmluconv.hxx>
#include <xmloff/xmlimp.hxx>
#include <com/sun/star/xml/sax/XAttributeList.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/text/XFootnotesSupplier.hpp>
#include <com/sun/star/text/XEndnotesSupplier.hpp>
#include <com/sun/star/text/FootnoteNumbering.hpp>
#include <com/sun/star/style/NumberingType.hpp>
using namespace ::com::sun::star::text;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::style;
using namespace ::com::sun::star::xml::sax;
using namespace ::xmloff::token;
// XMLFootnoteConfigHelper
/// local helper class for import of quo-vadis and ergo-sum elements
class XMLFootnoteConfigHelper : public SvXMLImportContext
{
OUStringBuffer sBuffer;
XMLFootnoteConfigurationImportContext& rConfig;
bool const bIsBegin;
public:
XMLFootnoteConfigHelper(
SvXMLImport& rImport,
sal_uInt16 nPrfx,
const OUString& rLName,
XMLFootnoteConfigurationImportContext& rConfigImport,
bool bBegin);
virtual void EndElement() override;
virtual void Characters( const OUString& rChars ) override;
};
XMLFootnoteConfigHelper::XMLFootnoteConfigHelper(
SvXMLImport& rImport,
sal_uInt16 nPrfx,
const OUString& rLName,
XMLFootnoteConfigurationImportContext& rConfigImport,
bool bBegin)
: SvXMLImportContext(rImport, nPrfx, rLName)
, sBuffer()
, rConfig(rConfigImport)
, bIsBegin(bBegin)
{
}
void XMLFootnoteConfigHelper::EndElement()
{
if (bIsBegin)
{
rConfig.SetBeginNotice(sBuffer.makeStringAndClear());
}
else
{
rConfig.SetEndNotice(sBuffer.makeStringAndClear());
}
// rConfig = NULL; // import contexts are ref-counted
}
void XMLFootnoteConfigHelper::Characters( const OUString& rChars )
{
sBuffer.append(rChars);
}
// XMLFootnoteConfigurationImportContext
static const OUStringLiteral gsPropertyAnchorCharStyleName("AnchorCharStyleName");
static const OUStringLiteral gsPropertyCharStyleName("CharStyleName");
static const OUStringLiteral gsPropertyNumberingType("NumberingType");
static const OUStringLiteral gsPropertyPageStyleName("PageStyleName");
static const OUStringLiteral gsPropertyParagraphStyleName("ParaStyleName");
static const OUStringLiteral gsPropertyPrefix("Prefix");
static const OUStringLiteral gsPropertyStartAt("StartAt");
static const OUStringLiteral gsPropertySuffix("Suffix");
static const OUStringLiteral gsPropertyPositionEndOfDoc("PositionEndOfDoc");
static const OUStringLiteral gsPropertyFootnoteCounting("FootnoteCounting");
static const OUStringLiteral gsPropertyEndNotice("EndNotice");
static const OUStringLiteral gsPropertyBeginNotice("BeginNotice");
XMLFootnoteConfigurationImportContext::XMLFootnoteConfigurationImportContext(
SvXMLImport& rImport,
sal_uInt16 nPrfx,
const OUString& rLocalName,
const Reference<XAttributeList> & xAttrList)
: SvXMLStyleContext(rImport, nPrfx, rLocalName, xAttrList, XML_STYLE_FAMILY_TEXT_FOOTNOTECONFIG)
, sNumFormat("1")
, sNumSync("false")
, nOffset(0)
, nNumbering(FootnoteNumbering::PER_PAGE)
, bPosition(false)
, bIsEndnote(false)
{
sal_Int16 nLength = xAttrList->getLength();
for(sal_Int16 nAttr = 0; nAttr < nLength; nAttr++)
{
OUString sLocalName;
sal_uInt16 nPrefix = GetImport().GetNamespaceMap().
GetKeyByAttrName( xAttrList->getNameByIndex(nAttr),
&sLocalName );
if( XML_NAMESPACE_TEXT == nPrefix && IsXMLToken( sLocalName,
XML_NOTE_CLASS ) )
{
const OUString& rValue = xAttrList->getValueByIndex( nAttr );
if( IsXMLToken( rValue, XML_ENDNOTE ) )
{
bIsEndnote = true;
SetFamily( XML_STYLE_FAMILY_TEXT_FOOTNOTECONFIG );
}
break;
}
}
}
XMLFootnoteConfigurationImportContext::~XMLFootnoteConfigurationImportContext()
{
}
namespace {
enum XMLFtnConfigToken
{
XML_TOK_FTNCONFIG_CITATION_STYLENAME,
XML_TOK_FTNCONFIG_ANCHOR_STYLENAME,
XML_TOK_FTNCONFIG_DEFAULT_STYLENAME,
XML_TOK_FTNCONFIG_PAGE_STYLENAME,
XML_TOK_FTNCONFIG_OFFSET,
XML_TOK_FTNCONFIG_NUM_PREFIX,
XML_TOK_FTNCONFIG_NUM_SUFFIX,
XML_TOK_FTNCONFIG_NUM_FORMAT,
XML_TOK_FTNCONFIG_NUM_SYNC,
XML_TOK_FTNCONFIG_START_AT,
XML_TOK_FTNCONFIG_POSITION
};
}
static const SvXMLTokenMapEntry aTextFieldAttrTokenMap[] =
{
{ XML_NAMESPACE_TEXT, XML_CITATION_STYLE_NAME, XML_TOK_FTNCONFIG_CITATION_STYLENAME },
{ XML_NAMESPACE_TEXT, XML_CITATION_BODY_STYLE_NAME, XML_TOK_FTNCONFIG_ANCHOR_STYLENAME },
{ XML_NAMESPACE_TEXT, XML_DEFAULT_STYLE_NAME, XML_TOK_FTNCONFIG_DEFAULT_STYLENAME },
{ XML_NAMESPACE_TEXT, XML_MASTER_PAGE_NAME, XML_TOK_FTNCONFIG_PAGE_STYLENAME },
{ XML_NAMESPACE_TEXT, XML_START_VALUE, XML_TOK_FTNCONFIG_OFFSET },
{ XML_NAMESPACE_STYLE, XML_NUM_PREFIX, XML_TOK_FTNCONFIG_NUM_PREFIX },
{ XML_NAMESPACE_STYLE, XML_NUM_SUFFIX, XML_TOK_FTNCONFIG_NUM_SUFFIX },
{ XML_NAMESPACE_STYLE, XML_NUM_FORMAT, XML_TOK_FTNCONFIG_NUM_FORMAT },
{ XML_NAMESPACE_STYLE, XML_NUM_LETTER_SYNC, XML_TOK_FTNCONFIG_NUM_SYNC },
{ XML_NAMESPACE_TEXT, XML_START_NUMBERING_AT, XML_TOK_FTNCONFIG_START_AT},
{ XML_NAMESPACE_TEXT, XML_FOOTNOTES_POSITION, XML_TOK_FTNCONFIG_POSITION},
// for backwards compatibility with SRC630 & earlier
{ XML_NAMESPACE_TEXT, XML_NUM_PREFIX, XML_TOK_FTNCONFIG_NUM_PREFIX },
{ XML_NAMESPACE_TEXT, XML_NUM_SUFFIX, XML_TOK_FTNCONFIG_NUM_SUFFIX },
{ XML_NAMESPACE_TEXT, XML_OFFSET, XML_TOK_FTNCONFIG_OFFSET },
XML_TOKEN_MAP_END
};
const SvXMLTokenMap&
XMLFootnoteConfigurationImportContext::GetFtnConfigAttrTokenMap()
{
if (!pAttrTokenMap)
{
pAttrTokenMap.reset( new SvXMLTokenMap(aTextFieldAttrTokenMap) );
}
return *pAttrTokenMap;
}
static SvXMLEnumMapEntry<sal_Int16> const aFootnoteNumberingMap[] =
{
{ XML_PAGE, FootnoteNumbering::PER_PAGE },
{ XML_CHAPTER, FootnoteNumbering::PER_CHAPTER },
{ XML_DOCUMENT, FootnoteNumbering::PER_DOCUMENT },
{ XML_TOKEN_INVALID, 0 },
};
void XMLFootnoteConfigurationImportContext::StartElement(
const Reference<XAttributeList> & xAttrList )
{
sal_Int16 nLength = xAttrList->getLength();
for(sal_Int16 nAttr = 0; nAttr < nLength; nAttr++)
{
OUString sLocalName;
sal_uInt16 nPrefix = GetImport().GetNamespaceMap().
GetKeyByAttrName( xAttrList->getNameByIndex(nAttr),
&sLocalName );
OUString sValue = xAttrList->getValueByIndex(nAttr);
switch (GetFtnConfigAttrTokenMap().Get(nPrefix, sLocalName))
{
case XML_TOK_FTNCONFIG_CITATION_STYLENAME:
sCitationStyle = sValue;
break;
case XML_TOK_FTNCONFIG_ANCHOR_STYLENAME:
sAnchorStyle = sValue;
break;
case XML_TOK_FTNCONFIG_DEFAULT_STYLENAME:
sDefaultStyle = sValue;
break;
case XML_TOK_FTNCONFIG_PAGE_STYLENAME:
sPageStyle = sValue;
break;
case XML_TOK_FTNCONFIG_OFFSET:
{
sal_Int32 nTmp;
if (::sax::Converter::convertNumber(nTmp, sValue))
{
nOffset = static_cast<sal_uInt16>(nTmp);
}
break;
}
case XML_TOK_FTNCONFIG_NUM_PREFIX:
sPrefix = sValue;
break;
case XML_TOK_FTNCONFIG_NUM_SUFFIX:
sSuffix = sValue;
break;
case XML_TOK_FTNCONFIG_NUM_FORMAT:
sNumFormat = sValue;
break;
case XML_TOK_FTNCONFIG_NUM_SYNC:
sNumSync = sValue;
break;
case XML_TOK_FTNCONFIG_START_AT:
{
(void)SvXMLUnitConverter::convertEnum(nNumbering, sValue,
aFootnoteNumberingMap);
break;
}
case XML_TOK_FTNCONFIG_POSITION:
bPosition = IsXMLToken( sValue, XML_DOCUMENT );
break;
default:
; // ignore
}
}
}
SvXMLImportContextRef XMLFootnoteConfigurationImportContext::CreateChildContext(
sal_uInt16 nPrefix,
const OUString& rLocalName,
const Reference<XAttributeList> & xAttrList )
{
SvXMLImportContextRef xContext;
if (!bIsEndnote)
{
if (XML_NAMESPACE_TEXT == nPrefix)
{
if ( IsXMLToken( rLocalName,
XML_FOOTNOTE_CONTINUATION_NOTICE_FORWARD ) )
{
xContext = new XMLFootnoteConfigHelper(GetImport(),
nPrefix, rLocalName,
*this, false);
}
else if ( IsXMLToken( rLocalName,
XML_FOOTNOTE_CONTINUATION_NOTICE_BACKWARD ) )
{
xContext = new XMLFootnoteConfigHelper(GetImport(),
nPrefix, rLocalName,
*this, true);
}
// else: default context
}
// else: unknown namespace -> default context
}
// else: endnote -> default context
if (!xContext)
{
// default: delegate to super class
xContext = SvXMLStyleContext::CreateChildContext(nPrefix,
rLocalName,
xAttrList);
}
return xContext;
}
// Rename method <CreateAndInsertLate(..)> to <Finish(..)> (#i40597#)
void XMLFootnoteConfigurationImportContext::Finish( bool bOverwrite )
{
if (bOverwrite)
{
if (bIsEndnote)
{
Reference<XEndnotesSupplier> xSupplier(
GetImport().GetModel(), UNO_QUERY);
if (xSupplier.is())
{
ProcessSettings(xSupplier->getEndnoteSettings());
}
}
else
{
Reference<XFootnotesSupplier> xSupplier(
GetImport().GetModel(), UNO_QUERY);
if (xSupplier.is())
{
ProcessSettings(xSupplier->getFootnoteSettings());
}
}
}
// else: ignore (there's only one configuration, so we can only overwrite)
}
void XMLFootnoteConfigurationImportContext::ProcessSettings(
const Reference<XPropertySet> & rConfig)
{
Any aAny;
if (!sCitationStyle.isEmpty())
{
aAny <<= GetImport().GetStyleDisplayName(
XML_STYLE_FAMILY_TEXT_TEXT, sCitationStyle );
rConfig->setPropertyValue(gsPropertyCharStyleName, aAny);
}
if (!sAnchorStyle.isEmpty())
{
aAny <<= GetImport().GetStyleDisplayName(
XML_STYLE_FAMILY_TEXT_TEXT, sAnchorStyle );
rConfig->setPropertyValue(gsPropertyAnchorCharStyleName, aAny);
}
if (!sPageStyle.isEmpty())
{
aAny <<= GetImport().GetStyleDisplayName(
XML_STYLE_FAMILY_MASTER_PAGE, sPageStyle );
rConfig->setPropertyValue(gsPropertyPageStyleName, aAny);
}
if (!sDefaultStyle.isEmpty())
{
aAny <<= GetImport().GetStyleDisplayName(
XML_STYLE_FAMILY_TEXT_PARAGRAPH, sDefaultStyle );
rConfig->setPropertyValue(gsPropertyParagraphStyleName, aAny);
}
rConfig->setPropertyValue(gsPropertyPrefix, Any(sPrefix));
rConfig->setPropertyValue(gsPropertySuffix, Any(sSuffix));
sal_Int16 nNumType = NumberingType::ARABIC;
GetImport().GetMM100UnitConverter().convertNumFormat( nNumType, sNumFormat,
sNumSync );
// #i61399: Corrupt file? It contains "Bullet" as numbering style for footnotes.
// Okay, even it seems to be corrupt, we will oversee this and set the style to ARABIC
if( NumberingType::CHAR_SPECIAL == nNumType )
nNumType = NumberingType::ARABIC;
rConfig->setPropertyValue(gsPropertyNumberingType, Any(nNumType));
rConfig->setPropertyValue(gsPropertyStartAt, Any(nOffset));
if (!bIsEndnote)
{
rConfig->setPropertyValue(gsPropertyPositionEndOfDoc, Any(bPosition));
rConfig->setPropertyValue(gsPropertyFootnoteCounting, Any(nNumbering));
rConfig->setPropertyValue(gsPropertyEndNotice, Any(sEndNotice));
rConfig->setPropertyValue(gsPropertyBeginNotice, Any(sBeginNotice));
}
}
void XMLFootnoteConfigurationImportContext::SetBeginNotice(
const OUString& sText)
{
sBeginNotice = sText;
}
void XMLFootnoteConfigurationImportContext::SetEndNotice(
const OUString& sText)
{
sEndNotice = sText;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */