xref: /trunk/main/sc/inc/bigrange.hxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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 #ifndef SC_BIGRANGE_HXX
29 #define SC_BIGRANGE_HXX
30 
31 
32 #include "global.hxx"
33 #include "document.hxx"
34 
35 
36 static const sal_Int32 nInt32Min = 0x80000000;
37 static const sal_Int32 nInt32Max = 0x7fffffff;
38 
39 
40 class ScBigAddress
41 {
42     sal_Int32   nRow;
43     sal_Int32   nCol;
44     sal_Int32   nTab;
45 
46 public:
47             ScBigAddress() : nRow(0), nCol(0), nTab(0) {}
48             ScBigAddress( sal_Int32 nColP, sal_Int32 nRowP, sal_Int32 nTabP )
49                 : nRow( nRowP ), nCol( nColP ), nTab( nTabP ) {}
50             ScBigAddress( const ScBigAddress& r )
51                 : nRow( r.nRow ), nCol( r.nCol ), nTab( r.nTab ) {}
52             ScBigAddress( const ScAddress& r )
53                 : nRow( r.Row() ), nCol( r.Col() ), nTab( r.Tab() ) {}
54 
55     sal_Int32   Col() const { return nCol; }
56     sal_Int32   Row() const { return nRow; }
57     sal_Int32   Tab() const { return nTab; }
58 
59     void    Set( sal_Int32 nColP, sal_Int32 nRowP, sal_Int32 nTabP )
60                 { nCol = nColP; nRow = nRowP; nTab = nTabP; }
61     void    SetCol( sal_Int32 nColP ) { nCol = nColP; }
62     void    SetRow( sal_Int32 nRowP ) { nRow = nRowP; }
63     void    SetTab( sal_Int32 nTabP ) { nTab = nTabP; }
64     void    IncCol( sal_Int32 n = 1 ) { nCol += n; }
65     void    IncRow( sal_Int32 n = 1 ) { nRow += n; }
66     void    IncTab( sal_Int32 n = 1 ) { nTab += n; }
67 
68     void    GetVars( sal_Int32& nColP, sal_Int32& nRowP, sal_Int32& nTabP ) const
69                 { nColP = nCol; nRowP = nRow; nTabP = nTab; }
70 
71     inline void     PutInOrder( ScBigAddress& r );
72     inline sal_Bool     IsValid( const ScDocument* ) const;
73     inline ScAddress    MakeAddress() const;
74 
75     ScBigAddress&   operator=( const ScBigAddress& r )
76                     { nCol = r.nCol; nRow = r.nRow; nTab = r.nTab; return *this; }
77     ScBigAddress&   operator=( const ScAddress& r )
78                     { nCol = r.Col(); nRow = r.Row(); nTab = r.Tab(); return *this; }
79     int             operator==( const ScBigAddress& r ) const
80                     { return nCol == r.nCol && nRow == r.nRow && nTab == r.nTab; }
81     int             operator!=( const ScBigAddress& r ) const
82                     { return !operator==( r ); }
83 
84     friend inline SvStream& operator<< ( SvStream& rStream, const ScBigAddress& rAdr );
85     friend inline SvStream& operator>> ( SvStream& rStream, ScBigAddress& rAdr );
86 };
87 
88 
89 inline void ScBigAddress::PutInOrder( ScBigAddress& r )
90 {
91     sal_Int32 nTmp;
92     if ( r.nCol < nCol )
93     {
94         nTmp = r.nCol;
95         r.nCol = nCol;
96         nCol = nTmp;
97     }
98     if ( r.nRow < nRow )
99     {
100         nTmp = r.nRow;
101         r.nRow = nRow;
102         nRow = nTmp;
103     }
104     if ( r.nTab < nTab )
105     {
106         nTmp = r.nTab;
107         r.nTab = nTab;
108         nTab = nTmp;
109     }
110 }
111 
112 
113 inline sal_Bool ScBigAddress::IsValid( const ScDocument* pDoc ) const
114 {   //! Min/Max sind ok, kennzeichnen ganze Col/Row/Tab
115     return
116         ((0 <= nCol && nCol <= MAXCOL)
117             || nCol == nInt32Min || nCol == nInt32Max) &&
118         ((0 <= nRow && nRow <= MAXROW)
119             || nRow == nInt32Min || nRow == nInt32Max) &&
120         ((0 <= nTab && nTab < pDoc->GetTableCount())
121             || nTab == nInt32Min || nTab == nInt32Max)
122         ;
123 }
124 
125 
126 inline ScAddress ScBigAddress::MakeAddress() const
127 {
128     SCCOL nColA;
129     SCROW nRowA;
130     SCTAB nTabA;
131 
132     if ( nCol < 0 )
133         nColA = 0;
134     else if ( nCol > MAXCOL )
135         nColA = MAXCOL;
136     else
137         nColA = (SCCOL) nCol;
138 
139     if ( nRow < 0 )
140         nRowA = 0;
141     else if ( nRow > MAXROW )
142         nRowA = MAXROW;
143     else
144         nRowA = (SCROW) nRow;
145 
146     if ( nTab < 0 )
147         nTabA = 0;
148     else if ( nTab > MAXTAB )
149         nTabA = MAXTAB;
150     else
151         nTabA = (SCTAB) nTab;
152 
153     return ScAddress( nColA, nRowA, nTabA );
154 }
155 
156 
157 inline SvStream& operator<< ( SvStream& rStream, const ScBigAddress& rAdr )
158 {
159     rStream << rAdr.nCol << rAdr.nRow << rAdr.nTab;
160     return rStream;
161 }
162 
163 
164 inline SvStream& operator>> ( SvStream& rStream, ScBigAddress& rAdr )
165 {
166     rStream >> rAdr.nCol >> rAdr.nRow >> rAdr.nTab;
167     return rStream;
168 }
169 
170 
171 class ScBigRange
172 {
173 public:
174 
175     ScBigAddress    aStart;
176     ScBigAddress    aEnd;
177 
178                     ScBigRange() : aStart(), aEnd() {}
179                     ScBigRange( const ScBigAddress& s, const ScBigAddress& e )
180                         : aStart( s ), aEnd( e ) { aStart.PutInOrder( aEnd ); }
181                     ScBigRange( const ScBigRange& r )
182                         : aStart( r.aStart ), aEnd( r.aEnd ) {}
183                     ScBigRange( const ScRange& r )
184                         : aStart( r.aStart ), aEnd( r.aEnd ) {}
185                     ScBigRange( const ScBigAddress& r )
186                         : aStart( r ), aEnd( r ) {}
187                     ScBigRange( const ScAddress& r )
188                         : aStart( r ), aEnd( r ) {}
189                     ScBigRange( sal_Int32 nCol, sal_Int32 nRow, sal_Int32 nTab )
190                         : aStart( nCol, nRow, nTab ), aEnd( aStart ) {}
191                     ScBigRange( sal_Int32 nCol1, sal_Int32 nRow1, sal_Int32 nTab1,
192                             sal_Int32 nCol2, sal_Int32 nRow2, sal_Int32 nTab2 )
193                         : aStart( nCol1, nRow1, nTab1 ),
194                         aEnd( nCol2, nRow2, nTab2 ) {}
195 
196     void    Set( sal_Int32 nCol1, sal_Int32 nRow1, sal_Int32 nTab1,
197                      sal_Int32 nCol2, sal_Int32 nRow2, sal_Int32 nTab2 )
198                 { aStart.Set( nCol1, nRow1, nTab1 );
199                     aEnd.Set( nCol2, nRow2, nTab2 ); }
200 
201     void    GetVars( sal_Int32& nCol1, sal_Int32& nRow1, sal_Int32& nTab1,
202                      sal_Int32& nCol2, sal_Int32& nRow2, sal_Int32& nTab2 ) const
203                 { aStart.GetVars( nCol1, nRow1, nTab1 );
204                     aEnd.GetVars( nCol2, nRow2, nTab2 ); }
205 
206     sal_Bool    IsValid( const ScDocument* pDoc ) const
207                 { return aStart.IsValid( pDoc ) && aEnd.IsValid( pDoc ); }
208     inline ScRange  MakeRange() const
209                     { return ScRange( aStart.MakeAddress(),
210                         aEnd.MakeAddress() ); }
211 
212     inline sal_Bool In( const ScBigAddress& ) const;    // ist Address& in Range?
213     inline sal_Bool In( const ScBigRange& ) const;      // ist Range& in Range?
214     inline sal_Bool Intersects( const ScBigRange& ) const;  // ueberschneiden sich zwei Ranges?
215 
216     ScBigRange&     operator=( const ScBigRange& r )
217                         { aStart = r.aStart; aEnd = r.aEnd; return *this; }
218     int             operator==( const ScBigRange& r ) const
219                         { return (aStart == r.aStart) && (aEnd == r.aEnd); }
220     int             operator!=( const ScBigRange& r ) const
221                         { return !operator==( r ); }
222 
223     friend inline SvStream& operator<< ( SvStream& rStream, const ScBigRange& rRange );
224     friend inline SvStream& operator>> ( SvStream& rStream, ScBigRange& rRange );
225 };
226 
227 
228 inline sal_Bool ScBigRange::In( const ScBigAddress& rAddr ) const
229 {
230     return
231         aStart.Col() <= rAddr.Col() && rAddr.Col() <= aEnd.Col() &&
232         aStart.Row() <= rAddr.Row() && rAddr.Row() <= aEnd.Row() &&
233         aStart.Tab() <= rAddr.Tab() && rAddr.Tab() <= aEnd.Tab();
234 }
235 
236 
237 inline sal_Bool ScBigRange::In( const ScBigRange& r ) const
238 {
239     return
240         aStart.Col() <= r.aStart.Col() && r.aEnd.Col() <= aEnd.Col() &&
241         aStart.Row() <= r.aStart.Row() && r.aEnd.Row() <= aEnd.Row() &&
242         aStart.Tab() <= r.aStart.Tab() && r.aEnd.Tab() <= aEnd.Tab();
243 }
244 
245 
246 inline sal_Bool ScBigRange::Intersects( const ScBigRange& r ) const
247 {
248     return !(
249         Min( aEnd.Col(), r.aEnd.Col() ) < Max( aStart.Col(), r.aStart.Col() )
250      || Min( aEnd.Row(), r.aEnd.Row() ) < Max( aStart.Row(), r.aStart.Row() )
251      || Min( aEnd.Tab(), r.aEnd.Tab() ) < Max( aStart.Tab(), r.aStart.Tab() )
252         );
253 }
254 
255 
256 inline SvStream& operator<< ( SvStream& rStream, const ScBigRange& rRange )
257 {
258     rStream << rRange.aStart;
259     rStream << rRange.aEnd;
260     return rStream;
261 }
262 
263 
264 inline SvStream& operator>> ( SvStream& rStream, ScBigRange& rRange )
265 {
266     rStream >> rRange.aStart;
267     rStream >> rRange.aEnd;
268     return rStream;
269 }
270 
271 
272 
273 #endif
274