diff options
131 files changed, 3087 insertions, 1898 deletions
diff --git a/chart2/prj/build.lst b/chart2/prj/build.lst index 3cdc9a26e3f5..469eb7554d6b 100644 --- a/chart2/prj/build.lst +++ b/chart2/prj/build.lst @@ -24,3 +24,4 @@ ch chart2\source\controller\chartapiwrapper nmake - all ch_source_controlle ch chart2\source\controller\main nmake - all ch_source_controller_main ch_inc NULL ch chart2\source\controller\menus nmake - all ch_source_controller_menus ch_inc NULL ch chart2\prj get - all ch_prj NULL +ch chart2\qa\unoapi nmake - all ch_qa_unoapi NULL diff --git a/chart2/qa/unoapi/knownissues.xcl b/chart2/qa/unoapi/knownissues.xcl index 99c0b9aa096e..155132922661 100644 --- a/chart2/qa/unoapi/knownissues.xcl +++ b/chart2/qa/unoapi/knownissues.xcl @@ -1,7 +1,5 @@ #i83851 sch.ChXChartDocument::com::sun::star::frame::XModel -#i83832 -sch.ChXChartDocument::com::sun::star::beans::XPropertySet #i83833 sch.ChXChartDocument::com::sun::star::chart::XChartDocument #i83834 @@ -12,8 +10,6 @@ sch.ChXChartView::com::sun::star::view::XSelectionSupplier #i83855 sch.ChXDiagram::com::sun::star::chart::LineDiagram -#i83857 -sch.ChXDiagram::com::sun::star::drawing::XShape #i83853 sch.ChXDiagram::com::sun::star::beans::XPropertySet #i83854 @@ -23,19 +19,9 @@ sch.ChXDiagram::com::sun::star::chart::ChartAxisZSupplier #i83856 sch.ChXDiagram::com::sun::star::chart::StockDiagram -#i83706 -sch.ChartLegend::com::sun::star::drawing::LineProperties -sch.ChartLegend::com::sun::star::drawing::FillProperties -sch.ChartLegend::com::sun::star::chart::ChartLegend -sch.ChartLegend::com::sun::star::style::CharacterProperties sch.ChartLegend::com::sun::star::drawing::XShape - #i83830 sch.ChartTitle::com::sun::star::drawing::XShape -#i83831 -sch.ChartTitle::com::sun::star::style::CharacterProperties -#i83827 -sch.ChartTitle::com::sun::star::chart::ChartTitle #i78867 sch.ChXChartDocument::com::sun::star::xml::UserDefinedAttributeSupplier @@ -50,14 +36,5 @@ sch.ChXDataPoint::com::sun::star::xml::UserDefinedAttributeSupplier #i83865 sch.ChXDataPoint::com::sun::star::drawing::LineProperties - -#i83866 -sch.ChXDataPoint::com::sun::star::chart::Chart3DBarProperties - -#i87138 -sch.ChXDiagram -# -> disabled in sch.sce - -### i87295 ### -sch.ChXChartAxis::com::sun::star::beans::XPropertySet +#112078 sch.ChartLegend::com::sun::star::beans::XPropertySet diff --git a/chart2/qa/unoapi/sch.sce b/chart2/qa/unoapi/sch.sce index 6f2df6fbb36d..b35dec7c2ef4 100644 --- a/chart2/qa/unoapi/sch.sce +++ b/chart2/qa/unoapi/sch.sce @@ -16,9 +16,9 @@ -o sch.ChXChartData -o sch.ChXChartDataArray -o sch.ChXChartView -#i83867 -o sch.ChXDataPoint +-o sch.ChXDataPoint #i83868 -o sch.ChXDataRow -#i87138 -o sch.ChXDiagram +-o sch.ChXDiagram -o sch.ChartArea -o sch.ChartGrid -o sch.ChartLegend diff --git a/chart2/qa/unoapi/testdocuments/TransparencyChart.sxs b/chart2/qa/unoapi/testdocuments/TransparencyChart.sxs Binary files differindex 95d6d22451c2..c3a5833ae27a 100644 --- a/chart2/qa/unoapi/testdocuments/TransparencyChart.sxs +++ b/chart2/qa/unoapi/testdocuments/TransparencyChart.sxs diff --git a/chart2/source/controller/chartapiwrapper/AxisWrapper.cxx b/chart2/source/controller/chartapiwrapper/AxisWrapper.cxx index 7ac8cec0ad62..6d53fb8b01f6 100644 --- a/chart2/source/controller/chartapiwrapper/AxisWrapper.cxx +++ b/chart2/source/controller/chartapiwrapper/AxisWrapper.cxx @@ -149,43 +149,43 @@ void lcl_AddPropertiesToVector( Property( C2U( "AutoMax" ), PROP_AXIS_AUTO_MAX, ::getBooleanCppuType(), - beans::PropertyAttribute::BOUND - | beans::PropertyAttribute::MAYBEDEFAULT )); + //#i111967# no PropertyChangeEvent is fired on change so far + beans::PropertyAttribute::MAYBEDEFAULT )); rOutProperties.push_back( Property( C2U( "AutoMin" ), PROP_AXIS_AUTO_MIN, ::getBooleanCppuType(), - beans::PropertyAttribute::BOUND - | beans::PropertyAttribute::MAYBEDEFAULT )); + //#i111967# no PropertyChangeEvent is fired on change so far + beans::PropertyAttribute::MAYBEDEFAULT )); rOutProperties.push_back( Property( C2U( "AutoStepMain" ), PROP_AXIS_AUTO_STEPMAIN, ::getBooleanCppuType(), - beans::PropertyAttribute::BOUND - | beans::PropertyAttribute::MAYBEDEFAULT )); + //#i111967# no PropertyChangeEvent is fired on change so far + beans::PropertyAttribute::MAYBEDEFAULT )); rOutProperties.push_back( Property( C2U( "AutoStepHelp" ), PROP_AXIS_AUTO_STEPHELP, ::getBooleanCppuType(), - beans::PropertyAttribute::BOUND - | beans::PropertyAttribute::MAYBEDEFAULT )); + //#i111967# no PropertyChangeEvent is fired on change so far + beans::PropertyAttribute::MAYBEDEFAULT )); rOutProperties.push_back( Property( C2U( "Logarithmic" ), PROP_AXIS_LOGARITHMIC, ::getBooleanCppuType(), - beans::PropertyAttribute::BOUND - | beans::PropertyAttribute::MAYBEDEFAULT )); + //#i111967# no PropertyChangeEvent is fired on change so far + beans::PropertyAttribute::MAYBEDEFAULT )); rOutProperties.push_back( Property( C2U( "ReverseDirection" ), PROP_AXIS_REVERSEDIRECTION, ::getBooleanCppuType(), - beans::PropertyAttribute::BOUND - | beans::PropertyAttribute::MAYBEDEFAULT )); + //#i111967# no PropertyChangeEvent is fired on change so far + beans::PropertyAttribute::MAYBEDEFAULT )); //todo: this property is missing in the API rOutProperties.push_back( @@ -219,8 +219,8 @@ void lcl_AddPropertiesToVector( Property( C2U( "AutoOrigin" ), PROP_AXIS_AUTO_ORIGIN, ::getBooleanCppuType(), - beans::PropertyAttribute::BOUND - | beans::PropertyAttribute::MAYBEDEFAULT )); + //#i111967# no PropertyChangeEvent is fired on change so far + beans::PropertyAttribute::MAYBEDEFAULT )); //Properties for interval marks: rOutProperties.push_back( @@ -312,15 +312,15 @@ void lcl_AddPropertiesToVector( Property( C2U( "Overlap" ), PROP_AXIS_OVERLAP, ::getCppuType( reinterpret_cast< const sal_Int32 * >(0)), - beans::PropertyAttribute::BOUND - | beans::PropertyAttribute::MAYBEDEFAULT )); + //#i111967# no PropertyChangeEvent is fired on change so far + beans::PropertyAttribute::MAYBEDEFAULT )); rOutProperties.push_back( Property( C2U( "GapWidth" ), PROP_AXIS_GAP_WIDTH, ::getCppuType( reinterpret_cast< const sal_Int32 * >(0)), - beans::PropertyAttribute::BOUND - | beans::PropertyAttribute::MAYBEDEFAULT )); + //#i111967# no PropertyChangeEvent is fired on change so far + beans::PropertyAttribute::MAYBEDEFAULT )); } const Sequence< Property > & lcl_GetPropertySequence() diff --git a/chart2/source/controller/chartapiwrapper/Chart2ModelContact.cxx b/chart2/source/controller/chartapiwrapper/Chart2ModelContact.cxx index 79f5dccc918a..ffc1e95ca796 100644 --- a/chart2/source/controller/chartapiwrapper/Chart2ModelContact.cxx +++ b/chart2/source/controller/chartapiwrapper/Chart2ModelContact.cxx @@ -38,6 +38,7 @@ #include "chartview/ExplicitValueProvider.hxx" #include "chartview/DrawModelWrapper.hxx" #include "AxisHelper.hxx" +#include "DiagramHelper.hxx" using namespace ::com::sun::star; using namespace ::com::sun::star::chart2; @@ -118,7 +119,7 @@ Reference< chart2::XDiagram > Chart2ModelContact::getChart2Diagram() const return ChartModelHelper::findDiagram( this->getChartModel() ); } -ExplicitValueProvider* Chart2ModelContact::getExplicitValueProvider() const +uno::Reference< lang::XUnoTunnel > Chart2ModelContact::getChartView() const { if(!m_xChartView.is()) { @@ -128,7 +129,12 @@ ExplicitValueProvider* Chart2ModelContact::getExplicitValueProvider() const if( xFact.is() ) m_xChartView = Reference< lang::XUnoTunnel >( xFact->createInstance( CHART_VIEW_SERVICE_NAME ), uno::UNO_QUERY ); } + return m_xChartView; +} +ExplicitValueProvider* Chart2ModelContact::getExplicitValueProvider() const +{ + getChartView(); if(!m_xChartView.is()) return 0; @@ -192,30 +198,54 @@ awt::Size Chart2ModelContact::GetPageSize() const return ChartModelHelper::getPageSize(m_xChartModel); } -awt::Rectangle Chart2ModelContact::GetDiagramRectangleInclusive() const +awt::Rectangle Chart2ModelContact::SubstractAxisTitleSizes( const awt::Rectangle& rPositionRect ) { - awt::Rectangle aRect; + awt::Rectangle aRect = ExplicitValueProvider::substractAxisTitleSizes( + m_xChartModel, getChartView(), rPositionRect ); + return aRect; +} + +awt::Rectangle Chart2ModelContact::GetDiagramRectangleIncludingTitle() const +{ + awt::Rectangle aRect( GetDiagramRectangleIncludingAxes() ); - ExplicitValueProvider* pProvider( getExplicitValueProvider() ); - if( pProvider ) - { - aRect = pProvider->getRectangleOfObject( lcl_getCIDForDiagram( m_xChartModel ) ); - } //add axis title sizes to the diagram size - aRect = ExplicitValueProvider::calculateDiagramPositionAndSizeInclusiveTitle( - m_xChartModel, m_xChartView, aRect ); + aRect = ExplicitValueProvider::addAxisTitleSizes( + m_xChartModel, getChartView(), aRect ); return aRect; } -awt::Size Chart2ModelContact::GetDiagramSizeInclusive() const +awt::Rectangle Chart2ModelContact::GetDiagramRectangleIncludingAxes() const { - return ToSize( this->GetDiagramRectangleInclusive() ); + awt::Rectangle aRect(0,0,0,0); + uno::Reference< XDiagram > xDiagram( ChartModelHelper::findDiagram( m_xChartModel ) ); + + if( DiagramPositioningMode_INCLUDING == DiagramHelper::getDiagramPositioningMode( xDiagram ) ) + aRect = DiagramHelper::getDiagramRectangleFromModel(m_xChartModel); + else + { + ExplicitValueProvider* pProvider( getExplicitValueProvider() ); + if( pProvider ) + aRect = pProvider->getRectangleOfObject( C2U("PlotAreaIncludingAxes") ); + } + return aRect; } -awt::Point Chart2ModelContact::GetDiagramPositionInclusive() const +awt::Rectangle Chart2ModelContact::GetDiagramRectangleExcludingAxes() const { - return ToPoint( this->GetDiagramRectangleInclusive() ); + awt::Rectangle aRect(0,0,0,0); + uno::Reference< XDiagram > xDiagram( ChartModelHelper::findDiagram( m_xChartModel ) ); + + if( DiagramPositioningMode_EXCLUDING == DiagramHelper::getDiagramPositioningMode( xDiagram ) ) + aRect = DiagramHelper::getDiagramRectangleFromModel(m_xChartModel); + else + { + ExplicitValueProvider* pProvider( getExplicitValueProvider() ); + if( pProvider ) + aRect = pProvider->getDiagramRectangleExcludingAxes(); + } + return aRect; } awt::Size Chart2ModelContact::GetLegendSize() const diff --git a/chart2/source/controller/chartapiwrapper/Chart2ModelContact.hxx b/chart2/source/controller/chartapiwrapper/Chart2ModelContact.hxx index dea25ddd50e4..e20167e216c2 100644 --- a/chart2/source/controller/chartapiwrapper/Chart2ModelContact.hxx +++ b/chart2/source/controller/chartapiwrapper/Chart2ModelContact.hxx @@ -93,15 +93,24 @@ public: */ ::com::sun::star::awt::Size GetPageSize() const; - /** Returns the size of the diagram object in logic coordinates inclusive - the space reserved for axis titles. + /** calculates the current axes title sizes and substract that space them from the given recangle */ - ::com::sun::star::awt::Size GetDiagramSizeInclusive() const; + ::com::sun::star::awt::Rectangle SubstractAxisTitleSizes( const ::com::sun::star::awt::Rectangle& rPositionRect ); - /** Returns the position of the diagram in logic coordinates inclusive - the space reserved for axis titles. + /** Returns the position and size of the diagram in logic coordinates (100th mm) including + the space used for axes including axes titles. */ - ::com::sun::star::awt::Point GetDiagramPositionInclusive() const; + ::com::sun::star::awt::Rectangle GetDiagramRectangleIncludingTitle() const; + + /** Returns the position and size of the diagram in logic coordinates (100th mm) including + the space used for axes excluding axes titles. + */ + ::com::sun::star::awt::Rectangle GetDiagramRectangleIncludingAxes() const; + + /** Returns the position and size of the diagram in logic coordinates (100th mm) excluding + the space used for axes (inner plot area). + */ + ::com::sun::star::awt::Rectangle GetDiagramRectangleExcludingAxes() const; /** Returns the size of the object in logic coordinates. */ @@ -134,7 +143,8 @@ public: private: //methods ExplicitValueProvider* getExplicitValueProvider() const; - ::com::sun::star::awt::Rectangle GetDiagramRectangleInclusive() const; + ::com::sun::star::uno::Reference< + ::com::sun::star::lang::XUnoTunnel > getChartView() const; public: //member ::com::sun::star::uno::Reference< diff --git a/chart2/source/controller/chartapiwrapper/ChartDocumentWrapper.cxx b/chart2/source/controller/chartapiwrapper/ChartDocumentWrapper.cxx index 37c41730523b..edf8ad2b6209 100644 --- a/chart2/source/controller/chartapiwrapper/ChartDocumentWrapper.cxx +++ b/chart2/source/controller/chartapiwrapper/ChartDocumentWrapper.cxx @@ -172,20 +172,20 @@ void lcl_AddPropertiesToVector( Property( C2U( "HasMainTitle" ), PROP_DOCUMENT_HAS_MAIN_TITLE, ::getBooleanCppuType(), - beans::PropertyAttribute::BOUND - | beans::PropertyAttribute::MAYBEDEFAULT )); + //#i111967# no PropertyChangeEvent is fired on change so far + beans::PropertyAttribute::MAYBEDEFAULT )); rOutProperties.push_back( Property( C2U( "HasSubTitle" ), PROP_DOCUMENT_HAS_SUB_TITLE, ::getBooleanCppuType(), - beans::PropertyAttribute::BOUND - | beans::PropertyAttribute::MAYBEDEFAULT )); + //#i111967# no PropertyChangeEvent is fired on change so far + beans::PropertyAttribute::MAYBEDEFAULT )); rOutProperties.push_back( Property( C2U( "HasLegend" ), PROP_DOCUMENT_HAS_LEGEND, ::getBooleanCppuType(), - beans::PropertyAttribute::BOUND - | beans::PropertyAttribute::MAYBEDEFAULT )); + //#i111967# no PropertyChangeEvent is fired on change so far + beans::PropertyAttribute::MAYBEDEFAULT )); // really needed? rOutProperties.push_back( @@ -198,8 +198,8 @@ void lcl_AddPropertiesToVector( Property( C2U( "DataSourceLabelsInFirstColumn" ), PROP_DOCUMENT_LABELS_IN_FIRST_COLUMN, ::getBooleanCppuType(), - beans::PropertyAttribute::BOUND - | beans::PropertyAttribute::MAYBEDEFAULT )); + //#i111967# no PropertyChangeEvent is fired on change so far + beans::PropertyAttribute::MAYBEDEFAULT )); //add-in rOutProperties.push_back( @@ -225,7 +225,8 @@ void lcl_AddPropertiesToVector( Property( C2U( "RefreshAddInAllowed" ), PROP_DOCUMENT_UPDATE_ADDIN, ::getBooleanCppuType(), - beans::PropertyAttribute::BOUND )); + //#i111967# no PropertyChangeEvent is fired on change so far + beans::PropertyAttribute::TRANSIENT )); // table:null-date // i99104 rOutProperties.push_back( @@ -757,6 +758,7 @@ Reference< drawing::XShape > SAL_CALL ChartDocumentWrapper::getTitle() { if( !m_xTitle.is() ) { + ControllerLockGuard aCtrlLockGuard( Reference< frame::XModel >( m_spChart2ModelContact->getChart2Document(), uno::UNO_QUERY )); m_xTitle = new TitleWrapper( TitleHelper::MAIN_TITLE, m_spChart2ModelContact ); } return m_xTitle; @@ -767,6 +769,7 @@ Reference< drawing::XShape > SAL_CALL ChartDocumentWrapper::getSubTitle() { if( !m_xSubTitle.is() ) { + ControllerLockGuard aCtrlLockGuard( Reference< frame::XModel >( m_spChart2ModelContact->getChart2Document(), uno::UNO_QUERY )); m_xSubTitle = new TitleWrapper( TitleHelper::SUB_TITLE, m_spChart2ModelContact ); } return m_xSubTitle; @@ -1514,6 +1517,16 @@ void SAL_CALL ChartDocumentWrapper::setDelegator( const uno::Reference< uno::XInterface >& rDelegator ) throw (uno::RuntimeException) { + if( m_bIsDisposed ) + { + if( rDelegator.is() ) + throw lang::DisposedException( + C2U("ChartDocumentWrapper is disposed" ), + static_cast< ::cppu::OWeakObject* >( this )); + else + return; + } + if( rDelegator.is()) { m_xDelegator = rDelegator; diff --git a/chart2/source/controller/chartapiwrapper/DiagramWrapper.cxx b/chart2/source/controller/chartapiwrapper/DiagramWrapper.cxx index b1db5981f6b3..eb3c76dd2c40 100644 --- a/chart2/source/controller/chartapiwrapper/DiagramWrapper.cxx +++ b/chart2/source/controller/chartapiwrapper/DiagramWrapper.cxx @@ -59,6 +59,7 @@ #include "DisposeHelper.hxx" #include <comphelper/InlineContainer.hxx> #include "WrappedAutomaticPositionProperties.hxx" +#include "CommonConverters.hxx" #include <com/sun/star/beans/PropertyAttribute.hpp> #include <com/sun/star/chart2/XTitled.hpp> @@ -737,49 +738,23 @@ Reference< awt::Point SAL_CALL DiagramWrapper::getPosition() throw (uno::RuntimeException) { - awt::Point aPosition; - - Reference< beans::XPropertySet > xProp( this->getInnerPropertySet() ); - if( xProp.is() ) - { - bool bSet = false; - chart2::RelativePosition aRelativePosition; - uno::Any aAPosition( xProp->getPropertyValue( C2U( "RelativePosition" ) ) ); - if( aAPosition >>= aRelativePosition ) - { - awt::Size aPageSize( m_spChart2ModelContact->GetPageSize() ); - aPosition.X = static_cast<sal_Int32>(aRelativePosition.Primary*aPageSize.Width); - aPosition.Y = static_cast<sal_Int32>(aRelativePosition.Secondary*aPageSize.Height); - - aPosition = RelativePositionHelper::getUpperLeftCornerOfAnchoredObject( - aPosition, DiagramWrapper::getSize(), aRelativePosition.Anchor ); - - bSet = true; - } - if(!bSet) - aPosition = m_spChart2ModelContact->GetDiagramPositionInclusive(); - } - + awt::Point aPosition = ToPoint( m_spChart2ModelContact->GetDiagramRectangleIncludingAxes() ); return aPosition; } void SAL_CALL DiagramWrapper::setPosition( const awt::Point& aPosition ) throw (uno::RuntimeException) { + ControllerLockGuard aCtrlLockGuard( m_spChart2ModelContact->getChartModel() ); Reference< beans::XPropertySet > xProp( this->getInnerPropertySet() ); if( xProp.is() ) { - if( aPosition.X < 0 || aPosition.Y < 0 ) + if( aPosition.X < 0 || aPosition.Y < 0 || aPosition.X > 1 || aPosition.Y > 1 ) { - if( !TitleHelper::getTitle( TitleHelper::X_AXIS_TITLE, m_spChart2ModelContact->getChartModel() ).is() && - !TitleHelper::getTitle( TitleHelper::Y_AXIS_TITLE, m_spChart2ModelContact->getChartModel() ).is() ) - { - DBG_ERROR("DiagramWrapper::setPosition called with negative position -> automatic values are taken instead" ); - uno::Any aEmpty; - xProp->setPropertyValue( C2U( "RelativePosition" ), aEmpty ); - return; - } - //else: The saved didagram size does include the axis title sizes thus the position and size could be negative + DBG_ERROR("DiagramWrapper::setPosition called with a position out of range -> automatic values are taken instead" ); + uno::Any aEmpty; + xProp->setPropertyValue( C2U( "RelativePosition" ), aEmpty ); + return; } awt::Size aPageSize( m_spChart2ModelContact->GetPageSize() ); @@ -789,31 +764,14 @@ void SAL_CALL DiagramWrapper::setPosition( const awt::Point& aPosition ) aRelativePosition.Primary = double(aPosition.X)/double(aPageSize.Width); aRelativePosition.Secondary = double(aPosition.Y)/double(aPageSize.Height); xProp->setPropertyValue( C2U( "RelativePosition" ), uno::makeAny(aRelativePosition) ); + xProp->setPropertyValue( C2U( "PosSizeExcludeAxes" ), uno::makeAny(false) ); } } awt::Size SAL_CALL DiagramWrapper::getSize() throw (uno::RuntimeException) { - awt::Size aSize; - - Reference< beans::XPropertySet > xProp( this->getInnerPropertySet() ); - if( xProp.is() ) - { - bool bSet = false; - chart2::RelativeSize aRelativeSize; - uno::Any aASize( xProp->getPropertyValue( C2U( "RelativeSize" ) ) ); - if(aASize>>=aRelativeSize) - { - awt::Size aPageSize( m_spChart2ModelContact->GetPageSize() ); - aSize.Width = static_cast<sal_Int32>(aRelativeSize.Primary*aPageSize.Width); - aSize.Height = static_cast<sal_Int32>(aRelativeSize.Secondary*aPageSize.Height); - bSet = true; - } - if(!bSet) - aSize = m_spChart2ModelContact->GetDiagramSizeInclusive(); - } - + awt::Size aSize = ToSize( m_spChart2ModelContact->GetDiagramRectangleIncludingAxes() ); return aSize; } @@ -821,6 +779,7 @@ void SAL_CALL DiagramWrapper::setSize( const awt::Size& aSize ) throw (beans::PropertyVetoException, uno::RuntimeException) { + ControllerLockGuard aCtrlLockGuard( m_spChart2ModelContact->getChartModel() ); Reference< beans::XPropertySet > xProp( this->getInnerPropertySet() ); if( xProp.is() ) { @@ -832,18 +791,14 @@ void SAL_CALL DiagramWrapper::setSize( const awt::Size& aSize ) if( aRelativeSize.Primary > 1 || aRelativeSize.Secondary > 1 ) { - if( !TitleHelper::getTitle( TitleHelper::X_AXIS_TITLE, m_spChart2ModelContact->getChartModel() ).is() && - !TitleHelper::getTitle( TitleHelper::Y_AXIS_TITLE, m_spChart2ModelContact->getChartModel() ).is() ) - { - DBG_ERROR("DiagramWrapper::setSize called with sizes bigger than page -> automatic values are taken instead" ); - uno::Any aEmpty; - xProp->setPropertyValue( C2U( "RelativeSize" ), aEmpty ); - return; - } - //else: The saved didagram size does include the axis title sizes thus the position and size could be out of range + DBG_ERROR("DiagramWrapper::setSize called with sizes bigger than page -> automatic values are taken instead" ); + uno::Any aEmpty; + xProp->setPropertyValue( C2U( "RelativeSize" ), aEmpty ); + return; } xProp->setPropertyValue( C2U( "RelativeSize" ), uno::makeAny(aRelativeSize) ); + xProp->setPropertyValue( C2U( "PosSizeExcludeAxes" ), uno::makeAny(false) ); } } @@ -854,6 +809,81 @@ OUString SAL_CALL DiagramWrapper::getShapeType() return C2U( "com.sun.star.chart.Diagram" ); } +// ____ XDiagramPositioning ____ + +void SAL_CALL DiagramWrapper::setAutomaticDiagramPositioning() throw (uno::RuntimeException) +{ + ControllerLockGuard aCtrlLockGuard( m_spChart2ModelContact->getChartModel() ); + uno::Reference< beans::XPropertySet > xDiaProps( this->getDiagram(), uno::UNO_QUERY ); + if( xDiaProps.is() ) + { + xDiaProps->setPropertyValue( C2U( "RelativeSize" ), Any() ); + xDiaProps->setPropertyValue( C2U( "RelativePosition" ), Any() ); + } +} +::sal_Bool SAL_CALL DiagramWrapper::isAutomaticDiagramPositioning( ) throw (uno::RuntimeException) +{ + uno::Reference< beans::XPropertySet > xDiaProps( this->getDiagram(), uno::UNO_QUERY ); + if( xDiaProps.is() ) + { + Any aRelativeSize( xDiaProps->getPropertyValue( C2U( "RelativeSize" ) ) ); + Any aRelativePosition( xDiaProps->getPropertyValue( C2U( "RelativePosition" ) ) ); + if( aRelativeSize.hasValue() && aRelativePosition.hasValue() ) + return false; + } + return true; +} +void SAL_CALL DiagramWrapper::setDiagramPositionExcludingAxes( const awt::Rectangle& rPositionRect ) throw (uno::RuntimeException) +{ + ControllerLockGuard aCtrlLockGuard( m_spChart2ModelContact->getChartModel() ); + DiagramHelper::setDiagramPositioning( m_spChart2ModelContact->getChartModel(), rPositionRect ); + uno::Reference< beans::XPropertySet > xDiaProps( this->getDiagram(), uno::UNO_QUERY ); + if( xDiaProps.is() ) + xDiaProps->setPropertyValue(C2U("PosSizeExcludeAxes"), uno::makeAny(true) ); +} +::sal_Bool SAL_CALL DiagramWrapper::isExcludingDiagramPositioning() throw (uno::RuntimeException) +{ + uno::Reference< beans::XPropertySet > xDiaProps( this->getDiagram(), uno::UNO_QUERY ); + if( xDiaProps.is() ) + { + Any aRelativeSize( xDiaProps->getPropertyValue( C2U( "RelativeSize" ) ) ); + Any aRelativePosition( xDiaProps->getPropertyValue( C2U( "RelativePosition" ) ) ); + if( aRelativeSize.hasValue() && aRelativePosition.hasValue() ) + { + sal_Bool bPosSizeExcludeAxes = false; + xDiaProps->getPropertyValue( C2U( "PosSizeExcludeAxes" ) ) >>= bPosSizeExcludeAxes; + return bPosSizeExcludeAxes; + } + } + return false; +} +awt::Rectangle SAL_CALL DiagramWrapper::calculateDiagramPositionExcludingAxes( ) throw (uno::RuntimeException) +{ + return m_spChart2ModelContact->GetDiagramRectangleExcludingAxes(); +} +void SAL_CALL DiagramWrapper::setDiagramPositionIncludingAxes( const awt::Rectangle& rPositionRect ) throw (uno::RuntimeException) +{ + ControllerLockGuard aCtrlLockGuard( m_spChart2ModelContact->getChartModel() ); + DiagramHelper::setDiagramPositioning( m_spChart2ModelContact->getChartModel(), rPositionRect ); + uno::Reference< beans::XPropertySet > xDiaProps( this->getDiagram(), uno::UNO_QUERY ); + if( xDiaProps.is() ) + xDiaProps->setPropertyValue(C2U("PosSizeExcludeAxes"), uno::makeAny(false) ); +} +awt::Rectangle SAL_CALL DiagramWrapper::calculateDiagramPositionIncludingAxes( ) throw (uno::RuntimeException) +{ + return m_spChart2ModelContact->GetDiagramRectangleIncludingAxes(); +} +void SAL_CALL DiagramWrapper::setDiagramPositionIncludingAxesAndAxisTitles( const awt::Rectangle& rPositionRect ) throw (uno::RuntimeException) +{ + ControllerLockGuard aCtrlLockGuard( m_spChart2ModelContact->getChartModel() ); + awt::Rectangle aRect( m_spChart2ModelContact->SubstractAxisTitleSizes(rPositionRect) ); + DiagramWrapper::setDiagramPositionIncludingAxes( aRect ); +} +::com::sun::star::awt::Rectangle SAL_CALL DiagramWrapper::calculateDiagramPositionIncludingAxesAndAxisTitles( ) throw (::com::sun::star::uno::RuntimeException) +{ + return m_spChart2ModelContact->GetDiagramRectangleIncludingTitle(); +} + // ____ XAxisZSupplier ____ Reference< drawing::XShape > SAL_CALL DiagramWrapper::getZAxisTitle() @@ -1221,7 +1251,13 @@ void WrappedDataRowSourceProperty::setPropertyValue( const Any& rOuterValue, con { ::com::sun::star::chart::ChartDataRowSource eChartDataRowSource = ::com::sun::star::chart::ChartDataRowSource_ROWS; if( ! (rOuterValue >>= eChartDataRowSource) ) - throw lang::IllegalArgumentException( C2U("Property DataRowSource requires ::com::sun::star::chart::ChartDataRowSource value"), 0, 0 ); + { + sal_Int32 nNew = ::com::sun::star::chart::ChartDataRowSource_ROWS; + if( !(rOuterValue >>= nNew) ) + throw lang::IllegalArgumentException( C2U("Property DataRowSource requires ::com::sun::star::chart::ChartDataRowSource value"), 0, 0 ); + else + eChartDataRowSource = ::com::sun::star::chart::ChartDataRowSource(nNew); + } m_aOuterValue = rOuterValue; diff --git a/chart2/source/controller/chartapiwrapper/DiagramWrapper.hxx b/chart2/source/controller/chartapiwrapper/DiagramWrapper.hxx index 96689eec2aac..111e24bd6a8b 100644 --- a/chart2/source/controller/chartapiwrapper/DiagramWrapper.hxx +++ b/chart2/source/controller/chartapiwrapper/DiagramWrapper.hxx @@ -30,12 +30,13 @@ #include "WrappedPropertySet.hxx" #include "ServiceMacros.hxx" #include "DiagramHelper.hxx" -#include <cppuhelper/implbase11.hxx> +#include <cppuhelper/implbase12.hxx> #include <comphelper/uno3.hxx> #include <cppuhelper/interfacecontainer.hxx> #include <com/sun/star/chart2/XChartDocument.hpp> #include <com/sun/star/chart2/XDiagram.hpp> #include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/chart/XDiagramPositioning.hpp> #include <com/sun/star/chart2/XDiagramProvider.hpp> #include <com/sun/star/chart2/XChartTypeTemplate.hpp> #include <com/sun/star/chart2/XChartTypeManager.hpp> @@ -61,7 +62,7 @@ namespace wrapper class Chart2ModelContact; -class DiagramWrapper : public ::cppu::ImplInheritanceHelper11< +class DiagramWrapper : public ::cppu::ImplInheritanceHelper12< WrappedPropertySet , ::com::sun::star::chart::XDiagram , ::com::sun::star::chart::XAxisZSupplier @@ -73,6 +74,7 @@ class DiagramWrapper : public ::cppu::ImplInheritanceHelper11< , ::com::sun::star::lang::XServiceInfo , ::com::sun::star::lang::XComponent // , ::com::sun::star::lang::XEventListener + , ::com::sun::star::chart::XDiagramPositioning , ::com::sun::star::chart2::XDiagramProvider , ::com::sun::star::chart::XSecondAxisTitleSupplier > @@ -209,6 +211,18 @@ public: // virtual void SAL_CALL disposing( const ::com::sun::star::lang::EventObject& Source ) // throw (::com::sun::star::uno::RuntimeException); + // ____ XDiagramPositioning ____ + + virtual void SAL_CALL setAutomaticDiagramPositioning( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL isAutomaticDiagramPositioning( ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setDiagramPositionExcludingAxes( const ::com::sun::star::awt::Rectangle& PositionRect ) throw (::com::sun::star::uno::RuntimeException); + virtual ::sal_Bool SAL_CALL isExcludingDiagramPositioning( ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::awt::Rectangle SAL_CALL calculateDiagramPositionExcludingAxes( ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setDiagramPositionIncludingAxes( const ::com::sun::star::awt::Rectangle& PositionRect ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::awt::Rectangle SAL_CALL calculateDiagramPositionIncludingAxes( ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL setDiagramPositionIncludingAxesAndAxisTitles( const ::com::sun::star::awt::Rectangle& PositionRect ) throw (::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::awt::Rectangle SAL_CALL calculateDiagramPositionIncludingAxesAndAxisTitles( ) throw (::com::sun::star::uno::RuntimeException); + // ____ XDiagramProvider ____ virtual ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDiagram > SAL_CALL getDiagram() diff --git a/chart2/source/controller/chartapiwrapper/LegendWrapper.cxx b/chart2/source/controller/chartapiwrapper/LegendWrapper.cxx index 5d4f3e718ff9..02ffcb942c99 100644 --- a/chart2/source/controller/chartapiwrapper/LegendWrapper.cxx +++ b/chart2/source/controller/chartapiwrapper/LegendWrapper.cxx @@ -242,8 +242,8 @@ void lcl_AddPropertiesToVector( Property( C2U( "Alignment" ), PROP_LEGEND_ALIGNMENT, ::getCppuType( reinterpret_cast< const ::com::sun::star::chart::ChartLegendPosition * >(0)), - beans::PropertyAttribute::BOUND - | beans::PropertyAttribute::MAYBEDEFAULT )); + //#i111967# no PropertyChangeEvent is fired on change so far + beans::PropertyAttribute::MAYBEDEFAULT )); } const Sequence< Property > & lcl_GetPropertySequence() diff --git a/chart2/source/controller/chartapiwrapper/TitleWrapper.cxx b/chart2/source/controller/chartapiwrapper/TitleWrapper.cxx index ec972f8b21ba..20785faa8b66 100644 --- a/chart2/source/controller/chartapiwrapper/TitleWrapper.cxx +++ b/chart2/source/controller/chartapiwrapper/TitleWrapper.cxx @@ -30,6 +30,8 @@ #include "TitleWrapper.hxx" #include "macros.hxx" #include "ContainerHelper.hxx" +#include "ControllerLockGuard.hxx" + #include <comphelper/InlineContainer.hxx> #include <com/sun/star/beans/PropertyAttribute.hpp> #include <com/sun/star/chart2/RelativePosition.hpp> @@ -225,6 +227,9 @@ TitleWrapper::TitleWrapper( ::chart::TitleHelper::eTitleType eTitleType, m_aEventListenerContainer( m_aMutex ), m_eTitleType(eTitleType) { + ControllerLockGuard aCtrlLockGuard( Reference< frame::XModel >( m_spChart2ModelContact->getChart2Document(), uno::UNO_QUERY )); + if( !getTitleObject().is() ) //#i83831# create an empty title at the model, thus references to properties can be mapped mapped correctly + TitleHelper::createTitle( m_eTitleType, OUString(), m_spChart2ModelContact->getChartModel(), m_spChart2ModelContact->m_xContext ); } TitleWrapper::~TitleWrapper() @@ -451,6 +456,33 @@ Any SAL_CALL TitleWrapper::getPropertyDefault( const OUString& rPropertyName ) return aRet; } +void SAL_CALL TitleWrapper::addPropertyChangeListener( const OUString& rPropertyName, const Reference< beans::XPropertyChangeListener >& xListener ) + throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException) +{ + sal_Int32 nHandle = getInfoHelper().getHandleByName( rPropertyName ); + if( CharacterProperties::IsCharacterPropertyHandle( nHandle ) ) + { + Reference< beans::XPropertySet > xPropSet( getFirstCharacterPropertySet(), uno::UNO_QUERY ); + if( xPropSet.is() ) + xPropSet->addPropertyChangeListener( rPropertyName, xListener ); + } + else + WrappedPropertySet::addPropertyChangeListener( rPropertyName, xListener ); +} +void SAL_CALL TitleWrapper::removePropertyChangeListener( const OUString& rPropertyName, const Reference< beans::XPropertyChangeListener >& xListener ) + throw (beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException) +{ + sal_Int32 nHandle = getInfoHelper().getHandleByName( rPropertyName ); + if( CharacterProperties::IsCharacterPropertyHandle( nHandle ) ) + { + Reference< beans::XPropertySet > xPropSet( getFirstCharacterPropertySet(), uno::UNO_QUERY ); + if( xPropSet.is() ) + xPropSet->removePropertyChangeListener( rPropertyName, xListener ); + } + else + WrappedPropertySet::removePropertyChangeListener( rPropertyName, xListener ); +} + // ================================================================================ //ReferenceSizePropertyProvider diff --git a/chart2/source/controller/chartapiwrapper/TitleWrapper.hxx b/chart2/source/controller/chartapiwrapper/TitleWrapper.hxx index fba346702d2a..63902e452ee3 100644 --- a/chart2/source/controller/chartapiwrapper/TitleWrapper.hxx +++ b/chart2/source/controller/chartapiwrapper/TitleWrapper.hxx @@ -104,6 +104,9 @@ protected: virtual void SAL_CALL setPropertyValue( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Any& aValue ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); virtual ::com::sun::star::uno::Any SAL_CALL getPropertyValue( const ::rtl::OUString& PropertyName ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL addPropertyChangeListener( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& xListener ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL removePropertyChangeListener( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& aListener ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::beans::PropertyState SAL_CALL getPropertyState( const ::rtl::OUString& PropertyName ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException); virtual void SAL_CALL setPropertyToDefault( const ::rtl::OUString& PropertyName ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException); diff --git a/chart2/source/controller/chartapiwrapper/WrappedStatisticProperties.cxx b/chart2/source/controller/chartapiwrapper/WrappedStatisticProperties.cxx index fef3e1c10b05..1c7b495bd566 100644 --- a/chart2/source/controller/chartapiwrapper/WrappedStatisticProperties.cxx +++ b/chart2/source/controller/chartapiwrapper/WrappedStatisticProperties.cxx @@ -976,7 +976,6 @@ void WrappedStatisticPropertySetProperty::setValueToSeries( const Reference< beans::XPropertySet >& /* xSeriesPropertySet */ , Reference< beans::XPropertySet > /* xNewValue */ ) const { - OSL_ENSURE( false, "Trying to set a read-only property" ); } //----------------------------------------------------------------------------- diff --git a/chart2/source/controller/chartapiwrapper/WrappedSymbolProperties.cxx b/chart2/source/controller/chartapiwrapper/WrappedSymbolProperties.cxx index ea0b8361ae45..4ca8f7161f6e 100644 --- a/chart2/source/controller/chartapiwrapper/WrappedSymbolProperties.cxx +++ b/chart2/source/controller/chartapiwrapper/WrappedSymbolProperties.cxx @@ -386,7 +386,6 @@ void WrappedSymbolBitmapURLProperty::setValueToSeries( { bool bMatchesPrefix = aNewGraphicURL.matchAsciiL( RTL_CONSTASCII_STRINGPARAM( UNO_NAME_GRAPHOBJ_URLPREFIX )); - OSL_ENSURE( bMatchesPrefix, "Invalid URL for Symbol Bitmap" ); if( bMatchesPrefix ) { GraphicObject aGrObj = GraphicObject( @@ -407,6 +406,7 @@ void WrappedSymbolBitmapURLProperty::setValueToSeries( C2U("URL"), -1, uno::makeAny( aNewGraphicURL ), beans::PropertyState_DIRECT_VALUE ); aSymbol.Graphic.set( xGraphProv->queryGraphic( aArgs )); + OSL_ENSURE( aSymbol.Graphic.is(), "Invalid URL for Symbol Bitmap" ); xSeriesPropertySet->setPropertyValue( C2U("Symbol"), uno::makeAny( aSymbol ) ); } catch( const uno::Exception & ex ) diff --git a/chart2/source/controller/dialogs/TabPages.hrc b/chart2/source/controller/dialogs/TabPages.hrc index ba9a330b250e..1f445083738f 100644 --- a/chart2/source/controller/dialogs/TabPages.hrc +++ b/chart2/source/controller/dialogs/TabPages.hrc @@ -46,7 +46,6 @@ ////#define RBT_DOWNUP 3 ////#define RBT_AUTOORDER 4 -//#define TP_STAT 905 #define FL_TEXTBREAK 3 #define CBX_TEXTBREAK 2 #define CBX_TEXTOVERLAP 4 diff --git a/chart2/source/controller/dialogs/dlg_InsertLegend.src b/chart2/source/controller/dialogs/dlg_InsertLegend.src index 9e957b4b203b..95a1d5516ab5 100644 --- a/chart2/source/controller/dialogs/dlg_InsertLegend.src +++ b/chart2/source/controller/dialogs/dlg_InsertLegend.src @@ -39,9 +39,9 @@ ModalDialog DLG_LEGEND HelpID = SID_INSERT_CHART_LEGEND ; OutputSize = TRUE ; SVLook = TRUE ; - Size = MAP_APPFONT ( 135 , 80 ) ; + Size = MAP_APPFONT ( 156 , 80 ) ; Moveable = TRUE ; - BUTTONS_OK_CANCEL_HELP_STACKED( 79 ) + BUTTONS_OK_CANCEL_HELP_STACKED( 101 ) RESOURCE_LEGENDDISPLAY( 6, 6 ) RESOURCE_LEGENDPOSITION( 15, 6 + RSC_CD_FIXEDTEXT_HEIGHT +6 ) }; diff --git a/chart2/source/controller/dialogs/res_LegendPosition_tmpl.hrc b/chart2/source/controller/dialogs/res_LegendPosition_tmpl.hrc index 4218b322a948..17f6518eabe4 100644 --- a/chart2/source/controller/dialogs/res_LegendPosition_tmpl.hrc +++ b/chart2/source/controller/dialogs/res_LegendPosition_tmpl.hrc @@ -35,7 +35,7 @@ CheckBox CBX_SHOWLEGEND \ { \ HelpID = HID_SCH_LEGEND_SHOW ; \ Pos = MAP_APPFONT ( xpos , ypos ) ; \ - Size = MAP_APPFONT ( 67 , 12 ) ; \ + Size = MAP_APPFONT ( 95 , 12 ) ; \ Text [ en-US ] = "~Display legend" ; \ TabStop = TRUE ; \ }; diff --git a/chart2/source/controller/dialogs/tp_ChartType.cxx b/chart2/source/controller/dialogs/tp_ChartType.cxx index 6460ba7ebb99..ec6c1d2a1c10 100644 --- a/chart2/source/controller/dialogs/tp_ChartType.cxx +++ b/chart2/source/controller/dialogs/tp_ChartType.cxx @@ -1153,7 +1153,7 @@ void ChartTypeTabPage::initializePage() } } -sal_Bool ChartTypeTabPage::commitPage( CommitPageReason /*eReason*/ ) +sal_Bool ChartTypeTabPage::commitPage( ::svt::WizardTypes::CommitPageReason /*eReason*/ ) { //commit changes to model if( !m_bDoLiveUpdate && m_pCurrentMainType ) diff --git a/chart2/source/controller/dialogs/tp_ChartType.hxx b/chart2/source/controller/dialogs/tp_ChartType.hxx index 233d9ee910c6..b40cbb1956db 100644 --- a/chart2/source/controller/dialogs/tp_ChartType.hxx +++ b/chart2/source/controller/dialogs/tp_ChartType.hxx @@ -73,7 +73,7 @@ public: virtual ~ChartTypeTabPage(); virtual void initializePage(); - virtual sal_Bool commitPage( CommitPageReason eReason ); + virtual sal_Bool commitPage( ::svt::WizardTypes::CommitPageReason eReason ); virtual ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartTypeTemplate > getCurrentTemplate() const; diff --git a/chart2/source/controller/dialogs/tp_DataSource.cxx b/chart2/source/controller/dialogs/tp_DataSource.cxx index 10f0421d4013..7c5f0fb3967b 100644 --- a/chart2/source/controller/dialogs/tp_DataSource.cxx +++ b/chart2/source/controller/dialogs/tp_DataSource.cxx @@ -382,10 +382,10 @@ void DataSourceTabPage::DeactivatePage() void DataSourceTabPage::commitPage() { - commitPage(eFinish); + commitPage(::svt::WizardTypes::eFinish); } -sal_Bool DataSourceTabPage::commitPage( CommitPageReason /*eReason*/ ) +sal_Bool DataSourceTabPage::commitPage( ::svt::WizardTypes::CommitPageReason /*eReason*/ ) { //ranges may have been edited in the meanwhile (dirty is true in that case here) if( isValid() ) diff --git a/chart2/source/controller/dialogs/tp_DataSource.hxx b/chart2/source/controller/dialogs/tp_DataSource.hxx index 44ffa2b3cdf2..e65b503bfcc2 100644 --- a/chart2/source/controller/dialogs/tp_DataSource.hxx +++ b/chart2/source/controller/dialogs/tp_DataSource.hxx @@ -89,7 +89,7 @@ public: protected: // OWizardPage virtual void ActivatePage(); - virtual sal_Bool commitPage( CommitPageReason eReason ); + virtual sal_Bool commitPage( ::svt::WizardTypes::CommitPageReason eReason ); //TabPage virtual void DeactivatePage(); diff --git a/chart2/source/controller/dialogs/tp_RangeChooser.cxx b/chart2/source/controller/dialogs/tp_RangeChooser.cxx index f1e4a1e5ff64..3ba6ca0f74b2 100644 --- a/chart2/source/controller/dialogs/tp_RangeChooser.cxx +++ b/chart2/source/controller/dialogs/tp_RangeChooser.cxx @@ -221,10 +221,10 @@ void RangeChooserTabPage::DeactivatePage() void RangeChooserTabPage::commitPage() { - commitPage(eFinish); + commitPage(::svt::WizardTypes::eFinish); } -sal_Bool RangeChooserTabPage::commitPage( CommitPageReason /*eReason*/ ) +sal_Bool RangeChooserTabPage::commitPage( ::svt::WizardTypes::CommitPageReason /*eReason*/ ) { //ranges may have been edited in the meanwhile (dirty is true in that case here) if( isValid() ) diff --git a/chart2/source/controller/dialogs/tp_RangeChooser.hxx b/chart2/source/controller/dialogs/tp_RangeChooser.hxx index 9a2b05628fa2..4d985669195c 100644 --- a/chart2/source/controller/dialogs/tp_RangeChooser.hxx +++ b/chart2/source/controller/dialogs/tp_RangeChooser.hxx @@ -73,7 +73,7 @@ protected: //methods //OWizardPage virtual void ActivatePage(); - virtual sal_Bool commitPage( CommitPageReason eReason ); + virtual sal_Bool commitPage( ::svt::WizardTypes::CommitPageReason eReason ); //TabPage virtual void DeactivatePage(); diff --git a/chart2/source/controller/dialogs/tp_Wizard_TitlesAndObjects.cxx b/chart2/source/controller/dialogs/tp_Wizard_TitlesAndObjects.cxx index 8c97de81dd5d..03988116854e 100644 --- a/chart2/source/controller/dialogs/tp_Wizard_TitlesAndObjects.cxx +++ b/chart2/source/controller/dialogs/tp_Wizard_TitlesAndObjects.cxx @@ -125,7 +125,7 @@ void TitlesAndObjectsTabPage::initializePage() m_bCommitToModel = true; } -sal_Bool TitlesAndObjectsTabPage::commitPage( CommitPageReason /*eReason*/ ) +sal_Bool TitlesAndObjectsTabPage::commitPage( ::svt::WizardTypes::CommitPageReason /*eReason*/ ) { if( m_apTitleResources->IsModified() ) //titles may have changed in the meanwhile commitToModel(); diff --git a/chart2/source/controller/dialogs/tp_Wizard_TitlesAndObjects.hxx b/chart2/source/controller/dialogs/tp_Wizard_TitlesAndObjects.hxx index d6bb869c2f6d..1cd9c6162a46 100644 --- a/chart2/source/controller/dialogs/tp_Wizard_TitlesAndObjects.hxx +++ b/chart2/source/controller/dialogs/tp_Wizard_TitlesAndObjects.hxx @@ -59,7 +59,7 @@ public: virtual ~TitlesAndObjectsTabPage(); virtual void initializePage(); - virtual sal_Bool commitPage( CommitPageReason eReason ); + virtual sal_Bool commitPage( ::svt::WizardTypes::CommitPageReason eReason ); virtual bool canAdvance() const; protected: diff --git a/chart2/source/controller/drawinglayer/DrawViewWrapper.cxx b/chart2/source/controller/drawinglayer/DrawViewWrapper.cxx index fbcca6a26bde..48c96a715c5f 100644 --- a/chart2/source/controller/drawinglayer/DrawViewWrapper.cxx +++ b/chart2/source/controller/drawinglayer/DrawViewWrapper.cxx @@ -30,6 +30,7 @@ #include "DrawViewWrapper.hxx" #include "chartview/DrawModelWrapper.hxx" #include "ConfigurationAccess.hxx" +#include "macros.hxx" #include <unotools/lingucfg.hxx> #include <editeng/langitem.hxx> @@ -241,6 +242,14 @@ SdrObject* DrawViewWrapper::getHitObject( const Point& rPnt ) const if( pRet ) { + //ignore some special shapes + rtl::OUString aShapeName = pRet->GetName(); + if( aShapeName.match(C2U("PlotAreaIncludingAxes")) || aShapeName.match(C2U("PlotAreaExcludingAxes")) ) + { + pRet->SetMarkProtect( true ); + return getHitObject( rPnt ); + } + //3d objects need a special treatment //because the simple PickObj method is not accurate in this case for performance reasons E3dObject* pE3d = dynamic_cast< E3dObject* >(pRet); diff --git a/chart2/source/controller/inc/PositionAndSizeHelper.hxx b/chart2/source/controller/inc/PositionAndSizeHelper.hxx index 43392e7a8235..312c92997055 100644 --- a/chart2/source/controller/inc/PositionAndSizeHelper.hxx +++ b/chart2/source/controller/inc/PositionAndSizeHelper.hxx @@ -51,8 +51,7 @@ public: static bool moveObject( const rtl::OUString& rObjectCID , const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& xChartModel , const ::com::sun::star::awt::Rectangle& rNewPositionAndSize - , const ::com::sun::star::awt::Rectangle& rPageRectangle - , ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > xChartView ); + , const ::com::sun::star::awt::Rectangle& rPageRectangle ); }; //............................................................................. diff --git a/chart2/source/controller/itemsetwrapper/SchWhichPairs.hxx b/chart2/source/controller/itemsetwrapper/SchWhichPairs.hxx index b3c4b7ea19f7..f7ddeb42c11e 100644 --- a/chart2/source/controller/itemsetwrapper/SchWhichPairs.hxx +++ b/chart2/source/controller/itemsetwrapper/SchWhichPairs.hxx @@ -87,27 +87,6 @@ const USHORT nGridWhichPairs[] = 0 }; -const USHORT nChartWhichPairs[] = -{ - SCHATTR_STYLE_START,SCHATTR_STYLE_END, // 59 - 68 sch/schattr.hxx - 0 -}; - -const USHORT nDiagramAreaWhichPairs[] = -{ - XATTR_LINE_FIRST, XATTR_LINE_LAST, // 1000 - 1016 svx/xdef.hxx - XATTR_FILL_FIRST, XATTR_FILL_LAST, // 1018 - 1046 svx/xdef.hxx - 0 -}; - -const USHORT nAreaAndChartWhichPairs[] = // pairs for chart AND area -{ - XATTR_LINE_FIRST, XATTR_LINE_LAST, // 1000 - 1016 svx/xdef.hxx - XATTR_FILL_FIRST, XATTR_FILL_LAST, // 1018 - 1046 svx/xdef.hxx - SCHATTR_STYLE_START,SCHATTR_STYLE_END, // 59 - 68 sch/schattr.hxx - 0 -}; - const USHORT nLegendWhichPairs[] = { XATTR_LINE_FIRST, XATTR_LINE_LAST, // 1000 - 1016 svx/xdef.hxx diff --git a/chart2/source/controller/main/ChartController.cxx b/chart2/source/controller/main/ChartController.cxx index 4c0c7dc38ae3..bf8afc65e78f 100644 --- a/chart2/source/controller/main/ChartController.cxx +++ b/chart2/source/controller/main/ChartController.cxx @@ -410,7 +410,7 @@ APPHELPER_XSERVICEINFO_IMPL(ChartController,CHART_CONTROLLER_SERVICE_IMPLEMENTAT m_apDropTargetHelper.reset(); } { - awt::Size aPageSize( ChartModelHelper::getPageSize(m_aModel->getModel()) ); + awt::Size aPageSize( ChartModelHelper::getPageSize(getModel()) ); // calls to VCL ::vos::OGuard aSolarGuard( Application::GetSolarMutex()); @@ -420,7 +420,7 @@ APPHELPER_XSERVICEINFO_IMPL(ChartController,CHART_CONTROLLER_SERVICE_IMPLEMENTAT m_pChartWindow->Show(); m_apDropTargetHelper.reset( new ChartDropTargetHelper( m_pChartWindow->GetDropTarget(), - uno::Reference< chart2::XChartDocument >( m_aModel->getModel(), uno::UNO_QUERY ))); + uno::Reference< chart2::XChartDocument >( getModel(), uno::UNO_QUERY ))); impl_createDrawViewController(); } @@ -514,7 +514,7 @@ void SAL_CALL ChartController::modeChanged( const util::ModeChangeEvent& rEvent if( m_aSelection.hasSelection() ) this->impl_selectObjectAndNotiy(); else - ChartModelHelper::triggerRangeHighlighting( m_aModel->getModel() ); + ChartModelHelper::triggerRangeHighlighting( getModel() ); impl_initializeAccessible(); @@ -601,7 +601,7 @@ void SAL_CALL ChartController::modeChanged( const util::ModeChangeEvent& rEvent //select chart area per default: select( uno::makeAny( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_PAGE, rtl::OUString() ) ) ); - uno::Reference< lang::XMultiServiceFactory > xFact( m_aModel->getModel(), uno::UNO_QUERY ); + uno::Reference< lang::XMultiServiceFactory > xFact( getModel(), uno::UNO_QUERY ); if( xFact.is()) { m_xChartView = xFact->createInstance( CHART_VIEW_SERVICE_NAME ); @@ -615,7 +615,7 @@ void SAL_CALL ChartController::modeChanged( const util::ModeChangeEvent& rEvent if( m_pChartWindow ) m_pChartWindow->Invalidate(); - uno::Reference< chart2::XUndoSupplier > xUndoSupplier( m_aModel->getModel(), uno::UNO_QUERY ); + uno::Reference< chart2::XUndoSupplier > xUndoSupplier( getModel(), uno::UNO_QUERY ); if( xUndoSupplier.is()) m_xUndoManager.set( xUndoSupplier->getUndoManager()); @@ -735,7 +735,7 @@ void ChartController::impl_createDrawViewController() if( m_pDrawModelWrapper ) { m_pDrawViewWrapper = new DrawViewWrapper(&m_pDrawModelWrapper->getSdrModel(),m_pChartWindow,true); - m_pDrawViewWrapper->attachParentReferenceDevice( m_aModel->getModel()); + m_pDrawViewWrapper->attachParentReferenceDevice( getModel() ); } } } @@ -776,7 +776,7 @@ void ChartController::impl_deleteDrawViewController() if( m_aModel.is()) { uno::Reference< view::XSelectionChangeListener > xSelectionChangeListener; - uno::Reference< chart2::data::XDataReceiver > xDataReceiver( m_aModel->getModel(), uno::UNO_QUERY ); + uno::Reference< chart2::data::XDataReceiver > xDataReceiver( getModel(), uno::UNO_QUERY ); if( xDataReceiver.is() ) xSelectionChangeListener = uno::Reference< view::XSelectionChangeListener >( xDataReceiver->getRangeHighlighter(), uno::UNO_QUERY ); if( xSelectionChangeListener.is() ) @@ -874,7 +874,7 @@ void ChartController::impl_deleteDrawViewController() throw(uno::RuntimeException) { ::vos::OGuard aGuard( Application::GetSolarMutex()); - if( m_aLifeTimeManager.impl_isDisposed() ) + if( m_aLifeTimeManager.impl_isDisposed(false) ) return; //behave passive if already disposed or suspended //--remove listener @@ -959,6 +959,8 @@ bool ChartController::impl_releaseThisModel( const uno::Reference< uno::XInterfa bReleaseModel = true; } } + if( bReleaseModel ) + m_aDispatchContainer.setModel( 0 ); return bReleaseModel; } @@ -1059,7 +1061,7 @@ bool lcl_isFormatObjectCommand( const rtl::OString& aCommand ) , sal_Int32 /* nSearchFlags */) throw(uno::RuntimeException) { - if ( !m_aLifeTimeManager.impl_isDisposed() ) + if ( !m_aLifeTimeManager.impl_isDisposed() && getModel().is() ) { if( rTargetFrameName.getLength() && rTargetFrameName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM("_self"))) @@ -1103,7 +1105,7 @@ bool lcl_isFormatObjectCommand( const rtl::OString& aCommand ) //---------------------------------- else if(aCommand.equals("Update")) //Update Chart { - ChartViewHelper::setViewToDirtyState( m_aModel->getModel() ); + ChartViewHelper::setViewToDirtyState( getModel() ); if( m_pChartWindow ) m_pChartWindow->Invalidate(); } @@ -1325,12 +1327,12 @@ void SAL_CALL ChartController::executeDispatch_ChartType() { // using assignment for broken gcc 3.3 UndoLiveUpdateGuard aUndoGuard = UndoLiveUpdateGuard( - ::rtl::OUString( String( SchResId( STR_ACTION_EDIT_CHARTTYPE ))), m_xUndoManager, m_aModel->getModel() ); + ::rtl::OUString( String( SchResId( STR_ACTION_EDIT_CHARTTYPE ))), m_xUndoManager, getModel() ); // /-- ::vos::OGuard aSolarGuard( Application::GetSolarMutex()); //prepare and open dialog - ChartTypeDialog aDlg( m_pChartWindow, m_aModel->getModel(), m_xCC ); + ChartTypeDialog aDlg( m_pChartWindow, getModel(), m_xCC ); if( aDlg.Execute() == RET_OK ) { impl_adaptDataSeriesAutoResize(); @@ -1343,14 +1345,14 @@ void SAL_CALL ChartController::executeDispatch_SourceData() { //------------------------------------------------------------- //convert properties to ItemSet - uno::Reference< XChartDocument > xChartDoc( m_aModel->getModel(), uno::UNO_QUERY ); + uno::Reference< XChartDocument > xChartDoc( getModel(), uno::UNO_QUERY ); DBG_ASSERT( xChartDoc.is(), "Invalid XChartDocument" ); if( !xChartDoc.is()) return; // using assignment for broken gcc 3.3 UndoLiveUpdateGuard aUndoGuard = UndoLiveUpdateGuard( - ::rtl::OUString( String( SchResId( STR_ACTION_EDIT_DATA_RANGES ))), m_xUndoManager, m_aModel->getModel() ); + ::rtl::OUString( String( SchResId( STR_ACTION_EDIT_DATA_RANGES ))), m_xUndoManager, getModel() ); if( xChartDoc.is()) { // /-- @@ -1367,20 +1369,20 @@ void SAL_CALL ChartController::executeDispatch_SourceData() void SAL_CALL ChartController::executeDispatch_MoveSeries( sal_Bool bForward ) { - ControllerLockGuard aCLGuard( m_aModel->getModel()); + ControllerLockGuard aCLGuard( getModel() ); //get selected series ::rtl::OUString aObjectCID(m_aSelection.getSelectedCID()); uno::Reference< XDataSeries > xGivenDataSeries( ObjectIdentifier::getDataSeriesForCID( //yyy todo also legendentries and labels? - aObjectCID, m_aModel->getModel() ) ); + aObjectCID, getModel() ) ); UndoGuardWithSelection aUndoGuard( ActionDescriptionProvider::createDescription( (bForward ? ActionDescriptionProvider::MOVE_TOTOP : ActionDescriptionProvider::MOVE_TOBOTTOM), ::rtl::OUString( String( SchResId( STR_OBJECT_DATASERIES )))), - m_xUndoManager, m_aModel->getModel()); + m_xUndoManager, getModel()); - bool bChanged = DiagramHelper::moveSeries( ChartModelHelper::findDiagram( m_aModel->getModel() ), xGivenDataSeries, bForward ); + bool bChanged = DiagramHelper::moveSeries( ChartModelHelper::findDiagram( getModel() ), xGivenDataSeries, bForward ); if( bChanged ) { m_aSelection.setSelection( ObjectIdentifier::getMovedSeriesCID( aObjectCID, bForward ) ); @@ -1432,7 +1434,7 @@ void SAL_CALL ChartController::modified( const lang::EventObject& /* aEvent */ ) { // the source can also be a subobject of the ChartModel // @todo: change the source in ChartModel to always be the model itself ? -// if( m_aModel->getModel() == aEvent.Source ) +// if( getModel() == aEvent.Source ) //todo? update menu states ? @@ -1511,7 +1513,7 @@ void ChartController::impl_initializeAccessible( const uno::Reference< lang::XIn uno::Sequence< uno::Any > aArguments(5); uno::Reference<view::XSelectionSupplier> xSelectionSupplier(this); aArguments[0]=uno::makeAny(xSelectionSupplier); - uno::Reference<frame::XModel> xModel(m_aModel->getModel()); + uno::Reference<frame::XModel> xModel(getModel()); aArguments[1]=uno::makeAny(xModel); aArguments[2]=uno::makeAny(m_xChartView); uno::Reference< XAccessible > xParent; diff --git a/chart2/source/controller/main/ChartController.hxx b/chart2/source/controller/main/ChartController.hxx index 8deffe47396f..f2b64eb7a9c5 100644 --- a/chart2/source/controller/main/ChartController.hxx +++ b/chart2/source/controller/main/ChartController.hxx @@ -597,7 +597,7 @@ private: //private methods sal_Bool impl_isDisposedOrSuspended() const; - ::std::auto_ptr< ReferenceSizeProvider > impl_createReferenceSizeProvider() const; + ::std::auto_ptr< ReferenceSizeProvider > impl_createReferenceSizeProvider(); void impl_adaptDataSeriesAutoResize(); void impl_createDrawViewController(); @@ -725,6 +725,8 @@ private: void impl_SetMousePointer( const MouseEvent & rEvent ); void impl_ClearSelection(); + + void impl_switchDiagramPositioningToExcludingPositioning(); }; //............................................................................. diff --git a/chart2/source/controller/main/ChartController_EditData.cxx b/chart2/source/controller/main/ChartController_EditData.cxx index 5b6d9c1a60b7..0248732a63a7 100644 --- a/chart2/source/controller/main/ChartController_EditData.cxx +++ b/chart2/source/controller/main/ChartController_EditData.cxx @@ -54,7 +54,7 @@ namespace chart void ChartController::executeDispatch_EditData() { - Reference< chart2::XChartDocument > xChartDoc( m_aModel->getModel(), uno::UNO_QUERY ); + Reference< chart2::XChartDocument > xChartDoc( getModel(), uno::UNO_QUERY ); if( xChartDoc.is()) { Window* pParent( NULL ); @@ -67,7 +67,7 @@ void ChartController::executeDispatch_EditData() // using assignment for broken gcc 3.3 UndoLiveUpdateGuardWithData aUndoGuard = UndoLiveUpdateGuardWithData( ::rtl::OUString( String( SchResId( STR_ACTION_EDIT_CHART_DATA ))), - m_xUndoManager, m_aModel->getModel()); + m_xUndoManager, getModel() ); DataEditor aDataEditorDialog( pParent, xChartDoc, m_xCC ); // the dialog has no OK/Cancel aDataEditorDialog.Execute(); diff --git a/chart2/source/controller/main/ChartController_Insert.cxx b/chart2/source/controller/main/ChartController_Insert.cxx index 13b0174a7d02..0a7a4057ef9a 100644 --- a/chart2/source/controller/main/ChartController_Insert.cxx +++ b/chart2/source/controller/main/ChartController_Insert.cxx @@ -122,12 +122,12 @@ void ChartController::executeDispatch_InsertAxes() UndoGuard aUndoGuard( ActionDescriptionProvider::createDescription( ActionDescriptionProvider::INSERT, ::rtl::OUString( String( SchResId( STR_OBJECT_AXES )))), - m_xUndoManager, m_aModel->getModel() ); + m_xUndoManager, getModel() ); try { InsertAxisOrGridDialogData aDialogInput; - uno::Reference< XDiagram > xDiagram = ChartModelHelper::findDiagram(m_aModel->getModel()); + uno::Reference< XDiagram > xDiagram = ChartModelHelper::findDiagram(getModel()); AxisHelper::getAxisOrGridExcistence( aDialogInput.aExistenceList, xDiagram, sal_True ); AxisHelper::getAxisOrGridPossibilities( aDialogInput.aPossibilityList, xDiagram, sal_True ); @@ -136,7 +136,7 @@ void ChartController::executeDispatch_InsertAxes() if( aDlg.Execute() == RET_OK ) { // lock controllers till end of block - ControllerLockGuard aCLGuard( m_aModel->getModel()); + ControllerLockGuard aCLGuard( getModel() ); InsertAxisOrGridDialogData aDialogOutput; aDlg.getResult( aDialogOutput ); @@ -160,12 +160,12 @@ void ChartController::executeDispatch_InsertGrid() UndoGuard aUndoGuard( ActionDescriptionProvider::createDescription( ActionDescriptionProvider::INSERT, ::rtl::OUString( String( SchResId( STR_OBJECT_GRIDS )))), - m_xUndoManager, m_aModel->getModel() ); + m_xUndoManager, getModel() ); try { InsertAxisOrGridDialogData aDialogInput; - uno::Reference< XDiagram > xDiagram = ChartModelHelper::findDiagram(m_aModel->getModel()); + uno::Reference< XDiagram > xDiagram = ChartModelHelper::findDiagram(getModel()); AxisHelper::getAxisOrGridExcistence( aDialogInput.aExistenceList, xDiagram, sal_False ); AxisHelper::getAxisOrGridPossibilities( aDialogInput.aPossibilityList, xDiagram, sal_False ); @@ -174,7 +174,7 @@ void ChartController::executeDispatch_InsertGrid() if( aDlg.Execute() == RET_OK ) { // lock controllers till end of block - ControllerLockGuard aCLGuard( m_aModel->getModel()); + ControllerLockGuard aCLGuard( getModel() ); InsertAxisOrGridDialogData aDialogOutput; aDlg.getResult( aDialogOutput ); bool bChanged = AxisHelper::changeVisibilityOfGrids( xDiagram @@ -197,22 +197,22 @@ void ChartController::executeDispatch_InsertTitles() UndoGuard aUndoGuard( ActionDescriptionProvider::createDescription( ActionDescriptionProvider::INSERT, ::rtl::OUString( String( SchResId( STR_OBJECT_TITLES )))), - m_xUndoManager, m_aModel->getModel() ); + m_xUndoManager, getModel() ); try { TitleDialogData aDialogInput; - aDialogInput.readFromModel( m_aModel->getModel() ); + aDialogInput.readFromModel( getModel() ); ::vos::OGuard aGuard( Application::GetSolarMutex()); SchTitleDlg aDlg( m_pChartWindow, aDialogInput ); if( aDlg.Execute() == RET_OK ) { // lock controllers till end of block - ControllerLockGuard aCLGuard( m_aModel->getModel()); + ControllerLockGuard aCLGuard( getModel() ); TitleDialogData aDialogOutput( impl_createReferenceSizeProvider()); aDlg.getResult( aDialogOutput ); - bool bChanged = aDialogOutput.writeDifferenceToModel( m_aModel->getModel(), m_xCC, &aDialogInput ); + bool bChanged = aDialogOutput.writeDifferenceToModel( getModel(), m_xCC, &aDialogInput ); if( bChanged ) aUndoGuard.commitAction(); } @@ -228,9 +228,9 @@ void ChartController::executeDispatch_DeleteLegend() UndoGuard aUndoGuard( ActionDescriptionProvider::createDescription( ActionDescriptionProvider::DELETE, ::rtl::OUString( String( SchResId( STR_OBJECT_LEGEND )))), - m_xUndoManager, m_aModel->getModel() ); + m_xUndoManager, getModel() ); - LegendHelper::hideLegend( m_aModel->getModel() ); + LegendHelper::hideLegend( getModel() ); aUndoGuard.commitAction(); } @@ -239,9 +239,9 @@ void ChartController::executeDispatch_InsertLegend() UndoGuard aUndoGuard( ActionDescriptionProvider::createDescription( ActionDescriptionProvider::INSERT, ::rtl::OUString( String( SchResId( STR_OBJECT_LEGEND )))), - m_xUndoManager, m_aModel->getModel() ); + m_xUndoManager, getModel() ); - Reference< chart2::XLegend > xLegend = LegendHelper::showLegend( m_aModel->getModel(), m_xCC ); + Reference< chart2::XLegend > xLegend = LegendHelper::showLegend( getModel(), m_xCC ); aUndoGuard.commitAction(); } @@ -250,19 +250,19 @@ void ChartController::executeDispatch_OpenLegendDialog() UndoGuard aUndoGuard( ActionDescriptionProvider::createDescription( ActionDescriptionProvider::INSERT, ::rtl::OUString( String( SchResId( STR_OBJECT_LEGEND )))), - m_xUndoManager, m_aModel->getModel() ); + m_xUndoManager, getModel() ); try { //prepare and open dialog ::vos::OGuard aGuard( Application::GetSolarMutex()); SchLegendDlg aDlg( m_pChartWindow, m_xCC ); - aDlg.init( m_aModel->getModel() ); + aDlg.init( getModel() ); if( aDlg.Execute() == RET_OK ) { // lock controllers till end of block - ControllerLockGuard aCLGuard( m_aModel->getModel() ); - bool bChanged = aDlg.writeToModel( m_aModel->getModel() ); + ControllerLockGuard aCLGuard( getModel() ); + bool bChanged = aDlg.writeToModel( getModel() ); if( bChanged ) aUndoGuard.commitAction(); } @@ -281,11 +281,11 @@ void ChartController::executeDispatch_InsertMenu_DataLabels() UndoGuard aUndoGuard( ActionDescriptionProvider::createDescription( ActionDescriptionProvider::INSERT, ::rtl::OUString( String( SchResId( STR_OBJECT_DATALABELS )))), - m_xUndoManager, m_aModel->getModel() ); + m_xUndoManager, getModel() ); //if a series is selected insert labels for that series only: uno::Reference< chart2::XDataSeries > xSeries( - ObjectIdentifier::getDataSeriesForCID( m_aSelection.getSelectedCID(), m_aModel->getModel()), uno::UNO_QUERY ); + ObjectIdentifier::getDataSeriesForCID( m_aSelection.getSelectedCID(), getModel()), uno::UNO_QUERY ); if( xSeries.is() ) { // add labels @@ -305,10 +305,10 @@ void ChartController::executeDispatch_InsertMenu_DataLabels() try { wrapper::AllDataLabelItemConverter aItemConverter( - m_aModel->getModel(), + getModel(), m_pDrawModelWrapper->GetItemPool(), m_pDrawModelWrapper->getSdrModel(), - uno::Reference< lang::XMultiServiceFactory >( m_aModel->getModel(), uno::UNO_QUERY )); + uno::Reference< lang::XMultiServiceFactory >( getModel(), uno::UNO_QUERY )); SfxItemSet aItemSet = aItemConverter.CreateEmptyItemSet(); aItemConverter.FillItemSet( aItemSet ); @@ -316,7 +316,7 @@ void ChartController::executeDispatch_InsertMenu_DataLabels() ::vos::OGuard aGuard( Application::GetSolarMutex()); //get number formatter - uno::Reference< util::XNumberFormatsSupplier > xNumberFormatsSupplier( m_aModel->getModel(), uno::UNO_QUERY ); + uno::Reference< util::XNumberFormatsSupplier > xNumberFormatsSupplier( getModel(), uno::UNO_QUERY ); NumberFormatterWrapper aNumberFormatterWrapper( xNumberFormatsSupplier ); SvNumberFormatter* pNumberFormatter = aNumberFormatterWrapper.getSvNumberFormatter(); @@ -327,7 +327,7 @@ void ChartController::executeDispatch_InsertMenu_DataLabels() SfxItemSet aOutItemSet = aItemConverter.CreateEmptyItemSet(); aDlg.FillItemSet( aOutItemSet ); // lock controllers till end of block - ControllerLockGuard aCLGuard( m_aModel->getModel()); + ControllerLockGuard aCLGuard( getModel() ); bool bChanged = aItemConverter.ApplyItemSet( aOutItemSet );//model should be changed now if( bChanged ) aUndoGuard.commitAction(); @@ -343,7 +343,7 @@ void ChartController::executeDispatch_InsertMenu_YErrorBars() { //if a series is selected insert error bars for that series only: uno::Reference< chart2::XDataSeries > xSeries( - ObjectIdentifier::getDataSeriesForCID( m_aSelection.getSelectedCID(), m_aModel->getModel()), uno::UNO_QUERY ); + ObjectIdentifier::getDataSeriesForCID( m_aSelection.getSelectedCID(), getModel() ), uno::UNO_QUERY ); if( xSeries.is()) { executeDispatch_InsertYErrorBars(); @@ -354,12 +354,12 @@ void ChartController::executeDispatch_InsertMenu_YErrorBars() UndoGuard aUndoGuard( ActionDescriptionProvider::createDescription( ActionDescriptionProvider::INSERT, ObjectNameProvider::getName_ObjectForAllSeries( OBJECTTYPE_DATA_ERRORS ) ), - m_xUndoManager, m_aModel->getModel() ); + m_xUndoManager, getModel() ); try { wrapper::AllSeriesStatisticsConverter aItemConverter( - m_aModel->getModel(), m_pDrawModelWrapper->GetItemPool() ); + getModel(), m_pDrawModelWrapper->GetItemPool() ); SfxItemSet aItemSet = aItemConverter.CreateEmptyItemSet(); aItemConverter.FillItemSet( aItemSet ); @@ -367,9 +367,9 @@ void ChartController::executeDispatch_InsertMenu_YErrorBars() ::vos::OGuard aGuard( Application::GetSolarMutex()); InsertErrorBarsDialog aDlg( m_pChartWindow, aItemSet, - uno::Reference< chart2::XChartDocument >( m_aModel->getModel(), uno::UNO_QUERY )); + uno::Reference< chart2::XChartDocument >( getModel(), uno::UNO_QUERY )); aDlg.SetAxisMinorStepWidthForErrorBarDecimals( - InsertErrorBarsDialog::getAxisMinorStepWidthForErrorBarDecimals( m_aModel->getModel(), m_xChartView, rtl::OUString() ) ); + InsertErrorBarsDialog::getAxisMinorStepWidthForErrorBarDecimals( getModel(), m_xChartView, rtl::OUString() ) ); if( aDlg.Execute() == RET_OK ) { @@ -377,7 +377,7 @@ void ChartController::executeDispatch_InsertMenu_YErrorBars() aDlg.FillItemSet( aOutItemSet ); // lock controllers till end of block - ControllerLockGuard aCLGuard( m_aModel->getModel()); + ControllerLockGuard aCLGuard( getModel() ); bool bChanged = aItemConverter.ApplyItemSet( aOutItemSet );//model should be changed now if( bChanged ) aUndoGuard.commitAction(); @@ -394,9 +394,9 @@ void ChartController::executeDispatch_InsertMeanValue() UndoGuard aUndoGuard( ActionDescriptionProvider::createDescription( ActionDescriptionProvider::INSERT, ::rtl::OUString( String( SchResId( STR_OBJECT_AVERAGE_LINE )))), - m_xUndoManager, m_aModel->getModel()); + m_xUndoManager, getModel() ); lcl_InsertMeanValueLine( m_xCC ).operator()( - ObjectIdentifier::getDataSeriesForCID( m_aSelection.getSelectedCID(), m_aModel->getModel())); + ObjectIdentifier::getDataSeriesForCID( m_aSelection.getSelectedCID(), getModel() )); aUndoGuard.commitAction(); } @@ -405,10 +405,10 @@ void ChartController::executeDispatch_InsertMenu_MeanValues() UndoGuard aUndoGuard( ActionDescriptionProvider::createDescription( ActionDescriptionProvider::INSERT, ::rtl::OUString( String( SchResId( STR_OBJECT_AVERAGE_LINE )))), - m_xUndoManager, m_aModel->getModel() ); + m_xUndoManager, getModel() ); uno::Reference< chart2::XDataSeries > xSeries( - ObjectIdentifier::getDataSeriesForCID( m_aSelection.getSelectedCID(), m_aModel->getModel()), uno::UNO_QUERY ); + ObjectIdentifier::getDataSeriesForCID( m_aSelection.getSelectedCID(), getModel() ), uno::UNO_QUERY ); if( xSeries.is() ) { //if a series is selected insert mean value only for that series: @@ -417,7 +417,7 @@ void ChartController::executeDispatch_InsertMenu_MeanValues() else { ::std::vector< uno::Reference< chart2::XDataSeries > > aSeries( - DiagramHelper::getDataSeriesFromDiagram( ChartModelHelper::findDiagram( m_aModel->getModel()))); + DiagramHelper::getDataSeriesFromDiagram( ChartModelHelper::findDiagram( getModel() ))); ::std::for_each( aSeries.begin(), aSeries.end(), lcl_InsertMeanValueLine( m_xCC )); } aUndoGuard.commitAction(); @@ -427,7 +427,7 @@ void ChartController::executeDispatch_InsertMenu_Trendlines() { //if a series is selected insert only for that series: uno::Reference< chart2::XDataSeries > xSeries( - ObjectIdentifier::getDataSeriesForCID( m_aSelection.getSelectedCID(), m_aModel->getModel()), uno::UNO_QUERY ); + ObjectIdentifier::getDataSeriesForCID( m_aSelection.getSelectedCID(), getModel() ), uno::UNO_QUERY ); if( xSeries.is()) { executeDispatch_InsertTrendline(); @@ -437,12 +437,12 @@ void ChartController::executeDispatch_InsertMenu_Trendlines() UndoGuard aUndoGuard( ActionDescriptionProvider::createDescription( ActionDescriptionProvider::INSERT, ObjectNameProvider::getName_ObjectForAllSeries( OBJECTTYPE_DATA_CURVE ) ), - m_xUndoManager, m_aModel->getModel() ); + m_xUndoManager, getModel() ); try { wrapper::AllSeriesStatisticsConverter aItemConverter( - m_aModel->getModel(), m_pDrawModelWrapper->GetItemPool() ); + getModel(), m_pDrawModelWrapper->GetItemPool() ); SfxItemSet aItemSet = aItemConverter.CreateEmptyItemSet(); aItemConverter.FillItemSet( aItemSet ); @@ -457,7 +457,7 @@ void ChartController::executeDispatch_InsertMenu_Trendlines() aDlg.FillItemSet( aOutItemSet ); // lock controllers till end of block - ControllerLockGuard aCLGuard( m_aModel->getModel()); + ControllerLockGuard aCLGuard( getModel() ); bool bChanged = aItemConverter.ApplyItemSet( aOutItemSet );//model should be changed now if( bChanged ) aUndoGuard.commitAction(); @@ -472,13 +472,13 @@ void ChartController::executeDispatch_InsertMenu_Trendlines() void ChartController::executeDispatch_InsertTrendline() { uno::Reference< chart2::XRegressionCurveContainer > xRegCurveCnt( - ObjectIdentifier::getDataSeriesForCID( m_aSelection.getSelectedCID(), m_aModel->getModel()), uno::UNO_QUERY ); + ObjectIdentifier::getDataSeriesForCID( m_aSelection.getSelectedCID(), getModel()), uno::UNO_QUERY ); if( xRegCurveCnt.is()) { UndoLiveUpdateGuard aUndoGuard( ActionDescriptionProvider::createDescription( ActionDescriptionProvider::INSERT, ::rtl::OUString( String( SchResId( STR_OBJECT_CURVE )))), - m_xUndoManager, m_aModel->getModel() ); + m_xUndoManager, getModel() ); // add a linear curve RegressionCurveHelper::addRegressionCurve( @@ -493,7 +493,7 @@ void ChartController::executeDispatch_InsertTrendline() wrapper::RegressionCurveItemConverter aItemConverter( xCurveProp, xRegCurveCnt, m_pDrawModelWrapper->getSdrModel().GetItemPool(), m_pDrawModelWrapper->getSdrModel(), - uno::Reference< lang::XMultiServiceFactory >( m_aModel->getModel(), uno::UNO_QUERY )); + uno::Reference< lang::XMultiServiceFactory >( getModel(), uno::UNO_QUERY )); // open dialog SfxItemSet aItemSet = aItemConverter.CreateEmptyItemSet(); @@ -502,11 +502,11 @@ void ChartController::executeDispatch_InsertTrendline() ObjectIdentifier::createDataCurveCID( ObjectIdentifier::getSeriesParticleFromCID( m_aSelection.getSelectedCID()), RegressionCurveHelper::getRegressionCurveIndex( xRegCurveCnt, xCurve ), false )); - aDialogParameter.init( m_aModel->getModel() ); + aDialogParameter.init( getModel() ); ViewElementListProvider aViewElementListProvider( m_pDrawModelWrapper.get()); ::vos::OGuard aGuard( Application::GetSolarMutex()); SchAttribTabDlg aDlg( m_pChartWindow, &aItemSet, &aDialogParameter, &aViewElementListProvider, - uno::Reference< util::XNumberFormatsSupplier >( m_aModel->getModel(), uno::UNO_QUERY )); + uno::Reference< util::XNumberFormatsSupplier >( getModel(), uno::UNO_QUERY )); // note: when a user pressed "OK" but didn't change any settings in the // dialog, the SfxTabDialog returns "Cancel" @@ -515,7 +515,7 @@ void ChartController::executeDispatch_InsertTrendline() const SfxItemSet* pOutItemSet = aDlg.GetOutputItemSet(); if( pOutItemSet ) { - ControllerLockGuard aCLGuard( m_aModel->getModel()); + ControllerLockGuard aCLGuard( getModel() ); aItemConverter.ApplyItemSet( *pOutItemSet ); } aUndoGuard.commitAction(); @@ -526,13 +526,13 @@ void ChartController::executeDispatch_InsertTrendline() void ChartController::executeDispatch_InsertYErrorBars() { uno::Reference< chart2::XDataSeries > xSeries( - ObjectIdentifier::getDataSeriesForCID( m_aSelection.getSelectedCID(), m_aModel->getModel()), uno::UNO_QUERY ); + ObjectIdentifier::getDataSeriesForCID( m_aSelection.getSelectedCID(), getModel() ), uno::UNO_QUERY ); if( xSeries.is()) { UndoLiveUpdateGuard aUndoGuard( ActionDescriptionProvider::createDescription( ActionDescriptionProvider::INSERT, ::rtl::OUString( String( SchResId( STR_OBJECT_ERROR_BARS )))), - m_xUndoManager, m_aModel->getModel() ); + m_xUndoManager, getModel() ); // add error bars with standard deviation uno::Reference< beans::XPropertySet > xErrorBarProp( @@ -540,9 +540,9 @@ void ChartController::executeDispatch_InsertYErrorBars() // get an appropriate item converter wrapper::ErrorBarItemConverter aItemConverter( - m_aModel->getModel(), xErrorBarProp, m_pDrawModelWrapper->getSdrModel().GetItemPool(), + getModel(), xErrorBarProp, m_pDrawModelWrapper->getSdrModel().GetItemPool(), m_pDrawModelWrapper->getSdrModel(), - uno::Reference< lang::XMultiServiceFactory >( m_aModel->getModel(), uno::UNO_QUERY )); + uno::Reference< lang::XMultiServiceFactory >( getModel(), uno::UNO_QUERY )); // open dialog SfxItemSet aItemSet = aItemConverter.CreateEmptyItemSet(); @@ -550,13 +550,13 @@ void ChartController::executeDispatch_InsertYErrorBars() ObjectPropertiesDialogParameter aDialogParameter = ObjectPropertiesDialogParameter( ObjectIdentifier::createClassifiedIdentifierWithParent( OBJECTTYPE_DATA_ERRORS, ::rtl::OUString(), m_aSelection.getSelectedCID())); - aDialogParameter.init( m_aModel->getModel() ); + aDialogParameter.init( getModel() ); ViewElementListProvider aViewElementListProvider( m_pDrawModelWrapper.get()); ::vos::OGuard aGuard( Application::GetSolarMutex()); SchAttribTabDlg aDlg( m_pChartWindow, &aItemSet, &aDialogParameter, &aViewElementListProvider, - uno::Reference< util::XNumberFormatsSupplier >( m_aModel->getModel(), uno::UNO_QUERY )); + uno::Reference< util::XNumberFormatsSupplier >( getModel(), uno::UNO_QUERY )); aDlg.SetAxisMinorStepWidthForErrorBarDecimals( - InsertErrorBarsDialog::getAxisMinorStepWidthForErrorBarDecimals( m_aModel->getModel(), m_xChartView, m_aSelection.getSelectedCID())); + InsertErrorBarsDialog::getAxisMinorStepWidthForErrorBarDecimals( getModel(), m_xChartView, m_aSelection.getSelectedCID())); // note: when a user pressed "OK" but didn't change any settings in the // dialog, the SfxTabDialog returns "Cancel" @@ -565,7 +565,7 @@ void ChartController::executeDispatch_InsertYErrorBars() const SfxItemSet* pOutItemSet = aDlg.GetOutputItemSet(); if( pOutItemSet ) { - ControllerLockGuard aCLGuard( m_aModel->getModel()); + ControllerLockGuard aCLGuard( getModel() ); aItemConverter.ApplyItemSet( *pOutItemSet ); } aUndoGuard.commitAction(); @@ -576,11 +576,11 @@ void ChartController::executeDispatch_InsertYErrorBars() void ChartController::executeDispatch_InsertTrendlineEquation( bool bInsertR2 ) { uno::Reference< chart2::XRegressionCurve > xRegCurve( - ObjectIdentifier::getObjectPropertySet( m_aSelection.getSelectedCID(), m_aModel->getModel()), uno::UNO_QUERY ); + ObjectIdentifier::getObjectPropertySet( m_aSelection.getSelectedCID(), getModel() ), uno::UNO_QUERY ); if( !xRegCurve.is() ) { uno::Reference< chart2::XRegressionCurveContainer > xRegCurveCnt( - ObjectIdentifier::getDataSeriesForCID( m_aSelection.getSelectedCID(), m_aModel->getModel()), uno::UNO_QUERY ); + ObjectIdentifier::getDataSeriesForCID( m_aSelection.getSelectedCID(), getModel() ), uno::UNO_QUERY ); xRegCurve.set( RegressionCurveHelper::getFirstCurveNotMeanValueLine( xRegCurveCnt ) ); } if( xRegCurve.is()) @@ -592,7 +592,7 @@ void ChartController::executeDispatch_InsertTrendlineEquation( bool bInsertR2 ) UndoGuard aUndoGuard = UndoGuard( ActionDescriptionProvider::createDescription( ActionDescriptionProvider::INSERT, ::rtl::OUString( String( SchResId( STR_OBJECT_CURVE_EQUATION )))), - m_xUndoManager, m_aModel->getModel() ); + m_xUndoManager, getModel() ); xEqProp->setPropertyValue( C2U("ShowEquation"), uno::makeAny( true )); xEqProp->setPropertyValue( C2U("ShowCorrelationCoefficient"), uno::makeAny( bInsertR2 )); aUndoGuard.commitAction(); @@ -603,13 +603,13 @@ void ChartController::executeDispatch_InsertTrendlineEquation( bool bInsertR2 ) void ChartController::executeDispatch_InsertR2Value() { uno::Reference< beans::XPropertySet > xEqProp( - ObjectIdentifier::getObjectPropertySet( m_aSelection.getSelectedCID(), m_aModel->getModel()), uno::UNO_QUERY ); + ObjectIdentifier::getObjectPropertySet( m_aSelection.getSelectedCID(), getModel() ), uno::UNO_QUERY ); if( xEqProp.is()) { UndoGuard aUndoGuard = UndoGuard( ActionDescriptionProvider::createDescription( ActionDescriptionProvider::INSERT, ::rtl::OUString( String( SchResId( STR_OBJECT_CURVE_EQUATION )))), - m_xUndoManager, m_aModel->getModel() ); + m_xUndoManager, getModel() ); xEqProp->setPropertyValue( C2U("ShowCorrelationCoefficient"), uno::makeAny( true )); aUndoGuard.commitAction(); } @@ -618,13 +618,13 @@ void ChartController::executeDispatch_InsertR2Value() void ChartController::executeDispatch_DeleteR2Value() { uno::Reference< beans::XPropertySet > xEqProp( - ObjectIdentifier::getObjectPropertySet( m_aSelection.getSelectedCID(), m_aModel->getModel()), uno::UNO_QUERY ); + ObjectIdentifier::getObjectPropertySet( m_aSelection.getSelectedCID(), getModel() ), uno::UNO_QUERY ); if( xEqProp.is()) { UndoGuard aUndoGuard = UndoGuard( ActionDescriptionProvider::createDescription( ActionDescriptionProvider::INSERT, ::rtl::OUString( String( SchResId( STR_OBJECT_CURVE_EQUATION )))), - m_xUndoManager, m_aModel->getModel() ); + m_xUndoManager, getModel() ); xEqProp->setPropertyValue( C2U("ShowCorrelationCoefficient"), uno::makeAny( false )); aUndoGuard.commitAction(); } @@ -633,13 +633,13 @@ void ChartController::executeDispatch_DeleteR2Value() void ChartController::executeDispatch_DeleteMeanValue() { uno::Reference< chart2::XRegressionCurveContainer > xRegCurveCnt( - ObjectIdentifier::getDataSeriesForCID( m_aSelection.getSelectedCID(), m_aModel->getModel()), uno::UNO_QUERY ); + ObjectIdentifier::getDataSeriesForCID( m_aSelection.getSelectedCID(), getModel() ), uno::UNO_QUERY ); if( xRegCurveCnt.is()) { UndoGuard aUndoGuard( ActionDescriptionProvider::createDescription( ActionDescriptionProvider::DELETE, ::rtl::OUString( String( SchResId( STR_OBJECT_AVERAGE_LINE )))), - m_xUndoManager, m_aModel->getModel()); + m_xUndoManager, getModel() ); RegressionCurveHelper::removeMeanValueLine( xRegCurveCnt ); aUndoGuard.commitAction(); } @@ -648,13 +648,13 @@ void ChartController::executeDispatch_DeleteMeanValue() void ChartController::executeDispatch_DeleteTrendline() { uno::Reference< chart2::XRegressionCurveContainer > xRegCurveCnt( - ObjectIdentifier::getDataSeriesForCID( m_aSelection.getSelectedCID(), m_aModel->getModel()), uno::UNO_QUERY ); + ObjectIdentifier::getDataSeriesForCID( m_aSelection.getSelectedCID(), getModel() ), uno::UNO_QUERY ); if( xRegCurveCnt.is()) { UndoGuard aUndoGuard( ActionDescriptionProvider::createDescription( ActionDescriptionProvider::DELETE, ::rtl::OUString( String( SchResId( STR_OBJECT_CURVE )))), - m_xUndoManager, m_aModel->getModel()); + m_xUndoManager, getModel() ); RegressionCurveHelper::removeAllExceptMeanValueLine( xRegCurveCnt ); aUndoGuard.commitAction(); } @@ -663,13 +663,13 @@ void ChartController::executeDispatch_DeleteTrendline() void ChartController::executeDispatch_DeleteTrendlineEquation() { uno::Reference< chart2::XRegressionCurveContainer > xRegCurveCnt( - ObjectIdentifier::getDataSeriesForCID( m_aSelection.getSelectedCID(), m_aModel->getModel()), uno::UNO_QUERY ); + ObjectIdentifier::getDataSeriesForCID( m_aSelection.getSelectedCID(), getModel() ), uno::UNO_QUERY ); if( xRegCurveCnt.is()) { UndoGuard aUndoGuard( ActionDescriptionProvider::createDescription( ActionDescriptionProvider::DELETE, ::rtl::OUString( String( SchResId( STR_OBJECT_CURVE_EQUATION )))), - m_xUndoManager, m_aModel->getModel()); + m_xUndoManager, getModel() ); RegressionCurveHelper::removeEquations( xRegCurveCnt ); aUndoGuard.commitAction(); } @@ -678,13 +678,13 @@ void ChartController::executeDispatch_DeleteTrendlineEquation() void ChartController::executeDispatch_DeleteYErrorBars() { uno::Reference< chart2::XDataSeries > xDataSeries( - ObjectIdentifier::getDataSeriesForCID( m_aSelection.getSelectedCID(), m_aModel->getModel())); + ObjectIdentifier::getDataSeriesForCID( m_aSelection.getSelectedCID(), getModel() )); if( xDataSeries.is()) { UndoGuard aUndoGuard( ActionDescriptionProvider::createDescription( ActionDescriptionProvider::DELETE, ::rtl::OUString( String( SchResId( STR_OBJECT_CURVE )))), - m_xUndoManager, m_aModel->getModel()); + m_xUndoManager, getModel() ); StatisticsHelper::removeErrorBars( xDataSeries ); aUndoGuard.commitAction(); } @@ -693,12 +693,12 @@ void ChartController::executeDispatch_DeleteYErrorBars() void ChartController::executeDispatch_InsertDataLabels() { uno::Reference< chart2::XDataSeries > xSeries( - ObjectIdentifier::getDataSeriesForCID( m_aSelection.getSelectedCID(), m_aModel->getModel()), uno::UNO_QUERY ); + ObjectIdentifier::getDataSeriesForCID( m_aSelection.getSelectedCID(), getModel() ), uno::UNO_QUERY ); if( xSeries.is() ) { UndoGuard aUndoGuard = UndoGuard( ActionDescriptionProvider::createDescription( ActionDescriptionProvider::INSERT, ::rtl::OUString( String( SchResId( STR_OBJECT_DATALABELS )))), - m_xUndoManager, m_aModel->getModel() ); + m_xUndoManager, getModel() ); DataSeriesHelper::insertDataLabelsToSeriesAndAllPoints( xSeries ); aUndoGuard.commitAction(); } @@ -708,20 +708,20 @@ void ChartController::executeDispatch_InsertDataLabel() { UndoGuard aUndoGuard = UndoGuard( ActionDescriptionProvider::createDescription( ActionDescriptionProvider::INSERT, ::rtl::OUString( String( SchResId( STR_OBJECT_LABEL )))), - m_xUndoManager, m_aModel->getModel() ); - DataSeriesHelper::insertDataLabelToPoint( ObjectIdentifier::getObjectPropertySet( m_aSelection.getSelectedCID(), m_aModel->getModel() ) ); + m_xUndoManager, getModel() ); + DataSeriesHelper::insertDataLabelToPoint( ObjectIdentifier::getObjectPropertySet( m_aSelection.getSelectedCID(), getModel() ) ); aUndoGuard.commitAction(); } void ChartController::executeDispatch_DeleteDataLabels() { uno::Reference< chart2::XDataSeries > xSeries( - ObjectIdentifier::getDataSeriesForCID( m_aSelection.getSelectedCID(), m_aModel->getModel()), uno::UNO_QUERY ); + ObjectIdentifier::getDataSeriesForCID( m_aSelection.getSelectedCID(), getModel() ), uno::UNO_QUERY ); if( xSeries.is() ) { UndoGuard aUndoGuard( ActionDescriptionProvider::createDescription( ActionDescriptionProvider::DELETE, ::rtl::OUString( String( SchResId( STR_OBJECT_DATALABELS )))), - m_xUndoManager, m_aModel->getModel()); + m_xUndoManager, getModel() ); DataSeriesHelper::deleteDataLabelsFromSeriesAndAllPoints( xSeries ); aUndoGuard.commitAction(); } @@ -731,8 +731,8 @@ void ChartController::executeDispatch_DeleteDataLabel() { UndoGuard aUndoGuard( ActionDescriptionProvider::createDescription( ActionDescriptionProvider::DELETE, ::rtl::OUString( String( SchResId( STR_OBJECT_LABEL )))), - m_xUndoManager, m_aModel->getModel()); - DataSeriesHelper::deleteDataLabelsFromPoint( ObjectIdentifier::getObjectPropertySet( m_aSelection.getSelectedCID(), m_aModel->getModel() ) ); + m_xUndoManager, getModel() ); + DataSeriesHelper::deleteDataLabelsFromPoint( ObjectIdentifier::getObjectPropertySet( m_aSelection.getSelectedCID(), getModel() ) ); aUndoGuard.commitAction(); } @@ -740,8 +740,8 @@ void ChartController::executeDispatch_ResetAllDataPoints() { UndoGuard aUndoGuard( ActionDescriptionProvider::createDescription( ActionDescriptionProvider::FORMAT, ::rtl::OUString( String( SchResId( STR_OBJECT_DATAPOINTS )))), - m_xUndoManager, m_aModel->getModel()); - uno::Reference< chart2::XDataSeries > xSeries( ObjectIdentifier::getDataSeriesForCID( m_aSelection.getSelectedCID(), m_aModel->getModel()), uno::UNO_QUERY ); + m_xUndoManager, getModel() ); + uno::Reference< chart2::XDataSeries > xSeries( ObjectIdentifier::getDataSeriesForCID( m_aSelection.getSelectedCID(), getModel() ), uno::UNO_QUERY ); if( xSeries.is() ) xSeries->resetAllDataPoints(); aUndoGuard.commitAction(); @@ -750,8 +750,8 @@ void ChartController::executeDispatch_ResetDataPoint() { UndoGuard aUndoGuard( ActionDescriptionProvider::createDescription( ActionDescriptionProvider::FORMAT, ::rtl::OUString( String( SchResId( STR_OBJECT_DATAPOINT )))), - m_xUndoManager, m_aModel->getModel()); - uno::Reference< chart2::XDataSeries > xSeries( ObjectIdentifier::getDataSeriesForCID( m_aSelection.getSelectedCID(), m_aModel->getModel()), uno::UNO_QUERY ); + m_xUndoManager, getModel() ); + uno::Reference< chart2::XDataSeries > xSeries( ObjectIdentifier::getDataSeriesForCID( m_aSelection.getSelectedCID(), getModel() ), uno::UNO_QUERY ); if( xSeries.is() ) { sal_Int32 nPointIndex = ObjectIdentifier::getIndexFromParticleOrCID( m_aSelection.getSelectedCID() ); @@ -769,13 +769,13 @@ void ChartController::executeDispatch_InsertAxisTitle() UndoGuard aUndoGuard( ActionDescriptionProvider::createDescription( ActionDescriptionProvider::INSERT, ::rtl::OUString( String( SchResId( STR_OBJECT_TITLE )))), - m_xUndoManager, m_aModel->getModel() ); + m_xUndoManager, getModel() ); - Reference< XAxis > xAxis = ObjectIdentifier::getAxisForCID( m_aSelection.getSelectedCID(), m_aModel->getModel() ); + Reference< XAxis > xAxis = ObjectIdentifier::getAxisForCID( m_aSelection.getSelectedCID(), getModel() ); sal_Int32 nDimensionIndex = -1; sal_Int32 nCooSysIndex = -1; sal_Int32 nAxisIndex = -1; - AxisHelper::getIndicesForAxis( xAxis, ChartModelHelper::findDiagram(m_aModel->getModel()), nCooSysIndex, nDimensionIndex, nAxisIndex ); + AxisHelper::getIndicesForAxis( xAxis, ChartModelHelper::findDiagram(getModel()), nCooSysIndex, nDimensionIndex, nAxisIndex ); TitleHelper::eTitleType eTitleType = TitleHelper::X_AXIS_TITLE; if( nDimensionIndex==0 ) @@ -786,14 +786,14 @@ void ChartController::executeDispatch_InsertAxisTitle() eTitleType = TitleHelper::Z_AXIS_TITLE; ::std::auto_ptr< ReferenceSizeProvider > apRefSizeProvider( impl_createReferenceSizeProvider()); - xTitle = TitleHelper::createTitle( eTitleType, ObjectNameProvider::getTitleNameByType(eTitleType), m_aModel->getModel(), m_xCC, apRefSizeProvider.get() ); + xTitle = TitleHelper::createTitle( eTitleType, ObjectNameProvider::getTitleNameByType(eTitleType), getModel(), m_xCC, apRefSizeProvider.get() ); aUndoGuard.commitAction(); } /* if( xTitle.is() ) { - OUString aTitleCID = ObjectIdentifier::createClassifiedIdentifierForObject( xTitle, m_aModel->getModel() ); + OUString aTitleCID = ObjectIdentifier::createClassifiedIdentifierForObject( xTitle, getModel() ); select( uno::makeAny(aTitleCID) ); executeDispatch_EditText(); } @@ -810,11 +810,11 @@ void ChartController::executeDispatch_InsertAxis() UndoGuard aUndoGuard( ActionDescriptionProvider::createDescription( ActionDescriptionProvider::INSERT, ::rtl::OUString( String( SchResId( STR_OBJECT_AXIS )))), - m_xUndoManager, m_aModel->getModel() ); + m_xUndoManager, getModel() ); try { - Reference< XAxis > xAxis = ObjectIdentifier::getAxisForCID( m_aSelection.getSelectedCID(), m_aModel->getModel() ); + Reference< XAxis > xAxis = ObjectIdentifier::getAxisForCID( m_aSelection.getSelectedCID(), getModel() ); if( xAxis.is() ) { AxisHelper::makeAxisVisible( xAxis ); @@ -832,11 +832,11 @@ void ChartController::executeDispatch_DeleteAxis() UndoGuard aUndoGuard( ActionDescriptionProvider::createDescription( ActionDescriptionProvider::DELETE, ::rtl::OUString( String( SchResId( STR_OBJECT_AXIS )))), - m_xUndoManager, m_aModel->getModel() ); + m_xUndoManager, getModel() ); try { - Reference< XAxis > xAxis = ObjectIdentifier::getAxisForCID( m_aSelection.getSelectedCID(), m_aModel->getModel() ); + Reference< XAxis > xAxis = ObjectIdentifier::getAxisForCID( m_aSelection.getSelectedCID(), getModel() ); if( xAxis.is() ) { AxisHelper::makeAxisInvisible( xAxis ); @@ -854,11 +854,11 @@ void ChartController::executeDispatch_InsertMajorGrid() UndoGuard aUndoGuard( ActionDescriptionProvider::createDescription( ActionDescriptionProvider::INSERT, ::rtl::OUString( String( SchResId( STR_OBJECT_GRID )))), - m_xUndoManager, m_aModel->getModel() ); + m_xUndoManager, getModel() ); try { - Reference< XAxis > xAxis = ObjectIdentifier::getAxisForCID( m_aSelection.getSelectedCID(), m_aModel->getModel() ); + Reference< XAxis > xAxis = ObjectIdentifier::getAxisForCID( m_aSelection.getSelectedCID(), getModel() ); if( xAxis.is() ) { AxisHelper::makeGridVisible( xAxis->getGridProperties() ); @@ -876,11 +876,11 @@ void ChartController::executeDispatch_DeleteMajorGrid() UndoGuard aUndoGuard( ActionDescriptionProvider::createDescription( ActionDescriptionProvider::DELETE, ::rtl::OUString( String( SchResId( STR_OBJECT_GRID )))), - m_xUndoManager, m_aModel->getModel() ); + m_xUndoManager, getModel() ); try { - Reference< XAxis > xAxis = ObjectIdentifier::getAxisForCID( m_aSelection.getSelectedCID(), m_aModel->getModel() ); + Reference< XAxis > xAxis = ObjectIdentifier::getAxisForCID( m_aSelection.getSelectedCID(), getModel() ); if( xAxis.is() ) { AxisHelper::makeGridInvisible( xAxis->getGridProperties() ); @@ -898,11 +898,11 @@ void ChartController::executeDispatch_InsertMinorGrid() UndoGuard aUndoGuard( ActionDescriptionProvider::createDescription( ActionDescriptionProvider::INSERT, ::rtl::OUString( String( SchResId( STR_OBJECT_GRID )))), - m_xUndoManager, m_aModel->getModel() ); + m_xUndoManager, getModel() ); try { - Reference< XAxis > xAxis = ObjectIdentifier::getAxisForCID( m_aSelection.getSelectedCID(), m_aModel->getModel() ); + Reference< XAxis > xAxis = ObjectIdentifier::getAxisForCID( m_aSelection.getSelectedCID(), getModel() ); if( xAxis.is() ) { Sequence< Reference< beans::XPropertySet > > aSubGrids( xAxis->getSubGridProperties() ); @@ -922,11 +922,11 @@ void ChartController::executeDispatch_DeleteMinorGrid() UndoGuard aUndoGuard( ActionDescriptionProvider::createDescription( ActionDescriptionProvider::DELETE, ::rtl::OUString( String( SchResId( STR_OBJECT_GRID )))), - m_xUndoManager, m_aModel->getModel() ); + m_xUndoManager, getModel() ); try { - Reference< XAxis > xAxis = ObjectIdentifier::getAxisForCID( m_aSelection.getSelectedCID(), m_aModel->getModel() ); + Reference< XAxis > xAxis = ObjectIdentifier::getAxisForCID( m_aSelection.getSelectedCID(), getModel() ); if( xAxis.is() ) { Sequence< Reference< beans::XPropertySet > > aSubGrids( xAxis->getSubGridProperties() ); diff --git a/chart2/source/controller/main/ChartController_Position.cxx b/chart2/source/controller/main/ChartController_Position.cxx index 6c988ebf22d5..619d308ffad2 100644 --- a/chart2/source/controller/main/ChartController_Position.cxx +++ b/chart2/source/controller/main/ChartController_Position.cxx @@ -139,7 +139,7 @@ void SAL_CALL ChartController::executeDispatch_PositionAndSize() ActionDescriptionProvider::createDescription( ActionDescriptionProvider::POS_SIZE, ObjectNameProvider::getName( ObjectIdentifier::getObjectType( aCID ))), - m_xUndoManager, m_aModel->getModel() ); + m_xUndoManager, getModel() ); SfxAbstractTabDialog * pDlg = NULL; try @@ -166,14 +166,13 @@ void SAL_CALL ChartController::executeDispatch_PositionAndSize() Rectangle aObjectRect; aItemSet.Put(*pOutItemSet);//overwrite old values with new values (-> all items are set) lcl_getPositionAndSizeFromItemSet( aItemSet, aObjectRect, aSelectedSize ); - awt::Size aPageSize( ChartModelHelper::getPageSize( m_aModel->getModel() ) ); + awt::Size aPageSize( ChartModelHelper::getPageSize( getModel() ) ); Rectangle aPageRect( 0,0,aPageSize.Width,aPageSize.Height ); bool bChanged = PositionAndSizeHelper::moveObject( m_aSelection.getSelectedCID() - , m_aModel->getModel() + , getModel() , awt::Rectangle(aObjectRect.getX(),aObjectRect.getY(),aObjectRect.getWidth(),aObjectRect.getHeight()) - , awt::Rectangle(aPageRect.getX(),aPageRect.getY(),aPageRect.getWidth(),aPageRect.getHeight()) - , m_xChartView ); + , awt::Rectangle(aPageRect.getX(),aPageRect.getY(),aPageRect.getWidth(),aPageRect.getHeight()) ); if( bChanged ) aUndoGuard.commitAction(); } diff --git a/chart2/source/controller/main/ChartController_Properties.cxx b/chart2/source/controller/main/ChartController_Properties.cxx index 3c5a0b135622..649b9cb62f9d 100644 --- a/chart2/source/controller/main/ChartController_Properties.cxx +++ b/chart2/source/controller/main/ChartController_Properties.cxx @@ -676,7 +676,7 @@ rtl::OUString lcl_getObjectCIDForCommand( const ::rtl::OString& rDispatchCommand void SAL_CALL ChartController::executeDispatch_FormatObject(const ::rtl::OUString& rDispatchCommand) { - uno::Reference< XChartDocument > xChartDocument( m_aModel->getModel(), uno::UNO_QUERY ); + uno::Reference< XChartDocument > xChartDocument( getModel(), uno::UNO_QUERY ); rtl::OString aCommand( rtl::OUStringToOString( rDispatchCommand, RTL_TEXTENCODING_ASCII_US ) ); rtl::OUString rObjectCID = lcl_getObjectCIDForCommand( aCommand, xChartDocument, m_aSelection.getSelectedCID() ); executeDlg_ObjectProperties( rObjectCID ); @@ -720,7 +720,7 @@ void SAL_CALL ChartController::executeDlg_ObjectProperties( const ::rtl::OUStrin UndoGuard aUndoGuard( ActionDescriptionProvider::createDescription( ActionDescriptionProvider::FORMAT, ObjectNameProvider::getName( ObjectIdentifier::getObjectType( aObjectCID ))), - m_xUndoManager, m_aModel->getModel() ); + m_xUndoManager, getModel() ); bool bSuccess = ChartController::executeDlg_ObjectProperties_withoutUndoGuard( aObjectCID, false ); if( bSuccess ) @@ -738,7 +738,7 @@ bool ChartController::executeDlg_ObjectProperties_withoutUndoGuard( const ::rtl: } try { - NumberFormatterWrapper aNumberFormatterWrapper( uno::Reference< util::XNumberFormatsSupplier >(m_aModel->getModel(), uno::UNO_QUERY) ); + NumberFormatterWrapper aNumberFormatterWrapper( uno::Reference< util::XNumberFormatsSupplier >(getModel(), uno::UNO_QUERY) ); //------------------------------------------------------------- //get type of object @@ -750,19 +750,19 @@ bool ChartController::executeDlg_ObjectProperties_withoutUndoGuard( const ::rtl: } if( OBJECTTYPE_DIAGRAM_WALL==eObjectType || OBJECTTYPE_DIAGRAM_FLOOR==eObjectType ) { - if( !DiagramHelper::isSupportingFloorAndWall( ChartModelHelper::findDiagram( m_aModel->getModel() ) ) ) + if( !DiagramHelper::isSupportingFloorAndWall( ChartModelHelper::findDiagram( getModel() ) ) ) return bRet; } //------------------------------------------------------------- //convert properties to ItemSet - awt::Size aPageSize( ChartModelHelper::getPageSize(m_aModel->getModel()) ); + awt::Size aPageSize( ChartModelHelper::getPageSize(getModel()) ); ::std::auto_ptr< ReferenceSizeProvider > pRefSizeProv( impl_createReferenceSizeProvider()); ::std::auto_ptr< ::comphelper::ItemConverter > apItemConverter( - createItemConverter( rObjectCID, m_aModel->getModel(), m_xCC, + createItemConverter( rObjectCID, getModel(), m_xCC, m_pDrawModelWrapper->getSdrModel(), &aNumberFormatterWrapper, ExplicitValueProvider::getExplicitValueProvider(m_xChartView), @@ -776,24 +776,24 @@ bool ChartController::executeDlg_ObjectProperties_withoutUndoGuard( const ::rtl: //------------------------------------------------------------- //prepare dialog ObjectPropertiesDialogParameter aDialogParameter = ObjectPropertiesDialogParameter( rObjectCID ); - aDialogParameter.init( m_aModel->getModel() ); + aDialogParameter.init( getModel() ); ViewElementListProvider aViewElementListProvider( m_pDrawModelWrapper.get() ); ::vos::OGuard aGuard( Application::GetSolarMutex()); SchAttribTabDlg aDlg( m_pChartWindow, &aItemSet, &aDialogParameter, &aViewElementListProvider - , uno::Reference< util::XNumberFormatsSupplier >( m_aModel->getModel(), uno::UNO_QUERY ) ); + , uno::Reference< util::XNumberFormatsSupplier >( getModel(), uno::UNO_QUERY ) ); if(aDialogParameter.HasSymbolProperties()) { SfxItemSet* pSymbolShapeProperties=NULL; uno::Reference< beans::XPropertySet > xObjectProperties = - ObjectIdentifier::getObjectPropertySet( rObjectCID, m_aModel->getModel() ); - wrapper::DataPointItemConverter aSymbolItemConverter( m_aModel->getModel(), m_xCC - , xObjectProperties, ObjectIdentifier::getDataSeriesForCID( rObjectCID, m_aModel->getModel() ) + ObjectIdentifier::getObjectPropertySet( rObjectCID, getModel() ); + wrapper::DataPointItemConverter aSymbolItemConverter( getModel(), m_xCC + , xObjectProperties, ObjectIdentifier::getDataSeriesForCID( rObjectCID, getModel() ) , m_pDrawModelWrapper->getSdrModel().GetItemPool() , m_pDrawModelWrapper->getSdrModel() , &aNumberFormatterWrapper - , uno::Reference< lang::XMultiServiceFactory >( m_aModel->getModel(), uno::UNO_QUERY ) + , uno::Reference< lang::XMultiServiceFactory >( getModel(), uno::UNO_QUERY ) , wrapper::GraphicPropertyItemConverter::FILLED_DATA_POINT ); pSymbolShapeProperties = new SfxItemSet( aSymbolItemConverter.CreateEmptyItemSet() ); @@ -807,7 +807,7 @@ bool ChartController::executeDlg_ObjectProperties_withoutUndoGuard( const ::rtl: if( aDialogParameter.HasStatisticProperties() ) { aDlg.SetAxisMinorStepWidthForErrorBarDecimals( - InsertErrorBarsDialog::getAxisMinorStepWidthForErrorBarDecimals( m_aModel->getModel(), m_xChartView, rObjectCID ) ); + InsertErrorBarsDialog::getAxisMinorStepWidthForErrorBarDecimals( getModel(), m_xChartView, rObjectCID ) ); } //------------------------------------------------------------- @@ -817,7 +817,7 @@ bool ChartController::executeDlg_ObjectProperties_withoutUndoGuard( const ::rtl: const SfxItemSet* pOutItemSet = aDlg.GetOutputItemSet(); if(pOutItemSet) { - ControllerLockGuard aCLGuard( m_aModel->getModel()); + ControllerLockGuard aCLGuard( getModel()); apItemConverter->ApplyItemSet( *pOutItemSet );//model should be changed now bRet = true; } @@ -839,12 +839,12 @@ void SAL_CALL ChartController::executeDispatch_View3D() // using assignment for broken gcc 3.3 UndoLiveUpdateGuard aUndoGuard = UndoLiveUpdateGuard( ::rtl::OUString( String( SchResId( STR_ACTION_EDIT_3D_VIEW ))), - m_xUndoManager, m_aModel->getModel()); + m_xUndoManager, getModel()); // /-- //open dialog ::vos::OGuard aSolarGuard( Application::GetSolarMutex()); - View3DDialog aDlg( m_pChartWindow, m_aModel->getModel(), m_pDrawModelWrapper->GetColorTable() ); + View3DDialog aDlg( m_pChartWindow, getModel(), m_pDrawModelWrapper->GetColorTable() ); if( aDlg.Execute() == RET_OK ) aUndoGuard.commitAction(); // \-- diff --git a/chart2/source/controller/main/ChartController_TextEdit.cxx b/chart2/source/controller/main/ChartController_TextEdit.cxx index 4df362ee80d2..a6e82430d8f6 100644 --- a/chart2/source/controller/main/ChartController_TextEdit.cxx +++ b/chart2/source/controller/main/ChartController_TextEdit.cxx @@ -80,7 +80,7 @@ void ChartController::StartTextEdit( const Point* pMousePixel ) if(!pTextObj) return; - m_xUndoManager->preAction( m_aModel->getModel()); + m_xUndoManager->preAction( getModel()); SdrOutliner* pOutliner = m_pDrawViewWrapper->getOutliner(); //pOutliner->SetRefDevice(m_pChartWindow); //pOutliner->SetStyleSheetPool((SfxStyleSheetPool*)pStyleSheetPool); @@ -159,7 +159,7 @@ bool ChartController::EndTextEdit() ObjectIdentifier::getObjectPropertySet( aObjectCID, getModel() ); // lock controllers till end of block - ControllerLockGuard aCLGuard( m_aModel->getModel()); + ControllerLockGuard aCLGuard( getModel() ); TitleHelper::setCompleteString( aString, uno::Reference< ::com::sun::star::chart2::XTitle >::query( xPropSet ), m_xCC ); diff --git a/chart2/source/controller/main/ChartController_Tools.cxx b/chart2/source/controller/main/ChartController_Tools.cxx index ff567636ba0e..ffe752f43a7a 100644 --- a/chart2/source/controller/main/ChartController_Tools.cxx +++ b/chart2/source/controller/main/ChartController_Tools.cxx @@ -50,6 +50,7 @@ #include "RegressionCurveHelper.hxx" #include "ShapeController.hxx" #include "DiagramHelper.hxx" +#include "ObjectNameProvider.hxx" #include <com/sun/star/chart2/DataPointLabel.hpp> #include <com/sun/star/beans/XPropertyState.hpp> @@ -204,13 +205,13 @@ bool lcl_deleteDataCurve( namespace chart { -::std::auto_ptr< ReferenceSizeProvider > ChartController::impl_createReferenceSizeProvider() const +::std::auto_ptr< ReferenceSizeProvider > ChartController::impl_createReferenceSizeProvider() { - awt::Size aPageSize( ChartModelHelper::getPageSize( m_aModel->getModel()) ); + awt::Size aPageSize( ChartModelHelper::getPageSize( getModel() ) ); return ::std::auto_ptr< ReferenceSizeProvider >( new ReferenceSizeProvider( aPageSize, - Reference< chart2::XChartDocument >( m_aModel->getModel(), uno::UNO_QUERY ))); + Reference< chart2::XChartDocument >( getModel(), uno::UNO_QUERY ))); } void ChartController::impl_adaptDataSeriesAutoResize() @@ -228,7 +229,7 @@ void ChartController::executeDispatch_NewArrangement() try { - Reference< frame::XModel > xModel( m_aModel->getModel()); + Reference< frame::XModel > xModel( getModel() ); Reference< chart2::XDiagram > xDiagram( ChartModelHelper::findDiagram( xModel )); if( xDiagram.is()) { @@ -242,6 +243,7 @@ void ChartController::executeDispatch_NewArrangement() Reference< beans::XPropertyState > xState( xDiagram, uno::UNO_QUERY_THROW ); xState->setPropertyToDefault( C2U("RelativeSize")); xState->setPropertyToDefault( C2U("RelativePosition")); + xState->setPropertyToDefault( C2U("PosSizeExcludeAxes")); // 3d rotation ThreeDHelper::set3DSettingsToDefault( uno::Reference< beans::XPropertySet >( xDiagram, uno::UNO_QUERY ) ); @@ -284,8 +286,8 @@ void ChartController::executeDispatch_ScaleText() // using assignment for broken gcc 3.3 UndoGuard aUndoGuard = UndoGuard( ::rtl::OUString( String( SchResId( STR_ACTION_SCALE_TEXT ))), - m_xUndoManager, m_aModel->getModel()); - ControllerLockGuard aCtlLockGuard( m_aModel->getModel()); + m_xUndoManager, getModel() ); + ControllerLockGuard aCtlLockGuard( getModel() ); ::std::auto_ptr< ReferenceSizeProvider > apRefSizeProv( impl_createReferenceSizeProvider()); OSL_ASSERT( apRefSizeProv.get()); if( apRefSizeProv.get()) @@ -377,7 +379,7 @@ void ChartController::impl_PasteGraphic( { // note: the XPropertySet of the model is the old API. Also the property // "AdditionalShapes" that is used there. - uno::Reference< beans::XPropertySet > xModelProp( m_aModel->getModel(), uno::UNO_QUERY ); + uno::Reference< beans::XPropertySet > xModelProp( getModel(), uno::UNO_QUERY ); DrawModelWrapper * pDrawModelWrapper( this->GetDrawModelWrapper()); if( ! (xGraphic.is() && xModelProp.is())) return; @@ -393,7 +395,7 @@ void ChartController::impl_PasteGraphic( xPage->add( xGraphicShape ); //need to change the model state manually { - uno::Reference< util::XModifiable > xModifiable( m_aModel->getModel(), uno::UNO_QUERY ); + uno::Reference< util::XModifiable > xModifiable( getModel(), uno::UNO_QUERY ); if( xModifiable.is() ) xModifiable->setModified( true ); } @@ -457,7 +459,7 @@ void ChartController::impl_PasteShapes( SdrModel* pModel ) } } - Reference< util::XModifiable > xModifiable( m_aModel->getModel(), uno::UNO_QUERY ); + Reference< util::XModifiable > xModifiable( getModel(), uno::UNO_QUERY ); if ( xModifiable.is() ) { xModifiable->setModified( true ); @@ -468,6 +470,8 @@ void ChartController::impl_PasteShapes( SdrModel* pModel ) m_aSelection.applySelection( m_pDrawViewWrapper ); m_pDrawViewWrapper->EndUndo(); + + impl_switchDiagramPositioningToExcludingPositioning(); } } } @@ -514,6 +518,8 @@ void ChartController::impl_PasteStringAsTextShape( const OUString& rString, cons m_pDrawViewWrapper->BegUndo( SVX_RESSTR( RID_SVX_3D_UNDO_EXCHANGE_PASTE ) ); m_pDrawViewWrapper->AddUndo( new SdrUndoInsertObj( *pObj ) ); m_pDrawViewWrapper->EndUndo(); + + impl_switchDiagramPositioningToExcludingPositioning(); } } catch ( const uno::Exception& ex ) @@ -637,7 +643,7 @@ bool ChartController::executeDispatch_Delete() return false; //remove chart object - uno::Reference< chart2::XChartDocument > xChartDoc( m_aModel->getModel(), uno::UNO_QUERY ); + uno::Reference< chart2::XChartDocument > xChartDoc( getModel(), uno::UNO_QUERY ); if( !xChartDoc.is() ) return false; @@ -650,9 +656,9 @@ bool ChartController::executeDispatch_Delete() UndoGuard aUndoGuard = UndoGuard( ActionDescriptionProvider::createDescription( ActionDescriptionProvider::DELETE, ::rtl::OUString( String( SchResId( STR_OBJECT_TITLE )))), - m_xUndoManager, m_aModel->getModel() ); + m_xUndoManager, getModel()); TitleHelper::removeTitle( - ObjectIdentifier::getTitleTypeForCID( aCID ), m_aModel->getModel()); + ObjectIdentifier::getTitleTypeForCID( aCID ), getModel() ); bReturn = true; aUndoGuard.commitAction(); break; @@ -669,7 +675,7 @@ bool ChartController::executeDispatch_Delete() UndoGuard aUndoGuard = UndoGuard( ActionDescriptionProvider::createDescription( ActionDescriptionProvider::DELETE, ::rtl::OUString( String( SchResId( STR_OBJECT_LEGEND )))), - m_xUndoManager, m_aModel->getModel() ); + m_xUndoManager, getModel() ); xLegendProp->setPropertyValue( C2U("Show"), uno::makeAny( false )); bReturn = true; aUndoGuard.commitAction(); @@ -679,7 +685,7 @@ bool ChartController::executeDispatch_Delete() } case OBJECTTYPE_DATA_SERIES: - bReturn = lcl_deleteDataSeries( aCID, m_aModel->getModel(), m_xUndoManager ); + bReturn = lcl_deleteDataSeries( aCID, getModel(), m_xUndoManager ); break; case OBJECTTYPE_LEGEND_ENTRY: @@ -687,9 +693,9 @@ bool ChartController::executeDispatch_Delete() ObjectType eParentObjectType = ObjectIdentifier::getObjectType( ObjectIdentifier::getFullParentParticle( aCID )); if( eParentObjectType == OBJECTTYPE_DATA_SERIES ) - bReturn = lcl_deleteDataSeries( aCID, m_aModel->getModel(), m_xUndoManager ); + bReturn = lcl_deleteDataSeries( aCID, getModel(), m_xUndoManager ); else if( eParentObjectType == OBJECTTYPE_DATA_CURVE ) - bReturn = lcl_deleteDataCurve( aCID, m_aModel->getModel(), m_xUndoManager ); + bReturn = lcl_deleteDataCurve( aCID, getModel(), m_xUndoManager ); break; } @@ -697,14 +703,14 @@ bool ChartController::executeDispatch_Delete() { uno::Reference< chart2::XRegressionCurveContainer > xRegCurveCnt( ObjectIdentifier::getObjectPropertySet( - ObjectIdentifier::getFullParentParticle( aCID ), m_aModel->getModel()), uno::UNO_QUERY ); + ObjectIdentifier::getFullParentParticle( aCID ), getModel()), uno::UNO_QUERY ); if( xRegCurveCnt.is()) { // using assignment for broken gcc 3.3 UndoGuard aUndoGuard = UndoGuard( ActionDescriptionProvider::createDescription( ActionDescriptionProvider::DELETE, ::rtl::OUString( String( SchResId( STR_OBJECT_AVERAGE_LINE )))), - m_xUndoManager, m_aModel->getModel() ); + m_xUndoManager, getModel() ); RegressionCurveHelper::removeMeanValueLine( xRegCurveCnt ); bReturn = true; aUndoGuard.commitAction(); @@ -713,16 +719,16 @@ bool ChartController::executeDispatch_Delete() } case OBJECTTYPE_DATA_CURVE: - bReturn = lcl_deleteDataCurve( aCID, m_aModel->getModel(), m_xUndoManager ); + bReturn = lcl_deleteDataCurve( aCID, getModel(), m_xUndoManager ); break; case OBJECTTYPE_DATA_CURVE_EQUATION: { uno::Reference< beans::XPropertySet > xEqProp( - ObjectIdentifier::getObjectPropertySet( aCID, m_aModel->getModel())); + ObjectIdentifier::getObjectPropertySet( aCID, getModel())); if( xEqProp.is()) { - uno::Reference< frame::XModel > xModel( m_aModel->getModel()); + uno::Reference< frame::XModel > xModel( getModel() ); // using assignment for broken gcc 3.3 UndoGuard aUndoGuard = UndoGuard( ActionDescriptionProvider::createDescription( @@ -742,10 +748,10 @@ bool ChartController::executeDispatch_Delete() case OBJECTTYPE_DATA_ERRORS: { uno::Reference< beans::XPropertySet > xErrorBarProp( - ObjectIdentifier::getObjectPropertySet( aCID, m_aModel->getModel())); + ObjectIdentifier::getObjectPropertySet( aCID, getModel() )); if( xErrorBarProp.is()) { - uno::Reference< frame::XModel > xModel( m_aModel->getModel()); + uno::Reference< frame::XModel > xModel( getModel() ); // using assignment for broken gcc 3.3 UndoGuard aUndoGuard = UndoGuard( ActionDescriptionProvider::createDescription( @@ -767,14 +773,14 @@ bool ChartController::executeDispatch_Delete() case OBJECTTYPE_DATA_LABEL: { uno::Reference< beans::XPropertySet > xObjectProperties = - ObjectIdentifier::getObjectPropertySet( aCID, m_aModel->getModel() ); + ObjectIdentifier::getObjectPropertySet( aCID, getModel() ); if( xObjectProperties.is() ) { UndoGuard aUndoGuard = UndoGuard( ActionDescriptionProvider::createDescription( ActionDescriptionProvider::DELETE, ::rtl::OUString( String( SchResId( aObjectType == OBJECTTYPE_DATA_LABEL ? STR_OBJECT_LABEL : STR_OBJECT_DATALABELS )))), - m_xUndoManager, m_aModel->getModel() ); + m_xUndoManager, getModel() ); chart2::DataPointLabel aLabel; xObjectProperties->getPropertyValue( C2U( "Label" ) ) >>= aLabel; aLabel.ShowNumber = false; @@ -783,7 +789,7 @@ bool ChartController::executeDispatch_Delete() aLabel.ShowLegendSymbol = false; if( aObjectType == OBJECTTYPE_DATA_LABELS ) { - uno::Reference< chart2::XDataSeries > xSeries( ObjectIdentifier::getDataSeriesForCID( aCID, m_aModel->getModel() )); + uno::Reference< chart2::XDataSeries > xSeries( ObjectIdentifier::getDataSeriesForCID( aCID, getModel() )); ::chart::DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints( xSeries, C2U( "Label" ), uno::makeAny(aLabel) ); } else @@ -838,7 +844,7 @@ bool ChartController::executeDispatch_Delete() void ChartController::executeDispatch_ToggleLegend() { - Reference< frame::XModel > xModel( m_aModel->getModel()); + Reference< frame::XModel > xModel( getModel() ); UndoGuard aUndoGuard = UndoGuard( ::rtl::OUString( String( SchResId( STR_ACTION_TOGGLE_LEGEND ))), m_xUndoManager, xModel ); Reference< beans::XPropertySet > xLegendProp( LegendHelper::getLegend( xModel ), uno::UNO_QUERY ); @@ -872,10 +878,10 @@ void ChartController::executeDispatch_ToggleLegend() void ChartController::executeDispatch_ToggleGridHorizontal() { - Reference< frame::XModel > xModel( m_aModel->getModel()); + Reference< frame::XModel > xModel( getModel() ); UndoGuard aUndoGuard = UndoGuard( ::rtl::OUString( String( SchResId( STR_ACTION_TOGGLE_GRID_HORZ ))), m_xUndoManager, xModel ); - Reference< chart2::XDiagram > xDiagram( ChartModelHelper::findDiagram( m_aModel->getModel())); + Reference< chart2::XDiagram > xDiagram( ChartModelHelper::findDiagram( getModel() )); if( xDiagram.is()) { sal_Int32 nDimensionIndex = 1; @@ -902,4 +908,14 @@ void ChartController::impl_ShapeControllerDispatch( const util::URL& rURL, const } } +void ChartController::impl_switchDiagramPositioningToExcludingPositioning() +{ + UndoGuard aUndoGuard( ActionDescriptionProvider::createDescription( + ActionDescriptionProvider::POS_SIZE, + ObjectNameProvider::getName( OBJECTTYPE_DIAGRAM)), + m_xUndoManager, m_aModel->getModel() ); + if( DiagramHelper::switchDiagramPositioningToExcludingPositioning( m_aModel->getModel(), true, true ) ) + aUndoGuard.commitAction(); +} + } // namespace chart diff --git a/chart2/source/controller/main/ChartController_Window.cxx b/chart2/source/controller/main/ChartController_Window.cxx index 6049be7e3199..56908ac4ef79 100644 --- a/chart2/source/controller/main/ChartController_Window.cxx +++ b/chart2/source/controller/main/ChartController_Window.cxx @@ -255,7 +255,7 @@ const short HITPIX=2; //hit-tolerance in pixel if( bIsEmbedded ) { //change map mode to fit new size - awt::Size aModelPageSize = ChartModelHelper::getPageSize( m_aModel->getModel() ); + awt::Size aModelPageSize = ChartModelHelper::getPageSize( getModel() ); sal_Int32 nScaleXNumerator = aLogicSize.Width(); sal_Int32 nScaleXDenominator = aModelPageSize.Width; sal_Int32 nScaleYNumerator = aLogicSize.Height(); @@ -292,7 +292,7 @@ const short HITPIX=2; //hit-tolerance in pixel else { //change visarea - ChartModelHelper::setPageSize( awt::Size( aLogicSize.Width(), aLogicSize.Height() ), m_aModel->getModel() ); + ChartModelHelper::setPageSize( awt::Size( aLogicSize.Width(), aLogicSize.Height() ), getModel() ); pWindow->SetPosSizePixel( X, Y, Width, Height, Flags ); } pWindow->Invalidate(); @@ -507,6 +507,11 @@ void ChartController::execute_Paint( const Rectangle& rRect ) { try { + uno::Reference< frame::XModel > xModel( getModel() ); + //DBG_ASSERT( xModel.is(), "ChartController::execute_Paint: have no model to paint"); + if( !xModel.is() ) + return; + //better performance for big data uno::Reference< beans::XPropertySet > xProp( m_xChartView, uno::UNO_QUERY ); if( xProp.is() ) @@ -693,7 +698,7 @@ void ChartController::execute_MouseButtonDown( const MouseEvent& rMEvt ) m_aSelection.adaptSelectionToNewPos( aMPos, pDrawViewWrapper , rMEvt.IsRight(), m_bWaitingForDoubleClick ); - if( !m_aSelection.isRotateableObjectSelected( m_aModel->getModel() ) ) + if( !m_aSelection.isRotateableObjectSelected( getModel() ) ) { m_eDragMode = SDRDRAG_MOVE; pDrawViewWrapper->SetDragMode(m_eDragMode); @@ -726,14 +731,14 @@ void ChartController::execute_MouseButtonDown( const MouseEvent& rMEvt ) else if( eKind==HDL_UPLFT || eKind==HDL_UPRGT || eKind==HDL_LWLFT || eKind==HDL_LWRGT ) eRotationDirection = DragMethod_RotateDiagram::ROTATIONDIRECTION_Z; } - pDragMethod = new DragMethod_RotateDiagram( *pDrawViewWrapper, m_aSelection.getSelectedCID(), m_aModel->getModel(), eRotationDirection ); + pDragMethod = new DragMethod_RotateDiagram( *pDrawViewWrapper, m_aSelection.getSelectedCID(), getModel(), eRotationDirection ); } } else { rtl::OUString aDragMethodServiceName( ObjectIdentifier::getDragMethodServiceName( m_aSelection.getSelectedCID() ) ); if( aDragMethodServiceName.equals( ObjectIdentifier::getPieSegmentDragMethodServiceName() ) ) - pDragMethod = new DragMethod_PieSegment( *pDrawViewWrapper, m_aSelection.getSelectedCID(), m_aModel->getModel() ); + pDragMethod = new DragMethod_PieSegment( *pDrawViewWrapper, m_aSelection.getSelectedCID(), getModel() ); } pDrawViewWrapper->SdrView::BegDragObj(aMPos, NULL, pHitSelectionHdl, nDrgLog, pDragMethod); } @@ -773,7 +778,7 @@ void ChartController::execute_Tracking( const TrackingEvent& /* rTEvt */ ) void ChartController::execute_MouseButtonUp( const MouseEvent& rMEvt ) { - ControllerLockGuard aCLGuard( m_aModel->getModel()); + ControllerLockGuard aCLGuard( getModel() ); bool bMouseUpWithoutMouseDown = !m_bWaitingForMouseUp; m_bWaitingForMouseUp = false; bool bNotifySelectionChange = false; @@ -797,6 +802,7 @@ void ChartController::execute_MouseButtonUp( const MouseEvent& rMEvt ) if ( m_eDrawMode == CHARTDRAW_INSERT && pDrawViewWrapper->IsCreateObj() ) { pDrawViewWrapper->EndCreateObj( SDRCREATE_FORCEEND ); + impl_switchDiagramPositioningToExcludingPositioning(); if ( pDrawViewWrapper->AreObjectsMarked() ) { if ( pDrawViewWrapper->GetCurrentObjIdentifier() == OBJ_TEXT ) @@ -833,7 +839,7 @@ void ChartController::execute_MouseButtonUp( const MouseEvent& rMEvt ) if( pChartDragMethod ) { UndoGuard aUndoGuard( pChartDragMethod->getUndoDescription(), - m_xUndoManager, m_aModel->getModel() ); + m_xUndoManager, getModel() ); if( pDrawViewWrapper->EndDragObj(false) ) { @@ -851,7 +857,7 @@ void ChartController::execute_MouseButtonUp( const MouseEvent& rMEvt ) if( pObj ) { Rectangle aObjectRect = pObj->GetSnapRect(); - awt::Size aPageSize( ChartModelHelper::getPageSize( m_aModel->getModel() ) ); + awt::Size aPageSize( ChartModelHelper::getPageSize( getModel() ) ); Rectangle aPageRect( 0,0,aPageSize.Width,aPageSize.Height ); const E3dObject* pE3dObject = dynamic_cast< const E3dObject*>( pObj ); @@ -866,12 +872,11 @@ void ChartController::execute_MouseButtonUp( const MouseEvent& rMEvt ) ActionDescriptionProvider::createDescription( eActionType, ObjectNameProvider::getName( ObjectIdentifier::getObjectType( m_aSelection.getSelectedCID() ))), - m_xUndoManager, m_aModel->getModel() ); + m_xUndoManager, getModel() ); bool bChanged = PositionAndSizeHelper::moveObject( m_aSelection.getSelectedCID() - , m_aModel->getModel() + , getModel() , awt::Rectangle(aObjectRect.getX(),aObjectRect.getY(),aObjectRect.getWidth(),aObjectRect.getHeight()) - , awt::Rectangle(aPageRect.getX(),aPageRect.getY(),aPageRect.getWidth(),aPageRect.getHeight()) - , m_xChartView ); + , awt::Rectangle(aPageRect.getX(),aPageRect.getY(),aPageRect.getWidth(),aPageRect.getHeight()) ); if( bChanged ) { bDraggingDone = true; @@ -890,7 +895,7 @@ void ChartController::execute_MouseButtonUp( const MouseEvent& rMEvt ) if( !bDraggingDone ) //mouse wasn't moved while dragging { bool bClickedTwiceOnDragableObject = SelectionHelper::isDragableObjectHitTwice( aMPos, m_aSelection.getSelectedCID(), *pDrawViewWrapper ); - bool bIsRotateable = m_aSelection.isRotateableObjectSelected( m_aModel->getModel() ); + bool bIsRotateable = m_aSelection.isRotateableObjectSelected( getModel() ); //toggel between move and rotate if( bIsRotateable && bClickedTwiceOnDragableObject && SDRDRAG_MOVE==m_eDragMode ) @@ -1030,7 +1035,7 @@ void ChartController::execute_Command( const CommandEvent& rCEvt ) { sal_Int16 nUniqueId = 1; ObjectType eObjectType = ObjectIdentifier::getObjectType( m_aSelection.getSelectedCID() ); - Reference< XDiagram > xDiagram = ChartModelHelper::findDiagram( m_aModel->getModel() ); + Reference< XDiagram > xDiagram = ChartModelHelper::findDiagram( getModel() ); OUString aFormatCommand( lcl_getFormatCommandForObjectCID( m_aSelection.getSelectedCID() ) ); lcl_insertMenuCommand( xPopupMenu, xMenuEx, nUniqueId++, aFormatCommand ); @@ -1040,7 +1045,7 @@ void ChartController::execute_Command( const CommandEvent& rCEvt ) if( OBJECTTYPE_DATA_SERIES == eObjectType || OBJECTTYPE_DATA_POINT == eObjectType ) { bool bIsPoint = ( OBJECTTYPE_DATA_POINT == eObjectType ); - uno::Reference< XDataSeries > xSeries = ObjectIdentifier::getDataSeriesForCID( m_aSelection.getSelectedCID(), m_aModel->getModel() ); + uno::Reference< XDataSeries > xSeries = ObjectIdentifier::getDataSeriesForCID( m_aSelection.getSelectedCID(), getModel() ); uno::Reference< chart2::XRegressionCurveContainer > xCurveCnt( xSeries, uno::UNO_QUERY ); Reference< chart2::XRegressionCurve > xTrendline( RegressionCurveHelper::getFirstCurveNotMeanValueLine( xCurveCnt ) ); bool bHasEquation = RegressionCurveHelper::hasEquation( xTrendline ); @@ -1205,7 +1210,7 @@ void ChartController::execute_Command( const CommandEvent& rCEvt ) //----- else if( OBJECTTYPE_AXIS == eObjectType || OBJECTTYPE_GRID == eObjectType || OBJECTTYPE_SUBGRID == eObjectType ) { - Reference< XAxis > xAxis = ObjectIdentifier::getAxisForCID( m_aSelection.getSelectedCID(), m_aModel->getModel() ); + Reference< XAxis > xAxis = ObjectIdentifier::getAxisForCID( m_aSelection.getSelectedCID(), getModel() ); if( xAxis.is() && xDiagram.is() ) { sal_Int32 nDimensionIndex = -1; @@ -1349,7 +1354,7 @@ bool ChartController::execute_KeyInput( const KeyEvent& rKEvt ) if( ! bReturn ) { // Natvigation (Tab/F3/Home/End) - uno::Reference< XChartDocument > xChartDoc( m_aModel->getModel(), uno::UNO_QUERY ); + uno::Reference< XChartDocument > xChartDoc( getModel(), uno::UNO_QUERY ); ObjectKeyNavigation aObjNav( m_aSelection.getSelectedOID(), xChartDoc, ExplicitValueProvider::getExplicitValueProvider( m_xChartView )); awt::KeyEvent aKeyEvent( ::svt::AcceleratorExecute::st_VCLKey2AWTKey( aKeyCode )); bReturn = aObjNav.handleKeyEvent( aKeyEvent ); @@ -1361,7 +1366,7 @@ bool ChartController::execute_KeyInput( const KeyEvent& rKEvt ) { aNewSelection = aNewOID.getAny(); } - if ( m_eDragMode == SDRDRAG_ROTATE && !SelectionHelper::isRotateableObject( aNewOID.getObjectCID(), m_aModel->getModel() ) ) + if ( m_eDragMode == SDRDRAG_ROTATE && !SelectionHelper::isRotateableObject( aNewOID.getObjectCID(), getModel() ) ) { m_eDragMode = SDRDRAG_MOVE; } @@ -1494,7 +1499,7 @@ bool ChartController::execute_KeyInput( const KeyEvent& rKEvt ) { awt::Point aPos( xShape->getPosition() ); awt::Size aSize( xShape->getSize() ); - awt::Size aPageSize( ChartModelHelper::getPageSize( m_aModel->getModel() ) ); + awt::Size aPageSize( ChartModelHelper::getPageSize( getModel() ) ); aPos.X = static_cast< long >( static_cast< double >( aPos.X ) + fShiftAmountX ); aPos.Y = static_cast< long >( static_cast< double >( aPos.Y ) + fShiftAmountY ); if( aPos.X + aSize.Width > aPageSize.Width ) @@ -1582,7 +1587,7 @@ bool ChartController::requestQuickHelp( { uno::Reference< frame::XModel > xChartModel; if( m_aModel.is()) - xChartModel.set( m_aModel->getModel()); + xChartModel.set( getModel() ); if( !xChartModel.is()) return false; @@ -1743,7 +1748,7 @@ bool ChartController::impl_moveOrResizeObject( bool bNeedShift = true; bool bNeedResize = ( eType == CENTERED_RESIZE_OBJECT ); - uno::Reference< frame::XModel > xChartModel( m_aModel->getModel()); + uno::Reference< frame::XModel > xChartModel( getModel() ); uno::Reference< beans::XPropertySet > xObjProp( ObjectIdentifier::getObjectPropertySet( rCID, xChartModel )); if( xObjProp.is()) @@ -1825,7 +1830,7 @@ bool ChartController::impl_DragDataPoint( const ::rtl::OUString & rCID, double f sal_Int32 nDataPointIndex = ObjectIdentifier::getIndexFromParticleOrCID( rCID ); uno::Reference< chart2::XDataSeries > xSeries( - ObjectIdentifier::getDataSeriesForCID( rCID, m_aModel->getModel())); + ObjectIdentifier::getDataSeriesForCID( rCID, getModel() )); if( xSeries.is()) { try @@ -1996,7 +2001,7 @@ void ChartController::impl_SetMousePointer( const MouseEvent & rEvent ) { if( (m_eDragMode == SDRDRAG_ROTATE) && SelectionHelper::isRotateableObject( aHitObjectCID - , m_aModel->getModel() ) ) + , getModel() ) ) pWindow->SetPointer( Pointer( POINTER_ROTATE ) ); else { diff --git a/chart2/source/controller/main/CommandDispatchContainer.cxx b/chart2/source/controller/main/CommandDispatchContainer.cxx index 3761d0c33ce0..e0d689340760 100644 --- a/chart2/source/controller/main/CommandDispatchContainer.cxx +++ b/chart2/source/controller/main/CommandDispatchContainer.cxx @@ -72,7 +72,7 @@ void CommandDispatchContainer::setModel( m_aCachedDispatches.clear(); DisposeHelper::DisposeAllElements( m_aToBeDisposedDispatches ); m_aToBeDisposedDispatches.clear(); - m_xModel.set( xModel ); + m_xModel = xModel; } // void CommandDispatchContainer::setUndoManager( @@ -102,33 +102,33 @@ Reference< frame::XDispatch > CommandDispatchContainer::getDispatchForURL( } else { - if( rURL.Path.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Undo" )) - || rURL.Path.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Redo" ))) + uno::Reference< frame::XModel > xModel( m_xModel ); + + if( xModel.is() && (rURL.Path.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Undo" )) + || rURL.Path.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Redo" ))) ) { - CommandDispatch * pDispatch = new UndoCommandDispatch( m_xContext, m_xModel ); + CommandDispatch * pDispatch = new UndoCommandDispatch( m_xContext, xModel ); xResult.set( pDispatch ); pDispatch->initialize(); m_aCachedDispatches[ C2U(".uno:Undo") ].set( xResult ); m_aCachedDispatches[ C2U(".uno:Redo") ].set( xResult ); m_aToBeDisposedDispatches.push_back( xResult ); } - else if( rURL.Path.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Context" )) - || rURL.Path.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ModifiedStatus" ))) + else if( xModel.is() && (rURL.Path.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Context" )) + || rURL.Path.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ModifiedStatus" ))) ) { - Reference< view::XSelectionSupplier > xSelSupp; - if( m_xModel.is()) - xSelSupp.set( m_xModel->getCurrentController(), uno::UNO_QUERY ); - CommandDispatch * pDispatch = new StatusBarCommandDispatch( m_xContext, m_xModel, xSelSupp ); + Reference< view::XSelectionSupplier > xSelSupp( xModel->getCurrentController(), uno::UNO_QUERY ); + CommandDispatch * pDispatch = new StatusBarCommandDispatch( m_xContext, xModel, xSelSupp ); xResult.set( pDispatch ); pDispatch->initialize(); m_aCachedDispatches[ C2U(".uno:Context") ].set( xResult ); m_aCachedDispatches[ C2U(".uno:ModifiedStatus") ].set( xResult ); m_aToBeDisposedDispatches.push_back( xResult ); } - else if( m_xModel.is() && + else if( xModel.is() && (m_aContainerDocumentCommands.find( rURL.Path ) != m_aContainerDocumentCommands.end()) ) { - xResult.set( getContainerDispatchForURL( m_xModel->getCurrentController(), rURL )); + xResult.set( getContainerDispatchForURL( xModel->getCurrentController(), rURL )); // ToDo: can those dispatches be cached? m_aCachedDispatches[ rURL.Complete ].set( xResult ); } diff --git a/chart2/source/controller/main/CommandDispatchContainer.hxx b/chart2/source/controller/main/CommandDispatchContainer.hxx index 2cee65405ef4..1c8769e0a6d9 100644 --- a/chart2/source/controller/main/CommandDispatchContainer.hxx +++ b/chart2/source/controller/main/CommandDispatchContainer.hxx @@ -33,6 +33,7 @@ #include <com/sun/star/frame/XModel.hpp> #include <com/sun/star/frame/DispatchDescriptor.hpp> +#include <cppuhelper/weakref.hxx> #include <cppuhelper/interfacecontainer.hxx> #include <set> @@ -140,7 +141,7 @@ private: mutable tDisposeVector m_aToBeDisposedDispatches; ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext > m_xContext; - ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel > m_xModel; + ::com::sun::star::uno::WeakReference< ::com::sun::star::frame::XModel > m_xModel; ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XUndoManager > m_xUndoManager; ::com::sun::star::uno::Reference< ::com::sun::star::frame::XDispatch > m_xChartDispatcher; diff --git a/chart2/source/controller/main/ObjectHierarchy.cxx b/chart2/source/controller/main/ObjectHierarchy.cxx index 0fefa3d52310..fe73d15500f5 100644 --- a/chart2/source/controller/main/ObjectHierarchy.cxx +++ b/chart2/source/controller/main/ObjectHierarchy.cxx @@ -194,13 +194,17 @@ ImplObjectHierarchy::ImplObjectHierarchy( void ImplObjectHierarchy::createTree( const Reference< XChartDocument >& xChartDocument ) { + m_aChildMap = tChildMap();//clear tree + if( !xChartDocument.is() ) return; //@todo: change ObjectIdentifier to take an XChartDocument rather than XModel Reference< frame::XModel > xModel( xChartDocument, uno::UNO_QUERY ); Reference< XDiagram > xDiagram( ChartModelHelper::findDiagram( xChartDocument ) ); - ObjectHierarchy::tOID aDiaOID( ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierForObject( xDiagram, xModel ) ) ); + ObjectHierarchy::tOID aDiaOID; + if( xDiagram.is() ) + aDiaOID = ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifierForObject( xDiagram, xModel ) ); ObjectHierarchy::tChildContainer aTopLevelContainer; // First Level @@ -209,9 +213,12 @@ void ImplObjectHierarchy::createTree( const Reference< XChartDocument >& xChartD if( m_bOrderingForElementSelector ) { aTopLevelContainer.push_back( ObjectIdentifier( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_PAGE, OUString() ) ) ); - aTopLevelContainer.push_back( aDiaOID ); - createWallAndFloor( aTopLevelContainer, xDiagram ); - createLegendTree( aTopLevelContainer, xChartDocument, xDiagram ); + if( xDiagram.is() ) + { + aTopLevelContainer.push_back( aDiaOID ); + createWallAndFloor( aTopLevelContainer, xDiagram ); + createLegendTree( aTopLevelContainer, xChartDocument, xDiagram ); + } } // Main Title diff --git a/chart2/source/controller/main/PositionAndSizeHelper.cxx b/chart2/source/controller/main/PositionAndSizeHelper.cxx index 089abb1822f6..f0ce3eaaa04e 100644 --- a/chart2/source/controller/main/PositionAndSizeHelper.cxx +++ b/chart2/source/controller/main/PositionAndSizeHelper.cxx @@ -141,8 +141,6 @@ bool PositionAndSizeHelper::moveObject( ObjectType eObjectType { //@todo decide wether x is primary or secondary - //xChartView - //set position: chart2::RelativePosition aRelativePosition; aRelativePosition.Anchor = drawing::Alignment_CENTER; @@ -169,7 +167,6 @@ bool PositionAndSizeHelper::moveObject( const rtl::OUString& rObjectCID , const uno::Reference< frame::XModel >& xChartModel , const awt::Rectangle& rNewPositionAndSize , const awt::Rectangle& rPageRectangle - , uno::Reference< uno::XInterface > xChartView ) { ControllerLockGuard aLockedControllers( xChartModel ); @@ -183,10 +180,6 @@ bool PositionAndSizeHelper::moveObject( const rtl::OUString& rObjectCID xObjectProp = uno::Reference< beans::XPropertySet >( ObjectIdentifier::getDiagramForCID( rObjectCID, xChartModel ), uno::UNO_QUERY ); if(!xObjectProp.is()) return false; - - //add axis title sizes to the diagram size - aNewPositionAndSize = ExplicitValueProvider::calculateDiagramPositionAndSizeInclusiveTitle( - xChartModel, xChartView, rNewPositionAndSize ); } return moveObject( eObjectType, xObjectProp, aNewPositionAndSize, rPageRectangle ); } diff --git a/chart2/source/controller/main/UndoGuard.cxx b/chart2/source/controller/main/UndoGuard.cxx index 61bed4029db5..8513b6ba9093 100644 --- a/chart2/source/controller/main/UndoGuard.cxx +++ b/chart2/source/controller/main/UndoGuard.cxx @@ -55,7 +55,7 @@ UndoGuard_Base::~UndoGuard_Base() void UndoGuard_Base::commitAction() { - if( !m_bActionPosted ) + if( !m_bActionPosted && m_xUndoManager.is() ) m_xUndoManager->postAction( m_aUndoString ); m_bActionPosted = true; } @@ -67,12 +67,13 @@ UndoGuard::UndoGuard( const OUString& rUndoString , const uno::Reference< frame::XModel > & xModel ) : UndoGuard_Base( rUndoString, xUndoManager, xModel ) { - m_xUndoManager->preAction( m_xModel ); + if( m_xUndoManager.is() ) + m_xUndoManager->preAction( m_xModel ); } UndoGuard::~UndoGuard() { - if( !m_bActionPosted ) + if( !m_bActionPosted && m_xUndoManager.is() ) m_xUndoManager->cancelAction(); } @@ -83,12 +84,13 @@ UndoLiveUpdateGuard::UndoLiveUpdateGuard( const OUString& rUndoString , const uno::Reference< frame::XModel > & xModel ) : UndoGuard_Base( rUndoString, xUndoManager, xModel ) { - m_xUndoManager->preAction( m_xModel ); + if( m_xUndoManager.is() ) + m_xUndoManager->preAction( m_xModel ); } UndoLiveUpdateGuard::~UndoLiveUpdateGuard() { - if( !m_bActionPosted ) + if( !m_bActionPosted && m_xUndoManager.is() ) m_xUndoManager->cancelActionWithUndo( m_xModel ); } @@ -99,16 +101,19 @@ UndoLiveUpdateGuardWithData::UndoLiveUpdateGuardWithData( const OUString& rUndoS , const uno::Reference< frame::XModel > & xModel ) : UndoGuard_Base( rUndoString, xUndoManager, xModel ) { - Sequence< beans::PropertyValue > aArgs(1); - aArgs[0] = beans::PropertyValue( - OUString( RTL_CONSTASCII_USTRINGPARAM("WithData")), -1, uno::Any(), - beans::PropertyState_DIRECT_VALUE ); - m_xUndoManager->preActionWithArguments( m_xModel, aArgs ); + if( m_xUndoManager.is() ) + { + Sequence< beans::PropertyValue > aArgs(1); + aArgs[0] = beans::PropertyValue( + OUString( RTL_CONSTASCII_USTRINGPARAM("WithData")), -1, uno::Any(), + beans::PropertyState_DIRECT_VALUE ); + m_xUndoManager->preActionWithArguments( m_xModel, aArgs ); + } } UndoLiveUpdateGuardWithData::~UndoLiveUpdateGuardWithData() { - if( !m_bActionPosted ) + if( !m_bActionPosted && m_xUndoManager.is() ) m_xUndoManager->cancelActionWithUndo( m_xModel ); } @@ -119,16 +124,19 @@ UndoGuardWithSelection::UndoGuardWithSelection( const rtl::OUString& rUndoString , const uno::Reference< frame::XModel > & xModel ) : UndoGuard_Base( rUndoString, xUndoManager, xModel ) { - Sequence< beans::PropertyValue > aArgs(1); - aArgs[0] = beans::PropertyValue( - OUString( RTL_CONSTASCII_USTRINGPARAM("WithSelection")), -1, uno::Any(), - beans::PropertyState_DIRECT_VALUE ); - m_xUndoManager->preActionWithArguments( m_xModel, aArgs ); + if( m_xUndoManager.is() ) + { + Sequence< beans::PropertyValue > aArgs(1); + aArgs[0] = beans::PropertyValue( + OUString( RTL_CONSTASCII_USTRINGPARAM("WithSelection")), -1, uno::Any(), + beans::PropertyState_DIRECT_VALUE ); + m_xUndoManager->preActionWithArguments( m_xModel, aArgs ); + } } UndoGuardWithSelection::~UndoGuardWithSelection() { - if( !m_bActionPosted ) + if( !m_bActionPosted && m_xUndoManager.is() ) m_xUndoManager->cancelAction(); } diff --git a/chart2/source/inc/DiagramHelper.hxx b/chart2/source/inc/DiagramHelper.hxx index 14113e7396ca..c7cda6189680 100644 --- a/chart2/source/inc/DiagramHelper.hxx +++ b/chart2/source/inc/DiagramHelper.hxx @@ -46,6 +46,13 @@ namespace chart { +enum DiagramPositioningMode +{ + DiagramPositioningMode_AUTO, + DiagramPositioningMode_EXCLUDING, + DiagramPositioningMode_INCLUDING +}; + class OOO_DLLPUBLIC_CHARTTOOLS DiagramHelper { public: @@ -318,6 +325,19 @@ public: const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartType >& xChartType ); + static DiagramPositioningMode getDiagramPositioningMode( const ::com::sun::star::uno::Reference< + ::com::sun::star::chart2::XDiagram > & xDiagram ); + + static bool setDiagramPositioning( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& xChartModel, + const ::com::sun::star::awt::Rectangle& rPosRect /*100th mm*/ ); + + static ::com::sun::star::awt::Rectangle getDiagramRectangleFromModel( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& xChartModel ); + + static bool switchDiagramPositioningToExcludingPositioning( const ::com::sun::star::uno::Reference< + ::com::sun::star::frame::XModel >& xChartModel + , bool bResetModifiedState //set model back to unchanged if it was unchanged before + , bool bConvertAlsoFromAutoPositioning ); + private: // not implemented DiagramHelper(); diff --git a/chart2/source/inc/LifeTime.hxx b/chart2/source/inc/LifeTime.hxx index cb199b7c2947..8e278168259f 100644 --- a/chart2/source/inc/LifeTime.hxx +++ b/chart2/source/inc/LifeTime.hxx @@ -52,7 +52,7 @@ public: OOO_DLLPUBLIC_CHARTTOOLS LifeTimeManager( ::com::sun::star::lang::XComponent* pComponent, sal_Bool bLongLastingCallsCancelable = sal_False ); OOO_DLLPUBLIC_CHARTTOOLS virtual ~LifeTimeManager(); -OOO_DLLPUBLIC_CHARTTOOLS sal_Bool impl_isDisposed(); +OOO_DLLPUBLIC_CHARTTOOLS bool impl_isDisposed( bool bAssert=true ); OOO_DLLPUBLIC_CHARTTOOLS sal_Bool dispose() throw(::com::sun::star::uno::RuntimeException); public: @@ -105,7 +105,7 @@ OOO_DLLPUBLIC_CHARTTOOLS CloseableLifeTimeManager( ::com::sun::star::util::XC , sal_Bool bLongLastingCallsCancelable = sal_False ); OOO_DLLPUBLIC_CHARTTOOLS virtual ~CloseableLifeTimeManager(); -OOO_DLLPUBLIC_CHARTTOOLS sal_Bool impl_isDisposedOrClosed(); +OOO_DLLPUBLIC_CHARTTOOLS bool impl_isDisposedOrClosed( bool bAssert=true ); OOO_DLLPUBLIC_CHARTTOOLS sal_Bool g_close_startTryClose(sal_Bool bDeliverOwnership) throw ( ::com::sun::star::uno::Exception ); OOO_DLLPUBLIC_CHARTTOOLS sal_Bool g_close_isNeedToCancelLongLastingCalls( sal_Bool bDeliverOwnership, ::com::sun::star::util::CloseVetoException& ex ) diff --git a/chart2/source/inc/chartview/ExplicitValueProvider.hxx b/chart2/source/inc/chartview/ExplicitValueProvider.hxx index 49d38a4247ac..d10ee8d415fc 100644 --- a/chart2/source/inc/chartview/ExplicitValueProvider.hxx +++ b/chart2/source/inc/chartview/ExplicitValueProvider.hxx @@ -68,6 +68,8 @@ public: virtual ::com::sun::star::awt::Rectangle getRectangleOfObject( const rtl::OUString& rObjectCID, bool bSnapRect=false )=0; + virtual ::com::sun::star::awt::Rectangle getDiagramRectangleExcludingAxes()=0; + virtual ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > getShapeForCID( const rtl::OUString& rObjectCID )=0; @@ -77,12 +79,20 @@ public: static ExplicitValueProvider* getExplicitValueProvider( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& xChartView ); static ::com::sun::star::awt::Rectangle - calculateDiagramPositionAndSizeInclusiveTitle( + addAxisTitleSizes( + const ::com::sun::star::uno::Reference< + ::com::sun::star::frame::XModel >& xChartModel + , const ::com::sun::star::uno::Reference< + ::com::sun::star::uno::XInterface >& xChartView + , const ::com::sun::star::awt::Rectangle& rExcludingPositionAndSize ); + + static ::com::sun::star::awt::Rectangle + substractAxisTitleSizes( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& xChartModel , const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& xChartView - , const ::com::sun::star::awt::Rectangle& rExclusivePositionAndSize ); + , const ::com::sun::star::awt::Rectangle& rPositionAndSizeIncludingTitles ); static sal_Int32 getExplicitNumberFormatKeyForAxis( const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XAxis >& xAxis diff --git a/chart2/source/model/main/Axis.cxx b/chart2/source/model/main/Axis.cxx index cab49e8d0149..fd1d78ebe071 100644 --- a/chart2/source/model/main/Axis.cxx +++ b/chart2/source/model/main/Axis.cxx @@ -299,6 +299,7 @@ Axis::Axis( Reference< uno::XComponentContext > const & /* xContext */ ) : m_aSubGridProperties(), m_xTitle() { + osl_incrementInterlockedCount(&m_refCount); setFastPropertyValue_NoBroadcast( ::chart::LineProperties::PROP_LINE_COLOR, uno::makeAny( static_cast< sal_Int32 >( 0xb3b3b3 ) ) ); // gray30 @@ -308,6 +309,7 @@ Axis::Axis( Reference< uno::XComponentContext > const & /* xContext */ ) : ModifyListenerHelper::addListener( m_aScaleData.Categories, m_xModifyEventForwarder ); AllocateSubGrids(); + osl_decrementInterlockedCount(&m_refCount); } Axis::Axis( const Axis & rOther ) : @@ -365,28 +367,44 @@ Axis::~Axis() void Axis::AllocateSubGrids() { - sal_Int32 nNewSubIncCount = m_aScaleData.IncrementData.SubIncrements.getLength(); - sal_Int32 nOldSubIncCount = m_aSubGridProperties.getLength(); - - if( nOldSubIncCount > nNewSubIncCount ) - { - // remove superfluous entries - for( sal_Int32 i = nNewSubIncCount; i < nOldSubIncCount; ++i ) - ModifyListenerHelper::removeListener( m_aSubGridProperties[ i ], m_xModifyEventForwarder ); - m_aSubGridProperties.realloc( nNewSubIncCount ); - } - else if( nOldSubIncCount < nNewSubIncCount ) + Reference< util::XModifyListener > xModifyEventForwarder; + Reference< lang::XEventListener > xEventListener; + std::vector< Reference< beans::XPropertySet > > aOldBroadcasters; + std::vector< Reference< beans::XPropertySet > > aNewBroadcasters; { - m_aSubGridProperties.realloc( nNewSubIncCount ); + MutexGuard aGuard( m_aMutex ); + xModifyEventForwarder = m_xModifyEventForwarder; + xEventListener = this; + + sal_Int32 nNewSubIncCount = m_aScaleData.IncrementData.SubIncrements.getLength(); + sal_Int32 nOldSubIncCount = m_aSubGridProperties.getLength(); - // allocate new entries - for( sal_Int32 i = nOldSubIncCount; i < nNewSubIncCount; ++i ) + if( nOldSubIncCount > nNewSubIncCount ) { - m_aSubGridProperties[ i ] = new GridProperties(); - LineProperties::SetLineInvisible( m_aSubGridProperties[ i ] ); - ModifyListenerHelper::addListener( m_aSubGridProperties[ i ], m_xModifyEventForwarder ); + // remove superfluous entries + for( sal_Int32 i = nNewSubIncCount; i < nOldSubIncCount; ++i ) + aOldBroadcasters.push_back( m_aSubGridProperties[ i ] ); + m_aSubGridProperties.realloc( nNewSubIncCount ); + } + else if( nOldSubIncCount < nNewSubIncCount ) + { + m_aSubGridProperties.realloc( nNewSubIncCount ); + + // allocate new entries + for( sal_Int32 i = nOldSubIncCount; i < nNewSubIncCount; ++i ) + { + m_aSubGridProperties[ i ] = new GridProperties(); + LineProperties::SetLineInvisible( m_aSubGridProperties[ i ] ); + aNewBroadcasters.push_back( m_aSubGridProperties[ i ] ); + } } } + //don't keep the mutex locked while calling out + std::vector< Reference< beans::XPropertySet > >::iterator aBroadcaster = aOldBroadcasters.begin(); + for( ;aBroadcaster != aOldBroadcasters.end(); ++aBroadcaster ) + ModifyListenerHelper::removeListener( *aBroadcaster, xModifyEventForwarder ); + for( aBroadcaster = aNewBroadcasters.begin(); aBroadcaster != aNewBroadcasters.end(); ++aBroadcaster ) + ModifyListenerHelper::addListener( *aBroadcaster, xModifyEventForwarder ); } // -------------------------------------------------------------------------------- @@ -395,20 +413,29 @@ void Axis::AllocateSubGrids() void SAL_CALL Axis::setScaleData( const chart2::ScaleData& rScaleData ) throw (uno::RuntimeException) { + Reference< util::XModifyListener > xModifyEventForwarder; + Reference< lang::XEventListener > xEventListener; + Reference< chart2::data::XLabeledDataSequence > xOldCategories; + Reference< chart2::data::XLabeledDataSequence > xNewCategories = rScaleData.Categories; { - // /-- MutexGuard aGuard( m_aMutex ); - if( m_aScaleData.Categories.is()) - { - ModifyListenerHelper::removeListener( m_aScaleData.Categories, m_xModifyEventForwarder ); - EventListenerHelper::removeListener( m_aScaleData.Categories, this ); - } + xModifyEventForwarder = m_xModifyEventForwarder; + xEventListener = this; + xOldCategories = m_aScaleData.Categories; m_aScaleData = rScaleData; - ModifyListenerHelper::addListener( m_aScaleData.Categories, m_xModifyEventForwarder ); - EventListenerHelper::addListener( m_aScaleData.Categories, this ); + } + AllocateSubGrids(); - AllocateSubGrids(); - // \-- + //don't keep the mutex locked while calling out + if( xOldCategories.is() && xOldCategories != xNewCategories ) + { + ModifyListenerHelper::removeListener( xOldCategories, xModifyEventForwarder ); + EventListenerHelper::removeListener( xOldCategories, xEventListener ); + } + if( xNewCategories.is() && xOldCategories != xNewCategories ) + { + ModifyListenerHelper::addListener( xNewCategories, m_xModifyEventForwarder ); + EventListenerHelper::addListener( xNewCategories, xEventListener ); } fireModifyEvent(); } @@ -457,19 +484,23 @@ Reference< chart2::XTitle > SAL_CALL Axis::getTitleObject() // \-- } -void SAL_CALL Axis::setTitleObject( const Reference< chart2::XTitle >& Title ) +void SAL_CALL Axis::setTitleObject( const Reference< chart2::XTitle >& xNewTitle ) throw (uno::RuntimeException) { + Reference< util::XModifyListener > xModifyEventForwarder; + Reference< chart2::XTitle > xOldTitle; { - // /-- MutexGuard aGuard( GetMutex() ); - if( m_xTitle.is()) - ModifyListenerHelper::removeListener( m_xTitle, m_xModifyEventForwarder ); - m_xTitle = Title; - if( m_xTitle.is()) - ModifyListenerHelper::addListener( m_xTitle, m_xModifyEventForwarder ); - // \-- + xOldTitle = m_xTitle; + xModifyEventForwarder = m_xModifyEventForwarder; + m_xTitle = xNewTitle; } + + //don't keep the mutex locked while calling out + if( xOldTitle.is() && xOldTitle != xNewTitle ) + ModifyListenerHelper::removeListener( xOldTitle, xModifyEventForwarder ); + if( xNewTitle.is() && xOldTitle != xNewTitle ) + ModifyListenerHelper::addListener( xNewTitle, xModifyEventForwarder ); fireModifyEvent(); } diff --git a/chart2/source/model/main/ChartModel.cxx b/chart2/source/model/main/ChartModel.cxx index 2a34844c169d..950169395c95 100644..100755 --- a/chart2/source/model/main/ChartModel.cxx +++ b/chart2/source/model/main/ChartModel.cxx @@ -150,15 +150,28 @@ ChartModel::ChartModel( const ChartModel & rOther ) OSL_TRACE( "ChartModel: Copy-CTOR called" ); osl_incrementInterlockedCount(&m_refCount); - m_xChartTypeManager.set( CreateRefClone< Reference< chart2::XChartTypeManager > >()( rOther.m_xChartTypeManager )); - m_xTitle.set( CreateRefClone< Reference< chart2::XTitle > >()( rOther.m_xTitle )); - ModifyListenerHelper::addListener( m_xTitle, this ); - m_xPageBackground.set( CreateRefClone< Reference< beans::XPropertySet > >()( rOther.m_xPageBackground )); - ModifyListenerHelper::addListener( m_xPageBackground, this ); + Reference< util::XModifyListener > xListener; + Reference< chart2::XTitle > xNewTitle = CreateRefClone< Reference< chart2::XTitle > >()( rOther.m_xTitle ); + Reference< chart2::XDiagram > xNewDiagram = CreateRefClone< Reference< chart2::XDiagram > >()( rOther.m_xDiagram ); + Reference< beans::XPropertySet > xNewPageBackground = CreateRefClone< Reference< beans::XPropertySet > >()( rOther.m_xPageBackground ); + Reference< chart2::XChartTypeManager > xChartTypeManager = CreateRefClone< Reference< chart2::XChartTypeManager > >()( rOther.m_xChartTypeManager ); + Reference< container::XNameAccess > xXMLNamespaceMap = CreateRefClone< Reference< container::XNameAccess > >()( rOther.m_xXMLNamespaceMap ); + + { + MutexGuard aGuard( m_aModelMutex ); + xListener = this; + m_xTitle = xNewTitle; + m_xDiagram = xNewDiagram; + m_xPageBackground = xNewPageBackground; + m_xChartTypeManager = xChartTypeManager; + m_xXMLNamespaceMap = xXMLNamespaceMap; + } - m_xXMLNamespaceMap.set( CreateRefClone< Reference< container::XNameAccess > >()( rOther.m_xXMLNamespaceMap )); + ModifyListenerHelper::addListener( xNewTitle, xListener ); + ModifyListenerHelper::addListener( xNewDiagram, xListener ); + ModifyListenerHelper::addListener( xNewPageBackground, xListener ); + xListener.clear(); - CloneRefVector< Reference< chart2::XDiagram > >( rOther.m_aDiagrams, m_aDiagrams ); osl_decrementInterlockedCount(&m_refCount); } @@ -512,8 +525,7 @@ void SAL_CALL ChartModel::dispose() throw(uno::RuntimeException) m_xNumberFormatsSupplier.clear(); DisposeHelper::DisposeAndClear( m_xOwnNumberFormatsSupplier ); DisposeHelper::DisposeAndClear( m_xChartTypeManager ); - DisposeHelper::DisposeAllElements( m_aDiagrams ); - m_aDiagrams.clear(); + DisposeHelper::DisposeAndClear( m_xDiagram ); DisposeHelper::DisposeAndClear( m_xTitle ); DisposeHelper::DisposeAndClear( m_xPageBackground ); DisposeHelper::DisposeAndClear( m_xXMLNamespaceMap ); @@ -554,7 +566,7 @@ void SAL_CALL ChartModel::addEventListener( const uno::Reference< lang::XEventLi void SAL_CALL ChartModel::removeEventListener( const uno::Reference< lang::XEventListener > & xListener ) throw(uno::RuntimeException) { - if( m_aLifeTimeManager.impl_isDisposedOrClosed() ) + if( m_aLifeTimeManager.impl_isDisposedOrClosed(false) ) return; //behave passive if already disposed or closed m_aLifeTimeManager.m_aListenerContainer.removeInterface( ::getCppuType((const uno::Reference< lang::XEventListener >*)0), xListener ); @@ -573,7 +585,7 @@ void SAL_CALL ChartModel::addCloseListener( const uno::Reference< util::XClose void SAL_CALL ChartModel::removeCloseListener( const uno::Reference< util::XCloseListener > & xListener ) throw(uno::RuntimeException) { - if( m_aLifeTimeManager.impl_isDisposedOrClosed() ) + if( m_aLifeTimeManager.impl_isDisposedOrClosed(false) ) return; //behave passive if already disposed or closed m_aLifeTimeManager.m_aListenerContainer.removeInterface( ::getCppuType((const uno::Reference< util::XCloseListener >*)0), xListener ); @@ -684,38 +696,26 @@ uno::Reference< document::XDocumentProperties > SAL_CALL uno::Reference< chart2::XDiagram > SAL_CALL ChartModel::getFirstDiagram() throw (uno::RuntimeException) { - // /-- MutexGuard aGuard( m_aModelMutex ); - if( m_aDiagrams.size() ) - return m_aDiagrams[ 0 ]; - return uno::Reference< chart2::XDiagram >(); - // \-- + return m_xDiagram; } -void ChartModel::impl_removeAllDiagrams() -{ - ModifyListenerHelper::removeListenerFromAllElements( m_aDiagrams, this ); - m_aDiagrams.clear(); -} - -void ChartModel::impl_appendDiagram( const Reference< chart2::XDiagram > & xDiagram ) -{ - Reference< util::XModifyBroadcaster > xBroadcaster( xDiagram, uno::UNO_QUERY ); - ModifyListenerHelper::addListener( xDiagram, this ); - m_aDiagrams.push_back( xDiagram ); -} - - void SAL_CALL ChartModel::setFirstDiagram( const uno::Reference< chart2::XDiagram >& xDiagram ) throw (uno::RuntimeException) { + Reference< chart2::XDiagram > xOldDiagram; + Reference< util::XModifyListener > xListener; { - // /-- MutexGuard aGuard( m_aModelMutex ); - impl_removeAllDiagrams(); - impl_appendDiagram( xDiagram ); - // \-- + if( xDiagram == m_xDiagram ) + return; + xOldDiagram = m_xDiagram; + m_xDiagram = xDiagram; + xListener = this; } + //don't keep the mutex locked while calling out + ModifyListenerHelper::removeListener( xOldDiagram, xListener ); + ModifyListenerHelper::addListener( xDiagram, xListener ); setModified( sal_True ); } @@ -885,10 +885,7 @@ void SAL_CALL ChartModel::setArguments( const Sequence< beans::PropertyValue >& if( xDia.is()) xTemplate->changeDiagramData( xDia, xDataSource, aArguments ); else - { - impl_removeAllDiagrams(); - impl_appendDiagram( xTemplate->createDiagramByDataSource( xDataSource, aArguments )); - } + setFirstDiagram( xTemplate->createDiagramByDataSource( xDataSource, aArguments ) ); } } } diff --git a/chart2/source/model/main/ChartModel.hxx b/chart2/source/model/main/ChartModel.hxx index 860f71f909ea..23da02f3f83a 100644 --- a/chart2/source/model/main/ChartModel.hxx +++ b/chart2/source/model/main/ChartModel.hxx @@ -162,11 +162,8 @@ private: m_xChartTypeManager; // Diagram Access - typedef ::std::vector< ::com::sun::star::uno::Reference< - ::com::sun::star::chart2::XDiagram > > - tDiagramContainer; - - tDiagramContainer m_aDiagrams; + ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDiagram > + m_xDiagram; ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XTitle > m_xTitle; @@ -231,10 +228,6 @@ private: void impl_adjustAdditionalShapesPositionAndSize( const ::com::sun::star::awt::Size& aVisualAreaSize ); - void impl_removeAllDiagrams(); - void impl_appendDiagram( const ::com::sun::star::uno::Reference< - ::com::sun::star::chart2::XDiagram > & xDiagram ); - ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatsSupplier > impl_getNumberFormatsSupplier(); diff --git a/chart2/source/model/main/ChartModel_Persistence.cxx b/chart2/source/model/main/ChartModel_Persistence.cxx index 113be99915cb..1868c38e094f 100644 --- a/chart2/source/model/main/ChartModel_Persistence.cxx +++ b/chart2/source/model/main/ChartModel_Persistence.cxx @@ -413,8 +413,6 @@ void SAL_CALL ChartModel::initNew() try { // create default chart - impl_removeAllDiagrams(); - Reference< chart2::XChartTypeTemplate > xTemplate( impl_createDefaultChartTypeTemplate() ); if( xTemplate.is()) { @@ -433,7 +431,7 @@ void SAL_CALL ChartModel::initNew() Reference< chart2::XDiagram > xDiagram( xTemplate->createDiagramByDataSource( xDataSource, aParam ) ); - impl_appendDiagram( xDiagram ); + setFirstDiagram( xDiagram ); bool bIsRTL = Application::GetSettings().GetLayoutRTL(); //reverse x axis for rtl charts @@ -750,7 +748,7 @@ void SAL_CALL ChartModel::removeModifyListener( const uno::Reference< util::XModifyListener >& xListener ) throw(uno::RuntimeException) { - if( m_aLifeTimeManager.impl_isDisposedOrClosed() ) + if( m_aLifeTimeManager.impl_isDisposedOrClosed(false) ) return; //behave passive if already disposed or closed m_aLifeTimeManager.m_aListenerContainer.removeInterface( @@ -852,7 +850,7 @@ void SAL_CALL ChartModel::addStorageChangeListener( const Reference< document::X void SAL_CALL ChartModel::removeStorageChangeListener( const Reference< document::XStorageChangeListener >& xListener ) throw (uno::RuntimeException) { - if( m_aLifeTimeManager.impl_isDisposedOrClosed() ) + if( m_aLifeTimeManager.impl_isDisposedOrClosed(false) ) return; //behave passive if already disposed or closed m_aLifeTimeManager.m_aListenerContainer.removeInterface( diff --git a/chart2/source/model/main/DataSeries.cxx b/chart2/source/model/main/DataSeries.cxx index bdb46665004f..89197aa5ba3f 100644 --- a/chart2/source/model/main/DataSeries.cxx +++ b/chart2/source/model/main/DataSeries.cxx @@ -360,64 +360,76 @@ Reference< beans::XPropertySet > throw (lang::IndexOutOfBoundsException, uno::RuntimeException) { - Reference< beans::XPropertySet > aResult; + Reference< beans::XPropertySet > xResult; - // /-- - MutexGuard aGuard( GetMutex() ); + Sequence< Reference< chart2::data::XLabeledDataSequence > > aSequences; + { + MutexGuard aGuard( GetMutex() ); + aSequences = ContainerHelper::ContainerToSequence( m_aDataSequences ); + } - if( ! m_aDataSequences.empty() ) + ::std::vector< Reference< chart2::data::XLabeledDataSequence > > aValuesSeries( + DataSeriesHelper::getAllDataSequencesByRole( aSequences , C2U("values"), true ) ); + if( !aValuesSeries.empty() ) { - ::std::vector< Reference< chart2::data::XLabeledDataSequence > > aValuesSeries( - DataSeriesHelper::getAllDataSequencesByRole( - ContainerHelper::ContainerToSequence( m_aDataSequences ), - C2U("values"), true )); - if( ! aValuesSeries.empty()) + Reference< chart2::data::XDataSequence > xSeq( aValuesSeries.front()->getValues() ); + if( 0 <= nIndex && nIndex < xSeq->getData().getLength() ) { - Reference< chart2::data::XDataSequence > xSeq( aValuesSeries.front()->getValues()); - if( 0 <= nIndex && nIndex < xSeq->getData().getLength()) { - tDataPointAttributeContainer::iterator aIt( - m_aAttributedDataPoints.find( nIndex )); - - if( aIt == m_aAttributedDataPoints.end()) + MutexGuard aGuard( GetMutex() ); + tDataPointAttributeContainer::iterator aIt( m_aAttributedDataPoints.find( nIndex ) ); + if( aIt != m_aAttributedDataPoints.end() ) + xResult = (*aIt).second; + } + if( !xResult.is() ) + { + Reference< beans::XPropertySet > xParentProperties; + Reference< util::XModifyListener > xModifyEventForwarder; { - // create a new XPropertySet for this data point - aResult.set( new DataPoint( this )); - ModifyListenerHelper::addListener( aResult, m_xModifyEventForwarder ); - m_aAttributedDataPoints[ nIndex ] = aResult; + MutexGuard aGuard( GetMutex() ); + xParentProperties = this; + xModifyEventForwarder = m_xModifyEventForwarder; } - else + + // create a new XPropertySet for this data point + xResult.set( new DataPoint( xParentProperties ) ); { - aResult = (*aIt).second; + MutexGuard aGuard( GetMutex() ); + m_aAttributedDataPoints[ nIndex ] = xResult; } + ModifyListenerHelper::addListener( xResult, xModifyEventForwarder ); } } - else - { - throw lang::IndexOutOfBoundsException(); - } } else { throw lang::IndexOutOfBoundsException(); } - return aResult; - // \-- + return xResult; } void SAL_CALL DataSeries::resetDataPoint( sal_Int32 nIndex ) throw (uno::RuntimeException) { - MutexGuard aGuard( GetMutex() ); - tDataPointAttributeContainer::iterator aIt( m_aAttributedDataPoints.find( nIndex )); - if( aIt != m_aAttributedDataPoints.end()) + Reference< beans::XPropertySet > xDataPointProp; + Reference< util::XModifyListener > xModifyEventForwarder; + { + MutexGuard aGuard( GetMutex() ); + xModifyEventForwarder = m_xModifyEventForwarder; + tDataPointAttributeContainer::iterator aIt( m_aAttributedDataPoints.find( nIndex )); + if( aIt != m_aAttributedDataPoints.end()) + { + xDataPointProp = (*aIt).second; + m_aAttributedDataPoints.erase(aIt); + } + + } + if( xDataPointProp.is() ) { - Reference< beans::XPropertySet > xDataPointProp( (*aIt).second ); Reference< util::XModifyBroadcaster > xBroadcaster( xDataPointProp, uno::UNO_QUERY ); - if( xBroadcaster.is() && m_xModifyEventForwarder.is()) - xBroadcaster->removeModifyListener( m_xModifyEventForwarder ); - m_aAttributedDataPoints.erase(aIt); + if( xBroadcaster.is() && xModifyEventForwarder.is()) + xBroadcaster->removeModifyListener( xModifyEventForwarder ); fireModifyEvent(); } } @@ -425,9 +437,15 @@ void SAL_CALL DataSeries::resetDataPoint( sal_Int32 nIndex ) void SAL_CALL DataSeries::resetAllDataPoints() throw (uno::RuntimeException) { - MutexGuard aGuard( GetMutex() ); - ModifyListenerHelper::removeListenerFromAllMapElements( m_aAttributedDataPoints, m_xModifyEventForwarder ); - m_aAttributedDataPoints.clear(); + tDataPointAttributeContainer aOldAttributedDataPoints; + Reference< util::XModifyListener > xModifyEventForwarder; + { + MutexGuard aGuard( GetMutex() ); + xModifyEventForwarder = m_xModifyEventForwarder; + std::swap( aOldAttributedDataPoints, m_aAttributedDataPoints ); + } + ModifyListenerHelper::removeListenerFromAllMapElements( aOldAttributedDataPoints, xModifyEventForwarder ); + aOldAttributedDataPoints.clear(); fireModifyEvent(); } @@ -435,25 +453,31 @@ void SAL_CALL DataSeries::resetAllDataPoints() void SAL_CALL DataSeries::setData( const uno::Sequence< Reference< chart2::data::XLabeledDataSequence > >& aData ) throw (uno::RuntimeException) { - // /-- - MutexGuard aGuard( GetMutex() ); - ModifyListenerHelper::removeListenerFromAllElements( m_aDataSequences, m_xModifyEventForwarder ); - EventListenerHelper::removeListenerFromAllElements( m_aDataSequences, this ); - m_aDataSequences = ContainerHelper::SequenceToVector( aData ); - EventListenerHelper::addListenerToAllElements( m_aDataSequences, this ); - ModifyListenerHelper::addListenerToAllElements( m_aDataSequences, m_xModifyEventForwarder ); + tDataSequenceContainer aOldDataSequences; + tDataSequenceContainer aNewDataSequences; + Reference< util::XModifyListener > xModifyEventForwarder; + Reference< lang::XEventListener > xListener; + { + MutexGuard aGuard( GetMutex() ); + xModifyEventForwarder = m_xModifyEventForwarder; + xListener = this; + std::swap( aOldDataSequences, m_aDataSequences ); + aNewDataSequences = ContainerHelper::SequenceToVector( aData ); + m_aDataSequences = aNewDataSequences; + } + ModifyListenerHelper::removeListenerFromAllElements( aOldDataSequences, xModifyEventForwarder ); + EventListenerHelper::removeListenerFromAllElements( aOldDataSequences, xListener ); + EventListenerHelper::addListenerToAllElements( aNewDataSequences, xListener ); + ModifyListenerHelper::addListenerToAllElements( aNewDataSequences, xModifyEventForwarder ); fireModifyEvent(); - // \-- } // ____ XDataSource ____ Sequence< Reference< chart2::data::XLabeledDataSequence > > SAL_CALL DataSeries::getDataSequences() throw (uno::RuntimeException) { - // /-- MutexGuard aGuard( GetMutex() ); return ContainerHelper::ContainerToSequence( m_aDataSequences ); - // \-- } @@ -463,12 +487,16 @@ void SAL_CALL DataSeries::addRegressionCurve( throw (lang::IllegalArgumentException, uno::RuntimeException) { - if( ::std::find( m_aRegressionCurves.begin(), m_aRegressionCurves.end(), xRegressionCurve ) - != m_aRegressionCurves.end()) - throw lang::IllegalArgumentException(); - - m_aRegressionCurves.push_back( xRegressionCurve ); - ModifyListenerHelper::addListener( xRegressionCurve, m_xModifyEventForwarder ); + Reference< util::XModifyListener > xModifyEventForwarder; + { + MutexGuard aGuard( GetMutex() ); + xModifyEventForwarder = m_xModifyEventForwarder; + if( ::std::find( m_aRegressionCurves.begin(), m_aRegressionCurves.end(), xRegressionCurve ) + != m_aRegressionCurves.end()) + throw lang::IllegalArgumentException(); + m_aRegressionCurves.push_back( xRegressionCurve ); + } + ModifyListenerHelper::addListener( xRegressionCurve, xModifyEventForwarder ); fireModifyEvent(); } @@ -477,25 +505,30 @@ void SAL_CALL DataSeries::removeRegressionCurve( throw (container::NoSuchElementException, uno::RuntimeException) { - if( ! xRegressionCurve.is()) + if( !xRegressionCurve.is() ) throw container::NoSuchElementException(); - tRegressionCurveContainerType::iterator aIt( + Reference< util::XModifyListener > xModifyEventForwarder; + { + MutexGuard aGuard( GetMutex() ); + xModifyEventForwarder = m_xModifyEventForwarder; + tRegressionCurveContainerType::iterator aIt( ::std::find( m_aRegressionCurves.begin(), m_aRegressionCurves.end(), xRegressionCurve ) ); + if( aIt == m_aRegressionCurves.end()) + throw container::NoSuchElementException( + C2U( "The given regression curve is no element of this series" ), + static_cast< uno::XWeak * >( this )); + m_aRegressionCurves.erase( aIt ); + } - if( aIt == m_aRegressionCurves.end()) - throw container::NoSuchElementException( - C2U( "The given regression curve is no element of this series" ), - static_cast< uno::XWeak * >( this )); - - ModifyListenerHelper::removeListener( xRegressionCurve, m_xModifyEventForwarder ); - m_aRegressionCurves.erase( aIt ); + ModifyListenerHelper::removeListener( xRegressionCurve, xModifyEventForwarder ); fireModifyEvent(); } uno::Sequence< uno::Reference< chart2::XRegressionCurve > > SAL_CALL DataSeries::getRegressionCurves() throw (uno::RuntimeException) { + MutexGuard aGuard( GetMutex() ); return ContainerHelper::ContainerToSequence( m_aRegressionCurves ); } @@ -503,10 +536,18 @@ void SAL_CALL DataSeries::setRegressionCurves( const Sequence< Reference< chart2::XRegressionCurve > >& aRegressionCurves ) throw (uno::RuntimeException) { - ModifyListenerHelper::removeListenerFromAllElements( m_aRegressionCurves, m_xModifyEventForwarder ); - m_aRegressionCurves.clear(); - for( sal_Int32 i=0; i<aRegressionCurves.getLength(); ++i ) - addRegressionCurve( aRegressionCurves[i] ); + tRegressionCurveContainerType aOldCurves; + tRegressionCurveContainerType aNewCurves( ContainerHelper::SequenceToVector( aRegressionCurves ) ); + Reference< util::XModifyListener > xModifyEventForwarder; + { + MutexGuard aGuard( GetMutex() ); + xModifyEventForwarder = m_xModifyEventForwarder; + std::swap( aOldCurves, m_aRegressionCurves ); + m_aRegressionCurves = aNewCurves; + } + ModifyListenerHelper::removeListenerFromAllElements( aOldCurves, xModifyEventForwarder ); + ModifyListenerHelper::addListenerToAllElements( aNewCurves, xModifyEventForwarder ); + fireModifyEvent(); } // ____ XModifyBroadcaster ____ diff --git a/chart2/source/model/main/Diagram.cxx b/chart2/source/model/main/Diagram.cxx index f74764c398ef..ff8a0c4030bc 100644 --- a/chart2/source/model/main/Diagram.cxx +++ b/chart2/source/model/main/Diagram.cxx @@ -71,6 +71,7 @@ enum { PROP_DIAGRAM_REL_POS, PROP_DIAGRAM_REL_SIZE, + PROP_DIAGRAM_POSSIZE_EXCLUDE_LABELS, PROP_DIAGRAM_SORT_BY_X_VALUES, PROP_DIAGRAM_CONNECT_BARS, PROP_DIAGRAM_GROUP_BARS_PER_AXIS, @@ -101,6 +102,13 @@ void lcl_AddPropertiesToVector( | beans::PropertyAttribute::MAYBEVOID )); rOutProperties.push_back( + Property( C2U( "PosSizeExcludeAxes" ), + PROP_DIAGRAM_POSSIZE_EXCLUDE_LABELS, + ::getBooleanCppuType(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::MAYBEDEFAULT )); + + rOutProperties.push_back( Property( C2U( "SortByXValues" ), PROP_DIAGRAM_SORT_BY_X_VALUES, ::getBooleanCppuType(), @@ -171,6 +179,7 @@ void lcl_AddPropertiesToVector( void lcl_AddDefaultsToMap( ::chart::tPropertyValueMap & rOutMap ) { + ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_DIAGRAM_POSSIZE_EXCLUDE_LABELS, true ); ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_DIAGRAM_SORT_BY_X_VALUES, false ); ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_DIAGRAM_CONNECT_BARS, false ); ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_DIAGRAM_GROUP_BARS_PER_AXIS, true ); @@ -300,72 +309,91 @@ Diagram::~Diagram() uno::Reference< beans::XPropertySet > SAL_CALL Diagram::getWall() throw (uno::RuntimeException) { - // /-- - MutexGuard aGuard( GetMutex() ); - if( ! m_xWall.is()) + uno::Reference< beans::XPropertySet > xRet; + bool bAddListener = false; { - m_xWall.set( new Wall()); - ModifyListenerHelper::addListener( m_xWall, m_xModifyEventForwarder ); + MutexGuard aGuard( GetMutex() ); + if( !m_xWall.is() ) + { + m_xWall.set( new Wall() ); + bAddListener = true; + } + xRet = m_xWall; } - return m_xWall; - // \-- + if(bAddListener) + ModifyListenerHelper::addListener( xRet, m_xModifyEventForwarder ); + return xRet; } uno::Reference< beans::XPropertySet > SAL_CALL Diagram::getFloor() throw (uno::RuntimeException) { - // /-- - MutexGuard aGuard( GetMutex() ); - if( ! m_xFloor.is()) + uno::Reference< beans::XPropertySet > xRet; + bool bAddListener = false; { - m_xFloor.set( new Wall()); - ModifyListenerHelper::addListener( m_xFloor, m_xModifyEventForwarder ); + MutexGuard aGuard( GetMutex() ); + if( !m_xFloor.is() ) + { + m_xFloor.set( new Wall() ); + bAddListener = true; + } + xRet = m_xFloor; } - return m_xFloor; - // \-- + if(bAddListener) + ModifyListenerHelper::addListener( xRet, m_xModifyEventForwarder ); + return xRet; } uno::Reference< chart2::XLegend > SAL_CALL Diagram::getLegend() throw (uno::RuntimeException) { - // /-- MutexGuard aGuard( GetMutex() ); return m_xLegend; - // \-- } -void SAL_CALL Diagram::setLegend( const uno::Reference< chart2::XLegend >& xLegend ) +void SAL_CALL Diagram::setLegend( const uno::Reference< chart2::XLegend >& xNewLegend ) throw (uno::RuntimeException) { - // /-- - ::osl::ClearableMutexGuard aGuard( GetMutex() ); - if( xLegend != m_xLegend ) + Reference< chart2::XLegend > xOldLegend; { - if( m_xLegend.is()) - ModifyListenerHelper::removeListener( m_xLegend, m_xModifyEventForwarder ); - m_xLegend = xLegend; - if( m_xLegend.is()) - ModifyListenerHelper::addListener( m_xLegend, m_xModifyEventForwarder ); - aGuard.clear(); - // \-- - fireModifyEvent(); + MutexGuard aGuard( GetMutex() ); + if( m_xLegend == xNewLegend ) + return; + xOldLegend = m_xLegend; + m_xLegend = xNewLegend; } + if( xOldLegend.is()) + ModifyListenerHelper::removeListener( xOldLegend, m_xModifyEventForwarder ); + if( xNewLegend.is()) + ModifyListenerHelper::addListener( xNewLegend, m_xModifyEventForwarder ); + fireModifyEvent(); } Reference< chart2::XColorScheme > SAL_CALL Diagram::getDefaultColorScheme() throw (uno::RuntimeException) { - if( ! m_xColorScheme.is()) + Reference< chart2::XColorScheme > xRet; + { + MutexGuard aGuard( GetMutex() ); + xRet = m_xColorScheme; + } + + if( !xRet.is()) { - m_xColorScheme.set( createConfigColorScheme( m_xContext )); + xRet.set( createConfigColorScheme( m_xContext )); + MutexGuard aGuard( GetMutex() ); + m_xColorScheme = xRet; } - return m_xColorScheme; + return xRet; } void SAL_CALL Diagram::setDefaultColorScheme( const Reference< chart2::XColorScheme >& xColorScheme ) throw (uno::RuntimeException) { - m_xColorScheme.set( xColorScheme ); + { + MutexGuard aGuard( GetMutex() ); + m_xColorScheme.set( xColorScheme ); + } fireModifyEvent(); } @@ -373,27 +401,26 @@ void SAL_CALL Diagram::setDefaultColorScheme( const Reference< chart2::XColorSch uno::Reference< chart2::XTitle > SAL_CALL Diagram::getTitleObject() throw (uno::RuntimeException) { - // /-- MutexGuard aGuard( GetMutex() ); return m_xTitle; - // \-- } -void SAL_CALL Diagram::setTitleObject( const uno::Reference< chart2::XTitle >& Title ) +void SAL_CALL Diagram::setTitleObject( const uno::Reference< chart2::XTitle >& xNewTitle ) throw (uno::RuntimeException) { - // /-- - ::osl::ClearableMutexGuard aGuard( GetMutex() ); - - if( m_xTitle != Title ) + Reference< chart2::XTitle > xOldTitle; { - ModifyListenerHelper::removeListener( m_xTitle, m_xModifyEventForwarder ); - m_xTitle = Title; - ModifyListenerHelper::addListener( m_xTitle, m_xModifyEventForwarder ); - // \-- - aGuard.clear(); - fireModifyEvent(); + MutexGuard aGuard( GetMutex() ); + if( m_xTitle == xNewTitle ) + return; + xOldTitle = m_xTitle; + m_xTitle = xNewTitle; } + if( xOldTitle.is()) + ModifyListenerHelper::removeListener( xOldTitle, m_xModifyEventForwarder ); + if( xNewTitle.is()) + ModifyListenerHelper::addListener( xNewTitle, m_xModifyEventForwarder ); + fireModifyEvent(); } // ____ X3DDefaultSetter ____ @@ -421,18 +448,19 @@ void SAL_CALL Diagram::addCoordinateSystem( throw (lang::IllegalArgumentException, uno::RuntimeException) { - if( ::std::find( m_aCoordSystems.begin(), m_aCoordSystems.end(), aCoordSys ) - != m_aCoordSystems.end()) - throw lang::IllegalArgumentException(); - - if( m_aCoordSystems.size()>=1 ) { - OSL_ENSURE( false, "more than one coordinatesystem is not supported yet by the fileformat" ); - return; - } - - m_aCoordSystems.push_back( aCoordSys ); + MutexGuard aGuard( GetMutex() ); + if( ::std::find( m_aCoordSystems.begin(), m_aCoordSystems.end(), aCoordSys ) + != m_aCoordSystems.end()) + throw lang::IllegalArgumentException(); + if( m_aCoordSystems.size()>=1 ) + { + OSL_ENSURE( false, "more than one coordinatesystem is not supported yet by the fileformat" ); + return; + } + m_aCoordSystems.push_back( aCoordSys ); + } ModifyListenerHelper::addListener( aCoordSys, m_xModifyEventForwarder ); fireModifyEvent(); } @@ -442,15 +470,16 @@ void SAL_CALL Diagram::removeCoordinateSystem( throw (container::NoSuchElementException, uno::RuntimeException) { - ::std::vector< uno::Reference< chart2::XCoordinateSystem > >::iterator - aIt( ::std::find( m_aCoordSystems.begin(), m_aCoordSystems.end(), aCoordSys )); - if( aIt == m_aCoordSystems.end()) - throw container::NoSuchElementException( - C2U( "The given coordinate-system is no element of the container" ), - static_cast< uno::XWeak * >( this )); - - m_aCoordSystems.erase( aIt ); - + { + MutexGuard aGuard( GetMutex() ); + ::std::vector< uno::Reference< chart2::XCoordinateSystem > >::iterator + aIt( ::std::find( m_aCoordSystems.begin(), m_aCoordSystems.end(), aCoordSys )); + if( aIt == m_aCoordSystems.end()) + throw container::NoSuchElementException( + C2U( "The given coordinate-system is no element of the container" ), + static_cast< uno::XWeak * >( this )); + m_aCoordSystems.erase( aIt ); + } ModifyListenerHelper::removeListener( aCoordSys, m_xModifyEventForwarder ); fireModifyEvent(); } @@ -458,6 +487,7 @@ void SAL_CALL Diagram::removeCoordinateSystem( uno::Sequence< uno::Reference< chart2::XCoordinateSystem > > SAL_CALL Diagram::getCoordinateSystems() throw (uno::RuntimeException) { + MutexGuard aGuard( GetMutex() ); return ContainerHelper::ContainerToSequence( m_aCoordSystems ); } @@ -466,17 +496,20 @@ void SAL_CALL Diagram::setCoordinateSystems( throw (lang::IllegalArgumentException, uno::RuntimeException) { - Sequence< Reference< chart2::XCoordinateSystem > > aNew(aCoordinateSystems); - - if( aNew.getLength()>1 ) + tCoordinateSystemContainerType aNew; + tCoordinateSystemContainerType aOld; + if( aCoordinateSystems.getLength()>0 ) { - OSL_ENSURE( false, "more than one coordinatesystem is not supported yet by the fileformat" ); - aNew.realloc(1); + OSL_ENSURE( aCoordinateSystems.getLength()<=1, "more than one coordinatesystem is not supported yet by the fileformat" ); + aNew.push_back( aCoordinateSystems[0] ); } - - ModifyListenerHelper::removeListenerFromAllElements( m_aCoordSystems, m_xModifyEventForwarder ); - m_aCoordSystems = ContainerHelper::SequenceToVector( aNew ); - ModifyListenerHelper::addListenerToAllElements( m_aCoordSystems, m_xModifyEventForwarder ); + { + MutexGuard aGuard( GetMutex() ); + std::swap( aOld, m_aCoordSystems ); + m_aCoordSystems = aNew; + } + ModifyListenerHelper::removeListenerFromAllElements( aOld, m_xModifyEventForwarder ); + ModifyListenerHelper::addListenerToAllElements( aNew, m_xModifyEventForwarder ); fireModifyEvent(); } @@ -484,6 +517,7 @@ void SAL_CALL Diagram::setCoordinateSystems( Reference< util::XCloneable > SAL_CALL Diagram::createClone() throw (uno::RuntimeException) { + MutexGuard aGuard( GetMutex() ); return Reference< util::XCloneable >( new Diagram( *this )); } diff --git a/chart2/source/model/main/FormattedString.cxx b/chart2/source/model/main/FormattedString.cxx index ae810266df29..9d38fafd3cf7 100644 --- a/chart2/source/model/main/FormattedString.cxx +++ b/chart2/source/model/main/FormattedString.cxx @@ -122,11 +122,13 @@ uno::Reference< util::XCloneable > SAL_CALL FormattedString::createClone() void SAL_CALL FormattedString::setString( const ::rtl::OUString& String ) throw (uno::RuntimeException) { - // /-- - MutexGuard aGuard( GetMutex()); - m_aString = String; + { + MutexGuard aGuard( GetMutex()); + m_aString = String; + } + //don't keep the mutex locked while calling out fireModifyEvent(); - // \-- + } // ____ XModifyBroadcaster ____ diff --git a/chart2/source/model/main/Title.cxx b/chart2/source/model/main/Title.cxx index 0a215c2d4c15..d7c5691d160d 100644 --- a/chart2/source/model/main/Title.cxx +++ b/chart2/source/model/main/Title.cxx @@ -256,24 +256,25 @@ uno::Reference< util::XCloneable > SAL_CALL Title::createClone() uno::Sequence< uno::Reference< chart2::XFormattedString > > SAL_CALL Title::getText() throw (uno::RuntimeException) { - // /-- MutexGuard aGuard( GetMutex() ); return m_aStrings; - // \-- } -void SAL_CALL Title::setText( const uno::Sequence< uno::Reference< chart2::XFormattedString > >& Strings ) +void SAL_CALL Title::setText( const uno::Sequence< uno::Reference< chart2::XFormattedString > >& rNewStrings ) throw (uno::RuntimeException) { - // /-- - MutexGuard aGuard( GetMutex() ); + uno::Sequence< uno::Reference< chart2::XFormattedString > > aOldStrings; + { + MutexGuard aGuard( GetMutex() ); + std::swap( m_aStrings, aOldStrings ); + m_aStrings = rNewStrings; + } + //don't keep the mutex locked while calling out ModifyListenerHelper::removeListenerFromAllElements( - ContainerHelper::SequenceToVector( m_aStrings ), m_xModifyEventForwarder ); - m_aStrings = Strings; + ContainerHelper::SequenceToVector( aOldStrings ), m_xModifyEventForwarder ); ModifyListenerHelper::addListenerToAllElements( - ContainerHelper::SequenceToVector( m_aStrings ), m_xModifyEventForwarder ); + ContainerHelper::SequenceToVector( rNewStrings ), m_xModifyEventForwarder ); fireModifyEvent(); - // \-- } // ================================================================================ diff --git a/chart2/source/tools/CharacterProperties.cxx b/chart2/source/tools/CharacterProperties.cxx index 3b39609f8b85..cca655780a79 100644 --- a/chart2/source/tools/CharacterProperties.cxx +++ b/chart2/source/tools/CharacterProperties.cxx @@ -254,8 +254,8 @@ void CharacterProperties::AddPropertiesToVector( Property( C2U( "CharLocale" ), PROP_CHAR_LOCALE, ::getCppuType( reinterpret_cast< const lang::Locale * >(0)), - beans::PropertyAttribute::BOUND - | beans::PropertyAttribute::MAYBEDEFAULT )); + //#i111967# no PropertyChangeEvent is fired on change so far + beans::PropertyAttribute::MAYBEDEFAULT )); // CharShadowed rOutProperties.push_back( Property( C2U( "CharShadowed" ), @@ -385,8 +385,8 @@ void CharacterProperties::AddPropertiesToVector( Property( C2U( "CharLocaleAsian" ), PROP_CHAR_ASIAN_LOCALE, ::getCppuType( reinterpret_cast< const lang::Locale * >(0)), - beans::PropertyAttribute::BOUND - | beans::PropertyAttribute::MAYBEDEFAULT )); + //#i111967# no PropertyChangeEvent is fired on change so far + beans::PropertyAttribute::MAYBEDEFAULT )); // CharacterPropertiesComplex // === @@ -452,8 +452,8 @@ void CharacterProperties::AddPropertiesToVector( Property( C2U( "CharLocaleComplex" ), PROP_CHAR_COMPLEX_LOCALE, ::getCppuType( reinterpret_cast< const lang::Locale * >(0)), - beans::PropertyAttribute::BOUND - | beans::PropertyAttribute::MAYBEDEFAULT )); + //#i111967# no PropertyChangeEvent is fired on change so far + beans::PropertyAttribute::MAYBEDEFAULT )); // Writing Mode left to right vs right to left rOutProperties.push_back( diff --git a/chart2/source/tools/DiagramHelper.cxx b/chart2/source/tools/DiagramHelper.cxx index b95e7522943e..36afef60a6d4 100644 --- a/chart2/source/tools/DiagramHelper.cxx +++ b/chart2/source/tools/DiagramHelper.cxx @@ -39,8 +39,13 @@ #include "CommonConverters.hxx" #include "ExplicitCategoriesProvider.hxx" #include "servicenames_charttypes.hxx" +#include "ChartModelHelper.hxx" +#include "RelativePositionHelper.hxx" +#include "ControllerLockGuard.hxx" #include <com/sun/star/chart/MissingValueTreatment.hpp> +#include <com/sun/star/chart/XChartDocument.hpp> +#include <com/sun/star/chart/XDiagramPositioning.hpp> #include <com/sun/star/chart2/XTitled.hpp> #include <com/sun/star/chart2/XChartTypeContainer.hpp> #include <com/sun/star/chart2/XChartTypeTemplate.hpp> @@ -49,10 +54,14 @@ #include <com/sun/star/chart2/InterpretedData.hpp> #include <com/sun/star/chart2/AxisType.hpp> #include <com/sun/star/chart2/DataPointGeometry3D.hpp> -#include <com/sun/star/drawing/ShadeMode.hpp> +#include <com/sun/star/chart2/RelativePosition.hpp> +#include <com/sun/star/chart2/RelativeSize.hpp> +#include <unotools/saveopt.hxx> #include <rtl/math.hxx> +#include <com/sun/star/util/XModifiable.hpp> + using namespace ::com::sun::star; using namespace ::com::sun::star::chart2; using namespace ::std; @@ -466,18 +475,20 @@ sal_Int32 DiagramHelper::getDimension( const Reference< XDiagram > & xDiagram ) try { - Reference< XCoordinateSystemContainer > xCooSysCnt( - xDiagram, uno::UNO_QUERY_THROW ); - Sequence< Reference< XCoordinateSystem > > aCooSysSeq( - xCooSysCnt->getCoordinateSystems()); - - for( sal_Int32 i=0; i<aCooSysSeq.getLength(); ++i ) + Reference< XCoordinateSystemContainer > xCooSysCnt( xDiagram, uno::UNO_QUERY ); + if( xCooSysCnt.is() ) { - Reference< XCoordinateSystem > xCooSys( aCooSysSeq[i] ); - if(xCooSys.is()) + Sequence< Reference< XCoordinateSystem > > aCooSysSeq( + xCooSysCnt->getCoordinateSystems()); + + for( sal_Int32 i=0; i<aCooSysSeq.getLength(); ++i ) { - nResult = xCooSys->getDimension(); - break; + Reference< XCoordinateSystem > xCooSys( aCooSysSeq[i] ); + if(xCooSys.is()) + { + nResult = xCooSys->getDimension(); + break; + } } } } @@ -1407,4 +1418,142 @@ sal_Int32 DiagramHelper::getCorrectedMissingValueTreatment( return nResult; } +//static +DiagramPositioningMode DiagramHelper::getDiagramPositioningMode( const uno::Reference< + chart2::XDiagram > & xDiagram ) +{ + DiagramPositioningMode eMode = DiagramPositioningMode_AUTO; + uno::Reference< beans::XPropertySet > xDiaProps( xDiagram, uno::UNO_QUERY ); + if( xDiaProps.is() ) + { + RelativePosition aRelPos; + RelativeSize aRelSize; + if( (xDiaProps->getPropertyValue(C2U("RelativePosition")) >>= aRelPos ) && + (xDiaProps->getPropertyValue(C2U("RelativeSize")) >>= aRelSize ) ) + { + bool bPosSizeExcludeAxes=false; + xDiaProps->getPropertyValue(C2U("PosSizeExcludeAxes")) >>= bPosSizeExcludeAxes; + if( bPosSizeExcludeAxes ) + eMode = DiagramPositioningMode_EXCLUDING; + else + eMode = DiagramPositioningMode_INCLUDING; + } + } + return eMode; +} + +void lcl_ensureRange0to1( double& rValue ) +{ + if(rValue<0.0) + rValue=0.0; + if(rValue>1.0) + rValue=1.0; +} + +//static +bool DiagramHelper::setDiagramPositioning( const uno::Reference< frame::XModel >& xChartModel, + const awt::Rectangle& rPosRect /*100th mm*/ ) +{ + ControllerLockGuard aCtrlLockGuard( xChartModel ); + + bool bChanged = false; + awt::Size aPageSize( ChartModelHelper::getPageSize(xChartModel) ); + uno::Reference< beans::XPropertySet > xDiaProps( ChartModelHelper::findDiagram( xChartModel ), uno::UNO_QUERY ); + if( !xDiaProps.is() ) + return bChanged; + + RelativePosition aOldPos; + RelativeSize aOldSize; + xDiaProps->getPropertyValue(C2U("RelativePosition") ) >>= aOldPos; + xDiaProps->getPropertyValue(C2U("RelativeSize") ) >>= aOldSize; + + RelativePosition aNewPos; + aNewPos.Anchor = drawing::Alignment_TOP_LEFT; + aNewPos.Primary = double(rPosRect.X)/double(aPageSize.Width); + aNewPos.Secondary = double(rPosRect.Y)/double(aPageSize.Height); + + chart2::RelativeSize aNewSize; + aNewSize.Primary = double(rPosRect.Width)/double(aPageSize.Width); + aNewSize.Secondary = double(rPosRect.Height)/double(aPageSize.Height); + + lcl_ensureRange0to1( aNewPos.Primary ); + lcl_ensureRange0to1( aNewPos.Secondary ); + lcl_ensureRange0to1( aNewSize.Primary ); + lcl_ensureRange0to1( aNewSize.Secondary ); + if( (aNewPos.Primary + aNewSize.Primary) > 1.0 ) + aNewPos.Primary = 1.0 - aNewSize.Primary; + if( (aNewPos.Secondary + aNewSize.Secondary) > 1.0 ) + aNewPos.Secondary = 1.0 - aNewSize.Secondary; + + xDiaProps->setPropertyValue( C2U( "RelativePosition" ), uno::makeAny(aNewPos) ); + xDiaProps->setPropertyValue( C2U( "RelativeSize" ), uno::makeAny(aNewSize) ); + + bChanged = (aOldPos.Anchor!=aNewPos.Anchor) || + (aOldPos.Primary!=aNewPos.Primary) || + (aOldPos.Secondary!=aNewPos.Secondary) || + (aOldSize.Primary!=aNewSize.Primary) || + (aOldSize.Secondary!=aNewSize.Secondary); + return bChanged; +} + +//static +awt::Rectangle DiagramHelper::getDiagramRectangleFromModel( const uno::Reference< frame::XModel >& xChartModel ) +{ + awt::Rectangle aRet(-1,-1,-1,-1); + + uno::Reference< beans::XPropertySet > xDiaProps( ChartModelHelper::findDiagram( xChartModel ), uno::UNO_QUERY ); + if( !xDiaProps.is() ) + return aRet; + + awt::Size aPageSize( ChartModelHelper::getPageSize(xChartModel) ); + + RelativePosition aRelPos; + RelativeSize aRelSize; + xDiaProps->getPropertyValue(C2U("RelativePosition") ) >>= aRelPos; + xDiaProps->getPropertyValue(C2U("RelativeSize") ) >>= aRelSize; + + awt::Size aAbsSize( + aRelSize.Primary * aPageSize.Width, + aRelSize.Secondary * aPageSize.Height ); + + awt::Point aAbsPos( + static_cast< sal_Int32 >( aRelPos.Primary * aPageSize.Width ), + static_cast< sal_Int32 >( aRelPos.Secondary * aPageSize.Height )); + + awt::Point aAbsPosLeftTop = RelativePositionHelper::getUpperLeftCornerOfAnchoredObject( aAbsPos, aAbsSize, aRelPos.Anchor ); + + aRet = awt::Rectangle(aAbsPosLeftTop.X, aAbsPosLeftTop.Y, aAbsSize.Width, aAbsSize.Height ); + + return aRet; +} + +//static +bool DiagramHelper::switchDiagramPositioningToExcludingPositioning( + const uno::Reference< frame::XModel >& xChartModel + , bool bResetModifiedState, bool bConvertAlsoFromAutoPositioning ) +{ + //return true if something was changed + const SvtSaveOptions::ODFDefaultVersion nCurrentODFVersion( SvtSaveOptions().GetODFDefaultVersion() ); + if( nCurrentODFVersion == SvtSaveOptions::ODFVER_LATEST )//#i100778# todo: change this dependent on fileformat evolution + { + uno::Reference< ::com::sun::star::chart::XChartDocument > xOldDoc( xChartModel, uno::UNO_QUERY ) ; + if( xOldDoc.is() ) + { + uno::Reference< ::com::sun::star::chart::XDiagramPositioning > xDiagramPositioning( xOldDoc->getDiagram(), uno::UNO_QUERY ); + if( xDiagramPositioning.is() && ( bConvertAlsoFromAutoPositioning || !xDiagramPositioning->isAutomaticDiagramPositioning() ) + && !xDiagramPositioning->isExcludingDiagramPositioning() ) + { + ControllerLockGuard aCtrlLockGuard( xChartModel ); + uno::Reference< util::XModifiable > xModifiable( xChartModel, uno::UNO_QUERY ); + bool bModelWasModified = xModifiable.is() && xModifiable->isModified(); + xDiagramPositioning->setDiagramPositionExcludingAxes( xDiagramPositioning->calculateDiagramPositionExcludingAxes() ); + if(bResetModifiedState && !bModelWasModified && xModifiable.is() ) + xModifiable->setModified(sal_False); + return true; + } + } + } + return false; +} + } // namespace chart diff --git a/chart2/source/tools/LifeTime.cxx b/chart2/source/tools/LifeTime.cxx index 38aa07718d4a..444e894a101d 100644 --- a/chart2/source/tools/LifeTime.cxx +++ b/chart2/source/tools/LifeTime.cxx @@ -62,12 +62,15 @@ LifeTimeManager::~LifeTimeManager() { } - sal_Bool LifeTimeManager -::impl_isDisposed() +bool LifeTimeManager::impl_isDisposed( bool bAssert ) { if( m_bDisposed || m_bInDispose ) { - OSL_ENSURE( sal_False, "This component is already disposed " ); + if( bAssert ) + { + OSL_ENSURE( sal_False, "This component is already disposed " ); + (void)(bAssert); + } return sal_True; } return sal_False; @@ -185,15 +188,18 @@ CloseableLifeTimeManager::~CloseableLifeTimeManager() { } - sal_Bool CloseableLifeTimeManager -::impl_isDisposedOrClosed() +bool CloseableLifeTimeManager::impl_isDisposedOrClosed( bool bAssert ) { - if( impl_isDisposed() ) + if( impl_isDisposed( bAssert ) ) return sal_True; if( m_bClosed ) { - OSL_ENSURE( sal_False, "This object is already closed" ); + if( bAssert ) + { + OSL_ENSURE( sal_False, "This object is already closed" ); + (void)(bAssert);//avoid warnings + } return sal_True; } return sal_False; @@ -206,6 +212,8 @@ CloseableLifeTimeManager::~CloseableLifeTimeManager() //no mutex is allowed to be acquired { osl::ResettableGuard< osl::Mutex > aGuard( m_aAccessMutex ); + if( impl_isDisposedOrClosed(false) ) + return sal_False; //Mutex needs to be acquired exactly ones; will be released inbetween if( !impl_canStartApiCall() ) diff --git a/chart2/source/view/axes/ScaleAutomatism.cxx b/chart2/source/view/axes/ScaleAutomatism.cxx index 0a6137af3041..890bf87df96e 100644 --- a/chart2/source/view/axes/ScaleAutomatism.cxx +++ b/chart2/source/view/axes/ScaleAutomatism.cxx @@ -498,7 +498,7 @@ void ScaleAutomatism::calculateExplicitIncrementAndScaleForLogarithmic( { //scaling dependent //@todo autocalculate IntervalCount dependent on MainIncrement and scaling - rExplicitSubIncrement.IntervalCount = 5; + rExplicitSubIncrement.IntervalCount = 9; } lcl_ensureMaximumSubIncrementCount( rExplicitSubIncrement.IntervalCount ); if(!(rSubIncrement.PostEquidistant>>=rExplicitSubIncrement.PostEquidistant)) diff --git a/chart2/source/view/axes/TickmarkHelper.cxx b/chart2/source/view/axes/TickmarkHelper.cxx index 4d1f48795fa7..9e2e2707c035 100644 --- a/chart2/source/view/axes/TickmarkHelper.cxx +++ b/chart2/source/view/axes/TickmarkHelper.cxx @@ -472,15 +472,17 @@ sal_Int32 TickmarkHelper::getMaxTickCount( sal_Int32 nDepth ) const if( m_rIncrement.Distance<=0.0) return 0; - sal_Int32 nIntervalCount; + double fSub; if(m_rIncrement.PostEquidistant ) - nIntervalCount = static_cast<sal_Int32> - ( approxSub( m_fScaledVisibleMax, m_fScaledVisibleMin ) - / m_rIncrement.Distance ); + fSub = approxSub( m_fScaledVisibleMax, m_fScaledVisibleMin ); else - nIntervalCount = static_cast<sal_Int32> - ( approxSub( m_rScale.Maximum, m_rScale.Minimum ) - / m_rIncrement.Distance ); + fSub = approxSub( m_rScale.Maximum, m_rScale.Minimum ); + + if (!isFinite(fSub)) + return 0; + + sal_Int32 nIntervalCount = static_cast<sal_Int32>( fSub / m_rIncrement.Distance ); + nIntervalCount+=3; for(sal_Int32 nN=0; nN<nDepth-1; nN++) { diff --git a/chart2/source/view/charttypes/PieChart.cxx b/chart2/source/view/charttypes/PieChart.cxx index b9eac0fc7291..eee13848b11b 100644 --- a/chart2/source/view/charttypes/PieChart.cxx +++ b/chart2/source/view/charttypes/PieChart.cxx @@ -121,10 +121,12 @@ bool PiePositionHelper::getInnerAndOuterRadius( double fCategoryX //----------------------------------------------------------------------------- PieChart::PieChart( const uno::Reference<XChartType>& xChartTypeModel - , sal_Int32 nDimensionCount ) + , sal_Int32 nDimensionCount + , bool bExcludingPositioning ) : VSeriesPlotter( xChartTypeModel, nDimensionCount ) , m_pPosHelper( new PiePositionHelper( NormalAxis_Z, (m_nDimension==3)?0.0:90.0 ) ) , m_bUseRings(false) + , m_bSizeExcludesLabelsAndExplodedSegments(bExcludingPositioning) { ::rtl::math::setNan(&m_fMaxOffset); @@ -181,6 +183,11 @@ bool PieChart::keepAspectRatio() const return true; } +bool PieChart::shouldSnapRectToUsedArea() +{ + return true; +} + //----------------------------------------------------------------- // lang::XServiceInfo //----------------------------------------------------------------- @@ -273,18 +280,21 @@ double PieChart::getMaxOffset() if(fExplodePercentage>m_fMaxOffset) m_fMaxOffset=fExplodePercentage; - uno::Sequence< sal_Int32 > aAttributedDataPointIndexList; - if( xSeriesProp->getPropertyValue( C2U( "AttributedDataPoints" ) ) >>= aAttributedDataPointIndexList ) + if(!m_bSizeExcludesLabelsAndExplodedSegments) { - for(sal_Int32 nN=aAttributedDataPointIndexList.getLength();nN--;) + uno::Sequence< sal_Int32 > aAttributedDataPointIndexList; + if( xSeriesProp->getPropertyValue( C2U( "AttributedDataPoints" ) ) >>= aAttributedDataPointIndexList ) { - uno::Reference< beans::XPropertySet > xPointProp( pSeries->getPropertiesOfPoint(aAttributedDataPointIndexList[nN]) ); - if(xPointProp.is()) + for(sal_Int32 nN=aAttributedDataPointIndexList.getLength();nN--;) { - fExplodePercentage=0.0; - xPointProp->getPropertyValue( C2U( "Offset" )) >>= fExplodePercentage; - if(fExplodePercentage>m_fMaxOffset) - m_fMaxOffset=fExplodePercentage; + uno::Reference< beans::XPropertySet > xPointProp( pSeries->getPropertiesOfPoint(aAttributedDataPointIndexList[nN]) ); + if(xPointProp.is()) + { + fExplodePercentage=0.0; + xPointProp->getPropertyValue( C2U( "Offset" )) >>= fExplodePercentage; + if(fExplodePercentage>m_fMaxOffset) + m_fMaxOffset=fExplodePercentage; + } } } } @@ -396,7 +406,8 @@ void PieChart::createShapes() for( nPointIndex = 0; nPointIndex < nPointCount; nPointIndex++ ) { double fLogicInnerRadius, fLogicOuterRadius; - bool bIsVisible = m_pPosHelper->getInnerAndOuterRadius( fSlotX+1.0, fLogicInnerRadius, fLogicOuterRadius, m_bUseRings, getMaxOffset() ); + double fOffset = getMaxOffset(); + bool bIsVisible = m_pPosHelper->getInnerAndOuterRadius( fSlotX+1.0, fLogicInnerRadius, fLogicOuterRadius, m_bUseRings, fOffset ); if( !bIsVisible ) continue; diff --git a/chart2/source/view/charttypes/PieChart.hxx b/chart2/source/view/charttypes/PieChart.hxx index 52545f6476b8..e6fedb05d52e 100644 --- a/chart2/source/view/charttypes/PieChart.hxx +++ b/chart2/source/view/charttypes/PieChart.hxx @@ -46,7 +46,7 @@ class PieChart : public VSeriesPlotter public: PieChart( const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartType >& xChartTypeModel - , sal_Int32 nDimensionCount ); + , sal_Int32 nDimensionCount, bool bExcludingPositioning ); virtual ~PieChart(); //------------------------------------------------------------------------- @@ -72,6 +72,7 @@ public: //------------------- virtual ::com::sun::star::drawing::Direction3D getPreferredDiagramAspectRatio() const; virtual bool keepAspectRatio() const; + virtual bool shouldSnapRectToUsedArea(); //MinimumAndMaximumSupplier virtual double getMinimumX(); @@ -113,6 +114,7 @@ struct PieLabelInfo; private: //member PiePositionHelper* m_pPosHelper; bool m_bUseRings; + bool m_bSizeExcludesLabelsAndExplodedSegments; struct PieLabelInfo { diff --git a/chart2/source/view/charttypes/VSeriesPlotter.cxx b/chart2/source/view/charttypes/VSeriesPlotter.cxx index 37888c8f0a9b..840cbbe3e1e1 100644 --- a/chart2/source/view/charttypes/VSeriesPlotter.cxx +++ b/chart2/source/view/charttypes/VSeriesPlotter.cxx @@ -1744,6 +1744,13 @@ bool VSeriesPlotter::WantToPlotInFrontOfAxisLine() return ChartTypeHelper::isSeriesInFrontOfAxisLine( m_xChartTypeModel ); } +bool VSeriesPlotter::shouldSnapRectToUsedArea() +{ + if( m_nDimension == 3 ) + return false; + return true; +} + Sequence< ViewLegendEntry > SAL_CALL VSeriesPlotter::createLegendEntries( LegendExpansion eLegendExpansion , const Reference< beans::XPropertySet >& xTextProperties @@ -2066,7 +2073,8 @@ std::vector< ViewLegendEntry > SAL_CALL VSeriesPlotter::createLegendEntriesForCh //static VSeriesPlotter* VSeriesPlotter::createSeriesPlotter( const uno::Reference<XChartType>& xChartTypeModel - , sal_Int32 nDimensionCount ) + , sal_Int32 nDimensionCount + , bool bExcludingPositioning ) { rtl::OUString aChartType = xChartTypeModel->getChartType(); @@ -2085,7 +2093,7 @@ VSeriesPlotter* VSeriesPlotter::createSeriesPlotter( else if( aChartType.equalsIgnoreAsciiCase(CHART2_SERVICE_NAME_CHARTTYPE_BUBBLE) ) pRet = new BubbleChart(xChartTypeModel,nDimensionCount); else if( aChartType.equalsIgnoreAsciiCase(CHART2_SERVICE_NAME_CHARTTYPE_PIE) ) - pRet = new PieChart(xChartTypeModel,nDimensionCount); + pRet = new PieChart(xChartTypeModel,nDimensionCount, bExcludingPositioning ); else if( aChartType.equalsIgnoreAsciiCase(CHART2_SERVICE_NAME_CHARTTYPE_NET) ) pRet = new AreaChart(xChartTypeModel,nDimensionCount,true,true,new PolarPlottingPositionHelper(),true,false,1,drawing::Direction3D(1,1,1) ); else if( aChartType.equalsIgnoreAsciiCase(CHART2_SERVICE_NAME_CHARTTYPE_FILLED_NET) ) diff --git a/chart2/source/view/diagram/VDiagram.cxx b/chart2/source/view/diagram/VDiagram.cxx index 5ffec22969a0..4174226b6f62 100644 --- a/chart2/source/view/diagram/VDiagram.cxx +++ b/chart2/source/view/diagram/VDiagram.cxx @@ -49,6 +49,8 @@ #include <com/sun/star/lang/XTypeProvider.hpp> // header for class SvxShape #include <svx/unoshape.hxx> +// header for GetSdrObjectFromXShape +#include <svx/unoapi.hxx> // header for class E3dScene #include <svx/scene3d.hxx> #include <rtl/math.hxx> @@ -179,6 +181,8 @@ void VDiagram::createShapes_2d() uno::Reference< drawing::XShapes > xOuterGroup_Shapes = m_pShapeFactory->createGroup2D(m_xLogicTarget); m_xOuterGroupShape = uno::Reference<drawing::XShape>( xOuterGroup_Shapes, uno::UNO_QUERY ); + uno::Reference< drawing::XShapes > xGroupForWall( m_pShapeFactory->createGroup2D(xOuterGroup_Shapes,C2U("PlotAreaExcludingAxes")) ); + //create independent group shape as container for datapoints and such things { uno::Reference< drawing::XShapes > xShapes = m_pShapeFactory->createGroup2D(xOuterGroup_Shapes,C2U("testonly;CooContainer=XXX_CID")); @@ -195,8 +199,7 @@ void VDiagram::createShapes_2d() "com.sun.star.drawing.RectangleShape" ) ), uno::UNO_QUERY ); //m_xWall2D->setPosition(m_aAvailablePosIncludingAxes); //m_xWall2D->setSize(m_aAvailableSizeIncludingAxes); - uno::Reference< drawing::XShapes > xShapes( m_xCoordinateRegionShape, uno::UNO_QUERY ); - xShapes->add(m_xWall2D); + xGroupForWall->add(m_xWall2D); uno::Reference< beans::XPropertySet > xProp( m_xWall2D, uno::UNO_QUERY ); if( xProp.is()) { @@ -518,6 +521,7 @@ void VDiagram::createShapes_3d() m_xOuterGroupShape = uno::Reference< drawing::XShape >( m_xShapeFactory->createInstance( C2U( "com.sun.star.drawing.Shape3DSceneObject" ) ), uno::UNO_QUERY ); + ShapeFactory::setShapeName( m_xOuterGroupShape, C2U("PlotAreaExcludingAxes") ); m_xLogicTarget->add(m_xOuterGroupShape); uno::Reference< drawing::XShapes > xOuterGroup_Shapes = diff --git a/chart2/source/view/inc/VSeriesPlotter.hxx b/chart2/source/view/inc/VSeriesPlotter.hxx index 02c1f3b044e9..6b6b06437542 100644 --- a/chart2/source/view/inc/VSeriesPlotter.hxx +++ b/chart2/source/view/inc/VSeriesPlotter.hxx @@ -264,7 +264,8 @@ public: static VSeriesPlotter* createSeriesPlotter( const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartType >& xChartTypeModel - , sal_Int32 nDimensionCount ); + , sal_Int32 nDimensionCount + , bool bExcludingPositioning = false /*for pie and donut charts labels and exploded segments are excluded from the given size*/); sal_Int32 getPointCount() const; @@ -293,6 +294,7 @@ public: virtual void rearrangeLabelToAvoidOverlapIfRequested( const ::com::sun::star::awt::Size& rPageSize ); bool WantToPlotInFrontOfAxisLine(); + virtual bool shouldSnapRectToUsedArea(); //------------------------------------------------------------------------- //------------------------------------------------------------------------- diff --git a/chart2/source/view/main/ChartItemPool.cxx b/chart2/source/view/main/ChartItemPool.cxx index 83368fa3907a..d8f997d36da9 100644 --- a/chart2/source/view/main/ChartItemPool.cxx +++ b/chart2/source/view/main/ChartItemPool.cxx @@ -37,6 +37,7 @@ #include <editeng/brshitem.hxx> #include <editeng/sizeitem.hxx> #include <svl/stritem.hxx> +#include <svl/rectitem.hxx> #include <svl/ilstitem.hxx> #define _SVSTDARR_ULONGS #include <svl/svstdarr.hxx> diff --git a/chart2/source/view/main/ChartView.cxx b/chart2/source/view/main/ChartView.cxx index c5ba0c38ab05..2347824664c5 100644 --- a/chart2/source/view/main/ChartView.cxx +++ b/chart2/source/view/main/ChartView.cxx @@ -169,6 +169,7 @@ ChartView::ChartView( , m_nScaleYNumerator(1) , m_nScaleYDenominator(1) , m_bSdrViewIsInEditMode(sal_False) + , m_aResultingDiagramRectangleExcludingAxes(0,0,0,0) { } @@ -210,7 +211,11 @@ void SAL_CALL ChartView::initialize( const uno::Sequence< uno::Any >& aArguments ChartView::~ChartView() { if( m_pDrawModelWrapper.get() ) + { EndListening( m_pDrawModelWrapper->getSdrModel(), FALSE /*bAllDups*/ ); + ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + m_pDrawModelWrapper.reset(); + } m_xDrawPage = NULL; impl_deleteCoordinateSystems(); } @@ -313,7 +318,7 @@ uno::Any SAL_CALL ChartView::getTransferData( const datatransfer::DataFlavor& aF if( ! (bHighContrastMetaFile || aFlavor.MimeType.equals(lcl_aGDIMetaFileMIMEType)) ) return aRet; - impl_updateView(); + update(); SvMemoryStream aStream( 1024, 1024 ); utl::OStreamWrapper* pStreamWrapper = new utl::OStreamWrapper( aStream ); @@ -681,7 +686,8 @@ void SeriesPlotterContainer::initializeCooSysAndSeriesPlotter( if(nT==0) m_bChartTypeUsesShiftedXAxisTicksPerDefault = ChartTypeHelper::shiftTicksAtXAxisPerDefault( xChartType ); - VSeriesPlotter* pPlotter = VSeriesPlotter::createSeriesPlotter( xChartType, nDimensionCount ); + bool bExcludingPositioning = DiagramPositioningMode_EXCLUDING == DiagramHelper::getDiagramPositioningMode( xDiagram ); + VSeriesPlotter* pPlotter = VSeriesPlotter::createSeriesPlotter( xChartType, nDimensionCount, bExcludingPositioning ); if( !pPlotter ) continue; m_aSeriesPlotterList.push_back( pPlotter ); @@ -1166,7 +1172,7 @@ drawing::Direction3D SeriesPlotterContainer::getPreferredAspectRatio() namespace { -bool lcl_resizeAfterCompleteCreation( const uno::Reference< XDiagram >& xDiagram ) +bool lcl_IsPieOrDonut( const uno::Reference< XDiagram >& xDiagram ) { //special treatment for pie charts //the size is checked after complete creation to get the datalabels into the given space @@ -1324,16 +1330,23 @@ sal_Int16 lcl_getDefaultWritingModeFromPool( ::boost::shared_ptr< DrawModelWrapp } //end anonymous namespace //------------ create complete diagram shape (inclusive axis and series) -void ChartView::impl_createDiagramAndContent( SeriesPlotterContainer& rSeriesPlotterContainer + +awt::Rectangle ChartView::impl_createDiagramAndContent( SeriesPlotterContainer& rSeriesPlotterContainer , const uno::Reference< drawing::XShapes>& xDiagramPlusAxes_Shapes , const awt::Point& rAvailablePos , const awt::Size& rAvailableSize - , const awt::Size& rPageSize ) + , const awt::Size& rPageSize + , bool bUseFixedInnerSize + , const uno::Reference< drawing::XShape>& xDiagram_MarkHandles /*needs to be resized to fit the result*/ + ) { + //return the used rectangle + awt::Rectangle aUsedOuterRect( rAvailablePos.X, rAvailablePos.Y, 0, 0 ); + // sal_Int32 nDiagramIndex = 0;//todo if more than one diagam is supported uno::Reference< XDiagram > xDiagram( ChartModelHelper::findDiagram( m_xChartModel ) ); if( !xDiagram.is()) - return; + return aUsedOuterRect; sal_Int32 nDimensionCount = DiagramHelper::getDimension( xDiagram ); if(!nDimensionCount) @@ -1389,7 +1402,8 @@ void ChartView::impl_createDiagramAndContent( SeriesPlotterContainer& rSeriesPlo aVDiagram.init(xDiagramPlusAxes_Shapes,xDiagramPlusAxes_Shapes,m_xShapeFactory); aVDiagram.createShapes(rAvailablePos,rAvailableSize); xSeriesTargetInFrontOfAxis = aVDiagram.getCoordinateRegion(); - aVDiagram.reduceToMimimumSize(); + if( !bUseFixedInnerSize ) + aVDiagram.reduceToMimimumSize(); } uno::Reference< drawing::XShapes > xTextTargetShapes( ShapeFactory(m_xShapeFactory).createGroup2D(xDiagramPlusAxes_Shapes) ); @@ -1410,19 +1424,21 @@ void ChartView::impl_createDiagramAndContent( SeriesPlotterContainer& rSeriesPlo //calculate resulting size respecting axis label layout and fontscaling + uno::Reference< drawing::XShape > xBoundingShape( xDiagramPlusAxes_Shapes, uno::UNO_QUERY ); + ::basegfx::B2IRectangle aConsumedOuterRect; + //use first coosys only so far; todo: calculate for more than one coosys if we have more in future //todo: this is just a workaround at the moment for pie and donut labels - if( !lcl_resizeAfterCompleteCreation(xDiagram) && rVCooSysList.size() > 0 ) + bool bIsPieOrDonut = lcl_IsPieOrDonut(xDiagram); + if( !bIsPieOrDonut && rVCooSysList.size() > 0 ) { - uno::Reference< drawing::XShape > xBoundingShape( xDiagramPlusAxes_Shapes, uno::UNO_QUERY ); - - ::basegfx::B2IRectangle aFirstConsumedOuterRect( ShapeFactory::getRectangleOfShape(xBoundingShape) ); - VCoordinateSystem* pVCooSys = rVCooSysList[0]; pVCooSys->createMaximumAxesLabels(); - ::basegfx::B2IRectangle aConsumedOuterRect( ShapeFactory::getRectangleOfShape(xBoundingShape) ); - ::basegfx::B2IRectangle aNewInnerRect( aVDiagram.adjustInnerSize( aConsumedOuterRect ) ); + aConsumedOuterRect = ::basegfx::B2IRectangle( ShapeFactory::getRectangleOfShape(xBoundingShape) ); + ::basegfx::B2IRectangle aNewInnerRect( aVDiagram.getCurrentRectangle() ); + if( !bUseFixedInnerSize ) + aNewInnerRect = aVDiagram.adjustInnerSize( aConsumedOuterRect ); pVCooSys->setTransformationSceneToScreen( B3DHomMatrixToHomogenMatrix( createTransformationSceneToScreen( aNewInnerRect ) )); @@ -1445,13 +1461,13 @@ void ChartView::impl_createDiagramAndContent( SeriesPlotterContainer& rSeriesPlo bLessSpaceConsumedThanExpected = true; } - if( bLessSpaceConsumedThanExpected ) + if( bLessSpaceConsumedThanExpected && !bUseFixedInnerSize ) { aVDiagram.adjustInnerSize( aConsumedOuterRect ); pVCooSys->setTransformationSceneToScreen( B3DHomMatrixToHomogenMatrix( createTransformationSceneToScreen( aVDiagram.getCurrentRectangle() ) )); - pVCooSys->updatePositions(); } + pVCooSys->updatePositions();//todo: logically this belongs to the condition above, but it seems also to be neccessary to give the axes group shapes the right bounding rects for hit test - probably caused by bug i106183 -> check again if fixed } //create axes and grids for the final size @@ -1481,7 +1497,7 @@ void ChartView::impl_createDiagramAndContent( SeriesPlotterContainer& rSeriesPlo else { xSeriesTarget = xSeriesTargetBehindAxis; - DBG_ASSERT( !lcl_resizeAfterCompleteCreation(xDiagram), "not implemented yet! - during a complete recreation this shape is destroyed so no series can be created anymore" ); + DBG_ASSERT( !bIsPieOrDonut, "not implemented yet! - during a complete recreation this shape is destroyed so no series can be created anymore" ); } pSeriesPlotter->initPlotter( xSeriesTarget,xTextTargetShapes,m_xShapeFactory,aCID ); pSeriesPlotter->setPageReferenceSize( rPageSize ); @@ -1500,15 +1516,15 @@ void ChartView::impl_createDiagramAndContent( SeriesPlotterContainer& rSeriesPlo m_bPointsWereSkipped = m_bPointsWereSkipped || pSeriesPlotter->PointsWereSkipped(); } - //recreate with corrected sizes if requested - if( lcl_resizeAfterCompleteCreation(xDiagram) ) + //recreate all with corrected sizes if requested + if( bIsPieOrDonut ) { m_bPointsWereSkipped = false; - uno::Reference< drawing::XShape > xBoundingShape( xDiagramPlusAxes_Shapes, uno::UNO_QUERY ); - ::basegfx::B2IRectangle aConsumedOuterRect( ShapeFactory::getRectangleOfShape(xBoundingShape) ); - - ::basegfx::B2IRectangle aNewInnerRect( aVDiagram.adjustInnerSize( aConsumedOuterRect ) ); + aConsumedOuterRect = ::basegfx::B2IRectangle( ShapeFactory::getRectangleOfShape(xBoundingShape) ); + ::basegfx::B2IRectangle aNewInnerRect( aVDiagram.getCurrentRectangle() ); + if( !bUseFixedInnerSize ) + aNewInnerRect = aVDiagram.adjustInnerSize( aConsumedOuterRect ); for( aPlotterIter = rSeriesPlotterList.begin(); aPlotterIter != aPlotterEnd; aPlotterIter++ ) { @@ -1565,6 +1581,63 @@ void ChartView::impl_createDiagramAndContent( SeriesPlotterContainer& rSeriesPlo pSeriesPlotter->rearrangeLabelToAvoidOverlapIfRequested( rPageSize ); } } + + if( bUseFixedInnerSize ) + { + //if( !bIsPieOrDonut ) + // aConsumedOuterRect = ::basegfx::B2IRectangle( ShapeFactory::getRectangleOfShape(xBoundingShape) ); + aUsedOuterRect = awt::Rectangle( aConsumedOuterRect.getMinX(), aConsumedOuterRect.getMinY(), aConsumedOuterRect.getWidth(), aConsumedOuterRect.getHeight() ); + } + else + aUsedOuterRect = awt::Rectangle( rAvailablePos.X, rAvailablePos.Y, rAvailableSize.Width, rAvailableSize.Height ); + + bool bSnapRectToUsedArea = false; + for( aPlotterIter = rSeriesPlotterList.begin(); aPlotterIter != aPlotterEnd; aPlotterIter++ ) + { + VSeriesPlotter* pSeriesPlotter = *aPlotterIter; + bSnapRectToUsedArea = pSeriesPlotter->shouldSnapRectToUsedArea(); + if(bSnapRectToUsedArea) + break; + } + if(bSnapRectToUsedArea) + { + if( bUseFixedInnerSize ) + m_aResultingDiagramRectangleExcludingAxes = getRectangleOfObject( C2U("PlotAreaExcludingAxes") ); + else + { + ::basegfx::B2IRectangle aConsumedInnerRect = aVDiagram.getCurrentRectangle(); + m_aResultingDiagramRectangleExcludingAxes = awt::Rectangle( aConsumedInnerRect.getMinX(), aConsumedInnerRect.getMinY(), aConsumedInnerRect.getWidth(), aConsumedInnerRect.getHeight() ); + } + } + else + { + if( bUseFixedInnerSize ) + m_aResultingDiagramRectangleExcludingAxes = awt::Rectangle( rAvailablePos.X, rAvailablePos.Y, rAvailableSize.Width, rAvailableSize.Height ); + else + { + ::basegfx::B2IRectangle aConsumedInnerRect = aVDiagram.getCurrentRectangle(); + m_aResultingDiagramRectangleExcludingAxes = awt::Rectangle( aConsumedInnerRect.getMinX(), aConsumedInnerRect.getMinY(), aConsumedInnerRect.getWidth(), aConsumedInnerRect.getHeight() ); + } + } + + if( xDiagram_MarkHandles.is() ) + { + awt::Point aPos(rAvailablePos); + awt::Size aSize(rAvailableSize); + bool bPosSizeExcludeAxesProperty = true; + uno::Reference< beans::XPropertySet > xDiaProps( xDiagram, uno::UNO_QUERY_THROW ); + if( xDiaProps.is() ) + xDiaProps->getPropertyValue(C2U("PosSizeExcludeAxes")) >>= bPosSizeExcludeAxesProperty; + if( bUseFixedInnerSize || bPosSizeExcludeAxesProperty ) + { + aPos = awt::Point( m_aResultingDiagramRectangleExcludingAxes.X, m_aResultingDiagramRectangleExcludingAxes.Y ); + aSize = awt::Size( m_aResultingDiagramRectangleExcludingAxes.Width, m_aResultingDiagramRectangleExcludingAxes.Height ); + } + xDiagram_MarkHandles->setPosition( aPos ); + xDiagram_MarkHandles->setSize( aSize ); + } + + return aUsedOuterRect; } //------------------------------------------------------------- @@ -1622,6 +1695,12 @@ uno::Reference< drawing::XShape > ChartView::getShapeForCID( const rtl::OUString return 0; } +awt::Rectangle ChartView::getDiagramRectangleExcludingAxes() +{ + impl_updateView(); + return m_aResultingDiagramRectangleExcludingAxes; +} + awt::Rectangle ChartView::getRectangleOfObject( const rtl::OUString& rObjectCID, bool bSnapRect ) { impl_updateView(); @@ -1645,7 +1724,10 @@ awt::Rectangle ChartView::getRectangleOfObject( const rtl::OUString& rObjectCID, SdrObjList* pRootList = pRootSdrObject->GetSubList(); if( pRootList ) { - SdrObject* pShape = DrawModelWrapper::getNamedSdrObject( C2U("MarkHandles"), pRootList ); + OUString aShapeName = C2U("MarkHandles"); + if( eObjectType == OBJECTTYPE_DIAGRAM ) + aShapeName = C2U("PlotAreaIncludingAxes"); + SdrObject* pShape = DrawModelWrapper::getNamedSdrObject( aShapeName, pRootList ); if( pShape ) xShape = uno::Reference< drawing::XShape >( pShape->getUnoShape(), uno::UNO_QUERY); } @@ -1933,12 +2015,12 @@ sal_Int32 ExplicitValueProvider::getExplicitPercentageNumberFormatKeyForDataLabe } //static -awt::Rectangle ExplicitValueProvider::calculateDiagramPositionAndSizeInclusiveTitle( +awt::Rectangle ExplicitValueProvider::addAxisTitleSizes( const Reference< frame::XModel >& xChartModel , const Reference< uno::XInterface >& xChartView - , const awt::Rectangle& rExclusivePositionAndSize ) + , const awt::Rectangle& rExcludingPositionAndSize ) { - awt::Rectangle aRet(rExclusivePositionAndSize); + awt::Rectangle aRet(rExcludingPositionAndSize); //add axis title sizes to the diagram size uno::Reference< chart2::XTitle > xTitle_Height( TitleHelper::getTitle( TitleHelper::TITLE_AT_STANDARD_X_AXIS_POSITION, xChartModel ) ); @@ -2000,6 +2082,74 @@ awt::Rectangle ExplicitValueProvider::calculateDiagramPositionAndSizeInclusiveTi return aRet; } +//static +awt::Rectangle ExplicitValueProvider::substractAxisTitleSizes( + const Reference< frame::XModel >& xChartModel + , const Reference< uno::XInterface >& xChartView + , const awt::Rectangle& rPositionAndSizeIncludingTitles ) +{ + awt::Rectangle aRet(rPositionAndSizeIncludingTitles); + + //add axis title sizes to the diagram size + uno::Reference< chart2::XTitle > xTitle_Height( TitleHelper::getTitle( TitleHelper::TITLE_AT_STANDARD_X_AXIS_POSITION, xChartModel ) ); + uno::Reference< chart2::XTitle > xTitle_Width( TitleHelper::getTitle( TitleHelper::TITLE_AT_STANDARD_Y_AXIS_POSITION, xChartModel ) ); + uno::Reference< chart2::XTitle > xSecondTitle_Height( TitleHelper::getTitle( TitleHelper::SECONDARY_X_AXIS_TITLE, xChartModel ) ); + uno::Reference< chart2::XTitle > xSecondTitle_Width( TitleHelper::getTitle( TitleHelper::SECONDARY_Y_AXIS_TITLE, xChartModel ) ); + if( xTitle_Height.is() || xTitle_Width.is() || xSecondTitle_Height.is() || xSecondTitle_Width.is() ) + { + ExplicitValueProvider* pExplicitValueProvider = ExplicitValueProvider::getExplicitValueProvider(xChartView); + if( pExplicitValueProvider ) + { + //detect wether x axis points into x direction or not + if( lcl_getPropertySwapXAndYAxis( ChartModelHelper::findDiagram( xChartModel ) ) ) + { + std::swap( xTitle_Height, xTitle_Width ); + std::swap( xSecondTitle_Height, xSecondTitle_Width ); + } + + sal_Int32 nTitleSpaceWidth = 0; + sal_Int32 nTitleSpaceHeight = 0; + sal_Int32 nSecondTitleSpaceWidth = 0; + sal_Int32 nSecondTitleSpaceHeight = 0; + + if( xTitle_Height.is() ) + { + rtl::OUString aCID_X( ObjectIdentifier::createClassifiedIdentifierForObject( xTitle_Height, xChartModel ) ); + nTitleSpaceHeight = pExplicitValueProvider->getRectangleOfObject( aCID_X, true ).Height; + if( nTitleSpaceHeight ) + nTitleSpaceHeight+=lcl_getDiagramTitleSpace(); + } + if( xTitle_Width.is() ) + { + rtl::OUString aCID_Y( ObjectIdentifier::createClassifiedIdentifierForObject( xTitle_Width, xChartModel ) ); + nTitleSpaceWidth = pExplicitValueProvider->getRectangleOfObject( aCID_Y, true ).Width; + if(nTitleSpaceWidth) + nTitleSpaceWidth+=lcl_getDiagramTitleSpace(); + } + if( xSecondTitle_Height.is() ) + { + rtl::OUString aCID_X( ObjectIdentifier::createClassifiedIdentifierForObject( xSecondTitle_Height, xChartModel ) ); + nSecondTitleSpaceHeight = pExplicitValueProvider->getRectangleOfObject( aCID_X, true ).Height; + if( nSecondTitleSpaceHeight ) + nSecondTitleSpaceHeight+=lcl_getDiagramTitleSpace(); + } + if( xSecondTitle_Width.is() ) + { + rtl::OUString aCID_Y( ObjectIdentifier::createClassifiedIdentifierForObject( xSecondTitle_Width, xChartModel ) ); + nSecondTitleSpaceWidth += pExplicitValueProvider->getRectangleOfObject( aCID_Y, true ).Width; + if( nSecondTitleSpaceWidth ) + nSecondTitleSpaceWidth+=lcl_getDiagramTitleSpace(); + } + + aRet.X += nTitleSpaceWidth; + aRet.Y += nSecondTitleSpaceHeight; + aRet.Width -= (nTitleSpaceWidth + nSecondTitleSpaceWidth); + aRet.Height -= (nTitleSpaceHeight + nSecondTitleSpaceHeight); + } + } + return aRet; +} + double lcl_getPageLayoutDistancePercentage() { return 0.02; @@ -2010,9 +2160,10 @@ bool getAvailablePosAndSizeForDiagram( , const awt::Rectangle& rSpaceLeft , const awt::Size & rPageSize , const uno::Reference< XDiagram > & xDiagram - , VTitle* pXTitle, VTitle* pYTitle - , VTitle* pSecondXTitle, VTitle* pSecondYTitle ) + , bool& bUseFixedInnerSize ) { + bUseFixedInnerSize = false; + //@todo: we need a size dependent on the axis labels awt::Rectangle aRemainingSpace(rSpaceLeft); { @@ -2028,7 +2179,9 @@ bool getAvailablePosAndSizeForDiagram( uno::Reference< beans::XPropertySet > xProp(xDiagram, uno::UNO_QUERY); - bool bMakeRoomForTitle = false; + bool bPosSizeExcludeAxes = false; + if( xProp.is() ) + xProp->getPropertyValue( C2U( "PosSizeExcludeAxes" ) ) >>= bPosSizeExcludeAxes; //size: ::com::sun::star::chart2::RelativeSize aRelativeSize; @@ -2036,7 +2189,7 @@ bool getAvailablePosAndSizeForDiagram( { rOutAvailableDiagramSize.Height = static_cast<sal_Int32>(aRelativeSize.Secondary*rPageSize.Height); rOutAvailableDiagramSize.Width = static_cast<sal_Int32>(aRelativeSize.Primary*rPageSize.Width); - bMakeRoomForTitle = true; + bUseFixedInnerSize = bPosSizeExcludeAxes; } else rOutAvailableDiagramSize = awt::Size(aRemainingSpace.Width,aRemainingSpace.Height); @@ -2054,7 +2207,7 @@ bool getAvailablePosAndSizeForDiagram( rOutPos = RelativePositionHelper::getUpperLeftCornerOfAnchoredObject( awt::Point(static_cast<sal_Int32>(fX),static_cast<sal_Int32>(fY)) , rOutAvailableDiagramSize, aRelativePosition.Anchor ); - bMakeRoomForTitle = true; + bUseFixedInnerSize = bPosSizeExcludeAxes; } else rOutPos = awt::Point(aRemainingSpace.X,aRemainingSpace.Y); @@ -2067,52 +2220,6 @@ bool getAvailablePosAndSizeForDiagram( rOutAvailableDiagramSize.Width = rPageSize.Width - rOutPos.X; } - if( bMakeRoomForTitle ) - { - sal_Int32 nTitleSpaceWidth = 0; - sal_Int32 nTitleSpaceHeight = 0; - sal_Int32 nSecondTitleSpaceWidth = 0; - sal_Int32 nSecondTitleSpaceHeight = 0; - { - //todo detect wether x axis points into x direction or not - //detect wether x axis points into x direction or not - if( lcl_getPropertySwapXAndYAxis( xDiagram ) ) - { - std::swap( pXTitle, pYTitle ); - std::swap( pSecondXTitle, pSecondYTitle ); - } - - if( pXTitle ) - { - nTitleSpaceHeight = pXTitle->getFinalSize().Height; - if(nTitleSpaceHeight) - nTitleSpaceHeight+=lcl_getDiagramTitleSpace(); - } - if( pYTitle ) - { - nTitleSpaceWidth = pYTitle->getFinalSize().Width; - if(nTitleSpaceWidth) - nTitleSpaceWidth+=lcl_getDiagramTitleSpace(); - } - if( pSecondXTitle) - { - nSecondTitleSpaceHeight += pSecondXTitle->getFinalSize().Height; - if(nSecondTitleSpaceHeight) - nSecondTitleSpaceHeight+=lcl_getDiagramTitleSpace(); - } - if( pSecondYTitle) - { - nSecondTitleSpaceWidth += pSecondYTitle->getFinalSize().Width; - if(nSecondTitleSpaceWidth) - nSecondTitleSpaceWidth+=lcl_getDiagramTitleSpace(); - } - } - rOutAvailableDiagramSize.Height -= nTitleSpaceHeight + nSecondTitleSpaceHeight; - rOutAvailableDiagramSize.Width -= nTitleSpaceWidth + nSecondTitleSpaceWidth; - rOutPos.X += nTitleSpaceWidth; - rOutPos.Y += nSecondTitleSpaceHeight; - } - return true; } @@ -2154,6 +2261,19 @@ void changePositionOfAxisTitle( VTitle* pVTitle, TitleAlignment eAlignment break; } + sal_Int32 nMaxY = rPageSize.Height - aTitleSize.Height/2; + sal_Int32 nMaxX = rPageSize.Width - aTitleSize.Width/2; + sal_Int32 nMinX = aTitleSize.Width/2; + sal_Int32 nMinY = aTitleSize.Height/2; + if( aNewPosition.Y > nMaxY ) + aNewPosition.Y = nMaxY; + if( aNewPosition.X > nMaxX ) + aNewPosition.X = nMaxX; + if( aNewPosition.Y < nMinY ) + aNewPosition.Y = nMinY; + if( aNewPosition.X < nMinX ) + aNewPosition.X = nMinX; + pVTitle->changePosition( aNewPosition ); } @@ -2478,6 +2598,7 @@ void ChartView::createShapes() if( impl_AddInDrawsAllByItself() ) return; + m_aResultingDiagramRectangleExcludingAxes = awt::Rectangle(0,0,0,0); impl_deleteCoordinateSystems(); if( m_pDrawModelWrapper ) { @@ -2519,9 +2640,15 @@ void ChartView::createShapes() uno::Reference< XDiagram > xDiagram( ChartModelHelper::findDiagram( m_xChartModel ) ); rtl::OUString aDiagramCID( ObjectIdentifier::createClassifiedIdentifier( OBJECTTYPE_DIAGRAM, rtl::OUString::valueOf( sal_Int32(0) ) ) );//todo: other index if more than one diagram is possible uno::Reference< drawing::XShapes > xDiagramPlusAxesPlusMarkHandlesGroup_Shapes( ShapeFactory(m_xShapeFactory).createGroup2D(xPageShapes,aDiagramCID) ); - uno::Reference< drawing::XShape > xDiagramPlusAxes_MarkHandles( ShapeFactory(m_xShapeFactory).createInvisibleRectangle( + + uno::Reference< drawing::XShape > xDiagram_MarkHandles( ShapeFactory(m_xShapeFactory).createInvisibleRectangle( xDiagramPlusAxesPlusMarkHandlesGroup_Shapes, awt::Size(0,0) ) ); - ShapeFactory::setShapeName( xDiagramPlusAxes_MarkHandles, C2U("MarkHandles") ); + ShapeFactory::setShapeName( xDiagram_MarkHandles, C2U("MarkHandles") ); + + uno::Reference< drawing::XShape > xDiagram_OuterRect( ShapeFactory(m_xShapeFactory).createInvisibleRectangle( + xDiagramPlusAxesPlusMarkHandlesGroup_Shapes, awt::Size(0,0) ) ); + ShapeFactory::setShapeName( xDiagram_OuterRect, C2U("PlotAreaIncludingAxes") ); + uno::Reference< drawing::XShapes > xDiagramPlusAxes_Shapes( ShapeFactory(m_xShapeFactory).createGroup2D(xDiagramPlusAxesPlusMarkHandlesGroup_Shapes ) ); //------------ create some titles @@ -2606,21 +2733,22 @@ void ChartView::createShapes() //------------ create complete diagram shape (inclusive axis and series) awt::Point aAvailablePosDia; awt::Size aAvailableSizeForDiagram; - if( getAvailablePosAndSizeForDiagram( aAvailablePosDia, aAvailableSizeForDiagram, aRemainingSpace, aPageSize, ChartModelHelper::findDiagram( m_xChartModel ) - , apVTitle_X.get(), apVTitle_Y.get(), apVTitle_SecondX.get(), apVTitle_SecondY.get() ) ) + bool bUseFixedInnerSize = false; + if( getAvailablePosAndSizeForDiagram( aAvailablePosDia, aAvailableSizeForDiagram, aRemainingSpace, aPageSize + , ChartModelHelper::findDiagram( m_xChartModel ), bUseFixedInnerSize ) ) { - impl_createDiagramAndContent( aSeriesPlotterContainer + awt::Rectangle aUsedOuterRect = impl_createDiagramAndContent( aSeriesPlotterContainer , xDiagramPlusAxes_Shapes - , aAvailablePosDia ,aAvailableSizeForDiagram, aPageSize ); + , aAvailablePosDia ,aAvailableSizeForDiagram, aPageSize, bUseFixedInnerSize, xDiagram_MarkHandles ); - if(xDiagramPlusAxes_MarkHandles.is()) + if( xDiagram_OuterRect.is() ) { - xDiagramPlusAxes_MarkHandles->setPosition( aAvailablePosDia ); - xDiagramPlusAxes_MarkHandles->setSize( aAvailableSizeForDiagram ); + xDiagram_OuterRect->setPosition( awt::Point( aUsedOuterRect.X, aUsedOuterRect.Y ) ); + xDiagram_OuterRect->setSize( awt::Size( aUsedOuterRect.Width, aUsedOuterRect.Height ) ); } //correct axis title position - awt::Rectangle aDiagramPlusAxesRect(aAvailablePosDia.X,aAvailablePosDia.Y,aAvailableSizeForDiagram.Width,aAvailableSizeForDiagram.Height); + awt::Rectangle aDiagramPlusAxesRect( aUsedOuterRect ); if(bAutoPosition_XTitle) changePositionOfAxisTitle( apVTitle_X.get(), ALIGN_BOTTOM, aDiagramPlusAxesRect, aPageSize ); if(bAutoPosition_YTitle) @@ -2691,17 +2819,6 @@ void ChartView::impl_updateView() //create chart view { - /* - ::vos::OGuard aGuard( Application::GetSolarMutex()); - while( m_bViewDirty ) - { - createShapes(); - m_bViewDirty = m_bViewUpdatePending; - m_bViewUpdatePending = false; - m_bInViewUpdate = false; - } - */ - m_bViewDirty = false; m_bViewUpdatePending = false; createShapes(); @@ -2871,6 +2988,14 @@ void SAL_CALL ChartView::removeModeChangeApproveListener( const uno::Reference< void SAL_CALL ChartView::update() throw (uno::RuntimeException) { impl_updateView(); + + //#i100778# migrate all imported or old documents to a plot area sizing exclusive axes (in case the save settings allow for this): + //Although in general it is a bad idea to change the model from within the view this is exceptionally the best place to do this special conversion. + //When a view update is requested (what happens for creating the metafile or displaying + //the chart in edit mode or printing) it is most likely that all necessary informations are available - like the underlying spreadsheet data for example. + //Those data is important for the correct axis lable sizes which are needed during conversion. + if( DiagramHelper::switchDiagramPositioningToExcludingPositioning( m_xChartModel, true, false ) ) + impl_updateView(); } // ____ XPropertySet ____ diff --git a/chart2/source/view/main/ChartView.hxx b/chart2/source/view/main/ChartView.hxx index f56da298c5df..476adae03674 100644 --- a/chart2/source/view/main/ChartView.hxx +++ b/chart2/source/view/main/ChartView.hxx @@ -110,6 +110,8 @@ public: virtual ::com::sun::star::awt::Rectangle getRectangleOfObject( const rtl::OUString& rObjectCID, bool bSnapRect=false ); + virtual ::com::sun::star::awt::Rectangle getDiagramRectangleExcludingAxes(); + ::boost::shared_ptr< DrawModelWrapper > getDrawModelWrapper(); // ___XTransferable___ @@ -196,11 +198,13 @@ private: //methods void impl_updateView(); - void impl_createDiagramAndContent( SeriesPlotterContainer& rSeriesPlotterContainer + ::com::sun::star::awt::Rectangle impl_createDiagramAndContent( SeriesPlotterContainer& rSeriesPlotterContainer , const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes>& xDiagramPlusAxes_Shapes , const ::com::sun::star::awt::Point& rAvailablePos , const ::com::sun::star::awt::Size& rAvailableSize - , const ::com::sun::star::awt::Size& rPageSize ); + , const ::com::sun::star::awt::Size& rPageSize + , bool bUseFixedInnerSize + , const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape>& xDiagram_MarkHandles ); private: //member @@ -246,6 +250,8 @@ private: //member sal_Int32 m_nScaleYDenominator; sal_Bool m_bSdrViewIsInEditMode; + + ::com::sun::star::awt::Rectangle m_aResultingDiagramRectangleExcludingAxes; }; //............................................................................. diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx index c39d0deca0b7..503f0975c5c9 100644 --- a/sc/inc/column.hxx +++ b/sc/inc/column.hxx @@ -275,7 +275,6 @@ public: void CalcAfterLoad(); void CompileAll(); void CompileXML( ScProgress& rProgress ); - bool MarkUsedExternalReferences(); void ResetChanged( SCROW nStartRow, SCROW nEndRow ); diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx index 02c859723fa2..768dc815a482 100644 --- a/sc/inc/document.hxx +++ b/sc/inc/document.hxx @@ -906,7 +906,7 @@ public: bool ShrinkToUsedDataArea( SCTAB nTab, SCCOL& rStartCol, SCROW& rStartRow, SCCOL& rEndCol, SCROW& rEndRow, bool bColumnsOnly ) const; void GetDataArea( SCTAB nTab, SCCOL& rStartCol, SCROW& rStartRow, - SCCOL& rEndCol, SCROW& rEndRow, BOOL bIncludeOld, bool bOnlyDown ); + SCCOL& rEndCol, SCROW& rEndRow, BOOL bIncludeOld, bool bOnlyDown ) const; SC_DLLPUBLIC BOOL GetCellArea( SCTAB nTab, SCCOL& rEndCol, SCROW& rEndRow ) const; SC_DLLPUBLIC BOOL GetTableArea( SCTAB nTab, SCCOL& rEndCol, SCROW& rEndRow ) const; SC_DLLPUBLIC BOOL GetPrintArea( SCTAB nTab, SCCOL& rEndCol, SCROW& rEndRow, diff --git a/sc/inc/dpgroup.hxx b/sc/inc/dpgroup.hxx index 2a66f8b45555..a22b6fd6a2eb 100644 --- a/sc/inc/dpgroup.hxx +++ b/sc/inc/dpgroup.hxx @@ -207,7 +207,6 @@ class ScDPGroupTableData : public ScDPTableData void FillGroupValues( SCROW* pItemDataIndex, long nCount, const long* pDims ); virtual long GetSourceDim( long nDim ); // End Comments - void CopyFields(const ::std::vector<long>& rFieldDims, ::std::vector<long>& rNewFieldDims); bool IsNumGroupDimension( long nDimension ) const; void GetNumGroupInfo( long nDimension, ScDPNumGroupInfo& rInfo, diff --git a/sc/inc/externalrefmgr.hxx b/sc/inc/externalrefmgr.hxx index f47d99097b39..818920885493 100644 --- a/sc/inc/externalrefmgr.hxx +++ b/sc/inc/externalrefmgr.hxx @@ -36,12 +36,14 @@ #include "vcl/timer.hxx" #include "svl/zforlist.hxx" #include "scmatrix.hxx" +#include "rangelst.hxx" #include <hash_map> #include <hash_set> #include <boost/shared_ptr.hpp> #include <vector> #include <list> +#include <set> #include <formula/ExternalReferenceHelper.hxx> class ScDocument; @@ -55,6 +57,7 @@ class ScTokenArray; class String; class SfxObjectShellRef; class Window; +class ScFormulaCell; class ScExternalRefCache; @@ -126,6 +129,15 @@ public: class Table; friend class ScExternalRefCache::Table; + /** + * Represents a single cached table in an external document. It only + * stores non-empty cells; empty cells should never be stored in the data + * cache. Instead, cached ranges should be used to determine whether or + * not a cell is empty or needs fetching from the source document. If a + * cell's value is not stored but its address is within the cached ranges, + * that cell is already queried in the source document and we know it's + * empty. + */ class Table { public: @@ -140,7 +152,14 @@ public: Table(); ~Table(); - SC_DLLPUBLIC void setCell(SCCOL nCol, SCROW nRow, TokenRef pToken, sal_uInt32 nFmtIndex = 0); + /** + * Add cell value to the cache. + * + * @param bSetCacheRange if true, mark this cell 'cached'. This is + * false _only when_ adding a range of cell + * values, for performance reasons. + */ + SC_DLLPUBLIC void setCell(SCCOL nCol, SCROW nRow, TokenRef pToken, sal_uInt32 nFmtIndex = 0, bool bSetCacheRange = true); SC_DLLPUBLIC TokenRef getCell(SCCOL nCol, SCROW nRow, sal_uInt32* pnFmtIndex = NULL) const; bool hasRow( SCROW nRow ) const; /** Set/clear referenced status flag only if current status is not @@ -151,18 +170,39 @@ public: ReferencedFlag getReferencedFlag() const; bool isReferenced() const; /// Obtain a sorted vector of rows. - void getAllRows(::std::vector<SCROW>& rRows) const; + void getAllRows(::std::vector<SCROW>& rRows, SCROW nLow = 0, SCROW nHigh = MAXROW) const; /// Returns the half-open range of used rows in this table. Returns [0,0) if table is empty. SC_DLLPUBLIC ::std::pair< SCROW, SCROW > getRowRange() const; /// Obtain a sorted vector of columns. - void getAllCols(SCROW nRow, ::std::vector<SCCOL>& rCols) const; + void getAllCols(SCROW nRow, ::std::vector<SCCOL>& rCols, SCCOL nLow = 0, SCCOL nHigh = MAXCOL) const; /// Returns the half-open range of used columns in the specified row. Returns [0,0) if row is empty. SC_DLLPUBLIC ::std::pair< SCCOL, SCCOL > getColRange( SCROW nRow ) const; void getAllNumberFormats(::std::vector<sal_uInt32>& rNumFmts) const; + const ScRangeList& getCachedRanges() const; + bool isRangeCached(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2) const; + + void setCachedCell(SCCOL nCol, SCROW nRow); + void setCachedCellRange(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2); + + /** + * Call this to mark the entire table "cached". This will prevent all + * future attempts to access the source document even when non-cached + * cells are queried. In such case, non-cached cells are treated as + * empty cells. Useful when loading a document with own external data + * cache. + */ + SC_DLLPUBLIC void setWholeTableCached(); + private: + bool isInCachedRanges(SCCOL nCol, SCROW nRow) const; + TokenRef getEmptyOrNullToken(SCCOL nCol, SCROW nRow) const; private: - RowsDataType maRows; - ReferencedFlag meReferenced; + /** Data cache */ + RowsDataType maRows; + /** Collection of individual cached ranges. The table ranges are + * not used & always zero. */ + ScRangeList maCachedRanges; + ReferencedFlag meReferenced; }; typedef ::boost::shared_ptr<Table> TableTypeRef; @@ -185,8 +225,7 @@ public: * @return pointer to the token instance in the cache. */ ScExternalRefCache::TokenRef getCellData( - sal_uInt16 nFileId, const String& rTabName, SCCOL nCol, SCROW nRow, - bool bEmptyCellOnNull, bool bWriteEmpty, sal_uInt32* pnFmtIndex); + sal_uInt16 nFileId, const String& rTabName, SCCOL nCol, SCROW nRow, sal_uInt32* pnFmtIndex); /** * Get a cached cell range data. @@ -196,12 +235,12 @@ public: * guaranteed if the TokenArrayRef is properly used.. */ ScExternalRefCache::TokenArrayRef getCellRangeData( - sal_uInt16 nFileId, const String& rTabName, const ScRange& rRange, bool bEmptyCellOnNull, bool bWriteEmpty); + sal_uInt16 nFileId, const String& rTabName, const ScRange& rRange); ScExternalRefCache::TokenArrayRef getRangeNameTokens(sal_uInt16 nFileId, const String& rName); void setRangeNameTokens(sal_uInt16 nFileId, const String& rName, TokenArrayRef pArray); - void setCellData(sal_uInt16 nFileId, const String& rTabName, SCROW nRow, SCCOL nCol, TokenRef pToken, sal_uInt32 nFmtIndex); + void setCellData(sal_uInt16 nFileId, const String& rTabName, SCCOL nCol, SCROW nRow, TokenRef pToken, sal_uInt32 nFmtIndex); struct SingleRangeData { @@ -325,58 +364,8 @@ class SC_DLLPUBLIC ScExternalRefManager : public formula::ExternalReferenceHelpe { public: - // SUNWS needs a forward declared friend, otherwise types and members - // of the outer class are not accessible. - class RefCells; - friend class ScExternalRefManager::RefCells; - - /** - * Collection of cell addresses that contain external references. This - * data is used for link updates. - */ - class RefCells - { - public: - RefCells(); - ~RefCells(); - - void insertCell(const ScAddress& rAddr); - void removeCell(const ScAddress& rAddr); - void moveTable(SCTAB nOldTab, SCTAB nNewTab, bool bCopy); - void insertTable(SCTAB nPos); - void removeTable(SCTAB nPos); - void refreshAllCells(ScExternalRefManager& rRefMgr); - private: - - typedef ::std::hash_set<SCROW> RowSet; - typedef ::std::hash_map<SCCOL, RowSet> ColSet; - - // SUNWS needs a forward declared friend, otherwise types and members - // of the outer class are not accessible. - struct TabItem; - friend struct ScExternalRefManager::RefCells::TabItem; - - struct TabItem - { - SCTAB mnIndex; - ColSet maCols; - explicit TabItem(SCTAB nIndex); - explicit TabItem(const TabItem& r); - }; - typedef ::boost::shared_ptr<TabItem> TabItemRef; - - /** - * Return the position that points either to the specified table - * position or to the position where a new table would be inserted in - * case the specified table is not present. - * - * @param nTab index of the desired table - */ - ::std::list<TabItemRef>::iterator getTabPos(SCTAB nTab); - - // This list must be sorted by the table index at all times. - ::std::list<TabItemRef> maTables; - }; + typedef ::std::set<ScFormulaCell*> RefCellSet; + typedef ::std::hash_map<sal_uInt16, RefCellSet> RefCellMap; enum LinkUpdateType { LINK_MODIFIED, LINK_BROKEN }; @@ -401,6 +390,21 @@ public: }; }; + /** + * Use this guard when performing something from the API that might query + * values from external references. Interpreting formula strings is one + * such example. + */ + class ApiGuard + { + public: + ApiGuard(ScDocument* pDoc); + ~ApiGuard(); + private: + ScExternalRefManager* mpMgr; + bool mbOldInteractionEnabled; + }; + private: /** Shell instance for a source document. */ struct SrcShell @@ -412,7 +416,6 @@ private: typedef ::std::hash_map<sal_uInt16, SrcShell> DocShellMap; typedef ::std::hash_map<sal_uInt16, bool> LinkedDocMap; - typedef ::std::hash_map<sal_uInt16, RefCells> RefCellMap; typedef ::std::hash_map<sal_uInt16, SvNumberFormatterMergeMap> NumFmtMap; @@ -516,12 +519,7 @@ public: */ bool markUsedByLinkListeners(); - /** - * Set all tables of a document as referenced, used only during - * store-to-file. - * @returns <TRUE/> if ALL tables of ALL external documents are marked. - */ - bool setCacheDocReferenced( sal_uInt16 nFileId ); + bool markUsedExternalRefCells(); /** * Set a table as referenced, used only during store-to-file. @@ -540,7 +538,7 @@ public: * @returns <TRUE/> if setAllCacheTableReferencedStati(false) was called, * <FALSE/> if setAllCacheTableReferencedStati(true) was called. */ - bool isInReferenceMarking() const { return bInReferenceMarking; } + bool isInReferenceMarking() const { return mbInReferenceMarking; } void storeRangeNameTokens(sal_uInt16 nFileId, const String& rName, const ScTokenArray& rArray); @@ -561,7 +559,8 @@ public: * @return shared_ptr to a token array instance. <i>The caller must not * delete the instance returned by this method.</i> */ - ScExternalRefCache::TokenArrayRef getDoubleRefTokens(sal_uInt16 nFileId, const String& rTabName, const ScRange& rRange, const ScAddress* pCurPos); + ScExternalRefCache::TokenArrayRef getDoubleRefTokens( + sal_uInt16 nFileId, const String& rTabName, const ScRange& rRange, const ScAddress* pCurPos); /** * Get an array of tokens corresponding with a specified name in a @@ -574,7 +573,8 @@ public: * * @return shared_ptr to array of tokens composing the name */ - ScExternalRefCache::TokenArrayRef getRangeNameTokens(sal_uInt16 nFileId, const String& rName, const ScAddress* pCurPos = NULL); + ScExternalRefCache::TokenArrayRef getRangeNameTokens( + sal_uInt16 nFileId, const String& rName, const ScAddress* pCurPos = NULL); const String& getOwnDocumentName() const; bool isOwnDocument(const String& rFile) const; @@ -646,32 +646,12 @@ public: void resetSrcFileData(const String& rBaseFileUrl); /** - * Update a single referencing cell position. + * Stop tracking a specific formula cell. * - * @param rOldPos old position - * @param rNewPos new position + * @param pCell pointer to cell that formerly contained external + * reference. */ - void updateRefCell(const ScAddress& rOldPos, const ScAddress& rNewPos, bool bCopy); - - /** - * Update referencing cells affected by sheet movement. - * - * @param nOldTab old sheet position - * @param nNewTab new sheet position - * @param bCopy whether this is a sheet move (false) or sheet copy (true) - */ - void updateRefMoveTable(SCTAB nOldTab, SCTAB nNewTab, bool bCopy); - - /** - * Update referencing cells affected by sheet insertion. - * - * @param nPos sheet insertion position. All sheets to the right - * including the one at the insertion poistion shift to the - * right by one. - */ - void updateRefInsertTable(SCTAB nPos); - - void updateRefDeleteTable(SCTAB nPos); + void removeRefCell(ScFormulaCell* pCell); /** * Register a new link listener to a specified external document. Note @@ -723,8 +703,6 @@ private: */ void maybeCreateRealFileName(sal_uInt16 nFileId); - bool compileTokensByCell(const ScAddress& rCell); - /** * Purge those source document instances that have not been accessed for * the specified duration. @@ -764,7 +742,13 @@ private: ::std::vector<SrcFileData> maSrcFiles; /** Status whether in reference marking state. See isInReferenceMarking(). */ - bool bInReferenceMarking; + bool mbInReferenceMarking:1; + + /** + * Controls whether or not to allow user interaction. We don't want any + * user interaction when calling from the API. + */ + bool mbUserInteractionEnabled:1; AutoTimer maSrcDocTimer; DECL_LINK(TimeOutHdl, AutoTimer*); diff --git a/sc/inc/linkuno.hxx b/sc/inc/linkuno.hxx index 50b33c692752..284d851a45da 100644 --- a/sc/inc/linkuno.hxx +++ b/sc/inc/linkuno.hxx @@ -543,7 +543,7 @@ public: // XExternalDocLink virtual ::com::sun::star::uno::Reference< ::com::sun::star::sheet::XExternalSheetCache > - SAL_CALL addSheetCache( const ::rtl::OUString& aSheetName ) + SAL_CALL addSheetCache( const ::rtl::OUString& aSheetName, sal_Bool bDynamicCache ) throw (::com::sun::star::uno::RuntimeException); // XNameAccess diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx index 950f07565e19..aed123bd7a65 100644 --- a/sc/inc/table.hxx +++ b/sc/inc/table.hxx @@ -380,7 +380,7 @@ public: SCCOL nStartCol, SCROW nStartRow, SCCOL& rEndCol, SCROW nEndRow ); void GetDataArea( SCCOL& rStartCol, SCROW& rStartRow, SCCOL& rEndCol, SCROW& rEndRow, - BOOL bIncludeOld, bool bOnlyDown ) const; + BOOL bIncludeOld, bool bOnlyDown ) const; bool ShrinkToUsedDataArea( SCCOL& rStartCol, SCROW& rStartRow, SCCOL& rEndCol, SCROW& rEndRow, bool bColumnsOnly ) const; @@ -419,7 +419,6 @@ public: void CalcAfterLoad(); void CompileAll(); void CompileXML( ScProgress& rProgress ); - bool MarkUsedExternalReferences(); void UpdateReference( UpdateRefMode eUpdateRefMode, SCCOL nCol1, SCROW nRow1, SCTAB nTab1, SCCOL nCol2, SCROW nRow2, SCTAB nTab2, diff --git a/sc/sdi/cellsh.sdi b/sc/sdi/cellsh.sdi index ed6dc17fb2a0..4c27c656d15c 100644 --- a/sc/sdi/cellsh.sdi +++ b/sc/sdi/cellsh.sdi @@ -189,6 +189,9 @@ interface CellSelection SID_HANGUL_HANJA_CONVERSION [ ExecMethod = ExecuteEdit; StateMethod = GetState; ] SID_CHINESE_CONVERSION [ ExecMethod = ExecuteEdit; StateMethod = GetState; ] + SID_TRANSLITERATE_SENTENCE_CASE [ ExecMethod = ExecuteTrans; StateMethod = GetBlockState; ] + SID_TRANSLITERATE_TITLE_CASE [ ExecMethod = ExecuteTrans; StateMethod = GetBlockState; ] + SID_TRANSLITERATE_TOGGLE_CASE [ ExecMethod = ExecuteTrans; StateMethod = GetBlockState; ] SID_TRANSLITERATE_UPPER [ ExecMethod = ExecuteTrans; StateMethod = GetBlockState; ] SID_TRANSLITERATE_LOWER [ ExecMethod = ExecuteTrans; StateMethod = GetBlockState; ] SID_TRANSLITERATE_HALFWIDTH [ ExecMethod = ExecuteTrans; StateMethod = GetBlockState; ] diff --git a/sc/sdi/drtxtob.sdi b/sc/sdi/drtxtob.sdi index cde7d77753a9..cad53257c136 100644 --- a/sc/sdi/drtxtob.sdi +++ b/sc/sdi/drtxtob.sdi @@ -62,6 +62,8 @@ interface TableDrawText SID_CLIPBOARD_FORMAT_ITEMS [ ExecMethod = Execute; StateMethod = GetClipState; Export = FALSE; ] SID_SELECTALL [ ExecMethod = Execute; StateMethod = GetState; Export = FALSE; ] SID_CHARMAP [ ExecMethod = Execute; StateMethod = GetState; Export = FALSE; ] + SID_THES [ ExecMethod = Execute; StateMethod = GetState; Export = FALSE; ] + SID_THESAURUS [ ExecMethod = Execute; StateMethod = GetState; Export = FALSE; ] // Attribute: -------------------------------------------------- SID_TEXT_STANDARD [ ExecMethod = ExecuteAttr; StateMethod = GetState; Export = FALSE; ] SID_DRAWTEXT_ATTR_DLG [ ExecMethod = ExecuteAttr; StateMethod = GetState; Export = FALSE; ] @@ -126,6 +128,9 @@ interface TableDrawText SID_VERTICALTEXT_STATE [ StateMethod = GetAttrState ; Export = FALSE; ] SID_CTLFONT_STATE [ StateMethod = GetAttrState ; Export = FALSE; ] + SID_TRANSLITERATE_SENTENCE_CASE [ ExecMethod = ExecuteTrans; StateMethod = GetState; Export = FALSE; ] + SID_TRANSLITERATE_TITLE_CASE [ ExecMethod = ExecuteTrans; StateMethod = GetState; Export = FALSE; ] + SID_TRANSLITERATE_TOGGLE_CASE [ ExecMethod = ExecuteTrans; StateMethod = GetState; Export = FALSE; ] SID_TRANSLITERATE_UPPER [ ExecMethod = ExecuteTrans; StateMethod = GetState; Export = FALSE; ] SID_TRANSLITERATE_LOWER [ ExecMethod = ExecuteTrans; StateMethod = GetState; Export = FALSE; ] SID_TRANSLITERATE_HALFWIDTH [ ExecMethod = ExecuteTrans; StateMethod = GetState; Export = FALSE; ] diff --git a/sc/sdi/editsh.sdi b/sc/sdi/editsh.sdi index ae71120c883e..1d95f2debdc3 100644 --- a/sc/sdi/editsh.sdi +++ b/sc/sdi/editsh.sdi @@ -46,6 +46,7 @@ interface TableText SID_SELECTALL [ ExecMethod = Execute; StateMethod = GetState; Export = FALSE; ] SID_CHARMAP [ ExecMethod = Execute; StateMethod = GetState; Export = FALSE; ] FID_INSERT_NAME [ ExecMethod = Execute; StateMethod = GetState; Export = FALSE; ] + SID_THES [ ExecMethod = Execute; StateMethod = GetState; Export = FALSE; ] SID_UNDO [ ExecMethod = ExecuteUndo; StateMethod = GetUndoState; Export = FALSE; ] SID_REDO [ ExecMethod = ExecuteUndo; StateMethod = GetUndoState; Export = FALSE; ] @@ -80,6 +81,9 @@ interface TableText SID_HYPERLINK_GETLINK [ StateMethod = GetState; Export = FALSE; ] SID_OPEN_HYPERLINK [ ExecMethod = Execute; StateMethod = GetState; Export = FALSE; ] + SID_TRANSLITERATE_SENTENCE_CASE [ ExecMethod = ExecuteTrans; StateMethod = GetState; Export = FALSE; ] + SID_TRANSLITERATE_TITLE_CASE [ ExecMethod = ExecuteTrans; StateMethod = GetState; Export = FALSE; ] + SID_TRANSLITERATE_TOGGLE_CASE [ ExecMethod = ExecuteTrans; StateMethod = GetState; Export = FALSE; ] SID_TRANSLITERATE_UPPER [ ExecMethod = ExecuteTrans; StateMethod = GetState; Export = FALSE; ] SID_TRANSLITERATE_LOWER [ ExecMethod = ExecuteTrans; StateMethod = GetState; Export = FALSE; ] SID_TRANSLITERATE_HALFWIDTH [ ExecMethod = ExecuteTrans; StateMethod = GetState; Export = FALSE; ] diff --git a/sc/source/core/data/cell.cxx b/sc/source/core/data/cell.cxx index 56be361f6d38..a70a9b86e186 100644 --- a/sc/source/core/data/cell.cxx +++ b/sc/source/core/data/cell.cxx @@ -819,6 +819,10 @@ ScFormulaCell::ScFormulaCell( const ScFormulaCell& rCell, ScDocument& rDoc, cons ScFormulaCell::~ScFormulaCell() { pDocument->RemoveFromFormulaTree( this ); + + if (pDocument->HasExternalRefManager()) + pDocument->GetExternalRefManager()->removeRefCell(this); + delete pCode; #ifdef DBG_UTIL eCellType = CELLTYPE_DESTROYED; diff --git a/sc/source/core/data/cell2.cxx b/sc/source/core/data/cell2.cxx index 4de78c71fe79..1aab26acf3aa 100644 --- a/sc/source/core/data/cell2.cxx +++ b/sc/source/core/data/cell2.cxx @@ -1038,17 +1038,6 @@ void ScFormulaCell::UpdateReference(UpdateRefMode eUpdateRefMode, delete pOld; } - - pCode->Reset(); - for ( formula::FormulaToken* t = pCode->GetNextReferenceOrName(); t; t = pCode->GetNextReferenceOrName() ) - { - StackVar sv = t->GetType(); - if (sv == svExternalSingleRef || sv == svExternalDoubleRef || sv == svExternalName) - { - pDocument->GetExternalRefManager()->updateRefCell(aOldPos, aPos, eUpdateRefMode == URM_COPY); - break; - } - } } void ScFormulaCell::UpdateInsertTab(SCTAB nTable) diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx index ee670d5ba0ef..6a5fe824197b 100644 --- a/sc/source/core/data/column.cxx +++ b/sc/source/core/data/column.cxx @@ -2100,22 +2100,6 @@ void ScColumn::CalcAfterLoad() } -bool ScColumn::MarkUsedExternalReferences() -{ - bool bAllMarked = false; - if (pItems) - { - for (SCSIZE i = 0; i < nCount && !bAllMarked; ++i) - { - ScBaseCell* pCell = pItems[i].pCell; - if ( pCell->GetCellType() == CELLTYPE_FORMULA ) - bAllMarked = ((ScFormulaCell*)pCell)->MarkUsedExternalReferences(); - } - } - return bAllMarked; -} - - void ScColumn::ResetChanged( SCROW nStartRow, SCROW nEndRow ) { if (pItems) diff --git a/sc/source/core/data/docpool.cxx b/sc/source/core/data/docpool.cxx index d6aa91efcca6..cd763cfc0787 100644 --- a/sc/source/core/data/docpool.cxx +++ b/sc/source/core/data/docpool.cxx @@ -705,7 +705,7 @@ SfxItemPresentation lcl_HFPresentation nTmp = rLRItem.GetRight(); nRightMargin = nTmp < 0 ? 0 : USHORT(nTmp); - aText = SVX_RESSTR(RID_SVXITEMS_LRSPACE_LEFT); + aText = EE_RESSTR(RID_SVXITEMS_LRSPACE_LEFT); if ( 100 != nPropLeftMargin ) { aText += String::CreateFromInt32( nPropLeftMargin ); @@ -715,13 +715,13 @@ SfxItemPresentation lcl_HFPresentation { aText += GetMetricText( (long)nLeftMargin, eCoreMetric, ePresentationMetric, pIntl ); - aText += SVX_RESSTR(GetMetricId(ePresentationMetric)); + aText += EE_RESSTR(GetMetricId(ePresentationMetric)); } aText += cpDelim; // nPropFirstLineOfst haben wir nicht - aText += SVX_RESSTR(RID_SVXITEMS_LRSPACE_RIGHT); + aText += EE_RESSTR(RID_SVXITEMS_LRSPACE_RIGHT); if ( 100 != nPropRightMargin ) { aText += String::CreateFromInt32( nPropRightMargin ); @@ -731,7 +731,7 @@ SfxItemPresentation lcl_HFPresentation { aText += GetMetricText( (long)nRightMargin, eCoreMetric, ePresentationMetric, pIntl ); - aText += SVX_RESSTR(GetMetricId(ePresentationMetric)); + aText += EE_RESSTR(GetMetricId(ePresentationMetric)); } } break; diff --git a/sc/source/core/data/documen2.cxx b/sc/source/core/data/documen2.cxx index 138b55f0794c..c5922aa88dcc 100755 --- a/sc/source/core/data/documen2.cxx +++ b/sc/source/core/data/documen2.cxx @@ -804,10 +804,6 @@ BOOL ScDocument::MoveTab( SCTAB nOldPos, SCTAB nNewPos ) if (pDrawLayer) DrawMovePage( static_cast<sal_uInt16>(nOldPos), static_cast<sal_uInt16>(nNewPos) ); - // Update cells containing external references. - if (pExternalRefMgr.get()) - pExternalRefMgr->updateRefMoveTable(nOldPos, nNewPos, false); - bValid = TRUE; } } @@ -925,10 +921,6 @@ BOOL ScDocument::CopyTab( SCTAB nOldPos, SCTAB nNewPos, const ScMarkData* pOnlyM pTab[nNewPos]->SetPageStyle( pTab[nOldPos]->GetPageStyle() ); pTab[nNewPos]->SetPendingRowHeights( pTab[nOldPos]->IsPendingRowHeights() ); - - // Update cells containing external references. - if (pExternalRefMgr.get()) - pExternalRefMgr->updateRefMoveTable(nOldPos, nNewPos, true); } else SetAutoCalc( bOldAutoCalc ); diff --git a/sc/source/core/data/documen3.cxx b/sc/source/core/data/documen3.cxx index 557f181c9d8f..77f59254e049 100644 --- a/sc/source/core/data/documen3.cxx +++ b/sc/source/core/data/documen3.cxx @@ -465,11 +465,8 @@ void ScDocument::MarkUsedExternalReferences() // Charts. bool bAllMarked = pExternalRefMgr->markUsedByLinkListeners(); // Formula cells. - for (SCTAB nTab = 0; !bAllMarked && nTab < nMaxTableNumber; ++nTab) - { - if (pTab[nTab]) - bAllMarked = pTab[nTab]->MarkUsedExternalReferences(); - } + bAllMarked = pExternalRefMgr->markUsedExternalRefCells(); + /* NOTE: Conditional formats and validation objects are marked when * collecting them during export. */ } diff --git a/sc/source/core/data/documen5.cxx b/sc/source/core/data/documen5.cxx index d6653402c46a..d86d174ab414 100644 --- a/sc/source/core/data/documen5.cxx +++ b/sc/source/core/data/documen5.cxx @@ -705,6 +705,9 @@ void ScDocument::UpdateChartListenerCollection() SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab)); DBG_ASSERT(pPage,"Page ?"); + if (!pPage) + continue; + SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS ); SdrObject* pObject = aIter.Next(); while (pObject) diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx index ff132a1f204b..7c08c4327183 100644 --- a/sc/source/core/data/document.cxx +++ b/sc/source/core/data/document.cxx @@ -375,10 +375,6 @@ BOOL ScDocument::InsertTab( SCTAB nPos, const String& rName, if ( pChartListenerCollection ) pChartListenerCollection->UpdateScheduledSeriesRanges(); - // Update cells containing external references. - if (pExternalRefMgr.get()) - pExternalRefMgr->updateRefInsertTable(nPos); - SetDirty(); bValid = TRUE; } @@ -467,11 +463,6 @@ BOOL ScDocument::DeleteTab( SCTAB nTab, ScDocument* pRefUndoDoc ) // #81844# sheet names of references are not valid until sheet is deleted pChartListenerCollection->UpdateScheduledSeriesRanges(); - - // Update cells containing external references. - if (pExternalRefMgr.get()) - pExternalRefMgr->updateRefDeleteTable(nTab); - SetAutoCalc( bOldAutoCalc ); bValid = TRUE; } @@ -694,6 +685,10 @@ bool ScDocument::ShrinkToDataArea(SCTAB nTab, SCCOL& rStartCol, SCROW& rStartRow if (nRow2 < rEndRow) rEndRow = nRow2; + if (rStartCol > rEndCol || rStartRow > rEndRow) + // invalid range. + return false; + return true; // success! } @@ -708,11 +703,10 @@ bool ScDocument::ShrinkToUsedDataArea( SCTAB nTab, SCCOL& rStartCol, // zusammenhaengender Bereich void ScDocument::GetDataArea( SCTAB nTab, SCCOL& rStartCol, SCROW& rStartRow, - SCCOL& rEndCol, SCROW& rEndRow, BOOL bIncludeOld, bool bOnlyDown ) + SCCOL& rEndCol, SCROW& rEndRow, BOOL bIncludeOld, bool bOnlyDown ) const { - if (VALIDTAB(nTab)) - if (pTab[nTab]) - pTab[nTab]->GetDataArea( rStartCol, rStartRow, rEndCol, rEndRow, bIncludeOld, bOnlyDown ); + if (ValidTab(nTab) && pTab[nTab]) + pTab[nTab]->GetDataArea( rStartCol, rStartRow, rEndCol, rEndRow, bIncludeOld, bOnlyDown ); } diff --git a/sc/source/core/data/dpgroup.cxx b/sc/source/core/data/dpgroup.cxx index e71ec5c8b82c..edb3b787b9b2 100644 --- a/sc/source/core/data/dpgroup.cxx +++ b/sc/source/core/data/dpgroup.cxx @@ -1324,13 +1324,9 @@ void ScDPGroupTableData::GetDrillDownData(const vector<ScDPCacheTable::Criterion void ScDPGroupTableData::CalcResults(CalcInfo& rInfo, bool bAutoShow) { - // This CalcInfo instance is used only to retrive data from the original - // data source. - CalcInfo aInfoSrc = rInfo; - CopyFields(rInfo.aColLevelDims, aInfoSrc.aColLevelDims); - CopyFields(rInfo.aRowLevelDims, aInfoSrc.aRowLevelDims); - CopyFields(rInfo.aPageDims, aInfoSrc.aPageDims); - CopyFields(rInfo.aDataSrcCols, aInfoSrc.aDataSrcCols); + // #i111435# Inside FillRowDataFromCacheTable/GetItemData, virtual methods + // getIsDataLayoutDimension and GetSourceDim are used, so it has to be called + // with original rInfo, containing dimension indexes of the grouped data. const ScDPCacheTable& rCacheTable = pSourceData->GetCacheTable(); sal_Int32 nRowSize = rCacheTable.getRowSize(); @@ -1340,7 +1336,7 @@ void ScDPGroupTableData::CalcResults(CalcInfo& rInfo, bool bAutoShow) continue; CalcRowData aData; - FillRowDataFromCacheTable(nRow, rCacheTable, aInfoSrc, aData); + FillRowDataFromCacheTable(nRow, rCacheTable, rInfo, aData); if ( !rInfo.aColLevelDims.empty() ) FillGroupValues(&aData.aColData[0], rInfo.aColLevelDims.size(), &rInfo.aColLevelDims[0]); @@ -1358,35 +1354,6 @@ const ScDPCacheTable& ScDPGroupTableData::GetCacheTable() const return pSourceData->GetCacheTable(); } -void ScDPGroupTableData::CopyFields(const vector<long>& rFieldDims, vector<long>& rNewFieldDims) -{ - size_t nCount = rFieldDims.size(); - if (!nCount) - return; - - long nGroupedColumns = aGroups.size(); - - rNewFieldDims.clear(); - rNewFieldDims.reserve(nCount); - for (size_t i = 0; i < nCount; ++i) - { - if ( rFieldDims[i] >= nSourceCount ) - { - if ( rFieldDims[i] == nSourceCount + nGroupedColumns ) - // data layout in source - rNewFieldDims.push_back(nSourceCount); - else - { - // original dimension - long n = rFieldDims[i] - nSourceCount; - rNewFieldDims.push_back(aGroups[n].GetSourceDim()); - } - } - else - rNewFieldDims.push_back(rFieldDims[i]); - } -} - void ScDPGroupTableData::FillGroupValues( /*ScDPItemData* pItemData*/ SCROW* pItemDataIndex, long nCount, const long* pDims ) { long nGroupedColumns = aGroups.size(); diff --git a/sc/source/core/data/dpobject.cxx b/sc/source/core/data/dpobject.cxx index b9eb7d88a44d..affee8b469e6 100755 --- a/sc/source/core/data/dpobject.cxx +++ b/sc/source/core/data/dpobject.cxx @@ -623,6 +623,11 @@ void ScDPObject::BuildAllDimensionMembers() if (!pSaveData) return; + // #i111857# don't always create empty mpTableData for external service. + // Ideally, xSource should be used instead of mpTableData. + if (pServDesc) + return; + pSaveData->BuildAllDimensionMembers(GetTableData()); } diff --git a/sc/source/core/data/dpoutput.cxx b/sc/source/core/data/dpoutput.cxx index 5bbcdc5ab991..bdd6fd555b89 100755 --- a/sc/source/core/data/dpoutput.cxx +++ b/sc/source/core/data/dpoutput.cxx @@ -1087,6 +1087,72 @@ bool ScDPOutput::GetHeaderLayout() const return mbHeaderLayout; } +void lcl_GetTableVars( sal_Int32& rGrandTotalCols, sal_Int32& rGrandTotalRows, sal_Int32& rDataLayoutIndex, + std::vector<String>& rDataNames, std::vector<String>& rGivenNames, + sheet::DataPilotFieldOrientation& rDataOrient, + const uno::Reference<sheet::XDimensionsSupplier>& xSource ) +{ + rDataLayoutIndex = -1; // invalid + rGrandTotalCols = 0; + rGrandTotalRows = 0; + rDataOrient = sheet::DataPilotFieldOrientation_HIDDEN; + + uno::Reference<beans::XPropertySet> xSrcProp( xSource, uno::UNO_QUERY ); + BOOL bColGrand = ScUnoHelpFunctions::GetBoolProperty( xSrcProp, + rtl::OUString::createFromAscii(DP_PROP_COLUMNGRAND) ); + if ( bColGrand ) + rGrandTotalCols = 1; // default if data layout not in columns + + BOOL bRowGrand = ScUnoHelpFunctions::GetBoolProperty( xSrcProp, + rtl::OUString::createFromAscii(DP_PROP_ROWGRAND) ); + if ( bRowGrand ) + rGrandTotalRows = 1; // default if data layout not in rows + + if ( xSource.is() ) + { + // find index and orientation of "data layout" dimension, count data dimensions + + sal_Int32 nDataCount = 0; + + uno::Reference<container::XIndexAccess> xDims = new ScNameToIndexAccess( xSource->getDimensions() ); + long nDimCount = xDims->getCount(); + for (long nDim=0; nDim<nDimCount; nDim++) + { + uno::Reference<uno::XInterface> xDim = + ScUnoHelpFunctions::AnyToInterface( xDims->getByIndex(nDim) ); + uno::Reference<beans::XPropertySet> xDimProp( xDim, uno::UNO_QUERY ); + if ( xDimProp.is() ) + { + sheet::DataPilotFieldOrientation eDimOrient = + (sheet::DataPilotFieldOrientation) ScUnoHelpFunctions::GetEnumProperty( + xDimProp, rtl::OUString::createFromAscii(DP_PROP_ORIENTATION), + sheet::DataPilotFieldOrientation_HIDDEN ); + if ( ScUnoHelpFunctions::GetBoolProperty( xDimProp, + rtl::OUString::createFromAscii(DP_PROP_ISDATALAYOUT) ) ) + { + rDataLayoutIndex = nDim; + rDataOrient = eDimOrient; + } + if ( eDimOrient == sheet::DataPilotFieldOrientation_DATA ) + { + String aSourceName; + String aGivenName; + ScDPOutput::GetDataDimensionNames( aSourceName, aGivenName, xDim ); + rDataNames.push_back( aSourceName ); + rGivenNames.push_back( aGivenName ); + + ++nDataCount; + } + } + } + + if ( ( rDataOrient == sheet::DataPilotFieldOrientation_COLUMN ) && bColGrand ) + rGrandTotalCols = nDataCount; + else if ( ( rDataOrient == sheet::DataPilotFieldOrientation_ROW ) && bRowGrand ) + rGrandTotalRows = nDataCount; + } +} + void ScDPOutput::GetPositionData(const ScAddress& rPos, DataPilotTablePositionData& rPosData) { using namespace ::com::sun::star::sheet; @@ -1207,15 +1273,14 @@ bool ScDPOutput::GetDataResultPositionData(vector<sheet::DataPilotFieldFilter>& // No data field is present in this datapilot table. return false; - bool bColGrand = bool(); - Any any = xPropSet->getPropertyValue(rtl::OUString::createFromAscii(SC_UNO_COLGRAND)); - if (!(any >>= bColGrand)) - return false; - - bool bRowGrand = bool(); - any = xPropSet->getPropertyValue(rtl::OUString::createFromAscii(SC_UNO_ROWGRAND)); - if (!(any >>= bRowGrand)) - return false; + // #i111421# use lcl_GetTableVars for correct size of totals and data layout position + sal_Int32 nGrandTotalCols; + sal_Int32 nGrandTotalRows; + sal_Int32 nDataLayoutIndex; + std::vector<String> aDataNames; + std::vector<String> aGivenNames; + sheet::DataPilotFieldOrientation eDataOrient; + lcl_GetTableVars( nGrandTotalCols, nGrandTotalRows, nDataLayoutIndex, aDataNames, aGivenNames, eDataOrient, xSource ); SCCOL nCol = rPos.Col(); SCROW nRow = rPos.Row(); @@ -1232,12 +1297,16 @@ bool ScDPOutput::GetDataResultPositionData(vector<sheet::DataPilotFieldFilter>& return false; } - bool bFilterByCol = !(bColGrand && (nCol == nTabEndCol)); - bool bFilterByRow = !(bRowGrand && (nRow == nTabEndRow)); + bool bFilterByCol = (nCol <= static_cast<SCCOL>(nTabEndCol - nGrandTotalCols)); + bool bFilterByRow = (nRow <= static_cast<SCROW>(nTabEndRow - nGrandTotalRows)); // column fields for (SCCOL nColField = 0; nColField < nColFieldCount && bFilterByCol; ++nColField) { + if (pColFields[nColField].nDim == nDataLayoutIndex) + // There is no sense including the data layout field for filtering. + continue; + sheet::DataPilotFieldFilter filter; filter.FieldName = pColFields[nColField].maName; @@ -1256,10 +1325,9 @@ bool ScDPOutput::GetDataResultPositionData(vector<sheet::DataPilotFieldFilter>& } // row fields - bool bDataLayoutExists = (nDataFieldCount > 1); for (SCROW nRowField = 0; nRowField < nRowFieldCount && bFilterByRow; ++nRowField) { - if (bDataLayoutExists && nRowField == nRowFieldCount - 1) + if (pRowFields[nRowField].nDim == nDataLayoutIndex) // There is no sense including the data layout field for filtering. continue; @@ -1643,72 +1711,6 @@ void ScDPOutput::GetDataDimensionNames( String& rSourceName, String& rGivenName, } } -void lcl_GetTableVars( sal_Int32& rGrandTotalCols, sal_Int32& rGrandTotalRows, sal_Int32& rDataLayoutIndex, - std::vector<String>& rDataNames, std::vector<String>& rGivenNames, - sheet::DataPilotFieldOrientation& rDataOrient, - const uno::Reference<sheet::XDimensionsSupplier>& xSource ) -{ - rDataLayoutIndex = -1; // invalid - rGrandTotalCols = 0; - rGrandTotalRows = 0; - rDataOrient = sheet::DataPilotFieldOrientation_HIDDEN; - - uno::Reference<beans::XPropertySet> xSrcProp( xSource, uno::UNO_QUERY ); - BOOL bColGrand = ScUnoHelpFunctions::GetBoolProperty( xSrcProp, - rtl::OUString::createFromAscii(DP_PROP_COLUMNGRAND) ); - if ( bColGrand ) - rGrandTotalCols = 1; // default if data layout not in columns - - BOOL bRowGrand = ScUnoHelpFunctions::GetBoolProperty( xSrcProp, - rtl::OUString::createFromAscii(DP_PROP_ROWGRAND) ); - if ( bRowGrand ) - rGrandTotalRows = 1; // default if data layout not in rows - - if ( xSource.is() ) - { - // find index and orientation of "data layout" dimension, count data dimensions - - sal_Int32 nDataCount = 0; - - uno::Reference<container::XIndexAccess> xDims = new ScNameToIndexAccess( xSource->getDimensions() ); - long nDimCount = xDims->getCount(); - for (long nDim=0; nDim<nDimCount; nDim++) - { - uno::Reference<uno::XInterface> xDim = - ScUnoHelpFunctions::AnyToInterface( xDims->getByIndex(nDim) ); - uno::Reference<beans::XPropertySet> xDimProp( xDim, uno::UNO_QUERY ); - if ( xDimProp.is() ) - { - sheet::DataPilotFieldOrientation eDimOrient = - (sheet::DataPilotFieldOrientation) ScUnoHelpFunctions::GetEnumProperty( - xDimProp, rtl::OUString::createFromAscii(DP_PROP_ORIENTATION), - sheet::DataPilotFieldOrientation_HIDDEN ); - if ( ScUnoHelpFunctions::GetBoolProperty( xDimProp, - rtl::OUString::createFromAscii(DP_PROP_ISDATALAYOUT) ) ) - { - rDataLayoutIndex = nDim; - rDataOrient = eDimOrient; - } - if ( eDimOrient == sheet::DataPilotFieldOrientation_DATA ) - { - String aSourceName; - String aGivenName; - ScDPOutput::GetDataDimensionNames( aSourceName, aGivenName, xDim ); - rDataNames.push_back( aSourceName ); - rGivenNames.push_back( aGivenName ); - - ++nDataCount; - } - } - } - - if ( ( rDataOrient == sheet::DataPilotFieldOrientation_COLUMN ) && bColGrand ) - rGrandTotalCols = nDataCount; - else if ( ( rDataOrient == sheet::DataPilotFieldOrientation_ROW ) && bRowGrand ) - rGrandTotalRows = nDataCount; - } -} - // Returns TRUE on success and stores the result in rTarget // Returns FALSE if rFilters or rTarget describes something that is not visible BOOL ScDPOutput::GetPivotData( ScDPGetPivotDataField& rTarget, diff --git a/sc/source/core/data/dptabdat.cxx b/sc/source/core/data/dptabdat.cxx index cff18ef925d9..cb68732a237f 100755 --- a/sc/source/core/data/dptabdat.cxx +++ b/sc/source/core/data/dptabdat.cxx @@ -169,13 +169,19 @@ void ScDPTableData::FillRowDataFromCacheTable(sal_Int32 nRow, const ScDPCacheTab // page dimensions GetItemData(rCacheTable, nRow, rInfo.aPageDims, rData.aPageData); + long nCacheColumnCount = rCacheTable.GetCache()->GetColumnCount(); sal_Int32 n = rInfo.aDataSrcCols.size(); for (sal_Int32 i = 0; i < n; ++i) { long nDim = rInfo.aDataSrcCols[i]; rData.aValues.push_back( ScDPValueData() ); - ScDPValueData& rVal = rData.aValues.back(); - rCacheTable.getValue( rVal, static_cast<SCCOL>(nDim), static_cast<SCROW>(nRow), false); + // #i111435# GetItemData needs dimension indexes including groups, + // so the index must be checked here (groups aren't useful as data fields). + if ( nDim < nCacheColumnCount ) + { + ScDPValueData& rVal = rData.aValues.back(); + rCacheTable.getValue( rVal, static_cast<SCCOL>(nDim), static_cast<SCROW>(nRow), false); + } } } diff --git a/sc/source/core/data/dptabres.cxx b/sc/source/core/data/dptabres.cxx index af8b74d546a8..c79f7c1b17a6 100755 --- a/sc/source/core/data/dptabres.cxx +++ b/sc/source/core/data/dptabres.cxx @@ -1153,11 +1153,16 @@ void ScDPResultMember::LateInitFrom( LateInitParams& rParams/*const vector<ScDPD { if ( rParams.GetDim( nPos ) ->getIsDataLayoutDimension() ) { - if ( !pChildDimension ) - pChildDimension = new ScDPResultDimension( pResultData ); - rParams.SetInitChild( FALSE ); - pChildDimension->LateInitFrom( rParams, pItemData, nPos, rInitState ); - return; + if ( !pChildDimension ) + pChildDimension = new ScDPResultDimension( pResultData ); + + // #i111462# reset InitChild flag only for this child dimension's LateInitFrom call, + // not for following members of parent dimensions + BOOL bWasInitChild = rParams.GetInitChild(); + rParams.SetInitChild( FALSE ); + pChildDimension->LateInitFrom( rParams, pItemData, nPos, rInitState ); + rParams.SetInitChild( bWasInitChild ); + return; } else { //find next dim diff --git a/sc/source/core/data/table1.cxx b/sc/source/core/data/table1.cxx index 75b288272c1e..a8b819072c21 100644 --- a/sc/source/core/data/table1.cxx +++ b/sc/source/core/data/table1.cxx @@ -678,7 +678,7 @@ BOOL ScTable::GetDataStart( SCCOL& rStartCol, SCROW& rStartRow ) const } void ScTable::GetDataArea( SCCOL& rStartCol, SCROW& rStartRow, SCCOL& rEndCol, SCROW& rEndRow, - BOOL bIncludeOld, bool bOnlyDown ) const + BOOL bIncludeOld, bool bOnlyDown ) const { BOOL bLeft = FALSE; BOOL bRight = FALSE; diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx index 4dc7dddcaba1..69d16df7be58 100644 --- a/sc/source/core/data/table2.cxx +++ b/sc/source/core/data/table2.cxx @@ -1119,17 +1119,6 @@ void ScTable::CalcAfterLoad() } -bool ScTable::MarkUsedExternalReferences() -{ - bool bAllMarked = false; - for (SCCOL i=0; i <= MAXCOL && !bAllMarked; ++i) - { - bAllMarked = aCol[i].MarkUsedExternalReferences(); - } - return bAllMarked; -} - - void ScTable::ResetChanged( const ScRange& rRange ) { SCCOL nStartCol = rRange.aStart.Col(); diff --git a/sc/source/core/data/table4.cxx b/sc/source/core/data/table4.cxx index 4a736e8c11b7..434144d06e00 100644 --- a/sc/source/core/data/table4.cxx +++ b/sc/source/core/data/table4.cxx @@ -586,13 +586,13 @@ void ScTable::FillAuto( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, // Attributierung uebertragen const ScPatternAttr* pSrcPattern = NULL; + const ScStyleSheet* pStyleSheet = NULL; ULONG nAtSrc = nISrcStart; ScPatternAttr* pNewPattern = NULL; BOOL bGetPattern = TRUE; rInner = nIStart; while (true) // #i53728# with "for (;;)" old solaris/x86 compiler mis-optimizes { - const ScStyleSheet* pStyleSheet = NULL; if ( bGetPattern ) { if ( pNewPattern ) diff --git a/sc/source/core/data/table5.cxx b/sc/source/core/data/table5.cxx index 3a7117dfcd10..a3a0153a4b97 100644 --- a/sc/source/core/data/table5.cxx +++ b/sc/source/core/data/table5.cxx @@ -114,14 +114,25 @@ void ScTable::UpdatePageBreaks( const ScRange* pUserArea ) } // sonst alles } - // bSkipBreaks holen: + // get bSkipColBreaks/bSkipRowBreaks flags: - BOOL bSkipBreaks = FALSE; + bool bSkipColBreaks = false; + bool bSkipRowBreaks = false; if ( pStyleSet->GetItemState( ATTR_PAGE_SCALETOPAGES, FALSE, &pItem ) == SFX_ITEM_SET ) { DBG_ASSERT( pItem->ISA(SfxUInt16Item), "falsches Item" ); - bSkipBreaks = ( ((const SfxUInt16Item*)pItem)->GetValue() > 0 ); + bSkipColBreaks = bSkipRowBreaks = ( ((const SfxUInt16Item*)pItem)->GetValue() > 0 ); + } + + if ( !bSkipColBreaks && pStyleSet->GetItemState(ATTR_PAGE_SCALETO, FALSE, &pItem) == SFX_ITEM_SET ) + { + // #i54993# when fitting to width or height, ignore only manual breaks in that direction + const ScPageScaleToItem* pScaleToItem = static_cast<const ScPageScaleToItem*>(pItem); + if ( pScaleToItem->GetWidth() > 0 ) + bSkipColBreaks = true; + if ( pScaleToItem->GetHeight() > 0 ) + bSkipRowBreaks = true; } //-------------------------------------------------------------------------- @@ -149,7 +160,7 @@ void ScTable::UpdatePageBreaks( const ScRange* pUserArea ) { BOOL bStartOfPage = FALSE; long nThisX = ( pColFlags[nX] & CR_HIDDEN ) ? 0 : pColWidth[nX]; - if ( (nSizeX+nThisX > nPageSizeX) || ((pColFlags[nX] & CR_MANUALBREAK) && !bSkipBreaks) ) + if ( (nSizeX+nThisX > nPageSizeX) || ((pColFlags[nX] & CR_MANUALBREAK) && !bSkipColBreaks) ) { pColFlags[nX] |= CR_PAGEBREAK; nSizeX = 0; @@ -187,7 +198,7 @@ void ScTable::UpdatePageBreaks( const ScRange* pUserArea ) BOOL bStartOfPage = FALSE; BYTE nFlags = *aFlagsIter; long nThisY = (nFlags & CR_HIDDEN) ? 0 : *aHeightIter; - if ( (nSizeY+nThisY > nPageSizeY) || ((nFlags & CR_MANUALBREAK) && !bSkipBreaks) ) + if ( (nSizeY+nThisY > nPageSizeY) || ((nFlags & CR_MANUALBREAK) && !bSkipRowBreaks) ) { pRowFlags->SetValue( nY, nFlags | CR_PAGEBREAK); aFlagsIter.Resync( nY); diff --git a/sc/source/core/tool/queryparam.cxx b/sc/source/core/tool/queryparam.cxx index 47418ec85f4d..5b3b92f78ee4 100644 --- a/sc/source/core/tool/queryparam.cxx +++ b/sc/source/core/tool/queryparam.cxx @@ -171,7 +171,11 @@ ScQueryParamTable::~ScQueryParamTable() ScQueryParam::ScQueryParam() : ScQueryParamBase(), - ScQueryParamTable() + ScQueryParamTable(), + bDestPers(true), + nDestTab(0), + nDestCol(0), + nDestRow(0) { Clear(); } diff --git a/sc/source/filter/excel/excdoc.cxx b/sc/source/filter/excel/excdoc.cxx index bba1543dd403..5534f8e775a9 100644 --- a/sc/source/filter/excel/excdoc.cxx +++ b/sc/source/filter/excel/excdoc.cxx @@ -437,7 +437,8 @@ void ExcTable::FillAsTable( size_t nCodeNameIdx ) DBG_ASSERT( nExcTab <= static_cast<sal_uInt16>(MAXTAB), "-ExcTable::Table(): nExcTab - no ordinary table!" ); // create a new OBJ list for this sheet (may be used by notes, autofilter, data validation) - GetObjectManager().StartSheet(); + if( eBiff == EXC_BIFF8 ) + GetObjectManager().StartSheet(); // cell table: DEFROWHEIGHT, DEFCOLWIDTH, COLINFO, DIMENSIONS, ROW, cell records mxCellTable.reset( new XclExpCellTable( GetRoot() ) ); diff --git a/sc/source/filter/excel/read.cxx b/sc/source/filter/excel/read.cxx index 5b9cc3180699..3aef51d10c54 100644 --- a/sc/source/filter/excel/read.cxx +++ b/sc/source/filter/excel/read.cxx @@ -1211,7 +1211,9 @@ FltError ImportExcel8::Read( void ) pProgress.reset(); - AdjustRowHeight(); + if (pD->IsAdjustHeightEnabled()) + AdjustRowHeight(); + PostDocLoad(); pD->CalcAfterLoad(); diff --git a/sc/source/filter/excel/xechart.cxx b/sc/source/filter/excel/xechart.cxx index 1564b2db834e..b6b136da4b1e 100644 --- a/sc/source/filter/excel/xechart.cxx +++ b/sc/source/filter/excel/xechart.cxx @@ -39,6 +39,8 @@ #include <com/sun/star/chart/DataLabelPlacement.hpp> #include <com/sun/star/chart/ErrorBarStyle.hpp> #include <com/sun/star/chart/MissingValueTreatment.hpp> +#include <com/sun/star/chart/XChartDocument.hpp> +#include <com/sun/star/chart/XDiagramPositioning.hpp> #include <com/sun/star/chart2/XChartDocument.hpp> #include <com/sun/star/chart2/XDiagram.hpp> #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp> @@ -52,6 +54,9 @@ #include <com/sun/star/chart2/CurveStyle.hpp> #include <com/sun/star/chart2/DataPointGeometry3D.hpp> #include <com/sun/star/chart2/DataPointLabel.hpp> +#include <com/sun/star/chart2/LegendExpansion.hpp> +#include <com/sun/star/chart2/LegendPosition.hpp> +#include <com/sun/star/chart2/RelativePosition.hpp> #include <com/sun/star/chart2/StackingDirection.hpp> #include <com/sun/star/chart2/TickmarkStyle.hpp> @@ -75,38 +80,47 @@ using ::com::sun::star::uno::Any; using ::com::sun::star::uno::Reference; using ::com::sun::star::uno::Sequence; using ::com::sun::star::uno::UNO_QUERY; +using ::com::sun::star::uno::UNO_QUERY_THROW; +using ::com::sun::star::uno::UNO_SET_THROW; using ::com::sun::star::uno::Exception; using ::com::sun::star::beans::XPropertySet; using ::com::sun::star::i18n::XBreakIterator; using ::com::sun::star::frame::XModel; +using ::com::sun::star::drawing::XShape; using ::com::sun::star::drawing::XShapes; + +using ::com::sun::star::chart2::IncrementData; +using ::com::sun::star::chart2::RelativePosition; +using ::com::sun::star::chart2::ScaleData; +using ::com::sun::star::chart2::SubIncrement; +using ::com::sun::star::chart2::XAxis; using ::com::sun::star::chart2::XChartDocument; -using ::com::sun::star::chart2::XDiagram; -using ::com::sun::star::chart2::XCoordinateSystemContainer; -using ::com::sun::star::chart2::XCoordinateSystem; using ::com::sun::star::chart2::XChartTypeContainer; +using ::com::sun::star::chart2::XColorScheme; +using ::com::sun::star::chart2::XCoordinateSystem; +using ::com::sun::star::chart2::XCoordinateSystemContainer; using ::com::sun::star::chart2::XChartType; -using ::com::sun::star::chart2::XDataSeriesContainer; using ::com::sun::star::chart2::XDataSeries; -using ::com::sun::star::chart2::XRegressionCurveContainer; +using ::com::sun::star::chart2::XDataSeriesContainer; +using ::com::sun::star::chart2::XDiagram; +using ::com::sun::star::chart2::XFormattedString; +using ::com::sun::star::chart2::XLegend; using ::com::sun::star::chart2::XRegressionCurve; -using ::com::sun::star::chart2::XAxis; +using ::com::sun::star::chart2::XRegressionCurveContainer; using ::com::sun::star::chart2::XScaling; -using ::com::sun::star::chart2::ScaleData; -using ::com::sun::star::chart2::IncrementData; -using ::com::sun::star::chart2::SubIncrement; -using ::com::sun::star::chart2::XLegend; -using ::com::sun::star::chart2::XTitled; using ::com::sun::star::chart2::XTitle; -using ::com::sun::star::chart2::XFormattedString; -using ::com::sun::star::chart2::XColorScheme; +using ::com::sun::star::chart2::XTitled; + +using ::com::sun::star::chart2::data::XDataSequence; using ::com::sun::star::chart2::data::XDataSource; using ::com::sun::star::chart2::data::XLabeledDataSequence; -using ::com::sun::star::chart2::data::XDataSequence; using ::formula::FormulaGrammar; using ::formula::FormulaToken; +namespace cssc = ::com::sun::star::chart; +namespace cssc2 = ::com::sun::star::chart2; + // Helpers ==================================================================== namespace { @@ -160,13 +174,15 @@ bool lclIsAutoAnyOrGetScaledValue( double& rfValue, const Any& rAny, bool bLogSc // Common ===================================================================== /** Stores global data needed in various classes of the Chart export filter. */ -class XclExpChRootData : public XclChRootData +struct XclExpChRootData : public XclChRootData { -public: - explicit XclExpChRootData( XclExpChChart* pChartData ); + typedef ::std::vector< XclChFrBlock > XclChFrBlockVector; + + XclExpChChart& mrChartData; /// The chart data object. + XclChFrBlockVector maWrittenFrBlocks; /// Stack of future record levels already written out. + XclChFrBlockVector maUnwrittenFrBlocks; /// Stack of future record levels not yet written out. - /** Returns a reference to the parent chart data object. */ - inline XclExpChChart& GetChartData() const { return *mpChartData; } + inline explicit XclExpChRootData( XclExpChChart& rChartData ) : mrChartData( rChartData ) {} /** Registers a new future record level. */ void RegisterFutureRecBlock( const XclChFrBlock& rFrBlock ); @@ -174,22 +190,10 @@ public: void InitializeFutureRecBlock( XclExpStream& rStrm ); /** Finalizes the current future record level (writes CHFRBLOCKEND record if needed). */ void FinalizeFutureRecBlock( XclExpStream& rStrm ); - -private: - typedef ::std::vector< XclChFrBlock > XclChFrBlockVector; - - XclExpChChart* mpChartData; /// Pointer to the chart data object. - XclChFrBlockVector maWrittenFrBlocks; /// Stack of future record levels already written out. - XclChFrBlockVector maUnwrittenFrBlocks; /// Stack of future record levels not yet written out. }; // ---------------------------------------------------------------------------- -XclExpChRootData::XclExpChRootData( XclExpChChart* pChartData ) : - mpChartData( pChartData ) -{ -} - void XclExpChRootData::RegisterFutureRecBlock( const XclChFrBlock& rFrBlock ) { maUnwrittenFrBlocks.push_back( rFrBlock ); @@ -238,9 +242,9 @@ void XclExpChRootData::FinalizeFutureRecBlock( XclExpStream& rStrm ) // ---------------------------------------------------------------------------- -XclExpChRoot::XclExpChRoot( const XclExpRoot& rRoot, XclExpChChart* pChartData ) : +XclExpChRoot::XclExpChRoot( const XclExpRoot& rRoot, XclExpChChart& rChartData ) : XclExpRoot( rRoot ), - mxChData( new XclExpChRootData( pChartData ) ) + mxChData( new XclExpChRootData( rChartData ) ) { } @@ -248,29 +252,34 @@ XclExpChRoot::~XclExpChRoot() { } +Reference< XChartDocument > XclExpChRoot::GetChartDocument() const +{ + return mxChData->mxChartDoc; +} + XclExpChChart& XclExpChRoot::GetChartData() const { - return mxChData->GetChartData(); + return mxChData->mrChartData; } const XclChTypeInfo& XclExpChRoot::GetChartTypeInfo( XclChTypeId eType ) const { - return mxChData->GetTypeInfoProvider().GetTypeInfo( eType ); + return mxChData->mxTypeInfoProv->GetTypeInfo( eType ); } const XclChTypeInfo& XclExpChRoot::GetChartTypeInfo( const OUString& rServiceName ) const { - return mxChData->GetTypeInfoProvider().GetTypeInfoFromService( rServiceName ); + return mxChData->mxTypeInfoProv->GetTypeInfoFromService( rServiceName ); } const XclChFormatInfo& XclExpChRoot::GetFormatInfo( XclChObjectType eObjType ) const { - return mxChData->GetFormatInfoProvider().GetFormatInfo( eObjType ); + return mxChData->mxFmtInfoProv->GetFormatInfo( eObjType ); } -void XclExpChRoot::InitConversion( XChartDocRef xChartDoc ) const +void XclExpChRoot::InitConversion( XChartDocRef xChartDoc, const Rectangle& rChartRect ) const { - mxChData->InitConversion( xChartDoc ); + mxChData->InitConversion( GetRoot(), xChartDoc, rChartRect ); } void XclExpChRoot::FinishConversion() const @@ -291,11 +300,41 @@ void XclExpChRoot::SetSystemColor( Color& rColor, sal_uInt32& rnColorId, sal_uIn rnColorId = XclExpPalette::GetColorIdFromIndex( nSysColorIdx ); } +sal_Int32 XclExpChRoot::CalcChartXFromHmm( sal_Int32 nPosX ) const +{ + return ::limit_cast< sal_Int32, double >( (nPosX - mxChData->mnBorderGapX) / mxChData->mfUnitSizeX, 0, EXC_CHART_TOTALUNITS ); +} + +sal_Int32 XclExpChRoot::CalcChartYFromHmm( sal_Int32 nPosY ) const +{ + return ::limit_cast< sal_Int32, double >( (nPosY - mxChData->mnBorderGapY) / mxChData->mfUnitSizeY, 0, EXC_CHART_TOTALUNITS ); +} + +XclChRectangle XclExpChRoot::CalcChartRectFromHmm( const ::com::sun::star::awt::Rectangle& rRect ) const +{ + XclChRectangle aRect; + aRect.mnX = CalcChartXFromHmm( rRect.X ); + aRect.mnY = CalcChartYFromHmm( rRect.Y ); + aRect.mnWidth = CalcChartXFromHmm( rRect.Width ); + aRect.mnHeight = CalcChartYFromHmm( rRect.Height ); + return aRect; +} + +sal_Int32 XclExpChRoot::CalcChartXFromRelative( double fPosX ) const +{ + return CalcChartXFromHmm( static_cast< sal_Int32 >( fPosX * mxChData->maChartRect.GetWidth() + 0.5 ) ); +} + +sal_Int32 XclExpChRoot::CalcChartYFromRelative( double fPosY ) const +{ + return CalcChartYFromHmm( static_cast< sal_Int32 >( fPosY * mxChData->maChartRect.GetHeight() + 0.5 ) ); +} + void XclExpChRoot::ConvertLineFormat( XclChLineFormat& rLineFmt, const ScfPropertySet& rPropSet, XclChPropertyMode ePropMode ) const { GetChartPropSetHelper().ReadLineProperties( - rLineFmt, mxChData->GetLineDashTable(), rPropSet, ePropMode ); + rLineFmt, *mxChData->mxLineDashTable, rPropSet, ePropMode ); } bool XclExpChRoot::ConvertAreaFormat( XclChAreaFormat& rAreaFmt, @@ -309,7 +348,7 @@ void XclExpChRoot::ConvertEscherFormat( const ScfPropertySet& rPropSet, XclChPropertyMode ePropMode ) const { GetChartPropSetHelper().ReadEscherProperties( rEscherFmt, rPicFmt, - mxChData->GetGradientTable(), mxChData->GetHatchTable(), mxChData->GetBitmapTable(), rPropSet, ePropMode ); + *mxChData->mxGradientTable, *mxChData->mxHatchTable, *mxChData->mxBitmapTable, rPropSet, ePropMode ); } sal_uInt16 XclExpChRoot::ConvertFont( const ScfPropertySet& rPropSet, sal_Int16 nScript ) const @@ -404,6 +443,20 @@ void XclExpChFutureRecordBase::Save( XclExpStream& rStrm ) // Frame formatting =========================================================== +XclExpChFramePos::XclExpChFramePos( sal_uInt16 nTLMode, sal_uInt16 nBRMode ) : + XclExpRecord( EXC_ID_CHFRAMEPOS, 20 ) +{ + maData.mnTLMode = nTLMode; + maData.mnBRMode = nBRMode; +} + +void XclExpChFramePos::WriteBody( XclExpStream& rStrm ) +{ + rStrm << maData.mnTLMode << maData.mnBRMode << maData.maRect; +} + +// ---------------------------------------------------------------------------- + XclExpChLineFormat::XclExpChLineFormat( const XclExpChRoot& rRoot ) : XclExpRecord( EXC_ID_CHLINEFORMAT, (rRoot.GetBiff() == EXC_BIFF8) ? 12 : 10 ), mnColorId( XclExpPalette::GetColorIdFromIndex( EXC_COLOR_CHWINDOWTEXT ) ) @@ -1118,6 +1171,36 @@ void XclExpChText::ConvertTitle( Reference< XTitle > xTitle, sal_uInt16 nTarget // rotation ConvertRotationBase( GetChRoot(), aTitleProp, true ); + + // manual text position - only for main title + mxFramePos.reset( new XclExpChFramePos( EXC_CHFRAMEPOS_PARENT, EXC_CHFRAMEPOS_PARENT ) ); + if( nTarget == EXC_CHOBJLINK_TITLE ) + { + Any aRelPos; + if( aTitleProp.GetAnyProperty( aRelPos, EXC_CHPROP_RELATIVEPOSITION ) && aRelPos.has< RelativePosition >() ) try + { + // calculate absolute position for CHTEXT record + Reference< cssc::XChartDocument > xChart1Doc( GetChartDocument(), UNO_QUERY_THROW ); + Reference< XShape > xTitleShape( xChart1Doc->getTitle(), UNO_SET_THROW ); + ::com::sun::star::awt::Point aPos = xTitleShape->getPosition(); + ::com::sun::star::awt::Size aSize = xTitleShape->getSize(); + ::com::sun::star::awt::Rectangle aRect( aPos.X, aPos.Y, aSize.Width, aSize.Height ); + maData.maRect = CalcChartRectFromHmm( aRect ); + ::insert_value( maData.mnFlags2, EXC_CHTEXT_POS_MOVED, 0, 4 ); + // manual title position implies manual plot area + GetChartData().SetManualPlotArea(); + // calculate the default title position in chart units + sal_Int32 nDefPosX = ::std::max< sal_Int32 >( (EXC_CHART_TOTALUNITS - maData.maRect.mnWidth) / 2, 0 ); + sal_Int32 nDefPosY = 85; + // set the position relative to the standard position + XclChRectangle& rFrameRect = mxFramePos->GetFramePosData().maRect; + rFrameRect.mnX = maData.maRect.mnX - nDefPosX; + rFrameRect.mnY = maData.maRect.mnY - nDefPosY; + } + catch( Exception& ) + { + } + } } else { @@ -1137,8 +1220,7 @@ bool XclExpChText::ConvertDataLabel( const ScfPropertySet& rPropSet, { SetFutureRecordContext( EXC_CHFRBLOCK_TEXT_DATALABEL, rPointPos.mnPointIdx, rPointPos.mnSeriesIdx ); - namespace cssc = ::com::sun::star::chart2; - cssc::DataPointLabel aPointLabel; + cssc2::DataPointLabel aPointLabel; if( !rPropSet.GetProperty( aPointLabel, EXC_CHPROP_LABEL ) ) return false; @@ -1184,31 +1266,33 @@ bool XclExpChText::ConvertDataLabel( const ScfPropertySet& rPropSet, ConvertRotationBase( GetChRoot(), rPropSet, false ); // label placement sal_Int32 nPlacement = 0; + sal_uInt16 nLabelPos = EXC_CHTEXT_POS_AUTO; if( rPropSet.GetProperty( nPlacement, EXC_CHPROP_LABELPLACEMENT ) ) { using namespace ::com::sun::star::chart::DataLabelPlacement; if( nPlacement == rTypeInfo.mnDefaultLabelPos ) { - maData.mnPlacement = EXC_CHTEXT_POS_DEFAULT; + nLabelPos = EXC_CHTEXT_POS_DEFAULT; } else switch( nPlacement ) { - case AVOID_OVERLAP: maData.mnPlacement = EXC_CHTEXT_POS_AUTO; break; - case CENTER: maData.mnPlacement = EXC_CHTEXT_POS_CENTER; break; - case TOP: maData.mnPlacement = EXC_CHTEXT_POS_ABOVE; break; - case TOP_LEFT: maData.mnPlacement = EXC_CHTEXT_POS_LEFT; break; - case LEFT: maData.mnPlacement = EXC_CHTEXT_POS_LEFT; break; - case BOTTOM_LEFT: maData.mnPlacement = EXC_CHTEXT_POS_LEFT; break; - case BOTTOM: maData.mnPlacement = EXC_CHTEXT_POS_BELOW; break; - case BOTTOM_RIGHT: maData.mnPlacement = EXC_CHTEXT_POS_RIGHT; break; - case RIGHT: maData.mnPlacement = EXC_CHTEXT_POS_RIGHT; break; - case TOP_RIGHT: maData.mnPlacement = EXC_CHTEXT_POS_RIGHT; break; - case INSIDE: maData.mnPlacement = EXC_CHTEXT_POS_INSIDE; break; - case OUTSIDE: maData.mnPlacement = EXC_CHTEXT_POS_OUTSIDE; break; - case NEAR_ORIGIN: maData.mnPlacement = EXC_CHTEXT_POS_AXIS; break; + case AVOID_OVERLAP: nLabelPos = EXC_CHTEXT_POS_AUTO; break; + case CENTER: nLabelPos = EXC_CHTEXT_POS_CENTER; break; + case TOP: nLabelPos = EXC_CHTEXT_POS_ABOVE; break; + case TOP_LEFT: nLabelPos = EXC_CHTEXT_POS_LEFT; break; + case LEFT: nLabelPos = EXC_CHTEXT_POS_LEFT; break; + case BOTTOM_LEFT: nLabelPos = EXC_CHTEXT_POS_LEFT; break; + case BOTTOM: nLabelPos = EXC_CHTEXT_POS_BELOW; break; + case BOTTOM_RIGHT: nLabelPos = EXC_CHTEXT_POS_RIGHT; break; + case RIGHT: nLabelPos = EXC_CHTEXT_POS_RIGHT; break; + case TOP_RIGHT: nLabelPos = EXC_CHTEXT_POS_RIGHT; break; + case INSIDE: nLabelPos = EXC_CHTEXT_POS_INSIDE; break; + case OUTSIDE: nLabelPos = EXC_CHTEXT_POS_OUTSIDE; break; + case NEAR_ORIGIN: nLabelPos = EXC_CHTEXT_POS_AXIS; break; default: DBG_ERRORFILE( "XclExpChText::ConvertDataLabel - unknown label placement type" ); } } + ::insert_value( maData.mnFlags2, nLabelPos, 0, 4 ); // source link (contains number format) mxSrcLink.reset( new XclExpChSourceLink( GetChRoot(), EXC_CHSRCLINK_TITLE ) ); if( bShowValue || bShowPercent ) @@ -1255,6 +1339,8 @@ sal_uInt16 XclExpChText::GetAttLabelFlags() const void XclExpChText::WriteSubRecords( XclExpStream& rStrm ) { + // CHFRAMEPOS record + lclSaveRecord( rStrm, mxFramePos ); // CHFONT record lclSaveRecord( rStrm, mxFont ); // CHSOURCELINK group @@ -1279,7 +1365,7 @@ void XclExpChText::WriteBody( XclExpStream& rStrm ) if( GetBiff() == EXC_BIFF8 ) { rStrm << GetPalette().GetColorIndex( mnTextColorId ) - << maData.mnPlacement + << maData.mnFlags2 << maData.mnRotation; } } @@ -1604,7 +1690,6 @@ bool XclExpChSerErrorBar::Convert( XclExpChSourceLink& rValueLink, sal_uInt16& r bool bOk = rPropSet.GetProperty( nBarStyle, EXC_CHPROP_ERRORBARSTYLE ); if( bOk ) { - namespace cssc = ::com::sun::star::chart; switch( nBarStyle ) { case cssc::ErrorBarStyle::ABSOLUTE: @@ -2148,12 +2233,66 @@ void XclExpChLegend::Convert( const ScfPropertySet& rPropSet ) // text properties mxText.reset( new XclExpChText( GetChRoot() ) ); mxText->ConvertLegend( rPropSet ); - // special legend properties - GetChartPropSetHelper().ReadLegendProperties( maData, rPropSet ); + + // legend position + Any aRelPosAny; + rPropSet.GetAnyProperty( aRelPosAny, EXC_CHPROP_RELATIVEPOSITION ); + if( aRelPosAny.has< RelativePosition >() ) + { + try + { + /* The 'RelativePosition' property is used as indicator of manually + changed legend position, but due to the different anchor modes + used by this property (in the RelativePosition.Anchor member) + it cannot be used to calculate the position easily. For this, + the Chart1 API will be used instead. */ + Reference< ::com::sun::star::chart::XChartDocument > xChart1Doc( GetChartDocument(), UNO_QUERY_THROW ); + Reference< XShape > xChart1Legend( xChart1Doc->getLegend(), UNO_SET_THROW ); + // coordinates in CHLEGEND record written but not used by Excel + mxFramePos.reset( new XclExpChFramePos( EXC_CHFRAMEPOS_CHARTSIZE, EXC_CHFRAMEPOS_PARENT ) ); + XclChFramePos& rFramePos = mxFramePos->GetFramePosData(); + rFramePos.maRect.mnX = maData.maRect.mnX = CalcChartXFromHmm( xChart1Legend->getPosition().X ); + rFramePos.maRect.mnY = maData.maRect.mnY = CalcChartYFromHmm( xChart1Legend->getPosition().Y ); + // manual legend position implies manual plot area + GetChartData().SetManualPlotArea(); + maData.mnDockMode = EXC_CHLEGEND_NOTDOCKED; + } + catch( Exception& ) + { + OSL_ENSURE( false, "XclExpChLegend::Convert - cannot get legend shape" ); + maData.mnDockMode = EXC_CHLEGEND_RIGHT; + } + } + else + { + cssc2::LegendPosition eApiPos = cssc2::LegendPosition_CUSTOM; + rPropSet.GetProperty( eApiPos, EXC_CHPROP_ANCHORPOSITION ); + switch( eApiPos ) + { + case cssc2::LegendPosition_LINE_START: maData.mnDockMode = EXC_CHLEGEND_LEFT; break; + case cssc2::LegendPosition_LINE_END: maData.mnDockMode = EXC_CHLEGEND_RIGHT; break; + case cssc2::LegendPosition_PAGE_START: maData.mnDockMode = EXC_CHLEGEND_TOP; break; + case cssc2::LegendPosition_PAGE_END: maData.mnDockMode = EXC_CHLEGEND_BOTTOM; break; + default: + OSL_ENSURE( false, "XclExpChLegend::Convert - unrecognized legend position" ); + maData.mnDockMode = EXC_CHLEGEND_RIGHT; + } + } + + // legend expansion + cssc2::LegendExpansion eApiExpand = cssc2::LegendExpansion_BALANCED; + rPropSet.GetProperty( eApiExpand, EXC_CHPROP_EXPANSION ); + ::set_flag( maData.mnFlags, EXC_CHLEGEND_STACKED, eApiExpand != cssc2::LegendExpansion_WIDE ); + + // other flags + ::set_flag( maData.mnFlags, EXC_CHLEGEND_AUTOSERIES ); + const sal_uInt16 nAutoFlags = EXC_CHLEGEND_DOCKED | EXC_CHLEGEND_AUTOPOSX | EXC_CHLEGEND_AUTOPOSY; + ::set_flag( maData.mnFlags, nAutoFlags, maData.mnDockMode != EXC_CHLEGEND_NOTDOCKED ); } void XclExpChLegend::WriteSubRecords( XclExpStream& rStrm ) { + lclSaveRecord( rStrm, mxFramePos ); lclSaveRecord( rStrm, mxText ); lclSaveRecord( rStrm, mxFrame ); } @@ -2252,13 +2391,12 @@ void XclExpChTypeGroup::ConvertSeries( { // stacking direction (stacked/percent/deep 3d) from first series ScfPropertySet aSeriesProp( aSeriesVec.front() ); - namespace cssc = ::com::sun::star::chart2; - cssc::StackingDirection eStacking; + cssc2::StackingDirection eStacking; if( !aSeriesProp.GetProperty( eStacking, EXC_CHPROP_STACKINGDIR ) ) - eStacking = cssc::StackingDirection_NO_STACKING; + eStacking = cssc2::StackingDirection_NO_STACKING; // stacked or percent chart - if( maTypeInfo.mbSupportsStacking && (eStacking == cssc::StackingDirection_Y_STACKING) ) + if( maTypeInfo.mbSupportsStacking && (eStacking == cssc2::StackingDirection_Y_STACKING) ) { // percent overrides simple stacking maType.SetStacked( bPercent ); @@ -2275,7 +2413,7 @@ void XclExpChTypeGroup::ConvertSeries( } // deep 3d chart or clustered 3d chart (stacked is not clustered) - if( (eStacking == cssc::StackingDirection_NO_STACKING) && Is3dWallChart() ) + if( (eStacking == cssc2::StackingDirection_NO_STACKING) && Is3dWallChart() ) mxChart3d->SetClustered(); // varied point colors @@ -2396,7 +2534,8 @@ bool XclExpChTypeGroup::CreateStockSeries( Reference< XDataSeries > xDataSeries, void XclExpChTypeGroup::WriteBody( XclExpStream& rStrm ) { - rStrm << maData.maRect << maData.mnFlags << maData.mnGroupIdx; + rStrm.WriteZeroBytes( 16 ); + rStrm << maData.mnFlags << maData.mnGroupIdx; } // Axes ======================================================================= @@ -2421,7 +2560,6 @@ void XclExpChLabelRange::Convert( const ScaleData& rScaleData, bool bMirrorOrien void XclExpChLabelRange::ConvertAxisPosition( const ScfPropertySet& rPropSet ) { - namespace cssc = ::com::sun::star::chart; cssc::ChartAxisPosition eAxisPos = cssc::ChartAxisPosition_VALUE; rPropSet.GetProperty( eAxisPos, EXC_CHPROP_CROSSOVERPOSITION ); double fCrossingPos = 1.0; @@ -2479,13 +2617,11 @@ void XclExpChValueRange::Convert( const ScaleData& rScaleData ) ::set_flag( maData.mnFlags, EXC_CHVALUERANGE_AUTOMINOR, bAutoMinor ); // reverse order - namespace cssc = ::com::sun::star::chart2; - ::set_flag( maData.mnFlags, EXC_CHVALUERANGE_REVERSE, rScaleData.Orientation == cssc::AxisOrientation_REVERSE ); + ::set_flag( maData.mnFlags, EXC_CHVALUERANGE_REVERSE, rScaleData.Orientation == cssc2::AxisOrientation_REVERSE ); } void XclExpChValueRange::ConvertAxisPosition( const ScfPropertySet& rPropSet ) { - namespace cssc = ::com::sun::star::chart; cssc::ChartAxisPosition eAxisPos = cssc::ChartAxisPosition_VALUE; double fCrossingPos = 0.0; if( rPropSet.GetProperty( eAxisPos, EXC_CHPROP_CROSSOVERPOSITION ) && rPropSet.GetProperty( fCrossingPos, EXC_CHPROP_CROSSOVERVALUE ) ) @@ -2569,7 +2705,6 @@ void XclExpChTick::Convert( const ScfPropertySet& rPropSet, const XclChExtTypeIn } else { - namespace cssc = ::com::sun::star::chart; cssc::ChartAxisLabelPosition eApiLabelPos = cssc::ChartAxisLabelPosition_NEAR_AXIS; rPropSet.GetProperty( eApiLabelPos, EXC_CHPROP_LABELPOSITION ); switch( eApiLabelPos ) @@ -2602,9 +2737,9 @@ void XclExpChTick::WriteBody( XclExpStream& rStrm ) rStrm << maData.mnMajor << maData.mnMinor << maData.mnLabelPos - << maData.mnBackMode - << maData.maRect - << maData.maTextColor + << maData.mnBackMode; + rStrm.WriteZeroBytes( 16 ); + rStrm << maData.maTextColor << maData.mnFlags; if( GetBiff() == EXC_BIFF8 ) rStrm << GetPalette().GetColorIndex( mnTextColorId ) << maData.mnRotation; @@ -2758,7 +2893,8 @@ void XclExpChAxis::WriteSubRecords( XclExpStream& rStrm ) void XclExpChAxis::WriteBody( XclExpStream& rStrm ) { - rStrm << maData.mnType << maData.maRect; + rStrm << maData.mnType; + rStrm.WriteZeroBytes( 16 ); } // ---------------------------------------------------------------------------- @@ -2903,6 +3039,28 @@ sal_uInt16 XclExpChAxesSet::Convert( Reference< XDiagram > xDiagram, sal_uInt16 } } + // inner and outer plot area position and size + try + { + Reference< ::com::sun::star::chart::XChartDocument > xChart1Doc( GetChartDocument(), UNO_QUERY_THROW ); + Reference< ::com::sun::star::chart::XDiagramPositioning > xPositioning( xChart1Doc->getDiagram(), UNO_QUERY_THROW ); + // set manual flag in chart data + if( !xPositioning->isAutomaticDiagramPositioning() ) + GetChartData().SetManualPlotArea(); + // the CHAXESSET record contains the inner plot area + maData.maRect = CalcChartRectFromHmm( xPositioning->calculateDiagramPositionExcludingAxes() ); + // the embedded CHFRAMEPOS record contains the outer plot area + mxFramePos.reset( new XclExpChFramePos( EXC_CHFRAMEPOS_PARENT, EXC_CHFRAMEPOS_PARENT ) ); + // for pie charts, always use inner plot area size to exclude the data labels as Excel does + const XclExpChTypeGroup* pFirstTypeGroup = GetFirstTypeGroup().get(); + bool bPieChart = pFirstTypeGroup && (pFirstTypeGroup->GetTypeInfo().meTypeCateg == EXC_CHTYPECATEG_PIE); + mxFramePos->GetFramePosData().maRect = bPieChart ? maData.maRect : + CalcChartRectFromHmm( xPositioning->calculateDiagramPositionIncludingAxes() ); + } + catch( Exception& ) + { + } + // return first unused chart type group index for next axes set return nGroupIdx; } @@ -2915,14 +3073,7 @@ bool XclExpChAxesSet::Is3dChart() const void XclExpChAxesSet::WriteSubRecords( XclExpStream& rStrm ) { - /* Need to set a reasonable size for the plot area, otherwise Excel will - move away embedded shapes while auto-sizing the plot area. This is just - a wild guess, but will be fixed with implementing manual positioning of - chart elements. */ - rStrm.StartRecord( EXC_ID_CHFRAMEPOS, 20 ); - rStrm << sal_uInt16(2) << sal_uInt16(2) << sal_uInt32(66) << sal_uInt32(626) << sal_uInt32(3384) << sal_uInt32(3231); - rStrm.EndRecord(); - + lclSaveRecord( rStrm, mxFramePos ); lclSaveRecord( rStrm, mxXAxis ); lclSaveRecord( rStrm, mxYAxis ); lclSaveRecord( rStrm, mxZAxis ); @@ -2974,10 +3125,10 @@ void XclExpChAxesSet::WriteBody( XclExpStream& rStrm ) // The chart object =========================================================== XclExpChChart::XclExpChChart( const XclExpRoot& rRoot, - Reference< XChartDocument > xChartDoc, const Size& rSize ) : - XclExpChGroupBase( XclExpChRoot( rRoot, this ), EXC_CHFRBLOCK_TYPE_CHART, EXC_ID_CHCHART, 16 ) + Reference< XChartDocument > xChartDoc, const Rectangle& rChartRect ) : + XclExpChGroupBase( XclExpChRoot( rRoot, *this ), EXC_CHFRBLOCK_TYPE_CHART, EXC_ID_CHCHART, 16 ) { - Size aPtSize = OutputDevice::LogicToLogic( rSize, MapMode( MAP_100TH_MM ), MapMode( MAP_POINT ) ); + Size aPtSize = OutputDevice::LogicToLogic( rChartRect.GetSize(), MapMode( MAP_100TH_MM ), MapMode( MAP_POINT ) ); // rectangle is stored in 16.16 fixed-point format maRect.mnX = maRect.mnY = 0; maRect.mnWidth = static_cast< sal_Int32 >( aPtSize.Width() << 16 ); @@ -3001,8 +3152,8 @@ XclExpChChart::XclExpChChart( const XclExpRoot& rRoot, bool bIncludeHidden = aDiagramProp.GetBoolProperty( EXC_CHPROP_INCLUDEHIDDENCELLS ); ::set_flag( maProps.mnFlags, EXC_CHPROPS_SHOWVISIBLEONLY, !bIncludeHidden ); - // initialize API conversion (remembers xChartDoc internally) - InitConversion( xChartDoc ); + // initialize API conversion (remembers xChartDoc and rChartRect internally) + InitConversion( xChartDoc, rChartRect ); // chart frame ScfPropertySet aFrameProp( xChartDoc->getPageBackground() ); @@ -3060,6 +3211,13 @@ void XclExpChChart::SetDataLabel( XclExpChTextRef xText ) maLabels.AppendRecord( xText ); } +void XclExpChChart::SetManualPlotArea() +{ + // this flag does not exist in BIFF5 + if( GetBiff() == EXC_BIFF8 ) + ::set_flag( maProps.mnFlags, EXC_CHPROPS_USEMANPLOTAREA ); +} + void XclExpChChart::WriteSubRecords( XclExpStream& rStrm ) { // background format @@ -3105,7 +3263,7 @@ XclExpChartDrawing::XclExpChartDrawing( const XclExpRoot& rRoot, /* Create a new independent object manager with own DFF stream for the DGCONTAINER, pass global manager as parent for shared usage of global DFF data (picture container etc.). */ - mxObjMgr.reset( new XclExpEmbeddedObjectManager( GetObjectManager(), rChartSize, EXC_CHART_UNIT, EXC_CHART_UNIT ) ); + mxObjMgr.reset( new XclExpEmbeddedObjectManager( GetObjectManager(), rChartSize, EXC_CHART_TOTALUNITS, EXC_CHART_TOTALUNITS ) ); // initialize the drawing object list mxObjMgr->StartSheet(); // process the draw page (convert all shapes) @@ -3128,17 +3286,17 @@ void XclExpChartDrawing::Save( XclExpStream& rStrm ) // ---------------------------------------------------------------------------- -XclExpChart::XclExpChart( const XclExpRoot& rRoot, Reference< XModel > xModel, const Size& rSize ) : +XclExpChart::XclExpChart( const XclExpRoot& rRoot, Reference< XModel > xModel, const Rectangle& rChartRect ) : XclExpSubStream( EXC_BOF_CHART ), XclExpRoot( rRoot ) { AppendNewRecord( new XclExpChartPageSettings( rRoot ) ); AppendNewRecord( new XclExpBoolRecord( EXC_ID_PROTECT, false ) ); - AppendNewRecord( new XclExpChartDrawing( rRoot, xModel, rSize ) ); + AppendNewRecord( new XclExpChartDrawing( rRoot, xModel, rChartRect.GetSize() ) ); AppendNewRecord( new XclExpUInt16Record( EXC_ID_CHUNITS, EXC_CHUNITS_TWIPS ) ); Reference< XChartDocument > xChartDoc( xModel, UNO_QUERY ); - AppendNewRecord( new XclExpChChart( rRoot, xChartDoc, rSize ) ); + AppendNewRecord( new XclExpChChart( rRoot, xChartDoc, rChartRect ) ); } // ============================================================================ diff --git a/sc/source/filter/excel/xeescher.cxx b/sc/source/filter/excel/xeescher.cxx index 2df531a9b932..a4b5864668b4 100644 --- a/sc/source/filter/excel/xeescher.cxx +++ b/sc/source/filter/excel/xeescher.cxx @@ -956,8 +956,8 @@ XclExpChartObj::XclExpChartObj( XclExpObjectManager& rObjMgr, Reference< XShape aShapeProp.GetProperty( xModel, CREATE_OUSTRING( "Model" ) ); ::com::sun::star::awt::Rectangle aBoundRect; aShapeProp.GetProperty( aBoundRect, CREATE_OUSTRING( "BoundRect" ) ); - Size aSize( aBoundRect.Width, aBoundRect.Height ); - mxChart.reset( new XclExpChart( GetRoot(), xModel, aSize ) ); + Rectangle aChartRect( Point( aBoundRect.X, aBoundRect.Y ), Size( aBoundRect.Width, aBoundRect.Height ) ); + mxChart.reset( new XclExpChart( GetRoot(), xModel, aChartRect ) ); } XclExpChartObj::~XclExpChartObj() diff --git a/sc/source/filter/excel/xichart.cxx b/sc/source/filter/excel/xichart.cxx index 6734f90948e4..35ad5b41e0cb 100644 --- a/sc/source/filter/excel/xichart.cxx +++ b/sc/source/filter/excel/xichart.cxx @@ -37,12 +37,14 @@ #include <com/sun/star/drawing/Direction3D.hpp> #include <com/sun/star/drawing/ProjectionMode.hpp> #include <com/sun/star/drawing/ShadeMode.hpp> +#include <com/sun/star/drawing/XShape.hpp> #include <com/sun/star/drawing/XDrawPageSupplier.hpp> #include <com/sun/star/chart/ChartAxisArrangeOrderType.hpp> #include <com/sun/star/chart/ChartAxisLabelPosition.hpp> #include <com/sun/star/chart/ChartAxisMarkPosition.hpp> #include <com/sun/star/chart/ChartAxisPosition.hpp> #include <com/sun/star/chart/XChartDocument.hpp> +#include <com/sun/star/chart/XDiagramPositioning.hpp> #include <com/sun/star/chart2/XChartDocument.hpp> #include <com/sun/star/chart2/XDiagram.hpp> #include <com/sun/star/chart2/XCoordinateSystemContainer.hpp> @@ -57,8 +59,11 @@ #include <com/sun/star/chart2/CurveStyle.hpp> #include <com/sun/star/chart2/DataPointGeometry3D.hpp> #include <com/sun/star/chart2/DataPointLabel.hpp> +#include <com/sun/star/chart2/LegendExpansion.hpp> +#include <com/sun/star/chart2/LegendPosition.hpp> #include <com/sun/star/chart2/StackingDirection.hpp> #include <com/sun/star/chart2/TickmarkStyle.hpp> +#include <com/sun/star/chart2/RelativePosition.hpp> #include <com/sun/star/chart/DataLabelPlacement.hpp> #include <com/sun/star/chart/ErrorBarStyle.hpp> #include <com/sun/star/chart/MissingValueTreatment.hpp> @@ -98,36 +103,41 @@ using ::com::sun::star::frame::XModel; using ::com::sun::star::util::XNumberFormatsSupplier; using ::com::sun::star::drawing::XDrawPage; using ::com::sun::star::drawing::XDrawPageSupplier; +using ::com::sun::star::drawing::XShape; +using ::com::sun::star::chart2::IncrementData; +using ::com::sun::star::chart2::RelativePosition; +using ::com::sun::star::chart2::ScaleData; +using ::com::sun::star::chart2::SubIncrement; +using ::com::sun::star::chart2::XAxis; using ::com::sun::star::chart2::XChartDocument; -using ::com::sun::star::chart2::XDiagram; -using ::com::sun::star::chart2::XCoordinateSystemContainer; -using ::com::sun::star::chart2::XCoordinateSystem; -using ::com::sun::star::chart2::XChartTypeContainer; using ::com::sun::star::chart2::XChartType; -using ::com::sun::star::chart2::XDataSeriesContainer; +using ::com::sun::star::chart2::XChartTypeContainer; +using ::com::sun::star::chart2::XCoordinateSystem; +using ::com::sun::star::chart2::XCoordinateSystemContainer; using ::com::sun::star::chart2::XDataSeries; +using ::com::sun::star::chart2::XDataSeriesContainer; +using ::com::sun::star::chart2::XDiagram; +using ::com::sun::star::chart2::XFormattedString; +using ::com::sun::star::chart2::XLegend; using ::com::sun::star::chart2::XRegressionCurve; using ::com::sun::star::chart2::XRegressionCurveContainer; -using ::com::sun::star::chart2::XAxis; using ::com::sun::star::chart2::XScaling; -using ::com::sun::star::chart2::ScaleData; -using ::com::sun::star::chart2::IncrementData; -using ::com::sun::star::chart2::SubIncrement; -using ::com::sun::star::chart2::XLegend; -using ::com::sun::star::chart2::XTitled; using ::com::sun::star::chart2::XTitle; -using ::com::sun::star::chart2::XFormattedString; +using ::com::sun::star::chart2::XTitled; using ::com::sun::star::chart2::data::XDataProvider; using ::com::sun::star::chart2::data::XDataReceiver; +using ::com::sun::star::chart2::data::XDataSequence; using ::com::sun::star::chart2::data::XDataSink; using ::com::sun::star::chart2::data::XLabeledDataSequence; -using ::com::sun::star::chart2::data::XDataSequence; using ::formula::FormulaToken; using ::formula::StackVar; +namespace cssc = ::com::sun::star::chart; +namespace cssc2 = ::com::sun::star::chart2; + // Helpers ==================================================================== namespace { @@ -158,28 +168,18 @@ void lclSetExpValueOrClearAny( Any& rAny, double fValue, bool bLogScale, bool bC // Common ===================================================================== /** Stores global data needed in various classes of the Chart import filter. */ -class XclImpChRootData : public XclChRootData +struct XclImpChRootData : public XclChRootData { -public: - explicit XclImpChRootData( XclImpChChart* pChartData ); + XclImpChChart& mrChartData; /// The chart data object. - /** Returns a reference to the parent chart data object. */ - inline XclImpChChart& GetChartData() const { return *mpChartData; } - -private: - XclImpChChart* mpChartData; /// Pointer to the chart data object. + inline explicit XclImpChRootData( XclImpChChart& rChartData ) : mrChartData( rChartData ) {} }; -XclImpChRootData::XclImpChRootData( XclImpChChart* pChartData ) : - mpChartData( pChartData ) -{ -} - // ---------------------------------------------------------------------------- -XclImpChRoot::XclImpChRoot( const XclImpRoot& rRoot, XclImpChChart* pChartData ) : +XclImpChRoot::XclImpChRoot( const XclImpRoot& rRoot, XclImpChChart& rChartData ) : XclImpRoot( rRoot ), - mxChData( new XclImpChRootData( pChartData ) ) + mxChData( new XclImpChRootData( rChartData ) ) { } @@ -189,22 +189,22 @@ XclImpChRoot::~XclImpChRoot() XclImpChChart& XclImpChRoot::GetChartData() const { - return mxChData->GetChartData(); + return mxChData->mrChartData; } const XclChTypeInfo& XclImpChRoot::GetChartTypeInfo( XclChTypeId eType ) const { - return mxChData->GetTypeInfoProvider().GetTypeInfo( eType ); + return mxChData->mxTypeInfoProv->GetTypeInfo( eType ); } const XclChTypeInfo& XclImpChRoot::GetChartTypeInfo( sal_uInt16 nRecId ) const { - return mxChData->GetTypeInfoProvider().GetTypeInfoFromRecId( nRecId ); + return mxChData->mxTypeInfoProv->GetTypeInfoFromRecId( nRecId ); } const XclChFormatInfo& XclImpChRoot::GetFormatInfo( XclChObjectType eObjType ) const { - return mxChData->GetFormatInfoProvider().GetFormatInfo( eObjType ); + return mxChData->mxFmtInfoProv->GetFormatInfo( eObjType ); } Color XclImpChRoot::GetFontAutoColor() const @@ -225,10 +225,10 @@ Color XclImpChRoot::GetSeriesFillAutoColor( sal_uInt16 nFormatIdx ) const return ScfTools::GetMixedColor( aColor, rPal.GetColor( EXC_COLOR_CHWINDOWBACK ), nTrans ); } -void XclImpChRoot::InitConversion( Reference< XChartDocument > xChartDoc ) const +void XclImpChRoot::InitConversion( Reference< XChartDocument > xChartDoc, const Rectangle& rChartRect ) const { // create formatting object tables - mxChData->InitConversion( xChartDoc ); + mxChData->InitConversion( GetRoot(), xChartDoc, rChartRect ); // lock the model to suppress any internal updates Reference< XModel > xModel( xChartDoc, UNO_QUERY ); @@ -255,7 +255,7 @@ void XclImpChRoot::FinishConversion( XclImpDffConverter& rDffConv ) const { rDffConv.Progress( EXC_CHART_PROGRESS_SIZE ); // unlock the model - Reference< XModel > xModel( mxChData->GetChartDoc(), UNO_QUERY ); + Reference< XModel > xModel( mxChData->mxChartDoc, UNO_QUERY ); if( xModel.is() ) xModel->unlockControllers(); rDffConv.Progress( EXC_CHART_PROGRESS_SIZE ); @@ -265,14 +265,48 @@ void XclImpChRoot::FinishConversion( XclImpDffConverter& rDffConv ) const Reference< XDataProvider > XclImpChRoot::GetDataProvider() const { - return mxChData->GetChartDoc()->getDataProvider(); + return mxChData->mxChartDoc->getDataProvider(); +} + +Reference< XShape > XclImpChRoot::GetTitleShape( const XclChTextKey& rTitleKey ) const +{ + return mxChData->GetTitleShape( rTitleKey ); +} + +sal_Int32 XclImpChRoot::CalcHmmFromChartX( sal_Int32 nPosX ) const +{ + return static_cast< sal_Int32 >( mxChData->mfUnitSizeX * nPosX + mxChData->mnBorderGapX + 0.5 ); +} + +sal_Int32 XclImpChRoot::CalcHmmFromChartY( sal_Int32 nPosY ) const +{ + return static_cast< sal_Int32 >( mxChData->mfUnitSizeY * nPosY + mxChData->mnBorderGapY + 0.5 ); +} + +::com::sun::star::awt::Rectangle XclImpChRoot::CalcHmmFromChartRect( const XclChRectangle& rRect ) const +{ + return ::com::sun::star::awt::Rectangle( + CalcHmmFromChartX( rRect.mnX ), + CalcHmmFromChartY( rRect.mnY ), + CalcHmmFromChartX( rRect.mnWidth ), + CalcHmmFromChartY( rRect.mnHeight ) ); +} + +double XclImpChRoot::CalcRelativeFromChartX( sal_Int32 nPosX ) const +{ + return static_cast< double >( CalcHmmFromChartX( nPosX ) ) / mxChData->maChartRect.GetWidth(); +} + +double XclImpChRoot::CalcRelativeFromChartY( sal_Int32 nPosY ) const +{ + return static_cast< double >( CalcHmmFromChartY( nPosY ) ) / mxChData->maChartRect.GetHeight(); } void XclImpChRoot::ConvertLineFormat( ScfPropertySet& rPropSet, const XclChLineFormat& rLineFmt, XclChPropertyMode ePropMode ) const { GetChartPropSetHelper().WriteLineProperties( - rPropSet, mxChData->GetLineDashTable(), rLineFmt, ePropMode ); + rPropSet, *mxChData->mxLineDashTable, rLineFmt, ePropMode ); } void XclImpChRoot::ConvertAreaFormat( ScfPropertySet& rPropSet, @@ -286,7 +320,7 @@ void XclImpChRoot::ConvertEscherFormat( ScfPropertySet& rPropSet, XclChPropertyMode ePropMode ) const { GetChartPropSetHelper().WriteEscherProperties( rPropSet, - mxChData->GetGradientTable(), mxChData->GetHatchTable(), mxChData->GetBitmapTable(), + *mxChData->mxGradientTable, *mxChData->mxHatchTable, *mxChData->mxBitmapTable, rEscherFmt, rPicFmt, ePropMode ); } @@ -357,7 +391,13 @@ void XclImpChGroupBase::SkipBlock( XclImpStream& rStrm ) void XclImpChFramePos::ReadChFramePos( XclImpStream& rStrm ) { - rStrm >> maData.mnObjType >> maData.mnSizeMode >> maData.maRect; + rStrm >> maData.mnTLMode >> maData.mnBRMode; + /* According to the spec, the upper 16 bits of all members in the + rectangle are unused and may contain garbage. */ + maData.maRect.mnX = rStrm.ReadInt16(); rStrm.Ignore( 2 ); + maData.maRect.mnY = rStrm.ReadInt16(); rStrm.Ignore( 2 ); + maData.maRect.mnWidth = rStrm.ReadInt16(); rStrm.Ignore( 2 ); + maData.maRect.mnHeight = rStrm.ReadInt16(); rStrm.Ignore( 2 ); } // ---------------------------------------------------------------------------- @@ -862,9 +902,7 @@ void XclImpChText::ReadHeaderRecord( XclImpStream& rStrm ) // #116397# BIFF8: index into palette used instead of RGB data maData.maTextColor = GetPalette().GetColor( rStrm.ReaduInt16() ); // placement and rotation - rStrm >> maData.mnPlacement >> maData.mnRotation; - // lower 4 bits used for placement, other bits contain garbage - maData.mnPlacement &= 0x000F; + rStrm >> maData.mnFlags2 >> maData.mnRotation; } else { @@ -878,6 +916,10 @@ void XclImpChText::ReadSubRecord( XclImpStream& rStrm ) { switch( rStrm.GetRecId() ) { + case EXC_ID_CHFRAMEPOS: + mxFramePos.reset( new XclImpChFramePos ); + mxFramePos->ReadChFramePos( rStrm ); + break; case EXC_ID_CHFONT: mxFont.reset( new XclImpChFont ); mxFont->ReadChFont( rStrm ); @@ -1002,8 +1044,7 @@ void XclImpChText::ConvertDataLabel( ScfPropertySet& rPropSet, const XclChTypeIn bool bShowSymbol = bShowAny && ::get_flag( maData.mnFlags, EXC_CHTEXT_SHOWSYMBOL ); // create API struct for label values, set API label separator - namespace cssc = ::com::sun::star::chart2; - cssc::DataPointLabel aPointLabel( bShowValue, bShowPercent, bShowCateg, bShowSymbol ); + cssc2::DataPointLabel aPointLabel( bShowValue, bShowPercent, bShowCateg, bShowSymbol ); rPropSet.SetProperty( EXC_CHPROP_LABEL, aPointLabel ); String aSep = mxLabelProps.is() ? mxLabelProps->maSeparator : String( sal_Unicode( '\n' ) ); if( aSep.Len() == 0 ) @@ -1016,9 +1057,9 @@ void XclImpChText::ConvertDataLabel( ScfPropertySet& rPropSet, const XclChTypeIn ConvertFont( rPropSet ); ConvertRotation( rPropSet, false ); // label placement - using namespace ::com::sun::star::chart::DataLabelPlacement; + using namespace cssc::DataLabelPlacement; sal_Int32 nPlacement = rTypeInfo.mnDefaultLabelPos; - switch( maData.mnPlacement ) + switch( ::extract_value< sal_uInt16 >( maData.mnFlags2, 0, 4 ) ) { case EXC_CHTEXT_POS_DEFAULT: nPlacement = rTypeInfo.mnDefaultLabelPos; break; case EXC_CHTEXT_POS_OUTSIDE: nPlacement = OUTSIDE; break; @@ -1064,6 +1105,62 @@ Reference< XTitle > XclImpChText::CreateTitle() const return xTitle; } +void XclImpChText::ConvertTitlePosition( const XclChTextKey& rTitleKey ) const +{ + if( !mxFramePos ) return; + + const XclChFramePos& rPosData = mxFramePos->GetFramePosData(); + OSL_ENSURE( (rPosData.mnTLMode == EXC_CHFRAMEPOS_PARENT) && (rPosData.mnBRMode == EXC_CHFRAMEPOS_PARENT), + "XclImpChText::ConvertTitlePosition - unexpected frame position mode" ); + + /* Check if title is moved manually. To get the actual position of the + title, we do some kind of hack and use the values from the CHTEXT + record, effectively ignoring the contents of the CHFRAMEPOS record + which contains the position relative to the default title position + (according to the spec, the CHFRAMEPOS supersedes the CHTEXT record). + Especially when it comes to axis titles, things would become very + complicated here, because the relative title position is stored in a + measurement unit that is dependent on the size of the inner plot area, + the interpretation of the X and Y coordinate is dependent on the + direction of the axis, and in 3D charts, and the title default + positions are dependent on the 3D view settings (rotation, elevation, + and perspective). Thus, it is easier to assume that the creator has + written out the correct absolute position and size of the title in the + CHTEXT record. This is assured by checking that the shape size stored + in the CHTEXT record is non-zero. */ + if( (rPosData.mnTLMode == EXC_CHFRAMEPOS_PARENT) && + ((rPosData.maRect.mnX != 0) || (rPosData.maRect.mnY != 0)) && + (maData.maRect.mnWidth > 0) && (maData.maRect.mnHeight > 0) ) try + { + Reference< XShape > xTitleShape( GetTitleShape( rTitleKey ), UNO_SET_THROW ); + // the call to XShape.getSize() may recalc the chart view + ::com::sun::star::awt::Size aTitleSize = xTitleShape->getSize(); + // rotated titles need special handling... + sal_Int32 nScRot = XclTools::GetScRotation( GetRotation(), 0 ); + double fRad = nScRot * F_PI18000; + double fSin = fabs( sin( fRad ) ); + double fCos = fabs( cos( fRad ) ); + ::com::sun::star::awt::Size aBoundSize( + static_cast< sal_Int32 >( fCos * aTitleSize.Width + fSin * aTitleSize.Height + 0.5 ), + static_cast< sal_Int32 >( fSin * aTitleSize.Width + fCos * aTitleSize.Height + 0.5 ) ); + // calculate the title position from the values in the CHTEXT record + ::com::sun::star::awt::Point aTitlePos( + CalcHmmFromChartX( maData.maRect.mnX ), + CalcHmmFromChartY( maData.maRect.mnY ) ); + // add part of height to X direction, if title is rotated down (clockwise) + if( nScRot > 18000 ) + aTitlePos.X += static_cast< sal_Int32 >( fSin * aTitleSize.Height + 0.5 ); + // add part of width to Y direction, if title is rotated up (counterclockwise) + else if( nScRot > 0 ) + aTitlePos.Y += static_cast< sal_Int32 >( fSin * aTitleSize.Width + 0.5 ); + // set the resulting position at the title shape + xTitleShape->setPosition( aTitlePos ); + } + catch( Exception& ) + { + } +} + void XclImpChText::ReadChFrLabelProps( XclImpStream& rStrm ) { if( GetBiff() == EXC_BIFF8 ) @@ -1087,12 +1184,14 @@ void lclUpdateText( XclImpChTextRef& rxText, XclImpChTextRef xDefText ) rxText = xDefText; } -void lclFinalizeTitle( XclImpChTextRef& rxTitle, XclImpChTextRef xDefText ) +void lclFinalizeTitle( XclImpChTextRef& rxTitle, XclImpChTextRef xDefText, const String& rAutoTitle ) { /* Do not update a title, if it is not visible (if rxTitle is null). Existing reference indicates enabled title. */ if( rxTitle.is() ) { + if( !rxTitle->HasString() ) + rxTitle->SetString( rAutoTitle ); if( rxTitle->HasString() ) rxTitle->UpdateText( xDefText.get() ); else @@ -1544,7 +1643,6 @@ Reference< XPropertySet > XclImpChSerErrorBar::CreateErrorBar( const XclImpChSer aBarProp.SetBoolProperty( EXC_CHPROP_SHOWNEGATIVEERROR, pNegBar != 0 ); // type of displayed error - namespace cssc = ::com::sun::star::chart; switch( pPrimaryBar->maData.mnSourceType ) { case EXC_CHSERERR_PERCENT: @@ -2281,6 +2379,10 @@ void XclImpChLegend::ReadSubRecord( XclImpStream& rStrm ) { switch( rStrm.GetRecId() ) { + case EXC_ID_CHFRAMEPOS: + mxFramePos.reset( new XclImpChFramePos ); + mxFramePos->ReadChFramePos( rStrm ); + break; case EXC_ID_CHTEXT: mxText.reset( new XclImpChText( GetChRoot() ) ); mxText->ReadRecordGroup( rStrm ); @@ -2307,6 +2409,7 @@ Reference< XLegend > XclImpChLegend::CreateLegend() const if( xLegend.is() ) { ScfPropertySet aLegendProp( xLegend ); + aLegendProp.SetBoolProperty( EXC_CHPROP_SHOW, true ); // frame properties if( mxFrame.is() ) @@ -2314,8 +2417,69 @@ Reference< XLegend > XclImpChLegend::CreateLegend() const // text properties if( mxText.is() ) mxText->ConvertFont( aLegendProp ); - // special legend properties - GetChartPropSetHelper().WriteLegendProperties( aLegendProp, maData ); + + /* Legend position and size. Default positions are used only if the + plot area is positioned automatically (Excel sets the plot area to + manual mode, if the legend is moved or resized). With manual plot + areas, Excel ignores the value in maData.mnDockMode completely. */ + cssc2::LegendPosition eApiPos = cssc2::LegendPosition_CUSTOM; + cssc2::LegendExpansion eApiExpand = cssc2::LegendExpansion_BALANCED; + if( !GetChartData().IsManualPlotArea() ) switch( maData.mnDockMode ) + { + case EXC_CHLEGEND_LEFT: eApiPos = cssc2::LegendPosition_LINE_START; eApiExpand = cssc2::LegendExpansion_HIGH; break; + case EXC_CHLEGEND_RIGHT: eApiPos = cssc2::LegendPosition_LINE_END; eApiExpand = cssc2::LegendExpansion_HIGH; break; + case EXC_CHLEGEND_TOP: eApiPos = cssc2::LegendPosition_PAGE_START; eApiExpand = cssc2::LegendExpansion_WIDE; break; + case EXC_CHLEGEND_BOTTOM: eApiPos = cssc2::LegendPosition_PAGE_END; eApiExpand = cssc2::LegendExpansion_WIDE; break; + // top-right not supported + case EXC_CHLEGEND_CORNER: eApiPos = cssc2::LegendPosition_LINE_END; eApiExpand = cssc2::LegendExpansion_HIGH; break; + } + + // no automatic position: try to find the correct position and size + if( eApiPos == cssc2::LegendPosition_CUSTOM ) + { + const XclChFramePos* pFramePos = mxFramePos.is() ? &mxFramePos->GetFramePosData() : 0; + + /* Legend position. Only the settings from the CHFRAMEPOS record + are used by Excel, the position in the CHLEGEND record will be + ignored. */ + if( pFramePos ) + { + RelativePosition aRelPos; + aRelPos.Primary = CalcRelativeFromChartX( pFramePos->maRect.mnX ); + aRelPos.Secondary = CalcRelativeFromChartY( pFramePos->maRect.mnY ); + aRelPos.Anchor = ::com::sun::star::drawing::Alignment_TOP_LEFT; + aLegendProp.SetProperty( EXC_CHPROP_RELATIVEPOSITION, aRelPos ); + } + else + { + // no manual position found, just go for the default + eApiPos = cssc2::LegendPosition_LINE_END; + } + + + /* Legend size. #i71697# It is not possible to set the legend size + directly in the Chart, do some magic here. */ + if( !pFramePos || (pFramePos->mnBRMode != EXC_CHFRAMEPOS_ABSSIZE_POINTS) || + (pFramePos->maRect.mnWidth == 0) || (pFramePos->maRect.mnHeight == 0) ) + { + // automatic size: determine entry direction from flags + eApiExpand = ::get_flagvalue( maData.mnFlags, EXC_CHLEGEND_STACKED, + cssc2::LegendExpansion_HIGH, cssc2::LegendExpansion_WIDE ); + } + else + { + // legend size is given in points, not in chart units + double fRatio = static_cast< double >( pFramePos->maRect.mnWidth ) / pFramePos->maRect.mnHeight; + if( fRatio > 1.5 ) + eApiExpand = cssc2::LegendExpansion_WIDE; + else if( fRatio < 0.75 ) + eApiExpand = cssc2::LegendExpansion_HIGH; + else + eApiExpand = cssc2::LegendExpansion_BALANCED; + } + } + aLegendProp.SetProperty( EXC_CHPROP_ANCHORPOSITION, eApiPos ); + aLegendProp.SetProperty( EXC_CHPROP_EXPANSION, eApiExpand ); } return xLegend; } @@ -2358,7 +2522,8 @@ XclImpChTypeGroup::XclImpChTypeGroup( const XclImpChRoot& rRoot ) : void XclImpChTypeGroup::ReadHeaderRecord( XclImpStream& rStrm ) { - rStrm >> maData.maRect >> maData.mnFlags >> maData.mnGroupIdx; + rStrm.Ignore( 16 ); + rStrm >> maData.mnFlags >> maData.mnGroupIdx; } void XclImpChTypeGroup::ReadSubRecord( XclImpStream& rStrm ) @@ -2548,13 +2713,12 @@ void XclImpChTypeGroup::InsertDataSeries( Reference< XChartType > xChartType, if( xSeriesCont.is() && xSeries.is() ) { // series stacking mode - namespace cssc = ::com::sun::star::chart2; - cssc::StackingDirection eStacking = cssc::StackingDirection_NO_STACKING; + cssc2::StackingDirection eStacking = cssc2::StackingDirection_NO_STACKING; // stacked overrides deep-3d if( maType.IsStacked() || maType.IsPercent() ) - eStacking = cssc::StackingDirection_Y_STACKING; + eStacking = cssc2::StackingDirection_Y_STACKING; else if( Is3dDeepChart() ) - eStacking = cssc::StackingDirection_Z_STACKING; + eStacking = cssc2::StackingDirection_Z_STACKING; // additional series properties ScfPropertySet aSeriesProp( xSeries ); @@ -2674,11 +2838,9 @@ void XclImpChLabelRange::Convert( ScfPropertySet& rPropSet, ScaleData& rScaleDat // do not break text into several lines unless all labels are visible rPropSet.SetBoolProperty( EXC_CHPROP_TEXTBREAK, maData.mnLabelFreq == 1 ); // do not stagger labels in two lines - namespace cssc = ::com::sun::star::chart; rPropSet.SetProperty( EXC_CHPROP_ARRANGEORDER, cssc::ChartAxisArrangeOrderType_SIDE_BY_SIDE ); // reverse order - namespace cssc2 = ::com::sun::star::chart2; bool bReverse = ::get_flag( maData.mnFlags, EXC_CHLABELRANGE_REVERSE ) != bMirrorOrient; rScaleData.Orientation = bReverse ? cssc2::AxisOrientation_REVERSE : cssc2::AxisOrientation_MATHEMATICAL; @@ -2692,7 +2854,6 @@ void XclImpChLabelRange::ConvertAxisPosition( ScfPropertySet& rPropSet, bool b3d But: the Y axis has to be moved to "end", if the X axis is mirrored, to keep it at the left end of the chart. */ bool bMaxCross = ::get_flag( maData.mnFlags, b3dChart ? EXC_CHLABELRANGE_REVERSE : EXC_CHLABELRANGE_MAXCROSS ); - namespace cssc = ::com::sun::star::chart; cssc::ChartAxisPosition eAxisPos = bMaxCross ? cssc::ChartAxisPosition_END : cssc::ChartAxisPosition_VALUE; rPropSet.SetProperty( EXC_CHPROP_CROSSOVERPOSITION, eAxisPos ); @@ -2741,7 +2902,8 @@ void XclImpChValueRange::Convert( ScaleData& rScaleData, bool bMirrorOrient ) co Any& rIntervalCount = rSubIncrementSeq[ 0 ].IntervalCount; if( bLogScale ) { - rIntervalCount <<= sal_Int32( 10 ); + if( !bAutoMinor ) + rIntervalCount <<= sal_Int32( 9 ); } else { @@ -2756,7 +2918,6 @@ void XclImpChValueRange::Convert( ScaleData& rScaleData, bool bMirrorOrient ) co } // reverse order - namespace cssc2 = ::com::sun::star::chart2; bool bReverse = ::get_flag( maData.mnFlags, EXC_CHVALUERANGE_REVERSE ) != bMirrorOrient; rScaleData.Orientation = bReverse ? cssc2::AxisOrientation_REVERSE : cssc2::AxisOrientation_MATHEMATICAL; } @@ -2768,7 +2929,6 @@ void XclImpChValueRange::ConvertAxisPosition( ScfPropertySet& rPropSet ) const bool bLogScale = ::get_flag( maData.mnFlags, EXC_CHVALUERANGE_LOGSCALE ); // crossing mode (max-cross flag overrides other crossing settings) - namespace cssc = ::com::sun::star::chart; cssc::ChartAxisPosition eAxisPos = bMaxCross ? cssc::ChartAxisPosition_END : cssc::ChartAxisPosition_VALUE; rPropSet.SetProperty( EXC_CHPROP_CROSSOVERPOSITION, eAxisPos ); @@ -2791,7 +2951,7 @@ sal_Int32 lclGetApiTickmarks( sal_uInt8 nXclTickPos ) return nApiTickmarks; } -::com::sun::star::chart::ChartAxisLabelPosition lclGetApiLabelPosition( sal_Int8 nXclLabelPos ) +cssc::ChartAxisLabelPosition lclGetApiLabelPosition( sal_Int8 nXclLabelPos ) { using namespace ::com::sun::star::chart; switch( nXclLabelPos ) @@ -2815,9 +2975,9 @@ void XclImpChTick::ReadChTick( XclImpStream& rStrm ) rStrm >> maData.mnMajor >> maData.mnMinor >> maData.mnLabelPos - >> maData.mnBackMode - >> maData.maRect - >> maData.maTextColor + >> maData.mnBackMode; + rStrm.Ignore( 16 ); + rStrm >> maData.maTextColor >> maData.mnFlags; if( GetBiff() == EXC_BIFF8 ) @@ -2850,7 +3010,7 @@ void XclImpChTick::Convert( ScfPropertySet& rPropSet ) const rPropSet.SetProperty( EXC_CHPROP_MAJORTICKS, lclGetApiTickmarks( maData.mnMajor ) ); rPropSet.SetProperty( EXC_CHPROP_MINORTICKS, lclGetApiTickmarks( maData.mnMinor ) ); rPropSet.SetProperty( EXC_CHPROP_LABELPOSITION, lclGetApiLabelPosition( maData.mnLabelPos ) ); - rPropSet.SetProperty( EXC_CHPROP_MARKPOSITION, ::com::sun::star::chart::ChartAxisMarkPosition_AT_AXIS ); + rPropSet.SetProperty( EXC_CHPROP_MARKPOSITION, cssc::ChartAxisMarkPosition_AT_AXIS ); } // ---------------------------------------------------------------------------- @@ -2864,7 +3024,7 @@ XclImpChAxis::XclImpChAxis( const XclImpChRoot& rRoot, sal_uInt16 nAxisType ) : void XclImpChAxis::ReadHeaderRecord( XclImpStream& rStrm ) { - rStrm >> maData.mnType >> maData.maRect; + rStrm >> maData.mnType; } void XclImpChAxis::ReadSubRecord( XclImpStream& rStrm ) @@ -2941,8 +3101,6 @@ sal_uInt16 XclImpChAxis::GetRotation() const Reference< XAxis > XclImpChAxis::CreateAxis( const XclImpChTypeGroup& rTypeGroup, const XclImpChAxis* pCrossingAxis ) const { - namespace cssc2 = ::com::sun::star::chart2; - // create the axis object (always) Reference< XAxis > xAxis( ScfApiHelper::CreateInstance( SERVICE_CHART2_AXIS ), UNO_QUERY ); if( xAxis.is() ) @@ -3136,8 +3294,8 @@ void XclImpChAxesSet::ReadSubRecord( XclImpStream& rStrm ) switch( rStrm.GetRecId() ) { case EXC_ID_CHFRAMEPOS: - mxPos.reset( new XclImpChFramePos ); - mxPos->ReadChFramePos( rStrm ); + mxFramePos.reset( new XclImpChFramePos ); + mxFramePos->ReadChFramePos( rStrm ); break; case EXC_ID_CHAXIS: ReadChAxis( rStrm ); @@ -3188,9 +3346,10 @@ void XclImpChAxesSet::Finalize() // finalize axis titles XclImpChTextRef xDefText = GetChartData().GetDefaultText( EXC_CHTEXTTYPE_AXISTITLE ); - lclFinalizeTitle( mxXAxisTitle, xDefText ); - lclFinalizeTitle( mxYAxisTitle, xDefText ); - lclFinalizeTitle( mxZAxisTitle, xDefText ); + String aAutoTitle = CREATE_STRING( "Axis Title" ); + lclFinalizeTitle( mxXAxisTitle, xDefText, aAutoTitle ); + lclFinalizeTitle( mxYAxisTitle, xDefText, aAutoTitle ); + lclFinalizeTitle( mxZAxisTitle, xDefText, aAutoTitle ); // #i47745# missing plot frame -> invisible border and area if( !mxPlotFrame ) @@ -3252,6 +3411,16 @@ void XclImpChAxesSet::Convert( Reference< XDiagram > xDiagram ) const } } +void XclImpChAxesSet::ConvertTitlePositions() const +{ + if( mxXAxisTitle.is() ) + mxXAxisTitle->ConvertTitlePosition( XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, maData.mnAxesSetId, EXC_CHAXIS_X ) ); + if( mxYAxisTitle.is() ) + mxYAxisTitle->ConvertTitlePosition( XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, maData.mnAxesSetId, EXC_CHAXIS_Y ) ); + if( mxZAxisTitle.is() ) + mxZAxisTitle->ConvertTitlePosition( XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, maData.mnAxesSetId, EXC_CHAXIS_Z ) ); +} + void XclImpChAxesSet::ReadChAxis( XclImpStream& rStrm ) { XclImpChAxisRef xAxis( new XclImpChAxis( GetChRoot() ) ); @@ -3358,11 +3527,15 @@ void XclImpChAxesSet::ConvertAxis( if( xAxis.is() ) { // create and attach the axis title - if( xChAxisTitle.is() ) + if( xChAxisTitle.is() ) try { - Reference< XTitled > xTitled( xAxis, UNO_QUERY ); - if( xTitled.is() ) - xTitled->setTitleObject( xChAxisTitle->CreateTitle() ); + Reference< XTitled > xTitled( xAxis, UNO_QUERY_THROW ); + Reference< XTitle > xTitle( xChAxisTitle->CreateTitle(), UNO_SET_THROW ); + xTitled->setTitleObject( xTitle ); + } + catch( Exception& ) + { + DBG_ERRORFILE( "XclImpChAxesSet::ConvertAxis - cannot set axis title" ); } // insert axis into coordinate system @@ -3416,7 +3589,7 @@ void XclImpChAxesSet::ConvertBackground( Reference< XDiagram > xDiagram ) const // The chart object =========================================================== XclImpChChart::XclImpChChart( const XclImpRoot& rRoot ) : - XclImpChRoot( rRoot, this ) + XclImpChRoot( rRoot, *this ) { mxPrimAxesSet.reset( new XclImpChAxesSet( GetChRoot(), EXC_CHAXESSET_PRIMARY ) ); mxSecnAxesSet.reset( new XclImpChAxesSet( GetChRoot(), EXC_CHAXESSET_SECONDARY ) ); @@ -3516,23 +3689,34 @@ XclImpChTextRef XclImpChChart::GetDefaultText( XclChTextType eTextType ) const return maDefTexts.get( nDefTextId ); } -void XclImpChChart::Convert( Reference< XChartDocument > xChartDoc, XclImpDffConverter& rDffConv, const OUString& rObjName ) const +bool XclImpChChart::IsManualPlotArea() const +{ + // there is no real automatic mode in BIFF5 charts + return (GetBiff() <= EXC_BIFF5) || ::get_flag( maProps.mnFlags, EXC_CHPROPS_USEMANPLOTAREA ); +} + +void XclImpChChart::Convert( Reference< XChartDocument > xChartDoc, + XclImpDffConverter& rDffConv, const OUString& rObjName, const Rectangle& rChartRect ) const { // initialize conversion (locks the model to suppress any internal updates) - InitConversion( xChartDoc ); + InitConversion( xChartDoc, rChartRect ); - // chart frame and title + // chart frame formatting if( mxFrame.is() ) { ScfPropertySet aFrameProp( xChartDoc->getPageBackground() ); mxFrame->Convert( aFrameProp ); } - if( mxTitle.is() ) + + // chart title + if( mxTitle.is() ) try + { + Reference< XTitled > xTitled( xChartDoc, UNO_QUERY_THROW ); + Reference< XTitle > xTitle( mxTitle->CreateTitle(), UNO_SET_THROW ); + xTitled->setTitleObject( xTitle ); + } + catch( Exception& ) { - Reference< XTitled > xTitled( xChartDoc, UNO_QUERY ); - Reference< XTitle > xTitle = mxTitle->CreateTitle(); - if( xTitled.is() && xTitle.is() ) - xTitled->setTitleObject( xTitle ); } /* Create the diagram object and attach it to the chart document. Currently, @@ -3548,13 +3732,48 @@ void XclImpChChart::Convert( Reference< XChartDocument > xChartDoc, XclImpDffCon if( xDiagram.is() && mxLegend.is() ) xDiagram->setLegend( mxLegend->CreateLegend() ); - // set the IncludeHiddenCells property via the old API as only this ensures that the data provider and al created sequences get this flag correctly - Reference< com::sun::star::chart::XChartDocument > xStandardApiChartDoc( xChartDoc, UNO_QUERY ); - if( xStandardApiChartDoc.is() ) + /* Following all conversions needing the old Chart1 API that involves full + initialization of the chart view. */ + Reference< cssc::XChartDocument > xChart1Doc( xChartDoc, UNO_QUERY ); + if( xChart1Doc.is() ) { - ScfPropertySet aDiagramProp( xStandardApiChartDoc->getDiagram() ); - bool bShowVisCells = (maProps.mnFlags & EXC_CHPROPS_SHOWVISIBLEONLY); - aDiagramProp.SetBoolProperty( EXC_CHPROP_INCLUDEHIDDENCELLS, !bShowVisCells ); + Reference< cssc::XDiagram > xDiagram1 = xChart1Doc->getDiagram(); + + /* Set the 'IncludeHiddenCells' property via the old API as only this + ensures that the data provider and all created sequences get this + flag correctly. */ + ScfPropertySet aDiaProp( xDiagram1 ); + bool bShowVisCells = ::get_flag( maProps.mnFlags, EXC_CHPROPS_SHOWVISIBLEONLY ); + aDiaProp.SetBoolProperty( EXC_CHPROP_INCLUDEHIDDENCELLS, !bShowVisCells ); + + // plot area position and size (there is no real automatic mode in BIFF5 charts) + XclImpChFramePosRef xPlotAreaPos = mxPrimAxesSet->GetPlotAreaFramePos(); + if( IsManualPlotArea() && xPlotAreaPos.is() ) try + { + const XclChFramePos& rFramePos = xPlotAreaPos->GetFramePosData(); + if( (rFramePos.mnTLMode == EXC_CHFRAMEPOS_PARENT) && (rFramePos.mnBRMode == EXC_CHFRAMEPOS_PARENT) ) + { + Reference< cssc::XDiagramPositioning > xPositioning( xDiagram1, UNO_QUERY_THROW ); + ::com::sun::star::awt::Rectangle aDiagramRect = CalcHmmFromChartRect( rFramePos.maRect ); + // for pie charts, always set inner plot area size to exclude the data labels as Excel does + const XclImpChTypeGroup* pFirstTypeGroup = mxPrimAxesSet->GetFirstTypeGroup().get(); + if( pFirstTypeGroup && (pFirstTypeGroup->GetTypeInfo().meTypeCateg == EXC_CHTYPECATEG_PIE) ) + xPositioning->setDiagramPositionExcludingAxes( aDiagramRect ); + else if( pFirstTypeGroup && pFirstTypeGroup->Is3dChart() ) + xPositioning->setDiagramPositionIncludingAxesAndAxisTitles( aDiagramRect ); + else + xPositioning->setDiagramPositionIncludingAxes( aDiagramRect ); + } + } + catch( Exception& ) + { + } + + // positions of all title objects + if( mxTitle.is() ) + mxTitle->ConvertTitlePosition( XclChTextKey( EXC_CHTEXTTYPE_TITLE ) ); + mxPrimAxesSet->ConvertTitlePositions(); + mxSecnAxesSet->ConvertTitlePositions(); } // unlock the model @@ -3689,21 +3908,24 @@ void XclImpChChart::FinalizeDataFormats() void XclImpChChart::FinalizeTitle() { - if( (!mxTitle || (!mxTitle->IsDeleted() && !mxTitle->HasString())) && !mxSecnAxesSet->IsValidAxesSet() ) + // special handling for auto-generated title + String aAutoTitle; + if( !mxTitle || (!mxTitle->IsDeleted() && !mxTitle->HasString()) ) { - /* Chart title is auto-generated from series title, if there is only - one series with title in the chart. */ - const String& rSerTitle = mxPrimAxesSet->GetSingleSeriesTitle(); - if( rSerTitle.Len() > 0 ) + // automatic title from first series name (if there are no series on secondary axes set) + if( !mxSecnAxesSet->IsValidAxesSet() ) + aAutoTitle = mxPrimAxesSet->GetSingleSeriesTitle(); + if( mxTitle.is() || (aAutoTitle.Len() > 0) ) { if( !mxTitle ) mxTitle.reset( new XclImpChText( GetChRoot() ) ); - mxTitle->SetString( rSerTitle ); + if( aAutoTitle.Len() == 0 ) + aAutoTitle = CREATE_STRING( "Chart Title" ); } } - // will reset mxTitle, if it does not contain a string - lclFinalizeTitle( mxTitle, GetDefaultText( EXC_CHTEXTTYPE_TITLE ) ); + // will reset mxTitle, if it does not contain a string and no auto title exists + lclFinalizeTitle( mxTitle, GetDefaultText( EXC_CHTEXTTYPE_TITLE ), aAutoTitle ); } Reference< XDiagram > XclImpChChart::CreateDiagram() const @@ -3715,7 +3937,7 @@ Reference< XDiagram > XclImpChChart::CreateDiagram() const ScfPropertySet aDiaProp( xDiagram ); // treatment of missing values - using namespace ::com::sun::star::chart::MissingValueTreatment; + using namespace cssc::MissingValueTreatment; sal_Int32 nMissingValues = LEAVE_GAP; switch( maProps.mnEmptyMode ) { @@ -3775,10 +3997,10 @@ Rectangle XclImpChartDrawing::CalcAnchorRect( const XclObjAnchor& rAnchor, bool in the cell address components of the client anchor. In old BIFF3-BIFF5 objects, the position is stored in the offset components of the anchor. */ Rectangle aRect( - static_cast< long >( static_cast< double >( bDffAnchor ? rAnchor.maFirst.mnCol : rAnchor.mnLX ) / EXC_CHART_UNIT * maChartRect.GetWidth() + 0.5 ), - static_cast< long >( static_cast< double >( bDffAnchor ? rAnchor.maFirst.mnRow : rAnchor.mnTY ) / EXC_CHART_UNIT * maChartRect.GetHeight() + 0.5 ), - static_cast< long >( static_cast< double >( bDffAnchor ? rAnchor.maLast.mnCol : rAnchor.mnRX ) / EXC_CHART_UNIT * maChartRect.GetWidth() + 0.5 ), - static_cast< long >( static_cast< double >( bDffAnchor ? rAnchor.maLast.mnRow : rAnchor.mnBY ) / EXC_CHART_UNIT * maChartRect.GetHeight() + 0.5 ) ); + static_cast< long >( static_cast< double >( bDffAnchor ? rAnchor.maFirst.mnCol : rAnchor.mnLX ) / EXC_CHART_TOTALUNITS * maChartRect.GetWidth() + 0.5 ), + static_cast< long >( static_cast< double >( bDffAnchor ? rAnchor.maFirst.mnRow : rAnchor.mnTY ) / EXC_CHART_TOTALUNITS * maChartRect.GetHeight() + 0.5 ), + static_cast< long >( static_cast< double >( bDffAnchor ? rAnchor.maLast.mnCol : rAnchor.mnRX ) / EXC_CHART_TOTALUNITS * maChartRect.GetWidth() + 0.5 ), + static_cast< long >( static_cast< double >( bDffAnchor ? rAnchor.maLast.mnRow : rAnchor.mnBY ) / EXC_CHART_TOTALUNITS * maChartRect.GetHeight() + 0.5 ) ); aRect.Justify(); // move shapes into chart area for sheet charts if( mbOwnTab ) @@ -3892,7 +4114,7 @@ void XclImpChart::Convert( Reference< XModel > xModel, XclImpDffConverter& rDffC if( xChartDoc.is() ) { if( mxChartData.is() ) - mxChartData->Convert( xChartDoc, rDffConv, rObjName ); + mxChartData->Convert( xChartDoc, rDffConv, rObjName, rChartRect ); if( mxChartDrawing.is() ) mxChartDrawing->ConvertObjects( rDffConv, xModel, rChartRect ); } diff --git a/sc/source/filter/excel/xilink.cxx b/sc/source/filter/excel/xilink.cxx index 45eed0fd98a9..dc2234570ea6 100644 --- a/sc/source/filter/excel/xilink.cxx +++ b/sc/source/filter/excel/xilink.cxx @@ -575,6 +575,7 @@ void XclImpSupbook::LoadCachedValues() const String& rTabName = pTab->GetTabName(); ScExternalRefCache::TableTypeRef pCacheTable = pRefMgr->getCacheTable(nFileId, rTabName, true); pTab->LoadCachedValues(pCacheTable); + pCacheTable->setWholeTableCached(); } } diff --git a/sc/source/filter/excel/xlchart.cxx b/sc/source/filter/excel/xlchart.cxx index 41e682f85808..10a0657c7899 100644 --- a/sc/source/filter/excel/xlchart.cxx +++ b/sc/source/filter/excel/xlchart.cxx @@ -38,11 +38,13 @@ #include <com/sun/star/drawing/LineStyle.hpp> #include <com/sun/star/drawing/FillStyle.hpp> #include <com/sun/star/drawing/BitmapMode.hpp> -#include <com/sun/star/chart2/RelativePosition.hpp> -#include <com/sun/star/chart2/LegendPosition.hpp> -#include <com/sun/star/chart2/LegendExpansion.hpp> -#include <com/sun/star/chart2/Symbol.hpp> #include <com/sun/star/chart/DataLabelPlacement.hpp> +#include <com/sun/star/chart/XAxisXSupplier.hpp> +#include <com/sun/star/chart/XAxisYSupplier.hpp> +#include <com/sun/star/chart/XAxisZSupplier.hpp> +#include <com/sun/star/chart/XChartDocument.hpp> +#include <com/sun/star/chart/XSecondAxisTitleSupplier.hpp> +#include <com/sun/star/chart2/Symbol.hpp> #include <rtl/math.hxx> #include <svl/itemset.hxx> @@ -55,9 +57,8 @@ #include <filter/msfilter/escherex.hxx> #include <editeng/memberids.hrc> #include "global.hxx" -#include "xlconst.hxx" +#include "xlroot.hxx" #include "xlstyle.hxx" -#include "xltools.hxx" using ::rtl::OUString; using ::com::sun::star::uno::Any; @@ -66,6 +67,9 @@ using ::com::sun::star::uno::UNO_QUERY; using ::com::sun::star::uno::Exception; using ::com::sun::star::lang::XMultiServiceFactory; using ::com::sun::star::chart2::XChartDocument; +using ::com::sun::star::drawing::XShape; + +namespace cssc = ::com::sun::star::chart; // Common ===================================================================== @@ -104,8 +108,8 @@ XclChFrBlock::XclChFrBlock( sal_uInt16 nType ) : // Frame formatting =========================================================== XclChFramePos::XclChFramePos() : - mnObjType( EXC_CHFRAMEPOS_ANY ), - mnSizeMode( EXC_CHFRAMEPOS_AUTOSIZE ) + mnTLMode( EXC_CHFRAMEPOS_PARENT ), + mnBRMode( EXC_CHFRAMEPOS_PARENT ) { } @@ -189,7 +193,7 @@ XclChText::XclChText() : mnVAlign( EXC_CHTEXT_ALIGN_CENTER ), mnBackMode( EXC_CHTEXT_TRANSPARENT ), mnFlags( EXC_CHTEXT_AUTOCOLOR | EXC_CHTEXT_AUTOFILL ), - mnPlacement( EXC_CHTEXT_POS_DEFAULT ), + mnFlags2( EXC_CHTEXT_POS_DEFAULT ), mnRotation( EXC_ROT_NONE ) { } @@ -512,7 +516,7 @@ const sal_Char SERVICE_CHART2_SCATTER[] = "com.sun.star.chart2.ScatterChartTyp const sal_Char SERVICE_CHART2_BUBBLE[] = "com.sun.star.chart2.BubbleChartType"; const sal_Char SERVICE_CHART2_SURFACE[] = "com.sun.star.chart2.ColumnChartType"; // Todo -namespace csscd = ::com::sun::star::chart::DataLabelPlacement; +namespace csscd = cssc::DataLabelPlacement; static const XclChTypeInfo spTypeInfos[] = { @@ -680,10 +684,6 @@ const sal_Char* const sppcHatchNamesFilled[] = { "FillStyle", "HatchName", "Colo /** Property names for bitmap area style. */ const sal_Char* const sppcBitmapNames[] = { "FillStyle", "FillBitmapName", "FillBitmapMode", 0 }; -/** Property names for legend properties. */ -const sal_Char* const sppcLegendNames[] = - { "Show", "AnchorPosition", "Expansion", "RelativePosition", 0 }; - } // namespace // ---------------------------------------------------------------------------- @@ -698,8 +698,7 @@ XclChPropSetHelper::XclChPropSetHelper() : maGradHlpFilled( sppcGradNamesFilled ), maHatchHlpCommon( sppcHatchNamesCommon ), maHatchHlpFilled( sppcHatchNamesFilled ), - maBitmapHlp( sppcBitmapNames ), - maLegendHlp( sppcLegendNames ) + maBitmapHlp( sppcBitmapNames ) { } @@ -957,46 +956,6 @@ sal_uInt16 XclChPropSetHelper::ReadRotationProperties( const ScfPropertySet& rPr XclTools::GetXclRotation( static_cast< sal_Int32 >( fAngle * 100.0 + 0.5 ) ); } -void XclChPropSetHelper::ReadLegendProperties( XclChLegend& rLegend, const ScfPropertySet& rPropSet ) -{ - namespace cssc = ::com::sun::star::chart2; - namespace cssd = ::com::sun::star::drawing; - - // read the properties - bool bShow; - cssc::LegendPosition eApiPos; - cssc::LegendExpansion eApiExpand; - Any aRelPosAny; - maLegendHlp.ReadFromPropertySet( rPropSet ); - maLegendHlp >> bShow >> eApiPos >> eApiExpand >> aRelPosAny; - DBG_ASSERT( bShow, "XclChPropSetHelper::ReadLegendProperties - legend must be visible" ); - - // legend position - switch( eApiPos ) - { - case cssc::LegendPosition_LINE_START: rLegend.mnDockMode = EXC_CHLEGEND_LEFT; break; - case cssc::LegendPosition_LINE_END: rLegend.mnDockMode = EXC_CHLEGEND_RIGHT; break; - case cssc::LegendPosition_PAGE_START: rLegend.mnDockMode = EXC_CHLEGEND_TOP; break; - case cssc::LegendPosition_PAGE_END: rLegend.mnDockMode = EXC_CHLEGEND_BOTTOM; break; - default: rLegend.mnDockMode = EXC_CHLEGEND_NOTDOCKED; - } - // legend expansion - ::set_flag( rLegend.mnFlags, EXC_CHLEGEND_STACKED, eApiExpand != cssc::LegendExpansion_WIDE ); - // legend position - if( rLegend.mnDockMode == EXC_CHLEGEND_NOTDOCKED ) - { - cssc::RelativePosition aRelPos; - if( aRelPosAny >>= aRelPos ) - { - rLegend.maRect.mnX = limit_cast< sal_Int32 >( aRelPos.Primary * EXC_CHART_UNIT, 0, EXC_CHART_UNIT ); - rLegend.maRect.mnY = limit_cast< sal_Int32 >( aRelPos.Secondary * EXC_CHART_UNIT, 0, EXC_CHART_UNIT ); - } - else - rLegend.mnDockMode = EXC_CHLEGEND_LEFT; - } - ::set_flag( rLegend.mnFlags, EXC_CHLEGEND_DOCKED, rLegend.mnDockMode != EXC_CHLEGEND_NOTDOCKED ); -} - // write properties ----------------------------------------------------------- void XclChPropSetHelper::WriteLineProperties( @@ -1207,51 +1166,6 @@ void XclChPropSetHelper::WriteRotationProperties( } } -void XclChPropSetHelper::WriteLegendProperties( - ScfPropertySet& rPropSet, const XclChLegend& rLegend ) -{ - namespace cssc = ::com::sun::star::chart2; - namespace cssd = ::com::sun::star::drawing; - - // legend position - cssc::LegendPosition eApiPos = cssc::LegendPosition_CUSTOM; - switch( rLegend.mnDockMode ) - { - case EXC_CHLEGEND_LEFT: eApiPos = cssc::LegendPosition_LINE_START; break; - case EXC_CHLEGEND_RIGHT: eApiPos = cssc::LegendPosition_LINE_END; break; - case EXC_CHLEGEND_TOP: eApiPos = cssc::LegendPosition_PAGE_START; break; - case EXC_CHLEGEND_BOTTOM: eApiPos = cssc::LegendPosition_PAGE_END; break; - } - // legend expansion - cssc::LegendExpansion eApiExpand = ::get_flagvalue( - rLegend.mnFlags, EXC_CHLEGEND_STACKED, cssc::LegendExpansion_HIGH, cssc::LegendExpansion_WIDE ); - // legend position - Any aRelPosAny; - if( eApiPos == cssc::LegendPosition_CUSTOM ) - { - // #i71697# it is not possible to set the size directly, do some magic here - double fRatio = ((rLegend.maRect.mnWidth > 0) && (rLegend.maRect.mnHeight > 0)) ? - (static_cast< double >( rLegend.maRect.mnWidth ) / rLegend.maRect.mnHeight) : 1.0; - if( fRatio > 1.5 ) - eApiExpand = cssc::LegendExpansion_WIDE; - else if( fRatio < 0.75 ) - eApiExpand = cssc::LegendExpansion_HIGH; - else - eApiExpand = cssc::LegendExpansion_BALANCED; - // set position - cssc::RelativePosition aRelPos; - aRelPos.Primary = static_cast< double >( rLegend.maRect.mnX ) / EXC_CHART_UNIT; - aRelPos.Secondary = static_cast< double >( rLegend.maRect.mnY ) / EXC_CHART_UNIT; - aRelPos.Anchor = cssd::Alignment_TOP_LEFT; - aRelPosAny <<= aRelPos; - } - - // write the properties - maLegendHlp.InitializeWrite(); - maLegendHlp << true << eApiPos << eApiExpand << aRelPosAny; - maLegendHlp.WriteToPropertySet( rPropSet ); -} - // private -------------------------------------------------------------------- ScfPropSetHelper& XclChPropSetHelper::GetLineHelper( XclChPropertyMode ePropMode ) @@ -1301,27 +1215,81 @@ ScfPropSetHelper& XclChPropSetHelper::GetHatchHelper( XclChPropertyMode ePropMod // ============================================================================ +namespace { + +/* The following local functions implement getting the XShape interface of all + supported title objects (chart and axes). This needs some effort due to the + design of the old Chart1 API used to access these objects. */ + +/** A code fragment that returns a shape object from the passed shape supplier + using the specified interface function. Checks a boolean property first. */ +#define EXC_FRAGMENT_GETTITLESHAPE( shape_supplier, supplier_func, property_name ) \ + ScfPropertySet aPropSet( shape_supplier ); \ + if( shape_supplier.is() && aPropSet.GetBoolProperty( CREATE_OUSTRING( #property_name ) ) ) \ + return shape_supplier->supplier_func(); \ + return Reference< XShape >(); \ + +/** Implements a function returning the drawing shape of an axis title, if + existing, using the specified API interface and its function. */ +#define EXC_DEFINEFUNC_GETAXISTITLESHAPE( func_name, interface_type, supplier_func, property_name ) \ +Reference< XShape > func_name( const Reference< cssc::XChartDocument >& rxChart1Doc ) \ +{ \ + Reference< cssc::interface_type > xAxisSupp( rxChart1Doc->getDiagram(), UNO_QUERY ); \ + EXC_FRAGMENT_GETTITLESHAPE( xAxisSupp, supplier_func, property_name ) \ +} + +/** Returns the drawing shape of the main title, if existing. */ +Reference< XShape > lclGetMainTitleShape( const Reference< cssc::XChartDocument >& rxChart1Doc ) +{ + EXC_FRAGMENT_GETTITLESHAPE( rxChart1Doc, getTitle, HasMainTitle ) +} + +EXC_DEFINEFUNC_GETAXISTITLESHAPE( lclGetXAxisTitleShape, XAxisXSupplier, getXAxisTitle, HasXAxisTitle ) +EXC_DEFINEFUNC_GETAXISTITLESHAPE( lclGetYAxisTitleShape, XAxisYSupplier, getYAxisTitle, HasYAxisTitle ) +EXC_DEFINEFUNC_GETAXISTITLESHAPE( lclGetZAxisTitleShape, XAxisZSupplier, getZAxisTitle, HasZAxisTitle ) +EXC_DEFINEFUNC_GETAXISTITLESHAPE( lclGetSecXAxisTitleShape, XSecondAxisTitleSupplier, getSecondXAxisTitle, HasSecondaryXAxisTitle ) +EXC_DEFINEFUNC_GETAXISTITLESHAPE( lclGetSecYAxisTitleShape, XSecondAxisTitleSupplier, getSecondYAxisTitle, HasSecondaryYAxisTitle ) + +#undef EXC_DEFINEFUNC_GETAXISTITLESHAPE +#undef EXC_IMPLEMENT_GETTITLESHAPE + +} // namespace + +// ---------------------------------------------------------------------------- + XclChRootData::XclChRootData() : mxTypeInfoProv( new XclChTypeInfoProvider ), - mxFmtInfoProv( new XclChFormatInfoProvider ) + mxFmtInfoProv( new XclChFormatInfoProvider ), + mnBorderGapX( 0 ), + mnBorderGapY( 0 ) { + // remember some title shape getter functions + maGetShapeFuncs[ XclChTextKey( EXC_CHTEXTTYPE_TITLE ) ] = lclGetMainTitleShape; + maGetShapeFuncs[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, EXC_CHAXESSET_PRIMARY, EXC_CHAXIS_X ) ] = lclGetXAxisTitleShape; + maGetShapeFuncs[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, EXC_CHAXESSET_PRIMARY, EXC_CHAXIS_Y ) ] = lclGetYAxisTitleShape; + maGetShapeFuncs[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, EXC_CHAXESSET_PRIMARY, EXC_CHAXIS_Z ) ] = lclGetZAxisTitleShape; + maGetShapeFuncs[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, EXC_CHAXESSET_SECONDARY, EXC_CHAXIS_X ) ] = lclGetSecXAxisTitleShape; + maGetShapeFuncs[ XclChTextKey( EXC_CHTEXTTYPE_AXISTITLE, EXC_CHAXESSET_SECONDARY, EXC_CHAXIS_Y ) ] = lclGetSecYAxisTitleShape; } XclChRootData::~XclChRootData() { } -Reference< XChartDocument > XclChRootData::GetChartDoc() const +void XclChRootData::InitConversion( const XclRoot& rRoot, const Reference< XChartDocument >& rxChartDoc, const Rectangle& rChartRect ) { - DBG_ASSERT( mxChartDoc.is(), "XclChRootData::GetChartDoc - missing chart document" ); - return mxChartDoc; -} + // remember chart document reference and chart shape position/size + DBG_ASSERT( rxChartDoc.is(), "XclChRootData::InitConversion - missing chart document" ); + mxChartDoc = rxChartDoc; + maChartRect = rChartRect; -void XclChRootData::InitConversion( XChartDocRef xChartDoc ) -{ - // remember chart document reference - DBG_ASSERT( xChartDoc.is(), "XclChRootData::InitConversion - missing chart document" ); - mxChartDoc = xChartDoc; + // Excel excludes a border of 5 pixels in each direction from chart area + mnBorderGapX = rRoot.GetHmmFromPixelX( 5.0 ); + mnBorderGapY = rRoot.GetHmmFromPixelY( 5.0 ); + + // size of a chart unit in 1/100 mm + mfUnitSizeX = ::std::max< double >( maChartRect.GetWidth() - 2 * mnBorderGapX, mnBorderGapX ) / EXC_CHART_TOTALUNITS; + mfUnitSizeY = ::std::max< double >( maChartRect.GetHeight() - 2 * mnBorderGapY, mnBorderGapY ) / EXC_CHART_TOTALUNITS; // create object tables Reference< XMultiServiceFactory > xFactory( mxChartDoc, UNO_QUERY ); @@ -1346,5 +1314,15 @@ void XclChRootData::FinishConversion() mxChartDoc.clear(); } -// ============================================================================ +Reference< XShape > XclChRootData::GetTitleShape( const XclChTextKey& rTitleKey ) const +{ + XclChGetShapeFuncMap::const_iterator aIt = maGetShapeFuncs.find( rTitleKey ); + OSL_ENSURE( aIt != maGetShapeFuncs.end(), "XclChRootData::GetTitleShape - invalid title key" ); + Reference< cssc::XChartDocument > xChart1Doc( mxChartDoc, UNO_QUERY ); + Reference< XShape > xTitleShape; + if( xChart1Doc.is() && (aIt != maGetShapeFuncs.end()) ) + xTitleShape = (aIt->second)( xChart1Doc ); + return xTitleShape; +} +// ============================================================================ diff --git a/sc/source/filter/excel/xlroot.cxx b/sc/source/filter/excel/xlroot.cxx index 8a22b05828b9..2b2180db5e6a 100644 --- a/sc/source/filter/excel/xlroot.cxx +++ b/sc/source/filter/excel/xlroot.cxx @@ -28,7 +28,11 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sc.hxx" #include "xlroot.hxx" +#include <com/sun/star/awt/XDevice.hpp> +#include <com/sun/star/frame/XFrame.hpp> +#include <com/sun/star/frame/XFramesSupplier.hpp> #include <com/sun/star/i18n/ScriptType.hpp> +#include <comphelper/processfactory.hxx> #include <vcl/svapp.hxx> #include <svl/stritem.hxx> #include <svl/languageoptions.hxx> @@ -57,6 +61,15 @@ namespace ApiScriptType = ::com::sun::star::i18n::ScriptType; using ::rtl::OUString; +using ::com::sun::star::uno::Exception; +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::UNO_QUERY_THROW; +using ::com::sun::star::uno::UNO_SET_THROW; +using ::com::sun::star::awt::XDevice; +using ::com::sun::star::awt::DeviceInfo; +using ::com::sun::star::frame::XFrame; +using ::com::sun::star::frame::XFramesSupplier; +using ::com::sun::star::lang::XMultiServiceFactory; // Global data ================================================================ @@ -88,6 +101,8 @@ XclRootData::XclRootData( XclBiff eBiff, SfxMedium& rMedium, mxFontPropSetHlp( new XclFontPropSetHelper ), mxChPropSetHlp( new XclChPropSetHelper ), mxRD( new RootData ),//! + mfScreenPixelX( 50.0 ), + mfScreenPixelY( 50.0 ), mnCharWidth( 110 ), mnScTab( 0 ), mbExport( bExport ) @@ -129,6 +144,22 @@ XclRootData::XclRootData( XclBiff eBiff, SfxMedium& rMedium, mxExtDocOpt.reset( new ScExtDocOptions( *pOldDocOpt ) ); else mxExtDocOpt.reset( new ScExtDocOptions ); + + // screen pixel size + try + { + Reference< XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory(), UNO_SET_THROW ); + Reference< XFramesSupplier > xFramesSupp( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.frame.Desktop" ) ), UNO_QUERY_THROW ); + Reference< XFrame > xFrame( xFramesSupp->getActiveFrame(), UNO_SET_THROW ); + Reference< XDevice > xDevice( xFrame->getContainerWindow(), UNO_QUERY_THROW ); + DeviceInfo aDeviceInfo = xDevice->getInfo(); + mfScreenPixelX = (aDeviceInfo.PixelPerMeterX > 0) ? (100000.0 / aDeviceInfo.PixelPerMeterX) : 50.0; + mfScreenPixelY = (aDeviceInfo.PixelPerMeterY > 0) ? (100000.0 / aDeviceInfo.PixelPerMeterY) : 50.0; + } + catch( Exception& ) + { + OSL_ENSURE( false, "XclRootData::XclRootData - cannot get output device info" ); + } } XclRootData::~XclRootData() @@ -199,6 +230,16 @@ void XclRoot::SetCharWidth( const XclFontData& rFontData ) } } +sal_Int32 XclRoot::GetHmmFromPixelX( double fPixelX ) const +{ + return static_cast< sal_Int32 >( fPixelX * mrData.mfScreenPixelX + 0.5 ); +} + +sal_Int32 XclRoot::GetHmmFromPixelY( double fPixelY ) const +{ + return static_cast< sal_Int32 >( fPixelY * mrData.mfScreenPixelY + 0.5 ); +} + String XclRoot::RequestPassword( ::comphelper::IDocPasswordVerifier& rVerifier ) const { ::std::vector< OUString > aDefaultPasswords; diff --git a/sc/source/filter/inc/xechart.hxx b/sc/source/filter/inc/xechart.hxx index 2cf976b11efe..5bb75e029210 100644 --- a/sc/source/filter/inc/xechart.hxx +++ b/sc/source/filter/inc/xechart.hxx @@ -39,6 +39,10 @@ class Size; namespace com { namespace sun { namespace star { + namespace awt + { + struct Rectangle; + } namespace frame { class XModel; @@ -65,7 +69,7 @@ namespace com { namespace sun { namespace star { // Common ===================================================================== -class XclExpChRootData; +struct XclExpChRootData; class XclExpChChart; /** Base class for complex chart classes, provides access to other components @@ -80,11 +84,13 @@ public: typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartDocument > XChartDocRef; public: - explicit XclExpChRoot( const XclExpRoot& rRoot, XclExpChChart* pChartData ); + explicit XclExpChRoot( const XclExpRoot& rRoot, XclExpChChart& rChartData ); virtual ~XclExpChRoot(); /** Returns this root instance - for code readability in derived classes. */ inline const XclExpChRoot& GetChRoot() const { return *this; } + /** Returns the API Chart document model. */ + XChartDocRef GetChartDocument() const; /** Returns a reference to the parent chart data object. */ XclExpChChart& GetChartData() const; /** Returns chart type info for a unique chart type identifier. */ @@ -96,7 +102,7 @@ public: const XclChFormatInfo& GetFormatInfo( XclChObjectType eObjType ) const; /** Starts the API chart document conversion. Must be called once before all API conversion. */ - void InitConversion( XChartDocRef xChartDoc ) const; + void InitConversion( XChartDocRef xChartDoc, const Rectangle& rChartRect ) const; /** Finishes the API chart document conversion. Must be called once after all API conversion. */ void FinishConversion() const; @@ -105,6 +111,18 @@ public: /** Sets a system color and the respective color identifier. */ void SetSystemColor( Color& rColor, sal_uInt32& rnColorId, sal_uInt16 nSysColorIdx ) const; + /** Converts the passed horizontal coordinate from 1/100 mm to Excel chart units. */ + sal_Int32 CalcChartXFromHmm( sal_Int32 nPosX ) const; + /** Converts the passed vertical coordinate from 1/100 mm to Excel chart units. */ + sal_Int32 CalcChartYFromHmm( sal_Int32 nPosY ) const; + /** Converts the passed rectangle from 1/100 mm to Excel chart units. */ + XclChRectangle CalcChartRectFromHmm( const ::com::sun::star::awt::Rectangle& rRect ) const; + + /** Converts the passed horizontal coordinate from a relative position to Excel chart units. */ + sal_Int32 CalcChartXFromRelative( double fPosX ) const; + /** Converts the passed vertical coordinate from a relative position to Excel chart units. */ + sal_Int32 CalcChartYFromRelative( double fPosY ) const; + /** Reads all line properties from the passed property set. */ void ConvertLineFormat( XclChLineFormat& rLineFmt, @@ -191,6 +209,25 @@ public: // Frame formatting =========================================================== +class XclExpChFramePos : public XclExpRecord +{ +public: + explicit XclExpChFramePos( sal_uInt16 nTLMode, sal_uInt16 nBRMode ); + + /** Returns read/write access to the frame position data. */ + inline XclChFramePos& GetFramePosData() { return maData; } + +private: + virtual void WriteBody( XclExpStream& rStrm ); + +private: + XclChFramePos maData; /// Position of the frame. +}; + +typedef ScfRef< XclExpChFramePos > XclExpChFramePosRef; + +// ---------------------------------------------------------------------------- + class XclExpChLineFormat : public XclExpRecord { public: @@ -514,6 +551,7 @@ private: private: XclChText maData; /// Contents of the CHTEXT record. + XclExpChFramePosRef mxFramePos; /// Relative text frame position (CHFRAMEPOS record). XclExpChSourceLinkRef mxSrcLink; /// Linked data (CHSOURCELINK with CHSTRING record). XclExpChFrameRef mxFrame; /// Text object frame properties (CHFRAME group). XclExpChFontRef mxFont; /// Index into font buffer (CHFONT record). @@ -830,8 +868,8 @@ typedef ScfRef< XclExpChChart3d > XclExpChChart3dRef; /** Represents the CHLEGEND record group describing the chart legend. - The CHLEGEND group consists of: CHLEGEND, CHBEGIN, CHFRAME group, - CHTEXT group, CHEND. + The CHLEGEND group consists of: CHLEGEND, CHBEGIN, CHFRAMEPOS, CHFRAME + group, CHTEXT group, CHEND. */ class XclExpChLegend : public XclExpChGroupBase { @@ -849,6 +887,7 @@ private: private: XclChLegend maData; /// Contents of the CHLEGEND record. + XclExpChFramePosRef mxFramePos; /// Legend frame position (CHFRAMEPOS record). XclExpChTextRef mxText; /// Legend text format (CHTEXT group). XclExpChFrameRef mxFrame; /// Legend frame format (CHFRAME group). }; @@ -1137,6 +1176,7 @@ private: typedef XclExpRecordList< XclExpChTypeGroup > XclExpChTypeGroupList; XclChAxesSet maData; /// Contents of the CHAXESSET record. + XclExpChFramePosRef mxFramePos; /// Outer plot area position (CHFRAMEPOS record). XclExpChAxisRef mxXAxis; /// The X axis (CHAXIS group). XclExpChAxisRef mxYAxis; /// The Y axis (CHAXIS group). XclExpChAxisRef mxZAxis; /// The Z axis (CHAXIS group). @@ -1164,7 +1204,7 @@ public: public: explicit XclExpChChart( const XclExpRoot& rRoot, - XChartDocRef xChartDoc, const Size& rSize ); + XChartDocRef xChartDoc, const Rectangle& rChartRect ); /** Creates, registers and returns a new data series object. */ XclExpChSeriesRef CreateSeries(); @@ -1172,6 +1212,8 @@ public: void RemoveLastSeries(); /** Stores a CHTEXT group that describes a data point label. */ void SetDataLabel( XclExpChTextRef xText ); + /** Sets the plot area position and size to manual mode. */ + void SetManualPlotArea(); /** Writes all embedded records. */ virtual void WriteSubRecords( XclExpStream& rStrm ); @@ -1224,7 +1266,7 @@ public: public: explicit XclExpChart( const XclExpRoot& rRoot, - XModelRef xModel, const Size& rSize ); + XModelRef xModel, const Rectangle& rChartRect ); }; // ============================================================================ diff --git a/sc/source/filter/inc/xichart.hxx b/sc/source/filter/inc/xichart.hxx index 5d03c99b124a..d8289b3b671b 100644 --- a/sc/source/filter/inc/xichart.hxx +++ b/sc/source/filter/inc/xichart.hxx @@ -43,10 +43,18 @@ #include "xistring.hxx" namespace com { namespace sun { namespace star { + namespace awt + { + struct Rectangle; + } namespace frame { class XModel; } + namespace drawing + { + class XShape; + } namespace chart2 { struct ScaleData; @@ -75,7 +83,7 @@ struct XclObjFillData; // Common ===================================================================== class ScfProgressBar; -class XclImpChRootData; +struct XclImpChRootData; class XclImpChChart; class ScTokenArray; @@ -83,11 +91,10 @@ class ScTokenArray; class XclImpChRoot : public XclImpRoot { public: - typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartDocument > XChartDocRef; - typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::data::XDataProvider > XDataProviderRef; + typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartDocument > XChartDocRef; public: - explicit XclImpChRoot( const XclImpRoot& rRoot, XclImpChChart* pChartData ); + explicit XclImpChRoot( const XclImpRoot& rRoot, XclImpChChart& rChartData ); virtual ~XclImpChRoot(); /** Returns this root instance - for code readability in derived classes. */ @@ -109,12 +116,28 @@ public: Color GetSeriesFillAutoColor( sal_uInt16 nFormatIdx ) const; /** Starts the API chart document conversion. Must be called once before all API conversion. */ - void InitConversion( XChartDocRef xChartDoc ) const; + void InitConversion( XChartDocRef xChartDoc, const Rectangle& rChartRect ) const; /** Finishes the API chart document conversion. Must be called once after all API conversion. */ void FinishConversion( XclImpDffConverter& rDffConv ) const; /** Returns the data provider for the chart document. */ - XDataProviderRef GetDataProvider() const; + ::com::sun::star::uno::Reference< ::com::sun::star::chart2::data::XDataProvider > + GetDataProvider() const; + /** Returns the drawing shape interface of the specified title object. */ + ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > + GetTitleShape( const XclChTextKey& rTitleKey ) const; + + /** Converts the passed horizontal coordinate from Excel chart units into 1/100 mm. */ + sal_Int32 CalcHmmFromChartX( sal_Int32 nPosX ) const; + /** Converts the passed vertical coordinate from Excel chart units into 1/100 mm. */ + sal_Int32 CalcHmmFromChartY( sal_Int32 nPosY ) const; + /** Converts the passed rectangle from Excel chart units into 1/100 mm. */ + ::com::sun::star::awt::Rectangle CalcHmmFromChartRect( const XclChRectangle& rRect ) const; + + /** Converts the passed horizontal coordinate from Excel chart units into a relative position. */ + double CalcRelativeFromChartX( sal_Int32 nPosX ) const; + /** Converts the passed vertical coordinate from Excel chart units into a relative position. */ + double CalcRelativeFromChartY( sal_Int32 nPosY ) const; /** Writes all line properties to the passed property set. */ void ConvertLineFormat( @@ -184,6 +207,9 @@ public: /** Reads the CHFRAMEPOS record (frame position and size). */ void ReadChFramePos( XclImpStream& rStrm ); + /** Returns read-only access to the imported frame position data. */ + inline const XclChFramePos& GetFramePosData() const { return maData; } + private: XclChFramePos maData; /// Position of the frame. }; @@ -506,6 +532,8 @@ public: void ConvertDataLabel( ScfPropertySet& rPropSet, const XclChTypeInfo& rTypeInfo ) const; /** Creates a title text object. */ XTitleRef CreateTitle() const; + /** Converts the manual position of the specified title */ + void ConvertTitlePosition( const XclChTextKey& rTitleKey ) const; private: using XclImpChRoot::ConvertFont; @@ -519,6 +547,7 @@ private: XclChText maData; /// Contents of the CHTEXT record. XclChObjectLink maObjLink; /// Link target for this text object. XclFormatRunVec maFormats; /// Formatting runs (CHFORMATRUNS record). + XclImpChFramePosRef mxFramePos; /// Relative text frame position (CHFRAMEPOS record). XclImpChSourceLinkRef mxSrcLink; /// Linked data (CHSOURCELINK with CHSTRING record). XclImpChFrameRef mxFrame; /// Text object frame properties (CHFRAME group). XclImpChFontRef mxFont; /// Index into font buffer (CHFONT record). @@ -922,8 +951,8 @@ typedef ScfRef< XclImpChChart3d > XclImpChChart3dRef; /** Represents the CHLEGEND record group describing the chart legend. - The CHLEGEND group consists of: CHLEGEND, CHBEGIN, CHFRAME group, - CHTEXT group, CHEND. + The CHLEGEND group consists of: CHLEGEND, CHBEGIN, CHFRAMEPOS, CHFRAME + group, CHTEXT group, CHEND. */ class XclImpChLegend : public XclImpChGroupBase, protected XclImpChRoot { @@ -945,6 +974,7 @@ public: private: XclChLegend maData; /// Contents of the CHLEGEND record. + XclImpChFramePosRef mxFramePos; /// Legend frame position (CHFRAMEPOS record). XclImpChTextRef mxText; /// Legend text format (CHTEXT group). XclImpChFrameRef mxFrame; /// Legend frame format (CHFRAME group). }; @@ -1265,6 +1295,8 @@ public: /** Returns the axes set index used by the chart API. */ inline sal_Int32 GetApiAxesSetIndex() const { return maData.GetApiAxesSetIndex(); } + /** Returns the outer plot area position, if existing. */ + inline XclImpChFramePosRef GetPlotAreaFramePos() const { return mxFramePos; } /** Returns the specified chart type group. */ inline XclImpChTypeGroupRef GetTypeGroup( sal_uInt16 nGroupIdx ) const { return maTypeGroups.get( nGroupIdx ); } /** Returns the first chart type group. */ @@ -1276,6 +1308,8 @@ public: /** Creates a coordinate system and converts all series and axis settings. */ void Convert( XDiagramRef xDiagram ) const; + /** Converts the manual positions of all axis titles. */ + void ConvertTitlePositions() const; private: /** Reads a CHAXIS record group containing a single axis. */ @@ -1304,7 +1338,7 @@ private: typedef ScfRefMap< sal_uInt16, XclImpChTypeGroup > XclImpChTypeGroupMap; XclChAxesSet maData; /// Contents of the CHAXESSET record. - XclImpChFramePosRef mxPos; /// Position of the axes set (CHFRAMEPOS record). + XclImpChFramePosRef mxFramePos; /// Outer plot area position (CHFRAMEPOS record). XclImpChAxisRef mxXAxis; /// The X axis (CHAXIS group). XclImpChAxisRef mxYAxis; /// The Y axis (CHAXIS group). XclImpChAxisRef mxZAxis; /// The Z axis (CHAXIS group). @@ -1351,13 +1385,16 @@ public: XclImpChTypeGroupRef GetTypeGroup( sal_uInt16 nGroupIdx ) const; /** Returns the specified default text. */ XclImpChTextRef GetDefaultText( XclChTextType eTextType ) const; + /** Returns true, if the plot area has benn moved and/or resized manually. */ + bool IsManualPlotArea() const; /** Returns the number of units on the progress bar needed for the chart. */ inline sal_Size GetProgressSize() const { return 2 * EXC_CHART_PROGRESS_SIZE; } /** Converts and writes all properties to the passed chart. */ void Convert( XChartDocRef xChartDoc, XclImpDffConverter& rDffConv, - const ::rtl::OUString& rObjName ) const; + const ::rtl::OUString& rObjName, + const Rectangle& rChartRect ) const; private: /** Reads a CHSERIES group (data series source and formatting). */ diff --git a/sc/source/filter/inc/xlchart.hxx b/sc/source/filter/inc/xlchart.hxx index f6711211bc13..13eda8619cc0 100644 --- a/sc/source/filter/inc/xlchart.hxx +++ b/sc/source/filter/inc/xlchart.hxx @@ -34,14 +34,19 @@ #define EXC_CHART2_3DBAR_HAIRLINES_ONLY 1 #include <map> +#include <tools/gen.hxx> #include "fapihelper.hxx" namespace com { namespace sun { namespace star { namespace container { class XNameContainer; } namespace lang { class XMultiServiceFactory; } + namespace chart { class XChartDocument; } namespace chart2 { class XChartDocument; } + namespace drawing { class XShape; } } } } +class XclRoot; + // Property names ============================================================= // service names @@ -72,6 +77,7 @@ namespace com { namespace sun { namespace star { // property names #define EXC_CHPROP_ADDITIONALSHAPES CREATE_OUSTRING( "AdditionalShapes" ) +#define EXC_CHPROP_ANCHORPOSITION CREATE_OUSTRING( "AnchorPosition" ) #define EXC_CHPROP_ARRANGEORDER CREATE_OUSTRING( "ArrangeOrder" ) #define EXC_CHPROP_ATTAXISINDEX CREATE_OUSTRING( "AttachedAxisIndex" ) #define EXC_CHPROP_ATTRIBDATAPOINTS CREATE_OUSTRING( "AttributedDataPoints" ) @@ -94,10 +100,12 @@ namespace com { namespace sun { namespace star { #define EXC_CHPROP_ERRORBARSTYLE CREATE_OUSTRING( "ErrorBarStyle" ) #define EXC_CHPROP_ERRORBARX CREATE_OUSTRING( "ErrorBarX" ) #define EXC_CHPROP_ERRORBARY CREATE_OUSTRING( "ErrorBarY" ) +#define EXC_CHPROP_EXPANSION CREATE_OUSTRING( "Expansion" ) #define EXC_CHPROP_FILLBITMAPMODE CREATE_OUSTRING( "FillBitmapMode" ) #define EXC_CHPROP_FILLSTYLE CREATE_OUSTRING( "FillStyle" ) #define EXC_CHPROP_GAPWIDTHSEQ CREATE_OUSTRING( "GapwidthSequence" ) #define EXC_CHPROP_GEOMETRY3D CREATE_OUSTRING( "Geometry3D" ) +#define EXC_CHPROP_HASMAINTITLE CREATE_OUSTRING( "HasMainTitle" ) #define EXC_CHPROP_INCLUDEHIDDENCELLS CREATE_OUSTRING( "IncludeHiddenCells" ) #define EXC_CHPROP_JAPANESE CREATE_OUSTRING( "Japanese" ) #define EXC_CHPROP_LABEL CREATE_OUSTRING( "Label" ) @@ -116,6 +124,7 @@ namespace com { namespace sun { namespace star { #define EXC_CHPROP_PERCENTDIAGONAL CREATE_OUSTRING( "PercentDiagonal" ) #define EXC_CHPROP_PERSPECTIVE CREATE_OUSTRING( "Perspective" ) #define EXC_CHPROP_POSITIVEERROR CREATE_OUSTRING( "PositiveError" ) +#define EXC_CHPROP_RELATIVEPOSITION CREATE_OUSTRING( "RelativePosition" ) #define EXC_CHPROP_RIGHTANGLEDAXES CREATE_OUSTRING( "RightAngledAxes" ) #define EXC_CHPROP_ROLE CREATE_OUSTRING( "Role" ) #define EXC_CHPROP_ROTATIONHORIZONTAL CREATE_OUSTRING( "RotationHorizontal" ) @@ -169,7 +178,8 @@ const sal_Int32 EXC_CHART_AXESSET_NONE = -1; /// For internal use const sal_Int32 EXC_CHART_AXESSET_PRIMARY = 0; /// API primary axes set index. const sal_Int32 EXC_CHART_AXESSET_SECONDARY = 1; /// API secondary axes set index. -const sal_Int32 EXC_CHART_UNIT = 4000; /// Chart objects are positioned in 1/4000 of chart area. +const sal_Int32 EXC_CHART_TOTALUNITS = 4000; /// Most chart objects are positioned in 1/4000 of chart area. +const sal_Int32 EXC_CHART_PLOTAREAUNITS = 1000; /// For objects that are positioned in 1/1000 of plot area. // (0x0850) CHFRINFO ---------------------------------------------------------- @@ -604,7 +614,8 @@ const sal_uInt16 EXC_ID_CHPROPERTIES = 0x1044; const sal_uInt16 EXC_CHPROPS_MANSERIES = 0x0001; /// Manual series allocation. const sal_uInt16 EXC_CHPROPS_SHOWVISIBLEONLY = 0x0002; /// Show visible cells only. const sal_uInt16 EXC_CHPROPS_NORESIZE = 0x0004; /// Do not resize chart with window. -const sal_uInt16 EXC_CHPROPS_MANPLOTAREA = 0x0008; /// Plot area with CHFRAMEPOS records. +const sal_uInt16 EXC_CHPROPS_MANPLOTAREA = 0x0008; /// Manual plot area mode. +const sal_uInt16 EXC_CHPROPS_USEMANPLOTAREA = 0x0010; /// Manual plot area layout in CHFRAMEPOS record. const sal_uInt8 EXC_CHPROPS_EMPTY_SKIP = 0; /// Skip empty values. const sal_uInt8 EXC_CHPROPS_EMPTY_ZERO = 1; /// Plot empty values as zero. @@ -643,11 +654,11 @@ const sal_uInt16 EXC_ID_CHFORMAT = 0x104E; const sal_uInt16 EXC_ID_CHFRAMEPOS = 0x104F; -const sal_uInt16 EXC_CHFRAMEPOS_ANY = 2; -const sal_uInt16 EXC_CHFRAMEPOS_LEGEND = 5; - -const sal_uInt16 EXC_CHFRAMEPOS_MANUALSIZE = 1; -const sal_uInt16 EXC_CHFRAMEPOS_AUTOSIZE = 2; +const sal_uInt16 EXC_CHFRAMEPOS_POINTS = 0; +const sal_uInt16 EXC_CHFRAMEPOS_ABSSIZE_POINTS = 1; +const sal_uInt16 EXC_CHFRAMEPOS_PARENT = 2; +const sal_uInt16 EXC_CHFRAMEPOS_DEFOFFSET_PLOT = 3; +const sal_uInt16 EXC_CHFRAMEPOS_CHARTSIZE = 5; // (0x1050) CHFORMATRUNS ------------------------------------------------------ @@ -774,8 +785,8 @@ struct XclChFrBlock struct XclChFramePos { XclChRectangle maRect; /// Object dependent position data. - sal_uInt16 mnObjType; /// Object type. - sal_uInt16 mnSizeMode; /// Size mode (manual, automatic). + sal_uInt16 mnTLMode; /// Top-left position mode. + sal_uInt16 mnBRMode; /// Bottom-right position mode. explicit XclChFramePos(); }; @@ -885,7 +896,7 @@ struct XclChText sal_uInt8 mnVAlign; /// Vertical alignment. sal_uInt16 mnBackMode; /// Background mode: transparent, opaque. sal_uInt16 mnFlags; /// Additional flags. - sal_uInt16 mnPlacement; /// Text object placement (BIFF8+). + sal_uInt16 mnFlags2; /// Text object placement and text direction (BIFF8+). sal_uInt16 mnRotation; /// Text object rotation (BIFF8+). explicit XclChText(); @@ -1013,7 +1024,6 @@ struct XclChLegend struct XclChTypeGroup { - XclChRectangle maRect; /// Position (not used). sal_uInt16 mnFlags; /// Additional flags. sal_uInt16 mnGroupIdx; /// Chart type group index. @@ -1060,7 +1070,6 @@ struct XclChValueRange struct XclChTick { - XclChRectangle maRect; /// Position (not used). Color maTextColor; /// Tick labels color. sal_uInt8 mnMajor; /// Type of tick marks of major grid. sal_uInt8 mnMinor; /// Type of tick marks of minor grid. @@ -1076,7 +1085,6 @@ struct XclChTick struct XclChAxis { - XclChRectangle maRect; /// Position (not used). sal_uInt16 mnType; /// Axis type. explicit XclChAxis(); @@ -1089,7 +1097,7 @@ struct XclChAxis struct XclChAxesSet { - XclChRectangle maRect; /// Position of the axes set. + XclChRectangle maRect; /// Position of the axes set (inner plot area). sal_uInt16 mnAxesSetId; /// Primary/secondary axes set. explicit XclChAxesSet(); @@ -1158,16 +1166,6 @@ enum XclChFrameType EXC_CHFRAMETYPE_INVISIBLE /// Missing frame represents invisible formatting. }; -/** Enumerates different text box types for default text formatting. */ -enum XclChTextType -{ - EXC_CHTEXTTYPE_TITLE, /// Chart title. - EXC_CHTEXTTYPE_LEGEND, /// Chart legend. - EXC_CHTEXTTYPE_AXISTITLE, /// Chart axis titles. - EXC_CHTEXTTYPE_AXISLABEL, /// Chart axis labels. - EXC_CHTEXTTYPE_DATALABEL /// Data point labels. -}; - /** Contains information about auto formatting of a specific chart object type. */ struct XclChFormatInfo { @@ -1298,6 +1296,30 @@ private: XclChTypeInfoMap maInfoMap; /// Maps chart types to type info data. }; +// Chart text and title object helpers ======================================== + +/** Enumerates different text box types for default text formatting and title + positioning. */ +enum XclChTextType +{ + EXC_CHTEXTTYPE_TITLE, /// Chart title. + EXC_CHTEXTTYPE_LEGEND, /// Chart legend. + EXC_CHTEXTTYPE_AXISTITLE, /// Chart axis titles. + EXC_CHTEXTTYPE_AXISLABEL, /// Chart axis labels. + EXC_CHTEXTTYPE_DATALABEL /// Data point labels. +}; + +/** A map key for text and title objects. */ +struct XclChTextKey : public ::std::pair< XclChTextType, ::std::pair< sal_uInt16, sal_uInt16 > > +{ + inline explicit XclChTextKey( XclChTextType eTextType, sal_uInt16 nMainIdx = 0, sal_uInt16 nSubIdx = 0 ) + { first = eTextType; second.first = nMainIdx; second.second = nSubIdx; } +}; + +/** Function prototype receiving a chart document and returning a title shape. */ +typedef ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > + (*XclChGetShapeFunc)( const ::com::sun::star::uno::Reference< ::com::sun::star::chart::XChartDocument >& ); + // Property helpers =========================================================== class XclChObjectTable @@ -1363,10 +1385,6 @@ public: sal_uInt16 ReadRotationProperties( const ScfPropertySet& rPropSet, bool bSupportsStacked ); - /** Reads all legend properties from the passed property set. */ - void ReadLegendProperties( - XclChLegend& rLegend, - const ScfPropertySet& rPropSet ); /** Writes all line properties to the passed property set. */ void WriteLineProperties( @@ -1397,10 +1415,6 @@ public: ScfPropertySet& rPropSet, sal_uInt16 nRotation, bool bSupportsStacked ); - /** Writes all legend properties to the passed property set. */ - void WriteLegendProperties( - ScfPropertySet& rPropSet, - const XclChLegend& rLegend ); private: /** Returns a line property set helper according to the passed property mode. */ @@ -1423,51 +1437,47 @@ private: ScfPropSetHelper maHatchHlpCommon; /// Properties for hatches in common objects. ScfPropSetHelper maHatchHlpFilled; /// Properties for hatches in filled series. ScfPropSetHelper maBitmapHlp; /// Properties for bitmaps. - ScfPropSetHelper maLegendHlp; /// Properties for legend. }; // ============================================================================ /** Base struct for internal root data structs for import and export. */ -class XclChRootData +struct XclChRootData { -public: - typedef ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartDocument > XChartDocRef; + typedef ScfRef< XclChTypeInfoProvider > XclChTypeProvRef; + typedef ScfRef< XclChFormatInfoProvider > XclChFmtInfoProvRef; + typedef ScfRef< XclChObjectTable > XclChObjectTableRef; + typedef ::std::map< XclChTextKey, XclChGetShapeFunc > XclChGetShapeFuncMap; + + ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartDocument > + mxChartDoc; /// The chart document. + Rectangle maChartRect; /// Position and size of the chart shape. + XclChTypeProvRef mxTypeInfoProv; /// Provides info about chart types. + XclChFmtInfoProvRef mxFmtInfoProv; /// Provides info about auto formatting. + XclChObjectTableRef mxLineDashTable; /// Container for line dash styles. + XclChObjectTableRef mxGradientTable; /// Container for gradient fill styles. + XclChObjectTableRef mxHatchTable; /// Container for hatch fill styles. + XclChObjectTableRef mxBitmapTable; /// Container for bitmap fill styles. + XclChGetShapeFuncMap maGetShapeFuncs; /// Maps title shape getter functions. + sal_Int32 mnBorderGapX; /// Border gap to chart space in 1/100mm. + sal_Int32 mnBorderGapY; /// Border gap to chart space in 1/100mm. + double mfUnitSizeX; /// Size of a chart X unit (1/4000 of chart width) in 1/100 mm. + double mfUnitSizeY; /// Size of a chart Y unit (1/4000 of chart height) in 1/100 mm. -public: explicit XclChRootData(); virtual ~XclChRootData(); - /** Returns the API reference of the chart document. */ - XChartDocRef GetChartDoc() const; - - /** Returns the chart type info provider, that contains data about all chart types. */ - inline XclChTypeInfoProvider& GetTypeInfoProvider() const { return *mxTypeInfoProv; } - /** Returns the chart type info provider, that contains data about all chart types. */ - inline XclChFormatInfoProvider& GetFormatInfoProvider() const { return *mxFmtInfoProv; } - - inline XclChObjectTable& GetLineDashTable() const { return *mxLineDashTable; } - inline XclChObjectTable& GetGradientTable() const { return *mxGradientTable; } - inline XclChObjectTable& GetHatchTable() const { return *mxHatchTable; } - inline XclChObjectTable& GetBitmapTable() const { return *mxBitmapTable; } - /** Starts the API chart document conversion. Must be called once before any API access. */ - void InitConversion( XChartDocRef xChartDoc ); + void InitConversion( + const XclRoot& rRoot, + const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartDocument >& rxChartDoc, + const Rectangle& rChartRect ); /** Finishes the API chart document conversion. Must be called once before any API access. */ void FinishConversion(); -private: - typedef ScfRef< XclChTypeInfoProvider > XclChTypeProvRef; - typedef ScfRef< XclChFormatInfoProvider > XclChFmtInfoProvRef; - typedef ScfRef< XclChObjectTable > XclChObjectTableRef; - - XChartDocRef mxChartDoc; /// The chart document. - XclChTypeProvRef mxTypeInfoProv; /// Provides info about chart types. - XclChFmtInfoProvRef mxFmtInfoProv; /// Provides info about auto formatting. - XclChObjectTableRef mxLineDashTable; /// Container for line dash styles. - XclChObjectTableRef mxGradientTable; /// Container for gradient fill styles. - XclChObjectTableRef mxHatchTable; /// Container for hatch fill styles. - XclChObjectTableRef mxBitmapTable; /// Container for bitmap fill styles. + /** Returns the drawing shape interface of the specified title object. */ + ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > + GetTitleShape( const XclChTextKey& rTitleKey ) const; }; // ============================================================================ diff --git a/sc/source/filter/inc/xlroot.hxx b/sc/source/filter/inc/xlroot.hxx index f3b0f78a948c..2f029c74baa9 100644 --- a/sc/source/filter/inc/xlroot.hxx +++ b/sc/source/filter/inc/xlroot.hxx @@ -113,6 +113,8 @@ struct XclRootData XclTracerRef mxTracer; /// Filter tracer. RootDataRef mxRD; /// Old RootData struct. Will be removed. + double mfScreenPixelX; /// Width of a screen pixel (1/100 mm). + double mfScreenPixelY; /// Height of a screen pixel (1/100 mm). long mnCharWidth; /// Width of '0' in default font (twips). SCTAB mnScTab; /// Current Calc sheet index. const bool mbExport; /// false = Import, true = Export. @@ -177,6 +179,11 @@ public: /** Returns the current Calc sheet index. */ inline SCTAB GetCurrScTab() const { return mrData.mnScTab; } + /** Calculates the width of the passed number of pixels in 1/100 mm. */ + sal_Int32 GetHmmFromPixelX( double fPixelX ) const; + /** Calculates the height of the passed number of pixels in 1/100 mm. */ + sal_Int32 GetHmmFromPixelY( double fPixelY ) const; + /** Returns the medium to import from. */ inline SfxMedium& GetMedium() const { return mrData.mrMedium; } /** Returns the document URL of the imported/exported file. */ diff --git a/sc/source/filter/xml/XMLExportDataPilot.cxx b/sc/source/filter/xml/XMLExportDataPilot.cxx index a37617e0b8b9..e43ff21a114d 100644 --- a/sc/source/filter/xml/XMLExportDataPilot.cxx +++ b/sc/source/filter/xml/XMLExportDataPilot.cxx @@ -880,8 +880,8 @@ void ScXMLExportDataPilot::WriteDataPilots(const uno::Reference <sheet::XSpreads rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_SOURCE_NAME, rtl::OUString(pServSource->aParSource)); rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_OBJECT_NAME, rtl::OUString(pServSource->aParName)); rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_USER_NAME, rtl::OUString(pServSource->aParUser)); - // How to write the Passwort? We must know, whether the passwort shoulb be written encrypted and how or not - rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_PASSWORT, rtl::OUString(pServSource->aParPass)); + // #i111754# leave out password attribute as long as DataPilotSource doesn't specify the content + // rExport.AddAttribute(XML_NAMESPACE_TABLE, XML_PASSWORD, rtl::OUString(pServSource->aParPass)); SvXMLElementExport aElemSD(rExport, XML_NAMESPACE_TABLE, XML_SOURCE_SERVICE, sal_True, sal_True); rExport.CheckAttrList(); } diff --git a/sc/source/filter/xml/xmlexprt.cxx b/sc/source/filter/xml/xmlexprt.cxx index d38fd7aed7b6..27aba3b27d9c 100644 --- a/sc/source/filter/xml/xmlexprt.cxx +++ b/sc/source/filter/xml/xmlexprt.cxx @@ -3591,8 +3591,8 @@ sal_Bool ScXMLExport::IsCellEqual (ScMyCell& aCell1, ScMyCell& aCell2) { if (!aCell1.bHasAnnotation || (aCell1.bHasAnnotation && sal_False/*IsAnnotationEqual(aCell1.xCell, aCell2.xCell)*/)) // no longer compareable { - if (((aCell1.nStyleIndex == aCell2.nStyleIndex) && ((aCell1.bIsAutoStyle == aCell2.bIsAutoStyle) || - (aCell1.nStyleIndex == aCell2.nStyleIndex)) && (aCell1.nStyleIndex == -1)) && + if ((((aCell1.nStyleIndex == aCell2.nStyleIndex) && (aCell1.bIsAutoStyle == aCell2.bIsAutoStyle)) || + ((aCell1.nStyleIndex == aCell2.nStyleIndex) && (aCell1.nStyleIndex == -1))) && (aCell1.nValidationIndex == aCell2.nValidationIndex) && IsCellTypeEqual(aCell1, aCell2)) { diff --git a/sc/source/filter/xml/xmlexternaltabi.cxx b/sc/source/filter/xml/xmlexternaltabi.cxx index ce1f58f5d912..083a73d81872 100644 --- a/sc/source/filter/xml/xmlexternaltabi.cxx +++ b/sc/source/filter/xml/xmlexternaltabi.cxx @@ -370,7 +370,7 @@ SvXMLImportContext* ScXMLExternalRefCellContext::CreateChildContext( const SvXMLTokenMap& rTokenMap = mrScImport.GetTableRowCellElemTokenMap(); sal_uInt16 nToken = rTokenMap.Get(nPrefix, rLocalName); if (nToken == XML_TOK_TABLE_ROW_CELL_P) - return new ScXMLExternalRefCellTextContext(mrScImport, nPrefix, rLocalName, xAttrList, maCellString); + return new ScXMLExternalRefCellTextContext(mrScImport, nPrefix, rLocalName, xAttrList, *this); return new SvXMLImportContext(GetImport(), nPrefix, rLocalName); } @@ -399,14 +399,20 @@ void ScXMLExternalRefCellContext::EndElement() } } +void ScXMLExternalRefCellContext::SetCellString(const OUString& rStr) +{ + maCellString = rStr; +} + // ============================================================================ ScXMLExternalRefCellTextContext::ScXMLExternalRefCellTextContext( ScXMLImport& rImport, USHORT nPrefix, const OUString& rLName, - const Reference<XAttributeList>& /*xAttrList*/, OUString& rCellString ) : + const Reference<XAttributeList>& /*xAttrList*/, + ScXMLExternalRefCellContext& rParent ) : SvXMLImportContext( rImport, nPrefix, rLName ), mrScImport(rImport), - mrCellString(rCellString) + mrParent(rParent) { } @@ -422,9 +428,10 @@ SvXMLImportContext* ScXMLExternalRefCellTextContext::CreateChildContext( void ScXMLExternalRefCellTextContext::Characters(const OUString& rChar) { - mrCellString = rChar; + maCellStrBuf.append(rChar); } void ScXMLExternalRefCellTextContext::EndElement() { + mrParent.SetCellString(maCellStrBuf.makeStringAndClear()); } diff --git a/sc/source/filter/xml/xmlexternaltabi.hxx b/sc/source/filter/xml/xmlexternaltabi.hxx index 0007a8b29702..6aaff181315e 100644 --- a/sc/source/filter/xml/xmlexternaltabi.hxx +++ b/sc/source/filter/xml/xmlexternaltabi.hxx @@ -29,6 +29,7 @@ #define SC_XMLEXTERNALTABI_HXX #include <xmloff/xmlictxt.hxx> +#include "rtl/ustrbuf.hxx" class ScXMLImport; struct ScXMLExternalTabData; @@ -129,6 +130,8 @@ public: virtual void EndElement(); + void SetCellString(const ::rtl::OUString& rStr); + private: ScXMLImport& mrScImport; ScXMLExternalTabData& mrExternalRefInfo; @@ -150,7 +153,7 @@ public: const ::rtl::OUString& rLName, const ::com::sun::star::uno::Reference< ::com::sun::star::xml::sax::XAttributeList>& xAttrList, - ::rtl::OUString& rCellString ); + ScXMLExternalRefCellContext& rParent ); virtual ~ScXMLExternalRefCellTextContext(); @@ -165,7 +168,9 @@ public: private: ScXMLImport& mrScImport; - ::rtl::OUString& mrCellString; + ScXMLExternalRefCellContext& mrParent; + + ::rtl::OUStringBuffer maCellStrBuf; }; #endif diff --git a/sc/source/filter/xml/xmlimprt.cxx b/sc/source/filter/xml/xmlimprt.cxx index d1ef48bfa9ed..69c7144191d6 100644 --- a/sc/source/filter/xml/xmlimprt.cxx +++ b/sc/source/filter/xml/xmlimprt.cxx @@ -1368,7 +1368,7 @@ const SvXMLTokenMap& ScXMLImport::GetDataPilotTableSourceServiceAttrTokenMap() { XML_NAMESPACE_TABLE, XML_SOURCE_NAME, XML_TOK_SOURCE_SERVICE_ATTR_SOURCE_NAME }, { XML_NAMESPACE_TABLE, XML_OBJECT_NAME, XML_TOK_SOURCE_SERVICE_ATTR_OBJECT_NAME }, { XML_NAMESPACE_TABLE, XML_USER_NAME, XML_TOK_SOURCE_SERVICE_ATTR_USER_NAME }, - { XML_NAMESPACE_TABLE, XML_PASSWORT, XML_TOK_SOURCE_SERVICE_ATTR_PASSWORD }, + { XML_NAMESPACE_TABLE, XML_PASSWORD, XML_TOK_SOURCE_SERVICE_ATTR_PASSWORD }, XML_TOKEN_MAP_END }; diff --git a/sc/source/filter/xml/xmlstyle.cxx b/sc/source/filter/xml/xmlstyle.cxx index f9f0d063a843..733a11c9a1da 100644 --- a/sc/source/filter/xml/xmlstyle.cxx +++ b/sc/source/filter/xml/xmlstyle.cxx @@ -1039,8 +1039,10 @@ sal_Bool XmlScPropHdl_CellProtection::exportXML( rStrExpValue = GetXMLToken(XML_NONE); bRetval = sal_True; } - else if (aCellProtection.IsHidden && aCellProtection.IsLocked) + else if (aCellProtection.IsHidden) { + // #i105964# "Hide all" implies "Protected" in the UI, so it must be saved as "hidden-and-protected" + // even if "IsLocked" is not set in the CellProtection struct. rStrExpValue = GetXMLToken(XML_HIDDEN_AND_PROTECTED); bRetval = sal_True; } diff --git a/sc/source/filter/xml/xmltabi.cxx b/sc/source/filter/xml/xmltabi.cxx index 9afc08308feb..095b6ee6d450 100644 --- a/sc/source/filter/xml/xmltabi.cxx +++ b/sc/source/filter/xml/xmltabi.cxx @@ -98,21 +98,27 @@ static bool lcl_isExternalRefCache(const rtl::OUString& rName, rtl::OUString& rU const sal_Unicode c = p[i]; if (i <= 7) { + // Checking the prefix 'file://'. if (c != aPrefix[i]) return false; } - else if (c == '#') + else if (bInUrl) { - if (cPrev != '\'') - return false; + // parsing file URL + if (c == '#') + { + if (cPrev != '\'') + return false; - rUrl = aUrlBuf.makeStringAndClear(); - rUrl = rUrl.copy(0, rUrl.getLength()-1); // remove the trailing single-quote. - bInUrl = false; + rUrl = aUrlBuf.makeStringAndClear(); + rUrl = rUrl.copy(0, rUrl.getLength()-1); // remove the trailing single-quote. + bInUrl = false; + } + else + aUrlBuf.append(c); } - else if (bInUrl) - aUrlBuf.append(c); else + // parsing sheet name. aTabNameBuf.append(c); cPrev = c; @@ -206,6 +212,7 @@ ScXMLTableContext::ScXMLTableContext( ScXMLImport& rImport, ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager(); pExternalRefInfo->mnFileId = pRefMgr->getExternalFileId(aExtUrl); pExternalRefInfo->mpCacheTable = pRefMgr->getCacheTable(pExternalRefInfo->mnFileId, aExtTabName, true); + pExternalRefInfo->mpCacheTable->setWholeTableCached(); } } else diff --git a/sc/source/ui/app/inputhdl.cxx b/sc/source/ui/app/inputhdl.cxx index 28f178565da0..55aa0986d2ec 100644 --- a/sc/source/ui/app/inputhdl.cxx +++ b/sc/source/ui/app/inputhdl.cxx @@ -950,7 +950,7 @@ void ScInputHandler::ShowTipBelow( const String& rText ) } aPos = pTipVisibleSecParent->OutputToScreenPixel( aPos ); Rectangle aRect( aPos, aPos ); - USHORT nAlign = QUICKHELP_LEFT | QUICKHELP_TOP; + USHORT nAlign = QUICKHELP_LEFT | QUICKHELP_TOP | QUICKHELP_NOEVADEPOINTER; nTipVisibleSec = Help::ShowTip(pTipVisibleSecParent, aRect, rText, nAlign); pTipVisibleSecParent->AddEventListener( LINK( this, ScInputHandler, ShowHideTipVisibleSecParentListener ) ); } diff --git a/sc/source/ui/app/makefile.mk b/sc/source/ui/app/makefile.mk index a5e4fe8cc024..a7ff3fe86d7d 100644 --- a/sc/source/ui/app/makefile.mk +++ b/sc/source/ui/app/makefile.mk @@ -57,8 +57,10 @@ SLOFILES = \ EXCEPTIONSFILES= \ $(SLO)$/drwtrans.obj \ + $(SLO)$/scdll.obj \ $(SLO)$/scmod2.obj \ $(SLO)$/scmod.obj \ + $(SLO)$/typemap.obj \ $(SLO)$/client.obj \ $(SLO)$/inputwin.obj diff --git a/sc/source/ui/cctrl/makefile.mk b/sc/source/ui/cctrl/makefile.mk index 17fd9b40cb95..531013ea1c2e 100644 --- a/sc/source/ui/cctrl/makefile.mk +++ b/sc/source/ui/cctrl/makefile.mk @@ -41,6 +41,7 @@ LIBTARGET=NO # --- Files -------------------------------------------------------- EXCEPTIONSFILES= \ + $(SLO)$/tbinsert.obj \ $(SLO)$/tbzoomsliderctrl.obj \ $(SLO)$/dpcontrol.obj diff --git a/sc/source/ui/docshell/docfunc.cxx b/sc/source/ui/docshell/docfunc.cxx index 01d03d49b50a..e08c930301cf 100644 --- a/sc/source/ui/docshell/docfunc.cxx +++ b/sc/source/ui/docshell/docfunc.cxx @@ -98,9 +98,11 @@ #include "scui_def.hxx" //CHINA001 #include "tabprotection.hxx" #include "clipparam.hxx" +#include "externalrefmgr.hxx" #include <memory> #include <basic/basmgr.hxx> +#include <boost/scoped_ptr.hpp> using namespace com::sun::star; using ::com::sun::star::uno::Sequence; @@ -1042,6 +1044,10 @@ BOOL ScDocFunc::SetCellText( const ScAddress& rPos, const String& rText, { if ( bEnglish ) { + ::boost::scoped_ptr<ScExternalRefManager::ApiGuard> pExtRefGuard; + if (bApi) + pExtRefGuard.reset(new ScExternalRefManager::ApiGuard(pDoc)); + // code moved to own method InterpretEnglishString because it is also used in // ScCellRangeObj::setFormulaArray diff --git a/sc/source/ui/docshell/externalrefmgr.cxx b/sc/source/ui/docshell/externalrefmgr.cxx index e7b04afa9c4f..0569e95605b1 100644 --- a/sc/source/ui/docshell/externalrefmgr.cxx +++ b/sc/source/ui/docshell/externalrefmgr.cxx @@ -65,6 +65,8 @@ #include <memory> #include <algorithm> +#include <boost/scoped_ptr.hpp> + using ::std::auto_ptr; using ::com::sun::star::uno::Any; using ::rtl::OUString; @@ -135,6 +137,69 @@ private: ScExternalRefManager::LinkUpdateType meType; }; +struct UpdateFormulaCell : public unary_function<ScFormulaCell*, void> +{ + void operator() (ScFormulaCell* pCell) const + { + // Check to make sure the cell really contains ocExternalRef. + // External names, external cell and range references all have a + // ocExternalRef token. + const ScTokenArray* pCode = pCell->GetCode(); + if (!pCode->HasOpCode( ocExternalRef)) + return; + + ScTokenArray* pArray = pCell->GetCode(); + if (pArray) + // Clear the error code, or a cell with error won't get re-compiled. + pArray->SetCodeError(0); + + pCell->SetCompile(true); + pCell->CompileTokenArray(); + pCell->SetDirty(); + } +}; + +class RemoveFormulaCell : public unary_function<pair<const sal_uInt16, ScExternalRefManager::RefCellSet>, void> +{ +public: + explicit RemoveFormulaCell(ScFormulaCell* p) : mpCell(p) {} + void operator() (pair<const sal_uInt16, ScExternalRefManager::RefCellSet>& r) const + { + r.second.erase(mpCell); + } +private: + ScFormulaCell* mpCell; +}; + +class ConvertFormulaToStatic : public unary_function<ScFormulaCell*, void> +{ +public: + explicit ConvertFormulaToStatic(ScDocument* pDoc) : mpDoc(pDoc) {} + void operator() (ScFormulaCell* pCell) const + { + ScAddress aPos = pCell->aPos; + + // We don't check for empty cells because empty external cells are + // treated as having a value of 0. + + if (pCell->IsValue()) + { + // Turn this into value cell. + double fVal = pCell->GetValue(); + mpDoc->PutCell(aPos, new ScValueCell(fVal)); + } + else + { + // string cell otherwise. + String aVal; + pCell->GetString(aVal); + mpDoc->PutCell(aPos, new ScStringCell(aVal)); + } + } +private: + ScDocument* mpDoc; +}; + } // ============================================================================ @@ -170,7 +235,7 @@ bool ScExternalRefCache::Table::isReferenced() const return meReferenced != UNREFERENCED; } -void ScExternalRefCache::Table::setCell(SCCOL nCol, SCROW nRow, TokenRef pToken, sal_uInt32 nFmtIndex) +void ScExternalRefCache::Table::setCell(SCCOL nCol, SCROW nRow, TokenRef pToken, sal_uInt32 nFmtIndex, bool bSetCacheRange) { using ::std::pair; RowsDataType::iterator itrRow = maRows.find(nRow); @@ -193,6 +258,8 @@ void ScExternalRefCache::Table::setCell(SCCOL nCol, SCROW nRow, TokenRef pToken, aCell.mxToken = pToken; aCell.mnFmtIndex = nFmtIndex; rRow.insert(RowDataType::value_type(nCol, aCell)); + if (bSetCacheRange) + setCachedCell(nCol, nRow); } ScExternalRefCache::TokenRef ScExternalRefCache::Table::getCell(SCCOL nCol, SCROW nRow, sal_uInt32* pnFmtIndex) const @@ -201,7 +268,7 @@ ScExternalRefCache::TokenRef ScExternalRefCache::Table::getCell(SCCOL nCol, SCRO if (itrTable == maRows.end()) { // this table doesn't have the specified row. - return TokenRef(); + return getEmptyOrNullToken(nCol, nRow); } const RowDataType& rRowData = itrTable->second; @@ -209,7 +276,7 @@ ScExternalRefCache::TokenRef ScExternalRefCache::Table::getCell(SCCOL nCol, SCRO if (itrRow == rRowData.end()) { // this row doesn't have the specified column. - return TokenRef(); + return getEmptyOrNullToken(nCol, nRow); } const Cell& rCell = itrRow->second; @@ -225,13 +292,14 @@ bool ScExternalRefCache::Table::hasRow( SCROW nRow ) const return itrRow != maRows.end(); } -void ScExternalRefCache::Table::getAllRows(vector<SCROW>& rRows) const +void ScExternalRefCache::Table::getAllRows(vector<SCROW>& rRows, SCROW nLow, SCROW nHigh) const { vector<SCROW> aRows; aRows.reserve(maRows.size()); RowsDataType::const_iterator itr = maRows.begin(), itrEnd = maRows.end(); for (; itr != itrEnd; ++itr) - aRows.push_back(itr->first); + if (nLow <= itr->first && itr->first <= nHigh) + aRows.push_back(itr->first); // hash map is not ordered, so we need to explicitly sort it. ::std::sort(aRows.begin(), aRows.end()); @@ -258,7 +326,7 @@ void ScExternalRefCache::Table::getAllRows(vector<SCROW>& rRows) const return aRange; } -void ScExternalRefCache::Table::getAllCols(SCROW nRow, vector<SCCOL>& rCols) const +void ScExternalRefCache::Table::getAllCols(SCROW nRow, vector<SCCOL>& rCols, SCCOL nLow, SCCOL nHigh) const { RowsDataType::const_iterator itrRow = maRows.find(nRow); if (itrRow == maRows.end()) @@ -270,7 +338,8 @@ void ScExternalRefCache::Table::getAllCols(SCROW nRow, vector<SCCOL>& rCols) con aCols.reserve(rRowData.size()); RowDataType::const_iterator itrCol = rRowData.begin(), itrColEnd = rRowData.end(); for (; itrCol != itrColEnd; ++itrCol) - aCols.push_back(itrCol->first); + if (nLow <= itrCol->first && itrCol->first <= nHigh) + aCols.push_back(itrCol->first); // hash map is not ordered, so we need to explicitly sort it. ::std::sort(aCols.begin(), aCols.end()); @@ -319,6 +388,54 @@ void ScExternalRefCache::Table::getAllNumberFormats(vector<sal_uInt32>& rNumFmts } } +const ScRangeList& ScExternalRefCache::Table::getCachedRanges() const +{ + return maCachedRanges; +} + +bool ScExternalRefCache::Table::isRangeCached(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2) const +{ + return maCachedRanges.In(ScRange(nCol1, nRow1, 0, nCol2, nRow2, 0)); +} + +void ScExternalRefCache::Table::setCachedCell(SCCOL nCol, SCROW nRow) +{ + setCachedCellRange(nCol, nRow, nCol, nRow); +} + +void ScExternalRefCache::Table::setCachedCellRange(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2) +{ + ScRange aRange(nCol1, nRow1, 0, nCol2, nRow2, 0); + if (!maCachedRanges.Count()) + maCachedRanges.Append(aRange); + else + maCachedRanges.Join(aRange); + + String aStr; + maCachedRanges.Format(aStr, SCA_VALID); +} + +void ScExternalRefCache::Table::setWholeTableCached() +{ + setCachedCellRange(0, 0, MAXCOL, MAXROW); +} + +bool ScExternalRefCache::Table::isInCachedRanges(SCCOL nCol, SCROW nRow) const +{ + return maCachedRanges.In(ScRange(nCol, nRow, 0, nCol, nRow, 0)); +} + +ScExternalRefCache::TokenRef ScExternalRefCache::Table::getEmptyOrNullToken( + SCCOL nCol, SCROW nRow) const +{ + if (isInCachedRanges(nCol, nRow)) + { + TokenRef p(new ScEmptyCellToken(false, false)); + return p; + } + return TokenRef(); +} + // ---------------------------------------------------------------------------- ScExternalRefCache::TableName::TableName(const String& rUpper, const String& rReal) : @@ -383,8 +500,7 @@ const String* ScExternalRefCache::getRealRangeName(sal_uInt16 nFileId, const Str } ScExternalRefCache::TokenRef ScExternalRefCache::getCellData( - sal_uInt16 nFileId, const String& rTabName, SCCOL nCol, SCROW nRow, - bool bEmptyCellOnNull, bool bWriteEmpty, sal_uInt32* pnFmtIndex) + sal_uInt16 nFileId, const String& rTabName, SCCOL nCol, SCROW nRow, sal_uInt32* pnFmtIndex) { DocDataType::const_iterator itrDoc = maDocs.find(nFileId); if (itrDoc == maDocs.end()) @@ -409,18 +525,11 @@ ScExternalRefCache::TokenRef ScExternalRefCache::getCellData( return TokenRef(); } - TokenRef pToken = pTableData->getCell(nCol, nRow, pnFmtIndex); - if (!pToken && bEmptyCellOnNull) - { - pToken.reset(new ScEmptyCellToken(false, false)); - if (bWriteEmpty) - pTableData->setCell(nCol, nRow, pToken); - } - return pToken; + return pTableData->getCell(nCol, nRow, pnFmtIndex); } ScExternalRefCache::TokenArrayRef ScExternalRefCache::getCellRangeData( - sal_uInt16 nFileId, const String& rTabName, const ScRange& rRange, bool bEmptyCellOnNull, bool bWriteEmpty) + sal_uInt16 nFileId, const String& rTabName, const ScRange& rRange) { DocDataType::iterator itrDoc = maDocs.find(nFileId); if (itrDoc == maDocs.end()) @@ -450,13 +559,14 @@ ScExternalRefCache::TokenArrayRef ScExternalRefCache::getCellRangeData( return TokenArrayRef(); ScRange aCacheRange( nCol1, nRow1, static_cast<SCTAB>(nTabFirstId), nCol2, nRow2, static_cast<SCTAB>(nTabLastId)); + RangeArrayMap::const_iterator itrRange = rDoc.maRangeArrays.find( aCacheRange); if (itrRange != rDoc.maRangeArrays.end()) - { + // Cache hit! return itrRange->second; - } - TokenArrayRef pArray(new ScTokenArray); + ::boost::scoped_ptr<ScRange> pNewRange; + TokenArrayRef pArray; bool bFirstTab = true; for (size_t nTab = nTabFirstId; nTab <= nTabLastId; ++nTab) { @@ -464,27 +574,72 @@ ScExternalRefCache::TokenArrayRef ScExternalRefCache::getCellRangeData( if (!pTab.get()) return TokenArrayRef(); + SCCOL nDataCol1 = nCol1, nDataCol2 = nCol2; + SCROW nDataRow1 = nRow1, nDataRow2 = nRow2; + + if (!pTab->isRangeCached(nDataCol1, nDataRow1, nDataCol2, nDataRow2)) + { + // specified range is not entirely within cached ranges. + return TokenArrayRef(); + } + ScMatrixRef xMat = new ScMatrix( - static_cast<SCSIZE>(nCol2-nCol1+1), static_cast<SCSIZE>(nRow2-nRow1+1)); + static_cast<SCSIZE>(nDataCol2-nDataCol1+1), static_cast<SCSIZE>(nDataRow2-nDataRow1+1)); - for (SCROW nRow = nRow1; nRow <= nRow2; ++nRow) +#if 0 + // TODO: Switch to this code block once we have support for sparsely-filled + // matrices in ScMatrix. + + // Only fill non-empty cells, for better performance. + vector<SCROW> aRows; + pTab->getAllRows(aRows, nDataRow1, nDataRow2); + for (vector<SCROW>::const_iterator itr = aRows.begin(), itrEnd = aRows.end(); itr != itrEnd; ++itr) { - for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol) + SCROW nRow = *itr; + vector<SCCOL> aCols; + pTab->getAllCols(nRow, aCols, nDataCol1, nDataCol2); + for (vector<SCCOL>::const_iterator itrCol = aCols.begin(), itrColEnd = aCols.end(); itrCol != itrColEnd; ++itrCol) { + SCCOL nCol = *itrCol; TokenRef pToken = pTab->getCell(nCol, nRow); if (!pToken) + // This should never happen! + return TokenArrayRef(); + + SCSIZE nC = nCol - nDataCol1, nR = nRow - nDataRow1; + switch (pToken->GetType()) { - if (bEmptyCellOnNull) - { - pToken.reset(new ScEmptyCellToken(false, false)); - if (bWriteEmpty) - pTab->setCell(nCol, nRow, pToken); - } - else - return TokenArrayRef(); + case svDouble: + xMat->PutDouble(pToken->GetDouble(), nC, nR); + break; + case svString: + xMat->PutString(pToken->GetString(), nC, nR); + break; + default: + ; } + } + } +#else + vector<SCROW> aRows; + pTab->getAllRows(aRows, nDataRow1, nDataRow2); + if (aRows.empty()) + // Cache is empty. + return TokenArrayRef(); + else + // Trim the column below the last non-empty row. + nDataRow2 = aRows.back(); + // Empty all matrix elements first, and fill only non-empty elements. + for (SCROW nRow = nDataRow1; nRow <= nDataRow2; ++nRow) + { + for (SCCOL nCol = nDataCol1; nCol <= nDataCol2; ++nCol) + { + TokenRef pToken = pTab->getCell(nCol, nRow); SCSIZE nC = nCol - nCol1, nR = nRow - nRow1; + if (!pToken) + return TokenArrayRef(); + switch (pToken->GetType()) { case svDouble: @@ -498,17 +653,27 @@ ScExternalRefCache::TokenArrayRef ScExternalRefCache::getCellRangeData( } } } +#endif if (!bFirstTab) pArray->AddOpCode(ocSep); ScMatrix* pMat2 = xMat; ScMatrixToken aToken(pMat2); + if (!pArray) + pArray.reset(new ScTokenArray); pArray->AddToken(aToken); bFirstTab = false; + + if (!pNewRange) + pNewRange.reset(new ScRange(nDataCol1, nDataRow1, 0, nDataCol2, nDataRow2, 0)); + else + pNewRange->ExtendTo(ScRange(nDataCol1, nDataRow1, 0, nDataCol2, nDataRow2, 0)); } - rDoc.maRangeArrays.insert( RangeArrayMap::value_type( aCacheRange, pArray)); + + if (pNewRange) + rDoc.maRangeArrays.insert( RangeArrayMap::value_type(*pNewRange, pArray)); return pArray; } @@ -539,7 +704,7 @@ void ScExternalRefCache::setRangeNameTokens(sal_uInt16 nFileId, const String& rN pDoc->maRealRangeNameMap.insert(NamePairMap::value_type(aUpperName, rName)); } -void ScExternalRefCache::setCellData(sal_uInt16 nFileId, const String& rTabName, SCROW nRow, SCCOL nCol, +void ScExternalRefCache::setCellData(sal_uInt16 nFileId, const String& rTabName, SCCOL nCol, SCROW nRow, TokenRef pToken, sal_uInt32 nFmtIndex) { if (!isDocInitialized(nFileId)) @@ -564,6 +729,7 @@ void ScExternalRefCache::setCellData(sal_uInt16 nFileId, const String& rTabName, pTableData.reset(new Table); pTableData->setCell(nCol, nRow, pToken, nFmtIndex); + pTableData->setCachedCell(nCol, nRow); } void ScExternalRefCache::setCellRangeData(sal_uInt16 nFileId, const ScRange& rRange, const vector<SingleRangeData>& rData, @@ -609,20 +775,27 @@ void ScExternalRefCache::setCellRangeData(sal_uInt16 nFileId, const ScRange& rRa SCSIZE nC = nCol - nCol1, nR = nRow - nRow1; TokenRef pToken; const ScMatrixRef& pMat = itrData->mpRangeData; + if (pMat->IsEmpty(nC, nR)) + // Don't cache empty cells. + continue; + if (pMat->IsValue(nC, nR)) pToken.reset(new formula::FormulaDoubleToken(pMat->GetDouble(nC, nR))); else if (pMat->IsString(nC, nR)) pToken.reset(new formula::FormulaStringToken(pMat->GetString(nC, nR))); - else - pToken.reset(new ScEmptyCellToken(false, false)); - pTabData->setCell(nCol, nRow, pToken); + if (pToken) + // Don't mark this cell 'cached' here, for better performance. + pTabData->setCell(nCol, nRow, pToken, 0, false); } } + // Mark the whole range 'cached'. + pTabData->setCachedCellRange(nCol1, nRow1, nCol2, nRow2); } size_t nTabLastId = nTabFirstId + rRange.aEnd.Tab() - rRange.aStart.Tab(); ScRange aCacheRange( nCol1, nRow1, static_cast<SCTAB>(nTabFirstId), nCol2, nRow2, static_cast<SCTAB>(nTabLastId)); + rDoc.maRangeArrays.insert( RangeArrayMap::value_type( aCacheRange, pArray)); } @@ -1019,6 +1192,9 @@ ScExternalRefCache::TableTypeRef ScExternalRefCache::getCacheTable(sal_uInt16 nF { // specified table found. if( pnIndex ) *pnIndex = nIndex; + if (bCreateNew && !rDoc.maTables[nIndex]) + rDoc.maTables[nIndex].reset(new Table); + return rDoc.maTables[nIndex]; } @@ -1186,11 +1362,11 @@ static FormulaToken* lcl_convertToToken(ScBaseCell* pCell) return NULL; } -static ScTokenArray* lcl_convertToTokenArray(ScDocument* pSrcDoc, const ScRange& rRange, +static ScTokenArray* lcl_convertToTokenArray(ScDocument* pSrcDoc, ScRange& rRange, vector<ScExternalRefCache::SingleRangeData>& rCacheData) { - const ScAddress& s = rRange.aStart; - const ScAddress& e = rRange.aEnd; + ScAddress& s = rRange.aStart; + ScAddress& e = rRange.aEnd; SCTAB nTab1 = s.Tab(), nTab2 = e.Tab(); SCCOL nCol1 = s.Col(), nCol2 = e.Col(); @@ -1204,19 +1380,35 @@ static ScTokenArray* lcl_convertToTokenArray(ScDocument* pSrcDoc, const ScRange& // range to it. return NULL; + ::boost::scoped_ptr<ScRange> pUsedRange; + auto_ptr<ScTokenArray> pArray(new ScTokenArray); bool bFirstTab = true; vector<ScExternalRefCache::SingleRangeData>::iterator itrCache = rCacheData.begin(), itrCacheEnd = rCacheData.end(); + for (SCTAB nTab = nTab1; nTab <= nTab2 && itrCache != itrCacheEnd; ++nTab, ++itrCache) { + // Only loop within the data area. + SCCOL nDataCol1 = nCol1, nDataCol2 = nCol2; + SCROW nDataRow1 = nRow1, nDataRow2 = nRow2; + if (!pSrcDoc->ShrinkToDataArea(nTab, nDataCol1, nDataRow1, nDataCol2, nDataRow2)) + // no data within specified range. + continue; + + if (pUsedRange.get()) + // Make sure the used area only grows, not shrinks. + pUsedRange->ExtendTo(ScRange(nDataCol1, nDataRow1, 0, nDataCol2, nDataRow2, 0)); + else + pUsedRange.reset(new ScRange(nDataCol1, nDataRow1, 0, nDataCol2, nDataRow2, 0)); + ScMatrixRef xMat = new ScMatrix( - static_cast<SCSIZE>(nCol2-nCol1+1), - static_cast<SCSIZE>(nRow2-nRow1+1)); + static_cast<SCSIZE>(nDataCol2-nDataCol1+1), + static_cast<SCSIZE>(nDataRow2-nDataRow1+1)); - for (SCCOL nCol = nCol1; nCol <= nCol2; ++nCol) + for (SCCOL nCol = nDataCol1; nCol <= nDataCol2; ++nCol) { - for (SCROW nRow = nRow1; nRow <= nRow2; ++nRow) + for (SCROW nRow = nDataRow1; nRow <= nDataRow2; ++nRow) { SCSIZE nC = nCol - nCol1, nR = nRow - nRow1; ScBaseCell* pCell; @@ -1283,12 +1475,38 @@ static ScTokenArray* lcl_convertToTokenArray(ScDocument* pSrcDoc, const ScRange& bFirstTab = false; } + + if (!pUsedRange.get()) + return NULL; + + s.SetCol(pUsedRange->aStart.Col()); + s.SetRow(pUsedRange->aStart.Row()); + e.SetCol(pUsedRange->aEnd.Col()); + e.SetRow(pUsedRange->aEnd.Row()); + + return pArray.release(); +} + +static ScTokenArray* lcl_fillEmptyMatrix(const ScRange& rRange) +{ + SCSIZE nC = static_cast<SCSIZE>(rRange.aEnd.Col()-rRange.aStart.Col()+1); + SCSIZE nR = static_cast<SCSIZE>(rRange.aEnd.Row()-rRange.aStart.Row()+1); + ScMatrixRef xMat = new ScMatrix(nC, nR); + for (SCSIZE i = 0; i < nC; ++i) + for (SCSIZE j = 0; j < nR; ++j) + xMat->PutEmpty(i, j); + + ScMatrix* pMat2 = xMat; + ScMatrixToken aToken(pMat2); + auto_ptr<ScTokenArray> pArray(new ScTokenArray); + pArray->AddToken(aToken); return pArray.release(); } ScExternalRefManager::ScExternalRefManager(ScDocument* pDoc) : mpDoc(pDoc), - bInReferenceMarking(false) + mbInReferenceMarking(false), + mbUserInteractionEnabled(true) { maSrcDocTimer.SetTimeoutHdl( LINK(this, ScExternalRefManager, TimeOutHdl) ); maSrcDocTimer.SetTimeout(SRCDOC_SCAN_INTERVAL); @@ -1316,236 +1534,28 @@ ScExternalRefCache::TableTypeRef ScExternalRefManager::getCacheTable(sal_uInt16 // ============================================================================ -ScExternalRefManager::RefCells::TabItem::TabItem(SCTAB nIndex) : - mnIndex(nIndex) -{ -} - -ScExternalRefManager::RefCells::TabItem::TabItem(const TabItem& r) : - mnIndex(r.mnIndex), - maCols(r.maCols) -{ -} - -ScExternalRefManager::RefCells::RefCells() -{ -} - -ScExternalRefManager::RefCells::~RefCells() -{ -} - -list<ScExternalRefManager::RefCells::TabItemRef>::iterator ScExternalRefManager::RefCells::getTabPos(SCTAB nTab) -{ - list<TabItemRef>::iterator itr = maTables.begin(), itrEnd = maTables.end(); - for (; itr != itrEnd; ++itr) - if ((*itr)->mnIndex >= nTab) - return itr; - // Not found. return the end position. - return itrEnd; -} - -void ScExternalRefManager::RefCells::insertCell(const ScAddress& rAddr) -{ - SCTAB nTab = rAddr.Tab(); - SCCOL nCol = rAddr.Col(); - SCROW nRow = rAddr.Row(); - - // Search by table index. - list<TabItemRef>::iterator itrTab = getTabPos(nTab); - TabItemRef xTabRef; - if (itrTab == maTables.end()) - { - // All previous tables come before the specificed table. - xTabRef.reset(new TabItem(nTab)); - maTables.push_back(xTabRef); - } - else if ((*itrTab)->mnIndex > nTab) - { - // Insert at the current iterator position. - xTabRef.reset(new TabItem(nTab)); - maTables.insert(itrTab, xTabRef); - } - else if ((*itrTab)->mnIndex == nTab) - { - // The table found. - xTabRef = *itrTab; - } - ColSet& rCols = xTabRef->maCols; - - // Then by column index. - ColSet::iterator itrCol = rCols.find(nCol); - if (itrCol == rCols.end()) - { - RowSet aRows; - pair<ColSet::iterator, bool> r = rCols.insert(ColSet::value_type(nCol, aRows)); - if (!r.second) - // column insertion failed. - return; - itrCol = r.first; - } - RowSet& rRows = itrCol->second; - - // Finally, insert the row index. - rRows.insert(nRow); -} - -void ScExternalRefManager::RefCells::removeCell(const ScAddress& rAddr) -{ - SCTAB nTab = rAddr.Tab(); - SCCOL nCol = rAddr.Col(); - SCROW nRow = rAddr.Row(); - - // Search by table index. - list<TabItemRef>::iterator itrTab = getTabPos(nTab); - if (itrTab == maTables.end() || (*itrTab)->mnIndex != nTab) - // No such table. - return; - - ColSet& rCols = (*itrTab)->maCols; - - // Then by column index. - ColSet::iterator itrCol = rCols.find(nCol); - if (itrCol == rCols.end()) - // No such column - return; - - RowSet& rRows = itrCol->second; - rRows.erase(nRow); -} - -void ScExternalRefManager::RefCells::moveTable(SCTAB nOldTab, SCTAB nNewTab, bool bCopy) -{ - if (nOldTab == nNewTab) - // Nothing to do here. - return; - - list<TabItemRef>::iterator itrOld = getTabPos(nOldTab); - if (itrOld == maTables.end() || (*itrOld)->mnIndex != nOldTab) - // No table to move or copy. - return; - - list<TabItemRef>::iterator itrNew = getTabPos(nNewTab); - if (bCopy) - { - // Simply make a duplicate of the original table, insert it at the - // new tab position, and increment the table index for all tables - // that come after that inserted table. - - TabItemRef xNewTab(new TabItem(*(*itrOld))); - xNewTab->mnIndex = nNewTab; - maTables.insert(itrNew, xNewTab); - list<TabItemRef>::iterator itr = itrNew, itrEnd = maTables.end(); - if (itr != itrEnd) // #i99807# check that itr is not at end already - for (++itr; itr != itrEnd; ++itr) - (*itr)->mnIndex += 1; - } - else - { - if (itrOld == itrNew) - { - // No need to move the table. Just update the table index. - (*itrOld)->mnIndex = nNewTab; - return; - } - - if (nOldTab < nNewTab) - { - // Iterate from the old tab position to the new tab position (not - // inclusive of the old tab itself), and decrement their tab - // index by one. - list<TabItemRef>::iterator itr = itrOld; - for (++itr; itr != itrNew; ++itr) - (*itr)->mnIndex -= 1; - - // Insert a duplicate of the original table. This does not - // invalidate the iterators. - (*itrOld)->mnIndex = nNewTab - 1; - if (itrNew == maTables.end()) - maTables.push_back(*itrOld); - else - maTables.insert(itrNew, *itrOld); - - // Remove the original table. - maTables.erase(itrOld); - } - else - { - // nNewTab < nOldTab - - // Iterate from the new tab position to the one before the old tab - // position, and increment their tab index by one. - list<TabItemRef>::iterator itr = itrNew; - for (++itr; itr != itrOld; ++itr) - (*itr)->mnIndex += 1; - - (*itrOld)->mnIndex = nNewTab; - maTables.insert(itrNew, *itrOld); - - // Remove the original table. - maTables.erase(itrOld); - } - } -} - -void ScExternalRefManager::RefCells::insertTable(SCTAB nPos) -{ - TabItemRef xNewTab(new TabItem(nPos)); - list<TabItemRef>::iterator itr = getTabPos(nPos); - if (itr == maTables.end()) - maTables.push_back(xNewTab); - else - maTables.insert(itr, xNewTab); -} - -void ScExternalRefManager::RefCells::removeTable(SCTAB nPos) +ScExternalRefManager::LinkListener::LinkListener() { - list<TabItemRef>::iterator itr = getTabPos(nPos); - if (itr == maTables.end()) - // nothing to remove. - return; - - maTables.erase(itr); } -void ScExternalRefManager::RefCells::refreshAllCells(ScExternalRefManager& rRefMgr) +ScExternalRefManager::LinkListener::~LinkListener() { - // Get ALL the cell positions for re-compilation. - for (list<TabItemRef>::iterator itrTab = maTables.begin(), itrTabEnd = maTables.end(); - itrTab != itrTabEnd; ++itrTab) - { - SCTAB nTab = (*itrTab)->mnIndex; - ColSet& rCols = (*itrTab)->maCols; - for (ColSet::iterator itrCol = rCols.begin(), itrColEnd = rCols.end(); - itrCol != itrColEnd; ++itrCol) - { - SCCOL nCol = itrCol->first; - RowSet& rRows = itrCol->second; - RowSet aNewRows; - for (RowSet::iterator itrRow = rRows.begin(), itrRowEnd = rRows.end(); - itrRow != itrRowEnd; ++itrRow) - { - SCROW nRow = *itrRow; - ScAddress aCell(nCol, nRow, nTab); - if (rRefMgr.compileTokensByCell(aCell)) - // This cell still contains an external refernce. - aNewRows.insert(nRow); - } - // Update the rows so that cells with no external references are - // no longer tracked. - rRows.swap(aNewRows); - } - } } // ---------------------------------------------------------------------------- -ScExternalRefManager::LinkListener::LinkListener() +ScExternalRefManager::ApiGuard::ApiGuard(ScDocument* pDoc) : + mpMgr(pDoc->GetExternalRefManager()), + mbOldInteractionEnabled(mpMgr->mbUserInteractionEnabled) { + // We don't want user interaction handled in the API. + mpMgr->mbUserInteractionEnabled = false; } -ScExternalRefManager::LinkListener::~LinkListener() +ScExternalRefManager::ApiGuard::~ApiGuard() { + // Restore old value. + mpMgr->mbUserInteractionEnabled = mbOldInteractionEnabled; } // ---------------------------------------------------------------------------- @@ -1595,9 +1605,22 @@ bool ScExternalRefManager::markUsedByLinkListeners() return bAllMarked; } -bool ScExternalRefManager::setCacheDocReferenced( sal_uInt16 nFileId ) +bool ScExternalRefManager::markUsedExternalRefCells() { - return maRefCache.setCacheDocReferenced( nFileId); + RefCellMap::iterator itr = maRefCells.begin(), itrEnd = maRefCells.end(); + for (; itr != itrEnd; ++itr) + { + RefCellSet::iterator itrCell = itr->second.begin(), itrCellEnd = itr->second.end(); + for (; itrCell != itrCellEnd; ++itrCell) + { + ScFormulaCell* pCell = *itrCell; + bool bUsed = pCell->MarkUsedExternalReferences(); + if (bUsed) + // Return true when at least one cell references external docs. + return true; + } + } + return false; } bool ScExternalRefManager::setCacheTableReferenced( sal_uInt16 nFileId, const String& rTabName, size_t nSheets ) @@ -1617,7 +1640,7 @@ void ScExternalRefManager::setCacheTableReferencedPermanently( sal_uInt16 nFileI void ScExternalRefManager::setAllCacheTableReferencedStati( bool bReferenced ) { - bInReferenceMarking = !bReferenced; + mbInReferenceMarking = !bReferenced; maRefCache.setAllCacheTableReferencedStati( bReferenced ); } @@ -1642,20 +1665,13 @@ ScExternalRefCache::TokenRef ScExternalRefManager::getSingleRefToken( if (pFmt) pFmt->mbIsSet = false; - bool bLoading = mpDoc->IsImportingXML(); - // Check if the given table name and the cell position is cached. - // #i101304# When loading a file, the saved cache (hidden sheet) - // is assumed to contain all data for the loaded formulas. - // No cache entries are created from empty cells in the saved sheet, - // so they have to be created here (bWriteEmpty parameter). - // Otherwise, later interpretation of the loaded formulas would - // load the source document even if the user didn't want to update. sal_uInt32 nFmtIndex = 0; ScExternalRefCache::TokenRef pToken = maRefCache.getCellData( - nFileId, rTabName, rCell.Col(), rCell.Row(), bLoading, bLoading, &nFmtIndex); + nFileId, rTabName, rCell.Col(), rCell.Row(), &nFmtIndex); if (pToken) { + // Cache hit ! if (pFmt) { short nFmtType = mpDoc->GetFormatTable()->GetType(nFmtIndex); @@ -1673,11 +1689,8 @@ ScExternalRefCache::TokenRef ScExternalRefManager::getSingleRefToken( ScDocument* pSrcDoc = getSrcDocument(nFileId); if (!pSrcDoc) { - // Source document is not reachable. Try to get data from the cache - // once again, but this time treat a non-cached cell as an empty cell - // as long as the table itself is cached. - pToken = maRefCache.getCellData( - nFileId, rTabName, rCell.Col(), rCell.Row(), true, false, &nFmtIndex); + // Source document not reachable. Throw a reference error. + pToken.reset(new FormulaErrorToken(errNoRef)); return pToken; } @@ -1686,12 +1699,30 @@ ScExternalRefCache::TokenRef ScExternalRefManager::getSingleRefToken( if (!pSrcDoc->GetTable(rTabName, nTab)) { // specified table name doesn't exist in the source document. - return ScExternalRefCache::TokenRef(); + pToken.reset(new FormulaErrorToken(errNoRef)); + return pToken; } if (pTab) *pTab = nTab; + SCCOL nDataCol1 = 0, nDataCol2 = MAXCOL; + SCROW nDataRow1 = 0, nDataRow2 = MAXROW; + pSrcDoc->ShrinkToDataArea(nTab, nDataCol1, nDataRow1, nDataCol2, nDataRow2); + if (rCell.Col() < nDataCol1 || nDataCol2 < rCell.Col() || rCell.Row() < nDataRow1 || nDataRow2 < rCell.Row()) + { + // requested cell is outside the data area. Don't even bother caching + // this data, but add it to the cached range to prevent accessing the + // source document time and time again. + ScExternalRefCache::TableTypeRef pCacheTab = + maRefCache.getCacheTable(nFileId, rTabName, true, NULL); + if (pCacheTab) + pCacheTab->setCachedCell(rCell.Col(), rCell.Row()); + + pToken.reset(new ScEmptyCellToken(false, false)); + return pToken; + } + pSrcDoc->GetCell(rCell.Col(), rCell.Row(), nTab, pCell); ScExternalRefCache::TokenRef pTok(lcl_convertToToken(pCell)); @@ -1714,39 +1745,45 @@ ScExternalRefCache::TokenRef ScExternalRefManager::getSingleRefToken( pTok.reset( new FormulaErrorToken( errNoValue)); } - // Now, insert the token into cache table. - maRefCache.setCellData(nFileId, rTabName, rCell.Row(), rCell.Col(), pTok, nFmtIndex); + // Now, insert the token into cache table but don't cache empty cells. + if (pTok->GetType() != formula::svEmptyCell) + maRefCache.setCellData(nFileId, rTabName, rCell.Col(), rCell.Row(), pTok, nFmtIndex); + return pTok; } -ScExternalRefCache::TokenArrayRef ScExternalRefManager::getDoubleRefTokens(sal_uInt16 nFileId, const String& rTabName, const ScRange& rRange, const ScAddress* pCurPos) +ScExternalRefCache::TokenArrayRef ScExternalRefManager::getDoubleRefTokens( + sal_uInt16 nFileId, const String& rTabName, const ScRange& rRange, const ScAddress* pCurPos) { if (pCurPos) insertRefCell(nFileId, *pCurPos); maybeLinkExternalFile(nFileId); - bool bLoading = mpDoc->IsImportingXML(); - // Check if the given table name and the cell position is cached. - // #i101304# When loading, put empty cells into cache, see getSingleRefToken. - ScExternalRefCache::TokenArrayRef p = maRefCache.getCellRangeData(nFileId, rTabName, rRange, bLoading, bLoading); - if (p.get()) - return p; + ScExternalRefCache::TokenArrayRef pArray = + maRefCache.getCellRangeData(nFileId, rTabName, rRange); + if (pArray) + // Cache hit ! + return pArray; ScDocument* pSrcDoc = getSrcDocument(nFileId); if (!pSrcDoc) { - // Source document is not reachable. Try to get data from the cache - // once again, but this time treat non-cached cells as empty cells as - // long as the table itself is cached. - return maRefCache.getCellRangeData(nFileId, rTabName, rRange, true, false); + // Source document is not reachable. Throw a reference error. + pArray.reset(new ScTokenArray); + pArray->AddToken(FormulaErrorToken(errNoRef)); + return pArray; } SCTAB nTab1; if (!pSrcDoc->GetTable(rTabName, nTab1)) + { // specified table name doesn't exist in the source document. - return ScExternalRefCache::TokenArrayRef(); + pArray.reset(new ScTokenArray); + pArray->AddToken(FormulaErrorToken(errNoRef)); + return pArray; + } ScRange aRange(rRange); SCTAB nTabSpan = aRange.aEnd.Tab() - aRange.aStart.Tab(); @@ -1770,12 +1807,24 @@ ScExternalRefCache::TokenArrayRef ScExternalRefManager::getDoubleRefTokens(sal_u aRange.aStart.SetTab(nTab1); aRange.aEnd.SetTab(nTab1 + nTabSpan); - ScExternalRefCache::TokenArrayRef pArray; pArray.reset(lcl_convertToTokenArray(pSrcDoc, aRange, aCacheData)); if (pArray) // Cache these values. - maRefCache.setCellRangeData(nFileId, rRange, aCacheData, pArray); + maRefCache.setCellRangeData(nFileId, aRange, aCacheData, pArray); + else + { + // Array is empty. Fill it with an empty matrix of the required size. + pArray.reset(lcl_fillEmptyMatrix(rRange)); + + // Make sure to set this range 'cached', to prevent unnecessarily + // accessing the src document time and time again. + ScExternalRefCache::TableTypeRef pCacheTab = + maRefCache.getCacheTable(nFileId, rTabName, true, NULL); + if (pCacheTab) + pCacheTab->setCachedCellRange( + rRange.aStart.Col(), rRange.aStart.Row(), rRange.aEnd.Col(), rRange.aEnd.Row()); + } return pArray; } @@ -1858,8 +1907,8 @@ void ScExternalRefManager::refreshAllRefCells(sal_uInt16 nFileId) if (itrFile == maRefCells.end()) return; - RefCells& rRefCells = itrFile->second; - rRefCells.refreshAllCells(*this); + RefCellSet& rRefCells = itrFile->second; + for_each(rRefCells.begin(), rRefCells.end(), UpdateFormulaCell()); ScViewData* pViewData = ScDocShell::GetViewData(); if (!pViewData) @@ -1880,7 +1929,7 @@ void ScExternalRefManager::insertRefCell(sal_uInt16 nFileId, const ScAddress& rC RefCellMap::iterator itr = maRefCells.find(nFileId); if (itr == maRefCells.end()) { - RefCells aRefCells; + RefCellSet aRefCells; pair<RefCellMap::iterator, bool> r = maRefCells.insert( RefCellMap::value_type(nFileId, aRefCells)); if (!r.second) @@ -1889,7 +1938,10 @@ void ScExternalRefManager::insertRefCell(sal_uInt16 nFileId, const ScAddress& rC itr = r.first; } - itr->second.insertCell(rCell); + + ScBaseCell* pCell = mpDoc->GetCell(rCell); + if (pCell && pCell->GetCellType() == CELLTYPE_FORMULA) + itr->second.insert(static_cast<ScFormulaCell*>(pCell)); } ScDocument* ScExternalRefManager::getSrcDocument(sal_uInt16 nFileId) @@ -1902,6 +1954,12 @@ ScDocument* ScExternalRefManager::getSrcDocument(sal_uInt16 nFileId) if (itr != itrEnd) { + // document already loaded. + + // TODO: Find out a way to access a document that's already open in + // memory and re-use that instance, instead of loading it from the + // disk again. + SfxObjectShell* p = itr->second.maShell; itr->second.maLastAccess = Time(); return static_cast<ScDocShell*>(p)->GetDocument(); @@ -1996,7 +2054,8 @@ SfxObjectShellRef ScExternalRefManager::loadSrcDocument(sal_uInt16 nFileId, Stri if (pMedium->GetError() != ERRCODE_NONE) return NULL; - pMedium->UseInteractionHandler(false); + // To load encrypted documents with password, user interaction needs to be enabled. + pMedium->UseInteractionHandler(mbUserInteractionEnabled); ScDocShell* pNewShell = new ScDocShell(SFX_CREATE_MODE_INTERNAL); SfxObjectShellRef aRef = pNewShell; @@ -2005,6 +2064,10 @@ SfxObjectShellRef ScExternalRefManager::loadSrcDocument(sal_uInt16 nFileId, Stri ScExtDocOptions* pExtOpt = mpDoc->GetExtDocOptions(); sal_uInt32 nLinkCount = pExtOpt ? pExtOpt->GetDocSettings().mnLinkCnt : 0; ScDocument* pSrcDoc = pNewShell->GetDocument(); + pSrcDoc->EnableExecuteLink(false); // to prevent circular access of external references. + pSrcDoc->EnableUndo(false); + pSrcDoc->EnableAdjustHeight(false); + ScExtDocOptions* pExtOptNew = pSrcDoc->GetExtDocOptions(); if (!pExtOptNew) { @@ -2082,35 +2145,6 @@ void ScExternalRefManager::maybeCreateRealFileName(sal_uInt16 nFileId) maSrcFiles[nFileId].maybeCreateRealFileName(getOwnDocumentName()); } -bool ScExternalRefManager::compileTokensByCell(const ScAddress& rCell) -{ - ScBaseCell* pCell; - mpDoc->GetCell(rCell.Col(), rCell.Row(), rCell.Tab(), pCell); - - if (!pCell || pCell->GetCellType() != CELLTYPE_FORMULA) - return false; - - ScFormulaCell* pFC = static_cast<ScFormulaCell*>(pCell); - - // Check to make sure the cell really contains ocExternalRef. - // External names, external cell and range references all have a - // ocExternalRef token. - const ScTokenArray* pCode = pFC->GetCode(); - if (!pCode->HasOpCode( ocExternalRef)) - return false; - - ScTokenArray* pArray = pFC->GetCode(); - if (pArray) - // Clear the error code, or a cell with error won't get re-compiled. - pArray->SetCodeError(0); - - pFC->SetCompile(true); - pFC->CompileTokenArray(); - pFC->SetDirty(); - - return true; -} - const String& ScExternalRefManager::getOwnDocumentName() const { SfxObjectShell* pShell = mpDoc->GetDocumentShell(); @@ -2222,6 +2256,18 @@ void ScExternalRefManager::refreshNames(sal_uInt16 nFileId) void ScExternalRefManager::breakLink(sal_uInt16 nFileId) { + // Turn all formula cells referencing this external document into static + // cells. + RefCellMap::iterator itrRefs = maRefCells.find(nFileId); + if (itrRefs != maRefCells.end()) + { + // Make a copy because removing the formula cells below will modify + // the original container. + RefCellSet aSet = itrRefs->second; + for_each(aSet.begin(), aSet.end(), ConvertFormulaToStatic(mpDoc)); + maRefCells.erase(nFileId); + } + lcl_removeByFileId(nFileId, maDocShells); if (maDocShells.empty()) @@ -2293,32 +2339,9 @@ void ScExternalRefManager::resetSrcFileData(const String& rBaseFileUrl) } } -void ScExternalRefManager::updateRefCell(const ScAddress& rOldPos, const ScAddress& rNewPos, bool bCopy) -{ - for (RefCellMap::iterator itr = maRefCells.begin(), itrEnd = maRefCells.end(); itr != itrEnd; ++itr) - { - if (!bCopy) - itr->second.removeCell(rOldPos); - itr->second.insertCell(rNewPos); - } -} - -void ScExternalRefManager::updateRefMoveTable(SCTAB nOldTab, SCTAB nNewTab, bool bCopy) -{ - for (RefCellMap::iterator itr = maRefCells.begin(), itrEnd = maRefCells.end(); itr != itrEnd; ++itr) - itr->second.moveTable(nOldTab, nNewTab, bCopy); -} - -void ScExternalRefManager::updateRefInsertTable(SCTAB nPos) -{ - for (RefCellMap::iterator itr = maRefCells.begin(), itrEnd = maRefCells.end(); itr != itrEnd; ++itr) - itr->second.insertTable(nPos); -} - -void ScExternalRefManager::updateRefDeleteTable(SCTAB nPos) +void ScExternalRefManager::removeRefCell(ScFormulaCell* pCell) { - for (RefCellMap::iterator itr = maRefCells.begin(), itrEnd = maRefCells.end(); itr != itrEnd; ++itr) - itr->second.removeTable(nPos); + for_each(maRefCells.begin(), maRefCells.end(), RemoveFormulaCell(pCell)); } void ScExternalRefManager::addLinkListener(sal_uInt16 nFileId, LinkListener* pListener) diff --git a/sc/source/ui/drawfunc/drtxtob.cxx b/sc/source/ui/drawfunc/drtxtob.cxx index ece7c4ad6c3a..bfbeba2d1302 100644 --- a/sc/source/ui/drawfunc/drtxtob.cxx +++ b/sc/source/ui/drawfunc/drtxtob.cxx @@ -32,6 +32,9 @@ //------------------------------------------------------------------------- +#include <com/sun/star/linguistic2/XThesaurus.hpp> +#include <com/sun/star/lang/Locale.hpp> + #include "scitems.hxx" #include <editeng/adjitem.hxx> @@ -46,6 +49,7 @@ #include <svx/hlnkitem.hxx> #include <editeng/lspcitem.hxx> #include <svx/svdoutl.hxx> +#include <editeng/unolingu.hxx> #include <editeng/outlobj.hxx> #include <editeng/postitem.hxx> #include <editeng/scripttypeitem.hxx> @@ -71,6 +75,7 @@ #include "sc.hrc" #include "globstr.hrc" +#include "scmod.hxx" #include "drtxtob.hxx" #include "fudraw.hxx" #include "viewdata.hxx" @@ -83,6 +88,10 @@ #define ScDrawTextObjectBar #include "scslots.hxx" + +using namespace ::com::sun::star; + + SFX_IMPL_INTERFACE( ScDrawTextObjectBar, SfxShell, ScResId(SCSTR_DRAWTEXTSHELL) ) { SFX_OBJECTBAR_REGISTRATION( SFX_OBJECTBAR_OBJECT|SFX_VISIBILITY_STANDARD|SFX_VISIBILITY_SERVER, @@ -363,6 +372,24 @@ void __EXPORT ScDrawTextObjectBar::Execute( SfxRequest &rReq ) ExecuteGlobal( rReq ); break; #endif + + case SID_THES: + { + String aReplaceText; + SFX_REQUEST_ARG( rReq, pItem2, SfxStringItem, SID_THES, sal_False ); + if (pItem2) + aReplaceText = pItem2->GetValue(); + if (aReplaceText.Len() > 0) + ReplaceTextWithSynonym( pOutView->GetEditView(), aReplaceText ); + } + break; + + case SID_THESAURUS: + { + pOutView->StartThesaurus(); + } + break; + } } @@ -454,6 +481,25 @@ void __EXPORT ScDrawTextObjectBar::GetState( SfxItemSet& rSet ) rSet.Put( SfxBoolItem( SID_ENABLE_HYPHENATION, bValue ) ); } } + + if ( rSet.GetItemState( SID_THES ) != SFX_ITEM_UNKNOWN || + rSet.GetItemState( SID_THESAURUS ) != SFX_ITEM_UNKNOWN ) + { + SdrView * pView = pViewData->GetScDrawView(); + EditView & rEditView = pView->GetTextEditOutlinerView()->GetEditView(); + + String aStatusVal; + LanguageType nLang = LANGUAGE_NONE; + bool bIsLookUpWord = GetStatusValueForThesaurusFromContext( aStatusVal, nLang, rEditView ); + rSet.Put( SfxStringItem( SID_THES, aStatusVal ) ); + + // disable thesaurus main menu and context menu entry if there is nothing to look up + BOOL bCanDoThesaurus = ScModule::HasThesaurusLanguage( nLang ); + if (!bIsLookUpWord || !bCanDoThesaurus) + rSet.DisableItem( SID_THES ); + if (!bCanDoThesaurus) + rSet.DisableItem( SID_THESAURUS ); + } } IMPL_LINK( ScDrawTextObjectBar, ClipboardChanged, TransferableDataHelper*, pDataHelper ) diff --git a/sc/source/ui/drawfunc/makefile.mk b/sc/source/ui/drawfunc/makefile.mk index 52f54b56edce..a50c450ab373 100644 --- a/sc/source/ui/drawfunc/makefile.mk +++ b/sc/source/ui/drawfunc/makefile.mk @@ -75,7 +75,9 @@ SLOFILES = \ $(SLO)$/mediash.obj EXCEPTIONSFILES= \ - $(SLO)$/fuins2.obj + $(SLO)$/fuins2.obj \ + $(SLO)$/graphsh.obj \ + $(SLO)$/mediash.obj NOOPTFILES=\ $(SLO)$/fusel.obj diff --git a/sc/source/ui/inc/spelldialog.hxx b/sc/source/ui/inc/spelldialog.hxx index af97519a2b43..eef0d170c2c8 100644 --- a/sc/source/ui/inc/spelldialog.hxx +++ b/sc/source/ui/inc/spelldialog.hxx @@ -65,12 +65,12 @@ protected: next sentence with spelling errors. While doing so the view mode may be changed and text shapes are set into edit mode. */ - virtual ::svx::SpellPortions GetNextWrongSentence(); + virtual ::svx::SpellPortions GetNextWrongSentence( bool bRecheck ); /** This method is responsible for merging corrections made in the spelling dialog back into the document. */ - virtual void ApplyChangedSentence( const ::svx::SpellPortions& rChanged ); + virtual void ApplyChangedSentence( const ::svx::SpellPortions& rChanged, bool bRecheck ); virtual void GetFocus(); virtual void LoseFocus(); diff --git a/sc/source/ui/unoobj/cellsuno.cxx b/sc/source/ui/unoobj/cellsuno.cxx index afe29a8309a7..980a73307797 100644 --- a/sc/source/ui/unoobj/cellsuno.cxx +++ b/sc/source/ui/unoobj/cellsuno.cxx @@ -5265,6 +5265,8 @@ void SAL_CALL ScCellRangeObj::setFormulaArray( ScDocShell* pDocSh = GetDocShell(); if (pDocSh) { + ScExternalRefManager::ApiGuard aExtRefGuard(pDocSh->GetDocument()); + // GRAM_PODF_A1 for API compatibility. bDone = lcl_PutFormulaArray( *pDocSh, aRange, aArray, EMPTY_STRING, formula::FormulaGrammar::GRAM_PODF_A1 ); } diff --git a/sc/source/ui/unoobj/linkuno.cxx b/sc/source/ui/unoobj/linkuno.cxx index 6d9fcd1d23e4..a119eda13a32 100644 --- a/sc/source/ui/unoobj/linkuno.cxx +++ b/sc/source/ui/unoobj/linkuno.cxx @@ -1605,12 +1605,16 @@ ScExternalDocLinkObj::~ScExternalDocLinkObj() } Reference< sheet::XExternalSheetCache > SAL_CALL ScExternalDocLinkObj::addSheetCache( - const OUString& aSheetName ) + const OUString& aSheetName, sal_Bool bDynamicCache ) throw (RuntimeException) { ScUnoGuard aGuard; size_t nIndex = 0; ScExternalRefCache::TableTypeRef pTable = mpRefMgr->getCacheTable(mnFileId, aSheetName, true, &nIndex); + if (!bDynamicCache) + // Set the whole table cached to prevent access to the source document. + pTable->setWholeTableCached(); + Reference< sheet::XExternalSheetCache > aSheetCache(new ScExternalSheetCacheObj(pTable, nIndex)); return aSheetCache; } diff --git a/sc/source/ui/unoobj/tokenuno.cxx b/sc/source/ui/unoobj/tokenuno.cxx index fc14b53a6372..5e3b3102e14a 100644 --- a/sc/source/ui/unoobj/tokenuno.cxx +++ b/sc/source/ui/unoobj/tokenuno.cxx @@ -140,9 +140,11 @@ uno::Sequence<sheet::FormulaToken> SAL_CALL ScFormulaParserObj::parseFormula( if (mpDocShell) { + ScDocument* pDoc = mpDocShell->GetDocument(); + ScExternalRefManager::ApiGuard aExtRefGuard(pDoc); + ScAddress aRefPos( ScAddress::UNINITIALIZED ); ScUnoConversion::FillScAddress( aRefPos, rReferencePos ); - ScDocument* pDoc = mpDocShell->GetDocument(); ScCompiler aCompiler( pDoc, aRefPos); aCompiler.SetGrammar(pDoc->GetGrammar()); SetCompilerFlags( aCompiler ); diff --git a/sc/source/ui/view/editsh.cxx b/sc/source/ui/view/editsh.cxx index d228a205a5a3..848a0a3c7636 100644 --- a/sc/source/ui/view/editsh.cxx +++ b/sc/source/ui/view/editsh.cxx @@ -32,13 +32,16 @@ //------------------------------------------------------------------ +#include <com/sun/star/linguistic2/XThesaurus.hpp> + #include "scitems.hxx" #include <editeng/eeitem.hxx> #include <svx/clipfmtitem.hxx> #include <svx/svxdlg.hxx> #include <editeng/cntritem.hxx> -//CHINA001 #include <svx/chardlg.hxx> +#include <editeng/outliner.hxx> +#include <editeng/unolingu.hxx> #include <editeng/crsditem.hxx> #include <editeng/editeng.hxx> #include <editeng/editview.hxx> @@ -91,6 +94,11 @@ #include "scui_def.hxx" //CHINA001 #include "scabstdlg.hxx" //CHINA001 + + +using namespace ::com::sun::star; + + TYPEINIT1( ScEditShell, SfxShell ); SFX_IMPL_INTERFACE(ScEditShell, SfxShell, ScResId(SCSTR_EDITSHELL)) @@ -213,6 +221,17 @@ void ScEditShell::Execute( SfxRequest& rReq ) } break; + case SID_THES: + { + String aReplaceText; + SFX_REQUEST_ARG( rReq, pItem2, SfxStringItem, SID_THES , sal_False ); + if (pItem2) + aReplaceText = pItem2->GetValue(); + if (aReplaceText.Len() > 0) + ReplaceTextWithSynonym( *pEditView, aReplaceText ); + } + break; + case SID_COPY: pTableView->Copy(); break; @@ -680,6 +699,22 @@ void __EXPORT ScEditShell::GetState( SfxItemSet& rSet ) case SID_INSERT_ZWSP: ScViewUtil::HideDisabledSlot( rSet, pViewData->GetBindings(), nWhich ); break; + + case SID_THES: + { + String aStatusVal; + LanguageType nLang = LANGUAGE_NONE; + bool bIsLookUpWord = GetStatusValueForThesaurusFromContext( aStatusVal, nLang, *pActiveView ); + rSet.Put( SfxStringItem( SID_THES, aStatusVal ) ); + + // disable thesaurus context menu entry if there is nothing to look up + BOOL bCanDoThesaurus = ScModule::HasThesaurusLanguage( nLang ); + if (!bIsLookUpWord || !bCanDoThesaurus) + rSet.DisableItem( SID_THES ); + } + break; + + } nWhich = aIter.NextWhich(); } diff --git a/sc/source/ui/view/output2.cxx b/sc/source/ui/view/output2.cxx index b69f787a19b5..c92e4afbe9c7 100644 --- a/sc/source/ui/view/output2.cxx +++ b/sc/source/ui/view/output2.cxx @@ -632,7 +632,7 @@ long ScDrawStringsVars::GetMaxDigitWidth() return nMaxDigitWidth; sal_Char cZero = '0'; - for (int i = 0; i < 10; ++i) + for (sal_Char i = 0; i < 10; ++i) { sal_Char cDigit = cZero + i; long n = pOutput->pFmtDevice->GetTextWidth(String(cDigit)); diff --git a/sc/source/ui/view/spelldialog.cxx b/sc/source/ui/view/spelldialog.cxx index a178b0a0ada6..ee13ee9fbf90 100644 --- a/sc/source/ui/view/spelldialog.cxx +++ b/sc/source/ui/view/spelldialog.cxx @@ -79,7 +79,7 @@ void ScSpellDialogChildWindow::InvalidateSpellDialog() // protected ------------------------------------------------------------------ -::svx::SpellPortions ScSpellDialogChildWindow::GetNextWrongSentence() +::svx::SpellPortions ScSpellDialogChildWindow::GetNextWrongSentence( bool /*bRecheck*/ ) { ::svx::SpellPortions aPortions; if( mxEngine.get() && mpViewData ) @@ -103,11 +103,11 @@ void ScSpellDialogChildWindow::InvalidateSpellDialog() return aPortions; } -void ScSpellDialogChildWindow::ApplyChangedSentence( const ::svx::SpellPortions& rChanged ) +void ScSpellDialogChildWindow::ApplyChangedSentence( const ::svx::SpellPortions& rChanged, bool bRecheck ) { if( mxEngine.get() && mpViewData ) if( EditView* pEditView = mpViewData->GetSpellingView() ) - mxEngine->ApplyChangedSentence( *pEditView, rChanged, false ); + mxEngine->ApplyChangedSentence( *pEditView, rChanged, bRecheck ); } void ScSpellDialogChildWindow::GetFocus() diff --git a/sc/source/ui/view/viewutil.cxx b/sc/source/ui/view/viewutil.cxx index f73346398ea1..d887aec8bc5b 100644 --- a/sc/source/ui/view/viewutil.cxx +++ b/sc/source/ui/view/viewutil.cxx @@ -52,6 +52,8 @@ #include <svl/eitem.hxx> #include <com/sun/star/i18n/TransliterationModules.hpp> +#include <com/sun/star/i18n/TransliterationModulesExtra.hpp> + #include "viewutil.hxx" #include "global.hxx" @@ -120,6 +122,15 @@ sal_Int32 ScViewUtil::GetTransliterationType( USHORT nSlotID ) sal_Int32 nType = 0; switch ( nSlotID ) { + case SID_TRANSLITERATE_SENTENCE_CASE: + nType = com::sun::star::i18n::TransliterationModulesExtra::SENTENCE_CASE; + break; + case SID_TRANSLITERATE_TITLE_CASE: + nType = com::sun::star::i18n::TransliterationModulesExtra::TITLE_CASE; + break; + case SID_TRANSLITERATE_TOGGLE_CASE: + nType = com::sun::star::i18n::TransliterationModulesExtra::TOGGLE_CASE; + break; case SID_TRANSLITERATE_UPPER: nType = com::sun::star::i18n::TransliterationModules_LOWERCASE_UPPERCASE; break; diff --git a/sc/uiconfig/scalc/menubar/menubar.xml b/sc/uiconfig/scalc/menubar/menubar.xml index 949b1a10b619..da8e6efdad55 100644 --- a/sc/uiconfig/scalc/menubar/menubar.xml +++ b/sc/uiconfig/scalc/menubar/menubar.xml @@ -234,8 +234,11 @@ <menu:menuitem menu:id=".uno:ParagraphDialog"/> <menu:menu menu:id=".uno:TransliterateMenu"> <menu:menupopup> - <menu:menuitem menu:id=".uno:ChangeCaseToUpper"/> + <menu:menuitem menu:id=".uno:ChangeCaseToSentenceCase"/> <menu:menuitem menu:id=".uno:ChangeCaseToLower"/> + <menu:menuitem menu:id=".uno:ChangeCaseToUpper"/> + <menu:menuitem menu:id=".uno:ChangeCaseToTitleCase"/> + <menu:menuitem menu:id=".uno:ChangeCaseToToggleCase"/> <menu:menuitem menu:id=".uno:ChangeCaseToHalfWidth"/> <menu:menuitem menu:id=".uno:ChangeCaseToFullWidth"/> <menu:menuitem menu:id=".uno:ChangeCaseToHiragana"/> @@ -311,7 +314,7 @@ <menu:menupopup> <menu:menuitem menu:id=".uno:HangulHanjaConversion"/> <menu:menuitem menu:id=".uno:ChineseConversion"/> - <menu:menuitem menu:id=".uno:Thesaurus"/> + <menu:menuitem menu:id=".uno:ThesaurusDialog"/> <menu:menuitem menu:id=".uno:Hyphenate"/> <menu:menuseparator/> <menu:menuitem menu:id=".uno:MoreDictionaries"/> diff --git a/sc/uiconfig/scalc/toolbar/findbar.xml b/sc/uiconfig/scalc/toolbar/findbar.xml new file mode 100644 index 000000000000..9ef9d8a1a78f --- /dev/null +++ b/sc/uiconfig/scalc/toolbar/findbar.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE toolbar:toolbar PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "toolbar.dtd"> +<toolbar:toolbar xmlns:toolbar="http://openoffice.org/2001/toolbar" xmlns:xlink="http://www.w3.org/1999/xlink" toolbar:id="toolbar"> + <toolbar:toolbaritem xlink:href=".uno:FindText" toolbar:helpid="helpid:100105" /> + <toolbar:toolbaritem xlink:href=".uno:DownSearch" toolbar:helpid="helpid:100105" /> + <toolbar:toolbaritem xlink:href=".uno:UpSearch" toolbar:helpid="helpid:100105" /> + <toolbar:toolbaritem xlink:href=".uno:SearchDialog" toolbar:text="Find & Replace" toolbar:visible="false" toolbar:helpid="helpid:100105"/> +</toolbar:toolbar> diff --git a/sc/uiconfig/scalc/toolbar/toolbar.xml b/sc/uiconfig/scalc/toolbar/toolbar.xml index 6a34de3a4ebd..e42964a86b0b 100644 --- a/sc/uiconfig/scalc/toolbar/toolbar.xml +++ b/sc/uiconfig/scalc/toolbar/toolbar.xml @@ -8,7 +8,7 @@ <toolbar:toolbarseparator/> <toolbar:toolbaritem xlink:href=".uno:AutoFormat" toolbar:helpid="helpid:10242" /> <toolbar:toolbaritem xlink:href=".uno:ChooseDesign" toolbar:helpid="helpid:26082" /> - <toolbar:toolbaritem xlink:href=".uno:Thesaurus" toolbar:helpid="helpid:10245" toolbar:visible="false" /> + <toolbar:toolbaritem xlink:href=".uno:ThesaurusDialog" toolbar:helpid="helpid:10245" toolbar:visible="false" /> <toolbar:toolbarseparator/> <toolbar:toolbaritem xlink:href=".uno:DataFilterAutoFilter" toolbar:helpid="helpid:26325" /> <toolbar:toolbaritem xlink:href=".uno:DataFilterStandardFilter" toolbar:helpid="helpid:26323" toolbar:visible="false" /> @@ -20,4 +20,4 @@ <toolbar:toolbaritem xlink:href=".uno:GoalSeekDialog" toolbar:helpid="helpid:26153" toolbar:visible="false" /> <toolbar:toolbaritem xlink:href=".uno:Group" toolbar:helpid="helpid:26331" /> <toolbar:toolbaritem xlink:href=".uno:Ungroup" toolbar:helpid="helpid:26332" /> -</toolbar:toolbar>
\ No newline at end of file +</toolbar:toolbar> |