diff --git a/chart2/source/controller/dialogs/ChartTypeDialogController.cxx b/chart2/source/controller/dialogs/ChartTypeDialogController.cxx index d954ec1325f4..79efe0b04919 100644 --- a/chart2/source/controller/dialogs/ChartTypeDialogController.cxx +++ b/chart2/source/controller/dialogs/ChartTypeDialogController.cxx @@ -41,6 +41,7 @@ #include "ChartModelHelper.hxx" #include "DiagramHelper.hxx" #include "ControllerLockGuard.hxx" +#include "AxisHelper.hxx" #include #include @@ -53,6 +54,8 @@ #include // header for class Bitmap #include +#include + #include //............................................................................. @@ -358,6 +361,8 @@ bool ChartTypeDialogController::commitToModel( const ChartTypeParameter& rParame if( aTemplateWithService.first.is()) aTemplateWithService.first->resetStyles( xDiagram ); xTemplate->changeDiagram( xDiagram ); + if( Application::GetSettings().GetLayoutRTL() ) + AxisHelper::setRTLAxisLayout( AxisHelper::getCoordinateSystemByIndex( xDiagram, 0 ) ); if( rParameter.b3DLook ) ThreeDHelper::setScheme( xDiagram, rParameter.eThreeDLookScheme ); diff --git a/chart2/source/controller/main/ChartWindow.cxx b/chart2/source/controller/main/ChartWindow.cxx index f9afd365ed0d..5c9e201aebd8 100644 --- a/chart2/source/controller/main/ChartWindow.cxx +++ b/chart2/source/controller/main/ChartWindow.cxx @@ -66,6 +66,9 @@ ChartWindow::ChartWindow( WindowController* pWindowController, Window* pParent, adjustHighContrastMode(); // chart does not depend on exact pixel painting => enable antialiased drawing SetAntialiasing( ANTIALIASING_ENABLE_B2DDRAW | GetAntialiasing() ); + EnableRTL( FALSE ); + if( pParent ) + pParent->EnableRTL( FALSE );// #i96215# necessary for a correct position of the context menu in rtl mode } ChartWindow::~ChartWindow() diff --git a/chart2/source/inc/AxisHelper.hxx b/chart2/source/inc/AxisHelper.hxx index 6f4c9c162301..a6b91481af8a 100644 --- a/chart2/source/inc/AxisHelper.hxx +++ b/chart2/source/inc/AxisHelper.hxx @@ -227,6 +227,9 @@ public: getChartTypeByIndex( const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XCoordinateSystem >& xCooSys, sal_Int32 nIndex ); + static void setRTLAxisLayout( const ::com::sun::star::uno::Reference< + ::com::sun::star::chart2::XCoordinateSystem >& xCooSys ); + static ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartType > getFirstChartTypeWithSeriesAttachedToAxisIndex( const ::com::sun::star::uno::Reference< diff --git a/chart2/source/model/main/ImplChartModel.cxx b/chart2/source/model/main/ImplChartModel.cxx index 6360ccc7ee9c..bd4ad5630cb2 100644 --- a/chart2/source/model/main/ImplChartModel.cxx +++ b/chart2/source/model/main/ImplChartModel.cxx @@ -42,12 +42,16 @@ #include "DisposeHelper.hxx" #include "UndoManager.hxx" #include "ThreeDHelper.hxx" +#include "AxisHelper.hxx" // header for class SvNumberFormatter #include // header for class SvNumberFormatsSupplierObj #include +#include #include + +#include #include #include #include @@ -348,6 +352,11 @@ void ImplChartModel::CreateDefaultChart() AppendDiagram( xDiagram ); + bool bIsRTL = Application::GetSettings().GetLayoutRTL(); + //reverse x axis for rtl charts + if( bIsRTL ) + AxisHelper::setRTLAxisLayout( AxisHelper::getCoordinateSystemByIndex( xDiagram, 0 ) ); + // create and attach legend Reference< chart2::XLegend > xLegend( m_xContext->getServiceManager()->createInstanceWithContext( @@ -359,6 +368,9 @@ void ImplChartModel::CreateDefaultChart() xLegendProperties->setPropertyValue( C2U( "LineStyle" ), uno::makeAny( drawing::LineStyle_NONE )); xLegendProperties->setPropertyValue( C2U( "LineColor" ), uno::makeAny( static_cast< sal_Int32 >( 0xb3b3b3 ) )); // gray30 xLegendProperties->setPropertyValue( C2U( "FillColor" ), uno::makeAny( static_cast< sal_Int32 >( 0xe6e6e6 ) ) ); // gray10 + + if( bIsRTL ) + xLegendProperties->setPropertyValue( C2U( "AnchorPosition" ), uno::makeAny( chart2::LegendPosition_LINE_START )); } if(xDiagram.is()) xDiagram->setLegend( xLegend ); diff --git a/chart2/source/tools/AxisHelper.cxx b/chart2/source/tools/AxisHelper.cxx index 86fee326497b..b9778042baed 100644 --- a/chart2/source/tools/AxisHelper.cxx +++ b/chart2/source/tools/AxisHelper.cxx @@ -38,11 +38,13 @@ #include "AxisIndexDefines.hxx" #include "LineProperties.hxx" #include "ContainerHelper.hxx" +#include "servicenames_coosystems.hxx" #include "DataSeriesHelper.hxx" #include #include + #include #include #include @@ -848,6 +850,74 @@ Reference< XChartType > AxisHelper::getChartTypeByIndex( const Reference< XCoord return xChartType; } +void AxisHelper::setRTLAxisLayout( const Reference< XCoordinateSystem >& xCooSys ) +{ + if( xCooSys.is() ) + { + bool bCartesian = xCooSys->getViewServiceName().equals( CHART2_COOSYSTEM_CARTESIAN_VIEW_SERVICE_NAME ); + if( bCartesian ) + { + bool bVertical = false; + Reference< beans::XPropertySet > xCooSysProp( xCooSys, uno::UNO_QUERY ); + if( xCooSysProp.is() ) + xCooSysProp->getPropertyValue( C2U("SwapXAndYAxis") ) >>= bVertical; + + sal_Int32 nHorizontalAxisDimension = bVertical ? 1 : 0; + sal_Int32 nVerticalAxisDimension = bVertical ? 0 : 1; + + try + { + //reverse direction for horizontal main axis + Reference< chart2::XAxis > xHorizontalMainAxis( AxisHelper::getAxis( nHorizontalAxisDimension, MAIN_AXIS_INDEX, xCooSys ) ); + if( xHorizontalMainAxis.is() ) + { + chart2::ScaleData aScale = xHorizontalMainAxis->getScaleData(); + aScale.Orientation = chart2::AxisOrientation_REVERSE; + xHorizontalMainAxis->setScaleData(aScale); + } + + //mathematical direction for vertical main axis + Reference< chart2::XAxis > xVerticalMainAxis( AxisHelper::getAxis( nVerticalAxisDimension, MAIN_AXIS_INDEX, xCooSys ) ); + if( xVerticalMainAxis.is() ) + { + chart2::ScaleData aScale = xVerticalMainAxis->getScaleData(); + aScale.Orientation = chart2::AxisOrientation_MATHEMATICAL; + xVerticalMainAxis->setScaleData(aScale); + } + } + catch( uno::Exception & ex ) + { + ASSERT_EXCEPTION( ex ); + } + + try + { + //reverse direction for horizontal secondary axis + Reference< chart2::XAxis > xHorizontalSecondaryAxis( AxisHelper::getAxis( nHorizontalAxisDimension, SECONDARY_AXIS_INDEX, xCooSys ) ); + if( xHorizontalSecondaryAxis.is() ) + { + chart2::ScaleData aScale = xHorizontalSecondaryAxis->getScaleData(); + aScale.Orientation = chart2::AxisOrientation_REVERSE; + xHorizontalSecondaryAxis->setScaleData(aScale); + } + + //mathematical direction for vertical secondary axis + Reference< chart2::XAxis > xVerticalSecondaryAxis( AxisHelper::getAxis( nVerticalAxisDimension, SECONDARY_AXIS_INDEX, xCooSys ) ); + if( xVerticalSecondaryAxis.is() ) + { + chart2::ScaleData aScale = xVerticalSecondaryAxis->getScaleData(); + aScale.Orientation = chart2::AxisOrientation_MATHEMATICAL; + xVerticalSecondaryAxis->setScaleData(aScale); + } + } + catch( uno::Exception & ex ) + { + ASSERT_EXCEPTION( ex ); + } + } + } +} + Reference< XChartType > AxisHelper::getFirstChartTypeWithSeriesAttachedToAxisIndex( const Reference< chart2::XDiagram >& xDiagram, const sal_Int32 nAttachedAxisIndex ) { Reference< XChartType > xChartType; diff --git a/chart2/source/view/main/ChartView.cxx b/chart2/source/view/main/ChartView.cxx index f817412b5201..d9699afb059a 100644 --- a/chart2/source/view/main/ChartView.cxx +++ b/chart2/source/view/main/ChartView.cxx @@ -1297,6 +1297,18 @@ void lcl_setDefaultWritingMode( ::boost::shared_ptr< DrawModelWrapper > pDrawMod } } +sal_Int16 lcl_getDefaultWritingModeFromPool( ::boost::shared_ptr< DrawModelWrapper > pDrawModelWrapper ) +{ + sal_Int16 nWritingMode = text::WritingMode2::LR_TB; + if( pDrawModelWrapper.get() ) + { + const SfxPoolItem* pItem = &(pDrawModelWrapper->GetItemPool().GetDefaultItem( EE_PARA_WRITINGDIR )); + if( pItem ) + nWritingMode = static_cast< sal_Int16 >((static_cast< const SfxInt32Item * >( pItem ))->GetValue()); + } + return nWritingMode; +} + } //end anonymous namespace //------------ create complete diagram shape (inclusive axis and series) @@ -2187,12 +2199,14 @@ bool lcl_createLegend( const uno::Reference< XLegend > & xLegend , awt::Rectangle & rRemainingSpace , const awt::Size & rPageSize , const uno::Reference< frame::XModel > & xModel - , const std::vector< LegendEntryProvider* >& rLegendEntryProviderList ) + , const std::vector< LegendEntryProvider* >& rLegendEntryProviderList + , sal_Int16 nDefaultWritingMode ) { if( VLegend::isVisible( xLegend )) { VLegend aVLegend( xLegend, xContext, rLegendEntryProviderList ); aVLegend.init( xPageShapes, xShapeFactory, xModel ); + aVLegend.setDefaultWritingMode( nDefaultWritingMode ); aVLegend.createShapes( awt::Size( rRemainingSpace.Width, rRemainingSpace.Height ), rPageSize ); aVLegend.changePosition( rRemainingSpace, rPageSize ); @@ -2420,7 +2434,8 @@ void ChartView::createShapes() //------------ create legend lcl_createLegend( LegendHelper::getLegend( m_xChartModel ), xPageShapes, m_xShapeFactory, m_xCC - , aRemainingSpace, aPageSize, m_xChartModel, aSeriesPlotterContainer.getLegendEntryProviderList() ); + , aRemainingSpace, aPageSize, m_xChartModel, aSeriesPlotterContainer.getLegendEntryProviderList() + , lcl_getDefaultWritingModeFromPool( m_pDrawModelWrapper ) ); if(aRemainingSpace.Width<=0||aRemainingSpace.Height<=0) return; diff --git a/chart2/source/view/main/VLegend.cxx b/chart2/source/view/main/VLegend.cxx index 614943885dbc..b9fa4b3aba84 100644 --- a/chart2/source/view/main/VLegend.cxx +++ b/chart2/source/view/main/VLegend.cxx @@ -40,13 +40,16 @@ #include "RelativeSizeHelper.hxx" #include "LegendEntryProvider.hxx" #include +#include #include +#include #include #include #include #include #include #include +#include #include #include @@ -242,9 +245,10 @@ awt::Size lcl_createTextShapes( } -void lcl_createLegend( +void lcl_placeLegendEntries( const tViewLegendEntryContainer & rEntries, LegendExpansion eExpansion, + bool bSymbolsLeftSide, const Reference< beans::XPropertySet > & xProperties, tPropertyValues & rTextProperties, const Reference< drawing::XShapes > & xTarget, @@ -280,6 +284,9 @@ void lcl_createLegend( sal_Int32 nMaxEntryHeight = nYOffset + aMaxEntryExtent.Height; sal_Int32 nNumberOfEntries = rEntries.size(); + if( !bSymbolsLeftSide ) + nCurrentXPos = -nXPadding; + sal_Int32 nNumberOfColumns = 0, nNumberOfRows = 0; // determine layout depending on LegendExpansion @@ -384,26 +391,50 @@ void lcl_createLegend( aMaxSymbolExtent.Width * 75 / 100, aMaxSymbolExtent.Height * 75 / 100 ); xSymbol->setSize( aSymbolSize ); - xSymbol->setPosition( - awt::Point( - nCurrentXPos + ((aMaxSymbolExtent.Width - aSymbolSize.Width) / 2), + sal_Int32 nSymbolXPos = nCurrentXPos + ((aMaxSymbolExtent.Width - aSymbolSize.Width) / 2); + if( !bSymbolsLeftSide ) + nSymbolXPos = nSymbolXPos - aMaxSymbolExtent.Width; + xSymbol->setPosition( awt::Point( nSymbolXPos, nCurrentYPos + ((aMaxSymbolExtent.Height - aSymbolSize.Height) / 2))); } // position text shape awt::Size aTextSize( aTextShapes[ nEntry ]->getSize()); - nMaxWidth = ::std::max( - nMaxWidth, 2 * nXOffset + aMaxSymbolExtent.Width + aTextSize.Width ); - aTextShapes[ nEntry ]->setPosition( - awt::Point( nCurrentXPos + aMaxSymbolExtent.Width, nCurrentYPos )); + nMaxWidth = ::std::max( nMaxWidth, 2 * nXOffset + aMaxSymbolExtent.Width + aTextSize.Width ); + sal_Int32 nTextXPos = nCurrentXPos + aMaxSymbolExtent.Width; + if( !bSymbolsLeftSide ) + nTextXPos = nCurrentXPos - aMaxSymbolExtent.Width - aTextSize.Width; + aTextShapes[ nEntry ]->setPosition( awt::Point( nTextXPos, nCurrentYPos )); nCurrentYPos += nMaxHeights[ nRow ]; nMaxYPos = ::std::max( nMaxYPos, nCurrentYPos ); } - nCurrentXPos += nMaxWidth; + if( bSymbolsLeftSide ) + nCurrentXPos += nMaxWidth; + else + nCurrentXPos -= nMaxWidth; } - rOutLegendSize.Width = nCurrentXPos + nXPadding; + if( bSymbolsLeftSide ) + rOutLegendSize.Width = nCurrentXPos + nXPadding; + else + { + sal_Int32 nLegendWidth = -(nCurrentXPos-nXPadding); + rOutLegendSize.Width = nLegendWidth; + + awt::Point aPos(0,0); + for( sal_Int32 nEntry=0; nEntry xSymbol( rEntries[ nEntry ].aSymbol ); + aPos = xSymbol->getPosition(); + aPos.X += nLegendWidth; + xSymbol->setPosition( aPos ); + Reference< drawing::XShape > xText( aTextShapes[ nEntry ] ); + aPos = xText->getPosition(); + aPos.X += nLegendWidth; + xText->setPosition( aPos ); + } + } rOutLegendSize.Height = nMaxYPos + nYPadding; } @@ -528,6 +559,33 @@ void lcl_appendSeqToVector( const Sequence< T > & rSource, ::std::vector< T > & rDest.push_back( rSource[ i ] ); } +bool lcl_shouldSymbolsBePlacedOnTheLeftSide( const Reference< beans::XPropertySet >& xLegendProp, sal_Int16 nDefaultWritingMode ) +{ + bool bSymbolsLeftSide = true; + try + { + if( SvtLanguageOptions().IsCTLFontEnabled() ) + { + if(xLegendProp.is()) + { + sal_Int16 nWritingMode=-1; + if( (xLegendProp->getPropertyValue( C2U("WritingMode") ) >>= nWritingMode) ) + { + if( nWritingMode == text::WritingMode2::PAGE ) + nWritingMode = nDefaultWritingMode; + if( nWritingMode == text::WritingMode2::RL_TB ) + bSymbolsLeftSide=false; + } + } + } + } + catch( uno::Exception & ex ) + { + ASSERT_EXCEPTION( ex ); + } + return bSymbolsLeftSide; +} + } // anonymous namespace VLegend::VLegend( @@ -554,6 +612,13 @@ void SAL_CALL VLegend::init( // ---------------------------------------- +void VLegend::setDefaultWritingMode( sal_Int16 nDefaultWritingMode ) +{ + m_nDefaultWritingMode = nDefaultWritingMode; +} + +// ---------------------------------------- + // static bool VLegend::isVisible( const Reference< XLegend > & xLegend ) { @@ -653,13 +718,14 @@ void VLegend::createShapes( } } + bool bSymbolsLeftSide = lcl_shouldSymbolsBePlacedOnTheLeftSide( xLegendProp, m_nDefaultWritingMode ); + // place entries awt::Size aLegendSize; - lcl_createLegend( aViewEntries, eExpansion, xLegendProp, - aTextProperties, - xLegendContainer, m_xShapeFactory, m_xContext, - rAvailableSpace, rPageSize, - aLegendSize ); + lcl_placeLegendEntries( aViewEntries, eExpansion, bSymbolsLeftSide + , xLegendProp, aTextProperties + , xLegendContainer, m_xShapeFactory, m_xContext + , rAvailableSpace, rPageSize, aLegendSize ); if( xBorder.is()) xBorder->setSize( aLegendSize ); diff --git a/chart2/source/view/main/VLegend.hxx b/chart2/source/view/main/VLegend.hxx index 3cde9899ea20..cdb230cc06c7 100644 --- a/chart2/source/view/main/VLegend.hxx +++ b/chart2/source/view/main/VLegend.hxx @@ -66,6 +66,8 @@ public: const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > & xModel ); + void setDefaultWritingMode( sal_Int16 nDefaultWritingMode ); + void createShapes( const ::com::sun::star::awt::Size & rAvailableSpace, const ::com::sun::star::awt::Size & rPageSize ); @@ -101,6 +103,8 @@ private: ::com::sun::star::uno::XComponentContext > m_xContext; std::vector< LegendEntryProvider* > m_aLegendEntryProviderList; + + sal_Int16 m_nDefaultWritingMode;//to be used when writing mode is set to page }; //.............................................................................