| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_sc.hxx" |
| |
| |
| |
| #include "colrowst.hxx" |
| |
| #include <string.h> |
| |
| #include "document.hxx" |
| #include "root.hxx" |
| #include "ftools.hxx" |
| #include "xltable.hxx" |
| #include "xistream.hxx" |
| #include "xistyle.hxx" |
| #include "queryparam.hxx" |
| |
| // for filter manager |
| #include "excimp8.hxx" |
| |
| // ============================================================================ |
| |
| const sal_uInt8 EXC_COLROW_USED = 0x01; |
| const sal_uInt8 EXC_COLROW_DEFAULT = 0x02; |
| const sal_uInt8 EXC_COLROW_HIDDEN = 0x04; |
| const sal_uInt8 EXC_COLROW_MAN = 0x08; |
| |
| // ============================================================================ |
| |
| XclImpColRowSettings::XclImpColRowSettings( const XclImpRoot& rRoot ) : |
| XclImpRoot( rRoot ), |
| mnMaxCol( rRoot.GetXclMaxPos().Col() ), |
| mnMaxRow( rRoot.GetXclMaxPos().Row() ), |
| mnLastScRow( -1 ), |
| mnDefWidth( STD_COL_WIDTH ), |
| mnDefHeight( static_cast< sal_uInt16 >( STD_ROW_HEIGHT ) ), |
| mnDefRowFlags( EXC_DEFROW_DEFAULTFLAGS ), |
| mbHasStdWidthRec( false ), |
| mbHasDefHeight( false ), |
| mbDirty( true ) |
| { |
| maWidths.resize( static_cast< size_t >( mnMaxCol + 1 ), 0 ); |
| maColFlags.resize( static_cast< size_t >( mnMaxCol + 1 ), 0 ); |
| maHeights.resize( static_cast< size_t >( mnMaxRow + 1 ), 0 ); |
| maRowFlags.resize( static_cast< size_t >( mnMaxRow + 1 ), 0 ); |
| } |
| |
| XclImpColRowSettings::~XclImpColRowSettings() |
| { |
| } |
| |
| void XclImpColRowSettings::SetDefWidth( sal_uInt16 nDefWidth, bool bStdWidthRec ) |
| { |
| if( bStdWidthRec ) |
| { |
| // STANDARDWIDTH record overrides DEFCOLWIDTH record |
| mnDefWidth = nDefWidth; |
| mbHasStdWidthRec = true; |
| } |
| else if( !mbHasStdWidthRec ) |
| { |
| // use DEFCOLWIDTH record only, if no STANDARDWIDTH record exists |
| mnDefWidth = nDefWidth; |
| } |
| } |
| |
| void XclImpColRowSettings::SetWidthRange( SCCOL nScCol1, SCCOL nScCol2, sal_uInt16 nWidth ) |
| { |
| DBG_ASSERT( (0 <= nScCol1) && (nScCol1 <= nScCol2) && (nScCol2 <= mnMaxCol), |
| "XclImpColRowSettings::SetColWidthRange - invalid column range" ); |
| |
| nScCol2 = ::std::min( nScCol2, mnMaxCol ); |
| if( (0 <= nScCol1) && (nScCol1 <= nScCol2) ) |
| { |
| ::std::fill( maWidths.begin() + nScCol1, maWidths.begin() + nScCol2 + 1, nWidth ); |
| for( ScfUInt8Vec::iterator aIt = maColFlags.begin() + nScCol1, aEnd = maColFlags.begin() + nScCol2 + 1; aIt != aEnd; ++aIt ) |
| ::set_flag( *aIt, EXC_COLROW_USED ); |
| } |
| } |
| |
| void XclImpColRowSettings::HideCol( SCCOL nScCol ) |
| { |
| if( (0 <= nScCol) && (nScCol <= mnMaxCol) ) |
| ::set_flag( maColFlags[ nScCol ], EXC_COLROW_HIDDEN ); |
| } |
| |
| void XclImpColRowSettings::HideColRange( SCCOL nScCol1, SCCOL nScCol2 ) |
| { |
| DBG_ASSERT( (0 <= nScCol1) && (nScCol1 <= nScCol2) && (nScCol2 <= mnMaxCol), "XclImpColRowSettings::HideColRange - invalid column range" ); |
| nScCol2 = ::std::min( nScCol2, mnMaxCol ); |
| if( (0 <= nScCol1) && (nScCol1 <= nScCol2) ) |
| for( ScfUInt8Vec::iterator aIt = maColFlags.begin() + nScCol1, aEnd = maColFlags.begin() + nScCol2 + 1; aIt != aEnd; ++aIt ) |
| ::set_flag( *aIt, EXC_COLROW_HIDDEN ); |
| } |
| |
| void XclImpColRowSettings::SetDefHeight( sal_uInt16 nDefHeight, sal_uInt16 nFlags ) |
| { |
| mnDefHeight = nDefHeight; |
| mnDefRowFlags = nFlags; |
| if( mnDefHeight == 0 ) |
| { |
| mnDefHeight = static_cast< sal_uInt16 >( STD_ROW_HEIGHT ); |
| ::set_flag( mnDefRowFlags, EXC_DEFROW_HIDDEN ); |
| } |
| mbHasDefHeight = true; |
| } |
| |
| void XclImpColRowSettings::SetHeight( SCROW nScRow, sal_uInt16 nHeight ) |
| { |
| if( (0 <= nScRow) && (nScRow <= mnMaxRow) ) |
| { |
| sal_uInt16 nRawHeight = nHeight & EXC_ROW_HEIGHTMASK; |
| bool bDefHeight = ::get_flag( nHeight, EXC_ROW_FLAGDEFHEIGHT ) || (nRawHeight == 0); |
| maHeights[ nScRow ] = nRawHeight; |
| sal_uInt8& rnFlags = maRowFlags[ nScRow ]; |
| ::set_flag( rnFlags, EXC_COLROW_USED ); |
| if( !bDefHeight && (nRawHeight == 0) ) |
| ::set_flag( rnFlags, EXC_COLROW_HIDDEN ); |
| ::set_flag( rnFlags, EXC_COLROW_DEFAULT, bDefHeight ); |
| if( nScRow > mnLastScRow ) |
| mnLastScRow = nScRow; |
| } |
| } |
| |
| void XclImpColRowSettings::SetRowSettings( SCROW nScRow, sal_uInt16 nHeight, sal_uInt16 nFlags ) |
| { |
| if( (0 <= nScRow) && (nScRow <= mnMaxRow) ) |
| { |
| SetHeight( nScRow, nHeight ); |
| sal_uInt8& rnFlags = maRowFlags[ nScRow ]; |
| if( ::get_flag( nFlags, EXC_ROW_UNSYNCED ) ) |
| ::set_flag( rnFlags, EXC_COLROW_MAN ); |
| if( ::get_flag( nFlags, EXC_ROW_HIDDEN ) ) |
| ::set_flag( rnFlags, EXC_COLROW_HIDDEN ); |
| } |
| } |
| |
| void XclImpColRowSettings::SetManualRowHeight( SCROW nScRow ) |
| { |
| if( (0 <= nScRow) && (nScRow <= mnMaxRow) ) |
| ::set_flag( maRowFlags[ nScRow ], EXC_COLROW_MAN ); |
| } |
| |
| void XclImpColRowSettings::SetDefaultXF( SCCOL nScCol1, SCCOL nScCol2, sal_uInt16 nXFIndex ) |
| { |
| /* #109555# assign the default column formatting here to ensure that |
| explicit cell formatting is not overwritten. */ |
| DBG_ASSERT( (0 <= nScCol1) && (nScCol1 <= nScCol2) && (nScCol2 <= mnMaxCol), "XclImpColRowSettings::SetDefaultXF - invalid column index" ); |
| nScCol2 = ::std::min( nScCol2, mnMaxCol ); |
| if( (0 <= nScCol1) && (nScCol1 <= nScCol2) ) |
| { |
| XclImpXFRangeBuffer& rXFRangeBuffer = GetXFRangeBuffer(); |
| for( SCCOL nScCol = nScCol1; nScCol <= nScCol2; ++nScCol ) |
| rXFRangeBuffer.SetColumnDefXF( nScCol, nXFIndex ); |
| } |
| } |
| |
| void XclImpColRowSettings::Convert( SCTAB nScTab ) |
| { |
| if( !mbDirty ) |
| return; |
| |
| ScDocument& rDoc = GetDoc(); |
| rDoc.IncSizeRecalcLevel( nScTab ); |
| |
| // column widths ---------------------------------------------------------- |
| |
| for( SCCOL nScCol = 0; nScCol <= mnMaxCol; ++nScCol ) |
| { |
| sal_uInt16 nWidth = ::get_flag( maColFlags[ nScCol ], EXC_COLROW_USED ) ? maWidths[ nScCol ] : mnDefWidth; |
| /* Hidden columns: remember hidden state, but do not set hidden state |
| in document here. Needed for #i11776#, no HIDDEN flags in the |
| document, until filters and outlines are inserted. */ |
| if( nWidth == 0 ) |
| { |
| ::set_flag( maColFlags[ nScCol ], EXC_COLROW_HIDDEN ); |
| nWidth = mnDefWidth; |
| } |
| rDoc.SetColWidthOnly( nScCol, nScTab, nWidth ); |
| } |
| |
| // row heights ------------------------------------------------------------ |
| |
| // #i54252# set default row height |
| rDoc.SetRowHeightOnly( 0, MAXROW, nScTab, mnDefHeight ); |
| if( ::get_flag( mnDefRowFlags, EXC_DEFROW_UNSYNCED ) ) |
| // first access to row flags, do not ask for old flags |
| rDoc.SetRowFlags( 0, MAXROW, nScTab, CR_MANUALSIZE ); |
| bool bDefHideRow = ::get_flag( mnDefRowFlags, EXC_DEFROW_HIDDEN ); |
| |
| SCROW nFirstScRow = -1; |
| sal_uInt16 nLastHeight = 0; |
| for( SCROW nScRow = 0; nScRow <= mnLastScRow ; ++nScRow ) |
| { |
| // get height and hidden state from cached data |
| sal_uInt8 nFlags = maRowFlags[ nScRow ]; |
| sal_uInt16 nHeight = 0; |
| bool bHideRow = false; |
| if( ::get_flag( nFlags, EXC_COLROW_USED ) ) |
| { |
| if( ::get_flag( nFlags, EXC_COLROW_DEFAULT ) ) |
| { |
| nHeight = mnDefHeight; |
| bHideRow = bDefHideRow; |
| } |
| else |
| { |
| nHeight = maHeights[ nScRow ]; |
| if( nHeight == 0 ) |
| { |
| nHeight = mnDefHeight; |
| bHideRow = true; |
| } |
| } |
| |
| if( ::get_flag( nFlags, EXC_COLROW_MAN ) ) |
| rDoc.SetRowFlags( nScRow, nScTab, rDoc.GetRowFlags( nScRow, nScTab ) | CR_MANUALSIZE ); |
| } |
| else |
| { |
| nHeight = mnDefHeight; |
| bHideRow = bDefHideRow; |
| } |
| |
| /* Hidden rows: remember hidden state, but do not set hidden state in |
| document here. Needed for #i11776#, no HIDDEN flags in the document, |
| until filters and outlines are inserted. */ |
| if( bHideRow ) |
| ::set_flag( maRowFlags[ nScRow ], EXC_COLROW_HIDDEN ); |
| |
| // set height range |
| if( (nLastHeight != nHeight) || (nScRow == 0) ) |
| { |
| DBG_ASSERT( (nScRow == 0) || (nFirstScRow >= 0), "XclImpColRowSettings::Convert - algorithm error" ); |
| if( nScRow > 0 ) |
| rDoc.SetRowHeightOnly( nFirstScRow, nScRow - 1, nScTab, nLastHeight ); |
| |
| nFirstScRow = nScRow; |
| nLastHeight = nHeight; |
| } |
| } |
| |
| // set row height of last portion |
| if( mnLastScRow >= 0 ) |
| rDoc.SetRowHeightOnly( nFirstScRow, mnLastScRow, nScTab, nLastHeight ); |
| |
| // ------------------------------------------------------------------------ |
| |
| mbDirty = false; |
| rDoc.DecSizeRecalcLevel( nScTab ); |
| } |
| |
| void XclImpColRowSettings::ConvertHiddenFlags( SCTAB nScTab ) |
| { |
| ScDocument& rDoc = GetDoc(); |
| rDoc.IncSizeRecalcLevel( nScTab ); // #i116460# performance with many hidden rows |
| |
| // hide the columns |
| for( SCCOL nScCol = 0; nScCol <= mnMaxCol; ++nScCol ) |
| if( ::get_flag( maColFlags[ nScCol ], EXC_COLROW_HIDDEN ) ) |
| rDoc.SetColHidden( nScCol, nScCol, nScTab, sal_True ); |
| |
| // hide remaining columns outside Excel's sheet limits |
| if( ::get_flag( maColFlags[ mnMaxCol ], EXC_COLROW_HIDDEN ) && (mnMaxCol < MAXCOL) ) |
| rDoc.SetColHidden( mnMaxCol + 1, MAXCOL, nScTab, sal_True ); |
| |
| // #i38093# rows hidden by filter need extra flag |
| SCROW nFirstFilterScRow = SCROW_MAX; |
| SCROW nLastFilterScRow = SCROW_MAX; |
| if( GetBiff() == EXC_BIFF8 ) |
| { |
| const XclImpAutoFilterData* pFilter = GetFilterManager().GetByTab( nScTab ); |
| // #i70026# use IsFiltered() to set the CR_FILTERED flag for active filters only |
| if( pFilter && pFilter->IsActive() && pFilter->IsFiltered() ) |
| { |
| nFirstFilterScRow = pFilter->StartRow(); |
| nLastFilterScRow = pFilter->EndRow(); |
| } |
| } |
| |
| // hide the rows |
| for( SCROW nScRow = 0; nScRow <= mnLastScRow; ++nScRow ) |
| { |
| if( ::get_flag( maRowFlags[ nScRow ], EXC_COLROW_HIDDEN ) ) |
| { |
| // hide the row |
| rDoc.SetRowHidden(nScRow, nScRow, nScTab, true); // #i116460# SetRowHidden instead of ShowRow |
| // #i38093# rows hidden by filter need extra flag |
| if( (nFirstFilterScRow <= nScRow) && (nScRow <= nLastFilterScRow) ) |
| rDoc.SetRowFiltered(nScRow, nScRow, nScTab, true); |
| } |
| } |
| |
| // #i47438# if default row format is hidden, hide remaining rows |
| if( ::get_flag( mnDefRowFlags, EXC_DEFROW_HIDDEN ) && (mnLastScRow < MAXROW) ) |
| rDoc.ShowRows( mnLastScRow + 1, MAXROW, nScTab, sal_False ); |
| |
| rDoc.DecSizeRecalcLevel( nScTab ); // #i116460# performance with many hidden rows |
| } |
| |