summaryrefslogtreecommitdiffstats
path: root/svl/source/items
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 16:51:28 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-27 16:51:28 +0000
commit940b4d1848e8c70ab7642901a68594e8016caffc (patch)
treeeb72f344ee6c3d9b80a7ecc079ea79e9fba8676d /svl/source/items
parentInitial commit. (diff)
downloadlibreoffice-upstream.tar.xz
libreoffice-upstream.zip
Adding upstream version 1:7.0.4.upstream/1%7.0.4upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'svl/source/items')
-rw-r--r--svl/source/items/IndexedStyleSheets.cxx249
-rw-r--r--svl/source/items/aeitem.cxx72
-rw-r--r--svl/source/items/cenumitm.cxx148
-rw-r--r--svl/source/items/cintitem.cxx209
-rw-r--r--svl/source/items/custritm.cxx80
-rw-r--r--svl/source/items/flagitem.cxx64
-rw-r--r--svl/source/items/globalnameitem.cxx90
-rw-r--r--svl/source/items/grabbagitem.cxx70
-rw-r--r--svl/source/items/ilstitem.cxx88
-rw-r--r--svl/source/items/imageitm.cxx117
-rw-r--r--svl/source/items/int64item.cxx58
-rw-r--r--svl/source/items/intitem.cxx183
-rw-r--r--svl/source/items/itemiter.cxx63
-rw-r--r--svl/source/items/itempool.cxx947
-rw-r--r--svl/source/items/itemprop.cxx343
-rw-r--r--svl/source/items/itemset.cxx1745
-rw-r--r--svl/source/items/lckbitem.cxx102
-rw-r--r--svl/source/items/legacyitem.cxx69
-rw-r--r--svl/source/items/macitem.cxx238
-rw-r--r--svl/source/items/poolcach.cxx109
-rw-r--r--svl/source/items/poolio.cxx96
-rw-r--r--svl/source/items/poolitem.cxx648
-rw-r--r--svl/source/items/ptitem.cxx135
-rw-r--r--svl/source/items/rectitem.cxx132
-rw-r--r--svl/source/items/rngitem.cxx59
-rw-r--r--svl/source/items/sitem.cxx75
-rw-r--r--svl/source/items/slstitm.cxx187
-rw-r--r--svl/source/items/srchitem.cxx694
-rw-r--r--svl/source/items/stringio.cxx35
-rw-r--r--svl/source/items/stritem.cxx42
-rw-r--r--svl/source/items/style.cxx943
-rw-r--r--svl/source/items/stylepool.cxx471
-rw-r--r--svl/source/items/visitem.cxx67
-rw-r--r--svl/source/items/whiter.cxx53
34 files changed, 8681 insertions, 0 deletions
diff --git a/svl/source/items/IndexedStyleSheets.cxx b/svl/source/items/IndexedStyleSheets.cxx
new file mode 100644
index 000000000..4d71e7e6f
--- /dev/null
+++ b/svl/source/items/IndexedStyleSheets.cxx
@@ -0,0 +1,249 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+
+#include <svl/IndexedStyleSheets.hxx>
+#include <svl/style.hxx>
+
+#include <stdexcept>
+#include <algorithm>
+#include <utility>
+
+
+namespace {
+const size_t NUMBER_OF_FAMILIES = 7;
+size_t family_to_index(SfxStyleFamily family)
+{
+ switch (family) {
+ case SfxStyleFamily::Char:
+ return 0;
+ case SfxStyleFamily::Para:
+ return 1;
+ case SfxStyleFamily::Frame:
+ return 2;
+ case SfxStyleFamily::Page:
+ return 3;
+ case SfxStyleFamily::Pseudo:
+ return 4;
+ case SfxStyleFamily::Table:
+ return 5;
+ case SfxStyleFamily::All:
+ return 6;
+ default: break;
+ }
+ assert(false); // only for compiler warning. all cases are handled in the switch
+ return 0;
+}
+}
+
+namespace svl {
+
+IndexedStyleSheets::IndexedStyleSheets()
+{
+ for (size_t i = 0; i < NUMBER_OF_FAMILIES; i++) {
+ mStyleSheetPositionsByFamily.emplace_back();
+ }
+;}
+
+void
+IndexedStyleSheets::Register(const SfxStyleSheetBase& style, unsigned pos)
+{
+ mPositionsByName.insert(std::make_pair(style.GetName(), pos));
+ size_t position = family_to_index(style.GetFamily());
+ mStyleSheetPositionsByFamily.at(position).push_back(pos);
+ size_t positionForFamilyAll = family_to_index(SfxStyleFamily::All);
+ mStyleSheetPositionsByFamily.at(positionForFamilyAll).push_back(pos);
+}
+
+void
+IndexedStyleSheets::Reindex()
+{
+ mPositionsByName.clear();
+ mStyleSheetPositionsByFamily.clear();
+ for (size_t i = 0; i < NUMBER_OF_FAMILIES; i++) {
+ mStyleSheetPositionsByFamily.emplace_back();
+ }
+
+ unsigned i = 0;
+ for (const auto& rxStyleSheet : mStyleSheets) {
+ SfxStyleSheetBase* p = rxStyleSheet.get();
+ Register(*p, i);
+ ++i;
+ }
+}
+
+unsigned
+IndexedStyleSheets::GetNumberOfStyleSheets() const
+{
+ return mStyleSheets.size();
+}
+
+void
+IndexedStyleSheets::AddStyleSheet(const rtl::Reference< SfxStyleSheetBase >& style)
+{
+ if (!HasStyleSheet(style)) {
+ mStyleSheets.push_back(style);
+ // since we just added an element to the vector, we can safely do -1 as it will always be >= 1
+ Register(*style, mStyleSheets.size()-1);
+ }
+}
+
+bool
+IndexedStyleSheets::RemoveStyleSheet(const rtl::Reference< SfxStyleSheetBase >& style)
+{
+ std::pair<MapType::const_iterator, MapType::const_iterator> range = mPositionsByName.equal_range(style->GetName());
+ for (MapType::const_iterator it = range.first; it != range.second; ++it)
+ {
+ unsigned pos = it->second;
+ if (mStyleSheets.at(pos) == style)
+ {
+ mStyleSheets.erase(mStyleSheets.begin() + pos);
+ Reindex();
+ return true;
+ }
+ }
+ return false;
+}
+
+std::vector<unsigned>
+IndexedStyleSheets::FindPositionsByName(const OUString& name) const
+{
+ std::vector<unsigned> r;
+ std::pair<MapType::const_iterator, MapType::const_iterator> range = mPositionsByName.equal_range(name);
+ for (MapType::const_iterator it = range.first; it != range.second; ++it) {
+ r.push_back(it->second);
+ }
+ return r;
+}
+
+std::vector<unsigned>
+IndexedStyleSheets::FindPositionsByNameAndPredicate(const OUString& name,
+ StyleSheetPredicate& predicate, SearchBehavior behavior) const
+{
+ std::vector<unsigned> r;
+ auto range = mPositionsByName.equal_range(name);
+ for (auto it = range.first; it != range.second; ++it) {
+ unsigned pos = it->second;
+ SfxStyleSheetBase *ssheet = mStyleSheets.at(pos).get();
+ if (predicate.Check(*ssheet)) {
+ r.push_back(pos);
+ if (behavior == SearchBehavior::ReturnFirst) {
+ break;
+ }
+ }
+ }
+ return r;
+}
+
+
+unsigned
+IndexedStyleSheets::GetNumberOfStyleSheetsWithPredicate(StyleSheetPredicate& predicate) const
+{
+ return std::count_if(mStyleSheets.begin(), mStyleSheets.end(),
+ [&predicate](const rtl::Reference<SfxStyleSheetBase>& rxStyleSheet) {
+ const SfxStyleSheetBase *ssheet = rxStyleSheet.get();
+ return predicate.Check(*ssheet);
+ });
+}
+
+SfxStyleSheetBase*
+IndexedStyleSheets::GetNthStyleSheetThatMatchesPredicate(
+ unsigned n,
+ StyleSheetPredicate& predicate,
+ unsigned startAt)
+{
+ SfxStyleSheetBase* retval = nullptr;
+ unsigned matching = 0;
+ for (VectorType::const_iterator it = mStyleSheets.begin()+startAt; it != mStyleSheets.end(); ++it) {
+ SfxStyleSheetBase *ssheet = it->get();
+ if (predicate.Check(*ssheet)) {
+ if (matching == n) {
+ retval = it->get();
+ break;
+ }
+ ++matching;
+ }
+ }
+ return retval;
+}
+
+unsigned
+IndexedStyleSheets::FindStyleSheetPosition(const SfxStyleSheetBase& style) const
+{
+ VectorType::const_iterator it = std::find(mStyleSheets.begin(), mStyleSheets.end(), &style);
+ if (it == mStyleSheets.end()) {
+ throw std::runtime_error("IndexedStyleSheets::FindStylePosition Looked for style not in index");
+ }
+ return std::distance(mStyleSheets.begin(), it);
+}
+
+void
+IndexedStyleSheets::Clear(StyleSheetDisposer& disposer)
+{
+ for (const auto& rxStyleSheet : mStyleSheets) {
+ disposer.Dispose(rxStyleSheet);
+ }
+ mStyleSheets.clear();
+ mPositionsByName.clear();
+}
+
+IndexedStyleSheets::~IndexedStyleSheets()
+{
+}
+
+bool
+IndexedStyleSheets::HasStyleSheet(const rtl::Reference< SfxStyleSheetBase >& style) const
+{
+ std::pair<MapType::const_iterator, MapType::const_iterator> range = mPositionsByName.equal_range(style->GetName());
+ for (MapType::const_iterator it = range.first; it != range.second; ++it)
+ {
+ if (mStyleSheets.at(it->second) == style)
+ return true;
+ }
+ return false;
+}
+
+SfxStyleSheetBase*
+IndexedStyleSheets::GetStyleSheetByPosition(unsigned pos)
+{
+ if( pos < mStyleSheets.size() )
+ return mStyleSheets.at(pos).get();
+ return nullptr;
+}
+
+void
+IndexedStyleSheets::ApplyToAllStyleSheets(StyleSheetCallback& callback) const
+{
+ for (const auto& rxStyleSheet : mStyleSheets) {
+ callback.DoIt(*rxStyleSheet);
+ }
+}
+
+std::vector<unsigned>
+IndexedStyleSheets::FindPositionsByPredicate(StyleSheetPredicate& predicate) const
+{
+ std::vector<unsigned> r;
+ for (VectorType::const_iterator it = mStyleSheets.begin(); it != mStyleSheets.end(); ++it) {
+ if (predicate.Check(**it)) {
+ r.push_back(std::distance(mStyleSheets.begin(), it));
+ }
+ }
+ return r;
+}
+
+const std::vector<unsigned>&
+IndexedStyleSheets::GetStyleSheetPositionsByFamily(SfxStyleFamily e) const
+{
+ size_t position = family_to_index(e);
+ return mStyleSheetPositionsByFamily.at(position);
+}
+
+} /* namespace svl */
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svl/source/items/aeitem.cxx b/svl/source/items/aeitem.cxx
new file mode 100644
index 000000000..7c85153b6
--- /dev/null
+++ b/svl/source/items/aeitem.cxx
@@ -0,0 +1,72 @@
+/* -*- 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 <rtl/ustring.hxx>
+#include <svl/aeitem.hxx>
+
+#include <climits>
+#include <cstddef>
+
+SfxAllEnumItem::SfxAllEnumItem(sal_uInt16 which):
+ SfxPoolItem(which)
+{
+}
+
+SfxAllEnumItem::SfxAllEnumItem(const SfxAllEnumItem &rCopy):
+ SfxPoolItem(rCopy),
+ m_Values(rCopy.m_Values)
+{
+}
+
+SfxAllEnumItem::~SfxAllEnumItem()
+{
+}
+
+sal_Int32 SfxAllEnumItem::GetTextCount() const
+{
+ return m_Values.size();
+}
+
+OUString const & SfxAllEnumItem::GetTextByPos( sal_uInt16 nPos ) const
+{
+ return m_Values[nPos];
+}
+
+SfxAllEnumItem* SfxAllEnumItem::Clone( SfxItemPool * ) const
+{
+ return new SfxAllEnumItem(*this);
+}
+
+void SfxAllEnumItem::SetTextByPos( sal_uInt16 nPos, const OUString &rText )
+{
+ if (nPos >= m_Values.size())
+ m_Values.resize(nPos);
+ m_Values[nPos] = rText;
+}
+
+bool SfxAllEnumItem::operator==( const SfxPoolItem& rCmp ) const
+{
+ if (!SfxPoolItem::operator==(rCmp))
+ return false;
+ const SfxAllEnumItem& rOther = static_cast<const SfxAllEnumItem&>(rCmp);
+ return m_Values == rOther.m_Values;
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svl/source/items/cenumitm.cxx b/svl/source/items/cenumitm.cxx
new file mode 100644
index 000000000..3d0b7e581
--- /dev/null
+++ b/svl/source/items/cenumitm.cxx
@@ -0,0 +1,148 @@
+/* -*- 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 <com/sun/star/uno/Any.hxx>
+#include <svl/cenumitm.hxx>
+#include <svl/eitem.hxx>
+
+#include <comphelper/extract.hxx>
+#include <libxml/xmlwriter.h>
+#include <sal/log.hxx>
+
+
+// virtual
+bool SfxEnumItemInterface::operator ==(const SfxPoolItem & rItem) const
+{
+ SAL_WARN_IF(!SfxPoolItem::operator ==(rItem), "svl.items", "unequal type, with ID/pos " << Which() );
+ return GetEnumValue()
+ == static_cast< const SfxEnumItemInterface * >(&rItem)->
+ GetEnumValue();
+}
+
+// virtual
+bool SfxEnumItemInterface::GetPresentation(SfxItemPresentation, MapUnit,
+ MapUnit, OUString & rText,
+ const IntlWrapper&) const
+{
+ rText = OUString::number( GetEnumValue() );
+ return true;
+}
+
+// virtual
+bool SfxEnumItemInterface::QueryValue(css::uno::Any& rVal, sal_uInt8)
+ const
+{
+ rVal <<= sal_Int32(GetEnumValue());
+ return true;
+}
+
+// virtual
+bool SfxEnumItemInterface::PutValue(const css::uno::Any& rVal,
+ sal_uInt8)
+{
+ sal_Int32 nTheValue = 0;
+
+ if ( ::cppu::enum2int( nTheValue, rVal ) )
+ {
+ SetEnumValue(sal_uInt16(nTheValue));
+ return true;
+ }
+ SAL_WARN("svl.items", "SfxEnumItemInterface::PutValue(): Wrong type");
+ return false;
+}
+
+// virtual
+bool SfxEnumItemInterface::HasBoolValue() const
+{
+ return false;
+}
+
+// virtual
+bool SfxEnumItemInterface::GetBoolValue() const
+{
+ return false;
+}
+
+// virtual
+void SfxEnumItemInterface::SetBoolValue(bool)
+{}
+
+SfxPoolItem* SfxBoolItem::CreateDefault()
+{
+ return new SfxBoolItem();
+}
+
+// virtual
+bool SfxBoolItem::operator ==(const SfxPoolItem & rItem) const
+{
+ assert(dynamic_cast<const SfxBoolItem*>(&rItem) != nullptr);
+ return m_bValue == static_cast< SfxBoolItem const * >(&rItem)->m_bValue;
+}
+
+// virtual
+bool SfxBoolItem::GetPresentation(SfxItemPresentation,
+ MapUnit, MapUnit,
+ OUString & rText,
+ const IntlWrapper&) const
+{
+ rText = GetValueTextByVal(m_bValue);
+ return true;
+}
+
+void SfxBoolItem::dumpAsXml(xmlTextWriterPtr pWriter) const
+{
+ xmlTextWriterStartElement(pWriter, BAD_CAST("SfxBoolItem"));
+ xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr()));
+ xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"), BAD_CAST(GetValueTextByVal(m_bValue).toUtf8().getStr()));
+ xmlTextWriterEndElement(pWriter);
+}
+
+// virtual
+bool SfxBoolItem::QueryValue(css::uno::Any& rVal, sal_uInt8) const
+{
+ rVal <<= m_bValue;
+ return true;
+}
+
+// virtual
+bool SfxBoolItem::PutValue(const css::uno::Any& rVal, sal_uInt8)
+{
+ bool bTheValue = bool();
+ if (rVal >>= bTheValue)
+ {
+ m_bValue = bTheValue;
+ return true;
+ }
+ SAL_WARN("svl.items", "SfxBoolItem::PutValue(): Wrong type");
+ return false;
+}
+
+// virtual
+SfxBoolItem* SfxBoolItem::Clone(SfxItemPool *) const
+{
+ return new SfxBoolItem(*this);
+}
+
+// virtual
+OUString SfxBoolItem::GetValueTextByVal(bool bTheValue) const
+{
+ return bTheValue ? OUString("TRUE") : OUString("FALSE");
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svl/source/items/cintitem.cxx b/svl/source/items/cintitem.cxx
new file mode 100644
index 000000000..0f522f7a9
--- /dev/null
+++ b/svl/source/items/cintitem.cxx
@@ -0,0 +1,209 @@
+/* -*- 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 <com/sun/star/uno/Any.hxx>
+#include <svl/cintitem.hxx>
+#include <sal/log.hxx>
+
+
+// virtual
+bool CntByteItem::operator ==(const SfxPoolItem & rItem) const
+{
+ assert(dynamic_cast<const CntByteItem*>(&rItem) != nullptr);
+ return m_nValue == static_cast< const CntByteItem * >(&rItem)->m_nValue;
+}
+
+// virtual
+bool CntByteItem::GetPresentation(SfxItemPresentation, MapUnit, MapUnit,
+ OUString & rText,
+ const IntlWrapper&) const
+{
+ rText = OUString::number( m_nValue );
+ return true;
+}
+
+// virtual
+bool CntByteItem::QueryValue(css::uno::Any& rVal, sal_uInt8) const
+{
+ sal_Int8 nValue = m_nValue;
+ rVal <<= nValue;
+ return true;
+}
+
+// virtual
+bool CntByteItem::PutValue(const css::uno::Any& rVal, sal_uInt8)
+{
+ sal_Int8 nValue = sal_Int8();
+ if (rVal >>= nValue)
+ {
+ m_nValue = nValue;
+ return true;
+ }
+
+ SAL_WARN("svl.items", "CntByteItem::PutValue - Wrong type!");
+ return false;
+}
+
+// virtual
+CntByteItem* CntByteItem::Clone(SfxItemPool *) const
+{
+ return new CntByteItem(*this);
+}
+
+// virtual
+bool CntUInt16Item::operator ==(const SfxPoolItem & rItem) const
+{
+ assert(dynamic_cast<const CntUInt16Item*>(&rItem) != nullptr);
+ return m_nValue == static_cast<const CntUInt16Item *>(&rItem)->m_nValue;
+}
+
+// virtual
+bool CntUInt16Item::GetPresentation(SfxItemPresentation,
+ MapUnit, MapUnit,
+ OUString & rText,
+ const IntlWrapper&)
+ const
+{
+ rText = OUString::number( m_nValue );
+ return true;
+}
+
+// virtual
+bool CntUInt16Item::QueryValue(css::uno::Any& rVal, sal_uInt8) const
+{
+ sal_Int32 nValue = m_nValue;
+ rVal <<= nValue;
+ return true;
+}
+
+// virtual
+bool CntUInt16Item::PutValue(const css::uno::Any& rVal, sal_uInt8)
+{
+ sal_Int32 nValue = 0;
+ if (rVal >>= nValue)
+ {
+ SAL_WARN_IF(nValue < 0 || nValue > SAL_MAX_UINT16, "svl.items", "Overflow in UInt16 value!");
+ m_nValue = static_cast<sal_uInt16>(nValue);
+ return true;
+ }
+
+ SAL_WARN("svl.items", "CntUInt16Item::PutValue - Wrong type!");
+ return false;
+}
+
+// virtual
+CntUInt16Item* CntUInt16Item::Clone(SfxItemPool *) const
+{
+ return new CntUInt16Item(*this);
+}
+
+// virtual
+bool CntInt32Item::operator ==(const SfxPoolItem & rItem) const
+{
+ assert(dynamic_cast<const CntInt32Item*>(&rItem) != nullptr);
+ return m_nValue == static_cast<const CntInt32Item *>(&rItem)->m_nValue;
+}
+
+// virtual
+bool CntInt32Item::GetPresentation(SfxItemPresentation,
+ MapUnit, MapUnit,
+ OUString & rText,
+ const IntlWrapper&) const
+{
+ rText = OUString::number( m_nValue );
+ return true;
+}
+
+// virtual
+bool CntInt32Item::QueryValue(css::uno::Any& rVal, sal_uInt8) const
+{
+ sal_Int32 nValue = m_nValue;
+ rVal <<= nValue;
+ return true;
+}
+
+// virtual
+bool CntInt32Item::PutValue(const css::uno::Any& rVal, sal_uInt8)
+{
+ sal_Int32 nValue = 0;
+ if (rVal >>= nValue)
+ {
+ m_nValue = nValue;
+ return true;
+ }
+
+ SAL_WARN("svl.items", "CntInt32Item::PutValue - Wrong type!");
+ return false;
+}
+
+// virtual
+CntInt32Item* CntInt32Item::Clone(SfxItemPool *) const
+{
+ return new CntInt32Item(*this);
+}
+
+// virtual
+bool CntUInt32Item::operator ==(const SfxPoolItem & rItem) const
+{
+ assert(dynamic_cast<const CntUInt32Item*>(&rItem) != nullptr);
+ return m_nValue == static_cast<const CntUInt32Item *>(&rItem)->m_nValue;
+}
+
+// virtual
+bool CntUInt32Item::GetPresentation(SfxItemPresentation,
+ MapUnit, MapUnit,
+ OUString & rText,
+ const IntlWrapper&)
+ const
+{
+ rText = OUString::number(m_nValue);
+ return true;
+}
+
+// virtual
+bool CntUInt32Item::QueryValue(css::uno::Any& rVal, sal_uInt8) const
+{
+ sal_Int32 nValue = m_nValue;
+ SAL_WARN_IF(nValue < 0, "svl.items", "Overflow in UInt32 value!");
+ rVal <<= nValue;
+ return true;
+}
+
+// virtual
+bool CntUInt32Item::PutValue(const css::uno::Any& rVal, sal_uInt8)
+{
+ sal_Int32 nValue = 0;
+ if (rVal >>= nValue)
+ {
+ SAL_WARN_IF(nValue < 0, "svl.items", "Overflow in UInt32 value!");
+ m_nValue = nValue;
+ return true;
+ }
+
+ SAL_WARN("svl.items", "CntUInt32Item::PutValue - Wrong type!");
+ return false;
+}
+
+// virtual
+CntUInt32Item* CntUInt32Item::Clone(SfxItemPool *) const
+{
+ return new CntUInt32Item(*this);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svl/source/items/custritm.cxx b/svl/source/items/custritm.cxx
new file mode 100644
index 000000000..b6946a4f4
--- /dev/null
+++ b/svl/source/items/custritm.cxx
@@ -0,0 +1,80 @@
+/* -*- 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 <com/sun/star/uno/Any.hxx>
+
+#include <osl/diagnose.h>
+#include <unotools/intlwrapper.hxx>
+#include <svl/custritm.hxx>
+
+
+// virtual
+bool CntUnencodedStringItem::operator ==(const SfxPoolItem & rItem) const
+{
+ assert(dynamic_cast<const CntUnencodedStringItem*>( &rItem ));
+ return m_aValue
+ == static_cast< const CntUnencodedStringItem * >(&rItem)->
+ m_aValue;
+}
+
+bool CntUnencodedStringItem::operator<(const SfxPoolItem & rItem) const
+{
+ assert(dynamic_cast<const CntUnencodedStringItem*>( &rItem ));
+ return m_aValue
+ < static_cast< const CntUnencodedStringItem * >(&rItem)->
+ m_aValue;
+}
+
+// virtual
+bool CntUnencodedStringItem::GetPresentation(SfxItemPresentation, MapUnit,
+ MapUnit, OUString & rText,
+ const IntlWrapper&) const
+{
+ rText = m_aValue;
+ return true;
+}
+
+// virtual
+bool CntUnencodedStringItem::QueryValue(css::uno::Any& rVal, sal_uInt8) const
+{
+ rVal <<= m_aValue;
+ return true;
+}
+
+// virtual
+bool CntUnencodedStringItem::PutValue(const css::uno::Any& rVal,
+ sal_uInt8)
+{
+ OUString aTheValue;
+ if (rVal >>= aTheValue)
+ {
+ m_aValue = aTheValue;
+ return true;
+ }
+ OSL_FAIL("CntUnencodedStringItem::PutValue(): Wrong type");
+ return false;
+}
+
+// virtual
+CntUnencodedStringItem* CntUnencodedStringItem::Clone(SfxItemPool *) const
+{
+ return new CntUnencodedStringItem(*this);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svl/source/items/flagitem.cxx b/svl/source/items/flagitem.cxx
new file mode 100644
index 000000000..fd96c5317
--- /dev/null
+++ b/svl/source/items/flagitem.cxx
@@ -0,0 +1,64 @@
+/* -*- 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 <svl/flagitem.hxx>
+#include <svl/poolitem.hxx>
+#include <sal/log.hxx>
+
+
+SfxFlagItem::SfxFlagItem( sal_uInt16 nW, sal_uInt16 nV ) :
+ SfxPoolItem( nW ),
+ nVal(nV)
+{
+}
+
+bool SfxFlagItem::GetPresentation
+(
+ SfxItemPresentation /*ePresentation*/,
+ MapUnit /*eCoreMetric*/,
+ MapUnit /*ePresentationMetric*/,
+ OUString& rText,
+ const IntlWrapper&
+) const
+{
+ rText.clear();
+ for ( sal_uInt8 nFlag = 0; nFlag < GetFlagCount(); ++nFlag )
+ rText += GetFlag(nFlag) ? OUStringLiteral("true") : OUStringLiteral("false");
+ return true;
+}
+
+sal_uInt8 SfxFlagItem::GetFlagCount() const
+{
+ SAL_INFO("svl", "calling GetValueText(sal_uInt16) on SfxFlagItem -- override!");
+ return 0;
+}
+
+bool SfxFlagItem::operator==( const SfxPoolItem& rItem ) const
+{
+ assert(SfxPoolItem::operator==(rItem));
+ return static_cast<const SfxFlagItem&>(rItem).nVal == nVal;
+}
+
+SfxFlagItem* SfxFlagItem::Clone(SfxItemPool *) const
+{
+ return new SfxFlagItem( *this );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svl/source/items/globalnameitem.cxx b/svl/source/items/globalnameitem.cxx
new file mode 100644
index 000000000..3f8d3265d
--- /dev/null
+++ b/svl/source/items/globalnameitem.cxx
@@ -0,0 +1,90 @@
+/* -*- 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 <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <com/sun/star/script/Converter.hpp>
+
+#include <osl/diagnose.h>
+
+#include <comphelper/processfactory.hxx>
+
+#include <svl/globalnameitem.hxx>
+
+SfxPoolItem* SfxGlobalNameItem::CreateDefault() { return new SfxGlobalNameItem; }
+
+
+SfxGlobalNameItem::SfxGlobalNameItem()
+{
+}
+
+
+SfxGlobalNameItem::SfxGlobalNameItem( sal_uInt16 nW, const SvGlobalName& rName )
+: SfxPoolItem( nW ),
+ m_aName( rName )
+{
+}
+
+SfxGlobalNameItem::~SfxGlobalNameItem()
+{
+}
+
+bool SfxGlobalNameItem::operator==( const SfxPoolItem& rItem ) const
+{
+ return SfxPoolItem::operator==(rItem) &&
+ static_cast<const SfxGlobalNameItem&>(rItem).m_aName == m_aName;
+}
+
+SfxGlobalNameItem* SfxGlobalNameItem::Clone(SfxItemPool *) const
+{
+ return new SfxGlobalNameItem( *this );
+}
+
+// virtual
+bool SfxGlobalNameItem::PutValue( const css::uno::Any& rVal, sal_uInt8 )
+{
+ css::uno::Reference < css::script::XTypeConverter > xConverter
+ ( css::script::Converter::create( ::comphelper::getProcessComponentContext() ));
+ css::uno::Sequence< sal_Int8 > aSeq;
+ css::uno::Any aNew;
+
+ try { aNew = xConverter->convertTo( rVal, cppu::UnoType<css::uno::Sequence < sal_Int8 >>::get() ); }
+ catch (css::uno::Exception&) {}
+ aNew >>= aSeq;
+ if ( aSeq.getLength() == 16 )
+ {
+ m_aName.MakeFromMemory( aSeq.getConstArray() );
+ return true;
+ }
+
+ OSL_FAIL( "SfxGlobalNameItem::PutValue - Wrong type!" );
+ return true;
+}
+
+// virtual
+bool SfxGlobalNameItem::QueryValue( css::uno::Any& rVal, sal_uInt8 ) const
+{
+ css::uno::Sequence< sal_Int8 > aSeq( 16 );
+ void const * pData = &m_aName.GetCLSID();
+ memcpy( aSeq.getArray(), pData, 16 );
+ rVal <<= aSeq;
+ return true;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svl/source/items/grabbagitem.cxx b/svl/source/items/grabbagitem.cxx
new file mode 100644
index 000000000..39ee56686
--- /dev/null
+++ b/svl/source/items/grabbagitem.cxx
@@ -0,0 +1,70 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <svl/grabbagitem.hxx>
+#include <sal/config.h>
+
+#include <sal/log.hxx>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/uno/Sequence.hxx>
+
+using namespace com::sun::star;
+
+SfxGrabBagItem::SfxGrabBagItem() = default;
+
+SfxGrabBagItem::SfxGrabBagItem(sal_uInt16 nWhich)
+ : SfxPoolItem(nWhich)
+{
+}
+
+SfxGrabBagItem::~SfxGrabBagItem() = default;
+
+bool SfxGrabBagItem::operator==(const SfxPoolItem& rItem) const
+{
+ return SfxPoolItem::operator==(rItem)
+ && m_aMap == static_cast<const SfxGrabBagItem*>(&rItem)->m_aMap;
+}
+
+SfxGrabBagItem* SfxGrabBagItem::Clone(SfxItemPool* /*pPool*/) const
+{
+ return new SfxGrabBagItem(*this);
+}
+
+bool SfxGrabBagItem::PutValue(const uno::Any& rVal, sal_uInt8 /*nMemberId*/)
+{
+ uno::Sequence<beans::PropertyValue> aValue;
+ if (rVal >>= aValue)
+ {
+ m_aMap.clear();
+ for (beans::PropertyValue const& aPropertyValue : std::as_const(aValue))
+ {
+ m_aMap[aPropertyValue.Name] = aPropertyValue.Value;
+ }
+ return true;
+ }
+
+ SAL_WARN("svl", "SfxGrabBagItem::PutValue: wrong type");
+ return false;
+}
+
+bool SfxGrabBagItem::QueryValue(uno::Any& rVal, sal_uInt8 /*nMemberId*/) const
+{
+ uno::Sequence<beans::PropertyValue> aValue(m_aMap.size());
+ beans::PropertyValue* pValue = aValue.getArray();
+ for (const auto& i : m_aMap)
+ {
+ pValue[0].Name = i.first;
+ pValue[0].Value = i.second;
+ ++pValue;
+ }
+ rVal <<= aValue;
+ return true;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svl/source/items/ilstitem.cxx b/svl/source/items/ilstitem.cxx
new file mode 100644
index 000000000..d9ddeae21
--- /dev/null
+++ b/svl/source/items/ilstitem.cxx
@@ -0,0 +1,88 @@
+/* -*- 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 <com/sun/star/script/Converter.hpp>
+
+#include <comphelper/processfactory.hxx>
+#include <comphelper/sequence.hxx>
+
+#include <svl/ilstitem.hxx>
+
+
+SfxPoolItem* SfxIntegerListItem::CreateDefault() { return new SfxIntegerListItem; }
+
+SfxIntegerListItem::SfxIntegerListItem()
+{
+}
+
+SfxIntegerListItem::SfxIntegerListItem( sal_uInt16 which, const ::std::vector < sal_Int32 >& rList )
+ : SfxPoolItem( which )
+ , m_aList( rList )
+{
+}
+
+SfxIntegerListItem::SfxIntegerListItem( sal_uInt16 which, const css::uno::Sequence < sal_Int32 >& rList )
+ : SfxPoolItem( which )
+{
+ comphelper::sequenceToContainer(m_aList, rList);
+}
+
+SfxIntegerListItem::~SfxIntegerListItem()
+{
+}
+
+bool SfxIntegerListItem::operator==( const SfxPoolItem& rPoolItem ) const
+{
+ if ( !SfxPoolItem::operator==(rPoolItem) )
+ return false;
+
+ const SfxIntegerListItem & rItem = static_cast<const SfxIntegerListItem&>(rPoolItem);
+ return rItem.m_aList == m_aList;
+}
+
+SfxIntegerListItem* SfxIntegerListItem::Clone( SfxItemPool * ) const
+{
+ return new SfxIntegerListItem( *this );
+}
+
+bool SfxIntegerListItem::PutValue ( const css::uno::Any& rVal, sal_uInt8 )
+{
+ css::uno::Reference < css::script::XTypeConverter > xConverter
+ ( css::script::Converter::create(::comphelper::getProcessComponentContext()) );
+ css::uno::Any aNew;
+ try { aNew = xConverter->convertTo( rVal, cppu::UnoType<css::uno::Sequence < sal_Int32 >>::get() ); }
+ catch (css::uno::Exception&)
+ {
+ return true;
+ }
+
+ css::uno::Sequence<sal_Int32> aTempSeq;
+ bool bRet = aNew >>= aTempSeq;
+ if (bRet)
+ m_aList = comphelper::sequenceToContainer<std::vector<sal_Int32>>(aTempSeq);
+ return bRet;
+}
+
+bool SfxIntegerListItem::QueryValue( css::uno::Any& rVal, sal_uInt8 ) const
+{
+ rVal <<= comphelper::containerToSequence(m_aList);
+ return true;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svl/source/items/imageitm.cxx b/svl/source/items/imageitm.cxx
new file mode 100644
index 000000000..4959914b1
--- /dev/null
+++ b/svl/source/items/imageitm.cxx
@@ -0,0 +1,117 @@
+/* -*- 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 <svl/imageitm.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+
+SfxPoolItem* SfxImageItem::CreateDefault() { return new SfxImageItem; }
+
+struct SfxImageItem_Impl
+{
+ OUString aURL;
+ long nAngle;
+ bool bMirrored;
+ bool operator == ( const SfxImageItem_Impl& rOther ) const
+ { return nAngle == rOther.nAngle && bMirrored == rOther.bMirrored; }
+};
+
+
+SfxImageItem::SfxImageItem( sal_uInt16 which )
+ : SfxInt16Item( which, 0 ),
+ pImpl( new SfxImageItem_Impl)
+{
+ pImpl->nAngle = 0;
+ pImpl->bMirrored = false;
+}
+
+SfxImageItem::SfxImageItem( const SfxImageItem& rItem )
+ : SfxInt16Item( rItem ),
+ pImpl( new SfxImageItem_Impl( *rItem.pImpl ) )
+{
+}
+
+SfxImageItem::~SfxImageItem()
+{
+}
+
+SfxImageItem* SfxImageItem::Clone( SfxItemPool* ) const
+{
+ return new SfxImageItem( *this );
+}
+
+bool SfxImageItem::operator==( const SfxPoolItem& rItem ) const
+{
+ return SfxInt16Item::operator==(rItem) &&
+ *pImpl == *static_cast<const SfxImageItem&>(rItem).pImpl;
+}
+
+bool SfxImageItem::QueryValue( css::uno::Any& rVal, sal_uInt8 ) const
+{
+ css::uno::Sequence< css::uno::Any > aSeq( 4 );
+ aSeq[0] <<= GetValue();
+ aSeq[1] <<= pImpl->nAngle;
+ aSeq[2] <<= pImpl->bMirrored;
+ aSeq[3] <<= pImpl->aURL;
+
+ rVal <<= aSeq;
+ return true;
+}
+
+bool SfxImageItem::PutValue( const css::uno::Any& rVal, sal_uInt8 )
+{
+ css::uno::Sequence< css::uno::Any > aSeq;
+ if (( rVal >>= aSeq ) && ( aSeq.getLength() == 4 ))
+ {
+ sal_Int16 nVal = sal_Int16();
+ OUString aURL;
+ if ( aSeq[0] >>= nVal )
+ SetValue( nVal );
+ aSeq[1] >>= pImpl->nAngle;
+ aSeq[2] >>= pImpl->bMirrored;
+ if ( aSeq[3] >>= aURL )
+ pImpl->aURL = aURL;
+ return true;
+ }
+
+ return false;
+}
+
+void SfxImageItem::SetRotation( long nValue )
+{
+ pImpl->nAngle = nValue;
+}
+
+long SfxImageItem::GetRotation() const
+{
+ return pImpl->nAngle;
+}
+
+void SfxImageItem::SetMirrored( bool bSet )
+{
+ pImpl->bMirrored = bSet;
+}
+
+bool SfxImageItem::IsMirrored() const
+{
+ return pImpl->bMirrored;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svl/source/items/int64item.cxx b/svl/source/items/int64item.cxx
new file mode 100644
index 000000000..06efd1fc9
--- /dev/null
+++ b/svl/source/items/int64item.cxx
@@ -0,0 +1,58 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <svl/int64item.hxx>
+
+SfxInt64Item::SfxInt64Item( sal_uInt16 nWhich, sal_Int64 nVal ) :
+ SfxPoolItem(nWhich), mnValue(nVal)
+{
+}
+
+SfxInt64Item::~SfxInt64Item() {}
+
+bool SfxInt64Item::operator== ( const SfxPoolItem& rItem ) const
+{
+ return SfxPoolItem::operator==(rItem) && mnValue == static_cast<const SfxInt64Item&>(rItem).mnValue;
+}
+
+bool SfxInt64Item::GetPresentation(
+ SfxItemPresentation, MapUnit, MapUnit, OUString& rText,
+ const IntlWrapper& /*rIntlWrapper*/ ) const
+{
+ rText = OUString::number(mnValue);
+ return true;
+}
+
+bool SfxInt64Item::QueryValue(
+ css::uno::Any& rVal, sal_uInt8 /*nMemberId*/ ) const
+{
+ rVal <<= mnValue;
+ return true;
+}
+
+bool SfxInt64Item::PutValue(
+ const css::uno::Any& rVal, sal_uInt8 /*nMemberId*/ )
+{
+ sal_Int64 nVal;
+
+ if (rVal >>= nVal)
+ {
+ mnValue = nVal;
+ return true;
+ }
+
+ return false;
+}
+
+SfxInt64Item* SfxInt64Item::Clone( SfxItemPool* /*pOther*/ ) const
+{
+ return new SfxInt64Item(*this);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svl/source/items/intitem.cxx b/svl/source/items/intitem.cxx
new file mode 100644
index 000000000..c0c4831a5
--- /dev/null
+++ b/svl/source/items/intitem.cxx
@@ -0,0 +1,183 @@
+/* -*- 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 <svl/intitem.hxx>
+#include <com/sun/star/uno/Any.hxx>
+#include <osl/diagnose.h>
+#include <tools/bigint.hxx>
+#include <svl/metitem.hxx>
+#include <libxml/xmlwriter.h>
+#include <boost/property_tree/json_parser.hpp>
+
+
+
+
+SfxPoolItem* SfxByteItem::CreateDefault()
+{
+ return new SfxByteItem();
+};
+
+SfxPoolItem* SfxInt16Item::CreateDefault()
+{
+ return new SfxInt16Item();
+};
+
+// virtual
+bool SfxInt16Item::operator ==(const SfxPoolItem & rItem) const
+{
+ assert(SfxPoolItem::operator==(rItem));
+ return m_nValue == static_cast< const SfxInt16Item * >(&rItem)->
+ m_nValue;
+}
+
+// virtual
+bool SfxInt16Item::GetPresentation(SfxItemPresentation,
+ MapUnit, MapUnit,
+ OUString & rText,
+ const IntlWrapper&) const
+{
+ rText = OUString::number(m_nValue);
+ return true;
+}
+
+
+boost::property_tree::ptree SfxInt16Item::dumpAsJSON() const
+{
+ boost::property_tree::ptree aTree = SfxPoolItem::dumpAsJSON();
+ aTree.put("state", GetValue());
+ return aTree;
+}
+
+
+// virtual
+bool SfxInt16Item::QueryValue(css::uno::Any& rVal, sal_uInt8) const
+{
+ sal_Int16 nValue = m_nValue;
+ rVal <<= nValue;
+ return true;
+}
+
+// virtual
+bool SfxInt16Item::PutValue(const css::uno::Any& rVal, sal_uInt8 )
+{
+ sal_Int16 nValue = sal_Int16();
+ if (rVal >>= nValue)
+ {
+ m_nValue = nValue;
+ return true;
+ }
+
+ OSL_FAIL( "SfxInt16Item::PutValue - Wrong type!" );
+ return false;
+}
+
+SfxInt16Item* SfxInt16Item::Clone(SfxItemPool *) const
+{
+ return new SfxInt16Item(*this);
+}
+
+SfxPoolItem* SfxUInt16Item::CreateDefault()
+{
+ return new SfxUInt16Item();
+};
+
+void SfxUInt16Item::dumpAsXml(xmlTextWriterPtr pWriter) const
+{
+ xmlTextWriterStartElement(pWriter, BAD_CAST("SfxUInt16Item"));
+ xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr()));
+ xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"), BAD_CAST(OString::number(GetValue()).getStr()));
+ xmlTextWriterEndElement(pWriter);
+}
+
+boost::property_tree::ptree SfxUInt16Item::dumpAsJSON() const
+{
+ boost::property_tree::ptree aTree = SfxPoolItem::dumpAsJSON();
+ aTree.put("state", GetValue());
+ return aTree;
+}
+
+
+
+
+SfxPoolItem* SfxInt32Item::CreateDefault()
+{
+ return new SfxInt32Item();
+};
+
+void SfxInt32Item::dumpAsXml(xmlTextWriterPtr pWriter) const
+{
+ xmlTextWriterStartElement(pWriter, BAD_CAST("SfxInt32Item"));
+ xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr()));
+ xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"), BAD_CAST(OString::number(GetValue()).getStr()));
+ xmlTextWriterEndElement(pWriter);
+}
+
+boost::property_tree::ptree SfxInt32Item::dumpAsJSON() const
+{
+ boost::property_tree::ptree aTree = SfxPoolItem::dumpAsJSON();
+ aTree.put("state", GetValue());
+ return aTree;
+}
+
+
+
+
+SfxPoolItem* SfxUInt32Item::CreateDefault()
+{
+ return new SfxUInt32Item();
+};
+
+void SfxUInt32Item::dumpAsXml(xmlTextWriterPtr pWriter) const
+{
+ xmlTextWriterStartElement(pWriter, BAD_CAST("SfxUInt32Item"));
+ xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr()));
+ xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"), BAD_CAST(OString::number(GetValue()).getStr()));
+ xmlTextWriterEndElement(pWriter);
+}
+
+boost::property_tree::ptree SfxUInt32Item::dumpAsJSON() const
+{
+ boost::property_tree::ptree aTree = SfxPoolItem::dumpAsJSON();
+ aTree.put("state", GetValue());
+ return aTree;
+}
+
+SfxMetricItem::SfxMetricItem(sal_uInt16 which, sal_uInt32 nValue):
+ SfxInt32Item(which, nValue)
+{
+}
+
+// virtual
+void SfxMetricItem::ScaleMetrics(long nMult, long nDiv)
+{
+ BigInt aTheValue(GetValue());
+ aTheValue *= nMult;
+ aTheValue += nDiv / 2;
+ aTheValue /= nDiv;
+ SetValue(aTheValue);
+}
+
+// virtual
+bool SfxMetricItem::HasMetrics() const
+{
+ return true;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svl/source/items/itemiter.cxx b/svl/source/items/itemiter.cxx
new file mode 100644
index 000000000..fe0ee377f
--- /dev/null
+++ b/svl/source/items/itemiter.cxx
@@ -0,0 +1,63 @@
+/* -*- 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 <svl/itemiter.hxx>
+#include <svl/itemset.hxx>
+
+SfxItemIter::SfxItemIter( const SfxItemSet& rItemSet )
+ : m_rSet( rItemSet )
+{
+ if (!m_rSet.m_nCount)
+ {
+ m_nStart = 0;
+ m_nEnd = 0;
+ }
+ else
+ {
+ SfxPoolItem const** ppFnd = m_rSet.m_pItems.get();
+
+ // Find the first Item that is set
+ for (m_nStart = 0; !*(ppFnd + m_nStart ); ++m_nStart)
+ ; // empty loop
+ if (1 < m_rSet.Count())
+ for (m_nEnd = m_rSet.TotalCount(); !*(ppFnd + --m_nEnd); )
+ ; // empty loop
+ else
+ m_nEnd = m_nStart;
+ }
+
+ m_nCurrent = m_nStart;
+}
+
+SfxItemIter::~SfxItemIter()
+{
+}
+
+// Precondition : m_nCurrent < m_nEnd
+const SfxPoolItem* SfxItemIter::ImplNextItem()
+{
+ SfxPoolItem const** ppFnd = m_rSet.m_pItems.get();
+ do {
+ m_nCurrent++;
+ } while (m_nCurrent < m_nEnd && !*(ppFnd + m_nCurrent ));
+ return *(ppFnd+m_nCurrent);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svl/source/items/itempool.cxx b/svl/source/items/itempool.cxx
new file mode 100644
index 000000000..82668c909
--- /dev/null
+++ b/svl/source/items/itempool.cxx
@@ -0,0 +1,947 @@
+/* -*- 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 <svl/itempool.hxx>
+
+#include <string.h>
+#include <libxml/xmlwriter.h>
+
+#include <tools/solar.h>
+#include <osl/diagnose.h>
+#include <sal/log.hxx>
+#include <svl/SfxBroadcaster.hxx>
+#include <svl/hint.hxx>
+#include <svl/itemset.hxx>
+#include <poolio.hxx>
+
+#include <algorithm>
+#include <cassert>
+#include <vector>
+
+
+#if OSL_DEBUG_LEVEL > 0
+#include <map>
+
+static void
+lcl_CheckSlots2(std::map<sal_uInt16, sal_uInt16> & rSlotMap,
+ SfxItemPool const& rPool, SfxItemInfo const* pInfo)
+{
+ if (!pInfo)
+ return; // may not be initialized yet
+ if (rPool.GetName() == "EditEngineItemPool")
+ return; // HACK: this one has loads of duplicates already, ignore it :(
+ sal_uInt16 const nFirst(rPool.GetFirstWhich());
+ sal_uInt16 const nCount(rPool.GetLastWhich() - rPool.GetFirstWhich() + 1);
+ for (sal_uInt16 n = 0; n < nCount; ++n)
+ {
+ sal_uInt16 const nSlotId(pInfo[n]._nSID);
+ if (nSlotId != 0
+ && nSlotId != 10883 // preexisting duplicate SID_ATTR_GRAF_CROP
+ && nSlotId != 10023 // preexisting duplicate SID_ATTR_BORDER_INNER
+ && nSlotId != 10024 // preexisting duplicate SID_ATTR_BORDER_OUTER
+ && nSlotId != 11013 // preexisting duplicate SID_ATTR_BORDER_DIAG_TLBR
+ && nSlotId != 11014) // preexisting duplicate SID_ATTR_BORDER_DIAG_BLTR
+ { // check for duplicate slot-id mapping
+ std::map<sal_uInt16, sal_uInt16>::const_iterator const iter(
+ rSlotMap.find(nSlotId));
+ sal_uInt16 const nWhich(nFirst + n);
+ if (iter != rSlotMap.end())
+ {
+ SAL_WARN("svl", "SfxItemPool: duplicate SlotId " << nSlotId
+ << " mapped to " << iter->second << " and " << nWhich);
+ assert(false);
+ }
+ rSlotMap.insert(std::make_pair(nSlotId, nWhich));
+ }
+ }
+}
+
+#define CHECK_SLOTS() \
+do { \
+ std::map<sal_uInt16, sal_uInt16> slotmap; \
+ for (SfxItemPool * p = pImpl->mpMaster; p; p = p->pImpl->mpSecondary) \
+ { \
+ lcl_CheckSlots2(slotmap, *p, p->pItemInfos); \
+ } \
+} while (false)
+
+#else
+#define CHECK_SLOTS() do {} while (false)
+#endif
+
+
+void SfxItemPool::AddSfxItemPoolUser(SfxItemPoolUser& rNewUser)
+{
+ // maintain sorted to reduce cost of remove
+ const auto insertIt = ::std::lower_bound(
+ pImpl->maSfxItemPoolUsers.begin(), pImpl->maSfxItemPoolUsers.end(), &rNewUser);
+ pImpl->maSfxItemPoolUsers.insert(insertIt, &rNewUser);
+}
+
+void SfxItemPool::RemoveSfxItemPoolUser(SfxItemPoolUser& rOldUser)
+{
+ const auto aFindResult = ::std::lower_bound(
+ pImpl->maSfxItemPoolUsers.begin(), pImpl->maSfxItemPoolUsers.end(), &rOldUser);
+ if(aFindResult != pImpl->maSfxItemPoolUsers.end() && *aFindResult == &rOldUser)
+ {
+ pImpl->maSfxItemPoolUsers.erase(aFindResult);
+ }
+}
+
+const SfxPoolItem* SfxItemPool::GetPoolDefaultItem( sal_uInt16 nWhich ) const
+{
+ const SfxPoolItem* pRet;
+ if( IsInRange( nWhich ) )
+ pRet = pImpl->maPoolDefaults[GetIndex_Impl(nWhich)];
+ else if( pImpl->mpSecondary )
+ pRet = pImpl->mpSecondary->GetPoolDefaultItem( nWhich );
+ else
+ {
+ assert(false && "unknown WhichId - cannot get pool default");
+ pRet = nullptr;
+ }
+ return pRet;
+}
+
+
+bool SfxItemPool::IsItemPoolable_Impl( sal_uInt16 nPos ) const
+{
+ return pItemInfos[nPos]._bPoolable;
+}
+
+
+bool SfxItemPool::IsItemPoolable( sal_uInt16 nWhich ) const
+{
+ for ( const SfxItemPool *pPool = this; pPool; pPool = pPool->pImpl->mpSecondary )
+ {
+ if ( pPool->IsInRange(nWhich) )
+ return pPool->IsItemPoolable_Impl( pPool->GetIndex_Impl(nWhich));
+ }
+ DBG_ASSERT( !IsWhich(nWhich), "unknown which-id" );
+ return false;
+}
+
+
+SfxBroadcaster& SfxItemPool::BC()
+{
+ return pImpl->aBC;
+}
+
+
+/**
+ * This is the regular ctor to be used for this class.
+ * An SfxItemPool instance is initialized, which can manage Items in the
+ * range from 'nStartWhich' to 'nEndWhich'.
+ *
+ * For every one of these WhichIds a static Default must be present in the
+ * 'pDefaults' array. They start with an SfxPoolItem (with the WhichId
+ * 'nStartWhich'), are sorted by WhichId and consecutively stored.
+ *
+ * 'pItemInfos' is a USHORT array arranged in the same way, which holds
+ * SlotIds and Flags. These SlotIds can be 0, if the affected Items are
+ * exclusively used in the Core.
+ * The flags allow for e.g. enabling value sharing (poolable).
+ *
+ * If the Pool is supposed to hold SfxSetItems, the ctor cannot yet contain
+ * static Defaults. This needs to be done afterwards, using
+ * @see SfxItemPool::SetDefaults(std::vector<SfxPoolItem*>*).
+ *
+ * @see SfxItemPool::SetDefaults(std::vector<SfxPoolItem*>*)
+ * @see SfxItemPool::ReleaseDefaults(std::vector<SfxPoolItem*>*,sal_uInt16,sal_Bool)
+ * @see SfxItemPool::ReldaseDefaults(sal_Bool)
+ */
+SfxItemPool::SfxItemPool
+(
+ const OUString& rName, /* Pool name to identify in the file format */
+ sal_uInt16 nStartWhich, /* First WhichId of the Pool (must be > 0) */
+ sal_uInt16 nEndWhich, /* Last WhichId of the Pool */
+ const SfxItemInfo* pInfo, /* SID Map and Item flags */
+ std::vector<SfxPoolItem*>*
+ pDefaults /* Pointer to static Defaults;
+ is directly referenced by the Pool,
+ but no transfer of ownership */
+) :
+ pItemInfos(pInfo),
+ pImpl( new SfxItemPool_Impl( this, rName, nStartWhich, nEndWhich ) )
+{
+ pImpl->eDefMetric = MapUnit::MapTwip;
+
+ if ( pDefaults )
+ SetDefaults(pDefaults);
+}
+
+
+/**
+ * Copy ctor
+ *
+ * @see SfxItemPool::Clone() const
+*/
+SfxItemPool::SfxItemPool
+(
+ const SfxItemPool& rPool, // Copy from this instance
+ bool bCloneStaticDefaults /* true
+ Copy static Defaults
+
+ false
+ Take over static Defaults */
+) :
+ pItemInfos(rPool.pItemInfos),
+ pImpl( new SfxItemPool_Impl( this, rPool.pImpl->aName, rPool.pImpl->mnStart, rPool.pImpl->mnEnd ) )
+{
+ pImpl->eDefMetric = rPool.pImpl->eDefMetric;
+
+ // Take over static Defaults
+ if ( bCloneStaticDefaults )
+ {
+ std::vector<SfxPoolItem *>* ppDefaults = new std::vector<SfxPoolItem*>(pImpl->mnEnd-pImpl->mnStart+1);
+ for ( sal_uInt16 n = 0; n <= pImpl->mnEnd - pImpl->mnStart; ++n )
+ {
+ (*ppDefaults)[n] = (*rPool.pImpl->mpStaticDefaults)[n]->Clone(this);
+ (*ppDefaults)[n]->SetKind(SfxItemKind::StaticDefault);
+ }
+
+ SetDefaults( ppDefaults );
+ }
+ else
+ SetDefaults( rPool.pImpl->mpStaticDefaults );
+
+ // Copy Pool Defaults
+ for (size_t n = 0; n < pImpl->maPoolDefaults.size(); ++n )
+ if (rPool.pImpl->maPoolDefaults[n])
+ {
+ pImpl->maPoolDefaults[n] = rPool.pImpl->maPoolDefaults[n]->Clone(this); //resets kind
+ pImpl->maPoolDefaults[n]->SetKind(SfxItemKind::PoolDefault);
+ }
+
+ // Repair linkage
+ if ( rPool.pImpl->mpSecondary )
+ SetSecondaryPool( rPool.pImpl->mpSecondary->Clone() );
+}
+
+void SfxItemPool::SetDefaults( std::vector<SfxPoolItem*>* pDefaults )
+{
+ DBG_ASSERT( pDefaults, "first we ask for it, and then we don't give back..." );
+ DBG_ASSERT( !pImpl->mpStaticDefaults, "already have Defaults" );
+
+ pImpl->mpStaticDefaults = pDefaults;
+ //! if ((*mpStaticDefaults)->GetKind() != SfxItemKind::StaticDefault)
+ //! FIXME: Probably doesn't work with SetItems at the end
+ {
+ DBG_ASSERT( (*pImpl->mpStaticDefaults)[0]->GetRefCount() == 0 ||
+ IsDefaultItem( (*pImpl->mpStaticDefaults)[0] ),
+ "these are not static" );
+ for ( sal_uInt16 n = 0; n <= pImpl->mnEnd - pImpl->mnStart; ++n )
+ {
+ assert( ((*pImpl->mpStaticDefaults)[n]->Which() == n + pImpl->mnStart)
+ && "static defaults not sorted" );
+ (*pImpl->mpStaticDefaults)[n]->SetKind(SfxItemKind::StaticDefault);
+ DBG_ASSERT( pImpl->maPoolItemArrays[n].empty(), "defaults with setitems with items?!" );
+ }
+ }
+}
+
+void SfxItemPool::ClearDefaults()
+{
+ pImpl->mpStaticDefaults = nullptr;
+}
+
+/**
+ * Frees the static Defaults of the corresponding SfxItemPool instance
+ * and deletes them if specified.
+ *
+ * The SfxItemPool instance MUST NOT BE USED after this function has
+ * been called; only the dtor must be called.
+ */
+void SfxItemPool::ReleaseDefaults
+(
+ bool bDelete /* true
+ Deletes the array as well as the single static Defaults
+
+ false
+ Neither deletes the array not the single static Defaults */
+)
+
+
+{
+ DBG_ASSERT( pImpl->mpStaticDefaults, "requirements not met" );
+ ReleaseDefaults( pImpl->mpStaticDefaults, bDelete );
+
+ // mpStaticDefaults points to deleted memory if bDelete == true.
+ if ( bDelete )
+ pImpl->mpStaticDefaults = nullptr;
+}
+
+
+/**
+ * Frees the specified static Defaults and also deletes them, if so
+ * specified.
+ *
+ * This method MUST be called AFTER all SfxItemPool instances (which
+ * use the specified static Defaults 'pDefault') have been destroyed.
+ */
+void SfxItemPool::ReleaseDefaults
+(
+ std::vector<SfxPoolItem*>*
+ pDefaults, /* Static Defaults that are to be freed */
+
+ bool bDelete /* true
+ Deletes the array as well as the specified
+ static Defaults
+
+ false
+ Neither deletes the array nor the single
+ static Defaults */
+)
+{
+ DBG_ASSERT( pDefaults, "we first ask for it and the return nothing ..." );
+
+ for ( auto & rpItem : *pDefaults )
+ {
+ assert(IsStaticDefaultItem(rpItem));
+ rpItem->SetRefCount(0);
+ if ( bDelete )
+ {
+ delete rpItem;
+ rpItem = nullptr;
+ }
+ }
+
+ if ( bDelete )
+ {
+ delete pDefaults;
+ pDefaults = nullptr;
+ }
+}
+
+
+SfxItemPool::~SfxItemPool()
+{
+ if ( !pImpl->maPoolItemArrays.empty() && !pImpl->maPoolDefaults.empty() )
+ Delete();
+
+ if (pImpl->mpMaster != nullptr && pImpl->mpMaster != this)
+ {
+ // This condition indicates an error.
+ // A pImpl->mpMaster->SetSecondaryPool(...) call should have been made
+ // earlier to prevent this. At this point we can only try to
+ // prevent a crash later on.
+ DBG_ASSERT( pImpl->mpMaster == this, "destroying active Secondary-Pool" );
+ if (pImpl->mpMaster->pImpl->mpSecondary == this)
+ pImpl->mpMaster->pImpl->mpSecondary = nullptr;
+ }
+}
+
+void SfxItemPool::Free(SfxItemPool* pPool)
+{
+ if(!pPool)
+ return;
+
+ // tell all the registered SfxItemPoolUsers that the pool is in destruction
+ std::vector<SfxItemPoolUser*> aListCopy(pPool->pImpl->maSfxItemPoolUsers);
+ for(SfxItemPoolUser* pSfxItemPoolUser : aListCopy)
+ {
+ DBG_ASSERT(pSfxItemPoolUser, "corrupt SfxItemPoolUser list (!)");
+ pSfxItemPoolUser->ObjectInDestruction(*pPool);
+ }
+
+ // Clear the vector. This means that user do not need to call RemoveSfxItemPoolUser()
+ // when they get called from ObjectInDestruction().
+ pPool->pImpl->maSfxItemPoolUsers.clear();
+
+ // delete pool
+ delete pPool;
+}
+
+
+void SfxItemPool::SetSecondaryPool( SfxItemPool *pPool )
+{
+ // Reset Master in attached Pools
+ if ( pImpl->mpSecondary )
+ {
+#ifdef DBG_UTIL
+ if (pImpl->mpStaticDefaults != nullptr && !pImpl->maPoolItemArrays.empty()
+ && !pImpl->mpSecondary->pImpl->maPoolItemArrays.empty())
+ // Delete() did not yet run?
+ {
+ // Does the Master have SetItems?
+ bool bHasSetItems = false;
+ for ( sal_uInt16 i = 0; !bHasSetItems && i < pImpl->mnEnd - pImpl->mnStart; ++i )
+ bHasSetItems = dynamic_cast<const SfxSetItem *>((*pImpl->mpStaticDefaults)[i]) != nullptr;
+
+ // Detached Pools must be empty
+ bool bOK = bHasSetItems;
+ for (auto const& rSecArray : pImpl->mpSecondary->pImpl->maPoolItemArrays)
+ {
+ if (!bOK)
+ break;
+ if (rSecArray.size()>0)
+ {
+ SAL_WARN("svl.items", "old secondary pool: " << pImpl->mpSecondary->pImpl->aName
+ << " of pool: " << pImpl->aName << " must be empty.");
+ break;
+ }
+ }
+ }
+#endif
+
+ pImpl->mpSecondary->pImpl->mpMaster = pImpl->mpSecondary;
+ for ( SfxItemPool *p = pImpl->mpSecondary->pImpl->mpSecondary; p; p = p->pImpl->mpSecondary )
+ p->pImpl->mpMaster = pImpl->mpSecondary;
+ }
+
+ // Set Master of new Secondary Pools
+ DBG_ASSERT( !pPool || pPool->pImpl->mpMaster == pPool, "Secondary is present in two Pools" );
+ SfxItemPool *pNewMaster = GetMasterPool() ? pImpl->mpMaster : this;
+ for ( SfxItemPool *p = pPool; p; p = p->pImpl->mpSecondary )
+ p->pImpl->mpMaster = pNewMaster;
+
+ // Remember new Secondary Pool
+ pImpl->mpSecondary = pPool;
+
+ CHECK_SLOTS();
+}
+
+void SfxItemPool::SetItemInfos(SfxItemInfo const*const pInfo)
+{
+ pItemInfos = pInfo;
+ CHECK_SLOTS();
+}
+
+
+MapUnit SfxItemPool::GetMetric( sal_uInt16 ) const
+{
+ return pImpl->eDefMetric;
+}
+
+
+void SfxItemPool::SetDefaultMetric( MapUnit eNewMetric )
+{
+ pImpl->eDefMetric = eNewMetric;
+}
+
+const OUString& SfxItemPool::GetName() const
+{
+ return pImpl->aName;
+}
+
+
+bool SfxItemPool::GetPresentation
+(
+ const SfxPoolItem& rItem,
+ MapUnit eMetric,
+ OUString& rText,
+ const IntlWrapper& rIntlWrapper
+) const
+{
+ return rItem.GetPresentation(
+ SfxItemPresentation::Complete, GetMetric(rItem.Which()), eMetric, rText, rIntlWrapper );
+}
+
+
+SfxItemPool* SfxItemPool::Clone() const
+{
+ SfxItemPool *pPool = new SfxItemPool( *this );
+ return pPool;
+}
+
+
+void SfxItemPool::Delete()
+{
+ // Already deleted?
+ if (pImpl->maPoolItemArrays.empty() || pImpl->maPoolDefaults.empty())
+ return;
+
+ // Inform e.g. running Requests
+ pImpl->aBC.Broadcast( SfxHint( SfxHintId::Dying ) );
+
+ // Iterate through twice: first for the SetItems.
+ if (pImpl->mpStaticDefaults != nullptr) {
+ for (size_t n = 0; n < GetSize_Impl(); ++n)
+ {
+ // *mpStaticDefaultItem could've already been deleted in a class derived
+ // from SfxItemPool
+ // This causes chaos in Itempool!
+ const SfxPoolItem* pStaticDefaultItem = (*pImpl->mpStaticDefaults)[n];
+ if (dynamic_cast<const SfxSetItem*>(pStaticDefaultItem))
+ {
+ // SfxSetItem found, remove PoolItems (and defaults) with same ID
+ auto& rArray = pImpl->maPoolItemArrays[n];
+ for (auto& rItemPtr : rArray)
+ {
+ ReleaseRef(*rItemPtr, rItemPtr->GetRefCount()); // for RefCount check in dtor
+ delete rItemPtr;
+ }
+ rArray.clear();
+ // let pImpl->DeleteItems() delete item arrays in maPoolItems
+ auto& rItemPtr = pImpl->maPoolDefaults[n];
+ if (rItemPtr)
+ {
+#ifdef DBG_UTIL
+ ClearRefCount(*rItemPtr);
+#endif
+ delete rItemPtr;
+ rItemPtr = nullptr;
+ }
+ }
+ }
+ }
+
+ // now remove remaining PoolItems (and defaults) who didn't have SetItems
+ for (auto& rArray : pImpl->maPoolItemArrays)
+ {
+ for (auto& rItemPtr : rArray)
+ {
+ ReleaseRef(*rItemPtr, rItemPtr->GetRefCount()); // for RefCount check in dtor
+ delete rItemPtr;
+ }
+ rArray.clear();
+ // let pImpl->DeleteItems() delete item arrays in maPoolItems
+ }
+ pImpl->maPoolItemArrays.clear();
+ // default items
+ for (auto rItemPtr : pImpl->maPoolDefaults)
+ {
+ if (rItemPtr)
+ {
+#ifdef DBG_UTIL
+ ClearRefCount(*rItemPtr);
+#endif
+ delete rItemPtr;
+ rItemPtr = nullptr;
+ }
+ }
+
+ pImpl->DeleteItems();
+}
+
+
+void SfxItemPool::SetPoolDefaultItem(const SfxPoolItem &rItem)
+{
+ if ( IsInRange(rItem.Which()) )
+ {
+ auto& rOldDefault =
+ pImpl->maPoolDefaults[GetIndex_Impl(rItem.Which())];
+ SfxPoolItem *pNewDefault = rItem.Clone(this);
+ pNewDefault->SetKind(SfxItemKind::PoolDefault);
+ if (rOldDefault)
+ {
+ rOldDefault->SetRefCount(0);
+ DELETEZ(rOldDefault);
+ }
+ rOldDefault = pNewDefault;
+ }
+ else if ( pImpl->mpSecondary )
+ pImpl->mpSecondary->SetPoolDefaultItem(rItem);
+ else
+ {
+ assert(false && "unknown WhichId - cannot set pool default");
+ }
+}
+
+/**
+ * Resets the default of the given WhichId back to the static Default.
+ * If a pool default exists, it is removed.
+ */
+void SfxItemPool::ResetPoolDefaultItem( sal_uInt16 nWhichId )
+{
+ if ( IsInRange(nWhichId) )
+ {
+ auto& rOldDefault =
+ pImpl->maPoolDefaults[GetIndex_Impl(nWhichId)];
+ if (rOldDefault)
+ {
+ rOldDefault->SetRefCount(0);
+ DELETEZ(rOldDefault);
+ }
+ }
+ else if ( pImpl->mpSecondary )
+ pImpl->mpSecondary->ResetPoolDefaultItem(nWhichId);
+ else
+ {
+ assert(false && "unknown WhichId - cannot reset pool default");
+ }
+}
+
+
+const SfxPoolItem& SfxItemPool::PutImpl( const SfxPoolItem& rItem, sal_uInt16 nWhich, bool bPassingOwnership )
+{
+ if ( 0 == nWhich )
+ nWhich = rItem.Which();
+
+ // Find correct Secondary Pool
+ bool bSID = IsSlot(nWhich);
+ if ( !bSID && !IsInRange(nWhich) )
+ {
+ if ( pImpl->mpSecondary )
+ return pImpl->mpSecondary->PutImpl( rItem, nWhich, bPassingOwnership );
+ OSL_FAIL( "unknown WhichId - cannot put item" );
+ }
+
+ // SID ?
+ if (bSID)
+ {
+ assert((rItem.Which() != nWhich ||
+ !IsDefaultItem(&rItem) || rItem.GetKind() == SfxItemKind::DeleteOnIdle)
+ && "a non Pool Item is Default?!");
+ SfxPoolItem *pPoolItem = rItem.Clone(pImpl->mpMaster);
+ pPoolItem->SetWhich(nWhich);
+ AddRef( *pPoolItem );
+ if (bPassingOwnership)
+ delete &rItem;
+ return *pPoolItem;
+ }
+
+ assert(!pImpl->mpStaticDefaults ||
+ typeid(rItem) == typeid(GetDefaultItem(nWhich)));
+
+ const sal_uInt16 nIndex = GetIndex_Impl(nWhich);
+ SfxPoolItemArray_Impl& rItemArr = pImpl->maPoolItemArrays[nIndex];
+
+ // Is this a 'poolable' item - ie. should we re-use and return
+ // the same underlying item for equivalent (==) SfxPoolItems?
+ if ( IsItemPoolable_Impl( nIndex ) )
+ {
+ // if is already in a pool, then it is worth checking if it is in this one.
+ if ( IsPooledItem(&rItem) )
+ {
+ // 1. search for an identical pointer in the pool
+ auto it = rItemArr.find(const_cast<SfxPoolItem *>(&rItem));
+ if (it != rItemArr.end())
+ {
+ AddRef(rItem);
+ assert(!bPassingOwnership && "can't be passing ownership and have the item already in the pool");
+ return rItem;
+ }
+ }
+
+ const SfxPoolItem* pFoundItem = nullptr;
+ // 2. search for an item with matching attributes.
+ if (rItem.IsSortable())
+ {
+ pFoundItem = rItemArr.findByLessThan(&rItem);
+ if (pFoundItem)
+ assert(*pFoundItem == rItem);
+ }
+ else
+ {
+ for (auto itr = rItemArr.begin(); itr != rItemArr.end(); ++itr)
+ {
+ if (**itr == rItem)
+ {
+ pFoundItem = *itr;
+ break;
+ }
+ }
+ }
+ if (pFoundItem)
+ {
+ assert((!bPassingOwnership || (&rItem != pFoundItem)) && "can't be passing ownership and have the item already in the pool");
+ AddRef(*pFoundItem);
+ if (bPassingOwnership)
+ delete &rItem;
+ return *pFoundItem;
+ }
+ }
+
+ // 3. not found, so clone to insert into the pointer array.
+ SfxPoolItem* pNewItem;
+ if (bPassingOwnership)
+ {
+ assert(!dynamic_cast<const SfxItemSet*>(&rItem) && "can't pass ownership of SfxItem, they need to be cloned to the master pool");
+ pNewItem = const_cast<SfxPoolItem*>(&rItem);
+ }
+ else
+ pNewItem = rItem.Clone(pImpl->mpMaster);
+ pNewItem->SetWhich(nWhich);
+ assert(typeid(rItem) == typeid(*pNewItem) && "SfxItemPool::Put(): unequal types, no Clone() override?");
+ if (dynamic_cast<const SfxSetItem*>(&rItem) == nullptr)
+ {
+ assert((!IsItemPoolable(nWhich) || rItem == *pNewItem)
+ && "SfxItemPool::Put(): unequal items: no operator== override?");
+ assert((!IsItemPoolable(*pNewItem) || *pNewItem == rItem)
+ && "SfxItemPool::Put(): unequal items: no operator== override?");
+ }
+ AddRef( *pNewItem );
+
+ // 4. finally insert into the pointer array
+ rItemArr.insert( pNewItem );
+ return *pNewItem;
+}
+
+void SfxItemPool::Remove( const SfxPoolItem& rItem )
+{
+ assert(!IsPoolDefaultItem(&rItem) && "cannot remove Pool Default");
+
+ // Find correct Secondary Pool
+ const sal_uInt16 nWhich = rItem.Which();
+ bool bSID = IsSlot(nWhich);
+ if ( !bSID && !IsInRange(nWhich) )
+ {
+ if ( pImpl->mpSecondary )
+ {
+ pImpl->mpSecondary->Remove( rItem );
+ return;
+ }
+ OSL_FAIL( "unknown WhichId - cannot remove item" );
+ }
+
+ // SID ?
+ if ( bSID )
+ {
+ assert(!IsDefaultItem(&rItem) && "a non Pool Item is Default?!");
+ if ( 0 == ReleaseRef(rItem) )
+ {
+ delete &rItem;
+ }
+ return;
+ }
+
+ assert(rItem.GetRefCount() && "RefCount == 0, Remove impossible");
+
+ const sal_uInt16 nIndex = GetIndex_Impl(nWhich);
+ // Static Defaults are just there
+ if ( IsStaticDefaultItem(&rItem) &&
+ &rItem == (*pImpl->mpStaticDefaults)[nIndex])
+ return;
+
+ // Find Item in own Pool
+ SfxPoolItemArray_Impl& rItemArr = pImpl->maPoolItemArrays[nIndex];
+
+ auto it = rItemArr.find(const_cast<SfxPoolItem *>(&rItem));
+ if (it != rItemArr.end())
+ {
+ if ( rItem.GetRefCount() ) //!
+ ReleaseRef( rItem );
+ else
+ {
+ assert(false && "removing Item without ref");
+ }
+
+ // FIXME: Hack, for as long as we have problems with the Outliner
+ // See other MI-REF
+ if ( 0 == rItem.GetRefCount() && nWhich < 4000 )
+ {
+ rItemArr.erase(it);
+ delete &rItem;
+ }
+
+ return;
+ }
+
+ // not found
+ assert(false && "removing Item not in Pool");
+}
+
+
+const SfxPoolItem& SfxItemPool::GetDefaultItem( sal_uInt16 nWhich ) const
+{
+ if ( !IsInRange(nWhich) )
+ {
+ if ( pImpl->mpSecondary )
+ return pImpl->mpSecondary->GetDefaultItem( nWhich );
+ assert(!"unknown which - don't ask me for defaults");
+ }
+
+ DBG_ASSERT( pImpl->mpStaticDefaults, "no defaults known - don't ask me for defaults" );
+ sal_uInt16 nPos = GetIndex_Impl(nWhich);
+ SfxPoolItem* pDefault = pImpl->maPoolDefaults[nPos];
+ if ( pDefault )
+ return *pDefault;
+ return *(*pImpl->mpStaticDefaults)[nPos];
+}
+
+SfxItemPool* SfxItemPool::GetSecondaryPool() const
+{
+ return pImpl->mpSecondary;
+}
+
+SfxItemPool* SfxItemPool::GetMasterPool() const
+{
+ return pImpl->mpMaster;
+}
+
+/**
+ * This method should be called at the master pool, when all secondary
+ * pools are appended to it.
+ *
+ * It calculates the ranges of 'which-ids' for fast construction of
+ * item-sets, which contains all 'which-ids'.
+ */
+void SfxItemPool::FreezeIdRanges()
+{
+ FillItemIdRanges_Impl( pImpl->mpPoolRanges );
+}
+
+
+void SfxItemPool::FillItemIdRanges_Impl( std::unique_ptr<sal_uInt16[]>& pWhichRanges ) const
+{
+ DBG_ASSERT( !pImpl->mpPoolRanges, "GetFrozenRanges() would be faster!" );
+
+ const SfxItemPool *pPool;
+ sal_uInt16 nLevel = 0;
+ for( pPool = this; pPool; pPool = pPool->pImpl->mpSecondary )
+ ++nLevel;
+
+ pWhichRanges.reset(new sal_uInt16[ 2*nLevel + 1 ]);
+
+ nLevel = 0;
+ for( pPool = this; pPool; pPool = pPool->pImpl->mpSecondary )
+ {
+ pWhichRanges[nLevel++] = pPool->pImpl->mnStart;
+ pWhichRanges[nLevel++] = pPool->pImpl->mnEnd;
+ pWhichRanges[nLevel] = 0;
+ }
+}
+
+const sal_uInt16* SfxItemPool::GetFrozenIdRanges() const
+{
+ return pImpl->mpPoolRanges.get();
+}
+
+const SfxPoolItem *SfxItemPool::GetItem2Default(sal_uInt16 nWhich) const
+{
+ if ( !IsInRange(nWhich) )
+ {
+ if ( pImpl->mpSecondary )
+ return pImpl->mpSecondary->GetItem2Default( nWhich );
+ assert(false && "unknown WhichId - cannot resolve surrogate");
+ return nullptr;
+ }
+ return (*pImpl->mpStaticDefaults)[ GetIndex_Impl(nWhich) ];
+}
+
+SfxItemPool::Item2Range SfxItemPool::GetItemSurrogates(sal_uInt16 nWhich) const
+{
+ static const o3tl::sorted_vector<SfxPoolItem*> EMPTY;
+
+ if ( !IsInRange(nWhich) )
+ {
+ if ( pImpl->mpSecondary )
+ return pImpl->mpSecondary->GetItemSurrogates( nWhich );
+ assert(false && "unknown WhichId - cannot resolve surrogate");
+ return { EMPTY.end(), EMPTY.end() };
+ }
+
+ SfxPoolItemArray_Impl& rItemArr = pImpl->maPoolItemArrays[GetIndex_Impl(nWhich)];
+ return { rItemArr.begin(), rItemArr.end() };
+}
+
+/* This is only valid for SfxPoolItem that override IsSortable and operator< */
+std::vector<const SfxPoolItem*> SfxItemPool::FindItemSurrogate(sal_uInt16 nWhich, SfxPoolItem const & rSample) const
+{
+ if ( !IsInRange(nWhich) )
+ {
+ if ( pImpl->mpSecondary )
+ return pImpl->mpSecondary->FindItemSurrogate( nWhich, rSample );
+ assert(false && "unknown WhichId - cannot resolve surrogate");
+ return std::vector<const SfxPoolItem*>();
+ }
+
+ SfxPoolItemArray_Impl& rItemArr = pImpl->maPoolItemArrays[GetIndex_Impl(nWhich)];
+ return rItemArr.findSurrogateRange(&rSample);
+}
+
+sal_uInt32 SfxItemPool::GetItemCount2(sal_uInt16 nWhich) const
+{
+ if ( !IsInRange(nWhich) )
+ {
+ if ( pImpl->mpSecondary )
+ return pImpl->mpSecondary->GetItemCount2( nWhich );
+ assert(false && "unknown WhichId - cannot resolve surrogate");
+ return 0;
+ }
+
+ SfxPoolItemArray_Impl& rItemArr = pImpl->maPoolItemArrays[GetIndex_Impl(nWhich)];
+ return rItemArr.size();
+}
+
+
+sal_uInt16 SfxItemPool::GetWhich( sal_uInt16 nSlotId, bool bDeep ) const
+{
+ if ( !IsSlot(nSlotId) )
+ return nSlotId;
+
+ sal_uInt16 nCount = pImpl->mnEnd - pImpl->mnStart + 1;
+ for ( sal_uInt16 nOfs = 0; nOfs < nCount; ++nOfs )
+ if ( pItemInfos[nOfs]._nSID == nSlotId )
+ return nOfs + pImpl->mnStart;
+ if ( pImpl->mpSecondary && bDeep )
+ return pImpl->mpSecondary->GetWhich(nSlotId);
+ return nSlotId;
+}
+
+
+sal_uInt16 SfxItemPool::GetSlotId( sal_uInt16 nWhich ) const
+{
+ if ( !IsWhich(nWhich) )
+ return nWhich;
+
+ if ( !IsInRange( nWhich ) )
+ {
+ if ( pImpl->mpSecondary )
+ return pImpl->mpSecondary->GetSlotId(nWhich);
+ assert(false && "unknown WhichId - cannot get slot-id");
+ return 0;
+ }
+
+ sal_uInt16 nSID = pItemInfos[nWhich - pImpl->mnStart]._nSID;
+ return nSID ? nSID : nWhich;
+}
+
+
+sal_uInt16 SfxItemPool::GetTrueWhich( sal_uInt16 nSlotId, bool bDeep ) const
+{
+ if ( !IsSlot(nSlotId) )
+ return 0;
+
+ sal_uInt16 nCount = pImpl->mnEnd - pImpl->mnStart + 1;
+ for ( sal_uInt16 nOfs = 0; nOfs < nCount; ++nOfs )
+ if ( pItemInfos[nOfs]._nSID == nSlotId )
+ return nOfs + pImpl->mnStart;
+ if ( pImpl->mpSecondary && bDeep )
+ return pImpl->mpSecondary->GetTrueWhich(nSlotId);
+ return 0;
+}
+
+
+sal_uInt16 SfxItemPool::GetTrueSlotId( sal_uInt16 nWhich ) const
+{
+ if ( !IsWhich(nWhich) )
+ return 0;
+
+ if ( !IsInRange( nWhich ) )
+ {
+ if ( pImpl->mpSecondary )
+ return pImpl->mpSecondary->GetTrueSlotId(nWhich);
+ assert(false && "unknown WhichId - cannot get slot-id");
+ return 0;
+ }
+ return pItemInfos[nWhich - pImpl->mnStart]._nSID;
+}
+
+void SfxItemPool::dumpAsXml(xmlTextWriterPtr pWriter) const
+{
+ xmlTextWriterStartElement(pWriter, BAD_CAST("SfxItemPool"));
+ for (auto const & rArray : pImpl->maPoolItemArrays)
+ for (auto const & rItem : rArray)
+ rItem->dumpAsXml(pWriter);
+ xmlTextWriterEndElement(pWriter);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svl/source/items/itemprop.cxx b/svl/source/items/itemprop.cxx
new file mode 100644
index 000000000..5f4a4aacb
--- /dev/null
+++ b/svl/source/items/itemprop.cxx
@@ -0,0 +1,343 @@
+/* -*- 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 <svl/itemprop.hxx>
+#include <svl/itempool.hxx>
+#include <svl/itemset.hxx>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#include <memory>
+#include <unordered_map>
+/*
+ * UNO III Implementation
+ */
+using namespace com::sun::star;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::uno;
+
+typedef std::unordered_map< OUString,
+ SfxItemPropertySimpleEntry > SfxItemPropertyHashMap_t;
+
+class SfxItemPropertyMap_Impl : public SfxItemPropertyHashMap_t
+{
+public:
+ mutable uno::Sequence< beans::Property > m_aPropSeq;
+
+ SfxItemPropertyMap_Impl(){}
+ explicit SfxItemPropertyMap_Impl( const SfxItemPropertyMap_Impl* pSource );
+};
+
+SfxItemPropertyMap_Impl::SfxItemPropertyMap_Impl( const SfxItemPropertyMap_Impl* pSource )
+{
+ SfxItemPropertyHashMap_t::operator=( *pSource );
+ m_aPropSeq = pSource->m_aPropSeq;
+}
+
+SfxItemPropertyMap::SfxItemPropertyMap( const SfxItemPropertyMapEntry* pEntries ) :
+ m_pImpl( new SfxItemPropertyMap_Impl )
+{
+ while( !pEntries->aName.isEmpty() )
+ {
+ (*m_pImpl) [ pEntries->aName ] = pEntries;
+ ++pEntries;
+ }
+}
+
+SfxItemPropertyMap::SfxItemPropertyMap( const SfxItemPropertyMap& rSource ) :
+ m_pImpl( new SfxItemPropertyMap_Impl( rSource.m_pImpl.get() ) )
+{
+}
+
+SfxItemPropertyMap::~SfxItemPropertyMap()
+{
+}
+
+const SfxItemPropertySimpleEntry* SfxItemPropertyMap::getByName( const OUString &rName ) const
+{
+ SfxItemPropertyHashMap_t::const_iterator aIter = m_pImpl->find(rName);
+ if( aIter == m_pImpl->end() )
+ return nullptr;
+ return &aIter->second;
+}
+
+uno::Sequence<beans::Property> const & SfxItemPropertyMap::getProperties() const
+{
+ if( !m_pImpl->m_aPropSeq.hasElements() )
+ {
+ m_pImpl->m_aPropSeq.realloc( m_pImpl->size() );
+ beans::Property* pPropArray = m_pImpl->m_aPropSeq.getArray();
+ sal_uInt32 n = 0;
+ for( const auto& rEntry : *m_pImpl )
+ //for ( const SfxItemPropertyMap *pMap = _pMap; pMap->pName; ++pMap )
+ {
+ const SfxItemPropertySimpleEntry* pEntry = &rEntry.second;
+ pPropArray[n].Name = rEntry.first;
+ pPropArray[n].Handle = pEntry->nWID;
+ pPropArray[n].Type = pEntry->aType;
+ pPropArray[n].Attributes =
+ sal::static_int_cast< sal_Int16 >(pEntry->nFlags);
+ n++;
+ }
+ }
+
+ return m_pImpl->m_aPropSeq;
+}
+
+beans::Property SfxItemPropertyMap::getPropertyByName( const OUString & rName ) const
+{
+ SfxItemPropertyHashMap_t::const_iterator aIter = m_pImpl->find(rName);
+ if( aIter == m_pImpl->end() )
+ throw UnknownPropertyException(rName);
+ const SfxItemPropertySimpleEntry* pEntry = &aIter->second;
+ beans::Property aProp;
+ aProp.Name = rName;
+ aProp.Handle = pEntry->nWID;
+ aProp.Type = pEntry->aType;
+ aProp.Attributes = sal::static_int_cast< sal_Int16 >(pEntry->nFlags);
+ return aProp;
+}
+
+bool SfxItemPropertyMap::hasPropertyByName( const OUString& rName ) const
+{
+ SfxItemPropertyHashMap_t::const_iterator aIter = m_pImpl->find(rName);
+ return aIter != m_pImpl->end();
+}
+
+void SfxItemPropertyMap::mergeProperties( const uno::Sequence< beans::Property >& rPropSeq )
+{
+ for( const beans::Property& rProp : rPropSeq )
+ {
+ SfxItemPropertySimpleEntry aTemp(
+ sal::static_int_cast< sal_Int16 >( rProp.Handle ), //nWID
+ rProp.Type, //aType
+ rProp.Attributes); //nFlags
+ (*m_pImpl)[rProp.Name] = aTemp;
+ }
+}
+
+PropertyEntryVector_t SfxItemPropertyMap::getPropertyEntries() const
+{
+ PropertyEntryVector_t aRet;
+ aRet.reserve(m_pImpl->size());
+
+ for( const auto& rEntry : *m_pImpl )
+ {
+ const SfxItemPropertySimpleEntry* pEntry = &rEntry.second;
+ aRet.emplace_back( rEntry.first, * pEntry );
+ }
+ return aRet;
+}
+
+sal_uInt32 SfxItemPropertyMap::getSize() const
+{
+ return m_pImpl->size();
+}
+
+SfxItemPropertySet::~SfxItemPropertySet()
+{
+}
+
+void SfxItemPropertySet::getPropertyValue( const SfxItemPropertySimpleEntry& rEntry,
+ const SfxItemSet& rSet, Any& rAny ) const
+{
+ // get the SfxPoolItem
+ const SfxPoolItem* pItem = nullptr;
+ SfxItemState eState = rSet.GetItemState( rEntry.nWID, true, &pItem );
+ if (SfxItemState::SET != eState && SfxItemPool::IsWhich(rEntry.nWID) )
+ pItem = &rSet.GetPool()->GetDefaultItem(rEntry.nWID);
+ // return item values as uno::Any
+ if(eState >= SfxItemState::DEFAULT && pItem)
+ {
+ pItem->QueryValue( rAny, rEntry.nMemberId );
+ }
+ else if(0 == (rEntry.nFlags & PropertyAttribute::MAYBEVOID))
+ {
+ throw RuntimeException(
+ "Property not found in ItemSet but not MAYBEVOID?", nullptr);
+ }
+
+ // convert general SfxEnumItem values to specific values
+ if( rEntry.aType.getTypeClass() == TypeClass_ENUM &&
+ rAny.getValueTypeClass() == TypeClass_LONG )
+ {
+ sal_Int32 nTmp = *o3tl::forceAccess<sal_Int32>(rAny);
+ rAny.setValue( &nTmp, rEntry.aType );
+ }
+}
+
+void SfxItemPropertySet::getPropertyValue( const OUString &rName,
+ const SfxItemSet& rSet, Any& rAny ) const
+{
+ // detect which-id
+ const SfxItemPropertySimpleEntry* pEntry = m_aMap.getByName( rName );
+ if ( !pEntry )
+ throw UnknownPropertyException(rName);
+ getPropertyValue( *pEntry,rSet, rAny );
+}
+
+Any SfxItemPropertySet::getPropertyValue( const OUString &rName,
+ const SfxItemSet& rSet ) const
+{
+ Any aVal;
+ getPropertyValue( rName,rSet, aVal );
+ return aVal;
+}
+
+void SfxItemPropertySet::setPropertyValue( const SfxItemPropertySimpleEntry& rEntry,
+ const Any& aVal,
+ SfxItemSet& rSet ) const
+{
+ // get the SfxPoolItem
+ const SfxPoolItem* pItem = nullptr;
+ std::unique_ptr<SfxPoolItem> pNewItem;
+ SfxItemState eState = rSet.GetItemState( rEntry.nWID, true, &pItem );
+ if (SfxItemState::SET != eState && SfxItemPool::IsWhich(rEntry.nWID))
+ pItem = &rSet.GetPool()->GetDefaultItem(rEntry.nWID);
+ if (pItem)
+ {
+ pNewItem.reset(pItem->Clone());
+ }
+ if(pNewItem)
+ {
+ if( !pNewItem->PutValue( aVal, rEntry.nMemberId ) )
+ {
+ throw IllegalArgumentException();
+ }
+ // apply new item
+ rSet.Put( *pNewItem );
+ }
+}
+
+void SfxItemPropertySet::setPropertyValue( const OUString &rName,
+ const Any& aVal,
+ SfxItemSet& rSet ) const
+{
+ const SfxItemPropertySimpleEntry* pEntry = m_aMap.getByName( rName );
+ if ( !pEntry )
+ {
+ throw UnknownPropertyException(rName);
+ }
+ setPropertyValue(*pEntry, aVal, rSet);
+}
+
+PropertyState SfxItemPropertySet::getPropertyState(const SfxItemPropertySimpleEntry& rEntry, const SfxItemSet& rSet) const
+ throw()
+{
+ PropertyState eRet = PropertyState_DIRECT_VALUE;
+ sal_uInt16 nWhich = rEntry.nWID;
+
+ // Get item state
+ SfxItemState eState = rSet.GetItemState( nWhich, false );
+ // Return item value as UnoAny
+ if(eState == SfxItemState::DEFAULT)
+ eRet = PropertyState_DEFAULT_VALUE;
+ else if(eState < SfxItemState::DEFAULT)
+ eRet = PropertyState_AMBIGUOUS_VALUE;
+ return eRet;
+}
+
+PropertyState SfxItemPropertySet::getPropertyState(const OUString& rName, const SfxItemSet& rSet) const
+{
+ PropertyState eRet = PropertyState_DIRECT_VALUE;
+
+ // Get WhichId
+ const SfxItemPropertySimpleEntry* pEntry = m_aMap.getByName( rName );
+ if( !pEntry || !pEntry->nWID )
+ {
+ throw UnknownPropertyException(rName);
+ }
+ sal_uInt16 nWhich = pEntry->nWID;
+
+ // Get item state
+ SfxItemState eState = rSet.GetItemState(nWhich, false);
+ // Return item value as UnoAny
+ if(eState == SfxItemState::DEFAULT)
+ eRet = PropertyState_DEFAULT_VALUE;
+ else if(eState < SfxItemState::DEFAULT)
+ eRet = PropertyState_AMBIGUOUS_VALUE;
+ return eRet;
+}
+
+Reference<XPropertySetInfo> const & SfxItemPropertySet::getPropertySetInfo() const
+{
+ if( !m_xInfo.is() )
+ m_xInfo = new SfxItemPropertySetInfo( m_aMap );
+ return m_xInfo;
+}
+
+SfxItemPropertySetInfo::SfxItemPropertySetInfo(const SfxItemPropertyMap &rMap )
+ : m_aOwnMap( rMap )
+{
+}
+
+SfxItemPropertySetInfo::SfxItemPropertySetInfo(const SfxItemPropertyMapEntry *pEntries )
+ : m_aOwnMap( pEntries )
+{
+}
+
+Sequence< Property > SAL_CALL SfxItemPropertySetInfo::getProperties( )
+{
+ return m_aOwnMap.getProperties();
+}
+
+SfxItemPropertySetInfo::~SfxItemPropertySetInfo()
+{
+}
+
+Property SAL_CALL SfxItemPropertySetInfo::getPropertyByName( const OUString& rName )
+{
+ return m_aOwnMap.getPropertyByName( rName );
+}
+
+sal_Bool SAL_CALL SfxItemPropertySetInfo::hasPropertyByName( const OUString& rName )
+{
+ return m_aOwnMap.hasPropertyByName( rName );
+}
+
+SfxExtItemPropertySetInfo::SfxExtItemPropertySetInfo( const SfxItemPropertyMapEntry *pMap,
+ const Sequence<Property>& rPropSeq )
+ : aExtMap( pMap )
+{
+ aExtMap.mergeProperties( rPropSeq );
+}
+
+SfxExtItemPropertySetInfo::~SfxExtItemPropertySetInfo()
+{
+}
+
+Sequence< Property > SAL_CALL SfxExtItemPropertySetInfo::getProperties( )
+{
+ return aExtMap.getProperties();
+}
+
+Property SAL_CALL SfxExtItemPropertySetInfo::getPropertyByName( const OUString& rPropertyName )
+{
+ return aExtMap.getPropertyByName( rPropertyName );
+}
+
+sal_Bool SAL_CALL SfxExtItemPropertySetInfo::hasPropertyByName( const OUString& rPropertyName )
+{
+ return aExtMap.hasPropertyByName( rPropertyName );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svl/source/items/itemset.cxx b/svl/source/items/itemset.cxx
new file mode 100644
index 000000000..180c76a6a
--- /dev/null
+++ b/svl/source/items/itemset.cxx
@@ -0,0 +1,1745 @@
+/* -*- 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 <string.h>
+
+#include <algorithm>
+#include <cassert>
+#include <cstddef>
+
+#include <libxml/xmlwriter.h>
+
+#include <sal/log.hxx>
+#include <svl/itemset.hxx>
+#include <svl/itempool.hxx>
+#include <svl/itemiter.hxx>
+#include <svl/whiter.hxx>
+
+static const sal_uInt16 nInitCount = 10; // Single USHORTs => 5 pairs without '0'
+
+namespace
+{
+
+/**
+ * Determines the number of sal_uInt16s in a 0-terminated array of pairs of
+ * sal_uInt16s.
+ * The terminating 0 is not included in the count.
+ */
+sal_uInt16 Count_Impl( const sal_uInt16 *pRanges )
+{
+ sal_uInt16 nCount = 0;
+ while ( *pRanges )
+ {
+ nCount += 2;
+ pRanges += 2;
+ }
+ return nCount;
+}
+
+/**
+ * Determines the total number of sal_uInt16s described in a 0-terminated
+ * array of pairs of sal_uInt16s, each representing a range of sal_uInt16s.
+ */
+sal_uInt16 Capacity_Impl( const sal_uInt16 *pRanges )
+{
+ sal_uInt16 nCount = 0;
+
+ if ( pRanges )
+ {
+ while ( *pRanges )
+ {
+ nCount += pRanges[1] - pRanges[0] + 1;
+ pRanges += 2;
+ }
+ }
+ return nCount;
+}
+
+}
+
+/**
+ * Ctor for a SfxItemSet with exactly the Which Ranges, which are known to
+ * the supplied SfxItemPool.
+ *
+ * For Sfx programmers: an SfxItemSet constructed in this way cannot
+ * contain any Items with SlotIds as Which values.
+ */
+SfxItemSet::SfxItemSet(SfxItemPool& rPool)
+ : m_pPool( &rPool )
+ , m_pParent(nullptr)
+ , m_nCount(0)
+{
+ m_pWhichRanges = const_cast<sal_uInt16*>(m_pPool->GetFrozenIdRanges());
+ assert( m_pWhichRanges && "don't create ItemSets with full range before FreezeIdRanges()" );
+ if (!m_pWhichRanges)
+ {
+ std::unique_ptr<sal_uInt16[]> tmp;
+ m_pPool->FillItemIdRanges_Impl(tmp);
+ m_pWhichRanges = tmp.release();
+ }
+
+ const sal_uInt16 nSize = TotalCount();
+ m_pItems.reset(new const SfxPoolItem*[nSize]{});
+}
+
+void SfxItemSet::InitRanges_Impl(const sal_uInt16 *pWhichPairTable)
+{
+ sal_uInt16 nCnt = 0;
+ const sal_uInt16* pPtr = pWhichPairTable;
+ while( *pPtr )
+ {
+ nCnt += ( *(pPtr+1) - *pPtr ) + 1;
+ pPtr += 2;
+ }
+
+ m_pItems.reset( new const SfxPoolItem*[nCnt]{} );
+
+ std::ptrdiff_t cnt = pPtr - pWhichPairTable +1;
+ m_pWhichRanges = new sal_uInt16[ cnt ];
+ memcpy( m_pWhichRanges, pWhichPairTable, sizeof( sal_uInt16 ) * cnt );
+}
+
+SfxItemSet::SfxItemSet(
+ SfxItemPool & pool, std::initializer_list<sal_uInt16> wids,
+ std::size_t items):
+ m_pPool(&pool), m_pParent(nullptr),
+ m_pItems(new SfxPoolItem const *[items]{}),
+ m_pWhichRanges(new sal_uInt16[wids.size() + 1]),
+ // cannot overflow, assuming std::size_t is no smaller than sal_uInt16,
+ // as wids.size() must be substantially smaller than
+ // std::numeric_limits<sal_uInt16>::max() by construction in
+ // SfxItemSet::create
+ m_nCount(0)
+{
+ assert(wids.size() != 0);
+ assert(wids.size() % 2 == 0);
+ std::copy(wids.begin(), wids.end(), m_pWhichRanges);
+ m_pWhichRanges[wids.size()] = 0;
+}
+
+SfxItemSet::SfxItemSet(
+ SfxItemPool & pool, std::initializer_list<Pair> wids):
+ m_pPool(&pool), m_pParent(nullptr),
+ m_pWhichRanges(new sal_uInt16[2 * wids.size() + 1]), //TODO: overflow
+ m_nCount(0)
+{
+ assert(wids.size() != 0);
+ std::size_t i = 0;
+ std::size_t size = 0;
+#if !defined NDEBUG
+ //TODO: sal_uInt16 prev = 0;
+#endif
+ for (auto const & p: wids) {
+ assert(svl::detail::validRange(p.wid1, p.wid2));
+ //TODO: assert(prev == 0 || svl::detail::validGap(prev, p.wid1));
+ m_pWhichRanges[i++] = p.wid1;
+ m_pWhichRanges[i++] = p.wid2;
+ size += svl::detail::rangeSize(p.wid1, p.wid2);
+ // cannot overflow, assuming std::size_t is no smaller than
+ // sal_uInt16
+#if !defined NDEBUG
+ //TODO: prev = p.wid2;
+#endif
+ }
+ m_pWhichRanges[i] = 0;
+ m_pItems.reset( new SfxPoolItem const *[size]{} );
+}
+
+SfxItemSet::SfxItemSet( SfxItemPool& rPool, const sal_uInt16* pWhichPairTable )
+ : m_pPool(&rPool)
+ , m_pParent(nullptr)
+ , m_pWhichRanges(nullptr)
+ , m_nCount(0)
+{
+ // pWhichPairTable == 0 is for the SfxAllEnumItemSet
+ if ( pWhichPairTable )
+ InitRanges_Impl(pWhichPairTable);
+}
+
+SfxItemSet::SfxItemSet( const SfxItemSet& rASet )
+ : m_pPool( rASet.m_pPool )
+ , m_pParent( rASet.m_pParent )
+ , m_nCount( rASet.m_nCount )
+{
+ // Calculate the attribute count
+ sal_uInt16 nCnt = 0;
+ sal_uInt16* pPtr = rASet.m_pWhichRanges;
+ while( *pPtr )
+ {
+ nCnt += ( *(pPtr+1) - *pPtr ) + 1;
+ pPtr += 2;
+ }
+
+ m_pItems.reset( new const SfxPoolItem* [ nCnt ] );
+
+ // Copy attributes
+ SfxPoolItem const** ppDst = m_pItems.get();
+ SfxPoolItem const** ppSrc = rASet.m_pItems.get();
+ for( sal_uInt16 n = nCnt; n; --n, ++ppDst, ++ppSrc )
+ if ( nullptr == *ppSrc || // Current Default?
+ IsInvalidItem(*ppSrc) || // DontCare?
+ IsStaticDefaultItem(*ppSrc) ) // Defaults that are not to be pooled?
+ // Just copy the pointer
+ *ppDst = *ppSrc;
+ else if (m_pPool->IsItemPoolable( **ppSrc ))
+ {
+ // Just copy the pointer and increase RefCount
+ *ppDst = *ppSrc;
+ (*ppDst)->AddRef();
+ }
+ else if ( !(*ppSrc)->Which() )
+ *ppDst = (*ppSrc)->Clone();
+ else
+ // !IsPoolable() => assign via Pool
+ *ppDst = &m_pPool->Put( **ppSrc );
+
+ // Copy the WhichRanges
+ std::ptrdiff_t cnt = pPtr - rASet.m_pWhichRanges+1;
+ m_pWhichRanges = new sal_uInt16[ cnt ];
+ memcpy( m_pWhichRanges, rASet.m_pWhichRanges, sizeof( sal_uInt16 ) * cnt);
+}
+
+SfxItemSet::SfxItemSet(SfxItemSet&& rASet) noexcept
+ : m_pPool( rASet.m_pPool )
+ , m_pParent( rASet.m_pParent )
+ , m_pItems( std::move(rASet.m_pItems) )
+ , m_pWhichRanges( rASet.m_pWhichRanges )
+ , m_nCount( rASet.m_nCount )
+{
+ rASet.m_pPool = nullptr;
+ rASet.m_pParent = nullptr;
+ rASet.m_pWhichRanges = nullptr;
+ rASet.m_nCount = 0;
+}
+
+SfxItemSet::~SfxItemSet()
+{
+ if (m_pWhichRanges) // might be nullptr if we have been moved-from
+ {
+ sal_uInt16 nCount = TotalCount();
+ if( Count() )
+ {
+ SfxPoolItem const** ppFnd = m_pItems.get();
+ for( sal_uInt16 nCnt = nCount; nCnt; --nCnt, ++ppFnd )
+ if( *ppFnd && !IsInvalidItem(*ppFnd) )
+ {
+ if( !(*ppFnd)->Which() )
+ delete *ppFnd;
+ else {
+ // Still multiple references present, so just alter the RefCount
+ if ( 1 < (*ppFnd)->GetRefCount() && !IsDefaultItem(*ppFnd) )
+ (*ppFnd)->ReleaseRef();
+ else
+ if ( !IsDefaultItem(*ppFnd) )
+ // Delete from Pool
+ m_pPool->Remove( **ppFnd );
+ }
+ }
+ }
+ }
+
+ m_pItems.reset();
+ if (m_pPool && m_pWhichRanges != m_pPool->GetFrozenIdRanges())
+ delete[] m_pWhichRanges;
+ m_pWhichRanges = nullptr; // for invariant-testing
+}
+
+/**
+ * Delete single Items or all Items (nWhich == 0)
+ */
+sal_uInt16 SfxItemSet::ClearItem( sal_uInt16 nWhich )
+{
+ if( !Count() )
+ return 0;
+
+ sal_uInt16 nDel = 0;
+ SfxPoolItem const** ppFnd = m_pItems.get();
+
+ if( nWhich )
+ {
+ const sal_uInt16* pPtr = m_pWhichRanges;
+ while( *pPtr )
+ {
+ // Within this range?
+ if( *pPtr <= nWhich && nWhich <= *(pPtr+1) )
+ {
+ // Actually set?
+ ppFnd += nWhich - *pPtr;
+ if( *ppFnd )
+ {
+ // Due to the assertions in the sub calls, we need to do the following
+ --m_nCount;
+ const SfxPoolItem *pItemToClear = *ppFnd;
+ *ppFnd = nullptr;
+
+ if ( !IsInvalidItem(pItemToClear) )
+ {
+ if (SfxItemPool::IsWhich(nWhich))
+ {
+ const SfxPoolItem& rNew = m_pParent
+ ? m_pParent->Get( nWhich )
+ : m_pPool->GetDefaultItem( nWhich );
+
+ Changed( *pItemToClear, rNew );
+ }
+ if ( pItemToClear->Which() )
+ m_pPool->Remove( *pItemToClear );
+ }
+ ++nDel;
+ }
+
+ // found => break
+ break;
+ }
+ ppFnd += *(pPtr+1) - *pPtr + 1;
+ pPtr += 2;
+ }
+ }
+ else
+ {
+ nDel = m_nCount;
+
+ sal_uInt16* pPtr = m_pWhichRanges;
+ while( *pPtr )
+ {
+ for( nWhich = *pPtr; nWhich <= *(pPtr+1); ++nWhich, ++ppFnd )
+ if( *ppFnd )
+ {
+ // Due to the assertions in the sub calls, we need to do this
+ --m_nCount;
+ const SfxPoolItem *pItemToClear = *ppFnd;
+ *ppFnd = nullptr;
+
+ if ( !IsInvalidItem(pItemToClear) )
+ {
+ if (SfxItemPool::IsWhich(nWhich))
+ {
+ const SfxPoolItem& rNew = m_pParent
+ ? m_pParent->Get( nWhich )
+ : m_pPool->GetDefaultItem( nWhich );
+
+ Changed( *pItemToClear, rNew );
+ }
+
+ // #i32448#
+ // Take care of disabled items, too.
+ if (!pItemToClear->m_nWhich)
+ {
+ // item is disabled, delete it
+ delete pItemToClear;
+ }
+ else
+ {
+ // remove item from pool
+ m_pPool->Remove( *pItemToClear );
+ }
+ }
+ }
+ pPtr += 2;
+ }
+ }
+ return nDel;
+}
+
+void SfxItemSet::ClearInvalidItems()
+{
+ sal_uInt16* pPtr = m_pWhichRanges;
+ SfxPoolItem const** ppFnd = m_pItems.get();
+ while( *pPtr )
+ {
+ for( sal_uInt16 nWhich = *pPtr; nWhich <= *(pPtr+1); ++nWhich, ++ppFnd )
+ if( IsInvalidItem(*ppFnd) )
+ {
+ *ppFnd = nullptr;
+ --m_nCount;
+ }
+ pPtr += 2;
+ }
+}
+
+void SfxItemSet::InvalidateAllItems()
+{
+ assert( !m_nCount && "There are still Items set" );
+ m_nCount = TotalCount();
+ memset(static_cast<void*>(m_pItems.get()), -1, m_nCount * sizeof(SfxPoolItem*));
+}
+
+SfxItemState SfxItemSet::GetItemState( sal_uInt16 nWhich,
+ bool bSrchInParent,
+ const SfxPoolItem **ppItem ) const
+{
+ // Find the range in which the Which is located
+ const SfxItemSet* pCurrentSet = this;
+ SfxItemState eRet = SfxItemState::UNKNOWN;
+ do
+ {
+ SfxPoolItem const** ppFnd = pCurrentSet->m_pItems.get();
+ const sal_uInt16* pPtr = pCurrentSet->m_pWhichRanges;
+ if (pPtr)
+ {
+ while ( *pPtr )
+ {
+ if ( *pPtr <= nWhich && nWhich <= *(pPtr+1) )
+ {
+ // Within this range
+ ppFnd += nWhich - *pPtr;
+ if ( !*ppFnd )
+ {
+ eRet = SfxItemState::DEFAULT;
+ if( !bSrchInParent )
+ return eRet; // Not present
+ break; // Keep searching in the parents!
+ }
+
+ if ( IsInvalidItem(*ppFnd) )
+ // Different ones are present
+ return SfxItemState::DONTCARE;
+
+ if ( (*ppFnd)->IsVoidItem() )
+ return SfxItemState::DISABLED;
+
+ if (ppItem)
+ {
+ *ppItem = *ppFnd;
+ }
+ return SfxItemState::SET;
+ }
+ ppFnd += *(pPtr+1) - *pPtr + 1;
+ pPtr += 2;
+ }
+ }
+ if (!bSrchInParent)
+ break;
+ pCurrentSet = pCurrentSet->m_pParent;
+ } while (nullptr != pCurrentSet);
+ return eRet;
+}
+
+bool SfxItemSet::HasItem(sal_uInt16 nWhich, const SfxPoolItem** ppItem) const
+{
+ bool bRet = SfxItemState::SET == GetItemState(nWhich, true, ppItem);
+ if (!bRet && ppItem)
+ *ppItem = nullptr;
+ return bRet;
+}
+
+const SfxPoolItem* SfxItemSet::PutImpl( const SfxPoolItem& rItem, sal_uInt16 nWhich, bool bPassingOwnership )
+{
+ if ( !nWhich )
+ {
+ assert(!bPassingOwnership);
+ return nullptr; //FIXME: Only because of Outliner bug
+ }
+
+ SfxPoolItem const** ppFnd = m_pItems.get();
+ const sal_uInt16* pPtr = m_pWhichRanges;
+ while( *pPtr )
+ {
+ if( *pPtr <= nWhich && nWhich <= *(pPtr+1) )
+ {
+ // Within this range
+ ppFnd += nWhich - *pPtr;
+ if( *ppFnd ) // Already one present
+ {
+ // Same Item already present?
+ if ( *ppFnd == &rItem )
+ {
+ assert(!bPassingOwnership);
+ return nullptr;
+ }
+
+ // Will 'dontcare' or 'disabled' be overwritten with some real value?
+ if ( rItem.Which() && ( IsInvalidItem(*ppFnd) || !(*ppFnd)->Which() ) )
+ {
+ auto const old = *ppFnd;
+ *ppFnd = &m_pPool->PutImpl( rItem, nWhich, bPassingOwnership );
+ if (!IsInvalidItem(old)) {
+ assert(old->Which() == 0);
+ delete old;
+ }
+ return *ppFnd;
+ }
+
+ // Turns into disabled?
+ if( !rItem.Which() )
+ {
+ if (IsInvalidItem(*ppFnd) || (*ppFnd)->Which() != 0) {
+ *ppFnd = rItem.Clone(m_pPool);
+ }
+ if (bPassingOwnership)
+ delete &rItem;
+ return nullptr;
+ }
+ else
+ {
+ // Same value already present?
+ if ( rItem == **ppFnd )
+ {
+ if (bPassingOwnership)
+ delete &rItem;
+ return nullptr;
+ }
+
+ // Add the new one, remove the old one
+ const SfxPoolItem& rNew = m_pPool->PutImpl( rItem, nWhich, bPassingOwnership );
+ const SfxPoolItem* pOld = *ppFnd;
+ *ppFnd = &rNew;
+ if (SfxItemPool::IsWhich(nWhich))
+ Changed( *pOld, rNew );
+ m_pPool->Remove( *pOld );
+ }
+ }
+ else
+ {
+ ++m_nCount;
+ if( !rItem.Which() )
+ {
+ *ppFnd = rItem.Clone(m_pPool);
+ if (bPassingOwnership)
+ delete &rItem;
+ }
+ else
+ {
+ const SfxPoolItem& rNew = m_pPool->PutImpl( rItem, nWhich, bPassingOwnership );
+ *ppFnd = &rNew;
+ if (SfxItemPool::IsWhich(nWhich))
+ {
+ const SfxPoolItem& rOld = m_pParent
+ ? m_pParent->Get( nWhich )
+ : m_pPool->GetDefaultItem( nWhich );
+ Changed( rOld, rNew );
+ }
+ }
+ }
+ SAL_WARN_IF(!bPassingOwnership && m_pPool->IsItemPoolable(nWhich) &&
+ dynamic_cast<const SfxSetItem*>( &rItem ) == nullptr &&
+ **ppFnd != rItem,
+ "svl.items", "putted Item unequal, with ID/pos " << nWhich );
+ return *ppFnd;
+ }
+ ppFnd += *(pPtr+1) - *pPtr + 1;
+ pPtr += 2;
+ }
+ if (bPassingOwnership)
+ delete &rItem;
+ return nullptr;
+}
+
+bool SfxItemSet::Put( const SfxItemSet& rSet, bool bInvalidAsDefault )
+{
+ bool bRet = false;
+ if( rSet.Count() )
+ {
+ SfxPoolItem const** ppFnd = rSet.m_pItems.get();
+ const sal_uInt16* pPtr = rSet.m_pWhichRanges;
+ while ( *pPtr )
+ {
+ for ( sal_uInt16 nWhich = *pPtr; nWhich <= *(pPtr+1); ++nWhich, ++ppFnd )
+ if( *ppFnd )
+ {
+ if ( IsInvalidItem( *ppFnd ) )
+ {
+ if ( bInvalidAsDefault )
+ bRet |= 0 != ClearItem( nWhich );
+ // FIXME: Caused a SEGFAULT on non Windows-platforms:
+ // bRet |= 0 != Put( rSet.GetPool()->GetDefaultItem(nWhich), nWhich );
+ else
+ InvalidateItem( nWhich );
+ }
+ else
+ bRet |= nullptr != Put( **ppFnd, nWhich );
+ }
+ pPtr += 2;
+ }
+ }
+ return bRet;
+}
+
+/**
+ * This method takes the Items from the 'rSet' and adds to '*this'.
+ * Which ranges in '*this' that are non-existent in 'rSet' will not
+ * be altered. The Which range of '*this' is also not changed.
+ *
+ * Items set in 'rSet' are also set in '*this'.
+ * Default (0 pointer) and Invalid (-1 pointer) Items are processed
+ * according to their parameter 'eDontCareAs' and 'eDefaultAs':
+ *
+ * SfxItemState::SET: Hard set to the default of the Pool
+ * SfxItemState::DEFAULT: Deleted (0 pointer)
+ * SfxItemState::DONTCARE: Invalid (-1 pointer)
+ *
+ * NB: All other values for 'eDontCareAs' and 'eDefaultAs' are invalid
+ */
+void SfxItemSet::PutExtended
+(
+ const SfxItemSet& rSet, // Source of the Items to be put
+ SfxItemState eDontCareAs, // What will happen to the DontCare Items
+ SfxItemState eDefaultAs // What will happen to the Default Items
+)
+{
+ // don't "optimize" with "if( rSet.Count()" because of dont-care + defaults
+ SfxPoolItem const** ppFnd = rSet.m_pItems.get();
+ const sal_uInt16* pPtr = rSet.m_pWhichRanges;
+ while ( *pPtr )
+ {
+ for ( sal_uInt16 nWhich = *pPtr; nWhich <= *(pPtr+1); ++nWhich, ++ppFnd )
+ if( *ppFnd )
+ {
+ if ( IsInvalidItem( *ppFnd ) )
+ {
+ // Item is DontCare:
+ switch ( eDontCareAs )
+ {
+ case SfxItemState::SET:
+ Put( rSet.GetPool()->GetDefaultItem(nWhich), nWhich );
+ break;
+
+ case SfxItemState::DEFAULT:
+ ClearItem( nWhich );
+ break;
+
+ case SfxItemState::DONTCARE:
+ InvalidateItem( nWhich );
+ break;
+
+ default:
+ assert(!"invalid Argument for eDontCareAs");
+ }
+ }
+ else
+ // Item is set:
+ Put( **ppFnd, nWhich );
+ }
+ else
+ {
+ // Item is default:
+ switch ( eDefaultAs )
+ {
+ case SfxItemState::SET:
+ Put( rSet.GetPool()->GetDefaultItem(nWhich), nWhich );
+ break;
+
+ case SfxItemState::DEFAULT:
+ ClearItem( nWhich );
+ break;
+
+ case SfxItemState::DONTCARE:
+ InvalidateItem( nWhich );
+ break;
+
+ default:
+ assert(!"invalid Argument for eDefaultAs");
+ }
+ }
+ pPtr += 2;
+ }
+}
+
+/**
+ * Expands the ranges of settable items by 'nFrom' to 'nTo'. Keeps state of
+ * items which are new ranges too.
+ */
+void SfxItemSet::MergeRange( sal_uInt16 nFrom, sal_uInt16 nTo )
+{
+ // special case: exactly one sal_uInt16 which is already included?
+ if (nFrom == nTo)
+ if (SfxItemState eItemState = GetItemState(nFrom, false);
+ eItemState == SfxItemState::DEFAULT || eItemState == SfxItemState::SET)
+ return;
+
+#ifdef DBG_UTIL
+ assert(nFrom <= nTo);
+ for (const sal_uInt16 *pRange = m_pWhichRanges; *pRange; pRange += 2)
+ {
+ assert(pRange[0] <= pRange[1]);
+ // ranges must be sorted and discrete
+ assert(
+ !pRange[2] || (pRange[2] > pRange[1] && pRange[2] - pRange[1] > 1));
+ }
+#endif
+
+ // create vector of ranges (sal_uInt16 pairs of lower and upper bound)
+ const size_t nOldCount = Count_Impl(m_pWhichRanges);
+ std::vector<std::pair<sal_uInt16, sal_uInt16>> aRangesTable;
+ aRangesTable.reserve(nOldCount/2 + 1);
+ bool bAdded = false;
+ for (size_t i = 0; i < nOldCount; i += 2)
+ {
+ if (!bAdded && m_pWhichRanges[i] >= nFrom)
+ { // insert new range, keep ranges sorted
+ aRangesTable.emplace_back(std::pair<sal_uInt16, sal_uInt16>(nFrom, nTo));
+ bAdded = true;
+ }
+ // insert current range
+ aRangesTable.emplace_back(std::pair<sal_uInt16, sal_uInt16>(m_pWhichRanges[i], m_pWhichRanges[i+1]));
+ }
+ if (!bAdded)
+ aRangesTable.emplace_back(std::pair<sal_uInt16, sal_uInt16>(nFrom, nTo));
+
+ // true if ranges overlap or adjoin, false if ranges are separate
+ auto needMerge = [](std::pair<sal_uInt16, sal_uInt16> lhs, std::pair<sal_uInt16, sal_uInt16> rhs)
+ {return (lhs.first-1) <= rhs.second && (rhs.first-1) <= lhs.second;};
+
+ std::vector<std::pair<sal_uInt16, sal_uInt16> >::iterator it = aRangesTable.begin();
+ // we got at least one range
+ for (;;)
+ {
+ auto itNext = std::next(it);
+ if (itNext == aRangesTable.end())
+ break;
+ // check neighbouring ranges, find first range which overlaps or adjoins a previous range
+ if (needMerge(*it, *itNext))
+ {
+ // lower bounds are sorted, implies: it->first = min(it[0].first, it[1].first)
+ it->second = std::max(it->second, itNext->second);
+ aRangesTable.erase(itNext);
+ }
+ else
+ ++it;
+ }
+
+ // construct range array
+ const size_t nNewSize = 2 * aRangesTable.size() + 1;
+ std::vector<sal_uInt16> aRanges(nNewSize);
+ for (size_t i = 0; i < (nNewSize - 1); i +=2)
+ std::tie(aRanges[i], aRanges[i+1]) = aRangesTable[i/2];
+
+ // null terminate to be compatible with sal_uInt16* array pointers
+ aRanges.back() = 0;
+
+ SetRanges( aRanges.data() );
+}
+
+/**
+ * Modifies the ranges of settable items. Keeps state of items which
+ * are new ranges too.
+ */
+void SfxItemSet::SetRanges( const sal_uInt16 *pNewRanges )
+{
+ // Identical Ranges?
+ if (m_pWhichRanges == pNewRanges)
+ return;
+ const sal_uInt16* pOld = m_pWhichRanges;
+ const sal_uInt16* pNew = pNewRanges;
+ while ( *pOld == *pNew )
+ {
+ if ( !*pOld && !*pNew )
+ return;
+ ++pOld;
+ ++pNew;
+ }
+
+ // create new item-array (by iterating through all new ranges)
+ sal_uInt16 nSize = Capacity_Impl(pNewRanges);
+ SfxPoolItem const** aNewItems = new const SfxPoolItem* [ nSize ];
+ sal_uInt16 nNewCount = 0;
+ if (m_nCount == 0)
+ memset( aNewItems, 0, nSize * sizeof( SfxPoolItem* ) );
+ else
+ {
+ sal_uInt16 n = 0;
+ for ( const sal_uInt16 *pRange = pNewRanges; *pRange; pRange += 2 )
+ {
+ // iterate through all ids in the range
+ for ( sal_uInt16 nWID = *pRange; nWID <= pRange[1]; ++nWID, ++n )
+ {
+ // direct move of pointer (not via pool)
+ SfxItemState eState = GetItemState( nWID, false, aNewItems+n );
+ if ( SfxItemState::SET == eState )
+ {
+ // increment new item count and possibly increment ref count
+ ++nNewCount;
+ aNewItems[n]->AddRef();
+ }
+ else if ( SfxItemState::DISABLED == eState )
+ {
+ // put "disabled" item
+ ++nNewCount;
+ aNewItems[n] = new SfxVoidItem(0);
+ }
+ else if ( SfxItemState::DONTCARE == eState )
+ {
+ ++nNewCount;
+ aNewItems[n] = INVALID_POOL_ITEM;
+ }
+ else
+ {
+ // default
+ aNewItems[n] = nullptr;
+ }
+ }
+ }
+ // free old items
+ sal_uInt16 nOldTotalCount = TotalCount();
+ for ( sal_uInt16 nItem = 0; nItem < nOldTotalCount; ++nItem )
+ {
+ const SfxPoolItem *pItem = m_pItems[nItem];
+ if ( pItem && !IsInvalidItem(pItem) && pItem->Which() )
+ m_pPool->Remove(*pItem);
+ }
+ }
+
+ // replace old items-array and ranges
+ m_pItems.reset( aNewItems );
+ m_nCount = nNewCount;
+
+ if( pNewRanges == GetPool()->GetFrozenIdRanges() )
+ {
+ delete[] m_pWhichRanges;
+ m_pWhichRanges = const_cast<sal_uInt16*>(pNewRanges);
+ }
+ else
+ {
+ sal_uInt16 nCount = Count_Impl(pNewRanges) + 1;
+ if (m_pWhichRanges != m_pPool->GetFrozenIdRanges())
+ delete[] m_pWhichRanges;
+ m_pWhichRanges = new sal_uInt16[ nCount ];
+ memcpy( m_pWhichRanges, pNewRanges, sizeof( sal_uInt16 ) * nCount );
+ }
+}
+
+/**
+ * The SfxItemSet takes over exactly those SfxPoolItems that are
+ * set in rSet and are in their own Which range. All others are removed.
+ * The SfxItemPool is retained, such that SfxPoolItems that have been
+ * taken over, are moved from the rSet's SfxItemPool to the SfxItemPool
+ * of *this.
+ *
+ * SfxPoolItems in rSet, for which holds 'IsInvalidItem() == true' are
+ * taken over as invalid items.
+ *
+ * @return bool true
+ * SfxPoolItems have been taken over
+ *
+ * false
+ * No SfxPoolItems have been taken over, because
+ * e.g. the Which ranges of SfxItemSets are not intersecting
+ * or the intersection does not contain SfxPoolItems that are
+ * set in rSet
+ */
+bool SfxItemSet::Set
+(
+ const SfxItemSet& rSet, /* The SfxItemSet, whose SfxPoolItems are
+ to been taken over */
+
+ bool bDeep /* true (default)
+
+ The SfxPoolItems from the parents that may
+ be present in rSet, are also taken over into
+ this SfxPoolItemSet
+
+ false
+ The SfxPoolItems from the parents of
+ rSet are not taken into account */
+)
+{
+ bool bRet = false;
+ if (m_nCount)
+ ClearItem();
+ if ( bDeep )
+ {
+ SfxWhichIter aIter(*this);
+ sal_uInt16 nWhich = aIter.FirstWhich();
+ while ( nWhich )
+ {
+ const SfxPoolItem* pItem;
+ if( SfxItemState::SET == rSet.GetItemState( nWhich, true, &pItem ) )
+ bRet |= nullptr != Put( *pItem, pItem->Which() );
+ nWhich = aIter.NextWhich();
+ }
+ }
+ else
+ bRet = Put(rSet, false);
+
+ return bRet;
+}
+
+const SfxPoolItem* SfxItemSet::GetItem(sal_uInt16 nId, bool bSearchInParent) const
+{
+ // Convert to WhichId
+ sal_uInt16 nWhich = GetPool()->GetWhich(nId);
+
+ // Is the Item set or 'bDeep == true' available?
+ const SfxPoolItem *pItem = nullptr;
+ SfxItemState eState = GetItemState(nWhich, bSearchInParent, &pItem);
+ if (bSearchInParent && SfxItemState::DEFAULT == eState && SfxItemPool::IsWhich(nWhich))
+ {
+ pItem = &m_pPool->GetDefaultItem(nWhich);
+ }
+
+ return pItem;
+}
+
+const SfxPoolItem& SfxItemSet::Get( sal_uInt16 nWhich, bool bSrchInParent) const
+{
+ // Search the Range in which the Which is located in:
+ const SfxItemSet* pCurrentSet = this;
+ do
+ {
+ if( pCurrentSet->Count() )
+ {
+ SfxPoolItem const** ppFnd = pCurrentSet->m_pItems.get();
+ const sal_uInt16* pPtr = pCurrentSet->m_pWhichRanges;
+ while( *pPtr )
+ {
+ if( *pPtr <= nWhich && nWhich <= *(pPtr+1) )
+ {
+ // In this Range
+ ppFnd += nWhich - *pPtr;
+ if( *ppFnd )
+ {
+ if( IsInvalidItem(*ppFnd) ) {
+ //FIXME: The following code is duplicated further down
+ SAL_WARN_IF(!m_pPool, "svl.items", "no Pool, but status is ambiguous, with ID/pos " << nWhich);
+ //!((SfxAllItemSet *)this)->aDefault.SetWhich(nWhich);
+ //!return aDefault;
+ return m_pPool->GetDefaultItem( nWhich );
+ }
+#ifdef DBG_UTIL
+ const SfxPoolItem *pItem = *ppFnd;
+ if ( pItem->IsVoidItem() || !pItem->Which() )
+ SAL_INFO("svl.items", "SFX_WARNING: Getting disabled Item");
+#endif
+ return **ppFnd;
+ }
+ break; // Continue with Parent
+ }
+ ppFnd += *(pPtr+1) - *pPtr + 1;
+ pPtr += 2;
+ }
+ }
+//TODO: Search until end of Range: What are we supposed to do now? To the Parent or Default??
+// if( !*pPtr ) // Until the end of the search Range?
+// break;
+ if (!bSrchInParent)
+ break;
+ pCurrentSet = pCurrentSet->m_pParent;
+ } while (nullptr != pCurrentSet);
+
+ // Get the Default from the Pool and return
+ SAL_WARN_IF(!m_pPool, "svl.items", "no Pool, but status is ambiguous, with ID/pos " << nWhich);
+ const SfxPoolItem *pItem = &m_pPool->GetDefaultItem( nWhich );
+ return *pItem;
+}
+
+/**
+ * Notification callback
+ */
+void SfxItemSet::Changed( const SfxPoolItem&, const SfxPoolItem& )
+{
+}
+
+sal_uInt16 SfxItemSet::TotalCount() const
+{
+ sal_uInt16 nRet = 0;
+ sal_uInt16* pPtr = m_pWhichRanges;
+ while( *pPtr )
+ {
+ nRet += ( *(pPtr+1) - *pPtr ) + 1;
+ pPtr += 2;
+ }
+ return nRet;
+}
+
+/**
+ * Only retain the Items that are also present in rSet
+ * (nevermind their value).
+ */
+void SfxItemSet::Intersect( const SfxItemSet& rSet )
+{
+ assert(m_pPool && "Not implemented without Pool");
+ if( !Count() ) // None set?
+ return;
+
+ // Delete all Items not contained in rSet
+ if( !rSet.Count() )
+ {
+ ClearItem(); // Delete everything
+ return;
+ }
+
+ // Test whether the Which Ranges are different
+ sal_uInt16* pWh1 = m_pWhichRanges;
+ sal_uInt16* pWh2 = rSet.m_pWhichRanges;
+ sal_uInt16 nSize = 0;
+
+ for( sal_uInt16 n = 0; *pWh1 && *pWh2; ++pWh1, ++pWh2, ++n )
+ {
+ if( *pWh1 != *pWh2 )
+ {
+ break;
+ }
+ if( n & 1 )
+ nSize += ( *pWh1 - *(pWh1-1) ) + 1;
+ }
+ bool bEqual = *pWh1 == *pWh2; // Also check for 0
+
+ // If the Ranges are identical, we can easily process it
+ if( bEqual )
+ {
+ SfxPoolItem const** ppFnd1 = m_pItems.get();
+ SfxPoolItem const** ppFnd2 = rSet.m_pItems.get();
+
+ for( ; nSize; --nSize, ++ppFnd1, ++ppFnd2 )
+ if( *ppFnd1 && !*ppFnd2 )
+ {
+ // Delete from Pool
+ if( !IsInvalidItem( *ppFnd1 ) )
+ {
+ sal_uInt16 nWhich = (*ppFnd1)->Which();
+ if (SfxItemPool::IsWhich(nWhich))
+ {
+ const SfxPoolItem& rNew = m_pParent
+ ? m_pParent->Get( nWhich )
+ : m_pPool->GetDefaultItem( nWhich );
+
+ Changed( **ppFnd1, rNew );
+ }
+ m_pPool->Remove( **ppFnd1 );
+ }
+ *ppFnd1 = nullptr;
+ --m_nCount;
+ }
+ }
+ else
+ {
+ SfxItemIter aIter( *this );
+ const SfxPoolItem* pItem = aIter.GetCurItem();
+ do
+ {
+ sal_uInt16 nWhich = IsInvalidItem( pItem )
+ ? GetWhichByPos( aIter.GetCurPos() )
+ : pItem->Which();
+ if( SfxItemState::UNKNOWN == rSet.GetItemState( nWhich, false ) )
+ ClearItem( nWhich ); // Delete
+ pItem = aIter.NextItem();
+ } while (pItem);
+ }
+}
+
+void SfxItemSet::Differentiate( const SfxItemSet& rSet )
+{
+ if( !Count() || !rSet.Count() )// None set?
+ return;
+
+ // Test whether the Which Ranges are different
+ sal_uInt16* pWh1 = m_pWhichRanges;
+ sal_uInt16* pWh2 = rSet.m_pWhichRanges;
+ sal_uInt16 nSize = 0;
+
+ for( sal_uInt16 n = 0; *pWh1 && *pWh2; ++pWh1, ++pWh2, ++n )
+ {
+ if( *pWh1 != *pWh2 )
+ {
+ break;
+ }
+ if( n & 1 )
+ nSize += ( *pWh1 - *(pWh1-1) ) + 1;
+ }
+ bool bEqual = *pWh1 == *pWh2; // Also test for 0
+
+ // If the Ranges are identical, we can easily process it
+ if( bEqual )
+ {
+ SfxPoolItem const** ppFnd1 = m_pItems.get();
+ SfxPoolItem const** ppFnd2 = rSet.m_pItems.get();
+
+ for( ; nSize; --nSize, ++ppFnd1, ++ppFnd2 )
+ if( *ppFnd1 && *ppFnd2 )
+ {
+ // Delete from Pool
+ if( !IsInvalidItem( *ppFnd1 ) )
+ {
+ sal_uInt16 nWhich = (*ppFnd1)->Which();
+ if (SfxItemPool::IsWhich(nWhich))
+ {
+ const SfxPoolItem& rNew = m_pParent
+ ? m_pParent->Get( nWhich )
+ : m_pPool->GetDefaultItem( nWhich );
+
+ Changed( **ppFnd1, rNew );
+ }
+ m_pPool->Remove( **ppFnd1 );
+ }
+ *ppFnd1 = nullptr;
+ --m_nCount;
+ }
+ }
+ else
+ {
+ SfxItemIter aIter( *this );
+ const SfxPoolItem* pItem = aIter.GetCurItem();
+ do
+ {
+ sal_uInt16 nWhich = IsInvalidItem( pItem )
+ ? GetWhichByPos( aIter.GetCurPos() )
+ : pItem->Which();
+ if( SfxItemState::SET == rSet.GetItemState( nWhich, false ) )
+ ClearItem( nWhich ); // Delete
+ pItem = aIter.NextItem();
+ } while (pItem);
+
+ }
+}
+
+/**
+ * Decision table for MergeValue(s)
+ *
+ * Principles:
+ * 1. If the Which value in the 1st set is "unknown", there's never any action
+ * 2. If the Which value in the 2nd set is "unknown", it's made the "default"
+ * 3. For comparisons the values of the "default" Items are take into account
+ *
+ * 1st Item 2nd Item Values bIgnoreDefs Remove Assign Add
+ *
+ * set set == sal_False - - -
+ * default set == sal_False - - -
+ * dontcare set == sal_False - - -
+ * unknown set == sal_False - - -
+ * set default == sal_False - - -
+ * default default == sal_False - - -
+ * dontcare default == sal_False - - -
+ * unknown default == sal_False - - -
+ * set dontcare == sal_False 1st Item -1 -
+ * default dontcare == sal_False - -1 -
+ * dontcare dontcare == sal_False - - -
+ * unknown dontcare == sal_False - - -
+ * set unknown == sal_False 1st Item -1 -
+ * default unknown == sal_False - - -
+ * dontcare unknown == sal_False - - -
+ * unknown unknown == sal_False - - -
+ *
+ * set set != sal_False 1st Item -1 -
+ * default set != sal_False - -1 -
+ * dontcare set != sal_False - - -
+ * unknown set != sal_False - - -
+ * set default != sal_False 1st Item -1 -
+ * default default != sal_False - - -
+ * dontcare default != sal_False - - -
+ * unknown default != sal_False - - -
+ * set dontcare != sal_False 1st Item -1 -
+ * default dontcare != sal_False - -1 -
+ * dontcare dontcare != sal_False - - -
+ * unknown dontcare != sal_False - - -
+ * set unknown != sal_False 1st Item -1 -
+ * default unknown != sal_False - - -
+ * dontcare unknown != sal_False - - -
+ * unknown unknown != sal_False - - -
+ *
+ * set set == sal_True - - -
+ * default set == sal_True - 2nd Item 2nd Item
+ * dontcare set == sal_True - - -
+ * unknown set == sal_True - - -
+ * set default == sal_True - - -
+ * default default == sal_True - - -
+ * dontcare default == sal_True - - -
+ * unknown default == sal_True - - -
+ * set dontcare == sal_True - - -
+ * default dontcare == sal_True - -1 -
+ * dontcare dontcare == sal_True - - -
+ * unknown dontcare == sal_True - - -
+ * set unknown == sal_True - - -
+ * default unknown == sal_True - - -
+ * dontcare unknown == sal_True - - -
+ * unknown unknown == sal_True - - -
+ *
+ * set set != sal_True 1st Item -1 -
+ * default set != sal_True - 2nd Item 2nd Item
+ * dontcare set != sal_True - - -
+ * unknown set != sal_True - - -
+ * set default != sal_True - - -
+ * default default != sal_True - - -
+ * dontcare default != sal_True - - -
+ * unknown default != sal_True - - -
+ * set dontcare != sal_True 1st Item -1 -
+ * default dontcare != sal_True - -1 -
+ * dontcare dontcare != sal_True - - -
+ * unknown dontcare != sal_True - - -
+ * set unknown != sal_True - - -
+ * default unknown != sal_True - - -
+ * dontcare unknown != sal_True - - -
+ * unknown unknown != sal_True - - -
+ */
+static void MergeItem_Impl( SfxItemPool *_pPool, sal_uInt16 &rCount,
+ const SfxPoolItem **ppFnd1, const SfxPoolItem *pFnd2,
+ bool bIgnoreDefaults )
+{
+ assert(ppFnd1 != nullptr && "Merging to 0-Item");
+
+ // 1st Item is Default?
+ if ( !*ppFnd1 )
+ {
+ if ( IsInvalidItem(pFnd2) )
+ // Decision table: default, dontcare, doesn't matter, doesn't matter
+ *ppFnd1 = INVALID_POOL_ITEM;
+
+ else if ( pFnd2 && !bIgnoreDefaults &&
+ _pPool->GetDefaultItem(pFnd2->Which()) != *pFnd2 )
+ // Decision table: default, set, !=, sal_False
+ *ppFnd1 = INVALID_POOL_ITEM;
+
+ else if ( pFnd2 && bIgnoreDefaults )
+ // Decision table: default, set, doesn't matter, sal_True
+ *ppFnd1 = &_pPool->Put( *pFnd2 );
+
+ if ( *ppFnd1 )
+ ++rCount;
+ }
+
+ // 1st Item set?
+ else if ( !IsInvalidItem(*ppFnd1) )
+ {
+ if ( !pFnd2 )
+ {
+ // 2nd Item is Default
+ if ( !bIgnoreDefaults &&
+ **ppFnd1 != _pPool->GetDefaultItem((*ppFnd1)->Which()) )
+ {
+ // Decision table: set, default, !=, sal_False
+ _pPool->Remove( **ppFnd1 );
+ *ppFnd1 = INVALID_POOL_ITEM;
+ }
+ }
+ else if ( IsInvalidItem(pFnd2) )
+ {
+ // 2nd Item is dontcare
+ if ( !bIgnoreDefaults ||
+ **ppFnd1 != _pPool->GetDefaultItem( (*ppFnd1)->Which()) )
+ {
+ // Decision table: set, dontcare, doesn't matter, sal_False
+ // or: set, dontcare, !=, sal_True
+ _pPool->Remove( **ppFnd1 );
+ *ppFnd1 = INVALID_POOL_ITEM;
+ }
+ }
+ else
+ {
+ // 2nd Item is set
+ if ( **ppFnd1 != *pFnd2 )
+ {
+ // Decision table: set, set, !=, doesn't matter
+ _pPool->Remove( **ppFnd1 );
+ *ppFnd1 = INVALID_POOL_ITEM;
+ }
+ }
+ }
+}
+
+void SfxItemSet::MergeValues( const SfxItemSet& rSet )
+{
+ // WARNING! When making changes/fixing bugs, always update the table above!!
+ assert( GetPool() == rSet.GetPool() && "MergeValues with different Pools" );
+
+ // Test if the which Ranges are different
+ sal_uInt16* pWh1 = m_pWhichRanges;
+ sal_uInt16* pWh2 = rSet.m_pWhichRanges;
+ sal_uInt16 nSize = 0;
+
+ for( sal_uInt16 n = 0; *pWh1 && *pWh2; ++pWh1, ++pWh2, ++n )
+ {
+ if( *pWh1 != *pWh2 )
+ {
+ break;
+ }
+ if( n & 1 )
+ nSize += ( *pWh1 - *(pWh1-1) ) + 1;
+ }
+ bool bEqual = *pWh1 == *pWh2; // Also check for 0
+
+ // If the Ranges match, they are easier to process!
+ if( bEqual )
+ {
+ SfxPoolItem const** ppFnd1 = m_pItems.get();
+ SfxPoolItem const** ppFnd2 = rSet.m_pItems.get();
+
+ for( ; nSize; --nSize, ++ppFnd1, ++ppFnd2 )
+ MergeItem_Impl(m_pPool, m_nCount, ppFnd1, *ppFnd2, false/*bIgnoreDefaults*/);
+ }
+ else
+ {
+ SfxWhichIter aIter( rSet );
+ sal_uInt16 nWhich;
+ while( 0 != ( nWhich = aIter.NextWhich() ) )
+ {
+ const SfxPoolItem* pItem = nullptr;
+ (void)rSet.GetItemState( nWhich, true, &pItem );
+ if( !pItem )
+ {
+ // Not set, so default
+ MergeValue( rSet.GetPool()->GetDefaultItem( nWhich ) );
+ }
+ else if( IsInvalidItem( pItem ) )
+ // don't care
+ InvalidateItem( nWhich );
+ else
+ MergeValue( *pItem );
+ }
+ }
+}
+
+void SfxItemSet::MergeValue( const SfxPoolItem& rAttr, bool bIgnoreDefaults )
+{
+ SfxPoolItem const** ppFnd = m_pItems.get();
+ const sal_uInt16* pPtr = m_pWhichRanges;
+ const sal_uInt16 nWhich = rAttr.Which();
+ while( *pPtr )
+ {
+ // In this Range??
+ if( *pPtr <= nWhich && nWhich <= *(pPtr+1) )
+ {
+ ppFnd += nWhich - *pPtr;
+ MergeItem_Impl(m_pPool, m_nCount, ppFnd, &rAttr, bIgnoreDefaults);
+ break;
+ }
+ ppFnd += *(pPtr+1) - *pPtr + 1;
+ pPtr += 2;
+ }
+}
+
+void SfxItemSet::InvalidateItem( sal_uInt16 nWhich )
+{
+ SfxPoolItem const** ppFnd = m_pItems.get();
+ const sal_uInt16* pPtr = m_pWhichRanges;
+ while( *pPtr )
+ {
+ if( *pPtr <= nWhich && nWhich <= *(pPtr+1) )
+ {
+ // In this Range?
+ ppFnd += nWhich - *pPtr;
+
+ if( *ppFnd ) // Set for me
+ {
+ if( !IsInvalidItem(*ppFnd) )
+ {
+ m_pPool->Remove( **ppFnd );
+ *ppFnd = INVALID_POOL_ITEM;
+ }
+ }
+ else
+ {
+ *ppFnd = INVALID_POOL_ITEM;
+ ++m_nCount;
+ }
+ break;
+ }
+ ppFnd += *(pPtr+1) - *pPtr + 1;
+ pPtr += 2;
+ }
+}
+
+sal_uInt16 SfxItemSet::GetWhichByPos( sal_uInt16 nPos ) const
+{
+ sal_uInt16 n = 0;
+ sal_uInt16* pPtr = m_pWhichRanges;
+ while( *pPtr )
+ {
+ n = ( *(pPtr+1) - *pPtr ) + 1;
+ if( nPos < n )
+ return *pPtr + nPos;
+ nPos = nPos - n;
+ pPtr += 2;
+ }
+ assert(false);
+ return 0;
+}
+
+bool SfxItemSet::operator==(const SfxItemSet &rCmp) const
+{
+ return Equals( rCmp, true);
+}
+
+bool SfxItemSet::Equals(const SfxItemSet &rCmp, bool bComparePool) const
+{
+ // Values we can get quickly need to be the same
+ const bool bDifferentPools = (m_pPool != rCmp.m_pPool);
+ if ( (bComparePool && m_pParent != rCmp.m_pParent) ||
+ (bComparePool && bDifferentPools) ||
+ Count() != rCmp.Count() )
+ return false;
+
+ // If we reach here and bDifferentPools==true that means bComparePool==false.
+
+ // Counting Ranges takes longer; they also need to be the same, however
+ sal_uInt16 nCount1 = TotalCount();
+ sal_uInt16 nCount2 = rCmp.TotalCount();
+ if ( nCount1 != nCount2 )
+ return false;
+
+ // Are the Ranges themselves unequal?
+ for (sal_uInt16 nRange = 0; m_pWhichRanges[nRange]; nRange += 2)
+ {
+ if (m_pWhichRanges[nRange] != rCmp.m_pWhichRanges[nRange] ||
+ m_pWhichRanges[nRange+1] != rCmp.m_pWhichRanges[nRange+1])
+ {
+ // We must use the slow method then
+ SfxWhichIter aIter( *this );
+ for ( sal_uInt16 nWh = aIter.FirstWhich();
+ nWh;
+ nWh = aIter.NextWhich() )
+ {
+ // If the pointer of the poolable Items are unequal, the Items must match
+ const SfxPoolItem *pItem1 = nullptr, *pItem2 = nullptr;
+ if ( GetItemState( nWh, false, &pItem1 ) !=
+ rCmp.GetItemState( nWh, false, &pItem2 ) ||
+ ( pItem1 != pItem2 &&
+ ( !pItem1 || IsInvalidItem(pItem1) ||
+ (m_pPool->IsItemPoolable(*pItem1) &&
+ *pItem1 != *pItem2 ) ) ) )
+ return false;
+ }
+
+ return true;
+ }
+ }
+
+ // Are all pointers the same?
+ if (0 == memcmp( m_pItems.get(), rCmp.m_pItems.get(), nCount1 * sizeof(m_pItems[0]) ))
+ return true;
+
+ // We need to compare each one separately then
+ const SfxPoolItem **ppItem1 = m_pItems.get();
+ const SfxPoolItem **ppItem2 = rCmp.m_pItems.get();
+ for ( sal_uInt16 nPos = 0; nPos < nCount1; ++nPos )
+ {
+ // If the pointers of the poolable Items are not the same, the Items
+ // must match
+ if ( *ppItem1 != *ppItem2 &&
+ ( ( !*ppItem1 || !*ppItem2 ) ||
+ ( IsInvalidItem(*ppItem1) || IsInvalidItem(*ppItem2) ) ||
+ (!bDifferentPools && m_pPool->IsItemPoolable(**ppItem1)) ||
+ **ppItem1 != **ppItem2 ) )
+ return false;
+
+ ++ppItem1;
+ ++ppItem2;
+ }
+
+ return true;
+}
+
+std::unique_ptr<SfxItemSet> SfxItemSet::Clone(bool bItems, SfxItemPool *pToPool ) const
+{
+ if (pToPool && pToPool != m_pPool)
+ {
+ std::unique_ptr<SfxItemSet> pNewSet(new SfxItemSet(*pToPool, m_pWhichRanges));
+ if ( bItems )
+ {
+ SfxWhichIter aIter(*pNewSet);
+ sal_uInt16 nWhich = aIter.FirstWhich();
+ while ( nWhich )
+ {
+ const SfxPoolItem* pItem;
+ if ( SfxItemState::SET == GetItemState( nWhich, false, &pItem ) )
+ pNewSet->Put( *pItem, pItem->Which() );
+ nWhich = aIter.NextWhich();
+ }
+ }
+ return pNewSet;
+ }
+ else
+ return std::unique_ptr<SfxItemSet>(bItems
+ ? new SfxItemSet(*this)
+ : new SfxItemSet(*m_pPool, m_pWhichRanges));
+}
+
+void SfxItemSet::PutDirect(const SfxPoolItem &rItem)
+{
+ SfxPoolItem const** ppFnd = m_pItems.get();
+ const sal_uInt16* pPtr = m_pWhichRanges;
+ const sal_uInt16 nWhich = rItem.Which();
+#ifdef DBG_UTIL
+ IsPoolDefaultItem(&rItem) || m_pPool->CheckItemInPool(&rItem);
+ // Only cause assertion in the callees
+#endif
+ while( *pPtr )
+ {
+ if( *pPtr <= nWhich && nWhich <= *(pPtr+1) )
+ {
+ // In this Range?
+ ppFnd += nWhich - *pPtr;
+ const SfxPoolItem* pOld = *ppFnd;
+ if( pOld ) // One already present
+ {
+ if( rItem == **ppFnd )
+ return; // Already present!
+ m_pPool->Remove( *pOld );
+ }
+ else
+ ++m_nCount;
+
+ // Add the new one
+ if( IsPoolDefaultItem(&rItem) )
+ *ppFnd = &m_pPool->Put( rItem );
+ else
+ {
+ *ppFnd = &rItem;
+ if( !IsStaticDefaultItem( &rItem ) )
+ rItem.AddRef();
+ }
+
+ return;
+ }
+ ppFnd += *(pPtr+1) - *pPtr + 1;
+ pPtr += 2;
+ }
+}
+
+void SfxItemSet::dumpAsXml(xmlTextWriterPtr pWriter) const
+{
+ xmlTextWriterStartElement(pWriter, BAD_CAST("SfxItemSet"));
+ SfxItemIter aIter(*this);
+ for (const SfxPoolItem* pItem = aIter.GetCurItem(); pItem; pItem = aIter.NextItem())
+ pItem->dumpAsXml(pWriter);
+ xmlTextWriterEndElement(pWriter);
+}
+
+
+// ----------------------------------------------- class SfxAllItemSet
+
+SfxAllItemSet::SfxAllItemSet( SfxItemPool &rPool )
+: SfxItemSet(rPool, nullptr),
+ nFree(nInitCount)
+{
+ // Initially no Items
+ m_pItems = nullptr;
+
+ // Allocate nInitCount pairs at USHORTs for Ranges
+ m_pWhichRanges = new sal_uInt16[nInitCount + 1]{};
+}
+
+SfxAllItemSet::SfxAllItemSet(const SfxItemSet &rCopy)
+: SfxItemSet(rCopy),
+ nFree(0)
+{
+}
+
+/**
+ * Explicitly define this ctor to avoid auto-generation by the compiler.
+ * The compiler does not take the ctor with the 'const SfxItemSet&'!
+ */
+SfxAllItemSet::SfxAllItemSet(const SfxAllItemSet &rCopy)
+: SfxItemSet(rCopy),
+ nFree(0)
+{
+}
+
+/**
+ * This internal function creates a new WhichRanges array, which is copied
+ * from the 'nOldSize'-USHORTs long 'pUS'. It has new USHORTs at the end instead
+ * of 'nIncr'.
+ * The terminating sal_uInt16 with the '0' is neither accounted for in 'nOldSize'
+ * nor in 'nIncr', but always explicitly added.
+ *
+ * @returns the new WhichRanges array (the old 'pUS' is freed)
+ */
+static sal_uInt16 *AddRanges_Impl(
+ sal_uInt16 *pUS, std::ptrdiff_t nOldSize, sal_uInt16 nIncr)
+{
+ // Create new WhichRanges array
+ sal_uInt16 *pNew = new sal_uInt16[ nOldSize + nIncr + 1 ];
+
+ // Take over the old Ranges
+ memcpy( pNew, pUS, nOldSize * sizeof(sal_uInt16) );
+
+ // Initialize the new one to 0
+ memset( pNew + nOldSize, 0, ( nIncr + 1 ) * sizeof(sal_uInt16) );
+
+ // Free the old array
+ delete[] pUS;
+
+ return pNew;
+}
+
+/**
+ * This internal function creates a new ItemArray, which is copied from 'pItems',
+ * but has room for a new ItemPointer at 'nPos'.
+ *
+ * @returns the new ItemArray (the old 'pItems' is freed)
+ */
+static void AddItem_Impl(std::unique_ptr<SfxPoolItem const*[]> & rpItems, sal_uInt16 nOldSize, sal_uInt16 nPos)
+{
+ // Create new ItemArray
+ SfxPoolItem const** pNew = new const SfxPoolItem*[nOldSize+1];
+
+ // Was there one before?
+ if ( rpItems )
+ {
+ // Copy all Items before nPos
+ if ( nPos )
+ memcpy( static_cast<void*>(pNew), rpItems.get(), nPos * sizeof(SfxPoolItem *) );
+
+ // Copy all Items after nPos
+ if ( nPos < nOldSize )
+ memcpy( static_cast<void*>(pNew + nPos + 1), rpItems.get() + nPos,
+ (nOldSize-nPos) * sizeof(SfxPoolItem *) );
+ }
+
+ // Initialize new Item
+ *(pNew + nPos) = nullptr;
+
+ rpItems.reset(pNew);
+}
+
+/**
+ * Putting with automatic extension of the WhichId with the ID of the Item.
+ */
+const SfxPoolItem* SfxAllItemSet::PutImpl( const SfxPoolItem& rItem, sal_uInt16 nWhich, bool bPassingOwnership )
+{
+ sal_uInt16 nPos = 0; // Position for 'rItem' in 'm_pItems'
+ const sal_uInt16 nItemCount = TotalCount();
+
+ // Let's see first whether there's a suitable Range already
+ sal_uInt16 *pPtr = m_pWhichRanges;
+ while ( *pPtr )
+ {
+ // WhichId is within this Range?
+ if( *pPtr <= nWhich && nWhich <= *(pPtr+1) )
+ {
+ // Insert
+ nPos += nWhich - *pPtr;
+ break;
+ }
+
+ // Carry over the position of the Item in m_pItems
+ nPos += *(pPtr+1) - *pPtr + 1;
+
+ // To the next Range
+ pPtr += 2;
+ }
+
+ // WhichId not yet present?
+ if ( !*pPtr )
+ {
+ // Let's see if we can attach it somewhere
+ pPtr = m_pWhichRanges;
+ nPos = 0;
+ while ( *pPtr )
+ {
+ // WhichId is right before this Range?
+ if ( (nWhich+1) == *pPtr )
+ {
+ // Range grows downwards
+ (*pPtr)--;
+
+ // Make room before first Item of this Range
+ AddItem_Impl(m_pItems, nItemCount, nPos);
+ break;
+ }
+
+ // WhichId is right after this Range?
+ else if ( (nWhich-1) == *(pPtr+1) )
+ {
+ // Range grows upwards?
+ (*(pPtr+1))++;
+
+ // Make room after last Item of this Range
+ nPos += nWhich - *pPtr;
+ AddItem_Impl(m_pItems, nItemCount, nPos);
+ break;
+ }
+
+ // Carry over position of the Item in m_pItems
+ nPos += *(pPtr+1) - *pPtr + 1;
+
+ // To the next Range
+ pPtr += 2;
+ }
+ }
+
+ // No extensible Range found?
+ if ( !*pPtr )
+ {
+ // No room left in m_pWhichRanges? => Expand!
+ std::ptrdiff_t nSize = pPtr - m_pWhichRanges;
+ if( !nFree )
+ {
+ m_pWhichRanges = AddRanges_Impl(m_pWhichRanges, nSize, nInitCount);
+ nFree += nInitCount;
+ }
+
+ // Attach new WhichRange
+ pPtr = m_pWhichRanges + nSize;
+ *pPtr++ = nWhich;
+ *pPtr = nWhich;
+ nFree -= 2;
+
+ // Expand ItemArray
+ nPos = nItemCount;
+ AddItem_Impl(m_pItems, nItemCount, nPos);
+ }
+
+ // Add new Item to Pool
+ const SfxPoolItem& rNew = m_pPool->PutImpl( rItem, nWhich, bPassingOwnership );
+
+ // Remember old Item
+ bool bIncrementCount = false;
+ const SfxPoolItem* pOld = m_pItems[nPos];
+ if ( IsInvalidItem(pOld) ) // state "dontcare"
+ pOld = nullptr;
+ if ( !pOld )
+ {
+ bIncrementCount = true;
+ pOld = m_pParent
+ ? &m_pParent->Get( nWhich )
+ : (SfxItemPool::IsWhich(nWhich)
+ ? &m_pPool->GetDefaultItem(nWhich)
+ : nullptr);
+ }
+
+ // Add new Item to ItemSet
+ m_pItems[nPos] = &rNew;
+
+ // Send Changed Notification
+ if ( pOld )
+ {
+ Changed( *pOld, rNew );
+ if ( !IsDefaultItem(pOld) )
+ m_pPool->Remove( *pOld );
+ }
+
+ if ( bIncrementCount )
+ ++m_nCount;
+
+ return &rNew;
+}
+
+/**
+ * Disable Item
+ * Using a VoidItem with Which value 0
+ */
+void SfxItemSet::DisableItem(sal_uInt16 nWhich)
+{
+ Put( SfxVoidItem(0), nWhich );
+}
+
+std::unique_ptr<SfxItemSet> SfxAllItemSet::Clone(bool bItems, SfxItemPool *pToPool ) const
+{
+ if (pToPool && pToPool != m_pPool)
+ {
+ std::unique_ptr<SfxAllItemSet> pNewSet(new SfxAllItemSet( *pToPool ));
+ if ( bItems )
+ pNewSet->Set( *this );
+ return std::unique_ptr<SfxItemSet>(pNewSet.release()); // clang3.8 does not seem to be able to upcast std::unique_ptr
+ }
+ else
+ return std::unique_ptr<SfxItemSet>(bItems ? new SfxAllItemSet(*this) : new SfxAllItemSet(*m_pPool));
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svl/source/items/lckbitem.cxx b/svl/source/items/lckbitem.cxx
new file mode 100644
index 000000000..87165ae50
--- /dev/null
+++ b/svl/source/items/lckbitem.cxx
@@ -0,0 +1,102 @@
+/* -*- 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 <svl/lckbitem.hxx>
+#include <tools/stream.hxx>
+#include <osl/diagnose.h>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+
+
+SfxPoolItem* SfxLockBytesItem::CreateDefault() { return new SfxLockBytesItem; }
+
+
+SfxLockBytesItem::SfxLockBytesItem()
+{
+}
+
+
+SfxLockBytesItem::~SfxLockBytesItem()
+{
+}
+
+
+bool SfxLockBytesItem::operator==( const SfxPoolItem& rItem ) const
+{
+ return SfxPoolItem::operator==(rItem) && static_cast<const SfxLockBytesItem&>(rItem)._xVal == _xVal;
+}
+
+SfxLockBytesItem* SfxLockBytesItem::Clone(SfxItemPool *) const
+{
+ return new SfxLockBytesItem( *this );
+}
+
+// virtual
+bool SfxLockBytesItem::PutValue( const css::uno::Any& rVal, sal_uInt8 )
+{
+ css::uno::Sequence< sal_Int8 > aSeq;
+ if ( rVal >>= aSeq )
+ {
+ if ( aSeq.hasElements() )
+ {
+ SvMemoryStream* pStream = new SvMemoryStream();
+ pStream->WriteBytes( aSeq.getConstArray(), aSeq.getLength() );
+ pStream->Seek(0);
+
+ _xVal = new SvLockBytes( pStream, true );
+ }
+ else
+ _xVal = nullptr;
+
+ return true;
+ }
+
+ OSL_FAIL( "SfxLockBytesItem::PutValue - Wrong type!" );
+ return true;
+}
+
+// virtual
+bool SfxLockBytesItem::QueryValue( css::uno::Any& rVal, sal_uInt8 ) const
+{
+ if ( _xVal.is() )
+ {
+ sal_uInt32 nLen;
+ SvLockBytesStat aStat;
+
+ if ( _xVal->Stat( &aStat ) == ERRCODE_NONE )
+ nLen = aStat.nSize;
+ else
+ return false;
+
+ std::size_t nRead = 0;
+ css::uno::Sequence< sal_Int8 > aSeq( nLen );
+
+ _xVal->ReadAt( 0, aSeq.getArray(), nLen, &nRead );
+ rVal <<= aSeq;
+ }
+ else
+ {
+ css::uno::Sequence< sal_Int8 > aSeq( 0 );
+ rVal <<= aSeq;
+ }
+
+ return true;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svl/source/items/legacyitem.cxx b/svl/source/items/legacyitem.cxx
new file mode 100644
index 000000000..b0daa3b90
--- /dev/null
+++ b/svl/source/items/legacyitem.cxx
@@ -0,0 +1,69 @@
+/* -*- 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 <svl/legacyitem.hxx>
+#include <tools/stream.hxx>
+#include <svl/eitem.hxx>
+#include <svl/cintitem.hxx>
+
+namespace legacy
+{
+ namespace SfxBool
+ {
+ sal_uInt16 GetVersion(sal_uInt16)
+ {
+ return 0;
+ }
+
+ void Create(SfxBoolItem& rItem, SvStream& rStrm, sal_uInt16)
+ {
+ bool tmp(false);
+ rStrm.ReadCharAsBool(tmp);
+ rItem.SetValue(tmp);
+ }
+
+ SvStream& Store(const SfxBoolItem& rItem, SvStream& rStrm, sal_uInt16)
+ {
+ rStrm.WriteBool(rItem.GetValue()); // not bool for serialization!
+ return rStrm;
+ }
+ }
+ namespace CntInt32
+ {
+ sal_uInt16 GetVersion(sal_uInt16)
+ {
+ return 0;
+ }
+
+ void Create(CntInt32Item& rItem, SvStream& rStrm, sal_uInt16)
+ {
+ sal_Int32 tmp(0);
+ rStrm.ReadInt32(tmp);
+ rItem.SetValue(tmp);
+ }
+
+ SvStream& Store(const CntInt32Item& rItem, SvStream& rStrm, sal_uInt16)
+ {
+ rStrm.WriteInt32(rItem.GetValue());
+ return rStrm;
+ }
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svl/source/items/macitem.cxx b/svl/source/items/macitem.cxx
new file mode 100644
index 000000000..b0750212e
--- /dev/null
+++ b/svl/source/items/macitem.cxx
@@ -0,0 +1,238 @@
+/* -*- 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/safeint.hxx>
+#include <sal/log.hxx>
+#include <comphelper/fileformat.h>
+#include <tools/stream.hxx>
+
+#include <svl/macitem.hxx>
+#include <stringio.hxx>
+#include <algorithm>
+
+SvxMacro::SvxMacro( const OUString &rMacName, const OUString &rLanguage)
+ : aMacName( rMacName ), aLibName( rLanguage),
+ eType( EXTENDED_STYPE)
+{
+ if ( rLanguage == SVX_MACRO_LANGUAGE_STARBASIC )
+ eType=STARBASIC;
+ else if ( rLanguage == SVX_MACRO_LANGUAGE_JAVASCRIPT )
+ eType=JAVASCRIPT;
+}
+
+OUString SvxMacro::GetLanguage()const
+{
+ if(eType==STARBASIC)
+ {
+ return SVX_MACRO_LANGUAGE_STARBASIC;
+ }
+ else if(eType==JAVASCRIPT)
+ {
+ return SVX_MACRO_LANGUAGE_JAVASCRIPT;
+ }
+ else if(eType==EXTENDED_STYPE)
+ {
+ return SVX_MACRO_LANGUAGE_SF;
+
+ }
+ return aLibName;
+}
+
+SvxMacroTableDtor& SvxMacroTableDtor::operator=( const SvxMacroTableDtor& rTbl )
+{
+ if (this != &rTbl)
+ {
+ aSvxMacroTable.clear();
+ aSvxMacroTable.insert(rTbl.aSvxMacroTable.begin(), rTbl.aSvxMacroTable.end());
+ }
+ return *this;
+}
+
+bool SvxMacroTableDtor::operator==( const SvxMacroTableDtor& rOther ) const
+{
+ // Count different => odd in any case
+ // Compare single ones; the sequence matters due to performance reasons
+ return std::equal(aSvxMacroTable.begin(), aSvxMacroTable.end(),
+ rOther.aSvxMacroTable.begin(), rOther.aSvxMacroTable.end(),
+ [](const SvxMacroTable::value_type& rOwnEntry, const SvxMacroTable::value_type& rOtherEntry) {
+ const SvxMacro& rOwnMac = rOwnEntry.second;
+ const SvxMacro& rOtherMac = rOtherEntry.second;
+ return rOwnEntry.first == rOtherEntry.first
+ && rOwnMac.GetLibName() == rOtherMac.GetLibName()
+ && rOwnMac.GetMacName() == rOtherMac.GetMacName();
+ });
+}
+
+void SvxMacroTableDtor::Read( SvStream& rStrm )
+{
+ sal_uInt16 nVersion;
+ rStrm.ReadUInt16( nVersion );
+
+ short nReadMacro(0);
+ rStrm.ReadInt16(nReadMacro);
+ if (nReadMacro < 0)
+ {
+ SAL_WARN("editeng", "Parsing error: negative value " << nReadMacro);
+ return;
+ }
+
+ auto nMacro = o3tl::make_unsigned(nReadMacro);
+
+ const size_t nMinStringSize = rStrm.GetStreamCharSet() == RTL_TEXTENCODING_UNICODE ? 4 : 2;
+ size_t nMinRecordSize = 2 + 2*nMinStringSize;
+ if( SVX_MACROTBL_VERSION40 <= nVersion )
+ nMinRecordSize+=2;
+
+ const size_t nMaxRecords = rStrm.remainingSize() / nMinRecordSize;
+ if (nMacro > nMaxRecords)
+ {
+ SAL_WARN("editeng", "Parsing error: " << nMaxRecords <<
+ " max possible entries, but " << nMacro<< " claimed, truncating");
+ nMacro = nMaxRecords;
+ }
+
+ for (decltype(nMacro) i = 0; i < nMacro; ++i)
+ {
+ sal_uInt16 nCurKey, eType = STARBASIC;
+ OUString aLibName, aMacName;
+ rStrm.ReadUInt16( nCurKey );
+ aLibName = readByteString(rStrm);
+ aMacName = readByteString(rStrm);
+
+ if( SVX_MACROTBL_VERSION40 <= nVersion )
+ rStrm.ReadUInt16( eType );
+
+ aSvxMacroTable.emplace( SvMacroItemId(nCurKey), SvxMacro( aMacName, aLibName, static_cast<ScriptType>(eType) ) );
+ }
+}
+
+SvStream& SvxMacroTableDtor::Write( SvStream& rStream ) const
+{
+ sal_uInt16 nVersion = SOFFICE_FILEFORMAT_31 == rStream.GetVersion()
+ ? SVX_MACROTBL_VERSION31
+ : SVX_MACROTBL_VERSION40;
+
+ if( SVX_MACROTBL_VERSION40 <= nVersion )
+ rStream.WriteUInt16( nVersion );
+
+ rStream.WriteUInt16( aSvxMacroTable.size() );
+
+ for( const auto& rEntry : aSvxMacroTable )
+ {
+ if (rStream.GetError() != ERRCODE_NONE)
+ break;
+ const SvxMacro& rMac = rEntry.second;
+ rStream.WriteUInt16( static_cast<sal_uInt16>(rEntry.first) );
+ writeByteString(rStream, rMac.GetLibName());
+ writeByteString(rStream, rMac.GetMacName());
+
+ if( SVX_MACROTBL_VERSION40 <= nVersion )
+ rStream.WriteUInt16( rMac.GetScriptType() );
+ }
+ return rStream;
+}
+
+// returns NULL if no entry exists, or a pointer to the internal value
+const SvxMacro* SvxMacroTableDtor::Get(SvMacroItemId nEvent) const
+{
+ SvxMacroTable::const_iterator it = aSvxMacroTable.find(nEvent);
+ return it == aSvxMacroTable.end() ? nullptr : &(it->second);
+}
+
+// returns NULL if no entry exists, or a pointer to the internal value
+SvxMacro* SvxMacroTableDtor::Get(SvMacroItemId nEvent)
+{
+ SvxMacroTable::iterator it = aSvxMacroTable.find(nEvent);
+ return it == aSvxMacroTable.end() ? nullptr : &(it->second);
+}
+
+// return true if the key exists
+bool SvxMacroTableDtor::IsKeyValid(SvMacroItemId nEvent) const
+{
+ SvxMacroTable::const_iterator it = aSvxMacroTable.find(nEvent);
+ return it != aSvxMacroTable.end();
+}
+
+// This stores a copy of the rMacro parameter
+SvxMacro& SvxMacroTableDtor::Insert(SvMacroItemId nEvent, const SvxMacro& rMacro)
+{
+ return aSvxMacroTable.emplace( nEvent, rMacro ).first->second;
+}
+
+// If the entry exists, remove it from the map and release it's storage
+void SvxMacroTableDtor::Erase(SvMacroItemId nEvent)
+{
+ SvxMacroTable::iterator it = aSvxMacroTable.find(nEvent);
+ if ( it != aSvxMacroTable.end())
+ {
+ aSvxMacroTable.erase(it);
+ }
+}
+
+bool SvxMacroItem::operator==( const SfxPoolItem& rAttr ) const
+{
+ assert(SfxPoolItem::operator==(rAttr));
+
+ const SvxMacroTableDtor& rOwn = aMacroTable;
+ const SvxMacroTableDtor& rOther = static_cast<const SvxMacroItem&>(rAttr).aMacroTable;
+
+ return rOwn == rOther;
+}
+
+SvxMacroItem* SvxMacroItem::Clone( SfxItemPool* ) const
+{
+ return new SvxMacroItem( *this );
+}
+
+bool SvxMacroItem::GetPresentation
+(
+ SfxItemPresentation /*ePres*/,
+ MapUnit /*eCoreUnit*/,
+ MapUnit /*ePresUnit*/,
+ OUString& rText,
+ const IntlWrapper&
+) const
+{
+/*!!!
+ SvxMacroTableDtor& rTbl = (SvxMacroTableDtor&)GetMacroTable();
+ SvxMacro* pMac = rTbl.First();
+
+ while ( pMac )
+ {
+ rText += pMac->GetLibName();
+ rText += cpDelim;
+ rText += pMac->GetMacName();
+ pMac = rTbl.Next();
+ if ( pMac )
+ rText += cpDelim;
+ }
+*/
+ rText.clear();
+ return false;
+}
+
+
+void SvxMacroItem::SetMacro( SvMacroItemId nEvent, const SvxMacro& rMacro )
+{
+ aMacroTable.Insert( nEvent, rMacro);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svl/source/items/poolcach.cxx b/svl/source/items/poolcach.cxx
new file mode 100644
index 000000000..2d406e18c
--- /dev/null
+++ b/svl/source/items/poolcach.cxx
@@ -0,0 +1,109 @@
+/* -*- 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 <svl/itempool.hxx>
+#include <svl/itemset.hxx>
+#include <svl/poolcach.hxx>
+#include <tools/debug.hxx>
+
+SfxItemPoolCache::SfxItemPoolCache( SfxItemPool *pItemPool,
+ const SfxPoolItem *pPutItem ):
+ pPool(pItemPool),
+ pSetToPut( nullptr ),
+ pItemToPut( &pItemPool->Put(*pPutItem) )
+{
+ DBG_ASSERT(pItemPool, "No Pool provided");
+}
+
+
+SfxItemPoolCache::SfxItemPoolCache( SfxItemPool *pItemPool,
+ const SfxItemSet *pPutSet ):
+ pPool(pItemPool),
+ pSetToPut( pPutSet ),
+ pItemToPut( nullptr )
+{
+ DBG_ASSERT(pItemPool, "No Pool provided");
+}
+
+
+SfxItemPoolCache::~SfxItemPoolCache()
+{
+ for (const SfxItemModifyImpl & rImpl : m_aCache) {
+ pPool->Remove( *rImpl.pPoolItem );
+ pPool->Remove( *rImpl.pOrigItem );
+ }
+
+ if ( pItemToPut )
+ pPool->Remove( *pItemToPut );
+}
+
+
+const SfxSetItem& SfxItemPoolCache::ApplyTo( const SfxSetItem &rOrigItem )
+{
+ DBG_ASSERT( pPool == rOrigItem.GetItemSet().GetPool(), "invalid Pool" );
+ DBG_ASSERT( IsDefaultItem( &rOrigItem ) || IsPooledItem( &rOrigItem ),
+ "original not in pool" );
+
+ // Find whether this Transformations ever occurred
+ for (const SfxItemModifyImpl & rMapEntry : m_aCache)
+ {
+ if ( rMapEntry.pOrigItem == &rOrigItem )
+ {
+ // Did anything change at all?
+ if ( rMapEntry.pPoolItem != &rOrigItem )
+ {
+ rMapEntry.pPoolItem->AddRef(2); // One for the cache
+ pPool->Put( rOrigItem ); //FIXME: AddRef?
+ }
+ return *rMapEntry.pPoolItem;
+ }
+ }
+
+ // Insert the new attributes in a new Set
+ std::unique_ptr<SfxSetItem> pNewItem(rOrigItem.Clone());
+ if ( pItemToPut )
+ {
+ pNewItem->GetItemSet().PutDirect( *pItemToPut );
+ DBG_ASSERT( &pNewItem->GetItemSet().Get( pItemToPut->Which() ) == pItemToPut,
+ "wrong item in temporary set" );
+ }
+ else
+ pNewItem->GetItemSet().Put( *pSetToPut );
+ const SfxSetItem* pNewPoolItem = &pPool->Put( std::move(pNewItem) );
+
+ // Adapt refcount; one each for the cache
+ pNewPoolItem->AddRef( pNewPoolItem != &rOrigItem ? 2 : 1 );
+ pPool->Put( rOrigItem ); //FIXME: AddRef?
+
+ // Add the transformation to the cache
+ SfxItemModifyImpl aModify;
+ aModify.pOrigItem = &rOrigItem;
+ aModify.pPoolItem = const_cast<SfxSetItem*>(pNewPoolItem);
+ m_aCache.push_back( aModify );
+
+ DBG_ASSERT( !pItemToPut ||
+ &pNewPoolItem->GetItemSet().Get( pItemToPut->Which() ) == pItemToPut,
+ "wrong item in resulting set" );
+
+ return *pNewPoolItem;
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svl/source/items/poolio.cxx b/svl/source/items/poolio.cxx
new file mode 100644
index 000000000..313c431e9
--- /dev/null
+++ b/svl/source/items/poolio.cxx
@@ -0,0 +1,96 @@
+/* -*- 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 <poolio.hxx>
+
+#include <sal/log.hxx>
+#include <svl/itempool.hxx>
+
+#include <algorithm>
+#include <memory>
+
+/// clear array of PoolItem variants
+/// after all PoolItems are deleted
+/// or all ref counts are decreased
+void SfxPoolItemArray_Impl::clear()
+{
+ maPoolItemSet.clear();
+ maSortablePoolItems.clear();
+}
+
+sal_uInt16 SfxItemPool::GetFirstWhich() const
+{
+ return pImpl->mnStart;
+}
+
+sal_uInt16 SfxItemPool::GetLastWhich() const
+{
+ return pImpl->mnEnd;
+}
+
+bool SfxItemPool::IsInRange( sal_uInt16 nWhich ) const
+{
+ return nWhich >= pImpl->mnStart && nWhich <= pImpl->mnEnd;
+}
+
+sal_uInt16 SfxItemPool::GetIndex_Impl(sal_uInt16 nWhich) const
+{
+ if (nWhich < pImpl->mnStart || nWhich > pImpl->mnEnd)
+ {
+ assert(false && "missing bounds check before use");
+ return 0;
+ }
+ return nWhich - pImpl->mnStart;
+}
+
+sal_uInt16 SfxItemPool::GetSize_Impl() const
+{
+ return pImpl->mnEnd - pImpl->mnStart + 1;
+}
+
+
+bool SfxItemPool::CheckItemInPool(const SfxPoolItem *pItem) const
+{
+ DBG_ASSERT( pItem, "no 0-Pointer Surrogate" );
+ DBG_ASSERT( !IsInvalidItem(pItem), "no Invalid-Item Surrogate" );
+ DBG_ASSERT( !IsPoolDefaultItem(pItem), "no Pool-Default-Item Surrogate" );
+
+ if ( !IsInRange(pItem->Which()) )
+ {
+ if ( pImpl->mpSecondary )
+ return pImpl->mpSecondary->CheckItemInPool( pItem );
+ SAL_WARN( "svl.items", "unknown Which-Id - don't ask me for surrogates, with ID/pos " << pItem->Which());
+ }
+
+ // Pointer on static or pool-default attribute?
+ if( IsStaticDefaultItem(pItem) || IsPoolDefaultItem(pItem) )
+ return true;
+
+ SfxPoolItemArray_Impl& rItemArr = pImpl->maPoolItemArrays[GetIndex_Impl(pItem->Which())];
+
+ for ( auto p : rItemArr )
+ {
+ if ( p == pItem )
+ return true;
+ }
+ SAL_WARN( "svl.items", "Item not in the pool, with ID/pos " << pItem->Which());
+ return false;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svl/source/items/poolitem.cxx b/svl/source/items/poolitem.cxx
new file mode 100644
index 000000000..c5e09ddf9
--- /dev/null
+++ b/svl/source/items/poolitem.cxx
@@ -0,0 +1,648 @@
+/* -*- 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 <svl/poolitem.hxx>
+#include <unotools/intlwrapper.hxx>
+#include <unotools/syslocale.hxx>
+#include <osl/diagnose.h>
+#include <libxml/xmlwriter.h>
+#include <typeinfo>
+#include <boost/property_tree/json_parser.hpp>
+
+//////////////////////////////////////////////////////////////////////////////
+// list of classes derived from SfxPoolItem
+// will not be kept up-to-date, but give a good overview for right now
+//////////////////////////////////////////////////////////////////////////////
+//
+// class SbxItem : public SfxPoolItem
+// class SvxChartColorTableItem : public SfxPoolItem
+// class DriverPoolingSettingsItem final : public SfxPoolItem
+// class DatabaseMapItem final : public SfxPoolItem
+// class DbuTypeCollectionItem : public SfxPoolItem
+// class OptionalBoolItem : public SfxPoolItem
+// class OStringListItem : public SfxPoolItem
+// class MediaItem : public SfxPoolItem
+// class SvxBoxItem : public SfxPoolItem
+// class SvxBoxInfoItem : public SfxPoolItem
+// class SvxBrushItem : public SfxPoolItem
+// class SvxBulletItem : public SfxPoolItem
+// class SvxColorItem : public SfxPoolItem
+// class SvxBackgroundColorItem : public SvxColorItem
+// class SvxFontHeightItem : public SfxPoolItem
+// class SvxFieldItem : public SfxPoolItem
+// class SvxFontListItem : public SfxPoolItem
+// class SvxFontItem : public SfxPoolItem
+// class SvxHyphenZoneItem : public SfxPoolItem
+// class SvxLineItem : public SfxPoolItem
+// class SvxLRSpaceItem : public SfxPoolItem
+// class SvxNumBulletItem : public SfxPoolItem
+// class SfxHyphenRegionItem: public SfxPoolItem
+// class SvxProtectItem : public SfxPoolItem
+// class SvxSizeItem : public SfxPoolItem
+// class SwFormatFrameSize: public SvxSizeItem
+// class SvxTabStopItem : public SfxPoolItem
+// class SvxTwoLinesItem : public SfxPoolItem
+// class SvxULSpaceItem : public SfxPoolItem
+// class SvXMLAttrContainerItem: public SfxPoolItem
+// class SfxLinkItem : public SfxPoolItem
+// class SfxEventNamesItem : public SfxPoolItem
+// class SfxFrameItem: public SfxPoolItem
+// class SfxUnoAnyItem : public SfxPoolItem
+// class SfxUnoFrameItem : public SfxPoolItem
+// class SfxMacroInfoItem: public SfxPoolItem
+// class SfxObjectItem: public SfxPoolItem
+// class SfxObjectShellItem: public SfxPoolItem
+// class SfxViewFrameItem: public SfxPoolItem
+// class SfxWatermarkItem: public SfxPoolItem
+// class SfxAllEnumItem: public SfxPoolItem
+// class SfxEnumItemInterface: public SfxPoolItem
+// class SvxAdjustItem : public SfxEnumItemInterface
+// class SvxEscapementItem : public SfxEnumItemInterface
+// class SvxLineSpacingItem : public SfxEnumItemInterface
+// class SvxShadowItem : public SfxEnumItemInterface
+// class SfxEnumItem : public SfxEnumItemInterface
+// class SvxCharReliefItem : public SfxEnumItem<FontRelief>
+// class SvxCaseMapItem : public SfxEnumItem<SvxCaseMap>
+// class SvxCrossedOutItem : public SfxEnumItem<FontStrikeout>
+// class SvxFormatBreakItem : public SfxEnumItem<SvxBreak>
+// class SvxFrameDirectionItem : public SfxEnumItem<SvxFrameDirection>
+// class SvxHorJustifyItem: public SfxEnumItem<SvxCellHorJustify>
+// class SvxVerJustifyItem: public SfxEnumItem<SvxCellVerJustify>
+// class SvxJustifyMethodItem: public SfxEnumItem<SvxCellJustifyMethod>
+// class SvxLanguageItem_Base: public SfxEnumItem<LanguageType>
+// class SvxLanguageItem : public SvxLanguageItem_Base
+// class SvxPostureItem : public SfxEnumItem<FontItalic>
+// class SvxTextLineItem : public SfxEnumItem<FontLineStyle>
+// class SvxUnderlineItem : public SvxTextLineItem
+// class SvxOverlineItem : public SvxTextLineItem
+// class SvxWeightItem : public SfxEnumItem<FontWeight>
+// class SvxOrientationItem: public SfxEnumItem<SvxCellOrientation>
+// class SvxChartRegressItem : public SfxEnumItem<SvxChartRegress>
+// class SvxChartTextOrderItem : public SfxEnumItem<SvxChartTextOrder>
+// class SvxChartKindErrorItem : public SfxEnumItem<SvxChartKindError>
+// class SvxChartIndicateItem : public SfxEnumItem<SvxChartIndicate>
+// class SvxRotateModeItem: public SfxEnumItem<SvxRotateMode>
+// class SdrGrafModeItem_Base: public SfxEnumItem<GraphicDrawMode>
+// class SdrGrafModeItem : public SdrGrafModeItem_Base
+// class SdrTextAniDirectionItem: public SfxEnumItem<SdrTextAniDirection>
+// class SdrTextVertAdjustItem: public SfxEnumItem<SdrTextVertAdjust>
+// class SdrTextHorzAdjustItem: public SfxEnumItem<SdrTextHorzAdjust>
+// class SdrTextAniKindItem: public SfxEnumItem<SdrTextAniKind>
+// class SdrTextFitToSizeTypeItem : public SfxEnumItem<css::drawing::TextFitToSizeType>
+// class SdrCaptionEscDirItem: public SfxEnumItem<SdrCaptionEscDir>
+// class SdrCaptionTypeItem: public SfxEnumItem<SdrCaptionType>
+// class SdrEdgeKindItem: public SfxEnumItem<SdrEdgeKind>
+// class SdrMeasureTextHPosItem: public SfxEnumItem<css::drawing::MeasureTextHorzPos>
+// class SdrMeasureTextVPosItem: public SfxEnumItem<css::drawing::MeasureTextVertPos>
+// class SdrMeasureUnitItem: public SfxEnumItem<FieldUnit>
+// class XFillStyleItem : public SfxEnumItem<css::drawing::FillStyle>
+// class XFillBmpPosItem : public SfxEnumItem<RectPoint>
+// class XFormTextAdjustItem : public SfxEnumItem<XFormTextAdjust>
+// class XFormTextShadowItem : public SfxEnumItem<XFormTextShadow>
+// class XLineStyleItem : public SfxEnumItem<css::drawing::LineStyle>
+// class XLineJointItem : public SfxEnumItem<css::drawing::LineJoint>
+// class XLineCapItem : public SfxEnumItem<css::drawing::LineCap>
+// class XFormTextStyleItem : public SfxEnumItem<XFormTextStyle>
+// class ScViewObjectModeItem: public SfxEnumItem<ScVObjMode>
+// class SdrCircKindItem: public SfxEnumItem<SdrCircKind>
+// class SdrMeasureKindItem: public SfxEnumItem<SdrMeasureKind>
+// class SwFormatFillOrder: public SfxEnumItem<SwFillOrder>
+// class SwFormatFootnoteEndAtTextEnd : public SfxEnumItem<SwFootnoteEndPosEnum>
+// class SwFormatFootnoteAtTextEnd : public SwFormatFootnoteEndAtTextEnd
+// class SwFormatEndAtTextEnd : public SwFormatFootnoteEndAtTextEnd
+// class SwFormatSurround: public SfxEnumItem<css::text::WrapTextMode>
+// class SwMirrorGrf : public SfxEnumItem<MirrorGraph>
+// class SwDrawModeGrf_Base: public SfxEnumItem<GraphicDrawMode>
+// class SwDrawModeGrf : public SwDrawModeGrf_Base
+//class CntByteItem: public SfxPoolItem
+// class SfxByteItem: public CntByteItem
+// class SvxOrphansItem: public SfxByteItem
+// class SvxPaperBinItem : public SfxByteItem
+// class SvxWidowsItem: public SfxByteItem
+// class SwTransparencyGrf : public SfxByteItem
+//class CntUInt16Item: public SfxPoolItem
+// class SfxUInt16Item: public CntUInt16Item
+// class SvxTextRotateItem : public SfxUInt16Item
+// class SvxCharRotateItem : public SvxTextRotateItem
+// class SvxCharScaleWidthItem : public SfxUInt16Item
+// class SvxEmphasisMarkItem : public SfxUInt16Item
+// class SvxParaVertAlignItem : public SfxUInt16Item
+// class SvxWritingModeItem : public SfxUInt16Item
+// class SvxZoomItem: public SfxUInt16Item
+// class SdrPercentItem : public SfxUInt16Item
+// class SdrGrafTransparenceItem : public SdrPercentItem
+// class SdrTextAniCountItem: public SfxUInt16Item
+// class SdrTextAniDelayItem: public SfxUInt16Item
+// class Svx3DNormalsKindItem : public SfxUInt16Item
+// class Svx3DTextureProjectionXItem : public SfxUInt16Item
+// class Svx3DTextureProjectionYItem : public SfxUInt16Item
+// class Svx3DTextureKindItem : public SfxUInt16Item
+// class Svx3DTextureModeItem : public SfxUInt16Item
+// class Svx3DPerspectiveItem : public SfxUInt16Item
+// class Svx3DShadeModeItem : public SfxUInt16Item
+// class SdrEdgeLineDeltaCountItem: public SfxUInt16Item
+// class SvxViewLayoutItem: public SfxUInt16Item
+// class XFillBmpPosOffsetXItem : public SfxUInt16Item
+// class XFillBmpPosOffsetYItem : public SfxUInt16Item
+// class XFillBmpTileOffsetXItem : public SfxUInt16Item
+// class XFillBmpTileOffsetYItem : public SfxUInt16Item
+// class XFillTransparenceItem: public SfxUInt16Item
+// class XFormTextShadowTranspItem: public SfxUInt16Item
+// class XGradientStepCountItem: public SfxUInt16Item
+// class XLineTransparenceItem: public SfxUInt16Item
+// class SvxZoomSliderItem: public SfxUInt16Item
+// class SdrLayerIdItem: public SfxUInt16Item
+// class SwRotationGrf : public SfxUInt16Item
+//class CntInt32Item: public SfxPoolItem
+// class SfxInt32Item: public CntInt32Item
+// class SfxMetricItem: public SfxInt32Item
+// class XFillBmpSizeXItem : public SfxMetricItem
+// class XFillBmpSizeYItem : public SfxMetricItem
+// class XFormTextDistanceItem : public SfxMetricItem
+// class XFormTextShadowXValItem : public SfxMetricItem
+// class XFormTextShadowYValItem : public SfxMetricItem
+// class XFormTextStartItem : public SfxMetricItem
+// class XLineEndWidthItem : public SfxMetricItem
+// class XLineStartWidthItem : public SfxMetricItem
+// class XLineWidthItem : public SfxMetricItem
+// class SdrAngleItem: public SfxInt32Item
+//
+// class SdrCaptionAngleItem: public SdrAngleItem
+// class SdrMeasureTextFixedAngleItem: public SdrAngleItem
+// class SdrMeasureTextAutoAngleViewItem: public SdrAngleItem
+// class SdrRotateAllItem: public SdrAngleItem
+// class SdrRotateOneItem: public SdrAngleItem
+// class SdrShearAngleItem: public SdrAngleItem
+// class SdrHorzShearAllItem: public SdrAngleItem
+// class SdrVertShearAllItem: public SdrAngleItem
+// class SdrHorzShearOneItem: public SdrAngleItem
+// class SdrVertShearOneItem: public SdrAngleItem
+// class SdrMetricItem: public SfxInt32Item
+// class SdrCaptionEscAbsItem: public SdrMetricItem
+// class SdrCaptionGapItem: public SdrMetricItem
+// class SdrCaptionLineLenItem: public SdrMetricItem
+// class SdrEdgeNode1HorzDistItem: public SdrMetricItem
+// class SdrEdgeNode1VertDistItem: public SdrMetricItem
+// class SdrEdgeNode2HorzDistItem: public SdrMetricItem
+// class SdrEdgeNode2VertDistItem: public SdrMetricItem
+// class SdrEdgeNode1GlueDistItem: public SdrMetricItem
+// class SdrEdgeNode2GlueDistItem: public SdrMetricItem
+// class SdrAllPositionXItem: public SdrMetricItem
+// class SdrAllPositionYItem: public SdrMetricItem
+// class SdrAllSizeWidthItem: public SdrMetricItem
+// class SdrAllSizeHeightItem: public SdrMetricItem
+// class SdrLogicSizeWidthItem: public SdrMetricItem
+// class SdrLogicSizeHeightItem: public SdrMetricItem
+// class SdrMeasureOverhangItem: public SdrMetricItem
+// class SdrMoveXItem: public SdrMetricItem
+// class SdrMoveYItem: public SdrMetricItem
+// class SdrOnePositionXItem: public SdrMetricItem
+// class SdrOnePositionYItem: public SdrMetricItem
+// class SdrOneSizeWidthItem: public SdrMetricItem
+// class SdrOneSizeHeightItem: public SdrMetricItem
+// class SdrTransformRef1XItem: public SdrMetricItem
+// class SdrTransformRef1YItem: public SdrMetricItem
+// class SdrTransformRef2XItem: public SdrMetricItem
+// class SdrTransformRef2YItem: public SdrMetricItem
+// class SdrCaptionEscRelItem: public SfxInt32Item
+//class CntUInt32Item: public SfxPoolItem
+// class SfxUInt32Item: public CntUInt32Item
+// class SvxRsidItem : public SfxUInt32Item
+// class SdrGrafGamma100Item : public SfxUInt32Item
+// class SwTableBoxNumFormat : public SfxUInt32Item
+//class CntUnencodedStringItem: public SfxPoolItem
+// class SfxStringItem: public CntUnencodedStringItem
+// class SvxPageModelItem : public SfxStringItem
+// class SfxDocumentInfoItem : public SfxStringItem
+// class SvxPostItAuthorItem: public SfxStringItem
+// class SvxPostItDateItem: public SfxStringItem
+// class SvxPostItTextItem: public SfxStringItem
+// class SvxPostItIdItem: public SfxStringItem
+// class SdrMeasureFormatStringItem: public SfxStringItem
+// class NameOrIndex : public SfxStringItem
+// class XFillBitmapItem : public NameOrIndex
+// class XColorItem : public NameOrIndex
+// class XFillColorItem : public XColorItem
+// class XFormTextShadowColorItem : public XColorItem
+// class XLineColorItem : public XColorItem
+// class XSecondaryFillColorItem : public XColorItem
+// class XFillGradientItem : public NameOrIndex
+// class XFillFloatTransparenceItem : public XFillGradientItem
+// class XFillHatchItem : public NameOrIndex
+// class XLineDashItem : public NameOrIndex
+// class XLineEndItem : public NameOrIndex
+// class XLineStartItem : public NameOrIndex
+// class SfxScriptOrganizerItem : public SfxStringItem
+// class SdrLayerNameItem: public SfxStringItem
+// class SwNumRuleItem : public SfxStringItem
+//class SfxBoolItem : public SfxPoolItem
+// class SvxAutoKernItem : public SfxBoolItem
+// class SvxBlinkItem : public SfxBoolItem
+// class SvxCharHiddenItem : public SfxBoolItem
+// class SvxContourItem : public SfxBoolItem
+// class SvxForbiddenRuleItem : public SfxBoolItem
+// class SvxHangingPunctuationItem : public SfxBoolItem
+// class SvxFormatKeepItem : public SfxBoolItem
+// class SvxNoHyphenItem : public SfxBoolItem
+// class SvxOpaqueItem : public SfxBoolItem
+// class SvxParaGridItem : public SfxBoolItem
+// class SvxPrintItem : public SfxBoolItem
+// class SvxScriptSpaceItem : public SfxBoolItem
+// class SvxShadowedItem : public SfxBoolItem
+// class SvxFormatSplitItem : public SfxBoolItem
+// class SvxWordLineModeItem : public SfxBoolItem
+// class SdrOnOffItem: public SfxBoolItem
+// class SdrGrafInvertItem : public SdrOnOffItem
+// class SdrTextFixedCellHeightItem : public SfxBoolItem
+// class SdrYesNoItem: public SfxBoolItem
+// class SdrTextAniStartInsideItem: public SdrYesNoItem
+// class SdrTextAniStopInsideItem: public SdrYesNoItem
+// class SdrCaptionEscIsRelItem: public SdrYesNoItem
+// class SdrCaptionFitLineLenItem: public SdrYesNoItem
+// class SdrMeasureBelowRefEdgeItem: public SdrYesNoItem
+// class SdrMeasureTextIsFixedAngleItem: public SdrYesNoItem
+// class SdrMeasureTextRota90Item: public SdrYesNoItem
+// class SdrMeasureTextUpsideDownItem: public SdrYesNoItem
+// class SdrMeasureTextAutoAngleItem: public SdrYesNoItem
+// class SdrObjPrintableItem: public SdrYesNoItem
+// class SdrObjVisibleItem: public SdrYesNoItem
+// class Svx3DReducedLineGeometryItem : public SfxBoolItem
+// class Svx3DSmoothNormalsItem : public SfxBoolItem
+// class Svx3DSmoothLidsItem : public SfxBoolItem
+// class Svx3DCharacterModeItem : public SfxBoolItem
+// class Svx3DCloseFrontItem : public SfxBoolItem
+// class Svx3DCloseBackItem : public SfxBoolItem
+// class XFillBackgroundItem : public SfxBoolItem
+// class XFillBmpSizeLogItem : public SfxBoolItem
+// class XFillBmpTileItem : public SfxBoolItem
+// class XFillBmpStretchItem : public SfxBoolItem
+// class XFormTextMirrorItem : public SfxBoolItem
+// class XFormTextOutlineItem : public SfxBoolItem
+// class XLineEndCenterItem : public SfxBoolItem
+// class XLineStartCenterItem : public SfxBoolItem
+// class XFormTextHideFormItem : public SfxBoolItem
+// class SwFormatNoBalancedColumns : public SfxBoolItem
+// class SwFormatEditInReadonly : public SfxBoolItem
+// class SwFormatFollowTextFlow : public SfxBoolItem
+// class SwFormatLayoutSplit : public SfxBoolItem
+// class SwFormatRowSplit : public SfxBoolItem
+// class SwInvertGrf: public SfxBoolItem
+// class SwHeaderAndFooterEatSpacingItem : public SfxBoolItem
+// class SwRegisterItem : public SfxBoolItem
+// class SwParaConnectBorderItem : public SfxBoolItem
+// class SfxFlagItem: public SfxPoolItem
+// class SfxTemplateItem: public SfxFlagItem
+// class SfxGlobalNameItem: public SfxPoolItem
+// class SfxGrabBagItem : public SfxPoolItem
+// class SfxIntegerListItem : public SfxPoolItem
+// class SfxInt64Item : public SfxPoolItem
+// class SfxInt16Item: public SfxPoolItem
+// class SvxKerningItem : public SfxInt16Item
+// class SfxImageItem : public SfxInt16Item
+// class SdrSignedPercentItem : public SfxInt16Item
+// class SdrGrafRedItem : public SdrSignedPercentItem
+// class SdrGrafGreenItem : public SdrSignedPercentItem
+// class SdrGrafBlueItem : public SdrSignedPercentItem
+// class SdrGrafLuminanceItem : public SdrSignedPercentItem
+// class SdrGrafContrastItem : public SdrSignedPercentItem
+// class SdrTextAniAmountItem: public SfxInt16Item
+// class SdrMeasureDecimalPlacesItem: public SfxInt16Item
+// class ScMergeFlagAttr: public SfxInt16Item
+// class SwLuminanceGrf : public SfxInt16Item
+// class SwContrastGrf : public SfxInt16Item
+// class SwChannelGrf : public SfxInt16Item
+// class SfxLockBytesItem : public SfxPoolItem
+// class SvxMacroItem: public SfxPoolItem
+// class SfxVoidItem final: public SfxPoolItem
+// class SfxSetItem: public SfxPoolItem
+// class SvxScriptSetItem : public SfxSetItem
+// class SfxTabDialogItem: public SfxSetItem
+// class SvxSetItem: public SfxSetItem
+// class XFillAttrSetItem : public SfxSetItem
+// class XLineAttrSetItem : public SfxSetItem
+// class ScPatternAttr: public SfxSetItem
+// class SfxPointItem: public SfxPoolItem
+// class SfxRectangleItem: public SfxPoolItem
+// class SfxRangeItem : public SfxPoolItem
+// class SfxStringListItem : public SfxPoolItem
+// class SvxSearchItem : public SfxPoolItem
+// class SfxVisibilityItem: public SfxPoolItem
+// class AffineMatrixItem : public SfxPoolItem
+// class SvxMarginItem: public SfxPoolItem
+// class SvxDoubleItem : public SfxPoolItem
+// class SvxClipboardFormatItem : public SfxPoolItem
+// class SvxColorListItem: public SfxPoolItem
+// class SvxGradientListItem : public SfxPoolItem
+// class SvxHatchListItem : public SfxPoolItem
+// class SvxBitmapListItem : public SfxPoolItem
+// class SvxPatternListItem : public SfxPoolItem
+// class SvxDashListItem : public SfxPoolItem
+// class SvxLineEndListItem : public SfxPoolItem
+// class SvxB3DVectorItem : public SfxPoolItem
+// class SvxGalleryItem : public SfxPoolItem
+// class SvxGrfCrop : public SfxPoolItem
+// class SdrGrafCropItem : public SvxGrfCrop
+// class SwCropGrf : public SvxGrfCrop
+// class SvxHyperlinkItem : public SfxPoolItem
+// class SvxNumberInfoItem : public SfxPoolItem
+// class OfaPtrItem : public SfxPoolItem
+// class OfaRefItem : public SfxPoolItem
+// class SvxGridItem : public SvxOptionsGrid, public SfxPoolItem
+// class SdOptionsGridItem : public SvxGridItem
+// class SvxPageItem: public SfxPoolItem
+// class SvxLongLRSpaceItem : public SfxPoolItem
+// class SvxLongULSpaceItem : public SfxPoolItem
+// class SvxPagePosSizeItem : public SfxPoolItem
+// class SvxColumnItem : public SfxPoolItem
+// class SvxObjectItem : public SfxPoolItem
+// class SdrCustomShapeGeometryItem : public SfxPoolItem
+// class SvxSmartTagItem : public SfxPoolItem
+// class SvxGraphicItem: public SfxPoolItem
+// class SdrFractionItem: public SfxPoolItem
+// class SdrScaleItem: public SdrFractionItem
+// class SdrMeasureScaleItem: public SdrScaleItem
+// class SdrResizeXAllItem: public SdrFractionItem
+// class SdrResizeYAllItem: public SdrFractionItem
+// class SdrResizeXOneItem: public SdrFractionItem
+// class SdrResizeYOneItem: public SdrFractionItem
+// class ScMergeAttr: public SfxPoolItem
+// class ScProtectionAttr: public SfxPoolItem
+// class ScPageHFItem : public SfxPoolItem
+// class ScPageScaleToItem : public SfxPoolItem
+// class ScCondFormatItem : public SfxPoolItem
+// class ScTpDefaultsItem : public SfxPoolItem
+// class ScTpCalcItem : public SfxPoolItem
+// class ScTpFormulaItem : public SfxPoolItem
+// class ScTpPrintItem : public SfxPoolItem
+// class ScTpViewItem : public SfxPoolItem
+// class ScCondFormatDlgItem : public SfxPoolItem
+// class ScInputStatusItem : public SfxPoolItem
+// class ScSortItem : public SfxPoolItem
+// class ScQueryItem : public SfxPoolItem
+// class ScSubTotalItem : public SfxPoolItem
+// class cUserListItem : public SfxPoolItem
+// class ScConsolidateItem : public SfxPoolItem
+// class ScPivotItem : public SfxPoolItem
+// class ScSolveItem : public SfxPoolItem
+// class ScTabOpItem : public SfxPoolItem
+// class SdOptionsLayoutItem : public SfxPoolItem
+// class SdOptionsMiscItem : public SfxPoolItem
+// class SdOptionsSnapItem : public SfxPoolItem
+// class SdOptionsPrintItem : public SfxPoolItem
+// class SwCondCollItem : public SfxPoolItem
+// class SwTableBoxFormula : public SfxPoolItem, public SwTableFormula
+// class SwTableBoxValue : public SfxPoolItem
+// class SwFormatCharFormat: public SfxPoolItem, public SwClient
+// class SwFormatAnchor: public SfxPoolItem
+// class SwFormatAutoFormat: public SfxPoolItem
+// class SwFormatCol : public SfxPoolItem
+// class SwFormatChain: public SfxPoolItem
+// class SwFormatContent: public SfxPoolItem
+// class SwFormatFlyCnt : public SfxPoolItem
+// class SwFormatField : public SfxPoolItem
+// class SwFormatFootnote : public SfxPoolItem
+// class SwFormatHeader: public SfxPoolItem, public SwClient
+// class SwFormatFooter: public SfxPoolItem, public SwClient
+// class SwFormatINetFormat : public SfxPoolItem
+// class SwFormatLineNumber: public SfxPoolItem
+// class SwFormatMeta : public SfxPoolItem
+// class SwFormatVertOrient: public SfxPoolItem
+// class SwFormatHoriOrient: public SfxPoolItem
+// class SwFormatPageDesc : public SfxPoolItem, public SwClient
+// class SwFormatRefMark : public SfxPoolItem
+// class SwFormatRuby : public SfxPoolItem
+// class SwFormatURL: public SfxPoolItem
+// class SwFormatWrapInfluenceOnObjPos: public SfxPoolItem
+// class SwGammaGrf : public SfxPoolItem
+// class SwMsgPoolItem : public SfxPoolItem
+// class SwPtrMsgPoolItem : public SwMsgPoolItem
+// class SwFormatChg: public SwMsgPoolItem
+// class SwInsText: public SwMsgPoolItem
+// class SwDelChr: public SwMsgPoolItem
+// class SwDelText: public SwMsgPoolItem
+// class SwUpdateAttr : public SwMsgPoolItem
+// class SwRefMarkFieldUpdate : public SwMsgPoolItem
+// class SwDocPosUpdate : public SwMsgPoolItem
+// class SwTableFormulaUpdate : public SwMsgPoolItem
+// class SwAutoFormatGetDocNode: public SwMsgPoolItem
+// class SwAttrSetChg: public SwMsgPoolItem
+// class SwCondCollCondChg: public SwMsgPoolItem
+// class SwVirtPageNumInfo: public SwMsgPoolItem
+// class SwFindNearestNode : public SwMsgPoolItem
+// class SwStringMsgPoolItem : public SwMsgPoolItem
+// class SwFormatDrop: public SfxPoolItem, public SwClient
+// class SwTextGridItem : public SfxPoolItem
+// class SwTOXMark : public SfxPoolItem
+// class SwFltAnchor : public SfxPoolItem
+// class SwFltRedline : public SfxPoolItem
+// class SwFltBookmark : public SfxPoolItem
+// class SwFltRDFMark : public SfxPoolItem
+// class SwFltTOX : public SfxPoolItem
+// class SwDocDisplayItem : public SfxPoolItem
+// class SwElemItem : public SfxPoolItem
+// class SwAddPrinterItem : public SfxPoolItem, public SwPrintData
+// class SwShadowCursorItem : public SfxPoolItem
+// class SwTestItem : public SfxPoolItem
+// class SwEnvItem : public SfxPoolItem
+// class SwLabItem : public SfxPoolItem
+// class SwWrtShellItem: public SfxPoolItem
+// class SwPageFootnoteInfoItem : public SfxPoolItem
+// class SwPtrItem : public SfxPoolItem
+// class SwUINumRuleItem : public SfxPoolItem
+// class SwPaMItem : public SfxPoolItem
+//////////////////////////////////////////////////////////////////////////////
+
+SfxPoolItem::SfxPoolItem(sal_uInt16 const nWhich)
+ : m_nRefCount(0)
+ , m_nWhich(nWhich)
+ , m_nKind(SfxItemKind::NONE)
+{
+ assert(nWhich <= SHRT_MAX);
+}
+
+
+SfxPoolItem::~SfxPoolItem()
+{
+ assert((m_nRefCount == 0 || m_nRefCount > SFX_ITEMS_MAXREF)
+ && "destroying item in use");
+}
+
+
+bool SfxPoolItem::operator==( const SfxPoolItem& rCmp ) const
+{
+ assert(typeid(rCmp) == typeid(*this) && "comparing different pool item subclasses");
+ (void)rCmp;
+ return true;
+}
+
+
+/**
+ * This virtual method allows to get a textual representation of the value
+ * for the SfxPoolItem subclasses. It should be overridden by all UI-relevant
+ * SfxPoolItem subclasses.
+ *
+ * Because the unit of measure of the value in the SfxItemPool is only
+ * queryable via @see SfxItemPool::GetMetric(sal_uInt16) const (and not
+ * via the SfxPoolItem instance or subclass, the own unit of measure is
+ * passed to 'eCoreMetric'.
+ *
+ * The corresponding unit of measure is passed as 'ePresentationMetric'.
+ *
+ *
+ * @return SfxItemPresentation SfxItemPresentation::Nameless
+ * A textual representation (if applicable
+ * with a unit of measure) could be created,
+ * but it doesn't contain any semantic meaning
+ *
+ * SfxItemPresentation::Complete
+ * A complete textual representation could be
+ * created with semantic meaning (if applicable
+ * with unit of measure)
+ *
+ * Example:
+ *
+ * pSvxFontItem->GetPresentation( SFX_PRESENTATION_NAMELESS, ... )
+ * "12pt" with return SfxItemPresentation::Nameless
+ *
+ * pSvxColorItem->GetPresentation( SFX_PRESENTATION_COMPLETE, ... )
+ * "red" with return SfxItemPresentation::Nameless
+ * Because the SvxColorItem does not know which color it represents
+ * it cannot provide a name, which is communicated by the return value
+ *
+ * pSvxBorderItem->GetPresentation( SFX_PRESENTATION_COMPLETE, ... )
+ * "1cm top border, 2cm left border, 0.2cm bottom border, ..."
+ */
+bool SfxPoolItem::GetPresentation
+(
+ SfxItemPresentation /*ePresentation*/, // IN: how we should format
+ MapUnit /*eCoreMetric*/, // IN: current metric of the SfxPoolItems
+ MapUnit /*ePresentationMetric*/, // IN: target metric of the presentation
+ OUString& /*rText*/, // OUT: textual representation
+ const IntlWrapper&
+) const
+{
+ return false;
+}
+
+void SfxPoolItem::dumpAsXml(xmlTextWriterPtr pWriter) const
+{
+ xmlTextWriterStartElement(pWriter, BAD_CAST("SfxPoolItem"));
+ xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr()));
+ xmlTextWriterWriteAttribute(pWriter, BAD_CAST("typeName"), BAD_CAST(typeid(*this).name()));
+ OUString rText;
+ IntlWrapper aIntlWrapper(SvtSysLocale().GetUILanguageTag());
+ if (GetPresentation( SfxItemPresentation::Complete, MapUnit::Map100thMM, MapUnit::Map100thMM, rText, aIntlWrapper))
+ xmlTextWriterWriteAttribute(pWriter, BAD_CAST("presentation"), BAD_CAST(rText.getStr()));
+ xmlTextWriterEndElement(pWriter);
+}
+
+boost::property_tree::ptree SfxPoolItem::dumpAsJSON() const
+{
+ boost::property_tree::ptree aTree;
+ return aTree;
+}
+
+std::unique_ptr<SfxPoolItem> SfxPoolItem::CloneSetWhich( sal_uInt16 nNewWhich ) const
+{
+ std::unique_ptr<SfxPoolItem> pItem(Clone());
+ pItem->SetWhich(nNewWhich);
+ return pItem;
+}
+
+bool SfxPoolItem::IsVoidItem() const
+{
+ return false;
+}
+
+SfxPoolItem* SfxVoidItem::CreateDefault()
+{
+ return new SfxVoidItem(0);
+}
+
+SfxVoidItem::SfxVoidItem( sal_uInt16 which ):
+ SfxPoolItem(which)
+{
+}
+
+bool SfxVoidItem::operator==( const SfxPoolItem& rCmp ) const
+{
+ assert(SfxPoolItem::operator==(rCmp));
+ (void) rCmp;
+ return true;
+}
+
+
+bool SfxVoidItem::GetPresentation
+(
+ SfxItemPresentation /*ePresentation*/,
+ MapUnit /*eCoreMetric*/,
+ MapUnit /*ePresentationMetric*/,
+ OUString& rText,
+ const IntlWrapper&
+) const
+{
+ rText = "Void";
+ return true;
+}
+
+void SfxVoidItem::dumpAsXml(xmlTextWriterPtr pWriter) const
+{
+ xmlTextWriterStartElement(pWriter, BAD_CAST("SfxVoidItem"));
+ xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr()));
+ xmlTextWriterEndElement(pWriter);
+}
+
+SfxVoidItem* SfxVoidItem::Clone(SfxItemPool *) const
+{
+ return new SfxVoidItem(*this);
+}
+
+bool SfxVoidItem::IsVoidItem() const
+{
+ return true;
+}
+
+void SfxPoolItem::ScaleMetrics( long /*lMult*/, long /*lDiv*/ )
+{
+}
+
+bool SfxPoolItem::HasMetrics() const
+{
+ return false;
+}
+
+bool SfxPoolItem::QueryValue( css::uno::Any&, sal_uInt8 ) const
+{
+ OSL_FAIL("There is no implementation for QueryValue for this item!");
+ return false;
+}
+
+
+bool SfxPoolItem::PutValue( const css::uno::Any&, sal_uInt8 )
+{
+ OSL_FAIL("There is no implementation for PutValue for this item!");
+ return false;
+}
+
+SfxVoidItem::~SfxVoidItem()
+{
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svl/source/items/ptitem.cxx b/svl/source/items/ptitem.cxx
new file mode 100644
index 000000000..08912f557
--- /dev/null
+++ b/svl/source/items/ptitem.cxx
@@ -0,0 +1,135 @@
+/* -*- 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 <svl/ptitem.hxx>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/awt/Point.hpp>
+#include <osl/diagnose.h>
+#include <tools/mapunit.hxx>
+
+#include <svl/poolitem.hxx>
+#include <svl/memberid.h>
+
+using namespace ::com::sun::star;
+
+
+SfxPoolItem* SfxPointItem::CreateDefault() { return new SfxPointItem; }
+
+
+SfxPointItem::SfxPointItem()
+{
+}
+
+
+SfxPointItem::SfxPointItem( sal_uInt16 nW, const Point& rVal ) :
+ SfxPoolItem( nW ),
+ aVal( rVal )
+{
+}
+
+
+bool SfxPointItem::GetPresentation
+(
+ SfxItemPresentation /*ePresentation*/,
+ MapUnit /*eCoreMetric*/,
+ MapUnit /*ePresentationMetric*/,
+ OUString& rText,
+ const IntlWrapper&
+) const
+{
+ rText = OUString::number(aVal.X()) + ", " + OUString::number(aVal.Y()) + ", ";
+ return true;
+}
+
+
+bool SfxPointItem::operator==( const SfxPoolItem& rItem ) const
+{
+ assert(SfxPoolItem::operator==(rItem));
+ return static_cast<const SfxPointItem&>(rItem).aVal == aVal;
+}
+
+SfxPointItem* SfxPointItem::Clone(SfxItemPool *) const
+{
+ return new SfxPointItem( *this );
+}
+
+bool SfxPointItem::QueryValue( uno::Any& rVal,
+ sal_uInt8 nMemberId ) const
+{
+ bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
+ awt::Point aTmp(aVal.X(), aVal.Y());
+ if( bConvert )
+ {
+ aTmp.X = convertTwipToMm100(aTmp.X);
+ aTmp.Y = convertTwipToMm100(aTmp.Y);
+ }
+ nMemberId &= ~CONVERT_TWIPS;
+ switch ( nMemberId )
+ {
+ case 0: rVal <<= aTmp; break;
+ case MID_X: rVal <<= aTmp.X; break;
+ case MID_Y: rVal <<= aTmp.Y; break;
+ default: OSL_FAIL("Wrong MemberId!"); return true;
+ }
+
+ return true;
+}
+
+
+bool SfxPointItem::PutValue( const uno::Any& rVal,
+ sal_uInt8 nMemberId )
+{
+ bool bConvert = 0!=(nMemberId&CONVERT_TWIPS);
+ nMemberId &= ~CONVERT_TWIPS;
+ bool bRet = false;
+ awt::Point aValue;
+ sal_Int32 nVal = 0;
+ if ( !nMemberId )
+ {
+ bRet = ( rVal >>= aValue );
+ if( bConvert )
+ {
+ aValue.X = convertMm100ToTwip(aValue.X);
+ aValue.Y = convertMm100ToTwip(aValue.Y);
+ }
+ }
+ else
+ {
+ bRet = ( rVal >>= nVal );
+ if( bConvert )
+ nVal = convertMm100ToTwip( nVal );
+ }
+
+ if ( bRet )
+ {
+ switch ( nMemberId )
+ {
+ case 0: aVal.setX( aValue.X ); aVal.setY( aValue.Y ); break;
+ case MID_X: aVal.setX( nVal ); break;
+ case MID_Y: aVal.setY( nVal ); break;
+ default: OSL_FAIL("Wrong MemberId!"); return false;
+ }
+ }
+
+ return bRet;
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svl/source/items/rectitem.cxx b/svl/source/items/rectitem.cxx
new file mode 100644
index 000000000..1d9d00aa5
--- /dev/null
+++ b/svl/source/items/rectitem.cxx
@@ -0,0 +1,132 @@
+/* -*- 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 <svl/rectitem.hxx>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/awt/Rectangle.hpp>
+#include <osl/diagnose.h>
+
+#include <svl/poolitem.hxx>
+#include <svl/memberid.h>
+
+
+SfxPoolItem* SfxRectangleItem::CreateDefault() { return new SfxRectangleItem; }
+
+
+SfxRectangleItem::SfxRectangleItem()
+{
+}
+
+
+SfxRectangleItem::SfxRectangleItem( sal_uInt16 nW, const tools::Rectangle& rVal ) :
+ SfxPoolItem( nW ),
+ aVal( rVal )
+{
+}
+
+
+bool SfxRectangleItem::GetPresentation
+(
+ SfxItemPresentation /*ePresentation*/,
+ MapUnit /*eCoreMetric*/,
+ MapUnit /*ePresentationMetric*/,
+ OUString& rText,
+ const IntlWrapper&
+) const
+{
+ rText = OUString::number(aVal.Top()) + ", " +
+ OUString::number(aVal.Left()) + ", " +
+ OUString::number(aVal.Bottom()) + ", " +
+ OUString::number(aVal.Right());
+ return true;
+}
+
+
+bool SfxRectangleItem::operator==( const SfxPoolItem& rItem ) const
+{
+ assert(SfxPoolItem::operator==(rItem));
+ return static_cast<const SfxRectangleItem&>(rItem).aVal == aVal;
+}
+
+SfxRectangleItem* SfxRectangleItem::Clone(SfxItemPool *) const
+{
+ return new SfxRectangleItem( *this );
+}
+
+bool SfxRectangleItem::QueryValue( css::uno::Any& rVal,
+ sal_uInt8 nMemberId) const
+{
+ nMemberId &= ~CONVERT_TWIPS;
+ switch ( nMemberId )
+ {
+ case 0:
+ {
+ rVal <<= css::awt::Rectangle( aVal.getX(),
+ aVal.getY(),
+ aVal.getWidth(),
+ aVal.getHeight() );
+ break;
+ }
+ case MID_RECT_LEFT: rVal <<= aVal.getX(); break;
+ case MID_RECT_RIGHT: rVal <<= aVal.getY(); break;
+ case MID_WIDTH: rVal <<= aVal.getWidth(); break;
+ case MID_HEIGHT: rVal <<= aVal.getHeight(); break;
+ default: OSL_FAIL("Wrong MemberID!"); return false;
+ }
+
+ return true;
+}
+
+
+bool SfxRectangleItem::PutValue( const css::uno::Any& rVal,
+ sal_uInt8 nMemberId )
+{
+ bool bRet = false;
+ nMemberId &= ~CONVERT_TWIPS;
+ css::awt::Rectangle aValue;
+ sal_Int32 nVal = 0;
+ if ( !nMemberId )
+ bRet = (rVal >>= aValue);
+ else
+ bRet = (rVal >>= nVal);
+
+ if ( bRet )
+ {
+ switch ( nMemberId )
+ {
+ case 0:
+ aVal.setX( aValue.X );
+ aVal.setY( aValue.Y );
+ aVal.setWidth( aValue.Width );
+ aVal.setHeight( aValue.Height );
+ break;
+ case MID_RECT_LEFT: aVal.setX( nVal ); break;
+ case MID_RECT_RIGHT: aVal.setY( nVal ); break;
+ case MID_WIDTH: aVal.setWidth( nVal ); break;
+ case MID_HEIGHT: aVal.setHeight( nVal ); break;
+ default: OSL_FAIL("Wrong MemberID!"); return false;
+ }
+ }
+
+ return bRet;
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svl/source/items/rngitem.cxx b/svl/source/items/rngitem.cxx
new file mode 100644
index 000000000..89f7e642e
--- /dev/null
+++ b/svl/source/items/rngitem.cxx
@@ -0,0 +1,59 @@
+/* -*- 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 <svl/rngitem.hxx>
+
+
+SfxRangeItem::SfxRangeItem( sal_uInt16 which, sal_uInt16 from, sal_uInt16 to ):
+ SfxPoolItem( which ),
+ nFrom( from ),
+ nTo( to )
+{
+}
+
+
+bool SfxRangeItem::GetPresentation
+(
+ SfxItemPresentation /*ePresentation*/,
+ MapUnit /*eCoreMetric*/,
+ MapUnit /*ePresentationMetric*/,
+ OUString& rText,
+ const IntlWrapper&
+) const
+{
+ rText = OUString::number(nFrom) + ":" + OUString::number(nTo);
+ return true;
+}
+
+
+bool SfxRangeItem::operator==( const SfxPoolItem& rItem ) const
+{
+ assert(SfxPoolItem::operator==(rItem));
+ const SfxRangeItem& rT = static_cast<const SfxRangeItem&>(rItem);
+ return nFrom==rT.nFrom && nTo==rT.nTo;
+}
+
+SfxRangeItem* SfxRangeItem::Clone(SfxItemPool *) const
+{
+ return new SfxRangeItem( Which(), nFrom, nTo );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svl/source/items/sitem.cxx b/svl/source/items/sitem.cxx
new file mode 100644
index 000000000..79a6aa93d
--- /dev/null
+++ b/svl/source/items/sitem.cxx
@@ -0,0 +1,75 @@
+/* -*- 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 <utility>
+
+#include <rtl/ustring.hxx>
+#include <svl/itemset.hxx>
+#include <svl/poolitem.hxx>
+#include <tools/debug.hxx>
+
+SfxSetItem::SfxSetItem( sal_uInt16 which, const SfxItemSet &rSet) :
+ SfxPoolItem(which),
+ pSet(rSet.Clone())
+{
+}
+
+
+SfxSetItem::SfxSetItem( sal_uInt16 which, std::unique_ptr<SfxItemSet> &&pS) :
+ SfxPoolItem(which),
+ pSet(std::move(pS))
+{
+ DBG_ASSERT(pSet, "SfxSetItem without set constructed" );
+}
+
+
+SfxSetItem::SfxSetItem( const SfxSetItem& rCopy, SfxItemPool *pPool ) :
+ SfxPoolItem(rCopy),
+ pSet(rCopy.pSet->Clone(true, pPool))
+{
+}
+
+
+SfxSetItem::~SfxSetItem()
+{
+}
+
+
+bool SfxSetItem::operator==( const SfxPoolItem& rCmp) const
+{
+ assert(SfxPoolItem::operator==(rCmp));
+ return *pSet == *static_cast<const SfxSetItem &>(rCmp).pSet;
+}
+
+
+bool SfxSetItem::GetPresentation
+(
+ SfxItemPresentation /*ePresentation*/,
+ MapUnit /*eCoreMetric*/,
+ MapUnit /*ePresentationMetric*/,
+ OUString& /*rText*/,
+ const IntlWrapper&
+) const
+{
+ return false;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svl/source/items/slstitm.cxx b/svl/source/items/slstitm.cxx
new file mode 100644
index 000000000..54af34625
--- /dev/null
+++ b/svl/source/items/slstitm.cxx
@@ -0,0 +1,187 @@
+/* -*- 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 <svl/slstitm.hxx>
+#include <svl/poolitem.hxx>
+#include <com/sun/star/uno/Any.hxx>
+#include <com/sun/star/uno/Sequence.hxx>
+#include <comphelper/sequence.hxx>
+#include <osl/diagnose.h>
+#include <rtl/ustrbuf.hxx>
+#include <tools/lineend.hxx>
+
+SfxPoolItem* SfxStringListItem::CreateDefault() { return new SfxStringListItem; }
+
+SfxStringListItem::SfxStringListItem()
+{
+}
+
+
+SfxStringListItem::SfxStringListItem( sal_uInt16 which, const std::vector<OUString>* pList ) :
+ SfxPoolItem( which )
+{
+ // FIXME: Putting an empty list does not work
+ // Therefore the query after the count is commented out
+ if( pList /*!!! && pList->Count() */ )
+ {
+ mpList = std::make_shared<std::vector<OUString>>();
+ *mpList = *pList;
+ }
+}
+
+
+SfxStringListItem::~SfxStringListItem()
+{
+}
+
+
+std::vector<OUString>& SfxStringListItem::GetList()
+{
+ if( !mpList )
+ mpList = std::make_shared<std::vector<OUString>>();
+ return *mpList;
+}
+
+const std::vector<OUString>& SfxStringListItem::GetList () const
+{
+ return const_cast< SfxStringListItem * >(this)->GetList();
+}
+
+
+bool SfxStringListItem::operator==( const SfxPoolItem& rItem ) const
+{
+ assert(SfxPoolItem::operator==(rItem));
+
+ const SfxStringListItem& rSSLItem = static_cast<const SfxStringListItem&>(rItem);
+
+ return mpList == rSSLItem.mpList;
+}
+
+
+bool SfxStringListItem::GetPresentation
+(
+ SfxItemPresentation /*ePresentation*/,
+ MapUnit /*eCoreMetric*/,
+ MapUnit /*ePresentationMetric*/,
+ OUString& rText,
+ const IntlWrapper&
+) const
+{
+ rText = "(List)";
+ return false;
+}
+
+SfxStringListItem* SfxStringListItem::Clone( SfxItemPool *) const
+{
+ return new SfxStringListItem( *this );
+}
+
+void SfxStringListItem::SetString( const OUString& rStr )
+{
+ mpList = std::make_shared<std::vector<OUString>>();
+
+ sal_Int32 nStart = 0;
+ OUString aStr(convertLineEnd(rStr, LINEEND_CR));
+ for (;;)
+ {
+ const sal_Int32 nDelimPos = aStr.indexOf( '\r', nStart );
+ if ( nDelimPos < 0 )
+ {
+ if (nStart<aStr.getLength())
+ {
+ // put last string only if not empty
+ mpList->push_back(aStr.copy(nStart));
+ }
+ break;
+ }
+
+ mpList->push_back(aStr.copy(nStart, nDelimPos-nStart));
+
+ // skip both inserted string and delimiter
+ nStart = nDelimPos + 1 ;
+ }
+}
+
+
+OUString SfxStringListItem::GetString()
+{
+ OUStringBuffer aStr;
+ if ( mpList )
+ {
+ for (auto iter = mpList->begin(), end = mpList->end(); iter != end;)
+ {
+ aStr.append(*iter);
+ ++iter;
+
+ if (iter == end)
+ break;
+
+ aStr.append("\r");
+ }
+ }
+ return convertLineEnd(aStr.makeStringAndClear(), GetSystemLineEnd());
+}
+
+
+void SfxStringListItem::SetStringList( const css::uno::Sequence< OUString >& rList )
+{
+ mpList = std::make_shared<std::vector<OUString>>();
+
+ // String belongs to the list
+ comphelper::sequenceToContainer(*mpList, rList);
+}
+
+void SfxStringListItem::GetStringList( css::uno::Sequence< OUString >& rList ) const
+{
+ size_t nCount = mpList->size();
+
+ rList.realloc( nCount );
+ for( size_t i=0; i < nCount; i++ )
+ rList[i] = (*mpList)[i];
+}
+
+// virtual
+bool SfxStringListItem::PutValue( const css::uno::Any& rVal, sal_uInt8 )
+{
+ css::uno::Sequence< OUString > aValue;
+ if ( rVal >>= aValue )
+ {
+ SetStringList( aValue );
+ return true;
+ }
+
+ OSL_FAIL( "SfxStringListItem::PutValue - Wrong type!" );
+ return false;
+}
+
+// virtual
+bool SfxStringListItem::QueryValue( css::uno::Any& rVal, sal_uInt8 ) const
+{
+ // GetString() is not const!!!
+ SfxStringListItem* pThis = const_cast< SfxStringListItem * >( this );
+
+ css::uno::Sequence< OUString > aStringList;
+ pThis->GetStringList( aStringList );
+ rVal <<= aStringList;
+ return true;
+}
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svl/source/items/srchitem.cxx b/svl/source/items/srchitem.cxx
new file mode 100644
index 000000000..4588d7a8b
--- /dev/null
+++ b/svl/source/items/srchitem.cxx
@@ -0,0 +1,694 @@
+/* -*- 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 <sal/log.hxx>
+#include <svl/srchitem.hxx>
+#include <sal/macros.h>
+#include <osl/diagnose.h>
+
+#include <unotools/searchopt.hxx>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/lang/Locale.hpp>
+#include <svl/memberid.h>
+#include <i18nlangtag/languagetag.hxx>
+
+using namespace utl;
+using namespace com::sun::star;
+using namespace com::sun::star::beans;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::util;
+
+#define CFG_ROOT_NODE "Office.Common/SearchOptions"
+
+#define SRCH_PARAMS 13
+#define SRCH_PARA_OPTIONS "Options"
+#define SRCH_PARA_FAMILY "Family"
+#define SRCH_PARA_COMMAND "Command"
+#define SRCH_PARA_CELLTYPE "CellType"
+#define SRCH_PARA_APPFLAG "AppFlag"
+#define SRCH_PARA_ROWDIR "RowDirection"
+#define SRCH_PARA_ALLTABLES "AllTables"
+#define SRCH_PARA_SEARCHFILTERED "SearchFiltered"
+#define SRCH_PARA_SEARCHFORMATTED "SearchFormatted"
+#define SRCH_PARA_BACKWARD "Backward"
+#define SRCH_PARA_PATTERN "Pattern"
+#define SRCH_PARA_CONTENT "Content"
+#define SRCH_PARA_ASIANOPT "AsianOptions"
+
+SfxPoolItem* SvxSearchItem::CreateDefault() { return new SvxSearchItem(0);}
+
+
+static Sequence< OUString > lcl_GetNotifyNames()
+{
+ // names of transliteration relevant properties
+ static const char* aTranslitNames[] =
+ {
+ "IsMatchCase", // 0
+ "Japanese/IsMatchFullHalfWidthForms", // 1
+ "Japanese/IsMatchHiraganaKatakana", // 2
+ "Japanese/IsMatchContractions", // 3
+ "Japanese/IsMatchMinusDashCho-on", // 4
+ "Japanese/IsMatchRepeatCharMarks", // 5
+ "Japanese/IsMatchVariantFormKanji", // 6
+ "Japanese/IsMatchOldKanaForms", // 7
+ "Japanese/IsMatch_DiZi_DuZu", // 8
+ "Japanese/IsMatch_BaVa_HaFa", // 9
+ "Japanese/IsMatch_TsiThiChi_DhiZi", // 10
+ "Japanese/IsMatch_HyuIyu_ByuVyu", // 11
+ "Japanese/IsMatch_SeShe_ZeJe", // 12
+ "Japanese/IsMatch_IaIya", // 13
+ "Japanese/IsMatch_KiKu", // 14
+ "Japanese/IsIgnorePunctuation", // 15
+ "Japanese/IsIgnoreWhitespace", // 16
+ "Japanese/IsIgnoreProlongedSoundMark", // 17
+ "Japanese/IsIgnoreMiddleDot", // 18
+ "IsIgnoreDiacritics_CTL", // 19
+ "IsIgnoreKashida_CTL" // 20
+ };
+
+ const int nCount = SAL_N_ELEMENTS( aTranslitNames );
+ Sequence< OUString > aNames( nCount );
+ OUString* pNames = aNames.getArray();
+ for (sal_Int32 i = 0; i < nCount; ++i)
+ pNames[i] = OUString::createFromAscii( aTranslitNames[i] );
+
+ return aNames;
+}
+
+
+SvxSearchItem::SvxSearchItem( const sal_uInt16 nId ) :
+
+ SfxPoolItem( nId ),
+ ConfigItem( CFG_ROOT_NODE ),
+
+ m_aSearchOpt ( SearchAlgorithms_ABSOLUTE,
+ SearchFlags::LEV_RELAXED,
+ OUString(),
+ OUString(),
+ lang::Locale(),
+ 2, 2, 2,
+ TransliterationFlags::IGNORE_CASE,
+ SearchAlgorithms2::ABSOLUTE, '\\' ),
+ m_eFamily ( SfxStyleFamily::Para ),
+ m_nCommand ( SvxSearchCmd::FIND ),
+ m_nCellType ( SvxSearchCellType::FORMULA ),
+ m_nAppFlag ( SvxSearchApp::WRITER ),
+ m_bRowDirection ( true ),
+ m_bAllTables ( false ),
+ m_bSearchFiltered ( false ),
+ m_bSearchFormatted( false ),
+ m_bNotes ( false),
+ m_bBackward ( false ),
+ m_bPattern ( false ),
+ m_bContent ( false ),
+ m_bAsianOptions ( false ),
+ m_nStartPointX(0),
+ m_nStartPointY(0)
+{
+ EnableNotification( lcl_GetNotifyNames() );
+
+ SvtSearchOptions aOpt;
+
+ m_bBackward = aOpt.IsBackwards();
+ m_bAsianOptions = aOpt.IsUseAsianOptions();
+ m_bNotes = aOpt.IsNotes();
+
+ if (aOpt.IsUseWildcard())
+ {
+ m_aSearchOpt.AlgorithmType2 = SearchAlgorithms2::WILDCARD;
+ m_aSearchOpt.algorithmType = SearchAlgorithms_ABSOLUTE; // something valid
+ }
+ if (aOpt.IsUseRegularExpression())
+ {
+ m_aSearchOpt.AlgorithmType2 = SearchAlgorithms2::REGEXP;
+ m_aSearchOpt.algorithmType = SearchAlgorithms_REGEXP;
+ }
+ if (aOpt.IsSimilaritySearch())
+ {
+ m_aSearchOpt.AlgorithmType2 = SearchAlgorithms2::APPROXIMATE;
+ m_aSearchOpt.algorithmType = SearchAlgorithms_APPROXIMATE;
+ }
+ if (aOpt.IsWholeWordsOnly())
+ m_aSearchOpt.searchFlag |= SearchFlags::NORM_WORD_ONLY;
+
+ TransliterationFlags& rFlags = m_aSearchOpt.transliterateFlags;
+
+ if (!aOpt.IsMatchCase())
+ rFlags |= TransliterationFlags::IGNORE_CASE;
+ if ( aOpt.IsMatchFullHalfWidthForms())
+ rFlags |= TransliterationFlags::IGNORE_WIDTH;
+ if ( aOpt.IsIgnoreDiacritics_CTL())
+ rFlags |= TransliterationFlags::IGNORE_DIACRITICS_CTL ;
+ if ( aOpt.IsIgnoreKashida_CTL())
+ rFlags |= TransliterationFlags::IGNORE_KASHIDA_CTL ;
+ if ( !m_bAsianOptions )
+ return;
+
+ if ( aOpt.IsMatchHiraganaKatakana())
+ rFlags |= TransliterationFlags::IGNORE_KANA;
+ if ( aOpt.IsMatchContractions())
+ rFlags |= TransliterationFlags::ignoreSize_ja_JP;
+ if ( aOpt.IsMatchMinusDashChoon())
+ rFlags |= TransliterationFlags::ignoreMinusSign_ja_JP;
+ if ( aOpt.IsMatchRepeatCharMarks())
+ rFlags |= TransliterationFlags::ignoreIterationMark_ja_JP;
+ if ( aOpt.IsMatchVariantFormKanji())
+ rFlags |= TransliterationFlags::ignoreTraditionalKanji_ja_JP;
+ if ( aOpt.IsMatchOldKanaForms())
+ rFlags |= TransliterationFlags::ignoreTraditionalKana_ja_JP;
+ if ( aOpt.IsMatchDiziDuzu())
+ rFlags |= TransliterationFlags::ignoreZiZu_ja_JP;
+ if ( aOpt.IsMatchBavaHafa())
+ rFlags |= TransliterationFlags::ignoreBaFa_ja_JP;
+ if ( aOpt.IsMatchTsithichiDhizi())
+ rFlags |= TransliterationFlags::ignoreTiJi_ja_JP;
+ if ( aOpt.IsMatchHyuiyuByuvyu())
+ rFlags |= TransliterationFlags::ignoreHyuByu_ja_JP;
+ if ( aOpt.IsMatchSesheZeje())
+ rFlags |= TransliterationFlags::ignoreSeZe_ja_JP;
+ if ( aOpt.IsMatchIaiya())
+ rFlags |= TransliterationFlags::ignoreIandEfollowedByYa_ja_JP;
+ if ( aOpt.IsMatchKiku())
+ rFlags |= TransliterationFlags::ignoreKiKuFollowedBySa_ja_JP;
+ if ( aOpt.IsIgnorePunctuation())
+ rFlags |= TransliterationFlags::ignoreSeparator_ja_JP;
+ if ( aOpt.IsIgnoreWhitespace())
+ rFlags |= TransliterationFlags::ignoreSpace_ja_JP;
+ if ( aOpt.IsIgnoreProlongedSoundMark())
+ rFlags |= TransliterationFlags::ignoreProlongedSoundMark_ja_JP;
+ if ( aOpt.IsIgnoreMiddleDot())
+ rFlags |= TransliterationFlags::ignoreMiddleDot_ja_JP;
+}
+
+
+SvxSearchItem::SvxSearchItem( const SvxSearchItem& rItem ) :
+
+ SfxPoolItem ( rItem ),
+ ConfigItem( CFG_ROOT_NODE ),
+
+ m_aSearchOpt ( rItem.m_aSearchOpt ),
+ m_eFamily ( rItem.m_eFamily ),
+ m_nCommand ( rItem.m_nCommand ),
+ m_nCellType ( rItem.m_nCellType ),
+ m_nAppFlag ( rItem.m_nAppFlag ),
+ m_bRowDirection ( rItem.m_bRowDirection ),
+ m_bAllTables ( rItem.m_bAllTables ),
+ m_bSearchFiltered ( rItem.m_bSearchFiltered ),
+ m_bSearchFormatted ( rItem.m_bSearchFormatted ),
+ m_bNotes ( rItem.m_bNotes),
+ m_bBackward ( rItem.m_bBackward ),
+ m_bPattern ( rItem.m_bPattern ),
+ m_bContent ( rItem.m_bContent ),
+ m_bAsianOptions ( rItem.m_bAsianOptions ),
+ m_nStartPointX(rItem.m_nStartPointX),
+ m_nStartPointY(rItem.m_nStartPointY)
+{
+ EnableNotification( lcl_GetNotifyNames() );
+}
+
+SvxSearchItem::~SvxSearchItem()
+{
+}
+
+SvxSearchItem* SvxSearchItem::Clone( SfxItemPool *) const
+{
+ return new SvxSearchItem(*this);
+}
+
+//! used below
+static bool equalsWithoutLocale( const i18nutil::SearchOptions2& rItem1, const i18nutil::SearchOptions2& rItem2 )
+{
+ return rItem1.algorithmType == rItem2.algorithmType &&
+ rItem1.searchFlag == rItem2.searchFlag &&
+ rItem1.searchString == rItem2.searchString &&
+ rItem1.replaceString == rItem2.replaceString &&
+ //rItem1.Locale == rItem2.Locale &&
+ rItem1.changedChars == rItem2.changedChars &&
+ rItem1.deletedChars == rItem2.deletedChars &&
+ rItem1.insertedChars == rItem2.insertedChars &&
+ rItem1.transliterateFlags == rItem2.transliterateFlags &&
+ rItem1.AlgorithmType2 == rItem2.AlgorithmType2 &&
+ rItem1.WildcardEscapeCharacter == rItem2.WildcardEscapeCharacter;
+}
+
+
+bool SvxSearchItem::operator==( const SfxPoolItem& rItem ) const
+{
+ assert(SfxPoolItem::operator==(rItem));
+ const SvxSearchItem &rSItem = static_cast<const SvxSearchItem &>(rItem);
+ return ( m_nCommand == rSItem.m_nCommand ) &&
+ ( m_bBackward == rSItem.m_bBackward ) &&
+ ( m_bPattern == rSItem.m_bPattern ) &&
+ ( m_bContent == rSItem.m_bContent ) &&
+ ( m_eFamily == rSItem.m_eFamily ) &&
+ ( m_bRowDirection == rSItem.m_bRowDirection ) &&
+ ( m_bAllTables == rSItem.m_bAllTables ) &&
+ ( m_bSearchFiltered == rSItem.m_bSearchFiltered ) &&
+ ( m_bSearchFormatted == rSItem.m_bSearchFormatted ) &&
+ ( m_nCellType == rSItem.m_nCellType ) &&
+ ( m_nAppFlag == rSItem.m_nAppFlag ) &&
+ ( m_bAsianOptions == rSItem.m_bAsianOptions ) &&
+ ( equalsWithoutLocale(m_aSearchOpt,rSItem.m_aSearchOpt )) &&
+ ( m_bNotes == rSItem.m_bNotes );
+}
+
+
+bool SvxSearchItem::GetPresentation
+(
+ SfxItemPresentation ,
+ MapUnit ,
+ MapUnit ,
+ OUString& ,
+ const IntlWrapper&
+) const
+{
+ return false;
+}
+
+void SvxSearchItem::Notify( const Sequence< OUString > & )
+{
+ // applies transliteration changes in the configuration database
+ // to the current SvxSearchItem
+ SetTransliterationFlags( SvtSearchOptions().GetTransliterationFlags() );
+}
+
+void SvxSearchItem::ImplCommit()
+{
+}
+
+void SvxSearchItem::SetMatchFullHalfWidthForms( bool bVal )
+{
+ if (bVal)
+ m_aSearchOpt.transliterateFlags |= TransliterationFlags::IGNORE_WIDTH;
+ else
+ m_aSearchOpt.transliterateFlags &= ~TransliterationFlags::IGNORE_WIDTH;
+}
+
+
+void SvxSearchItem::SetWordOnly( bool bVal )
+{
+ if (bVal)
+ m_aSearchOpt.searchFlag |= SearchFlags::NORM_WORD_ONLY;
+ else
+ m_aSearchOpt.searchFlag &= ~SearchFlags::NORM_WORD_ONLY;
+}
+
+
+void SvxSearchItem::SetExact( bool bVal )
+{
+ if (!bVal)
+ m_aSearchOpt.transliterateFlags |= TransliterationFlags::IGNORE_CASE;
+ else
+ m_aSearchOpt.transliterateFlags &= ~TransliterationFlags::IGNORE_CASE;
+}
+
+
+void SvxSearchItem::SetSelection( bool bVal )
+{
+ if (bVal)
+ {
+ m_aSearchOpt.searchFlag |= (SearchFlags::REG_NOT_BEGINOFLINE |
+ SearchFlags::REG_NOT_ENDOFLINE);
+ }
+ else
+ {
+ m_aSearchOpt.searchFlag &= ~(SearchFlags::REG_NOT_BEGINOFLINE |
+ SearchFlags::REG_NOT_ENDOFLINE);
+ }
+}
+
+
+void SvxSearchItem::SetRegExp( bool bVal )
+{
+ if ( bVal )
+ {
+ m_aSearchOpt.AlgorithmType2 = SearchAlgorithms2::REGEXP;
+ m_aSearchOpt.algorithmType = SearchAlgorithms_REGEXP;
+ }
+ else if ( SearchAlgorithms2::REGEXP == m_aSearchOpt.AlgorithmType2 )
+ {
+ m_aSearchOpt.AlgorithmType2 = SearchAlgorithms2::ABSOLUTE;
+ m_aSearchOpt.algorithmType = SearchAlgorithms_ABSOLUTE;
+ }
+}
+
+
+void SvxSearchItem::SetWildcard( bool bVal )
+{
+ if ( bVal )
+ {
+ m_aSearchOpt.AlgorithmType2 = SearchAlgorithms2::WILDCARD;
+ m_aSearchOpt.algorithmType = SearchAlgorithms_ABSOLUTE; // something valid
+ }
+ else if ( SearchAlgorithms2::REGEXP == m_aSearchOpt.AlgorithmType2 )
+ {
+ m_aSearchOpt.AlgorithmType2 = SearchAlgorithms2::ABSOLUTE;
+ m_aSearchOpt.algorithmType = SearchAlgorithms_ABSOLUTE;
+ }
+}
+
+
+void SvxSearchItem::SetLEVRelaxed( bool bVal )
+{
+ if (bVal)
+ m_aSearchOpt.searchFlag |= SearchFlags::LEV_RELAXED;
+ else
+ m_aSearchOpt.searchFlag &= ~SearchFlags::LEV_RELAXED;
+}
+
+
+void SvxSearchItem::SetLevenshtein( bool bVal )
+{
+ if ( bVal )
+ {
+ m_aSearchOpt.AlgorithmType2 = SearchAlgorithms2::APPROXIMATE;
+ m_aSearchOpt.algorithmType = SearchAlgorithms_APPROXIMATE;
+ }
+ else if ( SearchAlgorithms2::APPROXIMATE == m_aSearchOpt.AlgorithmType2 )
+ {
+ m_aSearchOpt.AlgorithmType2 = SearchAlgorithms2::ABSOLUTE;
+ m_aSearchOpt.algorithmType = SearchAlgorithms_ABSOLUTE;
+ }
+}
+
+
+void SvxSearchItem::SetTransliterationFlags( TransliterationFlags nFlags )
+{
+ m_aSearchOpt.transliterateFlags = nFlags;
+}
+
+bool SvxSearchItem::QueryValue( css::uno::Any& rVal, sal_uInt8 nMemberId ) const
+{
+ nMemberId &= ~CONVERT_TWIPS;
+ switch ( nMemberId )
+ {
+ case 0 :
+ {
+ Sequence< PropertyValue > aSeq( SRCH_PARAMS );
+ aSeq[0].Name = SRCH_PARA_OPTIONS;
+ aSeq[0].Value <<= m_aSearchOpt.toUnoSearchOptions2();
+ aSeq[1].Name = SRCH_PARA_FAMILY;
+ aSeq[1].Value <<= sal_Int16( m_eFamily );
+ aSeq[2].Name = SRCH_PARA_COMMAND;
+ aSeq[2].Value <<= static_cast<sal_uInt16>(m_nCommand);
+ aSeq[3].Name = SRCH_PARA_CELLTYPE;
+ aSeq[3].Value <<= static_cast<sal_uInt16>(m_nCellType);
+ aSeq[4].Name = SRCH_PARA_APPFLAG;
+ aSeq[4].Value <<= static_cast<sal_uInt16>(m_nAppFlag);
+ aSeq[5].Name = SRCH_PARA_ROWDIR;
+ aSeq[5].Value <<= m_bRowDirection;
+ aSeq[6].Name = SRCH_PARA_ALLTABLES;
+ aSeq[6].Value <<= m_bAllTables;
+ aSeq[7].Name = SRCH_PARA_SEARCHFILTERED;
+ aSeq[7].Value <<= m_bSearchFiltered;
+ aSeq[8].Name = SRCH_PARA_SEARCHFORMATTED;
+ aSeq[8].Value <<= m_bSearchFormatted;
+ aSeq[9].Name = SRCH_PARA_BACKWARD;
+ aSeq[9].Value <<= m_bBackward;
+ aSeq[10].Name = SRCH_PARA_PATTERN;
+ aSeq[10].Value <<= m_bPattern;
+ aSeq[11].Name = SRCH_PARA_CONTENT;
+ aSeq[11].Value <<= m_bContent;
+ aSeq[12].Name = SRCH_PARA_ASIANOPT;
+ aSeq[12].Value <<= m_bAsianOptions;
+ rVal <<= aSeq;
+ }
+ break;
+ case MID_SEARCH_COMMAND:
+ rVal <<= static_cast<sal_Int16>(m_nCommand); break;
+ case MID_SEARCH_STYLEFAMILY:
+ rVal <<= static_cast<sal_Int16>(m_eFamily); break;
+ case MID_SEARCH_CELLTYPE:
+ rVal <<= static_cast<sal_Int32>(m_nCellType); break;
+ case MID_SEARCH_ROWDIRECTION:
+ rVal <<= m_bRowDirection; break;
+ case MID_SEARCH_ALLTABLES:
+ rVal <<= m_bAllTables; break;
+ case MID_SEARCH_SEARCHFILTERED:
+ rVal <<= m_bSearchFiltered; break;
+ case MID_SEARCH_SEARCHFORMATTED:
+ rVal <<= m_bSearchFormatted; break;
+ case MID_SEARCH_BACKWARD:
+ rVal <<= m_bBackward; break;
+ case MID_SEARCH_PATTERN:
+ rVal <<= m_bPattern; break;
+ case MID_SEARCH_CONTENT:
+ rVal <<= m_bContent; break;
+ case MID_SEARCH_ASIANOPTIONS:
+ rVal <<= m_bAsianOptions; break;
+ case MID_SEARCH_ALGORITHMTYPE:
+ rVal <<= static_cast<sal_Int16>(m_aSearchOpt.algorithmType); break;
+ case MID_SEARCH_ALGORITHMTYPE2:
+ rVal <<= m_aSearchOpt.AlgorithmType2; break;
+ case MID_SEARCH_FLAGS:
+ rVal <<= m_aSearchOpt.searchFlag; break;
+ case MID_SEARCH_SEARCHSTRING:
+ rVal <<= m_aSearchOpt.searchString; break;
+ case MID_SEARCH_REPLACESTRING:
+ rVal <<= m_aSearchOpt.replaceString; break;
+ case MID_SEARCH_CHANGEDCHARS:
+ rVal <<= m_aSearchOpt.changedChars; break;
+ case MID_SEARCH_DELETEDCHARS:
+ rVal <<= m_aSearchOpt.deletedChars; break;
+ case MID_SEARCH_INSERTEDCHARS:
+ rVal <<= m_aSearchOpt.insertedChars; break;
+ case MID_SEARCH_TRANSLITERATEFLAGS:
+ rVal <<= static_cast<sal_Int32>(m_aSearchOpt.transliterateFlags); break;
+ case MID_SEARCH_LOCALE:
+ {
+ LanguageType nLocale;
+ if (!m_aSearchOpt.Locale.Language.isEmpty() || !m_aSearchOpt.Locale.Country.isEmpty() )
+ nLocale = LanguageTag::convertToLanguageType( m_aSearchOpt.Locale );
+ else
+ nLocale = LANGUAGE_NONE;
+ rVal <<= static_cast<sal_Int16>(static_cast<sal_uInt16>(nLocale));
+ break;
+ }
+
+ default:
+ SAL_WARN( "svl.items", "SvxSearchItem::QueryValue(): Unknown MemberId" );
+ return false;
+ }
+
+ return true;
+}
+
+
+bool SvxSearchItem::PutValue( const css::uno::Any& rVal, sal_uInt8 nMemberId )
+{
+ nMemberId &= ~CONVERT_TWIPS;
+ bool bRet = false;
+ sal_Int32 nInt = 0;
+ switch ( nMemberId )
+ {
+ case 0 :
+ {
+ Sequence< PropertyValue > aSeq;
+ if ( ( rVal >>= aSeq ) && ( aSeq.getLength() == SRCH_PARAMS ) )
+ {
+ sal_Int16 nConvertedCount( 0 );
+ for ( const auto& rProp : std::as_const(aSeq) )
+ {
+ if ( rProp.Name == SRCH_PARA_OPTIONS )
+ {
+ css::util::SearchOptions2 nTmpSearchOpt2;
+ if ( rProp.Value >>= nTmpSearchOpt2 )
+ {
+ m_aSearchOpt = nTmpSearchOpt2;
+ ++nConvertedCount;
+ }
+ }
+ else if ( rProp.Name == SRCH_PARA_FAMILY )
+ {
+ sal_uInt16 nTemp( 0 );
+ if ( rProp.Value >>= nTemp )
+ {
+ m_eFamily = SfxStyleFamily( nTemp );
+ ++nConvertedCount;
+ }
+ }
+ else if ( rProp.Name == SRCH_PARA_COMMAND )
+ {
+ sal_uInt16 nTmp;
+ if ( rProp.Value >>= nTmp )
+ {
+ m_nCommand = static_cast<SvxSearchCmd>(nTmp);
+ ++nConvertedCount;
+ }
+ }
+ else if ( rProp.Name == SRCH_PARA_CELLTYPE )
+ {
+ sal_uInt16 nTmp;
+ if ( rProp.Value >>= nTmp )
+ {
+ m_nCellType = static_cast<SvxSearchCellType>(nTmp);
+ ++nConvertedCount;
+ }
+ }
+ else if ( rProp.Name == SRCH_PARA_APPFLAG )
+ {
+ sal_uInt16 nTmp;
+ if ( rProp.Value >>= nTmp )
+ {
+ m_nAppFlag = static_cast<SvxSearchApp>(nTmp);
+ ++nConvertedCount;
+ }
+ }
+ else if ( rProp.Name == SRCH_PARA_ROWDIR )
+ {
+ if ( rProp.Value >>= m_bRowDirection )
+ ++nConvertedCount;
+ }
+ else if ( rProp.Name == SRCH_PARA_ALLTABLES )
+ {
+ if ( rProp.Value >>= m_bAllTables )
+ ++nConvertedCount;
+ }
+ else if ( rProp.Name == SRCH_PARA_SEARCHFILTERED )
+ {
+ if ( rProp.Value >>= m_bSearchFiltered )
+ ++nConvertedCount;
+ }
+ else if ( rProp.Name == SRCH_PARA_SEARCHFORMATTED )
+ {
+ if ( rProp.Value >>= m_bSearchFormatted )
+ ++nConvertedCount;
+ }
+ else if ( rProp.Name == SRCH_PARA_BACKWARD )
+ {
+ if ( rProp.Value >>= m_bBackward )
+ ++nConvertedCount;
+ }
+ else if ( rProp.Name == SRCH_PARA_PATTERN )
+ {
+ if ( rProp.Value >>= m_bPattern )
+ ++nConvertedCount;
+ }
+ else if ( rProp.Name == SRCH_PARA_CONTENT )
+ {
+ if ( rProp.Value >>= m_bContent )
+ ++nConvertedCount;
+ }
+ else if ( rProp.Name == SRCH_PARA_ASIANOPT )
+ {
+ if ( rProp.Value >>= m_bAsianOptions )
+ ++nConvertedCount;
+ }
+ }
+
+ bRet = ( nConvertedCount == SRCH_PARAMS );
+ }
+ break;
+ }
+ case MID_SEARCH_COMMAND:
+ bRet = (rVal >>= nInt); m_nCommand = static_cast<SvxSearchCmd>(nInt); break;
+ case MID_SEARCH_STYLEFAMILY:
+ bRet = (rVal >>= nInt); m_eFamily = static_cast<SfxStyleFamily>(static_cast<sal_Int16>(nInt)); break;
+ case MID_SEARCH_CELLTYPE:
+ bRet = (rVal >>= nInt); m_nCellType = static_cast<SvxSearchCellType>(nInt); break;
+ case MID_SEARCH_ROWDIRECTION:
+ bRet = (rVal >>= m_bRowDirection); break;
+ case MID_SEARCH_ALLTABLES:
+ bRet = (rVal >>= m_bAllTables); break;
+ case MID_SEARCH_SEARCHFILTERED:
+ bRet = (rVal >>= m_bSearchFiltered); break;
+ case MID_SEARCH_SEARCHFORMATTED:
+ bRet = (rVal >>= m_bSearchFormatted); break;
+ case MID_SEARCH_BACKWARD:
+ bRet = (rVal >>= m_bBackward); break;
+ case MID_SEARCH_PATTERN:
+ bRet = (rVal >>= m_bPattern); break;
+ case MID_SEARCH_CONTENT:
+ bRet = (rVal >>= m_bContent); break;
+ case MID_SEARCH_ASIANOPTIONS:
+ bRet = (rVal >>= m_bAsianOptions); break;
+ case MID_SEARCH_ALGORITHMTYPE:
+ bRet = (rVal >>= nInt); m_aSearchOpt.algorithmType = static_cast<SearchAlgorithms>(static_cast<sal_Int16>(nInt)); break;
+ case MID_SEARCH_ALGORITHMTYPE2:
+ bRet = (rVal >>= nInt); m_aSearchOpt.AlgorithmType2 = static_cast<sal_Int16>(nInt); break;
+ case MID_SEARCH_FLAGS:
+ bRet = (rVal >>= m_aSearchOpt.searchFlag); break;
+ case MID_SEARCH_SEARCHSTRING:
+ bRet = (rVal >>= m_aSearchOpt.searchString); break;
+ case MID_SEARCH_REPLACESTRING:
+ bRet = (rVal >>= m_aSearchOpt.replaceString); break;
+ case MID_SEARCH_CHANGEDCHARS:
+ bRet = (rVal >>= m_aSearchOpt.changedChars); break;
+ case MID_SEARCH_DELETEDCHARS:
+ bRet = (rVal >>= m_aSearchOpt.deletedChars); break;
+ case MID_SEARCH_INSERTEDCHARS:
+ bRet = (rVal >>= m_aSearchOpt.insertedChars); break;
+ case MID_SEARCH_TRANSLITERATEFLAGS:
+ {
+ bRet = (rVal >>= nInt);
+ if (bRet)
+ m_aSearchOpt.transliterateFlags = static_cast<TransliterationFlags>(nInt);
+ break;
+ }
+ case MID_SEARCH_LOCALE:
+ {
+ bRet = (rVal >>= nInt);
+ if ( bRet )
+ {
+ if ( LanguageType(nInt) == LANGUAGE_NONE )
+ {
+ m_aSearchOpt.Locale = css::lang::Locale();
+ }
+ else
+ {
+ m_aSearchOpt.Locale = LanguageTag::convertToLocale( LanguageType(nInt) );
+ }
+ }
+ break;
+ }
+ case MID_SEARCH_STARTPOINTX:
+ {
+ bRet = (rVal >>= m_nStartPointX);
+ break;
+ }
+ case MID_SEARCH_STARTPOINTY:
+ {
+ bRet = (rVal >>= m_nStartPointY);
+ break;
+ }
+ default:
+ OSL_FAIL( "Unknown MemberId" );
+ }
+
+ return bRet;
+}
+
+sal_Int32 SvxSearchItem::GetStartPointX() const
+{
+ return m_nStartPointX;
+}
+
+sal_Int32 SvxSearchItem::GetStartPointY() const
+{
+ return m_nStartPointY;
+}
+
+bool SvxSearchItem::HasStartPoint() const
+{
+ return m_nStartPointX > 0 || m_nStartPointY > 0;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svl/source/items/stringio.cxx b/svl/source/items/stringio.cxx
new file mode 100644
index 000000000..98b1cb707
--- /dev/null
+++ b/svl/source/items/stringio.cxx
@@ -0,0 +1,35 @@
+/* -*- 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 <stringio.hxx>
+
+#include <tools/stream.hxx>
+
+
+OUString readByteString(SvStream& rStream)
+{
+ return rStream.ReadUniOrByteString(rStream.GetStreamCharSet());
+}
+
+void writeByteString(SvStream & rStream, const OUString& rString)
+{
+ rStream.WriteUniOrByteString(rString, rStream.GetStreamCharSet());
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svl/source/items/stritem.cxx b/svl/source/items/stritem.cxx
new file mode 100644
index 000000000..86e2087cd
--- /dev/null
+++ b/svl/source/items/stritem.cxx
@@ -0,0 +1,42 @@
+/* -*- 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 <svl/stritem.hxx>
+#include <libxml/xmlwriter.h>
+
+// virtual
+SfxStringItem* SfxStringItem::Clone(SfxItemPool *) const
+{
+ return new SfxStringItem(*this);
+}
+
+void SfxStringItem::dumpAsXml(xmlTextWriterPtr pWriter) const
+{
+ xmlTextWriterStartElement(pWriter, BAD_CAST("SfxStringItem"));
+ xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr()));
+ xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"), BAD_CAST(GetValue().toUtf8().getStr()));
+ xmlTextWriterEndElement(pWriter);
+}
+
+SfxPoolItem* SfxStringItem::CreateDefault()
+{
+ return new SfxStringItem();
+};
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svl/source/items/style.cxx b/svl/source/items/style.cxx
new file mode 100644
index 000000000..db0ee8d42
--- /dev/null
+++ b/svl/source/items/style.cxx
@@ -0,0 +1,943 @@
+/* -*- 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 <memory>
+#include <svl/style.hxx>
+
+#include <com/sun/star/lang/XComponent.hpp>
+
+#include <sal/log.hxx>
+#include <osl/diagnose.h>
+#include <unotools/intlwrapper.hxx>
+#include <svl/hint.hxx>
+#include <svl/poolitem.hxx>
+#include <svl/itemset.hxx>
+#include <svl/itempool.hxx>
+#include <svl/IndexedStyleSheets.hxx>
+#include <svl/itemiter.hxx>
+#include <unotools/syslocale.hxx>
+#include <comphelper/servicehelper.hxx>
+#include <rtl/ustrbuf.hxx>
+
+#include <string.h>
+
+#ifdef DBG_UTIL
+namespace {
+
+class DbgStyleSheetReferences
+{
+public:
+ DbgStyleSheetReferences() : mnStyles(0), mnPools(0) {}
+ ~DbgStyleSheetReferences()
+ {
+ SAL_WARN_IF(
+ mnStyles != 0 || mnPools != 0, "svl.items",
+ "SfxStyleSheetBase left " << mnStyles
+ << "; SfxStyleSheetBasePool left " << mnPools);
+ }
+
+ sal_uInt32 mnStyles;
+ sal_uInt32 mnPools;
+};
+
+}
+
+static DbgStyleSheetReferences aDbgStyleSheetReferences;
+#endif
+
+
+SfxStyleSheetModifiedHint::SfxStyleSheetModifiedHint
+(
+ const OUString& rOldName,
+ SfxStyleSheetBase& rStyleSheet // Remains with the caller
+)
+: SfxStyleSheetHint( SfxHintId::StyleSheetModified, rStyleSheet ),
+ aName( rOldName )
+{}
+
+
+SfxStyleSheetHint::SfxStyleSheetHint
+(
+ SfxHintId nAction,
+ SfxStyleSheetBase& rStyleSheet // Remains with the caller
+)
+: SfxHint(nAction), pStyleSh( &rStyleSheet )
+{}
+
+
+class SfxStyleSheetBasePool_Impl
+{
+private:
+ SfxStyleSheetBasePool_Impl(const SfxStyleSheetBasePool_Impl&) = delete;
+ SfxStyleSheetBasePool_Impl& operator=(const SfxStyleSheetBasePool_Impl&) = delete;
+public:
+ std::shared_ptr<SfxStyleSheetIterator> pIter;
+
+ /** This member holds the indexed style sheets.
+ *
+ * @internal
+ * This member is private and not protected in order to have more control which style sheets are added
+ * where. Ideally, all calls which add/remove/change style sheets are done in the base class.
+ */
+ std::shared_ptr<svl::IndexedStyleSheets> mxIndexedStyleSheets;
+
+ SfxStyleSheetBasePool_Impl() :
+ mxIndexedStyleSheets(std::make_shared<svl::IndexedStyleSheets>()) {}
+};
+
+
+SfxStyleSheetBase::SfxStyleSheetBase( const OUString& rName, SfxStyleSheetBasePool* p, SfxStyleFamily eFam, SfxStyleSearchBits mask )
+ : m_pPool( p )
+ , nFamily( eFam )
+ , aName( rName )
+ , aParent()
+ , aFollow( rName )
+ , pSet( nullptr )
+ , nMask(mask)
+ , nHelpId( 0 )
+ , bMySet( false )
+ , bHidden( false )
+{
+#ifdef DBG_UTIL
+ aDbgStyleSheetReferences.mnStyles++;
+#endif
+}
+
+SfxStyleSheetBase::SfxStyleSheetBase( const SfxStyleSheetBase& r )
+ : comphelper::OWeakTypeObject(r)
+ , m_pPool( r.m_pPool )
+ , nFamily( r.nFamily )
+ , aName( r.aName )
+ , aParent( r.aParent )
+ , aFollow( r.aFollow )
+ , aHelpFile( r.aHelpFile )
+ , nMask( r.nMask )
+ , nHelpId( r.nHelpId )
+ , bMySet( r.bMySet )
+ , bHidden( r.bHidden )
+{
+#ifdef DBG_UTIL
+ aDbgStyleSheetReferences.mnStyles++;
+#endif
+ if( r.pSet )
+ pSet = bMySet ? new SfxItemSet( *r.pSet ) : r.pSet;
+ else
+ pSet = nullptr;
+}
+
+SfxStyleSheetBase::~SfxStyleSheetBase()
+{
+#ifdef DBG_UTIL
+ --aDbgStyleSheetReferences.mnStyles;
+#endif
+
+ if( bMySet )
+ {
+ delete pSet;
+ pSet = nullptr;
+ }
+}
+
+// Change name
+const OUString& SfxStyleSheetBase::GetName() const
+{
+ return aName;
+}
+
+bool SfxStyleSheetBase::SetName(const OUString& rName, bool bReIndexNow)
+{
+ if(rName.isEmpty())
+ return false;
+
+ if( aName != rName )
+ {
+ OUString aOldName = aName;
+ SfxStyleSheetBase *pOther = m_pPool->Find( rName, nFamily ) ;
+ if ( pOther && pOther != this )
+ return false;
+
+ if ( !aName.isEmpty() )
+ m_pPool->ChangeParent(aName, rName, nFamily, false);
+
+ if ( aFollow == aName )
+ aFollow = rName;
+ aName = rName;
+ if (bReIndexNow)
+ m_pPool->Reindex();
+
+ m_pPool->Broadcast( SfxStyleSheetModifiedHint( aOldName, *this ) );
+ }
+ return true;
+}
+
+// Change Parent
+const OUString& SfxStyleSheetBase::GetParent() const
+{
+ return aParent;
+}
+
+bool SfxStyleSheetBase::SetParent( const OUString& rName )
+{
+ if ( rName == aName )
+ return false;
+
+ if( aParent != rName )
+ {
+ SfxStyleSheetBase* pIter = m_pPool->Find(rName, nFamily);
+ if( !rName.isEmpty() && !pIter )
+ {
+ OSL_FAIL( "StyleSheet-Parent not found" );
+ return false;
+ }
+ // prevent recursive linkages
+ if( !aName.isEmpty() )
+ {
+ while(pIter)
+ {
+ if(pIter->GetName() == aName)
+ return false;
+ pIter = m_pPool->Find(pIter->GetParent(), nFamily);
+ }
+ }
+ aParent = rName;
+ }
+ m_pPool->Broadcast( SfxStyleSheetHint( SfxHintId::StyleSheetModified, *this ) );
+ return true;
+}
+
+void SfxStyleSheetBase::SetHidden( bool hidden )
+{
+ bHidden = hidden;
+ m_pPool->Broadcast( SfxStyleSheetHint( SfxHintId::StyleSheetModified, *this ) );
+}
+
+/**
+ * Change follow
+ */
+const OUString& SfxStyleSheetBase::GetFollow() const
+{
+ return aFollow;
+}
+
+bool SfxStyleSheetBase::SetFollow( const OUString& rName )
+{
+ if( aFollow != rName )
+ {
+ if( !m_pPool->Find( rName, nFamily ) )
+ {
+ SAL_WARN( "svl.items", "StyleSheet-Follow not found" );
+ return false;
+ }
+ aFollow = rName;
+ }
+ m_pPool->Broadcast( SfxStyleSheetHint( SfxHintId::StyleSheetModified, *this ) );
+ return true;
+}
+
+/**
+ * Set Itemset
+ * The default implementation creates a new set
+ */
+SfxItemSet& SfxStyleSheetBase::GetItemSet()
+{
+ if( !pSet )
+ {
+ pSet = new SfxItemSet( m_pPool->GetPool() );
+ bMySet = true;
+ }
+ return *pSet;
+}
+
+std::unique_ptr<SfxItemSet> SfxStyleSheetBase::GetItemSetForPreview()
+{
+ return std::make_unique<SfxItemSet>(GetItemSet());
+}
+
+/**
+ * Set help file and ID and return it
+ */
+sal_uLong SfxStyleSheetBase::GetHelpId( OUString& rFile )
+{
+ rFile = aHelpFile;
+ return nHelpId;
+}
+
+void SfxStyleSheetBase::SetHelpId( const OUString& rFile, sal_uLong nId )
+{
+ aHelpFile = rFile;
+ nHelpId = nId;
+}
+
+/**
+ * Next style possible?
+ * Default: Yes
+ */
+bool SfxStyleSheetBase::HasFollowSupport() const
+{
+ return true;
+}
+
+/**
+ * Base template possible?
+ * Default: Yes
+ */
+bool SfxStyleSheetBase::HasParentSupport() const
+{
+ return true;
+}
+
+/**
+ * Setting base template to NULL possible?
+ * Default: No
+ */
+bool SfxStyleSheetBase::HasClearParentSupport() const
+{
+ return false;
+}
+
+/**
+ * By default all stylesheets are set to used
+ */
+bool SfxStyleSheetBase::IsUsed() const
+{
+ return true;
+}
+
+/**
+ * Return set attributes
+ */
+OUString SfxStyleSheetBase::GetDescription( MapUnit eMetric )
+{
+ SfxItemIter aIter( GetItemSet() );
+ OUStringBuffer aDesc;
+
+ IntlWrapper aIntlWrapper(SvtSysLocale().GetUILanguageTag());
+ for (const SfxPoolItem* pItem = aIter.GetCurItem(); pItem; pItem = aIter.NextItem())
+ {
+ OUString aItemPresentation;
+
+ if ( !IsInvalidItem( pItem ) &&
+ m_pPool->GetPool().GetPresentation(
+ *pItem, eMetric, aItemPresentation, aIntlWrapper ) )
+ {
+ if ( !aDesc.isEmpty() && !aItemPresentation.isEmpty() )
+ aDesc.append(" + ");
+ if ( !aItemPresentation.isEmpty() )
+ aDesc.append(aItemPresentation);
+ }
+ }
+ return aDesc.makeStringAndClear();
+}
+
+SfxStyleFamily SfxStyleSheetIterator::GetSearchFamily() const
+{
+ return nSearchFamily;
+}
+
+inline bool SfxStyleSheetIterator::IsTrivialSearch() const
+{
+ return (( nMask & SfxStyleSearchBits::AllVisible ) == SfxStyleSearchBits::AllVisible) &&
+ (GetSearchFamily() == SfxStyleFamily::All);
+}
+
+namespace {
+
+struct DoesStyleMatchStyleSheetPredicate final : public svl::StyleSheetPredicate
+{
+ explicit DoesStyleMatchStyleSheetPredicate(SfxStyleSheetIterator *it)
+ : mIterator(it) {}
+
+ bool
+ Check(const SfxStyleSheetBase& styleSheet) override
+ {
+ bool bMatchFamily = ((mIterator->GetSearchFamily() == SfxStyleFamily::All) ||
+ ( styleSheet.GetFamily() == mIterator->GetSearchFamily() ));
+
+ bool bUsed = mIterator->SearchUsed() && styleSheet.IsUsed( );
+
+ bool bSearchHidden( mIterator->GetSearchMask() & SfxStyleSearchBits::Hidden );
+ bool bMatchVisibility = !( !bSearchHidden && styleSheet.IsHidden() && !bUsed );
+ bool bOnlyHidden = mIterator->GetSearchMask( ) == SfxStyleSearchBits::Hidden && styleSheet.IsHidden( );
+
+ bool bMatches = bMatchFamily && bMatchVisibility
+ && (( styleSheet.GetMask() & ( mIterator->GetSearchMask() & ~SfxStyleSearchBits::Used )) ||
+ bUsed || bOnlyHidden ||
+ ( mIterator->GetSearchMask() & SfxStyleSearchBits::AllVisible ) == SfxStyleSearchBits::AllVisible );
+ return bMatches;
+ }
+
+ SfxStyleSheetIterator *mIterator;
+};
+
+}
+
+SfxStyleSheetIterator::SfxStyleSheetIterator(SfxStyleSheetBasePool *pBase,
+ SfxStyleFamily eFam, SfxStyleSearchBits n)
+ : pCurrentStyle(nullptr)
+ , nCurrentPosition(0)
+{
+ pBasePool=pBase;
+ nSearchFamily=eFam;
+ bSearchUsed=false;
+ if( (( n & SfxStyleSearchBits::AllVisible ) != SfxStyleSearchBits::AllVisible )
+ && ((n & SfxStyleSearchBits::Used) == SfxStyleSearchBits::Used))
+ {
+ bSearchUsed = true;
+ n &= ~SfxStyleSearchBits::Used;
+ }
+ nMask=n;
+}
+
+SfxStyleSheetIterator::~SfxStyleSheetIterator()
+{
+}
+
+sal_uInt16 SfxStyleSheetIterator::Count()
+{
+ sal_uInt16 n = 0;
+ if( IsTrivialSearch())
+ {
+ n = static_cast<sal_uInt16>(pBasePool->pImpl->mxIndexedStyleSheets->GetNumberOfStyleSheets());
+ }
+ else if(nMask == SfxStyleSearchBits::All)
+ {
+ n = static_cast<sal_uInt16>(pBasePool->pImpl->mxIndexedStyleSheets->GetStyleSheetPositionsByFamily(nSearchFamily).size());
+ }
+ else
+ {
+ DoesStyleMatchStyleSheetPredicate predicate(this);
+ n = pBasePool->pImpl->mxIndexedStyleSheets->GetNumberOfStyleSheetsWithPredicate(predicate);
+ }
+ return n;
+}
+
+SfxStyleSheetBase* SfxStyleSheetIterator::operator[](sal_uInt16 nIdx)
+{
+ SfxStyleSheetBase* retval = nullptr;
+ if( IsTrivialSearch())
+ {
+ retval = pBasePool->pImpl->mxIndexedStyleSheets->GetStyleSheetByPosition(nIdx);
+ nCurrentPosition = nIdx;
+ }
+ else if(nMask == SfxStyleSearchBits::All)
+ {
+ rtl::Reference< SfxStyleSheetBase > ref =
+ pBasePool->pImpl->mxIndexedStyleSheets->GetStyleSheetByPosition(
+ pBasePool->pImpl->mxIndexedStyleSheets->GetStyleSheetPositionsByFamily(nSearchFamily).at(nIdx))
+ ;
+ retval = ref.get();
+ nCurrentPosition = nIdx;
+ }
+ else
+ {
+ DoesStyleMatchStyleSheetPredicate predicate(this);
+ rtl::Reference< SfxStyleSheetBase > ref =
+ pBasePool->pImpl->mxIndexedStyleSheets->GetNthStyleSheetThatMatchesPredicate(nIdx, predicate);
+ if (ref.get() != nullptr)
+ {
+ nCurrentPosition = pBasePool->pImpl->mxIndexedStyleSheets->FindStyleSheetPosition(*ref);
+ retval = ref.get();
+ }
+ }
+
+ if (retval == nullptr)
+ {
+ OSL_FAIL("Incorrect index");
+ }
+
+ return retval;
+}
+
+SfxStyleSheetBase* SfxStyleSheetIterator::First()
+{
+ if (Count() != 0) {
+ return operator[](0);
+ }
+ else {
+ return nullptr;
+ }
+}
+
+SfxStyleSheetBase* SfxStyleSheetIterator::Next()
+{
+ SfxStyleSheetBase* retval = nullptr;
+
+ if ( IsTrivialSearch() )
+ {
+ unsigned nStyleSheets = pBasePool->pImpl->mxIndexedStyleSheets->GetNumberOfStyleSheets();
+ unsigned newPosition = nCurrentPosition +1;
+ if (nStyleSheets > newPosition)
+ {
+ nCurrentPosition = newPosition;
+ retval = pBasePool->pImpl->mxIndexedStyleSheets->GetStyleSheetByPosition(nCurrentPosition);
+ }
+ }
+ else if(nMask == SfxStyleSearchBits::All)
+ {
+ unsigned newPosition = nCurrentPosition +1;
+ const std::vector<unsigned>& familyVector =
+ pBasePool->pImpl->mxIndexedStyleSheets->GetStyleSheetPositionsByFamily(nSearchFamily);
+ if (familyVector.size() > newPosition)
+ {
+ nCurrentPosition = newPosition;
+ unsigned stylePosition = familyVector[newPosition];
+ retval = pBasePool->pImpl->mxIndexedStyleSheets->GetStyleSheetByPosition(stylePosition);
+ }
+ }
+ else
+ {
+ DoesStyleMatchStyleSheetPredicate predicate(this);
+ rtl::Reference< SfxStyleSheetBase > ref =
+ pBasePool->pImpl->mxIndexedStyleSheets->GetNthStyleSheetThatMatchesPredicate(
+ 0, predicate, nCurrentPosition+1);
+ retval = ref.get();
+ if (retval != nullptr) {
+ nCurrentPosition = pBasePool->pImpl->mxIndexedStyleSheets->FindStyleSheetPosition(*ref);
+ }
+ }
+ pCurrentStyle = retval;
+ return retval;
+}
+
+SfxStyleSheetBase* SfxStyleSheetIterator::Find(const OUString& rStr)
+{
+ DoesStyleMatchStyleSheetPredicate predicate(this);
+
+ std::vector<unsigned> positions =
+ pBasePool->pImpl->mxIndexedStyleSheets->FindPositionsByNameAndPredicate(rStr, predicate,
+ svl::IndexedStyleSheets::SearchBehavior::ReturnFirst);
+ if (positions.empty()) {
+ return nullptr;
+ }
+
+ unsigned pos = positions.front();
+ SfxStyleSheetBase* pStyle = pBasePool->pImpl->mxIndexedStyleSheets->GetStyleSheetByPosition(pos);
+ nCurrentPosition = pos;
+ pCurrentStyle = pStyle;
+ return pCurrentStyle;
+}
+
+SfxStyleSearchBits SfxStyleSheetIterator::GetSearchMask() const
+{
+ SfxStyleSearchBits mask = nMask;
+
+ if ( bSearchUsed )
+ mask |= SfxStyleSearchBits::Used;
+ return mask;
+}
+
+SfxStyleSheetIterator* SfxStyleSheetBasePool::GetCachedIterator()
+{
+ return pImpl->pIter.get();
+}
+
+SfxStyleSheetIterator& SfxStyleSheetBasePool::GetIterator_Impl(SfxStyleFamily eFamily, SfxStyleSearchBits eMask)
+{
+ if (!pImpl->pIter || (pImpl->pIter->GetSearchMask() != eMask) || (pImpl->pIter->GetSearchFamily() != eFamily))
+ pImpl->pIter = CreateIterator(eFamily, eMask);
+ return *pImpl->pIter;
+}
+
+SfxStyleSheetBasePool::SfxStyleSheetBasePool( SfxItemPool& r ) :
+ pImpl(new SfxStyleSheetBasePool_Impl),
+ rPool(r)
+{
+#ifdef DBG_UTIL
+ aDbgStyleSheetReferences.mnPools++;
+#endif
+}
+
+SfxStyleSheetBasePool::SfxStyleSheetBasePool( const SfxStyleSheetBasePool& r ) :
+ SfxBroadcaster( r ),
+ comphelper::OWeakTypeObject(r),
+ pImpl(new SfxStyleSheetBasePool_Impl),
+ rPool(r.rPool)
+{
+#ifdef DBG_UTIL
+ aDbgStyleSheetReferences.mnPools++;
+#endif
+
+ *this += r;
+}
+
+SfxStyleSheetBasePool::~SfxStyleSheetBasePool()
+{
+#ifdef DBG_UTIL
+ aDbgStyleSheetReferences.mnPools--;
+#endif
+
+ Broadcast( SfxHint(SfxHintId::Dying) );
+ Clear();
+}
+
+bool SfxStyleSheetBasePool::SetParent(SfxStyleFamily eFam, const OUString& rStyle, const OUString& rParent)
+{
+ SfxStyleSheetIterator aIter(this, eFam, SfxStyleSearchBits::All);
+ SfxStyleSheetBase *pStyle = aIter.Find(rStyle);
+ OSL_ENSURE(pStyle, "Template not found. Writer with solar <2541?");
+ if(pStyle)
+ return pStyle->SetParent(rParent);
+ else
+ return false;
+}
+
+std::unique_ptr<SfxStyleSheetIterator> SfxStyleSheetBasePool::CreateIterator
+(
+ SfxStyleFamily eFam,
+ SfxStyleSearchBits mask
+)
+{
+ return std::make_unique<SfxStyleSheetIterator>(this,eFam,mask);
+}
+
+SfxStyleSheetBase* SfxStyleSheetBasePool::Create
+(
+ const OUString& rName,
+ SfxStyleFamily eFam,
+ SfxStyleSearchBits mask
+)
+{
+ return new SfxStyleSheetBase( rName, this, eFam, mask );
+}
+
+SfxStyleSheetBase* SfxStyleSheetBasePool::Create( const SfxStyleSheetBase& r )
+{
+ return new SfxStyleSheetBase( r );
+}
+
+SfxStyleSheetBase& SfxStyleSheetBasePool::Make( const OUString& rName, SfxStyleFamily eFam, SfxStyleSearchBits mask)
+{
+ OSL_ENSURE( eFam != SfxStyleFamily::All, "svl::SfxStyleSheetBasePool::Make(), FamilyAll is not an allowed Family" );
+
+ SfxStyleSheetIterator aIter(this, eFam, mask);
+ rtl::Reference< SfxStyleSheetBase > xStyle( aIter.Find( rName ) );
+ OSL_ENSURE( !xStyle.is(), "svl::SfxStyleSheetBasePool::Make(), StyleSheet already exists" );
+
+ if( !xStyle.is() )
+ {
+ xStyle = Create( rName, eFam, mask );
+ StoreStyleSheet(xStyle);
+ Broadcast(SfxStyleSheetHint(SfxHintId::StyleSheetCreated, *xStyle));
+ }
+ return *xStyle;
+}
+
+/**
+ * Helper function: If a template with this name exists it is created
+ * anew. All templates that have this template as a parent are reconnected.
+ */
+void SfxStyleSheetBasePool::Add( const SfxStyleSheetBase& rSheet )
+{
+ SfxStyleSheetIterator aIter(this, rSheet.GetFamily(), SfxStyleSearchBits::All);
+ SfxStyleSheetBase* pOld = aIter.Find( rSheet.GetName() );
+ if (pOld) {
+ Remove( pOld );
+ }
+ rtl::Reference< SfxStyleSheetBase > xNew( Create( rSheet ) );
+ pImpl->mxIndexedStyleSheets->AddStyleSheet(xNew);
+ Broadcast(SfxStyleSheetHint(SfxHintId::StyleSheetChanged, *xNew));
+}
+
+SfxStyleSheetBasePool& SfxStyleSheetBasePool::operator=( const SfxStyleSheetBasePool& r )
+{
+ if( &r != this )
+ {
+ Clear();
+ *this += r;
+ }
+ return *this;
+}
+
+namespace {
+struct AddStyleSheetCallback : svl::StyleSheetCallback
+{
+ explicit AddStyleSheetCallback(SfxStyleSheetBasePool *pool)
+ : mPool(pool) {}
+
+ void DoIt(const SfxStyleSheetBase& ssheet) override
+ {
+ mPool->Add(ssheet);
+ }
+
+ SfxStyleSheetBasePool *mPool;
+};
+}
+
+SfxStyleSheetBasePool& SfxStyleSheetBasePool::operator+=( const SfxStyleSheetBasePool& r )
+{
+ if( &r != this )
+ {
+ AddStyleSheetCallback callback(this);
+ pImpl->mxIndexedStyleSheets->ApplyToAllStyleSheets(callback);
+ }
+ return *this;
+}
+
+SfxStyleSheetBase* SfxStyleSheetBasePool::Find(const OUString& rName,
+ SfxStyleFamily eFamily,
+ SfxStyleSearchBits eMask)
+{
+ SfxStyleSheetIterator aIter(this, eFamily, eMask);
+ return aIter.Find(rName);
+}
+
+SfxStyleSheetBase* SfxStyleSheetBasePool::First(SfxStyleFamily eFamily, SfxStyleSearchBits eMask)
+{
+ return GetIterator_Impl(eFamily, eMask).First();
+}
+
+SfxStyleSheetBase* SfxStyleSheetBasePool::Next()
+{
+ assert(pImpl->pIter && "Next called without a previous First");
+ return pImpl->pIter->Next();
+}
+
+void SfxStyleSheetBasePool::Remove( SfxStyleSheetBase* p )
+{
+ if( !p )
+ return;
+
+ // Reference to keep p alive until after Broadcast call!
+ rtl::Reference<SfxStyleSheetBase> xP(p);
+ bool bWasRemoved = pImpl->mxIndexedStyleSheets->RemoveStyleSheet(xP);
+ if( !bWasRemoved )
+ return;
+
+ // Adapt all styles which have this style as parent
+ ChangeParent(p->GetName(), p->GetParent(), p->GetFamily());
+
+ // #120015# Do not dispose, the removed StyleSheet may still be used in
+ // existing SdrUndoAttrObj incarnations. Rely on refcounting for disposal,
+ // this works well under normal conditions (checked breaking and counting
+ // on SfxStyleSheetBase constructors and destructors)
+
+ // css::uno::Reference< css::lang::XComponent > xComp( static_cast< ::cppu::OWeakObject* >((*aIter).get()), css::uno::UNO_QUERY );
+ // if( xComp.is() ) try
+ // {
+ // xComp->dispose();
+ // }
+ // catch( css::uno::Exception& )
+ // {
+ // }
+ Broadcast( SfxStyleSheetHint( SfxHintId::StyleSheetErased, *p ) );
+}
+
+void SfxStyleSheetBasePool::Insert( SfxStyleSheetBase* p )
+{
+#if OSL_DEBUG_LEVEL > 0
+ OSL_ENSURE( p, "svl::SfxStyleSheetBasePool::Insert(), no stylesheet?" );
+
+ SfxStyleSheetIterator aIter(this, p->GetFamily(), p->GetMask());
+ SfxStyleSheetBase* pOld = aIter.Find( p->GetName() );
+ OSL_ENSURE( !pOld, "svl::SfxStyleSheetBasePool::Insert(), StyleSheet already inserted" );
+ if( !p->GetParent().isEmpty() )
+ {
+ pOld = aIter.Find( p->GetParent() );
+ OSL_ENSURE( pOld, "svl::SfxStyleSheetBasePool::Insert(), Parent not found!" );
+ }
+#endif
+ StoreStyleSheet(rtl::Reference< SfxStyleSheetBase >( p ) );
+ Broadcast( SfxStyleSheetHint( SfxHintId::StyleSheetCreated, *p ) );
+}
+
+namespace
+{
+
+struct StyleSheetDisposerFunctor final : public svl::StyleSheetDisposer
+{
+ explicit StyleSheetDisposerFunctor(SfxStyleSheetBasePool* pool)
+ : mPool(pool) {}
+
+ void
+ Dispose(rtl::Reference<SfxStyleSheetBase> styleSheet) override
+ {
+ cppu::OWeakObject* weakObject = styleSheet.get();
+ css::uno::Reference< css::lang::XComponent > xComp( weakObject, css::uno::UNO_QUERY );
+ if( xComp.is() ) try
+ {
+ xComp->dispose();
+ }
+ catch( css::uno::Exception& )
+ {
+ }
+ mPool->Broadcast(SfxStyleSheetHint(SfxHintId::StyleSheetErased, *styleSheet));
+ }
+
+ SfxStyleSheetBasePool* mPool;
+};
+
+}
+
+void SfxStyleSheetBasePool::Clear()
+{
+ StyleSheetDisposerFunctor cleanup(this);
+ pImpl->mxIndexedStyleSheets->Clear(cleanup);
+}
+
+void SfxStyleSheetBasePool::ChangeParent(const OUString& rOld,
+ const OUString& rNew,
+ SfxStyleFamily eFamily,
+ bool bVirtual)
+{
+ for( SfxStyleSheetBase* p = First(eFamily); p; p = Next() )
+ {
+ if( p->GetParent() == rOld )
+ {
+ if(bVirtual)
+ p->SetParent( rNew );
+ else
+ p->aParent = rNew;
+ }
+ }
+}
+
+SfxStyleSheet::SfxStyleSheet(const OUString &rName,
+ const SfxStyleSheetBasePool& r_Pool,
+ SfxStyleFamily eFam,
+ SfxStyleSearchBits mask )
+ : SfxStyleSheetBase(rName, const_cast< SfxStyleSheetBasePool* >( &r_Pool ), eFam, mask)
+{
+}
+
+SfxStyleSheet::SfxStyleSheet(const SfxStyleSheet& rStyle)
+ : SfxStyleSheetBase(rStyle)
+ , SfxListener( rStyle )
+ , SfxBroadcaster( rStyle )
+ , svl::StyleSheetUser()
+{
+}
+
+SfxStyleSheet::~SfxStyleSheet()
+{
+ Broadcast( SfxStyleSheetHint( SfxHintId::StyleSheetInDestruction, *this ) );
+}
+
+
+bool SfxStyleSheet::SetParent( const OUString& rName )
+{
+ if(aParent == rName)
+ return true;
+ const OUString aOldParent(aParent);
+ if(SfxStyleSheetBase::SetParent(rName))
+ {
+ // Remove from notification chain of the old parent if applicable
+ if(!aOldParent.isEmpty())
+ {
+ SfxStyleSheet *pParent = static_cast<SfxStyleSheet *>(m_pPool->Find(aOldParent, nFamily));
+ if(pParent)
+ EndListening(*pParent);
+ }
+ // Add to the notification chain of the new parent
+ if(!aParent.isEmpty())
+ {
+ SfxStyleSheet *pParent = static_cast<SfxStyleSheet *>(m_pPool->Find(aParent, nFamily));
+ if(pParent)
+ StartListening(*pParent);
+ }
+ return true;
+ }
+ return false;
+}
+
+/**
+ * Notify all listeners
+ */
+void SfxStyleSheet::Notify(SfxBroadcaster& rBC, const SfxHint& rHint )
+{
+ Forward(rBC, rHint);
+}
+
+bool SfxStyleSheet::isUsedByModel() const
+{
+ return IsUsed();
+}
+
+
+SfxStyleSheetPool::SfxStyleSheetPool( SfxItemPool const& rSet)
+: SfxStyleSheetBasePool( const_cast< SfxItemPool& >( rSet ) )
+{
+}
+
+SfxStyleSheetBase* SfxStyleSheetPool::Create( const OUString& rName,
+ SfxStyleFamily eFam, SfxStyleSearchBits mask )
+{
+ return new SfxStyleSheet( rName, *this, eFam, mask );
+}
+
+SfxUnoStyleSheet::SfxUnoStyleSheet( const OUString& _rName, const SfxStyleSheetBasePool& _rPool, SfxStyleFamily _eFamily, SfxStyleSearchBits _nMask )
+: cppu::ImplInheritanceHelper<SfxStyleSheet, css::style::XStyle, css::lang::XUnoTunnel>(_rName, _rPool, _eFamily, _nMask)
+{
+}
+
+SfxUnoStyleSheet* SfxUnoStyleSheet::getUnoStyleSheet( const css::uno::Reference< css::style::XStyle >& xStyle )
+{
+ SfxUnoStyleSheet* pRet = dynamic_cast< SfxUnoStyleSheet* >( xStyle.get() );
+ if( !pRet )
+ pRet = comphelper::getUnoTunnelImplementation<SfxUnoStyleSheet>(xStyle);
+ return pRet;
+}
+
+/**
+ * XUnoTunnel
+ */
+::sal_Int64 SAL_CALL SfxUnoStyleSheet::getSomething( const css::uno::Sequence< ::sal_Int8 >& rId )
+{
+ if( isUnoTunnelId<SfxUnoStyleSheet>(rId) )
+ {
+ return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_uIntPtr>(this));
+ }
+
+ return 0;
+}
+
+void
+SfxStyleSheetBasePool::StoreStyleSheet(const rtl::Reference< SfxStyleSheetBase >& xStyle)
+{
+ pImpl->mxIndexedStyleSheets->AddStyleSheet(xStyle);
+}
+
+namespace
+{
+ class theSfxUnoStyleSheetIdentifier : public rtl::Static< UnoTunnelIdInit, theSfxUnoStyleSheetIdentifier > {};
+}
+
+const css::uno::Sequence< ::sal_Int8 >& SfxUnoStyleSheet::getUnoTunnelId()
+{
+ return theSfxUnoStyleSheetIdentifier::get().getSeq();
+}
+
+void
+SfxStyleSheetBasePool::Reindex()
+{
+ pImpl->mxIndexedStyleSheets->Reindex();
+}
+
+const svl::IndexedStyleSheets&
+SfxStyleSheetBasePool::GetIndexedStyleSheets() const
+{
+ return *pImpl->mxIndexedStyleSheets;
+}
+
+SfxStyleSheetBase*
+SfxStyleSheetBasePool::GetStyleSheetByPositionInIndex(unsigned pos)
+{
+ return pImpl->mxIndexedStyleSheets->GetStyleSheetByPosition(pos);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svl/source/items/stylepool.cxx b/svl/source/items/stylepool.cxx
new file mode 100644
index 000000000..ea3efeaeb
--- /dev/null
+++ b/svl/source/items/stylepool.cxx
@@ -0,0 +1,471 @@
+/* -*- 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 <svl/stylepool.hxx>
+#include <svl/itemiter.hxx>
+#include <svl/itempool.hxx>
+#include <tools/debug.hxx>
+#include <algorithm>
+#include <map>
+#include <memory>
+#include <vector>
+
+namespace {
+ /** A "Node" represents a subset of inserted SfxItemSets
+ * The root node represents the empty set
+ * The other nodes contain a SfxPoolItem and represents an item set which contains their
+ * pool item and the pool items of their parents.
+ */
+ class Node
+ {
+ std::vector<std::unique_ptr<Node>> mChildren; // child nodes, create by findChildNode(..)
+ // container of shared pointers of inserted item sets; for non-poolable
+ // items more than one item set is needed
+ std::vector< std::shared_ptr<SfxItemSet> > maItemSet;
+ std::unique_ptr<const SfxPoolItem> mpItem; // my pool item
+ Node *mpUpper; // if I'm a child node that's my parent node
+ // #i86923#
+ const bool mbIsItemIgnorable;
+ public:
+ // #i86923#
+ Node() // root node Ctor
+ : mChildren(),
+ maItemSet(),
+ mpUpper( nullptr ),
+ mbIsItemIgnorable( false )
+ {}
+ Node( const SfxPoolItem& rItem, Node* pParent, const bool bIgnorable ) // child node Ctor
+ : mChildren(),
+ maItemSet(),
+ mpItem( rItem.Clone() ),
+ mpUpper( pParent ),
+ mbIsItemIgnorable( bIgnorable )
+ {}
+ // #i86923#
+ bool hasItemSet( const bool bCheckUsage ) const;
+ // #i87808#
+ std::shared_ptr<SfxItemSet> const & getItemSet() const
+ {
+ return maItemSet.back();
+ }
+ std::shared_ptr<SfxItemSet> const & getUsedOrLastAddedItemSet() const;
+ void setItemSet( const SfxItemSet& rSet ){ maItemSet.push_back( std::shared_ptr<SfxItemSet>( rSet.Clone() ) ); }
+ // #i86923#
+ Node* findChildNode( const SfxPoolItem& rItem,
+ const bool bIsItemIgnorable );
+ Node* nextItemSet( Node const * pLast,
+ const bool bSkipUnusedItemSet,
+ const bool bSkipIgnorable );
+ // #i86923#
+ bool hasIgnorableChildren( const bool bCheckUsage ) const;
+ std::shared_ptr<SfxItemSet> getItemSetOfIgnorableChild(
+ const bool bSkipUnusedItemSets ) const;
+ };
+
+ // #i87808#
+ std::shared_ptr<SfxItemSet> const & Node::getUsedOrLastAddedItemSet() const
+ {
+ auto aIter = std::find_if(maItemSet.rbegin(), maItemSet.rend(),
+ [](const std::shared_ptr<SfxItemSet>& rxItemSet) { return rxItemSet.use_count() > 1; });
+
+ if (aIter != maItemSet.rend())
+ return *aIter;
+
+ return maItemSet.back();
+ }
+
+ // #i86923#
+ bool Node::hasItemSet( const bool bCheckUsage ) const
+ {
+ bool bHasItemSet = false;
+
+ if ( !maItemSet.empty())
+ {
+ if ( bCheckUsage )
+ {
+ bHasItemSet = std::any_of(maItemSet.rbegin(), maItemSet.rend(),
+ [](const std::shared_ptr<SfxItemSet>& rxItemSet) { return rxItemSet.use_count() > 1; });
+ }
+ else
+ {
+ bHasItemSet = true;
+ }
+ }
+ return bHasItemSet;
+ }
+
+ // #i86923#
+ Node* Node::findChildNode( const SfxPoolItem& rItem,
+ const bool bIsItemIgnorable )
+ {
+ for( auto const & rChild : mChildren )
+ {
+ if( rItem.Which() == rChild->mpItem->Which() &&
+ rItem == *rChild->mpItem )
+ return rChild.get();
+ }
+ // #i86923#
+ auto pNextNode = new Node( rItem, this, bIsItemIgnorable );
+ mChildren.emplace_back( pNextNode );
+ return pNextNode;
+ }
+
+ /**
+ * Find the next node which has a SfxItemSet.
+ * The input parameter pLast has a sophisticated meaning:
+ * downstairs only:
+ * pLast == 0 => scan your children and their children
+ * but neither your parents neither your siblings
+ * downstairs and upstairs:
+ * pLast == this => scan your children, their children,
+ * the children of your parent behind you, and so on
+ * partial downstairs and upstairs
+ * pLast != 0 && pLast != this => scan your children behind the given children,
+ * the children of your parent behind you and so on.
+ *
+ * OD 2008-03-11 #i86923#
+ * introduce parameters <bSkipUnusedItemSets> and <bSkipIgnorable>
+ * and its handling.
+ */
+ Node* Node::nextItemSet( Node const * pLast,
+ const bool bSkipUnusedItemSets,
+ const bool bSkipIgnorable )
+ {
+ // Searching downstairs
+ auto aIter = mChildren.begin();
+ // For pLast == 0 and pLast == this all children are of interest
+ // for another pLast the search starts behind pLast...
+ if( pLast && pLast != this )
+ {
+ aIter = std::find_if( mChildren.begin(), mChildren.end(),
+ [&] (std::unique_ptr<Node> const &p) { return p.get() == pLast; });
+ if( aIter != mChildren.end() )
+ ++aIter;
+ }
+ Node *pNext = nullptr;
+ while( aIter != mChildren.end() )
+ {
+ // #i86923#
+ if ( bSkipIgnorable && (*aIter)->mbIsItemIgnorable )
+ {
+ ++aIter;
+ continue;
+ }
+ pNext = aIter->get();
+ // #i86923#
+ if ( pNext->hasItemSet( bSkipUnusedItemSets ) )
+ {
+ return pNext;
+ }
+ if ( bSkipIgnorable &&
+ pNext->hasIgnorableChildren( bSkipUnusedItemSets ) )
+ {
+ return pNext;
+ }
+ pNext = pNext->nextItemSet( nullptr, bSkipUnusedItemSets, bSkipIgnorable ); // 0 => downstairs only
+ if( pNext )
+ return pNext;
+ ++aIter;
+ }
+ // Searching upstairs
+ if( pLast && mpUpper )
+ {
+ // #i86923#
+ pNext = mpUpper->nextItemSet( this, bSkipUnusedItemSets, bSkipIgnorable );
+ }
+ return pNext;
+ }
+
+ // #i86923#
+ bool Node::hasIgnorableChildren( const bool bCheckUsage ) const
+ {
+ return std::any_of(mChildren.begin(), mChildren.end(),
+ [&bCheckUsage](const std::unique_ptr<Node>& rxChild) {
+ Node* pChild = rxChild.get();
+ return pChild->mbIsItemIgnorable &&
+ (!bCheckUsage ||
+ ( pChild->hasItemSet( bCheckUsage /* == true */ ) ||
+ pChild->hasIgnorableChildren( bCheckUsage /* == true */ ) ));
+ });
+ }
+
+ std::shared_ptr<SfxItemSet> Node::getItemSetOfIgnorableChild(
+ const bool bSkipUnusedItemSets ) const
+ {
+ DBG_ASSERT( hasIgnorableChildren( bSkipUnusedItemSets ),
+ "<Node::getItemSetOfIgnorableChild> - node has no ignorable children" );
+
+ for( const auto& rxChild : mChildren )
+ {
+ Node* pChild = rxChild.get();
+ if ( pChild->mbIsItemIgnorable )
+ {
+ if ( pChild->hasItemSet( bSkipUnusedItemSets ) )
+ {
+ return pChild->getUsedOrLastAddedItemSet();
+ }
+ else
+ {
+ pChild = pChild->nextItemSet( nullptr, bSkipUnusedItemSets, false );
+ if ( pChild )
+ {
+ return pChild->getUsedOrLastAddedItemSet();
+ }
+ }
+ }
+ }
+
+ std::shared_ptr<SfxItemSet> pReturn;
+ return pReturn;
+ }
+
+ class Iterator : public IStylePoolIteratorAccess
+ {
+ std::map< const SfxItemSet*, Node >& mrRoot;
+ std::map< const SfxItemSet*, Node >::iterator mpCurrNode;
+ Node* mpNode;
+ const bool mbSkipUnusedItemSets;
+ const bool mbSkipIgnorable;
+ /// List of item set parents, ordered by their name.
+ std::vector<const SfxItemSet*> maParents;
+ /// The iterator's current position.
+ std::vector<const SfxItemSet*>::iterator mpCurrParent;
+ public:
+ // #i86923#
+ Iterator( std::map< const SfxItemSet*, Node >& rR,
+ const bool bSkipUnusedItemSets,
+ const bool bSkipIgnorable,
+ const std::map< const SfxItemSet*, OUString>& rParentNames )
+ : mrRoot( rR ),
+ mpNode(nullptr),
+ mbSkipUnusedItemSets( bSkipUnusedItemSets ),
+ mbSkipIgnorable( bSkipIgnorable )
+ {
+ // Collect the parent pointers into a vector we can sort.
+ for (const auto& rParent : mrRoot)
+ maParents.push_back(rParent.first);
+
+ // Sort the parents using their name, if they have one.
+ if (!rParentNames.empty())
+ {
+ std::sort(maParents.begin(), maParents.end(),
+ [&rParentNames](const SfxItemSet* pA, const SfxItemSet* pB) {
+ OUString aA;
+ OUString aB;
+ auto it = rParentNames.find(pA);
+ if (it != rParentNames.end())
+ aA = it->second;
+ it = rParentNames.find(pB);
+ if (it != rParentNames.end())
+ aB = it->second;
+ return aA < aB;
+ });
+ }
+
+ // Start the iteration.
+ mpCurrParent = maParents.begin();
+ if (mpCurrParent != maParents.end())
+ mpCurrNode = mrRoot.find(*mpCurrParent);
+ }
+ virtual std::shared_ptr<SfxItemSet> getNext() override;
+ };
+
+ std::shared_ptr<SfxItemSet> Iterator::getNext()
+ {
+ std::shared_ptr<SfxItemSet> pReturn;
+ while( mpNode || mpCurrParent != maParents.end() )
+ {
+ if( !mpNode )
+ {
+ mpNode = &mpCurrNode->second;
+ // Perform the actual increment.
+ ++mpCurrParent;
+ if (mpCurrParent != maParents.end())
+ mpCurrNode = mrRoot.find(*mpCurrParent);
+ // #i86923#
+ if ( mpNode->hasItemSet( mbSkipUnusedItemSets ) )
+ {
+ // #i87808#
+ return mpNode->getUsedOrLastAddedItemSet();
+ }
+ }
+ // #i86923#
+ mpNode = mpNode->nextItemSet( mpNode, mbSkipUnusedItemSets, mbSkipIgnorable );
+ if ( mpNode && mpNode->hasItemSet( mbSkipUnusedItemSets ) )
+ {
+ // #i87808#
+ return mpNode->getUsedOrLastAddedItemSet();
+ }
+ if ( mbSkipIgnorable &&
+ mpNode && mpNode->hasIgnorableChildren( mbSkipUnusedItemSets ) )
+ {
+ return mpNode->getItemSetOfIgnorableChild( mbSkipUnusedItemSets );
+ }
+ }
+ return pReturn;
+ }
+
+}
+
+/**
+ * This static method creates a unique name from a shared pointer to a SfxItemSet
+ * The name is the memory address of the SfxItemSet itself.
+ */
+OUString StylePool::nameOf( const std::shared_ptr<SfxItemSet>& pSet )
+{
+ return OUString::number( reinterpret_cast<sal_IntPtr>( pSet.get() ), 16 );
+}
+
+/**
+ * class StylePoolImpl organized a tree-structure where every node represents a SfxItemSet.
+ * The insertItemSet method adds a SfxItemSet into the tree if necessary and returns a shared_ptr
+ * to a copy of the SfxItemSet.
+ * The aRoot-Node represents an empty SfxItemSet.
+ */
+class StylePoolImpl
+{
+private:
+ std::map< const SfxItemSet*, Node > maRoot;
+ /// Names of maRoot keys.
+ std::map< const SfxItemSet*, OUString> maParentNames;
+ // #i86923#
+ std::unique_ptr<SfxItemSet> mpIgnorableItems;
+#ifdef DEBUG
+ sal_Int32 mnCount;
+#endif
+public:
+ // #i86923#
+ explicit StylePoolImpl( SfxItemSet const * pIgnorableItems )
+ : maRoot(),
+#ifdef DEBUG
+ mnCount(0),
+#endif
+ mpIgnorableItems( pIgnorableItems != nullptr
+ ? pIgnorableItems->Clone( false )
+ : nullptr )
+ {
+ DBG_ASSERT( !pIgnorableItems || !pIgnorableItems->Count(),
+ "<StylePoolImpl::StylePoolImpl(..)> - misusage: item set for ignorable item should be empty. Please correct usage." );
+ DBG_ASSERT( !mpIgnorableItems || !mpIgnorableItems->Count(),
+ "<StylePoolImpl::StylePoolImpl(..)> - <SfxItemSet::Clone( sal_False )> does not work as expected - <mpIgnorableItems> is not empty." );
+ }
+
+ std::shared_ptr<SfxItemSet> insertItemSet( const SfxItemSet& rSet, const OUString* pParentName = nullptr );
+
+ // #i86923#
+ std::unique_ptr<IStylePoolIteratorAccess> createIterator( bool bSkipUnusedItemSets,
+ bool bSkipIgnorableItems );
+};
+
+
+std::shared_ptr<SfxItemSet> StylePoolImpl::insertItemSet( const SfxItemSet& rSet, const OUString* pParentName )
+{
+ bool bNonPoolable = false;
+ Node* pCurNode = &maRoot[ rSet.GetParent() ];
+ if (pParentName)
+ maParentNames[ rSet.GetParent() ] = *pParentName;
+ SfxItemIter aIter( rSet );
+ const SfxPoolItem* pItem = aIter.GetCurItem();
+ // Every SfxPoolItem in the SfxItemSet causes a step deeper into the tree,
+ // a complete empty SfxItemSet would stay at the root node.
+ // #i86923# insert ignorable items to the tree leaves.
+ std::unique_ptr<SfxItemSet> xFoundIgnorableItems;
+ if ( mpIgnorableItems )
+ {
+ xFoundIgnorableItems.reset( new SfxItemSet( *mpIgnorableItems ) );
+ }
+ while( pItem )
+ {
+ if( !rSet.GetPool()->IsItemPoolable(pItem->Which() ) )
+ bNonPoolable = true;
+ if (!xFoundIgnorableItems || (xFoundIgnorableItems->Put(*pItem) == nullptr))
+ {
+ pCurNode = pCurNode->findChildNode( *pItem, false );
+ }
+ pItem = aIter.NextItem();
+ }
+ if ( xFoundIgnorableItems && xFoundIgnorableItems->Count() > 0 )
+ {
+ SfxItemIter aIgnorableItemsIter( *xFoundIgnorableItems );
+ pItem = aIgnorableItemsIter.GetCurItem();
+ while( pItem )
+ {
+ if( !rSet.GetPool()->IsItemPoolable(pItem->Which() ) )
+ bNonPoolable = true;
+ pCurNode = pCurNode->findChildNode( *pItem, true );
+ pItem = aIgnorableItemsIter.NextItem();
+ }
+ }
+ // Every leaf node represents an inserted item set, but "non-leaf" nodes represents subsets
+ // of inserted itemsets.
+ // These nodes could have but does not need to have a shared_ptr to an item set.
+ if( !pCurNode->hasItemSet( false ) )
+ {
+ pCurNode->setItemSet( rSet );
+ bNonPoolable = false; // to avoid a double insertion
+#ifdef DEBUG
+ ++mnCount;
+#endif
+ }
+ // If rSet contains at least one non poolable item, a new itemset has to be inserted
+ if( bNonPoolable )
+ pCurNode->setItemSet( rSet );
+#ifdef DEBUG
+ {
+ sal_Int32 nCheck = -1;
+ std::unique_ptr<IStylePoolIteratorAccess> pIter = createIterator(false,false);
+ std::shared_ptr<SfxItemSet> pTemp;
+ do
+ {
+ ++nCheck;
+ pTemp = pIter->getNext();
+ } while( pTemp.get() );
+ DBG_ASSERT( mnCount == nCheck, "Wrong counting");
+ }
+#endif
+ return pCurNode->getItemSet();
+}
+
+// #i86923#
+std::unique_ptr<IStylePoolIteratorAccess> StylePoolImpl::createIterator( bool bSkipUnusedItemSets,
+ bool bSkipIgnorableItems )
+{
+ return std::make_unique<Iterator>( maRoot, bSkipUnusedItemSets, bSkipIgnorableItems, maParentNames );
+}
+// Ctor, Dtor and redirected methods of class StylePool, nearly inline ;-)
+
+// #i86923#
+StylePool::StylePool( SfxItemSet const * pIgnorableItems )
+ : pImpl( new StylePoolImpl( pIgnorableItems ) )
+{}
+
+std::shared_ptr<SfxItemSet> StylePool::insertItemSet( const SfxItemSet& rSet, const OUString* pParentName )
+{ return pImpl->insertItemSet( rSet, pParentName ); }
+
+// #i86923#
+std::unique_ptr<IStylePoolIteratorAccess> StylePool::createIterator( const bool bSkipUnusedItemSets,
+ const bool bSkipIgnorableItems )
+{
+ return pImpl->createIterator( bSkipUnusedItemSets, bSkipIgnorableItems );
+}
+
+StylePool::~StylePool()
+{}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svl/source/items/visitem.cxx b/svl/source/items/visitem.cxx
new file mode 100644
index 000000000..2ba61a517
--- /dev/null
+++ b/svl/source/items/visitem.cxx
@@ -0,0 +1,67 @@
+/* -*- 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 <svl/visitem.hxx>
+#include <com/sun/star/uno/Any.hxx>
+#include <osl/diagnose.h>
+
+
+// virtual
+bool SfxVisibilityItem::operator ==(const SfxPoolItem & rItem) const
+{
+ assert(SfxPoolItem::operator==(rItem));
+ return m_nValue.bVisible == static_cast< const SfxVisibilityItem * >(&rItem)->
+ m_nValue.bVisible;
+}
+
+// virtual
+bool SfxVisibilityItem::GetPresentation(SfxItemPresentation,
+ MapUnit, MapUnit,
+ OUString & rText,
+ const IntlWrapper&) const
+{
+ rText = m_nValue.bVisible ? OUStringLiteral("TRUE") : OUStringLiteral("FALSE");
+ return true;
+}
+
+
+// virtual
+bool SfxVisibilityItem::QueryValue(css::uno::Any& rVal, sal_uInt8) const
+{
+ rVal <<= m_nValue;
+ return true;
+}
+
+// virtual
+bool SfxVisibilityItem::PutValue(const css::uno::Any& rVal, sal_uInt8)
+{
+ if (rVal >>= m_nValue)
+ return true;
+
+ OSL_FAIL( "SfxInt16Item::PutValue - Wrong type!" );
+ return false;
+}
+
+// virtual
+SfxVisibilityItem* SfxVisibilityItem::Clone(SfxItemPool *) const
+{
+ return new SfxVisibilityItem(*this);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svl/source/items/whiter.cxx b/svl/source/items/whiter.cxx
new file mode 100644
index 000000000..88b487b02
--- /dev/null
+++ b/svl/source/items/whiter.cxx
@@ -0,0 +1,53 @@
+/* -*- 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 <svl/whiter.hxx>
+#include <svl/itemset.hxx>
+
+SfxWhichIter::SfxWhichIter( const SfxItemSet& rSet ):
+ pStart(rSet.GetRanges()),
+ pRanges(pStart),
+ nOffset(0)
+{
+}
+
+sal_uInt16 SfxWhichIter::NextWhich()
+{
+ if ( 0 == pRanges[0] )
+ return 0;
+
+ const sal_uInt16 nLastWhich = pRanges[0] + nOffset;
+ ++nOffset;
+ if (pRanges[1] == nLastWhich)
+ {
+ pRanges += 2;
+ nOffset = 0;
+ }
+ return pRanges[0] + nOffset;
+}
+
+sal_uInt16 SfxWhichIter::FirstWhich()
+{
+ pRanges = pStart;
+ nOffset = 0;
+ return pRanges[0];
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */