summaryrefslogtreecommitdiffstats
path: root/sw/source/core/doc/tblafmt.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/core/doc/tblafmt.cxx')
-rw-r--r--sw/source/core/doc/tblafmt.cxx1237
1 files changed, 1237 insertions, 0 deletions
diff --git a/sw/source/core/doc/tblafmt.cxx b/sw/source/core/doc/tblafmt.cxx
new file mode 100644
index 000000000..5a1357f99
--- /dev/null
+++ b/sw/source/core/doc/tblafmt.cxx
@@ -0,0 +1,1237 @@
+/* -*- 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 <comphelper/fileformat.h>
+#include <tools/stream.hxx>
+#include <sfx2/docfile.hxx>
+#include <svl/numformat.hxx>
+#include <svl/zforlist.hxx>
+#include <svl/zformat.hxx>
+#include <unotools/configmgr.hxx>
+#include <unotools/pathoptions.hxx>
+#include <swtable.hxx>
+#include <swtblfmt.hxx>
+#include <com/sun/star/text/VertOrientation.hpp>
+#include <swtypes.hxx>
+#include <doc.hxx>
+#include <poolfmt.hxx>
+#include <tblafmt.hxx>
+#include <cellatr.hxx>
+#include <SwStyleNameMapper.hxx>
+#include <hintids.hxx>
+#include <fmtornt.hxx>
+#include <editsh.hxx>
+#include <fmtlsplt.hxx>
+#include <fmtrowsplt.hxx>
+#include <sal/log.hxx>
+#include <osl/diagnose.h>
+#include <osl/thread.h>
+
+#include <editeng/adjustitem.hxx>
+#include <editeng/boxitem.hxx>
+#include <editeng/brushitem.hxx>
+#include <editeng/colritem.hxx>
+#include <editeng/contouritem.hxx>
+#include <editeng/crossedoutitem.hxx>
+#include <editeng/fontitem.hxx>
+#include <editeng/formatbreakitem.hxx>
+#include <editeng/fhgtitem.hxx>
+#include <editeng/justifyitem.hxx>
+#include <editeng/legacyitem.hxx>
+#include <editeng/lineitem.hxx>
+#include <editeng/postitem.hxx>
+#include <editeng/shdditem.hxx>
+#include <editeng/udlnitem.hxx>
+#include <editeng/wghtitem.hxx>
+#include <svx/algitem.hxx>
+#include <svx/rotmodit.hxx>
+#include <legacyitem.hxx>
+
+#include <memory>
+#include <vector>
+
+/*
+ * XXX: BIG RED NOTICE! Changes MUST be binary file format compatible and MUST
+ * be synchronized with Calc's ScAutoFormat sc/source/core/tool/autoform.cxx
+ */
+
+using ::editeng::SvxBorderLine;
+
+// until SO5PF
+const sal_uInt16 AUTOFORMAT_ID_X = 9501;
+const sal_uInt16 AUTOFORMAT_ID_358 = 9601;
+const sal_uInt16 AUTOFORMAT_DATA_ID_X = 9502;
+
+// from SO5
+//! In follow-up versions these IDs' values need to increase
+const sal_uInt16 AUTOFORMAT_ID_504 = 9801;
+const sal_uInt16 AUTOFORMAT_DATA_ID_504 = 9802;
+
+const sal_uInt16 AUTOFORMAT_DATA_ID_552 = 9902;
+
+// --- from 680/dr25 on: store strings as UTF-8
+const sal_uInt16 AUTOFORMAT_ID_680DR25 = 10021;
+
+// --- Bug fix to fdo#31005: Table Autoformats does not save/apply all properties (Writer and Calc)
+const sal_uInt16 AUTOFORMAT_ID_31005 = 10041;
+const sal_uInt16 AUTOFORMAT_DATA_ID_31005 = 10042;
+
+// current version
+const sal_uInt16 AUTOFORMAT_ID = AUTOFORMAT_ID_31005;
+const sal_uInt16 AUTOFORMAT_DATA_ID = AUTOFORMAT_DATA_ID_31005;
+const sal_uInt16 AUTOFORMAT_FILE_VERSION= SOFFICE_FILEFORMAT_50;
+
+SwBoxAutoFormat* SwTableAutoFormat::s_pDefaultBoxAutoFormat = nullptr;
+
+constexpr OUStringLiteral AUTOTABLE_FORMAT_NAME = u"autotbl.fmt";
+
+namespace
+{
+ /// Begins a writer-specific data block. Call before serializing any writer-specific properties.
+ sal_uInt64 BeginSwBlock(SvStream& rStream)
+ {
+ // We need to write down the offset of the end of the writer-specific data, so that
+ // calc can skip it. We'll only have that value after writing the data, so we
+ // write a placeholder value first, write the data, then jump back and write the
+ // real offset.
+
+ // Note that we explicitly use sal_uInt64 instead of sal_Size (which can be 32
+ // or 64 depending on platform) to ensure 64-bit portability on this front. I don't
+ // actually know if autotbl.fmt as a whole is portable, since that requires all serialization
+ // logic to be written with portability in mind.
+ sal_uInt64 whereToWriteEndOfSwBlock = rStream.Tell();
+
+ rStream.WriteUInt64( 0 ); // endOfSwBlock
+
+ return whereToWriteEndOfSwBlock;
+ }
+
+ /// Ends a writer-specific data block. Call after serializing writer-specific properties.
+ /// Closes a corresponding BeginSwBlock call.
+ void EndSwBlock(SvStream& rStream, sal_uInt64 whereToWriteEndOfSwBlock)
+ {
+ sal_uInt64 endOfSwBlock = rStream.Tell();
+ rStream.Seek(whereToWriteEndOfSwBlock);
+ rStream.WriteUInt64( endOfSwBlock );
+ rStream.Seek(endOfSwBlock);
+ }
+
+ /**
+ Helper class for writer-specific blocks. Begins a writer-specific block on construction,
+ and closes it on destruction.
+
+ See also: BeginSwBlock and EndSwBlock.
+ */
+ class WriterSpecificAutoFormatBlock
+ {
+ public:
+ explicit WriterSpecificAutoFormatBlock(SvStream& rStream)
+ : mrStream(rStream)
+ , mnWhereToWriteEndOfBlock(BeginSwBlock(rStream))
+ {
+ }
+
+ ~WriterSpecificAutoFormatBlock() { EndSwBlock(mrStream, mnWhereToWriteEndOfBlock); }
+
+ private:
+ WriterSpecificAutoFormatBlock(WriterSpecificAutoFormatBlock const&) = delete;
+ WriterSpecificAutoFormatBlock& operator=(WriterSpecificAutoFormatBlock const&) = delete;
+
+ SvStream& mrStream;
+ sal_uInt64 mnWhereToWriteEndOfBlock;
+ };
+
+ /// Checks whether a writer-specific block exists (i.e. size is not zero)
+ sal_Int64 WriterSpecificBlockExists(SvStream &stream)
+ {
+ sal_uInt64 endOfSwBlock = 0;
+ stream.ReadUInt64( endOfSwBlock );
+
+ // end-of-block pointing to itself indicates a zero-size block.
+ return endOfSwBlock - stream.Tell();
+ }
+}
+
+// Struct with version numbers of the Items
+
+struct SwAfVersions : public AutoFormatVersions
+{
+public:
+ sal_uInt16 m_nTextOrientationVersion;
+ sal_uInt16 m_nVerticalAlignmentVersion;
+
+ SwAfVersions();
+ void Load( SvStream& rStream, sal_uInt16 nVer );
+ static void Write(SvStream& rStream, sal_uInt16 fileVersion);
+};
+
+SwAfVersions::SwAfVersions()
+: m_nTextOrientationVersion(0),
+ m_nVerticalAlignmentVersion(0)
+{
+}
+
+void SwAfVersions::Load( SvStream& rStream, sal_uInt16 nVer )
+{
+ LoadBlockA(rStream, nVer);
+ if (nVer >= AUTOFORMAT_ID_31005 && WriterSpecificBlockExists(rStream))
+ {
+ rStream.ReadUInt16( m_nTextOrientationVersion );
+ rStream.ReadUInt16( m_nVerticalAlignmentVersion );
+ }
+ LoadBlockB(rStream, nVer);
+}
+
+void SwAfVersions::Write(SvStream& rStream, sal_uInt16 fileVersion)
+{
+ AutoFormatVersions::WriteBlockA(rStream, fileVersion);
+
+ if (fileVersion >= SOFFICE_FILEFORMAT_50)
+ {
+ WriterSpecificAutoFormatBlock block(rStream);
+
+ rStream.WriteUInt16(legacy::SvxFrameDirection::GetVersion(fileVersion));
+ rStream.WriteUInt16(legacy::SwFormatVert::GetVersion(fileVersion));
+ }
+
+ AutoFormatVersions::WriteBlockB(rStream, fileVersion);
+}
+
+
+
+SwBoxAutoFormat::SwBoxAutoFormat()
+: m_aTextOrientation(std::make_unique<SvxFrameDirectionItem>(SvxFrameDirection::Environment, RES_FRAMEDIR)),
+ m_aVerticalAlignment(std::make_unique<SwFormatVertOrient>(0, css::text::VertOrientation::NONE, css::text::RelOrientation::FRAME)),
+ m_eSysLanguage(::GetAppLanguage()),
+ m_eNumFormatLanguage(::GetAppLanguage())
+{
+ // need to set default instances for base class AutoFormatBase here
+ // due to resource defines (e.g. RES_CHRATR_FONT) which are not available
+ // in svx and different in the different usages of derivations
+ m_aFont = std::make_unique<SvxFontItem>(*GetDfltAttr( RES_CHRATR_FONT ) );
+ m_aHeight = std::make_unique<SvxFontHeightItem>(240, 100, RES_CHRATR_FONTSIZE );
+ m_aWeight = std::make_unique<SvxWeightItem>(WEIGHT_NORMAL, RES_CHRATR_WEIGHT );
+ m_aPosture = std::make_unique<SvxPostureItem>(ITALIC_NONE, RES_CHRATR_POSTURE );
+ m_aCJKFont = std::make_unique<SvxFontItem>(*GetDfltAttr( RES_CHRATR_CJK_FONT ) );
+ m_aCJKHeight = std::make_unique<SvxFontHeightItem>(240, 100, RES_CHRATR_CJK_FONTSIZE );
+ m_aCJKWeight = std::make_unique<SvxWeightItem>(WEIGHT_NORMAL, RES_CHRATR_CJK_WEIGHT );
+ m_aCJKPosture = std::make_unique<SvxPostureItem>(ITALIC_NONE, RES_CHRATR_CJK_POSTURE );
+ m_aCTLFont = std::make_unique<SvxFontItem>(*GetDfltAttr( RES_CHRATR_CTL_FONT ) );
+ m_aCTLHeight = std::make_unique<SvxFontHeightItem>(240, 100, RES_CHRATR_CTL_FONTSIZE );
+ m_aCTLWeight = std::make_unique<SvxWeightItem>(WEIGHT_NORMAL, RES_CHRATR_CTL_WEIGHT );
+ m_aCTLPosture = std::make_unique<SvxPostureItem>(ITALIC_NONE, RES_CHRATR_CTL_POSTURE );
+ m_aUnderline = std::make_unique<SvxUnderlineItem>(LINESTYLE_NONE, RES_CHRATR_UNDERLINE );
+ m_aOverline = std::make_unique<SvxOverlineItem>(LINESTYLE_NONE, RES_CHRATR_OVERLINE );
+ m_aCrossedOut = std::make_unique<SvxCrossedOutItem>(STRIKEOUT_NONE, RES_CHRATR_CROSSEDOUT );
+ m_aContour = std::make_unique<SvxContourItem>(false, RES_CHRATR_CONTOUR );
+ m_aShadowed = std::make_unique<SvxShadowedItem>(false, RES_CHRATR_SHADOWED );
+ m_aColor = std::make_unique<SvxColorItem>(RES_CHRATR_COLOR );
+ m_aBox = std::make_unique<SvxBoxItem>(RES_BOX );
+ m_aTLBR = std::make_unique<SvxLineItem>(0 );
+ m_aBLTR = std::make_unique<SvxLineItem>(0 );
+ m_aBackground = std::make_unique<SvxBrushItem>(RES_BACKGROUND );
+ m_aAdjust = std::make_unique<SvxAdjustItem>(SvxAdjust::Left, RES_PARATR_ADJUST );
+ m_aHorJustify = std::make_unique<SvxHorJustifyItem>(SvxCellHorJustify::Standard, 0);
+ m_aVerJustify = std::make_unique<SvxVerJustifyItem>(SvxCellVerJustify::Standard, 0);
+ m_aStacked = std::make_unique<SfxBoolItem>(0 );
+ m_aMargin = std::make_unique<SvxMarginItem>( TypedWhichId<SvxMarginItem>(0) );
+ m_aLinebreak = std::make_unique<SfxBoolItem>(0 );
+ m_aRotateAngle = std::make_unique<SfxInt32Item>(0 );
+ m_aRotateMode = std::make_unique<SvxRotateModeItem>(SVX_ROTATE_MODE_STANDARD, TypedWhichId<SvxRotateModeItem>(0) );
+
+// FIXME - add attribute IDs for the diagonal line items
+// aTLBR( RES_... ),
+// aBLTR( RES_... ),
+ m_aBox->SetAllDistances(55);
+}
+
+SwBoxAutoFormat::SwBoxAutoFormat( const SwBoxAutoFormat& rNew )
+: AutoFormatBase(rNew),
+ m_aTextOrientation(rNew.m_aTextOrientation->Clone()),
+ m_aVerticalAlignment(rNew.m_aVerticalAlignment->Clone()),
+ m_sNumFormatString( rNew.m_sNumFormatString ),
+ m_eSysLanguage( rNew.m_eSysLanguage ),
+ m_eNumFormatLanguage( rNew.m_eNumFormatLanguage )
+{
+}
+
+SwBoxAutoFormat::~SwBoxAutoFormat()
+{
+}
+
+SwBoxAutoFormat& SwBoxAutoFormat::operator=(const SwBoxAutoFormat& rRef)
+{
+ // check self-assignment
+ if(this == &rRef)
+ {
+ return *this;
+ }
+
+ // call baseclass implementation
+ AutoFormatBase::operator=(rRef);
+
+ // copy local members - this will use ::Clone() on all involved Items
+ SetTextOrientation(rRef.GetTextOrientation());
+ SetVerticalAlignment(rRef.GetVerticalAlignment());
+ SetNumFormatString(rRef.GetNumFormatString());
+ SetSysLanguage(rRef.GetSysLanguage());
+ SetNumFormatLanguage(rRef.GetNumFormatLanguage());
+
+ // m_wXObject used to not be copied before 1e2682235cded9a7cd90e55f0bfc60a1285e9a46
+ // "WIP: Further preparations for deeper Item changes" by this operator, so do not do it now, too
+ // rRef.SetXObject(GetXObject());
+
+ return *this;
+}
+
+bool SwBoxAutoFormat::operator==(const SwBoxAutoFormat& rRight) const
+{
+ return GetBackground().GetColor() == rRight.GetBackground().GetColor();
+}
+
+bool SwBoxAutoFormat::Load( SvStream& rStream, const SwAfVersions& rVersions, sal_uInt16 nVer )
+{
+ LoadBlockA( rStream, rVersions, nVer );
+
+ if (nVer >= AUTOFORMAT_DATA_ID_31005)
+ {
+ sal_Int64 const nSize(WriterSpecificBlockExists(rStream));
+ if (0 < nSize && nSize < std::numeric_limits<sal_uInt16>::max())
+ {
+ legacy::SvxFrameDirection::Create(*m_aTextOrientation, rStream, rVersions.m_nTextOrientationVersion);
+ // HORRIBLE HACK to read both 32-bit and 64-bit "long": abuse nSize
+ legacy::SwFormatVert::Create(*m_aVerticalAlignment, rStream, /*rVersions.m_nVerticalAlignmentVersion*/ nSize);
+ }
+ }
+
+ LoadBlockB( rStream, rVersions, nVer );
+
+ if( 0 == rVersions.nNumFormatVersion )
+ {
+ sal_uInt16 eSys, eLge;
+ // --- from 680/dr25 on: store strings as UTF-8
+ rtl_TextEncoding eCharSet = (nVer >= AUTOFORMAT_ID_680DR25) ? RTL_TEXTENCODING_UTF8 : rStream.GetStreamCharSet();
+ m_sNumFormatString = rStream.ReadUniOrByteString( eCharSet );
+ rStream.ReadUInt16( eSys ).ReadUInt16( eLge );
+ m_eSysLanguage = LanguageType(eSys);
+ m_eNumFormatLanguage = LanguageType(eLge);
+ if ( m_eSysLanguage == LANGUAGE_SYSTEM ) // from old versions (Calc)
+ m_eSysLanguage = ::GetAppLanguage();
+ }
+
+ return ERRCODE_NONE == rStream.GetError();
+}
+
+bool SwBoxAutoFormat::Save( SvStream& rStream, sal_uInt16 fileVersion ) const
+{
+ SaveBlockA( rStream, fileVersion );
+
+ if (fileVersion >= SOFFICE_FILEFORMAT_50)
+ {
+ WriterSpecificAutoFormatBlock block(rStream);
+
+ legacy::SvxFrameDirection::Store(*m_aTextOrientation, rStream, legacy::SvxFrameDirection::GetVersion(fileVersion));
+ legacy::SwFormatVert::Store(*m_aVerticalAlignment, rStream, legacy::SwFormatVert::GetVersion(fileVersion));
+ }
+
+ SaveBlockB( rStream, fileVersion );
+
+ // --- from 680/dr25 on: store strings as UTF-8
+ write_uInt16_lenPrefixed_uInt8s_FromOUString(rStream, m_sNumFormatString,
+ RTL_TEXTENCODING_UTF8);
+ rStream.WriteUInt16( static_cast<sal_uInt16>(m_eSysLanguage) ).WriteUInt16( static_cast<sal_uInt16>(m_eNumFormatLanguage) );
+
+ return ERRCODE_NONE == rStream.GetError();
+}
+
+SwTableAutoFormat::SwTableAutoFormat( const OUString& rName )
+ : m_aName( rName )
+ , m_nStrResId( USHRT_MAX )
+ , m_aKeepWithNextPara(std::make_shared<SvxFormatKeepItem>(false, RES_KEEP))
+ , m_aRepeatHeading( 0 )
+ , m_bLayoutSplit( true )
+ , m_bRowSplit( true )
+ , m_bCollapsingBorders(true)
+ , m_aShadow(std::make_shared<SvxShadowItem>(RES_SHADOW))
+ , m_bHidden( false )
+ , m_bUserDefined( true )
+{
+ m_bInclFont = true;
+ m_bInclJustify = true;
+ m_bInclFrame = true;
+ m_bInclBackground = true;
+ m_bInclValueFormat = true;
+ m_bInclWidthHeight = true;
+}
+
+SwTableAutoFormat::SwTableAutoFormat( const SwTableAutoFormat& rNew )
+ : m_aShadow(std::make_shared<SvxShadowItem>(RES_SHADOW))
+{
+ for(SwBoxAutoFormat* & rp : m_aBoxAutoFormat)
+ rp = nullptr;
+ *this = rNew;
+}
+
+SwTableAutoFormat& SwTableAutoFormat::operator=( const SwTableAutoFormat& rNew )
+{
+ if (&rNew == this)
+ return *this;
+
+ for( sal_uInt8 n = 0; n < 16; ++n )
+ {
+ if( m_aBoxAutoFormat[ n ] )
+ delete m_aBoxAutoFormat[ n ];
+
+ SwBoxAutoFormat* pFormat = rNew.m_aBoxAutoFormat[ n ];
+ if( pFormat ) // if is set -> copy
+ m_aBoxAutoFormat[ n ] = new SwBoxAutoFormat( *pFormat );
+ else // else default
+ m_aBoxAutoFormat[ n ] = nullptr;
+ }
+
+ m_aName = rNew.m_aName;
+ m_nStrResId = rNew.m_nStrResId;
+ m_bInclFont = rNew.m_bInclFont;
+ m_bInclJustify = rNew.m_bInclJustify;
+ m_bInclFrame = rNew.m_bInclFrame;
+ m_bInclBackground = rNew.m_bInclBackground;
+ m_bInclValueFormat = rNew.m_bInclValueFormat;
+ m_bInclWidthHeight = rNew.m_bInclWidthHeight;
+
+ m_aKeepWithNextPara.reset(rNew.m_aKeepWithNextPara->Clone());
+ m_aRepeatHeading = rNew.m_aRepeatHeading;
+ m_bLayoutSplit = rNew.m_bLayoutSplit;
+ m_bRowSplit = rNew.m_bRowSplit;
+ m_bCollapsingBorders = rNew.m_bCollapsingBorders;
+ m_aShadow.reset(rNew.m_aShadow->Clone());
+ m_bHidden = rNew.m_bHidden;
+ m_bUserDefined = rNew.m_bUserDefined;
+
+ return *this;
+}
+
+SwTableAutoFormat::~SwTableAutoFormat()
+{
+ SwBoxAutoFormat** ppFormat = m_aBoxAutoFormat;
+ for( sal_uInt8 n = 0; n < 16; ++n, ++ppFormat )
+ if( *ppFormat )
+ delete *ppFormat;
+}
+
+void SwTableAutoFormat::SetBoxFormat( const SwBoxAutoFormat& rNew, sal_uInt8 nPos )
+{
+ OSL_ENSURE( nPos < 16, "wrong area" );
+
+ SwBoxAutoFormat* pFormat = m_aBoxAutoFormat[ nPos ];
+ if( pFormat ) // if is set -> copy
+ *m_aBoxAutoFormat[ nPos ] = rNew;
+ else // else set anew
+ m_aBoxAutoFormat[ nPos ] = new SwBoxAutoFormat( rNew );
+}
+
+const SwBoxAutoFormat& SwTableAutoFormat::GetBoxFormat( sal_uInt8 nPos ) const
+{
+ OSL_ENSURE( nPos < 16, "wrong area" );
+
+ SwBoxAutoFormat* pFormat = m_aBoxAutoFormat[ nPos ];
+ if( pFormat ) // if is set -> copy
+ return *pFormat;
+ else // else return the default
+ {
+ // If it doesn't exist yet:
+ if( !s_pDefaultBoxAutoFormat )
+ s_pDefaultBoxAutoFormat = new SwBoxAutoFormat;
+ return *s_pDefaultBoxAutoFormat;
+ }
+}
+
+SwBoxAutoFormat& SwTableAutoFormat::GetBoxFormat( sal_uInt8 nPos )
+{
+ SAL_WARN_IF(!(nPos < 16), "sw.core", "GetBoxFormat wrong area");
+
+ SwBoxAutoFormat** pFormat = &m_aBoxAutoFormat[ nPos ];
+ if( !*pFormat )
+ {
+ // If default doesn't exist yet:
+ if( !s_pDefaultBoxAutoFormat )
+ s_pDefaultBoxAutoFormat = new SwBoxAutoFormat();
+ *pFormat = new SwBoxAutoFormat(*s_pDefaultBoxAutoFormat);
+ }
+ return **pFormat;
+}
+
+const SwBoxAutoFormat& SwTableAutoFormat::GetDefaultBoxFormat()
+{
+ if(!s_pDefaultBoxAutoFormat)
+ s_pDefaultBoxAutoFormat = new SwBoxAutoFormat();
+
+ return *s_pDefaultBoxAutoFormat;
+}
+
+void SwTableAutoFormat::UpdateFromSet( sal_uInt8 nPos,
+ const SfxItemSet& rSet,
+ SwTableAutoFormatUpdateFlags eFlags,
+ SvNumberFormatter const * pNFormatr)
+{
+ OSL_ENSURE( nPos < 16, "wrong area" );
+
+ SwBoxAutoFormat* pFormat = m_aBoxAutoFormat[ nPos ];
+ if( !pFormat ) // if is set -> copy
+ {
+ pFormat = new SwBoxAutoFormat;
+ m_aBoxAutoFormat[ nPos ] = pFormat;
+ }
+
+ if( SwTableAutoFormatUpdateFlags::Char & eFlags )
+ {
+ pFormat->SetFont( rSet.Get( RES_CHRATR_FONT ) );
+ pFormat->SetHeight( rSet.Get( RES_CHRATR_FONTSIZE ) );
+ pFormat->SetWeight( rSet.Get( RES_CHRATR_WEIGHT ) );
+ pFormat->SetPosture( rSet.Get( RES_CHRATR_POSTURE ) );
+ pFormat->SetCJKFont( rSet.Get( RES_CHRATR_CJK_FONT ) );
+ pFormat->SetCJKHeight( rSet.Get( RES_CHRATR_CJK_FONTSIZE ) );
+ pFormat->SetCJKWeight( rSet.Get( RES_CHRATR_CJK_WEIGHT ) );
+ pFormat->SetCJKPosture( rSet.Get( RES_CHRATR_CJK_POSTURE ) );
+ pFormat->SetCTLFont( rSet.Get( RES_CHRATR_CTL_FONT ) );
+ pFormat->SetCTLHeight( rSet.Get( RES_CHRATR_CTL_FONTSIZE ) );
+ pFormat->SetCTLWeight( rSet.Get( RES_CHRATR_CTL_WEIGHT ) );
+ pFormat->SetCTLPosture( rSet.Get( RES_CHRATR_CTL_POSTURE ) );
+ pFormat->SetUnderline( rSet.Get( RES_CHRATR_UNDERLINE ) );
+ pFormat->SetOverline( rSet.Get( RES_CHRATR_OVERLINE ) );
+ pFormat->SetCrossedOut( rSet.Get( RES_CHRATR_CROSSEDOUT ) );
+ pFormat->SetContour( rSet.Get( RES_CHRATR_CONTOUR ) );
+ pFormat->SetShadowed( rSet.Get( RES_CHRATR_SHADOWED ) );
+ pFormat->SetColor( rSet.Get( RES_CHRATR_COLOR ) );
+ pFormat->SetAdjust( rSet.Get( RES_PARATR_ADJUST ) );
+ }
+ if( !(SwTableAutoFormatUpdateFlags::Box & eFlags) )
+ return;
+
+ pFormat->SetBox( rSet.Get( RES_BOX ) );
+// FIXME - add attribute IDs for the diagonal line items
+// pFormat->SetTLBR( (SvxLineItem&)rSet.Get( RES_... ) );
+// pFormat->SetBLTR( (SvxLineItem&)rSet.Get( RES_... ) );
+ pFormat->SetBackground( rSet.Get( RES_BACKGROUND ) );
+ pFormat->SetTextOrientation(rSet.Get(RES_FRAMEDIR));
+ pFormat->SetVerticalAlignment(rSet.Get(RES_VERT_ORIENT));
+
+ const SwTableBoxNumFormat* pNumFormatItem;
+ const SvNumberformat* pNumFormat = nullptr;
+ if( pNFormatr && (pNumFormatItem = rSet.GetItemIfSet( RES_BOXATR_FORMAT )) &&
+ nullptr != (pNumFormat = pNFormatr->GetEntry( pNumFormatItem->GetValue() )) )
+ pFormat->SetValueFormat( pNumFormat->GetFormatstring(),
+ pNumFormat->GetLanguage(),
+ ::GetAppLanguage());
+ else
+ {
+ // default
+ pFormat->SetValueFormat( OUString(), LANGUAGE_SYSTEM,
+ ::GetAppLanguage() );
+ }
+
+ // we cannot handle the rest, that's specific to StarCalc
+}
+
+void SwTableAutoFormat::UpdateToSet(const sal_uInt8 nPos, const bool bSingleRowTable, const bool bSingleColTable, SfxItemSet& rSet,
+ SwTableAutoFormatUpdateFlags eFlags, SvNumberFormatter* pNFormatr) const
+{
+ const SwBoxAutoFormat& rChg = GetBoxFormat( nPos );
+
+ if( SwTableAutoFormatUpdateFlags::Char & eFlags )
+ {
+ if( IsFont() )
+ {
+ rSet.Put( rChg.GetFont() );
+ rSet.Put( rChg.GetHeight() );
+ rSet.Put( rChg.GetWeight() );
+ rSet.Put( rChg.GetPosture() );
+ // do not insert empty CJK font
+ const SvxFontItem& rCJKFont = rChg.GetCJKFont();
+ if (!rCJKFont.GetStyleName().isEmpty())
+ {
+ rSet.Put( rChg.GetCJKFont() );
+ rSet.Put( rChg.GetCJKHeight() );
+ rSet.Put( rChg.GetCJKWeight() );
+ rSet.Put( rChg.GetCJKPosture() );
+ }
+ else
+ {
+ rSet.Put( rChg.GetHeight().CloneSetWhich(RES_CHRATR_CJK_FONTSIZE) );
+ rSet.Put( rChg.GetWeight().CloneSetWhich(RES_CHRATR_CJK_WEIGHT) );
+ rSet.Put( rChg.GetPosture().CloneSetWhich(RES_CHRATR_CJK_POSTURE) );
+ }
+ // do not insert empty CTL font
+ const SvxFontItem& rCTLFont = rChg.GetCTLFont();
+ if (!rCTLFont.GetStyleName().isEmpty())
+ {
+ rSet.Put( rChg.GetCTLFont() );
+ rSet.Put( rChg.GetCTLHeight() );
+ rSet.Put( rChg.GetCTLWeight() );
+ rSet.Put( rChg.GetCTLPosture() );
+ }
+ else
+ {
+ rSet.Put( rChg.GetHeight().CloneSetWhich(RES_CHRATR_CTL_FONTSIZE) );
+ rSet.Put( rChg.GetWeight().CloneSetWhich(RES_CHRATR_CTL_WEIGHT) );
+ rSet.Put( rChg.GetPosture().CloneSetWhich(RES_CHRATR_CTL_POSTURE) );
+ }
+ rSet.Put( rChg.GetUnderline() );
+ rSet.Put( rChg.GetOverline() );
+ rSet.Put( rChg.GetCrossedOut() );
+ rSet.Put( rChg.GetContour() );
+ rSet.Put( rChg.GetShadowed() );
+ rSet.Put( rChg.GetColor() );
+ }
+ if( IsJustify() )
+ rSet.Put( rChg.GetAdjust() );
+ }
+
+ if( !(SwTableAutoFormatUpdateFlags::Box & eFlags) )
+ return;
+
+ if( IsFrame() )
+ {
+ SvxBoxItem aAutoFormatBox = rChg.GetBox();
+
+ // No format box is adequate to specify the borders of single column/row tables, so combine first/last.
+ if ( bSingleRowTable || bSingleColTable )
+ {
+ sal_uInt8 nSingleRowOrColumnId = 15; //LAST_ROW_END_COLUMN
+ if ( !bSingleRowTable )
+ nSingleRowOrColumnId = nPos + 3; //LAST COLUMN (3, 7, 11, 15)
+ else if ( !bSingleColTable )
+ nSingleRowOrColumnId = nPos + 12; //LAST ROW (12, 13, 14, 15)
+
+ assert( nSingleRowOrColumnId < 16 );
+ const SvxBoxItem aLastAutoFormatBox( GetBoxFormat(nSingleRowOrColumnId).GetBox() );
+ if ( bSingleRowTable )
+ aAutoFormatBox.SetLine( aLastAutoFormatBox.GetLine(SvxBoxItemLine::BOTTOM), SvxBoxItemLine::BOTTOM );
+ if ( bSingleColTable )
+ aAutoFormatBox.SetLine( aLastAutoFormatBox.GetLine(SvxBoxItemLine::RIGHT), SvxBoxItemLine::RIGHT );
+ }
+
+ rSet.Put( aAutoFormatBox );
+// FIXME - uncomment the lines to put the diagonal line items
+// rSet.Put( rChg.GetTLBR() );
+// rSet.Put( rChg.GetBLTR() );
+ }
+ if( IsBackground() )
+ rSet.Put( rChg.GetBackground() );
+
+ rSet.Put(rChg.GetTextOrientation());
+
+ // Do not put a VertAlign when it has default value.
+ // It prevents the export of default value by automatic cell-styles export.
+ if (rChg.GetVerticalAlignment().GetVertOrient() != GetDefaultBoxFormat().GetVerticalAlignment().GetVertOrient())
+ rSet.Put(rChg.GetVerticalAlignment());
+
+ if( !(IsValueFormat() && pNFormatr) )
+ return;
+
+ OUString sFormat;
+ LanguageType eLng, eSys;
+ rChg.GetValueFormat( sFormat, eLng, eSys );
+ if( !sFormat.isEmpty() )
+ {
+ SvNumFormatType nType;
+ bool bNew;
+ sal_Int32 nCheckPos;
+ sal_uInt32 nKey = pNFormatr->GetIndexPuttingAndConverting( sFormat, eLng,
+ eSys, nType, bNew, nCheckPos);
+ rSet.Put( SwTableBoxNumFormat( nKey ));
+ }
+ else
+ rSet.ClearItem( RES_BOXATR_FORMAT );
+
+ // we cannot handle the rest, that's specific to StarCalc
+}
+
+void SwTableAutoFormat::RestoreTableProperties(SwTable &table) const
+{
+ SwTableFormat* pFormat = table.GetFrameFormat();
+ if (!pFormat)
+ return;
+
+ SwDoc *pDoc = pFormat->GetDoc();
+ if (!pDoc)
+ return;
+
+ SfxItemSet rSet(pDoc->GetAttrPool(), aTableSetRange);
+
+ rSet.Put(SwFormatLayoutSplit(m_bLayoutSplit));
+ rSet.Put(SfxBoolItem(RES_COLLAPSING_BORDERS, m_bCollapsingBorders));
+ if ( m_aKeepWithNextPara->GetValue() )
+ rSet.Put(*m_aKeepWithNextPara);
+ rSet.Put(*m_aShadow);
+
+ pFormat->SetFormatAttr(rSet);
+
+ if (SwEditShell *pShell = pDoc->GetEditShell())
+ pDoc->SetRowSplit(*pShell->getShellCursor(false), SwFormatRowSplit(m_bRowSplit));
+
+ table.SetRowsToRepeat(m_aRepeatHeading);
+}
+
+void SwTableAutoFormat::StoreTableProperties(const SwTable &table)
+{
+ SwTableFormat* pFormat = table.GetFrameFormat();
+ if (!pFormat)
+ return;
+
+ SwDoc *pDoc = pFormat->GetDoc();
+ if (!pDoc)
+ return;
+
+ SwEditShell *pShell = pDoc->GetEditShell();
+ std::unique_ptr<SwFormatRowSplit> pRowSplit(pShell ? SwDoc::GetRowSplit(*pShell->getShellCursor(false)) : nullptr);
+ m_bRowSplit = pRowSplit && pRowSplit->GetValue();
+ pRowSplit.reset();
+
+ const SfxItemSet &rSet = pFormat->GetAttrSet();
+
+ const SwFormatLayoutSplit &layoutSplit = rSet.Get(RES_LAYOUT_SPLIT);
+ m_bLayoutSplit = layoutSplit.GetValue();
+ m_bCollapsingBorders = rSet.Get(RES_COLLAPSING_BORDERS).GetValue();
+
+ m_aKeepWithNextPara.reset(rSet.Get(RES_KEEP).Clone());
+ m_aRepeatHeading = table.GetRowsToRepeat();
+ m_aShadow.reset(rSet.Get(RES_SHADOW).Clone());
+}
+
+bool SwTableAutoFormat::FirstRowEndColumnIsRow()
+{
+ return GetBoxFormat(3) == GetBoxFormat(2);
+}
+bool SwTableAutoFormat::FirstRowStartColumnIsRow()
+{
+ return GetBoxFormat(0) == GetBoxFormat(1);
+}
+bool SwTableAutoFormat::LastRowEndColumnIsRow()
+{
+ return GetBoxFormat(14) == GetBoxFormat(15);
+}
+bool SwTableAutoFormat::LastRowStartColumnIsRow()
+{
+ return GetBoxFormat(12) == GetBoxFormat(13);
+}
+
+bool SwTableAutoFormat::Load( SvStream& rStream, const SwAfVersions& rVersions )
+{
+ sal_uInt16 nVal = 0;
+ rStream.ReadUInt16( nVal );
+ bool bRet = ERRCODE_NONE == rStream.GetError();
+
+ if( bRet && (nVal == AUTOFORMAT_DATA_ID_X ||
+ (AUTOFORMAT_DATA_ID_504 <= nVal && nVal <= AUTOFORMAT_DATA_ID)) )
+ {
+ bool b;
+ // --- from 680/dr25 on: store strings as UTF-8
+ rtl_TextEncoding eCharSet = (nVal >= AUTOFORMAT_ID_680DR25) ? RTL_TEXTENCODING_UTF8 : rStream.GetStreamCharSet();
+ m_aName = rStream.ReadUniOrByteString( eCharSet );
+ if( AUTOFORMAT_DATA_ID_552 <= nVal )
+ {
+ rStream.ReadUInt16( m_nStrResId );
+ // start from 3d because default is added via constructor
+ if( m_nStrResId < RES_POOLTABLESTYLE_END - RES_POOLTABLESTYLE_3D )
+ {
+ m_aName = SwStyleNameMapper::GetUIName(RES_POOLTABLESTYLE_3D + m_nStrResId, m_aName);
+ }
+ else
+ m_nStrResId = USHRT_MAX;
+ }
+ rStream.ReadCharAsBool( b ); m_bInclFont = b;
+ rStream.ReadCharAsBool( b ); m_bInclJustify = b;
+ rStream.ReadCharAsBool( b ); m_bInclFrame = b;
+ rStream.ReadCharAsBool( b ); m_bInclBackground = b;
+ rStream.ReadCharAsBool( b ); m_bInclValueFormat = b;
+ rStream.ReadCharAsBool( b ); m_bInclWidthHeight = b;
+
+ if (nVal >= AUTOFORMAT_DATA_ID_31005 && WriterSpecificBlockExists(rStream))
+ {
+ //this only exists for file format compat
+ SvxFormatBreakItem aBreak(SvxBreak::NONE, RES_BREAK);
+ legacy::SvxFormatBreak::Create(aBreak, rStream, AUTOFORMAT_FILE_VERSION);
+ legacy::SvxFormatKeep::Create(*m_aKeepWithNextPara, rStream, AUTOFORMAT_FILE_VERSION);
+
+ rStream.ReadUInt16( m_aRepeatHeading ).ReadCharAsBool( m_bLayoutSplit ).ReadCharAsBool( m_bRowSplit ).ReadCharAsBool( m_bCollapsingBorders );
+
+ legacy::SvxShadow::Create(*m_aShadow, rStream, AUTOFORMAT_FILE_VERSION);
+ }
+
+ bRet = ERRCODE_NONE== rStream.GetError();
+
+ for( sal_uInt8 i = 0; bRet && i < 16; ++i )
+ {
+ SwBoxAutoFormat* pFormat = new SwBoxAutoFormat;
+ bRet = pFormat->Load( rStream, rVersions, nVal );
+ if( bRet )
+ m_aBoxAutoFormat[ i ] = pFormat;
+ else
+ {
+ delete pFormat;
+ break;
+ }
+ }
+ }
+ m_bUserDefined = false;
+ return bRet;
+}
+
+bool SwTableAutoFormat::Save( SvStream& rStream, sal_uInt16 fileVersion ) const
+{
+ rStream.WriteUInt16( AUTOFORMAT_DATA_ID );
+ // --- from 680/dr25 on: store strings as UTF-8
+ write_uInt16_lenPrefixed_uInt8s_FromOUString(rStream, m_aName,
+ RTL_TEXTENCODING_UTF8 );
+ rStream.WriteUInt16( m_nStrResId );
+ rStream.WriteBool( m_bInclFont );
+ rStream.WriteBool( m_bInclJustify );
+ rStream.WriteBool( m_bInclFrame );
+ rStream.WriteBool( m_bInclBackground );
+ rStream.WriteBool( m_bInclValueFormat );
+ rStream.WriteBool( m_bInclWidthHeight );
+
+ {
+ WriterSpecificAutoFormatBlock block(rStream);
+ //this only exists for file format compat
+ SvxFormatBreakItem aBreak(SvxBreak::NONE, RES_BREAK);
+ legacy::SvxFormatBreak::Store(aBreak, rStream, legacy::SvxFormatBreak::GetVersion(fileVersion));
+ legacy::SvxFormatKeep::Store(*m_aKeepWithNextPara, rStream, legacy::SvxFormatKeep::GetVersion(fileVersion));
+ rStream.WriteUInt16( m_aRepeatHeading ).WriteBool( m_bLayoutSplit ).WriteBool( m_bRowSplit ).WriteBool( m_bCollapsingBorders );
+ legacy::SvxShadow::Store(*m_aShadow, rStream, legacy::SvxShadow::GetVersion(fileVersion));
+ }
+
+ bool bRet = ERRCODE_NONE == rStream.GetError();
+
+ for( int i = 0; bRet && i < 16; ++i )
+ {
+ SwBoxAutoFormat* pFormat = m_aBoxAutoFormat[ i ];
+ if( !pFormat ) // if not set -> write default
+ {
+ // If it doesn't exist yet:
+ if( !s_pDefaultBoxAutoFormat )
+ s_pDefaultBoxAutoFormat = new SwBoxAutoFormat;
+ pFormat = s_pDefaultBoxAutoFormat;
+ }
+ bRet = pFormat->Save( rStream, fileVersion );
+ }
+ return bRet;
+}
+
+OUString SwTableAutoFormat::GetTableTemplateCellSubName(const SwBoxAutoFormat& rBoxFormat) const
+{
+ sal_Int32 nIndex = 0;
+ for (; nIndex < 16; ++nIndex)
+ if (m_aBoxAutoFormat[nIndex] == &rBoxFormat) break;
+
+ // box format doesn't belong to this table format
+ if (16 <= nIndex)
+ return OUString();
+
+ const std::vector<sal_Int32> aTableTemplateMap = GetTableTemplateMap();
+ for (size_t i=0; i < aTableTemplateMap.size(); ++i)
+ {
+ if (aTableTemplateMap[i] == nIndex)
+ return "." + OUString::number(i + 1);
+ }
+
+ // box format doesn't belong to a table template
+ return OUString();
+}
+
+/*
+ * Mapping schema
+ * 0 1 2 3 4 5
+ * +-----------------------------------------------------------------------+
+ * 0 | FRSC | FR | FREC | | | FRENC |
+ * +-----------------------------------------------------------------------+
+ * 1 | FC | ER | EC | | | LC |
+ * +-----------------------------------------------------------------------+
+ * 2 | OR | OC | BODY | | | BCKG |
+ * +-----------------------------------------------------------------------+
+ * 3 | | | | | | |
+ * +-----------------------------------------------------------------------+
+ * 4 | | | | | | |
+ * +-----------------------------------------------------------------------+
+ * 5 | LRSC | LR | LREC | | | LRENC |
+ * +-----------+-----------+-----------+-----------+-----------+-----------+
+ * ODD = 1, 3, 5, ...
+ * EVEN = 2, 4, 6, ...
+ */
+const std::vector<sal_Int32> & SwTableAutoFormat::GetTableTemplateMap()
+{
+ static std::vector<sal_Int32> const aTableTemplateMap
+ {
+ 1 , // FIRST_ROW // FR
+ 13, // LAST_ROW // LR
+ 4 , // FIRST_COLUMN // FC
+ 7 , // LAST_COLUMN // LC
+ 5 , // EVEN_ROWS // ER
+ 8 , // ODD_ROWS // OR
+ 6 , // EVEN_COLUMNS // EC
+ 9 , // ODD_COLUMNS // OC
+ 10, // BODY
+ 11, // BACKGROUND // BCKG
+ 0 , // FIRST_ROW_START_COLUMN // FRSC
+ 3 , // FIRST_ROW_END_COLUMN // FRENC
+ 12, // LAST_ROW_START_COLUMN // LRSC
+ 15, // LAST_ROW_END_COLUMN // LRENC
+ 2 , // FIRST_ROW_EVEN_COLUMN // FREC
+ 14, // LAST_ROW_EVEN_COLUMN // LREC
+ };
+ return aTableTemplateMap;
+}
+
+sal_uInt8 SwTableAutoFormat::CountPos(sal_uInt32 nCol, sal_uInt32 nCols, sal_uInt32 nRow,
+ sal_uInt32 nRows)
+{
+ sal_uInt8 nRet = static_cast<sal_uInt8>(
+ !nRow ? 0 : ((nRow + 1 == nRows) ? 12 : (4 * (1 + ((nRow - 1) & 1)))));
+ nRet = nRet
+ + static_cast<sal_uInt8>(!nCol ? 0 : (nCol + 1 == nCols ? 3 : (1 + ((nCol - 1) & 1))));
+ return nRet;
+}
+
+struct SwTableAutoFormatTable::Impl
+{
+ std::vector<std::unique_ptr<SwTableAutoFormat>> m_AutoFormats;
+};
+
+size_t SwTableAutoFormatTable::size() const
+{
+ return m_pImpl->m_AutoFormats.size();
+}
+
+SwTableAutoFormat const& SwTableAutoFormatTable::operator[](size_t const i) const
+{
+ return *m_pImpl->m_AutoFormats[i];
+}
+SwTableAutoFormat & SwTableAutoFormatTable::operator[](size_t const i)
+{
+ return *m_pImpl->m_AutoFormats[i];
+}
+
+void SwTableAutoFormatTable::AddAutoFormat(const SwTableAutoFormat& rTableStyle)
+{
+ // don't insert when we already have style of this name
+ if (FindAutoFormat(rTableStyle.GetName()))
+ return;
+
+ InsertAutoFormat(size(), std::make_unique<SwTableAutoFormat>(rTableStyle));
+}
+
+void SwTableAutoFormatTable::InsertAutoFormat(size_t const i, std::unique_ptr<SwTableAutoFormat> pFormat)
+{
+ m_pImpl->m_AutoFormats.insert(m_pImpl->m_AutoFormats.begin() + i, std::move(pFormat));
+}
+
+void SwTableAutoFormatTable::EraseAutoFormat(size_t const i)
+{
+ m_pImpl->m_AutoFormats.erase(m_pImpl->m_AutoFormats.begin() + i);
+}
+
+void SwTableAutoFormatTable::EraseAutoFormat(const OUString& rName)
+{
+ auto iter = std::find_if(m_pImpl->m_AutoFormats.begin(), m_pImpl->m_AutoFormats.end(),
+ [&rName](const std::unique_ptr<SwTableAutoFormat>& rpFormat) { return rpFormat->GetName() == rName; });
+ if (iter != m_pImpl->m_AutoFormats.end())
+ {
+ m_pImpl->m_AutoFormats.erase(iter);
+ return;
+ }
+ SAL_INFO("sw.core", "SwTableAutoFormatTable::EraseAutoFormat, SwTableAutoFormat with given name not found");
+}
+
+std::unique_ptr<SwTableAutoFormat> SwTableAutoFormatTable::ReleaseAutoFormat(size_t const i)
+{
+ auto const iter(m_pImpl->m_AutoFormats.begin() + i);
+ std::unique_ptr<SwTableAutoFormat> pRet(std::move(*iter));
+ m_pImpl->m_AutoFormats.erase(iter);
+ return pRet;
+}
+
+std::unique_ptr<SwTableAutoFormat> SwTableAutoFormatTable::ReleaseAutoFormat(const OUString& rName)
+{
+ std::unique_ptr<SwTableAutoFormat> pRet;
+ auto iter = std::find_if(m_pImpl->m_AutoFormats.begin(), m_pImpl->m_AutoFormats.end(),
+ [&rName](const std::unique_ptr<SwTableAutoFormat>& rpFormat) { return rpFormat->GetName() == rName; });
+ if (iter != m_pImpl->m_AutoFormats.end())
+ {
+ pRet = std::move(*iter);
+ m_pImpl->m_AutoFormats.erase(iter);
+ }
+ return pRet;
+}
+
+SwTableAutoFormat* SwTableAutoFormatTable::FindAutoFormat(std::u16string_view rName) const
+{
+ for (const auto &rFormat : m_pImpl->m_AutoFormats)
+ {
+ if (rFormat->GetName() == rName)
+ return rFormat.get();
+ }
+
+ return nullptr;
+}
+
+SwTableAutoFormatTable::~SwTableAutoFormatTable()
+{
+}
+
+SwTableAutoFormatTable::SwTableAutoFormatTable()
+ : m_pImpl(new Impl)
+{
+ std::unique_ptr<SwTableAutoFormat> pNew(new SwTableAutoFormat(
+ SwStyleNameMapper::GetUIName(RES_POOLTABLESTYLE_DEFAULT, OUString())));
+
+ sal_uInt8 i;
+
+ Color aColor( COL_BLACK );
+ SvxBoxItem aBox( RES_BOX );
+
+ aBox.SetAllDistances(55);
+ SvxBorderLine aLn( &aColor, SvxBorderLineWidth::VeryThin );
+ aBox.SetLine( &aLn, SvxBoxItemLine::LEFT );
+ aBox.SetLine( &aLn, SvxBoxItemLine::BOTTOM );
+
+ for( i = 0; i <= 15; ++i )
+ {
+ aBox.SetLine( i <= 3 ? &aLn : nullptr, SvxBoxItemLine::TOP );
+ aBox.SetLine( (3 == ( i & 3 )) ? &aLn : nullptr, SvxBoxItemLine::RIGHT );
+ pNew->GetBoxFormat( i ).SetBox( aBox );
+ }
+
+ pNew->SetUserDefined(false);
+ m_pImpl->m_AutoFormats.push_back(std::move(pNew));
+}
+
+void SwTableAutoFormatTable::Load()
+{
+ if (utl::ConfigManager::IsFuzzing())
+ return;
+ OUString sNm(AUTOTABLE_FORMAT_NAME);
+ SvtPathOptions aOpt;
+ if( aOpt.SearchFile( sNm ))
+ {
+ SfxMedium aStream( sNm, StreamMode::STD_READ );
+ Load( *aStream.GetInStream() );
+ }
+}
+
+bool SwTableAutoFormatTable::Save() const
+{
+ if (utl::ConfigManager::IsFuzzing())
+ return false;
+ SvtPathOptions aPathOpt;
+ const OUString sNm( aPathOpt.GetUserConfigPath() + "/" + AUTOTABLE_FORMAT_NAME );
+ SfxMedium aStream(sNm, StreamMode::STD_WRITE );
+ return Save( *aStream.GetOutStream() ) && aStream.Commit();
+}
+
+bool SwTableAutoFormatTable::Load( SvStream& rStream )
+{
+ bool bRet = ERRCODE_NONE == rStream.GetError();
+ if (bRet)
+ {
+ // Attention: We need to read a general Header here
+ sal_uInt16 nVal = 0;
+ rStream.ReadUInt16( nVal );
+ bRet = ERRCODE_NONE == rStream.GetError();
+
+ if( bRet )
+ {
+ SwAfVersions aVersions;
+
+ // Default version is 5.0, unless we detect an old format ID.
+ sal_uInt16 nFileVers = SOFFICE_FILEFORMAT_50;
+ if(nVal < AUTOFORMAT_ID_31005)
+ nFileVers = SOFFICE_FILEFORMAT_40;
+
+ if( nVal == AUTOFORMAT_ID_358 ||
+ (AUTOFORMAT_ID_504 <= nVal && nVal <= AUTOFORMAT_ID) )
+ {
+ sal_uInt8 nChrSet, nCnt;
+ sal_uInt64 nPos = rStream.Tell();
+ rStream.ReadUChar( nCnt ).ReadUChar( nChrSet );
+ if( rStream.Tell() != nPos + nCnt )
+ {
+ OSL_ENSURE( false, "The Header contains more or newer Data" );
+ rStream.Seek( nPos + nCnt );
+ }
+ rStream.SetStreamCharSet( static_cast<rtl_TextEncoding>(nChrSet) );
+ rStream.SetVersion( nFileVers );
+ }
+
+ if( nVal == AUTOFORMAT_ID_358 || nVal == AUTOFORMAT_ID_X ||
+ (AUTOFORMAT_ID_504 <= nVal && nVal <= AUTOFORMAT_ID) )
+ {
+ aVersions.Load( rStream, nVal ); // Item versions
+
+ sal_uInt16 nCount = 0;
+ rStream.ReadUInt16( nCount );
+
+ bRet = ERRCODE_NONE== rStream.GetError();
+ if (bRet)
+ {
+ const size_t nMinRecordSize = sizeof(sal_uInt16);
+ const size_t nMaxRecords = rStream.remainingSize() / nMinRecordSize;
+ if (nCount > nMaxRecords)
+ {
+ SAL_WARN("sw.core", "Parsing error: " << nMaxRecords <<
+ " max possible entries, but " << nCount << " claimed, truncating");
+ nCount = nMaxRecords;
+ }
+ for (sal_uInt16 i = 0; i < nCount; ++i)
+ {
+ std::unique_ptr<SwTableAutoFormat> pNew(
+ new SwTableAutoFormat( OUString() ));
+ bRet = pNew->Load( rStream, aVersions );
+ if( bRet )
+ {
+ m_pImpl->m_AutoFormats.push_back(std::move(pNew));
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+ }
+ else
+ {
+ bRet = false;
+ }
+ }
+ }
+ return bRet;
+}
+
+bool SwTableAutoFormatTable::Save( SvStream& rStream ) const
+{
+ bool bRet = ERRCODE_NONE == rStream.GetError();
+ if (bRet)
+ {
+ rStream.SetVersion(AUTOFORMAT_FILE_VERSION);
+
+ // Attention: We need to save a general Header here
+ rStream.WriteUInt16( AUTOFORMAT_ID )
+ .WriteUChar( 2 ) // Character count of the Header including this value
+ .WriteUChar( GetStoreCharSet( ::osl_getThreadTextEncoding() ) );
+
+ bRet = ERRCODE_NONE == rStream.GetError();
+ if (!bRet)
+ return false;
+
+ // Write this version number for all attributes
+ SwAfVersions::Write(rStream, AUTOFORMAT_FILE_VERSION);
+
+ rStream.WriteUInt16( m_pImpl->m_AutoFormats.size() - 1 );
+ bRet = ERRCODE_NONE == rStream.GetError();
+
+ for (size_t i = 1; bRet && i < m_pImpl->m_AutoFormats.size(); ++i)
+ {
+ SwTableAutoFormat const& rFormat = *m_pImpl->m_AutoFormats[i];
+ bRet = rFormat.Save(rStream, AUTOFORMAT_FILE_VERSION);
+ }
+ }
+ rStream.FlushBuffer();
+ return bRet;
+}
+
+SwCellStyleTable::SwCellStyleTable()
+{ }
+
+SwCellStyleTable::~SwCellStyleTable()
+{
+}
+
+size_t SwCellStyleTable::size() const
+{
+ return m_aCellStyles.size();
+}
+
+void SwCellStyleTable::clear()
+{
+ m_aCellStyles.clear();
+}
+
+SwCellStyleDescriptor SwCellStyleTable::operator[](size_t i) const
+{
+ return SwCellStyleDescriptor(m_aCellStyles[i]);
+}
+
+void SwCellStyleTable::AddBoxFormat(const SwBoxAutoFormat& rBoxFormat, const OUString& sName)
+{
+ m_aCellStyles.emplace_back(sName, std::make_unique<SwBoxAutoFormat>(rBoxFormat));
+}
+
+void SwCellStyleTable::RemoveBoxFormat(const OUString& sName)
+{
+ auto iter = std::find_if(m_aCellStyles.begin(), m_aCellStyles.end(),
+ [&sName](const std::pair<OUString, std::unique_ptr<SwBoxAutoFormat>>& rStyle) { return rStyle.first == sName; });
+ if (iter != m_aCellStyles.end())
+ {
+ m_aCellStyles.erase(iter);
+ return;
+ }
+ SAL_INFO("sw.core", "SwCellStyleTable::RemoveBoxFormat, format with given name doesn't exists");
+}
+
+OUString SwCellStyleTable::GetBoxFormatName(const SwBoxAutoFormat& rBoxFormat) const
+{
+ for (size_t i=0; i < m_aCellStyles.size(); ++i)
+ {
+ if (m_aCellStyles[i].second.get() == &rBoxFormat)
+ return m_aCellStyles[i].first;
+ }
+
+ // box format not found
+ return OUString();
+}
+
+SwBoxAutoFormat* SwCellStyleTable::GetBoxFormat(std::u16string_view sName) const
+{
+ for (size_t i=0; i < m_aCellStyles.size(); ++i)
+ {
+ if (m_aCellStyles[i].first == sName)
+ return m_aCellStyles[i].second.get();
+ }
+
+ return nullptr;
+}
+
+void SwCellStyleTable::ChangeBoxFormatName(std::u16string_view sFromName, const OUString& sToName)
+{
+ if (!GetBoxFormat(sToName))
+ {
+ SAL_INFO("sw.core", "SwCellStyleTable::ChangeBoxName, box with given name already exists");
+ return;
+ }
+ for (size_t i=0; i < m_aCellStyles.size(); ++i)
+ {
+ if (m_aCellStyles[i].first == sFromName)
+ {
+ m_aCellStyles[i].first = sToName;
+ // changed successfully
+ return;
+ }
+ }
+ SAL_INFO("sw.core", "SwCellStyleTable::ChangeBoxName, box with given name not found");
+}
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */