In summary the import filters seem to calculate the shape positions incorrectly, the further down the document the shape is, the more incorrect the position can be. In the case of the xlsx filter it seems the row height adjustment that is made at the end of the import makes a difference but additionally non-uniform row heights, document content and zoom factor all seem to affect the position error. Worryingly there seems to be a rather bizarre effect present even in 'normal' calc documents where depending on the document content we can find that the desired anchor position of a shape and the actual position it is drawn at are skewed. There seems to be some issue with how the drawing layer and the grid/view part calculate positions :/ they just don't agree. ( see attachments - note the actual cell anchoring position is indicated by the cell bordered in red ). This effect of course also has a bearing on the filter(s) because they also get the same error when attempting to calculate the position of the shape. The patch attempts to address this by an inglorious hack ( that works well ) where when the shapes ( which have an anchor ) are imported we save the anchor position by actually making the shapes cell anchored, then at the end of the import ( and after any strange resizing of rows or other things that may happen on import to affect things ) we remove the cell anchoring, recalculate the shape position ( but recalculate it the way the grid/view does ) and position the shapes absolutely. Ideally we would of course like to just keep the shapes cell anchored ( where appropriate ) but because of the pre-existing potential anchor skew this just isn't feasible.
Eike I cc you here as maybe you can shed some light on this weirdness ( I confess it confuses the hell out me ) otoh I think this patch is safe, it also addresses another issue ( see details in bug ) where sometimes ( like in the attached test document ) the shape size is imported incorrectly and the shape may not be visible.
Note: for the xlsx import ole controls are not 'corrected' I need to a little more effort to make that work ( binary import though handles them fine ) I will send a follow up patch for that.
thanks Noel
Attachment:
SkewedAnchor-3.5.png
Description: PNG image
Attachment:
anotheranchorskew.ods
Description: application/vnd.oasis.opendocument.spreadsheet
From 48f58ecee5362100f7071eb5ba556fd8e5c6874d Mon Sep 17 00:00:00 2001 From: Noel Power <noel.power@novell.com> Date: Fri, 4 May 2012 10:03:15 +0100 Subject: [PATCH 2/2] tweak imported shape position for xls( binary ) format fdo#49430 --- sc/source/filter/excel/read.cxx | 9 +++++++++ sc/source/filter/excel/xiescher.cxx | 22 ++++++++++++++++++++++ 2 files changed, 31 insertions(+), 0 deletions(-) diff --git a/sc/source/filter/excel/read.cxx b/sc/source/filter/excel/read.cxx index 4f0ce42e..179af68 100644 --- a/sc/source/filter/excel/read.cxx +++ b/sc/source/filter/excel/read.cxx @@ -52,6 +52,7 @@ #include "root.hxx" #include "imp_op.hxx" #include "excimp8.hxx" +#include <sfx2/objsh.hxx> FltError ImportExcel::Read( void ) { @@ -1309,6 +1310,14 @@ FltError ImportExcel8::Read( void ) PostDocLoad(); pD->CalcAfterLoad(); + SfxObjectShell* pDocShell = GetDocShell(); + + if ( pDocShell ) + { + std::vector< OrientationInfo > savedOrientations; + ScGlobal::CaptureShapeOrientationInfo( savedOrientations, pDocShell->GetModel() ); + ScGlobal::ApplyShapeOrientationInfo( savedOrientations, pDocShell->GetModel(), *pD ); + } // import change tracking data XclImpChangeTrack aImpChTr( GetRoot(), maStrm ); diff --git a/sc/source/filter/excel/xiescher.cxx b/sc/source/filter/excel/xiescher.cxx index f6fda06..f440b05b 100644 --- a/sc/source/filter/excel/xiescher.cxx +++ b/sc/source/filter/excel/xiescher.cxx @@ -497,6 +497,28 @@ void XclImpDrawObjBase::PreProcessSdrObject( XclImpDffConverter& rDffConv, SdrOb } } + if ( GetAnchor() ) + { + ScDrawObjData* pAnchor = ScDrawLayer::GetObjData( &rSdrObj, sal_True); + if ( pAnchor ) + { + // Temporarily get start position of shape. + // At the end of the import we do some post processing + // to adjust the shape position to take into account + // errors between the drawing layer and the view/grid + pAnchor->maStart.SetRow( GetAnchor()->maFirst.mnRow ); + pAnchor->maStart.SetCol( GetAnchor()->maFirst.mnCol ); + pAnchor->maStart.SetTab( GetTab() ); + XclObjAnchor tmpAnchor( *GetAnchor() ); + + // Calculate the start offset ( from the cell postion ) + Rectangle withOffset = tmpAnchor.GetRect( GetRoot(), GetTab(), MAP_100TH_MM ); + tmpAnchor.mnLX = tmpAnchor.mnTY = tmpAnchor.mnRX = tmpAnchor.mnBY = 0; + Rectangle noOffset = tmpAnchor.GetRect( GetRoot(), GetTab(), MAP_100TH_MM ); + pAnchor->maStartOffset.X() = withOffset.Left() - noOffset.Left(); + pAnchor->maStartOffset.Y() = withOffset.Top() - noOffset.Top(); + } + } // call virtual function for object type specific processing DoPreProcessSdrObj( rDffConv, rSdrObj ); } -- 1.7.3.4
From e01d256f02dd60bef28b11a5b80ffc08f280f7ac Mon Sep 17 00:00:00 2001 From: Noel Power <noel.power@novell.com> Date: Fri, 4 May 2012 09:48:27 +0100 Subject: [PATCH 1/2] fix bad import positions of shapes & controls fdo#49430 --- oox/inc/oox/xls/drawingbase.hxx | 10 ++- oox/source/token/properties.txt | 3 + oox/source/xls/drawingbase.cxx | 40 ++++++++++ oox/source/xls/drawingfragment.cxx | 9 ++- sc/inc/global.hxx | 19 +++++ sc/source/core/data/global.cxx | 147 +++++++++++++++++++++++++++++++++++- sc/source/ui/unoobj/docuno.cxx | 17 ++++ sc/source/ui/view/viewdata.cxx | 7 +- 8 files changed, 246 insertions(+), 6 deletions(-) diff --git a/oox/inc/oox/xls/drawingbase.hxx b/oox/inc/oox/xls/drawingbase.hxx index c79eb7a..95fae46 100644 --- a/oox/inc/oox/xls/drawingbase.hxx +++ b/oox/inc/oox/xls/drawingbase.hxx @@ -32,6 +32,9 @@ #include "oox/drawingml/drawingmltypes.hxx" #include "oox/xls/worksheethelper.hxx" +#include <com/sun/star/drawing/XShape.hpp> +#include <com/sun/star/table/XCell.hpp> + namespace oox { namespace xls { @@ -108,7 +111,12 @@ public: /** Calculates the resulting shape anchor in 1/100 mm. */ ::com::sun::star::awt::Rectangle calcAnchorRectHmm( const ::com::sun::star::awt::Size& rPageSizeHmm ) const; - + /** Returns the 'to' cell if it exists */ + ::com::sun::star::uno::Reference< ::com::sun::star::table::XCell > getToCell() const; + /** Returns the 'from' cell if it exists */ + ::com::sun::star::uno::Reference< ::com::sun::star::table::XCell > getFromCell() const; + /** Applies Cell Anchor to an XShape if needed*/ + void applyToXShape( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape>& rxShape ); private: /** Converts the passed anchor to an absolute position in EMUs. */ ::oox::drawingml::EmuPoint calcCellAnchorEmu( const CellAnchorModel& rModel ) const; diff --git a/oox/source/token/properties.txt b/oox/source/token/properties.txt index 9127c38..176ae08 100644 --- a/oox/source/token/properties.txt +++ b/oox/source/token/properties.txt @@ -9,6 +9,7 @@ AdjustLuminance AdjustmentValues Address Align +Anchor AnchorPosition ApplyFormDesignMode AreaLinks @@ -217,6 +218,7 @@ HelpText HideInactiveSelection HoriJustify HoriJustifyMethod +HoriOrientPosition HorizontalSplitMode HorizontalSplitPositionTwips IgnoreBlankCells @@ -495,6 +497,7 @@ VertJustifyMethod VerticalAlign VerticalSplitMode VerticalSplitPositionTwips +VertOrientPosition ViewBox Visible VisibleFlag diff --git a/oox/source/xls/drawingbase.cxx b/oox/source/xls/drawingbase.cxx index 3369ba9..e740c39 100644 --- a/oox/source/xls/drawingbase.cxx +++ b/oox/source/xls/drawingbase.cxx @@ -32,6 +32,7 @@ #include "oox/helper/attributelist.hxx" #include "oox/helper/binaryinputstream.hxx" #include "oox/xls/unitconverter.hxx" +#include "oox/helper/propertyset.hxx" namespace oox { namespace xls { @@ -170,6 +171,7 @@ void ShapeAnchor::setCellPos( sal_Int32 nElement, sal_Int32 nParentContext, cons void ShapeAnchor::importVmlAnchor( const OUString& rAnchor ) { meAnchorType = ANCHOR_VML; + meCellAnchorType = CELLANCHOR_PIXEL; ::std::vector< OUString > aTokens; sal_Int32 nIndex = 0; @@ -281,6 +283,44 @@ Rectangle ShapeAnchor::calcAnchorRectHmm( const Size& rPageSizeHmm ) const return Rectangle( lclEmuToHmm( aAnchorRect.X ), lclEmuToHmm( aAnchorRect.Y ), lclEmuToHmm( aAnchorRect.Width ), lclEmuToHmm( aAnchorRect.Height ) ); } +::com::sun::star::uno::Reference< ::com::sun::star::table::XCell > +ShapeAnchor::getToCell() const +{ + CellAddress aAddress; + aAddress.Sheet = getSheetIndex(); + aAddress.Row = maTo.mnRow; + aAddress.Column = maTo.mnCol; + return getCell( aAddress ); +} +::com::sun::star::uno::Reference< ::com::sun::star::table::XCell > +ShapeAnchor::getFromCell() const +{ + CellAddress aAddress; + aAddress.Sheet = getSheetIndex(); + aAddress.Row = maFrom.mnRow; + aAddress.Column = maFrom.mnCol; + return getCell( aAddress ); +} + +void +ShapeAnchor::applyToXShape( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape>& rxShape ) +{ + if ( ( meAnchorType == ANCHOR_VML || meAnchorType == ANCHOR_TWOCELL || meAnchorType == ANCHOR_ONECELL ) && getFromCell().is() ) + { + PropertySet aShapeProp( rxShape ); + CellAnchorModel offSets; + offSets.mnColOffset = maFrom.mnColOffset; + offSets.mnRowOffset = maFrom.mnRowOffset; + EmuPoint aPos = calcCellAnchorEmu( offSets ); + + Point aZeroZero; + rxShape->setPosition( aZeroZero ); + aShapeProp.setProperty( PROP_HoriOrientPosition, lclEmuToHmm( aPos.X ) ); + aShapeProp.setProperty( PROP_VertOrientPosition, lclEmuToHmm( aPos.Y ) ); + aShapeProp.setProperty( PROP_Anchor, getFromCell() ); + } +} + // private -------------------------------------------------------------------- EmuPoint ShapeAnchor::calcCellAnchorEmu( const CellAnchorModel& rModel ) const diff --git a/oox/source/xls/drawingfragment.cxx b/oox/source/xls/drawingfragment.cxx index 64f0164..5cd6d2b 100644 --- a/oox/source/xls/drawingfragment.cxx +++ b/oox/source/xls/drawingfragment.cxx @@ -290,7 +290,8 @@ void DrawingFragment::onEndElement() basegfx::B2DHomMatrix aTransformation; mxShape->addShape( getOoxFilter(), &getTheme(), mxDrawPage, aTransformation, &aShapeRectEmu32 ); - + // apply Cell anchoring if necessary + mxAnchor->applyToXShape( mxShape->getXShape() ); /* Collect all shape positions in the WorksheetHelper base class. But first, scale EMUs to 1/100 mm. */ Rectangle aShapeRectHmm( @@ -631,6 +632,12 @@ Reference< XShape > VmlDrawing::createAndInsertClientXShape( const ::oox::vml::S } } + if ( pClientData->maAnchor.getLength() ) + { + ShapeAnchor aAnchor( *this ); + aAnchor.importVmlAnchor( pClientData->maAnchor ); + aAnchor.applyToXShape( xShape ); + } return xShape; } } diff --git a/sc/inc/global.hxx b/sc/inc/global.hxx index ac10094..c431598 100644 --- a/sc/inc/global.hxx +++ b/sc/inc/global.hxx @@ -34,9 +34,11 @@ #include <tools/stream.hxx> #include <osl/endian.h> #include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/table/CellAddress.hpp> #include "scdllapi.h" #include <boost/unordered_map.hpp> +#include <vector> class ImageList; class Bitmap; @@ -497,12 +499,27 @@ namespace com { namespace sun { namespace star { namespace i18n { class XOrdinalSuffix; } + namespace frame { + class XModel; + } + namespace drawing { + class XShape; + } }}} namespace utl { class TransliterationWrapper; } #ifndef _SCALC_EXE +struct SC_DLLPUBLIC OrientationInfo +{ + OrientationInfo() : mnVert( 0 ), mnHori( 0 ) {} + ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > mxShape; + ::com::sun::star::table::CellAddress maAddress; + sal_Int32 mnVert; + sal_Int32 mnHori; +}; + class ScGlobal { static SvxSearchItem* pSearchItem; @@ -695,6 +712,8 @@ SC_DLLPUBLIC static const sal_Unicode* FindUnquoted( const sal_Unicode* pStri /** Obtain the ordinal suffix for a number according to the system locale */ static String GetOrdinalSuffix( sal_Int32 nNumber); + SC_DLLPUBLIC static void CaptureShapeOrientationInfo( std::vector< OrientationInfo >& infos, const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& rxModel ); + SC_DLLPUBLIC static void ApplyShapeOrientationInfo( std::vector< OrientationInfo >& infos, const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& rxModel, ScDocument& rDoc ); }; #endif diff --git a/sc/source/core/data/global.cxx b/sc/source/core/data/global.cxx index c43a853..a5a9c0e 100644 --- a/sc/source/core/data/global.cxx +++ b/sc/source/core/data/global.cxx @@ -63,6 +63,15 @@ #include <unotools/calendarwrapper.hxx> #include <unotools/collatorwrapper.hxx> #include <com/sun/star/i18n/CollatorOptions.hpp> +#include <com/sun/star/frame/XModel.hpp> +#include <com/sun/star/drawing/XDrawPagesSupplier.hpp> +#include <com/sun/star/document/XViewDataSupplier.hpp> +#include <com/sun/star/container/XIndexAccess.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/table/XCell.hpp> +#include <com/sun/star/sheet/XSpreadsheet.hpp> +#include <com/sun/star/sheet/XSpreadsheetDocument.hpp> +#include <com/sun/star/sheet/XCellAddressable.hpp> #include <unotools/intlwrapper.hxx> #include <unotools/syslocale.hxx> #include <unotools/transliterationwrapper.hxx> @@ -87,11 +96,15 @@ #include "sc.hrc" #include "scmod.hxx" #include "appoptio.hxx" - +#include "unonames.hxx" +#include "drawview.hxx" +#include "drawutil.hxx" +#include "viewdata.hxx" // ----------------------------------------------------------------------- using ::rtl::OUString; using ::rtl::OUStringBuffer; +using namespace ::com::sun::star; #define CLIPST_AVAILABLE 0 #define CLIPST_CAPTURED 1 @@ -1180,5 +1193,137 @@ IntlWrapper* ScGlobal::GetScIntlWrapper() } return pLocale; } +void ScGlobal::CaptureShapeOrientationInfo( std::vector< OrientationInfo >& infos, const uno::Reference<frame::XModel >& rxModel ) +{ + rtl::OUString sHori( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_HORIPOS ) ); + rtl::OUString sVert( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_VERTPOS ) ); + uno::Reference<drawing::XDrawPagesSupplier> xDrwSupp( rxModel, uno::UNO_QUERY ); + uno::Reference<container::XIndexAccess> xPages( xDrwSupp.is() ? xDrwSupp->getDrawPages() : NULL, uno::UNO_QUERY ); + if ( xPages.is() ) + { + for ( sal_Int32 nIndex = 0, nPages = xPages->getCount(); nIndex < nPages; ++nIndex ) + { + uno::Reference<container::XIndexAccess> xShapes( xPages->getByIndex( nIndex ), uno::UNO_QUERY ); + for ( sal_Int32 nShapeIndex = 0, nShapes = xShapes->getCount(); nShapeIndex < nShapes; ++nShapeIndex ) + { + uno::Reference< beans::XPropertySet > xShape( xShapes->getByIndex( nShapeIndex ), uno::UNO_QUERY ); + uno::Reference< table::XCell > xCell( xShape->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_ANCHOR ) ) ), uno::UNO_QUERY ); + uno::Reference< sheet::XSpreadsheetDocument > xSpreadSheet( rxModel, uno::UNO_QUERY ); + uno::Reference< container::XIndexAccess > xSheets( xSpreadSheet.is() ? xSpreadSheet->getSheets() : NULL, uno::UNO_QUERY ); + uno::Reference< sheet::XSpreadsheet > xSheet; + uno::Reference< sheet::XCellAddressable > xAddressable( xCell, uno::UNO_QUERY ); + if ( xSheets.is() && xAddressable.is() && xSpreadSheet.is() ) + xSheet.set( xSheets->getByIndex( xAddressable->getCellAddress().Sheet ), uno::UNO_QUERY ); + // only capture orientation if the shape is anchored to cell + if ( xShape.is() && xCell.is() && xAddressable.is() && xSheet.is() ) + { + uno::Reference< beans::XPropertySetInfo > xShapePropInfo = xShape->getPropertySetInfo(); + if ( xShapePropInfo.is() && xShapePropInfo->hasPropertyByName( sHori ) && xShapePropInfo->hasPropertyByName( sVert ) ) + { + OrientationInfo aShape; + aShape.mxShape.set( xShape, uno::UNO_QUERY ); + xShape->getPropertyValue( sHori ) >>= aShape.mnHori; + xShape->getPropertyValue( sVert ) >>= aShape.mnVert; + aShape.maAddress = xAddressable->getCellAddress(); + infos.push_back( aShape ); + // Remove temporary cell anchor. Ideally we should + // preserve the cell anchoring but the drawing layer + // and the ScGridWindow don't calcuate positions in the + // same way. This means unfortunately ( especially if + // row heights above the shape are not uniform ) that + // the shape anchor position and the shape position + // can be quite skewed. The only alterative + // unfortunately is to position the shape absolutely + // rather than relative to a cell address :-( + xShape->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_ANCHOR ) ), uno::makeAny( xSheet ) ); + } + } + } + } + } +} + +// Note: this method is only expected to be called when importing an alien +// document. +void ScGlobal::ApplyShapeOrientationInfo( std::vector< OrientationInfo >& infos, const uno::Reference< frame::XModel >& rxModel, ScDocument& rDoc ) +{ + // For each shape previously anchored to a cell calculate the shape + // position ( as the view would ) based on the available zoom and scaling. + // This prevents the shape being being drawn in an unexpected postion due to + // a) differences in the calculation of shape position by drawinglayer and + // the postion of the actual rows drawn by ScGridwin + // b) affect of UpdateAllRowHeights + for ( std::vector< OrientationInfo >::iterator it = infos.begin(), it_end = infos.end(); it != it_end; ++it ) + { + OutputDevice* pDevice = Application::GetDefaultDevice(); + if ( pDevice ) + { + uno::Reference< document::XViewDataSupplier > xViewSup( rxModel, uno::UNO_QUERY ); + uno::Reference< container::XIndexAccess > xIndexAccess; + if ( xViewSup.is() ) + xIndexAccess = xViewSup->getViewData(); + uno::Sequence< beans::PropertyValue > aSeq; + // set up partial view data to calculate zoom, pptx & ppty values + ScViewData aViewData( NULL, NULL ); + aViewData.InitData( &rDoc ); + // support initialising view data from binary import + if ( ScExtDocOptions* pDocOptions = rDoc.GetExtDocOptions() ) + { + aViewData.ReadExtOptions( *pDocOptions ); + } + else // or from the view data from the model ( oox import ) + { + if ( xIndexAccess.is() && xIndexAccess->getCount() ) + xIndexAccess->getByIndex(0) >>= aSeq; + aViewData.ReadUserDataSequence( aSeq ); + } + + aViewData.SetTabNo( it->maAddress.Sheet ); + + long nHeight = 0; + long nWidth = 0; + + MapMode aTmpMode( MAP_TWIP ); + // get postion of shape based on the start anchor + for ( int i = 0; i < it->maAddress.Column; ++i ) + { + long nTwip = aViewData.GetDocument()->GetColWidth( i, it->maAddress.Sheet ); + nWidth += ( nTwip * aViewData.GetPPTX() ); + } + for ( int i = 0; i < it->maAddress.Row; ++i ) + { + long nTwip = aViewData.GetDocument()->GetRowHeight( i, it->maAddress.Sheet ); + nHeight += ( nTwip * aViewData.GetPPTY() ); + } + + // determine the scale that will be used by the view + Fraction aScaleX; + Fraction aScaleY; + SCROW nEndRow = it->maAddress.Row; + SCCOL nEndCol = it->maAddress.Column; + aViewData.GetDocument()->GetTableArea( aViewData.GetTabNo(), nEndCol, nEndRow ); + if (nEndCol<20) + nEndCol = 20; + if (nEndRow<20) + nEndRow = 20; + + ScDrawUtil::CalcScale( aViewData.GetDocument(), aViewData.GetTabNo(), 0,0, nEndCol,nEndRow, pDevice,aViewData.GetZoomX(),aViewData.GetZoomY(),aViewData.GetPPTX(),aViewData.GetPPTY(), aScaleX,aScaleY ); + + // finally calculate and apply the position of shape ( including + // any vertical and horizontal offsets ) + Point aTmpPos( nWidth, nHeight); + aTmpMode = MapMode ( MAP_100TH_MM ); + aTmpMode.SetScaleX(aScaleX); + aTmpMode.SetScaleY(aScaleY); + + aTmpPos = pDevice->PixelToLogic( aTmpPos, aTmpMode ); + if ( it->mxShape.is() ) + { + com::sun::star::awt::Point aUnoPos( aTmpPos.X() + it->mnHori, aTmpPos.Y() + it->mnVert ); + it->mxShape->setPosition( aUnoPos ); + } + } + } +} /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/ui/unoobj/docuno.cxx b/sc/source/ui/unoobj/docuno.cxx index b9be493..d8851fc 100644 --- a/sc/source/ui/unoobj/docuno.cxx +++ b/sc/source/ui/unoobj/docuno.cxx @@ -1692,7 +1692,24 @@ void SAL_CALL ScModelObj::setPropertyValue( { pDoc->EnableAdjustHeight( bAdjustHeightEnabled ); if( bAdjustHeightEnabled ) + { + // during import ( e.g. oox ) shapes anchored by cell lose + // any additional Hori/Vert orientation ( which offsets the + // shape position relative to the cell ) when + // UpdateAllRowHeights is called. Here we save Hori/Vert + // values before calling UpdateAllRowHeights. Also due to + // differences between the drawing layer and gridwindow + // position calculations we actually can't reliably use cell + // anchoring so we need to remove the cell anchoring, custom + // calculate where the view would position the shape and + // then position the shape absolutely at the newly + // calculated postion. + std::vector< OrientationInfo > savedOrientations; + uno::Reference< frame::XModel > xModel( this ); + ScGlobal::CaptureShapeOrientationInfo( savedOrientations, xModel ); pDocShell->UpdateAllRowHeights(); + ScGlobal::ApplyShapeOrientationInfo( savedOrientations, xModel, *pDoc ); + } } } else if ( aString.EqualsAscii( SC_UNO_ISEXECUTELINKENABLED ) ) diff --git a/sc/source/ui/view/viewdata.cxx b/sc/source/ui/view/viewdata.cxx index 26c6346..875889e 100644 --- a/sc/source/ui/view/viewdata.cxx +++ b/sc/source/ui/view/viewdata.cxx @@ -2480,7 +2480,8 @@ void ScViewData::ReadExtOptions( const ScExtDocOptions& rDocOpt ) /* Width of the tabbar, relative to frame window width. We do not have the correct width of the frame window here -> store in ScTabView, which sets the size in the next resize. */ - pView->SetPendingRelTabBarWidth( rDocSett.mfTabBarWidth ); + if ( pView ) + pView->SetPendingRelTabBarWidth( rDocSett.mfTabBarWidth ); // sheet settings for( SCTAB nTab = 0; nTab < static_cast<SCTAB>(maTabData.size()); ++nTab ) @@ -2780,12 +2781,12 @@ void ScViewData::ReadUserDataSequence(const uno::Sequence <beans::PropertyValue> nTabNo = nTab; } } - else if (sName.compareToAscii(SC_HORIZONTALSCROLLBARWIDTH) == 0) + else if (pView && sName.compareToAscii(SC_HORIZONTALSCROLLBARWIDTH) == 0) { if (rSettings[i].Value >>= nTemp32) pView->SetTabBarWidth(nTemp32); } - else if (sName.compareToAscii(SC_RELHORIZONTALTABBARWIDTH) == 0) + else if (pView && sName.compareToAscii(SC_RELHORIZONTALTABBARWIDTH) == 0) { double fWidth = 0.0; if (rSettings[i].Value >>= fWidth) -- 1.7.3.4