diff options
Diffstat (limited to 'sw/inc/tblafmt.hxx')
-rw-r--r-- | sw/inc/tblafmt.hxx | 331 |
1 files changed, 331 insertions, 0 deletions
diff --git a/sw/inc/tblafmt.hxx b/sw/inc/tblafmt.hxx new file mode 100644 index 0000000000..dbbec1909a --- /dev/null +++ b/sw/inc/tblafmt.hxx @@ -0,0 +1,331 @@ +/* -*- 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 . + */ +#ifndef INCLUDED_SW_INC_TBLAFMT_HXX +#define INCLUDED_SW_INC_TBLAFMT_HXX +/* + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + * + * The structure of table auto formatting should not be changed. It is used + * by different code of Writer and Calc. If a change is necessary, the + * source code of both applications must be changed! + * + * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + */ + +#include <memory> + +#include <editeng/keepitem.hxx> +#include <editeng/frmdiritem.hxx> +#include <editeng/shaditem.hxx> +#include <svx/autoformathelper.hxx> +#include <unotools/weakref.hxx> +#include <rtl/ref.hxx> +#include "fmtornt.hxx" +#include "swdllapi.h" + +struct SwAfVersions; + +class SvNumberFormatter; +class SwTable; +class SwXTextCellStyle; +class SwXTextTableStyle; + +class SW_DLLPUBLIC SwBoxAutoFormat : public AutoFormatBase +{ +private: + // Writer specific + std::unique_ptr<SvxFrameDirectionItem> m_aTextOrientation; + std::unique_ptr<SwFormatVertOrient> m_aVerticalAlignment; + + // number format + OUString m_sNumFormatString; + LanguageType m_eSysLanguage; + LanguageType m_eNumFormatLanguage; + + // associated UNO object, if such exists + unotools::WeakReference<SwXTextCellStyle> m_xAutoFormatUnoObject; + +public: + SwBoxAutoFormat(); + SwBoxAutoFormat( const SwBoxAutoFormat& rNew ); + ~SwBoxAutoFormat(); + + /// assignment-op (still used) + SwBoxAutoFormat& operator=(const SwBoxAutoFormat& rRef); + + /// Comparing based of boxes backgrounds. + bool operator==(const SwBoxAutoFormat& rRight) const; + + // The get-methods. + const SvxFrameDirectionItem& GetTextOrientation() const { return *m_aTextOrientation; } + const SwFormatVertOrient& GetVerticalAlignment() const { return *m_aVerticalAlignment; } + + void GetValueFormat( OUString& rFormat, LanguageType& rLng, LanguageType& rSys ) const + { rFormat = m_sNumFormatString; rLng = m_eNumFormatLanguage; rSys = m_eSysLanguage; } + + const OUString& GetNumFormatString() const { return m_sNumFormatString; } + const LanguageType& GetSysLanguage() const { return m_eSysLanguage; } + const LanguageType& GetNumFormatLanguage() const { return m_eNumFormatLanguage; } + + // The set-methods. + void SetTextOrientation( const SvxFrameDirectionItem& rNew ) { m_aTextOrientation.reset(rNew.Clone()); } + void SetVerticalAlignment( const SwFormatVertOrient& rNew ) { m_aVerticalAlignment.reset(rNew.Clone()); } + + void SetValueFormat( const OUString& rFormat, LanguageType eLng, LanguageType eSys ) + { m_sNumFormatString = rFormat; m_eNumFormatLanguage = eLng; m_eSysLanguage = eSys; } + + void SetNumFormatString(const OUString& rNew) { m_sNumFormatString = rNew; } + void SetSysLanguage(const LanguageType& rNew) { m_eSysLanguage = rNew; } + void SetNumFormatLanguage(const LanguageType& rNew) { m_eNumFormatLanguage = rNew; } + + unotools::WeakReference<SwXTextCellStyle> const& GetXObject() const + { return m_xAutoFormatUnoObject; } + void SetXObject(rtl::Reference<SwXTextCellStyle> const& xObject); + + bool Load( SvStream& rStream, const SwAfVersions& rVersions, sal_uInt16 nVer ); + bool Save( SvStream& rStream, sal_uInt16 fileVersion ) const; +}; + +enum class SwTableAutoFormatUpdateFlags { Char = 1, Box = 2 }; +namespace o3tl { + template<> struct typed_flags<SwTableAutoFormatUpdateFlags> : is_typed_flags<SwTableAutoFormatUpdateFlags, 0x03> {}; +}; + +/* +@remarks +A table has a number of lines. These lines seem to correspond with rows, except in the case of +rows spanning more than one line. Each line contains a number of boxes/cells. + +AutoFormat properties are retrieved and stored in a grid of 16 table boxes. A sampling approach +is used to read the data. 4 lines are picked, and 4 boxes are picked from each. + +The line picking and box picking algorithms are similar. We start at the first line/box, and pick +lines/boxes one by one for a maximum of 3. The 4th line/box is the last line/box in the current +table/line. If we hit the end of lines/boxes, the last line/box encountered is picked several times. + +For example, in a 2x3 table, the 4 lines will be [0, 1, 1, 1]. In each line, the boxes will be +[0, 1, 2, 2]. In a 6x5 table, the 4 lines will be [0, 1, 2, 4] and the boxes per line will be +[0, 1, 2, 5]. + +As you can see, property extraction/application is lossless for tables that are 4x4 or smaller +(and in fact has a bit of redundancy). For larger tables, we lose any individual cell formatting +for the range [(3,rows - 1) -> (3, cols - 1)]. That formatting is replaced by formatting from +the saved cells: + + 0 1 2 3 4 5 + +-----------------------------------------------------------------------+ + 0 | Saved | Saved | Saved | | | Saved | + +-----------------------------------------------------------------------+ + 1 | Saved | Saved | Saved | | | Saved | + +-----------------------------------------------------------------------+ + 2 | Saved | Saved | Saved | | | Saved | + +-----------------------------------------------------------------------+ + 3 | | | | | | | + +-----------------------------------------------------------------------+ + 4 | | | | | | | + +-----------------------------------------------------------------------+ + 5 | Saved | Saved | Saved | | | Saved | + +-----------+-----------+-----------+-----------+-----------+-----------+ + +The properties saved are divided into three categories: + 1. Character properties: Font, font size, weight, etc. + 2. Box properties: Box, cell background + 3. Table properties: Properties that are set in the Table->Table Properties dialog. + +Character and box properties are stored per cell (and are lossy for tables larger than 4x4). Table +properties are stored per-table, and are lossless. +*/ +class SW_DLLPUBLIC SwTableAutoFormat +{ + friend class SwDocTest; + friend void FinitCore(); // To destroy default pointer. + static SwBoxAutoFormat* s_pDefaultBoxAutoFormat; + + unotools::WeakReference<SwXTextTableStyle> m_xUnoTextTableStyle; + + OUString m_aName; + sal_uInt16 m_nStrResId; + + // Common flags of Calc and Writer. + bool m_bInclFont : 1; + bool m_bInclJustify : 1; + bool m_bInclFrame : 1; + bool m_bInclBackground : 1; + bool m_bInclValueFormat : 1; + + // Calc specific flags. + bool m_bInclWidthHeight : 1; + + SwBoxAutoFormat* m_aBoxAutoFormat[ 16 ] = {}; + + // Writer-specific options + std::shared_ptr<SvxFormatKeepItem> m_aKeepWithNextPara; + sal_uInt16 m_aRepeatHeading; + bool m_bLayoutSplit; + bool m_bRowSplit; + bool m_bCollapsingBorders; + std::shared_ptr<SvxShadowItem> m_aShadow; + + bool m_bHidden; + bool m_bUserDefined; +public: + SwTableAutoFormat( OUString aName ); + SwTableAutoFormat( const SwTableAutoFormat& rNew ); + ~SwTableAutoFormat(); + + SwTableAutoFormat& operator=( const SwTableAutoFormat& rNew ); + + const SvxFormatKeepItem& GetKeepWithNextPara() const { return *m_aKeepWithNextPara; } + const SvxShadowItem& GetShadow() const { return *m_aShadow; } + + void SetKeepWithNextPara(const SvxFormatKeepItem& rNew) { m_aKeepWithNextPara.reset(rNew.Clone()); } + void SetShadow(const SvxShadowItem& rNew) { m_aShadow.reset(rNew.Clone()); } + + void SetBoxFormat( const SwBoxAutoFormat& rNew, sal_uInt8 nPos ); + const SwBoxAutoFormat& GetBoxFormat( sal_uInt8 nPos ) const; + SwBoxAutoFormat& GetBoxFormat( sal_uInt8 nPos ); + static const SwBoxAutoFormat& GetDefaultBoxFormat(); + + void SetName( const OUString& rNew ) { m_aName = rNew; m_nStrResId = USHRT_MAX; } + const OUString& GetName() const { return m_aName; } + + void UpdateFromSet( sal_uInt8 nPos, const SfxItemSet& rSet, + SwTableAutoFormatUpdateFlags eFlags, SvNumberFormatter const * ); + void UpdateToSet( const sal_uInt8 nPos, const bool bSingleRowTable, const bool bSingleColTable, + SfxItemSet& rSet, SwTableAutoFormatUpdateFlags eFlags, + SvNumberFormatter* ) const ; + + void RestoreTableProperties(SwTable &table) const; + void StoreTableProperties(const SwTable &table); + + bool IsFont() const { return m_bInclFont; } + bool IsJustify() const { return m_bInclJustify; } + bool IsFrame() const { return m_bInclFrame; } + bool IsBackground() const { return m_bInclBackground; } + bool IsValueFormat() const { return m_bInclValueFormat; } + + /// Check if style is hidden. + bool IsHidden() const { return m_bHidden; } + /// Check if style is defined by user. + bool IsUserDefined() const { return m_bUserDefined; } + + void SetFont( const bool bNew ) { m_bInclFont = bNew; } + void SetJustify( const bool bNew ) { m_bInclJustify = bNew; } + void SetFrame( const bool bNew ) { m_bInclFrame = bNew; } + void SetBackground( const bool bNew ) { m_bInclBackground = bNew; } + void SetValueFormat( const bool bNew ) { m_bInclValueFormat = bNew; } + void SetWidthHeight( const bool bNew ) { m_bInclWidthHeight = bNew; } + + /// Set if style is hidden. + void SetHidden(bool bHidden) { m_bHidden = bHidden; } + /// Set if style is user defined. + void SetUserDefined(bool bUserDefined) { m_bUserDefined = bUserDefined; } + + /// These methods returns what style (row or column) is applied first on given Cell + bool FirstRowEndColumnIsRow(); + bool FirstRowStartColumnIsRow(); + bool LastRowEndColumnIsRow(); + bool LastRowStartColumnIsRow(); + bool HasHeaderRow() const; + + bool Load( SvStream& rStream, const SwAfVersions& ); + bool Save( SvStream& rStream, sal_uInt16 fileVersion ) const; + + unotools::WeakReference<SwXTextTableStyle> const& GetXObject() const + { return m_xUnoTextTableStyle; } + void SetXObject(rtl::Reference<SwXTextTableStyle> const& xObject); + + /// Returns the cell's name postfix. eg. ".1" + OUString GetTableTemplateCellSubName(const SwBoxAutoFormat& rBoxFormat) const; + /// Returns a vector of indexes in aBoxAutoFormat array. Returned indexes points to cells which are mapped to a table-template. + static const std::vector<sal_Int32>& GetTableTemplateMap(); + + /** + * Calculates the relevant position in the table autoformat for a given + * cell in a given table. + */ + static sal_uInt8 CountPos(sal_uInt32 nCol, sal_uInt32 nCols, sal_uInt32 nRow, sal_uInt32 nRows); +}; + +class SW_DLLPUBLIC SwTableAutoFormatTable +{ + struct Impl; + std::unique_ptr<Impl> m_pImpl; + + SAL_DLLPRIVATE bool Load( SvStream& rStream ); + SAL_DLLPRIVATE bool Save( SvStream& rStream ) const; + +public: + explicit SwTableAutoFormatTable(); + ~SwTableAutoFormatTable(); + + size_t size() const; + SwTableAutoFormat const& operator[](size_t i) const; + SwTableAutoFormat & operator[](size_t i); + + /// Append table style to the existing styles. + void AddAutoFormat(const SwTableAutoFormat& rFormat); + + void InsertAutoFormat(size_t i, std::unique_ptr<SwTableAutoFormat> pFormat); + void EraseAutoFormat(size_t i); + void EraseAutoFormat(const OUString& rName); + std::unique_ptr<SwTableAutoFormat> ReleaseAutoFormat(size_t i); + /// Removes an autoformat. Returns pointer to the removed autoformat or nullptr. + std::unique_ptr<SwTableAutoFormat> ReleaseAutoFormat(const OUString& rName); + + /// Find table style with the provided name, return nullptr when not found. + SwTableAutoFormat* FindAutoFormat(std::u16string_view rName) const; + + void Load(); + bool Save() const; +}; + +class SwCellStyleDescriptor +{ + const std::pair<OUString, std::unique_ptr<SwBoxAutoFormat>>& m_rCellStyleDesc; +public: + SwCellStyleDescriptor(const std::pair<OUString, std::unique_ptr<SwBoxAutoFormat>>& rCellStyleDesc) : m_rCellStyleDesc(rCellStyleDesc) { } + + const OUString& GetName() const { return m_rCellStyleDesc.first; } +}; + +class SwCellStyleTable +{ + std::vector<std::pair<OUString, std::unique_ptr<SwBoxAutoFormat>>> m_aCellStyles; +public: + SwCellStyleTable(); + ~SwCellStyleTable(); + + size_t size() const; + SwCellStyleDescriptor operator[](size_t i) const; + void clear(); + + /// Add a copy of rBoxFormat + void AddBoxFormat(const SwBoxAutoFormat& rBoxFormat, const OUString& sName); + void RemoveBoxFormat(const OUString& sName); + void ChangeBoxFormatName(std::u16string_view sFromName, const OUString& sToName); + /// If found returns its name. If not found returns an empty OUString + OUString GetBoxFormatName(const SwBoxAutoFormat& rBoxFormat) const; + /// If found returns a ptr to a BoxFormat. If not found returns nullptr + SwBoxAutoFormat* GetBoxFormat(std::u16string_view sName) const; +}; + +#endif + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |