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