1 /*************************************************************************
3 * OpenOffice.org - a multi-platform office productivity suite
5 * $RCSfile: sheetcellrangemap.cxx,v $
9 * last change: $Author: rt $ $Date: 2008-01-17 08:06:09 $
11 * The Contents of this file are made available subject to
12 * the terms of GNU Lesser General Public License Version 2.1.
15 * GNU Lesser General Public License Version 2.1
16 * =============================================
17 * Copyright 2007 by Sun Microsystems, Inc.
18 * 901 San Antonio Road, Palo Alto, CA 94303, USA
20 * This library is free software; you can redistribute it and/or
21 * modify it under the terms of the GNU Lesser General Public
22 * License version 2.1, as published by the Free Software Foundation.
24 * This library is distributed in the hope that it will be useful,
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
27 * Lesser General Public License for more details.
29 * You should have received a copy of the GNU Lesser General Public
30 * License along with this library; if not, write to the Free Software
31 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
34 ************************************************************************/
36 #include "oox/xls/sheetcellrangemap.hxx"
38 #define DEBUG_OOX_CELLRANGE_MAP 0
40 #include <com/sun/star/table/CellRangeAddress.hpp>
41 #include <com/sun/star/table/CellAddress.hpp>
43 #if DEBUG_OOX_CELLRANGE_MAP
47 using ::com::sun::star::table::CellAddress
;
48 using ::com::sun::star::table::CellRangeAddress
;
53 SheetCellRangeMap::SheetCellRangeMap()
57 SheetCellRangeMap::~SheetCellRangeMap() throw()
61 void SheetCellRangeMap::addCellRange( const CellRangeAddress
& aRangeAddr
)
63 size_t nAreaId
= maAreas
.size();
65 // First, find the sheet ID.
66 SheetMapType::iterator posSheet
= maSheetMap
.find(aRangeAddr
.Sheet
);
67 if ( posSheet
== maSheetMap
.end() )
69 maSheetMap
.insert( SheetMapType::value_type(aRangeAddr
.Sheet
, SheetSet()) );
70 posSheet
= maSheetMap
.find(aRangeAddr
.Sheet
);
71 OSL_ENSURE( posSheet
!= maSheetMap
.end(), "SheetCellRangeMap::addCellRange: insertion failure" );
73 SheetSet
& rSheet
= posSheet
->second
;
75 addRange(rSheet
.maColRanges
, aRangeAddr
.StartColumn
, aRangeAddr
.EndColumn
, nAreaId
);
76 addRange(rSheet
.maRowRanges
, aRangeAddr
.StartRow
, aRangeAddr
.EndRow
, nAreaId
);
78 #if DEBUG_OOX_CELLRANGE_MAP
79 fprintf(stdout
, "SheetCellRangeMap::addCellRange: adding (sheet: %d) (col: %ld - %ld) (row: %ld - %ld) (area: %d)\n",
80 aRangeAddr
.Sheet
, aRangeAddr
.StartColumn
, aRangeAddr
.EndColumn
, aRangeAddr
.StartRow
, aRangeAddr
.EndRow
, nAreaId
);fflush(stdout
);
83 maAreas
.push_back(aRangeAddr
);
86 bool SheetCellRangeMap::isOverlapping( const CellAddress
& aCellAddr
) const
88 if ( maAreas
.empty() )
91 SheetMapType::const_iterator pos
= maSheetMap
.find(aCellAddr
.Sheet
);
92 if ( pos
== maSheetMap
.end() )
93 // There is no cell range registered for this sheet.
96 const SheetSet
& rSheet
= pos
->second
;
97 return searchColumns( rSheet
, aCellAddr
);
100 void SheetCellRangeMap::addRange( StartEndMapType
& rRangeMap
, sal_Int32 nStart
, sal_Int32 nEnd
, size_t nAreaId
)
102 StartEndMapType::iterator posStart
= rRangeMap
.find(nStart
);
103 if ( posStart
== rRangeMap
.end() )
105 EndAreaIdMapType aMap
;
106 rRangeMap
.insert( StartEndMapType::value_type(nStart
, aMap
) );
107 posStart
= rRangeMap
.find(nStart
);
108 OSL_ENSURE( posStart
!= rRangeMap
.end(), "TableBuffer::addRangeToSet: insertion failure" );
110 EndAreaIdMapType
& rEndMap
= posStart
->second
;
112 EndAreaIdMapType::iterator posEnd
= rEndMap
.find(nEnd
);
113 if ( posEnd
== rEndMap
.end() )
116 rEndMap
.insert( EndAreaIdMapType::value_type(nEnd
, aSet
) );
117 posEnd
= rEndMap
.find(nEnd
);
118 OSL_ENSURE( posEnd
!= rEndMap
.end(), "TableBuffer::addRangeToSet: insertion failure" );
121 AreaIdSetType
& rSet
= posEnd
->second
;
122 rSet
.push_back(nAreaId
);
125 bool SheetCellRangeMap::expandSearch( const EndAreaIdMapType
& rEndMap
, const CellAddress
& rCellAddr
, bool bColumn
) const
127 sal_Int32 nId
= bColumn
? rCellAddr
.Column
: rCellAddr
.Row
;
129 EndAreaIdMapType::const_reverse_iterator itr
, itrBeg
= rEndMap
.rbegin(), itrEnd
= rEndMap
.rend();
130 for ( itr
= itrBeg
; itr
!= itrEnd
; ++itr
)
132 if ( itr
->first
>= nId
)
134 // The point is in-range.
135 const AreaIdSetType
& rSet
= itr
->second
;
136 AreaIdSetType::const_iterator itr2
= rSet
.begin(), itr2End
= rSet
.end();
137 for ( ; itr2
!= itr2End
; ++itr2
)
139 OSL_ENSURE( maAreas
.size() > *itr2
, "SheetCellRangeMap::expandSearch: size mismatch" );
140 const CellRangeAddress
& rRange
= maAreas
[*itr2
];
141 if ( bColumn
&& rCellAddr
.Row
>= rRange
.StartRow
&& rCellAddr
.Row
<= rRange
.EndRow
)
143 if ( !bColumn
&& rCellAddr
.Column
>= rRange
.StartColumn
&& rCellAddr
.Column
<= rRange
.EndColumn
)
147 else if ( itr
->first
< nId
)
148 // No more enclosing ranges.
154 bool SheetCellRangeMap::searchColumns( const SheetSet
& rSheet
, const CellAddress
& aCellAddr
) const
156 StartEndMapType::const_iterator itr
, itrBeg
= rSheet
.maColRanges
.begin(), itrEnd
= rSheet
.maColRanges
.end();
157 for ( itr
= itrBeg
; itr
!= itrEnd
; ++itr
)
159 if ( itr
->first
<= aCellAddr
.Column
)
161 if ( expandSearch(itr
->second
, aCellAddr
, true) )
164 else if ( itr
->first
> aCellAddr
.Column
)