1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_sw.hxx" 26 27 #include <float.h> 28 #include <rtl/math.hxx> 29 #include <hintids.hxx> // fuer RES_.. 30 #include <cellatr.hxx> 31 #include <calc.hxx> 32 #include <format.hxx> 33 #include <doc.hxx> 34 #include <swtable.hxx> 35 #include <node.hxx> 36 #include <hints.hxx> 37 #include <rolbck.hxx> 38 #include <switerator.hxx> 39 40 41 //TYPEINIT1( SwFmt, SwClient ); //rtti fuer SwFmt 42 43 /************************************************************************* 44 |* 45 *************************************************************************/ 46 47 48 SwTblBoxNumFormat::SwTblBoxNumFormat( sal_uInt32 nFormat, sal_Bool bFlag ) 49 : SfxUInt32Item( RES_BOXATR_FORMAT, nFormat ), bAuto( bFlag ) 50 { 51 } 52 53 54 int SwTblBoxNumFormat::operator==( const SfxPoolItem& rAttr ) const 55 { 56 ASSERT( SfxPoolItem::operator==( rAttr ), "keine gleichen Attribute" ); 57 return GetValue() == ((SwTblBoxNumFormat&)rAttr).GetValue() && 58 bAuto == ((SwTblBoxNumFormat&)rAttr).bAuto; 59 } 60 61 62 SfxPoolItem* SwTblBoxNumFormat::Clone( SfxItemPool* ) const 63 { 64 return new SwTblBoxNumFormat( GetValue(), bAuto ); 65 } 66 67 68 /************************************************************************* 69 |* 70 *************************************************************************/ 71 72 73 74 SwTblBoxFormula::SwTblBoxFormula( const String& rFormula ) 75 : SfxPoolItem( RES_BOXATR_FORMULA ), 76 SwTableFormula( rFormula ), 77 pDefinedIn( 0 ) 78 { 79 } 80 81 82 int SwTblBoxFormula::operator==( const SfxPoolItem& rAttr ) const 83 { 84 ASSERT( SfxPoolItem::operator==( rAttr ), "keine gleichen Attribute" ); 85 return GetFormula() == ((SwTblBoxFormula&)rAttr).GetFormula() && 86 pDefinedIn == ((SwTblBoxFormula&)rAttr).pDefinedIn; 87 } 88 89 90 SfxPoolItem* SwTblBoxFormula::Clone( SfxItemPool* ) const 91 { 92 // auf externe Darstellung umschalten!! 93 SwTblBoxFormula* pNew = new SwTblBoxFormula( GetFormula() ); 94 pNew->SwTableFormula::operator=( *this ); 95 return pNew; 96 } 97 98 99 100 // suche den Node, in dem die Formel steht: 101 // TextFeld -> TextNode, 102 // BoxAttribut -> BoxStartNode 103 // !!! MUSS VON JEDER ABLEITUNG UEBERLADEN WERDEN !!! 104 const SwNode* SwTblBoxFormula::GetNodeOfFormula() const 105 { 106 const SwNode* pRet = 0; 107 if( pDefinedIn ) 108 { 109 SwTableBox* pBox = SwIterator<SwTableBox,SwModify>::FirstElement( *pDefinedIn ); 110 if( pBox ) 111 pRet = pBox->GetSttNd(); 112 } 113 return pRet; 114 } 115 116 117 SwTableBox* SwTblBoxFormula::GetTableBox() 118 { 119 SwTableBox* pBox = 0; 120 if( pDefinedIn ) 121 pBox = SwIterator<SwTableBox,SwModify>::FirstElement( *pDefinedIn ); 122 return pBox; 123 } 124 125 126 void SwTblBoxFormula::ChangeState( const SfxPoolItem* pItem ) 127 { 128 if( !pDefinedIn ) 129 return ; 130 131 SwTableFmlUpdate* pUpdtFld; 132 if( !pItem || RES_TABLEFML_UPDATE != pItem->Which() ) 133 { 134 // setze bei allen das Value-Flag zurueck 135 ChgValid( sal_False ); 136 return ; 137 } 138 139 pUpdtFld = (SwTableFmlUpdate*)pItem; 140 141 // bestimme die Tabelle, in der das Attribut steht 142 const SwTableNode* pTblNd; 143 const SwNode* pNd = GetNodeOfFormula(); 144 if( pNd && &pNd->GetNodes() == &pNd->GetDoc()->GetNodes() && 145 0 != ( pTblNd = pNd->FindTableNode() )) 146 { 147 switch( pUpdtFld->eFlags ) 148 { 149 case TBL_CALC: 150 // setze das Value-Flag zurueck 151 // JP 17.06.96: interne Darstellung auf alle Formeln 152 // (Referenzen auf andere Tabellen!!!) 153 // if( VF_CMD & pFld->GetFormat() ) 154 // pFld->PtrToBoxNm( pUpdtFld->pTbl ); 155 // else 156 ChgValid( sal_False ); 157 break; 158 case TBL_BOXNAME: 159 // ist es die gesuchte Tabelle ?? 160 if( &pTblNd->GetTable() == pUpdtFld->pTbl ) 161 // zur externen Darstellung 162 PtrToBoxNm( pUpdtFld->pTbl ); 163 break; 164 case TBL_BOXPTR: 165 // zur internen Darstellung 166 // JP 17.06.96: interne Darstellung auf alle Formeln 167 // (Referenzen auf andere Tabellen!!!) 168 BoxNmToPtr( &pTblNd->GetTable() ); 169 break; 170 case TBL_RELBOXNAME: 171 // ist es die gesuchte Tabelle ?? 172 if( &pTblNd->GetTable() == pUpdtFld->pTbl ) 173 // zur relativen Darstellung 174 ToRelBoxNm( pUpdtFld->pTbl ); 175 break; 176 177 case TBL_SPLITTBL: 178 if( &pTblNd->GetTable() == pUpdtFld->pTbl ) 179 { 180 sal_uInt16 nLnPos = SwTableFormula::GetLnPosInTbl( 181 pTblNd->GetTable(), GetTableBox() ); 182 pUpdtFld->bBehindSplitLine = USHRT_MAX != nLnPos && 183 pUpdtFld->nSplitLine <= nLnPos; 184 } 185 else 186 pUpdtFld->bBehindSplitLine = sal_False; 187 // kein break 188 case TBL_MERGETBL: 189 if( pUpdtFld->pHistory ) 190 { 191 // fuer die History brauche ich aber die unveraenderte Formel 192 SwTblBoxFormula aCopy( *this ); 193 pUpdtFld->bModified = sal_False; 194 ToSplitMergeBoxNm( *pUpdtFld ); 195 196 if( pUpdtFld->bModified ) 197 { 198 // und dann in der externen Darstellung 199 aCopy.PtrToBoxNm( &pTblNd->GetTable() ); 200 pUpdtFld->pHistory->Add( &aCopy, &aCopy, 201 pNd->FindTableBoxStartNode()->GetIndex() ); 202 } 203 } 204 else 205 ToSplitMergeBoxNm( *pUpdtFld ); 206 break; 207 } 208 } 209 } 210 211 212 void SwTblBoxFormula::Calc( SwTblCalcPara& rCalcPara, double& rValue ) 213 { 214 if( !rCalcPara.rCalc.IsCalcError() ) // ist schon Fehler gesetzt ? 215 { 216 // erzeuge aus den BoxNamen die Pointer 217 BoxNmToPtr( rCalcPara.pTbl ); 218 String sFml( MakeFormel( rCalcPara )); 219 if( !rCalcPara.rCalc.IsCalcError() ) 220 rValue = rCalcPara.rCalc.Calculate( sFml ).GetDouble(); 221 else 222 rValue = DBL_MAX; 223 ChgValid( !rCalcPara.IsStackOverFlow() ); // der Wert ist wieder gueltig 224 } 225 } 226 227 /************************************************************************* 228 |* 229 *************************************************************************/ 230 231 232 SwTblBoxValue::SwTblBoxValue() 233 : SfxPoolItem( RES_BOXATR_VALUE ), nValue( 0 ) 234 { 235 } 236 237 238 SwTblBoxValue::SwTblBoxValue( const double nVal ) 239 : SfxPoolItem( RES_BOXATR_VALUE ), nValue( nVal ) 240 { 241 } 242 243 244 int SwTblBoxValue::operator==( const SfxPoolItem& rAttr ) const 245 { 246 ASSERT(SfxPoolItem::operator==(rAttr), "SwTblBoxValue: item not equal"); 247 SwTblBoxValue const& rOther( static_cast<SwTblBoxValue const&>(rAttr) ); 248 // items with NaN should be equal to enable pooling 249 return ::rtl::math::isNan(nValue) 250 ? ::rtl::math::isNan(rOther.nValue) 251 : (nValue == rOther.nValue); 252 } 253 254 255 SfxPoolItem* SwTblBoxValue::Clone( SfxItemPool* ) const 256 { 257 return new SwTblBoxValue( nValue ); 258 } 259 260 261 262 263