1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <comphelper/fileformat.h>
21 #include <tools/stream.hxx>
22 #include <sfx2/docfile.hxx>
23 #include <svl/numformat.hxx>
24 #include <svl/zforlist.hxx>
25 #include <svl/zformat.hxx>
26 #include <unotools/configmgr.hxx>
27 #include <unotools/pathoptions.hxx>
28 #include <swtable.hxx>
29 #include <swtblfmt.hxx>
30 #include <com/sun/star/text/VertOrientation.hpp>
31 #include <swtypes.hxx>
33 #include <poolfmt.hxx>
34 #include <tblafmt.hxx>
35 #include <cellatr.hxx>
36 #include <SwStyleNameMapper.hxx>
37 #include <hintids.hxx>
38 #include <fmtornt.hxx>
40 #include <fmtlsplt.hxx>
41 #include <fmtrowsplt.hxx>
42 #include <sal/log.hxx>
43 #include <osl/diagnose.h>
44 #include <osl/thread.h>
46 #include <editeng/adjustitem.hxx>
47 #include <editeng/boxitem.hxx>
48 #include <editeng/brushitem.hxx>
49 #include <editeng/colritem.hxx>
50 #include <editeng/contouritem.hxx>
51 #include <editeng/crossedoutitem.hxx>
52 #include <editeng/fontitem.hxx>
53 #include <editeng/formatbreakitem.hxx>
54 #include <editeng/fhgtitem.hxx>
55 #include <editeng/justifyitem.hxx>
56 #include <editeng/legacyitem.hxx>
57 #include <editeng/lineitem.hxx>
58 #include <editeng/postitem.hxx>
59 #include <editeng/shdditem.hxx>
60 #include <editeng/udlnitem.hxx>
61 #include <editeng/wghtitem.hxx>
62 #include <svx/algitem.hxx>
63 #include <svx/rotmodit.hxx>
64 #include <legacyitem.hxx>
65 #include <unostyle.hxx>
72 * XXX: BIG RED NOTICE! Changes MUST be binary file format compatible and MUST
73 * be synchronized with Calc's ScAutoFormat sc/source/core/tool/autoform.cxx
76 using ::editeng::SvxBorderLine
;
79 const sal_uInt16 AUTOFORMAT_ID_X
= 9501;
80 const sal_uInt16 AUTOFORMAT_ID_358
= 9601;
81 const sal_uInt16 AUTOFORMAT_DATA_ID_X
= 9502;
84 //! In follow-up versions these IDs' values need to increase
85 const sal_uInt16 AUTOFORMAT_ID_504
= 9801;
86 const sal_uInt16 AUTOFORMAT_DATA_ID_504
= 9802;
88 const sal_uInt16 AUTOFORMAT_DATA_ID_552
= 9902;
90 // --- from 680/dr25 on: store strings as UTF-8
91 const sal_uInt16 AUTOFORMAT_ID_680DR25
= 10021;
93 // --- Bug fix to fdo#31005: Table Autoformats does not save/apply all properties (Writer and Calc)
94 const sal_uInt16 AUTOFORMAT_ID_31005
= 10041;
95 const sal_uInt16 AUTOFORMAT_DATA_ID_31005
= 10042;
98 const sal_uInt16 AUTOFORMAT_ID
= AUTOFORMAT_ID_31005
;
99 const sal_uInt16 AUTOFORMAT_DATA_ID
= AUTOFORMAT_DATA_ID_31005
;
100 const sal_uInt16 AUTOFORMAT_FILE_VERSION
= SOFFICE_FILEFORMAT_50
;
102 SwBoxAutoFormat
* SwTableAutoFormat::s_pDefaultBoxAutoFormat
= nullptr;
104 constexpr OUStringLiteral AUTOTABLE_FORMAT_NAME
= u
"autotbl.fmt";
108 /// Begins a writer-specific data block. Call before serializing any writer-specific properties.
109 sal_uInt64
BeginSwBlock(SvStream
& rStream
)
111 // We need to write down the offset of the end of the writer-specific data, so that
112 // calc can skip it. We'll only have that value after writing the data, so we
113 // write a placeholder value first, write the data, then jump back and write the
116 // Note that we explicitly use sal_uInt64 instead of sal_Size (which can be 32
117 // or 64 depending on platform) to ensure 64-bit portability on this front. I don't
118 // actually know if autotbl.fmt as a whole is portable, since that requires all serialization
119 // logic to be written with portability in mind.
120 sal_uInt64 whereToWriteEndOfSwBlock
= rStream
.Tell();
122 rStream
.WriteUInt64( 0 ); // endOfSwBlock
124 return whereToWriteEndOfSwBlock
;
127 /// Ends a writer-specific data block. Call after serializing writer-specific properties.
128 /// Closes a corresponding BeginSwBlock call.
129 void EndSwBlock(SvStream
& rStream
, sal_uInt64 whereToWriteEndOfSwBlock
)
131 sal_uInt64 endOfSwBlock
= rStream
.Tell();
132 rStream
.Seek(whereToWriteEndOfSwBlock
);
133 rStream
.WriteUInt64( endOfSwBlock
);
134 rStream
.Seek(endOfSwBlock
);
138 Helper class for writer-specific blocks. Begins a writer-specific block on construction,
139 and closes it on destruction.
141 See also: BeginSwBlock and EndSwBlock.
143 class WriterSpecificAutoFormatBlock
146 explicit WriterSpecificAutoFormatBlock(SvStream
& rStream
)
148 , mnWhereToWriteEndOfBlock(BeginSwBlock(rStream
))
152 ~WriterSpecificAutoFormatBlock() { EndSwBlock(mrStream
, mnWhereToWriteEndOfBlock
); }
155 WriterSpecificAutoFormatBlock(WriterSpecificAutoFormatBlock
const&) = delete;
156 WriterSpecificAutoFormatBlock
& operator=(WriterSpecificAutoFormatBlock
const&) = delete;
159 sal_uInt64 mnWhereToWriteEndOfBlock
;
162 /// Checks whether a writer-specific block exists (i.e. size is not zero)
163 sal_Int64
WriterSpecificBlockExists(SvStream
&stream
)
165 sal_uInt64 endOfSwBlock
= 0;
166 stream
.ReadUInt64( endOfSwBlock
);
168 // end-of-block pointing to itself indicates a zero-size block.
169 return endOfSwBlock
- stream
.Tell();
173 // Struct with version numbers of the Items
175 struct SwAfVersions
: public AutoFormatVersions
178 sal_uInt16 m_nTextOrientationVersion
;
179 sal_uInt16 m_nVerticalAlignmentVersion
;
182 void Load( SvStream
& rStream
, sal_uInt16 nVer
);
183 static void Write(SvStream
& rStream
, sal_uInt16 fileVersion
);
186 SwAfVersions::SwAfVersions()
187 : m_nTextOrientationVersion(0),
188 m_nVerticalAlignmentVersion(0)
192 void SwAfVersions::Load( SvStream
& rStream
, sal_uInt16 nVer
)
194 LoadBlockA(rStream
, nVer
);
195 if (nVer
>= AUTOFORMAT_ID_31005
&& WriterSpecificBlockExists(rStream
))
197 rStream
.ReadUInt16( m_nTextOrientationVersion
);
198 rStream
.ReadUInt16( m_nVerticalAlignmentVersion
);
200 LoadBlockB(rStream
, nVer
);
203 void SwAfVersions::Write(SvStream
& rStream
, sal_uInt16 fileVersion
)
205 AutoFormatVersions::WriteBlockA(rStream
, fileVersion
);
207 if (fileVersion
>= SOFFICE_FILEFORMAT_50
)
209 WriterSpecificAutoFormatBlock
block(rStream
);
211 rStream
.WriteUInt16(legacy::SvxFrameDirection::GetVersion(fileVersion
));
212 rStream
.WriteUInt16(legacy::SwFormatVert::GetVersion(fileVersion
));
215 AutoFormatVersions::WriteBlockB(rStream
, fileVersion
);
220 SwBoxAutoFormat::SwBoxAutoFormat()
221 : m_aTextOrientation(std::make_unique
<SvxFrameDirectionItem
>(SvxFrameDirection::Environment
, RES_FRAMEDIR
)),
222 m_aVerticalAlignment(std::make_unique
<SwFormatVertOrient
>(0, css::text::VertOrientation::NONE
, css::text::RelOrientation::FRAME
)),
223 m_eSysLanguage(::GetAppLanguage()),
224 m_eNumFormatLanguage(::GetAppLanguage())
226 // need to set default instances for base class AutoFormatBase here
227 // due to resource defines (e.g. RES_CHRATR_FONT) which are not available
228 // in svx and different in the different usages of derivations
229 m_aFont
= std::make_unique
<SvxFontItem
>(*GetDfltAttr( RES_CHRATR_FONT
) );
230 m_aHeight
= std::make_unique
<SvxFontHeightItem
>(240, 100, RES_CHRATR_FONTSIZE
);
231 m_aWeight
= std::make_unique
<SvxWeightItem
>(WEIGHT_NORMAL
, RES_CHRATR_WEIGHT
);
232 m_aPosture
= std::make_unique
<SvxPostureItem
>(ITALIC_NONE
, RES_CHRATR_POSTURE
);
233 m_aCJKFont
= std::make_unique
<SvxFontItem
>(*GetDfltAttr( RES_CHRATR_CJK_FONT
) );
234 m_aCJKHeight
= std::make_unique
<SvxFontHeightItem
>(240, 100, RES_CHRATR_CJK_FONTSIZE
);
235 m_aCJKWeight
= std::make_unique
<SvxWeightItem
>(WEIGHT_NORMAL
, RES_CHRATR_CJK_WEIGHT
);
236 m_aCJKPosture
= std::make_unique
<SvxPostureItem
>(ITALIC_NONE
, RES_CHRATR_CJK_POSTURE
);
237 m_aCTLFont
= std::make_unique
<SvxFontItem
>(*GetDfltAttr( RES_CHRATR_CTL_FONT
) );
238 m_aCTLHeight
= std::make_unique
<SvxFontHeightItem
>(240, 100, RES_CHRATR_CTL_FONTSIZE
);
239 m_aCTLWeight
= std::make_unique
<SvxWeightItem
>(WEIGHT_NORMAL
, RES_CHRATR_CTL_WEIGHT
);
240 m_aCTLPosture
= std::make_unique
<SvxPostureItem
>(ITALIC_NONE
, RES_CHRATR_CTL_POSTURE
);
241 m_aUnderline
= std::make_unique
<SvxUnderlineItem
>(LINESTYLE_NONE
, RES_CHRATR_UNDERLINE
);
242 m_aOverline
= std::make_unique
<SvxOverlineItem
>(LINESTYLE_NONE
, RES_CHRATR_OVERLINE
);
243 m_aCrossedOut
= std::make_unique
<SvxCrossedOutItem
>(STRIKEOUT_NONE
, RES_CHRATR_CROSSEDOUT
);
244 m_aContour
= std::make_unique
<SvxContourItem
>(false, RES_CHRATR_CONTOUR
);
245 m_aShadowed
= std::make_unique
<SvxShadowedItem
>(false, RES_CHRATR_SHADOWED
);
246 m_aColor
= std::make_unique
<SvxColorItem
>(RES_CHRATR_COLOR
);
247 m_aBox
= std::make_unique
<SvxBoxItem
>(RES_BOX
);
248 m_aTLBR
= std::make_unique
<SvxLineItem
>(0 );
249 m_aBLTR
= std::make_unique
<SvxLineItem
>(0 );
250 m_aBackground
= std::make_unique
<SvxBrushItem
>(RES_BACKGROUND
);
251 m_aAdjust
= std::make_unique
<SvxAdjustItem
>(SvxAdjust::Left
, RES_PARATR_ADJUST
);
252 m_aHorJustify
= std::make_unique
<SvxHorJustifyItem
>(SvxCellHorJustify::Standard
, 0);
253 m_aVerJustify
= std::make_unique
<SvxVerJustifyItem
>(SvxCellVerJustify::Standard
, 0);
254 m_aStacked
= std::make_unique
<SfxBoolItem
>(0 );
255 m_aMargin
= std::make_unique
<SvxMarginItem
>( TypedWhichId
<SvxMarginItem
>(0) );
256 m_aLinebreak
= std::make_unique
<SfxBoolItem
>(0 );
257 m_aRotateAngle
= std::make_unique
<SfxInt32Item
>(0 );
258 m_aRotateMode
= std::make_unique
<SvxRotateModeItem
>(SVX_ROTATE_MODE_STANDARD
, TypedWhichId
<SvxRotateModeItem
>(0) );
260 // FIXME - add attribute IDs for the diagonal line items
263 m_aBox
->SetAllDistances(55);
266 SwBoxAutoFormat::SwBoxAutoFormat( const SwBoxAutoFormat
& rNew
)
267 : AutoFormatBase(rNew
),
268 m_aTextOrientation(rNew
.m_aTextOrientation
->Clone()),
269 m_aVerticalAlignment(rNew
.m_aVerticalAlignment
->Clone()),
270 m_sNumFormatString( rNew
.m_sNumFormatString
),
271 m_eSysLanguage( rNew
.m_eSysLanguage
),
272 m_eNumFormatLanguage( rNew
.m_eNumFormatLanguage
)
276 SwBoxAutoFormat::~SwBoxAutoFormat()
280 SwBoxAutoFormat
& SwBoxAutoFormat::operator=(const SwBoxAutoFormat
& rRef
)
282 // check self-assignment
288 // call baseclass implementation
289 AutoFormatBase::operator=(rRef
);
291 // copy local members - this will use ::Clone() on all involved Items
292 SetTextOrientation(rRef
.GetTextOrientation());
293 SetVerticalAlignment(rRef
.GetVerticalAlignment());
294 SetNumFormatString(rRef
.GetNumFormatString());
295 SetSysLanguage(rRef
.GetSysLanguage());
296 SetNumFormatLanguage(rRef
.GetNumFormatLanguage());
298 // m_wXObject used to not be copied before 1e2682235cded9a7cd90e55f0bfc60a1285e9a46
299 // "WIP: Further preparations for deeper Item changes" by this operator, so do not do it now, too
300 // rRef.SetXObject(GetXObject());
305 bool SwBoxAutoFormat::operator==(const SwBoxAutoFormat
& rRight
) const
307 return GetBackground().GetColor() == rRight
.GetBackground().GetColor();
310 bool SwBoxAutoFormat::Load( SvStream
& rStream
, const SwAfVersions
& rVersions
, sal_uInt16 nVer
)
312 LoadBlockA( rStream
, rVersions
, nVer
);
314 if (nVer
>= AUTOFORMAT_DATA_ID_31005
)
316 sal_Int64
const nSize(WriterSpecificBlockExists(rStream
));
317 if (0 < nSize
&& nSize
< std::numeric_limits
<sal_uInt16
>::max())
319 legacy::SvxFrameDirection::Create(*m_aTextOrientation
, rStream
, rVersions
.m_nTextOrientationVersion
);
320 // HORRIBLE HACK to read both 32-bit and 64-bit "long": abuse nSize
321 legacy::SwFormatVert::Create(*m_aVerticalAlignment
, rStream
, /*rVersions.m_nVerticalAlignmentVersion*/ nSize
);
325 LoadBlockB( rStream
, rVersions
, nVer
);
327 if( 0 == rVersions
.nNumFormatVersion
)
329 sal_uInt16 eSys
, eLge
;
330 // --- from 680/dr25 on: store strings as UTF-8
331 rtl_TextEncoding eCharSet
= (nVer
>= AUTOFORMAT_ID_680DR25
) ? RTL_TEXTENCODING_UTF8
: rStream
.GetStreamCharSet();
332 m_sNumFormatString
= rStream
.ReadUniOrByteString( eCharSet
);
333 rStream
.ReadUInt16( eSys
).ReadUInt16( eLge
);
334 m_eSysLanguage
= LanguageType(eSys
);
335 m_eNumFormatLanguage
= LanguageType(eLge
);
336 if ( m_eSysLanguage
== LANGUAGE_SYSTEM
) // from old versions (Calc)
337 m_eSysLanguage
= ::GetAppLanguage();
340 return ERRCODE_NONE
== rStream
.GetError();
343 bool SwBoxAutoFormat::Save( SvStream
& rStream
, sal_uInt16 fileVersion
) const
345 SaveBlockA( rStream
, fileVersion
);
347 if (fileVersion
>= SOFFICE_FILEFORMAT_50
)
349 WriterSpecificAutoFormatBlock
block(rStream
);
351 legacy::SvxFrameDirection::Store(*m_aTextOrientation
, rStream
, legacy::SvxFrameDirection::GetVersion(fileVersion
));
352 legacy::SwFormatVert::Store(*m_aVerticalAlignment
, rStream
, legacy::SwFormatVert::GetVersion(fileVersion
));
355 SaveBlockB( rStream
, fileVersion
);
357 // --- from 680/dr25 on: store strings as UTF-8
358 write_uInt16_lenPrefixed_uInt8s_FromOUString(rStream
, m_sNumFormatString
,
359 RTL_TEXTENCODING_UTF8
);
360 rStream
.WriteUInt16( static_cast<sal_uInt16
>(m_eSysLanguage
) ).WriteUInt16( static_cast<sal_uInt16
>(m_eNumFormatLanguage
) );
362 return ERRCODE_NONE
== rStream
.GetError();
365 void SwBoxAutoFormat::SetXObject(rtl::Reference
<SwXTextCellStyle
> const& xObject
)
367 m_xAutoFormatUnoObject
= xObject
.get();
370 SwTableAutoFormat::SwTableAutoFormat( OUString aName
)
371 : m_aName( std::move(aName
) )
372 , m_nStrResId( USHRT_MAX
)
373 , m_aKeepWithNextPara(std::make_shared
<SvxFormatKeepItem
>(false, RES_KEEP
))
374 , m_aRepeatHeading( 0 )
375 , m_bLayoutSplit( true )
376 , m_bRowSplit( true )
377 , m_bCollapsingBorders(true)
378 , m_aShadow(std::make_shared
<SvxShadowItem
>(RES_SHADOW
))
380 , m_bUserDefined( true )
383 m_bInclJustify
= true;
385 m_bInclBackground
= true;
386 m_bInclValueFormat
= true;
387 m_bInclWidthHeight
= true;
390 SwTableAutoFormat::SwTableAutoFormat( const SwTableAutoFormat
& rNew
)
391 : m_aShadow(std::make_shared
<SvxShadowItem
>(RES_SHADOW
))
393 for(SwBoxAutoFormat
* & rp
: m_aBoxAutoFormat
)
398 SwTableAutoFormat
& SwTableAutoFormat::operator=( const SwTableAutoFormat
& rNew
)
403 for( sal_uInt8 n
= 0; n
< 16; ++n
)
405 if( m_aBoxAutoFormat
[ n
] )
406 delete m_aBoxAutoFormat
[ n
];
408 SwBoxAutoFormat
* pFormat
= rNew
.m_aBoxAutoFormat
[ n
];
409 if( pFormat
) // if is set -> copy
410 m_aBoxAutoFormat
[ n
] = new SwBoxAutoFormat( *pFormat
);
412 m_aBoxAutoFormat
[ n
] = nullptr;
415 m_aName
= rNew
.m_aName
;
416 m_nStrResId
= rNew
.m_nStrResId
;
417 m_bInclFont
= rNew
.m_bInclFont
;
418 m_bInclJustify
= rNew
.m_bInclJustify
;
419 m_bInclFrame
= rNew
.m_bInclFrame
;
420 m_bInclBackground
= rNew
.m_bInclBackground
;
421 m_bInclValueFormat
= rNew
.m_bInclValueFormat
;
422 m_bInclWidthHeight
= rNew
.m_bInclWidthHeight
;
424 m_aKeepWithNextPara
.reset(rNew
.m_aKeepWithNextPara
->Clone());
425 m_aRepeatHeading
= rNew
.m_aRepeatHeading
;
426 m_bLayoutSplit
= rNew
.m_bLayoutSplit
;
427 m_bRowSplit
= rNew
.m_bRowSplit
;
428 m_bCollapsingBorders
= rNew
.m_bCollapsingBorders
;
429 m_aShadow
.reset(rNew
.m_aShadow
->Clone());
430 m_bHidden
= rNew
.m_bHidden
;
431 m_bUserDefined
= rNew
.m_bUserDefined
;
436 SwTableAutoFormat::~SwTableAutoFormat()
438 SwBoxAutoFormat
** ppFormat
= m_aBoxAutoFormat
;
439 for( sal_uInt8 n
= 0; n
< 16; ++n
, ++ppFormat
)
444 void SwTableAutoFormat::SetBoxFormat( const SwBoxAutoFormat
& rNew
, sal_uInt8 nPos
)
446 OSL_ENSURE( nPos
< 16, "wrong area" );
448 SwBoxAutoFormat
* pFormat
= m_aBoxAutoFormat
[ nPos
];
449 if( pFormat
) // if is set -> copy
450 *m_aBoxAutoFormat
[ nPos
] = rNew
;
451 else // else set anew
452 m_aBoxAutoFormat
[ nPos
] = new SwBoxAutoFormat( rNew
);
455 const SwBoxAutoFormat
& SwTableAutoFormat::GetBoxFormat( sal_uInt8 nPos
) const
457 OSL_ENSURE( nPos
< 16, "wrong area" );
459 SwBoxAutoFormat
* pFormat
= m_aBoxAutoFormat
[ nPos
];
460 if( pFormat
) // if is set -> copy
462 else // else return the default
464 // If it doesn't exist yet:
465 if( !s_pDefaultBoxAutoFormat
)
466 s_pDefaultBoxAutoFormat
= new SwBoxAutoFormat
;
467 return *s_pDefaultBoxAutoFormat
;
471 SwBoxAutoFormat
& SwTableAutoFormat::GetBoxFormat( sal_uInt8 nPos
)
473 SAL_WARN_IF(!(nPos
< 16), "sw.core", "GetBoxFormat wrong area");
475 SwBoxAutoFormat
** pFormat
= &m_aBoxAutoFormat
[ nPos
];
478 // If default doesn't exist yet:
479 if( !s_pDefaultBoxAutoFormat
)
480 s_pDefaultBoxAutoFormat
= new SwBoxAutoFormat();
481 *pFormat
= new SwBoxAutoFormat(*s_pDefaultBoxAutoFormat
);
486 const SwBoxAutoFormat
& SwTableAutoFormat::GetDefaultBoxFormat()
488 if(!s_pDefaultBoxAutoFormat
)
489 s_pDefaultBoxAutoFormat
= new SwBoxAutoFormat();
491 return *s_pDefaultBoxAutoFormat
;
494 void SwTableAutoFormat::UpdateFromSet( sal_uInt8 nPos
,
495 const SfxItemSet
& rSet
,
496 SwTableAutoFormatUpdateFlags eFlags
,
497 SvNumberFormatter
const * pNFormatr
)
499 OSL_ENSURE( nPos
< 16, "wrong area" );
501 SwBoxAutoFormat
* pFormat
= m_aBoxAutoFormat
[ nPos
];
502 if( !pFormat
) // if is set -> copy
504 pFormat
= new SwBoxAutoFormat
;
505 m_aBoxAutoFormat
[ nPos
] = pFormat
;
508 if( SwTableAutoFormatUpdateFlags::Char
& eFlags
)
510 pFormat
->SetFont( rSet
.Get( RES_CHRATR_FONT
) );
511 pFormat
->SetHeight( rSet
.Get( RES_CHRATR_FONTSIZE
) );
512 pFormat
->SetWeight( rSet
.Get( RES_CHRATR_WEIGHT
) );
513 pFormat
->SetPosture( rSet
.Get( RES_CHRATR_POSTURE
) );
514 pFormat
->SetCJKFont( rSet
.Get( RES_CHRATR_CJK_FONT
) );
515 pFormat
->SetCJKHeight( rSet
.Get( RES_CHRATR_CJK_FONTSIZE
) );
516 pFormat
->SetCJKWeight( rSet
.Get( RES_CHRATR_CJK_WEIGHT
) );
517 pFormat
->SetCJKPosture( rSet
.Get( RES_CHRATR_CJK_POSTURE
) );
518 pFormat
->SetCTLFont( rSet
.Get( RES_CHRATR_CTL_FONT
) );
519 pFormat
->SetCTLHeight( rSet
.Get( RES_CHRATR_CTL_FONTSIZE
) );
520 pFormat
->SetCTLWeight( rSet
.Get( RES_CHRATR_CTL_WEIGHT
) );
521 pFormat
->SetCTLPosture( rSet
.Get( RES_CHRATR_CTL_POSTURE
) );
522 pFormat
->SetUnderline( rSet
.Get( RES_CHRATR_UNDERLINE
) );
523 pFormat
->SetOverline( rSet
.Get( RES_CHRATR_OVERLINE
) );
524 pFormat
->SetCrossedOut( rSet
.Get( RES_CHRATR_CROSSEDOUT
) );
525 pFormat
->SetContour( rSet
.Get( RES_CHRATR_CONTOUR
) );
526 pFormat
->SetShadowed( rSet
.Get( RES_CHRATR_SHADOWED
) );
527 pFormat
->SetColor( rSet
.Get( RES_CHRATR_COLOR
) );
528 pFormat
->SetAdjust( rSet
.Get( RES_PARATR_ADJUST
) );
530 if( !(SwTableAutoFormatUpdateFlags::Box
& eFlags
) )
533 pFormat
->SetBox( rSet
.Get( RES_BOX
) );
534 // FIXME - add attribute IDs for the diagonal line items
535 // pFormat->SetTLBR( (SvxLineItem&)rSet.Get( RES_... ) );
536 // pFormat->SetBLTR( (SvxLineItem&)rSet.Get( RES_... ) );
537 pFormat
->SetBackground( rSet
.Get( RES_BACKGROUND
) );
538 pFormat
->SetTextOrientation(rSet
.Get(RES_FRAMEDIR
));
539 pFormat
->SetVerticalAlignment(rSet
.Get(RES_VERT_ORIENT
));
541 const SwTableBoxNumFormat
* pNumFormatItem
;
542 const SvNumberformat
* pNumFormat
= nullptr;
543 if( pNFormatr
&& (pNumFormatItem
= rSet
.GetItemIfSet( RES_BOXATR_FORMAT
)) &&
544 nullptr != (pNumFormat
= pNFormatr
->GetEntry( pNumFormatItem
->GetValue() )) )
545 pFormat
->SetValueFormat( pNumFormat
->GetFormatstring(),
546 pNumFormat
->GetLanguage(),
551 pFormat
->SetValueFormat( OUString(), LANGUAGE_SYSTEM
,
552 ::GetAppLanguage() );
555 // we cannot handle the rest, that's specific to StarCalc
558 void SwTableAutoFormat::UpdateToSet(const sal_uInt8 nPos
, const bool bSingleRowTable
, const bool bSingleColTable
, SfxItemSet
& rSet
,
559 SwTableAutoFormatUpdateFlags eFlags
, SvNumberFormatter
* pNFormatr
) const
561 const SwBoxAutoFormat
& rChg
= GetBoxFormat( nPos
);
563 if( SwTableAutoFormatUpdateFlags::Char
& eFlags
)
567 rSet
.Put( rChg
.GetFont() );
568 rSet
.Put( rChg
.GetHeight() );
569 rSet
.Put( rChg
.GetWeight() );
570 rSet
.Put( rChg
.GetPosture() );
571 // do not insert empty CJK font
572 const SvxFontItem
& rCJKFont
= rChg
.GetCJKFont();
573 if (!rCJKFont
.GetStyleName().isEmpty())
575 rSet
.Put( rChg
.GetCJKFont() );
576 rSet
.Put( rChg
.GetCJKHeight() );
577 rSet
.Put( rChg
.GetCJKWeight() );
578 rSet
.Put( rChg
.GetCJKPosture() );
582 rSet
.Put( rChg
.GetHeight().CloneSetWhich(RES_CHRATR_CJK_FONTSIZE
) );
583 rSet
.Put( rChg
.GetWeight().CloneSetWhich(RES_CHRATR_CJK_WEIGHT
) );
584 rSet
.Put( rChg
.GetPosture().CloneSetWhich(RES_CHRATR_CJK_POSTURE
) );
586 // do not insert empty CTL font
587 const SvxFontItem
& rCTLFont
= rChg
.GetCTLFont();
588 if (!rCTLFont
.GetStyleName().isEmpty())
590 rSet
.Put( rChg
.GetCTLFont() );
591 rSet
.Put( rChg
.GetCTLHeight() );
592 rSet
.Put( rChg
.GetCTLWeight() );
593 rSet
.Put( rChg
.GetCTLPosture() );
597 rSet
.Put( rChg
.GetHeight().CloneSetWhich(RES_CHRATR_CTL_FONTSIZE
) );
598 rSet
.Put( rChg
.GetWeight().CloneSetWhich(RES_CHRATR_CTL_WEIGHT
) );
599 rSet
.Put( rChg
.GetPosture().CloneSetWhich(RES_CHRATR_CTL_POSTURE
) );
601 rSet
.Put( rChg
.GetUnderline() );
602 rSet
.Put( rChg
.GetOverline() );
603 rSet
.Put( rChg
.GetCrossedOut() );
604 rSet
.Put( rChg
.GetContour() );
605 rSet
.Put( rChg
.GetShadowed() );
606 rSet
.Put( rChg
.GetColor() );
609 rSet
.Put( rChg
.GetAdjust() );
612 if( !(SwTableAutoFormatUpdateFlags::Box
& eFlags
) )
617 SvxBoxItem aAutoFormatBox
= rChg
.GetBox();
619 // No format box is adequate to specify the borders of single column/row tables, so combine first/last.
620 if ( bSingleRowTable
|| bSingleColTable
)
622 sal_uInt8 nSingleRowOrColumnId
= 15; //LAST_ROW_END_COLUMN
623 if ( !bSingleRowTable
)
624 nSingleRowOrColumnId
= nPos
+ 3; //LAST COLUMN (3, 7, 11, 15)
625 else if ( !bSingleColTable
)
626 nSingleRowOrColumnId
= nPos
+ 12; //LAST ROW (12, 13, 14, 15)
628 assert( nSingleRowOrColumnId
< 16 );
629 const SvxBoxItem
aLastAutoFormatBox( GetBoxFormat(nSingleRowOrColumnId
).GetBox() );
630 if ( bSingleRowTable
)
631 aAutoFormatBox
.SetLine( aLastAutoFormatBox
.GetLine(SvxBoxItemLine::BOTTOM
), SvxBoxItemLine::BOTTOM
);
632 if ( bSingleColTable
)
633 aAutoFormatBox
.SetLine( aLastAutoFormatBox
.GetLine(SvxBoxItemLine::RIGHT
), SvxBoxItemLine::RIGHT
);
636 rSet
.Put( aAutoFormatBox
);
637 // FIXME - uncomment the lines to put the diagonal line items
638 // rSet.Put( rChg.GetTLBR() );
639 // rSet.Put( rChg.GetBLTR() );
642 rSet
.Put( rChg
.GetBackground() );
644 rSet
.Put(rChg
.GetTextOrientation());
646 // Do not put a VertAlign when it has default value.
647 // It prevents the export of default value by automatic cell-styles export.
648 if (rChg
.GetVerticalAlignment().GetVertOrient() != GetDefaultBoxFormat().GetVerticalAlignment().GetVertOrient())
649 rSet
.Put(rChg
.GetVerticalAlignment());
651 if( !(IsValueFormat() && pNFormatr
) )
655 LanguageType eLng
, eSys
;
656 rChg
.GetValueFormat( sFormat
, eLng
, eSys
);
657 if( !sFormat
.isEmpty() )
659 SvNumFormatType nType
;
662 sal_uInt32 nKey
= pNFormatr
->GetIndexPuttingAndConverting( sFormat
, eLng
,
663 eSys
, nType
, bNew
, nCheckPos
);
664 rSet
.Put( SwTableBoxNumFormat( nKey
));
667 rSet
.ClearItem( RES_BOXATR_FORMAT
);
669 // we cannot handle the rest, that's specific to StarCalc
672 void SwTableAutoFormat::RestoreTableProperties(SwTable
&table
) const
674 SwTableFormat
* pFormat
= table
.GetFrameFormat();
678 SwDoc
*pDoc
= pFormat
->GetDoc();
682 SfxItemSet
rSet(pDoc
->GetAttrPool(), aTableSetRange
);
684 rSet
.Put(SwFormatLayoutSplit(m_bLayoutSplit
));
685 rSet
.Put(SfxBoolItem(RES_COLLAPSING_BORDERS
, m_bCollapsingBorders
));
686 if ( m_aKeepWithNextPara
->GetValue() )
687 rSet
.Put(*m_aKeepWithNextPara
);
688 rSet
.Put(*m_aShadow
);
690 pFormat
->SetFormatAttr(rSet
);
692 if (SwEditShell
*pShell
= pDoc
->GetEditShell())
693 pDoc
->SetRowSplit(*pShell
->getShellCursor(false), SwFormatRowSplit(m_bRowSplit
));
695 table
.SetRowsToRepeat(m_aRepeatHeading
);
698 void SwTableAutoFormat::StoreTableProperties(const SwTable
&table
)
700 SwTableFormat
* pFormat
= table
.GetFrameFormat();
704 SwDoc
*pDoc
= pFormat
->GetDoc();
708 SwEditShell
*pShell
= pDoc
->GetEditShell();
709 std::unique_ptr
<SwFormatRowSplit
> pRowSplit(pShell
? SwDoc::GetRowSplit(*pShell
->getShellCursor(false)) : nullptr);
710 m_bRowSplit
= pRowSplit
&& pRowSplit
->GetValue();
713 const SfxItemSet
&rSet
= pFormat
->GetAttrSet();
715 const SwFormatLayoutSplit
&layoutSplit
= rSet
.Get(RES_LAYOUT_SPLIT
);
716 m_bLayoutSplit
= layoutSplit
.GetValue();
717 m_bCollapsingBorders
= rSet
.Get(RES_COLLAPSING_BORDERS
).GetValue();
719 m_aKeepWithNextPara
.reset(rSet
.Get(RES_KEEP
).Clone());
720 m_aRepeatHeading
= table
.GetRowsToRepeat();
721 m_aShadow
.reset(rSet
.Get(RES_SHADOW
).Clone());
724 bool SwTableAutoFormat::FirstRowEndColumnIsRow()
726 return GetBoxFormat(3) == GetBoxFormat(2);
728 bool SwTableAutoFormat::FirstRowStartColumnIsRow()
730 return GetBoxFormat(0) == GetBoxFormat(1);
732 bool SwTableAutoFormat::LastRowEndColumnIsRow()
734 return GetBoxFormat(14) == GetBoxFormat(15);
736 bool SwTableAutoFormat::LastRowStartColumnIsRow()
738 return GetBoxFormat(12) == GetBoxFormat(13);
740 bool SwTableAutoFormat::HasHeaderRow() const
741 { // Wild guessing for PDF export: is header different from odd or body?
742 // It would be vastly better to do like SdrTableObj and have flags that
743 // determine which "special" styles apply, instead of horrible guessing.
744 return !(GetBoxFormat(1) == GetBoxFormat(5))
745 || !(GetBoxFormat(1) == GetBoxFormat(10));
748 bool SwTableAutoFormat::Load( SvStream
& rStream
, const SwAfVersions
& rVersions
)
751 rStream
.ReadUInt16( nVal
);
752 bool bRet
= ERRCODE_NONE
== rStream
.GetError();
754 if( bRet
&& (nVal
== AUTOFORMAT_DATA_ID_X
||
755 (AUTOFORMAT_DATA_ID_504
<= nVal
&& nVal
<= AUTOFORMAT_DATA_ID
)) )
758 // --- from 680/dr25 on: store strings as UTF-8
759 rtl_TextEncoding eCharSet
= (nVal
>= AUTOFORMAT_ID_680DR25
) ? RTL_TEXTENCODING_UTF8
: rStream
.GetStreamCharSet();
760 m_aName
= rStream
.ReadUniOrByteString( eCharSet
);
761 if( AUTOFORMAT_DATA_ID_552
<= nVal
)
763 rStream
.ReadUInt16( m_nStrResId
);
764 // start from 3d because default is added via constructor
765 if( m_nStrResId
< RES_POOLTABLESTYLE_END
- RES_POOLTABLESTYLE_3D
)
767 m_aName
= SwStyleNameMapper::GetUIName(RES_POOLTABLESTYLE_3D
+ m_nStrResId
, m_aName
);
770 m_nStrResId
= USHRT_MAX
;
772 rStream
.ReadCharAsBool( b
); m_bInclFont
= b
;
773 rStream
.ReadCharAsBool( b
); m_bInclJustify
= b
;
774 rStream
.ReadCharAsBool( b
); m_bInclFrame
= b
;
775 rStream
.ReadCharAsBool( b
); m_bInclBackground
= b
;
776 rStream
.ReadCharAsBool( b
); m_bInclValueFormat
= b
;
777 rStream
.ReadCharAsBool( b
); m_bInclWidthHeight
= b
;
779 if (nVal
>= AUTOFORMAT_DATA_ID_31005
&& WriterSpecificBlockExists(rStream
))
781 //this only exists for file format compat
782 SvxFormatBreakItem
aBreak(SvxBreak::NONE
, RES_BREAK
);
783 legacy::SvxFormatBreak::Create(aBreak
, rStream
, AUTOFORMAT_FILE_VERSION
);
784 legacy::SvxFormatKeep::Create(*m_aKeepWithNextPara
, rStream
, AUTOFORMAT_FILE_VERSION
);
786 rStream
.ReadUInt16( m_aRepeatHeading
).ReadCharAsBool( m_bLayoutSplit
).ReadCharAsBool( m_bRowSplit
).ReadCharAsBool( m_bCollapsingBorders
);
788 legacy::SvxShadow::Create(*m_aShadow
, rStream
, AUTOFORMAT_FILE_VERSION
);
791 bRet
= ERRCODE_NONE
== rStream
.GetError();
793 for( sal_uInt8 i
= 0; bRet
&& i
< 16; ++i
)
795 SwBoxAutoFormat
* pFormat
= new SwBoxAutoFormat
;
796 bRet
= pFormat
->Load( rStream
, rVersions
, nVal
);
798 m_aBoxAutoFormat
[ i
] = pFormat
;
806 m_bUserDefined
= false;
810 bool SwTableAutoFormat::Save( SvStream
& rStream
, sal_uInt16 fileVersion
) const
812 rStream
.WriteUInt16( AUTOFORMAT_DATA_ID
);
813 // --- from 680/dr25 on: store strings as UTF-8
814 write_uInt16_lenPrefixed_uInt8s_FromOUString(rStream
, m_aName
,
815 RTL_TEXTENCODING_UTF8
);
816 rStream
.WriteUInt16( m_nStrResId
);
817 rStream
.WriteBool( m_bInclFont
);
818 rStream
.WriteBool( m_bInclJustify
);
819 rStream
.WriteBool( m_bInclFrame
);
820 rStream
.WriteBool( m_bInclBackground
);
821 rStream
.WriteBool( m_bInclValueFormat
);
822 rStream
.WriteBool( m_bInclWidthHeight
);
825 WriterSpecificAutoFormatBlock
block(rStream
);
826 //this only exists for file format compat
827 SvxFormatBreakItem
aBreak(SvxBreak::NONE
, RES_BREAK
);
828 legacy::SvxFormatBreak::Store(aBreak
, rStream
, legacy::SvxFormatBreak::GetVersion(fileVersion
));
829 legacy::SvxFormatKeep::Store(*m_aKeepWithNextPara
, rStream
, legacy::SvxFormatKeep::GetVersion(fileVersion
));
830 rStream
.WriteUInt16( m_aRepeatHeading
).WriteBool( m_bLayoutSplit
).WriteBool( m_bRowSplit
).WriteBool( m_bCollapsingBorders
);
831 legacy::SvxShadow::Store(*m_aShadow
, rStream
, legacy::SvxShadow::GetVersion(fileVersion
));
834 bool bRet
= ERRCODE_NONE
== rStream
.GetError();
836 for( int i
= 0; bRet
&& i
< 16; ++i
)
838 SwBoxAutoFormat
* pFormat
= m_aBoxAutoFormat
[ i
];
839 if( !pFormat
) // if not set -> write default
841 // If it doesn't exist yet:
842 if( !s_pDefaultBoxAutoFormat
)
843 s_pDefaultBoxAutoFormat
= new SwBoxAutoFormat
;
844 pFormat
= s_pDefaultBoxAutoFormat
;
846 bRet
= pFormat
->Save( rStream
, fileVersion
);
851 OUString
SwTableAutoFormat::GetTableTemplateCellSubName(const SwBoxAutoFormat
& rBoxFormat
) const
853 sal_Int32 nIndex
= 0;
854 for (; nIndex
< 16; ++nIndex
)
855 if (m_aBoxAutoFormat
[nIndex
] == &rBoxFormat
) break;
857 // box format doesn't belong to this table format
861 const std::vector
<sal_Int32
> aTableTemplateMap
= GetTableTemplateMap();
862 for (size_t i
=0; i
< aTableTemplateMap
.size(); ++i
)
864 if (aTableTemplateMap
[i
] == nIndex
)
865 return "." + OUString::number(i
+ 1);
868 // box format doesn't belong to a table template
875 * +-----------------------------------------------------------------------+
876 * 0 | FRSC | FR | FREC | | | FRENC |
877 * +-----------------------------------------------------------------------+
878 * 1 | FC | ER | EC | | | LC |
879 * +-----------------------------------------------------------------------+
880 * 2 | OR | OC | BODY | | | BCKG |
881 * +-----------------------------------------------------------------------+
883 * +-----------------------------------------------------------------------+
885 * +-----------------------------------------------------------------------+
886 * 5 | LRSC | LR | LREC | | | LRENC |
887 * +-----------+-----------+-----------+-----------+-----------+-----------+
889 * EVEN = 2, 4, 6, ...
891 const std::vector
<sal_Int32
> & SwTableAutoFormat::GetTableTemplateMap()
893 static std::vector
<sal_Int32
> const aTableTemplateMap
895 1 , // FIRST_ROW // FR
896 13, // LAST_ROW // LR
897 4 , // FIRST_COLUMN // FC
898 7 , // LAST_COLUMN // LC
899 5 , // EVEN_ROWS // ER
900 8 , // ODD_ROWS // OR
901 6 , // EVEN_COLUMNS // EC
902 9 , // ODD_COLUMNS // OC
904 11, // BACKGROUND // BCKG
905 0 , // FIRST_ROW_START_COLUMN // FRSC
906 3 , // FIRST_ROW_END_COLUMN // FRENC
907 12, // LAST_ROW_START_COLUMN // LRSC
908 15, // LAST_ROW_END_COLUMN // LRENC
909 2 , // FIRST_ROW_EVEN_COLUMN // FREC
910 14, // LAST_ROW_EVEN_COLUMN // LREC
912 return aTableTemplateMap
;
915 sal_uInt8
SwTableAutoFormat::CountPos(sal_uInt32 nCol
, sal_uInt32 nCols
, sal_uInt32 nRow
,
918 sal_uInt8 nRet
= static_cast<sal_uInt8
>(
919 !nRow
? 0 : ((nRow
+ 1 == nRows
) ? 12 : (4 * (1 + ((nRow
- 1) & 1)))));
921 + static_cast<sal_uInt8
>(!nCol
? 0 : (nCol
+ 1 == nCols
? 3 : (1 + ((nCol
- 1) & 1))));
925 void SwTableAutoFormat::SetXObject(rtl::Reference
<SwXTextTableStyle
> const& xObject
)
927 m_xUnoTextTableStyle
= xObject
.get();
930 struct SwTableAutoFormatTable::Impl
932 std::vector
<std::unique_ptr
<SwTableAutoFormat
>> m_AutoFormats
;
935 size_t SwTableAutoFormatTable::size() const
937 return m_pImpl
->m_AutoFormats
.size();
940 SwTableAutoFormat
const& SwTableAutoFormatTable::operator[](size_t const i
) const
942 return *m_pImpl
->m_AutoFormats
[i
];
944 SwTableAutoFormat
& SwTableAutoFormatTable::operator[](size_t const i
)
946 return *m_pImpl
->m_AutoFormats
[i
];
949 void SwTableAutoFormatTable::AddAutoFormat(const SwTableAutoFormat
& rTableStyle
)
951 // don't insert when we already have style of this name
952 if (FindAutoFormat(rTableStyle
.GetName()))
955 InsertAutoFormat(size(), std::make_unique
<SwTableAutoFormat
>(rTableStyle
));
958 void SwTableAutoFormatTable::InsertAutoFormat(size_t const i
, std::unique_ptr
<SwTableAutoFormat
> pFormat
)
960 m_pImpl
->m_AutoFormats
.insert(m_pImpl
->m_AutoFormats
.begin() + i
, std::move(pFormat
));
963 void SwTableAutoFormatTable::EraseAutoFormat(size_t const i
)
965 m_pImpl
->m_AutoFormats
.erase(m_pImpl
->m_AutoFormats
.begin() + i
);
968 void SwTableAutoFormatTable::EraseAutoFormat(const OUString
& rName
)
970 auto iter
= std::find_if(m_pImpl
->m_AutoFormats
.begin(), m_pImpl
->m_AutoFormats
.end(),
971 [&rName
](const std::unique_ptr
<SwTableAutoFormat
>& rpFormat
) { return rpFormat
->GetName() == rName
; });
972 if (iter
!= m_pImpl
->m_AutoFormats
.end())
974 m_pImpl
->m_AutoFormats
.erase(iter
);
977 SAL_INFO("sw.core", "SwTableAutoFormatTable::EraseAutoFormat, SwTableAutoFormat with given name not found");
980 std::unique_ptr
<SwTableAutoFormat
> SwTableAutoFormatTable::ReleaseAutoFormat(size_t const i
)
982 auto const iter(m_pImpl
->m_AutoFormats
.begin() + i
);
983 std::unique_ptr
<SwTableAutoFormat
> pRet(std::move(*iter
));
984 m_pImpl
->m_AutoFormats
.erase(iter
);
988 std::unique_ptr
<SwTableAutoFormat
> SwTableAutoFormatTable::ReleaseAutoFormat(const OUString
& rName
)
990 std::unique_ptr
<SwTableAutoFormat
> pRet
;
991 auto iter
= std::find_if(m_pImpl
->m_AutoFormats
.begin(), m_pImpl
->m_AutoFormats
.end(),
992 [&rName
](const std::unique_ptr
<SwTableAutoFormat
>& rpFormat
) { return rpFormat
->GetName() == rName
; });
993 if (iter
!= m_pImpl
->m_AutoFormats
.end())
995 pRet
= std::move(*iter
);
996 m_pImpl
->m_AutoFormats
.erase(iter
);
1001 SwTableAutoFormat
* SwTableAutoFormatTable::FindAutoFormat(std::u16string_view rName
) const
1003 for (const auto &rFormat
: m_pImpl
->m_AutoFormats
)
1005 if (rFormat
->GetName() == rName
)
1006 return rFormat
.get();
1012 SwTableAutoFormatTable::~SwTableAutoFormatTable()
1016 SwTableAutoFormatTable::SwTableAutoFormatTable()
1019 std::unique_ptr
<SwTableAutoFormat
> pNew(new SwTableAutoFormat(
1020 SwStyleNameMapper::GetUIName(RES_POOLTABLESTYLE_DEFAULT
, OUString())));
1024 Color
aColor( COL_BLACK
);
1025 SvxBoxItem
aBox( RES_BOX
);
1027 aBox
.SetAllDistances(55);
1028 SvxBorderLine
aLn( &aColor
, SvxBorderLineWidth::VeryThin
);
1029 aBox
.SetLine( &aLn
, SvxBoxItemLine::LEFT
);
1030 aBox
.SetLine( &aLn
, SvxBoxItemLine::BOTTOM
);
1032 for( i
= 0; i
<= 15; ++i
)
1034 aBox
.SetLine( i
<= 3 ? &aLn
: nullptr, SvxBoxItemLine::TOP
);
1035 aBox
.SetLine( (3 == ( i
& 3 )) ? &aLn
: nullptr, SvxBoxItemLine::RIGHT
);
1036 pNew
->GetBoxFormat( i
).SetBox( aBox
);
1039 pNew
->SetUserDefined(false);
1040 m_pImpl
->m_AutoFormats
.push_back(std::move(pNew
));
1043 void SwTableAutoFormatTable::Load()
1045 if (utl::ConfigManager::IsFuzzing())
1047 OUString
sNm(AUTOTABLE_FORMAT_NAME
);
1048 SvtPathOptions aOpt
;
1049 if( aOpt
.SearchFile( sNm
))
1051 SfxMedium
aStream( sNm
, StreamMode::STD_READ
);
1052 Load( *aStream
.GetInStream() );
1056 bool SwTableAutoFormatTable::Save() const
1058 if (utl::ConfigManager::IsFuzzing())
1060 SvtPathOptions aPathOpt
;
1061 const OUString
sNm( aPathOpt
.GetUserConfigPath() + "/" + AUTOTABLE_FORMAT_NAME
);
1062 SfxMedium
aStream(sNm
, StreamMode::STD_WRITE
);
1063 return Save( *aStream
.GetOutStream() ) && aStream
.Commit();
1066 bool SwTableAutoFormatTable::Load( SvStream
& rStream
)
1068 bool bRet
= ERRCODE_NONE
== rStream
.GetError();
1071 // Attention: We need to read a general Header here
1072 sal_uInt16 nVal
= 0;
1073 rStream
.ReadUInt16( nVal
);
1074 bRet
= ERRCODE_NONE
== rStream
.GetError();
1078 SwAfVersions aVersions
;
1080 // Default version is 5.0, unless we detect an old format ID.
1081 sal_uInt16 nFileVers
= SOFFICE_FILEFORMAT_50
;
1082 if(nVal
< AUTOFORMAT_ID_31005
)
1083 nFileVers
= SOFFICE_FILEFORMAT_40
;
1085 if( nVal
== AUTOFORMAT_ID_358
||
1086 (AUTOFORMAT_ID_504
<= nVal
&& nVal
<= AUTOFORMAT_ID
) )
1088 sal_uInt8 nChrSet
, nCnt
;
1089 sal_uInt64 nPos
= rStream
.Tell();
1090 rStream
.ReadUChar( nCnt
).ReadUChar( nChrSet
);
1091 if( rStream
.Tell() != nPos
+ nCnt
)
1093 OSL_ENSURE( false, "The Header contains more or newer Data" );
1094 rStream
.Seek( nPos
+ nCnt
);
1096 rStream
.SetStreamCharSet( static_cast<rtl_TextEncoding
>(nChrSet
) );
1097 rStream
.SetVersion( nFileVers
);
1100 if( nVal
== AUTOFORMAT_ID_358
|| nVal
== AUTOFORMAT_ID_X
||
1101 (AUTOFORMAT_ID_504
<= nVal
&& nVal
<= AUTOFORMAT_ID
) )
1103 aVersions
.Load( rStream
, nVal
); // Item versions
1105 sal_uInt16 nCount
= 0;
1106 rStream
.ReadUInt16( nCount
);
1108 bRet
= ERRCODE_NONE
== rStream
.GetError();
1111 const size_t nMinRecordSize
= sizeof(sal_uInt16
);
1112 const size_t nMaxRecords
= rStream
.remainingSize() / nMinRecordSize
;
1113 if (nCount
> nMaxRecords
)
1115 SAL_WARN("sw.core", "Parsing error: " << nMaxRecords
<<
1116 " max possible entries, but " << nCount
<< " claimed, truncating");
1117 nCount
= nMaxRecords
;
1119 for (sal_uInt16 i
= 0; i
< nCount
; ++i
)
1121 std::unique_ptr
<SwTableAutoFormat
> pNew(
1122 new SwTableAutoFormat( OUString() ));
1123 bRet
= pNew
->Load( rStream
, aVersions
);
1126 m_pImpl
->m_AutoFormats
.push_back(std::move(pNew
));
1144 bool SwTableAutoFormatTable::Save( SvStream
& rStream
) const
1146 bool bRet
= ERRCODE_NONE
== rStream
.GetError();
1149 rStream
.SetVersion(AUTOFORMAT_FILE_VERSION
);
1151 // Attention: We need to save a general Header here
1152 rStream
.WriteUInt16( AUTOFORMAT_ID
)
1153 .WriteUChar( 2 ) // Character count of the Header including this value
1154 .WriteUChar( GetStoreCharSet( ::osl_getThreadTextEncoding() ) );
1156 bRet
= ERRCODE_NONE
== rStream
.GetError();
1160 // Write this version number for all attributes
1161 SwAfVersions::Write(rStream
, AUTOFORMAT_FILE_VERSION
);
1163 rStream
.WriteUInt16( m_pImpl
->m_AutoFormats
.size() - 1 );
1164 bRet
= ERRCODE_NONE
== rStream
.GetError();
1166 for (size_t i
= 1; bRet
&& i
< m_pImpl
->m_AutoFormats
.size(); ++i
)
1168 SwTableAutoFormat
const& rFormat
= *m_pImpl
->m_AutoFormats
[i
];
1169 bRet
= rFormat
.Save(rStream
, AUTOFORMAT_FILE_VERSION
);
1172 rStream
.FlushBuffer();
1176 SwCellStyleTable::SwCellStyleTable()
1179 SwCellStyleTable::~SwCellStyleTable()
1183 size_t SwCellStyleTable::size() const
1185 return m_aCellStyles
.size();
1188 void SwCellStyleTable::clear()
1190 m_aCellStyles
.clear();
1193 SwCellStyleDescriptor
SwCellStyleTable::operator[](size_t i
) const
1195 return SwCellStyleDescriptor(m_aCellStyles
[i
]);
1198 void SwCellStyleTable::AddBoxFormat(const SwBoxAutoFormat
& rBoxFormat
, const OUString
& sName
)
1200 m_aCellStyles
.emplace_back(sName
, std::make_unique
<SwBoxAutoFormat
>(rBoxFormat
));
1203 void SwCellStyleTable::RemoveBoxFormat(const OUString
& sName
)
1205 auto iter
= std::find_if(m_aCellStyles
.begin(), m_aCellStyles
.end(),
1206 [&sName
](const std::pair
<OUString
, std::unique_ptr
<SwBoxAutoFormat
>>& rStyle
) { return rStyle
.first
== sName
; });
1207 if (iter
!= m_aCellStyles
.end())
1209 m_aCellStyles
.erase(iter
);
1212 SAL_INFO("sw.core", "SwCellStyleTable::RemoveBoxFormat, format with given name doesn't exists");
1215 OUString
SwCellStyleTable::GetBoxFormatName(const SwBoxAutoFormat
& rBoxFormat
) const
1217 for (size_t i
=0; i
< m_aCellStyles
.size(); ++i
)
1219 if (m_aCellStyles
[i
].second
.get() == &rBoxFormat
)
1220 return m_aCellStyles
[i
].first
;
1223 // box format not found
1227 SwBoxAutoFormat
* SwCellStyleTable::GetBoxFormat(std::u16string_view sName
) const
1229 for (size_t i
=0; i
< m_aCellStyles
.size(); ++i
)
1231 if (m_aCellStyles
[i
].first
== sName
)
1232 return m_aCellStyles
[i
].second
.get();
1238 void SwCellStyleTable::ChangeBoxFormatName(std::u16string_view sFromName
, const OUString
& sToName
)
1240 if (!GetBoxFormat(sToName
))
1242 SAL_INFO("sw.core", "SwCellStyleTable::ChangeBoxName, box with given name already exists");
1245 for (size_t i
=0; i
< m_aCellStyles
.size(); ++i
)
1247 if (m_aCellStyles
[i
].first
== sFromName
)
1249 m_aCellStyles
[i
].first
= sToName
;
1250 // changed successfully
1254 SAL_INFO("sw.core", "SwCellStyleTable::ChangeBoxName, box with given name not found");
1256 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */