Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2008 by Sun Microsystems, Inc.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include "simplerangelist.hxx"
30 : : #include "rangelst.hxx"
31 : :
32 : : using ::std::list;
33 : : using ::std::pair;
34 : : using ::std::max;
35 : :
36 : : // ============================================================================
37 : :
38 : 2391 : ScSimpleRangeList::Range::Range(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2) :
39 : 2391 : mnCol1(nCol1), mnRow1(nRow1), mnCol2(nCol2), mnRow2(nRow2) {}
40 : :
41 : : // ----------------------------------------------------------------------------
42 : :
43 : 946 : ScSimpleRangeList::ScSimpleRangeList()
44 : : {
45 : 946 : }
46 : :
47 : : namespace {
48 : :
49 : 12686 : bool maybeJoin(ScSimpleRangeList::Range& rOld, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2)
50 : : {
51 [ + + ][ + - ]: 12686 : if (rOld.mnRow1 == nRow1 && rOld.mnRow2 == nRow2)
52 : : {
53 : : // Check their column spans to see if they overlap.
54 [ - + ]: 340 : if (rOld.mnCol1 == nCol1)
55 : : {
56 : : // Their share the start column position.
57 : 0 : rOld.mnCol2 = max(rOld.mnCol2, nCol2);
58 : 0 : return true;
59 : : }
60 [ + - ]: 340 : else if (rOld.mnCol1 < nCol1)
61 : : {
62 : : // Old range sits on the left.
63 [ + + ]: 340 : if (nCol1 - rOld.mnCol2 <= 1)
64 : : {
65 : 29 : rOld.mnCol2 = max(rOld.mnCol2, nCol2);
66 : 29 : return true;
67 : : }
68 : : }
69 [ # # ]: 0 : else if (nCol1 < rOld.mnCol1)
70 : : {
71 : : // New range sits on the left.
72 [ # # ]: 0 : if (nCol1 - rOld.mnCol2 <= 1)
73 : : {
74 : 0 : rOld.mnCol1 = nCol1;
75 : 0 : rOld.mnCol2 = max(rOld.mnCol2, nCol2);
76 : 0 : return true;
77 : : }
78 : : }
79 : : }
80 : :
81 [ + + ][ + + ]: 12657 : if (rOld.mnCol1 == nCol1 && rOld.mnCol2 == nCol2)
82 : : {
83 [ - + ]: 11234 : if (rOld.mnRow1 == nRow1)
84 : : {
85 : : // Their share the start row position.
86 : 0 : rOld.mnRow2 = max(rOld.mnRow2, nRow2);
87 : 0 : return true;
88 : : }
89 [ + - ]: 11234 : else if (rOld.mnRow1 < nRow1)
90 : : {
91 : : // Old range sits above.
92 [ + + ]: 11234 : if (nRow1 - rOld.mnRow2 <= 1)
93 : : {
94 : 11212 : rOld.mnRow2 = max(rOld.mnRow2, nRow2);
95 : 11212 : return true;
96 : : }
97 : : }
98 [ # # ]: 0 : else if (nRow1 < rOld.mnRow1)
99 : : {
100 : : // New range sits above.
101 [ # # ]: 0 : if (nRow1 - rOld.mnRow2 <= 1)
102 : : {
103 : 0 : rOld.mnRow1 = nRow1;
104 : 0 : rOld.mnRow2 = max(rOld.mnRow2, nRow2);
105 : 0 : return true;
106 : : }
107 : : }
108 : : }
109 : :
110 : 12686 : return false;
111 : : }
112 : :
113 : : }
114 : :
115 : 13632 : void ScSimpleRangeList::addRange(const ScRange& rRange)
116 : : {
117 : 13632 : SCCOL nCol1 = rRange.aStart.Col();
118 : 13632 : SCROW nRow1 = rRange.aStart.Row();
119 : 13632 : SCTAB nTab1 = rRange.aStart.Tab();
120 : 13632 : SCCOL nCol2 = rRange.aEnd.Col();
121 : 13632 : SCROW nRow2 = rRange.aEnd.Row();
122 : 13632 : SCTAB nTab2 = rRange.aEnd.Tab();
123 : :
124 [ + + ]: 27264 : for (SCTAB nTab = nTab1; nTab <= nTab2; ++nTab)
125 : : {
126 [ + - ]: 13632 : RangeListRef pRef = findTab(nTab);
127 [ - + ]: 13632 : if (!pRef)
128 : : // This should never happen!
129 : 13632 : return;
130 : :
131 [ + + ][ + - ]: 13632 : if (pRef->empty() || !maybeJoin(pRef->back(), nCol1, nRow1, nCol2, nRow2))
[ + - ][ + + ]
[ + + ]
132 : : // Not joinable. Append it to the list.
133 [ + - ]: 13632 : pRef->push_back(Range(nCol1, nRow1, nCol2, nRow2));
134 [ + - ][ + - ]: 13632 : }
135 : : }
136 : :
137 : 231 : void ScSimpleRangeList::insertCol(SCCOL nCol, SCTAB nTab)
138 : : {
139 [ + - ]: 231 : RangeListRef pRef = findTab(nTab);
140 [ - + ]: 231 : if (!pRef)
141 : : // This should never happen!
142 : 231 : return;
143 : :
144 : 231 : list<Range>::iterator itr = pRef->begin(), itrEnd = pRef->end();
145 [ + + ]: 482 : for (; itr != itrEnd; ++itr)
146 : : {
147 : 251 : Range& r = *itr;
148 [ + - ]: 251 : if (r.mnCol2 < nCol)
149 : : // insertion point to the right of the range.
150 : 251 : continue;
151 : :
152 [ # # ]: 0 : if (nCol <= r.mnCol1)
153 : : {
154 : : // insertion point to the left of the range.
155 : 0 : ++r.mnCol1;
156 : 0 : ++r.mnCol2;
157 : : }
158 [ # # ]: 0 : else if (nCol <= r.mnCol2)
159 : : {
160 : : // insertion point cuts through the range.
161 : 0 : ++r.mnCol2;
162 : : }
163 [ + - ][ + - ]: 231 : }
164 : : }
165 : :
166 : 946 : void ScSimpleRangeList::getRangeList(list<ScRange>& rList) const
167 : : {
168 [ + - ]: 946 : list<ScRange> aList;
169 [ + + ]: 1892 : for (TabType::const_iterator itrTab = maTabs.begin(), itrTabEnd = maTabs.end(); itrTab != itrTabEnd; ++itrTab)
170 : : {
171 : 946 : SCTAB nTab = itrTab->first;
172 : 946 : const RangeListRef& pRanges = itrTab->second;
173 : 946 : list<Range>::const_iterator itr = pRanges->begin(), itrEnd = pRanges->end();
174 [ + + ]: 3337 : for (; itr != itrEnd; ++itr)
175 : : {
176 : 2391 : const Range& r = *itr;
177 [ + - ]: 2391 : aList.push_back(ScRange(r.mnCol1, r.mnRow1, nTab, r.mnCol2, r.mnRow2, nTab));
178 : : }
179 : : }
180 [ + - ]: 946 : rList.swap(aList);
181 : 946 : }
182 : :
183 : 941 : void ScSimpleRangeList::clear()
184 : : {
185 : 941 : maTabs.clear();
186 : 941 : }
187 : :
188 : 13863 : ScSimpleRangeList::RangeListRef ScSimpleRangeList::findTab(SCTAB nTab)
189 : : {
190 [ + - ]: 13863 : TabType::iterator itr = maTabs.find(nTab);
191 [ + + ]: 13863 : if (itr == maTabs.end())
192 : : {
193 [ + - ][ + - ]: 946 : RangeListRef p(new list<Range>);
[ + - ]
194 [ + - ][ + - ]: 946 : pair<TabType::iterator, bool> r = maTabs.insert(TabType::value_type(nTab, p));
[ + - ]
195 [ - + ]: 946 : if (!r.second)
196 [ # # ]: 0 : return RangeListRef();
197 [ + - ][ + - ]: 946 : itr = r.first;
198 : : }
199 : :
200 [ + - ]: 13863 : return itr->second;
201 : : }
202 : :
203 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|