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 2000, 2010 Oracle and/or its affiliates.
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 "colrowst.hxx"
30 : :
31 : : #include <string.h>
32 : :
33 : : #include "document.hxx"
34 : : #include "root.hxx"
35 : : #include "ftools.hxx"
36 : : #include "xltable.hxx"
37 : : #include "xistream.hxx"
38 : : #include "xistyle.hxx"
39 : : #include "queryparam.hxx"
40 : :
41 : : // for filter manager
42 : : #include "excimp8.hxx"
43 : :
44 : : // ============================================================================
45 : :
46 : : const sal_uInt8 EXC_COLROW_USED = 0x01;
47 : : const sal_uInt8 EXC_COLROW_DEFAULT = 0x02;
48 : : const sal_uInt8 EXC_COLROW_HIDDEN = 0x04;
49 : : const sal_uInt8 EXC_COLROW_MAN = 0x08;
50 : :
51 : : // ============================================================================
52 : :
53 : 165 : XclImpColRowSettings::XclImpColRowSettings( const XclImpRoot& rRoot ) :
54 : : XclImpRoot( rRoot ),
55 : : maWidths( MAXCOLCOUNT, 0 ),
56 : : maColFlags( MAXCOLCOUNT, 0 ),
57 : : maRowHeights(0, MAXROWCOUNT, 0),
58 : : maRowFlags(0, MAXROWCOUNT, 0),
59 : : maHiddenRows(0, MAXROWCOUNT, false),
60 : : mnLastScRow( -1 ),
61 : : mnDefWidth( STD_COL_WIDTH ),
62 : : mnDefHeight( static_cast< sal_uInt16 >( STD_ROW_HEIGHT ) ),
63 : : mnDefRowFlags( EXC_DEFROW_DEFAULTFLAGS ),
64 : : mbHasStdWidthRec( false ),
65 : : mbHasDefHeight( false ),
66 [ + - ][ + - ]: 165 : mbDirty( true )
[ + - ][ + - ]
[ + - ]
67 : : {
68 : 165 : }
69 : :
70 [ + - ][ + - ]: 165 : XclImpColRowSettings::~XclImpColRowSettings()
[ + - ]
71 : : {
72 [ - + ]: 330 : }
73 : :
74 : 162 : void XclImpColRowSettings::SetDefWidth( sal_uInt16 nDefWidth, bool bStdWidthRec )
75 : : {
76 [ - + ]: 162 : if( bStdWidthRec )
77 : : {
78 : : // STANDARDWIDTH record overrides DEFCOLWIDTH record
79 : 0 : mnDefWidth = nDefWidth;
80 : 0 : mbHasStdWidthRec = true;
81 : : }
82 [ + - ]: 162 : else if( !mbHasStdWidthRec )
83 : : {
84 : : // use DEFCOLWIDTH record only, if no STANDARDWIDTH record exists
85 : 162 : mnDefWidth = nDefWidth;
86 : : }
87 : 162 : }
88 : :
89 : 291 : void XclImpColRowSettings::SetWidthRange( SCCOL nScCol1, SCCOL nScCol2, sal_uInt16 nWidth )
90 : : {
91 : : OSL_ENSURE( (nScCol1 <= nScCol2) && ValidCol( nScCol2 ), "XclImpColRowSettings::SetColWidthRange - invalid column range" );
92 : 291 : nScCol2 = ::std::min( nScCol2, MAXCOL );
93 [ + + ]: 291 : if (nScCol2 == 256)
94 : : // In BIFF8, the column range is 0-255, and the use of 256 probably
95 : : // means the range should extend to the max column if the loading app
96 : : // support columns beyond 255.
97 : 96 : nScCol2 = MAXCOL;
98 : :
99 : 291 : nScCol1 = ::std::min( nScCol1, nScCol2 );
100 [ + - ][ + - ]: 291 : ::std::fill( maWidths.begin() + nScCol1, maWidths.begin() + nScCol2 + 1, nWidth );
[ + - ][ + - ]
101 [ + - ][ + - ]: 98673 : for( ScfUInt8Vec::iterator aIt = maColFlags.begin() + nScCol1, aEnd = maColFlags.begin() + nScCol2 + 1; aIt != aEnd; ++aIt )
[ + - ][ + - ]
[ + - ][ + + ]
102 [ + - ]: 98382 : ::set_flag( *aIt, EXC_COLROW_USED );
103 : 291 : }
104 : :
105 : 0 : void XclImpColRowSettings::HideCol( SCCOL nScCol )
106 : : {
107 [ # # ]: 0 : if( ValidCol( nScCol ) )
108 : 0 : ::set_flag( maColFlags[ nScCol ], EXC_COLROW_HIDDEN );
109 : 0 : }
110 : :
111 : 3 : void XclImpColRowSettings::HideColRange( SCCOL nScCol1, SCCOL nScCol2 )
112 : : {
113 : : OSL_ENSURE( (nScCol1 <= nScCol2) && ValidCol( nScCol2 ), "XclImpColRowSettings::HideColRange - invalid column range" );
114 : 3 : nScCol2 = ::std::min( nScCol2, MAXCOL );
115 : 3 : nScCol1 = ::std::min( nScCol1, nScCol2 );
116 [ + - ][ + - ]: 6 : for( ScfUInt8Vec::iterator aIt = maColFlags.begin() + nScCol1, aEnd = maColFlags.begin() + nScCol2 + 1; aIt != aEnd; ++aIt )
[ + - ][ + - ]
[ + + ][ + - ]
117 [ + - ]: 3 : ::set_flag( *aIt, EXC_COLROW_HIDDEN );
118 : 3 : }
119 : :
120 : 165 : void XclImpColRowSettings::SetDefHeight( sal_uInt16 nDefHeight, sal_uInt16 nFlags )
121 : : {
122 : 165 : mnDefHeight = nDefHeight;
123 : 165 : mnDefRowFlags = nFlags;
124 [ - + ]: 165 : if( mnDefHeight == 0 )
125 : : {
126 : 0 : mnDefHeight = static_cast< sal_uInt16 >( STD_ROW_HEIGHT );
127 : 0 : ::set_flag( mnDefRowFlags, EXC_DEFROW_HIDDEN );
128 : : }
129 : 165 : mbHasDefHeight = true;
130 : 165 : }
131 : :
132 : 3255 : void XclImpColRowSettings::SetHeight( SCROW nScRow, sal_uInt16 nHeight )
133 : : {
134 [ + - ]: 3255 : if (!ValidRow(nScRow))
135 : : return;
136 : :
137 : 3255 : sal_uInt16 nRawHeight = nHeight & EXC_ROW_HEIGHTMASK;
138 [ + - ][ - + ]: 3255 : bool bDefHeight = ::get_flag( nHeight, EXC_ROW_FLAGDEFHEIGHT ) || (nRawHeight == 0);
139 [ + - ]: 3255 : maRowHeights.insert_back(nScRow, nScRow+1, nRawHeight);
140 : 3255 : sal_uInt8 nFlagVal = 0;
141 [ + - ][ + - ]: 3255 : if (!maRowFlags.search(nScRow, nFlagVal).second)
142 : : return;
143 : :
144 : 3255 : ::set_flag(nFlagVal, EXC_COLROW_USED);
145 : 3255 : ::set_flag(nFlagVal, EXC_COLROW_DEFAULT, bDefHeight);
146 : :
147 [ - + ][ + - ]: 3255 : if (!bDefHeight && nRawHeight == 0)
148 [ # # ]: 0 : maHiddenRows.insert_back(nScRow, nScRow+1, true);
149 : :
150 [ + - ]: 3255 : maRowFlags.insert_back(nScRow, nScRow+1, nFlagVal);
151 : :
152 [ + - ]: 3255 : if (nScRow > mnLastScRow)
153 : 3255 : mnLastScRow = nScRow;
154 : : }
155 : :
156 : 3255 : void XclImpColRowSettings::SetRowSettings( SCROW nScRow, sal_uInt16 nHeight, sal_uInt16 nFlags )
157 : : {
158 [ + - ]: 3255 : if (!ValidRow(nScRow))
159 : : return;
160 : :
161 [ + - ]: 3255 : SetHeight(nScRow, nHeight);
162 : :
163 : 3255 : sal_uInt8 nFlagVal = 0;
164 [ + - ][ + - ]: 3255 : if (!maRowFlags.search(nScRow, nFlagVal).second)
165 : : return;
166 : :
167 [ + + ]: 3255 : if (::get_flag(nFlags, EXC_ROW_UNSYNCED))
168 : 471 : ::set_flag(nFlagVal, EXC_COLROW_MAN);
169 : :
170 [ + - ]: 3255 : maRowFlags.insert_back(nScRow, nScRow+1, nFlagVal);
171 : :
172 [ + + ]: 3255 : if (::get_flag(nFlags, EXC_ROW_HIDDEN))
173 [ + - ]: 3255 : maHiddenRows.insert_back(nScRow, nScRow+1, true);
174 : : }
175 : :
176 : 15 : void XclImpColRowSettings::SetManualRowHeight( SCROW nScRow )
177 : : {
178 [ + - ]: 15 : if (!ValidRow(nScRow))
179 : : return;
180 : :
181 : 15 : sal_uInt8 nFlagVal = 0;
182 [ + - ][ + - ]: 15 : if (!maRowFlags.search(nScRow, nFlagVal).second)
183 : : return;
184 : :
185 : 15 : ::set_flag(nFlagVal, EXC_COLROW_MAN);
186 [ + - ]: 15 : maRowFlags.insert_back(nScRow, nScRow+1, nFlagVal);
187 : : }
188 : :
189 : 291 : void XclImpColRowSettings::SetDefaultXF( SCCOL nScCol1, SCCOL nScCol2, sal_uInt16 nXFIndex )
190 : : {
191 : : /* assign the default column formatting here to ensure that
192 : : explicit cell formatting is not overwritten. */
193 : : OSL_ENSURE( (nScCol1 <= nScCol2) && ValidCol( nScCol2 ), "XclImpColRowSettings::SetDefaultXF - invalid column index" );
194 : 291 : nScCol2 = ::std::min( nScCol2, MAXCOL );
195 : 291 : nScCol1 = ::std::min( nScCol1, nScCol2 );
196 : 291 : XclImpXFRangeBuffer& rXFRangeBuffer = GetXFRangeBuffer();
197 [ + + ]: 25041 : for( SCCOL nScCol = nScCol1; nScCol <= nScCol2; ++nScCol )
198 : 24750 : rXFRangeBuffer.SetColumnDefXF( nScCol, nXFIndex );
199 : 291 : }
200 : :
201 : 165 : void XclImpColRowSettings::Convert( SCTAB nScTab )
202 : : {
203 [ + - ]: 165 : if( !mbDirty )
204 : : return;
205 : :
206 : 165 : ScDocument& rDoc = GetDoc();
207 [ + - ]: 165 : rDoc.IncSizeRecalcLevel( nScTab );
208 : :
209 : : // column widths ----------------------------------------------------------
210 : :
211 [ + + ]: 169125 : for( SCCOL nScCol = 0; nScCol <= MAXCOL; ++nScCol )
212 : : {
213 [ + - ][ + + ]: 168960 : sal_uInt16 nWidth = ::get_flag( maColFlags[ nScCol ], EXC_COLROW_USED ) ? maWidths[ nScCol ] : mnDefWidth;
[ + - ]
214 : : /* Hidden columns: remember hidden state, but do not set hidden state
215 : : in document here. Needed for #i11776#, no HIDDEN flags in the
216 : : document, until filters and outlines are inserted. */
217 [ - + ]: 168960 : if( nWidth == 0 )
218 : : {
219 [ # # ]: 0 : ::set_flag( maColFlags[ nScCol ], EXC_COLROW_HIDDEN );
220 : 0 : nWidth = mnDefWidth;
221 : : }
222 [ + - ]: 168960 : rDoc.SetColWidthOnly( nScCol, nScTab, nWidth );
223 : : }
224 : :
225 : : // row heights ------------------------------------------------------------
226 : :
227 : : // #i54252# set default row height
228 [ + - ]: 165 : rDoc.SetRowHeightOnly( 0, MAXROW, nScTab, mnDefHeight );
229 [ + + ]: 165 : if( ::get_flag( mnDefRowFlags, EXC_DEFROW_UNSYNCED ) )
230 : : // first access to row flags, do not ask for old flags
231 [ + - ]: 24 : rDoc.SetRowFlags( 0, MAXROW, nScTab, CR_MANUALSIZE );
232 : :
233 [ + - ]: 165 : maRowHeights.build_tree();
234 [ + - ]: 165 : if (!maRowHeights.is_tree_valid())
235 : : return;
236 : :
237 [ + - ][ + - ]: 165 : RowFlagsType::const_iterator itrFlags = maRowFlags.begin(), itrFlagsEnd = maRowFlags.end();
238 : 165 : SCROW nPrevRow = -1;
239 : 165 : sal_uInt8 nPrevFlags = 0;
240 [ + - ][ + - ]: 655 : for (; itrFlags != itrFlagsEnd; ++itrFlags)
[ + + ]
241 : : {
242 [ + - ]: 490 : SCROW nRow = itrFlags->first;
243 [ + - ]: 490 : sal_uInt8 nFlags = itrFlags->second;
244 [ + + ]: 490 : if (nPrevRow >= 0)
245 : : {
246 : 325 : sal_uInt16 nHeight = 0;
247 : :
248 [ + + ]: 325 : if (::get_flag(nPrevFlags, EXC_COLROW_USED))
249 : : {
250 [ - + ]: 225 : if (::get_flag(nPrevFlags, EXC_COLROW_DEFAULT))
251 : : {
252 : 0 : nHeight = mnDefHeight;
253 [ # # ]: 0 : rDoc.SetRowHeightOnly(nPrevRow, nRow-1, nScTab, nHeight);
254 : : }
255 : : else
256 : : {
257 [ + + ]: 525 : for (SCROW i = nPrevRow; i <= nRow - 1; ++i)
258 : : {
259 : : SCROW nLast;
260 [ + - ][ + - ]: 300 : if (!maRowHeights.search_tree(i, nHeight, NULL, &nLast))
261 : : {
262 : : // search failed for some reason
263 : : return;
264 : : }
265 : :
266 [ + + ]: 300 : if (nLast > nRow)
267 : 6 : nLast = nRow;
268 : :
269 [ + - ]: 300 : rDoc.SetRowHeightOnly(i, nLast-1, nScTab, nHeight);
270 : 300 : i = nLast-1;
271 : : }
272 : : }
273 : :
274 [ + + ]: 225 : if (::get_flag(nPrevFlags, EXC_COLROW_MAN))
275 [ + - ]: 69 : rDoc.SetManualHeight(nPrevRow, nRow-1, nScTab, true);
276 : : }
277 : : else
278 : : {
279 : 100 : nHeight = mnDefHeight;
280 [ + - ]: 325 : rDoc.SetRowHeightOnly(nPrevRow, nRow-1, nScTab, nHeight);
281 : : }
282 : : }
283 : :
284 : 490 : nPrevRow = nRow;
285 : 490 : nPrevFlags = nFlags;
286 : : }
287 : :
288 : : // ------------------------------------------------------------------------
289 : :
290 : 165 : mbDirty = false;
291 [ + - ]: 165 : rDoc.DecSizeRecalcLevel( nScTab );
292 : : }
293 : :
294 : 165 : void XclImpColRowSettings::ConvertHiddenFlags( SCTAB nScTab )
295 : : {
296 : 165 : ScDocument& rDoc = GetDoc();
297 [ + - ]: 165 : rDoc.IncSizeRecalcLevel( nScTab ); // #i116460# performance with many hidden rows
298 : :
299 : : // hide the columns
300 [ + + ]: 169125 : for( SCCOL nScCol = 0; nScCol <= MAXCOL; ++nScCol )
301 [ + - ][ + + ]: 168960 : if( ::get_flag( maColFlags[ nScCol ], EXC_COLROW_HIDDEN ) )
302 [ + - ]: 3 : rDoc.ShowCol( nScCol, nScTab, false );
303 : :
304 : : // #i38093# rows hidden by filter need extra flag
305 : 165 : SCROW nFirstFilterScRow = SCROW_MAX;
306 : 165 : SCROW nLastFilterScRow = SCROW_MAX;
307 [ + - ]: 165 : if( GetBiff() == EXC_BIFF8 )
308 : : {
309 [ + - ][ + - ]: 165 : const XclImpAutoFilterData* pFilter = GetFilterManager().GetByTab( nScTab );
310 : : // #i70026# use IsFiltered() to set the CR_FILTERED flag for active filters only
311 [ + + ][ + - ]: 165 : if( pFilter && pFilter->IsActive() && pFilter->IsFiltered() )
[ + + ][ + + ]
312 : : {
313 : 15 : nFirstFilterScRow = pFilter->StartRow();
314 : 15 : nLastFilterScRow = pFilter->EndRow();
315 : : }
316 : : }
317 : :
318 : : // In case the excel row limit is lower than calc's, use the visibility of
319 : : // the last row and extend it to calc's last row.
320 : 165 : SCROW nLastXLRow = GetRoot().GetXclMaxPos().Row();
321 [ + - ]: 165 : if (nLastXLRow < MAXROW)
322 : : {
323 : 165 : bool bHidden = false;
324 [ + - ][ + - ]: 165 : if (!maHiddenRows.search(nLastXLRow, bHidden).second)
325 : 165 : return;
326 : :
327 [ + - ]: 165 : maHiddenRows.insert_back(nLastXLRow, MAXROWCOUNT, bHidden);
328 : : }
329 : :
330 : 165 : SCROW nPrevRow = -1;
331 : 165 : bool bPrevHidden = false;
332 [ + - ][ + - ]: 165 : RowHiddenType::const_iterator itr = maHiddenRows.begin(), itrEnd = maHiddenRows.end();
333 [ + - ][ + - ]: 486 : for (; itr != itrEnd; ++itr)
[ + + ]
334 : : {
335 [ + - ]: 321 : SCROW nRow = itr->first;
336 [ + - ]: 321 : bool bHidden = itr->second;
337 [ + + ]: 321 : if (nPrevRow >= 0)
338 : : {
339 [ + + ]: 156 : if (bPrevHidden)
340 : : {
341 [ + - ]: 78 : rDoc.SetRowHidden(nPrevRow, nRow-1, nScTab, true); // #i116460# SetRowHidden instead of ShowRow
342 : : // #i38093# rows hidden by filter need extra flag
343 [ + + ][ + - ]: 78 : if (nFirstFilterScRow <= nPrevRow && nPrevRow <= nLastFilterScRow)
344 : : {
345 [ + - ]: 75 : SCROW nLast = ::std::min(nRow-1, nLastFilterScRow);
346 [ + - ]: 75 : rDoc.SetRowFiltered(nPrevRow, nLast, nScTab, true);
347 : : }
348 : : }
349 : : }
350 : :
351 : 321 : nPrevRow = nRow;
352 : 321 : bPrevHidden = bHidden;
353 : : }
354 : :
355 : : // #i47438# if default row format is hidden, hide remaining rows
356 [ - + ][ # # ]: 165 : if( ::get_flag( mnDefRowFlags, EXC_DEFROW_HIDDEN ) && (mnLastScRow < MAXROW) )
[ - + ]
357 [ # # ]: 0 : rDoc.ShowRows( mnLastScRow + 1, MAXROW, nScTab, false );
358 : :
359 [ + - ]: 165 : rDoc.DecSizeRecalcLevel( nScTab ); // #i116460# performance with many hidden rows
360 [ + - ][ + - ]: 24 : }
361 : :
362 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|