1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include "colrowst.hxx"
24 #include "document.hxx"
27 #include "xltable.hxx"
28 #include "xistream.hxx"
29 #include "xistyle.hxx"
30 #include "queryparam.hxx"
31 #include "excimp8.hxx"
33 const sal_uInt8 EXC_COLROW_USED
= 0x01;
34 const sal_uInt8 EXC_COLROW_DEFAULT
= 0x02;
35 const sal_uInt8 EXC_COLROW_HIDDEN
= 0x04;
36 const sal_uInt8 EXC_COLROW_MAN
= 0x08;
38 XclImpColRowSettings::XclImpColRowSettings( const XclImpRoot
& rRoot
) :
40 maColWidths(0, MAXCOLCOUNT
, 0),
41 maColFlags(0, MAXCOLCOUNT
, 0),
42 maRowHeights(0, MAXROWCOUNT
, 0),
43 maRowFlags(0, MAXROWCOUNT
, 0),
44 maHiddenRows(0, MAXROWCOUNT
, false),
46 mnDefWidth( STD_COL_WIDTH
),
47 mnDefHeight( static_cast< sal_uInt16
>( ScGlobal::nStdRowHeight
) ),
48 mnDefRowFlags( EXC_DEFROW_DEFAULTFLAGS
),
49 mbHasStdWidthRec( false ),
50 mbHasDefHeight( false ),
55 XclImpColRowSettings::~XclImpColRowSettings()
59 void XclImpColRowSettings::SetDefWidth( sal_uInt16 nDefWidth
, bool bStdWidthRec
)
63 // STANDARDWIDTH record overrides DEFCOLWIDTH record
64 mnDefWidth
= nDefWidth
;
65 mbHasStdWidthRec
= true;
67 else if( !mbHasStdWidthRec
)
69 // use DEFCOLWIDTH record only, if no STANDARDWIDTH record exists
70 mnDefWidth
= nDefWidth
;
74 void XclImpColRowSettings::SetWidthRange( SCCOL nCol1
, SCCOL nCol2
, sal_uInt16 nWidth
)
76 nCol2
= ::std::min( nCol2
, MAXCOL
);
78 // In BIFF8, the column range is 0-255, and the use of 256 probably
79 // means the range should extend to the max column if the loading app
80 // support columns beyond 255.
83 nCol1
= ::std::min( nCol1
, nCol2
);
84 maColWidths
.insert_back(nCol1
, nCol2
+1, nWidth
);
86 // We need to apply flag values individually since all flag values are aggregated for each column.
87 for (SCCOL nCol
= nCol1
; nCol
<= nCol2
; ++nCol
)
88 ApplyColFlag(nCol
, EXC_COLROW_USED
);
91 void XclImpColRowSettings::HideCol( SCCOL nCol
)
96 ApplyColFlag(nCol
, EXC_COLROW_HIDDEN
);
99 void XclImpColRowSettings::HideColRange( SCCOL nCol1
, SCCOL nCol2
)
101 nCol2
= ::std::min( nCol2
, MAXCOL
);
102 nCol1
= ::std::min( nCol1
, nCol2
);
104 for (SCCOL nCol
= nCol1
; nCol
<= nCol2
; ++nCol
)
105 ApplyColFlag(nCol
, EXC_COLROW_HIDDEN
);
108 void XclImpColRowSettings::SetDefHeight( sal_uInt16 nDefHeight
, sal_uInt16 nFlags
)
110 mnDefHeight
= nDefHeight
;
111 mnDefRowFlags
= nFlags
;
112 if( mnDefHeight
== 0 )
114 mnDefHeight
= static_cast< sal_uInt16
>( ScGlobal::nStdRowHeight
);
115 ::set_flag( mnDefRowFlags
, EXC_DEFROW_HIDDEN
);
117 mbHasDefHeight
= true;
120 void XclImpColRowSettings::SetHeight( SCROW nScRow
, sal_uInt16 nHeight
)
122 if (!ValidRow(nScRow
))
125 sal_uInt16 nRawHeight
= nHeight
& EXC_ROW_HEIGHTMASK
;
126 bool bDefHeight
= ::get_flag( nHeight
, EXC_ROW_FLAGDEFHEIGHT
) || (nRawHeight
== 0);
127 maRowHeights
.insert_back(nScRow
, nScRow
+1, nRawHeight
);
128 sal_uInt8 nFlagVal
= 0;
129 if (!maRowFlags
.search(nScRow
, nFlagVal
).second
)
132 ::set_flag(nFlagVal
, EXC_COLROW_USED
);
133 ::set_flag(nFlagVal
, EXC_COLROW_DEFAULT
, bDefHeight
);
135 maRowFlags
.insert_back(nScRow
, nScRow
+1, nFlagVal
);
137 if (nScRow
> mnLastScRow
)
138 mnLastScRow
= nScRow
;
141 void XclImpColRowSettings::SetRowSettings( SCROW nScRow
, sal_uInt16 nHeight
, sal_uInt16 nFlags
)
143 if (!ValidRow(nScRow
))
146 SetHeight(nScRow
, nHeight
);
148 sal_uInt8 nFlagVal
= 0;
149 if (!maRowFlags
.search(nScRow
, nFlagVal
).second
)
152 if (::get_flag(nFlags
, EXC_ROW_UNSYNCED
))
153 ::set_flag(nFlagVal
, EXC_COLROW_MAN
);
155 maRowFlags
.insert_back(nScRow
, nScRow
+1, nFlagVal
);
157 if (::get_flag(nFlags
, EXC_ROW_HIDDEN
))
158 maHiddenRows
.insert_back(nScRow
, nScRow
+1, true);
161 void XclImpColRowSettings::SetManualRowHeight( SCROW nScRow
)
163 if (!ValidRow(nScRow
))
166 sal_uInt8 nFlagVal
= 0;
167 if (!maRowFlags
.search(nScRow
, nFlagVal
).second
)
170 ::set_flag(nFlagVal
, EXC_COLROW_MAN
);
171 maRowFlags
.insert_back(nScRow
, nScRow
+1, nFlagVal
);
174 void XclImpColRowSettings::SetDefaultXF( SCCOL nCol1
, SCCOL nCol2
, sal_uInt16 nXFIndex
)
176 /* assign the default column formatting here to ensure that
177 explicit cell formatting is not overwritten. */
178 OSL_ENSURE( (nCol1
<= nCol2
) && ValidCol( nCol2
), "XclImpColRowSettings::SetDefaultXF - invalid column index" );
179 nCol2
= ::std::min( nCol2
, MAXCOL
);
180 nCol1
= ::std::min( nCol1
, nCol2
);
181 XclImpXFRangeBuffer
& rXFRangeBuffer
= GetXFRangeBuffer();
182 for( SCCOL nCol
= nCol1
; nCol
<= nCol2
; ++nCol
)
183 rXFRangeBuffer
.SetColumnDefXF( nCol
, nXFIndex
);
186 void XclImpColRowSettings::Convert( SCTAB nScTab
)
191 ScDocument
& rDoc
= GetDoc();
193 // column widths ----------------------------------------------------------
195 maColWidths
.build_tree();
196 for( SCCOL nCol
= 0; nCol
<= MAXCOL
; ++nCol
)
198 sal_uInt16 nWidth
= mnDefWidth
;
199 if (GetColFlag(nCol
, EXC_COLROW_USED
))
202 if (maColWidths
.search_tree(nCol
, nTmp
).second
)
206 /* Hidden columns: remember hidden state, but do not set hidden state
207 in document here. Needed for #i11776#, no HIDDEN flags in the
208 document, until filters and outlines are inserted. */
211 ApplyColFlag(nCol
, EXC_COLROW_HIDDEN
);
214 rDoc
.SetColWidthOnly( nCol
, nScTab
, nWidth
);
217 // row heights ------------------------------------------------------------
219 // #i54252# set default row height
220 rDoc
.SetRowHeightOnly( 0, MAXROW
, nScTab
, mnDefHeight
);
221 if( ::get_flag( mnDefRowFlags
, EXC_DEFROW_UNSYNCED
) )
222 // first access to row flags, do not ask for old flags
223 rDoc
.SetRowFlags( 0, MAXROW
, nScTab
, CR_MANUALSIZE
);
225 maRowHeights
.build_tree();
226 if (!maRowHeights
.is_tree_valid())
229 ColRowFlagsType::const_iterator itrFlags
= maRowFlags
.begin(), itrFlagsEnd
= maRowFlags
.end();
231 sal_uInt8 nPrevFlags
= 0;
232 for (; itrFlags
!= itrFlagsEnd
; ++itrFlags
)
234 SCROW nRow
= itrFlags
->first
;
235 sal_uInt8 nFlags
= itrFlags
->second
;
238 sal_uInt16 nHeight
= 0;
240 if (::get_flag(nPrevFlags
, EXC_COLROW_USED
))
242 if (::get_flag(nPrevFlags
, EXC_COLROW_DEFAULT
))
244 nHeight
= mnDefHeight
;
245 rDoc
.SetRowHeightOnly(nPrevRow
, nRow
-1, nScTab
, nHeight
);
249 for (SCROW i
= nPrevRow
; i
<= nRow
- 1; ++i
)
252 if (!maRowHeights
.search_tree(i
, nHeight
, NULL
, &nLast
).second
)
254 // search failed for some reason
261 rDoc
.SetRowHeightOnly(i
, nLast
-1, nScTab
, nHeight
);
266 if (::get_flag(nPrevFlags
, EXC_COLROW_MAN
))
267 rDoc
.SetManualHeight(nPrevRow
, nRow
-1, nScTab
, true);
271 nHeight
= mnDefHeight
;
272 rDoc
.SetRowHeightOnly(nPrevRow
, nRow
-1, nScTab
, nHeight
);
283 void XclImpColRowSettings::ConvertHiddenFlags( SCTAB nScTab
)
285 ScDocument
& rDoc
= GetDoc();
288 for( SCCOL nCol
= 0; nCol
<= MAXCOL
; ++nCol
)
289 if (GetColFlag(nCol
, EXC_COLROW_HIDDEN
))
290 rDoc
.ShowCol( nCol
, nScTab
, false );
292 // #i38093# rows hidden by filter need extra flag
293 SCROW nFirstFilterScRow
= SCROW_MAX
;
294 SCROW nLastFilterScRow
= SCROW_MAX
;
295 if( GetBiff() == EXC_BIFF8
)
297 const XclImpAutoFilterData
* pFilter
= GetFilterManager().GetByTab( nScTab
);
298 // #i70026# use IsFiltered() to set the CR_FILTERED flag for active filters only
299 if( pFilter
&& pFilter
->IsActive() && pFilter
->IsFiltered() )
301 nFirstFilterScRow
= pFilter
->StartRow();
302 nLastFilterScRow
= pFilter
->EndRow();
306 // In case the excel row limit is lower than calc's, use the visibility of
307 // the last row and extend it to calc's last row.
308 SCROW nLastXLRow
= GetRoot().GetXclMaxPos().Row();
309 if (nLastXLRow
< MAXROW
)
311 bool bHidden
= false;
312 if (!maHiddenRows
.search(nLastXLRow
, bHidden
).second
)
315 maHiddenRows
.insert_back(nLastXLRow
, MAXROWCOUNT
, bHidden
);
319 bool bPrevHidden
= false;
320 RowHiddenType::const_iterator itr
= maHiddenRows
.begin(), itrEnd
= maHiddenRows
.end();
321 for (; itr
!= itrEnd
; ++itr
)
323 SCROW nRow
= itr
->first
;
324 bool bHidden
= itr
->second
;
329 rDoc
.SetRowHidden(nPrevRow
, nRow
-1, nScTab
, true);
330 // #i38093# rows hidden by filter need extra flag
331 if (nFirstFilterScRow
<= nPrevRow
&& nPrevRow
<= nLastFilterScRow
)
333 SCROW nLast
= ::std::min(nRow
-1, nLastFilterScRow
);
334 rDoc
.SetRowFiltered(nPrevRow
, nLast
, nScTab
, true);
340 bPrevHidden
= bHidden
;
343 // #i47438# if default row format is hidden, hide remaining rows
344 if( ::get_flag( mnDefRowFlags
, EXC_DEFROW_HIDDEN
) && (mnLastScRow
< MAXROW
) )
345 rDoc
.ShowRows( mnLastScRow
+ 1, MAXROW
, nScTab
, false );
348 void XclImpColRowSettings::ApplyColFlag(SCCOL nCol
, sal_uInt8 nNewVal
)
350 // Get the original flag value.
351 sal_uInt8 nFlagVal
= 0;
352 std::pair
<ColRowFlagsType::const_iterator
,bool> r
= maColFlags
.search(nCol
, nFlagVal
);
357 ::set_flag(nFlagVal
, nNewVal
);
359 // Re-insert the flag value.
360 maColFlags
.insert(r
.first
, nCol
, nCol
+1, nFlagVal
);
363 bool XclImpColRowSettings::GetColFlag(SCCOL nCol
, sal_uInt8 nMask
) const
365 sal_uInt8 nFlagVal
= 0;
366 if (!maColFlags
.search(nCol
, nFlagVal
).second
)
370 return ::get_flag(nFlagVal
, nMask
);
373 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */