333 lines
14 KiB
C++
333 lines
14 KiB
C++
/* -*- 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 DisableAll();
|
|
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; }
|
|
const SwBoxAutoFormat& GetAutoFormat() const { return *m_rCellStyleDesc.second; }
|
|
};
|
|
|
|
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
|
|
const 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: */
|