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