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>
22 #include <document.hxx>
24 #include <xltable.hxx>
25 #include <xistyle.hxx>
26 #include <excimp8.hxx>
29 XclImpColRowSettings::XclImpColRowSettings( const XclImpRoot
& rRoot
) :
31 maColWidths(0, rRoot
.GetDoc().GetSheetLimits().GetMaxColCount(), 0),
32 maColFlags(0, rRoot
.GetDoc().GetSheetLimits().GetMaxColCount(), ExcColRowFlags::NONE
),
33 maRowHeights(0, rRoot
.GetDoc().GetSheetLimits().GetMaxRowCount(), 0),
34 maRowFlags(0, rRoot
.GetDoc().GetSheetLimits().GetMaxRowCount(), ExcColRowFlags::NONE
),
35 maHiddenRows(0, rRoot
.GetDoc().GetSheetLimits().GetMaxRowCount(), false),
37 mnDefWidth( STD_COL_WIDTH
),
38 mnDefHeight( ScGlobal::nStdRowHeight
),
39 mnDefRowFlags( EXC_DEFROW_DEFAULTFLAGS
),
40 mbHasStdWidthRec( false ),
41 mbHasDefHeight( false ),
46 XclImpColRowSettings::~XclImpColRowSettings()
50 void XclImpColRowSettings::SetDefWidth( sal_uInt16 nDefWidth
, bool bStdWidthRec
)
54 // STANDARDWIDTH record overrides DEFCOLWIDTH record
55 mnDefWidth
= nDefWidth
;
56 mbHasStdWidthRec
= true;
58 else if( !mbHasStdWidthRec
)
60 // use DEFCOLWIDTH record only, if no STANDARDWIDTH record exists
61 mnDefWidth
= nDefWidth
;
65 void XclImpColRowSettings::SetWidthRange( SCCOL nCol1
, SCCOL nCol2
, sal_uInt16 nWidth
)
67 ScDocument
& rDoc
= GetDoc();
68 nCol2
= ::std::min( nCol2
, rDoc
.MaxCol() );
70 // In BIFF8, the column range is 0-255, and the use of 256 probably
71 // means the range should extend to the max column if the loading app
72 // support columns beyond 255.
73 nCol2
= rDoc
.MaxCol();
75 nCol1
= ::std::min( nCol1
, nCol2
);
76 maColWidths
.insert_back(nCol1
, nCol2
+1, nWidth
);
78 // We need to apply flag values individually since all flag values are aggregated for each column.
79 for (SCCOL nCol
= nCol1
; nCol
<= nCol2
; ++nCol
)
80 ApplyColFlag(nCol
, ExcColRowFlags::Used
);
83 void XclImpColRowSettings::HideCol( SCCOL nCol
)
85 if (!GetDoc().ValidCol(nCol
))
88 ApplyColFlag(nCol
, ExcColRowFlags::Hidden
);
91 void XclImpColRowSettings::HideColRange( SCCOL nCol1
, SCCOL nCol2
)
93 nCol2
= ::std::min( nCol2
, GetDoc().MaxCol() );
94 nCol1
= ::std::min( nCol1
, nCol2
);
96 for (SCCOL nCol
= nCol1
; nCol
<= nCol2
; ++nCol
)
97 ApplyColFlag(nCol
, ExcColRowFlags::Hidden
);
100 void XclImpColRowSettings::SetDefHeight( sal_uInt16 nDefHeight
, sal_uInt16 nFlags
)
102 mnDefHeight
= nDefHeight
;
103 mnDefRowFlags
= nFlags
;
104 if( mnDefHeight
== 0 )
106 mnDefHeight
= ScGlobal::nStdRowHeight
;
107 ::set_flag( mnDefRowFlags
, EXC_DEFROW_HIDDEN
);
109 mbHasDefHeight
= true;
112 void XclImpColRowSettings::SetHeight( SCROW nScRow
, sal_uInt16 nHeight
)
114 if (!GetDoc().ValidRow(nScRow
))
117 sal_uInt16 nRawHeight
= nHeight
& EXC_ROW_HEIGHTMASK
;
118 bool bDefHeight
= ::get_flag( nHeight
, EXC_ROW_FLAGDEFHEIGHT
) || (nRawHeight
== 0);
119 maRowHeights
.insert_back(nScRow
, nScRow
+1, nRawHeight
);
120 ExcColRowFlags nFlagVal
= ExcColRowFlags::NONE
;
121 if (!maRowFlags
.search(nScRow
, nFlagVal
).second
)
124 ::set_flag(nFlagVal
, ExcColRowFlags::Used
);
125 ::set_flag(nFlagVal
, ExcColRowFlags::Default
, bDefHeight
);
127 maRowFlags
.insert_back(nScRow
, nScRow
+1, nFlagVal
);
129 if (nScRow
> mnLastScRow
)
130 mnLastScRow
= nScRow
;
133 void XclImpColRowSettings::SetRowSettings( SCROW nScRow
, sal_uInt16 nHeight
, sal_uInt16 nFlags
)
135 if (!GetDoc().ValidRow(nScRow
))
138 SetHeight(nScRow
, nHeight
);
140 ExcColRowFlags nFlagVal
= ExcColRowFlags::NONE
;
141 if (!maRowFlags
.search(nScRow
, nFlagVal
).second
)
144 if (::get_flag(nFlags
, EXC_ROW_UNSYNCED
))
145 ::set_flag(nFlagVal
, ExcColRowFlags::Man
);
147 maRowFlags
.insert_back(nScRow
, nScRow
+1, nFlagVal
);
149 if (::get_flag(nFlags
, EXC_ROW_HIDDEN
))
150 maHiddenRows
.insert_back(nScRow
, nScRow
+1, true);
153 void XclImpColRowSettings::SetManualRowHeight( SCROW nScRow
)
155 if (!GetDoc().ValidRow(nScRow
))
158 ExcColRowFlags nFlagVal
= ExcColRowFlags::NONE
;
159 if (!maRowFlags
.search(nScRow
, nFlagVal
).second
)
162 nFlagVal
|= ExcColRowFlags::Man
;
163 maRowFlags
.insert_back(nScRow
, nScRow
+1, nFlagVal
);
166 void XclImpColRowSettings::SetDefaultXF( SCCOL nCol1
, SCCOL nCol2
, sal_uInt16 nXFIndex
)
168 /* assign the default column formatting here to ensure that
169 explicit cell formatting is not overwritten. */
170 OSL_ENSURE( (nCol1
<= nCol2
) && GetDoc().ValidCol( nCol2
), "XclImpColRowSettings::SetDefaultXF - invalid column index" );
171 nCol2
= ::std::min( nCol2
, GetDoc().MaxCol() );
172 nCol1
= ::std::min( nCol1
, nCol2
);
173 XclImpXFRangeBuffer
& rXFRangeBuffer
= GetXFRangeBuffer();
174 for( SCCOL nCol
= nCol1
; nCol
<= nCol2
; ++nCol
)
175 rXFRangeBuffer
.SetColumnDefXF( nCol
, nXFIndex
);
178 void XclImpColRowSettings::Convert( SCTAB nScTab
)
183 ScDocument
& rDoc
= GetDoc();
185 // column widths ----------------------------------------------------------
187 maColWidths
.build_tree();
188 for (SCCOL nCol
= 0; nCol
<= rDoc
.MaxCol(); ++nCol
)
190 sal_uInt16 nWidth
= mnDefWidth
;
191 if (GetColFlag(nCol
, ExcColRowFlags::Used
))
194 if (maColWidths
.search_tree(nCol
, nTmp
).second
)
198 /* Hidden columns: remember hidden state, but do not set hidden state
199 in document here. Needed for #i11776#, no HIDDEN flags in the
200 document, until filters and outlines are inserted. */
203 ApplyColFlag(nCol
, ExcColRowFlags::Hidden
);
206 rDoc
.SetColWidthOnly( nCol
, nScTab
, nWidth
);
209 // row heights ------------------------------------------------------------
211 // #i54252# set default row height
212 rDoc
.SetRowHeightOnly( 0, rDoc
.MaxRow(), nScTab
, mnDefHeight
);
213 if( ::get_flag( mnDefRowFlags
, EXC_DEFROW_UNSYNCED
) )
214 // first access to row flags, do not ask for old flags
215 rDoc
.SetRowFlags( 0, rDoc
.MaxRow(), nScTab
, CRFlags::ManualSize
);
217 maRowHeights
.build_tree();
218 if (!maRowHeights
.is_tree_valid())
222 ExcColRowFlags nPrevFlags
= ExcColRowFlags::NONE
;
223 for (const auto& [nRow
, nFlags
] : maRowFlags
)
227 sal_uInt16 nHeight
= 0;
229 if (nPrevFlags
& ExcColRowFlags::Used
)
231 if (nPrevFlags
& ExcColRowFlags::Default
)
233 nHeight
= mnDefHeight
;
234 rDoc
.SetRowHeightOnly(nPrevRow
, nRow
-1, nScTab
, nHeight
);
238 for (SCROW i
= nPrevRow
; i
<= nRow
- 1; ++i
)
241 if (!maRowHeights
.search_tree(i
, nHeight
, nullptr, &nLast
).second
)
243 // search failed for some reason
250 rDoc
.SetRowHeightOnly(i
, nLast
-1, nScTab
, nHeight
);
255 if (nPrevFlags
& ExcColRowFlags::Man
)
256 rDoc
.SetManualHeight(nPrevRow
, nRow
-1, nScTab
, true);
260 nHeight
= mnDefHeight
;
261 rDoc
.SetRowHeightOnly(nPrevRow
, nRow
-1, nScTab
, nHeight
);
272 void XclImpColRowSettings::ConvertHiddenFlags( SCTAB nScTab
)
274 ScDocument
& rDoc
= GetDoc();
277 for( SCCOL nCol
: rDoc
.GetColumnsRange(nScTab
, 0, rDoc
.MaxCol()) )
278 if (GetColFlag(nCol
, ExcColRowFlags::Hidden
))
279 rDoc
.ShowCol( nCol
, nScTab
, false );
281 // #i38093# rows hidden by filter need extra flag
282 SCROW nFirstFilterScRow
= SCROW_MAX
;
283 SCROW nLastFilterScRow
= SCROW_MAX
;
284 if( GetBiff() == EXC_BIFF8
)
286 const XclImpAutoFilterData
* pFilter
= GetFilterManager().GetByTab( nScTab
);
287 // #i70026# use IsFiltered() to set the CRFlags::Filtered flag for active filters only
288 if( pFilter
&& pFilter
->IsActive() && pFilter
->IsFiltered() )
290 nFirstFilterScRow
= pFilter
->StartRow();
291 nLastFilterScRow
= pFilter
->EndRow();
295 // In case the excel row limit is lower than calc's, use the visibility of
296 // the last row and extend it to calc's last row.
297 SCROW nLastXLRow
= GetRoot().GetXclMaxPos().Row();
298 if (nLastXLRow
< rDoc
.MaxRow())
300 bool bHidden
= false;
301 if (!maHiddenRows
.search(nLastXLRow
, bHidden
).second
)
304 maHiddenRows
.insert_back(nLastXLRow
, GetDoc().GetSheetLimits().GetMaxRowCount(), bHidden
);
308 bool bPrevHidden
= false;
309 for (const auto& [nRow
, bHidden
] : maHiddenRows
)
315 rDoc
.SetRowHidden(nPrevRow
, nRow
-1, nScTab
, true);
316 // #i38093# rows hidden by filter need extra flag
317 if (nFirstFilterScRow
<= nPrevRow
&& nPrevRow
<= nLastFilterScRow
)
319 SCROW nLast
= ::std::min(nRow
-1, nLastFilterScRow
);
320 rDoc
.SetRowFiltered(nPrevRow
, nLast
, nScTab
, true);
326 bPrevHidden
= bHidden
;
329 // #i47438# if default row format is hidden, hide remaining rows
330 if( ::get_flag( mnDefRowFlags
, EXC_DEFROW_HIDDEN
) && (mnLastScRow
< rDoc
.MaxRow()) )
331 rDoc
.ShowRows( mnLastScRow
+ 1, rDoc
.MaxRow(), nScTab
, false );
334 void XclImpColRowSettings::ApplyColFlag(SCCOL nCol
, ExcColRowFlags nNewVal
)
336 // Get the original flag value.
337 ExcColRowFlags nFlagVal
= ExcColRowFlags::NONE
;
338 std::pair
<ColRowFlagsType::const_iterator
,bool> r
= maColFlags
.search(nCol
, nFlagVal
);
343 ::set_flag(nFlagVal
, nNewVal
);
345 // Re-insert the flag value.
346 maColFlags
.insert(r
.first
, nCol
, nCol
+1, nFlagVal
);
349 bool XclImpColRowSettings::GetColFlag(SCCOL nCol
, ExcColRowFlags nMask
) const
351 ExcColRowFlags nFlagVal
= ExcColRowFlags::NONE
;
352 if (!maColFlags
.search(nCol
, nFlagVal
).second
)
356 return bool(nFlagVal
& nMask
);
359 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */