1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 /* 3 * This file is part of the LibreOffice project. 4 * 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/. 8 * 9 * This file incorporates work covered by the following license notice: 10 * 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 . 18 */ 19 #ifndef INCLUDED_SW_INC_TBLAFMT_HXX 20 #define INCLUDED_SW_INC_TBLAFMT_HXX 21 /* 22 * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 23 * 24 * The structure of table auto formatting should not be changed. It is used 25 * by different code of Writer and Calc. If a change is necessary, the 26 * source code of both applications must be changed! 27 * 28 * !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 29 */ 30 31 #include <memory> 32 33 #include <editeng/formatbreakitem.hxx> 34 #include <editeng/keepitem.hxx> 35 #include <editeng/frmdiritem.hxx> 36 #include <editeng/shaditem.hxx> 37 #include <svx/autoformathelper.hxx> 38 #include "fmtpdsc.hxx" 39 #include "fmtornt.hxx" 40 #include "swdllapi.h" 41 42 struct SwAfVersions; 43 44 class SvNumberFormatter; 45 class SwTable; 46 47 class SwBoxAutoFormat : public AutoFormatBase 48 { 49 private: 50 // Writer specific 51 std::unique_ptr<SvxFrameDirectionItem> m_aTextOrientation; 52 std::unique_ptr<SwFormatVertOrient> m_aVerticalAlignment; 53 54 // number format 55 OUString m_sNumFormatString; 56 LanguageType m_eSysLanguage; 57 LanguageType m_eNumFormatLanguage; 58 59 css::uno::WeakReference<css::uno::XInterface> m_wXObject; 60 61 public: 62 SwBoxAutoFormat(); 63 SwBoxAutoFormat( const SwBoxAutoFormat& rNew ); 64 ~SwBoxAutoFormat(); 65 66 /// assignment-op (still used) 67 SwBoxAutoFormat& operator=(const SwBoxAutoFormat& rRef); 68 69 /// Comparing based of boxes backgrounds. 70 bool operator==(const SwBoxAutoFormat& rRight); 71 72 // The get-methods. GetTextOrientation() const73 const SvxFrameDirectionItem& GetTextOrientation() const { return *m_aTextOrientation; } GetVerticalAlignment() const74 const SwFormatVertOrient& GetVerticalAlignment() const { return *m_aVerticalAlignment; } 75 GetValueFormat(OUString & rFormat,LanguageType & rLng,LanguageType & rSys) const76 void GetValueFormat( OUString& rFormat, LanguageType& rLng, LanguageType& rSys ) const 77 { rFormat = m_sNumFormatString; rLng = m_eNumFormatLanguage; rSys = m_eSysLanguage; } 78 GetNumFormatString() const79 const OUString& GetNumFormatString() const { return m_sNumFormatString; } GetSysLanguage() const80 const LanguageType& GetSysLanguage() const { return m_eSysLanguage; } GetNumFormatLanguage() const81 const LanguageType& GetNumFormatLanguage() const { return m_eNumFormatLanguage; } 82 83 // The set-methods. SetTextOrientation(const SvxFrameDirectionItem & rNew)84 void SetTextOrientation( const SvxFrameDirectionItem& rNew ) { m_aTextOrientation.reset(static_cast<SvxFrameDirectionItem*>(rNew.Clone())); } SetVerticalAlignment(const SwFormatVertOrient & rNew)85 void SetVerticalAlignment( const SwFormatVertOrient& rNew ) { m_aVerticalAlignment.reset(static_cast<SwFormatVertOrient*>(rNew.Clone())); } 86 SetValueFormat(const OUString & rFormat,LanguageType eLng,LanguageType eSys)87 void SetValueFormat( const OUString& rFormat, LanguageType eLng, LanguageType eSys ) 88 { m_sNumFormatString = rFormat; m_eNumFormatLanguage = eLng; m_eSysLanguage = eSys; } 89 SetNumFormatString(const OUString & rNew)90 void SetNumFormatString(const OUString& rNew) { m_sNumFormatString = rNew; } SetSysLanguage(const LanguageType & rNew)91 void SetSysLanguage(const LanguageType& rNew) { m_eSysLanguage = rNew; } SetNumFormatLanguage(const LanguageType & rNew)92 void SetNumFormatLanguage(const LanguageType& rNew) { m_eNumFormatLanguage = rNew; } 93 GetXObject() const94 css::uno::WeakReference<css::uno::XInterface> const& GetXObject() const 95 { return m_wXObject; } SetXObject(css::uno::Reference<css::uno::XInterface> const & xObject)96 void SetXObject(css::uno::Reference<css::uno::XInterface> const& xObject) 97 { m_wXObject = xObject; } 98 99 bool Load( SvStream& rStream, const SwAfVersions& rVersions, sal_uInt16 nVer ); 100 bool Save( SvStream& rStream, sal_uInt16 fileVersion ) const; 101 }; 102 103 enum class SwTableAutoFormatUpdateFlags { Char = 1, Box = 2 }; 104 namespace o3tl { 105 template<> struct typed_flags<SwTableAutoFormatUpdateFlags> : is_typed_flags<SwTableAutoFormatUpdateFlags, 0x03> {}; 106 }; 107 108 /* 109 @remarks 110 A table has a number of lines. These lines seem to correspond with rows, except in the case of 111 rows spanning more than one line. Each line contains a number of boxes/cells. 112 113 AutoFormat properties are retrieved and stored in a grid of 16 table boxes. A sampling approach 114 is used to read the data. 4 lines are picked, and 4 boxes are picked from each. 115 116 The line picking and box picking algorithms are similar. We start at the first line/box, and pick 117 lines/boxes one by one for a maximum of 3. The 4th line/box is the last line/box in the current 118 table/line. If we hit the end of lines/boxes, the last line/box encountered is picked several times. 119 120 For example, in a 2x3 table, the 4 lines will be [0, 1, 1, 1]. In each line, the boxes will be 121 [0, 1, 2, 2]. In a 6x5 table, the 4 lines will be [0, 1, 2, 4] and the boxes per line will be 122 [0, 1, 2, 5]. 123 124 As you can see, property extraction/application is lossless for tables that are 4x4 or smaller 125 (and in fact has a bit of redundancy). For larger tables, we lose any individual cell formatting 126 for the range [(3,rows - 1) -> (3, cols - 1)]. That formatting is replaced by formatting from 127 the saved cells: 128 129 0 1 2 3 4 5 130 +-----------------------------------------------------------------------+ 131 0 | Saved | Saved | Saved | | | Saved | 132 +-----------------------------------------------------------------------+ 133 1 | Saved | Saved | Saved | | | Saved | 134 +-----------------------------------------------------------------------+ 135 2 | Saved | Saved | Saved | | | Saved | 136 +-----------------------------------------------------------------------+ 137 3 | | | | | | | 138 +-----------------------------------------------------------------------+ 139 4 | | | | | | | 140 +-----------------------------------------------------------------------+ 141 5 | Saved | Saved | Saved | | | Saved | 142 +-----------+-----------+-----------+-----------+-----------+-----------+ 143 144 The properties saved are divided into three categories: 145 1. Character properties: Font, font size, weight, etc. 146 2. Box properties: Box, cell background 147 3. Table properties: Properties that are set in the Table->Table Properties dialog. 148 149 Character and box properties are stored per cell (and are lossy for tables larger than 4x4). Table 150 properties are stored per-table, and are lossless. 151 */ 152 class SW_DLLPUBLIC SwTableAutoFormat 153 { 154 friend class SwDocTest; 155 friend void FinitCore(); // To destroy default pointer. 156 static SwBoxAutoFormat* pDfltBoxAutoFormat; 157 158 css::uno::WeakReference<css::uno::XInterface> m_wXObject; 159 160 OUString m_aName; 161 sal_uInt16 m_nStrResId; 162 163 // Common flags of Calc and Writer. 164 bool m_bInclFont : 1; 165 bool m_bInclJustify : 1; 166 bool m_bInclFrame : 1; 167 bool m_bInclBackground : 1; 168 bool m_bInclValueFormat : 1; 169 170 // Calc specific flags. 171 bool m_bInclWidthHeight : 1; 172 173 SwBoxAutoFormat* m_aBoxAutoFormat[ 16 ] = {}; 174 175 // Writer-specific options 176 std::shared_ptr<SvxFormatBreakItem> m_aBreak; 177 SwFormatPageDesc m_aPageDesc; 178 std::shared_ptr<SvxFormatKeepItem> m_aKeepWithNextPara; 179 sal_uInt16 m_aRepeatHeading; 180 bool m_bLayoutSplit; 181 bool m_bRowSplit; 182 bool m_bCollapsingBorders; 183 std::shared_ptr<SvxShadowItem> m_aShadow; 184 185 bool m_bHidden; 186 bool m_bUserDefined; 187 public: 188 SwTableAutoFormat( const OUString& rName ); 189 SwTableAutoFormat( const SwTableAutoFormat& rNew ); 190 ~SwTableAutoFormat(); 191 192 SwTableAutoFormat& operator=( const SwTableAutoFormat& rNew ); 193 GetBreak() const194 const SvxFormatBreakItem& GetBreak() const { return *m_aBreak; } GetKeepWithNextPara() const195 const SvxFormatKeepItem& GetKeepWithNextPara() const { return *m_aKeepWithNextPara; } GetShadow() const196 const SvxShadowItem& GetShadow() const { return *m_aShadow; } 197 SetBreak(const SvxFormatBreakItem & rNew)198 void SetBreak(const SvxFormatBreakItem& rNew) { m_aBreak.reset(static_cast<SvxFormatBreakItem*>(rNew.Clone())); } SetKeepWithNextPara(const SvxFormatKeepItem & rNew)199 void SetKeepWithNextPara(const SvxFormatKeepItem& rNew) { m_aKeepWithNextPara.reset(static_cast<SvxFormatKeepItem*>(rNew.Clone())); } SetShadow(const SvxShadowItem & rNew)200 void SetShadow(const SvxShadowItem& rNew) { m_aShadow.reset(static_cast<SvxShadowItem*>(rNew.Clone())); } 201 202 void SetBoxFormat( const SwBoxAutoFormat& rNew, sal_uInt8 nPos ); 203 const SwBoxAutoFormat& GetBoxFormat( sal_uInt8 nPos ) const; 204 SwBoxAutoFormat& GetBoxFormat( sal_uInt8 nPos ); 205 static const SwBoxAutoFormat& GetDefaultBoxFormat(); 206 SetName(const OUString & rNew)207 void SetName( const OUString& rNew ) { m_aName = rNew; m_nStrResId = USHRT_MAX; } GetName() const208 const OUString& GetName() const { return m_aName; } 209 210 void UpdateFromSet( sal_uInt8 nPos, const SfxItemSet& rSet, 211 SwTableAutoFormatUpdateFlags eFlags, SvNumberFormatter const * ); 212 void UpdateToSet( const sal_uInt8 nPos, const bool bSingleRowTable, const bool bSingleColTable, 213 SfxItemSet& rSet, SwTableAutoFormatUpdateFlags eFlags, 214 SvNumberFormatter* ) const ; 215 216 void RestoreTableProperties(SwTable &table) const; 217 void StoreTableProperties(const SwTable &table); 218 IsFont() const219 bool IsFont() const { return m_bInclFont; } IsJustify() const220 bool IsJustify() const { return m_bInclJustify; } IsFrame() const221 bool IsFrame() const { return m_bInclFrame; } IsBackground() const222 bool IsBackground() const { return m_bInclBackground; } IsValueFormat() const223 bool IsValueFormat() const { return m_bInclValueFormat; } 224 225 /// Check if style is hidden. IsHidden() const226 bool IsHidden() const { return m_bHidden; } 227 /// Check if style is defined by user. IsUserDefined() const228 bool IsUserDefined() const { return m_bUserDefined; } 229 SetFont(const bool bNew)230 void SetFont( const bool bNew ) { m_bInclFont = bNew; } SetJustify(const bool bNew)231 void SetJustify( const bool bNew ) { m_bInclJustify = bNew; } SetFrame(const bool bNew)232 void SetFrame( const bool bNew ) { m_bInclFrame = bNew; } SetBackground(const bool bNew)233 void SetBackground( const bool bNew ) { m_bInclBackground = bNew; } SetValueFormat(const bool bNew)234 void SetValueFormat( const bool bNew ) { m_bInclValueFormat = bNew; } SetWidthHeight(const bool bNew)235 void SetWidthHeight( const bool bNew ) { m_bInclWidthHeight = bNew; } 236 237 /// Set if style is hidden. SetHidden(bool bHidden)238 void SetHidden(bool bHidden) { m_bHidden = bHidden; } 239 /// Set if style is user defined. SetUserDefined(bool bUserDefined)240 void SetUserDefined(bool bUserDefined) { m_bUserDefined = bUserDefined; } 241 242 /// These methods returns what style (row or column) is applied first on given Cell 243 bool FirstRowEndColumnIsRow(); 244 bool FirstRowStartColumnIsRow(); 245 bool LastRowEndColumnIsRow(); 246 bool LastRowStartColumnIsRow(); 247 248 bool Load( SvStream& rStream, const SwAfVersions& ); 249 bool Save( SvStream& rStream, sal_uInt16 fileVersion ) const; 250 GetXObject() const251 css::uno::WeakReference<css::uno::XInterface> const& GetXObject() const 252 { return m_wXObject; } SetXObject(css::uno::Reference<css::uno::XInterface> const & xObject)253 void SetXObject(css::uno::Reference<css::uno::XInterface> const& xObject) 254 { m_wXObject = xObject; } 255 256 /// Returns the cell's name postfix. eg. ".1" 257 OUString GetTableTemplateCellSubName(const SwBoxAutoFormat& rBoxFormat) const; 258 /// Returns a vector of indexes in aBoxAutoFormat array. Returned indexes points to cells which are mapped to a table-template. 259 static const std::vector<sal_Int32>& GetTableTemplateMap(); 260 261 /** 262 * Calculates the relevant position in the table autoformat for a given 263 * cell in a given table. 264 */ 265 static sal_uInt8 CountPos(sal_uInt32 nCol, sal_uInt32 nCols, sal_uInt32 nRow, sal_uInt32 nRows); 266 }; 267 268 class SW_DLLPUBLIC SwTableAutoFormatTable 269 { 270 struct Impl; 271 std::unique_ptr<Impl> m_pImpl; 272 273 SAL_DLLPRIVATE bool Load( SvStream& rStream ); 274 SAL_DLLPRIVATE bool Save( SvStream& rStream ) const; 275 276 public: 277 explicit SwTableAutoFormatTable(); 278 ~SwTableAutoFormatTable(); 279 280 size_t size() const; 281 SwTableAutoFormat const& operator[](size_t i) const; 282 SwTableAutoFormat & operator[](size_t i); 283 284 /// Append table style to the existing styles. 285 void AddAutoFormat(const SwTableAutoFormat& rFormat); 286 287 void InsertAutoFormat(size_t i, std::unique_ptr<SwTableAutoFormat> pFormat); 288 void EraseAutoFormat(size_t i); 289 void EraseAutoFormat(const OUString& rName); 290 std::unique_ptr<SwTableAutoFormat> ReleaseAutoFormat(size_t i); 291 /// Removes an autoformat. Returns pointer to the removed autoformat or nullptr. 292 std::unique_ptr<SwTableAutoFormat> ReleaseAutoFormat(const OUString& rName); 293 294 /// Find table style with the provided name, return nullptr when not found. 295 SwTableAutoFormat* FindAutoFormat(const OUString& rName) const; 296 297 void Load(); 298 bool Save() const; 299 }; 300 301 class SwCellStyleDescriptor 302 { 303 const std::pair<OUString, std::unique_ptr<SwBoxAutoFormat>>& m_rCellStyleDesc; 304 public: SwCellStyleDescriptor(const std::pair<OUString,std::unique_ptr<SwBoxAutoFormat>> & rCellStyleDesc)305 SwCellStyleDescriptor(const std::pair<OUString, std::unique_ptr<SwBoxAutoFormat>>& rCellStyleDesc) : m_rCellStyleDesc(rCellStyleDesc) { } 306 GetName() const307 const OUString& GetName() const { return m_rCellStyleDesc.first; } 308 }; 309 310 class SwCellStyleTable 311 { 312 std::vector<std::pair<OUString, std::unique_ptr<SwBoxAutoFormat>>> m_aCellStyles; 313 public: 314 SwCellStyleTable(); 315 ~SwCellStyleTable(); 316 317 size_t size() const; 318 SwCellStyleDescriptor operator[](size_t i) const; 319 void clear(); 320 321 /// Add a copy of rBoxFormat 322 void AddBoxFormat(const SwBoxAutoFormat& rBoxFormat, const OUString& sName); 323 void RemoveBoxFormat(const OUString& sName); 324 void ChangeBoxFormatName(const OUString& sFromName, const OUString& sToName); 325 /// If found returns its name. If not found returns an empty OUString 326 OUString GetBoxFormatName(const SwBoxAutoFormat& rBoxFormat) const; 327 /// If found returns a ptr to a BoxFormat. If not found returns nullptr 328 SwBoxAutoFormat* GetBoxFormat(const OUString& sName) const; 329 }; 330 331 #endif 332 333 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 334