From d34fa1fc643cc49253e7340b3de1c87a49875e8a Mon Sep 17 00:00:00 2001 From: Eike Rathke Date: Tue, 29 Aug 2017 11:09:34 +0200 Subject: Export to PNG: export selected cell range only, not as page, tdf#108317 Change-Id: If662f4ed360c702e572fc5d7b473eb53b9cb14d2 --- sc/inc/docuno.hxx | 3 +- sc/source/ui/unoobj/docuno.cxx | 130 ++++++++++++++++----- .../source/filter/DocumentToGraphicRenderer.cxx | 8 +- 3 files changed, 107 insertions(+), 34 deletions(-) diff --git a/sc/inc/docuno.hxx b/sc/inc/docuno.hxx index 00ff88999bd0..67ee07440884 100644 --- a/sc/inc/docuno.hxx +++ b/sc/inc/docuno.hxx @@ -106,7 +106,8 @@ private: bool FillRenderMarkData( const css::uno::Any& aSelection, const css::uno::Sequence< css::beans::PropertyValue >& rOptions, - ScMarkData& rMark, ScPrintSelectionStatus& rStatus, OUString& rPagesStr ) const; + ScMarkData& rMark, ScPrintSelectionStatus& rStatus, OUString& rPagesStr, + bool& rbRenderToGraphic ) const; css::uno::Reference const & GetFormatter(); void HandleCalculateEvents(); diff --git a/sc/source/ui/unoobj/docuno.cxx b/sc/source/ui/unoobj/docuno.cxx index 67659f7076e4..b7b55293edd9 100644 --- a/sc/source/ui/unoobj/docuno.cxx +++ b/sc/source/ui/unoobj/docuno.cxx @@ -1432,7 +1432,8 @@ static bool lcl_ParseTarget( const OUString& rTarget, ScRange& rTargetRange, too bool ScModelObj::FillRenderMarkData( const uno::Any& aSelection, const uno::Sequence< beans::PropertyValue >& rOptions, ScMarkData& rMark, - ScPrintSelectionStatus& rStatus, OUString& rPagesStr ) const + ScPrintSelectionStatus& rStatus, OUString& rPagesStr, + bool& rbRenderToGraphic ) const { OSL_ENSURE( !rMark.IsMarked() && !rMark.IsMultiMarked(), "FillRenderMarkData: MarkData must be empty" ); OSL_ENSURE( pDocShell, "FillRenderMarkData: DocShell must be set" ); @@ -1477,6 +1478,10 @@ bool ScModelObj::FillRenderMarkData( const uno::Any& aSelection, { rOptions[i].Value >>= xView; } + else if ( rOptions[i].Name == "RenderToGraphic" ) + { + rOptions[i].Value >>= rbRenderToGraphic; + } } // "Print Content" selection wins over "Selected Sheets" option @@ -1613,7 +1618,8 @@ sal_Int32 SAL_CALL ScModelObj::getRendererCount(const uno::Any& aSelection, ScMarkData aMark; ScPrintSelectionStatus aStatus; OUString aPagesStr; - if ( !FillRenderMarkData( aSelection, rOptions, aMark, aStatus, aPagesStr ) ) + bool bRenderToGraphic = false; + if ( !FillRenderMarkData( aSelection, rOptions, aMark, aStatus, aPagesStr, bRenderToGraphic ) ) return 0; // The same ScPrintFuncCache object in pPrintFuncCache is used as long as @@ -1650,6 +1656,11 @@ static sal_Int32 lcl_GetRendererNum( sal_Int32 nSelRenderer, const OUString& rPa return *aIter; // returns -1 if reached the end } +static bool lcl_renderSelectionToGraphic( bool bRenderToGraphic, const ScPrintSelectionStatus& rStatus ) +{ + return bRenderToGraphic && rStatus.GetMode() == SC_PRINTSEL_RANGE; +} + uno::Sequence SAL_CALL ScModelObj::getRenderer( sal_Int32 nSelRenderer, const uno::Any& aSelection, const uno::Sequence& rOptions ) { @@ -1665,7 +1676,8 @@ uno::Sequence SAL_CALL ScModelObj::getRenderer( sal_Int32 OUString aPagesStr; // #i115266# if FillRenderMarkData fails, keep nTotalPages at 0, but still handle getRenderer(0) below long nTotalPages = 0; - if ( FillRenderMarkData( aSelection, rOptions, aMark, aStatus, aPagesStr ) ) + bool bRenderToGraphic = false; + if ( FillRenderMarkData( aSelection, rOptions, aMark, aStatus, aPagesStr, bRenderToGraphic ) ) { if ( !pPrintFuncCache || !pPrintFuncCache->IsSameSelection( aStatus ) ) { @@ -1681,10 +1693,26 @@ uno::Sequence SAL_CALL ScModelObj::getRenderer( sal_Int32 { // getRenderer(0) is used to query the settings, so it must always return something - SCTAB const nCurTab = 0; //! use current sheet from view? - ScPrintFunc aDefaultFunc( pDocShell, pDocShell->GetPrinter(), nCurTab ); - Size aTwips = aDefaultFunc.GetPageSize(); - awt::Size aPageSize( TwipsToHMM( aTwips.Width() ), TwipsToHMM( aTwips.Height() ) ); + awt::Size aPageSize; + if (lcl_renderSelectionToGraphic( bRenderToGraphic, aStatus)) + { + assert( aMark.IsMarked()); + ScRange aRange; + aMark.GetMarkArea( aRange ); + tools::Rectangle aMMRect( pDocShell->GetDocument().GetMMRect( + aRange.aStart.Col(), aRange.aStart.Row(), + aRange.aEnd.Col(), aRange.aEnd.Row(), aRange.aStart.Tab())); + aPageSize.Width = aMMRect.GetWidth(); + aPageSize.Height = aMMRect.GetHeight(); + } + else + { + SCTAB const nCurTab = 0; //! use current sheet from view? + ScPrintFunc aDefaultFunc( pDocShell, pDocShell->GetPrinter(), nCurTab ); + Size aTwips = aDefaultFunc.GetPageSize(); + aPageSize.Width = TwipsToHMM( aTwips.Width()); + aPageSize.Height = TwipsToHMM( aTwips.Height()); + } uno::Sequence aSequence( comphelper::InitPropertySequence({ { SC_UNONAME_PAGESIZE, uno::Any(aPageSize) } @@ -1712,24 +1740,41 @@ uno::Sequence SAL_CALL ScModelObj::getRenderer( sal_Int32 aMark.GetMarkArea( aRange ); pSelRange = &aRange; } - ScPrintFunc aFunc( pDocShell, pDocShell->GetPrinter(), nTab, - pPrintFuncCache->GetFirstAttr(nTab), nTotalPages, pSelRange, &aStatus.GetOptions() ); - aFunc.SetRenderFlag( true ); - Range aPageRange( nRenderer+1, nRenderer+1 ); - MultiSelection aPage( aPageRange ); - aPage.SetTotalRange( Range(0,RANGE_MAX) ); - aPage.Select( aPageRange ); + awt::Size aPageSize; + bool bWasCellRange = false; + ScRange aCellRange; + if (lcl_renderSelectionToGraphic( bRenderToGraphic, aStatus)) + { + bWasCellRange = true; + aCellRange = aRange; + tools::Rectangle aMMRect( pDocShell->GetDocument().GetMMRect( + aRange.aStart.Col(), aRange.aStart.Row(), + aRange.aEnd.Col(), aRange.aEnd.Row(), aRange.aStart.Tab())); + aPageSize.Width = aMMRect.GetWidth(); + aPageSize.Height = aMMRect.GetHeight(); + } + else + { + ScPrintFunc aFunc( pDocShell, pDocShell->GetPrinter(), nTab, + pPrintFuncCache->GetFirstAttr(nTab), nTotalPages, pSelRange, &aStatus.GetOptions() ); + aFunc.SetRenderFlag( true ); - long nDisplayStart = pPrintFuncCache->GetDisplayStart( nTab ); - long nTabStart = pPrintFuncCache->GetTabStart( nTab ); + Range aPageRange( nRenderer+1, nRenderer+1 ); + MultiSelection aPage( aPageRange ); + aPage.SetTotalRange( Range(0,RANGE_MAX) ); + aPage.Select( aPageRange ); - (void)aFunc.DoPrint( aPage, nTabStart, nDisplayStart, false, nullptr ); + long nDisplayStart = pPrintFuncCache->GetDisplayStart( nTab ); + long nTabStart = pPrintFuncCache->GetTabStart( nTab ); - ScRange aCellRange; - bool bWasCellRange = aFunc.GetLastSourceRange( aCellRange ); - Size aTwips = aFunc.GetPageSize(); - awt::Size aPageSize( TwipsToHMM( aTwips.Width() ), TwipsToHMM( aTwips.Height() ) ); + (void)aFunc.DoPrint( aPage, nTabStart, nDisplayStart, false, nullptr ); + + bWasCellRange = aFunc.GetLastSourceRange( aCellRange ); + Size aTwips = aFunc.GetPageSize(); + aPageSize.Width = TwipsToHMM( aTwips.Width()); + aPageSize.Height = TwipsToHMM( aTwips.Height()); + } long nPropCount = bWasCellRange ? 3 : 2; uno::Sequence aSequence(nPropCount); @@ -1769,7 +1814,8 @@ void SAL_CALL ScModelObj::render( sal_Int32 nSelRenderer, const uno::Any& aSelec ScMarkData aMark; ScPrintSelectionStatus aStatus; OUString aPagesStr; - if ( !FillRenderMarkData( aSelection, rOptions, aMark, aStatus, aPagesStr ) ) + bool bRenderToGraphic = false; + if ( !FillRenderMarkData( aSelection, rOptions, aMark, aStatus, aPagesStr, bRenderToGraphic ) ) throw lang::IllegalArgumentException(); if ( !pPrintFuncCache || !pPrintFuncCache->IsSameSelection( aStatus ) ) @@ -1786,9 +1832,38 @@ void SAL_CALL ScModelObj::render( sal_Int32 nSelRenderer, const uno::Any& aSelec if ( !pDev ) throw lang::IllegalArgumentException(); - SCTAB nTab = pPrintFuncCache->GetTabForPage( nRenderer ); ScDocument& rDoc = pDocShell->GetDocument(); + ScRange aRange; + const ScRange* pSelRange = nullptr; + if ( aMark.IsMarked() ) + { + aMark.GetMarkArea( aRange ); + pSelRange = &aRange; + } + + if (lcl_renderSelectionToGraphic( bRenderToGraphic, aStatus)) + { + // Similar to as in and when calling ScTransferObj::PaintToDev() + + Point aPoint; + tools::Rectangle aBound( aPoint, pDev->GetOutputSize()); + + ScViewData aViewData(nullptr,nullptr); + aViewData.InitData( &rDoc ); + + aViewData.SetTabNo( aRange.aStart.Tab() ); + aViewData.SetScreen( aRange.aStart.Col(), aRange.aStart.Row(), aRange.aEnd.Col(), aRange.aEnd.Row() ); + + const double nPrintFactor = 1.0; /* XXX: currently (2017-08-28) is not evaluated */ + // The bMetaFile argument maybe could be + // pDev->GetConnectMetaFile() != nullptr + // but for some yet unknow reason does not draw cell content if true. + ScPrintFunc::DrawToDev( &rDoc, pDev, nPrintFactor, aBound, &aViewData, false /*bMetaFile*/ ); + + return; + } + struct DrawViewKeeper { FmFormView* mpDrawView; @@ -1803,6 +1878,7 @@ void SAL_CALL ScModelObj::render( sal_Int32 nSelRenderer, const uno::Any& aSelec } } aDrawViewKeeper; + SCTAB nTab = pPrintFuncCache->GetTabForPage( nRenderer ); ScDrawLayer* pModel = rDoc.GetDrawLayer(); if( pModel ) @@ -1812,14 +1888,6 @@ void SAL_CALL ScModelObj::render( sal_Int32 nSelRenderer, const uno::Any& aSelec aDrawViewKeeper.mpDrawView->SetPrintPreview(); } - ScRange aRange; - const ScRange* pSelRange = nullptr; - if ( aMark.IsMarked() ) - { - aMark.GetMarkArea( aRange ); - pSelRange = &aRange; - } - // to increase performance, ScPrintState might be used here for subsequent // pages of the same sheet diff --git a/svtools/source/filter/DocumentToGraphicRenderer.cxx b/svtools/source/filter/DocumentToGraphicRenderer.cxx index 9c23168b209a..6c95747ef09d 100644 --- a/svtools/source/filter/DocumentToGraphicRenderer.cxx +++ b/svtools/source/filter/DocumentToGraphicRenderer.cxx @@ -89,13 +89,15 @@ Size DocumentToGraphicRenderer::getDocumentSizeIn100mm(sal_Int32 aCurrentPage) PropertyValues renderProperties; - renderProperties.realloc( 3 ); + renderProperties.realloc( 4 ); renderProperties[0].Name = "IsPrinter"; renderProperties[0].Value <<= true; renderProperties[1].Name = "RenderDevice"; renderProperties[1].Value <<= xDevice; renderProperties[2].Name = "View"; renderProperties[2].Value <<= mxController; + renderProperties[3].Name = "RenderToGraphic"; + renderProperties[3].Value <<= true; awt::Size aSize; @@ -133,13 +135,15 @@ Graphic DocumentToGraphicRenderer::renderToGraphic( double fScaleY = aTargetSizePixel.Height() / (double) aDocumentSizePixel.Height(); PropertyValues renderProps; - renderProps.realloc( 3 ); + renderProps.realloc( 4 ); renderProps[0].Name = "IsPrinter"; renderProps[0].Value <<= true; renderProps[1].Name = "RenderDevice"; renderProps[1].Value <<= xDevice; renderProps[2].Name = "View"; renderProps[2].Value <<= mxController; + renderProps[3].Name = "RenderToGraphic"; + renderProps[3].Value <<= true; GDIMetaFile aMtf; -- cgit