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