Line data Source code
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 "refdata.hxx"
21 :
22 :
23 1384 : void ScSingleRefData::CalcRelFromAbs( const ScAddress& rPos )
24 : {
25 1384 : nRelCol = nCol - rPos.Col();
26 1384 : nRelRow = nRow - rPos.Row();
27 1384 : nRelTab = nTab - rPos.Tab();
28 1384 : }
29 :
30 :
31 0 : void ScSingleRefData::SmartRelAbs( const ScAddress& rPos )
32 : {
33 0 : if ( Flags.bColRel )
34 0 : nCol = nRelCol + rPos.Col();
35 : else
36 0 : nRelCol = nCol - rPos.Col();
37 :
38 0 : if ( Flags.bRowRel )
39 0 : nRow = nRelRow + rPos.Row();
40 : else
41 0 : nRelRow = nRow - rPos.Row();
42 :
43 0 : if ( Flags.bTabRel )
44 0 : nTab = nRelTab + rPos.Tab();
45 : else
46 0 : nRelTab = nTab - rPos.Tab();
47 0 : }
48 :
49 :
50 9992 : void ScSingleRefData::CalcAbsIfRel( const ScAddress& rPos )
51 : {
52 9992 : if ( Flags.bColRel )
53 : {
54 9751 : nCol = nRelCol + rPos.Col();
55 9751 : if ( !VALIDCOL( nCol ) )
56 0 : Flags.bColDeleted = sal_True;
57 : }
58 9992 : if ( Flags.bRowRel )
59 : {
60 9720 : nRow = nRelRow + rPos.Row();
61 9720 : if ( !VALIDROW( nRow ) )
62 0 : Flags.bRowDeleted = sal_True;
63 : }
64 9992 : if ( Flags.bTabRel )
65 : {
66 7921 : nTab = nRelTab + rPos.Tab();
67 7921 : if ( !VALIDTAB( nTab ) )
68 2 : Flags.bTabDeleted = sal_True;
69 : }
70 9992 : }
71 :
72 :
73 :
74 2 : sal_Bool ScSingleRefData::operator==( const ScSingleRefData& r ) const
75 : {
76 : return bFlags == r.bFlags &&
77 : (Flags.bColRel ? nRelCol == r.nRelCol : nCol == r.nCol) &&
78 : (Flags.bRowRel ? nRelRow == r.nRelRow : nRow == r.nRow) &&
79 2 : (Flags.bTabRel ? nRelTab == r.nRelTab : nTab == r.nTab);
80 : }
81 :
82 0 : bool ScSingleRefData::operator!=( const ScSingleRefData& r ) const
83 : {
84 0 : return !operator==(r);
85 : }
86 :
87 253 : static void lcl_putInOrder( ScSingleRefData & rRef1, ScSingleRefData & rRef2 )
88 : {
89 : SCCOL nCol1, nCol2;
90 : SCROW nRow1, nRow2;
91 : SCTAB nTab1, nTab2;
92 : sal_Bool bTmp;
93 : sal_uInt8 nRelState1, nRelState2;
94 253 : if ( rRef1.Flags.bRelName )
95 : nRelState1 =
96 : ((rRef1.Flags.bTabRel & 0x01) << 2)
97 : | ((rRef1.Flags.bRowRel & 0x01) << 1)
98 203 : | ((rRef1.Flags.bColRel & 0x01));
99 : else
100 50 : nRelState1 = 0;
101 253 : if ( rRef2.Flags.bRelName )
102 : nRelState2 =
103 : ((rRef2.Flags.bTabRel & 0x01) << 2)
104 : | ((rRef2.Flags.bRowRel & 0x01) << 1)
105 203 : | ((rRef2.Flags.bColRel & 0x01));
106 : else
107 50 : nRelState2 = 0;
108 253 : if ( (nCol1 = rRef1.nCol) > (nCol2 = rRef2.nCol) )
109 : {
110 0 : rRef1.nCol = nCol2;
111 0 : rRef2.nCol = nCol1;
112 0 : nCol1 = rRef1.nRelCol;
113 0 : rRef1.nRelCol = rRef2.nRelCol;
114 0 : rRef2.nRelCol = nCol1;
115 0 : if ( rRef1.Flags.bRelName && rRef1.Flags.bColRel )
116 0 : nRelState2 |= 1;
117 : else
118 0 : nRelState2 &= ~1;
119 0 : if ( rRef2.Flags.bRelName && rRef2.Flags.bColRel )
120 0 : nRelState1 |= 1;
121 : else
122 0 : nRelState1 &= ~1;
123 0 : bTmp = rRef1.Flags.bColRel;
124 0 : rRef1.Flags.bColRel = rRef2.Flags.bColRel;
125 0 : rRef2.Flags.bColRel = bTmp;
126 0 : bTmp = rRef1.Flags.bColDeleted;
127 0 : rRef1.Flags.bColDeleted = rRef2.Flags.bColDeleted;
128 0 : rRef2.Flags.bColDeleted = bTmp;
129 : }
130 253 : if ( (nRow1 = rRef1.nRow) > (nRow2 = rRef2.nRow) )
131 : {
132 0 : rRef1.nRow = nRow2;
133 0 : rRef2.nRow = nRow1;
134 0 : nRow1 = rRef1.nRelRow;
135 0 : rRef1.nRelRow = rRef2.nRelRow;
136 0 : rRef2.nRelRow = nRow1;
137 0 : if ( rRef1.Flags.bRelName && rRef1.Flags.bRowRel )
138 0 : nRelState2 |= 2;
139 : else
140 0 : nRelState2 &= ~2;
141 0 : if ( rRef2.Flags.bRelName && rRef2.Flags.bRowRel )
142 0 : nRelState1 |= 2;
143 : else
144 0 : nRelState1 &= ~2;
145 0 : bTmp = rRef1.Flags.bRowRel;
146 0 : rRef1.Flags.bRowRel = rRef2.Flags.bRowRel;
147 0 : rRef2.Flags.bRowRel = bTmp;
148 0 : bTmp = rRef1.Flags.bRowDeleted;
149 0 : rRef1.Flags.bRowDeleted = rRef2.Flags.bRowDeleted;
150 0 : rRef2.Flags.bRowDeleted = bTmp;
151 : }
152 253 : if ( (nTab1 = rRef1.nTab) > (nTab2 = rRef2.nTab) )
153 : {
154 0 : rRef1.nTab = nTab2;
155 0 : rRef2.nTab = nTab1;
156 0 : nTab1 = rRef1.nRelTab;
157 0 : rRef1.nRelTab = rRef2.nRelTab;
158 0 : rRef2.nRelTab = nTab1;
159 0 : if ( rRef1.Flags.bRelName && rRef1.Flags.bTabRel )
160 0 : nRelState2 |= 4;
161 : else
162 0 : nRelState2 &= ~4;
163 0 : if ( rRef2.Flags.bRelName && rRef2.Flags.bTabRel )
164 0 : nRelState1 |= 4;
165 : else
166 0 : nRelState1 &= ~4;
167 0 : bTmp = rRef1.Flags.bTabRel;
168 0 : rRef1.Flags.bTabRel = rRef2.Flags.bTabRel;
169 0 : rRef2.Flags.bTabRel = bTmp;
170 0 : bTmp = rRef1.Flags.bTabDeleted;
171 0 : rRef1.Flags.bTabDeleted = rRef2.Flags.bTabDeleted;
172 0 : rRef2.Flags.bTabDeleted = bTmp;
173 : }
174 253 : rRef1.Flags.bRelName = ( nRelState1 ? sal_True : false );
175 253 : rRef2.Flags.bRelName = ( nRelState2 ? sal_True : false );
176 253 : }
177 :
178 :
179 253 : void ScComplexRefData::PutInOrder()
180 : {
181 253 : lcl_putInOrder( Ref1, Ref2);
182 253 : }
183 :
184 :
185 0 : static void lcl_adjustInOrder( ScSingleRefData & rRef1, ScSingleRefData & rRef2, bool bFirstLeader )
186 : {
187 : // a1:a2:a3, bFirstLeader: rRef1==a1==r1, rRef2==a3==r2
188 : // else: rRef1==a3==r2, rRef2==a2==r1
189 0 : ScSingleRefData& r1 = (bFirstLeader ? rRef1 : rRef2);
190 0 : ScSingleRefData& r2 = (bFirstLeader ? rRef2 : rRef1);
191 0 : if (r1.Flags.bFlag3D && !r2.Flags.bFlag3D)
192 : {
193 : // [$]Sheet1.A5:A6 on Sheet2 do still refer only Sheet1.
194 0 : r2.nTab = r1.nTab;
195 0 : r2.nRelTab = r1.nRelTab;
196 0 : r2.Flags.bTabRel = r1.Flags.bTabRel;
197 : }
198 0 : lcl_putInOrder( rRef1, rRef2);
199 0 : }
200 :
201 :
202 0 : ScComplexRefData& ScComplexRefData::Extend( const ScSingleRefData & rRef, const ScAddress & rPos )
203 : {
204 0 : CalcAbsIfRel( rPos);
205 0 : ScSingleRefData aRef = rRef;
206 0 : aRef.CalcAbsIfRel( rPos);
207 0 : bool bInherit3D = Ref1.IsFlag3D() && !Ref2.IsFlag3D();
208 0 : bool bInherit3Dtemp = bInherit3D && !rRef.IsFlag3D();
209 0 : if (aRef.nCol < Ref1.nCol || aRef.nRow < Ref1.nRow || aRef.nTab < Ref1.nTab)
210 : {
211 0 : lcl_adjustInOrder( Ref1, aRef, true);
212 0 : aRef = rRef;
213 0 : aRef.CalcAbsIfRel( rPos);
214 : }
215 0 : if (aRef.nCol > Ref2.nCol || aRef.nRow > Ref2.nRow || aRef.nTab > Ref2.nTab)
216 : {
217 0 : if (bInherit3D)
218 0 : Ref2.SetFlag3D( true);
219 0 : lcl_adjustInOrder( aRef, Ref2, false);
220 0 : if (bInherit3Dtemp)
221 0 : Ref2.SetFlag3D( false);
222 0 : aRef = rRef;
223 0 : aRef.CalcAbsIfRel( rPos);
224 : }
225 : // In Ref2 use absolute/relative addressing from non-extended parts if
226 : // equal and therefor not adjusted.
227 : // A$5:A5 => A$5:A$5:A5 => A$5:A5, and not A$5:A$5
228 : // A$6:$A5 => A$6:A$6:$A5 => A5:$A$6
229 0 : if (Ref2.nCol == aRef.nCol)
230 0 : Ref2.SetColRel( aRef.IsColRel());
231 0 : if (Ref2.nRow == aRef.nRow)
232 0 : Ref2.SetRowRel( aRef.IsRowRel());
233 : // $Sheet1.$A$5:$A$6 => $Sheet1.$A$5:$A$5:$A$6 => $Sheet1.$A$5:$A$6, and
234 : // not $Sheet1.$A$5:Sheet1.$A$6 (with invisible second 3D, but relative).
235 0 : if (Ref2.nTab == aRef.nTab)
236 0 : Ref2.SetTabRel( bInherit3Dtemp ? Ref1.IsTabRel() : aRef.IsTabRel());
237 0 : Ref2.CalcRelFromAbs( rPos);
238 : // Force 3D if necessary. References to other sheets always.
239 0 : if (Ref1.nTab != rPos.Tab())
240 0 : Ref1.SetFlag3D( true);
241 : // In the second part only if different sheet thus not inherited.
242 0 : if (Ref2.nTab != Ref1.nTab)
243 0 : Ref2.SetFlag3D( true);
244 : // Merge Flag3D to Ref2 in case there was nothing to inherit and/or range
245 : // wasn't extended as in A5:A5:Sheet1.A5 if on Sheet1.
246 0 : if (rRef.IsFlag3D())
247 0 : Ref2.SetFlag3D( true);
248 0 : return *this;
249 : }
250 :
251 :
252 0 : ScComplexRefData& ScComplexRefData::Extend( const ScComplexRefData & rRef, const ScAddress & rPos )
253 : {
254 0 : return Extend( rRef.Ref1, rPos).Extend( rRef.Ref2, rPos);
255 : }
256 :
257 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|