LibreOffice Module sw (master)  1
cellatr.cxx
Go to the documentation of this file.
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 
20 #include <calc.hxx>
21 #include <cellatr.hxx>
22 #include <doc.hxx>
23 #include <float.h>
24 #include <format.hxx>
25 #include <hintids.hxx>
26 #include <hints.hxx>
27 #include <node.hxx>
28 #include <rolbck.hxx>
29 #include <rtl/math.hxx>
30 #include <rtl/ustring.hxx>
31 #include <calbck.hxx>
32 #include <swtable.hxx>
33 
34 // The % SV_COUNTRY_LANGUAGE_OFFSET result checks if nFormat is a mere built-in
35 // @ Text format of *any* locale and if so uses the default text format. Text
36 // is text, the locale doesn't matter for Writer's number formatting purposes.
37 // The advantage is that this is the pool's default item value and some places
38 // benefit from this special treatment in that they don't have to handle/store
39 // attribute specifics, especially when writing a document.
43  getSwDefaultTextFormat() : nFormat))
44 {
45 }
46 
47 bool SwTableBoxNumFormat::operator==( const SfxPoolItem& rAttr ) const
48 {
49  assert(SfxPoolItem::operator==(rAttr));
50  return GetValue() == static_cast<const SwTableBoxNumFormat&>(rAttr).GetValue();
51 }
52 
54 {
55  return new SwTableBoxNumFormat( GetValue() );
56 }
57 
58 SwTableBoxFormula::SwTableBoxFormula( const OUString& rFormula )
60  SwTableFormula( rFormula ),
61  m_pDefinedIn( nullptr )
62 {
63 }
64 
65 bool SwTableBoxFormula::operator==( const SfxPoolItem& rAttr ) const
66 {
67  assert(SfxPoolItem::operator==(rAttr));
68  return GetFormula() == static_cast<const SwTableBoxFormula&>(rAttr).GetFormula() &&
69  m_pDefinedIn == static_cast<const SwTableBoxFormula&>(rAttr).m_pDefinedIn;
70 }
71 
73 {
74  // switch to external rendering
76  pNew->SwTableFormula::operator=( *this );
77  return pNew;
78 }
79 
88 {
89  const SwNode* pRet = nullptr;
90  if( m_pDefinedIn )
91  {
92  SwTableBox* pBox = SwIterator<SwTableBox,SwModify>( *m_pDefinedIn ).First();
93  if( pBox )
94  pRet = pBox->GetSttNd();
95  }
96  return pRet;
97 }
98 
100 {
101  SwTableBox* pBox = nullptr;
102  if( m_pDefinedIn )
103  pBox = SwIterator<SwTableBox,SwModify>( *m_pDefinedIn ).First();
104  return pBox;
105 }
106 
108 {
109  if( !m_pDefinedIn )
110  return ;
111 
112  SwTableFormulaUpdate* pUpdateField;
113  if( !pItem || RES_TABLEFML_UPDATE != pItem->Which() )
114  {
115  // reset value flag
116  ChgValid( false );
117  return ;
118  }
119 
120  pUpdateField = const_cast<SwTableFormulaUpdate*>(static_cast<const SwTableFormulaUpdate*>(pItem));
121 
122  // detect table that contains this attribute
123  const SwTableNode* pTableNd;
124  const SwNode* pNd = GetNodeOfFormula();
125  if (!pNd || &pNd->GetNodes() != &pNd->GetDoc()->GetNodes())
126  return;
127  pTableNd = pNd->FindTableNode();
128  if( pTableNd != nullptr )
129  {
130  switch( pUpdateField->m_eFlags )
131  {
132  case TBL_CALC:
133  // reset value flag
134  ChgValid( false );
135  break;
136  case TBL_BOXNAME:
137  if( &pTableNd->GetTable() == pUpdateField->m_pTable )
138  // use external rendering
139  PtrToBoxNm( pUpdateField->m_pTable );
140  break;
141  case TBL_BOXPTR:
142  // internal rendering
143  BoxNmToPtr( &pTableNd->GetTable() );
144  break;
145  case TBL_RELBOXNAME:
146  if( &pTableNd->GetTable() == pUpdateField->m_pTable )
147  // relative rendering
148  ToRelBoxNm( pUpdateField->m_pTable );
149  break;
150 
151  case TBL_SPLITTBL:
152  if( &pTableNd->GetTable() == pUpdateField->m_pTable )
153  {
154  sal_uInt16 nLnPos = SwTableFormula::GetLnPosInTable(
155  pTableNd->GetTable(), GetTableBox() );
156  pUpdateField->m_bBehindSplitLine = USHRT_MAX != nLnPos &&
157  pUpdateField->m_nSplitLine <= nLnPos;
158  }
159  else
160  pUpdateField->m_bBehindSplitLine = false;
161  [[fallthrough]];
162  case TBL_MERGETBL:
163  if( pUpdateField->m_pHistory )
164  {
165  // for a history record the unchanged formula is needed
166  SwTableBoxFormula aCopy( *this );
167  pUpdateField->m_bModified = false;
168  ToSplitMergeBoxNm( *pUpdateField );
169 
170  if( pUpdateField->m_bModified )
171  {
172  // external rendering
173  aCopy.PtrToBoxNm( &pTableNd->GetTable() );
174  pUpdateField->m_pHistory->Add(
175  &aCopy,
176  &aCopy,
177  pNd->FindTableBoxStartNode()->GetIndex());
178  }
179  }
180  else
181  ToSplitMergeBoxNm( *pUpdateField );
182  break;
183  }
184  }
185 }
186 
187 void SwTableBoxFormula::Calc( SwTableCalcPara& rCalcPara, double& rValue )
188 {
189  if( !rCalcPara.m_rCalc.IsCalcError() )
190  {
191  // create pointers from box names
192  BoxNmToPtr( rCalcPara.m_pTable );
193  const OUString sFormula( MakeFormula( rCalcPara ));
194  if( !rCalcPara.m_rCalc.IsCalcError() )
195  rValue = rCalcPara.m_rCalc.Calculate( sFormula ).GetDouble();
196  else
197  rValue = DBL_MAX;
198  ChgValid( !rCalcPara.IsStackOverflow() ); // value is now valid again
199  }
200 }
201 
203  : SfxPoolItem( RES_BOXATR_VALUE ), m_nValue( 0 )
204 {
205 }
206 
208  : SfxPoolItem( RES_BOXATR_VALUE ), m_nValue( nVal )
209 {
210 }
211 
212 bool SwTableBoxValue::operator==( const SfxPoolItem& rAttr ) const
213 {
214  assert(SfxPoolItem::operator==(rAttr));
215  SwTableBoxValue const& rOther( static_cast<SwTableBoxValue const&>(rAttr) );
216  // items with NaN should be equal to enable pooling
217  return ::rtl::math::isNan( m_nValue )
218  ? ::rtl::math::isNan( rOther.m_nValue )
219  : ( m_nValue == rOther.m_nValue );
220 }
221 
223 {
224  return new SwTableBoxValue( m_nValue );
225 }
226 
227 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual bool operator==(const SfxPoolItem &) const override
Definition: cellatr.cxx:212
sal_uLong GetIndex() const
Definition: node.hxx:282
SwHistory * m_pHistory
Definition: hints.hxx:206
const SwTable * m_pTable
current table
Definition: cellfml.hxx:46
bool IsCalcError() const
Definition: calc.hxx:238
virtual bool operator==(const SfxPoolItem &) const override
Definition: cellatr.cxx:65
OUString MakeFormula(SwTableCalcPara &rCalcPara) const
Definition: cellfml.hxx:104
void ChangeState(const SfxPoolItem *pItem)
Definition: cellatr.cxx:107
#define RES_TABLEFML_UPDATE
Definition: hintids.hxx:292
void BoxNmToPtr(const SwTable *pTable)
create from the external formula the internal
Definition: cellfml.cxx:567
const SwTable * m_pTable
Pointer to the current table.
Definition: hints.hxx:201
SwTableBoxNumFormat(sal_uInt32 nFormat=getSwDefaultTextFormat())
Definition: cellatr.cxx:40
SwTableBox * GetTableBox()
Definition: cellatr.cxx:99
const SwTable & GetTable() const
Definition: node.hxx:497
virtual SfxPoolItem * Clone(SfxItemPool *pPool=nullptr) const override
Definition: cellatr.cxx:72
static sal_uInt16 GetLnPosInTable(const SwTable &rTable, const SwTableBox *pBox)
Definition: cellfml.cxx:1044
void PtrToBoxNm(const SwTable *pTable)
create from the internal formula (for CORE) the external formula (for UI)
Definition: cellfml.cxx:542
double GetDouble() const
Definition: calc.cxx:1412
TElementType * First()
Definition: calbck.hxx:345
SwDoc * GetDoc()
Definition: node.hxx:702
virtual SfxPoolItem * Clone(SfxItemPool *pPool=nullptr) const override
Definition: cellatr.cxx:222
virtual bool operator==(const SfxPoolItem &) const override
Definition: cellatr.cxx:47
SwNodes & GetNodes()
Node is in which nodes-array/doc?
Definition: node.hxx:693
bool IsStackOverflow() const
Definition: cellfml.hxx:52
void ToSplitMergeBoxNm(SwTableFormulaUpdate &rTableUpd)
gets called before/after merging/splitting of tables
Definition: cellfml.cxx:1203
#define RES_BOXATR_VALUE
Definition: hintids.hxx:263
#define SV_COUNTRY_LANGUAGE_OFFSET
SwTableBoxFormula(const OUString &rFormula)
Definition: cellatr.cxx:58
void Add(const SfxPoolItem *pOldValue, const SfxPoolItem *pNewValue, sal_uLong nNodeIdx)
Definition: rolbck.cxx:974
SwSbxValue Calculate(const OUString &rStr)
Definition: calc.cxx:349
void Calc(SwTableCalcPara &rCalcPara, double &rValue)
Definition: cellatr.cxx:187
const SwStartNode * GetSttNd() const
Definition: swtable.hxx:439
void ChgValid(bool bNew)
Definition: cellfml.hxx:134
const OUString & GetFormula() const
Definition: cellfml.hxx:136
virtual const SwNode * GetNodeOfFormula() const override
Get node type of the node containing this formula.
Definition: cellatr.cxx:87
const o3tl::enumarray< SvxAdjust, unsigned short > aSvxToUnoAdjust USHRT_MAX
Definition: unosett.cxx:261
SwNodes & GetNodes()
Definition: doc.hxx:403
void ToRelBoxNm(const SwTable *pTable)
create from the external/internal formula the relative formula
Definition: cellfml.cxx:592
SwTableBox is one table cell in the document model.
Definition: swtable.hxx:386
virtual SfxPoolItem * Clone(SfxItemPool *pPool=nullptr) const override
Definition: cellatr.cxx:53
SwModify * m_pDefinedIn
Definition: cellatr.hxx:54
const SwStartNode * FindTableBoxStartNode() const
Definition: node.hxx:196
SwTableNode * FindTableNode()
Search table node, in which it is.
Definition: node.cxx:351
sal_uInt32 GetValue() const
double m_nValue
Definition: cellatr.hxx:80
TableFormulaUpdateFlags m_eFlags
Definition: hints.hxx:208
constexpr sal_uInt32 getSwDefaultTextFormat()
The number formatter's default locale's @ Text format.
Definition: cellatr.hxx:34
sal_uInt16 Which() const
SwCalc & m_rCalc
current Calculator
Definition: cellfml.hxx:45
#define RES_BOXATR_FORMAT
Definition: hintids.hxx:261
sal_uInt16 m_nSplitLine
Split: from this BaseLine on will be splitted.
Definition: hints.hxx:207
#define RES_BOXATR_FORMULA
Definition: hintids.hxx:262
Base class of the Writer document model elements.
Definition: node.hxx:79