Impressum unostyle.cxx
Sprache: 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 <sal/config.h>
#include <o3tl/any.hxx>
#include <o3tl/safeint.hxx>
#include <o3tl/string_view.hxx>
#include <comphelper/propertysequence.hxx>
#include <hintids.hxx>
#include <utility>
#include <vcl/svapp.hxx>
#include <svl/hint.hxx>
#include <svtools/ctrltool.hxx>
#include <svl/style.hxx>
#include <svl/itemiter.hxx>
#include <svl/listener.hxx>
#include <svl/numformat.hxx>
#include <svl/zforlist.hxx>
#include <svl/zformat.hxx>
#include <svx/pageitem.hxx>
#include <editeng/colritem.hxx>
#include <editeng/contouritem.hxx>
#include <editeng/crossedoutitem.hxx>
#include <editeng/fontitem.hxx>
#include <editeng/sizeitem.hxx>
#include <editeng/udlnitem.hxx>
#include <editeng/ulspitem.hxx>
#include <editeng/lrspitem.hxx>
#include <editeng/boxitem.hxx>
#include <editeng/postitem.hxx>
#include <editeng/shdditem.hxx>
#include <editeng/brushitem.hxx>
#include <editeng/flstitem.hxx>
#include <editeng/fhgtitem.hxx>
#include <editeng/paperinf.hxx>
#include <editeng/wghtitem.hxx>
#include <autostyle_helper.hxx>
#include <pagedesc.hxx>
#include <doc.hxx>
#include <IDocumentUndoRedo.hxx>
#include <IDocumentDeviceAccess.hxx>
#include <IDocumentStylePoolAccess.hxx>
#include <docary.hxx>
#include <charfmt.hxx>
#include <cmdid.h>
#include <unomid.h>
#include <unomap.hxx>
#include <unostyle.hxx>
#include <unosett.hxx>
#include <docsh.hxx>
#include <paratr.hxx>
#include <unoprnms.hxx>
#include <shellio.hxx>
#include <docstyle.hxx>
#include <unotextbodyhf.hxx>
#include <fmthdft.hxx>
#include <fmtpdsc.hxx>
#include <strings.hrc>
#include <poolfmt.hxx>
#include <unoevent.hxx>
#include <fmtruby.hxx>
#include <SwStyleNameMapper.hxx>
#include <sfx2/printer.hxx>
#include <com/sun/star/frame/XModel.hpp>
#include <com/sun/star/io/IOException.hpp>
#include <com/sun/star/style/ParagraphStyleCategory.hpp>
#include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
#include <com/sun/star/beans/PropertyAttribute.hpp>
#include <com/sun/star/beans/NamedValue.hpp>
#include <com/sun/star/drawing/BitmapMode.hpp>
#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
#include <com/sun/star/lang/IllegalArgumentException.hpp>
#include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
#include <com/sun/star/document/XEventsSupplier.hpp>
#include <com/sun/star/io/XInputStream.hpp>
#include <istyleaccess.hxx>
#include <fmtfsize.hxx>
#include <numrule.hxx>
#include <tblafmt.hxx>
#include <frameformats.hxx>
#include <comphelper/servicehelper.hxx>
#include <cppuhelper/exc_hlp.hxx>
#include <cppuhelper/supportsservice.hxx>
#include <cppuhelper/typeprovider.hxx>
#include <comphelper/sequence.hxx>
#include <sal/log.hxx>
#include <svl/stylepool.hxx>
#include <svx/unobrushitemhelper.hxx>
#include <editeng/unoipset.hxx>
#include <editeng/memberids.h>
#include <svx/unomid.hxx>
#include <svx/unoshape.hxx>
#include <svx/xflbstit.hxx>
#include <svx/xflbmtit.hxx>
#include <swunohelper.hxx>
#include <svx/xbtmpit.hxx>
#include <ccoll.hxx>
#include <hints.hxx>
#include <uiitems.hxx>
#include <unoxstyle.hxx>
#include <ndtxt.hxx>
#include <txatbase.hxx>
#include <cassert>
#include <memory>
#include <set>
#include <string_view>
#include <limits>
#include <unotxdoc.hxx>
#include <names.hxx>
using namespace css;
using namespace css::io;
using namespace css::lang;
using namespace css::uno;
namespace {
// these should really be constexprs, but MSVC still is apparently too stupid for them
#define nPoolChrNormalRange (RES_POOLCHR_NORMAL_END - RES_POOLCHR_NORMAL_BEGIN)
#define nPoolChrHtmlRange (RES_POOLCHR_HTML_END - RES_POOLCHR_HTML_BEGIN)
#define nPoolCollTextRange ( RES_POOLCOLL_TEXT_END - RES_POOLCOLL_TEXT_BEGIN)
#define nPoolCollListsRange ( RES_POOLCOLL_LISTS_END - RES_POOLCOLL_LISTS_BEGIN)
#define nPoolCollExtraRange ( RES_POOLCOLL_EXTRA_END - RES_POOLCOLL_EXTRA_BEGIN)
#define nPoolCollRegisterRange ( RES_POOLCOLL_REGISTER_END - RES_POOLCOLL_REGISTER_BE GIN)
#define nPoolCollDocRange ( RES_POOLCOLL_DOC_END - RES_POOLCOLL_DOC_BEGIN)
#define nPoolCollHtmlRange ( RES_POOLCOLL_HTML_END - RES_POOLCOLL_HTML_BEGIN)
#define nPoolFrameRange ( RES_POOLFRM_END - RES_POOLFRM_BEGIN)
#define nPoolPageRange ( RES_POOLPAGE_END - RES_POOLPAGE_BEGIN)
#define nPoolNumRange ( RES_POOLNUMRULE_END - RES_POOLNUMRULE_BEGIN)
#define nPoolCollListsStackedStart ( nPoolCollTextRange)
#define nPoolCollExtraStackedStart ( nPoolCollListsStackedStart + nPoolCollListsRange)
#define nPoolCollRegisterStackedStart ( nPoolCollExtraStackedStart + nPoolCollExtraRange)
#define nPoolCollDocStackedStart ( nPoolCollRegisterStackedStart + nPoolCollRegisterRange)
#define nPoolCollHtmlStackedStart ( nPoolCollDocStackedStart + nPoolCollDocRange)
using paragraphstyle_t = std::remove_const<decltype(style::ParagraphStyleCategory::TEXT)>::type;
using collectionbits_t = sal_uInt16;
struct ParagraphStyleCategoryEntry
{
paragraphstyle_t m_eCategory;
SfxStyleSearchBits m_nSwStyleBits;
collectionbits_t m_nCollectionBits;
constexpr ParagraphStyleCategoryEntry(paragraphstyle_t eCategory, SfxStyleSearchBits nSwStyleBits, collectionbits_t nCollectionBits)
: m_eCategory(eCategory)
, m_nSwStyleBits(nSwStyleBits)
, m_nCollectionBits(nCollectionBits)
{ }
};
constexpr ParagraphStyleCategoryEntry sParagraphStyleCategoryEntries[]
{
{ style::ParagraphStyleCategory::TEXT, SfxStyleSearchBits::SwText, COLL_TEXT_BITS },
{ style::ParagraphStyleCategory::CHAPTER, SfxStyleSearchBits::SwChapter, COLL_DOC_BITS },
{ style::ParagraphStyleCategory::LIST, SfxStyleSearchBits::SwList, COLL_LISTS_BITS },
{ style::ParagraphStyleCategory::INDEX, SfxStyleSearchBits::SwIndex, COLL_REGISTER_BITS },
{ style::ParagraphStyleCategory::EXTRA, SfxStyleSearchBits::SwExtra, COLL_EXTRA_BITS },
{ style::ParagraphStyleCategory::HTML, SfxStyleSearchBits::SwHtml, COLL_HTML_BITS }
};
} // namespace anonymous
class StyleFamilyEntry
{
public:
template <SfxStyleFamily f> static StyleFamilyEntry Create(sal_uInt16 nPropMapType, SwGetPoolIdFromName aPoolId, const OUString& sName, TranslateId pResId)
{
return StyleFamilyEntry(f, nPropMapType, aPoolId, sName, pResId, GetCountOrName<f>, TranslateIndex<f>);
}
SfxStyleFamily family() const { return m_eFamily; }
sal_uInt16 propMapType() const { return m_nPropMapType; }
const uno::Reference<beans::XPropertySetInfo>& xPSInfo() const { return m_xPSInfo; }
SwGetPoolIdFromName poolId() const { return m_aPoolId; }
const OUString& name() const { return m_sName; }
const TranslateId& resId() const { return m_pResId; }
sal_Int32 getCountOrName(const SwDoc& rDoc, UIName* pString, sal_Int32 nIndex) const { return m_fGetCountOrName(rDoc, pString, nIndex); }
sal_uInt16 translateIndex(const sal_uInt16 nIndex) const { return m_fTranslateIndex(nIndex); }
private:
using GetCountOrName_t = sal_Int32 (*)(const SwDoc&, UIName*, sal_Int32);
using TranslateIndex_t = sal_uInt16(*)(const sal_uInt16);
SfxStyleFamily m_eFamily;
sal_uInt16 m_nPropMapType;
uno::Reference<beans::XPropertySetInfo> m_xPSInfo;
SwGetPoolIdFromName m_aPoolId;
OUString m_sName;
TranslateId m_pResId;
GetCountOrName_t m_fGetCountOrName;
TranslateIndex_t m_fTranslateIndex;
StyleFamilyEntry(SfxStyleFamily eFamily, sal_uInt16 nPropMapType, SwGetPoolIdFromName aPoolId, OUString sName, TranslateId pResId, GetCountOrName_t fGetCountOrName, TranslateIndex_t fTranslateIndex)
: m_eFamily(eFamily)
, m_nPropMapType(nPropMapType)
, m_xPSInfo(aSwMapProvider.GetPropertySet(nPropMapType)->getPropertySetInfo())
, m_aPoolId(aPoolId)
, m_sName(std::move(sName))
, m_pResId(pResId)
, m_fGetCountOrName(fGetCountOrName)
, m_fTranslateIndex(fTranslateIndex)
{ }
template<SfxStyleFamily> static inline sal_Int32 GetCountOrName(const SwDoc& rDoc, UIName* pString, sal_Int32 nIndex);
template<SfxStyleFamily> static inline sal_uInt16 TranslateIndex(const sal_uInt16 nIndex) { return nIndex; }
};
template<>
sal_Int32 StyleFamilyEntry::GetCountOrName<SfxStyleFamily::Char>(const SwDoc& rDoc, UIName* pString, sal_Int32 nIndex)
{
const sal_uInt16 nBaseCount = nPoolChrHtmlRange + nPoolChrNormalRange;
nIndex -= nBaseCount;
sal_Int32 nCount = 0;
for(auto pFormat : *rDoc.GetCharFormats())
{
if(pFormat->IsDefault() && pFormat != rDoc.GetDfltCharFormat())
continue;
if(!IsPoolUserFormat(pFormat->GetPoolFormatId()))
continue;
if(nIndex == nCount)
{
// the default character format needs to be set to "Default!"
if(rDoc.GetDfltCharFormat() == pFormat)
*pString = UIName(SwResId(STR_POOLCHR_STANDARD));
else
*pString = pFormat->GetName();
break;
}
++nCount;
}
return nCount + nBaseCount;
}
template<>
sal_Int32 StyleFamilyEntry::GetCountOrName<SfxStyleFamily::Para>(const SwDoc& rDoc, UIName* pString, sal_Int32 nIndex)
{
const sal_uInt16 nBaseCount = nPoolCollHtmlStackedStart + nPoolCollHtmlRange;
nIndex -= nBaseCount;
sal_Int32 nCount = 0;
for(auto pColl : *rDoc.GetTextFormatColls())
{
if(pColl->IsDefault())
continue;
if(!IsPoolUserFormat(pColl->GetPoolFormatId()))
continue;
if(nIndex == nCount)
{
*pString = pColl->GetName();
break;
}
++nCount;
}
return nCount + nBaseCount;
}
template<>
sal_Int32 StyleFamilyEntry::GetCountOrName<SfxStyleFamily::Frame>(const SwDoc& rDoc, UIName* pString, sal_Int32 nIndex)
{
nIndex -= nPoolFrameRange;
sal_Int32 nCount = 0;
for(const auto pFormat : *rDoc.GetFrameFormats())
{
if(pFormat->IsDefault() || pFormat->IsAuto())
continue;
if(!IsPoolUserFormat(pFormat->GetPoolFormatId()))
continue;
if(nIndex == nCount)
{
*pString = pFormat->GetName();
break;
}
++nCount;
}
return nCount + nPoolFrameRange;
}
template<>
sal_Int32 StyleFamilyEntry::GetCountOrName<SfxStyleFamily::Page>(const SwDoc& rDoc, UIName* pString, sal_Int32 nIndex)
{
nIndex -= nPoolPageRange;
sal_Int32 nCount = 0;
const size_t nArrLen = rDoc.GetPageDescCnt();
for(size_t i = 0; i < nArrLen; ++i)
{
const SwPageDesc& rDesc = rDoc.GetPageDesc(i);
if(!IsPoolUserFormat(rDesc.GetPoolFormatId()))
continue;
if(nIndex == nCount)
{
*pString = rDesc.GetName();
break;
}
++nCount;
}
nCount += nPoolPageRange;
return nCount;
}
template<>
sal_Int32 StyleFamilyEntry::GetCountOrName<SfxStyleFamily::Pseudo>(const SwDoc& rDoc, UIName* pString, sal_Int32 nIndex)
{
nIndex -= nPoolNumRange;
sal_Int32 nCount = 0;
for(const auto pRule : rDoc.GetNumRuleTable())
{
if(pRule->IsAutoRule())
continue;
if(!IsPoolUserFormat(pRule->GetPoolFormatId()))
continue;
if(nIndex == nCount)
{
*pString = pRule->GetName();
break;
}
++nCount;
}
return nCount + nPoolNumRange;
}
template<>
sal_Int32 StyleFamilyEntry::GetCountOrName<SfxStyleFamily::Table>(const SwDoc& rDoc, UIName* pString, sal_Int32 nIndex)
{
if (!rDoc.HasTableStyles())
return 0;
const auto pAutoFormats = &rDoc.GetTableStyles();
const sal_Int32 nCount = pAutoFormats->size();
if (0 <= nIndex && nIndex < nCount)
*pString = UIName(pAutoFormats->operator[](nIndex).GetName().toString());
return nCount;
}
template<>
sal_Int32 StyleFamilyEntry::GetCountOrName<SfxStyleFamily::Cell>(const SwDoc& rDoc, UIName* pString, sal_Int32 nIndex)
{
const auto& rAutoFormats = rDoc.GetTableStyles();
const auto& rTableTemplateMap = SwTableAutoFormat::GetTableTemplateMap();
const sal_Int32 nUsedCellStylesCount = rAutoFormats.size() * rTableTemplateMap.size();
const sal_Int32 nCount = nUsedCellStylesCount + rDoc.GetCellStyles().size();
if (0 <= nIndex && nIndex < nCount)
{
if (nUsedCellStylesCount > nIndex)
{
const sal_Int32 nAutoFormat = nIndex / rTableTemplateMap.size();
const sal_Int32 nBoxFormat = rTableTemplateMap[nIndex % rTableTemplateMap.size()];
const SwTableAutoFormat& rTableFormat = rAutoFormats[nAutoFormat];
ProgName aProgName;
SwStyleNameMapper::FillProgName(UIName(rTableFormat.GetName().toString()), aProgName, SwGetPoolIdFromName::TableStyle);
*pString = UIName(aProgName.toString() + rTableFormat.GetTableTemplateCellSubName(rTableFormat.GetBoxFormat(nBoxFormat)));
}
else
*pString = rDoc.GetCellStyles()[nIndex-nUsedCellStylesCount].GetName();
}
return nCount;
}
template<>
sal_uInt16 StyleFamilyEntry::TranslateIndex<SfxStyleFamily::Char>(const sal_uInt16 nIndex)
{
static_assert(nPoolChrNormalRange > 0 && nPoolChrHtmlRange > 0, "invalid pool range");
if (nIndex < nPoolChrNormalRange)
return nIndex + RES_POOLCHR_NORMAL_BEGIN;
else if (nIndex < (nPoolChrHtmlRange + nPoolChrNormalRange))
return nIndex + RES_POOLCHR_HTML_BEGIN - nPoolChrNormalRange;
throw lang::IndexOutOfBoundsException();
}
template<>
sal_uInt16 StyleFamilyEntry::TranslateIndex<SfxStyleFamily::Para>(const sal_uInt16 nIndex)
{
static_assert(nPoolCollTextRange > 0 && nPoolCollListsRange > 0 && nPoolCollExtraRange > 0 && nPoolCollRegisterRange > 0 && nPoolCollDocRange > 0 && nPoolCollHtmlRange > 0, "weird pool range");
if (nIndex < nPoolCollListsStackedStart)
return nIndex + RES_POOLCOLL_TEXT_BEGIN;
else if (nIndex < nPoolCollExtraStackedStart)
return nIndex + RES_POOLCOLL_LISTS_BEGIN - nPoolCollListsStackedStart;
else if (nIndex < nPoolCollRegisterStackedStart)
return nIndex + RES_POOLCOLL_EXTRA_BEGIN - nPoolCollExtraStackedStart;
else if (nIndex < nPoolCollDocStackedStart)
return nIndex + RES_POOLCOLL_REGISTER_BEGIN - nPoolCollRegisterStackedStart;
else if (nIndex < nPoolCollHtmlStackedStart)
return nIndex + RES_POOLCOLL_DOC_BEGIN - nPoolCollDocStackedStart;
else if (nIndex < nPoolCollHtmlStackedStart + nPoolCollTextRange)
return nIndex + RES_POOLCOLL_HTML_BEGIN - nPoolCollHtmlStackedStart;
throw lang::IndexOutOfBoundsException();
}
template<>
sal_uInt16 StyleFamilyEntry::TranslateIndex<SfxStyleFamily::Page>(const sal_uInt16 nIndex)
{
if (nIndex < nPoolPageRange)
return nIndex + RES_POOLPAGE_BEGIN;
throw lang::IndexOutOfBoundsException();
}
template<>
sal_uInt16 StyleFamilyEntry::TranslateIndex<SfxStyleFamily::Frame>(const sal_uInt16 nIndex)
{
if (nIndex < nPoolFrameRange)
return nIndex + RES_POOLFRM_BEGIN;
throw lang::IndexOutOfBoundsException();
}
template<>
sal_uInt16 StyleFamilyEntry::TranslateIndex<SfxStyleFamily::Pseudo>(const sal_uInt16 nIndex)
{
if (nIndex < nPoolNumRange)
return nIndex + RES_POOLNUMRULE_BEGIN;
throw lang::IndexOutOfBoundsException();
}
static const std::vector<StyleFamilyEntry>& lcl_GetStyleFamilyEntries()
{
static const std::vector<StyleFamilyEntry> our_pStyleFamilyEntries{
StyleFamilyEntry::Create<SfxStyleFamily::Char> (PROPERTY_MAP_CHAR_STYLE, SwGetPoolIdFromName::ChrFmt, u"CharacterStyles"_ustr, STR_STYLE_FAMILY_CHARACTER),
StyleFamilyEntry::Create<SfxStyleFamily::Para> (PROPERTY_MAP_PARA_STYLE, SwGetPoolIdFromName::TxtColl, u"ParagraphStyles"_ustr, STR_STYLE_FAMILY_PARAGRAPH),
StyleFamilyEntry::Create<SfxStyleFamily::Page> (PROPERTY_MAP_PAGE_STYLE, SwGetPoolIdFromName::PageDesc, u"PageStyles"_ustr, STR_STYLE_FAMILY_PAGE),
StyleFamilyEntry::Create<SfxStyleFamily::Frame> (PROPERTY_MAP_FRAME_STYLE, SwGetPoolIdFromName::FrmFmt, u"FrameStyles"_ustr, STR_STYLE_FAMILY_FRAME),
StyleFamilyEntry::Create<SfxStyleFamily::Pseudo>(PROPERTY_MAP_NUM_STYLE, SwGetPoolIdFromName::NumRule, u"NumberingStyles"_ustr, STR_STYLE_FAMILY_NUMBERING),
StyleFamilyEntry::Create<SfxStyleFamily::Table> (PROPERTY_MAP_TABLE_STYLE, SwGetPoolIdFromName::TableStyle, u"TableStyles"_ustr, STR_STYLE_FAMILY_TABLE),
StyleFamilyEntry::Create<SfxStyleFamily::Cell> (PROPERTY_MAP_CELL_STYLE, SwGetPoolIdFromName::CellStyle, u"CellStyles"_ustr, STR_STYLE_FAMILY_CELL),
};
return our_pStyleFamilyEntries;
}
class SwStyleBase_Impl
{
private:
SwDoc& m_rDoc;
const SwPageDesc* m_pOldPageDesc;
rtl::Reference<SwDocStyleSheet> m_xNewBase;
SfxItemSet* m_pItemSet;
std::optional<SfxItemSet> m_oMyItemSet;
UIName m_sStyleUIName;
const SwAttrSet* m_pParentStyle;
public:
SwStyleBase_Impl(SwDoc& rSwDoc, UIName sUIName, const SwAttrSet* pParentStyle)
: m_rDoc(rSwDoc)
, m_pOldPageDesc(nullptr)
, m_pItemSet(nullptr)
, m_sStyleUIName(std::move(sUIName))
, m_pParentStyle(pParentStyle)
{ }
rtl::Reference<SwDocStyleSheet>& getNewBase()
{
return m_xNewBase;
}
void setNewBase(SwDocStyleSheet* pNew)
{
m_xNewBase = pNew;
}
bool HasItemSet() const
{
return m_xNewBase.is();
}
SfxItemSet& GetItemSet()
{
assert(m_xNewBase.is());
if(!m_pItemSet)
{
m_oMyItemSet.emplace(m_xNewBase->GetItemSet());
m_pItemSet = &*m_oMyItemSet;
// set parent style to have the correct XFillStyle setting as XFILL_NONE
if(!m_pItemSet->GetParent() && m_pParentStyle)
m_pItemSet->SetParent(m_pParentStyle);
}
return *m_pItemSet;
}
const SwPageDesc* GetOldPageDesc();
// still a hack, but a bit more explicit and with a proper scope
struct ItemSetOverrider
{
SwStyleBase_Impl& m_rStyleBase;
SfxItemSet* m_pOldSet;
ItemSetOverrider(SwStyleBase_Impl& rStyleBase, SfxItemSet* pTemp)
: m_rStyleBase(rStyleBase)
, m_pOldSet(m_rStyleBase.m_pItemSet)
{ m_rStyleBase.m_pItemSet = pTemp; }
~ItemSetOverrider()
{ m_rStyleBase.m_pItemSet = m_pOldSet; };
};
};
SfxStyleFamily SwXStyle::GetFamily() const
{return m_rEntry.family();}
OUString SwXStyle::getImplementationName()
{ return {u"SwXStyle"_ustr}; };
sal_Bool SwXStyle::supportsService(const OUString& rServiceName)
{ return cppu::supportsService(this, rServiceName); };
class SwStyleProperties_Impl
{
const SfxItemPropertyMap& mrMap;
std::map<OUString, uno::Any> m_vPropertyValues;
public:
explicit SwStyleProperties_Impl(const SfxItemPropertyMap& rMap)
: mrMap(rMap)
{ }
bool AllowsKey(std::u16string_view rName)
{
return mrMap.hasPropertyByName(rName);
}
bool SetProperty(const OUString& rName, const uno::Any& rValue)
{
if(!AllowsKey(rName))
return false;
m_vPropertyValues[rName] = rValue;
return true;
}
void GetProperty(const OUString& rName, const uno::Any*& pAny)
{
if(!AllowsKey(rName))
{
pAny = nullptr;
return;
}
pAny = &m_vPropertyValues[rName];
return;
}
bool ClearProperty( const OUString& rName )
{
if(!AllowsKey(rName))
return false;
m_vPropertyValues[rName] = uno::Any();
return true;
}
void ClearAllProperties( )
{ m_vPropertyValues.clear(); }
void Apply(SwXStyle& rStyle)
{
for(const auto& rPropertyPair : m_vPropertyValues)
{
if(rPropertyPair.second.hasValue())
rStyle.setPropertyValue(rPropertyPair.first, rPropertyPair.second);
}
}
};
static rtl::Reference<SwXStyle> CreateStyleCharOrParaOrPseudo(SfxStyleSheetBasePool* pBasePool, SwDocShell* pDocShell, const UIName& rStyleUIName, SfxStyleFamily eFamily)
{
return pBasePool ? new SwXStyle(pBasePool, eFamily, pDocShell->GetDoc(), rStyleUIName) : new SwXStyle(pDocShell->GetDoc(), eFamily, false);
}
static rtl::Reference<SwXFrameStyle> CreateStyleFrame(SfxStyleSheetBasePool* pBasePool, SwDocShell* pDocShell, const UIName& rStyleUIName)
{
return pBasePool ? new SwXFrameStyle(*pBasePool, pDocShell->GetDoc(), rStyleUIName) : new SwXFrameStyle(pDocShell->GetDoc());
}
static rtl::Reference<SwXPageStyle> CreateStylePage(SfxStyleSheetBasePool* pBasePool, SwDocShell* pDocShell, const UIName& rStyleUIName)
{
return pBasePool ? new SwXPageStyle(*pBasePool, pDocShell, rStyleUIName) : new SwXPageStyle(pDocShell);
}
static rtl::Reference<SwXTextTableStyle> CreateStyleTable(SwDocShell* pDocShell, const TableStyleName& rStyleUIName)
{
return SwXTextTableStyle::CreateXTextTableStyle(pDocShell, rStyleUIName);
}
static rtl::Reference<SwXTextCellStyle> CreateStyleCell(SwDocShell* pDocShell, const UIName& rStyleUIName)
{
return SwXTextCellStyle::CreateXTextCellStyle(pDocShell, rStyleUIName);
}
sal_Int32 SwXStyleFamily::GetCountOrName(UIName* pString, sal_Int32 nIndex)
{
return m_rEntry.getCountOrName(*m_pDocShell->GetDoc(), pString, nIndex);
};
/*static*/ const StyleFamilyEntry& SwXStyleFamily::InitEntry(SfxStyleFamily eFamily)
{
auto& entries = lcl_GetStyleFamilyEntries();
const auto pEntry = std::find_if(entries.begin(), entries.end(),
[eFamily] (const StyleFamilyEntry& e) { return e.family() == eFamily; });
assert(pEntry != entries.end());
return *pEntry;
}
SwXStyleFamily::SwXStyleFamily(SwDocShell* pDocShell, const SfxStyleFamily eFamily)
: m_rEntry(InitEntry(eFamily))
, m_pBasePool(pDocShell->GetStyleSheetPool())
, m_pDocShell(pDocShell)
{
if (m_pBasePool) //tdf#124142 html docs can have no styles
StartListening(*m_pBasePool);
}
//XIndexAccess
sal_Int32 SAL_CALL SwXStyleFamily::getCount()
{
SolarMutexGuard aGuard;
return GetCountOrName(nullptr);
};
//XElementAccess
uno::Type SAL_CALL SwXStyleFamily::getElementType()
{
return cppu::UnoType<style::XStyle>::get();
};
sal_Bool SAL_CALL SwXStyleFamily::hasElements()
{
if(!m_pBasePool)
throw uno::RuntimeException();
return true;
}
//XPropertySet
uno::Reference< beans::XPropertySetInfo > SAL_CALL SwXStyleFamily::getPropertySetInfo()
{ return {}; };
void SAL_CALL SwXStyleFamily::setPropertyValue( const OUString&, const uno::Any&)
{ SAL_WARN("sw.uno", "###unexpected!"); };
void SAL_CALL SwXStyleFamily::addPropertyChangeListener( const OUString&, const uno::Reference<beans::XPropertyChangeListener>&)
{ SAL_WARN("sw.uno", "###unexpected!"); };
void SAL_CALL SwXStyleFamily::removePropertyChangeListener( const OUString&, const uno::Reference<beans::XPropertyChangeListener>&)
{ SAL_WARN("sw.uno", "###unexpected!"); };
void SAL_CALL SwXStyleFamily::addVetoableChangeListener(const OUString&, const uno::Reference<beans::XVetoableChangeListener>&)
{ SAL_WARN("sw.uno", "###unexpected!"); };
void SAL_CALL SwXStyleFamily::removeVetoableChangeListener(const OUString&, const uno::Reference<beans::XVetoableChangeListener>&)
{ SAL_WARN("sw.uno", "###unexpected!"); };
//SfxListener
void SwXStyleFamily::Notify(SfxBroadcaster& rBC, const SfxHint& rHint)
{
if(rHint.GetId() == SfxHintId::Dying)
{
m_pBasePool = nullptr;
m_pDocShell = nullptr;
EndListening(rBC);
}
}
//XServiceInfo
OUString SAL_CALL SwXStyleFamily::getImplementationName()
{ return {u"XStyleFamily"_ustr}; };
sal_Bool SAL_CALL SwXStyleFamily::supportsService(const OUString& rServiceName)
{ return cppu::supportsService(this, rServiceName); };
uno::Sequence< OUString > SAL_CALL SwXStyleFamily::getSupportedServiceNames()
{ return { u"com.sun.star.style.StyleFamily"_ustr }; }
OUString SwXStyleFamilies::getImplementationName()
{ return {u"SwXStyleFamilies"_ustr}; }
sal_Bool SwXStyleFamilies::supportsService(const OUString& rServiceName)
{
return cppu::supportsService(this, rServiceName);
}
uno::Sequence< OUString > SwXStyleFamilies::getSupportedServiceNames()
{ return { u"com.sun.star.style.StyleFamilies"_ustr }; }
SwXStyleFamilies::SwXStyleFamilies(SwDocShell& rDocShell) :
SwUnoCollection(rDocShell.GetDoc()),
m_pDocShell(&rDocShell)
{ }
SwXStyleFamilies::~SwXStyleFamilies()
{ }
uno::Any SAL_CALL SwXStyleFamilies::getByName(const OUString& Name)
{
return uno::Any(uno::Reference(static_cast<css::container::XNameContainer*>(GetStylesByName(Name).get())));
}
rtl::Reference<SwXStyleFamily> SwXStyleFamilies::GetStylesByName(const OUString& Name)
{
SolarMutexGuard aGuard;
if(!IsValid())
throw uno::RuntimeException();
auto& entries(lcl_GetStyleFamilyEntries());
const auto pEntry = std::find_if(entries.begin(), entries.end(),
[&Name] (const StyleFamilyEntry& e) { return e.name() == Name; });
if(pEntry == entries.end())
throw container::NoSuchElementException();
return GetStylesByIndex(pEntry - entries.begin());
}
rtl::Reference<SwXStyleFamily> SwXStyleFamilies::GetPageStyles()
{
return GetStylesByName(u"PageStyles"_ustr);
}
rtl::Reference<SwXStyleFamily> SwXStyleFamilies::GetCharacterStyles()
{
return GetStylesByName(u"CharacterStyles"_ustr);
}
rtl::Reference<SwXStyleFamily> SwXStyleFamilies::GetParagraphStyles()
{
return GetStylesByName(u"ParagraphStyles"_ustr);
}
rtl::Reference<SwXStyleFamily> SwXStyleFamilies::GetNumberingStyles()
{
return GetStylesByName(u"NumberingStyles"_ustr);
}
uno::Sequence< OUString > SwXStyleFamilies::getElementNames()
{
auto& entries(lcl_GetStyleFamilyEntries());
uno::Sequence<OUString> aNames(entries.size());
std::transform(entries.begin(), entries.end(),
aNames.getArray(), [] (const StyleFamilyEntry& e) { return e.name(); });
return aNames;
}
sal_Bool SwXStyleFamilies::hasByName(const OUString& Name)
{
auto& entries(lcl_GetStyleFamilyEntries());
return std::any_of(entries.begin(), entries.end(),
[&Name] (const StyleFamilyEntry& e) { return e.name() == Name; });
}
sal_Int32 SwXStyleFamilies::getCount()
{
return lcl_GetStyleFamilyEntries().size();
}
uno::Any SwXStyleFamilies::getByIndex(sal_Int32 nIndex)
{
return uno::Any(uno::Reference(static_cast<css::container::XNameContainer*>(GetStylesByIndex(nIndex).get())));
}
rtl::Reference<SwXStyleFamily> SwXStyleFamilies::GetStylesByIndex(sal_Int32 nIndex)
{
auto& entries(lcl_GetStyleFamilyEntries());
SolarMutexGuard aGuard;
if(nIndex < 0 || o3tl::make_unsigned(nIndex) >= entries.size())
throw lang::IndexOutOfBoundsException();
if(!IsValid())
throw uno::RuntimeException();
auto eFamily = entries[nIndex].family();
assert(eFamily != SfxStyleFamily::All);
auto& rxFamily = m_vFamilies[eFamily];
if(!rxFamily.is())
rxFamily = new SwXStyleFamily(m_pDocShell, eFamily);
return rxFamily;
}
uno::Type SwXStyleFamilies::getElementType()
{
return cppu::UnoType<container::XNameContainer>::get();
}
sal_Bool SwXStyleFamilies::hasElements()
{ return true; }
void SwXStyleFamilies::loadStylesFromURL(const OUString& rURL,
const uno::Sequence< beans::PropertyValue >& aOptions)
{
SolarMutexGuard aGuard;
if(!IsValid() || rURL.isEmpty())
throw uno::RuntimeException();
SwgReaderOption aOpt;
aOpt.SetFrameFormats(true);
aOpt.SetTextFormats(true);
aOpt.SetPageDescs(true);
aOpt.SetNumRules(true);
aOpt.SetMerge(false);
for(const auto& rProperty: aOptions)
{
bool bValue = false;
if(rProperty.Value.getValueType() == cppu::UnoType<bool>::get())
bValue = rProperty.Value.get<bool>();
if(rProperty.Name == UNO_NAME_OVERWRITE_STYLES)
aOpt.SetMerge(!bValue);
else if(rProperty.Name == UNO_NAME_LOAD_NUMBERING_STYLES)
aOpt.SetNumRules(bValue);
else if(rProperty.Name == UNO_NAME_LOAD_PAGE_STYLES)
aOpt.SetPageDescs(bValue);
else if(rProperty.Name == UNO_NAME_LOAD_FRAME_STYLES)
aOpt.SetFrameFormats(bValue);
else if(rProperty.Name == UNO_NAME_LOAD_TEXT_STYLES)
aOpt.SetTextFormats(bValue);
else if(rProperty.Name == "InputStream")
{
Reference<XInputStream> xInputStream;
if (!(rProperty.Value >>= xInputStream))
throw IllegalArgumentException(u"Parameter 'InputStream' could not be converted to "
"type 'com::sun::star::io::XInputStream'"_ustr,
nullptr, 0);
aOpt.SetInputStream(xInputStream);
}
}
const ErrCodeMsg nErr = m_pDocShell->LoadStylesFromFile( rURL, aOpt, true );
if(nErr)
throw io::IOException();
}
uno::Sequence< beans::PropertyValue > SwXStyleFamilies::getStyleLoaderOptions()
{
const uno::Any aVal(true);
return comphelper::InitPropertySequence({
{ UNO_NAME_LOAD_TEXT_STYLES, aVal },
{ UNO_NAME_LOAD_FRAME_STYLES, aVal },
{ UNO_NAME_LOAD_PAGE_STYLES, aVal },
{ UNO_NAME_LOAD_NUMBERING_STYLES, aVal },
{ UNO_NAME_OVERWRITE_STYLES, aVal }
});
}
static bool lcl_GetHeaderFooterItem(
SfxItemSet const& rSet, std::u16string_view rPropName, bool const bFooter,
SvxSetItem const*& o_rpItem)
{
o_rpItem = rSet.GetItemIfSet(
bFooter ? SID_ATTR_PAGE_FOOTERSET : SID_ATTR_PAGE_HEADERSET,
false);
if (!o_rpItem &&
rPropName == UNO_NAME_FIRST_IS_SHARED)
{ // fdo#79269 header may not exist, check footer then
o_rpItem = rSet.GetItemIfSet(
(!bFooter) ? SID_ATTR_PAGE_FOOTERSET : SID_ATTR_PAGE_HEADERSET,
false);
}
return o_rpItem;
}
css::uno::Reference<css::style::XStyle> SwXStyleFamilies::CreateStyle(SfxStyleFamily eFamily, SwDoc& rDoc)
{
switch (eFamily)
{
case SfxStyleFamily::Char:
case SfxStyleFamily::Para:
case SfxStyleFamily::Pseudo:
return CreateStyleCharOrParaOrPseudo(eFamily, rDoc);
case SfxStyleFamily::Page:
return CreateStylePage(rDoc);
case SfxStyleFamily::Frame:
return CreateStyleFrame(rDoc);
case SfxStyleFamily::Table:
return CreateStyleTable(rDoc);
case SfxStyleFamily::Cell:
return CreateStyleCell(rDoc);
default:
assert(false);
return nullptr;
}
}
rtl::Reference<SwXStyle> SwXStyleFamilies::CreateStyleCharOrParaOrPseudo(SfxStyleFamily eFamily, SwDoc& rDoc)
{
return ::CreateStyleCharOrParaOrPseudo(nullptr, rDoc.GetDocShell(), UIName(u""_ustr), eFamily);
}
rtl::Reference<SwXPageStyle> SwXStyleFamilies::CreateStylePage(SwDoc& rDoc)
{
return ::CreateStylePage(nullptr, rDoc.GetDocShell(), UIName(u""_ustr));
}
rtl::Reference<SwXFrameStyle> SwXStyleFamilies::CreateStyleFrame(SwDoc& rDoc)
{
return ::CreateStyleFrame(nullptr, rDoc.GetDocShell(), UIName());
}
rtl::Reference<SwXTextTableStyle> SwXStyleFamilies::CreateStyleTable(SwDoc& rDoc)
{
return ::CreateStyleTable(rDoc.GetDocShell(), TableStyleName(u""_ustr));
}
rtl::Reference<SwXTextCellStyle> SwXStyleFamilies::CreateStyleCell(SwDoc& rDoc)
{
return ::CreateStyleCell(rDoc.GetDocShell(), UIName(u""_ustr));
}
// FIXME: Ugly special casing that should die.
uno::Reference<css::style::XStyle> SwXStyleFamilies::CreateStyleCondParagraph(SwDoc& rDoc)
{ return new SwXStyle(&rDoc, SfxStyleFamily::Para, true); };
uno::Any SwXStyleFamily::getByIndex(sal_Int32 nIndex)
{
SolarMutexGuard aGuard;
if(nIndex < 0)
throw lang::IndexOutOfBoundsException();
if(!m_pBasePool)
throw uno::RuntimeException();
ProgName sStyleProgName;
try
{
SwStyleNameMapper::FillProgName(m_rEntry.translateIndex(nIndex), sStyleProgName);
} catch(...) {}
if (!sStyleProgName.isEmpty())
return getByName(sStyleProgName.toString());
UIName sStyleUIName;
GetCountOrName(&sStyleUIName, nIndex);
if(sStyleUIName.isEmpty())
throw lang::IndexOutOfBoundsException();
SfxStyleSheetBase* pBase = m_pBasePool->Find(sStyleUIName.toString(), m_rEntry.family());
return uno::Any(uno::Reference<style::XStyle>(getStyle(pBase, sStyleUIName)));
}
uno::Any SwXStyleFamily::getByName(const OUString& rName)
{
return uno::Any(uno::Reference<style::XStyle>(getStyleByName(rName)));
}
rtl::Reference<SwXPageStyle> SwXStyleFamily::getPageStyleByName(const OUString& rName)
{
rtl::Reference<SwXBaseStyle> xStyle = getStyleByName(rName);
rtl::Reference<SwXPageStyle> xPageStyle = dynamic_cast<SwXPageStyle*>(xStyle.get());
assert(bool(xStyle) == bool(xPageStyle));
return xPageStyle;
}
rtl::Reference<SwXStyle> SwXStyleFamily::getCharacterStyleByName(const OUString& rName)
{
rtl::Reference<SwXBaseStyle> xStyle = getStyleByName(rName);
rtl::Reference<SwXStyle> xCharStyle = dynamic_cast<SwXStyle*>(xStyle.get());
assert(bool(xStyle) == bool(xCharStyle));
return xCharStyle;
}
rtl::Reference<SwXStyle> SwXStyleFamily::getParagraphStyleByName(const OUString& rName)
{
rtl::Reference<SwXBaseStyle> xStyle = getStyleByName(rName);
rtl::Reference<SwXStyle> xCharStyle = dynamic_cast<SwXStyle*>(xStyle.get());
assert(bool(xStyle) == bool(xCharStyle));
return xCharStyle;
}
rtl::Reference<SwXBaseStyle> SwXStyleFamily::getStyleByName(const OUString& rProgName)
{
SolarMutexGuard aGuard;
if(!m_pBasePool)
throw uno::RuntimeException();
UIName sStyleName;
SwStyleNameMapper::FillUIName(ProgName(rProgName), sStyleName, m_rEntry.poolId());
SfxStyleSheetBase* pBase = m_pBasePool->Find(sStyleName.toString(), m_rEntry.family());
if(!pBase)
throw container::NoSuchElementException(rProgName);
return getStyle(pBase, sStyleName);
}
rtl::Reference<SwXBaseStyle> SwXStyleFamily::getStyle(const SfxStyleSheetBase* pBase, const UIName& sStyleName)
{
rtl::Reference<SwXBaseStyle> xStyle = FindStyle(sStyleName);
if(!xStyle.is())
switch (m_rEntry.family())
{
case SfxStyleFamily::Char:
case SfxStyleFamily::Para:
case SfxStyleFamily::Pseudo:
xStyle = ::CreateStyleCharOrParaOrPseudo(m_pBasePool, m_pDocShell, sStyleName, m_rEntry.family());
break;
case SfxStyleFamily::Page:
xStyle = ::CreateStylePage(m_pBasePool, m_pDocShell, sStyleName);
break;
case SfxStyleFamily::Frame:
xStyle = ::CreateStyleFrame(m_pBasePool, m_pDocShell, UIName(pBase->GetName()));
break;
case SfxStyleFamily::Table:
xStyle = ::CreateStyleTable(m_pDocShell, TableStyleName(sStyleName.toString()));
break;
case SfxStyleFamily::Cell:
xStyle = ::CreateStyleCell(m_pDocShell, sStyleName);
break;
default:
assert(false);
}
return xStyle;
}
uno::Sequence<OUString> SwXStyleFamily::getElementNames()
{
SolarMutexGuard aGuard;
if(!m_pBasePool)
throw uno::RuntimeException();
std::vector<OUString> vRet;
std::unique_ptr<SfxStyleSheetIterator> pIt = m_pBasePool->CreateIterator(m_rEntry.family());
for (SfxStyleSheetBase* pStyle = pIt->First(); pStyle; pStyle = pIt->Next())
{
ProgName sName;
SwStyleNameMapper::FillProgName(UIName(pStyle->GetName()), sName, m_rEntry.poolId());
vRet.push_back(sName.toString());
}
return comphelper::containerToSequence(vRet);
}
sal_Bool SwXStyleFamily::hasByName(const OUString& rProgName)
{
SolarMutexGuard aGuard;
if(!m_pBasePool)
throw uno::RuntimeException();
UIName sStyleName;
SwStyleNameMapper::FillUIName(ProgName(rProgName), sStyleName, m_rEntry.poolId());
SfxStyleSheetBase* pBase = m_pBasePool->Find(sStyleName.toString(), m_rEntry.family());
return nullptr != pBase;
}
void SwXStyleFamily::insertStyleByName(const OUString& rProgName, const rtl::Reference<SwXStyle>& pNewStyle)
{
SolarMutexGuard aGuard;
if(!m_pBasePool)
throw uno::RuntimeException();
UIName sStyleName;
SwStyleNameMapper::FillUIName(ProgName(rProgName), sStyleName, m_rEntry.poolId());
SfxStyleSheetBase* pBase = m_pBasePool->Find(sStyleName.toString(), m_rEntry.family());
if (pBase)
throw container::ElementExistException();
insertStyleByNameImpl(pNewStyle, sStyleName);
}
void SwXStyleFamily::insertByName(const OUString& rProgName, const uno::Any& rElement)
{
SolarMutexGuard aGuard;
if(!m_pBasePool)
throw uno::RuntimeException();
UIName sStyleName;
SwStyleNameMapper::FillUIName(ProgName(rProgName), sStyleName, m_rEntry.poolId());
SfxStyleSheetBase* pBase = m_pBasePool->Find(sStyleName.toString(), m_rEntry.family());
if (pBase)
throw container::ElementExistException();
if(rElement.getValueTypeClass() != uno::TypeClass_INTERFACE)
throw lang::IllegalArgumentException();
if (SwGetPoolIdFromName::CellStyle == m_rEntry.poolId())
{
// handle cell style
uno::Reference<style::XStyle> xStyle = rElement.get<uno::Reference<style::XStyle>>();
SwXTextCellStyle* pNewStyle = dynamic_cast<SwXTextCellStyle*>(xStyle.get());
if (!pNewStyle)
throw lang::IllegalArgumentException();
pNewStyle->setName(sStyleName.toString()); // insertByName sets the element name
m_pDocShell->GetDoc()->GetCellStyles().AddBoxFormat(*pNewStyle->GetBoxFormat(), sStyleName);
pNewStyle->SetPhysical();
}
else if (SwGetPoolIdFromName::TableStyle == m_rEntry.poolId())
{
// handle table style
uno::Reference<style::XStyle> xStyle = rElement.get<uno::Reference<style::XStyle>>();
SwXTextTableStyle* pNewStyle = dynamic_cast<SwXTextTableStyle*>(xStyle.get());
if (!pNewStyle)
throw lang::IllegalArgumentException();
pNewStyle->setName(rProgName); // insertByName sets the element name
m_pDocShell->GetDoc()->GetTableStyles().AddAutoFormat(*pNewStyle->GetTableFormat());
pNewStyle->SetPhysical();
}
else
{
uno::Reference<lang::XUnoTunnel> xStyleTunnel = rElement.get<uno::Reference<lang::XUnoTunnel>>();
SwXStyle* pNewStyle = comphelper::getFromUnoTunnel<SwXStyle>(xStyleTunnel);
if (!pNewStyle)
throw lang::IllegalArgumentException();
insertStyleByNameImpl(pNewStyle, sStyleName);
}
}
void SwXStyleFamily::insertStyleByNameImpl(const rtl::Reference<SwXStyle>& pNewStyle, const UIName& rUIName)
{
if (!pNewStyle->IsDescriptor() || pNewStyle->GetFamily() != m_rEntry.family())
throw lang::IllegalArgumentException();
SfxStyleSearchBits nMask = SfxStyleSearchBits::All;
if(m_rEntry.family() == SfxStyleFamily::Para && !pNewStyle->IsConditional())
nMask &= ~SfxStyleSearchBits::SwCondColl;
auto pStyle = &m_pBasePool->Make(rUIName.toString(), m_rEntry.family(), nMask);
pNewStyle->SetDoc(m_pDocShell->GetDoc(), m_pBasePool);
pNewStyle->SetStyleUIName(rUIName);
pStyle->SetParent(pNewStyle->GetParentStyleUIName().toString());
// after all, we still need to apply the properties of the descriptor
pNewStyle->ApplyDescriptorProperties();
}
void SwXStyleFamily::replaceByName(const OUString& rProgName, const uno::Any& rElement)
{
SolarMutexGuard aGuard;
if(!m_pBasePool)
throw uno::RuntimeException();
UIName sStyleName;
SwStyleNameMapper::FillUIName(ProgName(rProgName), sStyleName, m_rEntry.poolId());
SfxStyleSheetBase* pBase = m_pBasePool->Find(sStyleName.toString(), m_rEntry.family());
// replacements only for userdefined styles
if(!pBase)
throw container::NoSuchElementException();
if (SwGetPoolIdFromName::CellStyle == m_rEntry.poolId())
{
// handle cell styles, don't call on assigned cell styles (TableStyle child)
TableStyleName sParent;
SwBoxAutoFormat* pBoxAutoFormat = SwXTextCellStyle::GetBoxAutoFormat(m_pDocShell, sStyleName, &sParent);
if (pBoxAutoFormat && sParent.isEmpty())// if parent exists then this style is assigned to a table style. Don't replace.
{
uno::Reference<style::XStyle> xStyle = rElement.get<uno::Reference<style::XStyle>>();
SwXTextCellStyle* pStyleToReplaceWith = dynamic_cast<SwXTextCellStyle*>(xStyle.get());
if (!pStyleToReplaceWith)
throw lang::IllegalArgumentException();
pStyleToReplaceWith->setName(sStyleName.toString());
*pBoxAutoFormat = *pStyleToReplaceWith->GetBoxFormat();
pStyleToReplaceWith->SetPhysical();
}
}
else if (SwGetPoolIdFromName::TableStyle == m_rEntry.poolId())
{
// handle table styles
SwTableAutoFormat* pTableAutoFormat = SwXTextTableStyle::GetTableAutoFormat(m_pDocShell, TableStyleName(sStyleName.toString()));
if (pTableAutoFormat)
{
uno::Reference<style::XStyle> xStyle = rElement.get<uno::Reference<style::XStyle>>();
SwXTextTableStyle* pStyleToReplaceWith = dynamic_cast<SwXTextTableStyle*>(xStyle.get());
if (!pStyleToReplaceWith)
throw lang::IllegalArgumentException();
pStyleToReplaceWith->setName(rProgName);
*pTableAutoFormat = *pStyleToReplaceWith->GetTableFormat();
pStyleToReplaceWith->SetPhysical();
}
}
else
{
if(!pBase->IsUserDefined())
throw lang::IllegalArgumentException();
//if there's an object available to this style then it must be invalidated
uno::Reference<style::XStyle> xStyle = FindStyle(UIName(pBase->GetName()));
if(xStyle.is())
{
SwXStyle* pStyle = comphelper::getFromUnoTunnel<SwXStyle>(xStyle);
if(pStyle)
pStyle->Invalidate();
}
m_pBasePool->Remove(pBase);
insertByName(rProgName, rElement);
}
}
void SwXStyleFamily::removeByName(const OUString& rProgName)
{
SolarMutexGuard aGuard;
if(!m_pBasePool)
throw uno::RuntimeException();
UIName sName;
SwStyleNameMapper::FillUIName(ProgName(rProgName), sName, m_rEntry.poolId());
SfxStyleSheetBase* pBase = m_pBasePool->Find(sName.toString(), m_rEntry.family());
if(!pBase)
throw container::NoSuchElementException();
if (SwGetPoolIdFromName::CellStyle == m_rEntry.poolId())
{
// handle cell style
m_pDocShell->GetDoc()->GetCellStyles().RemoveBoxFormat(rProgName);
}
else if (SwGetPoolIdFromName::TableStyle == m_rEntry.poolId())
{
// handle table style
m_pDocShell->GetDoc()->GetTableStyles().EraseAutoFormat(TableStyleName(sName.toString()));
}
else
m_pBasePool->Remove(pBase);
}
uno::Any SAL_CALL SwXStyleFamily::getPropertyValue( const OUString& sPropertyName )
{
if(sPropertyName != "DisplayName")
throw beans::UnknownPropertyException( "unknown property: " + sPropertyName, getXWeak() );
SolarMutexGuard aGuard;
return uno::Any(SwResId(m_rEntry.resId()));
}
SwXStyle* SwXStyleFamily::FindStyle(const UIName& rStyleName) const
{
// put params for lambda into struct, so that the lambda does not allocate memory on the heap.
struct MyParams {
const StyleFamilyEntry& m_rEntry;
SwXStyle* pFoundStyle;
const UIName& aStyleName;
} aParams { m_rEntry, nullptr, rStyleName };
m_pBasePool->ForAllListeners(
[&aParams] (SfxListener* pListener)
{
if (!pListener->IsSwXStyle())
return false;
SwXStyle* pTempStyle = static_cast<SwXStyle*>(pListener);
if(pTempStyle
&& pTempStyle->GetFamily() == aParams.m_rEntry.family()
&& pTempStyle->GetStyleUIName() == aParams.aStyleName)
{
aParams.pFoundStyle = pTempStyle;
return true; // break
}
return false;
});
return aParams.pFoundStyle;
}
static SwGetPoolIdFromName lcl_GetSwEnumFromSfxEnum(SfxStyleFamily eFamily)
{
auto& entries(lcl_GetStyleFamilyEntries());
const auto pEntry = std::find_if(entries.begin(), entries.end(),
[eFamily] (const StyleFamilyEntry& e) { return e.family() == eFamily; });
if(pEntry != entries.end())
return pEntry->poolId();
SAL_WARN("sw.uno", "someone asking for all styles in unostyle.cxx!" );
return SwGetPoolIdFromName::ChrFmt;
}
const uno::Sequence<sal_Int8>& SwXStyle::getUnoTunnelId()
{
static const comphelper::UnoIdInit theSwXStyleUnoTunnelId;
return theSwXStyleUnoTunnelId.getSeq();
}
sal_Int64 SAL_CALL SwXStyle::getSomething(const uno::Sequence<sal_Int8>& rId)
{
return comphelper::getSomethingImpl(rId, this);
}
uno::Sequence< OUString > SwXStyle::getSupportedServiceNames()
{
tools::Long nCount = 1;
if(SfxStyleFamily::Para == m_rEntry.family())
{
nCount = 5;
if(m_bIsConditional)
nCount++;
}
else if(SfxStyleFamily::Char == m_rEntry.family())
nCount = 5;
else if(SfxStyleFamily::Page == m_rEntry.family())
nCount = 3;
uno::Sequence< OUString > aRet(nCount);
OUString* pArray = aRet.getArray();
pArray[0] = "com.sun.star.style.Style";
switch(m_rEntry.family())
{
case SfxStyleFamily::Char:
pArray[1] = "com.sun.star.style.CharacterStyle";
pArray[2] = "com.sun.star.style.CharacterProperties";
pArray[3] = "com.sun.star.style.CharacterPropertiesAsian";
pArray[4] = "com.sun.star.style.CharacterPropertiesComplex";
break;
case SfxStyleFamily::Page:
pArray[1] = "com.sun.star.style.PageStyle";
pArray[2] = "com.sun.star.style.PageProperties";
break;
case SfxStyleFamily::Para:
pArray[1] = "com.sun.star.style.ParagraphStyle";
pArray[2] = "com.sun.star.style.ParagraphProperties";
pArray[3] = "com.sun.star.style.ParagraphPropertiesAsian";
pArray[4] = "com.sun.star.style.ParagraphPropertiesComplex";
if(m_bIsConditional)
pArray[5] = "com.sun.star.style.ConditionalParagraphStyle";
break;
default:
;
}
return aRet;
}
static uno::Reference<beans::XPropertySet> lcl_InitStandardStyle(const SfxStyleFamily eFamily, uno::Reference<container::XNameAccess> const & rxStyleFamily)
{
using return_t = decltype(lcl_InitStandardStyle(eFamily, rxStyleFamily));
if(eFamily != SfxStyleFamily::Para && eFamily != SfxStyleFamily::Page)
return {};
auto aResult(rxStyleFamily->getByName(u"Standard"_ustr));
if(!aResult.has<return_t>())
return {};
return aResult.get<return_t>();
}
static uno::Reference<container::XNameAccess> lcl_InitStyleFamily(SwDoc* pDoc, const StyleFamilyEntry& rEntry)
{
using return_t = decltype(lcl_InitStyleFamily(pDoc, rEntry));
if(rEntry.family() != SfxStyleFamily::Char
&& rEntry.family() != SfxStyleFamily::Para
&& rEntry.family() != SfxStyleFamily::Page)
return {};
SwDocShell* pShell = pDoc->GetDocShell();
if (!pShell)
return {};
rtl::Reference<SwXTextDocument> xModel(pShell->GetBaseModel());
auto xFamilies = xModel->getStyleFamilies();
auto aResult(xFamilies->getByName(rEntry.name()));
if(!aResult.has<return_t>())
return {};
return aResult.get<return_t>();
}
static bool lcl_InitConditional(SfxStyleSheetBasePool* pBasePool, const SfxStyleFamily eFamily, const UIName& rStyleName)
{
if(!pBasePool || eFamily != SfxStyleFamily::Para)
return false;
SfxStyleSheetBase* pBase = pBasePool->Find(rStyleName.toString(), eFamily);
SAL_WARN_IF(!pBase, "sw.uno", "where is the style?" );
if(!pBase)
return false;
const sal_uInt16 nId(SwStyleNameMapper::GetPoolIdFromUIName(rStyleName, SwGetPoolIdFromName::TxtColl));
if(nId != USHRT_MAX)
return ::IsConditionalByPoolId(nId);
return RES_CONDTXTFMTCOLL == static_cast<SwDocStyleSheet*>(pBase)->GetCollection()->Which();
}
static const StyleFamilyEntry& lcl_GetStyleEntry(const SfxStyleFamily eFamily)
{
auto& entries = lcl_GetStyleFamilyEntries();
const auto pEntry = std::find_if(entries.begin(), entries.end(),
[eFamily] (const StyleFamilyEntry& e) { return e.family() == eFamily; });
assert(pEntry != entries.end());
return *pEntry;
}
SwXStyle::SwXStyle(SwDoc* pDoc, SfxStyleFamily eFamily, bool bConditional)
: m_pDoc(pDoc)
, m_rEntry(lcl_GetStyleEntry(eFamily))
, m_bIsDescriptor(true)
, m_bIsConditional(bConditional)
, m_pBasePool(nullptr)
, m_xStyleFamily(lcl_InitStyleFamily(pDoc, m_rEntry))
, m_xStyleData(lcl_InitStandardStyle(eFamily, m_xStyleFamily))
{
assert(!m_bIsConditional || m_rEntry.family() == SfxStyleFamily::Para); // only paragraph styles are conditional
// Register ourselves as a listener to the document (via the page descriptor)
SvtListener::StartListening(pDoc->getIDocumentStylePoolAccess().GetPageDescFromPool(RES_POOLPAGE_STANDARD)->GetNotifier());
m_pPropertiesImpl = std::make_unique<SwStyleProperties_Impl>(
aSwMapProvider.GetPropertySet(m_bIsConditional ? PROPERTY_MAP_CONDITIONAL_PARA_STYLE : m_rEntry.propMapType())->getPropertyMap());
}
SwXStyle::SwXStyle(SfxStyleSheetBasePool* pPool, SfxStyleFamily eFamily, SwDoc* pDoc, const UIName& rStyleName)
: m_pDoc(pDoc)
, m_sStyleUIName(rStyleName)
, m_rEntry(lcl_GetStyleEntry(eFamily))
, m_bIsDescriptor(false)
, m_bIsConditional(lcl_InitConditional(pPool, eFamily, rStyleName))
, m_pBasePool(pPool)
{ }
SwXStyle::~SwXStyle()
{
SolarMutexGuard aGuard;
if(m_pBasePool)
SfxListener::EndListening(*m_pBasePool);
m_pPropertiesImpl.reset();
SvtListener::EndListeningAll();
}
void SwXStyle::Notify(const SfxHint& rHint)
{
if(rHint.GetId() == SfxHintId::Dying)
{
m_pDoc = nullptr;
m_xStyleData.clear();
m_xStyleFamily.clear();
}
}
OUString SwXStyle::getName()
{
SolarMutexGuard aGuard;
if(!m_pBasePool)
{
ProgName ret;
SwStyleNameMapper::FillProgName(m_sStyleUIName, ret, lcl_GetSwEnumFromSfxEnum(m_rEntry.family()));
return ret.toString();
}
SfxStyleSheetBase* pBase = m_pBasePool->Find(m_sStyleUIName.toString(), m_rEntry.family());
SAL_WARN_IF(!pBase, "sw.uno", "where is the style?");
if(!pBase)
throw uno::RuntimeException();
ProgName aString;
SwStyleNameMapper::FillProgName(UIName(pBase->GetName()), aString, lcl_GetSwEnumFromSfxEnum ( m_rEntry.family()));
return aString.toString();
}
void SwXStyle::setName(const OUString& rProgName)
{
SolarMutexGuard aGuard;
if(!m_pBasePool)
{
// it looks like a descriptor style with a built-in name cannot be
// inserted into the document anyway - just convert name for consistency
SwStyleNameMapper::FillUIName(ProgName(rProgName), m_sStyleUIName, m_rEntry.poolId());
return;
}
SfxStyleSheetBase* pBase = m_pBasePool->Find(m_sStyleUIName.toString(), m_rEntry.family());
SAL_WARN_IF(!pBase, "sw.uno", "where is the style?");
if(!pBase || !pBase->IsUserDefined())
throw uno::RuntimeException();
UIName sUIName;
// conversion should actually be irrelevant due to IsUserDefined() check
SwStyleNameMapper::FillUIName(ProgName(rProgName), sUIName, m_rEntry.poolId());
rtl::Reference<SwDocStyleSheet> xTmp(new SwDocStyleSheet(*static_cast<SwDocStyleSheet*>(pBase)));
if (!xTmp->SetName(sUIName.toString()))
throw uno::RuntimeException();
m_sStyleUIName = std::move(sUIName);
}
sal_Bool SwXStyle::isUserDefined()
{
SolarMutexGuard aGuard;
if(!m_pBasePool)
throw uno::RuntimeException();
SfxStyleSheetBase* pBase = m_pBasePool->Find(m_sStyleUIName.toString(), m_rEntry.family());
//if it is not found it must be non user defined
return pBase && pBase->IsUserDefined();
}
sal_Bool SwXStyle::isInUse()
{
SolarMutexGuard aGuard;
if(!m_pBasePool)
throw uno::RuntimeException();
SfxStyleSheetBase* pBase = m_pBasePool->Find(m_sStyleUIName.toString(), m_rEntry.family(), SfxStyleSearchBits::Used);
return pBase && pBase->IsUsed();
}
OUString SwXStyle::getParentStyle()
{
SolarMutexGuard aGuard;
ProgName ret;
if(!m_pBasePool)
{
if(!m_bIsDescriptor)
throw uno::RuntimeException();
SwStyleNameMapper::FillProgName(m_sParentStyleUIName, ret, lcl_GetSwEnumFromSfxEnum(m_rEntry.family()));
return ret.toString();
}
SfxStyleSheetBase* pBase = m_pBasePool->Find(m_sStyleUIName.toString(), m_rEntry.family());
OUString aString;
if(pBase)
aString = pBase->GetParent();
SwStyleNameMapper::FillProgName(UIName(aString), ret, lcl_GetSwEnumFromSfxEnum(m_rEntry.family()));
return ret.toString();
}
void SwXStyle::setParentStyle(const OUString& rParentStyleProgName)
{
SolarMutexGuard aGuard;
UIName sParentStyle;
SwStyleNameMapper::FillUIName(ProgName(rParentStyleProgName), sParentStyle, lcl_GetSwEnumFromSfxEnum(m_rEntry.family()));
if(!m_pBasePool)
{
if(!m_bIsDescriptor)
throw uno::RuntimeException();
m_sParentStyleUIName = sParentStyle;
try
{
const auto aAny = m_xStyleFamily->getByName(rParentStyleProgName);
m_xStyleData = aAny.get<decltype(m_xStyleData)>();
}
catch(...)
{ }
return;
}
SfxStyleSheetBase* pBase = m_pBasePool->Find(m_sStyleUIName.toString(), m_rEntry.family());
if(!pBase)
throw uno::RuntimeException();
rtl::Reference<SwDocStyleSheet> xBase(new SwDocStyleSheet(*static_cast<SwDocStyleSheet*>(pBase)));
//make it a 'real' style - necessary for pooled styles
xBase->GetItemSet();
if(xBase->GetParent() != sParentStyle)
{
if(!xBase->SetParent(sParentStyle.toString()))
throw uno::RuntimeException();
}
}
uno::Reference<beans::XPropertySetInfo> SwXStyle::getPropertySetInfo()
{
if(m_bIsConditional)
{
assert(m_rEntry.family() == SfxStyleFamily::Para);
static auto xCondParaRef = aSwMapProvider.GetPropertySet(PROPERTY_MAP_CONDITIONAL_PARA_STYLE)->getPropertySetInfo();
return xCondParaRef;
}
return m_rEntry.xPSInfo();
}
void SwXStyle::ApplyDescriptorProperties()
{
m_bIsDescriptor = false;
m_xStyleData.clear();
m_xStyleFamily.clear();
m_pPropertiesImpl->Apply(*this);
}
const TranslateId STR_POOLPAGE_ARY[] =
{
// Page styles
STR_POOLPAGE_STANDARD,
STR_POOLPAGE_FIRST,
STR_POOLPAGE_LEFT,
STR_POOLPAGE_RIGHT,
STR_POOLPAGE_ENVELOPE,
STR_POOLPAGE_REGISTER,
STR_POOLPAGE_HTML,
STR_POOLPAGE_FOOTNOTE,
STR_POOLPAGE_ENDNOTE,
STR_POOLPAGE_LANDSCAPE
};
const SwPageDesc* SwStyleBase_Impl::GetOldPageDesc()
{
if(!m_pOldPageDesc)
{
SwPageDesc *pd = m_rDoc.FindPageDesc(m_sStyleUIName);
if(pd)
m_pOldPageDesc = pd;
if(!m_pOldPageDesc)
{
for (size_t i = 0; i < SAL_N_ELEMENTS(STR_POOLPAGE_ARY); ++i)
{
if (SwResId(STR_POOLPAGE_ARY[i]) == m_sStyleUIName)
{
m_pOldPageDesc = m_rDoc.getIDocumentStylePoolAccess().GetPageDescFromPool(RES_POOLPAGE_BEGIN + i);
break;
}
}
}
}
return m_pOldPageDesc;
}
static sal_uInt8 lcl_TranslateMetric(const SfxItemPropertyMapEntry& rEntry, SwDoc* pDoc, uno::Any& o_aValue)
{
// check for needed metric translation
if(!(rEntry.nMoreFlags & PropertyMoreFlags::METRIC_ITEM))
return rEntry.nMemberId;
// exception: If these ItemTypes are used, do not convert when these are negative
// since this means they are intended as percent values
if((XATTR_FILLBMP_SIZEX == rEntry.nWID || XATTR_FILLBMP_SIZEY == rEntry.nWID)
&& o_aValue.has<sal_Int32>()
&& o_aValue.get<sal_Int32>() < 0)
return rEntry.nMemberId;
if(!pDoc)
return rEntry.nMemberId;
const SfxItemPool& rPool = pDoc->GetAttrPool();
const MapUnit eMapUnit(rPool.GetMetric(rEntry.nWID));
if(eMapUnit != MapUnit::Map100thMM)
SvxUnoConvertFromMM(eMapUnit, o_aValue);
return rEntry.nMemberId;
}
template<>
void SwXStyle::SetPropertyValue<HINT_BEGIN>(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& /*rPropSet*/, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
{
// default ItemSet handling
SfxItemSet& rStyleSet = o_rStyleBase.GetItemSet();
SfxItemSet aSet(*rStyleSet.GetPool(), rEntry.nWID, rEntry.nWID);
aSet.SetParent(&rStyleSet);
SfxItemPropertySet::setPropertyValue(rEntry, rValue, aSet);
rStyleSet.Put(aSet);
}
template<>
void SwXStyle::SetPropertyValue<FN_UNO_HIDDEN>(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& rPropSet, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
{
bool bHidden = false;
if(rValue >>= bHidden)
{
//make it a 'real' style - necessary for pooled styles
o_rStyleBase.getNewBase()->GetItemSet();
o_rStyleBase.getNewBase()->SetHidden(bHidden);
}
SetPropertyValue<HINT_BEGIN>(rEntry, rPropSet, rValue, o_rStyleBase);
}
template<>
void SwXStyle::SetPropertyValue<FN_UNO_STYLE_INTEROP_GRAB_BAG>(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& rPropSet, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
{
o_rStyleBase.getNewBase()->GetItemSet();
o_rStyleBase.getNewBase()->SetGrabBagItem(rValue);
SetPropertyValue<HINT_BEGIN>(rEntry, rPropSet, rValue, o_rStyleBase);
}
template<>
void SwXStyle::SetPropertyValue<sal_uInt16(XATTR_FILLGRADIENT)>(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& rPropSet, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
{
uno::Any aValue(rValue);
const auto nMemberId(lcl_TranslateMetric(rEntry, m_pDoc, aValue));
if(MID_NAME == nMemberId)
{
// add set commands for FillName items
SfxItemSet& rStyleSet = o_rStyleBase.GetItemSet();
if(!aValue.has<OUString>())
throw lang::IllegalArgumentException();
SvxShape::SetFillAttribute(rEntry.nWID, aValue.get<OUString>(), rStyleSet);
}
else if(MID_BITMAP == nMemberId)
{
if(sal_uInt16(XATTR_FILLBITMAP) == rEntry.nWID)
{
Graphic aNullGraphic;
SfxItemSet& rStyleSet = o_rStyleBase.GetItemSet();
XFillBitmapItem aXFillBitmapItem(std::move(aNullGraphic));
aXFillBitmapItem.PutValue(aValue, nMemberId);
rStyleSet.Put(aXFillBitmapItem);
}
}
else
SetPropertyValue<HINT_BEGIN>(rEntry, rPropSet, aValue, o_rStyleBase);
}
template<>
void SwXStyle::SetPropertyValue<sal_uInt16(RES_BACKGROUND)>(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet&, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
{
SfxItemSet& rStyleSet = o_rStyleBase.GetItemSet();
const std::unique_ptr<SvxBrushItem> aOriginalBrushItem(getSvxBrushItemFromSourceSet(rStyleSet, RES_BACKGROUND, true, m_pDoc->IsInXMLImport()));
std::unique_ptr<SvxBrushItem> aChangedBrushItem(aOriginalBrushItem->Clone());
uno::Any aValue(rValue);
const auto nMemberId(lcl_TranslateMetric(rEntry, m_pDoc, aValue));
aChangedBrushItem->PutValue(aValue, nMemberId);
// 0xff is already the default - but if BackTransparent is set
// to true, it must be applied in the item set on ODF import
// to potentially override parent style, which is unknown yet
if(*aChangedBrushItem == *aOriginalBrushItem && (MID_GRAPHIC_TRANSPARENT != nMemberId || !aValue.has<bool>() || !aValue.get<bool>()))
return;
setSvxBrushItemAsFillAttributesToTargetSet(*aChangedBrushItem, rStyleSet);
}
template<>
void SwXStyle::SetPropertyValue<OWN_ATTR_FILLBMP_MODE>(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
{
drawing::BitmapMode eMode;
if(!(rValue >>= eMode))
{
if(!rValue.has<sal_Int32>())
throw lang::IllegalArgumentException();
eMode = static_cast<drawing::BitmapMode>(rValue.get<sal_Int32>());
}
SfxItemSet& rStyleSet = o_rStyleBase.GetItemSet();
rStyleSet.Put(XFillBmpStretchItem(drawing::BitmapMode_STRETCH == eMode));
rStyleSet.Put(XFillBmpTileItem(drawing::BitmapMode_REPEAT == eMode));
}
template<>
void SwXStyle::SetPropertyValue<sal_uInt16(RES_PAPER_BIN)>(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& /*rPropSet*/, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
{
if (!rValue.has<OUString>() && !rValue.has<sal_Int32>())
throw lang::IllegalArgumentException();
SfxPrinter* pPrinter = m_pDoc->getIDocumentDeviceAccess().getPrinter(true);
assert(pPrinter && "getPrinter(true) always returns a non-null SfxPrinter");
// PAPER_BINs have no meaning when there is no actual printer
if (pPrinter->IsDisplayPrinter())
return;
using printeridx_t = decltype(pPrinter->GetPaperBinCount());
printeridx_t nBin = std::numeric_limits<printeridx_t>::max();
if(rValue.has<OUString>())
{
OUString sValue(rValue.get<OUString>());
if(sValue == "[From printer settings]")
nBin = std::numeric_limits<printeridx_t>::max()-1;
else
{
for(printeridx_t i=0, nEnd = pPrinter->GetPaperBinCount(); i < nEnd; ++i)
{
if (sValue == pPrinter->GetPaperBinName(i))
{
nBin = i;
break;
}
}
}
}
else if (rValue.has<sal_Int32>())
{
sal_Int32 nValue (rValue.get<sal_Int32>());
nBin = pPrinter->GetPaperBinBySourceIndex(nValue);
}
if(nBin == std::numeric_limits<printeridx_t>::max())
throw lang::IllegalArgumentException();
SfxItemSet& rStyleSet = o_rStyleBase.GetItemSet();
SfxItemSet aSet(*rStyleSet.GetPool(), rEntry.nWID, rEntry.nWID);
aSet.SetParent(&rStyleSet);
SfxItemPropertySet::setPropertyValue(rEntry, uno::Any(static_cast<sal_Int8>(nBin == std::numeric_limits<printeridx_t>::max()-1 ? -1 : nBin)), aSet);
rStyleSet.Put(aSet);
}
template<>
void SwXStyle::SetPropertyValue<FN_UNO_NUM_RULES>(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
{
auto xNumberTunnel(rValue.get<uno::Reference<container::XIndexReplace>>());
if(!xNumberTunnel)
throw lang::IllegalArgumentException();
SwXNumberingRules* pSwXRules = dynamic_cast<SwXNumberingRules*>(xNumberTunnel.get());
if(!pSwXRules)
return;
SwNumRule aSetRule(*pSwXRules->GetNumRule());
for(sal_uInt16 i = 0; i < MAXLEVEL; ++i)
{
const SwNumFormat* pFormat = aSetRule.GetNumFormat(i);
if(!pFormat)
continue;
SwNumFormat aFormat(*pFormat);
const auto& rCharName(pSwXRules->GetNewCharStyleNames()[i]);
if(!rCharName.isEmpty()
&& !SwXNumberingRules::isInvalidStyle(rCharName)
&& (!pFormat->GetCharFormat() || pFormat->GetCharFormat()->GetName() != rCharName))
{
auto pCharFormatIt(std::find_if(m_pDoc->GetCharFormats()->begin(), m_pDoc->GetCharFormats()->end(),
[&rCharName] (SwCharFormat* pF) { return pF->GetName() == rCharName; }));
if(pCharFormatIt != m_pDoc->GetCharFormats()->end())
aFormat.SetCharFormat(*pCharFormatIt);
else if(m_pBasePool)
{
auto pBase(m_pBasePool->Find(rCharName.toString(), SfxStyleFamily::Char));
if(!pBase)
pBase = &m_pBasePool->Make(rCharName.toString(), SfxStyleFamily::Char);
aFormat.SetCharFormat(static_cast<SwDocStyleSheet*>(pBase)->GetCharFormat());
}
else
aFormat.SetCharFormat(nullptr);
}
// same for fonts:
const auto& rBulletName(pSwXRules->GetBulletFontNames()[i]);
if(!rBulletName.isEmpty()
&& !SwXNumberingRules::isInvalidStyle(rBulletName)
&& (!pFormat->GetBulletFont() || pFormat->GetBulletFont()->GetFamilyName() != rBulletName))
{
if (SwDocShell* pShell = m_pDoc->GetDocShell())
{
const auto pFontListItem(static_cast<const SvxFontListItem*>(pShell->GetItem(SID_ATTR_CHAR_FONTLIST)));
const auto pList(pFontListItem->GetFontList());
vcl::Font aFont(pList->Get(rBulletName.toString(), WEIGHT_NORMAL, ITALIC_NONE));
aFormat.SetBulletFont(&aFont);
}
}
aSetRule.Set(i, &aFormat);
}
o_rStyleBase.getNewBase()->SetNumRule(aSetRule);
}
template<>
void SwXStyle::SetPropertyValue<sal_uInt16(RES_PARATR_OUTLINELEVEL)>(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
{
if(!rValue.has<sal_Int16>())
return;
const auto nLevel(rValue.get<sal_Int16>());
if(0 <= nLevel && nLevel <= MAXLEVEL)
o_rStyleBase.getNewBase()->GetCollection()->SetAttrOutlineLevel(nLevel);
}
template<>
void SwXStyle::SetPropertyValue<FN_UNO_FOLLOW_STYLE>(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
{
if(!rValue.has<OUString>())
return;
const auto sValue(rValue.get<OUString>());
UIName aString;
SwStyleNameMapper::FillUIName(ProgName(sValue), aString, m_rEntry.poolId());
o_rStyleBase.getNewBase()->SetFollow(aString.toString());
}
template <>
void SwXStyle::SetPropertyValue<FN_UNO_LINK_STYLE>(const SfxItemPropertyMapEntry&,
const SfxItemPropertySet&,
const uno::Any& rValue,
SwStyleBase_Impl& o_rStyleBase)
{
if (!rValue.has<OUString>())
return;
const auto sValue(rValue.get<OUString>());
UIName aString;
SwStyleNameMapper::FillUIName(ProgName(sValue), aString, m_rEntry.poolId());
o_rStyleBase.getNewBase()->SetLink(aString.toString());
}
template<>
void SwXStyle::SetPropertyValue<sal_uInt16(RES_PAGEDESC)>(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& rPropSet, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
{
if(MID_PAGEDESC_PAGEDESCNAME != rEntry.nMemberId)
{
SetPropertyValue<HINT_BEGIN>(rEntry, rPropSet, rValue, o_rStyleBase);
return;
}
if(!rValue.has<OUString>())
throw lang::IllegalArgumentException();
// special handling for RES_PAGEDESC
SfxItemSet& rStyleSet = o_rStyleBase.GetItemSet();
std::unique_ptr<SwFormatPageDesc> pNewDesc;
if(const SwFormatPageDesc* pItem = rStyleSet.GetItemIfSet(RES_PAGEDESC))
pNewDesc.reset(new SwFormatPageDesc(*pItem));
else
pNewDesc.reset(new SwFormatPageDesc);
const auto sValue(rValue.get<OUString>());
UIName sDescName;
SwStyleNameMapper::FillUIName(ProgName(sValue), sDescName, SwGetPoolIdFromName::PageDesc);
if(pNewDesc->GetPageDesc() && pNewDesc->GetPageDesc()->GetName() == sDescName)
return;
if(sDescName.isEmpty())
{
rStyleSet.ClearItem(RES_BREAK);
rStyleSet.Put(SwFormatPageDesc());
}
else
{
SwPageDesc* pPageDesc(SwPageDesc::GetByName(*m_pDoc, sDescName));
if(!pPageDesc)
throw lang::IllegalArgumentException();
pNewDesc->RegisterToPageDesc(*pPageDesc);
rStyleSet.Put(std::move(pNewDesc));
}
}
template<>
void SwXStyle::SetPropertyValue<sal_uInt16(RES_TEXT_VERT_ADJUST)>(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& rPropSet, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
{
if(m_rEntry.family() != SfxStyleFamily::Page)
{
SetPropertyValue<HINT_BEGIN>(rEntry, rPropSet, rValue, o_rStyleBase);
return;
}
if(!m_pDoc || !rValue.has<drawing::TextVerticalAdjust>() || !o_rStyleBase.GetOldPageDesc())
return;
SwPageDesc* pPageDesc = m_pDoc->FindPageDesc(o_rStyleBase.GetOldPageDesc()->GetName());
if(pPageDesc)
pPageDesc->SetVerticalAdjustment(rValue.get<drawing::TextVerticalAdjust>());
}
template<>
void SwXStyle::SetPropertyValue<FN_UNO_IS_AUTO_UPDATE>(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
{
if(!rValue.has<bool>())
throw lang::IllegalArgumentException();
const bool bAuto(rValue.get<bool>());
if(SfxStyleFamily::Para == m_rEntry.family())
o_rStyleBase.getNewBase()->GetCollection()->SetAutoUpdateOnDirectFormat(bAuto);
else if(SfxStyleFamily::Frame == m_rEntry.family())
o_rStyleBase.getNewBase()->GetFrameFormat()->SetAutoUpdateOnDirectFormat(bAuto);
}
template<>
void SwXStyle::SetPropertyValue<FN_UNO_PARA_STYLE_CONDITIONS>(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
{
static_assert(COND_COMMAND_COUNT == 28, "invalid size of command count?");
using expectedarg_t = uno::Sequence<beans::NamedValue>;
if(!rValue.has<expectedarg_t>() || !m_pBasePool)
throw lang::IllegalArgumentException();
SwCondCollItem aCondItem;
const auto aNamedValues = rValue.get<expectedarg_t>();
for(const auto& rNamedValue : aNamedValues)
{
if(!rNamedValue.Value.has<OUString>())
throw lang::IllegalArgumentException();
const OUString sValue(rNamedValue.Value.get<OUString>());
// get UI style name from programmatic style name
UIName aStyleName;
SwStyleNameMapper::FillUIName(ProgName(sValue), aStyleName, lcl_GetSwEnumFromSfxEnum(m_rEntry.family()));
// check for correct context and style name
const auto nIdx(GetCommandContextIndex(rNamedValue.Name));
if (nIdx == -1)
throw lang::IllegalArgumentException();
bool bStyleFound = false;
for(auto pBase = m_pBasePool->First(SfxStyleFamily::Para); pBase; pBase = m_pBasePool->Next())
{
bStyleFound = pBase->GetName() == aStyleName;
if (bStyleFound)
break;
}
if (!bStyleFound)
throw lang::IllegalArgumentException();
aCondItem.SetStyle(&aStyleName, nIdx);
}
o_rStyleBase.GetItemSet().Put(aCondItem);
}
template<>
void SwXStyle::SetPropertyValue<FN_UNO_CATEGORY>(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
{
if(!o_rStyleBase.getNewBase()->IsUserDefined() || !rValue.has<paragraphstyle_t>())
throw lang::IllegalArgumentException();
static const std::map<paragraphstyle_t, SfxStyleSearchBits> aUnoToCore = []{
std::map<paragraphstyle_t, SfxStyleSearchBits> map;
std::transform(std::begin(sParagraphStyleCategoryEntries), std::end(sParagraphStyleCategoryEntries), std::inserter(map, map.end()),
[] (const ParagraphStyleCategoryEntry& rEntry) { return std::make_pair(rEntry.m_eCategory, rEntry.m_nSwStyleBits); });
return map;
}();
const auto pUnoToCoreIt(aUnoToCore.find(rValue.get<paragraphstyle_t>()));
if (pUnoToCoreIt == aUnoToCore.end())
throw lang::IllegalArgumentException();
o_rStyleBase.getNewBase()->SetMask( pUnoToCoreIt->second|SfxStyleSearchBits::UserDefined );
}
template<>
void SwXStyle::SetPropertyValue<SID_SWREGISTER_COLLECTION>(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
{
OUString sName;
rValue >>= sName;
SwRegisterItem aReg(!sName.isEmpty());
aReg.SetWhich(SID_SWREGISTER_MODE);
o_rStyleBase.GetItemSet().Put(aReg);
UIName aString;
SwStyleNameMapper::FillUIName(ProgName(sName), aString, SwGetPoolIdFromName::TxtColl);
o_rStyleBase.GetItemSet().Put(SfxStringItem(SID_SWREGISTER_COLLECTION, aString.toString() ) );
}
template<>
void SwXStyle::SetPropertyValue<sal_uInt16(RES_TXTATR_CJK_RUBY)>(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& rPropSet, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
{
if(MID_RUBY_CHARSTYLE != rEntry.nMemberId)
return;
if(!rValue.has<OUString>())
throw lang::IllegalArgumentException();
const auto sValue(rValue.get<OUString>());
SfxItemSet& rStyleSet(o_rStyleBase.GetItemSet());
std::unique_ptr<SwFormatRuby> pRuby;
if(const SwFormatRuby* pRubyItem = rStyleSet.GetItemIfSet(RES_TXTATR_CJK_RUBY))
pRuby.reset(new SwFormatRuby(*pRubyItem));
else
pRuby.reset(new SwFormatRuby(OUString()));
UIName sStyle;
SwStyleNameMapper::FillUIName(ProgName(sValue), sStyle, SwGetPoolIdFromName::ChrFmt);
pRuby->SetCharFormatName(sStyle);
pRuby->SetCharFormatId(0);
if(!sValue.isEmpty())
{
const sal_uInt16 nId(SwStyleNameMapper::GetPoolIdFromUIName(sStyle, SwGetPoolIdFromName::ChrFmt));
pRuby->SetCharFormatId(nId);
}
rStyleSet.Put(std::move(pRuby));
SetPropertyValue<HINT_BEGIN>(rEntry, rPropSet, rValue, o_rStyleBase);
}
template<>
void SwXStyle::SetPropertyValue<sal_uInt16(RES_PARATR_DROP)>(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& rPropSet, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
{
if(MID_DROPCAP_CHAR_STYLE_NAME != rEntry.nMemberId)
{
SetPropertyValue<HINT_BEGIN>(rEntry, rPropSet, rValue, o_rStyleBase);
return;
}
if(!rValue.has<OUString>())
throw lang::IllegalArgumentException();
SfxItemSet& rStyleSet(o_rStyleBase.GetItemSet());
std::unique_ptr<SwFormatDrop> pDrop;
if(const SwFormatDrop* pDropItem = rStyleSet.GetItemIfSet(RES_PARATR_DROP))
pDrop.reset(new SwFormatDrop(*pDropItem));
else
pDrop.reset(new SwFormatDrop);
const auto sValue(rValue.get<OUString>());
UIName sStyle;
SwStyleNameMapper::FillUIName(ProgName(sValue), sStyle, SwGetPoolIdFromName::ChrFmt);
SwDocStyleSheet* pStyle = nullptr;
if (SwDocShell* pShell = m_pDoc->GetDocShell())
pStyle = static_cast<SwDocStyleSheet*>(pShell->GetStyleSheetPool()->Find(sStyle.toString(), SfxStyleFamily::Char));
//default character style must not be set as default format
if(!pStyle || pStyle->GetCharFormat() == m_pDoc->GetDfltCharFormat() )
{
throw lang::IllegalArgumentException();
}
pDrop->SetCharFormat(pStyle->GetCharFormat());
rStyleSet.Put(std::move(pDrop));
}
template<>
void SwXStyle::SetPropertyValue<sal_uInt16(RES_PARATR_NUMRULE)>(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& rPropSet, const uno::Any& rValue, SwStyleBase_Impl& o_rStyleBase)
{
uno::Any aValue(rValue);
lcl_TranslateMetric(rEntry, m_pDoc, aValue);
SetPropertyValue<HINT_BEGIN>(rEntry, rPropSet, aValue, o_rStyleBase);
// --> OD 2006-10-18 #i70223#
if(SfxStyleFamily::Para == m_rEntry.family() &&
o_rStyleBase.getNewBase().is() && o_rStyleBase.getNewBase()->GetCollection() &&
//rBase.getNewBase()->GetCollection()->GetOutlineLevel() < MAXLEVEL /* assigned to list level of outline style */) //#outline level,removed by zhaojianwei
o_rStyleBase.getNewBase()->GetCollection()->IsAssignedToListLevelOfOutlineStyle()) ////<-end,add by zhaojianwei
{
OUString sNewNumberingRuleName;
aValue >>= sNewNumberingRuleName;
if(sNewNumberingRuleName.isEmpty() || sNewNumberingRuleName != m_pDoc->GetOutlineNumRule()->GetName())
o_rStyleBase.getNewBase()->GetCollection()->DeleteAssignmentToListLevelOfOutlineStyle();
}
}
void SwXStyle::SetStyleProperty(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& rPropSet, const uno::Any& rValue, SwStyleBase_Impl& rBase)
{
using propertytype_t = decltype(rEntry.nWID);
using coresetter_t = std::function<void(SwXStyle&, const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, const uno::Any&, SwStyleBase_Impl&)>;
static const std::map<propertytype_t, coresetter_t> aUnoToCore{
// these explicit std::mem_fn() calls shouldn't be needed, but apparently MSVC is currently too stupid for C++11 again
{ FN_UNO_HIDDEN, std::mem_fn(&SwXStyle::SetPropertyValue<FN_UNO_HIDDEN>) },
{ FN_UNO_STYLE_INTEROP_GRAB_BAG, std::mem_fn(&SwXStyle::SetPropertyValue<FN_UNO_STYLE_INTEROP_GRAB_BAG>) },
{ XATTR_FILLGRADIENT, std::mem_fn(&SwXStyle::SetPropertyValue<sal_uInt16(XATTR_FILLGRADIENT)>) },
{ XATTR_FILLHATCH, std::mem_fn(&SwXStyle::SetPropertyValue<sal_uInt16(XATTR_FILLGRADIENT)>) },
{ XATTR_FILLBITMAP, std::mem_fn(&SwXStyle::SetPropertyValue<sal_uInt16(XATTR_FILLGRADIENT)>) },
{ XATTR_FILLFLOATTRANSPARENCE, std::mem_fn(&SwXStyle::SetPropertyValue<sal_uInt16(XATTR_FILLGRADIENT)>) },
{ RES_BACKGROUND, std::mem_fn(&SwXStyle::SetPropertyValue<sal_uInt16(RES_BACKGROUND)>) },
{ OWN_ATTR_FILLBMP_MODE, std::mem_fn(&SwXStyle::SetPropertyValue<OWN_ATTR_FILLBMP_MODE>) },
{ RES_PAPER_BIN, std::mem_fn(&SwXStyle::SetPropertyValue<sal_uInt16(RES_PAPER_BIN)>) },
{ FN_UNO_NUM_RULES, std::mem_fn(&SwXStyle::SetPropertyValue<FN_UNO_NUM_RULES>) },
{ RES_PARATR_OUTLINELEVEL, std::mem_fn(&SwXStyle::SetPropertyValue<sal_uInt16(RES_PARATR_OUTLINELEVEL)>) },
{ FN_UNO_FOLLOW_STYLE, std::mem_fn(&SwXStyle::SetPropertyValue<FN_UNO_FOLLOW_STYLE>) },
{ FN_UNO_LINK_STYLE, std::mem_fn(&SwXStyle::SetPropertyValue<FN_UNO_LINK_STYLE>) },
{ RES_PAGEDESC, std::mem_fn(&SwXStyle::SetPropertyValue<sal_uInt16(RES_PAGEDESC)>) },
{ RES_TEXT_VERT_ADJUST, std::mem_fn(&SwXStyle::SetPropertyValue<sal_uInt16(RES_TEXT_VERT_ADJUST)>) },
{ FN_UNO_IS_AUTO_UPDATE, std::mem_fn(&SwXStyle::SetPropertyValue<FN_UNO_IS_AUTO_UPDATE>) },
{ FN_UNO_PARA_STYLE_CONDITIONS, std::mem_fn(&SwXStyle::SetPropertyValue<FN_UNO_PARA_STYLE_CONDITIONS>) },
{ FN_UNO_CATEGORY, std::mem_fn(&SwXStyle::SetPropertyValue<FN_UNO_CATEGORY>) },
{ SID_SWREGISTER_COLLECTION, std::mem_fn(&SwXStyle::SetPropertyValue<SID_SWREGISTER_COLLECTION>) },
{ RES_TXTATR_CJK_RUBY, std::mem_fn(&SwXStyle::SetPropertyValue<sal_uInt16(RES_TXTATR_CJK_RUBY)>) },
{ RES_PARATR_DROP, std::mem_fn(&SwXStyle::SetPropertyValue<sal_uInt16(RES_PARATR_DROP)>) },
{ RES_PARATR_NUMRULE, std::mem_fn(&SwXStyle::SetPropertyValue<sal_uInt16(RES_PARATR_NUMRULE)>) }
};
const auto pUnoToCoreIt(aUnoToCore.find(rEntry.nWID));
if(pUnoToCoreIt != aUnoToCore.end())
pUnoToCoreIt->second(*this, rEntry, rPropSet, rValue, rBase);
else
{
// adapted switch logic to a more readable state; removed goto's and made
// execution of standard setting of property in ItemSet dependent of this variable
uno::Any aValue(rValue);
lcl_TranslateMetric(rEntry, m_pDoc, aValue);
SetPropertyValue<HINT_BEGIN>(rEntry, rPropSet, aValue, rBase);
}
}
void SwXStyle::SetPropertyValues_Impl(const uno::Sequence<OUString>& rPropertyNames, const uno::Sequence<uno::Any>& rValues)
{
if(!m_pDoc)
throw uno::RuntimeException();
sal_uInt16 nPropSetId = m_bIsConditional ? PROPERTY_MAP_CONDITIONAL_PARA_STYLE : m_rEntry.propMapType();
const SfxItemPropertySet* pPropSet = aSwMapProvider.GetPropertySet(nPropSetId);
const SfxItemPropertyMap &rMap = pPropSet->getPropertyMap();
if(rPropertyNames.getLength() != rValues.getLength())
throw lang::IllegalArgumentException();
SwStyleBase_Impl aBaseImpl(*m_pDoc, m_sStyleUIName, &GetDoc()->GetDfltTextFormatColl()->GetAttrSet()); // add pDfltTextFormatColl as parent
if(m_pBasePool)
{
SfxStyleSheetBase* pBase = m_pBasePool->Find(m_sStyleUIName.toString(), m_rEntry.family());
SAL_WARN_IF(!pBase, "sw.uno", "where is the style?");
if(!pBase)
throw uno::RuntimeException();
aBaseImpl.setNewBase(new SwDocStyleSheet(*static_cast<SwDocStyleSheet*>(pBase)));
}
if(!aBaseImpl.getNewBase().is() && !m_bIsDescriptor)
throw uno::RuntimeException();
const OUString* pNames = rPropertyNames.getConstArray();
const uno::Any* pValues = rValues.getConstArray();
for(sal_Int32 nProp = 0; nProp < rPropertyNames.getLength(); ++nProp)
{
const SfxItemPropertyMapEntry* pEntry = rMap.getByName(pNames[nProp]);
if(!pEntry || (!m_bIsConditional && pNames[nProp] == UNO_NAME_PARA_STYLE_CONDITIONS))
throw beans::UnknownPropertyException("Unknown property: " + pNames[nProp], getXWeak());
if(pEntry->nFlags & beans::PropertyAttribute::READONLY)
throw beans::PropertyVetoException ("Property is read-only: " + pNames[nProp], getXWeak());
if(aBaseImpl.getNewBase().is())
SetStyleProperty(*pEntry, *pPropSet, pValues[nProp], aBaseImpl);
else if(!m_pPropertiesImpl->SetProperty(pNames[nProp], pValues[nProp]))
throw lang::IllegalArgumentException();
}
if(aBaseImpl.HasItemSet())
aBaseImpl.getNewBase()->SetItemSet(aBaseImpl.GetItemSet());
}
void SwXStyle::setPropertyValues(const uno::Sequence<OUString>& rPropertyNames, const uno::Sequence<uno::Any>& rValues)
{
SolarMutexGuard aGuard;
// workaround for bad designed API
try
{
SetPropertyValues_Impl( rPropertyNames, rValues );
}
catch (const beans::UnknownPropertyException &rException)
{
// wrap the original (here not allowed) exception in
// a lang::WrappedTargetException that gets thrown instead.
lang::WrappedTargetException aWExc;
aWExc.TargetException <<= rException;
throw aWExc;
}
}
SfxStyleSheetBase* SwXStyle::GetStyleSheetBase()
{
if(!m_pBasePool)
return nullptr;
SfxStyleSheetBase* pBase = m_pBasePool->Find(m_sStyleUIName.toString(), m_rEntry.family());
return pBase;
}
void SwXStyle::PrepareStyleBase(SwStyleBase_Impl& rBase)
{
if(!rBase.getNewBase().is())
{
SfxStyleSheetBase* pBase(GetStyleSheetBase());
if(!pBase)
throw uno::RuntimeException();
rBase.setNewBase(new SwDocStyleSheet(*static_cast<SwDocStyleSheet*>(pBase)));
}
}
template<>
uno::Any SwXStyle::GetStyleProperty<HINT_BEGIN>(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& rPropSet, SwStyleBase_Impl& rBase);
template<>
uno::Any SwXStyle::GetStyleProperty<FN_UNO_IS_PHYSICAL>(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, SwStyleBase_Impl&)
{
SfxStyleSheetBase* pBase(GetStyleSheetBase());
if(!pBase)
return uno::Any(false);
bool bPhys = static_cast<SwDocStyleSheet*>(pBase)->IsPhysical();
// The standard character format is not existing physically
if( bPhys && SfxStyleFamily::Char == GetFamily() &&
static_cast<SwDocStyleSheet*>(pBase)->GetCharFormat() &&
static_cast<SwDocStyleSheet*>(pBase)->GetCharFormat()->IsDefault() )
bPhys = false;
return uno::Any(bool(bPhys));
}
template<>
uno::Any SwXStyle::GetStyleProperty<FN_UNO_HIDDEN>(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, SwStyleBase_Impl&)
{
SfxStyleSheetBase* pBase(GetStyleSheetBase());
if(!pBase)
return uno::Any(false);
rtl::Reference<SwDocStyleSheet> xBase(new SwDocStyleSheet(*static_cast<SwDocStyleSheet*>(pBase)));
return uno::Any(xBase->IsHidden());
}
template<>
uno::Any SwXStyle::GetStyleProperty<FN_UNO_STYLE_INTEROP_GRAB_BAG>(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, SwStyleBase_Impl&)
{
SfxStyleSheetBase* pBase(GetStyleSheetBase());
if(!pBase)
return uno::Any();
uno::Any aRet;
rtl::Reference<SwDocStyleSheet> xBase(new SwDocStyleSheet(*static_cast<SwDocStyleSheet*>(pBase)));
xBase->GetGrabBagItem(aRet);
return aRet;
}
template<>
uno::Any SwXStyle::GetStyleProperty<sal_uInt16(RES_PAPER_BIN)>(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& /*rPropSet*/, SwStyleBase_Impl& rBase)
{
PrepareStyleBase(rBase);
SfxItemSet& rSet = rBase.GetItemSet();
uno::Any aValue;
SfxItemPropertySet::getPropertyValue(rEntry, rSet, aValue);
sal_Int8 nBin(aValue.get<sal_Int8>());
if(nBin == -1)
return uno::Any(u"[From printer settings]"_ustr);
SfxPrinter* pPrinter = GetDoc()->getIDocumentDeviceAccess().getPrinter(false);
if(!pPrinter)
return uno::Any();
return uno::Any(pPrinter->GetPaperBinName(nBin));
}
template<>
uno::Any SwXStyle::GetStyleProperty<FN_UNO_NUM_RULES>(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, SwStyleBase_Impl& rBase)
{
PrepareStyleBase(rBase);
const SwNumRule* pRule = rBase.getNewBase()->GetNumRule();
assert(pRule && "Where is the NumRule?");
uno::Reference<container::XIndexReplace> xRules(new SwXNumberingRules(*pRule, GetDoc()));
return uno::Any(xRules);
}
template<>
uno::Any SwXStyle::GetStyleProperty<sal_uInt16(RES_PARATR_OUTLINELEVEL)>(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, SwStyleBase_Impl& rBase)
{
PrepareStyleBase(rBase);
SAL_WARN_IF(SfxStyleFamily::Para != GetFamily(), "sw.uno", "only paras");
return uno::Any(sal_Int16(rBase.getNewBase()->GetCollection()->GetAttrOutlineLevel()));
}
template<>
uno::Any SwXStyle::GetStyleProperty<FN_UNO_FOLLOW_STYLE>(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, SwStyleBase_Impl& rBase)
{
PrepareStyleBase(rBase);
ProgName aString;
SwStyleNameMapper::FillProgName(UIName(rBase.getNewBase()->GetFollow()), aString, lcl_GetSwEnumFromSfxEnum(GetFamily()));
return uno::Any(aString.toString());
}
template <>
uno::Any SwXStyle::GetStyleProperty<FN_UNO_LINK_STYLE>(const SfxItemPropertyMapEntry&,
const SfxItemPropertySet&,
SwStyleBase_Impl& rBase)
{
PrepareStyleBase(rBase);
ProgName aString;
SwStyleNameMapper::FillProgName(UIName(rBase.getNewBase()->GetLink()), aString,
lcl_GetSwEnumFromSfxEnum(GetFamily()));
return uno::Any(aString.toString());
}
template<>
uno::Any SwXStyle::GetStyleProperty<sal_uInt16(RES_PAGEDESC)>(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& rPropSet, SwStyleBase_Impl& rBase)
{
PrepareStyleBase(rBase);
if(MID_PAGEDESC_PAGEDESCNAME != rEntry.nMemberId)
return GetStyleProperty<HINT_BEGIN>(rEntry, rPropSet, rBase);
// special handling for RES_PAGEDESC
const SwFormatPageDesc* pItem =
rBase.GetItemSet().GetItemIfSet(RES_PAGEDESC);
if(!pItem)
return uno::Any();
const SwPageDesc* pDesc = pItem->GetPageDesc();
if(!pDesc)
return uno::Any();
ProgName aString;
SwStyleNameMapper::FillProgName(pDesc->GetName(), aString, SwGetPoolIdFromName::PageDesc);
return uno::Any(aString.toString());
}
template<>
uno::Any SwXStyle::GetStyleProperty<FN_UNO_IS_AUTO_UPDATE>(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, SwStyleBase_Impl& rBase)
{
PrepareStyleBase(rBase);
switch(GetFamily())
{
case SfxStyleFamily::Para : return uno::Any(rBase.getNewBase()->GetCollection()->IsAutoUpdateOnDirectFormat());
case SfxStyleFamily::Frame: return uno::Any(rBase.getNewBase()->GetFrameFormat()->IsAutoUpdateOnDirectFormat());
default: return uno::Any();
}
}
template<>
uno::Any SwXStyle::GetStyleProperty<FN_UNO_DISPLAY_NAME>(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, SwStyleBase_Impl& rBase)
{
PrepareStyleBase(rBase);
return uno::Any(rBase.getNewBase()->GetName());
}
template<>
uno::Any SwXStyle::GetStyleProperty<FN_UNO_PARA_STYLE_CONDITIONS>(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, SwStyleBase_Impl& rBase)
{
PrepareStyleBase(rBase);
static_assert(COND_COMMAND_COUNT == 28, "invalid size of command count?");
uno::Sequence<beans::NamedValue> aSeq(COND_COMMAND_COUNT);
sal_uInt16 nIndex = 0;
for(auto& rNV : asNonConstRange(aSeq))
{
rNV.Name = GetCommandContextByIndex(nIndex++);
rNV.Value <<= OUString();
}
SwFormat* pFormat = static_cast<SwDocStyleSheet*>(GetStyleSheetBase())->GetCollection();
if(pFormat && RES_CONDTXTFMTCOLL == pFormat->Which())
{
const CommandStruct* pCmds = SwCondCollItem::GetCmds();
beans::NamedValue* pSeq = aSeq.getArray();
for(sal_uInt16 n = 0; n < COND_COMMAND_COUNT; ++n)
{
const SwCollCondition* pCond = static_cast<SwConditionTextFormatColl*>(pFormat)->HasCondition(SwCollCondition(nullptr, pCmds[n].nCnd, pCmds[n].nSubCond));
if(!pCond || !pCond->GetTextFormatColl())
continue;
// get programmatic style name from UI style name
UIName aStyleUIName = pCond->GetTextFormatColl()->GetName();
ProgName aStyleProgName;
SwStyleNameMapper::FillProgName(aStyleUIName, aStyleProgName, lcl_GetSwEnumFromSfxEnum(GetFamily()));
pSeq[n].Value <<= aStyleProgName.toString();
}
}
return uno::Any(aSeq);
}
template<>
uno::Any SwXStyle::GetStyleProperty<FN_UNO_CATEGORY>(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, SwStyleBase_Impl& rBase)
{
PrepareStyleBase(rBase);
static const std::map<collectionbits_t, paragraphstyle_t> aUnoToCore = []{
std::map<collectionbits_t, paragraphstyle_t> map;
std::transform(std::begin(sParagraphStyleCategoryEntries), std::end(sParagraphStyleCategoryEntries), std::inserter(map, map.end()),
[] (const ParagraphStyleCategoryEntry& rEntry) { return std::make_pair(rEntry.m_nCollectionBits, rEntry.m_eCategory); });
return map;
}();
const sal_uInt16 nPoolId = rBase.getNewBase()->GetCollection()->GetPoolFormatId();
const auto pUnoToCoreIt(aUnoToCore.find(COLL_GET_RANGE_BITS & nPoolId));
if(pUnoToCoreIt == aUnoToCore.end())
return uno::Any(sal_Int16(-1));
return uno::Any(pUnoToCoreIt->second);
}
template<>
uno::Any SwXStyle::GetStyleProperty<SID_SWREGISTER_COLLECTION>(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, SwStyleBase_Impl& rBase)
{
PrepareStyleBase(rBase);
const SwPageDesc *pPageDesc = rBase.getNewBase()->GetPageDesc();
if(!pPageDesc)
return uno::Any(OUString());
const SwTextFormatColl* pCol = pPageDesc->GetRegisterFormatColl();
if(!pCol)
return uno::Any(OUString());
ProgName aName;
SwStyleNameMapper::FillProgName(pCol->GetName(), aName, SwGetPoolIdFromName::TxtColl);
return uno::Any(aName.toString());
}
template<>
uno::Any SwXStyle::GetStyleProperty<sal_uInt16(RES_BACKGROUND)>(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet&, SwStyleBase_Impl& rBase)
{
PrepareStyleBase(rBase);
const SfxItemSet& rSet = rBase.GetItemSet();
const std::unique_ptr<SvxBrushItem> aOriginalBrushItem(getSvxBrushItemFromSourceSet(rSet, RES_BACKGROUND));
uno::Any aResult;
if(!aOriginalBrushItem->QueryValue(aResult, rEntry.nMemberId))
SAL_WARN("sw.uno", "error getting attribute from RES_BACKGROUND.");
return aResult;
}
template<>
uno::Any SwXStyle::GetStyleProperty<OWN_ATTR_FILLBMP_MODE>(const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, SwStyleBase_Impl& rBase)
{
PrepareStyleBase(rBase);
const SfxItemSet& rSet = rBase.GetItemSet();
if (rSet.Get(XATTR_FILLBMP_TILE).GetValue())
return uno::Any(drawing::BitmapMode_REPEAT);
if (rSet.Get(XATTR_FILLBMP_STRETCH).GetValue())
return uno::Any(drawing::BitmapMode_STRETCH);
return uno::Any(drawing::BitmapMode_NO_REPEAT);
}
template<>
uno::Any SwXStyle::GetStyleProperty<HINT_BEGIN>(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& /*rPropSet*/, SwStyleBase_Impl& rBase)
{
PrepareStyleBase(rBase);
SfxItemSet& rSet = rBase.GetItemSet();
uno::Any aResult;
SfxItemPropertySet::getPropertyValue(rEntry, rSet, aResult);
//
// check for needed metric translation
if(rEntry.nMoreFlags & PropertyMoreFlags::METRIC_ITEM && GetDoc())
{
const SfxItemPool& rPool = GetDoc()->GetAttrPool();
const MapUnit eMapUnit(rPool.GetMetric(rEntry.nWID));
bool bAllowedConvert(true);
// exception: If these ItemTypes are used, do not convert when these are negative
// since this means they are intended as percent values
if(XATTR_FILLBMP_SIZEX == rEntry.nWID || XATTR_FILLBMP_SIZEY == rEntry.nWID)
bAllowedConvert = !aResult.has<sal_Int32>() || aResult.get<sal_Int32>() > 0;
if(eMapUnit != MapUnit::Map100thMM && bAllowedConvert)
SvxUnoConvertToMM(eMapUnit, aResult);
}
return aResult;
}
uno::Any SwXStyle::GetStyleProperty_Impl(const SfxItemPropertyMapEntry& rEntry, const SfxItemPropertySet& rPropSet, SwStyleBase_Impl& rBase)
{
using propertytype_t = decltype(rEntry.nWID);
using coresetter_t = std::function<uno::Any(SwXStyle&, const SfxItemPropertyMapEntry&, const SfxItemPropertySet&, SwStyleBase_Impl&)>;
static const std::map<propertytype_t, coresetter_t> aUnoToCore{
// these explicit std::mem_fn() calls shouldn't be needed, but apparently MSVC is currently too stupid for C++11 again
{ FN_UNO_IS_PHYSICAL, std::mem_fn(&SwXStyle::GetStyleProperty<FN_UNO_IS_PHYSICAL>) },
{ FN_UNO_HIDDEN, std::mem_fn(&SwXStyle::GetStyleProperty<FN_UNO_HIDDEN>) },
{ FN_UNO_STYLE_INTEROP_GRAB_BAG, std::mem_fn(&SwXStyle::GetStyleProperty<FN_UNO_STYLE_INTEROP_GRAB_BAG>) },
{ RES_PAPER_BIN, std::mem_fn(&SwXStyle::GetStyleProperty<sal_uInt16(RES_PAPER_BIN)>) },
{ FN_UNO_NUM_RULES, std::mem_fn(&SwXStyle::GetStyleProperty<FN_UNO_NUM_RULES>) },
{ RES_PARATR_OUTLINELEVEL, std::mem_fn(&SwXStyle::GetStyleProperty<sal_uInt16(RES_PARATR_OUTLINELEVEL)>) },
{ FN_UNO_FOLLOW_STYLE, std::mem_fn(&SwXStyle::GetStyleProperty<FN_UNO_FOLLOW_STYLE>) },
{ FN_UNO_LINK_STYLE, std::mem_fn(&SwXStyle::GetStyleProperty<FN_UNO_LINK_STYLE>) },
{ RES_PAGEDESC, std::mem_fn(&SwXStyle::GetStyleProperty<sal_uInt16(RES_PAGEDESC)>) },
{ FN_UNO_IS_AUTO_UPDATE, std::mem_fn(&SwXStyle::GetStyleProperty<FN_UNO_IS_AUTO_UPDATE>) },
{ FN_UNO_DISPLAY_NAME, std::mem_fn(&SwXStyle::GetStyleProperty<FN_UNO_DISPLAY_NAME>) },
{ FN_UNO_PARA_STYLE_CONDITIONS, std::mem_fn(&SwXStyle::GetStyleProperty<FN_UNO_PARA_STYLE_CONDITIONS>) },
{ FN_UNO_CATEGORY, std::mem_fn(&SwXStyle::GetStyleProperty<FN_UNO_CATEGORY>) },
{ SID_SWREGISTER_COLLECTION, std::mem_fn(&SwXStyle::GetStyleProperty<SID_SWREGISTER_COLLECTION>) },
{ RES_BACKGROUND, std::mem_fn(&SwXStyle::GetStyleProperty<sal_uInt16(RES_BACKGROUND)>) },
{ OWN_ATTR_FILLBMP_MODE, std::mem_fn(&SwXStyle::GetStyleProperty<OWN_ATTR_FILLBMP_MODE>) }
};
const auto pUnoToCoreIt(aUnoToCore.find(rEntry.nWID));
if(pUnoToCoreIt != aUnoToCore.end())
return pUnoToCoreIt->second(*this, rEntry, rPropSet, rBase);
return GetStyleProperty<HINT_BEGIN>(rEntry, rPropSet, rBase);
}
uno::Any SwXStyle::GetPropertyValue_Impl(const SfxItemPropertySet* pPropSet, SwStyleBase_Impl& rBase, const OUString& rPropertyName)
{
const SfxItemPropertyMap& rMap = pPropSet->getPropertyMap();
const SfxItemPropertyMapEntry* pEntry = rMap.getByName(rPropertyName);
if(!pEntry || (!m_bIsConditional && rPropertyName == UNO_NAME_PARA_STYLE_CONDITIONS))
throw beans::UnknownPropertyException("Unknown property: " + rPropertyName, getXWeak());
if(m_pBasePool)
return GetStyleProperty_Impl(*pEntry, *pPropSet, rBase);
const uno::Any* pAny = nullptr;
m_pPropertiesImpl->GetProperty(rPropertyName, pAny);
if(pAny->hasValue())
return *pAny;
uno::Any aValue;
switch(m_rEntry.family())
{
case SfxStyleFamily::Pseudo:
throw uno::RuntimeException("No default value for: " + rPropertyName);
break;
case SfxStyleFamily::Para:
case SfxStyleFamily::Page:
aValue = m_xStyleData->getPropertyValue(rPropertyName);
break;
case SfxStyleFamily::Char:
case SfxStyleFamily::Frame:
{
if(pEntry->nWID < POOLATTR_BEGIN || pEntry->nWID >= RES_UNKNOWNATR_END)
throw uno::RuntimeException("No default value for: " + rPropertyName);
SwFormat* pFormat;
if(m_rEntry.family() == SfxStyleFamily::Char)
pFormat = m_pDoc->GetDfltCharFormat();
else
pFormat = m_pDoc->GetDfltFrameFormat();
const SwAttrPool* pPool = pFormat->GetAttrSet().GetPool();
const SfxPoolItem& rItem = pPool->GetUserOrPoolDefaultItem(pEntry->nWID);
rItem.QueryValue(aValue, pEntry->nMemberId);
}
break;
default:
;
}
return aValue;
}
rtl::Reference<SwXNumberingRules> SwXStyle::getNumberingRules()
{
SwStyleBase_Impl aBase(*m_pDoc, m_sStyleUIName, &m_pDoc->GetDfltTextFormatColl()->GetAttrSet()); // add pDfltTextFormatColl as parent
if(m_pBasePool)
{
PrepareStyleBase(aBase);
const SwNumRule* pRule = aBase.getNewBase()->GetNumRule();
assert(pRule && "Where is the NumRule?");
return new SwXNumberingRules(*pRule, GetDoc());
}
return nullptr;
}
uno::Any SwXStyle::getPropertyValue(const OUString& rPropertyName)
{
SolarMutexGuard aGuard;
if(!m_pDoc)
throw uno::RuntimeException();
if(!m_pBasePool && !m_bIsDescriptor)
throw uno::RuntimeException();
sal_uInt16 nPropSetId = m_bIsConditional ? PROPERTY_MAP_CONDITIONAL_PARA_STYLE : m_rEntry.propMapType();
const SfxItemPropertySet* pPropSet = aSwMapProvider.GetPropertySet(nPropSetId);
SwStyleBase_Impl aBase(*m_pDoc, m_sStyleUIName, &m_pDoc->GetDfltTextFormatColl()->GetAttrSet()); // add pDfltTextFormatColl as parent
return GetPropertyValue_Impl(pPropSet, aBase, rPropertyName);
}
static void lcl_getTogglePropertyValue( sal_uInt16 nWID, sal_uInt8 nMemberId,
const SfxItemSet& rSet, Any& rAny )
{
assert(SfxItemPool::IsWhich(nWID));
const SfxPoolItem* pItem = nullptr;
SfxItemState eState = rSet.GetItemState( nWID, true, &pItem );
if (SfxItemState::SET != eState )
pItem = &rSet.GetPool()->GetUserOrPoolDefaultItem(nWID);
// return item values as uno::Any
if(eState >= SfxItemState::DEFAULT && pItem)
{
pItem->QueryValue( rAny, nMemberId );
}
}
void SwXStyle::getToggleAttributes(
float& rfCharStyleBold,
float& rfCharStyleBoldComplex,
css::awt::FontSlant& reCharStylePosture,
css::awt::FontSlant& reCharStylePostureComplex,
sal_Int16& rnCharStyleCaseMap,
sal_Int16& rnCharStyleRelief,
bool& rbCharStyleContoured,
bool& rbCharStyleShadowed,
sal_Int16& rnCharStyleStrikeThrough,
bool& rbCharStyleHidden)
{
SolarMutexGuard aGuard;
assert(m_pDoc);
assert(m_pBasePool);
SfxStyleSheetBase* pStyleSheetBase = m_pBasePool->Find(m_sStyleUIName.toString(), m_rEntry.family());
assert(pStyleSheetBase);
rtl::Reference<SwDocStyleSheet> xDocStyleSheet;
auto it = maUnoStyleSheets.find(pStyleSheetBase);
if (it != maUnoStyleSheets.end())
xDocStyleSheet = it->second;
else
{
xDocStyleSheet = new SwDocStyleSheet(*static_cast<SwDocStyleSheet*>(pStyleSheetBase));
maUnoStyleSheets.insert({pStyleSheetBase, xDocStyleSheet});
}
std::optional<SfxItemSet> oTempItemSet;
const SfxItemSet* pItemSet;
if (xDocStyleSheet->GetItemSet().GetParent())
pItemSet = &xDocStyleSheet->GetItemSet();
else
{
// set parent style to have the correct XFillStyle setting as XFILL_NONE
oTempItemSet.emplace(xDocStyleSheet->GetItemSet());
oTempItemSet->SetParent(&m_pDoc->GetDfltTextFormatColl()->GetAttrSet());
pItemSet = &*oTempItemSet;
}
uno::Any aResult;
lcl_getTogglePropertyValue(RES_CHRATR_WEIGHT, MID_WEIGHT, *pItemSet, aResult);
aResult >>= rfCharStyleBold;
lcl_getTogglePropertyValue(RES_CHRATR_CTL_WEIGHT, MID_WEIGHT, *pItemSet, aResult);
aResult >>= rfCharStyleBoldComplex;
lcl_getTogglePropertyValue(RES_CHRATR_POSTURE, MID_POSTURE, *pItemSet, aResult);
aResult >>= reCharStylePosture;
lcl_getTogglePropertyValue(RES_CHRATR_CTL_POSTURE, MID_POSTURE, *pItemSet, aResult);
aResult >>= reCharStylePostureComplex;
lcl_getTogglePropertyValue(RES_CHRATR_CASEMAP, 0, *pItemSet, aResult);
aResult >>= rnCharStyleCaseMap;
lcl_getTogglePropertyValue(RES_CHRATR_RELIEF, 0, *pItemSet, aResult);
aResult >>= rnCharStyleRelief;
lcl_getTogglePropertyValue(RES_CHRATR_CONTOUR, 0, *pItemSet, aResult);
aResult >>= rbCharStyleContoured;
lcl_getTogglePropertyValue(RES_CHRATR_SHADOWED, 0, *pItemSet, aResult);
aResult >>= rbCharStyleShadowed;
lcl_getTogglePropertyValue(RES_CHRATR_CROSSEDOUT, MID_CROSS_OUT, *pItemSet, aResult);
aResult >>= rnCharStyleStrikeThrough;
lcl_getTogglePropertyValue(RES_CHRATR_HIDDEN, 0, *pItemSet, aResult);
aResult >>= rbCharStyleHidden;
}
uno::Sequence<uno::Any> SwXStyle::getPropertyValues(const uno::Sequence<OUString>& rPropertyNames)
{
SolarMutexGuard aGuard;
if(!m_pDoc)
throw uno::RuntimeException();
if(!m_pBasePool && !m_bIsDescriptor)
throw uno::RuntimeException();
sal_uInt16 nPropSetId = m_bIsConditional ? PROPERTY_MAP_CONDITIONAL_PARA_STYLE : m_rEntry.propMapType();
const SfxItemPropertySet* pPropSet = aSwMapProvider.GetPropertySet(nPropSetId);
SwStyleBase_Impl aBase(*m_pDoc, m_sStyleUIName, &m_pDoc->GetDfltTextFormatColl()->GetAttrSet()); // add pDfltTextFormatColl as parent
uno::Sequence<uno::Any> aValues(rPropertyNames.getLength());
auto aValuesRange = asNonConstRange(aValues);
// workaround for bad designed API
try
{
for(sal_Int32 nProp = 0; nProp < rPropertyNames.getLength(); ++nProp)
aValuesRange[nProp] = GetPropertyValue_Impl(pPropSet, aBase, rPropertyNames[nProp]);
}
catch(beans::UnknownPropertyException&)
{
css::uno::Any anyEx = cppu::getCaughtException();
throw css::lang::WrappedTargetRuntimeException(u"Unknown property exception caught"_ustr,
getXWeak(), anyEx );
}
catch(lang::WrappedTargetException&)
{
css::uno::Any anyEx = cppu::getCaughtException();
throw lang::WrappedTargetRuntimeException(u"WrappedTargetException caught"_ustr,
getXWeak(), anyEx );
}
return aValues;
}
void SwXStyle::setPropertyValue(const OUString& rPropertyName, const uno::Any& rValue)
{
SolarMutexGuard aGuard;
const uno::Sequence<OUString> aProperties(&rPropertyName, 1);
const uno::Sequence<uno::Any> aValues(&rValue, 1);
SetPropertyValues_Impl(aProperties, aValues);
}
beans::PropertyState SwXStyle::getPropertyState(const OUString& rPropertyName)
{
SolarMutexGuard aGuard;
uno::Sequence<OUString> aNames{rPropertyName};
uno::Sequence<beans::PropertyState> aStates = getPropertyStates(aNames);
return aStates.getConstArray()[0];
}
// allow to retarget the SfxItemSet working on, default correctly. Only
// use pSourceSet below this point (except in header/footer processing)
static const SfxItemSet* lcl_GetItemsetForProperty(const SfxItemSet& rSet, SfxStyleFamily eFamily, std::u16string_view rPropertyName)
{
if(eFamily != SfxStyleFamily::Page)
return &rSet;
const bool isFooter = o3tl::starts_with(rPropertyName, u"Footer");
if(!isFooter && !o3tl::starts_with(rPropertyName, u"Header") && rPropertyName != UNO_NAME_FIRST_IS_SHARED)
return &rSet;
const SvxSetItem* pSetItem;
if(!lcl_GetHeaderFooterItem(rSet, rPropertyName, isFooter, pSetItem))
return nullptr;
return &pSetItem->GetItemSet();
}
uno::Sequence<beans::PropertyState> SwXStyle::getPropertyStates(const uno::Sequence<OUString>& rPropertyNames)
{
SolarMutexGuard aGuard;
uno::Sequence<beans::PropertyState> aRet(rPropertyNames.getLength());
beans::PropertyState* pStates = aRet.getArray();
if(!m_pBasePool)
throw uno::RuntimeException();
SfxStyleSheetBase* pBase = m_pBasePool->Find(m_sStyleUIName.toString(), m_rEntry.family());
SAL_WARN_IF(!pBase, "sw.uno", "where is the style?");
if(!pBase)
throw uno::RuntimeException();
const OUString* pNames = rPropertyNames.getConstArray();
rtl::Reference<SwDocStyleSheet> xStyle(new SwDocStyleSheet(*static_cast<SwDocStyleSheet*>(pBase)));
sal_uInt16 nPropSetId = m_bIsConditional ? PROPERTY_MAP_CONDITIONAL_PARA_STYLE : m_rEntry.propMapType();
const SfxItemPropertySet* pPropSet = aSwMapProvider.GetPropertySet(nPropSetId);
const SfxItemPropertyMap& rMap = pPropSet->getPropertyMap();
const SfxItemSet& rSet = xStyle->GetItemSet();
for(sal_Int32 i = 0; i < rPropertyNames.getLength(); ++i)
{
const OUString sPropName = pNames[i];
const SfxItemPropertyMapEntry* pEntry = rMap.getByName(sPropName);
if(!pEntry)
throw beans::UnknownPropertyException("Unknown property: " + sPropName, getXWeak());
if (FN_UNO_NUM_RULES == pEntry->nWID || FN_UNO_FOLLOW_STYLE == pEntry->nWID
|| pEntry->nWID == FN_UNO_LINK_STYLE)
{
// handle NumRules first, done
pStates[i] = beans::PropertyState_DIRECT_VALUE;
continue;
}
const SfxItemSet* pSourceSet = lcl_GetItemsetForProperty(rSet, m_rEntry.family(), sPropName);
if(!pSourceSet)
{
// if no SetItem, value is ambiguous and we are done
pStates[i] = beans::PropertyState_AMBIGUOUS_VALUE;
continue;
}
switch(pEntry->nWID)
{
case OWN_ATTR_FILLBMP_MODE:
{
if(SfxItemState::SET == pSourceSet->GetItemState(XATTR_FILLBMP_STRETCH, false)
|| SfxItemState::SET == pSourceSet->GetItemState(XATTR_FILLBMP_TILE, false))
{
pStates[i] = beans::PropertyState_DIRECT_VALUE;
}
else
{
pStates[i] = beans::PropertyState_AMBIGUOUS_VALUE;
}
}
break;
case XATTR_FILLSTYLE:
{
if (m_rEntry.family() == SfxStyleFamily::Frame
&& xStyle->GetFrameFormat()->DerivedFrom() == GetDoc()->GetDfltFrameFormat())
{ // tdf#156155 mpDfltFrameFormat is the parent, but because
// it IsDefault() it is not enumerated/exported as a style
// to ODF, so export its one important value here.
pStates[i] = beans::PropertyState_DIRECT_VALUE;
}
else
{
pStates[i] = SfxItemPropertySet::getPropertyState(*pEntry, *pSourceSet);
}
}
break;
case RES_BACKGROUND:
{
// for FlyFrames we need to mark the used properties from type RES_BACKGROUND
// as beans::PropertyState_DIRECT_VALUE to let users of this property call
// getPropertyValue where the member properties will be mapped from the
// fill attributes to the according SvxBrushItem entries
if (SWUnoHelper::needToMapFillItemsToSvxBrushItemTypes(*pSourceSet, pEntry->nMemberId))
{
pStates[i] = beans::PropertyState_DIRECT_VALUE;
}
else
{
pStates[i] = beans::PropertyState_DEFAULT_VALUE;
}
}
break;
default:
{
pStates[i] = SfxItemPropertySet::getPropertyState(*pEntry, *pSourceSet);
if(SfxStyleFamily::Page == m_rEntry.family() && SID_ATTR_PAGE_SIZE == pEntry->nWID && beans::PropertyState_DIRECT_VALUE == pStates[i])
{
const SvxSizeItem& rSize = rSet.Get(SID_ATTR_PAGE_SIZE);
sal_uInt8 nMemberId = pEntry->nMemberId & 0x7f;
if((LONG_MAX == rSize.GetSize().Width() && (MID_SIZE_WIDTH == nMemberId || MID_SIZE_SIZE == nMemberId)) ||
(LONG_MAX == rSize.GetSize().Height() && MID_SIZE_HEIGHT == nMemberId))
{
pStates[i] = beans::PropertyState_DEFAULT_VALUE;
}
}
}
}
}
return aRet;
}
void SwXStyle::setPropertyToDefault(const OUString& rPropertyName)
{
const uno::Sequence<OUString> aSequence(&rPropertyName, 1);
setPropertiesToDefault(aSequence);
}
static SwFormat* lcl_GetFormatForStyle(SwDoc const * pDoc, const rtl::Reference<SwDocStyleSheet>& xStyle, const SfxStyleFamily eFamily)
{
if(!xStyle.is())
return nullptr;
switch(eFamily)
{
case SfxStyleFamily::Char: return xStyle->GetCharFormat();
case SfxStyleFamily::Para: return xStyle->GetCollection();
case SfxStyleFamily::Frame: return xStyle->GetFrameFormat();
case SfxStyleFamily::Page:
{
SwPageDesc* pDesc(pDoc->FindPageDesc(xStyle->GetPageDesc()->GetName()));
if(pDesc)
return &pDesc->GetMaster();
}
break;
default: ;
}
return nullptr;
}
void SAL_CALL SwXStyle::setPropertiesToDefault(const uno::Sequence<OUString>& aPropertyNames)
{
SolarMutexGuard aGuard;
const rtl::Reference<SwDocStyleSheet> xStyle(new SwDocStyleSheet(*static_cast<SwDocStyleSheet*>(GetStyleSheetBase())));
SwFormat* pTargetFormat = lcl_GetFormatForStyle(m_pDoc, xStyle, m_rEntry.family());
if(!pTargetFormat)
{
if(!m_bIsDescriptor)
return;
for(const auto& rName : aPropertyNames)
m_pPropertiesImpl->ClearProperty(rName);
return;
}
const sal_uInt16 nPropSetId = m_bIsConditional ? PROPERTY_MAP_CONDITIONAL_PARA_STYLE : m_rEntry.propMapType();
const SfxItemPropertySet* pPropSet = aSwMapProvider.GetPropertySet(nPropSetId);
const SfxItemPropertyMap &rMap = pPropSet->getPropertyMap();
for(const auto& rName : aPropertyNames)
{
const SfxItemPropertyMapEntry* pEntry = rMap.getByName(rName);
if(!pEntry)
throw beans::UnknownPropertyException("Unknown property: " + rName, getXWeak());
if (pEntry->nWID == FN_UNO_FOLLOW_STYLE || pEntry->nWID == FN_UNO_LINK_STYLE
|| pEntry->nWID == FN_UNO_NUM_RULES)
throw uno::RuntimeException("Cannot reset: " + rName, getXWeak());
if(pEntry->nFlags & beans::PropertyAttribute::READONLY)
throw uno::RuntimeException("setPropertiesToDefault: property is read-only: " + rName, getXWeak());
if(pEntry->nWID == RES_PARATR_OUTLINELEVEL)
{
static_cast<SwTextFormatColl*>(pTargetFormat)->DeleteAssignmentToListLevelOfOutlineStyle();
continue;
}
pTargetFormat->ResetFormatAttr(pEntry->nWID);
if(OWN_ATTR_FILLBMP_MODE == pEntry->nWID)
{
SwDoc& rDoc = pTargetFormat->GetDoc();
SfxItemSetFixed<XATTR_FILL_FIRST, XATTR_FILL_LAST> aSet(rDoc.GetAttrPool());
aSet.SetParent(&pTargetFormat->GetAttrSet());
aSet.ClearItem(XATTR_FILLBMP_STRETCH);
aSet.ClearItem(XATTR_FILLBMP_TILE);
pTargetFormat->SetFormatAttr(aSet);
}
}
}
void SAL_CALL SwXStyle::setAllPropertiesToDefault()
{
SolarMutexGuard aGuard;
if(!m_pBasePool)
{
if(!m_bIsDescriptor)
throw uno::RuntimeException();
m_pPropertiesImpl->ClearAllProperties();
return;
}
const rtl::Reference<SwDocStyleSheet> xStyle(new SwDocStyleSheet(*static_cast<SwDocStyleSheet*>(GetStyleSheetBase())));
if(!xStyle.is())
throw uno::RuntimeException();
if(SfxStyleFamily::Page == m_rEntry.family())
{
size_t nPgDscPos(0);
SwPageDesc* pDesc = m_pDoc->FindPageDesc(xStyle->GetPageDesc()->GetName(), &nPgDscPos);
SwFormat* pPageFormat(nullptr);
if(pDesc)
{
pPageFormat = &pDesc->GetMaster();
pDesc->SetUseOn(UseOnPage::All);
}
else
pPageFormat = lcl_GetFormatForStyle(m_pDoc, xStyle, m_rEntry.family());
SwPageDesc& rPageDesc = m_pDoc->GetPageDesc(nPgDscPos);
rPageDesc.ResetAllMasterAttr();
pPageFormat->SetPageFormatToDefault();
SwPageDesc* pStdPgDsc = m_pDoc->getIDocumentStylePoolAccess().GetPageDescFromPool(RES_POOLPAGE_STANDARD);
std::shared_ptr<SwFormatFrameSize> aFrameSz(std::make_shared<SwFormatFrameSize>(SwFrameSize::Fixed));
if(RES_POOLPAGE_STANDARD == rPageDesc.GetPoolFormatId())
{
if(m_pDoc->getIDocumentDeviceAccess().getPrinter(false))
{
const Size aPhysSize( SvxPaperInfo::GetPaperSize(
static_cast<Printer*>(m_pDoc->getIDocumentDeviceAccess().getPrinter(false))));
aFrameSz->SetSize(aPhysSize);
}
else
{
aFrameSz->SetSize(SvxPaperInfo::GetDefaultPaperSize());
}
}
else
{
aFrameSz.reset(pStdPgDsc->GetMaster().GetFrameSize().Clone());
}
if(pStdPgDsc->GetLandscape())
{
SwTwips nTmp = aFrameSz->GetHeight();
aFrameSz->SetHeight(aFrameSz->GetWidth());
aFrameSz->SetWidth(nTmp);
}
pPageFormat->SetFormatAttr(*aFrameSz);
m_pDoc->ChgPageDesc(nPgDscPos, m_pDoc->GetPageDesc(nPgDscPos));
return;
}
if(SfxStyleFamily::Para == m_rEntry.family())
{
if(xStyle->GetCollection())
xStyle->GetCollection()->DeleteAssignmentToListLevelOfOutlineStyle();
}
SwFormat* const pTargetFormat = lcl_GetFormatForStyle(m_pDoc, xStyle, m_rEntry.family()); | |