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_sc.hxx" 30 31 32 33 #include "refdata.hxx" 34 35 36 void ScSingleRefData::CalcRelFromAbs( const ScAddress& rPos ) 37 { 38 nRelCol = nCol - rPos.Col(); 39 nRelRow = nRow - rPos.Row(); 40 nRelTab = nTab - rPos.Tab(); 41 } 42 43 44 void ScSingleRefData::SmartRelAbs( const ScAddress& rPos ) 45 { 46 if ( Flags.bColRel ) 47 nCol = nRelCol + rPos.Col(); 48 else 49 nRelCol = nCol - rPos.Col(); 50 51 if ( Flags.bRowRel ) 52 nRow = nRelRow + rPos.Row(); 53 else 54 nRelRow = nRow - rPos.Row(); 55 56 if ( Flags.bTabRel ) 57 nTab = nRelTab + rPos.Tab(); 58 else 59 nRelTab = nTab - rPos.Tab(); 60 } 61 62 63 void ScSingleRefData::CalcAbsIfRel( const ScAddress& rPos ) 64 { 65 if ( Flags.bColRel ) 66 { 67 nCol = nRelCol + rPos.Col(); 68 if ( !VALIDCOL( nCol ) ) 69 Flags.bColDeleted = sal_True; 70 } 71 if ( Flags.bRowRel ) 72 { 73 nRow = nRelRow + rPos.Row(); 74 if ( !VALIDROW( nRow ) ) 75 Flags.bRowDeleted = sal_True; 76 } 77 if ( Flags.bTabRel ) 78 { 79 nTab = nRelTab + rPos.Tab(); 80 if ( !VALIDTAB( nTab ) ) 81 Flags.bTabDeleted = sal_True; 82 } 83 } 84 85 //UNUSED2008-05 void ScSingleRefData::OldBoolsToNewFlags( const OldSingleRefBools& rBools ) 86 //UNUSED2008-05 { 87 //UNUSED2008-05 switch ( rBools.bRelCol ) 88 //UNUSED2008-05 { 89 //UNUSED2008-05 case SR_DELETED : 90 //UNUSED2008-05 Flags.bColRel = sal_True; // der war verlorengegangen 91 //UNUSED2008-05 Flags.bColDeleted = sal_True; 92 //UNUSED2008-05 break; 93 //UNUSED2008-05 case SR_ABSOLUTE : 94 //UNUSED2008-05 Flags.bColRel = sal_False; 95 //UNUSED2008-05 Flags.bColDeleted = sal_False; 96 //UNUSED2008-05 break; 97 //UNUSED2008-05 case SR_RELABS : 98 //UNUSED2008-05 case SR_RELATIVE : 99 //UNUSED2008-05 default: 100 //UNUSED2008-05 Flags.bColRel = sal_True; 101 //UNUSED2008-05 Flags.bColDeleted = sal_False; 102 //UNUSED2008-05 } 103 //UNUSED2008-05 switch ( rBools.bRelRow ) 104 //UNUSED2008-05 { 105 //UNUSED2008-05 case SR_DELETED : 106 //UNUSED2008-05 Flags.bRowRel = sal_True; // der war verlorengegangen 107 //UNUSED2008-05 Flags.bRowDeleted = sal_True; 108 //UNUSED2008-05 break; 109 //UNUSED2008-05 case SR_ABSOLUTE : 110 //UNUSED2008-05 Flags.bRowRel = sal_False; 111 //UNUSED2008-05 Flags.bRowDeleted = sal_False; 112 //UNUSED2008-05 break; 113 //UNUSED2008-05 case SR_RELABS : 114 //UNUSED2008-05 case SR_RELATIVE : 115 //UNUSED2008-05 default: 116 //UNUSED2008-05 Flags.bRowRel = sal_True; 117 //UNUSED2008-05 Flags.bRowDeleted = sal_False; 118 //UNUSED2008-05 } 119 //UNUSED2008-05 switch ( rBools.bRelTab ) 120 //UNUSED2008-05 { 121 //UNUSED2008-05 case SR_DELETED : 122 //UNUSED2008-05 Flags.bTabRel = sal_True; // der war verlorengegangen 123 //UNUSED2008-05 Flags.bTabDeleted = sal_True; 124 //UNUSED2008-05 break; 125 //UNUSED2008-05 case SR_ABSOLUTE : 126 //UNUSED2008-05 Flags.bTabRel = sal_False; 127 //UNUSED2008-05 Flags.bTabDeleted = sal_False; 128 //UNUSED2008-05 break; 129 //UNUSED2008-05 case SR_RELABS : 130 //UNUSED2008-05 case SR_RELATIVE : 131 //UNUSED2008-05 default: 132 //UNUSED2008-05 Flags.bTabRel = sal_True; 133 //UNUSED2008-05 Flags.bTabDeleted = sal_False; 134 //UNUSED2008-05 } 135 //UNUSED2008-05 Flags.bFlag3D = (rBools.bOldFlag3D & SRF_3D ? sal_True : sal_False); 136 //UNUSED2008-05 Flags.bRelName = (rBools.bOldFlag3D & SRF_RELNAME ? sal_True : sal_False); 137 //UNUSED2008-05 if ( !Flags.bFlag3D ) 138 //UNUSED2008-05 Flags.bTabRel = sal_True; // ist bei einigen aelteren Dokumenten nicht gesetzt 139 //UNUSED2008-05 } 140 //UNUSED2008-05 141 //UNUSED2008-05 142 //UNUSED2008-05 /* 143 //UNUSED2008-05 bis Release 3.1 sah Store so aus 144 //UNUSED2008-05 145 //UNUSED2008-05 sal_uInt8 n = ( ( r.bOldFlag3D & 0x03 ) << 6 ) // RelName, 3D 146 //UNUSED2008-05 | ( ( r.bRelTab & 0x03 ) << 4 ) // Relative, RelAbs 147 //UNUSED2008-05 | ( ( r.bRelRow & 0x03 ) << 2 ) 148 //UNUSED2008-05 | ( r.bRelCol & 0x03 ); 149 //UNUSED2008-05 150 //UNUSED2008-05 bis Release 3.1 sah Load so aus 151 //UNUSED2008-05 152 //UNUSED2008-05 r.bRelCol = ( n & 0x03 ); 153 //UNUSED2008-05 r.bRelRow = ( ( n >> 2 ) & 0x03 ); 154 //UNUSED2008-05 r.bRelTab = ( ( n >> 4 ) & 0x03 ); 155 //UNUSED2008-05 r.bOldFlag3D = ( ( n >> 6 ) & 0x03 ); 156 //UNUSED2008-05 157 //UNUSED2008-05 bRelCol == SR_DELETED war identisch mit bRelCol == (SR_RELATIVE | SR_RELABS) 158 //UNUSED2008-05 leider.. 159 //UNUSED2008-05 3.1 liest Zukunft: Deleted wird nicht unbedingt erkannt, nur wenn auch Relativ. 160 //UNUSED2008-05 Aber immer noch nCol > MAXCOL und gut sollte sein.. 161 //UNUSED2008-05 */ 162 //UNUSED2008-05 163 //UNUSED2008-05 sal_uInt8 ScSingleRefData::CreateStoreByteFromFlags() const 164 //UNUSED2008-05 { 165 //UNUSED2008-05 return (sal_uInt8)( 166 //UNUSED2008-05 ( (Flags.bRelName & 0x01) << 7 ) 167 //UNUSED2008-05 | ( (Flags.bFlag3D & 0x01) << 6 ) 168 //UNUSED2008-05 | ( (Flags.bTabDeleted & 0x01) << 5 ) 169 //UNUSED2008-05 | ( (Flags.bTabRel & 0x01) << 4 ) 170 //UNUSED2008-05 | ( (Flags.bRowDeleted & 0x01) << 3 ) 171 //UNUSED2008-05 | ( (Flags.bRowRel & 0x01) << 2 ) 172 //UNUSED2008-05 | ( (Flags.bColDeleted & 0x01) << 1 ) 173 //UNUSED2008-05 | (Flags.bColRel & 0x01) 174 //UNUSED2008-05 ); 175 //UNUSED2008-05 } 176 //UNUSED2008-05 177 //UNUSED2008-05 178 //UNUSED2008-05 void ScSingleRefData::CreateFlagsFromLoadByte( sal_uInt8 n ) 179 //UNUSED2008-05 { 180 //UNUSED2008-05 Flags.bColRel = (n & 0x01 ); 181 //UNUSED2008-05 Flags.bColDeleted = ( (n >> 1) & 0x01 ); 182 //UNUSED2008-05 Flags.bRowRel = ( (n >> 2) & 0x01 ); 183 //UNUSED2008-05 Flags.bRowDeleted = ( (n >> 3) & 0x01 ); 184 //UNUSED2008-05 Flags.bTabRel = ( (n >> 4) & 0x01 ); 185 //UNUSED2008-05 Flags.bTabDeleted = ( (n >> 5) & 0x01 ); 186 //UNUSED2008-05 Flags.bFlag3D = ( (n >> 6) & 0x01 ); 187 //UNUSED2008-05 Flags.bRelName = ( (n >> 7) & 0x01 ); 188 //UNUSED2008-05 } 189 190 191 sal_Bool ScSingleRefData::operator==( const ScSingleRefData& r ) const 192 { 193 return bFlags == r.bFlags && 194 (Flags.bColRel ? nRelCol == r.nRelCol : nCol == r.nCol) && 195 (Flags.bRowRel ? nRelRow == r.nRelRow : nRow == r.nRow) && 196 (Flags.bTabRel ? nRelTab == r.nRelTab : nTab == r.nTab); 197 } 198 199 bool ScSingleRefData::operator!=( const ScSingleRefData& r ) const 200 { 201 return !operator==(r); 202 } 203 204 static void lcl_putInOrder( ScSingleRefData & rRef1, ScSingleRefData & rRef2 ) 205 { 206 SCCOL nCol1, nCol2; 207 SCROW nRow1, nRow2; 208 SCTAB nTab1, nTab2; 209 sal_Bool bTmp; 210 sal_uInt8 nRelState1, nRelState2; 211 if ( rRef1.Flags.bRelName ) 212 nRelState1 = 213 ((rRef1.Flags.bTabRel & 0x01) << 2) 214 | ((rRef1.Flags.bRowRel & 0x01) << 1) 215 | ((rRef1.Flags.bColRel & 0x01)); 216 else 217 nRelState1 = 0; 218 if ( rRef2.Flags.bRelName ) 219 nRelState2 = 220 ((rRef2.Flags.bTabRel & 0x01) << 2) 221 | ((rRef2.Flags.bRowRel & 0x01) << 1) 222 | ((rRef2.Flags.bColRel & 0x01)); 223 else 224 nRelState2 = 0; 225 if ( (nCol1 = rRef1.nCol) > (nCol2 = rRef2.nCol) ) 226 { 227 rRef1.nCol = nCol2; 228 rRef2.nCol = nCol1; 229 nCol1 = rRef1.nRelCol; 230 rRef1.nRelCol = rRef2.nRelCol; 231 rRef2.nRelCol = nCol1; 232 if ( rRef1.Flags.bRelName && rRef1.Flags.bColRel ) 233 nRelState2 |= 1; 234 else 235 nRelState2 &= ~1; 236 if ( rRef2.Flags.bRelName && rRef2.Flags.bColRel ) 237 nRelState1 |= 1; 238 else 239 nRelState1 &= ~1; 240 bTmp = rRef1.Flags.bColRel; 241 rRef1.Flags.bColRel = rRef2.Flags.bColRel; 242 rRef2.Flags.bColRel = bTmp; 243 bTmp = rRef1.Flags.bColDeleted; 244 rRef1.Flags.bColDeleted = rRef2.Flags.bColDeleted; 245 rRef2.Flags.bColDeleted = bTmp; 246 } 247 if ( (nRow1 = rRef1.nRow) > (nRow2 = rRef2.nRow) ) 248 { 249 rRef1.nRow = nRow2; 250 rRef2.nRow = nRow1; 251 nRow1 = rRef1.nRelRow; 252 rRef1.nRelRow = rRef2.nRelRow; 253 rRef2.nRelRow = nRow1; 254 if ( rRef1.Flags.bRelName && rRef1.Flags.bRowRel ) 255 nRelState2 |= 2; 256 else 257 nRelState2 &= ~2; 258 if ( rRef2.Flags.bRelName && rRef2.Flags.bRowRel ) 259 nRelState1 |= 2; 260 else 261 nRelState1 &= ~2; 262 bTmp = rRef1.Flags.bRowRel; 263 rRef1.Flags.bRowRel = rRef2.Flags.bRowRel; 264 rRef2.Flags.bRowRel = bTmp; 265 bTmp = rRef1.Flags.bRowDeleted; 266 rRef1.Flags.bRowDeleted = rRef2.Flags.bRowDeleted; 267 rRef2.Flags.bRowDeleted = bTmp; 268 } 269 if ( (nTab1 = rRef1.nTab) > (nTab2 = rRef2.nTab) ) 270 { 271 rRef1.nTab = nTab2; 272 rRef2.nTab = nTab1; 273 nTab1 = rRef1.nRelTab; 274 rRef1.nRelTab = rRef2.nRelTab; 275 rRef2.nRelTab = nTab1; 276 if ( rRef1.Flags.bRelName && rRef1.Flags.bTabRel ) 277 nRelState2 |= 4; 278 else 279 nRelState2 &= ~4; 280 if ( rRef2.Flags.bRelName && rRef2.Flags.bTabRel ) 281 nRelState1 |= 4; 282 else 283 nRelState1 &= ~4; 284 bTmp = rRef1.Flags.bTabRel; 285 rRef1.Flags.bTabRel = rRef2.Flags.bTabRel; 286 rRef2.Flags.bTabRel = bTmp; 287 bTmp = rRef1.Flags.bTabDeleted; 288 rRef1.Flags.bTabDeleted = rRef2.Flags.bTabDeleted; 289 rRef2.Flags.bTabDeleted = bTmp; 290 } 291 rRef1.Flags.bRelName = ( nRelState1 ? sal_True : sal_False ); 292 rRef2.Flags.bRelName = ( nRelState2 ? sal_True : sal_False ); 293 } 294 295 296 void ScComplexRefData::PutInOrder() 297 { 298 lcl_putInOrder( Ref1, Ref2); 299 } 300 301 302 static void lcl_adjustInOrder( ScSingleRefData & rRef1, ScSingleRefData & rRef2, bool bFirstLeader ) 303 { 304 // a1:a2:a3, bFirstLeader: rRef1==a1==r1, rRef2==a3==r2 305 // else: rRef1==a3==r2, rRef2==a2==r1 306 ScSingleRefData& r1 = (bFirstLeader ? rRef1 : rRef2); 307 ScSingleRefData& r2 = (bFirstLeader ? rRef2 : rRef1); 308 if (r1.Flags.bFlag3D && !r2.Flags.bFlag3D) 309 { 310 // [$]Sheet1.A5:A6 on Sheet2 do still refer only Sheet1. 311 r2.nTab = r1.nTab; 312 r2.nRelTab = r1.nRelTab; 313 r2.Flags.bTabRel = r1.Flags.bTabRel; 314 } 315 lcl_putInOrder( rRef1, rRef2); 316 } 317 318 319 ScComplexRefData& ScComplexRefData::Extend( const ScSingleRefData & rRef, const ScAddress & rPos ) 320 { 321 CalcAbsIfRel( rPos); 322 ScSingleRefData aRef = rRef; 323 aRef.CalcAbsIfRel( rPos); 324 bool bInherit3D = Ref1.IsFlag3D() && !Ref2.IsFlag3D(); 325 bool bInherit3Dtemp = bInherit3D && !rRef.IsFlag3D(); 326 if (aRef.nCol < Ref1.nCol || aRef.nRow < Ref1.nRow || aRef.nTab < Ref1.nTab) 327 { 328 lcl_adjustInOrder( Ref1, aRef, true); 329 aRef = rRef; 330 aRef.CalcAbsIfRel( rPos); 331 } 332 if (aRef.nCol > Ref2.nCol || aRef.nRow > Ref2.nRow || aRef.nTab > Ref2.nTab) 333 { 334 if (bInherit3D) 335 Ref2.SetFlag3D( true); 336 lcl_adjustInOrder( aRef, Ref2, false); 337 if (bInherit3Dtemp) 338 Ref2.SetFlag3D( false); 339 aRef = rRef; 340 aRef.CalcAbsIfRel( rPos); 341 } 342 // In Ref2 use absolute/relative addressing from non-extended parts if 343 // equal and therefor not adjusted. 344 // A$5:A5 => A$5:A$5:A5 => A$5:A5, and not A$5:A$5 345 // A$6:$A5 => A$6:A$6:$A5 => A5:$A$6 346 if (Ref2.nCol == aRef.nCol) 347 Ref2.SetColRel( aRef.IsColRel()); 348 if (Ref2.nRow == aRef.nRow) 349 Ref2.SetRowRel( aRef.IsRowRel()); 350 // $Sheet1.$A$5:$A$6 => $Sheet1.$A$5:$A$5:$A$6 => $Sheet1.$A$5:$A$6, and 351 // not $Sheet1.$A$5:Sheet1.$A$6 (with invisible second 3D, but relative). 352 if (Ref2.nTab == aRef.nTab) 353 Ref2.SetTabRel( bInherit3Dtemp ? Ref1.IsTabRel() : aRef.IsTabRel()); 354 Ref2.CalcRelFromAbs( rPos); 355 // Force 3D if necessary. References to other sheets always. 356 if (Ref1.nTab != rPos.Tab()) 357 Ref1.SetFlag3D( true); 358 // In the second part only if different sheet thus not inherited. 359 if (Ref2.nTab != Ref1.nTab) 360 Ref2.SetFlag3D( true); 361 // Merge Flag3D to Ref2 in case there was nothing to inherit and/or range 362 // wasn't extended as in A5:A5:Sheet1.A5 if on Sheet1. 363 if (rRef.IsFlag3D()) 364 Ref2.SetFlag3D( true); 365 return *this; 366 } 367 368 369 ScComplexRefData& ScComplexRefData::Extend( const ScComplexRefData & rRef, const ScAddress & rPos ) 370 { 371 return Extend( rRef.Ref1, rPos).Extend( rRef.Ref2, rPos); 372 } 373