diff options
author | Mike Kaganski <mike.kaganski@collabora.com> | 2021-05-27 13:00:10 +0300 |
---|---|---|
committer | Mike Kaganski <mike.kaganski@collabora.com> | 2021-06-08 14:50:55 +0200 |
commit | 95ebd24a629b4c8cd62cc20c0701683512cc8fa0 (patch) | |
tree | 8bdeab41e8b4d0092f639e62fd3e20ae8243f199 /svx | |
parent | c4f615b359be56e88e4fbf9aaaf30affb29d57e2 (diff) |
editengine-columns: ODF support [API CHANGE]
This uses existing ODF markup, as used by Writer's text frame:
style::columns child element of style:graphic-properties, its
fo:column-count and fo:column-gap attributes. No ODF extension
is required.
Since currently only columns with same width and spacing are
implemented, without additional settings, style:column child
elements are exported, but ignored on import.
This adds new property to css::drawing::TextProperties service:
TextColumns (of type css::text::XTextColumns).
Change-Id: I7e63293e5814b281ceec8a9632e696322d3629e8
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/116035
Tested-by: Jenkins
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
Diffstat (limited to 'svx')
-rw-r--r-- | svx/Library_svxcore.mk | 1 | ||||
-rw-r--r-- | svx/source/svdraw/svdotext.cxx | 20 | ||||
-rw-r--r-- | svx/source/unodraw/SvxXTextColumns.cxx | 325 | ||||
-rw-r--r-- | svx/source/unodraw/unomod.cxx | 5 | ||||
-rw-r--r-- | svx/source/unodraw/unopool.cxx | 7 | ||||
-rw-r--r-- | svx/source/unodraw/unoshape.cxx | 39 |
6 files changed, 397 insertions, 0 deletions
diff --git a/svx/Library_svxcore.mk b/svx/Library_svxcore.mk index 20915ae573c9..8e596acd4605 100644 --- a/svx/Library_svxcore.mk +++ b/svx/Library_svxcore.mk @@ -390,6 +390,7 @@ $(eval $(call gb_Library_add_exception_objects,svxcore,\ svx/source/toolbars/fontworkbar \ svx/source/unodraw/gluepts \ svx/source/unodraw/shapepropertynotifier \ + svx/source/unodraw/SvxXTextColumns \ svx/source/unodraw/tableshape \ svx/source/unodraw/unobrushitemhelper \ svx/source/unodraw/unobtabl \ diff --git a/svx/source/svdraw/svdotext.cxx b/svx/source/svdraw/svdotext.cxx index a5d9939a6103..27b514dc4ea9 100644 --- a/svx/source/svdraw/svdotext.cxx +++ b/svx/source/svdraw/svdotext.cxx @@ -1724,16 +1724,36 @@ SdrTextAniDirection SdrTextObj::GetTextAniDirection() const return GetObjectItemSet().Get(SDRATTR_TEXT_ANIDIRECTION).GetValue(); } +bool SdrTextObj::HasTextColumnsNumber() const +{ + return GetObjectItemSet().HasItem(SDRATTR_TEXTCOLUMNS_NUMBER); +} + sal_Int16 SdrTextObj::GetTextColumnsNumber() const { return GetObjectItemSet().Get(SDRATTR_TEXTCOLUMNS_NUMBER).GetValue(); } +void SdrTextObj::SetTextColumnsNumber(sal_Int16 nColumns) +{ + SetObjectItem(SfxInt16Item(SDRATTR_TEXTCOLUMNS_NUMBER, nColumns)); +} + +bool SdrTextObj::HasTextColumnsSpacing() const +{ + return GetObjectItemSet().HasItem(SDRATTR_TEXTCOLUMNS_SPACING); +} + sal_Int32 SdrTextObj::GetTextColumnsSpacing() const { return GetObjectItemSet().Get(SDRATTR_TEXTCOLUMNS_SPACING).GetValue(); } +void SdrTextObj::SetTextColumnsSpacing(sal_Int32 nSpacing) +{ + SetObjectItem(SdrMetricItem(SDRATTR_TEXTCOLUMNS_SPACING, nSpacing)); +} + // Get necessary data for text scroll animation. ATM base it on a Text-Metafile and a // painting rectangle. Rotation is excluded from the returned values. GDIMetaFile* SdrTextObj::GetTextScrollMetaFileAndRectangle( diff --git a/svx/source/unodraw/SvxXTextColumns.cxx b/svx/source/unodraw/SvxXTextColumns.cxx new file mode 100644 index 000000000000..d245f071391b --- /dev/null +++ b/svx/source/unodraw/SvxXTextColumns.cxx @@ -0,0 +1,325 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */ +/* + * 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 <com/sun/star/beans/PropertyAttribute.hpp> +#include <com/sun/star/beans/PropertyVetoException.hpp> +#include <com/sun/star/beans/UnknownPropertyException.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/lang/IllegalArgumentException.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/style/VerticalAlignment.hpp> +#include <com/sun/star/text/ColumnSeparatorStyle.hpp> +#include <com/sun/star/text/XTextColumns.hpp> +#include <com/sun/star/uno/Any.h> +#include <com/sun/star/util/Color.hpp> + +#include <cppuhelper/supportsservice.hxx> +#include <o3tl/safeint.hxx> +#include <svl/itemprop.hxx> +#include <svx/SvxXTextColumns.hxx> +#include <tools/UnitConversion.hxx> +#include <vcl/svapp.hxx> + +namespace +{ +enum : sal_uInt16 +{ + WID_TXTCOL_IS_AUTOMATIC, + WID_TXTCOL_AUTO_DISTANCE, + WID_TXTCOL_LINE_WIDTH, + WID_TXTCOL_LINE_COLOR, + WID_TXTCOL_LINE_REL_HGT, + WID_TXTCOL_LINE_ALIGN, + WID_TXTCOL_LINE_IS_ON, + WID_TXTCOL_LINE_STYLE, +}; + +SfxItemPropertyMapEntry const saTextColumns_Impl[] = { + { u"IsAutomatic", WID_TXTCOL_IS_AUTOMATIC, cppu::UnoType<bool>::get(), + css::beans::PropertyAttribute::READONLY, 0 }, + { u"AutomaticDistance", WID_TXTCOL_AUTO_DISTANCE, cppu::UnoType<sal_Int32>::get(), 0, 0 }, + { u"SeparatorLineWidth", WID_TXTCOL_LINE_WIDTH, cppu::UnoType<sal_Int32>::get(), 0, 0 }, + { u"SeparatorLineColor", WID_TXTCOL_LINE_COLOR, + cppu::UnoType<com::sun::star::util::Color>::get(), 0, 0 }, + { u"SeparatorLineRelativeHeight", WID_TXTCOL_LINE_REL_HGT, cppu::UnoType<sal_Int32>::get(), 0, + 0 }, + { u"SeparatorLineVerticalAlignment", WID_TXTCOL_LINE_ALIGN, + cppu::UnoType<css::style::VerticalAlignment>::get(), 0, 0 }, + { u"SeparatorLineIsOn", WID_TXTCOL_LINE_IS_ON, cppu::UnoType<bool>::get(), 0, 0 }, + { u"SeparatorLineStyle", WID_TXTCOL_LINE_STYLE, cppu::UnoType<sal_Int16>::get(), 0, 0 }, + { u"", 0, css::uno::Type(), 0, 0 }, +}; + +class SvxXTextColumns final + : public cppu::WeakImplHelper<css::beans::XPropertySet, css::text::XTextColumns, + css::lang::XServiceInfo> +{ +public: + SvxXTextColumns() = default; + + // XTextColumns + virtual sal_Int32 SAL_CALL getReferenceValue() override; + virtual sal_Int16 SAL_CALL getColumnCount() override; + virtual void SAL_CALL setColumnCount(sal_Int16 nColumns) override; + virtual css::uno::Sequence<css::text::TextColumn> SAL_CALL getColumns() override; + virtual void SAL_CALL + setColumns(const css::uno::Sequence<css::text::TextColumn>& Columns) override; + + // XPropertySet + virtual css::uno::Reference<css::beans::XPropertySetInfo> + SAL_CALL getPropertySetInfo() override; + virtual void SAL_CALL setPropertyValue(const OUString& aPropertyName, + const css::uno::Any& aValue) override; + virtual css::uno::Any SAL_CALL getPropertyValue(const OUString& PropertyName) override; + virtual void SAL_CALL addPropertyChangeListener( + const OUString& aPropertyName, + const css::uno::Reference<css::beans::XPropertyChangeListener>& xListener) override; + virtual void SAL_CALL removePropertyChangeListener( + const OUString& aPropertyName, + const css::uno::Reference<css::beans::XPropertyChangeListener>& aListener) override; + virtual void SAL_CALL addVetoableChangeListener( + const OUString& PropertyName, + const css::uno::Reference<css::beans::XVetoableChangeListener>& aListener) override; + virtual void SAL_CALL removeVetoableChangeListener( + const OUString& PropertyName, + const css::uno::Reference<css::beans::XVetoableChangeListener>& aListener) override; + + // XServiceInfo + virtual OUString SAL_CALL getImplementationName() override; + virtual sal_Bool SAL_CALL supportsService(const OUString& ServiceName) override; + virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override; + +private: + sal_Int32 m_nReference = USHRT_MAX; + css::uno::Sequence<css::text::TextColumn> m_aTextColumns; + bool m_bIsAutomaticWidth = true; + sal_Int32 m_nAutoDistance = 0; + + const SfxItemPropertySet m_aPropSet = { saTextColumns_Impl }; + + //separator line + sal_Int32 m_nSepLineWidth = 0; + com::sun::star::util::Color m_nSepLineColor = 0; // black + sal_Int32 m_nSepLineHeightRelative = 100; // full height + css::style::VerticalAlignment m_nSepLineVertAlign = css::style::VerticalAlignment_MIDDLE; + bool m_bSepLineIsOn = false; + sal_Int16 m_nSepLineStyle = css::text::ColumnSeparatorStyle::NONE; +}; + +OUString SvxXTextColumns::getImplementationName() { return "SvxXTextColumns"; } + +sal_Bool SvxXTextColumns::supportsService(const OUString& rServiceName) +{ + return cppu::supportsService(this, rServiceName); +} + +css::uno::Sequence<OUString> SvxXTextColumns::getSupportedServiceNames() +{ + return { "com.sun.star.text.TextColumns" }; +} + +sal_Int32 SvxXTextColumns::getReferenceValue() +{ + SolarMutexGuard aGuard; + return m_nReference; +} + +sal_Int16 SvxXTextColumns::getColumnCount() +{ + SolarMutexGuard aGuard; + return o3tl::narrowing<sal_Int16>(m_aTextColumns.getLength()); +} + +void SvxXTextColumns::setColumnCount(sal_Int16 nColumns) +{ + SolarMutexGuard aGuard; + if (nColumns <= 0) + throw css::uno::RuntimeException(); + m_bIsAutomaticWidth = true; + m_aTextColumns.realloc(nColumns); + css::text::TextColumn* pCols = m_aTextColumns.getArray(); + m_nReference = USHRT_MAX; + sal_Int32 nWidth = m_nReference / nColumns; + sal_Int32 nDiff = m_nReference - nWidth * nColumns; + sal_Int32 nDist = m_nAutoDistance / 2; + for (sal_Int16 i = 0; i < nColumns; i++) + { + pCols[i].Width = nWidth; + pCols[i].LeftMargin = i == 0 ? 0 : nDist; + pCols[i].RightMargin = i == nColumns - 1 ? 0 : nDist; + } + pCols[nColumns - 1].Width += nDiff; +} + +css::uno::Sequence<css::text::TextColumn> SvxXTextColumns::getColumns() +{ + SolarMutexGuard aGuard; + return m_aTextColumns; +} + +void SvxXTextColumns::setColumns(const css::uno::Sequence<css::text::TextColumn>& rColumns) +{ + SolarMutexGuard aGuard; + sal_Int32 nReferenceTemp = std::accumulate( + rColumns.begin(), rColumns.end(), sal_Int32(0), + [](const sal_Int32 nSum, const css::text::TextColumn& rCol) { return nSum + rCol.Width; }); + m_bIsAutomaticWidth = false; + m_nReference = !nReferenceTemp ? USHRT_MAX : nReferenceTemp; + m_aTextColumns = rColumns; +} + +css::uno::Reference<css::beans::XPropertySetInfo> SvxXTextColumns::getPropertySetInfo() +{ + return m_aPropSet.getPropertySetInfo(); +} + +void SvxXTextColumns::setPropertyValue(const OUString& rPropertyName, const css::uno::Any& aValue) +{ + const SfxItemPropertyMapEntry* pEntry = m_aPropSet.getPropertyMap().getByName(rPropertyName); + if (!pEntry) + throw css::beans::UnknownPropertyException("Unknown property: " + rPropertyName, + static_cast<cppu::OWeakObject*>(this)); + if (pEntry->nFlags & css::beans::PropertyAttribute::READONLY) + throw css::beans::PropertyVetoException("Property is read-only: " + rPropertyName, + static_cast<cppu::OWeakObject*>(this)); + + switch (pEntry->nWID) + { + case WID_TXTCOL_LINE_WIDTH: + if (sal_Int32 nTmp; !(aValue >>= nTmp) || nTmp < 0) + throw css::lang::IllegalArgumentException(); + else + m_nSepLineWidth = convertMm100ToTwip(nTmp); + break; + case WID_TXTCOL_LINE_COLOR: + if (!(aValue >>= m_nSepLineColor)) + throw css::lang::IllegalArgumentException(); + break; + case WID_TXTCOL_LINE_STYLE: + if (!(aValue >>= m_nSepLineStyle)) + throw css::lang::IllegalArgumentException(); + break; + case WID_TXTCOL_LINE_REL_HGT: + if (sal_Int32 nTmp; !(aValue >>= nTmp) || nTmp < 0) + throw css::lang::IllegalArgumentException(); + else + m_nSepLineHeightRelative = nTmp; + break; + case WID_TXTCOL_LINE_ALIGN: + if (css::style::VerticalAlignment eAlign; aValue >>= eAlign) + m_nSepLineVertAlign = eAlign; + else if (sal_Int8 nTmp; aValue >>= nTmp) + m_nSepLineVertAlign = static_cast<css::style::VerticalAlignment>(nTmp); + else + throw css::lang::IllegalArgumentException(); + break; + case WID_TXTCOL_LINE_IS_ON: + if (!(aValue >>= m_bSepLineIsOn)) + throw css::lang::IllegalArgumentException(); + break; + case WID_TXTCOL_AUTO_DISTANCE: + if (sal_Int32 nTmp; !(aValue >>= nTmp) || nTmp < 0 || nTmp >= m_nReference) + throw css::lang::IllegalArgumentException(); + else + { + m_nAutoDistance = nTmp; + sal_Int32 nColumns = m_aTextColumns.getLength(); + css::text::TextColumn* pCols = m_aTextColumns.getArray(); + sal_Int32 nDist = m_nAutoDistance / 2; + for (sal_Int32 i = 0; i < nColumns; i++) + { + pCols[i].LeftMargin = i == 0 ? 0 : nDist; + pCols[i].RightMargin = i == nColumns - 1 ? 0 : nDist; + } + } + break; + } +} + +css::uno::Any SvxXTextColumns::getPropertyValue(const OUString& rPropertyName) +{ + const SfxItemPropertyMapEntry* pEntry = m_aPropSet.getPropertyMap().getByName(rPropertyName); + if (!pEntry) + throw css::beans::UnknownPropertyException("Unknown property: " + rPropertyName, + static_cast<cppu::OWeakObject*>(this)); + + css::uno::Any aRet; + switch (pEntry->nWID) + { + case WID_TXTCOL_LINE_WIDTH: + aRet <<= o3tl::narrowing<sal_Int32>(convertTwipToMm100(m_nSepLineWidth)); + break; + case WID_TXTCOL_LINE_COLOR: + aRet <<= m_nSepLineColor; + break; + case WID_TXTCOL_LINE_STYLE: + aRet <<= m_nSepLineStyle; + break; + case WID_TXTCOL_LINE_REL_HGT: + aRet <<= m_nSepLineHeightRelative; + break; + case WID_TXTCOL_LINE_ALIGN: + aRet <<= m_nSepLineVertAlign; + break; + case WID_TXTCOL_LINE_IS_ON: + aRet <<= m_bSepLineIsOn; + break; + case WID_TXTCOL_IS_AUTOMATIC: + aRet <<= m_bIsAutomaticWidth; + break; + case WID_TXTCOL_AUTO_DISTANCE: + aRet <<= m_nAutoDistance; + break; + } + return aRet; +} + +void SvxXTextColumns::addPropertyChangeListener( + const OUString& /*rPropertyName*/, + const css::uno::Reference<css::beans::XPropertyChangeListener>& /*xListener*/) +{ +} + +void SvxXTextColumns::removePropertyChangeListener( + const OUString& /*rPropertyName*/, + const css::uno::Reference<css::beans::XPropertyChangeListener>& /*xListener*/) +{ +} + +void SvxXTextColumns::addVetoableChangeListener( + const OUString& /*rPropertyName*/, + const css::uno::Reference<css::beans::XVetoableChangeListener>& /*xListener*/) +{ +} + +void SvxXTextColumns::removeVetoableChangeListener( + const OUString& /*rPropertyName*/, + const css::uno::Reference<css::beans::XVetoableChangeListener>& /*xListener*/) +{ +} +} + +css::uno::Reference<css::uno::XInterface> SvxXTextColumns_createInstance() noexcept +{ + return static_cast<cppu::OWeakObject*>(new SvxXTextColumns); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */ diff --git a/svx/source/unodraw/unomod.cxx b/svx/source/unodraw/unomod.cxx index 5980da82d73d..25b6016dd419 100644 --- a/svx/source/unodraw/unomod.cxx +++ b/svx/source/unodraw/unomod.cxx @@ -48,6 +48,7 @@ #include <svx/unomodel.hxx> #include <svx/svdobj.hxx> #include <svx/svdpage.hxx> +#include <svx/SvxXTextColumns.hxx> #include <svx/unoshape.hxx> #include <svx/xmlgrhlp.hxx> @@ -182,6 +183,10 @@ css::uno::Reference<css::uno::XInterface> create( uno::Reference< uno::XInterface> xRet( static_cast< ::cppu::OWeakObject* >( pGraphicHelper.get() ) ); return xRet; } + else if (rServiceSpecifier == "com.sun.star.text.TextColumns") + { + return SvxXTextColumns_createInstance(); + } uno::Reference< uno::XInterface > xRet( SvxUnoDrawMSFactory::createTextField( rServiceSpecifier ) ); if( !xRet.is() ) diff --git a/svx/source/unodraw/unopool.cxx b/svx/source/unodraw/unopool.cxx index 5931087349c3..59c19c70262d 100644 --- a/svx/source/unodraw/unopool.cxx +++ b/svx/source/unodraw/unopool.cxx @@ -241,6 +241,13 @@ void SvxUnoDrawPool::_getPropertyStates( const comphelper::PropertyMapEntry** pp } } break; + case OWN_ATTR_TEXTCOLUMNS: + if (IsStaticDefaultItem(&pPool->GetDefaultItem(sal_uInt16(SDRATTR_TEXTCOLUMNS_NUMBER))) + && IsStaticDefaultItem(&pPool->GetDefaultItem(sal_uInt16(SDRATTR_TEXTCOLUMNS_SPACING)))) + *pStates = beans::PropertyState_DEFAULT_VALUE; + else + *pStates = beans::PropertyState_DIRECT_VALUE; + break; default: //#i18732# - correction: // use method <IsStaticDefaultItem(..)> instead of using probably diff --git a/svx/source/unodraw/unoshape.cxx b/svx/source/unodraw/unoshape.cxx index fd5296007a1d..32e3a5c6768a 100644 --- a/svx/source/unodraw/unoshape.cxx +++ b/svx/source/unodraw/unoshape.cxx @@ -86,6 +86,7 @@ #include <svx/sdtfsitm.hxx> #include <svx/svdoutl.hxx> #include <svx/svdopath.hxx> +#include <svx/SvxXTextColumns.hxx> #include <memory> #include <optional> @@ -2494,6 +2495,27 @@ bool SvxShape::setPropertyValueImpl( const OUString&, const SfxItemPropertyMapEn return false; } } + + case OWN_ATTR_TEXTCOLUMNS: + { + if (auto pTextObj = dynamic_cast<SdrTextObj*>(GetSdrObject())) + { + css::uno::Reference<css::text::XTextColumns> xTextColumns; + if (rValue >>= xTextColumns) + { + pTextObj->SetTextColumnsNumber(xTextColumns->getColumnCount()); + if (css::uno::Reference<css::beans::XPropertySet> xPropSet{ xTextColumns, + css::uno::UNO_QUERY }) + { + auto aVal = xPropSet->getPropertyValue("AutomaticDistance"); + if (sal_Int32 nSpacing; aVal >>= nSpacing) + pTextObj->SetTextColumnsSpacing(nSpacing); + } + } + } + return true; + } + default: { return false; @@ -2897,6 +2919,23 @@ bool SvxShape::getPropertyValueImpl( const OUString&, const SfxItemPropertyMapEn break; } + case OWN_ATTR_TEXTCOLUMNS: + { + if (auto pTextObj = dynamic_cast<const SdrTextObj*>(GetSdrObject())) + { + if (pTextObj->HasTextColumnsNumber() || pTextObj->HasTextColumnsSpacing()) + { + auto xIf = SvxXTextColumns_createInstance(); + css::uno::Reference<css::text::XTextColumns> xCols(xIf, css::uno::UNO_QUERY_THROW); + xCols->setColumnCount(pTextObj->GetTextColumnsNumber()); + css::uno::Reference<css::beans::XPropertySet> xProp(xIf, css::uno::UNO_QUERY_THROW); + xProp->setPropertyValue("AutomaticDistance", + css::uno::Any(pTextObj->GetTextColumnsSpacing())); + rValue <<= xIf; + } + } + break; + } default: return false; |