diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 09:06:44 +0000 |
commit | ed5640d8b587fbcfed7dd7967f3de04b37a76f26 (patch) | |
tree | 7a5f7c6c9d02226d7471cb3cc8fbbf631b415303 /editeng/source/items | |
parent | Initial commit. (diff) | |
download | libreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.tar.xz libreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.zip |
Adding upstream version 4:7.4.7.upstream/4%7.4.7upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'editeng/source/items')
-rw-r--r-- | editeng/source/items/CustomPropertyField.cxx | 72 | ||||
-rw-r--r-- | editeng/source/items/borderline.cxx | 699 | ||||
-rw-r--r-- | editeng/source/items/bulitem.cxx | 159 | ||||
-rw-r--r-- | editeng/source/items/charhiddenitem.cxx | 53 | ||||
-rw-r--r-- | editeng/source/items/flditem.cxx | 935 | ||||
-rw-r--r-- | editeng/source/items/frmitems.cxx | 3518 | ||||
-rw-r--r-- | editeng/source/items/itemtype.cxx | 232 | ||||
-rw-r--r-- | editeng/source/items/justifyitem.cxx | 368 | ||||
-rw-r--r-- | editeng/source/items/legacyitem.cxx | 826 | ||||
-rw-r--r-- | editeng/source/items/numitem.cxx | 1129 | ||||
-rw-r--r-- | editeng/source/items/optitems.cxx | 63 | ||||
-rw-r--r-- | editeng/source/items/paperinf.cxx | 121 | ||||
-rw-r--r-- | editeng/source/items/paraitem.cxx | 1285 | ||||
-rw-r--r-- | editeng/source/items/svdfield.cxx | 34 | ||||
-rw-r--r-- | editeng/source/items/svxfont.cxx | 860 | ||||
-rw-r--r-- | editeng/source/items/textitem.cxx | 2774 | ||||
-rw-r--r-- | editeng/source/items/writingmodeitem.cxx | 94 | ||||
-rw-r--r-- | editeng/source/items/xmlcnitm.cxx | 206 |
18 files changed, 13428 insertions, 0 deletions
diff --git a/editeng/source/items/CustomPropertyField.cxx b/editeng/source/items/CustomPropertyField.cxx new file mode 100644 index 000000000..939a6af0c --- /dev/null +++ b/editeng/source/items/CustomPropertyField.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/. + * + */ + +#include <editeng/CustomPropertyField.hxx> +#include <utility> +#include <vcl/metaact.hxx> +#include <com/sun/star/beans/XPropertyContainer.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/document/XDocumentProperties.hpp> + +using namespace css; + +namespace editeng +{ + +CustomPropertyField::CustomPropertyField(OUString aName, OUString aCurrentPresentation) + : msName(std::move(aName)) + , msCurrentPresentation(std::move(aCurrentPresentation)) +{} + +CustomPropertyField::~CustomPropertyField() +{} + +std::unique_ptr<SvxFieldData> CustomPropertyField::Clone() const +{ + return std::make_unique<CustomPropertyField>(msName, msCurrentPresentation); +} + +bool CustomPropertyField::operator==(const SvxFieldData& rOther) const +{ + if (typeid(rOther) != typeid(*this)) + return false; + + const CustomPropertyField& rOtherField = static_cast<const CustomPropertyField&>(rOther); + return (msName == rOtherField.msName && + msCurrentPresentation == rOtherField.msCurrentPresentation); +} + +MetaAction* CustomPropertyField::createBeginComment() const +{ + return new MetaCommentAction("FIELD_SEQ_BEGIN"); +} + +OUString CustomPropertyField::GetFormatted(uno::Reference<document::XDocumentProperties> const & xDocumentProperties) +{ + if (msName.isEmpty()) + return OUString(); + if (!xDocumentProperties.is()) + return OUString(); + uno::Reference<beans::XPropertyContainer> xPropertyContainer = xDocumentProperties->getUserDefinedProperties(); + if (!xPropertyContainer.is()) + return OUString(); + uno::Reference<beans::XPropertySet> xPropertySet(xPropertyContainer, uno::UNO_QUERY); + if (!xPropertySet.is()) + return OUString(); + uno::Any aAny = xPropertySet->getPropertyValue(msName); + if (!aAny.has<OUString>()) + return OUString(); + msCurrentPresentation = aAny.get<OUString>(); + return msCurrentPresentation; +} + +} // end editeng namespace + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/editeng/source/items/borderline.cxx b/editeng/source/items/borderline.cxx new file mode 100644 index 000000000..42d61b5da --- /dev/null +++ b/editeng/source/items/borderline.cxx @@ -0,0 +1,699 @@ +/* -*- 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 <algorithm> + +#include <basegfx/color/bcolor.hxx> +#include <basegfx/color/bcolortools.hxx> + +#include <editeng/borderline.hxx> +#include <editeng/itemtype.hxx> +#include <editeng/editrids.hrc> +#include <editeng/eerdll.hxx> +#include <tools/bigint.hxx> + +using namespace ::com::sun::star::table::BorderLineStyle; + +// class SvxBorderLine -------------------------------------------------- + +namespace { + + Color lcl_compute3DColor( Color aMain, int nLight, int nMedium, int nDark ) + { + basegfx::BColor color = aMain.getBColor( ); + basegfx::BColor hsl = basegfx::utils::rgb2hsl( color ); + + int nCoef = 0; + if ( hsl.getZ( ) >= 0.5 ) + nCoef = nLight; + else if ( 0.5 > hsl.getZ() && hsl.getZ() >= 0.25 ) + nCoef = nMedium; + else + nCoef = nDark; + + double L = std::min(hsl.getZ() * 255.0 + nCoef, 255.0); + hsl.setZ( L / 255.0 ); + color = basegfx::utils::hsl2rgb( hsl ); + + return Color( color ); + } +} // Anonymous namespace + +namespace editeng { + +Color SvxBorderLine::darkColor( Color aMain ) +{ + return aMain; +} + +Color SvxBorderLine::lightColor( Color aMain ) +{ + + // Divide Luminance by 2 + basegfx::BColor color = aMain.getBColor( ); + basegfx::BColor hsl = basegfx::utils::rgb2hsl( color ); + hsl.setZ( hsl.getZ() * 0.5 ); + color = basegfx::utils::hsl2rgb( hsl ); + + return Color( color ); +} + + +Color SvxBorderLine::threeDLightColor( Color aMain ) +{ + // These values have been defined in an empirical way + return lcl_compute3DColor( aMain, 3, 40, 83 ); +} + +Color SvxBorderLine::threeDDarkColor( Color aMain ) +{ + // These values have been defined in an empirical way + return lcl_compute3DColor( aMain, -85, -43, -1 ); +} + +Color SvxBorderLine::threeDMediumColor( Color aMain ) +{ + // These values have been defined in an empirical way + return lcl_compute3DColor( aMain, -42, -0, 42 ); +} + +SvxBorderLine::SvxBorderLine( const Color *pCol, tools::Long nWidth, + SvxBorderLineStyle nStyle, + Color (*pColorOutFn)( Color ), Color (*pColorInFn)( Color ) ) + : m_nWidth(nWidth) + , m_nMult(1) + , m_nDiv(1) + , m_pColorOutFn(pColorOutFn) + , m_pColorInFn(pColorInFn) + , m_pColorGapFn(nullptr) + , m_aWidthImpl(SvxBorderLine::getWidthImpl(nStyle)) + , m_nStyle(nStyle) + , m_bMirrorWidths(false) + , m_bUseLeftTop(false) +{ + if ( pCol ) + aColor = *pCol; +} + +SvxBorderLineStyle +ConvertBorderStyleFromWord(int const nWordLineStyle) +{ + switch (nWordLineStyle) + { + // First the single lines + case 1: + case 2: // thick line + case 5: // hairline + // and the unsupported special cases which we map to a single line + case 20: + return SvxBorderLineStyle::SOLID; + case 6: + return SvxBorderLineStyle::DOTTED; + case 7: + return SvxBorderLineStyle::DASHED; + case 22: + return SvxBorderLineStyle::FINE_DASHED; + case 8: + return SvxBorderLineStyle::DASH_DOT; + case 9: + return SvxBorderLineStyle::DASH_DOT_DOT; + // then the shading beams which we represent by a double line + case 23: + return SvxBorderLineStyle::DOUBLE; + // then the double lines, for which we have good matches + case 3: + case 10: // Don't have triple so use double + case 21: // Don't have double wave: use double instead + return SvxBorderLineStyle::DOUBLE; + case 11: + return SvxBorderLineStyle::THINTHICK_SMALLGAP; + case 12: + case 13: // Don't have thin thick thin, so use thick thin + return SvxBorderLineStyle::THICKTHIN_SMALLGAP; + case 14: + return SvxBorderLineStyle::THINTHICK_MEDIUMGAP; + case 15: + case 16: // Don't have thin thick thin, so use thick thin + return SvxBorderLineStyle::THICKTHIN_MEDIUMGAP; + case 17: + return SvxBorderLineStyle::THINTHICK_LARGEGAP; + case 18: + case 19: // Don't have thin thick thin, so use thick thin + return SvxBorderLineStyle::THICKTHIN_LARGEGAP; + case 24: + return SvxBorderLineStyle::EMBOSSED; + case 25: + return SvxBorderLineStyle::ENGRAVED; + case 26: + return SvxBorderLineStyle::OUTSET; + case 27: + return SvxBorderLineStyle::INSET; + default: + return SvxBorderLineStyle::NONE; + } +} + +const double THINTHICK_SMALLGAP_line2 = 15.0; +const double THINTHICK_SMALLGAP_gap = 15.0; +const double THINTHICK_LARGEGAP_line1 = 30.0; +const double THINTHICK_LARGEGAP_line2 = 15.0; +const double THICKTHIN_SMALLGAP_line1 = 15.0; +const double THICKTHIN_SMALLGAP_gap = 15.0; +const double THICKTHIN_LARGEGAP_line1 = 15.0; +const double THICKTHIN_LARGEGAP_line2 = 30.0; +const double OUTSET_line1 = 15.0; +const double INSET_line2 = 15.0; + +double +ConvertBorderWidthFromWord(SvxBorderLineStyle const eStyle, double const i_fWidth, + int const nWordLineStyle) +{ + // fdo#68779: at least for RTF, 0.75pt is the default if width is missing + double const fWidth((i_fWidth == 0.0) ? 15.0 : i_fWidth); + switch (eStyle) + { + // Single lines + case SvxBorderLineStyle::SOLID: + switch (nWordLineStyle) + { + case 2: + return (fWidth * 2.0); // thick + case 5: // fdo#55526: map 0 hairline width to > 0 + return std::max(fWidth, 1.0); + default: + return fWidth; + } + break; + + case SvxBorderLineStyle::DOTTED: + case SvxBorderLineStyle::DASHED: + case SvxBorderLineStyle::DASH_DOT: + case SvxBorderLineStyle::DASH_DOT_DOT: + return fWidth; + + // Display a minimum effective border width of 1pt + case SvxBorderLineStyle::FINE_DASHED: + return (fWidth > 0 && fWidth < 20) ? 20 : fWidth; + + // Double lines + case SvxBorderLineStyle::DOUBLE: + return fWidth * 3.0; + + case SvxBorderLineStyle::THINTHICK_MEDIUMGAP: + case SvxBorderLineStyle::THICKTHIN_MEDIUMGAP: + case SvxBorderLineStyle::EMBOSSED: + case SvxBorderLineStyle::ENGRAVED: + return fWidth * 2.0; + + case SvxBorderLineStyle::THINTHICK_SMALLGAP: + return fWidth + THINTHICK_SMALLGAP_line2 + THINTHICK_SMALLGAP_gap; + + case SvxBorderLineStyle::THINTHICK_LARGEGAP: + return fWidth + THINTHICK_LARGEGAP_line1 + THINTHICK_LARGEGAP_line2; + + case SvxBorderLineStyle::THICKTHIN_SMALLGAP: + return fWidth + THICKTHIN_SMALLGAP_line1 + THICKTHIN_SMALLGAP_gap; + + case SvxBorderLineStyle::THICKTHIN_LARGEGAP: + return fWidth + THICKTHIN_LARGEGAP_line1 + THICKTHIN_LARGEGAP_line2; + + case SvxBorderLineStyle::OUTSET: + return (fWidth * 2.0) + OUTSET_line1; + + case SvxBorderLineStyle::INSET: + return (fWidth * 2.0) + INSET_line2; + + default: + assert(false); // should only be called for known border style + } + return 0; +} + +double +ConvertBorderWidthToWord(SvxBorderLineStyle const eStyle, double const fWidth) +{ + if ( !fWidth ) + return 0; + + switch (eStyle) + { + // Single lines + case SvxBorderLineStyle::SOLID: + case SvxBorderLineStyle::DOTTED: + case SvxBorderLineStyle::DASHED: + case SvxBorderLineStyle::FINE_DASHED: + case SvxBorderLineStyle::DASH_DOT: + case SvxBorderLineStyle::DASH_DOT_DOT: + return fWidth; + + // Double lines + case SvxBorderLineStyle::DOUBLE: + case SvxBorderLineStyle::DOUBLE_THIN: + return std::max(1.0, fWidth / 3.0); + + case SvxBorderLineStyle::THINTHICK_MEDIUMGAP: + case SvxBorderLineStyle::THICKTHIN_MEDIUMGAP: + case SvxBorderLineStyle::EMBOSSED: + case SvxBorderLineStyle::ENGRAVED: + return std::max(1.0, fWidth / 2.0); + + case SvxBorderLineStyle::THINTHICK_SMALLGAP: + return std::max(1.0, fWidth - THINTHICK_SMALLGAP_line2 - THINTHICK_SMALLGAP_gap); + + case SvxBorderLineStyle::THINTHICK_LARGEGAP: + return std::max(1.0, fWidth - THINTHICK_LARGEGAP_line1 - THINTHICK_LARGEGAP_line2); + + case SvxBorderLineStyle::THICKTHIN_SMALLGAP: + return std::max(1.0, fWidth - THICKTHIN_SMALLGAP_line1 - THICKTHIN_SMALLGAP_gap); + + case SvxBorderLineStyle::THICKTHIN_LARGEGAP: + return std::max(1.0, fWidth - THICKTHIN_LARGEGAP_line1 - THICKTHIN_LARGEGAP_line2); + + case SvxBorderLineStyle::OUTSET: + return std::max(1.0, (fWidth - OUTSET_line1) / 2.0); + + case SvxBorderLineStyle::INSET: + return std::max(1.0, (fWidth - INSET_line2) / 2.0); + + case SvxBorderLineStyle::NONE: + return 0; + + default: + assert(false); // should only be called for known border style + return 0; + } +} + +/** Get the BorderWithImpl object corresponding to the given #nStyle, all the + units handled by the resulting object are Twips and the + BorderWidthImpl::GetLine1() corresponds to the Outer Line. + */ +BorderWidthImpl SvxBorderLine::getWidthImpl( SvxBorderLineStyle nStyle ) +{ + BorderWidthImpl aImpl; + + switch ( nStyle ) + { + // No line: no width + case SvxBorderLineStyle::NONE: + aImpl = BorderWidthImpl( BorderWidthImplFlags::FIXED, 0.0 ); + break; + + // Single lines + case SvxBorderLineStyle::SOLID: + case SvxBorderLineStyle::DOTTED: + case SvxBorderLineStyle::DASHED: + case SvxBorderLineStyle::FINE_DASHED: + case SvxBorderLineStyle::DASH_DOT: + case SvxBorderLineStyle::DASH_DOT_DOT: + aImpl = BorderWidthImpl( BorderWidthImplFlags::CHANGE_LINE1, 1.0 ); + break; + + // Double lines + + case SvxBorderLineStyle::DOUBLE: + aImpl = BorderWidthImpl( + BorderWidthImplFlags::CHANGE_LINE1 | BorderWidthImplFlags::CHANGE_LINE2 | BorderWidthImplFlags::CHANGE_DIST, + // fdo#46112 fdo#38542 fdo#43249: + // non-constant widths must sum to 1 + 1.0/3.0, 1.0/3.0, 1.0/3.0 ); + break; + + case SvxBorderLineStyle::DOUBLE_THIN: + aImpl = BorderWidthImpl(BorderWidthImplFlags::CHANGE_DIST, 10.0, 10.0, 1.0); + break; + + case SvxBorderLineStyle::THINTHICK_SMALLGAP: + aImpl = BorderWidthImpl( BorderWidthImplFlags::CHANGE_LINE1, 1.0, + THINTHICK_SMALLGAP_line2, THINTHICK_SMALLGAP_gap ); + break; + + case SvxBorderLineStyle::THINTHICK_MEDIUMGAP: + aImpl = BorderWidthImpl( + BorderWidthImplFlags::CHANGE_LINE1 | BorderWidthImplFlags::CHANGE_LINE2 | BorderWidthImplFlags::CHANGE_DIST, + 0.5, 0.25, 0.25 ); + break; + + case SvxBorderLineStyle::THINTHICK_LARGEGAP: + aImpl = BorderWidthImpl( BorderWidthImplFlags::CHANGE_DIST, + THINTHICK_LARGEGAP_line1, THINTHICK_LARGEGAP_line2, 1.0 ); + break; + + case SvxBorderLineStyle::THICKTHIN_SMALLGAP: + aImpl = BorderWidthImpl( BorderWidthImplFlags::CHANGE_LINE2, THICKTHIN_SMALLGAP_line1, + 1.0, THICKTHIN_SMALLGAP_gap ); + break; + + case SvxBorderLineStyle::THICKTHIN_MEDIUMGAP: + aImpl = BorderWidthImpl( + BorderWidthImplFlags::CHANGE_LINE1 | BorderWidthImplFlags::CHANGE_LINE2 | BorderWidthImplFlags::CHANGE_DIST, + 0.25, 0.5, 0.25 ); + break; + + case SvxBorderLineStyle::THICKTHIN_LARGEGAP: + aImpl = BorderWidthImpl( BorderWidthImplFlags::CHANGE_DIST, THICKTHIN_LARGEGAP_line1, + THICKTHIN_LARGEGAP_line2, 1.0 ); + break; + + // Engraved / Embossed + /* + * Word compat: the lines widths are exactly following this rule, should be: + * 0.75pt up to 3pt and then 3pt + */ + + case SvxBorderLineStyle::EMBOSSED: + case SvxBorderLineStyle::ENGRAVED: + aImpl = BorderWidthImpl( + BorderWidthImplFlags::CHANGE_LINE1 | BorderWidthImplFlags::CHANGE_LINE2 | BorderWidthImplFlags::CHANGE_DIST, + 0.25, 0.25, 0.5 ); + break; + + // Inset / Outset + /* + * Word compat: the gap width should be measured relatively to the biggest width for the + * row or column. + */ + case SvxBorderLineStyle::OUTSET: + aImpl = BorderWidthImpl( + BorderWidthImplFlags::CHANGE_LINE2 | BorderWidthImplFlags::CHANGE_DIST, + OUTSET_line1, 0.5, 0.5 ); + break; + + case SvxBorderLineStyle::INSET: + aImpl = BorderWidthImpl( + BorderWidthImplFlags::CHANGE_LINE1 | BorderWidthImplFlags::CHANGE_DIST, + 0.5, INSET_line2, 0.5 ); + break; + } + + return aImpl; +} + +void SvxBorderLine::ScaleMetrics( tools::Long nMult, tools::Long nDiv ) +{ + m_nMult = nMult; + m_nDiv = nDiv; +} + +void SvxBorderLine::GuessLinesWidths( SvxBorderLineStyle nStyle, sal_uInt16 nOut, sal_uInt16 nIn, sal_uInt16 nDist ) +{ + if (SvxBorderLineStyle::NONE == nStyle) + { + nStyle = SvxBorderLineStyle::SOLID; + if ( nOut > 0 && nIn > 0 ) + nStyle = SvxBorderLineStyle::DOUBLE; + } + + if ( nStyle == SvxBorderLineStyle::DOUBLE ) + { + static const SvxBorderLineStyle aDoubleStyles[] = + { + SvxBorderLineStyle::DOUBLE, + SvxBorderLineStyle::DOUBLE_THIN, + SvxBorderLineStyle::THINTHICK_SMALLGAP, + SvxBorderLineStyle::THINTHICK_MEDIUMGAP, + SvxBorderLineStyle::THINTHICK_LARGEGAP, + SvxBorderLineStyle::THICKTHIN_SMALLGAP, + SvxBorderLineStyle::THICKTHIN_MEDIUMGAP, + SvxBorderLineStyle::THICKTHIN_LARGEGAP + }; + + static size_t const len = SAL_N_ELEMENTS(aDoubleStyles); + tools::Long nWidth = 0; + SvxBorderLineStyle nTestStyle(SvxBorderLineStyle::NONE); + for (size_t i = 0; i < len && nWidth == 0; ++i) + { + nTestStyle = aDoubleStyles[i]; + BorderWidthImpl aWidthImpl = getWidthImpl( nTestStyle ); + nWidth = aWidthImpl.GuessWidth( nOut, nIn, nDist ); + } + + // If anything matched, then set it + if ( nWidth > 0 ) + { + nStyle = nTestStyle; + SetBorderLineStyle(nStyle); + m_nWidth = nWidth; + } + else + { + // fdo#38542: not a known double, default to something custom... + SetBorderLineStyle(nStyle); + m_nWidth = nOut + nIn + nDist; + if (m_nWidth) + { + m_aWidthImpl = BorderWidthImpl( + BorderWidthImplFlags::CHANGE_LINE1 | BorderWidthImplFlags::CHANGE_LINE2 | BorderWidthImplFlags::CHANGE_DIST, + static_cast<double>(nOut ) / static_cast<double>(m_nWidth), + static_cast<double>(nIn ) / static_cast<double>(m_nWidth), + static_cast<double>(nDist) / static_cast<double>(m_nWidth)); + } + } + } + else + { + SetBorderLineStyle(nStyle); + if (nOut == 0 && nIn > 0) + { + // If only inner width is given swap inner and outer widths for + // single line styles, otherwise GuessWidth() marks this as invalid + // and returns a 0 width. + switch (nStyle) + { + case SvxBorderLineStyle::SOLID: + case SvxBorderLineStyle::DOTTED: + case SvxBorderLineStyle::DASHED: + case SvxBorderLineStyle::FINE_DASHED: + case SvxBorderLineStyle::DASH_DOT: + case SvxBorderLineStyle::DASH_DOT_DOT: + std::swap( nOut, nIn); + break; + default: + ; // nothing + } + } + m_nWidth = m_aWidthImpl.GuessWidth( nOut, nIn, nDist ); + } +} + +sal_uInt16 SvxBorderLine::GetOutWidth() const +{ + sal_uInt16 nOut = static_cast<sal_uInt16>(BigInt::Scale( m_aWidthImpl.GetLine1( m_nWidth ), m_nMult, m_nDiv )); + if ( m_bMirrorWidths ) + nOut = static_cast<sal_uInt16>(BigInt::Scale( m_aWidthImpl.GetLine2( m_nWidth ), m_nMult, m_nDiv )); + return nOut; +} + +sal_uInt16 SvxBorderLine::GetInWidth() const +{ + sal_uInt16 nIn = static_cast<sal_uInt16>(BigInt::Scale( m_aWidthImpl.GetLine2( m_nWidth ), m_nMult, m_nDiv )); + if ( m_bMirrorWidths ) + nIn = static_cast<sal_uInt16>(BigInt::Scale( m_aWidthImpl.GetLine1( m_nWidth ), m_nMult, m_nDiv )); + return nIn; +} + +sal_uInt16 SvxBorderLine::GetDistance() const +{ + return static_cast<sal_uInt16>(BigInt::Scale( m_aWidthImpl.GetGap( m_nWidth ), m_nMult, m_nDiv )); +} + + +bool SvxBorderLine::operator==( const SvxBorderLine& rCmp ) const +{ + return ( ( aColor == rCmp.aColor ) && + ( m_nWidth == rCmp.m_nWidth ) && + ( m_bMirrorWidths == rCmp.m_bMirrorWidths ) && + ( m_aWidthImpl == rCmp.m_aWidthImpl ) && + ( m_nStyle == rCmp.GetBorderLineStyle()) && + ( m_bUseLeftTop == rCmp.m_bUseLeftTop ) && + ( m_pColorOutFn == rCmp.m_pColorOutFn ) && + ( m_pColorInFn == rCmp.m_pColorInFn ) && + ( m_pColorGapFn == rCmp.m_pColorGapFn ) ); +} + +void SvxBorderLine::SetBorderLineStyle( SvxBorderLineStyle nNew ) +{ + m_nStyle = nNew; + m_aWidthImpl = getWidthImpl( m_nStyle ); + + switch ( nNew ) + { + case SvxBorderLineStyle::EMBOSSED: + m_pColorOutFn = threeDLightColor; + m_pColorInFn = threeDDarkColor; + m_pColorGapFn = threeDMediumColor; + m_bUseLeftTop = true; + break; + case SvxBorderLineStyle::ENGRAVED: + m_pColorOutFn = threeDDarkColor; + m_pColorInFn = threeDLightColor; + m_pColorGapFn = threeDMediumColor; + m_bUseLeftTop = true; + break; + case SvxBorderLineStyle::OUTSET: + m_pColorOutFn = lightColor; + m_pColorInFn = darkColor; + m_bUseLeftTop = true; + m_pColorGapFn = nullptr; + break; + case SvxBorderLineStyle::INSET: + m_pColorOutFn = darkColor; + m_pColorInFn = lightColor; + m_bUseLeftTop = true; + m_pColorGapFn = nullptr; + break; + default: + m_pColorOutFn = darkColor; + m_pColorInFn = darkColor; + m_bUseLeftTop = false; + m_pColorGapFn = nullptr; + break; + } +} + +Color SvxBorderLine::GetColorOut( bool bLeftOrTop ) const +{ + Color aResult = aColor; + + if ( m_aWidthImpl.IsDouble() && m_pColorOutFn != nullptr ) + { + if ( !bLeftOrTop && m_bUseLeftTop ) + aResult = (*m_pColorInFn)( aColor ); + else + aResult = (*m_pColorOutFn)( aColor ); + } + + return aResult; +} + +Color SvxBorderLine::GetColorIn( bool bLeftOrTop ) const +{ + Color aResult = aColor; + + if ( m_aWidthImpl.IsDouble() && m_pColorInFn != nullptr ) + { + if ( !bLeftOrTop && m_bUseLeftTop ) + aResult = (*m_pColorOutFn)( aColor ); + else + aResult = (*m_pColorInFn)( aColor ); + } + + return aResult; +} + +Color SvxBorderLine::GetColorGap( ) const +{ + Color aResult = aColor; + + if ( m_aWidthImpl.IsDouble() && m_pColorGapFn != nullptr ) + { + aResult = (*m_pColorGapFn)( aColor ); + } + + return aResult; +} + +void SvxBorderLine::SetWidth( tools::Long nWidth ) +{ + m_nWidth = nWidth; +} + +OUString SvxBorderLine::GetValueString(MapUnit eSrcUnit, + MapUnit eDestUnit, + const IntlWrapper* pIntl, + bool bMetricStr) const +{ + static TranslateId aStyleIds[] = + { + RID_SOLID, + RID_DOTTED, + RID_DASHED, + RID_DOUBLE, + RID_THINTHICK_SMALLGAP, + RID_THINTHICK_MEDIUMGAP, + RID_THINTHICK_LARGEGAP, + RID_THICKTHIN_SMALLGAP, + RID_THICKTHIN_MEDIUMGAP, + RID_THICKTHIN_LARGEGAP, + RID_EMBOSSED, + RID_ENGRAVED, + RID_OUTSET, + RID_INSET, + RID_FINE_DASHED, + RID_DOUBLE_THIN, + RID_DASH_DOT, + RID_DASH_DOT_DOT + }; + OUString aStr = "(" + ::GetColorString( aColor ) + cpDelim; + + if ( static_cast<int>(m_nStyle) < int(SAL_N_ELEMENTS(aStyleIds)) ) + { + TranslateId pResId = aStyleIds[static_cast<int>(m_nStyle)]; + aStr += EditResId(pResId); + } + else + { + OUString sMetric = EditResId(GetMetricId( eDestUnit )); + aStr += GetMetricText( static_cast<tools::Long>(GetInWidth()), eSrcUnit, eDestUnit, pIntl ); + if ( bMetricStr ) + aStr += sMetric; + aStr += cpDelim + + GetMetricText( static_cast<tools::Long>(GetOutWidth()), eSrcUnit, eDestUnit, pIntl ); + if ( bMetricStr ) + aStr += sMetric; + aStr += cpDelim + + GetMetricText( static_cast<tools::Long>(GetDistance()), eSrcUnit, eDestUnit, pIntl ); + if ( bMetricStr ) + aStr += sMetric; + } + aStr += ")"; + return aStr; +} + +bool SvxBorderLine::HasPriority( const SvxBorderLine& rOtherLine ) const +{ + const sal_uInt16 nThisSize = GetScaledWidth(); + const sal_uInt16 nOtherSize = rOtherLine.GetScaledWidth(); + + if ( nThisSize > nOtherSize ) + { + return true; + } + else if ( nThisSize < nOtherSize ) + { + return false; + } + else if ( rOtherLine.GetInWidth() && !GetInWidth() ) + { + return true; + } + + return false; +} + +bool operator!=( const SvxBorderLine& rLeft, const SvxBorderLine& rRight ) +{ + return !(rLeft == rRight); +} + +} // namespace editeng + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/editeng/source/items/bulitem.cxx b/editeng/source/items/bulitem.cxx new file mode 100644 index 000000000..769179748 --- /dev/null +++ b/editeng/source/items/bulitem.cxx @@ -0,0 +1,159 @@ +/* -*- 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 <vcl/outdev.hxx> + +#include <editeng/bulletitem.hxx> + +SvxBulletItem::SvxBulletItem( sal_uInt16 _nWhich ) + : SfxPoolItem(_nWhich) + , aFont(OutputDevice::GetDefaultFont( DefaultFontType::FIXED, LANGUAGE_SYSTEM, GetDefaultFontFlags::NONE )) + , nStart(1) + , nStyle(SvxBulletStyle::N123) + , nWidth(1200) // 1.2cm + , nScale(75) + , cSymbol(' ') +{ + aFont.SetAlignment(ALIGN_BOTTOM); + aFont.SetTransparent( true ); +} + + +SvxBulletItem::SvxBulletItem( const SvxBulletItem& rItem ) + : SfxPoolItem(rItem) + , aFont(rItem.aFont) + , pGraphicObject(rItem.pGraphicObject ? new GraphicObject( *rItem.pGraphicObject ) : nullptr) + , aPrevText(rItem.aPrevText) + , aFollowText(rItem.aFollowText) + , nStart(rItem.nStart) + , nStyle(rItem.nStyle) + , nWidth(rItem.nWidth) + , nScale(rItem.nScale) + , cSymbol(rItem.cSymbol) +{ +} + + +SvxBulletItem::~SvxBulletItem() +{ +} + +SvxBulletItem* SvxBulletItem::Clone( SfxItemPool * /*pPool*/ ) const +{ + return new SvxBulletItem( *this ); +} + +void SvxBulletItem::CopyValidProperties( const SvxBulletItem& rCopyFrom ) +{ + vcl::Font _aFont = GetFont(); + vcl::Font aNewFont = rCopyFrom.GetFont(); + _aFont.SetFamilyName( aNewFont.GetFamilyName() ); + _aFont.SetFamily( aNewFont.GetFamilyType() ); + _aFont.SetStyleName( aNewFont.GetStyleName() ); + _aFont.SetColor( aNewFont.GetColor() ); + SetSymbol( rCopyFrom.cSymbol ); + SetGraphicObject( rCopyFrom.GetGraphicObject() ); + SetScale( rCopyFrom.nScale ); + SetStart( rCopyFrom.nStart ); + SetStyle( rCopyFrom.nStyle ); + aPrevText = rCopyFrom.aPrevText; + aFollowText = rCopyFrom.aFollowText; + SetFont( _aFont ); +} + + +bool SvxBulletItem::operator==( const SfxPoolItem& rItem ) const +{ + assert(SfxPoolItem::operator==(rItem)); + const SvxBulletItem& rBullet = static_cast<const SvxBulletItem&>(rItem); + // Compare with ValidMask, otherwise no put possible in an AttrSet if the + // item differs only in terms of the ValidMask from an existing one. + if( nStyle != rBullet.nStyle || + nScale != rBullet.nScale || + nWidth != rBullet.nWidth || + nStart != rBullet.nStart || + cSymbol != rBullet.cSymbol || + aPrevText != rBullet.aPrevText || + aFollowText != rBullet.aFollowText ) + return false; + + if( ( nStyle != SvxBulletStyle::BMP ) && ( aFont != rBullet.aFont ) ) + return false; + + if( nStyle == SvxBulletStyle::BMP ) + { + if( ( pGraphicObject && !rBullet.pGraphicObject ) || ( !pGraphicObject && rBullet.pGraphicObject ) ) + return false; + + if( ( pGraphicObject && rBullet.pGraphicObject ) && + ( ( *pGraphicObject != *rBullet.pGraphicObject ) || + ( pGraphicObject->GetPrefSize() != rBullet.pGraphicObject->GetPrefSize() ) ) ) + { + return false; + } + } + + return true; +} + + +OUString SvxBulletItem::GetFullText() const +{ + return aPrevText + OUStringChar(cSymbol) + aFollowText; +} + + +bool SvxBulletItem::GetPresentation +( + SfxItemPresentation /*ePres*/, + MapUnit /*eCoreUnit*/, + MapUnit /*ePresUnit*/, + OUString& rText, const IntlWrapper& +) const +{ + rText = GetFullText(); + return true; +} + + +const GraphicObject& SvxBulletItem::GetGraphicObject() const +{ + if( pGraphicObject ) + return *pGraphicObject; + else + { + static const GraphicObject aDefaultObject; + return aDefaultObject; + } +} + + +void SvxBulletItem::SetGraphicObject( const GraphicObject& rGraphicObject ) +{ + if( ( GraphicType::NONE == rGraphicObject.GetType() ) || ( GraphicType::Default == rGraphicObject.GetType() ) ) + { + pGraphicObject.reset(); + } + else + { + pGraphicObject.reset( new GraphicObject( rGraphicObject ) ); + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/editeng/source/items/charhiddenitem.cxx b/editeng/source/items/charhiddenitem.cxx new file mode 100644 index 000000000..ec2a0af3c --- /dev/null +++ b/editeng/source/items/charhiddenitem.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 <editeng/charhiddenitem.hxx> +#include <editeng/editrids.hrc> +#include <editeng/eerdll.hxx> +#include <unotools/resmgr.hxx> + + +SvxCharHiddenItem::SvxCharHiddenItem( const bool bHidden, const sal_uInt16 nId ) : + SfxBoolItem( nId, bHidden ) +{ +} + +SvxCharHiddenItem* SvxCharHiddenItem::Clone( SfxItemPool * ) const +{ + return new SvxCharHiddenItem( *this ); +} + +bool SvxCharHiddenItem::GetPresentation +( + SfxItemPresentation /*ePres*/, + MapUnit /*eCoreUnit*/, + MapUnit /*ePresUnit*/, + OUString& rText, + const IntlWrapper & /*rIntl*/ +) const +{ + TranslateId pId = RID_SVXITEMS_CHARHIDDEN_FALSE; + + if ( GetValue() ) + pId = RID_SVXITEMS_CHARHIDDEN_TRUE; + rText = EditResId(pId); + return true; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/editeng/source/items/flditem.cxx b/editeng/source/items/flditem.cxx new file mode 100644 index 000000000..1f6a9d9cc --- /dev/null +++ b/editeng/source/items/flditem.cxx @@ -0,0 +1,935 @@ +/* -*- 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 <osl/file.hxx> +#include <utility> +#include <vcl/metaact.hxx> +#include <svl/numformat.hxx> +#include <svl/zforlist.hxx> +#include <tools/urlobj.hxx> + +#include <editeng/flditem.hxx> +#include <editeng/CustomPropertyField.hxx> +#include <editeng/measfld.hxx> +#include <editeng/unonames.hxx> + +#include <tools/debug.hxx> + +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/text/XTextContent.hpp> +#include <com/sun/star/text/FilenameDisplayFormat.hpp> +#include <com/sun/star/util/DateTime.hpp> + +using namespace com::sun::star; + +SvxFieldData* SvxFieldData::Create(const uno::Reference<text::XTextContent>& xTextContent) +{ + uno::Reference<beans::XPropertySet> xPropSet(xTextContent, uno::UNO_QUERY); + if (!xPropSet.is()) + return nullptr; + + // we do not support these fields from Writer, so make sure we do not throw + // here - see fdo#63436 how to possibly extend Writer to make use of this + uno::Any aAny; + try { + aAny = xPropSet->getPropertyValue(UNO_TC_PROP_TEXTFIELD_TYPE); + if ( !aAny.has<sal_Int32>() ) + return nullptr; + + sal_Int32 nFieldType = aAny.get<sal_Int32>(); + + switch (nFieldType) + { + case text::textfield::Type::TIME: + case text::textfield::Type::EXTENDED_TIME: + case text::textfield::Type::DATE: + { + bool bIsDate = false; + xPropSet->getPropertyValue(UNO_TC_PROP_IS_DATE) >>= bIsDate; + + if (bIsDate) + { + util::DateTime aDateTime = xPropSet->getPropertyValue(UNO_TC_PROP_DATE_TIME).get<util::DateTime>(); + Date aDate(aDateTime.Day, aDateTime.Month, aDateTime.Year); + bool bIsFixed = false; + xPropSet->getPropertyValue(UNO_TC_PROP_IS_FIXED) >>= bIsFixed; + + SvxDateField* pData = new SvxDateField(aDate, bIsFixed ? SvxDateType::Fix : SvxDateType::Var); + sal_Int32 nNumFmt = -1; + xPropSet->getPropertyValue(UNO_TC_PROP_NUMFORMAT) >>= nNumFmt; + if (static_cast<SvxDateFormat>(nNumFmt) >= SvxDateFormat::AppDefault && + static_cast<SvxDateFormat>(nNumFmt) <= SvxDateFormat::F) + pData->SetFormat(static_cast<SvxDateFormat>(nNumFmt)); + + return pData; + } + + if (nFieldType != text::textfield::Type::TIME) + { + util::DateTime aDateTime = xPropSet->getPropertyValue(UNO_TC_PROP_DATE_TIME).get<util::DateTime>(); + tools::Time aTime(aDateTime); + + bool bIsFixed = false; + xPropSet->getPropertyValue(UNO_TC_PROP_IS_FIXED) >>= bIsFixed; + + SvxExtTimeField* pData = new SvxExtTimeField(aTime, bIsFixed ? SvxTimeType::Fix : SvxTimeType::Var); + + sal_Int32 nNumFmt = -1; + xPropSet->getPropertyValue(UNO_TC_PROP_NUMFORMAT) >>= nNumFmt; + if (static_cast<SvxTimeFormat>(nNumFmt) >= SvxTimeFormat::AppDefault && + static_cast<SvxTimeFormat>(nNumFmt) <= SvxTimeFormat::HH12_MM_SS_00_AMPM) + pData->SetFormat(static_cast<SvxTimeFormat>(nNumFmt)); + + return pData; + } + + return new SvxTimeField(); + } + case text::textfield::Type::URL: + { + OUString aRep, aTarget, aURL; + sal_Int16 nFmt = -1; + xPropSet->getPropertyValue(UNO_TC_PROP_URL_REPRESENTATION) >>= aRep; + xPropSet->getPropertyValue(UNO_TC_PROP_URL_TARGET) >>= aTarget; + xPropSet->getPropertyValue(UNO_TC_PROP_URL) >>= aURL; + xPropSet->getPropertyValue(UNO_TC_PROP_URL_FORMAT) >>= nFmt; + SvxURLField* pData = new SvxURLField(aURL, aRep, aRep.isEmpty() ? SvxURLFormat::Url : SvxURLFormat::Repr); + pData->SetTargetFrame(aTarget); + if (static_cast<SvxURLFormat>(nFmt) >= SvxURLFormat::AppDefault && + static_cast<SvxURLFormat>(nFmt) <= SvxURLFormat::Repr) + pData->SetFormat(static_cast<SvxURLFormat>(nFmt)); + + return pData; + } + case text::textfield::Type::PAGE: + return new SvxPageField(); + case text::textfield::Type::PAGES: + return new SvxPagesField(); + case text::textfield::Type::PAGE_NAME: + return new SvxPageTitleField(); + case text::textfield::Type::DOCINFO_TITLE: + return new SvxFileField(); + case text::textfield::Type::TABLE: + { + sal_Int32 nTab = 0; + xPropSet->getPropertyValue(UNO_TC_PROP_TABLE_POSITION) >>= nTab; + return new SvxTableField(nTab); + } + case text::textfield::Type::EXTENDED_FILE: + { + OUString aPresentation; + bool bIsFixed = false; + sal_Int16 nFmt = text::FilenameDisplayFormat::FULL; + xPropSet->getPropertyValue(UNO_TC_PROP_IS_FIXED) >>= bIsFixed; + xPropSet->getPropertyValue(UNO_TC_PROP_CURRENT_PRESENTATION) >>= aPresentation; + xPropSet->getPropertyValue(UNO_TC_PROP_FILE_FORMAT) >>= nFmt; + + SvxFileFormat eFmt = SvxFileFormat::NameAndExt; + switch (nFmt) + { + case text::FilenameDisplayFormat::FULL: eFmt = SvxFileFormat::PathFull; break; + case text::FilenameDisplayFormat::PATH: eFmt = SvxFileFormat::PathOnly; break; + case text::FilenameDisplayFormat::NAME: eFmt = SvxFileFormat::NameOnly; break; + default:; + } + + // pass fixed attribute to constructor + return new SvxExtFileField( + aPresentation, bIsFixed ? SvxFileType::Fix : SvxFileType::Var, eFmt); + } + case text::textfield::Type::AUTHOR: + { + bool bIsFixed = false; + bool bFullName = false; + sal_Int16 nFmt = -1; + OUString aPresentation, aContent, aFirstName, aLastName; + xPropSet->getPropertyValue(UNO_TC_PROP_IS_FIXED) >>= bIsFixed; + xPropSet->getPropertyValue(UNO_TC_PROP_AUTHOR_FULLNAME) >>= bFullName; + xPropSet->getPropertyValue(UNO_TC_PROP_CURRENT_PRESENTATION) >>= aPresentation; + xPropSet->getPropertyValue(UNO_TC_PROP_AUTHOR_CONTENT) >>= aContent; + xPropSet->getPropertyValue(UNO_TC_PROP_AUTHOR_FORMAT) >>= nFmt; + + // do we have CurrentPresentation given? Mimic behaviour of + // writer, which means: prefer CurrentPresentation over Content + // if both are given. + if (!aPresentation.isEmpty()) + aContent = aPresentation; + + sal_Int32 nPos = aContent.lastIndexOf(' ', 0); + if (nPos > 0) + { + aFirstName = aContent.copy(0, nPos); + aLastName = aContent.copy(nPos + 1); + } + else + { + aLastName = aContent; + } + + // #92009# pass fixed attribute to constructor + SvxAuthorField* pData = new SvxAuthorField( + aFirstName, aLastName, OUString(), bIsFixed ? SvxAuthorType::Fix : SvxAuthorType::Var); + + if (!bIsFixed) + { + if (!bFullName) + { + pData->SetFormat(SvxAuthorFormat::ShortName); + } + else if (static_cast<SvxAuthorFormat>(nFmt) >= SvxAuthorFormat::FullName && + static_cast<SvxAuthorFormat>(nFmt) <= SvxAuthorFormat::ShortName) + { + pData->SetFormat(static_cast<SvxAuthorFormat>(nFmt)); + } + } + + return pData; + } + case text::textfield::Type::MEASURE: + { + SdrMeasureFieldKind eKind = SdrMeasureFieldKind::Value; + sal_Int16 nTmp = -1; + xPropSet->getPropertyValue(UNO_TC_PROP_MEASURE_KIND) >>= nTmp; + if (nTmp == static_cast<sal_Int16>(SdrMeasureFieldKind::Unit) || + nTmp == static_cast<sal_Int16>(SdrMeasureFieldKind::Rotate90Blanks)) + eKind = static_cast<SdrMeasureFieldKind>(nTmp); + + return new SdrMeasureField(eKind); + } + case text::textfield::Type::PRESENTATION_HEADER: + return new SvxHeaderField(); + case text::textfield::Type::PRESENTATION_FOOTER: + return new SvxFooterField(); + case text::textfield::Type::PRESENTATION_DATE_TIME: + return new SvxDateTimeField(); + case text::textfield::Type::DOCINFO_CUSTOM: + { + OUString sName; + xPropSet->getPropertyValue(UNO_TC_PROP_NAME) >>= sName; + + OUString sCurrentPresentation; + xPropSet->getPropertyValue(UNO_TC_PROP_CURRENT_PRESENTATION) >>= sCurrentPresentation; + + return new editeng::CustomPropertyField(sName, sCurrentPresentation); + } + default: + ; + }; + } catch ( const beans::UnknownPropertyException& ) + { + return nullptr; + } + + return nullptr; +} + + +SvxFieldData::SvxFieldData() +{ +} + + +SvxFieldData::~SvxFieldData() +{ +} + + +std::unique_ptr<SvxFieldData> SvxFieldData::Clone() const +{ + return std::make_unique<SvxFieldData>(); +} + + +bool SvxFieldData::operator==( const SvxFieldData& rFld ) const +{ + DBG_ASSERT( typeid(*this) == typeid(rFld), "==: Different Types" ); + (void)rFld; + return true; // Basic class is always the same. +} + + +MetaAction* SvxFieldData::createBeginComment() const +{ + return new MetaCommentAction( "FIELD_SEQ_BEGIN" ); +} + +MetaAction* SvxFieldData::createEndComment() +{ + return new MetaCommentAction( "FIELD_SEQ_END" ); +} + + +SvxFieldItem::SvxFieldItem( std::unique_ptr<SvxFieldData> pField, const sal_uInt16 nId ) : + SfxPoolItem( nId ) + , mpField( std::move(pField) ) +{ +} + +SvxFieldItem::SvxFieldItem( const SvxFieldData& rField, const sal_uInt16 nId ) : + SfxPoolItem( nId ) + , mpField( rField.Clone() ) +{ +} + + +SvxFieldItem::SvxFieldItem( const SvxFieldItem& rItem ) : + SfxPoolItem ( rItem ) + , mpField( rItem.mpField ? rItem.mpField->Clone() : nullptr ) +{ +} + +SvxFieldItem::~SvxFieldItem() +{ +} + +SvxFieldItem* SvxFieldItem::Clone( SfxItemPool* ) const +{ + return new SvxFieldItem(*this); +} + +bool SvxFieldItem::operator==( const SfxPoolItem& rItem ) const +{ + assert(SfxPoolItem::operator==(rItem)); + + const SvxFieldData* pOtherFld = static_cast<const SvxFieldItem&>(rItem).GetField(); + if( mpField.get() == pOtherFld ) + return true; + if( mpField == nullptr || pOtherFld == nullptr ) + return false; + return ( typeid(*mpField) == typeid(*pOtherFld) ) + && ( *mpField == *pOtherFld ); +} + + +// The following are the derivatives of SvxFieldData ... + + +SvxDateField::SvxDateField() +{ + nFixDate = Date( Date::SYSTEM ).GetDate(); + eType = SvxDateType::Var; + eFormat = SvxDateFormat::StdSmall; +} + + +SvxDateField::SvxDateField( const Date& rDate, SvxDateType eT, SvxDateFormat eF ) +{ + nFixDate = rDate.GetDate(); + eType = eT; + eFormat = eF; +} + + +std::unique_ptr<SvxFieldData> SvxDateField::Clone() const +{ + return std::make_unique<SvxDateField>( *this ); +} + + +bool SvxDateField::operator==( const SvxFieldData& rOther ) const +{ + if ( typeid(rOther) != typeid(*this) ) + return false; + + const SvxDateField& rOtherFld = static_cast<const SvxDateField&>(rOther); + return ( ( nFixDate == rOtherFld.nFixDate ) && + ( eType == rOtherFld.eType ) && + ( eFormat == rOtherFld.eFormat ) ); +} + + + +OUString SvxDateField::GetFormatted( SvNumberFormatter& rFormatter, LanguageType eLang ) const +{ + Date aDate( Date::EMPTY ); + if ( eType == SvxDateType::Fix ) + aDate.SetDate( nFixDate ); + else + aDate = Date( Date::SYSTEM ); // current date + + return GetFormatted( aDate, eFormat, rFormatter, eLang ); +} + +OUString SvxDateField::GetFormatted( Date const & aDate, SvxDateFormat eFormat, SvNumberFormatter& rFormatter, LanguageType eLang ) +{ + if ( eFormat == SvxDateFormat::System ) + { + OSL_FAIL( "SvxDateFormat::System not implemented!" ); + eFormat = SvxDateFormat::StdSmall; + } + else if ( eFormat == SvxDateFormat::AppDefault ) + { + OSL_FAIL( "SvxDateFormat::AppDefault: take them from where? "); + eFormat = SvxDateFormat::StdSmall; + } + + sal_uInt32 nFormatKey; + + switch( eFormat ) + { + case SvxDateFormat::StdSmall: + // short + nFormatKey = rFormatter.GetFormatIndex( NF_DATE_SYSTEM_SHORT, eLang ); + break; + case SvxDateFormat::StdBig: + // long + nFormatKey = rFormatter.GetFormatIndex( NF_DATE_SYSTEM_LONG, eLang ); + break; + case SvxDateFormat::A: + // 13.02.96 + nFormatKey = rFormatter.GetFormatIndex( NF_DATE_SYS_DDMMYY, eLang ); + break; + case SvxDateFormat::B: + // 13.02.1996 + nFormatKey = rFormatter.GetFormatIndex( NF_DATE_SYS_DDMMYYYY, eLang ); + break; + case SvxDateFormat::C: + // 13. Feb 1996 + nFormatKey = rFormatter.GetFormatIndex( NF_DATE_SYS_DMMMYYYY, eLang ); + break; + case SvxDateFormat::D: + // 13. February 1996 + nFormatKey = rFormatter.GetFormatIndex( NF_DATE_SYS_DMMMMYYYY, eLang ); + break; + case SvxDateFormat::E: + // The, 13. February 1996 + nFormatKey = rFormatter.GetFormatIndex( NF_DATE_SYS_NNDMMMMYYYY, eLang ); + break; + case SvxDateFormat::F: + // Tuesday, 13. February 1996 + nFormatKey = rFormatter.GetFormatIndex( NF_DATE_SYS_NNNNDMMMMYYYY, eLang ); + break; + default: + nFormatKey = rFormatter.GetStandardFormat( SvNumFormatType::DATE, eLang ); + } + + double fDiffDate = aDate - rFormatter.GetNullDate(); + OUString aStr; + const Color* pColor = nullptr; + rFormatter.GetOutputString( fDiffDate, nFormatKey, aStr, &pColor ); + return aStr; +} + +MetaAction* SvxDateField::createBeginComment() const +{ + return new MetaCommentAction( "FIELD_SEQ_BEGIN" ); +} + +SvxURLField::SvxURLField() +{ + eFormat = SvxURLFormat::Url; +} + + +SvxURLField::SvxURLField( OUString _aURL, OUString aRepres, SvxURLFormat eFmt ) + : aURL(std::move( _aURL )), aRepresentation(std::move( aRepres )) +{ + eFormat = eFmt; +} + + +std::unique_ptr<SvxFieldData> SvxURLField::Clone() const +{ + return std::make_unique<SvxURLField>( *this ); +} + + +bool SvxURLField::operator==( const SvxFieldData& rOther ) const +{ + if ( typeid(rOther) != typeid(*this) ) + return false; + + const SvxURLField& rOtherFld = static_cast<const SvxURLField&>(rOther); + return ( ( eFormat == rOtherFld.eFormat ) && + ( aURL == rOtherFld.aURL ) && + ( aRepresentation == rOtherFld.aRepresentation ) && + ( aTargetFrame == rOtherFld.aTargetFrame ) ); +} + + +MetaAction* SvxURLField::createBeginComment() const +{ + // #i46618# Adding target URL to metafile comment + return new MetaCommentAction( "FIELD_SEQ_BEGIN", + 0, + reinterpret_cast<const sal_uInt8*>(aURL.getStr()), + 2*aURL.getLength() ); +} + +// +// SvxPageTitleField methods +// + +SvxPageTitleField::SvxPageTitleField() {} + +std::unique_ptr<SvxFieldData> SvxPageTitleField::Clone() const +{ + return std::make_unique<SvxPageTitleField>(); +} + +bool SvxPageTitleField::operator==( const SvxFieldData& rCmp ) const +{ + return ( dynamic_cast< const SvxPageTitleField *>(&rCmp) != nullptr ); +} + +MetaAction* SvxPageTitleField::createBeginComment() const +{ + return new MetaCommentAction( "FIELD_SEQ_BEGIN;PageTitleField" ); +} + +// +// SvxPagesField +// +// The fields that were removed from Calc: + + +SvxPageField::SvxPageField() {} + +std::unique_ptr<SvxFieldData> SvxPageField::Clone() const +{ + return std::make_unique<SvxPageField>(); // empty +} + +bool SvxPageField::operator==( const SvxFieldData& rCmp ) const +{ + return ( dynamic_cast< const SvxPageField *>(&rCmp) != nullptr ); +} + +MetaAction* SvxPageField::createBeginComment() const +{ + return new MetaCommentAction( "FIELD_SEQ_BEGIN;PageField" ); +} + + +SvxPagesField::SvxPagesField() {} + +std::unique_ptr<SvxFieldData> SvxPagesField::Clone() const +{ + return std::make_unique<SvxPagesField>(); // empty +} + +bool SvxPagesField::operator==( const SvxFieldData& rCmp ) const +{ + return ( dynamic_cast< const SvxPagesField *>(&rCmp) != nullptr); +} + +SvxTimeField::SvxTimeField() {} + +std::unique_ptr<SvxFieldData> SvxTimeField::Clone() const +{ + return std::make_unique<SvxTimeField>(); // empty +} + +bool SvxTimeField::operator==( const SvxFieldData& rCmp ) const +{ + return ( dynamic_cast< const SvxTimeField *>(&rCmp) != nullptr); +} + +MetaAction* SvxTimeField::createBeginComment() const +{ + return new MetaCommentAction( "FIELD_SEQ_BEGIN" ); +} + +SvxFileField::SvxFileField() {} + +std::unique_ptr<SvxFieldData> SvxFileField::Clone() const +{ + return std::make_unique<SvxFileField>(); // empty +} + +bool SvxFileField::operator==( const SvxFieldData& rCmp ) const +{ + return ( dynamic_cast< const SvxFileField *>(&rCmp) != nullptr ); +} + +SvxTableField::SvxTableField() : mnTab(0) {} + +SvxTableField::SvxTableField(int nTab) : mnTab(nTab) {} + +void SvxTableField::SetTab(int nTab) +{ + mnTab = nTab; +} + + +std::unique_ptr<SvxFieldData> SvxTableField::Clone() const +{ + return std::make_unique<SvxTableField>(mnTab); +} + +bool SvxTableField::operator==( const SvxFieldData& rCmp ) const +{ + if (dynamic_cast<const SvxTableField *>(&rCmp) == nullptr) + return false; + + return mnTab == static_cast<const SvxTableField&>(rCmp).mnTab; +} + +// SvxExtTimeField + + +SvxExtTimeField::SvxExtTimeField() + : m_nFixTime( tools::Time(tools::Time::SYSTEM).GetTime() ) +{ + eType = SvxTimeType::Var; + eFormat = SvxTimeFormat::Standard; +} + + +SvxExtTimeField::SvxExtTimeField( const tools::Time& rTime, SvxTimeType eT, SvxTimeFormat eF ) + : m_nFixTime( rTime.GetTime() ) +{ + eType = eT; + eFormat = eF; +} + + +std::unique_ptr<SvxFieldData> SvxExtTimeField::Clone() const +{ + return std::make_unique<SvxExtTimeField>( *this ); +} + + +bool SvxExtTimeField::operator==( const SvxFieldData& rOther ) const +{ + if ( typeid(rOther) != typeid(*this) ) + return false; + + const SvxExtTimeField& rOtherFld = static_cast<const SvxExtTimeField&>(rOther); + return ((m_nFixTime == rOtherFld.m_nFixTime) && + ( eType == rOtherFld.eType ) && + ( eFormat == rOtherFld.eFormat ) ); +} + + +OUString SvxExtTimeField::GetFormatted( SvNumberFormatter& rFormatter, LanguageType eLang ) const +{ + tools::Time aTime( tools::Time::EMPTY ); + if ( eType == SvxTimeType::Fix ) + aTime.SetTime(m_nFixTime); + else + aTime = tools::Time( tools::Time::SYSTEM ); // current time + return GetFormatted( aTime, eFormat, rFormatter, eLang ); +} + +OUString SvxExtTimeField::GetFormatted( tools::Time const & aTime, SvxTimeFormat eFormat, SvNumberFormatter& rFormatter, LanguageType eLang ) +{ + switch( eFormat ) + { + case SvxTimeFormat::System : + OSL_FAIL( "SvxTimeFormat::System: not implemented" ); + eFormat = SvxTimeFormat::Standard; + break; + case SvxTimeFormat::AppDefault : + OSL_FAIL( "SvxTimeFormat::AppDefault: not implemented" ); + eFormat = SvxTimeFormat::Standard; + break; + default: ;//prevent warning + } + + sal_uInt32 nFormatKey; + + switch( eFormat ) + { + case SvxTimeFormat::HH12_MM: + nFormatKey = rFormatter.GetFormatIndex( NF_TIME_HHMMAMPM, eLang ); + break; + case SvxTimeFormat::HH12_MM_SS_00: + { + // no builtin format available, try to insert or reuse + OUString aFormatCode( "HH:MM:SS.00 AM/PM" ); + sal_Int32 nCheckPos; + SvNumFormatType nType; + rFormatter.PutandConvertEntry( aFormatCode, nCheckPos, nType, + nFormatKey, LANGUAGE_ENGLISH_US, eLang, true); + DBG_ASSERT( nCheckPos == 0, "SvxTimeFormat::HH12_MM_SS_00: could not insert format code" ); + if ( nCheckPos ) + { + nFormatKey = rFormatter.GetFormatIndex( NF_TIME_HH_MMSS00, eLang ); + } + break; + } + case SvxTimeFormat::HH24_MM: + nFormatKey = rFormatter.GetFormatIndex( NF_TIME_HHMM, eLang ); + break; + case SvxTimeFormat::HH24_MM_SS_00: + nFormatKey = rFormatter.GetFormatIndex( NF_TIME_HH_MMSS00, eLang ); + break; + case SvxTimeFormat::HH12_MM_SS: + nFormatKey = rFormatter.GetFormatIndex( NF_TIME_HHMMSSAMPM, eLang ); + break; + case SvxTimeFormat::HH24_MM_SS: + nFormatKey = rFormatter.GetFormatIndex( NF_TIME_HHMMSS, eLang ); + break; + case SvxTimeFormat::Standard: + default: + nFormatKey = rFormatter.GetStandardFormat( SvNumFormatType::TIME, eLang ); + } + + double fFracTime = aTime.GetTimeInDays(); + OUString aStr; + const Color* pColor = nullptr; + rFormatter.GetOutputString( fFracTime, nFormatKey, aStr, &pColor ); + return aStr; +} + +MetaAction* SvxExtTimeField::createBeginComment() const +{ + return new MetaCommentAction( "FIELD_SEQ_BEGIN" ); +} + + +// SvxExtFileField + + +SvxExtFileField::SvxExtFileField() +{ + eType = SvxFileType::Var; + eFormat = SvxFileFormat::PathFull; +} + + +SvxExtFileField::SvxExtFileField( const OUString& rStr, SvxFileType eT, SvxFileFormat eF ) +{ + aFile = rStr; + eType = eT; + eFormat = eF; +} + + +std::unique_ptr<SvxFieldData> SvxExtFileField::Clone() const +{ + return std::make_unique<SvxExtFileField>( *this ); +} + + +bool SvxExtFileField::operator==( const SvxFieldData& rOther ) const +{ + if ( typeid(rOther) != typeid(*this) ) + return false; + + const SvxExtFileField& rOtherFld = static_cast<const SvxExtFileField&>(rOther); + return ( ( aFile == rOtherFld.aFile ) && + ( eType == rOtherFld.eType ) && + ( eFormat == rOtherFld.eFormat ) ); +} + + +OUString SvxExtFileField::GetFormatted() const +{ + OUString aString; + + INetURLObject aURLObj( aFile ); + + if( INetProtocol::NotValid == aURLObj.GetProtocol() ) + { + // invalid? try to interpret string as system file name + OUString aURLStr; + + osl::FileBase::getFileURLFromSystemPath( aFile, aURLStr ); + + aURLObj.SetURL( aURLStr ); + } + + // #92009# Be somewhat liberate when trying to + // get formatted content out of the FileField + if( INetProtocol::NotValid == aURLObj.GetProtocol() ) + { + // still not valid? Then output as is + aString = aFile; + } + else if( INetProtocol::File == aURLObj.GetProtocol() ) + { + switch( eFormat ) + { + case SvxFileFormat::PathFull: + aString = aURLObj.getFSysPath(FSysStyle::Detect); + break; + + case SvxFileFormat::PathOnly: + aURLObj.removeSegment(INetURLObject::LAST_SEGMENT, false); + // #101742# Leave trailing slash at the pathname + aURLObj.setFinalSlash(); + aString = aURLObj.getFSysPath(FSysStyle::Detect); + break; + + case SvxFileFormat::NameOnly: + aString = aURLObj.getBase(INetURLObject::LAST_SEGMENT,true,INetURLObject::DecodeMechanism::Unambiguous); + break; + + case SvxFileFormat::NameAndExt: + aString = aURLObj.getName(INetURLObject::LAST_SEGMENT,true,INetURLObject::DecodeMechanism::Unambiguous); + break; + } + } + else + { + switch( eFormat ) + { + case SvxFileFormat::PathFull: + aString = aURLObj.GetMainURL( INetURLObject::DecodeMechanism::ToIUri ); + break; + + case SvxFileFormat::PathOnly: + aURLObj.removeSegment(INetURLObject::LAST_SEGMENT, false); + // #101742# Leave trailing slash at the pathname + aURLObj.setFinalSlash(); + aString = aURLObj.GetMainURL( INetURLObject::DecodeMechanism::ToIUri ); + break; + + case SvxFileFormat::NameOnly: + aString = aURLObj.getBase(); + break; + + case SvxFileFormat::NameAndExt: + aString = aURLObj.getName(); + break; + } + } + + return aString; +} + + +// SvxAuthorField + + +SvxAuthorField::SvxAuthorField( const OUString& rFirstName, + const OUString& rLastName, + const OUString& rShortName, + SvxAuthorType eT, SvxAuthorFormat eF ) +{ + aName = rLastName; + aFirstName = rFirstName; + aShortName = rShortName; + eType = eT; + eFormat = eF; +} + + +std::unique_ptr<SvxFieldData> SvxAuthorField::Clone() const +{ + return std::make_unique<SvxAuthorField>( *this ); +} + + +bool SvxAuthorField::operator==( const SvxFieldData& rOther ) const +{ + if ( typeid(rOther) != typeid(*this) ) + return false; + + const SvxAuthorField& rOtherFld = static_cast<const SvxAuthorField&>(rOther); + return ( ( aName == rOtherFld.aName ) && + ( aFirstName == rOtherFld.aFirstName ) && + ( aShortName == rOtherFld.aShortName ) && + ( eType == rOtherFld.eType ) && + ( eFormat == rOtherFld.eFormat ) ); +} + + +OUString SvxAuthorField::GetFormatted() const +{ + OUString aString; + + switch( eFormat ) + { + case SvxAuthorFormat::FullName: + aString = aFirstName + " " + aName; + break; + case SvxAuthorFormat::LastName: + aString = aName; + break; + + case SvxAuthorFormat::FirstName: + aString = aFirstName; + break; + + case SvxAuthorFormat::ShortName: + aString = aShortName; + break; + } + + return aString; +} + +SvxHeaderField::SvxHeaderField() {} + +std::unique_ptr<SvxFieldData> SvxHeaderField::Clone() const +{ + return std::make_unique<SvxHeaderField>(); // empty +} + +bool SvxHeaderField::operator==( const SvxFieldData& rCmp ) const +{ + return ( dynamic_cast< const SvxHeaderField *>(&rCmp) != nullptr ); +} + +SvxFooterField::SvxFooterField() {} + +std::unique_ptr<SvxFieldData> SvxFooterField::Clone() const +{ + return std::make_unique<SvxFooterField>(); // empty +} + +bool SvxFooterField::operator==( const SvxFieldData& rCmp ) const +{ + return ( dynamic_cast< const SvxFooterField *>(&rCmp) != nullptr ); +} + +std::unique_ptr<SvxFieldData> SvxDateTimeField::Clone() const +{ + return std::make_unique<SvxDateTimeField>(); // empty +} + +bool SvxDateTimeField::operator==( const SvxFieldData& rCmp ) const +{ + return ( dynamic_cast< const SvxDateTimeField *>(&rCmp) != nullptr ); +} + +SvxDateTimeField::SvxDateTimeField() {} + +OUString SvxDateTimeField::GetFormatted( + Date const & rDate, tools::Time const & rTime, + SvxDateFormat eDateFormat, SvxTimeFormat eTimeFormat, + SvNumberFormatter& rFormatter, LanguageType eLanguage ) +{ + OUString aRet; + + if(eDateFormat != SvxDateFormat::AppDefault) + { + aRet = SvxDateField::GetFormatted( rDate, eDateFormat, rFormatter, eLanguage ); + } + + if(eTimeFormat != SvxTimeFormat::AppDefault) + { + OUStringBuffer aBuf(aRet); + + if (!aRet.isEmpty()) + aBuf.append(' '); + + aBuf.append( + SvxExtTimeField::GetFormatted(rTime, eTimeFormat, rFormatter, eLanguage)); + + aRet = aBuf.makeStringAndClear(); + } + + return aRet; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/editeng/source/items/frmitems.cxx b/editeng/source/items/frmitems.cxx new file mode 100644 index 000000000..35e1be7b0 --- /dev/null +++ b/editeng/source/items/frmitems.cxx @@ -0,0 +1,3518 @@ +/* -*- 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 <com/sun/star/uno/Any.hxx> +#include <com/sun/star/drawing/LineStyle.hpp> +#include <com/sun/star/script/Converter.hpp> +#include <com/sun/star/table/ShadowLocation.hpp> +#include <com/sun/star/table/ShadowFormat.hpp> +#include <com/sun/star/table/BorderLine2.hpp> +#include <com/sun/star/table/BorderLineStyle.hpp> +#include <com/sun/star/style/BreakType.hpp> +#include <com/sun/star/style/GraphicLocation.hpp> +#include <com/sun/star/awt/Size.hpp> +#include <com/sun/star/text/WritingMode2.hpp> +#include <com/sun/star/frame/status/UpperLowerMarginScale.hpp> +#include <com/sun/star/frame/status/LeftRightMarginScale.hpp> +#include <com/sun/star/drawing/ShadingPattern.hpp> +#include <com/sun/star/graphic/XGraphic.hpp> + +#include <osl/diagnose.h> +#include <i18nutil/unicode.hxx> +#include <unotools/ucbstreamhelper.hxx> +#include <comphelper/processfactory.hxx> +#include <utility> +#include <vcl/GraphicObject.hxx> +#include <tools/urlobj.hxx> +#include <tools/bigint.hxx> +#include <svl/memberid.h> +#include <rtl/math.hxx> +#include <rtl/ustring.hxx> +#include <tools/mapunit.hxx> +#include <tools/UnitConversion.hxx> +#include <vcl/graphicfilter.hxx> +#include <vcl/settings.hxx> +#include <vcl/svapp.hxx> +#include <editeng/editrids.hrc> +#include <editeng/pbinitem.hxx> +#include <editeng/sizeitem.hxx> +#include <editeng/lrspitem.hxx> +#include <editeng/ulspitem.hxx> +#include <editeng/prntitem.hxx> +#include <editeng/opaqitem.hxx> +#include <editeng/protitem.hxx> +#include <editeng/shaditem.hxx> +#include <editeng/borderline.hxx> +#include <editeng/boxitem.hxx> +#include <editeng/formatbreakitem.hxx> +#include <editeng/keepitem.hxx> +#include <editeng/lineitem.hxx> +#include <editeng/brushitem.hxx> +#include <editeng/frmdiritem.hxx> +#include <editeng/itemtype.hxx> +#include <editeng/eerdll.hxx> +#include <editeng/memberids.h> +#include <libxml/xmlwriter.h> +#include <o3tl/enumrange.hxx> +#include <o3tl/safeint.hxx> +#include <vcl/GraphicLoader.hxx> +#include <unotools/securityoptions.hxx> + +#include <boost/property_tree/ptree.hpp> + +using namespace ::editeng; +using namespace ::com::sun::star; +using namespace ::com::sun::star::drawing; +using namespace ::com::sun::star::table::BorderLineStyle; + + +SfxPoolItem* SvxPaperBinItem::CreateDefault() { return new SvxPaperBinItem(0);} +SfxPoolItem* SvxSizeItem::CreateDefault() { return new SvxSizeItem(0);} +SfxPoolItem* SvxLRSpaceItem::CreateDefault() { return new SvxLRSpaceItem(0);} +SfxPoolItem* SvxULSpaceItem::CreateDefault() { return new SvxULSpaceItem(0);} +SfxPoolItem* SvxProtectItem::CreateDefault() { return new SvxProtectItem(0);} +SfxPoolItem* SvxBrushItem::CreateDefault() { return new SvxBrushItem(0);} +SfxPoolItem* SvxShadowItem::CreateDefault() { return new SvxShadowItem(0);} +SfxPoolItem* SvxBoxItem::CreateDefault() { return new SvxBoxItem(0);} +SfxPoolItem* SvxBoxInfoItem::CreateDefault() { return new SvxBoxInfoItem(0);} +SfxPoolItem* SvxFormatBreakItem::CreateDefault() { return new SvxFormatBreakItem(SvxBreak::NONE, 0);} +SfxPoolItem* SvxFormatKeepItem::CreateDefault() { return new SvxFormatKeepItem(false, 0);} +SfxPoolItem* SvxLineItem::CreateDefault() { return new SvxLineItem(0);} + +SvxPaperBinItem* SvxPaperBinItem::Clone( SfxItemPool* ) const +{ + return new SvxPaperBinItem( *this ); +} + +bool SvxPaperBinItem::GetPresentation +( + SfxItemPresentation ePres, + MapUnit /*eCoreUnit*/, + MapUnit /*ePresUnit*/, + OUString& rText, const IntlWrapper& +) const +{ + switch ( ePres ) + { + case SfxItemPresentation::Nameless: + rText = OUString::number( GetValue() ); + return true; + + case SfxItemPresentation::Complete: + { + sal_uInt8 nValue = GetValue(); + + if ( PAPERBIN_PRINTER_SETTINGS == nValue ) + rText = EditResId(RID_SVXSTR_PAPERBIN_SETTINGS); + else + { + rText = EditResId(RID_SVXSTR_PAPERBIN) + " " + OUString::number( nValue ); + } + return true; + } + //no break necessary + default: ; //prevent warning + } + + return false; +} + + +SvxSizeItem::SvxSizeItem( const sal_uInt16 nId, const Size& rSize ) : + + SfxPoolItem( nId ), + + m_aSize( rSize ) +{ +} + + +bool SvxSizeItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const +{ + bool bConvert = 0!=(nMemberId&CONVERT_TWIPS); + nMemberId &= ~CONVERT_TWIPS; + + awt::Size aTmp(m_aSize.Width(), m_aSize.Height()); + if( bConvert ) + { + aTmp.Height = convertTwipToMm100(aTmp.Height); + aTmp.Width = convertTwipToMm100(aTmp.Width); + } + + switch( nMemberId ) + { + case MID_SIZE_SIZE: rVal <<= aTmp; break; + case MID_SIZE_WIDTH: rVal <<= aTmp.Width; break; + case MID_SIZE_HEIGHT: rVal <<= aTmp.Height; break; + default: OSL_FAIL("Wrong MemberId!"); return false; + } + + return true; +} + + +bool SvxSizeItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId ) +{ + bool bConvert = 0!=(nMemberId&CONVERT_TWIPS); + nMemberId &= ~CONVERT_TWIPS; + + switch( nMemberId ) + { + case MID_SIZE_SIZE: + { + awt::Size aTmp; + if( rVal >>= aTmp ) + { + if(bConvert) + { + aTmp.Height = o3tl::toTwips(aTmp.Height, o3tl::Length::mm100); + aTmp.Width = o3tl::toTwips(aTmp.Width, o3tl::Length::mm100); + } + m_aSize = Size( aTmp.Width, aTmp.Height ); + } + else + { + return false; + } + } + break; + case MID_SIZE_WIDTH: + { + sal_Int32 nVal = 0; + if(!(rVal >>= nVal )) + return false; + + m_aSize.setWidth( bConvert ? o3tl::toTwips(nVal, o3tl::Length::mm100) : nVal ); + } + break; + case MID_SIZE_HEIGHT: + { + sal_Int32 nVal = 0; + if(!(rVal >>= nVal)) + return true; + + m_aSize.setHeight( bConvert ? o3tl::toTwips(nVal, o3tl::Length::mm100) : nVal ); + } + break; + default: OSL_FAIL("Wrong MemberId!"); + return false; + } + return true; +} + + +SvxSizeItem::SvxSizeItem( const sal_uInt16 nId ) : + + SfxPoolItem( nId ) +{ +} + + +bool SvxSizeItem::operator==( const SfxPoolItem& rAttr ) const +{ + assert(SfxPoolItem::operator==(rAttr)); + + return ( m_aSize == static_cast<const SvxSizeItem&>( rAttr ).GetSize() ); +} + +SvxSizeItem* SvxSizeItem::Clone( SfxItemPool* ) const +{ + return new SvxSizeItem( *this ); +} + +bool SvxSizeItem::GetPresentation +( + SfxItemPresentation ePres, + MapUnit eCoreUnit, + MapUnit ePresUnit, + OUString& rText, const IntlWrapper& rIntl +) const +{ + OUString cpDelimTmp(cpDelim); + switch ( ePres ) + { + case SfxItemPresentation::Nameless: + rText = GetMetricText( m_aSize.Width(), eCoreUnit, ePresUnit, &rIntl ) + + cpDelimTmp + + GetMetricText( m_aSize.Height(), eCoreUnit, ePresUnit, &rIntl ); + return true; + + case SfxItemPresentation::Complete: + rText = EditResId(RID_SVXITEMS_SIZE_WIDTH) + + GetMetricText( m_aSize.Width(), eCoreUnit, ePresUnit, &rIntl ) + + " " + EditResId(GetMetricId(ePresUnit)) + + cpDelimTmp + + EditResId(RID_SVXITEMS_SIZE_HEIGHT) + + GetMetricText( m_aSize.Height(), eCoreUnit, ePresUnit, &rIntl ) + + " " + EditResId(GetMetricId(ePresUnit)); + return true; + // no break necessary + default: ; // prevent warning + + } + return false; +} + + +void SvxSizeItem::ScaleMetrics( tools::Long nMult, tools::Long nDiv ) +{ + m_aSize.setWidth( BigInt::Scale( m_aSize.Width(), nMult, nDiv ) ); + m_aSize.setHeight( BigInt::Scale( m_aSize.Height(), nMult, nDiv ) ); +} + + +bool SvxSizeItem::HasMetrics() const +{ + return true; +} + + +SvxLRSpaceItem::SvxLRSpaceItem( const sal_uInt16 nId ) : + + SfxPoolItem( nId ), + + nTxtLeft ( 0 ), + nLeftMargin ( 0 ), + nRightMargin ( 0 ), + m_nGutterMargin(0), + m_nRightGutterMargin(0), + nPropFirstLineOffset( 100 ), + nPropLeftMargin( 100 ), + nPropRightMargin( 100 ), + nFirstLineOffset ( 0 ), + bAutoFirst ( false ), + bExplicitZeroMarginValRight(false), + bExplicitZeroMarginValLeft(false) +{ +} + + +SvxLRSpaceItem::SvxLRSpaceItem( const tools::Long nLeft, const tools::Long nRight, + const tools::Long nTLeft, const short nOfset, + const sal_uInt16 nId ) +: SfxPoolItem( nId ), + + nTxtLeft ( nTLeft ), + nLeftMargin ( nLeft ), + nRightMargin ( nRight ), + m_nGutterMargin(0), + m_nRightGutterMargin(0), + nPropFirstLineOffset( 100 ), + nPropLeftMargin( 100 ), + nPropRightMargin( 100 ), + nFirstLineOffset ( nOfset ), + bAutoFirst ( false ), + bExplicitZeroMarginValRight(false), + bExplicitZeroMarginValLeft(false) +{ +} + + +bool SvxLRSpaceItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const +{ + bool bRet = true; + bool bConvert = 0!=(nMemberId&CONVERT_TWIPS); + nMemberId &= ~CONVERT_TWIPS; + switch( nMemberId ) + { + // now all signed + case 0: + { + css::frame::status::LeftRightMarginScale aLRSpace; + aLRSpace.Left = static_cast<sal_Int32>(bConvert ? convertTwipToMm100(nLeftMargin) : nLeftMargin); + aLRSpace.TextLeft = static_cast<sal_Int32>(bConvert ? convertTwipToMm100(nTxtLeft) : nTxtLeft); + aLRSpace.Right = static_cast<sal_Int32>(bConvert ? convertTwipToMm100(nRightMargin) : nRightMargin); + aLRSpace.ScaleLeft = static_cast<sal_Int16>(nPropLeftMargin); + aLRSpace.ScaleRight = static_cast<sal_Int16>(nPropRightMargin); + aLRSpace.FirstLine = static_cast<sal_Int32>(bConvert ? convertTwipToMm100(nFirstLineOffset) : nFirstLineOffset); + aLRSpace.ScaleFirstLine = static_cast<sal_Int16>(nPropFirstLineOffset); + aLRSpace.AutoFirstLine = IsAutoFirst(); + rVal <<= aLRSpace; + break; + } + case MID_L_MARGIN: + rVal <<= static_cast<sal_Int32>(bConvert ? convertTwipToMm100(nLeftMargin) : nLeftMargin); + break; + + case MID_TXT_LMARGIN : + rVal <<= static_cast<sal_Int32>(bConvert ? convertTwipToMm100(nTxtLeft) : nTxtLeft); + break; + case MID_R_MARGIN: + rVal <<= static_cast<sal_Int32>(bConvert ? convertTwipToMm100(nRightMargin) : nRightMargin); + break; + case MID_L_REL_MARGIN: + rVal <<= static_cast<sal_Int16>(nPropLeftMargin); + break; + case MID_R_REL_MARGIN: + rVal <<= static_cast<sal_Int16>(nPropRightMargin); + break; + + case MID_FIRST_LINE_INDENT: + rVal <<= static_cast<sal_Int32>(bConvert ? convertTwipToMm100(nFirstLineOffset) : nFirstLineOffset); + break; + + case MID_FIRST_LINE_REL_INDENT: + rVal <<= static_cast<sal_Int16>(nPropFirstLineOffset); + break; + + case MID_FIRST_AUTO: + rVal <<= IsAutoFirst(); + break; + + case MID_GUTTER_MARGIN: + rVal <<= static_cast<sal_Int32>(bConvert ? convertTwipToMm100(m_nGutterMargin) + : m_nGutterMargin); + break; + + default: + bRet = false; + // SfxDispatchController_Impl::StateChanged calls this with hardcoded 0 triggering this; there used to be a MID_LR_MARGIN 0 but what type would it have? + OSL_FAIL("unknown MemberId"); + } + return bRet; +} + + +bool SvxLRSpaceItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId ) +{ + bool bConvert = 0 != (nMemberId&CONVERT_TWIPS); + nMemberId &= ~CONVERT_TWIPS; + sal_Int32 nVal = 0; + if( nMemberId != 0 && nMemberId != MID_FIRST_AUTO && + nMemberId != MID_L_REL_MARGIN && nMemberId != MID_R_REL_MARGIN) + if(!(rVal >>= nVal)) + return false; + + switch( nMemberId ) + { + case 0: + { + css::frame::status::LeftRightMarginScale aLRSpace; + if(!(rVal >>= aLRSpace)) + return false; + + SetLeft( bConvert ? o3tl::toTwips(aLRSpace.Left, o3tl::Length::mm100) : aLRSpace.Left ); + SetTextLeft( bConvert ? o3tl::toTwips(aLRSpace.TextLeft, o3tl::Length::mm100) : aLRSpace.TextLeft ); + SetRight(bConvert ? o3tl::toTwips(aLRSpace.Right, o3tl::Length::mm100) : aLRSpace.Right); + nPropLeftMargin = aLRSpace.ScaleLeft; + nPropRightMargin = aLRSpace.ScaleRight; + SetTextFirstLineOffset(bConvert ? o3tl::toTwips(aLRSpace.FirstLine, o3tl::Length::mm100) : aLRSpace.FirstLine); + SetPropTextFirstLineOffset ( aLRSpace.ScaleFirstLine ); + SetAutoFirst( aLRSpace.AutoFirstLine ); + break; + } + case MID_L_MARGIN: + SetLeft( bConvert ? o3tl::toTwips(nVal, o3tl::Length::mm100) : nVal ); + break; + + case MID_TXT_LMARGIN : + SetTextLeft( bConvert ? o3tl::toTwips(nVal, o3tl::Length::mm100) : nVal ); + break; + + case MID_R_MARGIN: + SetRight(bConvert ? o3tl::toTwips(nVal, o3tl::Length::mm100) : nVal); + break; + case MID_L_REL_MARGIN: + case MID_R_REL_MARGIN: + { + sal_Int32 nRel = 0; + if((rVal >>= nRel) && nRel >= 0 && nRel < SAL_MAX_UINT16) + { + if(MID_L_REL_MARGIN== nMemberId) + nPropLeftMargin = static_cast<sal_uInt16>(nRel); + else + nPropRightMargin = static_cast<sal_uInt16>(nRel); + } + else + return false; + } + break; + case MID_FIRST_LINE_INDENT : + SetTextFirstLineOffset(bConvert ? o3tl::toTwips(nVal, o3tl::Length::mm100) : nVal); + break; + + case MID_FIRST_LINE_REL_INDENT: + SetPropTextFirstLineOffset ( nVal ); + break; + + case MID_FIRST_AUTO: + SetAutoFirst( Any2Bool(rVal) ); + break; + + case MID_GUTTER_MARGIN: + SetGutterMargin(bConvert ? o3tl::toTwips(nVal, o3tl::Length::mm100) : nVal); + break; + + default: + OSL_FAIL("unknown MemberId"); + return false; + } + return true; +} + + +/// Adapt nLeftMargin and nTxtLeft. +void SvxLRSpaceItem::AdjustLeft() +{ + if ( 0 > nFirstLineOffset ) + nLeftMargin = nTxtLeft + nFirstLineOffset; + else + nLeftMargin = nTxtLeft; +} + + +bool SvxLRSpaceItem::operator==( const SfxPoolItem& rAttr ) const +{ + assert(SfxPoolItem::operator==(rAttr)); + + const SvxLRSpaceItem& rOther = static_cast<const SvxLRSpaceItem&>(rAttr); + + return ( + nFirstLineOffset == rOther.GetTextFirstLineOffset() && + nTxtLeft == rOther.GetTextLeft() && + m_nGutterMargin == rOther.GetGutterMargin() && + m_nRightGutterMargin == rOther.GetRightGutterMargin() && + nLeftMargin == rOther.GetLeft() && + nRightMargin == rOther.GetRight() && + nPropFirstLineOffset == rOther.GetPropTextFirstLineOffset() && + nPropLeftMargin == rOther.GetPropLeft() && + nPropRightMargin == rOther.GetPropRight() && + bAutoFirst == rOther.IsAutoFirst() && + bExplicitZeroMarginValRight == rOther.IsExplicitZeroMarginValRight() && + bExplicitZeroMarginValLeft == rOther.IsExplicitZeroMarginValLeft() ); +} + +SvxLRSpaceItem* SvxLRSpaceItem::Clone( SfxItemPool* ) const +{ + return new SvxLRSpaceItem( *this ); +} + +bool SvxLRSpaceItem::GetPresentation +( + SfxItemPresentation ePres, + MapUnit eCoreUnit, + MapUnit ePresUnit, + OUString& rText, const IntlWrapper& rIntl +) const +{ + switch ( ePres ) + { + case SfxItemPresentation::Nameless: + { + if ( 100 != nPropLeftMargin ) + { + rText = unicode::formatPercent(nPropLeftMargin, + Application::GetSettings().GetUILanguageTag()); + } + else + rText = GetMetricText( nLeftMargin, + eCoreUnit, ePresUnit, &rIntl ); + rText += cpDelim; + if ( 100 != nPropFirstLineOffset ) + { + rText += unicode::formatPercent(nPropFirstLineOffset, + Application::GetSettings().GetUILanguageTag()); + } + else + rText += GetMetricText( static_cast<tools::Long>(nFirstLineOffset), + eCoreUnit, ePresUnit, &rIntl ); + rText += cpDelim; + if ( 100 != nRightMargin ) + { + rText += unicode::formatPercent(nRightMargin, + Application::GetSettings().GetUILanguageTag()); + } + else + rText += GetMetricText( nRightMargin, + eCoreUnit, ePresUnit, &rIntl ); + return true; + } + case SfxItemPresentation::Complete: + { + rText = EditResId(RID_SVXITEMS_LRSPACE_LEFT); + if ( 100 != nPropLeftMargin ) + rText += unicode::formatPercent(nPropLeftMargin, + Application::GetSettings().GetUILanguageTag()); + else + { + rText += GetMetricText( nLeftMargin, eCoreUnit, ePresUnit, &rIntl ) + + " " + EditResId(GetMetricId(ePresUnit)); + } + rText += cpDelim; + if ( 100 != nPropFirstLineOffset || nFirstLineOffset ) + { + rText += EditResId(RID_SVXITEMS_LRSPACE_FLINE); + if ( 100 != nPropFirstLineOffset ) + rText += unicode::formatPercent(nPropFirstLineOffset, + Application::GetSettings().GetUILanguageTag()); + else + { + rText += GetMetricText( static_cast<tools::Long>(nFirstLineOffset), + eCoreUnit, ePresUnit, &rIntl ) + + " " + EditResId(GetMetricId(ePresUnit)); + } + rText += cpDelim; + } + rText += EditResId(RID_SVXITEMS_LRSPACE_RIGHT); + if ( 100 != nPropRightMargin ) + rText += unicode::formatPercent(nPropRightMargin, + Application::GetSettings().GetUILanguageTag()); + else + { + rText += GetMetricText( nRightMargin, + eCoreUnit, ePresUnit, &rIntl ) + + " " + EditResId(GetMetricId(ePresUnit)); + } + return true; + } + default: ; // prevent warning + } + return false; +} + + +void SvxLRSpaceItem::ScaleMetrics( tools::Long nMult, tools::Long nDiv ) +{ + nFirstLineOffset = static_cast<short>(BigInt::Scale( nFirstLineOffset, nMult, nDiv )); + nTxtLeft = BigInt::Scale( nTxtLeft, nMult, nDiv ); + nLeftMargin = BigInt::Scale( nLeftMargin, nMult, nDiv ); + nRightMargin = BigInt::Scale( nRightMargin, nMult, nDiv ); +} + + +bool SvxLRSpaceItem::HasMetrics() const +{ + return true; +} + + +void SvxLRSpaceItem::dumpAsXml(xmlTextWriterPtr pWriter) const +{ + (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SvxLRSpaceItem")); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr())); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nFirstLineOffset"), BAD_CAST(OString::number(nFirstLineOffset).getStr())); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nTxtLeft"), BAD_CAST(OString::number(nTxtLeft).getStr())); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nLeftMargin"), BAD_CAST(OString::number(nLeftMargin).getStr())); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nRightMargin"), BAD_CAST(OString::number(nRightMargin).getStr())); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("m_nGutterMargin"), + BAD_CAST(OString::number(m_nGutterMargin).getStr())); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("m_nRightGutterMargin"), + BAD_CAST(OString::number(m_nRightGutterMargin).getStr())); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nPropFirstLineOffset"), BAD_CAST(OString::number(nPropFirstLineOffset).getStr())); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nPropLeftMargin"), BAD_CAST(OString::number(nPropLeftMargin).getStr())); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nPropRightMargin"), BAD_CAST(OString::number(nPropRightMargin).getStr())); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("bAutoFirst"), BAD_CAST(OString::number(int(bAutoFirst)).getStr())); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("bExplicitZeroMarginValRight"), BAD_CAST(OString::number(int(bExplicitZeroMarginValRight)).getStr())); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("bExplicitZeroMarginValLeft"), BAD_CAST(OString::number(int(bExplicitZeroMarginValLeft)).getStr())); + (void)xmlTextWriterEndElement(pWriter); +} + + +boost::property_tree::ptree SvxLRSpaceItem::dumpAsJSON() const +{ + boost::property_tree::ptree aTree = SfxPoolItem::dumpAsJSON(); + + boost::property_tree::ptree aState; + + MapUnit eTargetUnit = MapUnit::MapInch; + + OUString sLeft = GetMetricText(GetLeft(), + MapUnit::MapTwip, eTargetUnit, nullptr); + + OUString sRight = GetMetricText(GetRight(), + MapUnit::MapTwip, eTargetUnit, nullptr); + + OUString sFirstline = GetMetricText(GetTextFirstLineOffset(), + MapUnit::MapTwip, eTargetUnit, nullptr); + + aState.put("left", sLeft); + aState.put("right", sRight); + aState.put("firstline", sFirstline); + aState.put("unit", "inch"); + + aTree.push_back(std::make_pair("state", aState)); + + return aTree; +} + + +SvxULSpaceItem::SvxULSpaceItem( const sal_uInt16 nId ) + : SfxPoolItem(nId) + , nUpper(0) + , nLower(0) + , bContext(false) + , nPropUpper(100) + , nPropLower(100) +{ +} + + +SvxULSpaceItem::SvxULSpaceItem( const sal_uInt16 nUp, const sal_uInt16 nLow, + const sal_uInt16 nId ) + : SfxPoolItem(nId) + , nUpper(nUp) + , nLower(nLow) + , bContext(false) + , nPropUpper(100) + , nPropLower(100) +{ +} + + +bool SvxULSpaceItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const +{ + bool bConvert = 0!=(nMemberId&CONVERT_TWIPS); + nMemberId &= ~CONVERT_TWIPS; + switch( nMemberId ) + { + // now all signed + case 0: + { + css::frame::status::UpperLowerMarginScale aUpperLowerMarginScale; + aUpperLowerMarginScale.Upper = static_cast<sal_Int32>(bConvert ? convertTwipToMm100(nUpper) : nUpper); + aUpperLowerMarginScale.Lower = static_cast<sal_Int32>(bConvert ? convertTwipToMm100(nLower) : nPropUpper); + aUpperLowerMarginScale.ScaleUpper = static_cast<sal_Int16>(nPropUpper); + aUpperLowerMarginScale.ScaleLower = static_cast<sal_Int16>(nPropLower); + rVal <<= aUpperLowerMarginScale; + break; + } + case MID_UP_MARGIN: rVal <<= static_cast<sal_Int32>(bConvert ? convertTwipToMm100(nUpper) : nUpper); break; + case MID_LO_MARGIN: rVal <<= static_cast<sal_Int32>(bConvert ? convertTwipToMm100(nLower) : nLower); break; + case MID_CTX_MARGIN: rVal <<= bContext; break; + case MID_UP_REL_MARGIN: rVal <<= static_cast<sal_Int16>(nPropUpper); break; + case MID_LO_REL_MARGIN: rVal <<= static_cast<sal_Int16>(nPropLower); break; + } + return true; +} + + +bool SvxULSpaceItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId ) +{ + bool bConvert = 0!=(nMemberId&CONVERT_TWIPS); + nMemberId &= ~CONVERT_TWIPS; + sal_Int32 nVal = 0; + bool bVal = false; + switch( nMemberId ) + { + case 0: + { + css::frame::status::UpperLowerMarginScale aUpperLowerMarginScale; + if ( !(rVal >>= aUpperLowerMarginScale )) + return false; + { + SetUpper(bConvert ? o3tl::toTwips(aUpperLowerMarginScale.Upper, o3tl::Length::mm100) : aUpperLowerMarginScale.Upper); + SetLower(bConvert ? o3tl::toTwips(aUpperLowerMarginScale.Lower, o3tl::Length::mm100) : aUpperLowerMarginScale.Lower); + if( aUpperLowerMarginScale.ScaleUpper > 1 ) + nPropUpper = aUpperLowerMarginScale.ScaleUpper; + if( aUpperLowerMarginScale.ScaleLower > 1 ) + nPropUpper = aUpperLowerMarginScale.ScaleLower; + } + } + break; + case MID_UP_MARGIN : + if(!(rVal >>= nVal)) + return false; + SetUpper(bConvert ? o3tl::toTwips(nVal, o3tl::Length::mm100) : nVal); + break; + case MID_LO_MARGIN : + if(!(rVal >>= nVal) || nVal < 0) + return false; + SetLower(bConvert ? o3tl::toTwips(nVal, o3tl::Length::mm100) : nVal); + break; + case MID_CTX_MARGIN : + if (!(rVal >>= bVal)) + return false; + SetContextValue(bVal); + break; + case MID_UP_REL_MARGIN: + case MID_LO_REL_MARGIN: + { + sal_Int32 nRel = 0; + if((rVal >>= nRel) && nRel > 1 ) + { + if(MID_UP_REL_MARGIN == nMemberId) + nPropUpper = static_cast<sal_uInt16>(nRel); + else + nPropLower = static_cast<sal_uInt16>(nRel); + } + else + return false; + } + break; + + default: + OSL_FAIL("unknown MemberId"); + return false; + } + return true; +} + + +bool SvxULSpaceItem::operator==( const SfxPoolItem& rAttr ) const +{ + assert(SfxPoolItem::operator==(rAttr)); + + const SvxULSpaceItem& rSpaceItem = static_cast<const SvxULSpaceItem&>( rAttr ); + return ( nUpper == rSpaceItem.nUpper && + nLower == rSpaceItem.nLower && + bContext == rSpaceItem.bContext && + nPropUpper == rSpaceItem.nPropUpper && + nPropLower == rSpaceItem.nPropLower ); +} + +SvxULSpaceItem* SvxULSpaceItem::Clone( SfxItemPool* ) const +{ + return new SvxULSpaceItem( *this ); +} + +bool SvxULSpaceItem::GetPresentation +( + SfxItemPresentation ePres, + MapUnit eCoreUnit, + MapUnit ePresUnit, + OUString& rText, + const IntlWrapper& rIntl +) const +{ + switch ( ePres ) + { + case SfxItemPresentation::Nameless: + { + if ( 100 != nPropUpper ) + { + rText = unicode::formatPercent(nPropUpper, + Application::GetSettings().GetUILanguageTag()); + } + else + rText = GetMetricText( static_cast<tools::Long>(nUpper), eCoreUnit, ePresUnit, &rIntl ); + rText += cpDelim; + if ( 100 != nPropLower ) + { + rText += unicode::formatPercent(nPropLower, + Application::GetSettings().GetUILanguageTag()); + } + else + rText += GetMetricText( static_cast<tools::Long>(nLower), eCoreUnit, ePresUnit, &rIntl ); + return true; + } + case SfxItemPresentation::Complete: + { + rText = EditResId(RID_SVXITEMS_ULSPACE_UPPER); + if ( 100 != nPropUpper ) + { + rText += unicode::formatPercent(nPropUpper, + Application::GetSettings().GetUILanguageTag()); + } + else + { + rText += GetMetricText( static_cast<tools::Long>(nUpper), eCoreUnit, ePresUnit, &rIntl ) + + " " + EditResId(GetMetricId(ePresUnit)); + } + rText += cpDelim + EditResId(RID_SVXITEMS_ULSPACE_LOWER); + if ( 100 != nPropLower ) + { + rText += unicode::formatPercent(nPropLower, + Application::GetSettings().GetUILanguageTag()); + } + else + { + rText += GetMetricText( static_cast<tools::Long>(nLower), eCoreUnit, ePresUnit, &rIntl ) + + " " + EditResId(GetMetricId(ePresUnit)); + } + return true; + } + default: ; // prevent warning + } + return false; +} + + +void SvxULSpaceItem::ScaleMetrics( tools::Long nMult, tools::Long nDiv ) +{ + nUpper = static_cast<sal_uInt16>(BigInt::Scale( nUpper, nMult, nDiv )); + nLower = static_cast<sal_uInt16>(BigInt::Scale( nLower, nMult, nDiv )); +} + + +bool SvxULSpaceItem::HasMetrics() const +{ + return true; +} + + +void SvxULSpaceItem::dumpAsXml(xmlTextWriterPtr pWriter) const +{ + (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SvxULSpaceItem")); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr())); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nUpper"), BAD_CAST(OString::number(nUpper).getStr())); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nLower"), BAD_CAST(OString::number(nLower).getStr())); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("bContext"), BAD_CAST(OString::boolean(bContext).getStr())); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nPropUpper"), BAD_CAST(OString::number(nPropUpper).getStr())); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nPropLower"), BAD_CAST(OString::number(nPropLower).getStr())); + (void)xmlTextWriterEndElement(pWriter); +} + +boost::property_tree::ptree SvxULSpaceItem::dumpAsJSON() const +{ + boost::property_tree::ptree aTree = SfxPoolItem::dumpAsJSON(); + + boost::property_tree::ptree aState; + + MapUnit eTargetUnit = MapUnit::MapInch; + + OUString sUpper = GetMetricText(GetUpper(), + MapUnit::MapTwip, eTargetUnit, nullptr); + + OUString sLower = GetMetricText(GetLower(), + MapUnit::MapTwip, eTargetUnit, nullptr); + + aState.put("upper", sUpper); + aState.put("lower", sLower); + aState.put("unit", "inch"); + + aTree.push_back(std::make_pair("state", aState)); + + return aTree; +} + +SvxPrintItem* SvxPrintItem::Clone( SfxItemPool* ) const +{ + return new SvxPrintItem( *this ); +} + +bool SvxPrintItem::GetPresentation +( + SfxItemPresentation /*ePres*/, + MapUnit /*eCoreUnit*/, + MapUnit /*ePresUnit*/, + OUString& rText, const IntlWrapper& +) const +{ + TranslateId pId = RID_SVXITEMS_PRINT_FALSE; + + if ( GetValue() ) + pId = RID_SVXITEMS_PRINT_TRUE; + rText = EditResId(pId); + return true; +} + +SvxOpaqueItem* SvxOpaqueItem::Clone( SfxItemPool* ) const +{ + return new SvxOpaqueItem( *this ); +} + +bool SvxOpaqueItem::GetPresentation +( + SfxItemPresentation /*ePres*/, + MapUnit /*eCoreUnit*/, + MapUnit /*ePresUnit*/, + OUString& rText, const IntlWrapper& +) const +{ + TranslateId pId = RID_SVXITEMS_OPAQUE_FALSE; + + if ( GetValue() ) + pId = RID_SVXITEMS_OPAQUE_TRUE; + rText = EditResId(pId); + return true; +} + + +bool SvxProtectItem::operator==( const SfxPoolItem& rAttr ) const +{ + assert(SfxPoolItem::operator==(rAttr)); + + const SvxProtectItem& rItem = static_cast<const SvxProtectItem&>(rAttr); + return ( bCntnt == rItem.bCntnt && + bSize == rItem.bSize && + bPos == rItem.bPos ); +} + + +bool SvxProtectItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const +{ + nMemberId &= ~CONVERT_TWIPS; + bool bValue; + switch(nMemberId) + { + case MID_PROTECT_CONTENT : bValue = bCntnt; break; + case MID_PROTECT_SIZE : bValue = bSize; break; + case MID_PROTECT_POSITION: bValue = bPos; break; + default: + OSL_FAIL("Wrong MemberId"); + return false; + } + + rVal <<= bValue; + return true; +} + + +bool SvxProtectItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId ) +{ + nMemberId &= ~CONVERT_TWIPS; + bool bVal( Any2Bool(rVal) ); + switch(nMemberId) + { + case MID_PROTECT_CONTENT : bCntnt = bVal; break; + case MID_PROTECT_SIZE : bSize = bVal; break; + case MID_PROTECT_POSITION: bPos = bVal; break; + default: + OSL_FAIL("Wrong MemberId"); + return false; + } + return true; +} + +SvxProtectItem* SvxProtectItem::Clone( SfxItemPool* ) const +{ + return new SvxProtectItem( *this ); +} + +bool SvxProtectItem::GetPresentation +( + SfxItemPresentation /*ePres*/, + MapUnit /*eCoreUnit*/, + MapUnit /*ePresUnit*/, + OUString& rText, const IntlWrapper& +) const +{ + TranslateId pId = RID_SVXITEMS_PROT_CONTENT_FALSE; + + if ( bCntnt ) + pId = RID_SVXITEMS_PROT_CONTENT_TRUE; + rText = EditResId(pId) + cpDelim; + pId = RID_SVXITEMS_PROT_SIZE_FALSE; + + if ( bSize ) + pId = RID_SVXITEMS_PROT_SIZE_TRUE; + rText += EditResId(pId) + cpDelim; + pId = RID_SVXITEMS_PROT_POS_FALSE; + + if ( bPos ) + pId = RID_SVXITEMS_PROT_POS_TRUE; + rText += EditResId(pId); + return true; +} + + +void SvxProtectItem::dumpAsXml(xmlTextWriterPtr pWriter) const +{ + (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SvxProtectItem")); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr())); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("content"), BAD_CAST(OString::boolean(bCntnt).getStr())); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("size"), BAD_CAST(OString::boolean(bSize).getStr())); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("position"), BAD_CAST(OString::boolean(bPos).getStr())); + (void)xmlTextWriterEndElement(pWriter); +} + + +SvxShadowItem::SvxShadowItem( const sal_uInt16 nId, + const Color *pColor, const sal_uInt16 nW, + const SvxShadowLocation eLoc ) : + SfxEnumItemInterface( nId ), + aShadowColor(COL_GRAY), + nWidth ( nW ), + eLocation ( eLoc ) +{ + if ( pColor ) + aShadowColor = *pColor; +} + + +bool SvxShadowItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const +{ + bool bConvert = 0!=(nMemberId&CONVERT_TWIPS); + nMemberId &= ~CONVERT_TWIPS; + + table::ShadowFormat aShadow; + table::ShadowLocation eSet = table::ShadowLocation_NONE; + switch( eLocation ) + { + case SvxShadowLocation::TopLeft : eSet = table::ShadowLocation_TOP_LEFT ; break; + case SvxShadowLocation::TopRight : eSet = table::ShadowLocation_TOP_RIGHT ; break; + case SvxShadowLocation::BottomLeft : eSet = table::ShadowLocation_BOTTOM_LEFT ; break; + case SvxShadowLocation::BottomRight: eSet = table::ShadowLocation_BOTTOM_RIGHT; break; + default: ; // prevent warning + } + aShadow.Location = eSet; + aShadow.ShadowWidth = bConvert ? convertTwipToMm100(nWidth) : nWidth; + aShadow.IsTransparent = aShadowColor.IsTransparent(); + aShadow.Color = sal_Int32(aShadowColor); + + sal_Int8 nTransparence = rtl::math::round((float(255 - aShadowColor.GetAlpha()) * 100) / 255); + + switch ( nMemberId ) + { + case MID_LOCATION: rVal <<= aShadow.Location; break; + case MID_WIDTH: rVal <<= aShadow.ShadowWidth; break; + case MID_TRANSPARENT: rVal <<= aShadow.IsTransparent; break; + case MID_BG_COLOR: rVal <<= aShadow.Color; break; + case 0: rVal <<= aShadow; break; + case MID_SHADOW_TRANSPARENCE: rVal <<= nTransparence; break; + default: OSL_FAIL("Wrong MemberId!"); return false; + } + + return true; +} + +bool SvxShadowItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId ) +{ + bool bConvert = 0!=(nMemberId&CONVERT_TWIPS); + nMemberId &= ~CONVERT_TWIPS; + + table::ShadowFormat aShadow; + uno::Any aAny; + bool bRet = QueryValue( aAny, bConvert ? CONVERT_TWIPS : 0 ) && ( aAny >>= aShadow ); + switch ( nMemberId ) + { + case MID_LOCATION: + { + bRet = (rVal >>= aShadow.Location); + if ( !bRet ) + { + sal_Int16 nVal = 0; + bRet = (rVal >>= nVal); + aShadow.Location = static_cast<table::ShadowLocation>(nVal); + } + + break; + } + + case MID_WIDTH: rVal >>= aShadow.ShadowWidth; break; + case MID_TRANSPARENT: rVal >>= aShadow.IsTransparent; break; + case MID_BG_COLOR: rVal >>= aShadow.Color; break; + case 0: rVal >>= aShadow; break; + case MID_SHADOW_TRANSPARENCE: + { + sal_Int32 nTransparence = 0; + if ((rVal >>= nTransparence) && !o3tl::checked_multiply<sal_Int32>(nTransparence, 255, nTransparence)) + { + Color aColor(ColorTransparency, aShadow.Color); + aColor.SetAlpha(255 - rtl::math::round(float(nTransparence) / 100)); + aShadow.Color = sal_Int32(aColor); + } + break; + } + default: OSL_FAIL("Wrong MemberId!"); return false; + } + + if ( bRet ) + { + switch( aShadow.Location ) + { + case table::ShadowLocation_NONE : eLocation = SvxShadowLocation::NONE; break; + case table::ShadowLocation_TOP_LEFT : eLocation = SvxShadowLocation::TopLeft; break; + case table::ShadowLocation_TOP_RIGHT : eLocation = SvxShadowLocation::TopRight; break; + case table::ShadowLocation_BOTTOM_LEFT : eLocation = SvxShadowLocation::BottomLeft ; break; + case table::ShadowLocation_BOTTOM_RIGHT: eLocation = SvxShadowLocation::BottomRight; break; + default: ; // prevent warning + } + + nWidth = bConvert ? o3tl::toTwips(aShadow.ShadowWidth, o3tl::Length::mm100) : aShadow.ShadowWidth; + Color aSet(ColorTransparency, aShadow.Color); + aShadowColor = aSet; + } + + return bRet; +} + + +bool SvxShadowItem::operator==( const SfxPoolItem& rAttr ) const +{ + assert(SfxPoolItem::operator==(rAttr)); + + const SvxShadowItem& rItem = static_cast<const SvxShadowItem&>(rAttr); + return ( ( aShadowColor == rItem.aShadowColor ) && + ( nWidth == rItem.GetWidth() ) && + ( eLocation == rItem.GetLocation() ) ); +} + +SvxShadowItem* SvxShadowItem::Clone( SfxItemPool* ) const +{ + return new SvxShadowItem( *this ); +} + +sal_uInt16 SvxShadowItem::CalcShadowSpace( SvxShadowItemSide nShadow ) const +{ + sal_uInt16 nSpace = 0; + + switch ( nShadow ) + { + case SvxShadowItemSide::TOP: + if ( eLocation == SvxShadowLocation::TopLeft || + eLocation == SvxShadowLocation::TopRight ) + nSpace = nWidth; + break; + + case SvxShadowItemSide::BOTTOM: + if ( eLocation == SvxShadowLocation::BottomLeft || + eLocation == SvxShadowLocation::BottomRight ) + nSpace = nWidth; + break; + + case SvxShadowItemSide::LEFT: + if ( eLocation == SvxShadowLocation::TopLeft || + eLocation == SvxShadowLocation::BottomLeft ) + nSpace = nWidth; + break; + + case SvxShadowItemSide::RIGHT: + if ( eLocation == SvxShadowLocation::TopRight || + eLocation == SvxShadowLocation::BottomRight ) + nSpace = nWidth; + break; + + default: + OSL_FAIL( "wrong shadow" ); + } + return nSpace; +} + +static TranslateId RID_SVXITEMS_SHADOW[] = +{ + RID_SVXITEMS_SHADOW_NONE, + RID_SVXITEMS_SHADOW_TOPLEFT, + RID_SVXITEMS_SHADOW_TOPRIGHT, + RID_SVXITEMS_SHADOW_BOTTOMLEFT, + RID_SVXITEMS_SHADOW_BOTTOMRIGHT +}; + +bool SvxShadowItem::GetPresentation +( + SfxItemPresentation ePres, + MapUnit eCoreUnit, + MapUnit ePresUnit, + OUString& rText, const IntlWrapper& rIntl +) const +{ + switch ( ePres ) + { + case SfxItemPresentation::Nameless: + { + rText = ::GetColorString( aShadowColor ) + cpDelim; + TranslateId pId = RID_SVXITEMS_TRANSPARENT_FALSE; + + if ( aShadowColor.IsTransparent() ) + pId = RID_SVXITEMS_TRANSPARENT_TRUE; + rText += EditResId(pId) + + cpDelim + + GetMetricText( static_cast<tools::Long>(nWidth), eCoreUnit, ePresUnit, &rIntl ) + + cpDelim + + EditResId(RID_SVXITEMS_SHADOW[static_cast<int>(eLocation)]); + return true; + } + case SfxItemPresentation::Complete: + { + rText = EditResId(RID_SVXITEMS_SHADOW_COMPLETE) + + ::GetColorString( aShadowColor ) + + cpDelim; + + TranslateId pId = RID_SVXITEMS_TRANSPARENT_FALSE; + if ( aShadowColor.IsTransparent() ) + pId = RID_SVXITEMS_TRANSPARENT_TRUE; + rText += EditResId(pId) + + cpDelim + + GetMetricText( static_cast<tools::Long>(nWidth), eCoreUnit, ePresUnit, &rIntl ) + + " " + EditResId(GetMetricId(ePresUnit)) + + cpDelim + + EditResId(RID_SVXITEMS_SHADOW[static_cast<int>(eLocation)]); + return true; + } + default: ; // prevent warning + } + return false; +} + + +void SvxShadowItem::ScaleMetrics( tools::Long nMult, tools::Long nDiv ) +{ + nWidth = static_cast<sal_uInt16>(BigInt::Scale( nWidth, nMult, nDiv )); +} + + +bool SvxShadowItem::HasMetrics() const +{ + return true; +} + + +sal_uInt16 SvxShadowItem::GetValueCount() const +{ + return sal_uInt16(SvxShadowLocation::End); // SvxShadowLocation::BottomRight + 1 +} + +sal_uInt16 SvxShadowItem::GetEnumValue() const +{ + return static_cast<sal_uInt16>(GetLocation()); +} + + +void SvxShadowItem::SetEnumValue( sal_uInt16 nVal ) +{ + SetLocation( static_cast<SvxShadowLocation>(nVal) ); +} + +void SvxShadowItem::dumpAsXml(xmlTextWriterPtr pWriter) const +{ + (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SvxShadowItem")); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr())); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("aShadowColor"), BAD_CAST(aShadowColor.AsRGBHexString().toUtf8().getStr())); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nWidth"), BAD_CAST(OString::number(nWidth).getStr())); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("eLocation"), BAD_CAST(OString::number(static_cast<int>(eLocation)).getStr())); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("presentation"), BAD_CAST(EditResId(RID_SVXITEMS_SHADOW[static_cast<int>(eLocation)]).toUtf8().getStr())); + (void)xmlTextWriterEndElement(pWriter); +} + +// class SvxBoxItem ------------------------------------------------------ + +SvxBoxItem::SvxBoxItem( const SvxBoxItem& rCpy ) : + + SfxPoolItem ( rCpy ), + pTop ( rCpy.pTop ? new SvxBorderLine( *rCpy.pTop ) : nullptr ), + pBottom ( rCpy.pBottom ? new SvxBorderLine( *rCpy.pBottom ) : nullptr ), + pLeft ( rCpy.pLeft ? new SvxBorderLine( *rCpy.pLeft ) : nullptr ), + pRight ( rCpy.pRight ? new SvxBorderLine( *rCpy.pRight ) : nullptr ), + nTopDist ( rCpy.nTopDist ), + nBottomDist ( rCpy.nBottomDist ), + nLeftDist ( rCpy.nLeftDist ), + nRightDist ( rCpy.nRightDist ), + bRemoveAdjCellBorder ( rCpy.bRemoveAdjCellBorder ) +{ +} + + +SvxBoxItem::SvxBoxItem( const sal_uInt16 nId ) : + SfxPoolItem( nId ), + nTopDist ( 0 ), + nBottomDist ( 0 ), + nLeftDist ( 0 ), + nRightDist ( 0 ), + bRemoveAdjCellBorder ( false ) +{ +} + + +SvxBoxItem::~SvxBoxItem() +{ +} + +void SvxBoxItem::dumpAsXml(xmlTextWriterPtr pWriter) const +{ + (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SvxBoxItem")); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("top-dist"), + BAD_CAST(OString::number(nTopDist).getStr())); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("bottom-dist"), + BAD_CAST(OString::number(nBottomDist).getStr())); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("left-dist"), + BAD_CAST(OString::number(nLeftDist).getStr())); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("right-dist"), + BAD_CAST(OString::number(nRightDist).getStr())); + SfxPoolItem::dumpAsXml(pWriter); + (void)xmlTextWriterEndElement(pWriter); +} + +boost::property_tree::ptree SvxBoxItem::dumpAsJSON() const +{ + boost::property_tree::ptree aTree; + + boost::property_tree::ptree aState; + aState.put("top", GetTop() && !GetTop()->isEmpty()); + aState.put("bottom", GetBottom() && !GetBottom()->isEmpty()); + aState.put("left", GetLeft() && !GetLeft()->isEmpty()); + aState.put("right", GetRight() && !GetRight()->isEmpty()); + + aTree.push_back(std::make_pair("state", aState)); + aTree.put("commandName", ".uno:BorderOuter"); + + return aTree; +} + + +static bool CmpBrdLn( const std::unique_ptr<SvxBorderLine> & pBrd1, const SvxBorderLine* pBrd2 ) +{ + if( pBrd1.get() == pBrd2 ) + return true; + if( pBrd1 == nullptr || pBrd2 == nullptr) + return false; + return *pBrd1 == *pBrd2; +} + + +bool SvxBoxItem::operator==( const SfxPoolItem& rAttr ) const +{ + assert(SfxPoolItem::operator==(rAttr)); + + const SvxBoxItem& rBoxItem = static_cast<const SvxBoxItem&>(rAttr); + return ( + ( nTopDist == rBoxItem.nTopDist ) && + ( nBottomDist == rBoxItem.nBottomDist ) && + ( nLeftDist == rBoxItem.nLeftDist ) && + ( nRightDist == rBoxItem.nRightDist ) && + ( bRemoveAdjCellBorder == rBoxItem.bRemoveAdjCellBorder ) && + CmpBrdLn( pTop, rBoxItem.GetTop() ) && + CmpBrdLn( pBottom, rBoxItem.GetBottom() ) && + CmpBrdLn( pLeft, rBoxItem.GetLeft() ) && + CmpBrdLn( pRight, rBoxItem.GetRight() ) ); +} + + +table::BorderLine2 SvxBoxItem::SvxLineToLine(const SvxBorderLine* pLine, bool bConvert) +{ + table::BorderLine2 aLine; + if(pLine) + { + aLine.Color = sal_Int32(pLine->GetColor()); + aLine.InnerLineWidth = sal_uInt16( bConvert ? convertTwipToMm100(pLine->GetInWidth() ): pLine->GetInWidth() ); + aLine.OuterLineWidth = sal_uInt16( bConvert ? convertTwipToMm100(pLine->GetOutWidth()): pLine->GetOutWidth() ); + aLine.LineDistance = sal_uInt16( bConvert ? convertTwipToMm100(pLine->GetDistance()): pLine->GetDistance() ); + aLine.LineStyle = sal_Int16(pLine->GetBorderLineStyle()); + aLine.LineWidth = sal_uInt32( bConvert ? convertTwipToMm100( pLine->GetWidth( ) ) : pLine->GetWidth( ) ); + } + else + { + aLine.Color = aLine.InnerLineWidth = aLine.OuterLineWidth = aLine.LineDistance = 0; + aLine.LineStyle = table::BorderLineStyle::NONE; // 0 is SOLID! + } + return aLine; +} + +bool SvxBoxItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const +{ + bool bConvert = 0!=(nMemberId&CONVERT_TWIPS); + table::BorderLine2 aRetLine; + sal_Int16 nDist = 0; + bool bDistMember = false; + nMemberId &= ~CONVERT_TWIPS; + switch(nMemberId) + { + case 0: + { + // 4 Borders and 5 distances + uno::Sequence< uno::Any > aSeq{ + uno::Any(SvxBoxItem::SvxLineToLine(GetLeft(), bConvert)), + uno::Any(SvxBoxItem::SvxLineToLine(GetRight(), bConvert)), + uno::Any(SvxBoxItem::SvxLineToLine(GetBottom(), bConvert)), + uno::Any(SvxBoxItem::SvxLineToLine(GetTop(), bConvert)), + uno::Any(static_cast<sal_Int32>(bConvert ? convertTwipToMm100( GetSmallestDistance()) : GetSmallestDistance())), + uno::Any(static_cast<sal_Int32>(bConvert ? convertTwipToMm100( nTopDist ) : nTopDist )), + uno::Any(static_cast<sal_Int32>(bConvert ? convertTwipToMm100( nBottomDist ) : nBottomDist )), + uno::Any(static_cast<sal_Int32>(bConvert ? convertTwipToMm100( nLeftDist ) : nLeftDist )), + uno::Any(static_cast<sal_Int32>(bConvert ? convertTwipToMm100( nRightDist ) : nRightDist )) + }; + rVal <<= aSeq; + return true; + } + case MID_LEFT_BORDER: + case LEFT_BORDER: + aRetLine = SvxBoxItem::SvxLineToLine(GetLeft(), bConvert); + break; + case MID_RIGHT_BORDER: + case RIGHT_BORDER: + aRetLine = SvxBoxItem::SvxLineToLine(GetRight(), bConvert); + break; + case MID_BOTTOM_BORDER: + case BOTTOM_BORDER: + aRetLine = SvxBoxItem::SvxLineToLine(GetBottom(), bConvert); + break; + case MID_TOP_BORDER: + case TOP_BORDER: + aRetLine = SvxBoxItem::SvxLineToLine(GetTop(), bConvert); + break; + case BORDER_DISTANCE: + nDist = GetSmallestDistance(); + bDistMember = true; + break; + case TOP_BORDER_DISTANCE: + nDist = nTopDist; + bDistMember = true; + break; + case BOTTOM_BORDER_DISTANCE: + nDist = nBottomDist; + bDistMember = true; + break; + case LEFT_BORDER_DISTANCE: + nDist = nLeftDist; + bDistMember = true; + break; + case RIGHT_BORDER_DISTANCE: + nDist = nRightDist; + bDistMember = true; + break; + case LINE_STYLE: + case LINE_WIDTH: + // it doesn't make sense to return a value for these since it's + // probably ambiguous + return true; + } + + if( bDistMember ) + rVal <<= static_cast<sal_Int32>(bConvert ? convertTwipToMm100(nDist) : nDist); + else + rVal <<= aRetLine; + + return true; +} + +namespace +{ + +bool +lcl_lineToSvxLine(const table::BorderLine& rLine, SvxBorderLine& rSvxLine, bool bConvert, bool bGuessWidth) +{ + rSvxLine.SetColor( Color(ColorTransparency, rLine.Color)); + if ( bGuessWidth ) + { + rSvxLine.GuessLinesWidths( rSvxLine.GetBorderLineStyle(), + bConvert ? o3tl::toTwips(rLine.OuterLineWidth, o3tl::Length::mm100) : rLine.OuterLineWidth, + bConvert ? o3tl::toTwips(rLine.InnerLineWidth, o3tl::Length::mm100) : rLine.InnerLineWidth, + bConvert ? o3tl::toTwips(rLine.LineDistance, o3tl::Length::mm100) : rLine.LineDistance ); + } + + bool bRet = !rSvxLine.isEmpty(); + return bRet; +} + +} + + +bool SvxBoxItem::LineToSvxLine(const css::table::BorderLine& rLine, SvxBorderLine& rSvxLine, bool bConvert) +{ + return lcl_lineToSvxLine(rLine, rSvxLine, bConvert, true); +} + +bool +SvxBoxItem::LineToSvxLine(const css::table::BorderLine2& rLine, SvxBorderLine& rSvxLine, bool bConvert) +{ + SvxBorderLineStyle const nStyle = + (rLine.LineStyle < 0 || BORDER_LINE_STYLE_MAX < rLine.LineStyle) + ? SvxBorderLineStyle::SOLID // default + : static_cast<SvxBorderLineStyle>(rLine.LineStyle); + + rSvxLine.SetBorderLineStyle( nStyle ); + + bool bGuessWidth = true; + if ( rLine.LineWidth ) + { + rSvxLine.SetWidth( bConvert? o3tl::toTwips(rLine.LineWidth, o3tl::Length::mm100) : rLine.LineWidth ); + // fdo#46112: double does not necessarily mean symmetric + // for backwards compatibility + bGuessWidth = (SvxBorderLineStyle::DOUBLE == nStyle || SvxBorderLineStyle::DOUBLE_THIN == nStyle) && + (rLine.InnerLineWidth > 0) && (rLine.OuterLineWidth > 0); + } + + return lcl_lineToSvxLine(rLine, rSvxLine, bConvert, bGuessWidth); +} + + +namespace +{ + +bool +lcl_extractBorderLine(const uno::Any& rAny, table::BorderLine2& rLine) +{ + if (rAny >>= rLine) + return true; + + table::BorderLine aBorderLine; + if (rAny >>= aBorderLine) + { + rLine.Color = aBorderLine.Color; + rLine.InnerLineWidth = aBorderLine.InnerLineWidth; + rLine.OuterLineWidth = aBorderLine.OuterLineWidth; + rLine.LineDistance = aBorderLine.LineDistance; + rLine.LineStyle = table::BorderLineStyle::SOLID; + return true; + } + + return false; +} + +template<typename Item, typename Line> +bool +lcl_setLine(const uno::Any& rAny, Item& rItem, Line nLine, const bool bConvert) +{ + bool bDone = false; + table::BorderLine2 aBorderLine; + if (lcl_extractBorderLine(rAny, aBorderLine)) + { + SvxBorderLine aLine; + bool bSet = SvxBoxItem::LineToSvxLine(aBorderLine, aLine, bConvert); + rItem.SetLine( bSet ? &aLine : nullptr, nLine); + bDone = true; + } + return bDone; +} + +} + +bool SvxBoxItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId ) +{ + bool bConvert = 0!=(nMemberId&CONVERT_TWIPS); + SvxBoxItemLine nLine = SvxBoxItemLine::TOP; + bool bDistMember = false; + nMemberId &= ~CONVERT_TWIPS; + switch(nMemberId) + { + case 0: + { + uno::Sequence< uno::Any > aSeq; + if (( rVal >>= aSeq ) && ( aSeq.getLength() == 9 )) + { + // 4 Borders and 5 distances + const SvxBoxItemLine aBorders[] = { SvxBoxItemLine::LEFT, SvxBoxItemLine::RIGHT, SvxBoxItemLine::BOTTOM, SvxBoxItemLine::TOP }; + for (size_t n(0); n != std::size(aBorders); ++n) + { + if (!lcl_setLine(aSeq[n], *this, aBorders[n], bConvert)) + return false; + } + + // WTH are the borders and the distances saved in different order? + SvxBoxItemLine const nLines[4] = { SvxBoxItemLine::TOP, SvxBoxItemLine::BOTTOM, SvxBoxItemLine::LEFT, SvxBoxItemLine::RIGHT }; + for ( sal_Int32 n = 4; n < 9; n++ ) + { + sal_Int32 nDist = 0; + if ( aSeq[n] >>= nDist ) + { + if( bConvert ) + nDist = o3tl::toTwips(nDist, o3tl::Length::mm100); + if ( n == 4 ) + SetAllDistances(nDist); + else + SetDistance( nDist, nLines[n-5] ); + } + else + return false; + } + + return true; + } + else + return false; + } + case LEFT_BORDER_DISTANCE: + bDistMember = true; + [[fallthrough]]; + case LEFT_BORDER: + case MID_LEFT_BORDER: + nLine = SvxBoxItemLine::LEFT; + break; + case RIGHT_BORDER_DISTANCE: + bDistMember = true; + [[fallthrough]]; + case RIGHT_BORDER: + case MID_RIGHT_BORDER: + nLine = SvxBoxItemLine::RIGHT; + break; + case BOTTOM_BORDER_DISTANCE: + bDistMember = true; + [[fallthrough]]; + case BOTTOM_BORDER: + case MID_BOTTOM_BORDER: + nLine = SvxBoxItemLine::BOTTOM; + break; + case TOP_BORDER_DISTANCE: + bDistMember = true; + [[fallthrough]]; + case TOP_BORDER: + case MID_TOP_BORDER: + nLine = SvxBoxItemLine::TOP; + break; + case LINE_STYLE: + { + drawing::LineStyle eDrawingStyle; + rVal >>= eDrawingStyle; + SvxBorderLineStyle eBorderStyle = SvxBorderLineStyle::NONE; + switch ( eDrawingStyle ) + { + default: + case drawing::LineStyle_NONE: + break; + case drawing::LineStyle_SOLID: + eBorderStyle = SvxBorderLineStyle::SOLID; + break; + case drawing::LineStyle_DASH: + eBorderStyle = SvxBorderLineStyle::DASHED; + break; + } + + // Set the line style on all borders + for( SvxBoxItemLine n : o3tl::enumrange<SvxBoxItemLine>() ) + { + editeng::SvxBorderLine* pLine = const_cast< editeng::SvxBorderLine* >( GetLine( n ) ); + if( pLine ) + pLine->SetBorderLineStyle( eBorderStyle ); + } + return true; + } + break; + case LINE_WIDTH: + { + // Set the line width on all borders + tools::Long nWidth(0); + rVal >>= nWidth; + if( bConvert ) + nWidth = o3tl::toTwips(nWidth, o3tl::Length::mm100); + + // Set the line Width on all borders + for( SvxBoxItemLine n : o3tl::enumrange<SvxBoxItemLine>() ) + { + editeng::SvxBorderLine* pLine = const_cast< editeng::SvxBorderLine* >( GetLine( n ) ); + if( pLine ) + pLine->SetWidth( nWidth ); + } + } + return true; + } + + if( bDistMember || nMemberId == BORDER_DISTANCE ) + { + sal_Int32 nDist = 0; + if(!(rVal >>= nDist)) + return false; + + { + if( bConvert ) + nDist = o3tl::toTwips(nDist, o3tl::Length::mm100); + if( nMemberId == BORDER_DISTANCE ) + SetAllDistances(nDist); + else + SetDistance( nDist, nLine ); + } + } + else + { + SvxBorderLine aLine; + if( !rVal.hasValue() ) + return false; + + table::BorderLine2 aBorderLine; + if( lcl_extractBorderLine(rVal, aBorderLine) ) + { + // usual struct + } + else if (rVal.getValueTypeClass() == uno::TypeClass_SEQUENCE ) + { + // serialization for basic macro recording + uno::Reference < script::XTypeConverter > xConverter + ( script::Converter::create(::comphelper::getProcessComponentContext()) ); + uno::Sequence < uno::Any > aSeq; + uno::Any aNew; + try { aNew = xConverter->convertTo( rVal, cppu::UnoType<uno::Sequence < uno::Any >>::get() ); } + catch (const uno::Exception&) {} + + aNew >>= aSeq; + if (aSeq.getLength() >= 4 && aSeq.getLength() <= 6) + { + sal_Int32 nVal = 0; + if ( aSeq[0] >>= nVal ) + aBorderLine.Color = nVal; + if ( aSeq[1] >>= nVal ) + aBorderLine.InnerLineWidth = static_cast<sal_Int16>(nVal); + if ( aSeq[2] >>= nVal ) + aBorderLine.OuterLineWidth = static_cast<sal_Int16>(nVal); + if ( aSeq[3] >>= nVal ) + aBorderLine.LineDistance = static_cast<sal_Int16>(nVal); + if (aSeq.getLength() >= 5) // fdo#40874 added fields + { + if (aSeq[4] >>= nVal) + { + aBorderLine.LineStyle = nVal; + } + if (aSeq.getLength() >= 6) + { + if (aSeq[5] >>= nVal) + { + aBorderLine.LineWidth = nVal; + } + } + } + } + else + return false; + } + else + return false; + + bool bSet = SvxBoxItem::LineToSvxLine(aBorderLine, aLine, bConvert); + SetLine(bSet ? &aLine : nullptr, nLine); + } + + return true; +} + +SvxBoxItem* SvxBoxItem::Clone( SfxItemPool* ) const +{ + return new SvxBoxItem( *this ); +} + +bool SvxBoxItem::GetPresentation +( + SfxItemPresentation ePres, + MapUnit eCoreUnit, + MapUnit ePresUnit, + OUString& rText, const IntlWrapper& rIntl +) const +{ + OUString cpDelimTmp(cpDelim); + switch ( ePres ) + { + case SfxItemPresentation::Nameless: + { + rText.clear(); + + if ( pTop ) + { + rText = pTop->GetValueString( eCoreUnit, ePresUnit, &rIntl ) + cpDelimTmp; + } + if( !(pTop && pBottom && pLeft && pRight && + *pTop == *pBottom && *pTop == *pLeft && *pTop == *pRight) ) + { + if ( pBottom ) + { + rText += pBottom->GetValueString( eCoreUnit, ePresUnit, &rIntl ) + cpDelimTmp; + } + if ( pLeft ) + { + rText += pLeft->GetValueString( eCoreUnit, ePresUnit, &rIntl ) + cpDelimTmp; + } + if ( pRight ) + { + rText += pRight->GetValueString( eCoreUnit, ePresUnit, &rIntl ) + cpDelimTmp; + } + } + rText += GetMetricText( static_cast<tools::Long>(nTopDist), eCoreUnit, ePresUnit, &rIntl ); + if( nTopDist != nBottomDist || nTopDist != nLeftDist || + nTopDist != nRightDist ) + { + rText += cpDelimTmp + + GetMetricText( static_cast<tools::Long>(nBottomDist), eCoreUnit, + ePresUnit, &rIntl ) + + cpDelimTmp + + GetMetricText( static_cast<tools::Long>(nLeftDist), eCoreUnit, ePresUnit, &rIntl ) + + cpDelimTmp + + GetMetricText( static_cast<tools::Long>(nRightDist), eCoreUnit, + ePresUnit, &rIntl ); + } + return true; + } + case SfxItemPresentation::Complete: + { + if( !(pTop || pBottom || pLeft || pRight) ) + { + rText = EditResId(RID_SVXITEMS_BORDER_NONE) + cpDelimTmp; + } + else + { + rText = EditResId(RID_SVXITEMS_BORDER_COMPLETE); + if( pTop && pBottom && pLeft && pRight && + *pTop == *pBottom && *pTop == *pLeft && *pTop == *pRight ) + { + rText += pTop->GetValueString( eCoreUnit, ePresUnit, &rIntl, true ) + cpDelimTmp; + } + else + { + if ( pTop ) + { + rText += EditResId(RID_SVXITEMS_BORDER_TOP) + + pTop->GetValueString( eCoreUnit, ePresUnit, &rIntl, true ) + + cpDelimTmp; + } + if ( pBottom ) + { + rText += EditResId(RID_SVXITEMS_BORDER_BOTTOM) + + pBottom->GetValueString( eCoreUnit, ePresUnit, &rIntl, true ) + + cpDelimTmp; + } + if ( pLeft ) + { + rText += EditResId(RID_SVXITEMS_BORDER_LEFT) + + pLeft->GetValueString( eCoreUnit, ePresUnit, &rIntl, true ) + + cpDelimTmp; + } + if ( pRight ) + { + rText += EditResId(RID_SVXITEMS_BORDER_RIGHT) + + pRight->GetValueString( eCoreUnit, ePresUnit, &rIntl, true ) + + cpDelimTmp; + } + } + } + + rText += EditResId(RID_SVXITEMS_BORDER_DISTANCE); + if( nTopDist == nBottomDist && nTopDist == nLeftDist && + nTopDist == nRightDist ) + { + rText += GetMetricText( static_cast<tools::Long>(nTopDist), eCoreUnit, + ePresUnit, &rIntl ) + + " " + EditResId(GetMetricId(ePresUnit)); + } + else + { + rText += EditResId(RID_SVXITEMS_BORDER_TOP) + + GetMetricText( static_cast<tools::Long>(nTopDist), eCoreUnit, + ePresUnit, &rIntl ) + + " " + EditResId(GetMetricId(ePresUnit)) + + cpDelimTmp + + EditResId(RID_SVXITEMS_BORDER_BOTTOM) + + GetMetricText( static_cast<tools::Long>(nBottomDist), eCoreUnit, + ePresUnit, &rIntl ) + + " " + EditResId(GetMetricId(ePresUnit)) + + cpDelimTmp + + EditResId(RID_SVXITEMS_BORDER_LEFT) + + GetMetricText( static_cast<tools::Long>(nLeftDist), eCoreUnit, + ePresUnit, &rIntl ) + + " " + EditResId(GetMetricId(ePresUnit)) + + cpDelimTmp + + EditResId(RID_SVXITEMS_BORDER_RIGHT) + + GetMetricText( static_cast<tools::Long>(nRightDist), eCoreUnit, + ePresUnit, &rIntl ) + + " " + EditResId(GetMetricId(ePresUnit)); + } + return true; + } + default: ; // prevent warning + } + return false; +} + + +void SvxBoxItem::ScaleMetrics( tools::Long nMult, tools::Long nDiv ) +{ + if ( pTop ) pTop->ScaleMetrics( nMult, nDiv ); + if ( pBottom ) pBottom->ScaleMetrics( nMult, nDiv ); + if ( pLeft ) pLeft->ScaleMetrics( nMult, nDiv ); + if ( pRight ) pRight->ScaleMetrics( nMult, nDiv ); + nTopDist = static_cast<sal_Int16>(BigInt::Scale( nTopDist, nMult, nDiv )); + nBottomDist = static_cast<sal_Int16>(BigInt::Scale( nBottomDist, nMult, nDiv )); + nLeftDist = static_cast<sal_Int16>(BigInt::Scale( nLeftDist, nMult, nDiv )); + nRightDist = static_cast<sal_Int16>(BigInt::Scale( nRightDist, nMult, nDiv )); +} + + +bool SvxBoxItem::HasMetrics() const +{ + return true; +} + + +const SvxBorderLine *SvxBoxItem::GetLine( SvxBoxItemLine nLine ) const +{ + const SvxBorderLine *pRet = nullptr; + + switch ( nLine ) + { + case SvxBoxItemLine::TOP: + pRet = pTop.get(); + break; + case SvxBoxItemLine::BOTTOM: + pRet = pBottom.get(); + break; + case SvxBoxItemLine::LEFT: + pRet = pLeft.get(); + break; + case SvxBoxItemLine::RIGHT: + pRet = pRight.get(); + break; + default: + OSL_FAIL( "wrong line" ); + break; + } + + return pRet; +} + + +void SvxBoxItem::SetLine( const SvxBorderLine* pNew, SvxBoxItemLine nLine ) +{ + std::unique_ptr<SvxBorderLine> pTmp( pNew ? new SvxBorderLine( *pNew ) : nullptr ); + + switch ( nLine ) + { + case SvxBoxItemLine::TOP: + pTop = std::move( pTmp ); + break; + case SvxBoxItemLine::BOTTOM: + pBottom = std::move( pTmp ); + break; + case SvxBoxItemLine::LEFT: + pLeft = std::move( pTmp ); + break; + case SvxBoxItemLine::RIGHT: + pRight = std::move( pTmp ); + break; + default: + OSL_FAIL( "wrong line" ); + } +} + + +sal_uInt16 SvxBoxItem::GetSmallestDistance() const +{ + // The smallest distance that is not 0 will be returned. + sal_uInt16 nDist = nTopDist; + if( nBottomDist && (!nDist || nBottomDist < nDist) ) + nDist = nBottomDist; + if( nLeftDist && (!nDist || nLeftDist < nDist) ) + nDist = nLeftDist; + if( nRightDist && (!nDist || nRightDist < nDist) ) + nDist = nRightDist; + + return nDist; +} + + +sal_Int16 SvxBoxItem::GetDistance( SvxBoxItemLine nLine, bool bAllowNegative ) const +{ + sal_Int16 nDist = 0; + switch ( nLine ) + { + case SvxBoxItemLine::TOP: + nDist = nTopDist; + break; + case SvxBoxItemLine::BOTTOM: + nDist = nBottomDist; + break; + case SvxBoxItemLine::LEFT: + nDist = nLeftDist; + break; + case SvxBoxItemLine::RIGHT: + nDist = nRightDist; + break; + default: + OSL_FAIL( "wrong line" ); + } + + if (!bAllowNegative && nDist < 0) + { + nDist = 0; + } + return nDist; +} + + +void SvxBoxItem::SetDistance( sal_Int16 nNew, SvxBoxItemLine nLine ) +{ + switch ( nLine ) + { + case SvxBoxItemLine::TOP: + nTopDist = nNew; + break; + case SvxBoxItemLine::BOTTOM: + nBottomDist = nNew; + break; + case SvxBoxItemLine::LEFT: + nLeftDist = nNew; + break; + case SvxBoxItemLine::RIGHT: + nRightDist = nNew; + break; + default: + OSL_FAIL( "wrong line" ); + } +} + +sal_uInt16 SvxBoxItem::CalcLineWidth( SvxBoxItemLine nLine ) const +{ + SvxBorderLine* pTmp = nullptr; + sal_uInt16 nWidth = 0; + switch ( nLine ) + { + case SvxBoxItemLine::TOP: + pTmp = pTop.get(); + break; + case SvxBoxItemLine::BOTTOM: + pTmp = pBottom.get(); + break; + case SvxBoxItemLine::LEFT: + pTmp = pLeft.get(); + break; + case SvxBoxItemLine::RIGHT: + pTmp = pRight.get(); + break; + default: + OSL_FAIL( "wrong line" ); + } + + if( pTmp ) + nWidth = pTmp->GetScaledWidth(); + + return nWidth; +} + +sal_Int16 SvxBoxItem::CalcLineSpace( SvxBoxItemLine nLine, bool bEvenIfNoLine, bool bAllowNegative ) const +{ + SvxBorderLine* pTmp = nullptr; + sal_Int16 nDist = 0; + switch ( nLine ) + { + case SvxBoxItemLine::TOP: + pTmp = pTop.get(); + nDist = nTopDist; + break; + case SvxBoxItemLine::BOTTOM: + pTmp = pBottom.get(); + nDist = nBottomDist; + break; + case SvxBoxItemLine::LEFT: + pTmp = pLeft.get(); + nDist = nLeftDist; + break; + case SvxBoxItemLine::RIGHT: + pTmp = pRight.get(); + nDist = nRightDist; + break; + default: + OSL_FAIL( "wrong line" ); + } + + if( pTmp ) + { + nDist = nDist + pTmp->GetScaledWidth(); + } + else if( !bEvenIfNoLine ) + nDist = 0; + + if (!bAllowNegative && nDist < 0) + { + nDist = 0; + } + + return nDist; +} + +bool SvxBoxItem::HasBorder( bool bTreatPaddingAsBorder ) const +{ + return CalcLineSpace( SvxBoxItemLine::BOTTOM, bTreatPaddingAsBorder ) + || CalcLineSpace( SvxBoxItemLine::RIGHT, bTreatPaddingAsBorder ) + || CalcLineSpace( SvxBoxItemLine::TOP, bTreatPaddingAsBorder ) + || CalcLineSpace( SvxBoxItemLine::LEFT, bTreatPaddingAsBorder ); +} + +// class SvxBoxInfoItem -------------------------------------------------- + +SvxBoxInfoItem::SvxBoxInfoItem( const sal_uInt16 nId ) : + SfxPoolItem( nId ), + mbEnableHor( false ), + mbEnableVer( false ), + nDefDist( 0 ) +{ + bDist = bMinDist = false; + ResetFlags(); +} + + +SvxBoxInfoItem::SvxBoxInfoItem( const SvxBoxInfoItem& rCpy ) : + SfxPoolItem( rCpy ), + pHori( rCpy.pHori ? new SvxBorderLine( *rCpy.pHori ) : nullptr ), + pVert( rCpy.pVert ? new SvxBorderLine( *rCpy.pVert ) : nullptr ), + mbEnableHor( rCpy.mbEnableHor ), + mbEnableVer( rCpy.mbEnableVer ), + bDist( rCpy.bDist ), + bMinDist ( rCpy.bMinDist ), + nValidFlags( rCpy.nValidFlags ), + nDefDist( rCpy.nDefDist ) +{ +} + +SvxBoxInfoItem::~SvxBoxInfoItem() +{ +} + + +boost::property_tree::ptree SvxBoxInfoItem::dumpAsJSON() const +{ + boost::property_tree::ptree aTree; + + boost::property_tree::ptree aState; + aState.put("vertical", GetVert() && !GetVert()->isEmpty()); + aState.put("horizontal", GetHori() && !GetHori()->isEmpty()); + + aTree.push_back(std::make_pair("state", aState)); + aTree.put("commandName", ".uno:BorderInner"); + + return aTree; +} + + +bool SvxBoxInfoItem::operator==( const SfxPoolItem& rAttr ) const +{ + assert(SfxPoolItem::operator==(rAttr)); + + const SvxBoxInfoItem& rBoxInfo = static_cast<const SvxBoxInfoItem&>(rAttr); + + return ( mbEnableHor == rBoxInfo.mbEnableHor + && mbEnableVer == rBoxInfo.mbEnableVer + && bDist == rBoxInfo.IsDist() + && bMinDist == rBoxInfo.IsMinDist() + && nValidFlags == rBoxInfo.nValidFlags + && nDefDist == rBoxInfo.GetDefDist() + && CmpBrdLn( pHori, rBoxInfo.GetHori() ) + && CmpBrdLn( pVert, rBoxInfo.GetVert() ) + ); +} + + +void SvxBoxInfoItem::SetLine( const SvxBorderLine* pNew, SvxBoxInfoItemLine nLine ) +{ + std::unique_ptr<SvxBorderLine> pTmp( pNew ? new SvxBorderLine( *pNew ) : nullptr ); + + if ( SvxBoxInfoItemLine::HORI == nLine ) + { + pHori = std::move(pTmp); + } + else if ( SvxBoxInfoItemLine::VERT == nLine ) + { + pVert = std::move(pTmp); + } + else + { + OSL_FAIL( "wrong line" ); + } +} + +SvxBoxInfoItem* SvxBoxInfoItem::Clone( SfxItemPool* ) const +{ + return new SvxBoxInfoItem( *this ); +} + +bool SvxBoxInfoItem::GetPresentation +( + SfxItemPresentation /*ePres*/, + MapUnit /*eCoreUnit*/, + MapUnit /*ePresUnit*/, + OUString& rText, const IntlWrapper& +) const +{ + rText.clear(); + return false; +} + + +void SvxBoxInfoItem::ScaleMetrics( tools::Long nMult, tools::Long nDiv ) +{ + if ( pHori ) pHori->ScaleMetrics( nMult, nDiv ); + if ( pVert ) pVert->ScaleMetrics( nMult, nDiv ); + nDefDist = static_cast<sal_uInt16>(BigInt::Scale( nDefDist, nMult, nDiv )); +} + + +bool SvxBoxInfoItem::HasMetrics() const +{ + return true; +} + + +void SvxBoxInfoItem::ResetFlags() +{ + nValidFlags = static_cast<SvxBoxInfoItemValidFlags>(0x7F); // all valid except Disable +} + +bool SvxBoxInfoItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const +{ + bool bConvert = 0 != (nMemberId & CONVERT_TWIPS); + table::BorderLine2 aRetLine; + sal_Int16 nVal=0; + bool bIntMember = false; + nMemberId &= ~CONVERT_TWIPS; + switch(nMemberId) + { + case 0: + { + // 2 BorderLines, flags, valid flags and distance + if ( IsTable() ) + nVal |= 0x01; + if ( IsDist() ) + nVal |= 0x02; + if ( IsMinDist() ) + nVal |= 0x04; + css::uno::Sequence< css::uno::Any > aSeq{ + uno::Any(SvxBoxItem::SvxLineToLine( pHori.get(), bConvert)), + uno::Any(SvxBoxItem::SvxLineToLine( pVert.get(), bConvert)), + uno::Any(nVal), + uno::Any(static_cast<sal_Int16>(nValidFlags)), + uno::Any(static_cast<sal_Int32>(bConvert ? convertTwipToMm100(GetDefDist()) : GetDefDist())) + }; + rVal <<= aSeq; + return true; + } + + case MID_HORIZONTAL: + aRetLine = SvxBoxItem::SvxLineToLine( pHori.get(), bConvert); + break; + case MID_VERTICAL: + aRetLine = SvxBoxItem::SvxLineToLine( pVert.get(), bConvert); + break; + case MID_FLAGS: + bIntMember = true; + if ( IsTable() ) + nVal |= 0x01; + if ( IsDist() ) + nVal |= 0x02; + if ( IsMinDist() ) + nVal |= 0x04; + rVal <<= nVal; + break; + case MID_VALIDFLAGS: + bIntMember = true; + rVal <<= static_cast<sal_Int16>(nValidFlags); + break; + case MID_DISTANCE: + bIntMember = true; + rVal <<= static_cast<sal_Int32>(bConvert ? convertTwipToMm100(GetDefDist()) : GetDefDist()); + break; + default: OSL_FAIL("Wrong MemberId!"); return false; + } + + if( !bIntMember ) + rVal <<= aRetLine; + + return true; +} + + +bool SvxBoxInfoItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId ) +{ + bool bConvert = 0!=(nMemberId&CONVERT_TWIPS); + nMemberId &= ~CONVERT_TWIPS; + bool bRet; + switch(nMemberId) + { + case 0: + { + css::uno::Sequence< css::uno::Any > aSeq; + if (( rVal >>= aSeq ) && ( aSeq.getLength() == 5 )) + { + // 2 BorderLines, flags, valid flags and distance + if (!lcl_setLine(aSeq[0], *this, SvxBoxInfoItemLine::HORI, bConvert)) + return false; + if (!lcl_setLine(aSeq[1], *this, SvxBoxInfoItemLine::VERT, bConvert)) + return false; + + sal_Int16 nFlags( 0 ); + sal_Int32 nVal( 0 ); + if ( aSeq[2] >>= nFlags ) + { + SetTable ( ( nFlags & 0x01 ) != 0 ); + SetDist ( ( nFlags & 0x02 ) != 0 ); + SetMinDist( ( nFlags & 0x04 ) != 0 ); + } + else + return false; + if ( aSeq[3] >>= nFlags ) + nValidFlags = static_cast<SvxBoxInfoItemValidFlags>(nFlags); + else + return false; + if (( aSeq[4] >>= nVal ) && ( nVal >= 0 )) + { + if( bConvert ) + nVal = o3tl::toTwips(nVal, o3tl::Length::mm100); + SetDefDist( nVal ); + } + } + return true; + } + + case MID_HORIZONTAL: + case MID_VERTICAL: + { + if( !rVal.hasValue() ) + return false; + + table::BorderLine2 aBorderLine; + if( lcl_extractBorderLine(rVal, aBorderLine) ) + { + // usual struct + } + else if (rVal.getValueTypeClass() == uno::TypeClass_SEQUENCE ) + { + // serialization for basic macro recording + uno::Reference < script::XTypeConverter > xConverter( script::Converter::create(::comphelper::getProcessComponentContext()) ); + uno::Any aNew; + uno::Sequence < uno::Any > aSeq; + try { aNew = xConverter->convertTo( rVal, cppu::UnoType<uno::Sequence < uno::Any >>::get() ); } + catch (const uno::Exception&) {} + + if ((aNew >>= aSeq) && + aSeq.getLength() >= 4 && aSeq.getLength() <= 6) + { + sal_Int32 nVal = 0; + if ( aSeq[0] >>= nVal ) + aBorderLine.Color = nVal; + if ( aSeq[1] >>= nVal ) + aBorderLine.InnerLineWidth = static_cast<sal_Int16>(nVal); + if ( aSeq[2] >>= nVal ) + aBorderLine.OuterLineWidth = static_cast<sal_Int16>(nVal); + if ( aSeq[3] >>= nVal ) + aBorderLine.LineDistance = static_cast<sal_Int16>(nVal); + if (aSeq.getLength() >= 5) // fdo#40874 added fields + { + if (aSeq[4] >>= nVal) + { + aBorderLine.LineStyle = nVal; + } + if (aSeq.getLength() >= 6) + { + if (aSeq[5] >>= nVal) + { + aBorderLine.LineWidth = nVal; + } + } + } + } + else + return false; + } + else if (rVal.getValueType() == cppu::UnoType<css::uno::Sequence < sal_Int16 >>::get() ) + { + // serialization for basic macro recording + css::uno::Sequence < sal_Int16 > aSeq; + rVal >>= aSeq; + if (aSeq.getLength() >= 4 && aSeq.getLength() <= 6) + { + aBorderLine.Color = aSeq[0]; + aBorderLine.InnerLineWidth = aSeq[1]; + aBorderLine.OuterLineWidth = aSeq[2]; + aBorderLine.LineDistance = aSeq[3]; + if (aSeq.getLength() >= 5) // fdo#40874 added fields + { + aBorderLine.LineStyle = aSeq[4]; + if (aSeq.getLength() >= 6) + { + aBorderLine.LineWidth = aSeq[5]; + } + } + } + else + return false; + } + else + return false; + + SvxBorderLine aLine; + bool bSet = SvxBoxItem::LineToSvxLine(aBorderLine, aLine, bConvert); + if ( bSet ) + SetLine( &aLine, nMemberId == MID_HORIZONTAL ? SvxBoxInfoItemLine::HORI : SvxBoxInfoItemLine::VERT ); + break; + } + case MID_FLAGS: + { + sal_Int16 nFlags = sal_Int16(); + bRet = (rVal >>= nFlags); + if ( bRet ) + { + SetTable ( ( nFlags & 0x01 ) != 0 ); + SetDist ( ( nFlags & 0x02 ) != 0 ); + SetMinDist( ( nFlags & 0x04 ) != 0 ); + } + + break; + } + case MID_VALIDFLAGS: + { + sal_Int16 nFlags = sal_Int16(); + bRet = (rVal >>= nFlags); + if ( bRet ) + nValidFlags = static_cast<SvxBoxInfoItemValidFlags>(nFlags); + break; + } + case MID_DISTANCE: + { + sal_Int32 nVal = 0; + bRet = (rVal >>= nVal); + if ( bRet && nVal>=0 ) + { + if( bConvert ) + nVal = o3tl::toTwips(nVal, o3tl::Length::mm100); + SetDefDist( static_cast<sal_uInt16>(nVal) ); + } + break; + } + default: OSL_FAIL("Wrong MemberId!"); return false; + } + + return true; +} + + +namespace editeng +{ + +void BorderDistanceFromWord(bool bFromEdge, sal_Int32& nMargin, sal_Int32& nBorderDistance, + sal_Int32 nBorderWidth) +{ + // See https://wiki.openoffice.org/wiki/Writer/MSInteroperability/PageBorder + + sal_Int32 nNewMargin = nMargin; + sal_Int32 nNewBorderDistance = nBorderDistance; + + if (bFromEdge) + { + nNewMargin = nBorderDistance; + nNewBorderDistance = nMargin - nBorderDistance - nBorderWidth; + } + else + { + nNewMargin -= nBorderDistance + nBorderWidth; + } + + // Ensure correct distance from page edge to text in cases not supported by us: + // when border is outside entire page area (!bFromEdge && BorderDistance > Margin), + // and when border is inside page body area (bFromEdge && BorderDistance > Margin) + if (nNewMargin < 0) + { + nNewMargin = 0; + nNewBorderDistance = std::max<sal_Int32>(nMargin - nBorderWidth, 0); + } + else if (nNewBorderDistance < 0) + { + nNewMargin = nMargin; + } + + nMargin = nNewMargin; + nBorderDistance = nNewBorderDistance; +} + +// Heuristics to decide if we need to use "from edge" offset of borders +// +// There are two cases when we can safely use "from text" or "from edge" offset without distorting +// border position (modulo rounding errors): +// 1. When distance of all borders from text is no greater than 31 pt, we use "from text" +// 2. Otherwise, if distance of all borders from edge is no greater than 31 pt, we use "from edge" +// In all other cases, the position of borders would be distorted on export, because Word doesn't +// support the offset of >31 pts (https://msdn.microsoft.com/en-us/library/ff533820), and we need +// to decide which type of offset would provide less wrong result (i.e., the result would look +// closer to original). Here, we just check sum of distances from text to borders, and if it is +// less than sum of distances from borders to edges. The alternative would be to compare total areas +// between text-and-borders and between borders-and-edges (taking into account different lengths of +// borders, and visual impact of that). +void BorderDistancesToWord(const SvxBoxItem& rBox, const WordPageMargins& rMargins, + WordBorderDistances& rDistances) +{ + // Use signed sal_Int32 that can hold sal_uInt16, to prevent overflow at subtraction below + const sal_Int32 nT = rBox.GetDistance(SvxBoxItemLine::TOP, /*bAllowNegative=*/true); + const sal_Int32 nL = rBox.GetDistance(SvxBoxItemLine::LEFT, /*bAllowNegative=*/true); + const sal_Int32 nB = rBox.GetDistance(SvxBoxItemLine::BOTTOM, /*bAllowNegative=*/true); + const sal_Int32 nR = rBox.GetDistance(SvxBoxItemLine::RIGHT, /*bAllowNegative=*/true); + + // Only take into account existing borders + const SvxBorderLine* pLnT = rBox.GetLine(SvxBoxItemLine::TOP); + const SvxBorderLine* pLnL = rBox.GetLine(SvxBoxItemLine::LEFT); + const SvxBorderLine* pLnB = rBox.GetLine(SvxBoxItemLine::BOTTOM); + const SvxBorderLine* pLnR = rBox.GetLine(SvxBoxItemLine::RIGHT); + + // We need to take border widths into account + const tools::Long nWidthT = pLnT ? pLnT->GetScaledWidth() : 0; + const tools::Long nWidthL = pLnL ? pLnL->GetScaledWidth() : 0; + const tools::Long nWidthB = pLnB ? pLnB->GetScaledWidth() : 0; + const tools::Long nWidthR = pLnR ? pLnR->GetScaledWidth() : 0; + + // Resulting distances from text to borders + const sal_Int32 nT2BT = pLnT ? nT : 0; + const sal_Int32 nT2BL = pLnL ? nL : 0; + const sal_Int32 nT2BB = pLnB ? nB : 0; + const sal_Int32 nT2BR = pLnR ? nR : 0; + + // Resulting distances from edge to borders + const sal_Int32 nE2BT = pLnT ? std::max<sal_Int32>(rMargins.nTop - nT - nWidthT, 0) : 0; + const sal_Int32 nE2BL = pLnL ? std::max<sal_Int32>(rMargins.nLeft - nL - nWidthL, 0) : 0; + const sal_Int32 nE2BB = pLnB ? std::max<sal_Int32>(rMargins.nBottom - nB - nWidthB, 0) : 0; + const sal_Int32 nE2BR = pLnR ? std::max<sal_Int32>(rMargins.nRight - nR - nWidthR, 0) : 0; + + const sal_Int32 n32pt = 32 * 20; + // 1. If all borders are in range of 31 pts from text + if (nT2BT >= 0 && nT2BT < n32pt && nT2BL >= 0 && nT2BL < n32pt && nT2BB >= 0 && nT2BB < n32pt && nT2BR >= 0 && nT2BR < n32pt) + { + rDistances.bFromEdge = false; + } + else + { + // 2. If all borders are in range of 31 pts from edge + if (nE2BT < n32pt && nE2BL < n32pt && nE2BB < n32pt && nE2BR < n32pt) + { + rDistances.bFromEdge = true; + } + else + { + // Let's try to guess which would be the best approximation + rDistances.bFromEdge = + (nT2BT + nT2BL + nT2BB + nT2BR) > (nE2BT + nE2BL + nE2BB + nE2BR); + } + } + + if (rDistances.bFromEdge) + { + rDistances.nTop = sal::static_int_cast<sal_uInt16>(nE2BT); + rDistances.nLeft = sal::static_int_cast<sal_uInt16>(nE2BL); + rDistances.nBottom = sal::static_int_cast<sal_uInt16>(nE2BB); + rDistances.nRight = sal::static_int_cast<sal_uInt16>(nE2BR); + } + else + { + rDistances.nTop = sal::static_int_cast<sal_uInt16>(nT2BT); + rDistances.nLeft = sal::static_int_cast<sal_uInt16>(nT2BL); + rDistances.nBottom = sal::static_int_cast<sal_uInt16>(nT2BB); + rDistances.nRight = sal::static_int_cast<sal_uInt16>(nT2BR); + } +} + +} + +// class SvxFormatBreakItem ------------------------------------------------- + +bool SvxFormatBreakItem::operator==( const SfxPoolItem& rAttr ) const +{ + assert(SfxPoolItem::operator==(rAttr)); + + return GetValue() == static_cast<const SvxFormatBreakItem&>( rAttr ).GetValue(); +} + + +bool SvxFormatBreakItem::GetPresentation +( + SfxItemPresentation /*ePres*/, + MapUnit /*eCoreUnit*/, + MapUnit /*ePresUnit*/, + OUString& rText, const IntlWrapper& +) const +{ + rText = GetValueTextByPos( GetEnumValue() ); + return true; +} + +OUString SvxFormatBreakItem::GetValueTextByPos( sal_uInt16 nPos ) +{ + static TranslateId RID_SVXITEMS_BREAK[] = + { + RID_SVXITEMS_BREAK_NONE, + RID_SVXITEMS_BREAK_COLUMN_BEFORE, + RID_SVXITEMS_BREAK_COLUMN_AFTER, + RID_SVXITEMS_BREAK_COLUMN_BOTH, + RID_SVXITEMS_BREAK_PAGE_BEFORE, + RID_SVXITEMS_BREAK_PAGE_AFTER, + RID_SVXITEMS_BREAK_PAGE_BOTH + }; + static_assert(std::size(RID_SVXITEMS_BREAK) == size_t(SvxBreak::End), "unexpected size"); + assert(nPos < sal_uInt16(SvxBreak::End) && "enum overflow!"); + return EditResId(RID_SVXITEMS_BREAK[nPos]); +} + +bool SvxFormatBreakItem::QueryValue( uno::Any& rVal, sal_uInt8 /*nMemberId*/ ) const +{ + style::BreakType eBreak = style::BreakType_NONE; + switch ( GetBreak() ) + { + case SvxBreak::ColumnBefore: eBreak = style::BreakType_COLUMN_BEFORE; break; + case SvxBreak::ColumnAfter: eBreak = style::BreakType_COLUMN_AFTER ; break; + case SvxBreak::ColumnBoth: eBreak = style::BreakType_COLUMN_BOTH ; break; + case SvxBreak::PageBefore: eBreak = style::BreakType_PAGE_BEFORE ; break; + case SvxBreak::PageAfter: eBreak = style::BreakType_PAGE_AFTER ; break; + case SvxBreak::PageBoth: eBreak = style::BreakType_PAGE_BOTH ; break; + default: ; // prevent warning + } + rVal <<= eBreak; + return true; +} + +bool SvxFormatBreakItem::PutValue( const uno::Any& rVal, sal_uInt8 /*nMemberId*/ ) +{ + style::BreakType nBreak; + + if(!(rVal >>= nBreak)) + { + sal_Int32 nValue = 0; + if(!(rVal >>= nValue)) + return false; + + nBreak = static_cast<style::BreakType>(nValue); + } + + SvxBreak eBreak = SvxBreak::NONE; + switch( nBreak ) + { + case style::BreakType_COLUMN_BEFORE: eBreak = SvxBreak::ColumnBefore; break; + case style::BreakType_COLUMN_AFTER: eBreak = SvxBreak::ColumnAfter; break; + case style::BreakType_COLUMN_BOTH: eBreak = SvxBreak::ColumnBoth; break; + case style::BreakType_PAGE_BEFORE: eBreak = SvxBreak::PageBefore; break; + case style::BreakType_PAGE_AFTER: eBreak = SvxBreak::PageAfter; break; + case style::BreakType_PAGE_BOTH: eBreak = SvxBreak::PageBoth; break; + default: ; // prevent warning + } + SetValue(eBreak); + + return true; +} + +SvxFormatBreakItem* SvxFormatBreakItem::Clone( SfxItemPool* ) const +{ + return new SvxFormatBreakItem( *this ); +} + +sal_uInt16 SvxFormatBreakItem::GetValueCount() const +{ + return sal_uInt16(SvxBreak::End); // SvxBreak::PageBoth + 1 +} + +SvxFormatKeepItem* SvxFormatKeepItem::Clone( SfxItemPool* ) const +{ + return new SvxFormatKeepItem( *this ); +} + +bool SvxFormatKeepItem::GetPresentation +( + SfxItemPresentation /*ePres*/, + MapUnit /*eCoreUnit*/, + MapUnit /*ePresUnit*/, + OUString& rText, const IntlWrapper& + ) const +{ + TranslateId pId = RID_SVXITEMS_FMTKEEP_FALSE; + + if ( GetValue() ) + pId = RID_SVXITEMS_FMTKEEP_TRUE; + rText = EditResId(pId); + return true; +} + +void SvxFormatKeepItem::dumpAsXml(xmlTextWriterPtr pWriter) const +{ + (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SvxFormatKeepItem")); + + SfxBoolItem::dumpAsXml(pWriter); + + (void)xmlTextWriterEndElement(pWriter); +} + +SvxLineItem::SvxLineItem( const sal_uInt16 nId ) : + SfxPoolItem ( nId ) +{ +} + + +SvxLineItem::SvxLineItem( const SvxLineItem& rCpy ) : + SfxPoolItem ( rCpy ), + pLine(rCpy.pLine ? new SvxBorderLine( *rCpy.pLine ) : nullptr) +{ +} + + +SvxLineItem::~SvxLineItem() +{ +} + + +bool SvxLineItem::operator==( const SfxPoolItem& rAttr ) const +{ + assert(SfxPoolItem::operator==(rAttr)); + + return CmpBrdLn( pLine, static_cast<const SvxLineItem&>(rAttr).GetLine() ); +} + +SvxLineItem* SvxLineItem::Clone( SfxItemPool* ) const +{ + return new SvxLineItem( *this ); +} + +bool SvxLineItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemId ) const +{ + bool bConvert = 0!=(nMemId&CONVERT_TWIPS); + nMemId &= ~CONVERT_TWIPS; + if ( nMemId == 0 ) + { + rVal <<= SvxBoxItem::SvxLineToLine(pLine.get(), bConvert); + return true; + } + else if ( pLine ) + { + switch ( nMemId ) + { + case MID_FG_COLOR: rVal <<= pLine->GetColor(); break; + case MID_OUTER_WIDTH: rVal <<= sal_Int32(pLine->GetOutWidth()); break; + case MID_INNER_WIDTH: rVal <<= sal_Int32(pLine->GetInWidth( )); break; + case MID_DISTANCE: rVal <<= sal_Int32(pLine->GetDistance()); break; + default: + OSL_FAIL( "Wrong MemberId" ); + return false; + } + } + + return true; +} + + +bool SvxLineItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemId ) +{ + bool bConvert = 0!=(nMemId&CONVERT_TWIPS); + nMemId &= ~CONVERT_TWIPS; + sal_Int32 nVal = 0; + if ( nMemId == 0 ) + { + table::BorderLine2 aLine; + if ( lcl_extractBorderLine(rVal, aLine) ) + { + if ( !pLine ) + pLine.reset( new SvxBorderLine ); + if( !SvxBoxItem::LineToSvxLine(aLine, *pLine, bConvert) ) + pLine.reset(); + return true; + } + return false; + } + else if ( rVal >>= nVal ) + { + if ( !pLine ) + pLine.reset( new SvxBorderLine ); + + switch ( nMemId ) + { + case MID_FG_COLOR: pLine->SetColor( Color(ColorTransparency, nVal) ); break; + case MID_LINE_STYLE: + pLine->SetBorderLineStyle(static_cast<SvxBorderLineStyle>(nVal)); + break; + default: + OSL_FAIL( "Wrong MemberId" ); + return false; + } + + return true; + } + + return false; +} + + +bool SvxLineItem::GetPresentation +( + SfxItemPresentation ePres, + MapUnit eCoreUnit, + MapUnit ePresUnit, + OUString& rText, const IntlWrapper& rIntl +) const +{ + rText.clear(); + + if ( pLine ) + rText = pLine->GetValueString( eCoreUnit, ePresUnit, &rIntl, + (SfxItemPresentation::Complete == ePres) ); + return true; +} + + +void SvxLineItem::ScaleMetrics( tools::Long nMult, tools::Long nDiv ) +{ + if ( pLine ) pLine->ScaleMetrics( nMult, nDiv ); +} + + +bool SvxLineItem::HasMetrics() const +{ + return true; +} + + +void SvxLineItem::SetLine( const SvxBorderLine* pNew ) +{ + pLine.reset( pNew ? new SvxBorderLine( *pNew ) : nullptr ); +} + +SvxBrushItem::SvxBrushItem(sal_uInt16 _nWhich) + : SfxPoolItem(_nWhich) + , aColor(COL_TRANSPARENT) + , aFilterColor(COL_TRANSPARENT) + , nShadingValue(ShadingPattern::CLEAR) + , nGraphicTransparency(0) + , eGraphicPos(GPOS_NONE) + , bLoadAgain(true) +{ +} + +SvxBrushItem::SvxBrushItem(const Color& rColor, sal_uInt16 _nWhich) + : SfxPoolItem(_nWhich) + , aColor(rColor) + , aFilterColor(COL_TRANSPARENT) + , nShadingValue(ShadingPattern::CLEAR) + , nGraphicTransparency(0) + , eGraphicPos(GPOS_NONE) + , bLoadAgain(true) +{ +} + +SvxBrushItem::SvxBrushItem(const Graphic& rGraphic, SvxGraphicPosition ePos, sal_uInt16 _nWhich) + : SfxPoolItem(_nWhich) + , aColor(COL_TRANSPARENT) + , aFilterColor(COL_TRANSPARENT) + , nShadingValue(ShadingPattern::CLEAR) + , xGraphicObject(new GraphicObject(rGraphic)) + , nGraphicTransparency(0) + , eGraphicPos((GPOS_NONE != ePos) ? ePos : GPOS_MM) + , bLoadAgain(true) +{ + DBG_ASSERT( GPOS_NONE != ePos, "SvxBrushItem-Ctor with GPOS_NONE == ePos" ); +} + +SvxBrushItem::SvxBrushItem(const GraphicObject& rGraphicObj, SvxGraphicPosition ePos, sal_uInt16 _nWhich) + : SfxPoolItem(_nWhich) + , aColor(COL_TRANSPARENT) + , aFilterColor(COL_TRANSPARENT) + , nShadingValue(ShadingPattern::CLEAR) + , xGraphicObject(new GraphicObject(rGraphicObj)) + , nGraphicTransparency(0) + , eGraphicPos((GPOS_NONE != ePos) ? ePos : GPOS_MM) + , bLoadAgain(true) +{ + DBG_ASSERT( GPOS_NONE != ePos, "SvxBrushItem-Ctor with GPOS_NONE == ePos" ); +} + +SvxBrushItem::SvxBrushItem(OUString aLink, OUString aFilter, + SvxGraphicPosition ePos, sal_uInt16 _nWhich) + : SfxPoolItem(_nWhich) + , aColor(COL_TRANSPARENT) + , aFilterColor(COL_TRANSPARENT) + , nShadingValue(ShadingPattern::CLEAR) + , nGraphicTransparency(0) + , maStrLink(std::move(aLink)) + , maStrFilter(std::move(aFilter)) + , eGraphicPos((GPOS_NONE != ePos) ? ePos : GPOS_MM) + , bLoadAgain(true) +{ + DBG_ASSERT( GPOS_NONE != ePos, "SvxBrushItem-Ctor with GPOS_NONE == ePos" ); +} + +SvxBrushItem::SvxBrushItem(const SvxBrushItem& rItem) + : SfxPoolItem(rItem) + , aColor(rItem.aColor) + , aFilterColor(rItem.aFilterColor) + , nShadingValue(rItem.nShadingValue) + , xGraphicObject(rItem.xGraphicObject ? new GraphicObject(*rItem.xGraphicObject) : nullptr) + , nGraphicTransparency(rItem.nGraphicTransparency) + , maStrLink(rItem.maStrLink) + , maStrFilter(rItem.maStrFilter) + , eGraphicPos(rItem.eGraphicPos) + , bLoadAgain(rItem.bLoadAgain) +{ +} + +SvxBrushItem::SvxBrushItem(SvxBrushItem&& rItem) + : SfxPoolItem(std::move(rItem)) + , aColor(std::move(rItem.aColor)) + , aFilterColor(std::move(rItem.aFilterColor)) + , nShadingValue(std::move(rItem.nShadingValue)) + , xGraphicObject(std::move(rItem.xGraphicObject)) + , nGraphicTransparency(std::move(rItem.nGraphicTransparency)) + , maStrLink(std::move(rItem.maStrLink)) + , maStrFilter(std::move(rItem.maStrFilter)) + , eGraphicPos(std::move(rItem.eGraphicPos)) + , bLoadAgain(std::move(rItem.bLoadAgain)) +{ +} + +SvxBrushItem::~SvxBrushItem() +{ +} + +bool SvxBrushItem::isUsed() const +{ + if (GPOS_NONE != GetGraphicPos()) + { + // graphic used + return true; + } + else if (!GetColor().IsFullyTransparent()) + { + // color used + return true; + } + + return false; +} + + +static sal_Int8 lcl_PercentToTransparency(tools::Long nPercent) +{ + // 0xff must not be returned! + return sal_Int8(nPercent ? (50 + 0xfe * nPercent) / 100 : 0); +} + + +sal_Int8 SvxBrushItem::TransparencyToPercent(sal_Int32 nTrans) +{ + return static_cast<sal_Int8>((nTrans * 100 + 127) / 254); +} + + +bool SvxBrushItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const +{ + nMemberId &= ~CONVERT_TWIPS; + switch( nMemberId) + { + case MID_BACK_COLOR: + rVal <<= aColor; + break; + case MID_BACK_COLOR_R_G_B: + rVal <<= aColor.GetRGBColor(); + break; + case MID_BACK_COLOR_TRANSPARENCY: + rVal <<= SvxBrushItem::TransparencyToPercent(255 - aColor.GetAlpha()); + break; + case MID_GRAPHIC_POSITION: + rVal <<= static_cast<style::GraphicLocation>(static_cast<sal_Int16>(eGraphicPos)); + break; + + case MID_GRAPHIC_TRANSPARENT: + rVal <<= ( aColor.GetAlpha() == 0 ); + break; + + case MID_GRAPHIC_URL: + case MID_GRAPHIC: + { + uno::Reference<graphic::XGraphic> xGraphic; + if (!maStrLink.isEmpty()) + { + Graphic aGraphic(vcl::graphic::loadFromURL(maStrLink)); + xGraphic = aGraphic.GetXGraphic(); + } + else if (xGraphicObject) + { + xGraphic = xGraphicObject->GetGraphic().GetXGraphic(); + } + rVal <<= xGraphic; + } + break; + + case MID_GRAPHIC_FILTER: + { + rVal <<= maStrFilter; + } + break; + + case MID_GRAPHIC_TRANSPARENCY: + rVal <<= nGraphicTransparency; + break; + + case MID_SHADING_VALUE: + { + rVal <<= nShadingValue; + } + break; + } + + return true; +} + + +bool SvxBrushItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId ) +{ + nMemberId &= ~CONVERT_TWIPS; + switch( nMemberId) + { + case MID_BACK_COLOR: + case MID_BACK_COLOR_R_G_B: + { + Color aNewCol; + if ( !( rVal >>= aNewCol ) ) + return false; + if(MID_BACK_COLOR_R_G_B == nMemberId) + { + aNewCol.SetAlpha(aColor.GetAlpha()); + } + aColor = aNewCol; + } + break; + case MID_BACK_COLOR_TRANSPARENCY: + { + sal_Int32 nTrans = 0; + if ( !( rVal >>= nTrans ) || nTrans < 0 || nTrans > 100 ) + return false; + aColor.SetAlpha(255 - lcl_PercentToTransparency(nTrans)); + } + break; + + case MID_GRAPHIC_POSITION: + { + style::GraphicLocation eLocation; + if ( !( rVal>>=eLocation ) ) + { + sal_Int32 nValue = 0; + if ( !( rVal >>= nValue ) ) + return false; + eLocation = static_cast<style::GraphicLocation>(nValue); + } + SetGraphicPos( static_cast<SvxGraphicPosition>(static_cast<sal_uInt16>(eLocation)) ); + } + break; + + case MID_GRAPHIC_TRANSPARENT: + aColor.SetAlpha( Any2Bool( rVal ) ? 0 : 255 ); + break; + + case MID_GRAPHIC_URL: + case MID_GRAPHIC: + { + Graphic aGraphic; + + if (rVal.getValueType() == ::cppu::UnoType<OUString>::get()) + { + OUString aURL = rVal.get<OUString>(); + aGraphic = vcl::graphic::loadFromURL(aURL); + } + else if (rVal.getValueType() == cppu::UnoType<graphic::XGraphic>::get()) + { + auto xGraphic = rVal.get<uno::Reference<graphic::XGraphic>>(); + aGraphic = Graphic(xGraphic); + } + + if (!aGraphic.IsNone()) + { + maStrLink.clear(); + + std::unique_ptr<GraphicObject> xOldGrfObj(std::move(xGraphicObject)); + xGraphicObject.reset(new GraphicObject(aGraphic)); + ApplyGraphicTransparency_Impl(); + xOldGrfObj.reset(); + + if (!aGraphic.IsNone() && eGraphicPos == GPOS_NONE) + { + eGraphicPos = GPOS_MM; + } + else if (aGraphic.IsNone()) + { + eGraphicPos = GPOS_NONE; + } + } + } + break; + + case MID_GRAPHIC_FILTER: + { + if( rVal.getValueType() == ::cppu::UnoType<OUString>::get() ) + { + OUString sLink; + rVal >>= sLink; + SetGraphicFilter( sLink ); + } + } + break; + case MID_GRAPHIC_TRANSPARENCY : + { + sal_Int32 nTmp = 0; + rVal >>= nTmp; + if(nTmp >= 0 && nTmp <= 100) + { + nGraphicTransparency = sal_Int8(nTmp); + if (xGraphicObject) + ApplyGraphicTransparency_Impl(); + } + } + break; + + case MID_SHADING_VALUE: + { + sal_Int32 nVal = 0; + if (!(rVal >>= nVal)) + return false; + + nShadingValue = nVal; + } + break; + } + + return true; +} + + +bool SvxBrushItem::GetPresentation +( + SfxItemPresentation /*ePres*/, + MapUnit /*eCoreUnit*/, + MapUnit /*ePresUnit*/, + OUString& rText, const IntlWrapper& + ) const +{ + if ( GPOS_NONE == eGraphicPos ) + { + rText = ::GetColorString( aColor ) + cpDelim; + TranslateId pId = RID_SVXITEMS_TRANSPARENT_FALSE; + + if ( aColor.IsTransparent() ) + pId = RID_SVXITEMS_TRANSPARENT_TRUE; + rText += EditResId(pId); + } + else + { + rText = EditResId(RID_SVXITEMS_GRAPHIC); + } + + return true; +} + +bool SvxBrushItem::operator==( const SfxPoolItem& rAttr ) const +{ + assert(SfxPoolItem::operator==(rAttr)); + + const SvxBrushItem& rCmp = static_cast<const SvxBrushItem&>(rAttr); + bool bEqual = ( aColor == rCmp.aColor && aFilterColor == rCmp.aFilterColor && + eGraphicPos == rCmp.eGraphicPos && nGraphicTransparency == rCmp.nGraphicTransparency); + + if ( bEqual ) + { + if ( GPOS_NONE != eGraphicPos ) + { + bEqual = maStrLink == rCmp.maStrLink; + + if ( bEqual ) + { + bEqual = maStrFilter == rCmp.maStrFilter; + } + + if ( bEqual ) + { + if (!rCmp.xGraphicObject) + bEqual = !xGraphicObject; + else + bEqual = xGraphicObject && + (*xGraphicObject == *rCmp.xGraphicObject); + } + } + + if (bEqual) + { + bEqual = nShadingValue == rCmp.nShadingValue; + } + } + + return bEqual; +} + +SvxBrushItem* SvxBrushItem::Clone( SfxItemPool* ) const +{ + return new SvxBrushItem( *this ); +} + +const GraphicObject* SvxBrushItem::GetGraphicObject(OUString const & referer) const +{ + if (bLoadAgain && !maStrLink.isEmpty() && !xGraphicObject) + // when graphics already loaded, use as a cache + { + if (SvtSecurityOptions::isUntrustedReferer(referer)) { + return nullptr; + } + + // tdf#94088 prepare graphic and state + Graphic aGraphic; + bool bGraphicLoaded = false; + + // try to create stream directly from given URL + std::unique_ptr<SvStream> xStream(utl::UcbStreamHelper::CreateStream(maStrLink, StreamMode::STD_READ)); + // tdf#94088 if we have a stream, try to load it directly as graphic + if (xStream && !xStream->GetError()) + { + if (ERRCODE_NONE == GraphicFilter::GetGraphicFilter().ImportGraphic(aGraphic, maStrLink, *xStream, + GRFILTER_FORMAT_DONTKNOW, nullptr, GraphicFilterImportFlags::DontSetLogsizeForJpeg)) + { + bGraphicLoaded = true; + } + } + + // tdf#94088 if no succeeded, try if the string (which is not empty) contains + // a 'data:' scheme url and try to load that (embedded graphics) + if(!bGraphicLoaded) + { + INetURLObject aGraphicURL( maStrLink ); + + if( INetProtocol::Data == aGraphicURL.GetProtocol() ) + { + std::unique_ptr<SvMemoryStream> const xMemStream(aGraphicURL.getData()); + if (xMemStream) + { + if (ERRCODE_NONE == GraphicFilter::GetGraphicFilter().ImportGraphic(aGraphic, u"", *xMemStream)) + { + bGraphicLoaded = true; + + // tdf#94088 delete the no longer needed data scheme URL which + // is potentially pretty // large, containing a base64 encoded copy of the graphic + const_cast< SvxBrushItem* >(this)->maStrLink.clear(); + } + } + } + } + + // tdf#94088 when we got a graphic, set it + if(bGraphicLoaded && GraphicType::NONE != aGraphic.GetType()) + { + xGraphicObject.reset(new GraphicObject); + xGraphicObject->SetGraphic(aGraphic); + const_cast < SvxBrushItem*> (this)->ApplyGraphicTransparency_Impl(); + } + else + { + bLoadAgain = false; + } + } + + return xGraphicObject.get(); +} + +void SvxBrushItem::setGraphicTransparency(sal_Int8 nNew) +{ + if (nNew != nGraphicTransparency) + { + nGraphicTransparency = nNew; + ApplyGraphicTransparency_Impl(); + } +} + +const Graphic* SvxBrushItem::GetGraphic(OUString const & referer) const +{ + const GraphicObject* pGrafObj = GetGraphicObject(referer); + return( pGrafObj ? &( pGrafObj->GetGraphic() ) : nullptr ); +} + +void SvxBrushItem::SetGraphicPos( SvxGraphicPosition eNew ) +{ + eGraphicPos = eNew; + + if ( GPOS_NONE == eGraphicPos ) + { + xGraphicObject.reset(); + maStrLink.clear(); + maStrFilter.clear(); + } + else + { + if (!xGraphicObject && maStrLink.isEmpty()) + { + xGraphicObject.reset(new GraphicObject); // Creating a dummy + } + } +} + +void SvxBrushItem::SetGraphic( const Graphic& rNew ) +{ + if ( maStrLink.isEmpty() ) + { + if (xGraphicObject) + xGraphicObject->SetGraphic(rNew); + else + xGraphicObject.reset(new GraphicObject(rNew)); + + ApplyGraphicTransparency_Impl(); + + if ( GPOS_NONE == eGraphicPos ) + eGraphicPos = GPOS_MM; // None would be brush, then Default: middle + } + else + { + OSL_FAIL( "SetGraphic() on linked graphic! :-/" ); + } +} + +void SvxBrushItem::SetGraphicObject( const GraphicObject& rNewObj ) +{ + if ( maStrLink.isEmpty() ) + { + if (xGraphicObject) + *xGraphicObject = rNewObj; + else + xGraphicObject.reset(new GraphicObject(rNewObj)); + + ApplyGraphicTransparency_Impl(); + + if ( GPOS_NONE == eGraphicPos ) + eGraphicPos = GPOS_MM; // None would be brush, then Default: middle + } + else + { + OSL_FAIL( "SetGraphic() on linked graphic! :-/" ); + } +} + +void SvxBrushItem::SetGraphicLink( const OUString& rNew ) +{ + if ( rNew.isEmpty() ) + maStrLink.clear(); + else + { + maStrLink = rNew; + xGraphicObject.reset(); + } +} + +void SvxBrushItem::SetGraphicFilter( const OUString& rNew ) +{ + maStrFilter = rNew; +} + +void SvxBrushItem::ApplyGraphicTransparency_Impl() +{ + DBG_ASSERT(xGraphicObject, "no GraphicObject available" ); + if (xGraphicObject) + { + GraphicAttr aAttr(xGraphicObject->GetAttr()); + aAttr.SetAlpha(255 - lcl_PercentToTransparency( + nGraphicTransparency)); + xGraphicObject->SetAttr(aAttr); + } +} + +void SvxBrushItem::dumpAsXml(xmlTextWriterPtr pWriter) const +{ + (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SvxBrushItem")); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr())); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("color"), BAD_CAST(aColor.AsRGBHexString().toUtf8().getStr())); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("filtercolor"), BAD_CAST(aFilterColor.AsRGBHexString().toUtf8().getStr())); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("shadingValue"), BAD_CAST(OString::number(nShadingValue).getStr())); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("link"), BAD_CAST(maStrLink.toUtf8().getStr())); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("filter"), BAD_CAST(maStrFilter.toUtf8().getStr())); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("graphicPos"), BAD_CAST(OString::number(eGraphicPos).getStr())); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("loadAgain"), BAD_CAST(OString::boolean(bLoadAgain).getStr())); + (void)xmlTextWriterEndElement(pWriter); +} + + +SvxFrameDirectionItem::SvxFrameDirectionItem( SvxFrameDirection nValue , + sal_uInt16 _nWhich ) + : SfxEnumItem<SvxFrameDirection>( _nWhich, nValue ) +{ +} + + +SvxFrameDirectionItem::~SvxFrameDirectionItem() +{ +} + +SvxFrameDirectionItem* SvxFrameDirectionItem::Clone( SfxItemPool * ) const +{ + return new SvxFrameDirectionItem( *this ); +} + +TranslateId getFrmDirResId(size_t nIndex) +{ + TranslateId const RID_SVXITEMS_FRMDIR[] = + { + RID_SVXITEMS_FRMDIR_HORI_LEFT_TOP, + RID_SVXITEMS_FRMDIR_HORI_RIGHT_TOP, + RID_SVXITEMS_FRMDIR_VERT_TOP_RIGHT, + RID_SVXITEMS_FRMDIR_VERT_TOP_LEFT, + RID_SVXITEMS_FRMDIR_ENVIRONMENT, + RID_SVXITEMS_FRMDIR_VERT_BOT_LEFT + }; + return RID_SVXITEMS_FRMDIR[nIndex]; +} + +bool SvxFrameDirectionItem::GetPresentation( + SfxItemPresentation /*ePres*/, + MapUnit /*eCoreUnit*/, + MapUnit /*ePresUnit*/, + OUString& rText, const IntlWrapper&) const +{ + rText = EditResId(getFrmDirResId(GetEnumValue())); + return true; +} + +bool SvxFrameDirectionItem::PutValue( const css::uno::Any& rVal, + sal_uInt8 ) +{ + sal_Int16 nVal = sal_Int16(); + bool bRet = ( rVal >>= nVal ); + if( bRet ) + { + // translate WritingDirection2 constants into SvxFrameDirection + switch( nVal ) + { + case text::WritingMode2::LR_TB: + SetValue( SvxFrameDirection::Horizontal_LR_TB ); + break; + case text::WritingMode2::RL_TB: + SetValue( SvxFrameDirection::Horizontal_RL_TB ); + break; + case text::WritingMode2::TB_RL: + SetValue( SvxFrameDirection::Vertical_RL_TB ); + break; + case text::WritingMode2::TB_LR: + SetValue( SvxFrameDirection::Vertical_LR_TB ); + break; + case text::WritingMode2::BT_LR: + SetValue( SvxFrameDirection::Vertical_LR_BT ); + break; + case text::WritingMode2::PAGE: + SetValue( SvxFrameDirection::Environment ); + break; + default: + bRet = false; + break; + } + } + + return bRet; +} + + +bool SvxFrameDirectionItem::QueryValue( css::uno::Any& rVal, + sal_uInt8 ) const +{ + // translate SvxFrameDirection into WritingDirection2 + sal_Int16 nVal; + bool bRet = true; + switch( GetValue() ) + { + case SvxFrameDirection::Horizontal_LR_TB: + nVal = text::WritingMode2::LR_TB; + break; + case SvxFrameDirection::Horizontal_RL_TB: + nVal = text::WritingMode2::RL_TB; + break; + case SvxFrameDirection::Vertical_RL_TB: + nVal = text::WritingMode2::TB_RL; + break; + case SvxFrameDirection::Vertical_LR_TB: + nVal = text::WritingMode2::TB_LR; + break; + case SvxFrameDirection::Vertical_LR_BT: + nVal = text::WritingMode2::BT_LR; + break; + case SvxFrameDirection::Environment: + nVal = text::WritingMode2::PAGE; + break; + default: + OSL_FAIL("Unknown SvxFrameDirection value!"); + bRet = false; + break; + } + + // return value + error state + if( bRet ) + { + rVal <<= nVal; + } + return bRet; +} + +void SvxFrameDirectionItem::dumpAsXml(xmlTextWriterPtr pWriter) const +{ + (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SvxFrameDirectionItem")); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("m_nWhich"), + BAD_CAST(OString::number(Which()).getStr())); + (void)xmlTextWriterWriteAttribute( + pWriter, BAD_CAST("m_nValue"), + BAD_CAST(OString::number(static_cast<sal_Int16>(GetValue())).getStr())); + (void)xmlTextWriterEndElement(pWriter); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/editeng/source/items/itemtype.cxx b/editeng/source/items/itemtype.cxx new file mode 100644 index 000000000..cbb83c83b --- /dev/null +++ b/editeng/source/items/itemtype.cxx @@ -0,0 +1,232 @@ +/* -*- 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 <osl/diagnose.h> +#include <vcl/outdev.hxx> +#include <editeng/editrids.hrc> +#include <unotools/intlwrapper.hxx> +#include <unotools/localedatawrapper.hxx> +#include <editeng/itemtype.hxx> +#include <editeng/eerdll.hxx> +#include <rtl/ustrbuf.hxx> + + +OUString GetMetricText( tools::Long nVal, MapUnit eSrcUnit, MapUnit eDestUnit, const IntlWrapper* pIntl ) +{ + bool bNeg = false; + bool bShowAtLeastOneDecimalDigit = true; + sal_Int32 nRet = 0; + + if ( nVal < 0 ) + { + bNeg = true; + nVal *= -1; + } + + switch ( eDestUnit ) + { + case MapUnit::Map100thMM: + case MapUnit::Map10thMM: + case MapUnit::MapMM: + case MapUnit::MapCM: + { + nRet = OutputDevice::LogicToLogic( nVal, eSrcUnit, MapUnit::Map100thMM ); + + switch ( eDestUnit ) + { + case MapUnit::Map100thMM: nRet *= 1000; break; + case MapUnit::Map10thMM: nRet *= 100; break; + case MapUnit::MapMM: nRet *= 10; break; + default: ;//prevent warning + } + break; + } + + case MapUnit::Map1000thInch: + case MapUnit::Map100thInch: + case MapUnit::Map10thInch: + case MapUnit::MapInch: + { + nRet = OutputDevice::LogicToLogic( nVal, eSrcUnit, MapUnit::Map1000thInch ); + + switch ( eDestUnit ) + { + case MapUnit::Map1000thInch: nRet *= 1000; break; + case MapUnit::Map100thInch: nRet *= 100; break; + case MapUnit::Map10thInch: nRet *= 10; break; + default: ;//prevent warning + } + break; + } + + case MapUnit::MapPoint: + // fractions of a point are used, e.g., for font size + nRet = OutputDevice::LogicToLogic(nVal, eSrcUnit, MapUnit::MapTwip) * 50; + bShowAtLeastOneDecimalDigit = false; + break; + + case MapUnit::MapTwip: + case MapUnit::MapPixel: + return OUString::number( OutputDevice::LogicToLogic( + nVal, eSrcUnit, eDestUnit )); + + default: + OSL_FAIL( "not supported mapunit" ); + return OUString(); + } + + if ( MapUnit::MapCM == eDestUnit || MapUnit::MapInch == eDestUnit ) + { + sal_Int32 nMod = nRet % 10; + + if ( nMod > 4 ) + nRet += 10 - nMod; + else if ( nMod > 0 ) + nRet -= nMod; + } + + OUStringBuffer sRet; + + if ( bNeg ) + sRet.append('-'); + + tools::Long nDiff = 1000; + for( int nDigits = 4; nDigits; --nDigits, nDiff /= 10 ) + { + if ( nRet < nDiff ) + sRet.append('0'); + else + sRet.append(nRet / nDiff); + nRet %= nDiff; + if( 4 == nDigits && (bShowAtLeastOneDecimalDigit || nRet) ) + { + if(pIntl) + sRet.append(pIntl->getLocaleData()->getNumDecimalSep()); + else + sRet.append(','); + if( !nRet ) + { + sRet.append('0'); + break; + } + } + else if( !nRet ) + break; + } + return sRet.makeStringAndClear(); +} + +OUString GetColorString( const Color& rCol ) +{ + if (rCol == COL_AUTO) + return EditResId(RID_SVXSTR_AUTOMATIC); + + static const Color aColAry[] = { + COL_BLACK, COL_BLUE, COL_GREEN, COL_CYAN, + COL_RED, COL_MAGENTA, COL_BROWN, COL_GRAY, + COL_LIGHTGRAY, COL_LIGHTBLUE, COL_LIGHTGREEN, COL_LIGHTCYAN, + COL_LIGHTRED, COL_LIGHTMAGENTA, COL_YELLOW, COL_WHITE }; + + sal_uInt16 nColor = 0; + while ( nColor < SAL_N_ELEMENTS(aColAry) && + aColAry[nColor] != rCol.GetRGBColor() ) + { + nColor += 1; + } + + static TranslateId RID_SVXITEMS_COLORS[] = + { + RID_SVXITEMS_COLOR_BLACK, + RID_SVXITEMS_COLOR_BLUE, + RID_SVXITEMS_COLOR_GREEN, + RID_SVXITEMS_COLOR_CYAN, + RID_SVXITEMS_COLOR_RED, + RID_SVXITEMS_COLOR_MAGENTA, + RID_SVXITEMS_COLOR_BROWN, + RID_SVXITEMS_COLOR_GRAY, + RID_SVXITEMS_COLOR_LIGHTGRAY, + RID_SVXITEMS_COLOR_LIGHTBLUE, + RID_SVXITEMS_COLOR_LIGHTGREEN, + RID_SVXITEMS_COLOR_LIGHTCYAN, + RID_SVXITEMS_COLOR_LIGHTRED, + RID_SVXITEMS_COLOR_LIGHTMAGENTA, + RID_SVXITEMS_COLOR_YELLOW, + RID_SVXITEMS_COLOR_WHITE + }; + + static_assert(SAL_N_ELEMENTS(aColAry) == SAL_N_ELEMENTS(RID_SVXITEMS_COLORS), "must match"); + + OUString sStr; + if ( nColor < SAL_N_ELEMENTS(aColAry) ) + sStr = EditResId(RID_SVXITEMS_COLORS[nColor]); + + if ( sStr.isEmpty() ) + { + sStr += "RGB(" + + OUString::number( rCol.GetRed() ) + cpDelim + + OUString::number( rCol.GetGreen() ) + cpDelim + + OUString::number( rCol.GetBlue() ) + ")"; + } + return sStr; +} + +TranslateId GetMetricId( MapUnit eUnit ) +{ + TranslateId pId = RID_SVXITEMS_METRIC_MM; + + switch ( eUnit ) + { + case MapUnit::Map100thMM: + case MapUnit::Map10thMM: + case MapUnit::MapMM: + pId = RID_SVXITEMS_METRIC_MM; + break; + + case MapUnit::MapCM: + pId = RID_SVXITEMS_METRIC_CM; + break; + + case MapUnit::Map1000thInch: + case MapUnit::Map100thInch: + case MapUnit::Map10thInch: + case MapUnit::MapInch: + pId = RID_SVXITEMS_METRIC_INCH; + break; + + case MapUnit::MapPoint: + pId = RID_SVXITEMS_METRIC_POINT; + break; + + case MapUnit::MapTwip: + pId = RID_SVXITEMS_METRIC_TWIP; + break; + + case MapUnit::MapPixel: + pId = RID_SVXITEMS_METRIC_PIXEL; + break; + + default: + OSL_FAIL( "not supported mapunit" ); + } + return pId; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/editeng/source/items/justifyitem.cxx b/editeng/source/items/justifyitem.cxx new file mode 100644 index 000000000..7fe699cb2 --- /dev/null +++ b/editeng/source/items/justifyitem.cxx @@ -0,0 +1,368 @@ +/* -*- 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 <editeng/justifyitem.hxx> +#include <editeng/memberids.h> +#include <editeng/eerdll.hxx> + +#include <com/sun/star/table/CellHoriJustify.hpp> +#include <com/sun/star/style/ParagraphAdjust.hpp> +#include <com/sun/star/table/CellJustifyMethod.hpp> +#include <com/sun/star/table/CellVertJustify2.hpp> +#include <com/sun/star/style/VerticalAlignment.hpp> + +#include <strings.hrc> + +SfxPoolItem* SvxHorJustifyItem::CreateDefault() { return new SvxHorJustifyItem(SvxCellHorJustify::Standard, 0) ;} +SfxPoolItem* SvxVerJustifyItem::CreateDefault() { return new SvxVerJustifyItem(SvxCellVerJustify::Standard, 0) ;} + +using namespace ::com::sun::star; + + +SvxHorJustifyItem::SvxHorJustifyItem( const sal_uInt16 nId ) : + SfxEnumItem( nId, SvxCellHorJustify::Standard ) +{ +} + +SvxHorJustifyItem::SvxHorJustifyItem( const SvxCellHorJustify eJustify, + const sal_uInt16 nId ) : + SfxEnumItem( nId, eJustify ) +{ +} + + +bool SvxHorJustifyItem::GetPresentation +( + SfxItemPresentation /*ePres*/, + MapUnit /*eCoreUnit*/, + MapUnit /*ePresUnit*/, + OUString& rText, const IntlWrapper&) const +{ + rText = GetValueText(GetValue()); + return true; +} + + +bool SvxHorJustifyItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const +{ + nMemberId &= ~CONVERT_TWIPS; + switch ( nMemberId ) + { + case MID_HORJUST_HORJUST: + { + table::CellHoriJustify eUno = table::CellHoriJustify_STANDARD; + switch ( GetValue() ) + { + case SvxCellHorJustify::Standard: eUno = table::CellHoriJustify_STANDARD; break; + case SvxCellHorJustify::Left: eUno = table::CellHoriJustify_LEFT; break; + case SvxCellHorJustify::Center: eUno = table::CellHoriJustify_CENTER; break; + case SvxCellHorJustify::Right: eUno = table::CellHoriJustify_RIGHT; break; + case SvxCellHorJustify::Block: eUno = table::CellHoriJustify_BLOCK; break; + case SvxCellHorJustify::Repeat: eUno = table::CellHoriJustify_REPEAT; break; + } + rVal <<= eUno; + } + break; + case MID_HORJUST_ADJUST: + { + // ParagraphAdjust values, as in SvxAdjustItem + // (same value for ParaAdjust and ParaLastLineAdjust) + + style::ParagraphAdjust nAdjust = style::ParagraphAdjust_LEFT; + switch ( GetValue() ) + { + // ParagraphAdjust_LEFT is used for STANDARD and REPEAT + case SvxCellHorJustify::Standard: + case SvxCellHorJustify::Repeat: + case SvxCellHorJustify::Left: nAdjust = style::ParagraphAdjust_LEFT; break; + case SvxCellHorJustify::Center: nAdjust = style::ParagraphAdjust_CENTER; break; + case SvxCellHorJustify::Right: nAdjust = style::ParagraphAdjust_RIGHT; break; + case SvxCellHorJustify::Block: nAdjust = style::ParagraphAdjust_BLOCK; break; + } + rVal <<= static_cast<sal_Int16>(nAdjust); // as sal_Int16 + } + break; + } + return true; +} + +bool SvxHorJustifyItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId ) +{ + nMemberId &= ~CONVERT_TWIPS; + switch ( nMemberId ) + { + case MID_HORJUST_HORJUST: + { + table::CellHoriJustify eUno; + if(!(rVal >>= eUno)) + { + sal_Int32 nValue = 0; + if(!(rVal >>= nValue)) + return false; + eUno = static_cast<table::CellHoriJustify>(nValue); + } + SvxCellHorJustify eSvx = SvxCellHorJustify::Standard; + switch (eUno) + { + case table::CellHoriJustify_STANDARD: eSvx = SvxCellHorJustify::Standard; break; + case table::CellHoriJustify_LEFT: eSvx = SvxCellHorJustify::Left; break; + case table::CellHoriJustify_CENTER: eSvx = SvxCellHorJustify::Center; break; + case table::CellHoriJustify_RIGHT: eSvx = SvxCellHorJustify::Right; break; + case table::CellHoriJustify_BLOCK: eSvx = SvxCellHorJustify::Block; break; + case table::CellHoriJustify_REPEAT: eSvx = SvxCellHorJustify::Repeat; break; + default: ; //prevent warning + } + SetValue( eSvx ); + } + break; + case MID_HORJUST_ADJUST: + { + // property contains ParagraphAdjust values as sal_Int16 + sal_Int16 nVal = sal_Int16(); + if(!(rVal >>= nVal)) + return false; + + SvxCellHorJustify eSvx = SvxCellHorJustify::Standard; + switch (static_cast<style::ParagraphAdjust>(nVal)) + { + // STRETCH is treated as BLOCK + case style::ParagraphAdjust_LEFT: eSvx = SvxCellHorJustify::Left; break; + case style::ParagraphAdjust_RIGHT: eSvx = SvxCellHorJustify::Right; break; + case style::ParagraphAdjust_STRETCH: + case style::ParagraphAdjust_BLOCK: eSvx = SvxCellHorJustify::Block; break; + case style::ParagraphAdjust_CENTER: eSvx = SvxCellHorJustify::Center; break; + default: break; + } + SetValue( eSvx ); + } + } + return true; +} + +OUString SvxHorJustifyItem::GetValueText(SvxCellHorJustify nVal) +{ + assert(nVal <= SvxCellHorJustify::Repeat && "enum overflow!"); + return EditResId(RID_SVXITEMS_HORJUST[static_cast<size_t>(nVal)]); +} + +SvxHorJustifyItem* SvxHorJustifyItem::Clone( SfxItemPool* ) const +{ + return new SvxHorJustifyItem( *this ); +} + +sal_uInt16 SvxHorJustifyItem::GetValueCount() const +{ + return sal_uInt16(SvxCellHorJustify::Repeat) + 1; // Last Enum value + 1 +} + + +SvxVerJustifyItem::SvxVerJustifyItem( const sal_uInt16 nId ) : + SfxEnumItem( nId, SvxCellVerJustify::Standard ) +{ +} + +SvxVerJustifyItem::SvxVerJustifyItem( const SvxCellVerJustify eJustify, + const sal_uInt16 nId ) : + SfxEnumItem( nId, eJustify ) +{ +} + + +bool SvxVerJustifyItem::GetPresentation +( + SfxItemPresentation /*ePres*/, + MapUnit /*eCoreUnit*/, + MapUnit /*ePresUnit*/, + OUString& rText, + const IntlWrapper& ) const +{ + rText = GetValueText( GetValue() ); + return true; +} + + +bool SvxVerJustifyItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const +{ + nMemberId &= ~CONVERT_TWIPS; + switch ( nMemberId ) + { + case MID_HORJUST_ADJUST: + { + style::VerticalAlignment eUno = style::VerticalAlignment_TOP; + switch ( GetValue() ) + { + case SvxCellVerJustify::Top: eUno = style::VerticalAlignment_TOP; break; + case SvxCellVerJustify::Center: eUno = style::VerticalAlignment_MIDDLE; break; + case SvxCellVerJustify::Bottom: eUno = style::VerticalAlignment_BOTTOM; break; + default: ; //prevent warning + } + rVal <<= eUno; + break; + } + default: + { + sal_Int32 nUno = table::CellVertJustify2::STANDARD; + switch ( GetValue() ) + { + case SvxCellVerJustify::Standard: nUno = table::CellVertJustify2::STANDARD; break; + case SvxCellVerJustify::Top: nUno = table::CellVertJustify2::TOP; break; + case SvxCellVerJustify::Center: nUno = table::CellVertJustify2::CENTER; break; + case SvxCellVerJustify::Bottom: nUno = table::CellVertJustify2::BOTTOM; break; + case SvxCellVerJustify::Block: nUno = table::CellVertJustify2::BLOCK; break; + default: ; //prevent warning + } + rVal <<= nUno; + break; + } + } + return true; +} + +bool SvxVerJustifyItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId ) +{ + nMemberId &= ~CONVERT_TWIPS; + switch ( nMemberId ) + { + case MID_HORJUST_ADJUST: + { + // property contains ParagraphAdjust values as sal_Int16 + style::VerticalAlignment nVal = style::VerticalAlignment_TOP; + if(!(rVal >>= nVal)) + return false; + + SvxCellVerJustify eSvx = SvxCellVerJustify::Standard; + switch (nVal) + { + case style::VerticalAlignment_TOP: eSvx = SvxCellVerJustify::Top; break; + case style::VerticalAlignment_MIDDLE: eSvx = SvxCellVerJustify::Center; break; + case style::VerticalAlignment_BOTTOM: eSvx = SvxCellVerJustify::Bottom; break; + default:; + } + SetValue( eSvx ); + break; + } + default: + { + sal_Int32 eUno = table::CellVertJustify2::STANDARD; + rVal >>= eUno; + + SvxCellVerJustify eSvx = SvxCellVerJustify::Standard; + switch (eUno) + { + case table::CellVertJustify2::STANDARD: eSvx = SvxCellVerJustify::Standard; break; + case table::CellVertJustify2::TOP: eSvx = SvxCellVerJustify::Top; break; + case table::CellVertJustify2::CENTER: eSvx = SvxCellVerJustify::Center; break; + case table::CellVertJustify2::BOTTOM: eSvx = SvxCellVerJustify::Bottom; break; + case table::CellVertJustify2::BLOCK: eSvx = SvxCellVerJustify::Block; break; + default: ; //prevent warning + } + SetValue( eSvx ); + break; + } + } + + return true; +} + +OUString SvxVerJustifyItem::GetValueText( SvxCellVerJustify nVal ) +{ + assert(nVal <= SvxCellVerJustify::Block && "enum overflow!"); + return EditResId(RID_SVXITEMS_VERJUST[static_cast<size_t>(nVal)]); +} + +SvxVerJustifyItem* SvxVerJustifyItem::Clone( SfxItemPool* ) const +{ + return new SvxVerJustifyItem( *this ); +} + +sal_uInt16 SvxVerJustifyItem::GetValueCount() const +{ + return static_cast<sal_uInt16>(SvxCellVerJustify::Bottom) + 1; // Last Enum value + 1 +} + +SvxJustifyMethodItem::SvxJustifyMethodItem( const SvxCellJustifyMethod eJustify, + const sal_uInt16 nId ) : + SfxEnumItem( nId, eJustify ) +{ +} + +bool SvxJustifyMethodItem::GetPresentation +( + SfxItemPresentation /*ePres*/, + MapUnit /*eCoreUnit*/, + MapUnit /*ePresUnit*/, + OUString& rText, + const IntlWrapper& ) const +{ + rText = GetValueText( GetValue() ); + return true; +} + + +bool SvxJustifyMethodItem::QueryValue( uno::Any& rVal, sal_uInt8 /*nMemberId*/ ) const +{ + sal_Int32 nUno = table::CellJustifyMethod::AUTO; + switch (GetValue()) + { + case SvxCellJustifyMethod::Auto: nUno = table::CellJustifyMethod::AUTO; break; + case SvxCellJustifyMethod::Distribute: nUno = table::CellJustifyMethod::DISTRIBUTE; break; + default:; + } + rVal <<= nUno; + return true; +} + +bool SvxJustifyMethodItem::PutValue( const uno::Any& rVal, sal_uInt8 /*nMemberId*/ ) +{ + sal_Int32 nVal = table::CellJustifyMethod::AUTO; + if (!(rVal >>= nVal)) + return false; + + SvxCellJustifyMethod eSvx = SvxCellJustifyMethod::Auto; + switch (nVal) + { + case table::CellJustifyMethod::AUTO: + eSvx = SvxCellJustifyMethod::Auto; + break; + case table::CellJustifyMethod::DISTRIBUTE: + eSvx = SvxCellJustifyMethod::Distribute; + break; + default:; + } + SetValue(eSvx); + return true; +} + +OUString SvxJustifyMethodItem::GetValueText( SvxCellJustifyMethod nVal ) +{ + assert(nVal <= SvxCellJustifyMethod::Distribute && "enum overflow!"); + return EditResId(RID_SVXITEMS_JUSTMETHOD[static_cast<size_t>(nVal)]); +} + +SvxJustifyMethodItem* SvxJustifyMethodItem::Clone( SfxItemPool* ) const +{ + return new SvxJustifyMethodItem( *this ); +} + +sal_uInt16 SvxJustifyMethodItem::GetValueCount() const +{ + return static_cast<sal_uInt16>(SvxCellJustifyMethod::Distribute) + 1; // Last Enum value + 1 +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/editeng/source/items/legacyitem.cxx b/editeng/source/items/legacyitem.cxx new file mode 100644 index 000000000..89c15dd5a --- /dev/null +++ b/editeng/source/items/legacyitem.cxx @@ -0,0 +1,826 @@ +/* -*- 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 <editeng/legacyitem.hxx> +#include <unotools/fontdefs.hxx> +#include <tools/tenccvt.hxx> +#include <tools/stream.hxx> +#include <comphelper/fileformat.h> +#include <vcl/graph.hxx> +#include <vcl/GraphicObject.hxx> +#include <vcl/TypeSerializer.hxx> +#include <osl/diagnose.h> +#include <tools/urlobj.hxx> +#include <editeng/fontitem.hxx> +#include <editeng/fhgtitem.hxx> +#include <editeng/wghtitem.hxx> +#include <editeng/postitem.hxx> +#include <editeng/udlnitem.hxx> +#include <editeng/crossedoutitem.hxx> +#include <editeng/colritem.hxx> +#include <editeng/boxitem.hxx> +#include <editeng/borderline.hxx> +#include <editeng/lineitem.hxx> +#include <editeng/brushitem.hxx> +#include <editeng/editerr.hxx> +#include <editeng/adjustitem.hxx> +#include <editeng/justifyitem.hxx> +#include <editeng/frmdiritem.hxx> +#include <editeng/formatbreakitem.hxx> +#include <editeng/keepitem.hxx> +#include <editeng/shaditem.hxx> +#include <tools/GenericTypeSerializer.hxx> + + +void Create_legacy_direct_set(SvxFontHeightItem& rItem, sal_uInt32 nH, sal_uInt16 nP, MapUnit eP) +{ + rItem.legacy_direct_set(nH, nP, eP); +} + +namespace legacy +{ + namespace SvxFont + { + sal_uInt16 GetVersion(sal_uInt16) + { + return 0; + } + + void Create(SvxFontItem& rItem, SvStream& rStrm, sal_uInt16) + { + sal_uInt8 _eFamily, eFontPitch, eFontTextEncoding; + OUString aName, aStyle; + rStrm.ReadUChar( _eFamily ); + rStrm.ReadUChar( eFontPitch ); + rStrm.ReadUChar( eFontTextEncoding ); + + // UNICODE: rStrm >> aName; + aName = rStrm.ReadUniOrByteString(rStrm.GetStreamCharSet()); + + // UNICODE: rStrm >> aStyle; + aStyle = rStrm.ReadUniOrByteString(rStrm.GetStreamCharSet()); + + // Set the "correct" textencoding + eFontTextEncoding = static_cast<sal_uInt8>(GetSOLoadTextEncoding( eFontTextEncoding )); + + // at some point, the StarBats changes from ANSI font to SYMBOL font + if ( RTL_TEXTENCODING_SYMBOL != eFontTextEncoding && aName == "StarBats" ) + eFontTextEncoding = RTL_TEXTENCODING_SYMBOL; + + // Check if we have stored unicode + sal_uInt64 const nStreamPos = rStrm.Tell(); + // #define STORE_UNICODE_MAGIC_MARKER 0xFE331188 + sal_uInt32 nMagic = 0xFE331188; + rStrm.ReadUInt32( nMagic ); + if ( nMagic == 0xFE331188 ) + { + aName = rStrm.ReadUniOrByteString( RTL_TEXTENCODING_UNICODE ); + aStyle = rStrm.ReadUniOrByteString( RTL_TEXTENCODING_UNICODE ); + } + else + { + rStrm.Seek( nStreamPos ); + } + + rItem.SetFamilyName(aName); + rItem.SetStyleName(aStyle); + rItem.SetFamily(static_cast<FontFamily>(_eFamily)); + rItem.SetPitch(static_cast<FontPitch>(eFontPitch)); + rItem.SetCharSet(static_cast<rtl_TextEncoding>(eFontTextEncoding)); + } + + SvStream& Store(const SvxFontItem& rItem, SvStream& rStrm, sal_uInt16) + { + const bool bToBats(IsStarSymbol(rItem.GetFamilyName())); + + rStrm.WriteUChar(rItem.GetFamily()).WriteUChar(rItem.GetPitch()).WriteUChar(bToBats ? + RTL_TEXTENCODING_SYMBOL : + GetSOStoreTextEncoding(rItem.GetCharSet())); + + const OUString aStoreFamilyName(bToBats ? "StarBats" : rItem.GetFamilyName()); + + rStrm.WriteUniOrByteString(aStoreFamilyName, rStrm.GetStreamCharSet()); + rStrm.WriteUniOrByteString(rItem.GetStyleName(), rStrm.GetStreamCharSet()); + + return rStrm; + } + } + + namespace SvxFontHeight + { + sal_uInt16 GetVersion(sal_uInt16 nFileFormatVersion) + { + return (nFileFormatVersion <= SOFFICE_FILEFORMAT_40) + ? FONTHEIGHT_16_VERSION + : FONTHEIGHT_UNIT_VERSION; + } + + void Create(SvxFontHeightItem& rItem, SvStream& rStrm, sal_uInt16 nItemVersion) + { + sal_uInt16 nsize, nprop = 0; + MapUnit nPropUnit = MapUnit::MapRelative; + + rStrm.ReadUInt16( nsize ); + + if( FONTHEIGHT_16_VERSION <= nItemVersion ) + rStrm.ReadUInt16( nprop ); + else + { + sal_uInt8 nP; + rStrm .ReadUChar( nP ); + nprop = static_cast<sal_uInt16>(nP); + } + + if( FONTHEIGHT_UNIT_VERSION <= nItemVersion ) + { + sal_uInt16 nTmp; + rStrm.ReadUInt16( nTmp ); + nPropUnit = static_cast<MapUnit>(nTmp); + } + + Create_legacy_direct_set(rItem, nsize, nprop, nPropUnit); + } + + SvStream& Store(const SvxFontHeightItem& rItem, SvStream& rStrm, sal_uInt16 nItemVersion) + { + rStrm.WriteUInt16( rItem.GetHeight() ); + + if( FONTHEIGHT_UNIT_VERSION <= nItemVersion ) + rStrm.WriteUInt16( rItem.GetProp() ).WriteUInt16( static_cast<sal_uInt16>(rItem.GetPropUnit()) ); + else + { + // When exporting to the old versions the relative information is lost + // when there is no percentage + sal_uInt16 _nProp = rItem.GetProp(); + if( MapUnit::MapRelative != rItem.GetPropUnit() ) + _nProp = 100; + rStrm.WriteUInt16( _nProp ); + } + return rStrm; + } + } + + namespace SvxWeight + { + sal_uInt16 GetVersion(sal_uInt16) + { + return 0; + } + + void Create(SvxWeightItem& rItem, SvStream& rStrm, sal_uInt16) + { + sal_uInt8 nWeight(0); + rStrm.ReadUChar(nWeight); + rItem.SetValue(static_cast<FontWeight>(nWeight)); + } + + SvStream& Store(const SvxWeightItem& rItem, SvStream& rStrm, sal_uInt16) + { + rStrm.WriteUChar(rItem.GetValue()); + return rStrm; + } + } + + namespace SvxPosture + { + sal_uInt16 GetVersion(sal_uInt16) + { + return 0; + } + + void Create(SvxPostureItem& rItem, SvStream& rStrm, sal_uInt16) + { + sal_uInt8 nPosture(0); + rStrm.ReadUChar(nPosture); + rItem.SetValue(static_cast<FontItalic>(nPosture)); + } + + SvStream& Store(const SvxPostureItem& rItem, SvStream& rStrm, sal_uInt16) + { + rStrm.WriteUChar( rItem.GetValue() ); + return rStrm; + } + } + + namespace SvxTextLine // SvxUnderlineItem, SvxOverlineItem -> SvxTextLineItem + { + sal_uInt16 GetVersion(sal_uInt16) + { + return 0; + } + + void Create(SvxTextLineItem& rItem, SvStream& rStrm, sal_uInt16) + { + sal_uInt8 nState(0); + rStrm.ReadUChar(nState); + rItem.SetValue(static_cast<FontLineStyle>(nState)); + // GetColor() is *not* saved/loaded ?!? + } + + SvStream& Store(const SvxTextLineItem& rItem, SvStream& rStrm, sal_uInt16) + { + rStrm.WriteUChar(rItem.GetValue()); + // GetColor() is *not* saved/loaded ?!? + return rStrm; + } + } + + namespace SvxCrossedOut + { + sal_uInt16 GetVersion(sal_uInt16) + { + return 0; + } + + void Create(SvxCrossedOutItem& rItem, SvStream& rStrm, sal_uInt16) + { + sal_uInt8 eCross(0); + rStrm.ReadUChar(eCross); + rItem.SetValue(static_cast<FontStrikeout>(eCross)); + } + + SvStream& Store(const SvxCrossedOutItem& rItem, SvStream& rStrm, sal_uInt16) + { + rStrm.WriteUChar(rItem.GetValue()); + return rStrm; + } + } + + namespace SvxColor + { + sal_uInt16 GetVersion(sal_uInt16 nFileFormatVersion) + { + DBG_ASSERT( SOFFICE_FILEFORMAT_31==nFileFormatVersion || + SOFFICE_FILEFORMAT_40==nFileFormatVersion || + SOFFICE_FILEFORMAT_50==nFileFormatVersion, + "SvxColorItem: Is there a new file format? "); + return SOFFICE_FILEFORMAT_50 >= nFileFormatVersion ? VERSION_USEAUTOCOLOR : 0; + } + + void Create(SvxColorItem& rItem, SvStream& rStrm, sal_uInt16) + { + Color aColor(COL_AUTO); + tools::GenericTypeSerializer aSerializer(rStrm); + aSerializer.readColor(aColor); + rItem.SetValue(aColor); + } + + SvStream& Store(const SvxColorItem& rItem, SvStream& rStrm, sal_uInt16 nItemVersion) + { + tools::GenericTypeSerializer aSerializer(rStrm); + if( VERSION_USEAUTOCOLOR == nItemVersion && COL_AUTO == rItem.GetValue() ) + aSerializer.writeColor(COL_BLACK); + else + aSerializer.writeColor(rItem.GetValue()); + return rStrm; + } + } + + namespace SvxBox + { + sal_uInt16 GetVersion(sal_uInt16 nFileFormatVersion) + { + DBG_ASSERT( SOFFICE_FILEFORMAT_31==nFileFormatVersion || + SOFFICE_FILEFORMAT_40==nFileFormatVersion || + SOFFICE_FILEFORMAT_50==nFileFormatVersion, + "SvxBoxItem: Is there a new file format?" ); + return SOFFICE_FILEFORMAT_31==nFileFormatVersion || + SOFFICE_FILEFORMAT_40==nFileFormatVersion ? 0 : BOX_BORDER_STYLE_VERSION; + } + + /// Item version for saved border lines. The old version saves the line without style information. + const int BORDER_LINE_OLD_VERSION = 0; + /// Item version for saved border lies. The new version includes line style. + const int BORDER_LINE_WITH_STYLE_VERSION = 1; + + /// Creates a border line from a stream. + static ::editeng::SvxBorderLine CreateBorderLine(SvStream &stream, sal_uInt16 version) + { + sal_uInt16 nOutline, nInline, nDistance; + sal_uInt16 nStyle = css::table::BorderLineStyle::NONE; + Color aColor; + tools::GenericTypeSerializer aSerializer(stream); + aSerializer.readColor(aColor); + stream.ReadUInt16( nOutline ).ReadUInt16( nInline ).ReadUInt16( nDistance ); + + if (version >= BORDER_LINE_WITH_STYLE_VERSION) + stream.ReadUInt16( nStyle ); + + ::editeng::SvxBorderLine border(&aColor); + border.GuessLinesWidths(static_cast<SvxBorderLineStyle>(nStyle), nOutline, nInline, nDistance); + return border; + } + + /// Retrieves a BORDER_LINE_* version from a BOX_BORDER_* version. + static sal_uInt16 BorderLineVersionFromBoxVersion(sal_uInt16 boxVersion) + { + return (boxVersion >= BOX_BORDER_STYLE_VERSION)? BORDER_LINE_WITH_STYLE_VERSION : BORDER_LINE_OLD_VERSION; + } + + void Create(SvxBoxItem& rItem, SvStream& rStrm, sal_uInt16 nItemVersion) + { + sal_uInt16 nDistance(0); + rStrm.ReadUInt16( nDistance ); + SvxBoxItemLine aLineMap[4] = { SvxBoxItemLine::TOP, SvxBoxItemLine::LEFT, + SvxBoxItemLine::RIGHT, SvxBoxItemLine::BOTTOM }; + sal_Int8 cLine(0); + + while (rStrm.good()) + { + rStrm.ReadSChar( cLine ); + + if( cLine > 3 ) + break; + + ::editeng::SvxBorderLine aBorder = CreateBorderLine(rStrm, BorderLineVersionFromBoxVersion(nItemVersion)); + rItem.SetLine( &aBorder, aLineMap[cLine] ); + } + + if( nItemVersion >= BOX_4DISTS_VERSION && (cLine&0x10) != 0 ) + { + for(const SvxBoxItemLine & i : aLineMap) + { + sal_uInt16 nDist; + rStrm.ReadUInt16( nDist ); + rItem.SetDistance( nDist, i ); + } + } + else + { + rItem.SetAllDistances(nDistance); + } + } + + /// Store a border line to a stream. + static SvStream& StoreBorderLine(SvStream &stream, const ::editeng::SvxBorderLine &l, sal_uInt16 version) + { + tools::GenericTypeSerializer aSerializer(stream); + aSerializer.writeColor(l.GetColor()); + + stream.WriteUInt16( l.GetOutWidth() ) + .WriteUInt16( l.GetInWidth() ) + .WriteUInt16( l.GetDistance() ); + + if (version >= BORDER_LINE_WITH_STYLE_VERSION) + stream.WriteUInt16( static_cast<sal_uInt16>(l.GetBorderLineStyle()) ); + + return stream; + } + + SvStream& Store(const SvxBoxItem& rItem, SvStream& rStrm, sal_uInt16 nItemVersion) + { + rStrm.WriteUInt16( rItem.GetSmallestDistance() ); + const ::editeng::SvxBorderLine* pLine[ 4 ]; // top, left, right, bottom + pLine[ 0 ] = rItem.GetTop(); + pLine[ 1 ] = rItem.GetLeft(); + pLine[ 2 ] = rItem.GetRight(); + pLine[ 3 ] = rItem.GetBottom(); + + for( int i = 0; i < 4; i++ ) + { + const ::editeng::SvxBorderLine* l = pLine[ i ]; + if( l ) + { + rStrm.WriteSChar(i); + StoreBorderLine(rStrm, *l, BorderLineVersionFromBoxVersion(nItemVersion)); + } + } + sal_Int8 cLine = 4; + const sal_uInt16 nTopDist(rItem.GetDistance(SvxBoxItemLine::TOP)); + const sal_uInt16 nLeftDist(rItem.GetDistance(SvxBoxItemLine::LEFT)); + const sal_uInt16 nRightDist(rItem.GetDistance(SvxBoxItemLine::RIGHT)); + const sal_uInt16 nBottomDist(rItem.GetDistance(SvxBoxItemLine::BOTTOM)); + + if( nItemVersion >= BOX_4DISTS_VERSION && + !(nTopDist == nLeftDist && + nTopDist == nRightDist && + nTopDist == nBottomDist) ) + { + cLine |= 0x10; + } + + rStrm.WriteSChar( cLine ); + + if( nItemVersion >= BOX_4DISTS_VERSION && (cLine & 0x10) != 0 ) + { + rStrm.WriteUInt16( nTopDist ) + .WriteUInt16( nLeftDist ) + .WriteUInt16( nRightDist ) + .WriteUInt16( nBottomDist ); + } + + return rStrm; + } + } + + namespace SvxLine + { + sal_uInt16 GetVersion(sal_uInt16) + { + return 0; + } + + void Create(SvxLineItem& rItem, SvStream& rStrm, sal_uInt16) + { + short nOutline, nInline, nDistance; + Color aColor; + + tools::GenericTypeSerializer aSerializer(rStrm); + aSerializer.readColor(aColor); + rStrm.ReadInt16( nOutline ).ReadInt16( nInline ).ReadInt16( nDistance ); + if( nOutline ) + { + ::editeng::SvxBorderLine aLine( &aColor ); + aLine.GuessLinesWidths(SvxBorderLineStyle::NONE, nOutline, nInline, nDistance); + rItem.SetLine( &aLine ); + } + } + + SvStream& Store(const SvxLineItem& rItem, SvStream& rStrm, sal_uInt16) + { + const ::editeng::SvxBorderLine* pLine(rItem.GetLine()); + + if(nullptr != pLine) + { + tools::GenericTypeSerializer aSerializer(rStrm); + aSerializer.writeColor(pLine->GetColor()); + rStrm.WriteInt16( pLine->GetOutWidth() ) + .WriteInt16( pLine->GetInWidth() ) + .WriteInt16( pLine->GetDistance() ); + } + else + { + tools::GenericTypeSerializer aSerializer(rStrm); + aSerializer.writeColor(Color()); + rStrm.WriteInt16( 0 ).WriteInt16( 0 ).WriteInt16( 0 ); + } + + return rStrm; + } + } + + namespace SvxBrush + { + sal_uInt16 GetVersion(sal_uInt16) + { + return BRUSH_GRAPHIC_VERSION; + } + + const sal_uInt16 LOAD_GRAPHIC = (sal_uInt16(0x0001)); + const sal_uInt16 LOAD_LINK = (sal_uInt16(0x0002)); + const sal_uInt16 LOAD_FILTER = (sal_uInt16(0x0004)); + + void Create(SvxBrushItem& rItem, SvStream& rStrm, sal_uInt16 nItemVersion) + { + bool bTrans; + Color aTempColor; + Color aTempFillColor; + sal_Int8 nStyle; + + rStrm.ReadCharAsBool( bTrans ); + TypeSerializer aSerializer(rStrm); + aSerializer.readColor(aTempColor); + aSerializer.readColor(aTempFillColor); + rStrm.ReadSChar( nStyle ); + + switch ( nStyle ) + { + case 8: // BRUSH_25: + { + sal_uInt32 nRed = aTempColor.GetRed(); + sal_uInt32 nGreen = aTempColor.GetGreen(); + sal_uInt32 nBlue = aTempColor.GetBlue(); + nRed += static_cast<sal_uInt32>(aTempFillColor.GetRed())*2; + nGreen += static_cast<sal_uInt32>(aTempFillColor.GetGreen())*2; + nBlue += static_cast<sal_uInt32>(aTempFillColor.GetBlue())*2; + rItem.SetColor(Color( static_cast<sal_Int8>(nRed/3), static_cast<sal_Int8>(nGreen/3), static_cast<sal_Int8>(nBlue/3) )); + } + break; + + case 9: // BRUSH_50: + { + sal_uInt32 nRed = aTempColor.GetRed(); + sal_uInt32 nGreen = aTempColor.GetGreen(); + sal_uInt32 nBlue = aTempColor.GetBlue(); + nRed += static_cast<sal_uInt32>(aTempFillColor.GetRed()); + nGreen += static_cast<sal_uInt32>(aTempFillColor.GetGreen()); + nBlue += static_cast<sal_uInt32>(aTempFillColor.GetBlue()); + rItem.SetColor(Color( static_cast<sal_Int8>(nRed/2), static_cast<sal_Int8>(nGreen/2), static_cast<sal_Int8>(nBlue/2) )); + } + break; + + case 10: // BRUSH_75: + { + sal_uInt32 nRed = aTempColor.GetRed()*2; + sal_uInt32 nGreen = aTempColor.GetGreen()*2; + sal_uInt32 nBlue = aTempColor.GetBlue()*2; + nRed += static_cast<sal_uInt32>(aTempFillColor.GetRed()); + nGreen += static_cast<sal_uInt32>(aTempFillColor.GetGreen()); + nBlue += static_cast<sal_uInt32>(aTempFillColor.GetBlue()); + rItem.SetColor(Color( static_cast<sal_Int8>(nRed/3), static_cast<sal_Int8>(nGreen/3), static_cast<sal_Int8>(nBlue/3) )); + } + break; + + case 0: // BRUSH_NULL: + rItem.SetColor(COL_TRANSPARENT); + break; + + default: + rItem.SetColor(aTempColor); + } + + if ( nItemVersion < BRUSH_GRAPHIC_VERSION ) + return; + + sal_uInt16 nDoLoad = 0; + sal_Int8 nPos; + + rStrm.ReadUInt16( nDoLoad ); + + if ( nDoLoad & LOAD_GRAPHIC ) + { + Graphic aGraphic; + aSerializer.readGraphic(aGraphic); + rItem.SetGraphicObject(GraphicObject(aGraphic)); + + if( SVSTREAM_FILEFORMAT_ERROR == rStrm.GetError() ) + { + rStrm.ResetError(); + rStrm.SetError( ERRCODE_SVX_GRAPHIC_WRONG_FILEFORMAT.MakeWarning() ); + } + } + + if ( nDoLoad & LOAD_LINK ) + { + // UNICODE: rStrm >> aRel; + OUString aRel = rStrm.ReadUniOrByteString(rStrm.GetStreamCharSet()); + + // TODO/MBA: how can we get a BaseURL here?! + OSL_FAIL("No BaseURL!"); + OUString aAbs = INetURLObject::GetAbsURL( u"", aRel ); + DBG_ASSERT( !aAbs.isEmpty(), "Invalid URL!" ); + rItem.SetGraphicLink(aAbs); + } + + if ( nDoLoad & LOAD_FILTER ) + { + // UNICODE: rStrm >> maStrFilter; + rItem.SetGraphicFilter(rStrm.ReadUniOrByteString(rStrm.GetStreamCharSet())); + } + + rStrm.ReadSChar( nPos ); + + rItem.SetGraphicPos(static_cast<SvxGraphicPosition>(nPos)); + } + + SvStream& Store(const SvxBrushItem& rItem, SvStream& rStrm, sal_uInt16) + { + rStrm.WriteBool( false ); + TypeSerializer aSerializer(rStrm); + aSerializer.writeColor(rItem.GetColor()); + aSerializer.writeColor(rItem.GetColor()); + rStrm.WriteSChar( rItem.GetColor().IsTransparent() ? 0 : 1 ); //BRUSH_NULL : BRUSH_SOLID + + sal_uInt16 nDoLoad = 0; + const GraphicObject* pGraphicObject(rItem.GetGraphicObject()); + + if (nullptr != pGraphicObject && rItem.GetGraphicLink().isEmpty()) + nDoLoad |= LOAD_GRAPHIC; + if ( !rItem.GetGraphicLink().isEmpty() ) + nDoLoad |= LOAD_LINK; + if ( !rItem.GetGraphicFilter().isEmpty() ) + nDoLoad |= LOAD_FILTER; + rStrm.WriteUInt16( nDoLoad ); + + if (nullptr != pGraphicObject && rItem.GetGraphicLink().isEmpty()) + { + aSerializer.writeGraphic(pGraphicObject->GetGraphic()); + } + if ( !rItem.GetGraphicLink().isEmpty() ) + { + OSL_FAIL("No BaseURL!"); + // TODO/MBA: how to get a BaseURL?! + OUString aRel = INetURLObject::GetRelURL( u"", rItem.GetGraphicLink() ); + // UNICODE: rStrm << aRel; + rStrm.WriteUniOrByteString(aRel, rStrm.GetStreamCharSet()); + } + if ( !rItem.GetGraphicFilter().isEmpty() ) + { + // UNICODE: rStrm << rItem.GetGraphicFilter(); + rStrm.WriteUniOrByteString(rItem.GetGraphicFilter(), rStrm.GetStreamCharSet()); + } + rStrm.WriteSChar( rItem.GetGraphicPos() ); + return rStrm; + } + } + + namespace SvxAdjust + { + sal_uInt16 GetVersion(sal_uInt16 nFileFormatVersion) + { + return (nFileFormatVersion == SOFFICE_FILEFORMAT_31) + ? 0 : ADJUST_LASTBLOCK_VERSION; + } + + void Create(SvxAdjustItem& rItem, SvStream& rStrm, sal_uInt16 nItemVersion) + { + char eAdjustment; + rStrm.ReadChar(eAdjustment); + rItem.SetAdjust(static_cast<::SvxAdjust>(eAdjustment)); + + if( nItemVersion >= ADJUST_LASTBLOCK_VERSION ) + { + sal_Int8 nFlags; + rStrm.ReadSChar( nFlags ); + rItem.SetAsFlags(nFlags); + } + } + + SvStream& Store(const SvxAdjustItem& rItem, SvStream& rStrm, sal_uInt16 nItemVersion) + { + rStrm.WriteChar( static_cast<char>(rItem.GetAdjust()) ); + if ( nItemVersion >= ADJUST_LASTBLOCK_VERSION ) + { + const sal_Int8 nFlags(rItem.GetAsFlags()); + rStrm.WriteSChar( nFlags ); + } + return rStrm; + } + } + + namespace SvxHorJustify + { + sal_uInt16 GetVersion(sal_uInt16) + { + return 0; + } + + void Create(SvxHorJustifyItem& rItem, SvStream& rStrm, sal_uInt16) + { + sal_uInt16 nVal(0); + rStrm.ReadUInt16( nVal ); + rItem.SetValue(static_cast<::SvxCellHorJustify>(nVal)); + } + + SvStream& Store(const SvxHorJustifyItem& rItem, SvStream& rStrm, sal_uInt16) + { + rStrm.WriteUInt16( static_cast<sal_uInt16>(rItem.GetValue()) ); + return rStrm; + } + } + + namespace SvxVerJustify + { + sal_uInt16 GetVersion(sal_uInt16) + { + return 0; + } + + void Create(SvxVerJustifyItem& rItem, SvStream& rStrm, sal_uInt16) + { + sal_uInt16 nVal(0); + rStrm.ReadUInt16( nVal ); + rItem.SetValue(static_cast<::SvxCellVerJustify>(nVal)); + } + + SvStream& Store(const SvxVerJustifyItem& rItem, SvStream& rStrm, sal_uInt16) + { + rStrm.WriteUInt16( static_cast<sal_uInt16>(rItem.GetValue()) ); + return rStrm; + } + } + + namespace SvxFrameDirection + { + sal_uInt16 GetVersion(sal_uInt16 nFileFormatVersion) + { + return SOFFICE_FILEFORMAT_50 > nFileFormatVersion ? USHRT_MAX : 0; + } + + void Create(SvxFrameDirectionItem& rItem, SvStream& rStrm, sal_uInt16) + { + sal_uInt16 nVal(0); + rStrm.ReadUInt16( nVal ); + rItem.SetValue(static_cast<::SvxFrameDirection>(nVal)); + } + + SvStream& Store(const SvxFrameDirectionItem& rItem, SvStream& rStrm, sal_uInt16) + { + rStrm.WriteUInt16( static_cast<sal_uInt16>(rItem.GetValue()) ); + return rStrm; + } + } + + namespace SvxFormatBreak + { + sal_uInt16 GetVersion(sal_uInt16 nFileFormatVersion) + { + DBG_ASSERT( SOFFICE_FILEFORMAT_31==nFileFormatVersion || + SOFFICE_FILEFORMAT_40==nFileFormatVersion || + SOFFICE_FILEFORMAT_50==nFileFormatVersion, + "SvxFormatBreakItem: Is there a new file format? "); + return SOFFICE_FILEFORMAT_31==nFileFormatVersion || + SOFFICE_FILEFORMAT_40==nFileFormatVersion ? 0 : FMTBREAK_NOAUTO; + } + + void Create(SvxFormatBreakItem& rItem, SvStream& rStrm, sal_uInt16 nItemVersion) + { + sal_Int8 eBreak, bDummy; + rStrm.ReadSChar( eBreak ); + if( FMTBREAK_NOAUTO > nItemVersion ) + rStrm.ReadSChar( bDummy ); + rItem.SetValue(static_cast<::SvxBreak>(eBreak)); + } + + SvStream& Store(const SvxFormatBreakItem& rItem, SvStream& rStrm, sal_uInt16 nItemVersion) + { + rStrm.WriteSChar( rItem.GetEnumValue() ); + if( FMTBREAK_NOAUTO > nItemVersion ) + rStrm.WriteSChar( 0x01 ); + return rStrm; + } + } + + namespace SvxFormatKeep + { + sal_uInt16 GetVersion(sal_uInt16) + { + return 0; + } + + void Create(SvxFormatKeepItem& rItem, SvStream& rStrm, sal_uInt16) + { + // derived from SfxBoolItem, but that uses + // rStream.ReadCharAsBool( tmp ); + sal_Int8 bIsKeep; + rStrm.ReadSChar( bIsKeep ); + rItem.SetValue(static_cast<bool>(bIsKeep)); + } + + SvStream& Store(const SvxFormatKeepItem& rItem, SvStream& rStrm, sal_uInt16) + { + // derived from SfxBoolItem, but that uses + // rStream.WriteBool( m_bValue ); // not bool for serialization! + rStrm.WriteSChar( static_cast<sal_Int8>(rItem.GetValue()) ); + return rStrm; + } + } + + namespace SvxShadow + { + sal_uInt16 GetVersion(sal_uInt16) + { + return 0; + } + + void Create(SvxShadowItem& rItem, SvStream& rStrm, sal_uInt16) + { + sal_Int8 cLoc; + sal_uInt16 _nWidth; + bool bTrans; + Color aColor; + Color aFillColor; + sal_Int8 nStyle; + rStrm.ReadSChar( cLoc ).ReadUInt16( _nWidth ).ReadCharAsBool( bTrans ); + tools::GenericTypeSerializer aSerializer(rStrm); + aSerializer.readColor(aColor); + aSerializer.readColor(aFillColor); + rStrm.ReadSChar(nStyle); + aColor.SetAlpha(bTrans ? 0 : 255); + + rItem.SetLocation(static_cast<SvxShadowLocation>(cLoc)); + rItem.SetWidth(_nWidth); + rItem.SetColor(aColor); + } + + SvStream& Store(const SvxShadowItem& rItem, SvStream& rStrm, sal_uInt16) + { + rStrm.WriteSChar( static_cast<sal_uInt8>(rItem.GetLocation()) ) + .WriteUInt16( rItem.GetWidth() ) + .WriteBool( rItem.GetColor().IsTransparent() ); + tools::GenericTypeSerializer aSerializer(rStrm); + aSerializer.writeColor(rItem.GetColor()); + aSerializer.writeColor(rItem.GetColor()); + rStrm.WriteSChar( rItem.GetColor().IsTransparent() ? 0 : 1 ); //BRUSH_NULL : BRUSH_SOLID + return rStrm; + } + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/editeng/source/items/numitem.cxx b/editeng/source/items/numitem.cxx new file mode 100644 index 000000000..cbbd7efb9 --- /dev/null +++ b/editeng/source/items/numitem.cxx @@ -0,0 +1,1129 @@ +/* -*- 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 <algorithm> + +#include <editeng/numitem.hxx> + +#include <com/sun/star/text/VertOrientation.hpp> +#include <comphelper/propertyvalue.hxx> +#include <editeng/brushitem.hxx> +#include <rtl/ustrbuf.hxx> +#include <vcl/font.hxx> +#include <vcl/settings.hxx> +#include <editeng/editids.hrc> +#include <editeng/numdef.hxx> +#include <vcl/graph.hxx> +#include <vcl/outdev.hxx> +#include <vcl/svapp.hxx> +#include <com/sun/star/text/XNumberingFormatter.hpp> +#include <com/sun/star/text/DefaultNumberingProvider.hpp> +#include <com/sun/star/text/XDefaultNumberingProvider.hpp> +#include <com/sun/star/style/NumberingType.hpp> +#include <com/sun/star/lang/IllegalArgumentException.hpp> +#include <com/sun/star/beans/PropertyValue.hpp> +#include <comphelper/fileformat.h> +#include <comphelper/processfactory.hxx> +#include <tools/mapunit.hxx> +#include <tools/stream.hxx> +#include <tools/debug.hxx> +#include <tools/GenericTypeSerializer.hxx> +#include <unotools/configmgr.hxx> +#include <libxml/xmlwriter.h> +#include <editeng/unonrule.hxx> +#include <sal/log.hxx> +#include <i18nlangtag/languagetag.hxx> +#include <editeng/legacyitem.hxx> + +constexpr sal_Int32 DEF_WRITER_LSPACE = 500; //Standard Indentation +constexpr sal_Int32 DEF_DRAW_LSPACE = 800; //Standard Indentation + +constexpr sal_uInt16 NUMITEM_VERSION_03 = 0x03; +constexpr sal_uInt16 NUMITEM_VERSION_04 = 0x04; + +using namespace ::com::sun::star; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::text; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::style; + +sal_Int32 SvxNumberType::nRefCount = 0; +css::uno::Reference<css::text::XNumberingFormatter> SvxNumberType::xFormatter; +static void lcl_getFormatter(css::uno::Reference<css::text::XNumberingFormatter>& _xFormatter) +{ + if(_xFormatter.is()) + return; + + try + { + Reference<XComponentContext> xContext( ::comphelper::getProcessComponentContext() ); + Reference<XDefaultNumberingProvider> xRet = text::DefaultNumberingProvider::create(xContext); + _xFormatter.set(xRet, UNO_QUERY); + } + catch(const Exception&) + { + SAL_WARN("editeng", "service missing: \"com.sun.star.text.DefaultNumberingProvider\""); + } +} + +SvxNumberType::SvxNumberType(SvxNumType nType) : + nNumType(nType), + bShowSymbol(true) +{ + nRefCount++; +} + +SvxNumberType::SvxNumberType(const SvxNumberType& rType) : + nNumType(rType.nNumType), + bShowSymbol(rType.bShowSymbol) +{ + nRefCount++; +} + +SvxNumberType::~SvxNumberType() +{ + if(!--nRefCount) + xFormatter = nullptr; +} + +OUString SvxNumberType::GetNumStr( sal_Int32 nNo ) const +{ + LanguageTag aLang = utl::ConfigManager::IsFuzzing() ? + LanguageTag("en-US") : + Application::GetSettings().GetLanguageTag(); + return GetNumStr( nNo, aLang.getLocale() ); +} + +OUString SvxNumberType::GetNumStr( sal_Int32 nNo, const css::lang::Locale& rLocale ) const +{ + lcl_getFormatter(xFormatter); + if(!xFormatter.is()) + return OUString(); + + if(bShowSymbol) + { + switch(nNumType) + { + case NumberingType::CHAR_SPECIAL: + case NumberingType::BITMAP: + break; + default: + { + // '0' allowed for ARABIC numberings + if(NumberingType::ARABIC == nNumType && 0 == nNo ) + return OUString('0'); + else + { + static constexpr OUStringLiteral sNumberingType = u"NumberingType"; + static constexpr OUStringLiteral sValue = u"Value"; + Sequence< PropertyValue > aProperties + { + comphelper::makePropertyValue(sNumberingType, static_cast<sal_uInt16>(nNumType)), + comphelper::makePropertyValue(sValue, nNo) + }; + + try + { + return xFormatter->makeNumberingString( aProperties, rLocale ); + } + catch(const Exception&) + { + } + } + } + } + } + return OUString(); +} + +void SvxNumberType::dumpAsXml( xmlTextWriterPtr pWriter ) const +{ + (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SvxNumberType")); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("NumType"), BAD_CAST(OString::number(nNumType).getStr())); + (void)xmlTextWriterEndElement(pWriter); +} + +SvxNumberFormat::SvxNumberFormat( SvxNumType eType ) + : SvxNumberType(eType), + eNumAdjust(SvxAdjust::Left), + nInclUpperLevels(1), + nStart(1), + cBullet(SVX_DEF_BULLET), + nBulletRelSize(100), + nBulletColor(COL_BLACK), + mePositionAndSpaceMode( LABEL_WIDTH_AND_POSITION ), + nFirstLineOffset(0), + nAbsLSpace(0), + nCharTextDistance(0), + meLabelFollowedBy( LISTTAB ), + mnListtabPos( 0 ), + mnFirstLineIndent( 0 ), + mnIndentAt( 0 ), + eVertOrient(text::VertOrientation::NONE) +{ +} + +SvxNumberFormat::SvxNumberFormat(const SvxNumberFormat& rFormat) : + SvxNumberType(rFormat), + mePositionAndSpaceMode( rFormat.mePositionAndSpaceMode ) +{ + *this = rFormat; +} + +SvxNumberFormat::SvxNumberFormat( SvStream &rStream ) + : nStart(0) + , nBulletRelSize(100) + , nFirstLineOffset(0) + , nAbsLSpace(0) + , nCharTextDistance(0) +{ + sal_uInt16 nTmp16(0); + sal_Int32 nTmp32(0); + rStream.ReadUInt16( nTmp16 ); // Version number + + rStream.ReadUInt16( nTmp16 ); SetNumberingType( static_cast<SvxNumType>(nTmp16) ); + rStream.ReadUInt16( nTmp16 ); eNumAdjust = static_cast<SvxAdjust>(nTmp16); + rStream.ReadUInt16( nTmp16 ); nInclUpperLevels = nTmp16; + rStream.ReadUInt16( nStart ); + rStream.ReadUInt16( nTmp16 ); cBullet = static_cast<sal_Unicode>(nTmp16); + + sal_Int16 temp = 0; + rStream.ReadInt16( temp ); + nFirstLineOffset = temp; + temp = 0; + rStream.ReadInt16( temp ); + nAbsLSpace = temp; + rStream.SeekRel(2); //skip old now unused nLSpace; + + rStream.ReadInt16( nCharTextDistance ); + + sPrefix = rStream.ReadUniOrByteString( rStream.GetStreamCharSet() ); + sSuffix = rStream.ReadUniOrByteString( rStream.GetStreamCharSet() ); + sCharStyleName = rStream.ReadUniOrByteString( rStream.GetStreamCharSet() ); + + sal_uInt16 hasGraphicBrush = 0; + rStream.ReadUInt16( hasGraphicBrush ); + if ( hasGraphicBrush ) + { + pGraphicBrush.reset(new SvxBrushItem(SID_ATTR_BRUSH)); + legacy::SvxBrush::Create(*pGraphicBrush, rStream, BRUSH_GRAPHIC_VERSION); + } + else pGraphicBrush = nullptr; + rStream.ReadUInt16( nTmp16 ); eVertOrient = nTmp16; + + sal_uInt16 hasBulletFont = 0; + rStream.ReadUInt16( hasBulletFont ); + if ( hasBulletFont ) + { + pBulletFont.emplace(); + ReadFont( rStream, *pBulletFont ); + } + else pBulletFont.reset(); + + tools::GenericTypeSerializer aSerializer(rStream); + aSerializer.readSize(aGraphicSize); + aSerializer.readColor(nBulletColor); + + rStream.ReadUInt16( nBulletRelSize ); + rStream.ReadUInt16( nTmp16 ); SetShowSymbol( nTmp16 != 0 ); + + rStream.ReadUInt16( nTmp16 ); mePositionAndSpaceMode = static_cast<SvxNumPositionAndSpaceMode>(nTmp16); + rStream.ReadUInt16( nTmp16 ); meLabelFollowedBy = static_cast<LabelFollowedBy>(nTmp16); + rStream.ReadInt32( nTmp32 ); mnListtabPos = nTmp32; + rStream.ReadInt32( nTmp32 ); mnFirstLineIndent = nTmp32; + rStream.ReadInt32( nTmp32 ); mnIndentAt = nTmp32; +} + +SvxNumberFormat::~SvxNumberFormat() +{ +} + +void SvxNumberFormat::Store(SvStream &rStream, FontToSubsFontConverter pConverter) +{ + if(pConverter && pBulletFont) + { + cBullet = ConvertFontToSubsFontChar(pConverter, cBullet); + OUString sFontName = GetFontToSubsFontName(pConverter); + pBulletFont->SetFamilyName(sFontName); + } + + tools::GenericTypeSerializer aSerializer(rStream); + + rStream.WriteUInt16( NUMITEM_VERSION_04 ); + + rStream.WriteUInt16( GetNumberingType() ); + rStream.WriteUInt16( static_cast<sal_uInt16>(eNumAdjust) ); + rStream.WriteUInt16( nInclUpperLevels ); + rStream.WriteUInt16( nStart ); + rStream.WriteUInt16( cBullet ); + + rStream.WriteInt16( + sal_Int16(std::clamp<sal_Int32>(nFirstLineOffset, SAL_MIN_INT16, SAL_MAX_INT16)) ); + //TODO: better way to handle out-of-bounds value? + rStream.WriteInt16( + sal_Int16(std::clamp<sal_Int32>(nAbsLSpace, SAL_MIN_INT16, SAL_MAX_INT16)) ); + //TODO: better way to handle out-of-bounds value? + rStream.WriteInt16( 0 ); // write a dummy for old now unused nLSpace + + rStream.WriteInt16( nCharTextDistance ); + rtl_TextEncoding eEnc = osl_getThreadTextEncoding(); + rStream.WriteUniOrByteString(sPrefix, eEnc); + rStream.WriteUniOrByteString(sSuffix, eEnc); + rStream.WriteUniOrByteString(sCharStyleName, eEnc); + if(pGraphicBrush) + { + rStream.WriteUInt16( 1 ); + + // in SD or SI force bullet itself to be stored, + // for that purpose throw away link when link and graphic + // are present, so Brush save is forced + if(!pGraphicBrush->GetGraphicLink().isEmpty() && pGraphicBrush->GetGraphic()) + { + pGraphicBrush->SetGraphicLink(""); + } + + legacy::SvxBrush::Store(*pGraphicBrush, rStream, BRUSH_GRAPHIC_VERSION); + } + else + rStream.WriteUInt16( 0 ); + + rStream.WriteUInt16( eVertOrient ); + if(pBulletFont) + { + rStream.WriteUInt16( 1 ); + WriteFont( rStream, *pBulletFont ); + } + else + rStream.WriteUInt16( 0 ); + + aSerializer.writeSize(aGraphicSize); + + Color nTempColor = nBulletColor; + if(COL_AUTO == nBulletColor) + nTempColor = COL_BLACK; + + aSerializer.writeColor(nTempColor); + rStream.WriteUInt16( nBulletRelSize ); + rStream.WriteUInt16( sal_uInt16(IsShowSymbol()) ); + + rStream.WriteUInt16( mePositionAndSpaceMode ); + rStream.WriteUInt16( meLabelFollowedBy ); + rStream.WriteInt32( mnListtabPos ); + rStream.WriteInt32( mnFirstLineIndent ); + rStream.WriteInt32( mnIndentAt ); +} + +SvxNumberFormat& SvxNumberFormat::operator=( const SvxNumberFormat& rFormat ) +{ + if (& rFormat == this) { return *this; } + + SvxNumberType::SetNumberingType(rFormat.GetNumberingType()); + eNumAdjust = rFormat.eNumAdjust ; + nInclUpperLevels = rFormat.nInclUpperLevels ; + nStart = rFormat.nStart ; + cBullet = rFormat.cBullet ; + mePositionAndSpaceMode = rFormat.mePositionAndSpaceMode; + nFirstLineOffset = rFormat.nFirstLineOffset; + nAbsLSpace = rFormat.nAbsLSpace ; + nCharTextDistance = rFormat.nCharTextDistance ; + meLabelFollowedBy = rFormat.meLabelFollowedBy; + mnListtabPos = rFormat.mnListtabPos; + mnFirstLineIndent = rFormat.mnFirstLineIndent; + mnIndentAt = rFormat.mnIndentAt; + eVertOrient = rFormat.eVertOrient; + sPrefix = rFormat.sPrefix; + sSuffix = rFormat.sSuffix; + sListFormat = rFormat.sListFormat; + aGraphicSize = rFormat.aGraphicSize ; + nBulletColor = rFormat.nBulletColor ; + nBulletRelSize = rFormat.nBulletRelSize; + SetShowSymbol(rFormat.IsShowSymbol()); + sCharStyleName = rFormat.sCharStyleName; + pGraphicBrush.reset(); + if(rFormat.pGraphicBrush) + { + pGraphicBrush.reset( new SvxBrushItem(*rFormat.pGraphicBrush) ); + } + pBulletFont.reset(); + if(rFormat.pBulletFont) + pBulletFont = *rFormat.pBulletFont; + return *this; +} + +bool SvxNumberFormat::operator==( const SvxNumberFormat& rFormat) const +{ + if( GetNumberingType() != rFormat.GetNumberingType() || + eNumAdjust != rFormat.eNumAdjust || + nInclUpperLevels != rFormat.nInclUpperLevels || + nStart != rFormat.nStart || + cBullet != rFormat.cBullet || + mePositionAndSpaceMode != rFormat.mePositionAndSpaceMode || + nFirstLineOffset != rFormat.nFirstLineOffset || + nAbsLSpace != rFormat.nAbsLSpace || + nCharTextDistance != rFormat.nCharTextDistance || + meLabelFollowedBy != rFormat.meLabelFollowedBy || + mnListtabPos != rFormat.mnListtabPos || + mnFirstLineIndent != rFormat.mnFirstLineIndent || + mnIndentAt != rFormat.mnIndentAt || + eVertOrient != rFormat.eVertOrient || + sPrefix != rFormat.sPrefix || + sSuffix != rFormat.sSuffix || + sListFormat != rFormat.sListFormat || + aGraphicSize != rFormat.aGraphicSize || + nBulletColor != rFormat.nBulletColor || + nBulletRelSize != rFormat.nBulletRelSize || + IsShowSymbol() != rFormat.IsShowSymbol() || + sCharStyleName != rFormat.sCharStyleName + ) + return false; + if ( + (pGraphicBrush && !rFormat.pGraphicBrush) || + (!pGraphicBrush && rFormat.pGraphicBrush) || + (pGraphicBrush && *pGraphicBrush != *rFormat.pGraphicBrush) + ) + { + return false; + } + if ( + (pBulletFont && !rFormat.pBulletFont) || + (!pBulletFont && rFormat.pBulletFont) || + (pBulletFont && *pBulletFont != *rFormat.pBulletFont) + ) + { + return false; + } + return true; +} + +void SvxNumberFormat::SetGraphicBrush( const SvxBrushItem* pBrushItem, + const Size* pSize, const sal_Int16* pOrient) +{ + if (!pBrushItem) + pGraphicBrush.reset(); + else if ( !pGraphicBrush || (*pBrushItem != *pGraphicBrush) ) + pGraphicBrush.reset(pBrushItem->Clone()); + + if(pOrient) + eVertOrient = *pOrient; + else + eVertOrient = text::VertOrientation::NONE; + if(pSize) + aGraphicSize = *pSize; + else + { + aGraphicSize.setWidth(0); + aGraphicSize.setHeight(0); + } +} + +void SvxNumberFormat::SetGraphic( const OUString& rName ) +{ + if( pGraphicBrush && pGraphicBrush->GetGraphicLink() == rName ) + return ; + + pGraphicBrush.reset( new SvxBrushItem( rName, "", GPOS_AREA, 0 ) ); + if( eVertOrient == text::VertOrientation::NONE ) + eVertOrient = text::VertOrientation::TOP; + + aGraphicSize.setWidth(0); + aGraphicSize.setHeight(0); +} + +sal_Int16 SvxNumberFormat::GetVertOrient() const +{ + return eVertOrient; +} + +void SvxNumberFormat::SetBulletFont(const vcl::Font* pFont) +{ + if (pFont) + pBulletFont = *pFont; + else + pBulletFont.reset(); +} + +void SvxNumberFormat::SetPositionAndSpaceMode( SvxNumPositionAndSpaceMode ePositionAndSpaceMode ) +{ + mePositionAndSpaceMode = ePositionAndSpaceMode; +} + +sal_Int32 SvxNumberFormat::GetAbsLSpace() const +{ + return mePositionAndSpaceMode == LABEL_WIDTH_AND_POSITION + ? nAbsLSpace + : static_cast<sal_Int32>( GetFirstLineIndent() + GetIndentAt() ); +} +sal_Int32 SvxNumberFormat::GetFirstLineOffset() const +{ + return mePositionAndSpaceMode == LABEL_WIDTH_AND_POSITION + ? nFirstLineOffset + : static_cast<sal_Int32>( GetFirstLineIndent() ); +} +short SvxNumberFormat::GetCharTextDistance() const +{ + return mePositionAndSpaceMode == LABEL_WIDTH_AND_POSITION ? nCharTextDistance : 0; +} + +void SvxNumberFormat::SetLabelFollowedBy( const LabelFollowedBy eLabelFollowedBy ) +{ + meLabelFollowedBy = eLabelFollowedBy; +} + +OUString SvxNumberFormat::GetLabelFollowedByAsString() const +{ + switch (meLabelFollowedBy) + { + case LISTTAB: + return "\t"; + case SPACE: + return " "; + case NEWLINE: + return "\n"; + case NOTHING: + // intentionally left blank. + return OUString(); + default: + SAL_WARN("editeng", "Unknown SvxNumberFormat::GetLabelFollowedBy() return value"); + assert(false); + } + return OUString(); +} + +void SvxNumberFormat::SetListtabPos( const tools::Long nListtabPos ) +{ + mnListtabPos = nListtabPos; +} +void SvxNumberFormat::SetFirstLineIndent( const tools::Long nFirstLineIndent ) +{ + mnFirstLineIndent = nFirstLineIndent; +} +void SvxNumberFormat::SetIndentAt( const tools::Long nIndentAt ) +{ + mnIndentAt = nIndentAt; +} + +Size SvxNumberFormat::GetGraphicSizeMM100(const Graphic* pGraphic) +{ + const MapMode aMapMM100( MapUnit::Map100thMM ); + const Size& rSize = pGraphic->GetPrefSize(); + Size aRetSize; + if ( pGraphic->GetPrefMapMode().GetMapUnit() == MapUnit::MapPixel ) + { + OutputDevice* pOutDev = Application::GetDefaultDevice(); + MapMode aOldMap( pOutDev->GetMapMode() ); + pOutDev->SetMapMode( aMapMM100 ); + aRetSize = pOutDev->PixelToLogic( rSize ); + pOutDev->SetMapMode( aOldMap ); + } + else + aRetSize = OutputDevice::LogicToLogic( rSize, pGraphic->GetPrefMapMode(), aMapMM100 ); + return aRetSize; +} + +OUString SvxNumberFormat::CreateRomanString( sal_Int32 nNo, bool bUpper ) +{ + OUStringBuffer sRet; + + constexpr char romans[][13] = {"M", "CM", "D", "CD", "C", "XC", "L", "XL", "X", "IX", "V", "IV", "I"}; + constexpr sal_Int32 values[] = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1}; + + for (size_t i = 0; i < std::size(romans); ++i) + { + while(nNo - values[i] >= 0) + { + sRet.appendAscii(romans[i]); + nNo -= values[i]; + } + } + + return bUpper ? sRet.makeStringAndClear() + : sRet.makeStringAndClear().toAsciiLowerCase(); +} + +void SvxNumberFormat::SetListFormat(const OUString& rPrefix, const OUString& rSuffix, int nLevel) +{ + sPrefix = rPrefix; + sSuffix = rSuffix; + + // Generate list format + sListFormat = std::make_optional(sPrefix); + + for (int i = 1; i <= nInclUpperLevels; i++) + { + int nLevelId = nLevel - nInclUpperLevels + i; + if (nLevelId < 0) + // There can be cases with current level 1, but request to show 10 upper levels. Trim it + continue; + + *sListFormat += "%"; + *sListFormat += OUString::number(nLevelId + 1); + *sListFormat += "%"; + if (i != nInclUpperLevels) + *sListFormat += "."; // Default separator for older ODT + } + + *sListFormat += sSuffix; +} + +void SvxNumberFormat::SetListFormat(std::optional<OUString> oSet) +{ + sPrefix.clear(); + sSuffix.clear(); + + if (!oSet.has_value()) + { + return; + } + + sListFormat = oSet; + + // For backward compatibility and UI we should create something looking like + // a prefix, suffix and included levels also. This is not possible in general case + // since level format string is much more flexible. But for most cases is okay + sal_Int32 nFirstReplacement = sListFormat->indexOf('%'); + sal_Int32 nLastReplacement = sListFormat->lastIndexOf('%') + 1; + if (nFirstReplacement > 0) + // Everything before first '%' will be prefix + sPrefix = sListFormat->copy(0, nFirstReplacement); + if (nLastReplacement >= 0 && nLastReplacement < sListFormat->getLength()) + // Everything beyond last '%' is a suffix + sSuffix = sListFormat->copy(nLastReplacement); + + sal_uInt8 nPercents = 0; + for (sal_Int32 i = 0; i < sListFormat->getLength(); i++) + { + if ((*sListFormat)[i] == '%') + nPercents++; + } + nInclUpperLevels = nPercents/2; + if (nInclUpperLevels < 1) + { + // There should be always at least one level. This will be not required + // in future (when we get rid of prefix/suffix), but nowadays there + // are too many conversions "list format" <-> "prefix/suffix/inclUpperLevel" + nInclUpperLevels = 1; + } +} + +OUString SvxNumberFormat::GetListFormat(bool bIncludePrefixSuffix /*= true*/) const +{ + assert(sListFormat.has_value()); + + if (bIncludePrefixSuffix) + return *sListFormat; + + // Strip prefix & suffix from string + return sListFormat->copy(sPrefix.getLength(), sListFormat->getLength() - sPrefix.getLength() - sSuffix.getLength()); +} + +OUString SvxNumberFormat::GetCharFormatName()const +{ + return sCharStyleName; +} + +sal_Int32 SvxNumRule::nRefCount = 0; +static SvxNumberFormat* pStdNumFmt = nullptr; +static SvxNumberFormat* pStdOutlineNumFmt = nullptr; +SvxNumRule::SvxNumRule( SvxNumRuleFlags nFeatures, + sal_uInt16 nLevels, + bool bCont, + SvxNumRuleType eType, + SvxNumberFormat::SvxNumPositionAndSpaceMode + eDefaultNumberFormatPositionAndSpaceMode ) + : nLevelCount(nLevels), + nFeatureFlags(nFeatures), + eNumberingType(eType), + bContinuousNumbering(bCont) +{ + ++nRefCount; + for(sal_uInt16 i = 0; i < SVX_MAX_NUM; i++) + { + if(i < nLevels) + { + aFmts[i].reset( new SvxNumberFormat(SVX_NUM_CHARS_UPPER_LETTER) ); + // It is a distinction between writer and draw + if(nFeatures & SvxNumRuleFlags::CONTINUOUS) + { + if ( eDefaultNumberFormatPositionAndSpaceMode == + SvxNumberFormat::LABEL_WIDTH_AND_POSITION ) + { + aFmts[i]->SetAbsLSpace(o3tl::toTwips(DEF_WRITER_LSPACE * (i+1), o3tl::Length::mm100)); + aFmts[i]->SetFirstLineOffset(o3tl::toTwips(-DEF_WRITER_LSPACE, o3tl::Length::mm100)); + } + else if ( eDefaultNumberFormatPositionAndSpaceMode == + SvxNumberFormat::LABEL_ALIGNMENT ) + { + // first line indent of general numbering in inch: -0,25 inch + constexpr tools::Long cFirstLineIndent = o3tl::toTwips(-0.25, o3tl::Length::in); + // indent values of general numbering in inch: + // 0,5 0,75 1,0 1,25 1,5 + // 1,75 2,0 2,25 2,5 2,75 + constexpr tools::Long cIndentAt = o3tl::toTwips(0.25, o3tl::Length::in); + aFmts[i]->SetPositionAndSpaceMode( SvxNumberFormat::LABEL_ALIGNMENT ); + aFmts[i]->SetLabelFollowedBy( SvxNumberFormat::LISTTAB ); + aFmts[i]->SetListtabPos( cIndentAt * (i+2) ); + aFmts[i]->SetFirstLineIndent( cFirstLineIndent ); + aFmts[i]->SetIndentAt( cIndentAt * (i+2) ); + } + } + else + { + aFmts[i]->SetAbsLSpace( DEF_DRAW_LSPACE * i ); + } + } + else + aFmts[i] = nullptr; + aFmtsSet[i] = false; + } +} + +SvxNumRule::SvxNumRule(const SvxNumRule& rCopy) +{ + ++nRefCount; + nLevelCount = rCopy.nLevelCount ; + nFeatureFlags = rCopy.nFeatureFlags ; + bContinuousNumbering = rCopy.bContinuousNumbering; + eNumberingType = rCopy.eNumberingType; + for(sal_uInt16 i = 0; i < SVX_MAX_NUM; i++) + { + if(rCopy.aFmts[i]) + aFmts[i].reset( new SvxNumberFormat(*rCopy.aFmts[i]) ); + else + aFmts[i].reset(); + aFmtsSet[i] = rCopy.aFmtsSet[i]; + } +} + +SvxNumRule::SvxNumRule(SvxNumRule&& rCopy) noexcept +{ + ++nRefCount; + nLevelCount = rCopy.nLevelCount ; + nFeatureFlags = rCopy.nFeatureFlags ; + bContinuousNumbering = rCopy.bContinuousNumbering; + eNumberingType = rCopy.eNumberingType; + for(sal_uInt16 i = 0; i < SVX_MAX_NUM; i++) + { + if(rCopy.aFmts[i]) + aFmts[i] = std::move(rCopy.aFmts[i]); + aFmtsSet[i] = rCopy.aFmtsSet[i]; + } +} + +SvxNumRule::SvxNumRule( SvStream &rStream ) + : nLevelCount(0) +{ + sal_uInt16 nTmp16(0); + rStream.ReadUInt16( nTmp16 ); // NUM_ITEM_VERSION + rStream.ReadUInt16( nLevelCount ); + + if (nLevelCount > SVX_MAX_NUM) + { + SAL_WARN("editeng", "nLevelCount: " << nLevelCount << " greater than max of: " << SVX_MAX_NUM); + nLevelCount = SVX_MAX_NUM; + } + + // first nFeatureFlags of old Versions + rStream.ReadUInt16( nTmp16 ); nFeatureFlags = static_cast<SvxNumRuleFlags>(nTmp16); + rStream.ReadUInt16( nTmp16 ); bContinuousNumbering = nTmp16; + rStream.ReadUInt16( nTmp16 ); eNumberingType = static_cast<SvxNumRuleType>(nTmp16); + + for (sal_uInt16 i = 0; i < SVX_MAX_NUM; i++) + { + rStream.ReadUInt16( nTmp16 ); + bool hasNumberingFormat = nTmp16 & 1; + aFmtsSet[i] = nTmp16 & 2; // fdo#68648 reset flag + if ( hasNumberingFormat ){ + aFmts[i].reset( new SvxNumberFormat( rStream ) ); + } + else + { + aFmts[i].reset(); + aFmtsSet[i] = false; // actually only false is valid + } + } + //second nFeatureFlags for new versions + rStream.ReadUInt16( nTmp16 ); nFeatureFlags = static_cast<SvxNumRuleFlags>(nTmp16); +} + +void SvxNumRule::Store( SvStream &rStream ) +{ + rStream.WriteUInt16( NUMITEM_VERSION_03 ); + rStream.WriteUInt16( nLevelCount ); + //first save of nFeatureFlags for old versions + rStream.WriteUInt16( static_cast<sal_uInt16>(nFeatureFlags) ); + rStream.WriteUInt16( sal_uInt16(bContinuousNumbering) ); + rStream.WriteUInt16( static_cast<sal_uInt16>(eNumberingType) ); + + FontToSubsFontConverter pConverter = nullptr; + bool bConvertBulletFont = ( rStream.GetVersion() <= SOFFICE_FILEFORMAT_50 ) && ( rStream.GetVersion() ); + for(sal_uInt16 i = 0; i < SVX_MAX_NUM; i++) + { + sal_uInt16 nSetFlag(aFmtsSet[i] ? 2 : 0); // fdo#68648 store that too + if(aFmts[i]) + { + rStream.WriteUInt16( 1 | nSetFlag ); + if(bConvertBulletFont && aFmts[i]->GetBulletFont()) + { + if(!pConverter) + pConverter = + CreateFontToSubsFontConverter(aFmts[i]->GetBulletFont()->GetFamilyName(), + FontToSubsFontFlags::EXPORT); + } + aFmts[i]->Store(rStream, pConverter); + } + else + rStream.WriteUInt16( 0 | nSetFlag ); + } + //second save of nFeatureFlags for new versions + rStream.WriteUInt16( static_cast<sal_uInt16>(nFeatureFlags) ); +} + +void SvxNumRule::dumpAsXml(xmlTextWriterPtr pWriter) const +{ + (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SvxNumRule")); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("levelCount"), BAD_CAST(OString::number(nLevelCount).getStr())); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("continuousNumbering"), BAD_CAST(OString::boolean(bContinuousNumbering).getStr())); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("numberingType"), BAD_CAST(OString::number(static_cast<int>(eNumberingType)).getStr())); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("featureFlags"), BAD_CAST(OString::number(static_cast<int>(nFeatureFlags)).getStr())); + for(sal_uInt16 i = 0; i < SVX_MAX_NUM; i++) + { + if(aFmts[i]) + { + (void)xmlTextWriterStartElement(pWriter, BAD_CAST("aFmts")); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("i"), BAD_CAST(OString::number(i).getStr())); + (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("ptr"), "%p", aFmts[i].get()); + (void)xmlTextWriterEndElement(pWriter); + } + } + (void)xmlTextWriterEndElement(pWriter); +} + + +SvxNumRule::~SvxNumRule() +{ + if(!--nRefCount) + { + delete pStdNumFmt; + pStdNumFmt = nullptr; + delete pStdOutlineNumFmt; + pStdOutlineNumFmt = nullptr; + } +} + +SvxNumRule& SvxNumRule::operator=( const SvxNumRule& rCopy ) +{ + if (this != &rCopy) + { + nLevelCount = rCopy.nLevelCount; + nFeatureFlags = rCopy.nFeatureFlags; + bContinuousNumbering = rCopy.bContinuousNumbering; + eNumberingType = rCopy.eNumberingType; + for(sal_uInt16 i = 0; i < SVX_MAX_NUM; i++) + { + if(rCopy.aFmts[i]) + aFmts[i].reset( new SvxNumberFormat(*rCopy.aFmts[i]) ); + else + aFmts[i].reset(); + aFmtsSet[i] = rCopy.aFmtsSet[i]; + } + } + return *this; +} + +SvxNumRule& SvxNumRule::operator=( SvxNumRule&& rCopy ) noexcept +{ + if (this != &rCopy) + { + nLevelCount = rCopy.nLevelCount; + nFeatureFlags = rCopy.nFeatureFlags; + bContinuousNumbering = rCopy.bContinuousNumbering; + eNumberingType = rCopy.eNumberingType; + for(sal_uInt16 i = 0; i < SVX_MAX_NUM; i++) + { + if(rCopy.aFmts[i]) + aFmts[i] = std::move(rCopy.aFmts[i]); + aFmtsSet[i] = rCopy.aFmtsSet[i]; + } + } + return *this; +} + +bool SvxNumRule::operator==( const SvxNumRule& rCopy) const +{ + if(nLevelCount != rCopy.nLevelCount || + nFeatureFlags != rCopy.nFeatureFlags || + bContinuousNumbering != rCopy.bContinuousNumbering || + eNumberingType != rCopy.eNumberingType) + return false; + for(sal_uInt16 i = 0; i < nLevelCount; i++) + { + if ( + (aFmtsSet[i] != rCopy.aFmtsSet[i]) || + (!aFmts[i] && rCopy.aFmts[i]) || + (aFmts[i] && !rCopy.aFmts[i]) || + (aFmts[i] && *aFmts[i] != *rCopy.aFmts[i]) + ) + { + return false; + } + } + return true; +} + +const SvxNumberFormat* SvxNumRule::Get(sal_uInt16 nLevel)const +{ + DBG_ASSERT(nLevel < SVX_MAX_NUM, "Wrong Level" ); + if( nLevel < SVX_MAX_NUM ) + return aFmtsSet[nLevel] ? aFmts[nLevel].get() : nullptr; + else + return nullptr; +} + +const SvxNumberFormat& SvxNumRule::GetLevel(sal_uInt16 nLevel)const +{ + if(!pStdNumFmt) + { + pStdNumFmt = new SvxNumberFormat(SVX_NUM_ARABIC); + pStdOutlineNumFmt = new SvxNumberFormat(SVX_NUM_NUMBER_NONE); + } + + DBG_ASSERT(nLevel < SVX_MAX_NUM, "Wrong Level" ); + + return ( ( nLevel < SVX_MAX_NUM ) && aFmts[nLevel] ) ? + *aFmts[nLevel] : eNumberingType == SvxNumRuleType::NUMBERING ? + *pStdNumFmt : *pStdOutlineNumFmt; +} + +void SvxNumRule::SetLevel( sal_uInt16 i, const SvxNumberFormat& rNumFmt, bool bIsValid ) +{ + DBG_ASSERT(i < SVX_MAX_NUM, "Wrong Level" ); + + if( i >= SVX_MAX_NUM ) + return; + + bool bReplace = !aFmtsSet[i]; + if (!bReplace) + { + const SvxNumberFormat *pFmt = Get(i); + bReplace = pFmt == nullptr || rNumFmt != *pFmt; + } + + if (bReplace) + { + aFmts[i].reset( new SvxNumberFormat(rNumFmt) ); + aFmtsSet[i] = bIsValid; + } +} + +void SvxNumRule::SetLevel(sal_uInt16 nLevel, const SvxNumberFormat* pFmt) +{ + DBG_ASSERT(nLevel < SVX_MAX_NUM, "Wrong Level" ); + + if( nLevel < SVX_MAX_NUM ) + { + aFmtsSet[nLevel] = nullptr != pFmt; + if(pFmt) + SetLevel(nLevel, *pFmt); + else + { + aFmts[nLevel].reset(); + } + } +} + +OUString SvxNumRule::MakeNumString( const SvxNodeNum& rNum ) const +{ + OUStringBuffer aStr; + if( SVX_NO_NUM > rNum.GetLevel() && !( SVX_NO_NUMLEVEL & rNum.GetLevel() ) ) + { + const SvxNumberFormat& rMyNFmt = GetLevel( rNum.GetLevel() ); + aStr.append(rMyNFmt.GetPrefix()); + if( SVX_NUM_NUMBER_NONE != rMyNFmt.GetNumberingType() ) + { + sal_uInt8 i = rNum.GetLevel(); + + if( !IsContinuousNumbering() && + 1 < rMyNFmt.GetIncludeUpperLevels() ) // only on own level? + { + sal_uInt8 n = rMyNFmt.GetIncludeUpperLevels(); + if( 1 < n ) + { + if( i+1 >= n ) + i -= n - 1; + else + i = 0; + } + } + + for( ; i <= rNum.GetLevel(); ++i ) + { + const SvxNumberFormat& rNFmt = GetLevel( i ); + if( SVX_NUM_NUMBER_NONE == rNFmt.GetNumberingType() ) + { + continue; + } + + bool bDot = true; + if( rNum.GetLevelVal()[ i ] ) + { + if(SVX_NUM_BITMAP != rNFmt.GetNumberingType()) + { + const LanguageTag& rLang = Application::GetSettings().GetLanguageTag(); + aStr.append(rNFmt.GetNumStr( rNum.GetLevelVal()[ i ], rLang.getLocale() )); + } + else + bDot = false; + } + else + aStr.append("0"); // all 0-levels are a 0 + if( i != rNum.GetLevel() && bDot) + aStr.append("."); + } + } + + aStr.append(rMyNFmt.GetSuffix()); + } + return aStr.makeStringAndClear(); +} + +// changes linked to embedded bitmaps +void SvxNumRule::UnLinkGraphics() +{ + for(sal_uInt16 i = 0; i < GetLevelCount(); i++) + { + SvxNumberFormat aFmt(GetLevel(i)); + const SvxBrushItem* pBrush = aFmt.GetBrush(); + if(SVX_NUM_BITMAP == aFmt.GetNumberingType()) + { + if(pBrush && !pBrush->GetGraphicLink().isEmpty()) + { + const Graphic* pGraphic = pBrush->GetGraphic(); + if (pGraphic) + { + SvxBrushItem aTempItem(*pBrush); + aTempItem.SetGraphicLink(""); + aTempItem.SetGraphic(*pGraphic); + sal_Int16 eOrient = aFmt.GetVertOrient(); + aFmt.SetGraphicBrush( &aTempItem, &aFmt.GetGraphicSize(), &eOrient ); + } + } + } + else if((SVX_NUM_BITMAP|LINK_TOKEN) == static_cast<int>(aFmt.GetNumberingType())) + aFmt.SetNumberingType(SVX_NUM_BITMAP); + SetLevel(i, aFmt); + } +} + +SvxNumBulletItem::SvxNumBulletItem(SvxNumRule const & rRule) : + SfxPoolItem(SID_ATTR_NUMBERING_RULE), + maNumRule(rRule) +{ +} + +SvxNumBulletItem::SvxNumBulletItem(SvxNumRule && rRule) : + SfxPoolItem(SID_ATTR_NUMBERING_RULE), + maNumRule(std::move(rRule)) +{ +} + +SvxNumBulletItem::SvxNumBulletItem(SvxNumRule const & rRule, sal_uInt16 _nWhich ) : + SfxPoolItem(_nWhich), + maNumRule(rRule) +{ +} + +SvxNumBulletItem::SvxNumBulletItem(SvxNumRule && rRule, sal_uInt16 _nWhich ) : + SfxPoolItem(_nWhich), + maNumRule(std::move(rRule)) +{ +} + +SvxNumBulletItem::SvxNumBulletItem(const SvxNumBulletItem& rCopy) : + SfxPoolItem(rCopy), + maNumRule(rCopy.maNumRule) +{ +} + +SvxNumBulletItem::~SvxNumBulletItem() +{ +} + +bool SvxNumBulletItem::operator==( const SfxPoolItem& rCopy) const +{ + return SfxPoolItem::operator==(rCopy) && + maNumRule == static_cast<const SvxNumBulletItem&>(rCopy).maNumRule; +} + +SvxNumBulletItem* SvxNumBulletItem::Clone( SfxItemPool * ) const +{ + return new SvxNumBulletItem(*this); +} + +bool SvxNumBulletItem::QueryValue( css::uno::Any& rVal, sal_uInt8 /*nMemberId*/ ) const +{ + rVal <<= SvxCreateNumRule( maNumRule ); + return true; +} + +bool SvxNumBulletItem::PutValue( const css::uno::Any& rVal, sal_uInt8 /*nMemberId*/ ) +{ + uno::Reference< container::XIndexReplace > xRule; + if( rVal >>= xRule ) + { + try + { + SvxNumRule aNewRule( SvxGetNumRule( xRule ) ); + if( aNewRule.GetLevelCount() != maNumRule.GetLevelCount() || + aNewRule.GetNumRuleType() != maNumRule.GetNumRuleType() ) + { + aNewRule = SvxConvertNumRule( aNewRule, maNumRule.GetLevelCount(), maNumRule.GetNumRuleType() ); + } + maNumRule = std::move( aNewRule ); + return true; + } + catch(const lang::IllegalArgumentException&) + { + } + } + return false; +} + +void SvxNumBulletItem::dumpAsXml(xmlTextWriterPtr pWriter) const +{ + (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SvxNumBulletItem")); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr())); + maNumRule.dumpAsXml(pWriter); + (void)xmlTextWriterEndElement(pWriter); +} + +SvxNumRule SvxConvertNumRule( const SvxNumRule& rRule, sal_uInt16 nLevels, SvxNumRuleType eType ) +{ + const sal_uInt16 nSrcLevels = rRule.GetLevelCount(); + SvxNumRule aNewRule(rRule.GetFeatureFlags(), nLevels, rRule.IsContinuousNumbering(), eType ); + + for( sal_uInt16 nLevel = 0; (nLevel < nLevels) && (nLevel < nSrcLevels); nLevel++ ) + aNewRule.SetLevel( nLevel, rRule.GetLevel( nLevel ) ); + + return aNewRule; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/editeng/source/items/optitems.cxx b/editeng/source/items/optitems.cxx new file mode 100644 index 000000000..254da79d9 --- /dev/null +++ b/editeng/source/items/optitems.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 <editeng/optitems.hxx> +#include <editeng/eerdll.hxx> +#include <editeng/editrids.hrc> + + +// class SfxHyphenRegionItem ----------------------------------------------- + +SfxHyphenRegionItem::SfxHyphenRegionItem( const sal_uInt16 nId ) : + + SfxPoolItem( nId ) +{ + nMinLead = nMinTrail = 0; +} + +bool SfxHyphenRegionItem::operator==( const SfxPoolItem& rAttr ) const +{ + assert(SfxPoolItem::operator==(rAttr)); + + return ( ( static_cast<const SfxHyphenRegionItem&>( rAttr ).nMinLead == nMinLead ) && + ( static_cast<const SfxHyphenRegionItem&>( rAttr ).nMinTrail == nMinTrail ) ); +} + +SfxHyphenRegionItem* SfxHyphenRegionItem::Clone( SfxItemPool* ) const +{ + return new SfxHyphenRegionItem( *this ); +} + +bool SfxHyphenRegionItem::GetPresentation +( + SfxItemPresentation /*ePres*/, + MapUnit , + MapUnit , + OUString& rText, + const IntlWrapper& +) const +{ + rText += EditResId(RID_SVXITEMS_HYPHEN_MINLEAD).replaceAll("%1", OUString::number(nMinLead)) + + "," + + EditResId(RID_SVXITEMS_HYPHEN_MINTRAIL).replaceAll("%1", OUString::number(nMinTrail)); + return true; +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/editeng/source/items/paperinf.cxx b/editeng/source/items/paperinf.cxx new file mode 100644 index 000000000..86401e63f --- /dev/null +++ b/editeng/source/items/paperinf.cxx @@ -0,0 +1,121 @@ +/* -*- 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 <vcl/print.hxx> +#include <editeng/paperinf.hxx> + +/*-------------------------------------------------------------------- + Description: Is the printer valid + --------------------------------------------------------------------*/ + +static bool IsValidPrinter( const Printer* pPtr ) +{ + return !pPtr->GetName().isEmpty(); +} + + +Size SvxPaperInfo::GetPaperSize( Paper ePaper, MapUnit eUnit ) +{ + PaperInfo aInfo(ePaper); + Size aRet(aInfo.getWidth(), aInfo.getHeight()); // in 100thMM + return eUnit == MapUnit::Map100thMM + ? aRet + : OutputDevice::LogicToLogic(aRet, MapMode(MapUnit::Map100thMM), MapMode(eUnit)); +} + +/*------------------------------------------------------------------------ + Description: Return the paper size of the printer, aligned to our + own sizes. If no Printer is set in the system, A4 portrait + will be delivered as the default paper size. +------------------------------------------------------------------------*/ + +//Is this method may be confused about the units it returns ? +//Always returns TWIPS for known paper sizes or on failure. +//But in the case of PAPER_USER paper and with a Printer with a mapmode set +//will return in those printer units ? +Size SvxPaperInfo::GetPaperSize( const Printer* pPrinter ) +{ + if ( !IsValidPrinter(pPrinter) ) + return GetPaperSize( PAPER_A4 ); + const Paper ePaper = pPrinter->GetPaper(); + + if ( ePaper == PAPER_USER ) + { + // Orientation not take into account, as the right size has + // been already set by SV + Size aPaperSize = pPrinter->GetPaperSize(); + const Size aInvalidSize; + + if ( aPaperSize == aInvalidSize ) + return GetPaperSize(PAPER_A4); + const MapMode& aMap1 = pPrinter->GetMapMode(); + MapMode aMap2; + + if ( aMap1 == aMap2 ) + aPaperSize = + pPrinter->PixelToLogic( aPaperSize, MapMode( MapUnit::MapTwip ) ); + return aPaperSize; + } + + const Orientation eOrient = pPrinter->GetOrientation(); + Size aSize( GetPaperSize( ePaper ) ); + // for Landscape exchange the pages, has already been done by SV + if ( eOrient == Orientation::Landscape ) + Swap( aSize ); + return aSize; +} + + +Paper SvxPaperInfo::GetSvxPaper( const Size &rSize, MapUnit eUnit ) +{ + Size aSize(eUnit == MapUnit::Map100thMM ? rSize : OutputDevice::LogicToLogic(rSize, MapMode(eUnit), MapMode(MapUnit::Map100thMM))); + PaperInfo aInfo(aSize.Width(), aSize.Height()); + aInfo.doSloppyFit(); + return aInfo.getPaper(); +} + + +tools::Long SvxPaperInfo::GetSloppyPaperDimension( tools::Long nSize ) +{ + nSize = o3tl::convert(nSize, o3tl::Length::twip, o3tl::Length::mm100); + nSize = PaperInfo::sloppyFitPageDimension(nSize); + return o3tl::convert(nSize, o3tl::Length::mm100, o3tl::Length::twip); +} + + +Size SvxPaperInfo::GetDefaultPaperSize( MapUnit eUnit ) +{ + PaperInfo aInfo(PaperInfo::getSystemDefaultPaper()); + Size aRet(aInfo.getWidth(), aInfo.getHeight()); + return eUnit == MapUnit::Map100thMM + ? aRet + : OutputDevice::LogicToLogic(aRet, MapMode(MapUnit::Map100thMM), MapMode(eUnit)); +} + +/*------------------------------------------------------------------------ + Description: String representation for the SV-defines of paper size +------------------------------------------------------------------------*/ + +OUString SvxPaperInfo::GetName( Paper ePaper ) +{ + return Printer::GetPaperName( ePaper ); +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/editeng/source/items/paraitem.cxx b/editeng/source/items/paraitem.cxx new file mode 100644 index 000000000..9368dfdf3 --- /dev/null +++ b/editeng/source/items/paraitem.cxx @@ -0,0 +1,1285 @@ +/* -*- 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/style/TabStop.hpp> +#include <com/sun/star/style/LineSpacing.hpp> +#include <com/sun/star/style/LineSpacingMode.hpp> +#include <com/sun/star/uno/Sequence.hxx> +#include <libxml/xmlwriter.h> +#include <comphelper/extract.hxx> +#include <osl/diagnose.h> +#include <unotools/localedatawrapper.hxx> +#include <unotools/syslocale.hxx> +#include <tools/mapunit.hxx> +#include <tools/UnitConversion.hxx> +#include <svl/itempool.hxx> +#include <svl/memberid.h> +#include <editeng/editrids.hrc> +#include <editeng/lspcitem.hxx> +#include <editeng/adjustitem.hxx> +#include <editeng/orphitem.hxx> +#include <editeng/widwitem.hxx> +#include <editeng/tstpitem.hxx> +#include <editeng/pmdlitem.hxx> +#include <editeng/spltitem.hxx> +#include <editeng/hyphenzoneitem.hxx> +#include <editeng/scriptspaceitem.hxx> +#include <editeng/hngpnctitem.hxx> +#include <editeng/forbiddenruleitem.hxx> +#include <editeng/paravertalignitem.hxx> +#include <editeng/pgrditem.hxx> +#include <rtl/ustring.hxx> +#include <sal/log.hxx> +#include <editeng/memberids.h> +#include <editeng/itemtype.hxx> +#include <editeng/eerdll.hxx> + +using namespace ::com::sun::star; + + +SfxPoolItem* SvxLineSpacingItem::CreateDefault() { return new SvxLineSpacingItem(LINE_SPACE_DEFAULT_HEIGHT, 0);} +SfxPoolItem* SvxAdjustItem::CreateDefault() { return new SvxAdjustItem(SvxAdjust::Left, 0);} +SfxPoolItem* SvxWidowsItem::CreateDefault() { return new SvxWidowsItem(0, 0);} +SfxPoolItem* SvxOrphansItem::CreateDefault() { return new SvxOrphansItem(0, 0);} +SfxPoolItem* SvxHyphenZoneItem::CreateDefault() { return new SvxHyphenZoneItem(false, 0);} +SfxPoolItem* SvxTabStopItem::CreateDefault() { return new SvxTabStopItem(0);} +SfxPoolItem* SvxFormatSplitItem::CreateDefault() { return new SvxFormatSplitItem(false, 0);} +SfxPoolItem* SvxPageModelItem::CreateDefault() { return new SvxPageModelItem(0);} +SfxPoolItem* SvxParaVertAlignItem::CreateDefault() { return new SvxParaVertAlignItem(Align::Automatic, 0);} + +namespace { + +enum class SvxSpecialLineSpace +{ + User, + OneLine, + OnePointFiveLines, + TwoLines, + End +}; + +} + +SvxLineSpacingItem::SvxLineSpacingItem( sal_uInt16 nHeight, const sal_uInt16 nId ) + : SfxEnumItemInterface( nId ) +{ + nPropLineSpace = 100; + nInterLineSpace = 0; + nLineHeight = nHeight; + eLineSpaceRule = SvxLineSpaceRule::Auto; + eInterLineSpaceRule = SvxInterLineSpaceRule::Off; +} + + +bool SvxLineSpacingItem::operator==( const SfxPoolItem& rAttr ) const +{ + assert(SfxPoolItem::operator==(rAttr)); + + const SvxLineSpacingItem& rLineSpace = static_cast<const SvxLineSpacingItem&>(rAttr); + return + // Same Linespacing Rule? + (eLineSpaceRule == rLineSpace.eLineSpaceRule) + // For maximum and minimum Linespacing be the size must coincide. + && (eLineSpaceRule == SvxLineSpaceRule::Auto || + nLineHeight == rLineSpace.nLineHeight) + // Same Linespacing Rule? + && ( eInterLineSpaceRule == rLineSpace.eInterLineSpaceRule ) + // Either set proportional or additive. + && (( eInterLineSpaceRule == SvxInterLineSpaceRule::Off) + || (eInterLineSpaceRule == SvxInterLineSpaceRule::Prop + && nPropLineSpace == rLineSpace.nPropLineSpace) + || (eInterLineSpaceRule == SvxInterLineSpaceRule::Fix + && (nInterLineSpace == rLineSpace.nInterLineSpace))); +} + +/* Who does still know why the LineSpacingItem is so complicated? + We can not use it for UNO since there are only two values: + - a sal_uInt16 for the mode + - a sal_uInt32 for all values (distance, height, rel. detail) +*/ +bool SvxLineSpacingItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const +{ + bool bConvert = 0!=(nMemberId&CONVERT_TWIPS); + nMemberId &= ~CONVERT_TWIPS; + + style::LineSpacing aLSp; + switch( eLineSpaceRule ) + { + case SvxLineSpaceRule::Auto: + if(eInterLineSpaceRule == SvxInterLineSpaceRule::Fix) + { + aLSp.Mode = style::LineSpacingMode::LEADING; + aLSp.Height = ( bConvert ? static_cast<short>(convertTwipToMm100(nInterLineSpace)) : nInterLineSpace); + } + else if(eInterLineSpaceRule == SvxInterLineSpaceRule::Off) + { + aLSp.Mode = style::LineSpacingMode::PROP; + aLSp.Height = 100; + } + else + { + aLSp.Mode = style::LineSpacingMode::PROP; + aLSp.Height = nPropLineSpace; + } + break; + case SvxLineSpaceRule::Fix : + case SvxLineSpaceRule::Min : + aLSp.Mode = eLineSpaceRule == SvxLineSpaceRule::Fix ? style::LineSpacingMode::FIX : style::LineSpacingMode::MINIMUM; + aLSp.Height = ( bConvert ? static_cast<short>(convertTwipToMm100(nLineHeight)) : nLineHeight ); + break; + default: + ;//prevent warning about SvxLineSpaceRule::End + } + + switch ( nMemberId ) + { + case 0 : rVal <<= aLSp; break; + case MID_LINESPACE : rVal <<= aLSp.Mode; break; + case MID_HEIGHT : rVal <<= aLSp.Height; break; + default: OSL_FAIL("Wrong MemberId!"); break; + } + + return true; +} + +bool SvxLineSpacingItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId ) +{ + bool bConvert = 0!=(nMemberId&CONVERT_TWIPS); + nMemberId &= ~CONVERT_TWIPS; + + // fill with current data + style::LineSpacing aLSp; + uno::Any aAny; + bool bRet = QueryValue( aAny, bConvert ? CONVERT_TWIPS : 0 ) && ( aAny >>= aLSp ); + + // get new data + switch ( nMemberId ) + { + case 0 : bRet = (rVal >>= aLSp); break; + case MID_LINESPACE : bRet = (rVal >>= aLSp.Mode); break; + case MID_HEIGHT : bRet = (rVal >>= aLSp.Height); break; + default: OSL_FAIL("Wrong MemberId!"); break; + } + + if( bRet ) + { + nLineHeight = aLSp.Height; + switch( aLSp.Mode ) + { + case style::LineSpacingMode::LEADING: + { + eInterLineSpaceRule = SvxInterLineSpaceRule::Fix; + eLineSpaceRule = SvxLineSpaceRule::Auto; + nInterLineSpace = aLSp.Height; + if(bConvert) + nInterLineSpace = o3tl::toTwips(nInterLineSpace, o3tl::Length::mm100); + + } + break; + case style::LineSpacingMode::PROP: + { + eLineSpaceRule = SvxLineSpaceRule::Auto; + nPropLineSpace = aLSp.Height; + if(100 == aLSp.Height) + eInterLineSpaceRule = SvxInterLineSpaceRule::Off; + else + eInterLineSpaceRule = SvxInterLineSpaceRule::Prop; + } + break; + case style::LineSpacingMode::FIX: + case style::LineSpacingMode::MINIMUM: + { + eInterLineSpaceRule = SvxInterLineSpaceRule::Off; + eLineSpaceRule = aLSp.Mode == style::LineSpacingMode::FIX ? SvxLineSpaceRule::Fix : SvxLineSpaceRule::Min; + nLineHeight = aLSp.Height; + if(bConvert) + nLineHeight = o3tl::toTwips(nLineHeight, o3tl::Length::mm100); + } + break; + } + } + + return bRet; +} + +SvxLineSpacingItem* SvxLineSpacingItem::Clone( SfxItemPool * ) const +{ + return new SvxLineSpacingItem( *this ); +} + +bool SvxLineSpacingItem::GetPresentation +( + SfxItemPresentation ePres, + MapUnit eCoreUnit, + MapUnit ePresUnit, + OUString& rText, const IntlWrapper& rIntl +) const +{ + switch ( ePres ) + { + case SfxItemPresentation::Nameless: + case SfxItemPresentation::Complete: + { + switch( GetLineSpaceRule() ) + { + case SvxLineSpaceRule::Auto: + { + SvxInterLineSpaceRule eInter = GetInterLineSpaceRule(); + + switch( eInter ) + { + // Default single line spacing + case SvxInterLineSpaceRule::Off: + rText = EditResId(RID_SVXITEMS_LINESPACING_SINGLE); + break; + + // Default single line spacing + case SvxInterLineSpaceRule::Prop: + if ( 100 == GetPropLineSpace() ) + { + rText = EditResId(RID_SVXITEMS_LINESPACING_SINGLE); + break; + } + // 1.15 line spacing + if ( 115 == GetPropLineSpace() ) + { + rText = EditResId(RID_SVXITEMS_LINESPACING_115); + break; + } + // 1.5 line spacing + if ( 150 == GetPropLineSpace() ) + { + rText = EditResId(RID_SVXITEMS_LINESPACING_15); + break; + } + // double line spacing + if ( 200 == GetPropLineSpace() ) + { + rText = EditResId(RID_SVXITEMS_LINESPACING_DOUBLE); + break; + } + // the set per cent value + rText = EditResId(RID_SVXITEMS_LINESPACING_PROPORTIONAL) + " " + OUString::number(GetPropLineSpace()) + "%"; + break; + + case SvxInterLineSpaceRule::Fix: + rText = EditResId(RID_SVXITEMS_LINESPACING_LEADING) + + " " + GetMetricText(GetInterLineSpace(), eCoreUnit, ePresUnit, &rIntl) + + " " + EditResId(GetMetricId(ePresUnit)); + break; + default: ;//prevent warning + } + } + break; + case SvxLineSpaceRule::Fix: + rText = EditResId(RID_SVXITEMS_LINESPACING_FIXED) + + " " + GetMetricText(GetLineHeight(), eCoreUnit, ePresUnit, &rIntl) + + " " + EditResId(GetMetricId(ePresUnit)); + break; + + case SvxLineSpaceRule::Min: + rText = EditResId(RID_SVXITEMS_LINESPACING_MIN) + + " " + GetMetricText(GetLineHeight(), eCoreUnit, ePresUnit, &rIntl) + + " " + EditResId(GetMetricId(ePresUnit)); + break; + default: ;//prevent warning + } + } + } + return true; +} + +sal_uInt16 SvxLineSpacingItem::GetValueCount() const +{ + return sal_uInt16(SvxSpecialLineSpace::End); // SvxSpecialLineSpace::TwoLines + 1 +} + + +sal_uInt16 SvxLineSpacingItem::GetEnumValue() const +{ + SvxSpecialLineSpace nVal; + switch ( nPropLineSpace ) + { + case 100: nVal = SvxSpecialLineSpace::OneLine; break; + case 150: nVal = SvxSpecialLineSpace::OnePointFiveLines; break; + case 200: nVal = SvxSpecialLineSpace::TwoLines; break; + default: nVal = SvxSpecialLineSpace::User; break; + } + return static_cast<sal_uInt16>(nVal); +} + + +void SvxLineSpacingItem::SetEnumValue( sal_uInt16 nVal ) +{ + switch ( static_cast<SvxSpecialLineSpace>(nVal) ) + { + case SvxSpecialLineSpace::OneLine: nPropLineSpace = 100; break; + case SvxSpecialLineSpace::OnePointFiveLines: nPropLineSpace = 150; break; + case SvxSpecialLineSpace::TwoLines: nPropLineSpace = 200; break; + default: break; + } +} + +// class SvxAdjustItem --------------------------------------------------- + +SvxAdjustItem::SvxAdjustItem(const SvxAdjust eAdjst, const sal_uInt16 nId ) + : SfxEnumItemInterface( nId ), + bOneBlock( false ), bLastCenter( false ), bLastBlock( false ) +{ + SetAdjust( eAdjst ); +} + + +bool SvxAdjustItem::operator==( const SfxPoolItem& rAttr ) const +{ + assert(SfxPoolItem::operator==(rAttr)); + + const SvxAdjustItem& rItem = static_cast<const SvxAdjustItem&>(rAttr); + return GetAdjust() == rItem.GetAdjust() && + bOneBlock == rItem.bOneBlock && + bLastCenter == rItem.bLastCenter && + bLastBlock == rItem.bLastBlock; +} + +bool SvxAdjustItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const +{ + nMemberId &= ~CONVERT_TWIPS; + switch( nMemberId ) + { + case MID_PARA_ADJUST : rVal <<= static_cast<sal_Int16>(GetAdjust()); break; + case MID_LAST_LINE_ADJUST : rVal <<= static_cast<sal_Int16>(GetLastBlock()); break; + case MID_EXPAND_SINGLE : + { + rVal <<= bOneBlock; + break; + } + default: ;//prevent warning + } + return true; +} + +bool SvxAdjustItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId ) +{ + nMemberId &= ~CONVERT_TWIPS; + switch( nMemberId ) + { + case MID_PARA_ADJUST : + case MID_LAST_LINE_ADJUST : + { + sal_Int32 eVal = - 1; + ::cppu::enum2int(eVal,rVal); + if(eVal >= 0 && eVal <= 4) + { + SvxAdjust eAdjust = static_cast<SvxAdjust>(eVal); + if(MID_LAST_LINE_ADJUST == nMemberId && + eAdjust != SvxAdjust::Left && + eAdjust != SvxAdjust::Block && + eAdjust != SvxAdjust::Center) + return false; + nMemberId == MID_PARA_ADJUST ? SetAdjust(eAdjust) : SetLastBlock(eAdjust); + } + } + break; + case MID_EXPAND_SINGLE : + bOneBlock = Any2Bool(rVal); + break; + } + return true; +} + +SvxAdjustItem* SvxAdjustItem::Clone( SfxItemPool * ) const +{ + return new SvxAdjustItem( *this ); +} + +bool SvxAdjustItem::GetPresentation +( + SfxItemPresentation ePres, + MapUnit /*eCoreUnit*/, + MapUnit /*ePresUnit*/, + OUString& rText, const IntlWrapper& +) const +{ + switch ( ePres ) + { + case SfxItemPresentation::Nameless: + case SfxItemPresentation::Complete: + rText = GetValueTextByPos( static_cast<sal_uInt16>(GetAdjust()) ); + return true; + default: ;//prevent warning + } + return false; +} + + +sal_uInt16 SvxAdjustItem::GetValueCount() const +{ + return sal_uInt16(SvxAdjust::End); // SvxAdjust::BlockLine + 1 +} + +OUString SvxAdjustItem::GetValueTextByPos( sal_uInt16 nPos ) +{ + static TranslateId RID_SVXITEMS_ADJUST[] = + { + RID_SVXITEMS_ADJUST_LEFT, + RID_SVXITEMS_ADJUST_RIGHT, + RID_SVXITEMS_ADJUST_BLOCK, + RID_SVXITEMS_ADJUST_CENTER, + RID_SVXITEMS_ADJUST_BLOCKLINE + }; + static_assert(SAL_N_ELEMENTS(RID_SVXITEMS_ADJUST) - 1 == size_t(SvxAdjust::BlockLine), "unexpected size"); + assert(nPos <= sal_uInt16(SvxAdjust::BlockLine) && "enum overflow!"); + return EditResId(RID_SVXITEMS_ADJUST[nPos]); +} + +sal_uInt16 SvxAdjustItem::GetEnumValue() const +{ + return static_cast<sal_uInt16>(GetAdjust()); +} + + +void SvxAdjustItem::SetEnumValue( sal_uInt16 nVal ) +{ + SetAdjust( static_cast<SvxAdjust>(nVal) ); +} + + +// class SvxWidowsItem --------------------------------------------------- + +SvxWidowsItem::SvxWidowsItem(const sal_uInt8 nL, const sal_uInt16 nId ) : + SfxByteItem( nId, nL ) +{ +} + +SvxWidowsItem* SvxWidowsItem::Clone( SfxItemPool * ) const +{ + return new SvxWidowsItem( *this ); +} + +bool SvxWidowsItem::GetPresentation +( + SfxItemPresentation ePres, + MapUnit /*eCoreUnit*/, + MapUnit /*ePresUnit*/, + OUString& rText, const IntlWrapper& +) const +{ + switch ( ePres ) + { + case SfxItemPresentation::Nameless: + { + rText = EditResId(RID_SVXITEMS_LINES); + break; + } + + case SfxItemPresentation::Complete: + { + rText = EditResId(RID_SVXITEMS_WIDOWS_COMPLETE) + " " + EditResId(RID_SVXITEMS_LINES); + break; + } + + default: + { + SAL_WARN( "editeng.items", "SvxWidowsItem::GetPresentation(): unknown SfxItemPresentation" ); + } + } + + rText = rText.replaceFirst( "%1", OUString::number( GetValue() ) ); + return true; +} + +// class SvxOrphansItem -------------------------------------------------- + +SvxOrphansItem::SvxOrphansItem(const sal_uInt8 nL, const sal_uInt16 nId ) : + SfxByteItem( nId, nL ) +{ +} + +SvxOrphansItem* SvxOrphansItem::Clone( SfxItemPool * ) const +{ + return new SvxOrphansItem( *this ); +} + +bool SvxOrphansItem::GetPresentation +( + SfxItemPresentation ePres, + MapUnit /*eCoreUnit*/, + MapUnit /*ePresUnit*/, + OUString& rText, const IntlWrapper& +) const +{ + switch ( ePres ) + { + case SfxItemPresentation::Nameless: + { + rText = EditResId(RID_SVXITEMS_LINES); + break; + } + + case SfxItemPresentation::Complete: + { + rText = EditResId(RID_SVXITEMS_ORPHANS_COMPLETE) + " " + EditResId(RID_SVXITEMS_LINES); + break; + } + + default: + { + SAL_WARN( "editeng.items", "SvxOrphansItem::GetPresentation(): unknown SfxItemPresentation" ); + } + } + + rText = rText.replaceFirst( "%1", OUString::number( GetValue() ) ); + return true; +} + +// class SvxHyphenZoneItem ----------------------------------------------- + +SvxHyphenZoneItem::SvxHyphenZoneItem( const bool bHyph, const sal_uInt16 nId ) : + SfxPoolItem( nId ), + bHyphen(bHyph), + bPageEnd(true), + bNoCapsHyphenation(false), + bNoLastWordHyphenation(false), + nMinLead(0), + nMinTrail(0), + nMaxHyphens(255), + nMinWordLength(0), + nTextHyphenZone(0) +{ +} + + +bool SvxHyphenZoneItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const +{ + nMemberId &= ~CONVERT_TWIPS; + switch(nMemberId) + { + case MID_IS_HYPHEN: + rVal <<= bHyphen; + break; + case MID_HYPHEN_MIN_LEAD: + rVal <<= static_cast<sal_Int16>(nMinLead); + break; + case MID_HYPHEN_MIN_TRAIL: + rVal <<= static_cast<sal_Int16>(nMinTrail); + break; + case MID_HYPHEN_MAX_HYPHENS: + rVal <<= static_cast<sal_Int16>(nMaxHyphens); + break; + case MID_HYPHEN_NO_CAPS: + rVal <<= bNoCapsHyphenation; + break; + case MID_HYPHEN_NO_LAST_WORD: + rVal <<= bNoLastWordHyphenation; + break; + case MID_HYPHEN_MIN_WORD_LENGTH: + rVal <<= static_cast<sal_Int16>(nMinWordLength); + break; + case MID_HYPHEN_ZONE: + rVal <<= static_cast<sal_Int16>(nTextHyphenZone); + break; + } + return true; +} + +bool SvxHyphenZoneItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId ) +{ + nMemberId &= ~CONVERT_TWIPS; + sal_Int16 nNewVal = 0; + + if( nMemberId != MID_IS_HYPHEN && nMemberId != MID_HYPHEN_NO_CAPS && + nMemberId != MID_HYPHEN_NO_LAST_WORD ) + { + if(!(rVal >>= nNewVal)) + return false; + } + + switch(nMemberId) + { + case MID_IS_HYPHEN: + bHyphen = Any2Bool(rVal); + break; + case MID_HYPHEN_MIN_LEAD: + nMinLead = static_cast<sal_uInt8>(nNewVal); + break; + case MID_HYPHEN_MIN_TRAIL: + nMinTrail = static_cast<sal_uInt8>(nNewVal); + break; + case MID_HYPHEN_MAX_HYPHENS: + nMaxHyphens = static_cast<sal_uInt8>(nNewVal); + break; + case MID_HYPHEN_NO_CAPS: + bNoCapsHyphenation = Any2Bool(rVal); + break; + case MID_HYPHEN_NO_LAST_WORD: + bNoLastWordHyphenation = Any2Bool(rVal); + break; + case MID_HYPHEN_MIN_WORD_LENGTH: + nMinWordLength = static_cast<sal_uInt8>(nNewVal); + break; + case MID_HYPHEN_ZONE: + nTextHyphenZone = nNewVal; + break; + } + return true; +} + + +bool SvxHyphenZoneItem::operator==( const SfxPoolItem& rAttr ) const +{ + assert(SfxPoolItem::operator==(rAttr)); + + const SvxHyphenZoneItem& rItem = static_cast<const SvxHyphenZoneItem&>(rAttr); + return ( rItem.bHyphen == bHyphen + && rItem.bNoCapsHyphenation == bNoCapsHyphenation + && rItem.bNoLastWordHyphenation == bNoLastWordHyphenation + && rItem.bPageEnd == bPageEnd + && rItem.nMinLead == nMinLead + && rItem.nMinTrail == nMinTrail + && rItem.nMaxHyphens == nMaxHyphens + && rItem.nMinWordLength == nMinWordLength + && rItem.nTextHyphenZone == nTextHyphenZone ); +} + +SvxHyphenZoneItem* SvxHyphenZoneItem::Clone( SfxItemPool * ) const +{ + return new SvxHyphenZoneItem( *this ); +} + +bool SvxHyphenZoneItem::GetPresentation +( + SfxItemPresentation ePres, + MapUnit eCoreUnit, + MapUnit ePresUnit, + OUString& rText, const IntlWrapper& rIntl +) const +{ + OUString cpDelimTmp(cpDelim); + switch ( ePres ) + { + case SfxItemPresentation::Nameless: + { + TranslateId pId = RID_SVXITEMS_HYPHEN_FALSE; + + if ( bHyphen ) + pId = RID_SVXITEMS_HYPHEN_TRUE; + rText = EditResId(pId) + cpDelimTmp; + pId = RID_SVXITEMS_PAGE_END_FALSE; + + if ( bPageEnd ) + pId = RID_SVXITEMS_PAGE_END_TRUE; + rText += EditResId(pId) + cpDelimTmp + + OUString::number( nMinLead ) + cpDelimTmp + + OUString::number( nMinTrail ) + cpDelimTmp + + OUString::number( nMaxHyphens ) + cpDelimTmp + + OUString::number( nMinWordLength ) + cpDelimTmp + + GetMetricText( nTextHyphenZone, eCoreUnit, ePresUnit, &rIntl ) + + " " + EditResId(GetMetricId(ePresUnit)); + + if ( bNoCapsHyphenation ) + rText += cpDelimTmp + EditResId(RID_SVXITEMS_HYPHEN_NO_CAPS_TRUE); + + if ( bNoLastWordHyphenation ) + rText += cpDelimTmp + EditResId(RID_SVXITEMS_HYPHEN_LAST_WORD_TRUE); + + return true; + } + case SfxItemPresentation::Complete: + { + TranslateId pId = RID_SVXITEMS_HYPHEN_FALSE; + + if ( bHyphen ) + pId = RID_SVXITEMS_HYPHEN_TRUE; + rText = EditResId(pId) + cpDelimTmp; + pId = RID_SVXITEMS_PAGE_END_FALSE; + + if ( bPageEnd ) + pId = RID_SVXITEMS_PAGE_END_TRUE; + rText += EditResId(pId) + + cpDelimTmp + + EditResId(RID_SVXITEMS_HYPHEN_MINLEAD).replaceAll("%1", OUString::number(nMinLead)) + + cpDelimTmp + + EditResId(RID_SVXITEMS_HYPHEN_MINTRAIL).replaceAll("%1", OUString::number(nMinTrail)) + + cpDelimTmp + + EditResId(RID_SVXITEMS_HYPHEN_MAX).replaceAll("%1", OUString::number(nMaxHyphens)) + + cpDelimTmp + + EditResId(RID_SVXITEMS_HYPHEN_MINWORDLEN).replaceAll("%1", OUString::number(nMinWordLength)); + + if ( nTextHyphenZone > 0 ) + { + rText += cpDelimTmp + EditResId(RID_SVXITEMS_HYPHEN_ZONE) + + GetMetricText( nTextHyphenZone, eCoreUnit, ePresUnit, &rIntl ) + + " " + EditResId(GetMetricId(ePresUnit)); + } + + if ( bNoCapsHyphenation ) + rText += cpDelimTmp + EditResId(RID_SVXITEMS_HYPHEN_NO_CAPS_TRUE); + + if ( bNoLastWordHyphenation ) + rText += cpDelimTmp + EditResId(RID_SVXITEMS_HYPHEN_LAST_WORD_TRUE); + + return true; + } + default: ;//prevent warning + } + return false; +} + + +// class SvxTabStop ------------------------------------------------------ + +SvxTabStop::SvxTabStop() +{ + nTabPos = 0; + eAdjustment = SvxTabAdjust::Left; + m_cDecimal = cDfltDecimalChar; + cFill = cDfltFillChar; +} + + +SvxTabStop::SvxTabStop( const sal_Int32 nPos, const SvxTabAdjust eAdjst, + const sal_Unicode cDec, const sal_Unicode cFil ) +{ + nTabPos = nPos; + eAdjustment = eAdjst; + m_cDecimal = cDec; + cFill = cFil; +} + +void SvxTabStop::fillDecimal() const +{ + if ( cDfltDecimalChar == m_cDecimal ) + m_cDecimal = SvtSysLocale().GetLocaleData().getNumDecimalSep()[0]; +} + +void SvxTabStop::dumpAsXml(xmlTextWriterPtr pWriter) const +{ + (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SvxTabStop")); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nTabPos"), + BAD_CAST(OString::number(nTabPos).getStr())); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("eAdjustment"), + BAD_CAST(OString::number(static_cast<int>(eAdjustment)).getStr())); + (void)xmlTextWriterEndElement(pWriter); +} + +// class SvxTabStopItem -------------------------------------------------- + +SvxTabStopItem::SvxTabStopItem( sal_uInt16 _nWhich ) : + SfxPoolItem( _nWhich ) +{ + const sal_uInt16 nTabs = SVX_TAB_DEFCOUNT, nDist = SVX_TAB_DEFDIST; + const SvxTabAdjust eAdjst= SvxTabAdjust::Default; + + for (sal_uInt16 i = 0; i < nTabs; ++i) + { + SvxTabStop aTab( (i + 1) * nDist, eAdjst ); + maTabStops.insert( aTab ); + } +} + + +SvxTabStopItem::SvxTabStopItem( const sal_uInt16 nTabs, + const sal_uInt16 nDist, + const SvxTabAdjust eAdjst, + sal_uInt16 _nWhich ) : + SfxPoolItem( _nWhich ) +{ + for ( sal_uInt16 i = 0; i < nTabs; ++i ) + { + SvxTabStop aTab( (i + 1) * nDist, eAdjst ); + maTabStops.insert( aTab ); + } +} + + +sal_uInt16 SvxTabStopItem::GetPos( const SvxTabStop& rTab ) const +{ + SvxTabStopArr::const_iterator it = maTabStops.find( rTab ); + return it != maTabStops.end() ? it - maTabStops.begin() : SVX_TAB_NOTFOUND; +} + + +sal_uInt16 SvxTabStopItem::GetPos( const sal_Int32 nPos ) const +{ + SvxTabStopArr::const_iterator it = maTabStops.find( SvxTabStop( nPos ) ); + return it != maTabStops.end() ? it - maTabStops.begin() : SVX_TAB_NOTFOUND; +} + + +bool SvxTabStopItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const +{ + bool bConvert = 0!=(nMemberId&CONVERT_TWIPS); + nMemberId &= ~CONVERT_TWIPS; + switch ( nMemberId ) + { + case MID_TABSTOPS: + { + sal_uInt16 nCount = Count(); + uno::Sequence< style::TabStop> aSeq(nCount); + style::TabStop* pArr = aSeq.getArray(); + for(sal_uInt16 i = 0; i < nCount; i++) + { + const SvxTabStop& rTab = (*this)[i]; + pArr[i].Position = bConvert ? convertTwipToMm100(rTab.GetTabPos()) : rTab.GetTabPos(); + switch(rTab.GetAdjustment()) + { + case SvxTabAdjust::Left : pArr[i].Alignment = style::TabAlign_LEFT; break; + case SvxTabAdjust::Right : pArr[i].Alignment = style::TabAlign_RIGHT; break; + case SvxTabAdjust::Decimal: pArr[i].Alignment = style::TabAlign_DECIMAL; break; + case SvxTabAdjust::Center : pArr[i].Alignment = style::TabAlign_CENTER; break; + default: //SvxTabAdjust::Default + pArr[i].Alignment = style::TabAlign_DEFAULT; + + } + pArr[i].DecimalChar = rTab.GetDecimal(); + pArr[i].FillChar = rTab.GetFill(); + } + rVal <<= aSeq; + break; + } + case MID_STD_TAB: + { + const SvxTabStop &rTab = maTabStops.front(); + rVal <<= static_cast<sal_Int32>(bConvert ? convertTwipToMm100(rTab.GetTabPos()) : rTab.GetTabPos()); + break; + } + } + return true; +} + +bool SvxTabStopItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId ) +{ + bool bConvert = 0!=(nMemberId&CONVERT_TWIPS); + nMemberId &= ~CONVERT_TWIPS; + switch ( nMemberId ) + { + case MID_TABSTOPS: + { + uno::Sequence< style::TabStop> aSeq; + if(!(rVal >>= aSeq)) + { + uno::Sequence < uno::Sequence < uno::Any > > aAnySeq; + if (!(rVal >>= aAnySeq)) + return false; + auto aAnySeqRange = asNonConstRange(aAnySeq); + sal_Int32 nLength = aAnySeq.getLength(); + aSeq.realloc( nLength ); + auto pSeq = aSeq.getArray(); + for ( sal_Int32 n=0; n<nLength; n++ ) + { + uno::Sequence < uno::Any >& rAnySeq = aAnySeqRange[n]; + if ( rAnySeq.getLength() == 4 ) + { + if (!(rAnySeq[0] >>= pSeq[n].Position)) return false; + if (!(rAnySeq[1] >>= pSeq[n].Alignment)) + { + sal_Int32 nVal = 0; + if (rAnySeq[1] >>= nVal) + pSeq[n].Alignment = static_cast<css::style::TabAlign>(nVal); + else + return false; + } + if (!(rAnySeq[2] >>= pSeq[n].DecimalChar)) + { + OUString aVal; + if ( (rAnySeq[2] >>= aVal) && aVal.getLength() == 1 ) + pSeq[n].DecimalChar = aVal.toChar(); + else + return false; + } + if (!(rAnySeq[3] >>= pSeq[n].FillChar)) + { + OUString aVal; + if ( (rAnySeq[3] >>= aVal) && aVal.getLength() == 1 ) + pSeq[n].FillChar = aVal.toChar(); + else + return false; + } + } + else + return false; + } + } + + maTabStops.clear(); + const style::TabStop* pArr = aSeq.getConstArray(); + const sal_uInt16 nCount = static_cast<sal_uInt16>(aSeq.getLength()); + for(sal_uInt16 i = 0; i < nCount ; i++) + { + SvxTabAdjust eAdjust = SvxTabAdjust::Default; + switch(pArr[i].Alignment) + { + case style::TabAlign_LEFT : eAdjust = SvxTabAdjust::Left; break; + case style::TabAlign_CENTER : eAdjust = SvxTabAdjust::Center; break; + case style::TabAlign_RIGHT : eAdjust = SvxTabAdjust::Right; break; + case style::TabAlign_DECIMAL: eAdjust = SvxTabAdjust::Decimal; break; + default: ;//prevent warning + } + sal_Unicode cFill = pArr[i].FillChar; + sal_Unicode cDecimal = pArr[i].DecimalChar; + SvxTabStop aTab( bConvert ? o3tl::toTwips(pArr[i].Position, o3tl::Length::mm100) : pArr[i].Position, + eAdjust, + cDecimal, + cFill ); + Insert(aTab); + } + break; + } + case MID_STD_TAB: + { + sal_Int32 nNewPos = 0; + if (!(rVal >>= nNewPos) ) + return false; + if (bConvert) + nNewPos = o3tl::toTwips(nNewPos, o3tl::Length::mm100); + if (nNewPos <= 0) + return false; + const SvxTabStop& rTab = maTabStops.front(); + SvxTabStop aNewTab ( nNewPos, rTab.GetAdjustment(), rTab.GetDecimal(), rTab.GetFill() ); + Remove( 0 ); + Insert( aNewTab ); + break; + } + } + return true; +} + + +bool SvxTabStopItem::operator==( const SfxPoolItem& rAttr ) const +{ + assert(SfxPoolItem::operator==(rAttr)); + + const SvxTabStopItem& rTSI = static_cast<const SvxTabStopItem&>(rAttr); + + if ( Count() != rTSI.Count() ) + return false; + + for ( sal_uInt16 i = 0; i < Count(); ++i ) + if( (*this)[i] != rTSI[i] ) + return false; + return true; +} + +SvxTabStopItem* SvxTabStopItem::Clone( SfxItemPool * ) const +{ + return new SvxTabStopItem( *this ); +} + +bool SvxTabStopItem::GetPresentation +( + SfxItemPresentation ePres, + MapUnit eCoreUnit, + MapUnit ePresUnit, + OUString& rText, const IntlWrapper& rIntl +) const +{ + rText.clear(); + + bool bComma = false; + + for ( sal_uInt16 i = 0; i < Count(); ++i ) + { + if ( SvxTabAdjust::Default != ((*this)[i]).GetAdjustment() ) + { + if ( bComma ) + rText += ","; + rText += GetMetricText( + ((*this)[i]).GetTabPos(), eCoreUnit, ePresUnit, &rIntl ); + if ( SfxItemPresentation::Complete == ePres ) + { + rText += " " + EditResId(GetMetricId(ePresUnit)); + } + bComma = true; + } + } + return true; +} + + +bool SvxTabStopItem::Insert( const SvxTabStop& rTab ) +{ + sal_uInt16 nTabPos = GetPos(rTab); + if(SVX_TAB_NOTFOUND != nTabPos ) + Remove(nTabPos); + return maTabStops.insert( rTab ).second; +} + +void SvxTabStopItem::Insert( const SvxTabStopItem* pTabs ) +{ + for( sal_uInt16 i = 0; i < pTabs->Count(); i++ ) + { + const SvxTabStop& rTab = (*pTabs)[i]; + sal_uInt16 nTabPos = GetPos(rTab); + if(SVX_TAB_NOTFOUND != nTabPos) + Remove(nTabPos); + } + for( sal_uInt16 i = 0; i < pTabs->Count(); i++ ) + { + maTabStops.insert( (*pTabs)[i] ); + } +} + +void SvxTabStopItem::dumpAsXml(xmlTextWriterPtr pWriter) const +{ + (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SvxTabStopItem")); + for (const auto& rTabStop : maTabStops) + rTabStop.dumpAsXml(pWriter); + (void)xmlTextWriterEndElement(pWriter); +} + +// class SvxFormatSplitItem ------------------------------------------------- +SvxFormatSplitItem::~SvxFormatSplitItem() +{ +} + +SvxFormatSplitItem* SvxFormatSplitItem::Clone( SfxItemPool * ) const +{ + return new SvxFormatSplitItem( *this ); +} + +bool SvxFormatSplitItem::GetPresentation +( + SfxItemPresentation /*ePres*/, + MapUnit /*eCoreUnit*/, + MapUnit /*ePresUnit*/, + OUString& rText, const IntlWrapper& +) const +{ + TranslateId pId = RID_SVXITEMS_FMTSPLIT_FALSE; + + if ( GetValue() ) + pId = RID_SVXITEMS_FMTSPLIT_TRUE; + rText = EditResId(pId); + return true; +} + +SvxPageModelItem* SvxPageModelItem::Clone( SfxItemPool* ) const +{ + return new SvxPageModelItem( *this ); +} + +bool SvxPageModelItem::QueryValue( css::uno::Any& rVal, sal_uInt8 nMemberId ) const +{ + nMemberId &= ~CONVERT_TWIPS; + + switch ( nMemberId ) + { + case MID_AUTO: rVal <<= bAuto; break; + case MID_NAME: rVal <<= GetValue(); break; + default: OSL_FAIL("Wrong MemberId!"); return false; + } + + return true; +} + +bool SvxPageModelItem::PutValue( const css::uno::Any& rVal, sal_uInt8 nMemberId ) +{ + nMemberId &= ~CONVERT_TWIPS; + bool bRet; + OUString aStr; + switch ( nMemberId ) + { + case MID_AUTO: bRet = ( rVal >>= bAuto ); break; + case MID_NAME: bRet = ( rVal >>= aStr ); if ( bRet ) SetValue(aStr); break; + default: OSL_FAIL("Wrong MemberId!"); return false; + } + + return bRet; +} + +bool SvxPageModelItem::operator==( const SfxPoolItem& rAttr ) const +{ + return SfxStringItem::operator==(rAttr) && + bAuto == static_cast<const SvxPageModelItem&>( rAttr ).bAuto; +} + +bool SvxPageModelItem::GetPresentation +( + SfxItemPresentation ePres, + MapUnit /*eCoreUnit*/, + MapUnit /*ePresUnit*/, + OUString& rText, const IntlWrapper& +) const +{ + rText.clear(); + bool bSet = !GetValue().isEmpty(); + + switch ( ePres ) + { + case SfxItemPresentation::Nameless: + if ( bSet ) + rText = GetValue(); + return true; + + case SfxItemPresentation::Complete: + if ( bSet ) + { + rText = EditResId(RID_SVXITEMS_PAGEMODEL_COMPLETE) + GetValue(); + } + return true; + default: ;//prevent warning + } + return false; +} + + +SvxScriptSpaceItem::SvxScriptSpaceItem( bool bOn, const sal_uInt16 nId ) + : SfxBoolItem( nId, bOn ) +{ +} + +SvxScriptSpaceItem* SvxScriptSpaceItem::Clone( SfxItemPool * ) const +{ + return new SvxScriptSpaceItem( *this ); +} + +bool SvxScriptSpaceItem::GetPresentation( + SfxItemPresentation /*ePres*/, + MapUnit /*eCoreMetric*/, MapUnit /*ePresMetric*/, + OUString &rText, const IntlWrapper& /*rIntl*/ ) const +{ + rText = EditResId( !GetValue() + ? RID_SVXITEMS_SCRPTSPC_OFF + : RID_SVXITEMS_SCRPTSPC_ON ); + return true; +} + + +SvxHangingPunctuationItem::SvxHangingPunctuationItem( + bool bOn, const sal_uInt16 nId ) + : SfxBoolItem( nId, bOn ) +{ +} + +SvxHangingPunctuationItem* SvxHangingPunctuationItem::Clone( SfxItemPool * ) const +{ + return new SvxHangingPunctuationItem( *this ); +} + +bool SvxHangingPunctuationItem::GetPresentation( + SfxItemPresentation /*ePres*/, + MapUnit /*eCoreMetric*/, MapUnit /*ePresMetric*/, + OUString &rText, const IntlWrapper& /*rIntl*/ ) const +{ + rText = EditResId( !GetValue() + ? RID_SVXITEMS_HNGPNCT_OFF + : RID_SVXITEMS_HNGPNCT_ON ); + return true; +} + + +SvxForbiddenRuleItem::SvxForbiddenRuleItem( + bool bOn, const sal_uInt16 nId ) + : SfxBoolItem( nId, bOn ) +{ +} + +SvxForbiddenRuleItem* SvxForbiddenRuleItem::Clone( SfxItemPool * ) const +{ + return new SvxForbiddenRuleItem( *this ); +} + +bool SvxForbiddenRuleItem::GetPresentation( + SfxItemPresentation /*ePres*/, + MapUnit /*eCoreMetric*/, MapUnit /*ePresMetric*/, + OUString &rText, const IntlWrapper& /*rIntl*/ ) const +{ + rText = EditResId( !GetValue() + ? RID_SVXITEMS_FORBIDDEN_RULE_OFF + : RID_SVXITEMS_FORBIDDEN_RULE_ON ); + return true; +} + +/************************************************************************* +|* class SvxParaVertAlignItem +*************************************************************************/ + +SvxParaVertAlignItem::SvxParaVertAlignItem( Align nValue, + const sal_uInt16 nW ) + : SfxUInt16Item( nW, static_cast<sal_uInt16>(nValue) ) +{ +} + +SvxParaVertAlignItem* SvxParaVertAlignItem::Clone( SfxItemPool* ) const +{ + return new SvxParaVertAlignItem( *this ); +} + +bool SvxParaVertAlignItem::GetPresentation( + SfxItemPresentation /*ePres*/, + MapUnit /*eCoreMetric*/, MapUnit /*ePresMetric*/, + OUString &rText, const IntlWrapper& ) const +{ + TranslateId pTmp; + switch( GetValue() ) + { + case Align::Automatic: pTmp = RID_SVXITEMS_PARAVERTALIGN_AUTO; break; + case Align::Top: pTmp = RID_SVXITEMS_PARAVERTALIGN_TOP; break; + case Align::Center: pTmp = RID_SVXITEMS_PARAVERTALIGN_CENTER; break; + case Align::Bottom: pTmp = RID_SVXITEMS_PARAVERTALIGN_BOTTOM; break; + default: pTmp = RID_SVXITEMS_PARAVERTALIGN_BASELINE; break; + } + rText = EditResId(pTmp); + return true; +} + +bool SvxParaVertAlignItem::QueryValue( css::uno::Any& rVal, + sal_uInt8 /*nMemberId*/ ) const +{ + rVal <<= static_cast<sal_Int16>(GetValue()); + return true; +} + +bool SvxParaVertAlignItem::PutValue( const css::uno::Any& rVal, + sal_uInt8 /*nMemberId*/ ) +{ + sal_Int16 nVal = sal_Int16(); + if((rVal >>= nVal) && nVal >=0 && nVal <= sal_uInt16(Align::Bottom) ) + { + SetValue( static_cast<Align>(nVal) ); + return true; + } + else + return false; +} + +SvxParaGridItem::SvxParaGridItem( bool bOn, const sal_uInt16 nId ) + : SfxBoolItem( nId, bOn ) +{ +} + +SvxParaGridItem* SvxParaGridItem::Clone( SfxItemPool * ) const +{ + return new SvxParaGridItem( *this ); +} + +bool SvxParaGridItem::GetPresentation( + SfxItemPresentation /*ePres*/, + MapUnit /*eCoreMetric*/, MapUnit /*ePresMetric*/, + OUString &rText, const IntlWrapper& /*rIntl*/ ) const +{ + rText = GetValue() ? + EditResId( RID_SVXITEMS_PARASNAPTOGRID_ON ) : + EditResId( RID_SVXITEMS_PARASNAPTOGRID_OFF ); + + return true; +} + + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/editeng/source/items/svdfield.cxx b/editeng/source/items/svdfield.cxx new file mode 100644 index 000000000..a9b78148c --- /dev/null +++ b/editeng/source/items/svdfield.cxx @@ -0,0 +1,34 @@ +/* -*- 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 <editeng/measfld.hxx> + +SdrMeasureField::~SdrMeasureField() {} + +std::unique_ptr<SvxFieldData> SdrMeasureField::Clone() const +{ + return std::make_unique<SdrMeasureField>(*this); +} + +bool SdrMeasureField::operator==(const SvxFieldData& rSrc) const +{ + return eMeasureFieldKind == static_cast<const SdrMeasureField&>(rSrc).GetMeasureFieldKind(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/editeng/source/items/svxfont.cxx b/editeng/source/items/svxfont.cxx new file mode 100644 index 000000000..ca8c5f3fd --- /dev/null +++ b/editeng/source/items/svxfont.cxx @@ -0,0 +1,860 @@ +/* -*- 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 <editeng/svxfont.hxx> + +#include <vcl/glyphitemcache.hxx> +#include <vcl/metric.hxx> +#include <vcl/outdev.hxx> +#include <vcl/print.hxx> +#include <tools/debug.hxx> +#include <tools/gen.hxx> +#include <tools/poly.hxx> +#include <unotools/charclass.hxx> +#include <com/sun/star/i18n/KCharacterType.hpp> +#include <editeng/escapementitem.hxx> +#include <sal/log.hxx> +#include <limits> + +static tools::Long GetTextArray( const OutputDevice* pOut, const OUString& rStr, std::vector<sal_Int32>* pDXAry, + sal_Int32 nIndex, sal_Int32 nLen ) + +{ + const SalLayoutGlyphs* layoutGlyphs = SalLayoutGlyphsCache::self()->GetLayoutGlyphs(pOut, rStr, nIndex, nLen); + return pOut->GetTextArray( rStr, pDXAry, nIndex, nLen, nullptr, layoutGlyphs); +} + +SvxFont::SvxFont() +{ + nKern = nEsc = 0; + nPropr = 100; + eCaseMap = SvxCaseMap::NotMapped; + SetLanguage(LANGUAGE_SYSTEM); +} + +SvxFont::SvxFont( const vcl::Font &rFont ) + : Font( rFont ) +{ + nKern = nEsc = 0; + nPropr = 100; + eCaseMap = SvxCaseMap::NotMapped; + SetLanguage(LANGUAGE_SYSTEM); +} + +SvxFont::SvxFont( const SvxFont &rFont ) + : Font( rFont ) +{ + nKern = rFont.GetFixKerning(); + nEsc = rFont.GetEscapement(); + nPropr = rFont.GetPropr(); + eCaseMap = rFont.GetCaseMap(); + SetLanguage(rFont.GetLanguage()); +} + +void SvxFont::SetNonAutoEscapement(short nNewEsc, const OutputDevice* pOutDev) +{ + nEsc = nNewEsc; + if ( abs(nEsc) == DFLT_ESC_AUTO_SUPER ) + { + double fAutoAscent = .8; + double fAutoDescent = .2; + if ( pOutDev ) + { + const FontMetric& rFontMetric = pOutDev->GetFontMetric(); + double fFontHeight = rFontMetric.GetAscent() + rFontMetric.GetDescent(); + if ( fFontHeight ) + { + fAutoAscent = rFontMetric.GetAscent() / fFontHeight; + fAutoDescent = rFontMetric.GetDescent() / fFontHeight; + } + } + + if ( nEsc == DFLT_ESC_AUTO_SUPER ) + nEsc = fAutoAscent * (100 - nPropr); + else //DFLT_ESC_AUTO_SUB + nEsc = fAutoDescent * -(100 - nPropr); + } + + if ( nEsc > MAX_ESC_POS ) + nEsc = MAX_ESC_POS; + else if ( nEsc < -MAX_ESC_POS ) + nEsc = -MAX_ESC_POS; +} + +tools::Polygon SvxFont::DrawArrow( OutputDevice &rOut, const tools::Rectangle& rRect, + const Size& rSize, const Color& rCol, bool bLeftOrTop, bool bVertical ) +{ + tools::Polygon aPoly; + Point aTmp; + Point aNxt; + if (bVertical) + { + tools::Long nLeft = ((rRect.Left() + rRect.Right()) / 2) - (rSize.Height() / 2); + tools::Long nRight = ((rRect.Left() + rRect.Right()) / 2) + (rSize.Height() / 2); + tools::Long nMid = (rRect.Left() + rRect.Right()) / 2; + tools::Long nTop = ((rRect.Top() + rRect.Bottom()) / 2) - (rSize.Height() / 2); + tools::Long nBottom = nTop + rSize.Height(); + if (nTop < rRect.Top()) + { + if (bLeftOrTop) + { + nTop = rRect.Top(); + nBottom = rRect.Bottom(); + } + else + { + nTop = rRect.Bottom(); + nBottom = rRect.Bottom() - (rSize.Height() / 2); + } + } + aTmp.setX(nRight); + aTmp.setY(nBottom); + aNxt.setX(nMid); + aNxt.setY(nTop); + aPoly.Insert(0, aTmp); + aPoly.Insert(0, aNxt); + aTmp.setX(nLeft); + aPoly.Insert(0, aTmp); + } + else + { + tools::Long nLeft = (rRect.Left() + rRect.Right() - rSize.Width()) / 2; + tools::Long nRight = nLeft + rSize.Width(); + tools::Long nMid = (rRect.Top() + rRect.Bottom()) / 2; + tools::Long nTop = nMid - rSize.Height() / 2; + tools::Long nBottom = nTop + rSize.Height(); + if (nLeft < rRect.Left()) + { + nLeft = rRect.Left(); + nRight = rRect.Right(); + } + aTmp.setX(bLeftOrTop ? nLeft : nRight); + aTmp.setY(nMid); + aNxt.setX(bLeftOrTop ? nRight : nLeft); + aNxt.setY(nTop); + aPoly.Insert(0, aTmp); + aPoly.Insert(0, aNxt); + aNxt.setY(nBottom); + aPoly.Insert(0, aNxt); + } + Color aOldLineColor = rOut.GetLineColor(); + Color aOldFillColor = rOut.GetFillColor(); + rOut.SetFillColor( rCol ); + rOut.SetLineColor( COL_BLACK ); + rOut.DrawPolygon( aPoly ); + rOut.DrawLine( aTmp, aNxt ); + rOut.SetLineColor( aOldLineColor ); + rOut.SetFillColor( aOldFillColor ); + return aPoly; +} + +OUString SvxFont::CalcCaseMap(const OUString &rTxt) const +{ + if (!IsCaseMap() || rTxt.isEmpty()) + return rTxt; + OUString aTxt(rTxt); + // I still have to get the language + const LanguageType eLang = LANGUAGE_DONTKNOW == GetLanguage() + ? LANGUAGE_SYSTEM : GetLanguage(); + + CharClass aCharClass(( LanguageTag(eLang) )); + + switch( eCaseMap ) + { + case SvxCaseMap::SmallCaps: + case SvxCaseMap::Uppercase: + { + aTxt = aCharClass.uppercase( aTxt ); + break; + } + + case SvxCaseMap::Lowercase: + { + aTxt = aCharClass.lowercase( aTxt ); + break; + } + case SvxCaseMap::Capitalize: + { + // Every beginning of a word is capitalized, the rest of the word + // is taken over as is. + // Bug: if the attribute starts in the middle of the word. + bool bBlank = true; + + for (sal_Int32 i = 0; i < aTxt.getLength(); ++i) + { + if( aTxt[i] == ' ' || aTxt[i] == '\t') + bBlank = true; + else + { + if (bBlank) + { + OUString sTitle(aCharClass.uppercase(OUString(aTxt[i]))); + aTxt = aTxt.replaceAt(i, 1, sTitle); + } + bBlank = false; + } + } + break; + } + default: + { + SAL_WARN( "editeng", "SvxFont::CaseMapTxt: unknown casemap"); + break; + } + } + return aTxt; +} + +/************************************************************************* + * class SvxDoCapitals + * The virtual Method Do si called by SvxFont::DoOnCapitals alternately + * the uppercase and lowercase parts. The derivate of SvxDoCapitals fills + * this method with life. + *************************************************************************/ + +class SvxDoCapitals +{ +protected: + VclPtr<OutputDevice> pOut; + const OUString &rTxt; + const sal_Int32 nIdx; + const sal_Int32 nLen; + +public: + SvxDoCapitals( OutputDevice *_pOut, const OUString &_rTxt, + const sal_Int32 _nIdx, const sal_Int32 _nLen ) + : pOut(_pOut), rTxt(_rTxt), nIdx(_nIdx), nLen(_nLen) + { } + + virtual ~SvxDoCapitals() {} + + virtual void DoSpace( const bool bDraw ); + virtual void SetSpace(); + virtual void Do( const OUString &rTxt, + const sal_Int32 nIdx, const sal_Int32 nLen, + const bool bUpper ) = 0; + + const OUString &GetTxt() const { return rTxt; } + sal_Int32 GetIdx() const { return nIdx; } + sal_Int32 GetLen() const { return nLen; } +}; + +void SvxDoCapitals::DoSpace( const bool /*bDraw*/ ) { } + +void SvxDoCapitals::SetSpace() { } + +/************************************************************************* + * SvxFont::DoOnCapitals() const + * Decomposes the String into uppercase and lowercase letters and then + * calls the method SvxDoCapitals::Do( ). + *************************************************************************/ + +void SvxFont::DoOnCapitals(SvxDoCapitals &rDo) const +{ + const OUString &rTxt = rDo.GetTxt(); + const sal_Int32 nIdx = rDo.GetIdx(); + const sal_Int32 nLen = rDo.GetLen(); + + const OUString aTxt( CalcCaseMap( rTxt ) ); + const sal_Int32 nTxtLen = std::min( rTxt.getLength(), nLen ); + sal_Int32 nPos = 0; + sal_Int32 nOldPos = nPos; + + // Test if string length differ between original and CaseMapped + bool bCaseMapLengthDiffers(aTxt.getLength() != rTxt.getLength()); + + const LanguageType eLang = LANGUAGE_DONTKNOW == GetLanguage() + ? LANGUAGE_SYSTEM : GetLanguage(); + + CharClass aCharClass(( LanguageTag(eLang) )); + OUString aCharString; + + while( nPos < nTxtLen ) + { + // first in turn are the uppercase letters + + // There are characters that are both upper- and lower-case L (eg blank) + // Such ambiguities lead to chaos, this is why these characters are + // allocated to the lowercase characters! + + while( nPos < nTxtLen ) + { + aCharString = rTxt.copy( nPos + nIdx, 1 ); + sal_Int32 nCharacterType = aCharClass.getCharacterType( aCharString, 0 ); + if ( nCharacterType & css::i18n::KCharacterType::LOWER ) + break; + if ( ! ( nCharacterType & css::i18n::KCharacterType::UPPER ) ) + break; + ++nPos; + } + if( nOldPos != nPos ) + { + if(bCaseMapLengthDiffers) + { + // If strings differ work preparing the necessary snippet to address that + // potential difference + const OUString aSnippet = rTxt.copy(nIdx + nOldPos, nPos-nOldPos); + OUString aNewText = CalcCaseMap(aSnippet); + + rDo.Do( aNewText, 0, aNewText.getLength(), true ); + } + else + { + rDo.Do( aTxt, nIdx + nOldPos, nPos-nOldPos, true ); + } + + nOldPos = nPos; + } + // Now the lowercase are processed (without blanks) + while( nPos < nTxtLen ) + { + sal_uInt32 nCharacterType = aCharClass.getCharacterType( aCharString, 0 ); + if ( nCharacterType & css::i18n::KCharacterType::UPPER ) + break; + if ( aCharString == " " ) + break; + if( ++nPos < nTxtLen ) + aCharString = rTxt.copy( nPos + nIdx, 1 ); + } + if( nOldPos != nPos ) + { + if(bCaseMapLengthDiffers) + { + // If strings differ work preparing the necessary snippet to address that + // potential difference + const OUString aSnippet = rTxt.copy(nIdx + nOldPos, nPos - nOldPos); + OUString aNewText = CalcCaseMap(aSnippet); + + rDo.Do( aNewText, 0, aNewText.getLength(), false ); + } + else + { + rDo.Do( aTxt, nIdx + nOldPos, nPos-nOldPos, false ); + } + + nOldPos = nPos; + } + // Now the blanks are<processed + while( nPos < nTxtLen && aCharString == " " && ++nPos < nTxtLen ) + aCharString = rTxt.copy( nPos + nIdx, 1 ); + + if( nOldPos != nPos ) + { + rDo.DoSpace( false ); + + if(bCaseMapLengthDiffers) + { + // If strings differ work preparing the necessary snippet to address that + // potential difference + const OUString aSnippet = rTxt.copy(nIdx + nOldPos, nPos - nOldPos); + OUString aNewText = CalcCaseMap(aSnippet); + + rDo.Do( aNewText, 0, aNewText.getLength(), false ); + } + else + { + rDo.Do( aTxt, nIdx + nOldPos, nPos - nOldPos, false ); + } + + nOldPos = nPos; + rDo.SetSpace(); + } + } + rDo.DoSpace( true ); +} + + +void SvxFont::SetPhysFont(OutputDevice& rOut) const +{ + const vcl::Font& rCurrentFont = rOut.GetFont(); + if ( nPropr == 100 ) + { + if ( !rCurrentFont.IsSameInstance( *this ) ) + rOut.SetFont( *this ); + } + else + { + Font aNewFont( *this ); + Size aSize( aNewFont.GetFontSize() ); + aNewFont.SetFontSize( Size( aSize.Width() * nPropr / 100, + aSize.Height() * nPropr / 100 ) ); + if ( !rCurrentFont.IsSameInstance( aNewFont ) ) + rOut.SetFont( aNewFont ); + } +} + +vcl::Font SvxFont::ChgPhysFont(OutputDevice& rOut) const +{ + vcl::Font aOldFont(rOut.GetFont()); + SetPhysFont(rOut); + return aOldFont; +} + +Size SvxFont::GetPhysTxtSize( const OutputDevice *pOut, const OUString &rTxt, + const sal_Int32 nIdx, const sal_Int32 nLen ) const +{ + if ( !IsCaseMap() && !IsKern() ) + return Size( pOut->GetTextWidth( rTxt, nIdx, nLen ), + pOut->GetTextHeight() ); + + Size aTxtSize; + aTxtSize.setHeight( pOut->GetTextHeight() ); + if ( !IsCaseMap() ) + aTxtSize.setWidth( pOut->GetTextWidth( rTxt, nIdx, nLen ) ); + else + { + const OUString aNewText = CalcCaseMap(rTxt); + bool bCaseMapLengthDiffers(aNewText.getLength() != rTxt.getLength()); + sal_Int32 nWidth(0); + + if(bCaseMapLengthDiffers) + { + // If strings differ work preparing the necessary snippet to address that + // potential difference + const OUString aSnippet = rTxt.copy(nIdx, nLen); + OUString _aNewText = CalcCaseMap(aSnippet); + nWidth = pOut->GetTextWidth( _aNewText, 0, _aNewText.getLength() ); + } + else + { + nWidth = pOut->GetTextWidth( aNewText, nIdx, nLen ); + } + + aTxtSize.setWidth(nWidth); + } + + if( IsKern() && ( nLen > 1 ) ) + { + std::vector<sal_Int32> aDXArray(nLen); + GetTextArray(pOut, rTxt, &aDXArray, nIdx, nLen); + tools::Long nOldValue = aDXArray[0]; + sal_Int32 nSpaceCount = 0; + for(sal_Int32 i = 1; i < nLen; ++i) + { + if (aDXArray[i] != nOldValue) + { + nOldValue = aDXArray[i]; + ++nSpaceCount; + } + } + aTxtSize.AdjustWidth( nSpaceCount * tools::Long( nKern ) ); + } + + return aTxtSize; +} + +Size SvxFont::GetPhysTxtSize( const OutputDevice *pOut ) +{ + if ( !IsCaseMap() && !IsKern() ) + return Size( pOut->GetTextWidth( "" ), pOut->GetTextHeight() ); + + Size aTxtSize; + aTxtSize.setHeight( pOut->GetTextHeight() ); + if ( !IsCaseMap() ) + aTxtSize.setWidth( pOut->GetTextWidth( "" ) ); + else + aTxtSize.setWidth( pOut->GetTextWidth( CalcCaseMap( "" ) ) ); + + return aTxtSize; +} + +Size SvxFont::QuickGetTextSize( const OutputDevice *pOut, const OUString &rTxt, + const sal_Int32 nIdx, const sal_Int32 nLen, std::vector<sal_Int32>* pDXArray ) const +{ + if ( !IsCaseMap() && !IsKern() ) + return Size( GetTextArray( pOut, rTxt, pDXArray, nIdx, nLen ), + pOut->GetTextHeight() ); + + std::vector<sal_Int32> aDXArray; + + // We always need pDXArray to count the number of kern spaces + if (!pDXArray && IsKern() && nLen > 1) + { + pDXArray = &aDXArray; + aDXArray.reserve(nLen); + } + + Size aTxtSize; + aTxtSize.setHeight( pOut->GetTextHeight() ); + if ( !IsCaseMap() ) + aTxtSize.setWidth( GetTextArray( pOut, rTxt, pDXArray, nIdx, nLen ) ); + else + aTxtSize.setWidth( GetTextArray( pOut, CalcCaseMap( rTxt ), + pDXArray, nIdx, nLen ) ); + + if( IsKern() && ( nLen > 1 ) ) + { + tools::Long nOldValue = (*pDXArray)[0]; + tools::Long nSpaceSum = nKern; + (*pDXArray)[0] += nSpaceSum; + + for ( sal_Int32 i = 1; i < nLen; i++ ) + { + if ( (*pDXArray)[i] != nOldValue ) + { + nOldValue = (*pDXArray)[i]; + nSpaceSum += nKern; + } + (*pDXArray)[i] += nSpaceSum; + } + + // The last one is a nKern too big: + nOldValue = (*pDXArray)[nLen - 1]; + tools::Long nNewValue = nOldValue - nKern; + for ( sal_Int32 i = nLen - 1; i >= 0 && (*pDXArray)[i] == nOldValue; --i) + (*pDXArray)[i] = nNewValue; + + aTxtSize.AdjustWidth(nSpaceSum - nKern); + } + + return aTxtSize; +} + +Size SvxFont::GetTextSize(const OutputDevice& rOut, const OUString &rTxt, + const sal_Int32 nIdx, const sal_Int32 nLen) const +{ + sal_Int32 nTmp = nLen; + if ( nTmp == SAL_MAX_INT32 ) // already initialized? + nTmp = rTxt.getLength(); + Font aOldFont( ChgPhysFont(const_cast<OutputDevice&>(rOut))); + Size aTxtSize; + if( IsCapital() && !rTxt.isEmpty() ) + { + aTxtSize = GetCapitalSize(&rOut, rTxt, nIdx, nTmp); + } + else aTxtSize = GetPhysTxtSize(&rOut,rTxt,nIdx,nTmp); + const_cast<OutputDevice&>(rOut).SetFont(aOldFont); + return aTxtSize; +} + +static void DrawTextArray( OutputDevice* pOut, const Point& rStartPt, const OUString& rStr, + o3tl::span<const sal_Int32> pDXAry, + sal_Int32 nIndex, sal_Int32 nLen ) +{ + const SalLayoutGlyphs* layoutGlyphs = SalLayoutGlyphsCache::self()->GetLayoutGlyphs(pOut, rStr, nIndex, nLen); + pOut->DrawTextArray(rStartPt, rStr, pDXAry, nIndex, nLen, SalLayoutFlags::NONE, layoutGlyphs); +} + +void SvxFont::QuickDrawText( OutputDevice *pOut, + const Point &rPos, const OUString &rTxt, + const sal_Int32 nIdx, const sal_Int32 nLen, o3tl::span<const sal_Int32> pDXArray ) const +{ + + // Font has to be selected in OutputDevice... + if ( !IsCaseMap() && !IsCapital() && !IsKern() && !IsEsc() ) + { + DrawTextArray( pOut, rPos, rTxt, pDXArray, nIdx, nLen ); + return; + } + + Point aPos( rPos ); + + if ( nEsc ) + { + tools::Long nDiff = GetFontSize().Height(); + nDiff *= nEsc; + nDiff /= 100; + + if ( !IsVertical() ) + aPos.AdjustY( -nDiff ); + else + aPos.AdjustX(nDiff ); + } + + if( IsCapital() ) + { + DBG_ASSERT( pDXArray.empty(), "DrawCapital not for TextArray!" ); + DrawCapital( pOut, aPos, rTxt, nIdx, nLen ); + } + else + { + if ( IsKern() && pDXArray.empty() ) + { + Size aSize = GetPhysTxtSize( pOut, rTxt, nIdx, nLen ); + + if ( !IsCaseMap() ) + pOut->DrawStretchText( aPos, aSize.Width(), rTxt, nIdx, nLen ); + else + pOut->DrawStretchText( aPos, aSize.Width(), CalcCaseMap( rTxt ), nIdx, nLen ); + } + else + { + if ( !IsCaseMap() ) + DrawTextArray( pOut, aPos, rTxt, pDXArray, nIdx, nLen ); + else + DrawTextArray( pOut, aPos, CalcCaseMap( rTxt ), pDXArray, nIdx, nLen ); + } + } +} + + +void SvxFont::DrawPrev( OutputDevice *pOut, Printer* pPrinter, + const Point &rPos, const OUString &rTxt, + const sal_Int32 nIdx, const sal_Int32 nLen ) const +{ + if ( !nLen || rTxt.isEmpty() ) + return; + sal_Int32 nTmp = nLen; + + if ( nTmp == SAL_MAX_INT32 ) // already initialized? + nTmp = rTxt.getLength(); + Point aPos( rPos ); + + if ( nEsc ) + { + short nTmpEsc; + if( DFLT_ESC_AUTO_SUPER == nEsc ) + { + nTmpEsc = .8 * (100 - nPropr); + assert (nTmpEsc == DFLT_ESC_SUPER && "I'm sure this formula needs to be changed, but how to confirm that???"); + nTmpEsc = DFLT_ESC_SUPER; + } + else if( DFLT_ESC_AUTO_SUB == nEsc ) + { + nTmpEsc = .2 * -(100 - nPropr); + assert (nTmpEsc == -20 && "I'm sure this formula needs to be changed, but how to confirm that???"); + nTmpEsc = -20; + } + else + nTmpEsc = nEsc; + Size aSize = GetFontSize(); + aPos.AdjustY( -(( nTmpEsc * aSize.Height() ) / 100) ); + } + Font aOldFont( ChgPhysFont(*pOut) ); + Font aOldPrnFont( ChgPhysFont(*pPrinter) ); + + if ( IsCapital() ) + DrawCapital( pOut, aPos, rTxt, nIdx, nTmp ); + else + { + Size aSize = GetPhysTxtSize( pPrinter, rTxt, nIdx, nTmp ); + + if ( !IsCaseMap() ) + pOut->DrawStretchText( aPos, aSize.Width(), rTxt, nIdx, nTmp ); + else + { + const OUString aNewText = CalcCaseMap(rTxt); + bool bCaseMapLengthDiffers(aNewText.getLength() != rTxt.getLength()); + + if(bCaseMapLengthDiffers) + { + // If strings differ work preparing the necessary snippet to address that + // potential difference + const OUString aSnippet(rTxt.copy( nIdx, nTmp)); + OUString _aNewText = CalcCaseMap(aSnippet); + + pOut->DrawStretchText( aPos, aSize.Width(), _aNewText, 0, _aNewText.getLength() ); + } + else + { + pOut->DrawStretchText( aPos, aSize.Width(), CalcCaseMap( rTxt ), nIdx, nTmp ); + } + } + } + pOut->SetFont(aOldFont); + pPrinter->SetFont( aOldPrnFont ); +} + + +SvxFont& SvxFont::operator=( const vcl::Font& rFont ) +{ + Font::operator=( rFont ); + return *this; +} + +SvxFont& SvxFont::operator=( const SvxFont& rFont ) +{ + Font::operator=( rFont ); + eCaseMap = rFont.eCaseMap; + nEsc = rFont.nEsc; + nPropr = rFont.nPropr; + nKern = rFont.nKern; + return *this; +} + +namespace { + +class SvxDoGetCapitalSize : public SvxDoCapitals +{ +protected: + SvxFont* pFont; + Size aTxtSize; + short nKern; +public: + SvxDoGetCapitalSize( SvxFont *_pFnt, const OutputDevice *_pOut, + const OUString &_rTxt, const sal_Int32 _nIdx, + const sal_Int32 _nLen, const short _nKrn ) + : SvxDoCapitals( const_cast<OutputDevice*>(_pOut), _rTxt, _nIdx, _nLen ), + pFont( _pFnt ), + nKern( _nKrn ) + { } + + virtual void Do( const OUString &rTxt, const sal_Int32 nIdx, + const sal_Int32 nLen, const bool bUpper ) override; + + const Size &GetSize() const { return aTxtSize; }; +}; + +} + +void SvxDoGetCapitalSize::Do( const OUString &_rTxt, const sal_Int32 _nIdx, + const sal_Int32 _nLen, const bool bUpper ) +{ + Size aPartSize; + if ( !bUpper ) + { + sal_uInt8 nProp = pFont->GetPropr(); + pFont->SetProprRel( SMALL_CAPS_PERCENTAGE ); + pFont->SetPhysFont( *pOut ); + aPartSize.setWidth( pOut->GetTextWidth( _rTxt, _nIdx, _nLen ) ); + aPartSize.setHeight( pOut->GetTextHeight() ); + aTxtSize.setHeight( aPartSize.Height() ); + pFont->SetPropr( nProp ); + pFont->SetPhysFont( *pOut ); + } + else + { + aPartSize.setWidth( pOut->GetTextWidth( _rTxt, _nIdx, _nLen ) ); + aPartSize.setHeight( pOut->GetTextHeight() ); + } + aTxtSize.AdjustWidth(aPartSize.Width() ); + aTxtSize.AdjustWidth( _nLen * tools::Long( nKern ) ); +} + +Size SvxFont::GetCapitalSize( const OutputDevice *pOut, const OUString &rTxt, + const sal_Int32 nIdx, const sal_Int32 nLen) const +{ + // Start: + SvxDoGetCapitalSize aDo( const_cast<SvxFont *>(this), pOut, rTxt, nIdx, nLen, nKern ); + DoOnCapitals( aDo ); + Size aTxtSize( aDo.GetSize() ); + + // End: + if( !aTxtSize.Height() ) + { + aTxtSize.setWidth( 0 ); + aTxtSize.setHeight( pOut->GetTextHeight() ); + } + return aTxtSize; +} + +namespace { + +class SvxDoDrawCapital : public SvxDoCapitals +{ +protected: + SvxFont *pFont; + Point aPos; + Point aSpacePos; + short nKern; +public: + SvxDoDrawCapital( SvxFont *pFnt, OutputDevice *_pOut, const OUString &_rTxt, + const sal_Int32 _nIdx, const sal_Int32 _nLen, + const Point &rPos, const short nKrn ) + : SvxDoCapitals( _pOut, _rTxt, _nIdx, _nLen ), + pFont( pFnt ), + aPos( rPos ), + aSpacePos( rPos ), + nKern( nKrn ) + { } + virtual void DoSpace( const bool bDraw ) override; + virtual void SetSpace() override; + virtual void Do( const OUString &rTxt, const sal_Int32 nIdx, + const sal_Int32 nLen, const bool bUpper ) override; +}; + +} + +void SvxDoDrawCapital::DoSpace( const bool bDraw ) +{ + if ( !(bDraw || pFont->IsWordLineMode()) ) + return; + + sal_uLong nDiff = static_cast<sal_uLong>(aPos.X() - aSpacePos.X()); + if ( nDiff ) + { + bool bWordWise = pFont->IsWordLineMode(); + bool bTrans = pFont->IsTransparent(); + pFont->SetWordLineMode( false ); + pFont->SetTransparent( true ); + pFont->SetPhysFont(*pOut); + pOut->DrawStretchText( aSpacePos, nDiff, " ", 0, 2 ); + pFont->SetWordLineMode( bWordWise ); + pFont->SetTransparent( bTrans ); + pFont->SetPhysFont(*pOut); + } +} + +void SvxDoDrawCapital::SetSpace() +{ + if ( pFont->IsWordLineMode() ) + aSpacePos.setX( aPos.X() ); +} + +void SvxDoDrawCapital::Do( const OUString &_rTxt, const sal_Int32 _nIdx, + const sal_Int32 _nLen, const bool bUpper) +{ + sal_uInt8 nProp = 0; + Size aPartSize; + + // Set the desired font + FontLineStyle eUnder = pFont->GetUnderline(); + FontStrikeout eStrike = pFont->GetStrikeout(); + pFont->SetUnderline( LINESTYLE_NONE ); + pFont->SetStrikeout( STRIKEOUT_NONE ); + if ( !bUpper ) + { + nProp = pFont->GetPropr(); + pFont->SetProprRel( SMALL_CAPS_PERCENTAGE ); + } + pFont->SetPhysFont(*pOut); + + aPartSize.setWidth( pOut->GetTextWidth( _rTxt, _nIdx, _nLen ) ); + aPartSize.setHeight( pOut->GetTextHeight() ); + tools::Long nWidth = aPartSize.Width(); + if ( nKern ) + { + aPos.AdjustX(nKern/2); + if ( _nLen ) nWidth += (_nLen*tools::Long(nKern)); + } + pOut->DrawStretchText(aPos,nWidth-nKern,_rTxt,_nIdx,_nLen); + + // Restore Font + pFont->SetUnderline( eUnder ); + pFont->SetStrikeout( eStrike ); + if ( !bUpper ) + pFont->SetPropr( nProp ); + pFont->SetPhysFont(*pOut); + + aPos.AdjustX(nWidth-(nKern/2) ); +} + +/************************************************************************* + * SvxFont::DrawCapital() draws the uppercase letter. + *************************************************************************/ + +void SvxFont::DrawCapital( OutputDevice *pOut, + const Point &rPos, const OUString &rTxt, + const sal_Int32 nIdx, const sal_Int32 nLen ) const +{ + SvxDoDrawCapital aDo( const_cast<SvxFont *>(this),pOut,rTxt,nIdx,nLen,rPos,nKern ); + DoOnCapitals( aDo ); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/editeng/source/items/textitem.cxx b/editeng/source/items/textitem.cxx new file mode 100644 index 000000000..147fa301d --- /dev/null +++ b/editeng/source/items/textitem.cxx @@ -0,0 +1,2774 @@ +/* -*- 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/style/CaseMap.hpp> +#include <com/sun/star/awt/FontDescriptor.hpp> +#include <com/sun/star/frame/status/FontHeight.hpp> +#include <math.h> +#include <sal/log.hxx> +#include <o3tl/safeint.hxx> +#include <osl/diagnose.h> +#include <unotools/fontdefs.hxx> +#include <unotools/intlwrapper.hxx> +#include <unotools/syslocale.hxx> +#include <utility> +#include <vcl/outdev.hxx> +#include <vcl/unohelp.hxx> +#include <svtools/unitconv.hxx> + +#include <editeng/editids.hrc> +#include <editeng/editrids.hrc> +#include <tools/bigint.hxx> +#include <tools/mapunit.hxx> +#include <tools/UnitConversion.hxx> + +#include <rtl/math.hxx> +#include <rtl/ustring.hxx> +#include <i18nlangtag/languagetag.hxx> +#include <svl/itemset.hxx> + +#include <svtools/langtab.hxx> +#include <svl/itempool.hxx> +#include <svtools/ctrltool.hxx> +#include <com/sun/star/awt/FontSlant.hpp> +#include <com/sun/star/lang/Locale.hpp> +#include <com/sun/star/text/FontEmphasis.hpp> +#include <editeng/rsiditem.hxx> +#include <editeng/memberids.h> +#include <editeng/flstitem.hxx> +#include <editeng/fontitem.hxx> +#include <editeng/postitem.hxx> +#include <editeng/wghtitem.hxx> +#include <editeng/fhgtitem.hxx> +#include <editeng/udlnitem.hxx> +#include <editeng/crossedoutitem.hxx> +#include <editeng/shdditem.hxx> +#include <editeng/autokernitem.hxx> +#include <editeng/wrlmitem.hxx> +#include <editeng/contouritem.hxx> +#include <editeng/colritem.hxx> +#include <editeng/kernitem.hxx> +#include <editeng/cmapitem.hxx> +#include <editeng/escapementitem.hxx> +#include <editeng/langitem.hxx> +#include <editeng/nhypitem.hxx> +#include <editeng/blinkitem.hxx> +#include <editeng/emphasismarkitem.hxx> +#include <editeng/twolinesitem.hxx> +#include <editeng/scripttypeitem.hxx> +#include <editeng/charrotateitem.hxx> +#include <editeng/charscaleitem.hxx> +#include <editeng/charreliefitem.hxx> +#include <editeng/itemtype.hxx> +#include <editeng/eerdll.hxx> +#include <libxml/xmlwriter.h> + +using namespace ::com::sun::star; +using namespace ::com::sun::star::text; + +SfxPoolItem* SvxFontItem::CreateDefault() {return new SvxFontItem(0);} +SfxPoolItem* SvxPostureItem::CreateDefault() { return new SvxPostureItem(ITALIC_NONE, 0);} +SfxPoolItem* SvxWeightItem::CreateDefault() {return new SvxWeightItem(WEIGHT_NORMAL, 0);} +SfxPoolItem* SvxFontHeightItem::CreateDefault() {return new SvxFontHeightItem(240, 100, 0);} +SfxPoolItem* SvxUnderlineItem::CreateDefault() {return new SvxUnderlineItem(LINESTYLE_NONE, 0);} +SfxPoolItem* SvxOverlineItem::CreateDefault() {return new SvxOverlineItem(LINESTYLE_NONE, 0);} +SfxPoolItem* SvxCrossedOutItem::CreateDefault() {return new SvxCrossedOutItem(STRIKEOUT_NONE, 0);} +SfxPoolItem* SvxShadowedItem::CreateDefault() {return new SvxShadowedItem(false, 0);} +SfxPoolItem* SvxAutoKernItem::CreateDefault() {return new SvxAutoKernItem(false, 0);} +SfxPoolItem* SvxWordLineModeItem::CreateDefault() {return new SvxWordLineModeItem(false, 0);} +SfxPoolItem* SvxContourItem::CreateDefault() {return new SvxContourItem(false, 0);} +SfxPoolItem* SvxColorItem::CreateDefault() {return new SvxColorItem(0);} +SfxPoolItem* SvxKerningItem::CreateDefault() {return new SvxKerningItem(0, 0);} +SfxPoolItem* SvxCaseMapItem::CreateDefault() {return new SvxCaseMapItem(SvxCaseMap::NotMapped, 0);} +SfxPoolItem* SvxEscapementItem::CreateDefault() {return new SvxEscapementItem(0);} +SfxPoolItem* SvxLanguageItem::CreateDefault() {return new SvxLanguageItem(LANGUAGE_GERMAN, 0);} +SfxPoolItem* SvxEmphasisMarkItem::CreateDefault() {return new SvxEmphasisMarkItem(FontEmphasisMark::NONE, 0);} +SfxPoolItem* SvxCharRotateItem::CreateDefault() {return new SvxCharRotateItem(0_deg10, false, 0);} +SfxPoolItem* SvxCharScaleWidthItem::CreateDefault() {return new SvxCharScaleWidthItem(100, 0);} +SfxPoolItem* SvxCharReliefItem::CreateDefault() {return new SvxCharReliefItem(FontRelief::NONE, 0);} + + +// class SvxFontListItem ------------------------------------------------- + +SvxFontListItem::SvxFontListItem( const FontList* pFontLst, + const sal_uInt16 nId ) : + SfxPoolItem( nId ), + pFontList( pFontLst ) +{ + if ( pFontList ) + { + sal_Int32 nCount = pFontList->GetFontNameCount(); + aFontNameSeq.realloc( nCount ); + auto pFontNameSeq = aFontNameSeq.getArray(); + + for ( sal_Int32 i = 0; i < nCount; i++ ) + pFontNameSeq[i] = pFontList->GetFontName(i).GetFamilyName(); + } +} + +SvxFontListItem* SvxFontListItem::Clone( SfxItemPool* ) const +{ + return new SvxFontListItem( *this ); +} + +bool SvxFontListItem::operator==( const SfxPoolItem& rAttr ) const +{ + assert(SfxPoolItem::operator==(rAttr)); + + return( pFontList == static_cast<const SvxFontListItem&>(rAttr).pFontList ); +} + +bool SvxFontListItem::QueryValue( css::uno::Any& rVal, sal_uInt8 /*nMemberId*/ ) const +{ + rVal <<= aFontNameSeq; + return true; +} + + +bool SvxFontListItem::GetPresentation +( + SfxItemPresentation /*ePres*/, + MapUnit /*eCoreUnit*/, + MapUnit /*ePresUnit*/, + OUString& rText, const IntlWrapper& /*rIntl*/ +) const +{ + rText.clear(); + return false; +} + +// class SvxFontItem ----------------------------------------------------- + +namespace +{ +sal_Int32 CompareTo(sal_Int32 nA, sal_Int32 nB) +{ + if (nA < nB) + { + return -1; + } + + if (nA > nB) + { + return 1; + } + + return 0; +} +} + +SvxFontItem::SvxFontItem( const sal_uInt16 nId ) : + SfxPoolItem( nId ) +{ + eFamily = FAMILY_SWISS; + ePitch = PITCH_VARIABLE; + eTextEncoding = RTL_TEXTENCODING_DONTKNOW; +} + + +SvxFontItem::SvxFontItem( const FontFamily eFam, OUString aName, + OUString aStName, const FontPitch eFontPitch, + const rtl_TextEncoding eFontTextEncoding, const sal_uInt16 nId ) : + + SfxPoolItem( nId ), + + aFamilyName(std::move(aName)), + aStyleName(std::move(aStName)) +{ + eFamily = eFam; + ePitch = eFontPitch; + eTextEncoding = eFontTextEncoding; +} + + +bool SvxFontItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const +{ + nMemberId &= ~CONVERT_TWIPS; + switch(nMemberId) + { + case 0: + { + css::awt::FontDescriptor aFontDescriptor; + aFontDescriptor.Name = aFamilyName; + aFontDescriptor.StyleName = aStyleName; + aFontDescriptor.Family = static_cast<sal_Int16>(eFamily); + aFontDescriptor.CharSet = static_cast<sal_Int16>(eTextEncoding); + aFontDescriptor.Pitch = static_cast<sal_Int16>(ePitch); + rVal <<= aFontDescriptor; + } + break; + case MID_FONT_FAMILY_NAME: + rVal <<= aFamilyName; + break; + case MID_FONT_STYLE_NAME: + rVal <<= aStyleName; + break; + case MID_FONT_FAMILY : rVal <<= static_cast<sal_Int16>(eFamily); break; + case MID_FONT_CHAR_SET : rVal <<= static_cast<sal_Int16>(eTextEncoding); break; + case MID_FONT_PITCH : rVal <<= static_cast<sal_Int16>(ePitch); break; + } + return true; +} + +bool SvxFontItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId) +{ + nMemberId &= ~CONVERT_TWIPS; + switch(nMemberId) + { + case 0: + { + css::awt::FontDescriptor aFontDescriptor; + if ( !( rVal >>= aFontDescriptor )) + return false; + + aFamilyName = aFontDescriptor.Name; + aStyleName = aFontDescriptor.StyleName; + eFamily = static_cast<FontFamily>(aFontDescriptor.Family); + eTextEncoding = static_cast<rtl_TextEncoding>(aFontDescriptor.CharSet); + ePitch = static_cast<FontPitch>(aFontDescriptor.Pitch); + } + break; + case MID_FONT_FAMILY_NAME : + { + OUString aStr; + if(!(rVal >>= aStr)) + return false; + aFamilyName = aStr; + } + break; + case MID_FONT_STYLE_NAME: + { + OUString aStr; + if(!(rVal >>= aStr)) + return false; + aStyleName = aStr; + } + break; + case MID_FONT_FAMILY : + { + sal_Int16 nFamily = sal_Int16(); + if(!(rVal >>= nFamily)) + return false; + eFamily = static_cast<FontFamily>(nFamily); + } + break; + case MID_FONT_CHAR_SET : + { + sal_Int16 nSet = sal_Int16(); + if(!(rVal >>= nSet)) + return false; + eTextEncoding = static_cast<rtl_TextEncoding>(nSet); + } + break; + case MID_FONT_PITCH : + { + sal_Int16 nPitch = sal_Int16(); + if(!(rVal >>= nPitch)) + return false; + ePitch = static_cast<FontPitch>(nPitch); + } + break; + } + return true; +} + + +bool SvxFontItem::operator==( const SfxPoolItem& rAttr ) const +{ + assert(SfxPoolItem::operator==(rAttr)); + + const SvxFontItem& rItem = static_cast<const SvxFontItem&>(rAttr); + + bool bRet = ( eFamily == rItem.eFamily && + aFamilyName == rItem.aFamilyName && + aStyleName == rItem.aStyleName ); + + if ( bRet ) + { + if ( ePitch != rItem.ePitch || eTextEncoding != rItem.eTextEncoding ) + { + bRet = false; + SAL_INFO( "editeng.items", "FontItem::operator==(): only pitch or rtl_TextEncoding different "); + } + } + return bRet; +} + +bool SvxFontItem::operator<(const SfxPoolItem& rCmp) const +{ + const auto& rOther = static_cast<const SvxFontItem&>(rCmp); + sal_Int32 nRet = GetFamilyName().compareTo(rOther.GetFamilyName()); + if (nRet != 0) + { + return nRet < 0; + } + + nRet = GetStyleName().compareTo(rOther.GetStyleName()); + if (nRet != 0) + { + return nRet < 0; + } + + nRet = CompareTo(GetFamily(), rOther.GetFamily()); + if (nRet != 0) + { + return nRet < 0; + } + + nRet = CompareTo(GetPitch(), rOther.GetPitch()); + if (nRet != 0) + { + return nRet < 0; + } + + return GetCharSet() < rOther.GetCharSet(); +} + +SvxFontItem* SvxFontItem::Clone( SfxItemPool * ) const +{ + return new SvxFontItem( *this ); +} + +bool SvxFontItem::GetPresentation +( + SfxItemPresentation /*ePres*/, + MapUnit /*eCoreUnit*/, + MapUnit /*ePresUnit*/, + OUString& rText, const IntlWrapper& /*rIntl*/ +) const +{ + rText = aFamilyName; + return true; +} + + +void SvxFontItem::dumpAsXml(xmlTextWriterPtr pWriter) const +{ + (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SvxFontItem")); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr())); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("familyName"), BAD_CAST(aFamilyName.toUtf8().getStr())); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("styleName"), BAD_CAST(aStyleName.toUtf8().getStr())); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("family"), BAD_CAST(OString::number(eFamily).getStr())); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("pitch"), BAD_CAST(OString::number(ePitch).getStr())); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("textEncoding"), BAD_CAST(OString::number(eTextEncoding).getStr())); + (void)xmlTextWriterEndElement(pWriter); +} + +// class SvxPostureItem -------------------------------------------------- + +SvxPostureItem::SvxPostureItem( const FontItalic ePosture, const sal_uInt16 nId ) : + SfxEnumItem( nId, ePosture ) +{ +} + +SvxPostureItem* SvxPostureItem::Clone( SfxItemPool * ) const +{ + return new SvxPostureItem( *this ); +} + +sal_uInt16 SvxPostureItem::GetValueCount() const +{ + return ITALIC_NORMAL + 1; // ITALIC_NONE also belongs here +} + + +bool SvxPostureItem::GetPresentation +( + SfxItemPresentation /*ePres*/, + MapUnit /*eCoreUnit*/, + MapUnit /*ePresUnit*/, + OUString& rText, const IntlWrapper& /*rIntl*/ +) const +{ + rText = GetValueTextByPos( GetValue() ); + return true; +} + + +OUString SvxPostureItem::GetValueTextByPos( sal_uInt16 nPos ) +{ + DBG_ASSERT( nPos <= sal_uInt16(ITALIC_NORMAL), "enum overflow!" ); + + FontItalic eItalic = static_cast<FontItalic>(nPos); + TranslateId pId; + + switch ( eItalic ) + { + case ITALIC_NONE: pId = RID_SVXITEMS_ITALIC_NONE; break; + case ITALIC_OBLIQUE: pId = RID_SVXITEMS_ITALIC_OBLIQUE; break; + case ITALIC_NORMAL: pId = RID_SVXITEMS_ITALIC_NORMAL; break; + default: ;//prevent warning + } + + return pId ? EditResId(pId) : OUString(); +} + +bool SvxPostureItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const +{ + nMemberId &= ~CONVERT_TWIPS; + switch( nMemberId ) + { + case MID_ITALIC: + rVal <<= GetBoolValue(); + break; + case MID_POSTURE: + rVal <<= vcl::unohelper::ConvertFontSlant(GetValue()); + break; + } + return true; +} + +bool SvxPostureItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId ) +{ + nMemberId &= ~CONVERT_TWIPS; + switch( nMemberId ) + { + case MID_ITALIC: + SetBoolValue(Any2Bool(rVal)); + break; + case MID_POSTURE: + { + awt::FontSlant eSlant; + if(!(rVal >>= eSlant)) + { + sal_Int32 nValue = 0; + if(!(rVal >>= nValue)) + return false; + + eSlant = static_cast<awt::FontSlant>(nValue); + } + SetValue(vcl::unohelper::ConvertFontSlant(eSlant)); + } + } + return true; +} + +bool SvxPostureItem::HasBoolValue() const +{ + return true; +} + +bool SvxPostureItem::GetBoolValue() const +{ + return ( GetValue() >= ITALIC_OBLIQUE ); +} + +void SvxPostureItem::SetBoolValue( bool bVal ) +{ + SetValue( bVal ? ITALIC_NORMAL : ITALIC_NONE ); +} + +void SvxPostureItem::dumpAsXml(xmlTextWriterPtr pWriter) const +{ + (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SvxPostureItem")); + (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("whichId"), "%d", Which()); + (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("value"), "%d", GetValue()); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("presentation"), BAD_CAST(GetValueTextByPos(GetValue()).toUtf8().getStr())); + (void)xmlTextWriterEndElement(pWriter); +} + +// class SvxWeightItem --------------------------------------------------- + +SvxWeightItem::SvxWeightItem( const FontWeight eWght, const sal_uInt16 nId ) : + SfxEnumItem( nId, eWght ) +{ +} + + +bool SvxWeightItem::HasBoolValue() const +{ + return true; +} + + +bool SvxWeightItem::GetBoolValue() const +{ + return GetValue() >= WEIGHT_BOLD; +} + + +void SvxWeightItem::SetBoolValue( bool bVal ) +{ + SetValue( bVal ? WEIGHT_BOLD : WEIGHT_NORMAL ); +} + + +sal_uInt16 SvxWeightItem::GetValueCount() const +{ + return WEIGHT_BLACK; // WEIGHT_DONTKNOW does not belong +} + +SvxWeightItem* SvxWeightItem::Clone( SfxItemPool * ) const +{ + return new SvxWeightItem( *this ); +} + +bool SvxWeightItem::GetPresentation +( + SfxItemPresentation /*ePres*/, + MapUnit /*eCoreUnit*/, + MapUnit /*ePresUnit*/, + OUString& rText, const IntlWrapper& /*rIntl*/ +) const +{ + rText = GetValueTextByPos( GetValue() ); + return true; +} + +OUString SvxWeightItem::GetValueTextByPos( sal_uInt16 nPos ) +{ + static TranslateId RID_SVXITEMS_WEIGHTS[] = + { + RID_SVXITEMS_WEIGHT_DONTKNOW, + RID_SVXITEMS_WEIGHT_THIN, + RID_SVXITEMS_WEIGHT_ULTRALIGHT, + RID_SVXITEMS_WEIGHT_LIGHT, + RID_SVXITEMS_WEIGHT_SEMILIGHT, + RID_SVXITEMS_WEIGHT_NORMAL, + RID_SVXITEMS_WEIGHT_MEDIUM, + RID_SVXITEMS_WEIGHT_SEMIBOLD, + RID_SVXITEMS_WEIGHT_BOLD, + RID_SVXITEMS_WEIGHT_ULTRABOLD, + RID_SVXITEMS_WEIGHT_BLACK + }; + + static_assert(SAL_N_ELEMENTS(RID_SVXITEMS_WEIGHTS) - 1 == WEIGHT_BLACK, "must match"); + assert(nPos <= sal_uInt16(WEIGHT_BLACK) && "enum overflow!" ); + return EditResId(RID_SVXITEMS_WEIGHTS[nPos]); +} + +bool SvxWeightItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const +{ + nMemberId &= ~CONVERT_TWIPS; + switch( nMemberId ) + { + case MID_BOLD : + rVal <<= GetBoolValue(); + break; + case MID_WEIGHT: + { + rVal <<= vcl::unohelper::ConvertFontWeight( GetValue() ); + } + break; + } + return true; +} + +bool SvxWeightItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId ) +{ + nMemberId &= ~CONVERT_TWIPS; + switch( nMemberId ) + { + case MID_BOLD : + SetBoolValue(Any2Bool(rVal)); + break; + case MID_WEIGHT: + { + double fValue = 0; + if(!(rVal >>= fValue)) + { + sal_Int32 nValue = 0; + if(!(rVal >>= nValue)) + return false; + fValue = static_cast<float>(nValue); + } + SetValue( vcl::unohelper::ConvertFontWeight(static_cast<float>(fValue)) ); + } + break; + } + return true; +} + +void SvxWeightItem::dumpAsXml(xmlTextWriterPtr pWriter) const +{ + (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SvxWeightItem")); + (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("whichId"), "%d", Which()); + (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("value"), "%d", GetValue()); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("presentation"), BAD_CAST(GetValueTextByPos(GetValue()).toUtf8().getStr())); + (void)xmlTextWriterEndElement(pWriter); +} + +// class SvxFontHeightItem ----------------------------------------------- + +SvxFontHeightItem::SvxFontHeightItem( const sal_uInt32 nSz, + const sal_uInt16 nPrp, + const sal_uInt16 nId ) : + SfxPoolItem( nId ) +{ + SetHeight( nSz,nPrp ); // calculate in percentage +} + +SvxFontHeightItem* SvxFontHeightItem::Clone( SfxItemPool * ) const +{ + return new SvxFontHeightItem( *this ); +} + +bool SvxFontHeightItem::operator==( const SfxPoolItem& rItem ) const +{ + assert(SfxPoolItem::operator==(rItem)); + return GetHeight() == static_cast<const SvxFontHeightItem&>(rItem).GetHeight() && + GetProp() == static_cast<const SvxFontHeightItem&>(rItem).GetProp() && + GetPropUnit() == static_cast<const SvxFontHeightItem&>(rItem).GetPropUnit(); +} + +bool SvxFontHeightItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const +{ + // In StarOne is the uno::Any always 1/100mm. Through the MemberId it is + // controlled if the value in the Item should be 1/100mm or Twips. + + bool bConvert = 0!=(nMemberId&CONVERT_TWIPS); + nMemberId &= ~CONVERT_TWIPS; + switch( nMemberId ) + { + case 0: + { + css::frame::status::FontHeight aFontHeight; + + // Point (i.e. Twips) is asked for, thus re-calculate if + // CONVERT_TWIPS is not set. + if( bConvert ) + { + aFontHeight.Height = o3tl::convert<double>(nHeight, o3tl::Length::twip, o3tl::Length::pt); + } + else + { + double fPoints = o3tl::convert<double>(nHeight, o3tl::Length::mm100, o3tl::Length::pt); + aFontHeight.Height = rtl::math::round(fPoints, 1); + } + + aFontHeight.Prop = MapUnit::MapRelative == ePropUnit ? nProp : 100; + + float fRet = nProp; + switch( ePropUnit ) + { + case MapUnit::MapRelative: + fRet = 0.; + break; + case MapUnit::Map100thMM: + fRet = o3tl::convert(fRet, o3tl::Length::mm100, o3tl::Length::pt); + break; + case MapUnit::MapPoint: + + break; + case MapUnit::MapTwip: + fRet = o3tl::convert(fRet, o3tl::Length::twip, o3tl::Length::pt); + break; + default: ;//prevent warning + } + aFontHeight.Diff = fRet; + rVal <<= aFontHeight; + } + break; + case MID_FONTHEIGHT: + { + // Point (i.e. Twips) is asked for, thus re-calculate if + // CONVERT_TWIPS is not set. + if( bConvert ) + { + rVal <<= static_cast<float>(o3tl::convert<double>(nHeight, o3tl::Length::twip, o3tl::Length::pt)); + } + else + { + double fPoints = o3tl::convert<double>(nHeight, o3tl::Length::mm100, o3tl::Length::pt); + rVal <<= static_cast<float>(::rtl::math::round(fPoints, 1)); + } + } + break; + case MID_FONTHEIGHT_PROP: + rVal <<= static_cast<sal_Int16>(MapUnit::MapRelative == ePropUnit ? nProp : 100); + break; + case MID_FONTHEIGHT_DIFF: + { + float fRet = nProp; + switch( ePropUnit ) + { + case MapUnit::MapRelative: + fRet = 0.; + break; + case MapUnit::Map100thMM: + fRet = o3tl::convert(fRet, o3tl::Length::mm100, o3tl::Length::pt); + break; + case MapUnit::MapPoint: + + break; + case MapUnit::MapTwip: + fRet = o3tl::convert(fRet, o3tl::Length::twip, o3tl::Length::pt); + break; + default: ;//prevent warning + } + rVal <<= fRet; + } + break; + } + return true; +} + +// Try to reconstruct the original height input value from the modified height +// and the prop data; this seems somewhat futile given the various ways how the +// modified height is calculated (with and without conversion between twips and +// 100th mm; with an additional eCoreMetric input in one of the SetHeight +// overloads), and indeed known to occasionally produce nRet values that would +// be negative, so just guard against negative results here and throw the hands +// up in despair: +static sal_uInt32 lcl_GetRealHeight_Impl(sal_uInt32 nHeight, sal_uInt16 nProp, MapUnit eProp, bool bCoreInTwip) +{ + sal_uInt32 nRet = nHeight; + short nDiff = 0; + switch( eProp ) + { + case MapUnit::MapRelative: + if (nProp) + { + nRet *= 100; + nRet /= nProp; + } + break; + case MapUnit::MapPoint: + { + short nTemp = static_cast<short>(nProp); + nDiff = nTemp * 20; + if(!bCoreInTwip) + nDiff = static_cast<short>(convertTwipToMm100(static_cast<tools::Long>(nDiff))); + break; + } + case MapUnit::Map100thMM: + //then the core is surely also in 1/100 mm + nDiff = static_cast<short>(nProp); + break; + case MapUnit::MapTwip: + // Here surely TWIP + nDiff = static_cast<short>(nProp); + break; + default: + break; + } + nRet = (nDiff < 0 || nRet >= o3tl::make_unsigned(nDiff)) + ? nRet - nDiff : 0; + //TODO: overflow in case nDiff < 0 and nRet - nDiff > SAL_MAX_UINT32 + + return nRet; +} + +bool SvxFontHeightItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId ) +{ + bool bConvert = 0!=(nMemberId&CONVERT_TWIPS); + nMemberId &= ~CONVERT_TWIPS; + switch( nMemberId ) + { + case 0: + { + css::frame::status::FontHeight aFontHeight; + if ( rVal >>= aFontHeight ) + { + // Height + ePropUnit = MapUnit::MapRelative; + nProp = 100; + double fPoint = aFontHeight.Height; + if( fPoint < 0. || fPoint > 10000. ) + return false; + + nHeight = static_cast<tools::Long>( fPoint * 20.0 + 0.5 ); // Twips + if (!bConvert) + nHeight = convertTwipToMm100(nHeight); // Convert, if the item contains 1/100mm + + nProp = aFontHeight.Prop; + } + else + return false; + } + break; + case MID_FONTHEIGHT: + { + ePropUnit = MapUnit::MapRelative; + nProp = 100; + double fPoint = 0; + if(!(rVal >>= fPoint)) + { + sal_Int32 nValue = 0; + if(!(rVal >>= nValue)) + return false; + fPoint = static_cast<float>(nValue); + } + if(fPoint < 0. || fPoint > 10000.) + return false; + + nHeight = static_cast<tools::Long>( fPoint * 20.0 + 0.5 ); // Twips + if (!bConvert) + nHeight = convertTwipToMm100(nHeight); // Convert, if the item contains 1/100mm + } + break; + case MID_FONTHEIGHT_PROP: + { + sal_Int16 nNew = sal_Int16(); + if(!(rVal >>= nNew)) + return true; + + nHeight = lcl_GetRealHeight_Impl(nHeight, nProp, ePropUnit, bConvert); + + nHeight *= nNew; + nHeight /= 100; + nProp = nNew; + ePropUnit = MapUnit::MapRelative; + } + break; + case MID_FONTHEIGHT_DIFF: + { + nHeight = lcl_GetRealHeight_Impl(nHeight, nProp, ePropUnit, bConvert); + float fValue = 0; + if(!(rVal >>= fValue)) + { + sal_Int32 nValue = 0; + if(!(rVal >>= nValue)) + return false; + fValue = static_cast<float>(nValue); + } + sal_Int16 nCoreDiffValue = static_cast<sal_Int16>(fValue * 20.); + nHeight += bConvert ? nCoreDiffValue : convertTwipToMm100(nCoreDiffValue); + nProp = static_cast<sal_uInt16>(static_cast<sal_Int16>(fValue)); + ePropUnit = MapUnit::MapPoint; + } + break; + } + return true; +} + + +bool SvxFontHeightItem::GetPresentation +( + SfxItemPresentation /*ePres*/, + MapUnit eCoreUnit, + MapUnit /*ePresUnit*/, + OUString& rText, const IntlWrapper& rIntl +) const +{ + if( MapUnit::MapRelative != ePropUnit ) + { + rText = OUString::number( static_cast<short>(nProp) ) + + " " + EditResId( GetMetricId( ePropUnit ) ); + if( 0 <= static_cast<short>(nProp) ) + rText = "+" + rText; + } + else if( 100 == nProp ) + { + rText = GetMetricText( static_cast<tools::Long>(nHeight), + eCoreUnit, MapUnit::MapPoint, &rIntl ) + + " " + EditResId(GetMetricId(MapUnit::MapPoint)); + } + else + rText = OUString::number( nProp ) + "%"; + return true; +} + + +void SvxFontHeightItem::ScaleMetrics( tools::Long nMult, tools::Long nDiv ) +{ + nHeight = static_cast<sal_uInt32>(BigInt::Scale( nHeight, nMult, nDiv )); +} + + +bool SvxFontHeightItem::HasMetrics() const +{ + return true; +} + +void SvxFontHeightItem::SetHeight( sal_uInt32 nNewHeight, const sal_uInt16 nNewProp, + MapUnit eUnit ) +{ + DBG_ASSERT( GetRefCount() == 0, "SetValue() with pooled item" ); + + if( MapUnit::MapRelative != eUnit ) + nHeight = nNewHeight + ::ItemToControl( short(nNewProp), eUnit, + FieldUnit::TWIP ); + else if( 100 != nNewProp ) + nHeight = sal_uInt32(( nNewHeight * nNewProp ) / 100 ); + else + nHeight = nNewHeight; + + nProp = nNewProp; + ePropUnit = eUnit; +} + +void SvxFontHeightItem::SetHeight( sal_uInt32 nNewHeight, sal_uInt16 nNewProp, + MapUnit eMetric, MapUnit eCoreMetric ) +{ + DBG_ASSERT( GetRefCount() == 0, "SetValue() with pooled item" ); + + if( MapUnit::MapRelative != eMetric ) + nHeight = nNewHeight + + ::ControlToItem( ::ItemToControl(static_cast<short>(nNewProp), eMetric, + FieldUnit::TWIP ), FieldUnit::TWIP, + eCoreMetric ); + else if( 100 != nNewProp ) + nHeight = sal_uInt32(( nNewHeight * nNewProp ) / 100 ); + else + nHeight = nNewHeight; + + nProp = nNewProp; + ePropUnit = eMetric; +} + +void SvxFontHeightItem::dumpAsXml(xmlTextWriterPtr pWriter) const +{ + (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SvxFontHeightItem")); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr())); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("height"), BAD_CAST(OString::number(nHeight).getStr())); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("prop"), BAD_CAST(OString::number(nProp).getStr())); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("propUnit"), BAD_CAST(OString::number(static_cast<int>(ePropUnit)).getStr())); + (void)xmlTextWriterEndElement(pWriter); +} + +// class SvxTextLineItem ------------------------------------------------ + +SvxTextLineItem::SvxTextLineItem( const FontLineStyle eSt, const sal_uInt16 nId ) + : SfxEnumItem( nId, eSt ), mColor( COL_TRANSPARENT ) +{ +} + + +bool SvxTextLineItem::HasBoolValue() const +{ + return true; +} + + +bool SvxTextLineItem::GetBoolValue() const +{ + return GetValue() != LINESTYLE_NONE; +} + + +void SvxTextLineItem::SetBoolValue( bool bVal ) +{ + SetValue( bVal ? LINESTYLE_SINGLE : LINESTYLE_NONE ); +} + +SvxTextLineItem* SvxTextLineItem::Clone( SfxItemPool * ) const +{ + return new SvxTextLineItem( *this ); +} + +sal_uInt16 SvxTextLineItem::GetValueCount() const +{ + return LINESTYLE_DOTTED + 1; // LINESTYLE_NONE also belongs here +} + + +bool SvxTextLineItem::GetPresentation +( + SfxItemPresentation /*ePres*/, + MapUnit /*eCoreUnit*/, + MapUnit /*ePresUnit*/, + OUString& rText, const IntlWrapper& /*rIntl*/ +) const +{ + rText = GetValueTextByPos( GetValue() ); + if( !mColor.IsTransparent() ) + rText += cpDelim + ::GetColorString( mColor ); + return true; +} + + +OUString SvxTextLineItem::GetValueTextByPos( sal_uInt16 /*nPos*/ ) const +{ + OSL_FAIL("SvxTextLineItem::GetValueTextByPos: Pure virtual method"); + return OUString(); +} + +bool SvxTextLineItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const +{ + nMemberId &= ~CONVERT_TWIPS; + switch(nMemberId) + { + case MID_TEXTLINED: + rVal <<= GetBoolValue(); + break; + case MID_TL_STYLE: + rVal <<= static_cast<sal_Int16>(GetValue()); + break; + case MID_TL_COLOR: + rVal <<= mColor; + break; + case MID_TL_HASCOLOR: + rVal <<= mColor.GetAlpha() == 255; + break; + } + return true; + +} + +bool SvxTextLineItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId ) +{ + nMemberId &= ~CONVERT_TWIPS; + bool bRet = true; + switch(nMemberId) + { + case MID_TEXTLINED: + SetBoolValue(Any2Bool(rVal)); + break; + case MID_TL_STYLE: + { + sal_Int32 nValue = 0; + if(!(rVal >>= nValue)) + bRet = false; + else + SetValue(static_cast<FontLineStyle>(nValue)); + } + break; + case MID_TL_COLOR: + { + Color nCol; + if( !( rVal >>= nCol ) ) + bRet = false; + else + { + // Keep transparence, because it contains the information + // whether the font color or the stored color should be used + sal_uInt8 nAlpha = mColor.GetAlpha(); + mColor = nCol; + mColor.SetAlpha( nAlpha ); + } + } + break; + case MID_TL_HASCOLOR: + mColor.SetAlpha( Any2Bool( rVal ) ? 255 : 0 ); + break; + } + return bRet; +} + +bool SvxTextLineItem::operator==( const SfxPoolItem& rItem ) const +{ + return SfxEnumItem::operator==( rItem ) && + GetColor() == static_cast<const SvxTextLineItem&>(rItem).GetColor(); +} + +// class SvxUnderlineItem ------------------------------------------------ + + +SvxUnderlineItem::SvxUnderlineItem( const FontLineStyle eSt, const sal_uInt16 nId ) + : SvxTextLineItem( eSt, nId ) +{ +} + +SvxUnderlineItem* SvxUnderlineItem::Clone( SfxItemPool * ) const +{ + return new SvxUnderlineItem( *this ); +} + +OUString SvxUnderlineItem::GetValueTextByPos( sal_uInt16 nPos ) const +{ + static TranslateId RID_SVXITEMS_UL[] = + { + RID_SVXITEMS_UL_NONE, + RID_SVXITEMS_UL_SINGLE, + RID_SVXITEMS_UL_DOUBLE, + RID_SVXITEMS_UL_DOTTED, + RID_SVXITEMS_UL_DONTKNOW, + RID_SVXITEMS_UL_DASH, + RID_SVXITEMS_UL_LONGDASH, + RID_SVXITEMS_UL_DASHDOT, + RID_SVXITEMS_UL_DASHDOTDOT, + RID_SVXITEMS_UL_SMALLWAVE, + RID_SVXITEMS_UL_WAVE, + RID_SVXITEMS_UL_DOUBLEWAVE, + RID_SVXITEMS_UL_BOLD, + RID_SVXITEMS_UL_BOLDDOTTED, + RID_SVXITEMS_UL_BOLDDASH, + RID_SVXITEMS_UL_BOLDLONGDASH, + RID_SVXITEMS_UL_BOLDDASHDOT, + RID_SVXITEMS_UL_BOLDDASHDOTDOT, + RID_SVXITEMS_UL_BOLDWAVE + }; + static_assert(SAL_N_ELEMENTS(RID_SVXITEMS_UL) - 1 == LINESTYLE_BOLDWAVE, "must match"); + assert(nPos <= sal_uInt16(LINESTYLE_BOLDWAVE) && "enum overflow!"); + return EditResId(RID_SVXITEMS_UL[nPos]); +} + +// class SvxOverlineItem ------------------------------------------------ + +SvxOverlineItem::SvxOverlineItem( const FontLineStyle eSt, const sal_uInt16 nId ) + : SvxTextLineItem( eSt, nId ) +{ +} + +SvxOverlineItem* SvxOverlineItem::Clone( SfxItemPool * ) const +{ + return new SvxOverlineItem( *this ); +} + +OUString SvxOverlineItem::GetValueTextByPos( sal_uInt16 nPos ) const +{ + static TranslateId RID_SVXITEMS_OL[] = + { + RID_SVXITEMS_OL_NONE, + RID_SVXITEMS_OL_SINGLE, + RID_SVXITEMS_OL_DOUBLE, + RID_SVXITEMS_OL_DOTTED, + RID_SVXITEMS_OL_DONTKNOW, + RID_SVXITEMS_OL_DASH, + RID_SVXITEMS_OL_LONGDASH, + RID_SVXITEMS_OL_DASHDOT, + RID_SVXITEMS_OL_DASHDOTDOT, + RID_SVXITEMS_OL_SMALLWAVE, + RID_SVXITEMS_OL_WAVE, + RID_SVXITEMS_OL_DOUBLEWAVE, + RID_SVXITEMS_OL_BOLD, + RID_SVXITEMS_OL_BOLDDOTTED, + RID_SVXITEMS_OL_BOLDDASH, + RID_SVXITEMS_OL_BOLDLONGDASH, + RID_SVXITEMS_OL_BOLDDASHDOT, + RID_SVXITEMS_OL_BOLDDASHDOTDOT, + RID_SVXITEMS_OL_BOLDWAVE + }; + static_assert(SAL_N_ELEMENTS(RID_SVXITEMS_OL) - 1 == LINESTYLE_BOLDWAVE, "must match"); + assert(nPos <= sal_uInt16(LINESTYLE_BOLDWAVE) && "enum overflow!"); + return EditResId(RID_SVXITEMS_OL[nPos]); +} + +// class SvxCrossedOutItem ----------------------------------------------- + +SvxCrossedOutItem::SvxCrossedOutItem( const FontStrikeout eSt, const sal_uInt16 nId ) + : SfxEnumItem( nId, eSt ) +{ +} + + +bool SvxCrossedOutItem::HasBoolValue() const +{ + return true; +} + + +bool SvxCrossedOutItem::GetBoolValue() const +{ + return GetValue() != STRIKEOUT_NONE; +} + + +void SvxCrossedOutItem::SetBoolValue( bool bVal ) +{ + SetValue( bVal ? STRIKEOUT_SINGLE : STRIKEOUT_NONE ); +} + + +sal_uInt16 SvxCrossedOutItem::GetValueCount() const +{ + return STRIKEOUT_DOUBLE + 1; // STRIKEOUT_NONE belongs also here +} + +SvxCrossedOutItem* SvxCrossedOutItem::Clone( SfxItemPool * ) const +{ + return new SvxCrossedOutItem( *this ); +} + +bool SvxCrossedOutItem::GetPresentation +( + SfxItemPresentation /*ePres*/, + MapUnit /*eCoreUnit*/, + MapUnit /*ePresUnit*/, + OUString& rText, const IntlWrapper& /*rIntl*/ +) const +{ + rText = GetValueTextByPos( GetValue() ); + return true; +} + +OUString SvxCrossedOutItem::GetValueTextByPos( sal_uInt16 nPos ) +{ + static TranslateId RID_SVXITEMS_STRIKEOUT[] = + { + RID_SVXITEMS_STRIKEOUT_NONE, + RID_SVXITEMS_STRIKEOUT_SINGLE, + RID_SVXITEMS_STRIKEOUT_DOUBLE, + RID_SVXITEMS_STRIKEOUT_DONTKNOW, + RID_SVXITEMS_STRIKEOUT_BOLD, + RID_SVXITEMS_STRIKEOUT_SLASH, + RID_SVXITEMS_STRIKEOUT_X + }; + static_assert(SAL_N_ELEMENTS(RID_SVXITEMS_STRIKEOUT) - 1 == STRIKEOUT_X, "must match"); + assert(nPos <= sal_uInt16(STRIKEOUT_X) && "enum overflow!"); + return EditResId(RID_SVXITEMS_STRIKEOUT[nPos]); +} + +bool SvxCrossedOutItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const +{ + nMemberId &= ~CONVERT_TWIPS; + switch(nMemberId) + { + case MID_CROSSED_OUT: + rVal <<= GetBoolValue(); + break; + case MID_CROSS_OUT: + rVal <<= static_cast<sal_Int16>(GetValue()); + break; + } + return true; +} + +bool SvxCrossedOutItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId ) +{ + nMemberId &= ~CONVERT_TWIPS; + switch(nMemberId) + { + case MID_CROSSED_OUT: + SetBoolValue(Any2Bool(rVal)); + break; + case MID_CROSS_OUT: + { + sal_Int32 nValue = 0; + if(!(rVal >>= nValue)) + return false; + SetValue(static_cast<FontStrikeout>(nValue)); + } + break; + } + return true; +} +// class SvxShadowedItem ------------------------------------------------- + +SvxShadowedItem::SvxShadowedItem( const bool bShadowed, const sal_uInt16 nId ) : + SfxBoolItem( nId, bShadowed ) +{ +} + +SvxShadowedItem* SvxShadowedItem::Clone( SfxItemPool * ) const +{ + return new SvxShadowedItem( *this ); +} + +bool SvxShadowedItem::GetPresentation +( + SfxItemPresentation /*ePres*/, + MapUnit /*eCoreUnit*/, + MapUnit /*ePresUnit*/, + OUString& rText, const IntlWrapper& /*rIntl*/ +) const +{ + TranslateId pId = RID_SVXITEMS_SHADOWED_FALSE; + + if ( GetValue() ) + pId = RID_SVXITEMS_SHADOWED_TRUE; + rText = EditResId(pId); + return true; +} + +// class SvxAutoKernItem ------------------------------------------------- + +SvxAutoKernItem::SvxAutoKernItem( const bool bAutoKern, const sal_uInt16 nId ) : + SfxBoolItem( nId, bAutoKern ) +{ +} + +SvxAutoKernItem* SvxAutoKernItem::Clone( SfxItemPool * ) const +{ + return new SvxAutoKernItem( *this ); +} + +bool SvxAutoKernItem::GetPresentation +( + SfxItemPresentation /*ePres*/, + MapUnit /*eCoreUnit*/, + MapUnit /*ePresUnit*/, + OUString& rText, const IntlWrapper& /*rIntl*/ +) const +{ + TranslateId pId = RID_SVXITEMS_AUTOKERN_FALSE; + + if ( GetValue() ) + pId = RID_SVXITEMS_AUTOKERN_TRUE; + rText = EditResId(pId); + return true; +} + +// class SvxWordLineModeItem --------------------------------------------- + +SvxWordLineModeItem::SvxWordLineModeItem( const bool bWordLineMode, + const sal_uInt16 nId ) : + SfxBoolItem( nId, bWordLineMode ) +{ +} + +SvxWordLineModeItem* SvxWordLineModeItem::Clone( SfxItemPool * ) const +{ + return new SvxWordLineModeItem( *this ); +} + +bool SvxWordLineModeItem::GetPresentation +( + SfxItemPresentation /*ePres*/, + MapUnit /*eCoreUnit*/, + MapUnit /*ePresUnit*/, + OUString& rText, const IntlWrapper& /*rIntl*/ +) const +{ + TranslateId pId = RID_SVXITEMS_WORDLINE_FALSE; + + if ( GetValue() ) + pId = RID_SVXITEMS_WORDLINE_TRUE; + rText = EditResId(pId); + return true; +} + +// class SvxContourItem -------------------------------------------------- + +SvxContourItem::SvxContourItem( const bool bContoured, const sal_uInt16 nId ) : + SfxBoolItem( nId, bContoured ) +{ +} + +SvxContourItem* SvxContourItem::Clone( SfxItemPool * ) const +{ + return new SvxContourItem( *this ); +} + +bool SvxContourItem::GetPresentation +( + SfxItemPresentation /*ePres*/, + MapUnit /*eCoreUnit*/, + MapUnit /*ePresUnit*/, + OUString& rText, const IntlWrapper& /*rIntl*/ +) const +{ + TranslateId pId = RID_SVXITEMS_CONTOUR_FALSE; + + if ( GetValue() ) + pId = RID_SVXITEMS_CONTOUR_TRUE; + rText = EditResId(pId); + return true; +} + +SvxThemeColor::SvxThemeColor() + : maThemeIndex(-1), + mnLumMod(10000), + mnLumOff(0) +{ +} + +bool SvxThemeColor::operator==(const SvxThemeColor& rThemeColor) const +{ + return maThemeIndex == rThemeColor.maThemeIndex && + mnLumMod == rThemeColor.mnLumMod && + mnLumOff == rThemeColor.mnLumOff; +} + +void SvxThemeColor::dumpAsXml(xmlTextWriterPtr pWriter) const +{ + (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SvxThemeColor")); + + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("theme-index"), + BAD_CAST(OString::number(maThemeIndex).getStr())); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("lum-mod"), + BAD_CAST(OString::number(mnLumMod).getStr())); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("lum-off"), + BAD_CAST(OString::number(mnLumOff).getStr())); + + (void)xmlTextWriterEndElement(pWriter); +} + +// class SvxColorItem ---------------------------------------------------- +SvxColorItem::SvxColorItem( const sal_uInt16 nId ) : + SfxPoolItem(nId), + mColor( COL_BLACK ), + maTintShade(0) +{ +} + +SvxColorItem::SvxColorItem( const Color& rCol, const sal_uInt16 nId ) : + SfxPoolItem( nId ), + mColor( rCol ), + maTintShade(0) +{ +} + +SvxColorItem::~SvxColorItem() +{ +} + +bool SvxColorItem::operator==( const SfxPoolItem& rAttr ) const +{ + assert(SfxPoolItem::operator==(rAttr)); + const SvxColorItem& rColorItem = static_cast<const SvxColorItem&>(rAttr); + + return mColor == rColorItem.mColor && + maThemeColor == rColorItem.maThemeColor && + maTintShade == rColorItem.maTintShade; +} + +bool SvxColorItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const +{ + nMemberId &= ~CONVERT_TWIPS; + switch (nMemberId) + { + case MID_COLOR_ALPHA: + { + auto fTransparency = static_cast<double>(255 - mColor.GetAlpha()) * 100 / 255; + rVal <<= static_cast<sal_Int16>(basegfx::fround(fTransparency)); + break; + } + case MID_GRAPHIC_TRANSPARENT: + { + rVal <<= mColor.GetAlpha() == 0; + break; + } + case MID_COLOR_THEME_INDEX: + { + rVal <<= maThemeColor.GetThemeIndex(); + break; + } + case MID_COLOR_TINT_OR_SHADE: + { + rVal <<= maTintShade; + break; + } + case MID_COLOR_LUM_MOD: + { + rVal <<= maThemeColor.GetLumMod(); + break; + } + case MID_COLOR_LUM_OFF: + { + rVal <<= maThemeColor.GetLumOff(); + break; + } + default: + { + rVal <<= mColor; + break; + } + } + return true; +} + +bool SvxColorItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId ) +{ + nMemberId &= ~CONVERT_TWIPS; + switch(nMemberId) + { + case MID_COLOR_ALPHA: + { + sal_Int16 nTransparency = 0; + bool bRet = rVal >>= nTransparency; + if (bRet) + { + auto fTransparency = static_cast<double>(nTransparency) * 255 / 100; + mColor.SetAlpha(255 - static_cast<sal_uInt8>(basegfx::fround(fTransparency))); + } + return bRet; + } + case MID_GRAPHIC_TRANSPARENT: + { + mColor.SetAlpha( Any2Bool( rVal ) ? 0 : 255 ); + return true; + } + case MID_COLOR_THEME_INDEX: + { + sal_Int16 nIndex = -1; + if (!(rVal >>= nIndex)) + return false; + maThemeColor.SetThemeIndex(nIndex); + } + break; + case MID_COLOR_TINT_OR_SHADE: + { + sal_Int16 nTintShade = -1; + if (!(rVal >>= nTintShade)) + return false; + maTintShade = nTintShade; + } + break; + case MID_COLOR_LUM_MOD: + { + sal_Int16 nLumMod = -1; + if (!(rVal >>= nLumMod)) + return false; + maThemeColor.SetLumMod(nLumMod); + } + break; + case MID_COLOR_LUM_OFF: + { + sal_Int16 nLumOff = -1; + if (!(rVal >>= nLumOff)) + return false; + maThemeColor.SetLumOff(nLumOff); + } + break; + default: + { + return rVal >>= mColor; + } + break; + } + return true; +} + +SvxColorItem* SvxColorItem::Clone( SfxItemPool * ) const +{ + return new SvxColorItem( *this ); +} + +bool SvxColorItem::GetPresentation +( + SfxItemPresentation /*ePres*/, + MapUnit /*eCoreUnit*/, + MapUnit /*ePresUnit*/, + OUString& rText, const IntlWrapper& /*rIntl*/ +) const +{ + rText = ::GetColorString( mColor ); + return true; +} + +void SvxColorItem::dumpAsXml(xmlTextWriterPtr pWriter) const +{ + (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SvxColorItem")); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr())); + + std::stringstream ss; + ss << mColor; + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"), BAD_CAST(ss.str().c_str())); + + OUString aStr; + IntlWrapper aIntlWrapper(SvtSysLocale().GetUILanguageTag()); + GetPresentation( SfxItemPresentation::Complete, MapUnit::Map100thMM, MapUnit::Map100thMM, aStr, aIntlWrapper); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("presentation"), BAD_CAST(OUStringToOString(aStr, RTL_TEXTENCODING_UTF8).getStr())); + + maThemeColor.dumpAsXml(pWriter); + + (void)xmlTextWriterEndElement(pWriter); +} + + + +void SvxColorItem::SetValue( const Color& rNewCol ) +{ + mColor = rNewCol; +} + +// class SvxKerningItem -------------------------------------------------- + +SvxKerningItem::SvxKerningItem( const short nKern, const sal_uInt16 nId ) : + SfxInt16Item( nId, nKern ) +{ +} + +SvxKerningItem* SvxKerningItem::Clone( SfxItemPool * ) const +{ + return new SvxKerningItem( *this ); +} + +void SvxKerningItem::ScaleMetrics( tools::Long nMult, tools::Long nDiv ) +{ + SetValue( static_cast<sal_Int16>(BigInt::Scale( GetValue(), nMult, nDiv )) ); +} + + +bool SvxKerningItem::HasMetrics() const +{ + return true; +} + + +bool SvxKerningItem::GetPresentation +( + SfxItemPresentation ePres, + MapUnit eCoreUnit, + MapUnit /*ePresUnit*/, + OUString& rText, const IntlWrapper& rIntl +) const +{ + switch ( ePres ) + { + case SfxItemPresentation::Nameless: + rText = GetMetricText( static_cast<tools::Long>(GetValue()), eCoreUnit, MapUnit::MapPoint, &rIntl ) + + " " + EditResId(GetMetricId(MapUnit::MapPoint)); + return true; + case SfxItemPresentation::Complete: + { + rText = EditResId(RID_SVXITEMS_KERNING_COMPLETE); + TranslateId pId; + + if ( GetValue() > 0 ) + pId = RID_SVXITEMS_KERNING_EXPANDED; + else if ( GetValue() < 0 ) + pId = RID_SVXITEMS_KERNING_CONDENSED; + + if (pId) + rText += EditResId(pId); + rText += GetMetricText( static_cast<tools::Long>(GetValue()), eCoreUnit, MapUnit::MapPoint, &rIntl ) + + " " + EditResId(GetMetricId(MapUnit::MapPoint)); + return true; + } + default: ; //prevent warning + } + return false; +} + +bool SvxKerningItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const +{ + sal_Int16 nVal = GetValue(); + if(nMemberId & CONVERT_TWIPS) + nVal = static_cast<sal_Int16>(convertTwipToMm100(nVal)); + rVal <<= nVal; + return true; +} + +bool SvxKerningItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId) +{ + sal_Int16 nVal = sal_Int16(); + if(!(rVal >>= nVal)) + return false; + if(nMemberId & CONVERT_TWIPS) + nVal = o3tl::toTwips(nVal, o3tl::Length::mm100); + SetValue(nVal); + return true; +} + +// class SvxCaseMapItem -------------------------------------------------- + +SvxCaseMapItem::SvxCaseMapItem( const SvxCaseMap eMap, const sal_uInt16 nId ) : + SfxEnumItem( nId, eMap ) +{ +} + +sal_uInt16 SvxCaseMapItem::GetValueCount() const +{ + return sal_uInt16(SvxCaseMap::End); // SvxCaseMap::SmallCaps + 1 +} + +SvxCaseMapItem* SvxCaseMapItem::Clone( SfxItemPool * ) const +{ + return new SvxCaseMapItem( *this ); +} + +bool SvxCaseMapItem::GetPresentation +( + SfxItemPresentation /*ePres*/, + MapUnit /*eCoreUnit*/, + MapUnit /*ePresUnit*/, + OUString& rText, const IntlWrapper& /*rIntl*/ +) const +{ + rText = GetValueTextByPos( static_cast<sal_uInt16>(GetValue()) ); + return true; +} + +OUString SvxCaseMapItem::GetValueTextByPos( sal_uInt16 nPos ) +{ + static TranslateId RID_SVXITEMS_CASEMAP[] = + { + RID_SVXITEMS_CASEMAP_NONE, + RID_SVXITEMS_CASEMAP_UPPERCASE, + RID_SVXITEMS_CASEMAP_LOWERCASE, + RID_SVXITEMS_CASEMAP_TITLE, + RID_SVXITEMS_CASEMAP_SMALLCAPS + }; + + static_assert(SAL_N_ELEMENTS(RID_SVXITEMS_CASEMAP) == size_t(SvxCaseMap::End), "must match"); + assert(nPos < sal_uInt16(SvxCaseMap::End) && "enum overflow!"); + return EditResId(RID_SVXITEMS_CASEMAP[nPos]); +} + +bool SvxCaseMapItem::QueryValue( uno::Any& rVal, sal_uInt8 /*nMemberId*/ ) const +{ + sal_Int16 nRet = style::CaseMap::NONE; + switch( GetValue() ) + { + case SvxCaseMap::Uppercase : nRet = style::CaseMap::UPPERCASE; break; + case SvxCaseMap::Lowercase : nRet = style::CaseMap::LOWERCASE; break; + case SvxCaseMap::Capitalize : nRet = style::CaseMap::TITLE ; break; + case SvxCaseMap::SmallCaps: nRet = style::CaseMap::SMALLCAPS; break; + default: break; + } + rVal <<= nRet; + return true; +} + +bool SvxCaseMapItem::PutValue( const uno::Any& rVal, sal_uInt8 /*nMemberId*/ ) +{ + sal_uInt16 nVal = sal_uInt16(); + if(!(rVal >>= nVal)) + return false; + + SvxCaseMap eVal; + switch( nVal ) + { + case style::CaseMap::NONE : eVal = SvxCaseMap::NotMapped; break; + case style::CaseMap::UPPERCASE: eVal = SvxCaseMap::Uppercase; break; + case style::CaseMap::LOWERCASE: eVal = SvxCaseMap::Lowercase; break; + case style::CaseMap::TITLE : eVal = SvxCaseMap::Capitalize; break; + case style::CaseMap::SMALLCAPS: eVal = SvxCaseMap::SmallCaps; break; + default: return false; + } + SetValue(eVal); + return true; +} + +// class SvxEscapementItem ----------------------------------------------- + +SvxEscapementItem::SvxEscapementItem( const sal_uInt16 nId ) : + SfxEnumItemInterface( nId ), + + nEsc ( 0 ), + nProp ( 100 ) +{ +} + + +SvxEscapementItem::SvxEscapementItem( const SvxEscapement eEscape, + const sal_uInt16 nId ) : + SfxEnumItemInterface( nId ), + nProp( 100 ) +{ + SetEscapement( eEscape ); + if( nEsc ) + nProp = DFLT_ESC_PROP; +} + + +SvxEscapementItem::SvxEscapementItem( const short _nEsc, + const sal_uInt8 _nProp, + const sal_uInt16 nId ) : + SfxEnumItemInterface( nId ), + nEsc ( _nEsc ), + nProp ( _nProp ) +{ +} + + +bool SvxEscapementItem::operator==( const SfxPoolItem& rAttr ) const +{ + assert(SfxPoolItem::operator==(rAttr)); + + return( nEsc == static_cast<const SvxEscapementItem&>(rAttr).nEsc && + nProp == static_cast<const SvxEscapementItem&>(rAttr).nProp ); +} + +SvxEscapementItem* SvxEscapementItem::Clone( SfxItemPool * ) const +{ + return new SvxEscapementItem( *this ); +} + +sal_uInt16 SvxEscapementItem::GetValueCount() const +{ + return sal_uInt16(SvxEscapement::End); // SvxEscapement::Subscript + 1 +} + + +bool SvxEscapementItem::GetPresentation +( + SfxItemPresentation /*ePres*/, + MapUnit /*eCoreUnit*/, + MapUnit /*ePresUnit*/, + OUString& rText, const IntlWrapper& /*rIntl*/ +) const +{ + rText = GetValueTextByPos( GetEnumValue() ); + + if ( nEsc != 0 ) + { + if( DFLT_ESC_AUTO_SUPER == nEsc || DFLT_ESC_AUTO_SUB == nEsc ) + rText += EditResId(RID_SVXITEMS_ESCAPEMENT_AUTO); + else + rText += OUString::number( nEsc ) + "%"; + } + return true; +} + +OUString SvxEscapementItem::GetValueTextByPos( sal_uInt16 nPos ) +{ + static TranslateId RID_SVXITEMS_ESCAPEMENT[] = + { + RID_SVXITEMS_ESCAPEMENT_OFF, + RID_SVXITEMS_ESCAPEMENT_SUPER, + RID_SVXITEMS_ESCAPEMENT_SUB + }; + + static_assert(SAL_N_ELEMENTS(RID_SVXITEMS_ESCAPEMENT) == size_t(SvxEscapement::End), "must match"); + assert(nPos < sal_uInt16(SvxEscapement::End) && "enum overflow!"); + return EditResId(RID_SVXITEMS_ESCAPEMENT[nPos]); +} + +sal_uInt16 SvxEscapementItem::GetEnumValue() const +{ + if ( nEsc < 0 ) + return sal_uInt16(SvxEscapement::Subscript); + else if ( nEsc > 0 ) + return sal_uInt16(SvxEscapement::Superscript); + return sal_uInt16(SvxEscapement::Off); +} + + +void SvxEscapementItem::SetEnumValue( sal_uInt16 nVal ) +{ + SetEscapement( static_cast<SvxEscapement>(nVal) ); +} + +bool SvxEscapementItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const +{ + nMemberId &= ~CONVERT_TWIPS; + switch(nMemberId) + { + case MID_ESC: + rVal <<= static_cast<sal_Int16>(nEsc); + break; + case MID_ESC_HEIGHT: + rVal <<= static_cast<sal_Int8>(nProp); + break; + case MID_AUTO_ESC: + rVal <<= (DFLT_ESC_AUTO_SUB == nEsc || DFLT_ESC_AUTO_SUPER == nEsc); + break; + } + return true; +} + +bool SvxEscapementItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId ) +{ + nMemberId &= ~CONVERT_TWIPS; + switch(nMemberId) + { + case MID_ESC: + { + sal_Int16 nVal = sal_Int16(); + if( (rVal >>= nVal) && (std::abs(nVal) <= MAX_ESC_POS+1)) + nEsc = nVal; + else + return false; + } + break; + case MID_ESC_HEIGHT: + { + sal_Int8 nVal = sal_Int8(); + if( (rVal >>= nVal) && (nVal <= 100)) + nProp = nVal; + else + return false; + } + break; + case MID_AUTO_ESC: + { + bool bVal = Any2Bool(rVal); + if(bVal) + { + if(nEsc < 0) + nEsc = DFLT_ESC_AUTO_SUB; + else + nEsc = DFLT_ESC_AUTO_SUPER; + } + else + if(DFLT_ESC_AUTO_SUPER == nEsc ) + --nEsc; + else if(DFLT_ESC_AUTO_SUB == nEsc) + ++nEsc; + } + break; + } + return true; +} + +// class SvxLanguageItem ------------------------------------------------- + +SvxLanguageItem::SvxLanguageItem( const LanguageType eLang, const sal_uInt16 nId ) + : SvxLanguageItem_Base( nId , eLang ) +{ +} + + +sal_uInt16 SvxLanguageItem::GetValueCount() const +{ + // #i50205# got rid of class International + SAL_WARN( "editeng.items", "SvxLanguageItem::GetValueCount: supposed to return a count of what?"); + // Could be SvtLanguageTable::GetEntryCount() (all locales with resource string)? + // Could be LocaleDataWrapper::getInstalledLanguageTypes() (all locales with locale data)? + return 0; +} + +SvxLanguageItem* SvxLanguageItem::Clone( SfxItemPool * ) const +{ + return new SvxLanguageItem( *this ); +} + +bool SvxLanguageItem::GetPresentation +( + SfxItemPresentation /*ePres*/, + MapUnit /*eCoreUnit*/, + MapUnit /*ePresUnit*/, + OUString& rText, const IntlWrapper& /*rIntl*/ +) const +{ + rText = SvtLanguageTable::GetLanguageString( GetValue() ); + return true; +} + +bool SvxLanguageItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const +{ + nMemberId &= ~CONVERT_TWIPS; + switch(nMemberId) + { + case MID_LANG_INT: // for basic conversions! + rVal <<= static_cast<sal_Int16>(static_cast<sal_uInt16>(GetValue())); + break; + case MID_LANG_LOCALE: + lang::Locale aRet( LanguageTag::convertToLocale( GetValue(), false)); + rVal <<= aRet; + break; + } + return true; +} + +bool SvxLanguageItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId ) +{ + nMemberId &= ~CONVERT_TWIPS; + switch(nMemberId) + { + case MID_LANG_INT: // for basic conversions! + { + sal_Int32 nValue = 0; + if(!(rVal >>= nValue)) + return false; + + SetValue(LanguageType(nValue)); + } + break; + case MID_LANG_LOCALE: + { + lang::Locale aLocale; + if(!(rVal >>= aLocale)) + return false; + + SetValue( LanguageTag::convertToLanguageType( aLocale, false)); + } + break; + } + return true; +} + +// class SvxNoHyphenItem ------------------------------------------------- + +SvxNoHyphenItem::SvxNoHyphenItem( const sal_uInt16 nId ) : + SfxBoolItem( nId , true ) +{ +} + +SvxNoHyphenItem* SvxNoHyphenItem::Clone( SfxItemPool* ) const +{ + return new SvxNoHyphenItem( *this ); +} + +bool SvxNoHyphenItem::GetPresentation +( + SfxItemPresentation /*ePres*/, + MapUnit /*eCoreUnit*/, + MapUnit /*ePresUnit*/, + OUString& rText, const IntlWrapper& /*rIntl*/ +) const +{ + rText.clear(); + return false; +} + +/* + * Dummy item for ToolBox controls: + * + */ + + +// class SvxBlinkItem ------------------------------------------------- + + +SvxBlinkItem::SvxBlinkItem( const bool bBlink, const sal_uInt16 nId ) : + SfxBoolItem( nId, bBlink ) +{ +} + +SvxBlinkItem* SvxBlinkItem::Clone( SfxItemPool * ) const +{ + return new SvxBlinkItem( *this ); +} + +bool SvxBlinkItem::GetPresentation +( + SfxItemPresentation /*ePres*/, + MapUnit /*eCoreUnit*/, + MapUnit /*ePresUnit*/, + OUString& rText, const IntlWrapper& /*rIntl*/ +) const +{ + TranslateId pId = RID_SVXITEMS_BLINK_FALSE; + + if ( GetValue() ) + pId = RID_SVXITEMS_BLINK_TRUE; + rText = EditResId(pId); + return true; +} + +// class SvxEmphaisMarkItem --------------------------------------------------- + +SvxEmphasisMarkItem::SvxEmphasisMarkItem( const FontEmphasisMark nValue, + const sal_uInt16 nId ) + : SfxUInt16Item( nId, static_cast<sal_uInt16>(nValue) ) +{ +} + +SvxEmphasisMarkItem* SvxEmphasisMarkItem::Clone( SfxItemPool * ) const +{ + return new SvxEmphasisMarkItem( *this ); +} + +bool SvxEmphasisMarkItem::GetPresentation +( + SfxItemPresentation /*ePres*/, + MapUnit /*eCoreUnit*/, + MapUnit /*ePresUnit*/, + OUString& rText, + const IntlWrapper& /*rIntl*/ +) const +{ + static TranslateId RID_SVXITEMS_EMPHASIS[] = + { + RID_SVXITEMS_EMPHASIS_NONE_STYLE, + RID_SVXITEMS_EMPHASIS_DOT_STYLE, + RID_SVXITEMS_EMPHASIS_CIRCLE_STYLE, + RID_SVXITEMS_EMPHASIS_DISC_STYLE, + RID_SVXITEMS_EMPHASIS_ACCENT_STYLE + }; + + FontEmphasisMark nVal = GetEmphasisMark(); + rText = EditResId(RID_SVXITEMS_EMPHASIS[ + static_cast<sal_uInt16>(static_cast<FontEmphasisMark>( nVal & FontEmphasisMark::Style ))]); + TranslateId pId = ( FontEmphasisMark::PosAbove & nVal ) + ? RID_SVXITEMS_EMPHASIS_ABOVE_POS + : ( FontEmphasisMark::PosBelow & nVal ) + ? RID_SVXITEMS_EMPHASIS_BELOW_POS + : TranslateId(); + if( pId ) + rText += EditResId( pId ); + return true; +} + +bool SvxEmphasisMarkItem::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const +{ + nMemberId &= ~CONVERT_TWIPS; + switch( nMemberId ) + { + case MID_EMPHASIS: + { + FontEmphasisMark nValue = GetEmphasisMark(); + sal_Int16 nRet = 0; + switch(nValue & FontEmphasisMark::Style) + { + case FontEmphasisMark::NONE : nRet = FontEmphasis::NONE; break; + case FontEmphasisMark::Dot : nRet = FontEmphasis::DOT_ABOVE; break; + case FontEmphasisMark::Circle : nRet = FontEmphasis::CIRCLE_ABOVE; break; + case FontEmphasisMark::Disc : nRet = FontEmphasis::DISK_ABOVE; break; + case FontEmphasisMark::Accent : nRet = FontEmphasis::ACCENT_ABOVE; break; + default: break; + } + if(nRet && nValue & FontEmphasisMark::PosBelow) + nRet += 10; + rVal <<= nRet; + } + break; + } + return true; +} + +bool SvxEmphasisMarkItem::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId ) +{ + nMemberId &= ~CONVERT_TWIPS; + switch( nMemberId ) + { + case MID_EMPHASIS: + { + sal_Int32 nValue = -1; + rVal >>= nValue; + FontEmphasisMark nMark; + switch(nValue) + { + case FontEmphasis::NONE : nMark = FontEmphasisMark::NONE; break; + case FontEmphasis::DOT_ABOVE : nMark = FontEmphasisMark::Dot|FontEmphasisMark::PosAbove; break; + case FontEmphasis::CIRCLE_ABOVE: nMark = FontEmphasisMark::Circle|FontEmphasisMark::PosAbove; break; + case FontEmphasis::DISK_ABOVE : nMark = FontEmphasisMark::Disc|FontEmphasisMark::PosAbove; break; + case FontEmphasis::ACCENT_ABOVE: nMark = FontEmphasisMark::Accent|FontEmphasisMark::PosAbove; break; + case FontEmphasis::DOT_BELOW : nMark = FontEmphasisMark::Dot|FontEmphasisMark::PosBelow; break; + case FontEmphasis::CIRCLE_BELOW: nMark = FontEmphasisMark::Circle|FontEmphasisMark::PosBelow; break; + case FontEmphasis::DISK_BELOW : nMark = FontEmphasisMark::Disc|FontEmphasisMark::PosBelow; break; + case FontEmphasis::ACCENT_BELOW: nMark = FontEmphasisMark::Accent|FontEmphasisMark::PosBelow; break; + default: return false; + } + SetValue( static_cast<sal_Int16>(nMark) ); + } + break; + } + return true; +} + +/************************************************************************* +|* class SvxTwoLinesItem +*************************************************************************/ + +SvxTwoLinesItem::SvxTwoLinesItem( bool bFlag, sal_Unicode nStartBracket, + sal_Unicode nEndBracket, sal_uInt16 nW ) + : SfxPoolItem( nW ), + cStartBracket( nStartBracket ), cEndBracket( nEndBracket ), bOn( bFlag ) +{ +} + +SvxTwoLinesItem::~SvxTwoLinesItem() +{ +} + +bool SvxTwoLinesItem::operator==( const SfxPoolItem& rAttr ) const +{ + assert(SfxPoolItem::operator==(rAttr)); + return bOn == static_cast<const SvxTwoLinesItem&>(rAttr).bOn && + cStartBracket == static_cast<const SvxTwoLinesItem&>(rAttr).cStartBracket && + cEndBracket == static_cast<const SvxTwoLinesItem&>(rAttr).cEndBracket; +} + +SvxTwoLinesItem* SvxTwoLinesItem::Clone( SfxItemPool* ) const +{ + return new SvxTwoLinesItem( *this ); +} + +bool SvxTwoLinesItem::QueryValue( css::uno::Any& rVal, + sal_uInt8 nMemberId ) const +{ + nMemberId &= ~CONVERT_TWIPS; + bool bRet = true; + switch( nMemberId ) + { + case MID_TWOLINES: + rVal <<= bOn; + break; + case MID_START_BRACKET: + { + OUString s; + if( cStartBracket ) + s = OUString( cStartBracket ); + rVal <<= s; + } + break; + case MID_END_BRACKET: + { + OUString s; + if( cEndBracket ) + s = OUString( cEndBracket ); + rVal <<= s; + } + break; + default: + bRet = false; + break; + } + return bRet; +} + +bool SvxTwoLinesItem::PutValue( const css::uno::Any& rVal, + sal_uInt8 nMemberId ) +{ + nMemberId &= ~CONVERT_TWIPS; + bool bRet = false; + OUString s; + switch( nMemberId ) + { + case MID_TWOLINES: + bOn = Any2Bool( rVal ); + bRet = true; + break; + case MID_START_BRACKET: + if( rVal >>= s ) + { + cStartBracket = s.isEmpty() ? 0 : s[ 0 ]; + bRet = true; + } + break; + case MID_END_BRACKET: + if( rVal >>= s ) + { + cEndBracket = s.isEmpty() ? 0 : s[ 0 ]; + bRet = true; + } + break; + } + return bRet; +} + +bool SvxTwoLinesItem::GetPresentation( SfxItemPresentation /*ePres*/, + MapUnit /*eCoreMetric*/, MapUnit /*ePresMetric*/, + OUString &rText, const IntlWrapper& /*rIntl*/ ) const +{ + if( !GetValue() ) + rText = EditResId( RID_SVXITEMS_TWOLINES_OFF ); + else + { + rText = EditResId( RID_SVXITEMS_TWOLINES ); + if( GetStartBracket() ) + rText = OUStringChar(GetStartBracket()) + rText; + if( GetEndBracket() ) + rText += OUStringChar(GetEndBracket()); + } + return true; +} + + +/************************************************************************* +|* class SvxTextRotateItem +*************************************************************************/ + +SvxTextRotateItem::SvxTextRotateItem(Degree10 nValue, const sal_uInt16 nW) + : SfxUInt16Item(nW, nValue.get()) +{ +} + +SvxTextRotateItem* SvxTextRotateItem::Clone(SfxItemPool*) const +{ + return new SvxTextRotateItem(*this); +} + +bool SvxTextRotateItem::GetPresentation( + SfxItemPresentation /*ePres*/, + MapUnit /*eCoreMetric*/, MapUnit /*ePresMetric*/, + OUString &rText, const IntlWrapper&) const +{ + if (!GetValue()) + rText = EditResId(RID_SVXITEMS_TEXTROTATE_OFF); + else + { + rText = EditResId(RID_SVXITEMS_TEXTROTATE); + rText = rText.replaceFirst("$(ARG1)", + OUString::number(toDegrees(GetValue()))); + } + return true; +} + +bool SvxTextRotateItem::QueryValue(css::uno::Any& rVal, + sal_uInt8 nMemberId) const +{ + nMemberId &= ~CONVERT_TWIPS; + bool bRet = true; + switch (nMemberId) + { + case MID_ROTATE: + rVal <<= static_cast<sal_Int16>(GetValue()); + break; + default: + bRet = false; + break; + } + return bRet; +} + +bool SvxTextRotateItem::PutValue(const css::uno::Any& rVal, sal_uInt8 nMemberId) +{ + nMemberId &= ~CONVERT_TWIPS; + bool bRet = true; + switch (nMemberId) + { + case MID_ROTATE: + { + sal_Int16 nVal = 0; + if ((rVal >>= nVal) && (0 == nVal || 900 == nVal || 2700 == nVal)) + SetValue(Degree10(nVal)); + else + bRet = false; + break; + } + default: + bRet = false; + } + return bRet; +} + +void SvxTextRotateItem::dumpAsXml(xmlTextWriterPtr pWriter) const +{ + (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SvxTextRotateItem")); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr())); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"), BAD_CAST(OString::number(GetValue().get()).getStr())); + (void)xmlTextWriterEndElement(pWriter); +} + + +/************************************************************************* +|* class SvxCharRotateItem +*************************************************************************/ + +SvxCharRotateItem::SvxCharRotateItem( Degree10 nValue, + bool bFitIntoLine, + const sal_uInt16 nW ) + : SvxTextRotateItem(nValue, nW), bFitToLine( bFitIntoLine ) +{ +} + +SvxCharRotateItem* SvxCharRotateItem::Clone( SfxItemPool* ) const +{ + return new SvxCharRotateItem( *this ); +} + +bool SvxCharRotateItem::GetPresentation( + SfxItemPresentation /*ePres*/, + MapUnit /*eCoreMetric*/, MapUnit /*ePresMetric*/, + OUString &rText, const IntlWrapper&) const +{ + if( !GetValue() ) + rText = EditResId( RID_SVXITEMS_CHARROTATE_OFF ); + else + { + rText = EditResId( RID_SVXITEMS_CHARROTATE ); + rText = rText.replaceFirst( "$(ARG1)", + OUString::number( toDegrees(GetValue()) )); + if( IsFitToLine() ) + rText += EditResId( RID_SVXITEMS_CHARROTATE_FITLINE ); + } + return true; +} + +bool SvxCharRotateItem::QueryValue( css::uno::Any& rVal, + sal_uInt8 nMemberId ) const +{ + bool bRet = true; + switch(nMemberId & ~CONVERT_TWIPS) + { + case MID_ROTATE: + SvxTextRotateItem::QueryValue(rVal, nMemberId); + break; + case MID_FITTOLINE: + rVal <<= IsFitToLine(); + break; + default: + bRet = false; + break; + } + return bRet; +} + +bool SvxCharRotateItem::PutValue( const css::uno::Any& rVal, + sal_uInt8 nMemberId ) +{ + bool bRet = true; + switch(nMemberId & ~CONVERT_TWIPS) + { + case MID_ROTATE: + { + bRet = SvxTextRotateItem::PutValue(rVal, nMemberId); + break; + } + + case MID_FITTOLINE: + SetFitToLine( Any2Bool( rVal ) ); + break; + default: + bRet = false; + } + return bRet; +} + +bool SvxCharRotateItem::operator==( const SfxPoolItem& rItem ) const +{ + assert(SfxPoolItem::operator==(rItem)); + return SvxTextRotateItem::operator==( rItem ) && + IsFitToLine() == static_cast<const SvxCharRotateItem&>(rItem).IsFitToLine(); +} + +void SvxCharRotateItem::dumpAsXml(xmlTextWriterPtr pWriter) const +{ + (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SvxCharRotateItem")); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("whichId"), BAD_CAST(OString::number(Which()).getStr())); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("value"), BAD_CAST(OString::number(GetValue().get()).getStr())); + (void)xmlTextWriterWriteAttribute(pWriter, BAD_CAST("fitToLine"), BAD_CAST(OString::boolean(IsFitToLine()).getStr())); + (void)xmlTextWriterEndElement(pWriter); +} + +/************************************************************************* +|* class SvxCharScaleItem +*************************************************************************/ + +SvxCharScaleWidthItem::SvxCharScaleWidthItem( sal_uInt16 nValue, + const sal_uInt16 nW ) + : SfxUInt16Item( nW, nValue ) +{ +} + +SvxCharScaleWidthItem* SvxCharScaleWidthItem::Clone( SfxItemPool* ) const +{ + return new SvxCharScaleWidthItem( *this ); +} + +bool SvxCharScaleWidthItem::GetPresentation( + SfxItemPresentation /*ePres*/, + MapUnit /*eCoreMetric*/, MapUnit /*ePresMetric*/, + OUString &rText, const IntlWrapper&) const +{ + if( !GetValue() ) + rText = EditResId( RID_SVXITEMS_CHARSCALE_OFF ); + else + { + rText = EditResId( RID_SVXITEMS_CHARSCALE ); + rText = rText.replaceFirst( "$(ARG1)", + OUString::number( GetValue() )); + } + return true; +} + +bool SvxCharScaleWidthItem::PutValue( const uno::Any& rVal, sal_uInt8 /*nMemberId*/ ) +{ + // SfxUInt16Item::QueryValue returns sal_Int32 in Any now... (srx642w) + // where we still want this to be a sal_Int16 + sal_Int16 nValue = sal_Int16(); + if (rVal >>= nValue) + { + SetValue( static_cast<sal_uInt16>(nValue) ); + return true; + } + + SAL_WARN("editeng.items", "SvxCharScaleWidthItem::PutValue - Wrong type!" ); + return false; +} + +bool SvxCharScaleWidthItem::QueryValue( uno::Any& rVal, sal_uInt8 /*nMemberId*/ ) const +{ + // SfxUInt16Item::QueryValue returns sal_Int32 in Any now... (srx642w) + // where we still want this to be a sal_Int16 + rVal <<= static_cast<sal_Int16>(GetValue()); + return true; +} + +/************************************************************************* +|* class SvxCharReliefItem +*************************************************************************/ + +SvxCharReliefItem::SvxCharReliefItem( FontRelief eValue, + const sal_uInt16 nId ) + : SfxEnumItem( nId, eValue ) +{ +} + +SvxCharReliefItem* SvxCharReliefItem::Clone( SfxItemPool * ) const +{ + return new SvxCharReliefItem( *this ); +} + +static TranslateId RID_SVXITEMS_RELIEF[] = +{ + RID_SVXITEMS_RELIEF_NONE, + RID_SVXITEMS_RELIEF_EMBOSSED, + RID_SVXITEMS_RELIEF_ENGRAVED +}; + +OUString SvxCharReliefItem::GetValueTextByPos(sal_uInt16 nPos) +{ + assert(nPos < SAL_N_ELEMENTS(RID_SVXITEMS_RELIEF) && "enum overflow"); + return EditResId(RID_SVXITEMS_RELIEF[nPos]); +} + +sal_uInt16 SvxCharReliefItem::GetValueCount() const +{ + return SAL_N_ELEMENTS(RID_SVXITEMS_RELIEF) - 1; +} + +bool SvxCharReliefItem::GetPresentation +( + SfxItemPresentation /*ePres*/, + MapUnit /*eCoreUnit*/, + MapUnit /*ePresUnit*/, + OUString& rText, const IntlWrapper& /*rIntl*/ +) const +{ + rText = GetValueTextByPos( static_cast<sal_uInt16>(GetValue()) ); + return true; +} + +bool SvxCharReliefItem::PutValue( const css::uno::Any& rVal, + sal_uInt8 nMemberId ) +{ + nMemberId &= ~CONVERT_TWIPS; + bool bRet = true; + switch( nMemberId ) + { + case MID_RELIEF: + { + sal_Int16 nVal = -1; + rVal >>= nVal; + if(nVal >= 0 && nVal <= sal_Int16(FontRelief::Engraved)) + SetValue( static_cast<FontRelief>(nVal) ); + else + bRet = false; + } + break; + default: + bRet = false; + break; + } + return bRet; +} + +bool SvxCharReliefItem::QueryValue( css::uno::Any& rVal, + sal_uInt8 nMemberId ) const +{ + nMemberId &= ~CONVERT_TWIPS; + bool bRet = true; + switch( nMemberId ) + { + case MID_RELIEF: + rVal <<= static_cast<sal_Int16>(GetValue()); + break; + default: + bRet = false; + break; + } + return bRet; +} + +/************************************************************************* +|* class SvxScriptSetItem +*************************************************************************/ + +SvxScriptSetItem::SvxScriptSetItem( sal_uInt16 nSlotId, SfxItemPool& rPool ) + : SfxSetItem( nSlotId, SfxItemSet( rPool, + svl::Items<SID_ATTR_CHAR_FONT, SID_ATTR_CHAR_FONT> )) +{ + sal_uInt16 nLatin, nAsian, nComplex; + GetWhichIds( nLatin, nAsian, nComplex ); + GetItemSet().MergeRange( nLatin, nLatin ); + GetItemSet().MergeRange( nAsian, nAsian ); + GetItemSet().MergeRange( nComplex, nComplex ); +} + +SvxScriptSetItem* SvxScriptSetItem::Clone( SfxItemPool * ) const +{ + SvxScriptSetItem* p = new SvxScriptSetItem( Which(), *GetItemSet().GetPool() ); + p->GetItemSet().Put( GetItemSet(), false ); + return p; +} + +const SfxPoolItem* SvxScriptSetItem::GetItemOfScriptSet( + const SfxItemSet& rSet, sal_uInt16 nId ) +{ + const SfxPoolItem* pI; + SfxItemState eSt = rSet.GetItemState( nId, false, &pI ); + if( SfxItemState::SET != eSt ) + pI = SfxItemState::DEFAULT == eSt ? &rSet.Get( nId ) : nullptr; + return pI; +} + +const SfxPoolItem* SvxScriptSetItem::GetItemOfScript( sal_uInt16 nSlotId, const SfxItemSet& rSet, SvtScriptType nScript ) +{ + sal_uInt16 nLatin, nAsian, nComplex; + GetWhichIds( nSlotId, rSet, nLatin, nAsian, nComplex ); + + const SfxPoolItem *pRet, *pAsn, *pCmplx; + if (nScript == SvtScriptType::ASIAN) + { + pRet = GetItemOfScriptSet( rSet, nAsian ); + } else if (nScript == SvtScriptType::COMPLEX) + { + pRet = GetItemOfScriptSet( rSet, nComplex ); + } else if (nScript == (SvtScriptType::LATIN|SvtScriptType::ASIAN)) + { + if( nullptr == (pRet = GetItemOfScriptSet( rSet, nLatin )) || + nullptr == (pAsn = GetItemOfScriptSet( rSet, nAsian )) || + *pRet != *pAsn ) + pRet = nullptr; + } else if (nScript == (SvtScriptType::LATIN|SvtScriptType::COMPLEX)) + { + if( nullptr == (pRet = GetItemOfScriptSet( rSet, nLatin )) || + nullptr == (pCmplx = GetItemOfScriptSet( rSet, nComplex )) || + *pRet != *pCmplx ) + pRet = nullptr; + } else if (nScript == (SvtScriptType::ASIAN|SvtScriptType::COMPLEX)) + { + if( nullptr == (pRet = GetItemOfScriptSet( rSet, nAsian )) || + nullptr == (pCmplx = GetItemOfScriptSet( rSet, nComplex )) || + *pRet != *pCmplx ) + pRet = nullptr; + } else if (nScript == (SvtScriptType::LATIN|SvtScriptType::ASIAN|SvtScriptType::COMPLEX)) + { + if( nullptr == (pRet = GetItemOfScriptSet( rSet, nLatin )) || + nullptr == (pAsn = GetItemOfScriptSet( rSet, nAsian )) || + nullptr == (pCmplx = GetItemOfScriptSet( rSet, nComplex )) || + *pRet != *pAsn || *pRet != *pCmplx ) + pRet = nullptr; + } else { + //no one valid -> match to latin + pRet = GetItemOfScriptSet( rSet, nLatin ); + } + return pRet; +} + +const SfxPoolItem* SvxScriptSetItem::GetItemOfScript( SvtScriptType nScript ) const +{ + return GetItemOfScript( Which(), GetItemSet(), nScript ); +} + +void SvxScriptSetItem::PutItemForScriptType( SvtScriptType nScriptType, + const SfxPoolItem& rItem ) +{ + sal_uInt16 nLatin, nAsian, nComplex; + GetWhichIds( nLatin, nAsian, nComplex ); + + if( SvtScriptType::LATIN & nScriptType ) + { + GetItemSet().Put( rItem.CloneSetWhich(nLatin) ); + } + if( SvtScriptType::ASIAN & nScriptType ) + { + GetItemSet().Put( rItem.CloneSetWhich(nAsian) ); + } + if( SvtScriptType::COMPLEX & nScriptType ) + { + GetItemSet().Put( rItem.CloneSetWhich(nComplex) ); + } +} + +void SvxScriptSetItem::GetWhichIds( sal_uInt16 nSlotId, const SfxItemSet& rSet, sal_uInt16& rLatin, sal_uInt16& rAsian, sal_uInt16& rComplex ) +{ + const SfxItemPool& rPool = *rSet.GetPool(); + GetSlotIds( nSlotId, rLatin, rAsian, rComplex ); + rLatin = rPool.GetWhich( rLatin ); + rAsian = rPool.GetWhich( rAsian ); + rComplex = rPool.GetWhich( rComplex ); +} + +void SvxScriptSetItem::GetWhichIds( sal_uInt16& rLatin, sal_uInt16& rAsian, + sal_uInt16& rComplex ) const +{ + GetWhichIds( Which(), GetItemSet(), rLatin, rAsian, rComplex ); +} + +void SvxScriptSetItem::GetSlotIds( sal_uInt16 nSlotId, sal_uInt16& rLatin, + sal_uInt16& rAsian, sal_uInt16& rComplex ) +{ + switch( nSlotId ) + { + default: + SAL_WARN( "editeng.items", "wrong SlotId for class SvxScriptSetItem" ); + [[fallthrough]]; // default to font - Id Range !! + + case SID_ATTR_CHAR_FONT: + rLatin = SID_ATTR_CHAR_FONT; + rAsian = SID_ATTR_CHAR_CJK_FONT; + rComplex = SID_ATTR_CHAR_CTL_FONT; + break; + case SID_ATTR_CHAR_FONTHEIGHT: + rLatin = SID_ATTR_CHAR_FONTHEIGHT; + rAsian = SID_ATTR_CHAR_CJK_FONTHEIGHT; + rComplex = SID_ATTR_CHAR_CTL_FONTHEIGHT; + break; + case SID_ATTR_CHAR_WEIGHT: + rLatin = SID_ATTR_CHAR_WEIGHT; + rAsian = SID_ATTR_CHAR_CJK_WEIGHT; + rComplex = SID_ATTR_CHAR_CTL_WEIGHT; + break; + case SID_ATTR_CHAR_POSTURE: + rLatin = SID_ATTR_CHAR_POSTURE; + rAsian = SID_ATTR_CHAR_CJK_POSTURE; + rComplex = SID_ATTR_CHAR_CTL_POSTURE; + break; + case SID_ATTR_CHAR_LANGUAGE: + rLatin = SID_ATTR_CHAR_LANGUAGE; + rAsian = SID_ATTR_CHAR_CJK_LANGUAGE; + rComplex = SID_ATTR_CHAR_CTL_LANGUAGE; + break; + case SID_ATTR_CHAR_SHADOWED: + rLatin = SID_ATTR_CHAR_SHADOWED; + rAsian = SID_ATTR_CHAR_SHADOWED; + rComplex = SID_ATTR_CHAR_SHADOWED; + break; + case SID_ATTR_CHAR_STRIKEOUT: + rLatin = SID_ATTR_CHAR_STRIKEOUT; + rAsian = SID_ATTR_CHAR_STRIKEOUT; + rComplex = SID_ATTR_CHAR_STRIKEOUT; + break; + } +} + +void GetDefaultFonts( SvxFontItem& rLatin, SvxFontItem& rAsian, SvxFontItem& rComplex ) +{ + const sal_uInt16 nItemCnt = 3; + + static struct + { + DefaultFontType nFontType; + LanguageType nLanguage; + } + const aOutTypeArr[ nItemCnt ] = + { + { DefaultFontType::LATIN_TEXT, LANGUAGE_ENGLISH_US }, + { DefaultFontType::CJK_TEXT, LANGUAGE_ENGLISH_US }, + { DefaultFontType::CTL_TEXT, LANGUAGE_ARABIC_SAUDI_ARABIA } + }; + + SvxFontItem* aItemArr[ nItemCnt ] = { &rLatin, &rAsian, &rComplex }; + + for ( sal_uInt16 n = 0; n < nItemCnt; ++n ) + { + vcl::Font aFont( OutputDevice::GetDefaultFont( aOutTypeArr[ n ].nFontType, + aOutTypeArr[ n ].nLanguage, + GetDefaultFontFlags::OnlyOne ) ); + SvxFontItem* pItem = aItemArr[ n ]; + pItem->SetFamily( aFont.GetFamilyType() ); + pItem->SetFamilyName( aFont.GetFamilyName() ); + pItem->SetStyleName( OUString() ); + pItem->SetPitch( aFont.GetPitch()); + pItem->SetCharSet(aFont.GetCharSet()); + } +} + + +bool SvxRsidItem::QueryValue( uno::Any& rVal, sal_uInt8 ) const +{ + rVal <<= GetValue(); + return true; +} + +bool SvxRsidItem::PutValue( const uno::Any& rVal, sal_uInt8 ) +{ + sal_uInt32 nRsid = 0; + if( !( rVal >>= nRsid ) ) + return false; + + SetValue( nRsid ); + return true; +} + +SvxRsidItem* SvxRsidItem::Clone( SfxItemPool * ) const +{ + return new SvxRsidItem( *this ); +} + +bool SvxRsidItem::GetPresentation +( + SfxItemPresentation /*ePres*/, + MapUnit /*eCoreUnit*/, + MapUnit /*ePresUnit*/, + OUString& rText, const IntlWrapper& /*rIntl*/ +) const +{ + rText.clear(); + return false; +} + +void SvxRsidItem::dumpAsXml(xmlTextWriterPtr pWriter) const +{ + (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SvxRsidItem")); + (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("whichId"), "%d", Which()); + (void)xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("value"), "%" SAL_PRIuUINT32, GetValue()); + (void)xmlTextWriterEndElement(pWriter); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/editeng/source/items/writingmodeitem.cxx b/editeng/source/items/writingmodeitem.cxx new file mode 100644 index 000000000..252c8c055 --- /dev/null +++ b/editeng/source/items/writingmodeitem.cxx @@ -0,0 +1,94 @@ +/* -*- 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 <editeng/writingmodeitem.hxx> +#include <editeng/frmdir.hxx> +#include <editeng/eerdll.hxx> + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::text; + + +SvxWritingModeItem::SvxWritingModeItem( WritingMode eValue, sal_uInt16 _nWhich ) + : SfxUInt16Item( _nWhich, static_cast<sal_uInt16>(eValue) ) +{ +} + +SvxWritingModeItem::~SvxWritingModeItem() +{ +} + +SvxWritingModeItem* SvxWritingModeItem::Clone( SfxItemPool * ) const +{ + return new SvxWritingModeItem( *this ); +} + +bool SvxWritingModeItem::GetPresentation( SfxItemPresentation /*ePres*/, + MapUnit /*eCoreMetric*/, + MapUnit /*ePresMetric*/, + OUString &rText, + const IntlWrapper& ) const +{ + rText = EditResId(getFrmDirResId(static_cast<int>(GetValue()))); + return true; +} + +bool SvxWritingModeItem::PutValue( const css::uno::Any& rVal, sal_uInt8 ) +{ + sal_Int32 nVal = 0; + bool bRet = ( rVal >>= nVal ); + + if( !bRet ) + { + WritingMode eMode; + bRet = rVal >>= eMode; + + if( bRet ) + { + nVal = static_cast<sal_Int32>(eMode); + } + } + + if( bRet ) + { + switch( static_cast<WritingMode>(nVal) ) + { + case WritingMode_LR_TB: + case WritingMode_RL_TB: + case WritingMode_TB_RL: + SetValue( static_cast<sal_uInt16>(nVal) ); + bRet = true; + break; + default: + bRet = false; + break; + } + } + + return bRet; +} + +bool SvxWritingModeItem::QueryValue( css::uno::Any& rVal, + sal_uInt8 ) const +{ + rVal <<= GetValue(); + return true; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/editeng/source/items/xmlcnitm.cxx b/editeng/source/items/xmlcnitm.cxx new file mode 100644 index 000000000..50733ade4 --- /dev/null +++ b/editeng/source/items/xmlcnitm.cxx @@ -0,0 +1,206 @@ +/* -*- 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 <comphelper/servicehelper.hxx> +#include <com/sun/star/xml/AttributeData.hpp> +#include <com/sun/star/lang/XUnoTunnel.hpp> +#include <o3tl/any.hxx> +#include <xmloff/xmlcnimp.hxx> +#include <xmloff/unoatrcn.hxx> +#include <editeng/xmlcnitm.hxx> + +using namespace ::com::sun::star::uno; +using namespace ::com::sun::star::container; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::xml; + + +SvXMLAttrContainerItem::SvXMLAttrContainerItem( sal_uInt16 _nWhich ) : + SfxPoolItem( _nWhich ) +{ +} + +SvXMLAttrContainerItem::SvXMLAttrContainerItem( + const SvXMLAttrContainerItem& rItem ) : + SfxPoolItem( rItem ), + maContainerData( rItem.maContainerData ) +{ +} + +SvXMLAttrContainerItem::~SvXMLAttrContainerItem() +{ +} + +bool SvXMLAttrContainerItem::operator==( const SfxPoolItem& rItem ) const +{ + return SfxPoolItem::operator==(rItem) && + maContainerData == static_cast<const SvXMLAttrContainerItem&>(rItem).maContainerData; +} + +bool SvXMLAttrContainerItem::GetPresentation( + SfxItemPresentation /*ePresentation*/, + MapUnit /*eCoreMetric*/, + MapUnit /*ePresentationMetric*/, + OUString & /*rText*/, + const IntlWrapper& /*rIntlWrapper*/ ) const +{ + return false; +} + +bool SvXMLAttrContainerItem::QueryValue( css::uno::Any& rVal, sal_uInt8 /*nMemberId*/ ) const +{ + Reference<XNameContainer> xContainer + = new SvUnoAttributeContainer(std::make_unique<SvXMLAttrContainerData>(maContainerData)); + + rVal <<= xContainer; + return true; +} + +bool SvXMLAttrContainerItem::PutValue( const css::uno::Any& rVal, sal_uInt8 /*nMemberId*/ ) +{ + Reference<XUnoTunnel> xTunnel(rVal, UNO_QUERY); + if (auto pContainer = comphelper::getFromUnoTunnel<SvUnoAttributeContainer>(xTunnel)) + { + maContainerData = *pContainer->GetContainerImpl(); + } + else + { + SvXMLAttrContainerData aNewImpl; + + try + { + Reference<XNameContainer> xContainer( rVal, UNO_QUERY ); + if( !xContainer.is() ) + return false; + + const Sequence< OUString > aNameSequence( xContainer->getElementNames() ); + const OUString* pNames = aNameSequence.getConstArray(); + const sal_Int32 nCount = aNameSequence.getLength(); + Any aAny; + sal_Int32 nAttr; + + for( nAttr = 0; nAttr < nCount; nAttr++ ) + { + const OUString aName( *pNames++ ); + + aAny = xContainer->getByName( aName ); + auto pData = o3tl::tryAccess<AttributeData>(aAny); + if( !pData ) + return false; + + sal_Int32 pos = aName.indexOf( ':' ); + if( pos != -1 ) + { + const OUString aPrefix( aName.copy( 0, pos )); + const OUString aLName( aName.copy( pos+1 )); + + if( pData->Namespace.isEmpty() ) + { + if( !aNewImpl.AddAttr( aPrefix, aLName, pData->Value ) ) + break; + } + else + { + if( !aNewImpl.AddAttr( aPrefix, pData->Namespace, aLName, pData->Value ) ) + break; + } + } + else + { + if( !aNewImpl.AddAttr( aName, pData->Value ) ) + break; + } + } + + if( nAttr == nCount ) + maContainerData = std::move(aNewImpl); + else + return false; + } + catch(...) + { + return false; + } + } + return true; +} + + +bool SvXMLAttrContainerItem::AddAttr( const OUString& rLName, + const OUString& rValue ) +{ + return maContainerData.AddAttr( rLName, rValue ); +} + +bool SvXMLAttrContainerItem::AddAttr( const OUString& rPrefix, + const OUString& rNamespace, const OUString& rLName, + const OUString& rValue ) +{ + return maContainerData.AddAttr( rPrefix, rNamespace, rLName, rValue ); +} + +sal_uInt16 SvXMLAttrContainerItem::GetAttrCount() const +{ + return static_cast<sal_uInt16>(maContainerData.GetAttrCount()); +} + +OUString SvXMLAttrContainerItem::GetAttrNamespace( sal_uInt16 i ) const +{ + return maContainerData.GetAttrNamespace( i ); +} + +OUString SvXMLAttrContainerItem::GetAttrPrefix( sal_uInt16 i ) const +{ + return maContainerData.GetAttrPrefix( i ); +} + +const OUString& SvXMLAttrContainerItem::GetAttrLName( sal_uInt16 i ) const +{ + return maContainerData.GetAttrLName( i ); +} + +const OUString& SvXMLAttrContainerItem::GetAttrValue( sal_uInt16 i ) const +{ + return maContainerData.GetAttrValue( i ); +} + + +sal_uInt16 SvXMLAttrContainerItem::GetFirstNamespaceIndex() const +{ + return maContainerData.GetFirstNamespaceIndex(); +} + +sal_uInt16 SvXMLAttrContainerItem::GetNextNamespaceIndex( sal_uInt16 nIdx ) const +{ + return maContainerData.GetNextNamespaceIndex( nIdx ); +} + +const OUString& SvXMLAttrContainerItem::GetNamespace( sal_uInt16 i ) const +{ + return maContainerData.GetNamespace( i ); +} + +const OUString& SvXMLAttrContainerItem::GetPrefix( sal_uInt16 i ) const +{ + return maContainerData.GetPrefix( i ); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |