diff options
author | Mathias Bauer <mba@openoffice.org> | 2010-07-13 14:38:37 +0200 |
---|---|---|
committer | Mathias Bauer <mba@openoffice.org> | 2010-07-13 14:38:37 +0200 |
commit | 0266406fef116fbed7b8e69e309bcda0df4896dd (patch) | |
tree | 7d08d330d7ee76707ab4eb757a60fe2559178957 | |
parent | 4a02c63d1431b2e8686a035e119c4a2f5c972592 (diff) | |
parent | 686b7955271806e65222a3a4bfe97365cab33a06 (diff) |
CWS changehid: resync to m84
407 files changed, 15555 insertions, 8237 deletions
diff --git a/chart2/prj/build.lst b/chart2/prj/build.lst index 370eacebe0c2..469eb7554d6b 100644 --- a/chart2/prj/build.lst +++ b/chart2/prj/build.lst @@ -24,4 +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 +ch chart2\qa\unoapi nmake - all ch_qa_unoapi NULL diff --git a/chart2/prj/d.lst b/chart2/prj/d.lst index 3acff468e141..440e2efbe8c5 100644 --- a/chart2/prj/d.lst +++ b/chart2/prj/d.lst @@ -4,8 +4,6 @@ mkdir: %_DEST%\xml%_EXT%\uiconfig\modules mkdir: %_DEST%\xml%_EXT%\uiconfig\modules\schart mkdir: %_DEST%\xml%_EXT%\uiconfig\modules\schart\menubar mkdir: %_DEST%\xml%_EXT%\uiconfig\modules\schart\toolbar -mkdir: %_DEST%\xml%_EXT%\uiconfig\modules\schart\accelerator -mkdir: %_DEST%\xml%_EXT%\uiconfig\modules\schart\accelerator\en-US mkdir: %_DEST%\xml%_EXT%\uiconfig\modules\schart\statusbar ..\%COMMON_OUTDIR%\misc\*.hid %COMMON_DEST%\bin%_EXT%\hid\*.hid @@ -20,7 +18,6 @@ mkdir: %_DEST%\xml%_EXT%\uiconfig\modules\schart\statusbar ..\uiconfig\menubar\*.xml %_DEST%\xml%_EXT%\uiconfig\modules\schart\menubar\*.xml ..\uiconfig\toolbar\*.xml %_DEST%\xml%_EXT%\uiconfig\modules\schart\toolbar\*.xml -..\uiconfig\accelerator\en-US\*.xml %_DEST%\xml%_EXT%\uiconfig\modules\schart\accelerator\en-US\*.xml ..\uiconfig\statusbar\*.xml %_DEST%\xml%_EXT%\uiconfig\modules\schart\statusbar\*.xml mkdir: %_DEST%\inc%_EXT%\chart2 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 14a20e133ff1..edf8ad2b6209 100644 --- a/chart2/source/controller/chartapiwrapper/ChartDocumentWrapper.cxx +++ b/chart2/source/controller/chartapiwrapper/ChartDocumentWrapper.cxx @@ -160,7 +160,9 @@ enum PROP_DOCUMENT_BASEDIAGRAM, PROP_DOCUMENT_ADDITIONAL_SHAPES, PROP_DOCUMENT_UPDATE_ADDIN, - PROP_DOCUMENT_NULL_DATE + PROP_DOCUMENT_NULL_DATE, + PROP_DOCUMENT_DISABLE_COMPLEX_CHARTTYPES, + PROP_DOCUMENT_DISABLE_DATATABLE_DIALOG }; void lcl_AddPropertiesToVector( @@ -170,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( @@ -196,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( @@ -223,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( @@ -231,6 +234,19 @@ void lcl_AddPropertiesToVector( PROP_DOCUMENT_NULL_DATE, ::getCppuType( static_cast< const ::com::sun::star::util::DateTime * >(0)), beans::PropertyAttribute::MAYBEVOID )); + + rOutProperties.push_back( + Property( C2U( "DisableComplexChartTypes" ), + PROP_DOCUMENT_DISABLE_COMPLEX_CHARTTYPES, + ::getBooleanCppuType(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::MAYBEDEFAULT ) ); + rOutProperties.push_back( + Property( C2U( "DisableDataTableDialog" ), + PROP_DOCUMENT_DISABLE_DATATABLE_DIALOG, + ::getBooleanCppuType(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::MAYBEDEFAULT ) ); } const uno::Sequence< Property > & lcl_GetPropertySequence() @@ -742,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; @@ -752,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; @@ -1499,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; @@ -1570,6 +1598,8 @@ const std::vector< WrappedProperty* > ChartDocumentWrapper::createWrappedPropert aWrappedProperties.push_back( new WrappedAdditionalShapesProperty( *this ) ); aWrappedProperties.push_back( new WrappedRefreshAddInAllowedProperty( *this ) ); aWrappedProperties.push_back( new WrappedIgnoreProperty( C2U("NullDate"),Any() ) ); // i99104 + aWrappedProperties.push_back( new WrappedIgnoreProperty( C2U( "DisableComplexChartTypes" ), uno::makeAny( sal_False ) ) ); + aWrappedProperties.push_back( new WrappedIgnoreProperty( C2U( "DisableDataTableDialog" ), uno::makeAny( sal_False ) ) ); return aWrappedProperties; } 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 cfe8ab3493e0..1f768f7c065b 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 = HID_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_ErrorBar.cxx b/chart2/source/controller/dialogs/res_ErrorBar.cxx index 75457a5e7cad..8b649072538e 100644 --- a/chart2/source/controller/dialogs/res_ErrorBar.cxx +++ b/chart2/source/controller/dialogs/res_ErrorBar.cxx @@ -37,6 +37,7 @@ #include "RangeSelectionHelper.hxx" // for RANGE_SELECTION_INVALID_RANGE_BACKGROUND_COLOR #include "TabPageNotifiable.hxx" +#include "macros.hxx" #include <rtl/math.hxx> #include <vcl/dialog.hxx> @@ -147,7 +148,8 @@ ErrorBarResources::ErrorBarResources( Window* pParent, Dialog * pParentDialog, m_pParentWindow( pParent ), m_pParentDialog( pParentDialog ), m_pCurrentRangeChoosingField( 0 ), - m_bHasInternalDataProvider( true ) + m_bHasInternalDataProvider( true ), + m_bDisableDataTableDialog( false ) { if( m_bNoneAvailable ) m_aRbNone.SetClickHdl( LINK( this, ErrorBarResources, CategoryChosen )); @@ -197,7 +199,21 @@ void ErrorBarResources::SetChartDocumentForRangeChoosing( const uno::Reference< chart2::XChartDocument > & xChartDocument ) { if( xChartDocument.is()) + { m_bHasInternalDataProvider = xChartDocument->hasInternalDataProvider(); + uno::Reference< beans::XPropertySet > xProps( xChartDocument, uno::UNO_QUERY ); + if ( xProps.is() ) + { + try + { + xProps->getPropertyValue( C2U( "DisableDataTableDialog" ) ) >>= m_bDisableDataTableDialog; + } + catch( uno::Exception& e ) + { + ASSERT_EXCEPTION( e ); + } + } + } m_apRangeSelectionHelper.reset( new RangeSelectionHelper( xChartDocument )); // has internal data provider => rename "cell range" to "from data" @@ -240,6 +256,7 @@ void ErrorBarResources::UpdateControlStates() m_aLbFunction.Enable( bIsFunction ); // range buttons + m_aRbRange.Enable( !m_bHasInternalDataProvider || !m_bDisableDataTableDialog ); bool bShowRange = ( m_aRbRange.IsChecked()); bool bCanChooseRange = ( bShowRange && 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 244d23ed8eff..ec6c1d2a1c10 100644 --- a/chart2/source/controller/dialogs/tp_ChartType.cxx +++ b/chart2/source/controller/dialogs/tp_ChartType.cxx @@ -853,15 +853,35 @@ ChartTypeTabPage::ChartTypeTabPage( Window* pParent bool bIsHighContrast = ( true && GetSettings().GetStyleSettings().GetHighContrastMode() ); + bool bDisableComplexChartTypes = false; + uno::Reference< beans::XPropertySet > xProps( m_xChartModel, uno::UNO_QUERY ); + if ( xProps.is() ) + { + try + { + xProps->getPropertyValue( C2U( "DisableComplexChartTypes" ) ) >>= bDisableComplexChartTypes; + } + catch( uno::Exception& e ) + { + ASSERT_EXCEPTION( e ); + } + } + m_aChartTypeDialogControllerList.push_back(new ColumnChartDialogController() ); m_aChartTypeDialogControllerList.push_back(new BarChartDialogController() ); m_aChartTypeDialogControllerList.push_back(new PieChartDialogController() ); m_aChartTypeDialogControllerList.push_back(new AreaChartDialogController() ); m_aChartTypeDialogControllerList.push_back(new LineChartDialogController() ); - m_aChartTypeDialogControllerList.push_back(new XYChartDialogController() ); - m_aChartTypeDialogControllerList.push_back(new BubbleChartDialogController() ); + if ( !bDisableComplexChartTypes ) + { + m_aChartTypeDialogControllerList.push_back(new XYChartDialogController() ); + m_aChartTypeDialogControllerList.push_back(new BubbleChartDialogController() ); + } m_aChartTypeDialogControllerList.push_back(new NetChartDialogController() ); - m_aChartTypeDialogControllerList.push_back(new StockChartDialogController() ); + if ( !bDisableComplexChartTypes ) + { + m_aChartTypeDialogControllerList.push_back(new StockChartDialogController() ); + } m_aChartTypeDialogControllerList.push_back(new CombiColumnLineChartDialogController() ); ::std::vector< ChartTypeDialogController* >::const_iterator aIter = m_aChartTypeDialogControllerList.begin(); @@ -1133,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/inc/res_ErrorBar.hxx b/chart2/source/controller/inc/res_ErrorBar.hxx index 36bceaffce9f..0b5f33b5c128 100644 --- a/chart2/source/controller/inc/res_ErrorBar.hxx +++ b/chart2/source/controller/inc/res_ErrorBar.hxx @@ -135,6 +135,7 @@ private: m_apRangeSelectionHelper; Edit * m_pCurrentRangeChoosingField; bool m_bHasInternalDataProvider; + bool m_bDisableDataTableDialog; DECL_LINK( CategoryChosen, void * ); DECL_LINK( SynchronizePosAndNeg, void * ); 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/ControllerCommandDispatch.cxx b/chart2/source/controller/main/ControllerCommandDispatch.cxx index 2652aadfdb32..a01b80bfa22b 100644 --- a/chart2/source/controller/main/ControllerCommandDispatch.cxx +++ b/chart2/source/controller/main/ControllerCommandDispatch.cxx @@ -528,6 +528,23 @@ void ControllerCommandDispatch::updateCommandAvailability() bool bShapeContext = ( m_pChartController ? m_pChartController->isShapeContext() : false ); + bool bDisableDataTableDialog = false; + if ( m_xController.is() ) + { + Reference< beans::XPropertySet > xProps( m_xController->getModel(), uno::UNO_QUERY ); + if ( xProps.is() ) + { + try + { + xProps->getPropertyValue( C2U( "DisableDataTableDialog" ) ) >>= bDisableDataTableDialog; + } + catch( uno::Exception& e ) + { + ASSERT_EXCEPTION( e ); + } + } + } + // edit commands m_aCommandAvailability[ C2U(".uno:Cut")] = bIsWritable && bControllerStateIsValid && m_apControllerState->bIsDeleteableObjectSelected; m_aCommandAvailability[ C2U(".uno:Copy")] = bControllerStateIsValid && m_apControllerState->bHasSelectedObject; @@ -595,7 +612,7 @@ void ControllerCommandDispatch::updateCommandAvailability() // depending on own data m_aCommandAvailability[ C2U(".uno:DataRanges")] = bIsWritable && bModelStateIsValid && (! m_apModelState->bHasOwnData); - m_aCommandAvailability[ C2U(".uno:DiagramData")] = bIsWritable && bModelStateIsValid && m_apModelState->bHasOwnData; + m_aCommandAvailability[ C2U(".uno:DiagramData")] = bIsWritable && bModelStateIsValid && m_apModelState->bHasOwnData && !bDisableDataTableDialog; // titles m_aCommandAvailability[ C2U(".uno:MainTitle")] = bIsWritable && bModelStateIsValid && m_apModelState->bHasMainTitle; @@ -631,9 +648,9 @@ void ControllerCommandDispatch::updateCommandAvailability() // series arrangement m_aCommandAvailability[ C2U(".uno:Forward")] = ( bShapeContext ? isShapeControllerCommandAvailable( C2U( ".uno:Forward" ) ) : - ( bIsWritable && bControllerStateIsValid && m_apControllerState->bMayMoveSeriesForward ) ); + ( bIsWritable && bControllerStateIsValid && m_apControllerState->bMayMoveSeriesForward && !bDisableDataTableDialog ) ); m_aCommandAvailability[ C2U(".uno:Backward")] = ( bShapeContext ? isShapeControllerCommandAvailable( C2U( ".uno:Backward" ) ) : - ( bIsWritable && bControllerStateIsValid && m_apControllerState->bMayMoveSeriesBackward ) ); + ( bIsWritable && bControllerStateIsValid && m_apControllerState->bMayMoveSeriesBackward && !bDisableDataTableDialog ) ); m_aCommandAvailability[ C2U(".uno:InsertDataLabels")] = bIsWritable; m_aCommandAvailability[ C2U(".uno:InsertDataLabel")] = bIsWritable; 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 --- 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/tools/WrappedPropertySet.cxx b/chart2/source/tools/WrappedPropertySet.cxx index 116ce6f417f9..843aeb261a5f 100644 --- a/chart2/source/tools/WrappedPropertySet.cxx +++ b/chart2/source/tools/WrappedPropertySet.cxx @@ -34,6 +34,8 @@ // header for define DELETEZ #include <tools/solar.h> +#include <tools/debug.hxx> + //............................................................................. namespace chart { @@ -115,7 +117,11 @@ void SAL_CALL WrappedPropertySet::setPropertyValue( const OUString& rPropertyNam else if( xInnerPropertySet.is() ) xInnerPropertySet->setPropertyValue( rPropertyName, rValue ); else - throw beans::UnknownPropertyException(); + { +#if OSL_DEBUG_LEVEL > 1 + DBG_ERROR("found no inner property set to map to"); +#endif + } } catch( beans::UnknownPropertyException& ex ) { @@ -160,7 +166,11 @@ Any SAL_CALL WrappedPropertySet::getPropertyValue( const OUString& rPropertyName else if( xInnerPropertySet.is() ) aRet = xInnerPropertySet->getPropertyValue( rPropertyName ); else - throw beans::UnknownPropertyException(); + { +#if OSL_DEBUG_LEVEL > 1 + DBG_ERROR("found no inner property set to map to"); +#endif + } } catch( beans::UnknownPropertyException& ex ) { 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/AccessibleFilterTopWindow.hxx b/sc/inc/AccessibleFilterTopWindow.hxx index 7d01317c6b8d..55fcb503f51b 100644 --- a/sc/inc/AccessibleFilterTopWindow.hxx +++ b/sc/inc/AccessibleFilterTopWindow.hxx @@ -58,9 +58,6 @@ public: // Non-UNO Methods - ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > - getAccessibleChildMenu(); - enum ChildControlType { LISTBOX, TOGGLE_ALL, SINGLE_ON_BTN, SINGLE_OFF_BTN, OK_BTN, CANCEL_BTN }; diff --git a/sc/inc/ViewSettingsSequenceDefines.hxx b/sc/inc/ViewSettingsSequenceDefines.hxx index 9e787ea590fe..f23229d31a43 100644 --- a/sc/inc/ViewSettingsSequenceDefines.hxx +++ b/sc/inc/ViewSettingsSequenceDefines.hxx @@ -61,7 +61,7 @@ // this are the defines for the position of the settings in the // TableViewSettingsSequence -#define SC_TABLE_VIEWSETTINGS_COUNT 14 +#define SC_TABLE_VIEWSETTINGS_COUNT 15 #define SC_CURSOR_X 0 #define SC_CURSOR_Y 1 @@ -77,6 +77,7 @@ #define SC_TABLE_ZOOM_TYPE 11 #define SC_TABLE_ZOOM_VALUE 12 #define SC_TABLE_PAGE_VIEW_ZOOM_VALUE 13 +#define SC_TABLE_TAB_BG_COLOR 14 #define SC_CURSORPOSITIONX "CursorPositionX" #define SC_CURSORPOSITIONY "CursorPositionY" diff --git a/sc/inc/address.hxx b/sc/inc/address.hxx index 3eef919e2f1b..c5d49632292e 100644 --- a/sc/inc/address.hxx +++ b/sc/inc/address.hxx @@ -82,9 +82,10 @@ const SCSIZE SCSIZE_MAX = ::std::numeric_limits<SCSIZE>::max(); // A define to handle critical sections we hopefully don't need very often. #define SC_ROWLIMIT_MORE_THAN_32K 1 /* set to 1 if we throw the switch */ -// The maximum values. Defines are needed for preprocessor checks in -// bcaslot.cxx, otherwise type safe constants are preferred. -#define MAXROWCOUNT_DEFINE 65536 +// The maximum values. Defines are needed for preprocessor checks, for example +// in bcaslot.cxx, otherwise type safe constants are preferred. +//#define MAXROWCOUNT_DEFINE 65536 +#define MAXROWCOUNT_DEFINE 1048576 #define MAXCOLCOUNT_DEFINE 1024 // Count values @@ -123,7 +124,11 @@ const SCROW SCROW_REPEAT_NONE = SCROW_MAX; // #if SC_ROWLIMIT_MORE_THAN_64K // #error row limit 64k // #endif -#define SC_ROWLIMIT_MORE_THAN_64K 0 /* set to 1 if we throw the switch */ +#if MAXROWCOUNT_DEFINE > 65536 +#define SC_ROWLIMIT_MORE_THAN_64K 1 +#else +#define SC_ROWLIMIT_MORE_THAN_64K 0 +#endif const SCROW SCROWS64K = 65536; // === old stuff defines ===================================================== diff --git a/sc/inc/attarray.hxx b/sc/inc/attarray.hxx index c82d607577bf..11b21bab0162 100644 --- a/sc/inc/attarray.hxx +++ b/sc/inc/attarray.hxx @@ -35,6 +35,7 @@ class ScDocument; class ScMarkArray; class ScPatternAttr; class ScStyleSheet; +class ScFlatBoolRowSegments; class Rectangle; class SfxItemPoolCache; @@ -154,7 +155,7 @@ public: BOOL bRefresh, BOOL bAttrs ); BOOL RemoveAreaMerge( SCROW nStartRow, SCROW nEndRow ); - void FindStyleSheet( const SfxStyleSheetBase* pStyleSheet, BOOL* pUsed, BOOL bReset ); + void FindStyleSheet( const SfxStyleSheetBase* pStyleSheet, ScFlatBoolRowSegments& rUsedRows, bool bReset ); BOOL IsStyleSheetUsed( const ScStyleSheet& rStyle, BOOL bGatherAllStyles ) const; void DeleteAreaSafe(SCROW nStartRow, SCROW nEndRow); diff --git a/sc/inc/cellsuno.hxx b/sc/inc/cellsuno.hxx index 13469b110455..a53f167b164a 100644 --- a/sc/inc/cellsuno.hxx +++ b/sc/inc/cellsuno.hxx @@ -90,6 +90,7 @@ #include <com/sun/star/document/XActionLockable.hpp> #include <com/sun/star/beans/XTolerantMultiPropertySet.hpp> #include <com/sun/star/sheet/XExternalSheetName.hpp> +#include <com/sun/star/document/XEventsSupplier.hpp> #include <cppuhelper/implbase2.hxx> #include <cppuhelper/implbase3.hxx> @@ -1002,7 +1003,8 @@ class ScTableSheetObj : public ScCellRangeObj, public com::sun::star::util::XProtectable, public com::sun::star::sheet::XScenario, public com::sun::star::sheet::XScenarioEnhanced, - public com::sun::star::sheet::XExternalSheetName + public com::sun::star::sheet::XExternalSheetName, + public com::sun::star::document::XEventsSupplier { friend class ScTableSheetsObj; // fuer insertByName() @@ -1207,6 +1209,10 @@ public: throw (::com::sun::star::container::ElementExistException, ::com::sun::star::uno::RuntimeException); + // XEventsSupplier + virtual ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameReplace > SAL_CALL getEvents() + throw (::com::sun::star::uno::RuntimeException); + // XPropertySet ueberladen wegen Sheet-Properties virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() diff --git a/sc/inc/chartuno.hxx b/sc/inc/chartuno.hxx index 795d655f3d06..fe261f26e517 100644 --- a/sc/inc/chartuno.hxx +++ b/sc/inc/chartuno.hxx @@ -31,6 +31,8 @@ #include "address.hxx" #include <svl/lstner.hxx> #include <tools/string.hxx> +#include <comphelper/proparrhlp.hxx> +#include <comphelper/propertycontainer.hxx> #include <com/sun/star/table/XTableChart.hpp> #include <com/sun/star/table/XTableCharts.hpp> @@ -39,6 +41,7 @@ #include <com/sun/star/container/XEnumerationAccess.hpp> #include <com/sun/star/container/XIndexAccess.hpp> #include <com/sun/star/container/XNamed.hpp> +#include <cppuhelper/compbase4.hxx> #include <cppuhelper/implbase4.hxx> @@ -113,12 +116,20 @@ public: }; -class ScChartObj : public cppu::WeakImplHelper4< - com::sun::star::table::XTableChart, - com::sun::star::document::XEmbeddedObjectSupplier, - com::sun::star::container::XNamed, - com::sun::star::lang::XServiceInfo >, - public SfxListener +typedef ::cppu::WeakComponentImplHelper4< + ::com::sun::star::table::XTableChart, + ::com::sun::star::document::XEmbeddedObjectSupplier, + ::com::sun::star::container::XNamed, + ::com::sun::star::lang::XServiceInfo > ScChartObj_Base; + +typedef ::comphelper::OPropertyContainer ScChartObj_PBase; +typedef ::comphelper::OPropertyArrayUsageHelper< ScChartObj > ScChartObj_PABase; + +class ScChartObj : public ::comphelper::OBaseMutex + ,public ScChartObj_Base + ,public ScChartObj_PBase + ,public ScChartObj_PABase + ,public SfxListener { private: ScDocShell* pDocShell; @@ -128,12 +139,32 @@ private: void Update_Impl( const ScRangeListRef& rRanges, bool bColHeaders, bool bRowHeaders ); void GetData_Impl( ScRangeListRef& rRanges, bool& rColHeaders, bool& rRowHeaders ) const; +protected: + // ::comphelper::OPropertySetHelper + virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper(); + virtual void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const ::com::sun::star::uno::Any& rValue ) + throw (::com::sun::star::uno::Exception); + using ::cppu::OPropertySetHelper::getFastPropertyValue; + virtual void SAL_CALL getFastPropertyValue( ::com::sun::star::uno::Any& rValue, sal_Int32 nHandle ) const; + + // ::comphelper::OPropertyArrayUsageHelper + virtual ::cppu::IPropertyArrayHelper* createArrayHelper() const; + public: ScChartObj(ScDocShell* pDocSh, SCTAB nT, const String& rN); virtual ~ScChartObj(); virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ); + // XInterface + DECLARE_XINTERFACE() + + // XTypeProvider + DECLARE_XTYPEPROVIDER() + + // XComponent + virtual void SAL_CALL disposing(); + // XTableChart virtual sal_Bool SAL_CALL getHasColumnHeaders() throw(::com::sun::star::uno::RuntimeException); virtual void SAL_CALL setHasColumnHeaders( sal_Bool bHasColumnHeaders ) @@ -163,6 +194,10 @@ public: throw(::com::sun::star::uno::RuntimeException); virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() throw(::com::sun::star::uno::RuntimeException); + + // XPropertySet + virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() + throw (::com::sun::star::uno::RuntimeException); }; #endif diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx index 7027b55259d0..af6292bbd830 100644 --- a/sc/inc/column.hxx +++ b/sc/inc/column.hxx @@ -30,7 +30,6 @@ #include "markarr.hxx" #include "global.hxx" -#include "compressedarray.hxx" #include "address.hxx" #include "rangenam.hxx" #include <tools/solar.h> @@ -65,7 +64,7 @@ class ScPostIt; struct ScFunctionData; struct ScLineFlags; struct ScMergePatternState; - +class ScFlatBoolRowSegments; #define COLUMN_DELTA 4 @@ -209,10 +208,10 @@ public: // UpdateSelectionFunction: Mehrfachselektion void UpdateSelectionFunction( const ScMarkData& rMark, ScFunctionData& rData, - const ScBitMaskCompressedArray< SCROW, BYTE>* pRowFlags, + ScFlatBoolRowSegments& rHiddenRows, BOOL bDoExclude, SCROW nExStartRow, SCROW nExEndRow ); void UpdateAreaFunction( ScFunctionData& rData, - const ScBitMaskCompressedArray< SCROW, BYTE>* pRowFlags, + ScFlatBoolRowSegments& rHiddenRows, SCROW nStartRow, SCROW nEndRow ); void CopyToColumn(SCROW nRow1, SCROW nRow2, USHORT nFlags, BOOL bMarked, @@ -275,7 +274,6 @@ public: void CalcAfterLoad(); void CompileAll(); void CompileXML( ScProgress& rProgress ); - bool MarkUsedExternalReferences(); void ResetChanged( SCROW nStartRow, SCROW nEndRow ); @@ -330,7 +328,7 @@ public: const ScStyleSheet* GetSelectionStyle( const ScMarkData& rMark, BOOL& rFound ) const; const ScStyleSheet* GetAreaStyle( BOOL& rFound, SCROW nRow1, SCROW nRow2 ) const; - void FindStyleSheet( const SfxStyleSheetBase* pStyleSheet, BOOL* pUsed, BOOL bReset ); + void FindStyleSheet( const SfxStyleSheetBase* pStyleSheet, ScFlatBoolRowSegments& rUsedRows, bool bReset ); BOOL IsStyleSheetUsed( const ScStyleSheet& rStyle, BOOL bGatherAllStyles ) const; /// May return -1 if not found @@ -397,8 +395,8 @@ public: void CompileColRowNameFormula(); sal_Int32 GetMaxStringLen( SCROW nRowStart, SCROW nRowEnd, CharSet eCharSet ) const; - xub_StrLen GetMaxNumberStringLen( USHORT& nPrecision, - SCROW nRowStart, SCROW nRowEnd ) const; + xub_StrLen GetMaxNumberStringLen( sal_uInt16& nPrecision, + SCROW nRowStart, SCROW nRowEnd ) const; private: ScBaseCell* CloneCell(SCSIZE nIndex, USHORT nFlags, ScDocument& rDestDoc, const ScAddress& rDestPos); diff --git a/sc/inc/convuno.hxx b/sc/inc/convuno.hxx index 135ac055b2fe..0f93d6d6de0d 100644 --- a/sc/inc/convuno.hxx +++ b/sc/inc/convuno.hxx @@ -28,6 +28,7 @@ #ifndef SC_CONVUNO_HXX #define SC_CONVUNO_HXX +#include <algorithm> #include <i18npool/lang.h> #include <com/sun/star/table/CellAddress.hpp> #include <com/sun/star/table/CellRangeAddress.hpp> @@ -70,6 +71,19 @@ public: static inline void FillApiEndAddress( ::com::sun::star::table::CellAddress& rApiAddress, const ::com::sun::star::table::CellRangeAddress& rApiRange ); + + /** Returns true, if the passed ranges have at least one common cell. */ + static inline bool Intersects( + const ::com::sun::star::table::CellRangeAddress& rApiARange1, + const ::com::sun::star::table::CellRangeAddress& rApiARange2 ); + /** Returns true, if the passed address rApiInner is inside the passed range rApiOuter. */ + static inline bool Contains( + const ::com::sun::star::table::CellRangeAddress& rApiOuter, + const ::com::sun::star::table::CellAddress& rApiInner ); + /** Returns true, if the passed range rApiInner is completely inside the passed range rApiOuter. */ + static inline bool Contains( + const ::com::sun::star::table::CellRangeAddress& rApiOuter, + const ::com::sun::star::table::CellRangeAddress& rApiInner ); }; @@ -135,6 +149,33 @@ inline void ScUnoConversion::FillApiEndAddress( rApiAddress.Sheet = rApiRange.Sheet; } +inline bool ScUnoConversion::Intersects( + const ::com::sun::star::table::CellRangeAddress& rApiRange1, + const ::com::sun::star::table::CellRangeAddress& rApiRange2 ) +{ + return (rApiRange1.Sheet == rApiRange2.Sheet) && + (::std::max( rApiRange1.StartColumn, rApiRange2.StartColumn ) <= ::std::min( rApiRange1.EndColumn, rApiRange2.EndColumn )) && + (::std::max( rApiRange1.StartRow, rApiRange2.StartRow ) <= ::std::min( rApiRange1.EndRow, rApiRange2.EndRow )); +} + +inline bool ScUnoConversion::Contains( + const ::com::sun::star::table::CellRangeAddress& rApiOuter, + const ::com::sun::star::table::CellAddress& rApiInner ) +{ + return (rApiOuter.Sheet == rApiInner.Sheet) && + (rApiOuter.StartColumn <= rApiInner.Column) && (rApiInner.Column <= rApiOuter.EndColumn) && + (rApiOuter.StartRow <= rApiInner.Row) && (rApiInner.Row <= rApiOuter.EndRow); +} + +inline bool ScUnoConversion::Contains( + const ::com::sun::star::table::CellRangeAddress& rApiOuter, + const ::com::sun::star::table::CellRangeAddress& rApiInner ) +{ + return (rApiOuter.Sheet == rApiInner.Sheet) && + (rApiOuter.StartColumn <= rApiInner.StartColumn) && (rApiInner.EndColumn <= rApiOuter.EndColumn) && + (rApiOuter.StartRow <= rApiInner.StartRow) && (rApiInner.EndRow <= rApiOuter.EndRow); +} + //___________________________________________________________________ inline sal_Bool operator==( diff --git a/sc/inc/dociter.hxx b/sc/inc/dociter.hxx index dd1d18e49a51..d995550a2f1d 100644 --- a/sc/inc/dociter.hxx +++ b/sc/inc/dociter.hxx @@ -36,6 +36,8 @@ #include <memory> +#include <set> + class ScDocument; class ScBaseCell; class ScPatternAttr; @@ -206,8 +208,6 @@ private: ::std::auto_ptr<ScDBQueryParamBase> mpParam; ::std::auto_ptr<DataAccess> mpData; - bool GetThis(Value& rValue); - public: ScDBQueryDataIterator(ScDocument* pDocument, ScDBQueryParamBase* pParam); /// Does NOT reset rValue if no value found! @@ -305,7 +305,6 @@ public: ScBaseCell* GetNext(); SCCOL GetCol() { return nCol; } SCROW GetRow() { return nRow; } - ULONG GetNumberFormat(); // setzt alle Entry.nField einen weiter, wenn Spalte // wechselt, fuer ScInterpreter ScHLookup() @@ -514,6 +513,23 @@ public: const ScBaseCell* GetCell() const { return pFoundCell; } }; +// ============================================================================ + +class ScRowBreakIterator +{ +public: + static SCROW NOT_FOUND; + + explicit ScRowBreakIterator(::std::set<SCROW>& rBreaks); + SCROW first(); + SCROW next(); + +private: + ::std::set<SCROW>& mrBreaks; + ::std::set<SCROW>::const_iterator maItr; + ::std::set<SCROW>::const_iterator maEnd; +}; + #endif diff --git a/sc/inc/docoptio.hxx b/sc/inc/docoptio.hxx index 9dd1057db67f..6f6d4c859a5c 100644 --- a/sc/inc/docoptio.hxx +++ b/sc/inc/docoptio.hxx @@ -38,7 +38,7 @@ class SC_DLLPUBLIC ScDocOptions { double fIterEps; // Epsilon-Wert dazu USHORT nIterCount; // Anzahl - USHORT nPrecStandardFormat; // Nachkommastellen Standard + sal_uInt16 nPrecStandardFormat; // precision for standard format USHORT nDay; // Nulldatum: USHORT nMonth; USHORT nYear; @@ -86,8 +86,8 @@ public: inline int operator==( const ScDocOptions& rOpt ) const; inline int operator!=( const ScDocOptions& rOpt ) const; - USHORT GetStdPrecision() const { return nPrecStandardFormat; } - void SetStdPrecision( USHORT n ) { nPrecStandardFormat = n; } + sal_uInt16 GetStdPrecision() const { return nPrecStandardFormat; } + void SetStdPrecision( sal_uInt16 n ) { nPrecStandardFormat = n; } BOOL IsCalcAsShown() const { return bCalcAsShown; } void SetCalcAsShown( BOOL bVal ) { bCalcAsShown = bVal; } diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx index e9bbfbd8b40d..f7ae5e63f165 100644 --- a/sc/inc/document.hxx +++ b/sc/inc/document.hxx @@ -44,6 +44,7 @@ #include <memory> #include <map> +#include <set> // Wang Xu Ming -- 2009-8-17 // DataPilot Migration - Cache&&Performance @@ -144,6 +145,7 @@ class SfxUndoManager; class ScFormulaParserPool; struct ScClipParam; struct ScClipRangeNameData; +class ScRowBreakIterator; namespace com { namespace sun { namespace star { namespace lang { @@ -159,6 +161,9 @@ namespace com { namespace sun { namespace star { namespace embed { class XEmbeddedObject; } + namespace sheet { + struct TablePageBreakData; + } } } } #include <svl/zforlist.hxx> @@ -381,12 +386,12 @@ private: // kein Broadcast, keine Listener aufbauen waehrend aus einem anderen // Doc (per Filter o.ae.) inserted wird, erst bei CompileAll / CalcAfterLoad BOOL bInsertingFromOtherDoc; - BOOL bImportingXML; // special handling of formula text + bool bLoadingMedium; + bool bImportingXML; // special handling of formula text BOOL bXMLFromWrapper; // distinguish ScXMLImportWrapper from external component BOOL bCalcingAfterLoad; // in CalcAfterLoad TRUE // wenn temporaer keine Listener auf/abgebaut werden sollen BOOL bNoListening; - BOOL bLoadingDone; BOOL bIdleDisabled; BOOL bInLinkUpdate; // TableLink or AreaLink BOOL bChartListenerCollectionNeedsUpdate; @@ -428,8 +433,6 @@ private: sal_Int16 mnNamedRangesLockCount; - inline BOOL RowHidden( SCROW nRow, SCTAB nTab ); // FillInfo - public: SC_DLLPUBLIC ULONG GetCellCount() const; // alle Zellen SCSIZE GetCellCount(SCTAB nTab, SCCOL nCol) const; @@ -616,6 +619,9 @@ public: Color& rColor, USHORT& rFlags ) const; SC_DLLPUBLIC void SetScenarioData( SCTAB nTab, const String& rComment, const Color& rColor, USHORT nFlags ); + SC_DLLPUBLIC Color GetTabBgColor( SCTAB nTab ) const; + SC_DLLPUBLIC void SetTabBgColor( SCTAB nTab, const Color& rColor ); + SC_DLLPUBLIC bool IsDefaultTabBgColor( SCTAB nTab ) const; void GetScenarioFlags( SCTAB nTab, USHORT& rFlags ) const; SC_DLLPUBLIC BOOL IsActiveScenario( SCTAB nTab ) const; SC_DLLPUBLIC void SetActiveScenario( SCTAB nTab, BOOL bActive ); // nur fuer Undo etc. @@ -731,6 +737,14 @@ public: BOOL HasBackgroundDraw( SCTAB nTab, const Rectangle& rMMRect ); BOOL HasAnyDraw( SCTAB nTab, const Rectangle& rMMRect ); + const ScSheetEvents* GetSheetEvents( SCTAB nTab ) const; + void SetSheetEvents( SCTAB nTab, const ScSheetEvents* pNew ); + bool HasSheetEventScript( sal_Int32 nEvent ) const; // on any sheet + + BOOL HasCalcNotification( SCTAB nTab ) const; + void SetCalcNotification( SCTAB nTab ); + void ResetCalcNotifications(); + SC_DLLPUBLIC ScOutlineTable* GetOutlineTable( SCTAB nTab, BOOL bCreate = FALSE ); BOOL SetOutlineTable( SCTAB nTab, const ScOutlineTable* pNewOutline ); @@ -906,7 +920,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, @@ -917,12 +931,17 @@ public: SCROW& rEndRow, BOOL bNotes = TRUE ) const; void InvalidateTableArea(); + SC_DLLPUBLIC BOOL GetDataStart( SCTAB nTab, SCCOL& rStartCol, SCROW& rStartRow ) const; + /** + * Find the maximum column position that contains printable data for the + * specified row range. The final column position must be equal or less + * than the initial value of rEndCol. + */ void ExtendPrintArea( OutputDevice* pDev, SCTAB nTab, SCCOL nStartCol, SCROW nStartRow, SCCOL& rEndCol, SCROW nEndRow ); - SC_DLLPUBLIC SCSIZE GetEmptyLinesInBlock( SCCOL nStartCol, SCROW nStartRow, SCTAB nStartTab, SCCOL nEndCol, SCROW nEndRow, SCTAB nEndTab, ScDirection eDir ); @@ -1246,19 +1265,20 @@ public: void DeleteSelection( USHORT nDelFlag, const ScMarkData& rMark ); void DeleteSelectionTab( SCTAB nTab, USHORT nDelFlag, const ScMarkData& rMark ); - // - SC_DLLPUBLIC void SetColWidth( SCCOL nCol, SCTAB nTab, USHORT nNewWidth ); SC_DLLPUBLIC void SetRowHeight( SCROW nRow, SCTAB nTab, USHORT nNewHeight ); SC_DLLPUBLIC void SetRowHeightRange( SCROW nStartRow, SCROW nEndRow, SCTAB nTab, USHORT nNewHeight ); - void SetManualHeight( SCROW nStartRow, SCROW nEndRow, SCTAB nTab, BOOL bManual ); + + SC_DLLPUBLIC void SetRowHeightOnly( SCROW nStartRow, SCROW nEndRow, SCTAB nTab, + USHORT nNewHeight ); + void SetManualHeight( SCROW nStartRow, SCROW nEndRow, SCTAB nTab, BOOL bManual ); SC_DLLPUBLIC USHORT GetColWidth( SCCOL nCol, SCTAB nTab ) const; - SC_DLLPUBLIC USHORT GetRowHeight( SCROW nRow, SCTAB nTab ) const; + SC_DLLPUBLIC USHORT GetRowHeight( SCROW nRow, SCTAB nTab, bool bHiddenAsZero = true ) const; SC_DLLPUBLIC ULONG GetRowHeight( SCROW nStartRow, SCROW nEndRow, SCTAB nTab ) const; - ULONG GetScaledRowHeight( SCROW nStartRow, SCROW nEndRow, SCTAB nTab, double fScale ) const; - SC_DLLPUBLIC const ScSummableCompressedArray< SCROW, USHORT> & GetRowHeightArray( SCTAB nTab ) const; + SCROW GetRowForHeight( SCTAB nTab, ULONG nHeight ) const; + ULONG GetScaledRowHeight( SCROW nStartRow, SCROW nEndRow, SCTAB nTab, double fScale ) const; SC_DLLPUBLIC ULONG GetColOffset( SCCOL nCol, SCTAB nTab ) const; SC_DLLPUBLIC ULONG GetRowOffset( SCROW nRow, SCTAB nTab ) const; @@ -1267,22 +1287,6 @@ public: USHORT GetCommonWidth( SCCOL nEndCol, SCTAB nTab ) const; - // All FastGet...() methods have no check for valid nTab! - // They access ScCompressedArray objects, so using the - // single row taking ones in loops to access a sequence of - // single rows is no good idea! Use specialized range - // taking methods instead, or iterators. - SC_DLLPUBLIC ULONG FastGetRowHeight( SCROW nStartRow, SCROW nEndRow, - SCTAB nTab ) const; - inline ULONG FastGetScaledRowHeight( SCROW nStartRow, SCROW nEndRow, - SCTAB nTab, double fScale ) const; - SC_DLLPUBLIC inline USHORT FastGetRowHeight( SCROW nRow, SCTAB nTab ) const; - inline SCROW FastGetRowForHeight( SCTAB nTab, ULONG nHeight ) const; - inline SCROW FastGetFirstNonHiddenRow( SCROW nStartRow, SCTAB nTab ) const; - /** No check for flags whether row is hidden, height value - is returned unconditionally. */ - inline USHORT FastGetOriginalRowHeight( SCROW nRow, SCTAB nTab ) const; - SCROW GetHiddenRowCount( SCROW nRow, SCTAB nTab ) const; USHORT GetOptimalColWidth( SCCOL nCol, SCTAB nTab, OutputDevice* pDev, @@ -1319,6 +1323,44 @@ public: SC_DLLPUBLIC const ScBitMaskCompressedArray< SCROW, BYTE> & GetRowFlagsArray( SCTAB nTab ) const; SC_DLLPUBLIC ScBitMaskCompressedArray< SCROW, BYTE> & GetRowFlagsArrayModifiable( SCTAB nTab ); + SC_DLLPUBLIC void GetAllRowBreaks(::std::set<SCROW>& rBreaks, SCTAB nTab, bool bPage, bool bManual) const; + SC_DLLPUBLIC void GetAllColBreaks(::std::set<SCCOL>& rBreaks, SCTAB nTab, bool bPage, bool bManual) const; + SC_DLLPUBLIC ScBreakType HasRowBreak(SCROW nRow, SCTAB nTab) const; + SC_DLLPUBLIC ScBreakType HasColBreak(SCCOL nCol, SCTAB nTab) const; + SC_DLLPUBLIC void SetRowBreak(SCROW nRow, SCTAB nTab, bool bPage, bool bManual); + SC_DLLPUBLIC void SetColBreak(SCCOL nCol, SCTAB nTab, bool bPage, bool bManual); + void RemoveRowBreak(SCROW nRow, SCTAB nTab, bool bPage, bool bManual); + void RemoveColBreak(SCCOL nCol, SCTAB nTab, bool bPage, bool bManual); + ::com::sun::star::uno::Sequence< + ::com::sun::star::sheet::TablePageBreakData> GetRowBreakData(SCTAB nTab) const; + + SC_DLLPUBLIC bool RowHidden(SCROW nRow, SCTAB nTab, SCROW* pFirstRow = NULL, SCROW* pLastRow = NULL); + SC_DLLPUBLIC bool RowHidden(SCROW nRow, SCTAB nTab, SCROW& rLastRow); + SC_DLLPUBLIC bool HasHiddenRows(SCROW nStartRow, SCROW nEndRow, SCTAB nTab); + SC_DLLPUBLIC bool ColHidden(SCCOL nCol, SCTAB nTab, SCCOL& rLastCol); + SC_DLLPUBLIC bool ColHidden(SCCOL nCol, SCTAB nTab, SCCOL* pFirstCol = NULL, SCCOL* pLastCol = NULL); + SC_DLLPUBLIC void SetRowHidden(SCROW nStartRow, SCROW nEndRow, SCTAB nTab, bool bHidden); + SC_DLLPUBLIC void SetColHidden(SCCOL nStartCol, SCCOL nEndCol, SCTAB nTab, bool bHidden); + SC_DLLPUBLIC SCROW FirstVisibleRow(SCROW nStartRow, SCROW nEndRow, SCTAB nTab); + SC_DLLPUBLIC SCROW LastVisibleRow(SCROW nStartRow, SCROW nEndRow, SCTAB nTab); + SCROW CountVisibleRows(SCROW nStartRow, SCROW nEndRow, SCTAB nTab); + + bool RowFiltered(SCROW nRow, SCTAB nTab, SCROW* pFirstRow = NULL, SCROW* pLastRow = NULL); + bool HasFilteredRows(SCROW nStartRow, SCROW nEndRow, SCTAB nTab); + bool ColFiltered(SCCOL nCol, SCTAB nTab, SCCOL* pFirstCol = NULL, SCCOL* pLastCol = NULL); + SC_DLLPUBLIC void SetRowFiltered(SCROW nStartRow, SCROW nEndRow, SCTAB nTab, bool bFiltered); + SC_DLLPUBLIC void SetColFiltered(SCCOL nStartCol, SCCOL nEndCol, SCTAB nTab, bool bFiltered); + SCROW FirstNonFilteredRow(SCROW nStartRow, SCROW nEndRow, SCTAB nTab); + SCROW LastNonFilteredRow(SCROW nStartRow, SCROW nEndRow, SCTAB nTab); + SCROW CountNonFilteredRows(SCROW nStartRow, SCROW nEndRow, SCTAB nTab); + + /** + * Write all column row flags to table's flag data, because not all column + * row attributes are stored in the flag data members. This is necessary + * for ods export. + */ + void SyncColRowFlags(); + /// @return the index of the last row with any set flags (auto-pagebreak is ignored). SC_DLLPUBLIC SCROW GetLastFlaggedRow( SCTAB nTab ) const; @@ -1340,8 +1382,6 @@ public: BOOL GetColDefault( SCTAB nTab, SCCOL nCol, SCROW nLastRow, SCROW& nDefault); BOOL GetRowDefault( SCTAB nTab, SCROW nRow, SCCOL nLastCol, SCCOL& nDefault); - BOOL IsFiltered( SCROW nRow, SCTAB nTab ) const; - BOOL UpdateOutlineCol( SCCOL nStartCol, SCCOL nEndCol, SCTAB nTab, BOOL bShow ); BOOL UpdateOutlineRow( SCROW nStartRow, SCROW nEndRow, SCTAB nTab, BOOL bShow ); @@ -1358,6 +1398,7 @@ public: Size GetPageSize( SCTAB nTab ) const; void SetPageSize( SCTAB nTab, const Size& rSize ); void SetRepeatArea( SCTAB nTab, SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCROW nEndRow ); + void InvalidatePageBreaks(SCTAB nTab); void UpdatePageBreaks( SCTAB nTab, const ScRange* pUserArea = NULL ); void RemoveManualBreaks( SCTAB nTab ); BOOL HasManualBreaks( SCTAB nTab ) const; @@ -1454,8 +1495,6 @@ public: void DoColResize( SCTAB nTab, SCCOL nCol1, SCCOL nCol2, SCSIZE nAdd ); - // Idleberechnung der OutputDevice-Zelltextbreite - BOOL IsLoadingDone() const { return bLoadingDone; } void InvalidateTextWidth( const String& rStyleName ); void InvalidateTextWidth( SCTAB nTab ); void InvalidateTextWidth( const ScAddress* pAdrFrom, const ScAddress* pAdrTo, BOOL bNumFormatChanged ); @@ -1492,8 +1531,9 @@ public: BOOL GetNoSetDirty() const { return bNoSetDirty; } void SetInsertingFromOtherDoc( BOOL bVal ) { bInsertingFromOtherDoc = bVal; } BOOL IsInsertingFromOtherDoc() const { return bInsertingFromOtherDoc; } - void SetImportingXML( BOOL bVal ); - BOOL IsImportingXML() const { return bImportingXML; } + void SetLoadingMedium( bool bVal ); + void SetImportingXML( bool bVal ); + bool IsImportingXML() const { return bImportingXML; } void SetXMLFromWrapper( BOOL bVal ); BOOL IsXMLFromWrapper() const { return bXMLFromWrapper; } void SetCalcingAfterLoad( BOOL bVal ) { bCalcingAfterLoad = bVal; } @@ -1692,9 +1732,9 @@ public: /** Maximum string length of numerical cells of a column, e.g. for dBase export. @return String length in characters (!) including the decimal separator, and the decimal precision needed. */ - xub_StrLen GetMaxNumberStringLen( USHORT& nPrecision, - SCTAB nTab, SCCOL nCol, - SCROW nRowStart, SCROW nRowEnd ) const; + xub_StrLen GetMaxNumberStringLen( sal_uInt16& nPrecision, + SCTAB nTab, SCCOL nCol, + SCROW nRowStart, SCROW nRowEnd ) const; void KeyInput( const KeyEvent& rKEvt ); // TimerDelays etc. @@ -1749,6 +1789,9 @@ public: { return eStorageGrammar; } SfxUndoManager* GetUndoManager(); + bool IsInVBAMode() const; + ScRowBreakIterator* GetRowBreakIterator(SCTAB nTab) const; + private: // CLOOK-Impl-Methoden /** @@ -1810,53 +1853,6 @@ inline void ScDocument::SetSortParam( ScSortParam& rParam, SCTAB nTab ) mSheetSortParams[ nTab ] = rParam; } - -inline ULONG ScDocument::FastGetScaledRowHeight( SCROW nStartRow, SCROW nEndRow, - SCTAB nTab, double fScale ) const -{ - return pTab[nTab]->pRowFlags->SumScaledCoupledArrayForCondition( nStartRow, - nEndRow, CR_HIDDEN, 0, *(pTab[nTab]->pRowHeight), fScale); -} - -inline USHORT ScDocument::FastGetRowHeight( SCROW nRow, SCTAB nTab ) const -{ - return ( pTab[nTab]->pRowFlags->GetValue(nRow) & CR_HIDDEN ) ? 0 : - pTab[nTab]->pRowHeight->GetValue(nRow); -} - -inline SCROW ScDocument::FastGetRowForHeight( SCTAB nTab, ULONG nHeight ) const -{ - ScCoupledCompressedArrayIterator< SCROW, BYTE, USHORT> aIter( - *(pTab[nTab]->pRowFlags), 0, MAXROW, CR_HIDDEN, 0, - *(pTab[nTab]->pRowHeight)); - ULONG nSum = 0; - for ( ; aIter; aIter.NextRange() ) - { - ULONG nNew = *aIter * (aIter.GetRangeEnd() - aIter.GetRangeStart() + 1); - if (nSum + nNew > nHeight) - { - for ( ; aIter && nSum <= nHeight; ++aIter ) - { - nSum += *aIter; - } - return aIter.GetPos(); - } - nSum += nNew; - } - return aIter.GetPos(); -} - -inline SCROW ScDocument::FastGetFirstNonHiddenRow( SCROW nStartRow, SCTAB nTab) const -{ - return pTab[nTab]->pRowFlags->GetFirstForCondition( nStartRow, MAXROW, - CR_HIDDEN, 0); -} - -inline USHORT ScDocument::FastGetOriginalRowHeight( SCROW nRow, SCTAB nTab ) const -{ - return pTab[nTab]->pRowHeight->GetValue(nRow); -} - #endif diff --git a/sc/inc/docuno.hxx b/sc/inc/docuno.hxx index 15a0c5e72359..14c9515dfacb 100644 --- a/sc/inc/docuno.hxx +++ b/sc/inc/docuno.hxx @@ -112,9 +112,9 @@ private: const com::sun::star::uno::Sequence< com::sun::star::beans::PropertyValue >& rOptions, ScMarkData& rMark, ScPrintSelectionStatus& rStatus, String& rPagesStr ) const; com::sun::star::uno::Reference<com::sun::star::uno::XAggregation> GetFormatter(); + void HandleCalculateEvents(); rtl::OUString maBuildId; - sal_Int32 mnXlsWriteProtPass; protected: const SfxItemPropertySet& GetPropertySet() const { return aPropSet; } 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/dpobject.hxx b/sc/inc/dpobject.hxx index 65e89ec75d41..44aa1daa9a92 100644 --- a/sc/inc/dpobject.hxx +++ b/sc/inc/dpobject.hxx @@ -276,6 +276,7 @@ public: virtual ScDataObject* Clone() const; ScDPObject* operator[](USHORT nIndex) const {return (ScDPObject*)At(nIndex);} + ScDPObject* GetByName(const String& rName) const; void DeleteOnTab( SCTAB nTab ); void UpdateReference( UpdateRefMode eUpdateRefMode, diff --git a/sc/inc/dptabres.hxx b/sc/inc/dptabres.hxx index e35975ab170f..7f9720a4b143 100644 --- a/sc/inc/dptabres.hxx +++ b/sc/inc/dptabres.hxx @@ -87,7 +87,7 @@ public: // Wang Xu Ming -- 2009-8-17 // DataPilot Migration - Cache&&Performance const SCROW* GetNameIds() const { return pData; } - const SCROW GetNameIdForIndex( long nIndexValue ) const; + SCROW GetNameIdForIndex( long nIndexValue ) const; // End Comments }; diff --git a/sc/inc/eventuno.hxx b/sc/inc/eventuno.hxx new file mode 100755 index 000000000000..f3ae72f0f1bf --- /dev/null +++ b/sc/inc/eventuno.hxx @@ -0,0 +1,91 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: sheetdata.hxx,v $ + * $Revision: 1.16.32.2 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SC_EVENTUNO_HXX +#define SC_EVENTUNO_HXX + +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/container/XNameReplace.hpp> +#include <cppuhelper/implbase2.hxx> +#include <svl/lstner.hxx> + +#include "global.hxx" + +class ScDocShell; + +class ScSheetEventsObj : public cppu::WeakImplHelper2< + com::sun::star::container::XNameReplace, + com::sun::star::lang::XServiceInfo>, + public SfxListener +{ +private: + ScDocShell* mpDocShell; + SCTAB mnTab; + +public: + ScSheetEventsObj(ScDocShell* pDocSh, SCTAB nT); + virtual ~ScSheetEventsObj(); + + virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint ); + + // XNameReplace + virtual void SAL_CALL replaceByName( const ::rtl::OUString& aName, + const ::com::sun::star::uno::Any& aElement ) + throw(::com::sun::star::lang::IllegalArgumentException, + ::com::sun::star::container::NoSuchElementException, + ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException); + + // XNameAccess + virtual ::com::sun::star::uno::Any SAL_CALL getByName( const ::rtl::OUString& aName ) + throw(::com::sun::star::container::NoSuchElementException, + ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getElementNames() + throw(::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName ) + throw(::com::sun::star::uno::RuntimeException); + + // XElementAccess + virtual ::com::sun::star::uno::Type SAL_CALL getElementType() + throw(::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL hasElements() throw(::com::sun::star::uno::RuntimeException); + + // XServiceInfo + virtual ::rtl::OUString SAL_CALL getImplementationName() + throw(::com::sun::star::uno::RuntimeException); + virtual sal_Bool SAL_CALL supportsService( const ::rtl::OUString& ServiceName ) + throw(::com::sun::star::uno::RuntimeException); + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getSupportedServiceNames() + throw(::com::sun::star::uno::RuntimeException); +}; + +#endif + 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/funcuno.hxx b/sc/inc/funcuno.hxx index 3eef9082e26d..4413782a0e2f 100644 --- a/sc/inc/funcuno.hxx +++ b/sc/inc/funcuno.hxx @@ -72,7 +72,8 @@ private: ScTempDocCache aDocCache; ScDocOptions* pOptions; SfxItemPropertyMap aPropertyMap; - BOOL bInvalid; + bool mbArray; + bool mbValid; public: ScFunctionAccess(); diff --git a/sc/inc/global.hxx b/sc/inc/global.hxx index 23668aa6813d..8178eb4a01d2 100644 --- a/sc/inc/global.hxx +++ b/sc/inc/global.hxx @@ -203,13 +203,16 @@ const SCSIZE PIVOT_MAXPAGEFIELD = 10; // FILTERED und MANUALSIZE nur fuer Zeilen moeglich const BYTE CR_HIDDEN = 1; //const BYTE CR_MARKED = 2; -const BYTE CR_PAGEBREAK = 4; +//const BYTE CR_PAGEBREAK = 4; const BYTE CR_MANUALBREAK = 8; const BYTE CR_FILTERED = 16; const BYTE CR_MANUALSIZE = 32; +const BYTE CR_ALL = (CR_HIDDEN | CR_MANUALBREAK | CR_FILTERED | CR_MANUALSIZE); -// was davon kommt in die Datei: -#define CR_SAVEMASK ( ~CR_PAGEBREAK ) +typedef BYTE ScBreakType; +const ScBreakType BREAK_NONE = 0; +const ScBreakType BREAK_PAGE = 1; +const ScBreakType BREAK_MANUAL = 2; // Insert-/Delete-Flags const USHORT IDF_NONE = 0x0000; diff --git a/sc/inc/globstr.hrc b/sc/inc/globstr.hrc index bca93e7aa441..31934067988a 100644 --- a/sc/inc/globstr.hrc +++ b/sc/inc/globstr.hrc @@ -353,7 +353,7 @@ #define STR_SCATTR_PAGE_SCALETOPAGES 277 #define STR_NOREF_STR 278 /* moved to compiler.src, keep define! */ -#define STR_ODER_SO 279 +// unused: 279 #define STR_UNDO_CHARTDATA 280 #define STR_UNDO_ORIGINALSIZE 281 @@ -571,9 +571,13 @@ #define STR_STYLE_FAMILY_PAGE 434 #define STR_ERR_DATAPILOTSOURCE 435 -#define STR_PIVOT_FIRSTROWEMPTYERR 436 +#define STR_PIVOT_FIRSTROWEMPTYERR 436 #define STR_PIVOT_ONLYONEROWERR 437 -#define STR_COUNT 438 + +#define STR_UNDO_SET_TAB_BG_COLOR 438 +#define STR_UNDO_SET_MULTI_TAB_BG_COLOR 439 + +#define STR_COUNT 440 #endif 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/olinetab.hxx b/sc/inc/olinetab.hxx index 3ffc03f4a249..82a49b3ba025 100644 --- a/sc/inc/olinetab.hxx +++ b/sc/inc/olinetab.hxx @@ -30,24 +30,24 @@ #include "collect.hxx" -#include "compressedarray.hxx" #include "scdllapi.h" #define SC_OL_MAXDEPTH 7 class SvStream; +class ScTable; class ScOutlineEntry : public ScDataObject { SCCOLROW nStart; SCSIZE nSize; - BOOL bHidden; - BOOL bVisible; + bool bHidden; + bool bVisible; public: ScOutlineEntry( SCCOLROW nNewStart, SCCOLROW nNewSize, - BOOL bNewHidden = FALSE ); + bool bNewHidden = FALSE ); ScOutlineEntry( const ScOutlineEntry& rEntry ); virtual ScDataObject* Clone() const; @@ -55,14 +55,14 @@ public: SCCOLROW GetStart() const { return nStart; } SCSIZE GetSize() const { return nSize; } SCCOLROW GetEnd() const { return nStart+nSize-1; } - BOOL IsHidden() const { return bHidden; } // Gruppe versteckt - BOOL IsVisible() const { return bVisible; } // Control sichtbar? + bool IsHidden() const { return bHidden; } // Gruppe versteckt + bool IsVisible() const { return bVisible; } // Control sichtbar? void Move( SCsCOLROW nDelta ); void SetSize( SCSIZE nNewSize ); void SetPosSize( SCCOLROW nNewPos, SCSIZE nNewSize ); - void SetHidden( BOOL bNewHidden ); - void SetVisible( BOOL bNewVisible ); + void SetHidden( bool bNewHidden ); + void SetVisible( bool bNewVisible ); }; @@ -123,9 +123,7 @@ public: void InsertSpace( SCCOLROW nStartPos, SCSIZE nSize ); BOOL DeleteSpace( SCCOLROW nStartPos, SCSIZE nSize ); - BOOL ManualAction( SCCOLROW nStartPos, SCCOLROW nEndPos, - BOOL bShow, - const ScBitMaskCompressedArray< SCCOLROW, BYTE>& rHiddenFlags ); + bool ManualAction( SCCOLROW nStartPos, SCCOLROW nEndPos, bool bShow, ScTable& rTable, bool bCol ); void RemoveAll(); }; diff --git a/sc/inc/sc.hrc b/sc/inc/sc.hrc index 10d61b783c18..9fd04cadf751 100644 --- a/sc/inc/sc.hrc +++ b/sc/inc/sc.hrc @@ -844,8 +844,11 @@ #define FID_TAB_INDEX (TAB_POPUP_START+6) #define FID_TAB_RTL (TAB_POPUP_START+7) #define FID_TAB_DESELECTALL (TAB_POPUP_START+8) +#define FID_TAB_MENU_SET_TAB_BG_COLOR (TAB_POPUP_START + 9) +#define FID_TAB_SET_TAB_BG_COLOR (TAB_POPUP_START + 10) +#define FID_TAB_EVENTS (TAB_POPUP_START+11) -#define TAB_POPUP_END (DATA_MENU_END + 20) +#define TAB_POPUP_END (TAB_POPUP_START + 20) #define OBJBAR_FORMAT_START (TAB_POPUP_END) #define SID_ALIGNLEFT (OBJBAR_FORMAT_START+6) @@ -1157,9 +1160,6 @@ #define RID_IMGLIST_INPUTWIN (SC_RESOURCE_START+22) #define RID_ERRHDLSC (SC_RESOURCE_START+23) #define RID_POPUP_GRAPHIC (SC_RESOURCE_START+24) -#define RID_SCTEAMDLGBMP1 (SC_RESOURCE_START+25) -#define RID_SCTEAMDLGBMP2 (SC_RESOURCE_START+26) -#define RID_SCTEAMDLGBMP3 (SC_RESOURCE_START+27) #define RID_POPUP_DRAWTEXT (SC_RESOURCE_START+29) #define RID_MN_FORMAT_ALGN (SC_RESOURCE_START+30) #define RID_MN_FORMAT_STYLE (SC_RESOURCE_START+31) @@ -1437,7 +1437,10 @@ #define RID_SCSTR_ONCLICK (STR_START + 402) -#define STR_END RID_SCSTR_ONCLICK +#define SCSTR_SET_TAB_BG_COLOR (STR_START + 403) +#define SCSTR_NO_TAB_BG_COLOR (STR_START + 404) + +#define STR_END (SCSTR_NO_TAB_BG_COLOR) #define BMP_START (STR_END) @@ -1541,7 +1544,6 @@ #define RID_SCDLG_NAMES_PASTE (SC_DIALOGS_START + 72) #define RID_SCDLG_NAMES_CREATE (SC_DIALOGS_START + 73) #define RID_SCDLG_NAMES_APPLY (SC_DIALOGS_START + 74) //NYI -#define RID_SCDLG_TEAM (SC_DIALOGS_START + 75) #define RID_SCDLG_CHAR (SC_DIALOGS_START + 76) #define RID_SCDLG_PARAGRAPH (SC_DIALOGS_START + 77) @@ -1646,8 +1648,9 @@ #define RID_SCDLG_RETYPEPASS_INPUT (SC_DIALOGS_START + 151) #define RID_SCDLG_TEXT_IMPORT_OPTIONS (SC_DIALOGS_START + 152) #define RID_POPUP_FILTER (SC_DIALOGS_START + 153) +#define RID_SCDLG_TAB_BG_COLOR (SC_DIALOGS_START + 154) -#define SC_DIALOGS_END (SC_DIALOGS_START + 154) +#define SC_DIALOGS_END (SC_DIALOGS_START + 155) #ifndef STD_MASKCOLOR #define STD_MASKCOLOR Color { Red = 0xFF00; Green = 0x0000; Blue = 0xFF00; } diff --git a/sc/inc/scabstdlg.hxx b/sc/inc/scabstdlg.hxx index d91ada912058..40711a200e19 100644 --- a/sc/inc/scabstdlg.hxx +++ b/sc/inc/scabstdlg.hxx @@ -286,6 +286,12 @@ public: virtual void GetInputString( String& rString ) const = 0; }; +class AbstractScTabBgColorDlg : public VclAbstractDialog //add for ScTabBgColorDlg +{ +public: + virtual void GetSelectedColor( Color& rColor ) const = 0; +}; + class AbstractScImportOptionsDlg : public VclAbstractDialog //add for ScImportOptionsDlg { public: @@ -435,6 +441,14 @@ public: const String& rDefault, const rtl::OString& sHelpId, const rtl::OString& sEditHelpId, int nId ) = 0; + + virtual AbstractScTabBgColorDlg * CreateScTabBgColorDlg ( Window* pParent, //add for ScTabBgColorDlg + const String& rTitle, //Dialog Title + const String& rTabBgColorNoColorText, //Label for no tab color + const Color& rDefaultColor, //Currently selected Color + const rtl::OString& , + int nId ) = 0; + virtual AbstractScImportOptionsDlg * CreateScImportOptionsDlg ( Window* pParent, //add for ScImportOptionsDlg int nId, BOOL bAscii = TRUE, diff --git a/sc/inc/sccommands.h b/sc/inc/sccommands.h index 7a1581f96627..98c26150305e 100644 --- a/sc/inc/sccommands.h +++ b/sc/inc/sccommands.h @@ -329,5 +329,8 @@ #define CMD_SID_MARKARRAYFORMULA ".uno:SelectArrayFormula"
#define CMD_FID_TAB_RTL ".uno:SheetRightToLeft"
#define CMD_SID_SHARE_DOC ".uno:ShareDocument"
+#define CMD_FID_TAB_EVENTS ".uno:TableEvents"
+#define CMD_FID_TAB_MENU_SET_TAB_BG_COLOR ".uno:SetTabBgColor"
+#define CMD_FID_TAB_SET_TAB_BG_COLOR ".uno:TabBgColor"
#endif
diff --git a/sc/inc/scextopt.hxx b/sc/inc/scextopt.hxx index b02df9816ef4..d7586fb8df95 100644 --- a/sc/inc/scextopt.hxx +++ b/sc/inc/scextopt.hxx @@ -38,7 +38,6 @@ /** Extended settings for the document, used in import/export filters. */ struct ScExtDocSettings { - ScRange maOleSize; /// Visible range if embedded. String maGlobCodeName; /// Global codename (VBA module name). double mfTabBarWidth; /// Width of the tabbar, relative to frame window width (0.0 ... 1.0). sal_uInt32 mnLinkCnt; /// Recursive counter for loading external documents. diff --git a/sc/inc/scmod.hxx b/sc/inc/scmod.hxx index e9fbf493da02..e1d9ab0fd4b9 100644 --- a/sc/inc/scmod.hxx +++ b/sc/inc/scmod.hxx @@ -74,7 +74,6 @@ class ScInputWindow; class ScTabViewShell; class ScFunctionDlg; class ScArgDlgBase; -class ScTeamDlg; class ScEditFunctionDlg; class ScMessagePool; class EditFieldInfo; @@ -126,7 +125,6 @@ class ScModule: public SfxModule, public SfxListener, utl::ConfigurationListener ScMessagePool* pMessagePool; // globalen InputHandler gibt's nicht mehr, jede View hat einen ScInputHandler* pRefInputHandler; - ScTeamDlg* pTeamDlg; ScViewCfg* pViewCfg; ScDocCfg* pDocCfg; ScAppCfg* pAppCfg; @@ -267,9 +265,6 @@ SC_DLLPUBLIC void SetAppOptions ( const ScAppOptions& rO BOOL IsFormulaMode(); BOOL IsRefDialogOpen(); BOOL IsTableLocked(); - void OpenTeamDlg(); - void SetTeamDlg( ScTeamDlg* pDlg ) { pTeamDlg = pDlg; } - ScTeamDlg* GetTeamDlg() const { return pTeamDlg; } void SetReference( const ScRange& rRef, ScDocument* pDoc, const ScMarkData* pMarkData = NULL ); void AddRefEntry(); @@ -286,13 +281,11 @@ SC_DLLPUBLIC void SetAppOptions ( const ScAppOptions& rO void SetInSharedDocSaving( bool bNew ) { mbIsInSharedDocSaving = bNew; } bool IsInSharedDocSaving() const { return mbIsInSharedDocSaving; } - //<!--Added by PengYunQuan for Validity Cell Range Picker SC_DLLPUBLIC BOOL RegisterRefWindow( USHORT nSlotId, Window *pWnd ); SC_DLLPUBLIC BOOL UnregisterRefWindow( USHORT nSlotId, Window *pWnd ); SC_DLLPUBLIC BOOL IsAliveRefDlg( USHORT nSlotId, Window *pWnd ); SC_DLLPUBLIC Window * Find1RefWindow( USHORT nSlotId, Window *pWndAncestor ); SC_DLLPUBLIC Window * Find1RefWindow( Window *pWndAncestor ); - //-->Added by PengYunQuan for Validity Cell Range Picker }; #define SC_MOD() ( *(ScModule**) GetAppData(SHL_CALC) ) diff --git a/sc/inc/segmenttree.hxx b/sc/inc/segmenttree.hxx new file mode 100644 index 000000000000..195331c750ad --- /dev/null +++ b/sc/inc/segmenttree.hxx @@ -0,0 +1,172 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SC_SEGMENTTREE_HXX +#define SC_SEGMENTTREE_HXX + +#include "address.hxx" + +#include <memory> + +class ScFlatBoolSegmentsImpl; + +class ScFlatBoolRowSegments +{ +public: + struct RangeData + { + SCROW mnRow1; + SCROW mnRow2; + bool mbValue; + }; + + class ForwardIterator + { + public: + explicit ForwardIterator(ScFlatBoolRowSegments& rSegs); + + bool getValue(SCROW nPos, bool& rVal); + SCROW getLastPos() const; + + private: + ScFlatBoolRowSegments& mrSegs; + + SCROW mnCurPos; + SCROW mnLastPos; + bool mbCurValue; + }; + + class RangeIterator + { + public: + explicit RangeIterator(ScFlatBoolRowSegments& rSegs); + bool getFirst(RangeData& rRange); + bool getNext(RangeData& rRange); + private: + ScFlatBoolRowSegments& mrSegs; + }; + + ScFlatBoolRowSegments(); + ScFlatBoolRowSegments(const ScFlatBoolRowSegments& r); + ~ScFlatBoolRowSegments(); + + void setTrue(SCROW nRow1, SCROW nRow2); + void setFalse(SCROW nRow1, SCROW nRow2); + bool getValue(SCROW nRow); + bool getRangeData(SCROW nRow, RangeData& rData); + void removeSegment(SCROW nRow1, SCROW nRow2); + void insertSegment(SCROW nRow, SCROW nSize, bool bSkipStartBoundary); + + SCROW findLastNotOf(bool bValue) const; + + void enableTreeSearch(bool bEnable); + void setInsertFromBack(bool bInsertFromBack); + +private: + ::std::auto_ptr<ScFlatBoolSegmentsImpl> mpImpl; +}; + +// ============================================================================ + +class ScFlatBoolColSegments +{ +public: + struct RangeData + { + SCCOL mnCol1; + SCCOL mnCol2; + bool mbValue; + }; + ScFlatBoolColSegments(); + ScFlatBoolColSegments(const ScFlatBoolColSegments& r); + ~ScFlatBoolColSegments(); + + void setTrue(SCCOL nCol1, SCCOL nCol2); + void setFalse(SCCOL nCol1, SCCOL nCol2); + bool getValue(SCCOL nCol); + bool getRangeData(SCCOL nCol, RangeData& rData); + void removeSegment(SCCOL nCol1, SCCOL nCol2); + void insertSegment(SCCOL nCol, SCCOL nSize, bool bSkipStartBoundary); + + void enableTreeSearch(bool bEnable); + void setInsertFromBack(bool bInsertFromBack); + +private: + ::std::auto_ptr<ScFlatBoolSegmentsImpl> mpImpl; +}; + +// ============================================================================ + +class ScFlatUInt16SegmentsImpl; + +class ScFlatUInt16RowSegments +{ +public: + struct RangeData + { + SCROW mnRow1; + SCROW mnRow2; + sal_uInt16 mnValue; + }; + + class ForwardIterator + { + public: + explicit ForwardIterator(ScFlatUInt16RowSegments& rSegs); + + bool getValue(SCROW nPos, sal_uInt16& rVal); + SCROW getLastPos() const; + + private: + ScFlatUInt16RowSegments& mrSegs; + + SCROW mnCurPos; + SCROW mnLastPos; + sal_uInt16 mnCurValue; + }; + + ScFlatUInt16RowSegments(sal_uInt16 nDefault); + ScFlatUInt16RowSegments(const ScFlatUInt16RowSegments& r); + ~ScFlatUInt16RowSegments(); + + void setValue(SCROW nRow1, SCROW nRow2, sal_uInt16 nValue); + sal_uInt16 getValue(SCROW nRow); + sal_uInt32 getSumValue(SCROW nRow1, SCROW nRow2); + bool getRangeData(SCROW nRow, RangeData& rData); + void removeSegment(SCROW nRow1, SCROW nRow2); + void insertSegment(SCROW nRow, SCROW nSize, bool bSkipStartBoundary); + + SCROW findLastNotOf(sal_uInt16 nValue) const; + + void enableTreeSearch(bool bEnable); + void setInsertFromBack(bool bInsertFromBack); + +private: + ::std::auto_ptr<ScFlatUInt16SegmentsImpl> mpImpl; +}; + +#endif diff --git a/sc/inc/servuno.hxx b/sc/inc/servuno.hxx index e45d80e742c7..4f2f1ec40de2 100644 --- a/sc/inc/servuno.hxx +++ b/sc/inc/servuno.hxx @@ -88,12 +88,16 @@ class ScDocShell; // BM #define SC_SERVICE_CHDATAPROV 37 +// formula parser #define SC_SERVICE_FORMULAPARS 38 #define SC_SERVICE_OPCODEMAPPER 39 -#define SC_SERVICE_VBACODENAMEPROVIDER 40 -#define SC_SERVICE_VBAGLOBALS 41 -#define SC_SERVICE_COUNT 42 +// VBA specific +#define SC_SERVICE_VBAOBJECTPROVIDER 40 +#define SC_SERVICE_VBACODENAMEPROVIDER 41 +#define SC_SERVICE_VBAGLOBALS 42 + +#define SC_SERVICE_COUNT 43 #define SC_SERVICE_INVALID USHRT_MAX diff --git a/sc/inc/sheetevents.hxx b/sc/inc/sheetevents.hxx new file mode 100755 index 000000000000..8f52efb990f7 --- /dev/null +++ b/sc/inc/sheetevents.hxx @@ -0,0 +1,65 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: sheetdata.hxx,v $ + * $Revision: 1.16.32.2 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SC_SHEETEVENTS_HXX +#define SC_SHEETEVENTS_HXX + +#include <rtl/ustring.hxx> + +#define SC_SHEETEVENT_FOCUS 0 +#define SC_SHEETEVENT_UNFOCUS 1 +#define SC_SHEETEVENT_SELECT 2 +#define SC_SHEETEVENT_DOUBLECLICK 3 +#define SC_SHEETEVENT_RIGHTCLICK 4 +#define SC_SHEETEVENT_CHANGE 5 +#define SC_SHEETEVENT_CALCULATE 6 +#define SC_SHEETEVENT_COUNT 7 + +class ScSheetEvents +{ + rtl::OUString** mpScriptNames; + + void Clear(); + +public: + ScSheetEvents(); + ScSheetEvents(const ScSheetEvents& rOther); + ~ScSheetEvents(); + + const ScSheetEvents& operator= (const ScSheetEvents& rOther); + + const rtl::OUString* GetScript(sal_Int32 nEvent) const; + void SetScript(sal_Int32 nEvent, const rtl::OUString* pNew); + + static rtl::OUString GetEventName(sal_Int32 nEvent); +}; + +#endif + diff --git a/sc/source/ui/inc/teamdlg.hxx b/sc/inc/tabbgcolor.hxx index 9f44f06c4b12..c2b2a63baf65 100644 --- a/sc/source/ui/inc/teamdlg.hxx +++ b/sc/inc/tabbgcolor.hxx @@ -2,10 +2,13 @@ * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * Copyright 2000, 2010 Oracle and/or its affiliates. + * Copyright 2008 by Sun Microsystems, Inc. * * OpenOffice.org - a multi-platform office productivity suite * + * $RCSfile: tabbgcolor.hxx,v $ + * $Revision: 1.00 $ + * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify @@ -25,29 +28,27 @@ * ************************************************************************/ -#ifndef SC_TEAMDLG_HXX -#define SC_TEAMDLG_HXX - - -#include <vcl/floatwin.hxx> -#include <vcl/fixed.hxx> +#ifndef SC_TABBGCOLOR_HXX +#define SC_TABBGCOLOR_HXX +#include "tools/color.hxx" +#include "address.hxx" -//======================================================================== +#include <vector> -class ScTeamDlg : public FloatingWindow +struct ScUndoTabColorInfo { -public: - ScTeamDlg( Window* pParent ); - ~ScTeamDlg(); + SCTAB mnTabId; + Color maOldTabBgColor; + Color maNewTabBgColor; - virtual BOOL Close(); - void Center(); + bool IsDefaultOldTabBgColor() const; + bool IsDefaultNewTabBgColor() const; -private: - FixedBitmap aBmpTeam; -}; + explicit ScUndoTabColorInfo(SCTAB nTab); + ScUndoTabColorInfo(const ScUndoTabColorInfo& r); + typedef ::std::vector<ScUndoTabColorInfo> List; +}; #endif - diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx index 42fcbb063930..78e5875b6879 100644 --- a/sc/inc/table.hxx +++ b/sc/inc/table.hxx @@ -39,12 +39,20 @@ #include "compressedarray.hxx" #include <memory> +#include <set> +#include <boost/shared_ptr.hpp> namespace utl { class SearchParam; class TextSearch; } +namespace com { namespace sun { namespace star { + namespace sheet { + struct TablePageBreakData; + } +} } } + class SfxItemSet; class SfxStyleSheetBase; class SvxBoxInfoItem; @@ -63,6 +71,7 @@ class ScPrintSaverTab; class ScProgress; class ScProgress; class ScRangeList; +class ScSheetEvents; class ScSortInfoArray; class ScStyleSheet; class ScTableLink; @@ -72,6 +81,9 @@ struct RowInfo; struct ScFunctionData; struct ScLineFlags; class CollatorWrapper; +class ScFlatUInt16RowSegments; +class ScFlatBoolRowSegments; +class ScFlatBoolColSegments; class ScTable @@ -111,13 +123,24 @@ private: ::std::auto_ptr<ScTableProtection> pTabProtection; USHORT* pColWidth; - ScSummableCompressedArray< SCROW, USHORT>* pRowHeight; + ::boost::shared_ptr<ScFlatUInt16RowSegments> mpRowHeights; BYTE* pColFlags; ScBitMaskCompressedArray< SCROW, BYTE>* pRowFlags; + ::boost::shared_ptr<ScFlatBoolColSegments> mpHiddenCols; + ::boost::shared_ptr<ScFlatBoolRowSegments> mpHiddenRows; + ::boost::shared_ptr<ScFlatBoolColSegments> mpFilteredCols; + ::boost::shared_ptr<ScFlatBoolRowSegments> mpFilteredRows; + + ::std::set<SCROW> maRowPageBreaks; + ::std::set<SCROW> maRowManualBreaks; + ::std::set<SCCOL> maColPageBreaks; + ::std::set<SCCOL> maColManualBreaks; ScOutlineTable* pOutlineTable; + ScSheetEvents* pSheetEvents; + SCCOL nTableAreaX; SCROW nTableAreaY; BOOL bTableAreaValid; @@ -126,6 +149,7 @@ private: BOOL bVisible; BOOL bStreamValid; BOOL bPendingRowHeights; + BOOL bCalcNotification; SCTAB nTab; USHORT nRecalcLvl; // Rekursionslevel Size-Recalc @@ -153,8 +177,10 @@ private: ScRangeList* pScenarioRanges; Color aScenarioColor; + Color aTabBgColor; USHORT nScenarioFlags; BOOL bActiveScenario; + bool mbPageBreaksValid; friend class ScDocument; // fuer FillInfo friend class ScDocumentIterator; @@ -189,6 +215,9 @@ public: void RemoveSubTotals( ScSubTotalParam& rParam ); BOOL DoSubTotals( ScSubTotalParam& rParam ); + const ScSheetEvents* GetSheetEvents() const { return pSheetEvents; } + void SetSheetEvents( const ScSheetEvents* pNew ); + BOOL IsVisible() const { return bVisible; } void SetVisible( BOOL bVis ); @@ -198,6 +227,9 @@ public: BOOL IsPendingRowHeights() const { return bPendingRowHeights; } void SetPendingRowHeights( BOOL bSet ); + BOOL GetCalcNotification() const { return bCalcNotification; } + void SetCalcNotification( BOOL bSet ); + BOOL IsLayoutRTL() const { return bLayoutRTL; } BOOL IsLoadingRTL() const { return bLoadingRTL; } void SetLayoutRTL( BOOL bSet ); @@ -209,6 +241,8 @@ public: void SetScenarioComment( const String& rComment ) { aComment = rComment; } const Color& GetScenarioColor() const { return aScenarioColor; } void SetScenarioColor(const Color& rNew) { aScenarioColor = rNew; } + const Color& GetTabBgColor() const; + void SetTabBgColor(const Color& rColor); USHORT GetScenarioFlags() const { return nScenarioFlags; } void SetScenarioFlags(USHORT nNew) { nScenarioFlags = nNew; } void SetActiveScenario(BOOL bSet) { bActiveScenario = bSet; } @@ -364,7 +398,8 @@ public: void CopyUpdated( const ScTable* pPosTab, ScTable* pDestTab ) const; - void InvalidateTableArea() { bTableAreaValid = FALSE; } + void InvalidateTableArea(); + void InvalidatePageBreaks(); BOOL GetCellArea( SCCOL& rEndCol, SCROW& rEndRow ) const; // FALSE = leer BOOL GetTableArea( SCCOL& rEndCol, SCROW& rEndRow ) const; @@ -380,7 +415,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 +454,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, @@ -464,7 +498,7 @@ public: SCCOL& rCol, SCROW& rRow, ScMarkData& rMark, String& rUndoStr, ScDocument* pUndoDoc); - void FindMaxRotCol( RowInfo* pRowInfo, SCSIZE nArrCount, SCCOL nX1, SCCOL nX2 ) const; + void FindMaxRotCol( RowInfo* pRowInfo, SCSIZE nArrCount, SCCOL nX1, SCCOL nX2 ); void GetBorderLines( SCCOL nCol, SCROW nRow, const SvxBorderLine** ppLeft, const SvxBorderLine** ppTop, @@ -581,29 +615,49 @@ public: void SetRowHeight( SCROW nRow, USHORT nNewHeight ); BOOL SetRowHeightRange( SCROW nStartRow, SCROW nEndRow, USHORT nNewHeight, double nPPTX, double nPPTY ); + + /** + * Set specified row height to specified ranges. Don't check for drawing + * objects etc. Just set the row height. Nothing else. + * + * Note that setting a new row height via this function will not + * invalidate page breaks. + */ + void SetRowHeightOnly( SCROW nStartRow, SCROW nEndRow, USHORT nNewHeight ); + // nPPT fuer Test auf Veraenderung void SetManualHeight( SCROW nStartRow, SCROW nEndRow, BOOL bManual ); - USHORT GetColWidth( SCCOL nCol ) const; - USHORT GetRowHeight( SCROW nRow ) const; - ULONG GetRowHeight( SCROW nStartRow, SCROW nEndRow ) const; - ULONG GetScaledRowHeight( SCROW nStartRow, SCROW nEndRow, double fScale ) const; - ULONG GetColOffset( SCCOL nCol ) const; - ULONG GetRowOffset( SCROW nRow ) const; + USHORT GetColWidth( SCCOL nCol ); + SC_DLLPUBLIC USHORT GetRowHeight( SCROW nRow, SCROW* pStartRow = NULL, SCROW* pEndRow = NULL, bool bHiddenAsZero = true ); + ULONG GetRowHeight( SCROW nStartRow, SCROW nEndRow ); + ULONG GetScaledRowHeight( SCROW nStartRow, SCROW nEndRow, double fScale ); + ULONG GetColOffset( SCCOL nCol ); + ULONG GetRowOffset( SCROW nRow ); + + /** + * Get the last row such that the height of row 0 to the end row is as + * high as possible without exceeding the specified height value. + * + * @param nHeight maximum desired height + * + * @return SCROW last row of the range within specified height. + */ + SCROW GetRowForHeight(ULONG nHeight); USHORT GetOriginalWidth( SCCOL nCol ) const; USHORT GetOriginalHeight( SCROW nRow ) const; - USHORT GetCommonWidth( SCCOL nEndCol ) const; + USHORT GetCommonWidth( SCCOL nEndCol ); - SCROW GetHiddenRowCount( SCROW nRow ) const; + SCROW GetHiddenRowCount( SCROW nRow ); - void ShowCol(SCCOL nCol, BOOL bShow); - void ShowRow(SCROW nRow, BOOL bShow); - void DBShowRow(SCROW nRow, BOOL bShow); + void ShowCol(SCCOL nCol, bool bShow); + void ShowRow(SCROW nRow, bool bShow); + void DBShowRow(SCROW nRow, bool bShow); - void ShowRows(SCROW nRow1, SCROW nRow2, BOOL bShow); - void DBShowRows(SCROW nRow1, SCROW nRow2, BOOL bShow); + void ShowRows(SCROW nRow1, SCROW nRow2, bool bShow); + void DBShowRows(SCROW nRow1, SCROW nRow2, bool bShow); void SetColFlags( SCCOL nCol, BYTE nNewFlags ); void SetRowFlags( SCROW nRow, BYTE nNewFlags ); @@ -617,15 +671,11 @@ public: /// @return the index of the last changed row (flags and row height, auto pagebreak is ignored). SCROW GetLastChangedRow() const; - BOOL IsFiltered(SCROW nRow) const; - BYTE GetColFlags( SCCOL nCol ) const; BYTE GetRowFlags( SCROW nRow ) const; const ScBitMaskCompressedArray< SCROW, BYTE> * GetRowFlagsArray() const { return pRowFlags; } - const ScSummableCompressedArray< SCROW, USHORT> * GetRowHeightArray() const - { return pRowHeight; } BOOL UpdateOutlineCol( SCCOL nStartCol, SCCOL nEndCol, BOOL bShow ); BOOL UpdateOutlineRow( SCROW nStartRow, SCROW nEndRow, BOOL bShow ); @@ -634,6 +684,63 @@ public: void RemoveManualBreaks(); BOOL HasManualBreaks() const; + void GetAllRowBreaks(::std::set<SCROW>& rBreaks, bool bPage, bool bManual) const; + void GetAllColBreaks(::std::set<SCCOL>& rBreaks, bool bPage, bool bManual) const; + bool HasRowPageBreak(SCROW nRow) const; + bool HasColPageBreak(SCCOL nCol) const; + bool HasRowManualBreak(SCROW nRow) const; + bool HasColManualBreak(SCCOL nCol) const; + + /** + * Get the row position of the next manual break that occurs at or below + * specified row. When no more manual breaks are present at or below + * the specified row, -1 is returned. + * + * @param nRow row at which the search begins. + * + * @return SCROW next row position with manual page break, or -1 if no + * more manual breaks are present. + */ + SCROW GetNextManualBreak(SCROW nRow) const; + + void RemoveRowPageBreaks(SCROW nStartRow, SCROW nEndRow); + void RemoveRowBreak(SCROW nRow, bool bPage, bool bManual); + void RemoveColBreak(SCCOL nCol, bool bPage, bool bManual); + void SetRowBreak(SCROW nRow, bool bPage, bool bManual); + void SetColBreak(SCCOL nCol, bool bPage, bool bManual); + ::com::sun::star::uno::Sequence< + ::com::sun::star::sheet::TablePageBreakData> GetRowBreakData() const; + + bool RowHidden(SCROW nRow, SCROW* pFirstRow = NULL, SCROW* pLastRow = NULL); + bool RowHidden(SCROW nRow, SCROW& rLastRow); + bool HasHiddenRows(SCROW nStartRow, SCROW nEndRow); + bool ColHidden(SCCOL nCol, SCCOL& rLastCol); + bool ColHidden(SCCOL nCol, SCCOL* pFirstCol = NULL, SCCOL* pLastCol = NULL); + void SetRowHidden(SCROW nStartRow, SCROW nEndRow, bool bHidden); + void SetColHidden(SCCOL nStartCol, SCCOL nEndCol, bool bHidden); + void CopyColHidden(ScTable& rTable, SCCOL nStartCol, SCCOL nEndCol); + void CopyRowHidden(ScTable& rTable, SCROW nStartRow, SCROW nEndRow); + void CopyRowHeight(ScTable& rSrcTable, SCROW nStartRow, SCROW nEndRow, SCROW nSrcOffset); + SCROW FirstVisibleRow(SCROW nStartRow, SCROW nEndRow); + SCROW LastVisibleRow(SCROW nStartRow, SCROW nEndRow); + SCROW CountVisibleRows(SCROW nStartRow, SCROW nEndRow); + sal_uInt32 GetTotalRowHeight(SCROW nStartRow, SCROW nEndRow); + + SCCOLROW LastHiddenColRow(SCCOLROW nPos, bool bCol); + + bool RowFiltered(SCROW nRow, SCROW* pFirstRow = NULL, SCROW* pLastRow = NULL); + bool ColFiltered(SCCOL nCol, SCCOL* pFirstCol = NULL, SCCOL* pLastCol = NULL); + bool HasFilteredRows(SCROW nStartRow, SCROW nEndRow); + void CopyColFiltered(ScTable& rTable, SCCOL nStartCol, SCCOL nEndCol); + void CopyRowFiltered(ScTable& rTable, SCROW nStartRow, SCROW nEndRow); + void SetRowFiltered(SCROW nStartRow, SCROW nEndRow, bool bFiltered); + void SetColFiltered(SCCOL nStartCol, SCCOL nEndCol, bool bFiltered); + SCROW FirstNonFilteredRow(SCROW nStartRow, SCROW nEndRow); + SCROW LastNonFilteredRow(SCROW nStartRow, SCROW nEndRow); + SCROW CountNonFilteredRows(SCROW nStartRow, SCROW nEndRow); + + void SyncColRowFlags(); + void StripHidden( SCCOL& rX1, SCROW& rY1, SCCOL& rX2, SCROW& rY2 ); void ExtendHidden( SCCOL& rX1, SCROW& rY1, SCCOL& rX2, SCROW& rY2 ); @@ -654,11 +761,12 @@ public: void DoColResize( SCCOL nCol1, SCCOL nCol2, SCSIZE nAdd ); + sal_Int32 GetMaxStringLen( SCCOL nCol, SCROW nRowStart, SCROW nRowEnd, CharSet eCharSet ) const; - xub_StrLen GetMaxNumberStringLen( USHORT& nPrecision, - SCCOL nCol, - SCROW nRowStart, SCROW nRowEnd ) const; + xub_StrLen GetMaxNumberStringLen( sal_uInt16& nPrecision, + SCCOL nCol, + SCROW nRowStart, SCROW nRowEnd ) const; void FindConditionalFormat( ULONG nKey, ScRangeList& rRanges ); @@ -750,14 +858,65 @@ private: void StartNeededListeners(); // only for cells where NeedsListening()==TRUE void SetRelNameDirty(); + void SetLoadingMedium(bool bLoading); + SCSIZE FillMaxRot( RowInfo* pRowInfo, SCSIZE nArrCount, SCCOL nX1, SCCOL nX2, SCCOL nCol, SCROW nAttrRow1, SCROW nAttrRow2, SCSIZE nArrY, - const ScPatternAttr* pPattern, const SfxItemSet* pCondSet ) const; + const ScPatternAttr* pPattern, const SfxItemSet* pCondSet ); // idle calculation of OutputDevice text width for cell // also invalidates script type, broadcasts for "calc as shown" void InvalidateTextWidth( const ScAddress* pAdrFrom, const ScAddress* pAdrTo, BOOL bNumFormatChanged, BOOL bBroadcast ); + + /** + * In case the cell text goes beyond the column width, move the max column + * position to the right. This is called from ExtendPrintArea. + */ + void MaybeAddExtraColumn(SCCOL& rCol, SCROW nRow, OutputDevice* pDev, double nPPTX, double nPPTY); + + /** + * Use this to iterate through non-empty visible cells in a single column. + */ + class VisibleDataCellIterator + { + public: + static SCROW ROW_NOT_FOUND; + + explicit VisibleDataCellIterator(ScFlatBoolRowSegments& rRowSegs, ScColumn& rColumn); + ~VisibleDataCellIterator(); + + /** + * Set the start row position. In case there is not visible data cell + * at the specified row position, it will move to the position of the + * first visible data cell below that point. + * + * @return First visible data cell if found, or NULL otherwise. + */ + ScBaseCell* reset(SCROW nRow); + + /** + * Find the next visible data cell position. + * + * @return Next visible data cell if found, or NULL otherwise. + */ + ScBaseCell* next(); + + /** + * Get the current row position. + * + * @return Current row position, or ROW_NOT_FOUND if the iterator + * doesn't point to a valid data cell position. + */ + SCROW getRow() const; + + private: + ScFlatBoolRowSegments& mrRowSegs; + ScColumn& mrColumn; + ScBaseCell* mpCell; + SCROW mnCurRow; + SCROW mnUBound; + }; }; diff --git a/sc/inc/unonames.hxx b/sc/inc/unonames.hxx index f5de35c9d033..2d011f425398 100644 --- a/sc/inc/unonames.hxx +++ b/sc/inc/unonames.hxx @@ -173,6 +173,7 @@ #define SC_UNONAME_COPYFORM "CopyFormulas" #define SC_UNONAME_TABLAYOUT "TableLayout" #define SC_UNONAME_AUTOPRINT "AutomaticPrintArea" +#define SC_UNONAME_TABCOLOR "TabColor" // LinkTarget #define SC_UNO_LINKDISPBIT "LinkDisplayBitmap" @@ -484,6 +485,7 @@ #define SC_UNO_ISEXECUTELINKENABLED "IsExecuteLinkEnabled" #define SC_UNO_ISCHANGEREADONLYENABLED "IsChangeReadOnlyEnabled" #define SC_UNO_REFERENCEDEVICE "ReferenceDevice" +#define SC_UNO_CODENAME "CodeName" // document properties from FormModel #define SC_UNO_APPLYFMDES "ApplyFormDesignMode" @@ -526,6 +528,7 @@ #define SC_UNO_ZOOMTYPE "ZoomType" #define SC_UNO_ZOOMVALUE "ZoomValue" #define SC_UNO_UPDTEMPL "UpdateFromTemplate" + /*Stampit enable/disable print cancel */ #define SC_UNO_ALLOWPRINTJOBCANCEL "AllowPrintJobCancel" @@ -595,6 +598,7 @@ #define SC_UNONAME_PAGESIZE "PageSize" #define SC_UNONAME_RENDERDEV "RenderDevice" #define SC_UNONAME_SOURCERANGE "SourceRange" +#define SC_UNONAME_INC_NP_AREA "PageIncludesNonprintableArea" // CellValueBinding #define SC_UNONAME_BOUNDCELL "BoundCell" @@ -610,6 +614,7 @@ // --> PB 2004-08-23 #i33095# Security Options #define SC_UNO_LOADREADONLY "LoadReadonly" // <-- +#define SC_UNO_MODIFYPASSWORDINFO "ModifyPasswordInfo" // FormulaParser #define SC_UNO_COMPILEENGLISH "CompileEnglish" @@ -630,5 +635,10 @@ #define SC_UNO_SHAREDOC "IsDocumentShared" +// EventDescriptor + +#define SC_UNO_EVENTTYPE "EventType" +#define SC_UNO_SCRIPT "Script" + #endif diff --git a/sc/inc/unowids.hxx b/sc/inc/unowids.hxx index 1765b9d06361..175022a0ba14 100644 --- a/sc/inc/unowids.hxx +++ b/sc/inc/unowids.hxx @@ -77,7 +77,9 @@ #define SC_WID_UNO_TABLAYOUT ( SC_WID_UNO_START + 37 ) #define SC_WID_UNO_AUTOPRINT ( SC_WID_UNO_START + 38 ) #define SC_WID_UNO_ABSNAME ( SC_WID_UNO_START + 39 ) -#define SC_WID_UNO_END ( SC_WID_UNO_START + 39 ) +#define SC_WID_UNO_CODENAME ( SC_WID_UNO_START + 40 ) +#define SC_WID_UNO_TABCOLOR ( SC_WID_UNO_START + 41 ) +#define SC_WID_UNO_END ( SC_WID_UNO_START + 41 ) inline BOOL IsScUnoWid( USHORT nWid ) diff --git a/sc/inc/viewuno.hxx b/sc/inc/viewuno.hxx index 988602b2056f..19b5c60fd070 100644 --- a/sc/inc/viewuno.hxx +++ b/sc/inc/viewuno.hxx @@ -48,6 +48,8 @@ #include <com/sun/star/lang/XUnoTunnel.hpp> #include <com/sun/star/datatransfer/XTransferableSupplier.hpp> +#include "address.hxx" + class ScTabViewShell; #define SC_VIEWPANE_ACTIVE 0xFFFF @@ -195,6 +197,7 @@ private: XViewPropertyChangeListenerArr_Impl aPropertyChgListeners; XMouseClickHandlerArr_Impl aMouseClickHandlers; XActivationEventListenerArr_Impl aActivationListeners; + SCTAB nPreviousTab; sal_Bool bDrawSelModeSet; ScViewPaneObj* GetObjectByIndex_Impl(USHORT nIndex) const; @@ -223,7 +226,7 @@ public: void SelectionChanged(); void VisAreaChanged(); void SheetChanged(); - sal_Bool IsMouseListening() { return aMouseClickHandlers.Count() > 0; } + bool IsMouseListening() const; sal_Bool MousePressed( const ::com::sun::star::awt::MouseEvent& e ) throw (::com::sun::star::uno::RuntimeException); sal_Bool MouseReleased( const ::com::sun::star::awt::MouseEvent& e ) throw (::com::sun::star::uno::RuntimeException); diff --git a/sc/prj/build.lst b/sc/prj/build.lst index e32d8938afc4..afdd953d2274 100755 --- a/sc/prj/build.lst +++ b/sc/prj/build.lst @@ -1,4 +1,4 @@ -sc sc : filter l10n vbahelper oovbaapi svx uui stoc BOOST:boost formula oox NULL +sc sc : filter l10n vbahelper oovbaapi svx uui stoc BOOST:boost formula MDDS:mdds oox NULL sc sc usr1 - all sc_mkout NULL sc sc\inc nmake - all sc_inc NULL sc sc\prj get - all sc_prj NULL @@ -48,4 +48,3 @@ sc sc\addin\datefunc nmake - all sc_addfu sc_add sc_sdi sc_inc NULL sc sc\addin\rot13 nmake - all sc_adrot sc_add sc_sdi sc_inc NULL sc sc\addin\util nmake - all sc_adutil sc_addfu sc_adrot sc_sdi sc_inc NULL sc sc\util nmake - all sc_util sc_addfu sc_adrot sc_adutil sc_app sc_attr sc_cctrl sc_cosrc sc_data sc_dbgui sc_dif sc_docsh sc_drfnc sc_excel sc_form sc_html sc_lotus sc_qpro sc_misc sc_name sc_nvipi sc_opt sc_page sc_rtf sc_scalc sc_style sc_tool sc_uisrc sc_undo sc_unobj sc_view sc_xcl97 sc_xml sc_acc sc_ftools sc_inc sc_vba NULL -sc sc\qa\unoapi nmake - all sc_qa_unoapi NULL diff --git a/sc/prj/d.lst b/sc/prj/d.lst index b1e0dfde7a3d..6f4e95203bed 100644 --- a/sc/prj/d.lst +++ b/sc/prj/d.lst @@ -4,11 +4,6 @@ mkdir: %_DEST%\xml%_EXT%\uiconfig\modules mkdir: %_DEST%\xml%_EXT%\uiconfig\modules\scalc mkdir: %_DEST%\xml%_EXT%\uiconfig\modules\scalc\menubar mkdir: %_DEST%\xml%_EXT%\uiconfig\modules\scalc\toolbar -mkdir: %_DEST%\xml%_EXT%\uiconfig\modules\scalc\accelerator -mkdir: %_DEST%\xml%_EXT%\uiconfig\modules\scalc\accelerator\en-US -mkdir: %_DEST%\xml%_EXT%\uiconfig\modules\scalc\accelerator\de -mkdir: %_DEST%\xml%_EXT%\uiconfig\modules\scalc\accelerator\es -mkdir: %_DEST%\xml%_EXT%\uiconfig\modules\scalc\accelerator\fr mkdir: %_DEST%\xml%_EXT%\uiconfig\modules\scalc\statusbar ..\%COMMON_OUTDIR%\misc\*.hid %COMMON_DEST%\bin%_EXT%\hid\*.hid @@ -34,10 +29,6 @@ mkdir: %_DEST%\xml%_EXT%\uiconfig\modules\scalc\statusbar ..\uiconfig\scalc\menubar\*.xml %_DEST%\xml%_EXT%\uiconfig\modules\scalc\menubar\*.xml ..\uiconfig\scalc\toolbar\*.xml %_DEST%\xml%_EXT%\uiconfig\modules\scalc\toolbar\*.xml -..\uiconfig\scalc\accelerator\en-US\*.xml %_DEST%\xml%_EXT%\uiconfig\modules\scalc\accelerator\en-US\*.xml -..\uiconfig\scalc\accelerator\de\*.xml %_DEST%\xml%_EXT%\uiconfig\modules\scalc\accelerator\de\*.xml -..\uiconfig\scalc\accelerator\es\*.xml %_DEST%\xml%_EXT%\uiconfig\modules\scalc\accelerator\es\*.xml -..\uiconfig\scalc\accelerator\fr\*.xml %_DEST%\xml%_EXT%\uiconfig\modules\scalc\accelerator\fr\*.xml ..\uiconfig\scalc\statusbar\*.xml %_DEST%\xml%_EXT%\uiconfig\modules\scalc\statusbar\*.xml ..\%__SRC%\bin\*-layout.zip %_DEST%\pck%_EXT%\*.* diff --git a/sc/qa/unoapi/knownissues.xcl b/sc/qa/unoapi/knownissues.xcl index e6863cd75cab..205123fc0e48 100644 --- a/sc/qa/unoapi/knownissues.xcl +++ b/sc/qa/unoapi/knownissues.xcl @@ -191,3 +191,9 @@ sc.ScAnnotationShapeObj::com::sun::star::text::XTextRange sc.ScAnnotationsObj::com::sun::star::container::XElementAccess sc.ScCellObj::com::sun::star::sheet::XSheetAnnotationAnchor sc.ScDataPilotFieldObj::com::sun::star::sheet::XDataPilotFieldGrouping + +### i110862 ### +sc.ScDataPilotTableObj::com::sun::star::sheet::XDataPilotTable + +### i111032 ### +sc.ScAccessibleCell::com::sun::star::accessibility::XAccessibleText 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/docsh.sdi b/sc/sdi/docsh.sdi index 80a330f51890..94cd06d9f699 100644 --- a/sc/sdi/docsh.sdi +++ b/sc/sdi/docsh.sdi @@ -60,6 +60,7 @@ interface TableSelection FID_DELETE_TABLE [ ExecMethod = ExecuteTable; StateMethod = GetStateTable; ] FID_TAB_RENAME [ ExecMethod = ExecuteTable; StateMethod = GetStateTable; ] FID_TAB_RTL [ ExecMethod = ExecuteTable; StateMethod = GetStateTable; ] + FID_TAB_SET_TAB_BG_COLOR [ ExecMethod = ExecuteTable; StateMethod = GetStateTable; ] SID_TABLE_ACTIVATE [ ExecMethod = Execute; ] } 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/sdi/scalc.sdi b/sc/sdi/scalc.sdi index 904ee22d3d8c..1e42ce5fb1dc 100644 --- a/sc/sdi/scalc.sdi +++ b/sc/sdi/scalc.sdi @@ -6819,6 +6819,31 @@ SfxVoidItem TableDeselectAll FID_TAB_DESELECTALL ] //-------------------------------------------------------------------------- +SfxVoidItem TableEvents FID_TAB_EVENTS +() +[ + /* flags: */ + AutoUpdate = FALSE, + Cachable = Cachable, + FastCall = FALSE, + HasCoreId = FALSE, + HasDialog = TRUE, + ReadOnlyDoc = TRUE, + Toggle = FALSE, + Container = FALSE, + RecordAbsolute = FALSE, + RecordPerSet; + Synchron; + + /* config: */ + AccelConfig = TRUE, + MenuConfig = TRUE, + StatusBarConfig = FALSE, + ToolBoxConfig = FALSE, + GroupId = GID_EDIT; +] + +//-------------------------------------------------------------------------- SfxVoidItem TextAttributes SID_DRAWTEXT_ATTR_DLG () [ @@ -7748,3 +7773,56 @@ SfxVoidItem ShareDocument SID_SHARE_DOC ToolBoxConfig = FALSE, GroupId = GID_OPTIONS; ] + +//-------------------------------------------------------------------------- +SvxColorItem TabBgColor FID_TAB_SET_TAB_BG_COLOR + +[ + // flags: + AutoUpdate = FALSE, + Cachable = Cachable, + FastCall = FALSE, + HasCoreId = FALSE, + HasDialog = TRUE, + ReadOnlyDoc = TRUE, + Toggle = FALSE, + Container = FALSE, + RecordAbsolute = FALSE, + RecordPerSet; + Synchron; + + Readonly = FALSE, + + // config: + AccelConfig = TRUE, + MenuConfig = TRUE, + StatusBarConfig = FALSE, + ToolBoxConfig = FALSE, + GroupId = GID_FORMAT; +] + +//-------------------------------------------------------------------------- +SfxVoidItem SetTabBgColor FID_TAB_MENU_SET_TAB_BG_COLOR +(SvxColorItem TabBgColor FID_TAB_SET_TAB_BG_COLOR) +[ + /* flags: */ + AutoUpdate = FALSE, + Cachable = Cachable, + FastCall = FALSE, + HasCoreId = FALSE, + HasDialog = TRUE, + ReadOnlyDoc = TRUE, + Toggle = FALSE, + Container = FALSE, + RecordAbsolute = FALSE, + RecordPerSet; + Synchron; + + /* config: */ + AccelConfig = TRUE, + MenuConfig = TRUE, + StatusBarConfig = FALSE, + ToolBoxConfig = FALSE, + GroupId = GID_FORMAT; +] + diff --git a/sc/sdi/tabvwsh.sdi b/sc/sdi/tabvwsh.sdi index 4129aaef7d85..fac67839e656 100644 --- a/sc/sdi/tabvwsh.sdi +++ b/sc/sdi/tabvwsh.sdi @@ -52,12 +52,14 @@ interface Tables FID_TAB_SELECTALL [ ExecMethod = Execute; StateMethod = GetState; ] FID_TAB_DESELECTALL [ ExecMethod = Execute; StateMethod = GetState; ] FID_TAB_MENU_RENAME [ ExecMethod = ExecuteTable; StateMethod = GetStateTable; ] - FID_TAB_APPEND [ ExecMethod = ExecuteTable; StateMethod = GetStateTable; ] - FID_INS_TABLE [ ExecMethod = ExecuteTable; StateMethod = GetStateTable; ] + FID_TAB_APPEND [ ExecMethod = ExecuteTable; StateMethod = GetStateTable; ] + FID_INS_TABLE [ ExecMethod = ExecuteTable; StateMethod = GetStateTable; ] FID_INS_TABLE_EXT [ ExecMethod = ExecuteTable; StateMethod = GetStateTable; ] - FID_TABLE_HIDE [ ExecMethod = ExecuteTable; StateMethod = GetStateTable; ] - FID_TABLE_SHOW [ ExecMethod = ExecuteTable; StateMethod = GetStateTable; ] - SID_SELECT_TABLES [ ExecMethod = Execute; StateMethod = GetState; ] + FID_TABLE_HIDE [ ExecMethod = ExecuteTable; StateMethod = GetStateTable; ] + FID_TABLE_SHOW [ ExecMethod = ExecuteTable; StateMethod = GetStateTable; ] + SID_SELECT_TABLES [ ExecMethod = Execute; StateMethod = GetState; ] + FID_TAB_MENU_SET_TAB_BG_COLOR [ ExecMethod = ExecuteTable; StateMethod = GetStateTable; ] + FID_TAB_EVENTS [ ExecMethod = ExecuteTable; StateMethod = GetStateTable; ] } // =========================================================================== diff --git a/sc/source/core/data/attarray.cxx b/sc/source/core/data/attarray.cxx index 53df13b4cd62..f3443312bd4e 100644 --- a/sc/source/core/data/attarray.cxx +++ b/sc/source/core/data/attarray.cxx @@ -52,7 +52,7 @@ #include "markarr.hxx" #include "rechead.hxx" #include "globstr.hrc" - +#include "segmenttree.hxx" #undef DBG_INVALIDATE #define DBGOUTPUT(s) \ @@ -1727,8 +1727,7 @@ SCsROW ScAttrArray::GetNextUnprotected( SCsROW nRow, BOOL bUp ) const return nRet; } - -void ScAttrArray::FindStyleSheet( const SfxStyleSheetBase* pStyleSheet, BOOL* pUsed, BOOL bReset ) +void ScAttrArray::FindStyleSheet( const SfxStyleSheetBase* pStyleSheet, ScFlatBoolRowSegments& rUsedRows, bool bReset ) { SCROW nStart = 0; SCSIZE nPos = 0; @@ -1740,7 +1739,7 @@ void ScAttrArray::FindStyleSheet( const SfxStyleSheetBase* pStyleSheet, BOOL* pU // for (SCROW nRow = nStart; nRow <= nEnd; nRow++) // pUsed[nRow] = TRUE; - memset( &pUsed[nStart], TRUE, nEnd-nStart+1 ); + rUsedRows.setTrue(nStart, nEnd); if (bReset) { diff --git a/sc/source/core/data/bcaslot.cxx b/sc/source/core/data/bcaslot.cxx index 48a0e8597e1c..95482b1c624b 100644 --- a/sc/source/core/data/bcaslot.cxx +++ b/sc/source/core/data/bcaslot.cxx @@ -47,8 +47,10 @@ #define BCA_SLOTS_COL ((MAXCOLCOUNT_DEFINE) / 16) #if MAXROWCOUNT_DEFINE == 32000 #define BCA_SLOTS_ROW 256 +#define BCA_SLICE 125 #else -#define BCA_SLOTS_ROW ((MAXROWCOUNT_DEFINE) / 128) +#define BCA_SLICE 128 +#define BCA_SLOTS_ROW ((MAXROWCOUNT_DEFINE) / BCA_SLICE) #endif #define BCA_SLOT_COLS ((MAXCOLCOUNT_DEFINE) / BCA_SLOTS_COL) #define BCA_SLOT_ROWS ((MAXROWCOUNT_DEFINE) / BCA_SLOTS_ROW) @@ -59,7 +61,7 @@ #if (BCA_SLOT_ROWS * BCA_SLOTS_ROW) != (MAXROWCOUNT_DEFINE) #error bad BCA_SLOTS_ROW value! #endif -// size of slot array +// size of slot array if linear #define BCA_SLOTS_DEFINE (BCA_SLOTS_COL * BCA_SLOTS_ROW) // Arbitrary 2**31/8, assuming size_t can hold at least 2^31 values and // sizeof_ptr is at most 8 bytes. You'd probably doom your machine's memory @@ -67,14 +69,60 @@ #if BCA_SLOTS_DEFINE > 268435456 #error BCA_SLOTS_DEFINE DOOMed! #endif -// type safe constant -const SCSIZE BCA_SLOTS = BCA_SLOTS_DEFINE; // STATIC DATA ----------------------------------------------------------- TYPEINIT1( ScHint, SfxSimpleHint ); TYPEINIT1( ScAreaChangedHint, SfxHint ); +struct ScSlotData +{ + SCROW nStartRow; // first row of this segment + SCROW nStopRow; // first row of next segment + SCSIZE nSlice; // slice size in this segment + SCSIZE nCumulated; // cumulated slots of previous segments + + ScSlotData( SCROW r1, SCROW r2, SCSIZE s, SCSIZE c ) : nStartRow(r1), nStopRow(r2), nSlice(s), nCumulated(c) {} +}; +typedef ::std::vector< ScSlotData > ScSlotDistribution; +#if MAXROWCOUNT_DEFINE <= 65536 +// Linear distribution. +static ScSlotDistribution aSlotDistribution( ScSlotData( 0, MAXROWCOUNT, BCA_SLOT_ROWS, 0)); +static SCSIZE nBcaSlotsRow = BCA_SLOTS_ROW; +static SCSIZE nBcaSlots = BCA_SLOTS_DEFINE; +#else +// Logarithmic or any other distribution. +// Upper sheet part usually is more populated and referenced and gets fine +// grained resolution, larger data in larger hunks. +// Could be further enhanced by also applying a different distribution of +// column slots. +static SCSIZE initSlotDistribution( ScSlotDistribution & rSD, SCSIZE & rBSR ) +{ + SCSIZE nSlots = 0; + SCROW nRow1 = 0; + SCROW nRow2 = 32*1024; + SCSIZE nSlice = 128; + // Must be sorted by row1,row2! + while (nRow2 <= MAXROWCOUNT) + { + //fprintf( stderr, "r1,r2,slice,cum: %7zu, %7zu, %7zu, %7zu\n", (size_t)nRow1, (size_t)nRow2, (size_t)nSlice, (size_t)nSlots); + // {0,32k,128,0;32k,64k,256,0+256;64k,128k,512,0+256+128;128k,256k,1024,0+256+128+128;256k,512k,2048,...;512k,1M,4096,...} + rSD.push_back( ScSlotData( nRow1, nRow2, nSlice, nSlots)); + nSlots += (nRow2 - nRow1) / nSlice; + nRow1 = nRow2; + nRow2 *= 2; + nSlice *= 2; + } + //fprintf( stderr, "Slices: %zu, slots per sheet: %zu, memory per referenced sheet: %zu\n", (size_t) nSlots, (size_t) nSlots * BCA_SLOTS_COL, (size_t) nSlots * BCA_SLOTS_COL * sizeof(void*)); + rBSR = nSlots; + return nSlots; +} +static ScSlotDistribution aSlotDistribution; +static SCSIZE nBcaSlotsRow; +static SCSIZE nBcaSlots = initSlotDistribution( aSlotDistribution, nBcaSlotsRow) * BCA_SLOTS_COL; +// Ensure that all static variables are initialized with this one call. +#endif + ScBroadcastAreaSlot::ScBroadcastAreaSlot( ScDocument* pDocument, ScBroadcastAreaSlotMachine* pBASMa ) : @@ -393,14 +441,14 @@ void ScBroadcastAreaSlot::UpdateInsert( ScBroadcastArea* pArea ) ScBroadcastAreaSlotMachine::TableSlots::TableSlots() { - ppSlots = new ScBroadcastAreaSlot* [ BCA_SLOTS ]; - memset( ppSlots, 0 , sizeof( ScBroadcastAreaSlot* ) * BCA_SLOTS ); + ppSlots = new ScBroadcastAreaSlot* [ nBcaSlots ]; + memset( ppSlots, 0 , sizeof( ScBroadcastAreaSlot* ) * nBcaSlots ); } ScBroadcastAreaSlotMachine::TableSlots::~TableSlots() { - for ( ScBroadcastAreaSlot** pp = ppSlots + BCA_SLOTS; --pp >= ppSlots; /* nothing */ ) + for ( ScBroadcastAreaSlot** pp = ppSlots + nBcaSlots; --pp >= ppSlots; /* nothing */ ) { if (*pp) delete *pp; @@ -417,16 +465,16 @@ ScBroadcastAreaSlotMachine::ScBroadcastAreaSlotMachine( pEOUpdateChain( NULL ), nInBulkBroadcast( 0 ) { - for (TableSlotsMap::iterator iTab( aTableSlotsMap.begin()); - iTab != aTableSlotsMap.end(); ++iTab) - { - delete (*iTab).second; - } } ScBroadcastAreaSlotMachine::~ScBroadcastAreaSlotMachine() { + for (TableSlotsMap::iterator iTab( aTableSlotsMap.begin()); + iTab != aTableSlotsMap.end(); ++iTab) + { + delete (*iTab).second; + } delete pBCAlways; } @@ -438,13 +486,21 @@ inline SCSIZE ScBroadcastAreaSlotMachine::ComputeSlotOffset( SCCOL nCol = rAddress.Col(); if ( !ValidRow(nRow) || !ValidCol(nCol) ) { - DBG_ASSERT( FALSE, "Row/Col ungueltig!" ); + DBG_ERRORFILE( "Row/Col invalid, using first slot!" ); return 0; } - else - return - static_cast<SCSIZE>(nRow) / BCA_SLOT_ROWS + - static_cast<SCSIZE>(nCol) / BCA_SLOT_COLS * BCA_SLOTS_ROW; + for (size_t i=0; i < aSlotDistribution.size(); ++i) + { + if (nRow < aSlotDistribution[i].nStopRow) + { + const ScSlotData& rSD = aSlotDistribution[i]; + return rSD.nCumulated + + (static_cast<SCSIZE>(nRow - rSD.nStartRow)) / rSD.nSlice + + static_cast<SCSIZE>(nCol) / BCA_SLOT_COLS * nBcaSlotsRow; + } + } + DBG_ERRORFILE( "No slot found, using last!" ); + return nBcaSlots - 1; } @@ -459,9 +515,28 @@ void ScBroadcastAreaSlotMachine::ComputeAreaPoints( const ScRange& rRange, } +inline void ComputeNextSlot( SCSIZE & nOff, SCSIZE & nBreak, ScBroadcastAreaSlot** & pp, + SCSIZE & nStart, ScBroadcastAreaSlot** const & ppSlots, SCSIZE const & nRowBreak ) +{ + if ( nOff < nBreak ) + { + ++nOff; + ++pp; + } + else + { + nStart += nBcaSlotsRow; + nOff = nStart; + pp = ppSlots + nOff; + nBreak = nOff + nRowBreak; + } +} + + void ScBroadcastAreaSlotMachine::StartListeningArea( const ScRange& rRange, SvtListener* pListener ) { + //fprintf( stderr, "StartListeningArea (c,r,t): %d, %d, %d, %d, %d, %d\n", (int)rRange.aStart.Col(), (int)rRange.aStart.Row(), (int)rRange.aStart.Tab(), (int)rRange.aEnd.Col(), (int)rRange.aEnd.Row(), (int)rRange.aEnd.Tab()); if ( rRange == BCA_LISTEN_ALWAYS ) { if ( !pBCAlways ) @@ -500,18 +575,7 @@ void ScBroadcastAreaSlotMachine::StartListeningArea( const ScRange& rRange, } else (*pp)->InsertListeningArea( pArea); - if ( nOff < nBreak ) - { - ++nOff; - ++pp; - } - else - { - nStart += BCA_SLOTS_ROW; - nOff = nStart; - pp = ppSlots + nOff; - nBreak = nOff + nRowBreak; - } + ComputeNextSlot( nOff, nBreak, pp, nStart, ppSlots, nRowBreak); } } } @@ -521,6 +585,7 @@ void ScBroadcastAreaSlotMachine::StartListeningArea( const ScRange& rRange, void ScBroadcastAreaSlotMachine::EndListeningArea( const ScRange& rRange, SvtListener* pListener ) { + //fprintf( stderr, "EndListeningArea (c,r,t): %d, %d, %d, %d, %d, %d\n", (int)rRange.aStart.Col(), (int)rRange.aStart.Row(), (int)rRange.aStart.Tab(), (int)rRange.aEnd.Col(), (int)rRange.aEnd.Row(), (int)rRange.aEnd.Tab()); if ( rRange == BCA_LISTEN_ALWAYS ) { DBG_ASSERT( pBCAlways, "ScBroadcastAreaSlotMachine::EndListeningArea: BCA_LISTEN_ALWAYS but none established"); @@ -547,7 +612,7 @@ void ScBroadcastAreaSlotMachine::EndListeningArea( const ScRange& rRange, SCSIZE nBreak = nOff + nRowBreak; ScBroadcastAreaSlot** pp = ppSlots + nOff; ScBroadcastArea* pArea = NULL; - if (nOff == 0 && nEnd == BCA_SLOTS-1) + if (nOff == 0 && nEnd == nBcaSlots-1) { // Slightly optimized for 0,0,MAXCOL,MAXROW calls as they // happen for insertion and deletion of sheets. @@ -564,18 +629,7 @@ void ScBroadcastAreaSlotMachine::EndListeningArea( const ScRange& rRange, { if ( *pp ) (*pp)->EndListeningArea( rRange, pListener, pArea ); - if ( nOff < nBreak ) - { - ++nOff; - ++pp; - } - else - { - nStart += BCA_SLOTS_ROW; - nOff = nStart; - pp = ppSlots + nOff; - nBreak = nOff + nRowBreak; - } + ComputeNextSlot( nOff, nBreak, pp, nStart, ppSlots, nRowBreak); } } } @@ -629,18 +683,7 @@ BOOL ScBroadcastAreaSlotMachine::AreaBroadcastInRange( const ScRange& rRange, { if ( *pp ) bBroadcasted |= (*pp)->AreaBroadcastInRange( rRange, rHint ); - if ( nOff < nBreak ) - { - ++nOff; - ++pp; - } - else - { - nStart += BCA_SLOTS_ROW; - nOff = nStart; - pp = ppSlots + nOff; - nBreak = nOff + nRowBreak; - } + ComputeNextSlot( nOff, nBreak, pp, nStart, ppSlots, nRowBreak); } } return bBroadcasted; @@ -660,7 +703,7 @@ void ScBroadcastAreaSlotMachine::DelBroadcastAreasInRange( SCSIZE nOff = nStart; SCSIZE nBreak = nOff + nRowBreak; ScBroadcastAreaSlot** pp = ppSlots + nOff; - if (nOff == 0 && nEnd == BCA_SLOTS-1) + if (nOff == 0 && nEnd == nBcaSlots-1) { // Slightly optimized for 0,0,MAXCOL,MAXROW calls as they // happen for insertion and deletion of sheets. @@ -677,18 +720,7 @@ void ScBroadcastAreaSlotMachine::DelBroadcastAreasInRange( { if ( *pp ) (*pp)->DelBroadcastAreasInRange( rRange ); - if ( nOff < nBreak ) - { - ++nOff; - ++pp; - } - else - { - nStart += BCA_SLOTS_ROW; - nOff = nStart; - pp = ppSlots + nOff; - nBreak = nOff + nRowBreak; - } + ComputeNextSlot( nOff, nBreak, pp, nStart, ppSlots, nRowBreak); } } } @@ -711,7 +743,7 @@ void ScBroadcastAreaSlotMachine::UpdateBroadcastAreas( SCSIZE nOff = nStart; SCSIZE nBreak = nOff + nRowBreak; ScBroadcastAreaSlot** pp = ppSlots + nOff; - if (nOff == 0 && nEnd == BCA_SLOTS-1) + if (nOff == 0 && nEnd == nBcaSlots-1) { // Slightly optimized for 0,0,MAXCOL,MAXROW calls as they // happen for insertion and deletion of sheets. @@ -728,18 +760,7 @@ void ScBroadcastAreaSlotMachine::UpdateBroadcastAreas( { if ( *pp ) (*pp)->UpdateRemove( eUpdateRefMode, rRange, nDx, nDy, nDz ); - if ( nOff < nBreak ) - { - ++nOff; - ++pp; - } - else - { - nStart += BCA_SLOTS_ROW; - nOff = nStart; - pp = ppSlots + nOff; - nBreak = nOff + nRowBreak; - } + ComputeNextSlot( nOff, nBreak, pp, nStart, ppSlots, nRowBreak); } } } @@ -771,18 +792,7 @@ void ScBroadcastAreaSlotMachine::UpdateBroadcastAreas( { if (*pp) (*pp)->UpdateRemoveArea( pArea); - if ( nOff < nBreak ) - { - ++nOff; - ++pp; - } - else - { - nStart += BCA_SLOTS_ROW; - nOff = nStart; - pp = ppSlots + nOff; - nBreak = nOff + nRowBreak; - } + ComputeNextSlot( nOff, nBreak, pp, nStart, ppSlots, nRowBreak); } } @@ -876,18 +886,7 @@ void ScBroadcastAreaSlotMachine::UpdateBroadcastAreas( if (!*pp) *pp = new ScBroadcastAreaSlot( pDoc, this ); (*pp)->UpdateInsert( pArea ); - if ( nOff < nBreak ) - { - ++nOff; - ++pp; - } - else - { - nStart += BCA_SLOTS_ROW; - nOff = nStart; - pp = ppSlots + nOff; - nBreak = nOff + nRowBreak; - } + ComputeNextSlot( nOff, nBreak, pp, nStart, ppSlots, nRowBreak); } } diff --git a/sc/source/core/data/cell.cxx b/sc/source/core/data/cell.cxx index 56be361f6d38..aa492630ab0e 100644 --- a/sc/source/core/data/cell.cxx +++ b/sc/source/core/data/cell.cxx @@ -277,21 +277,21 @@ void ScBaseCell::StartListeningTo( ScDocument* pDoc ) if ( rRef1.IsColRel() ) { // ColName pDoc->StartListeningArea( ScRange ( - 0, + rRef1.nCol, rRef1.nRow, rRef1.nTab, - MAXCOL, - rRef2.nRow, + rRef2.nCol, + MAXROW, rRef2.nTab ), pFormCell ); } else { // RowName pDoc->StartListeningArea( ScRange ( rRef1.nCol, - 0, + rRef1.nRow, rRef1.nTab, - rRef2.nCol, - MAXROW, + MAXCOL, + rRef2.nRow, rRef2.nTab ), pFormCell ); } } @@ -367,21 +367,21 @@ void ScBaseCell::EndListeningTo( ScDocument* pDoc, ScTokenArray* pArr, if ( rRef1.IsColRel() ) { // ColName pDoc->EndListeningArea( ScRange ( - 0, + rRef1.nCol, rRef1.nRow, rRef1.nTab, - MAXCOL, - rRef2.nRow, + rRef2.nCol, + MAXROW, rRef2.nTab ), pFormCell ); } else { // RowName pDoc->EndListeningArea( ScRange ( rRef1.nCol, - 0, + rRef1.nRow, rRef1.nTab, - rRef2.nCol, - MAXROW, + MAXCOL, + rRef2.nRow, rRef2.nTab ), pFormCell ); } } @@ -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..e9fd26ced939 100644 --- a/sc/source/core/data/column.cxx +++ b/sc/source/core/data/column.cxx @@ -600,13 +600,11 @@ const ScStyleSheet* ScColumn::GetAreaStyle( BOOL& rFound, SCROW nRow1, SCROW nRo return bEqual ? pStyle : NULL; } - -void ScColumn::FindStyleSheet( const SfxStyleSheetBase* pStyleSheet, BOOL* pUsed, BOOL bReset ) +void ScColumn::FindStyleSheet( const SfxStyleSheetBase* pStyleSheet, ScFlatBoolRowSegments& rUsedRows, bool bReset ) { - pAttrArray->FindStyleSheet( pStyleSheet, pUsed, bReset ); + pAttrArray->FindStyleSheet( pStyleSheet, rUsedRows, bReset ); } - BOOL ScColumn::IsStyleSheetUsed( const ScStyleSheet& rStyle, BOOL bGatherAllStyles ) const { return pAttrArray->IsStyleSheetUsed( rStyle, bGatherAllStyles ); @@ -893,11 +891,6 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2) SvtBroadcaster* pBC2 = pCell2->ReleaseBroadcaster(); pCell1->TakeBroadcaster( pBC2 ); pCell2->TakeBroadcaster( pBC1 ); - - ScHint aHint1( SC_HINT_DATACHANGED, aPos1, pCell2 ); - pDocument->Broadcast( aHint1 ); - ScHint aHint2( SC_HINT_DATACHANGED, aPos2, pCell1 ); - pDocument->Broadcast( aHint2 ); } else { @@ -918,7 +911,6 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2) // insert ColEntry at new position Insert( nRow2, pCell1 ); - pDocument->Broadcast( ScHint( SC_HINT_DATACHANGED, aPos1, pDummyCell ) ); } return; @@ -999,14 +991,6 @@ void ScColumn::SwapRow(SCROW nRow1, SCROW nRow2) Delete( nRow2 ); // deletes pCell2 else if ( pNew2 ) Insert( nRow2, pNew2 ); // deletes pCell2 (if existing), inserts pNew2 - - // #64122# Bei Formeln hinterher nochmal broadcasten, damit die Formel nicht in irgendwelchen - // FormulaTrack-Listen landet, ohne die Broadcaster beruecksichtigt zu haben - // (erst hier, wenn beide Zellen eingefuegt sind) - if ( pBC1 && pFmlaCell2 ) - pDocument->Broadcast( ScHint( SC_HINT_DATACHANGED, aPos1, pNew1 ) ); - if ( pBC2 && pFmlaCell1 ) - pDocument->Broadcast( ScHint( SC_HINT_DATACHANGED, aPos2, pNew2 ) ); } @@ -1402,7 +1386,7 @@ void ScColumn::CopyScenarioFrom( const ScColumn& rSrcCol ) // Dies ist die Szenario-Tabelle, die Daten werden hineinkopiert ScAttrIterator aAttrIter( pAttrArray, 0, MAXROW ); - SCROW nStart, nEnd; + SCROW nStart = -1, nEnd = -1; const ScPatternAttr* pPattern = aAttrIter.Next( nStart, nEnd ); while (pPattern) { @@ -1433,7 +1417,7 @@ void ScColumn::CopyScenarioTo( ScColumn& rDestCol ) const // Dies ist die Szenario-Tabelle, die Daten werden in die andere kopiert ScAttrIterator aAttrIter( pAttrArray, 0, MAXROW ); - SCROW nStart, nEnd; + SCROW nStart = -1, nEnd = -1; const ScPatternAttr* pPattern = aAttrIter.Next( nStart, nEnd ); while (pPattern) { @@ -1482,7 +1466,7 @@ void ScColumn::MarkScenarioIn( ScMarkData& rDestMark ) const ScRange aRange( nCol, 0, nTab ); ScAttrIterator aAttrIter( pAttrArray, 0, MAXROW ); - SCROW nStart, nEnd; + SCROW nStart = -1, nEnd = -1; const ScPatternAttr* pPattern = aAttrIter.Next( nStart, nEnd ); while (pPattern) { @@ -2100,22 +2084,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/column2.cxx b/sc/source/core/data/column2.cxx index 9e3ed1c7ef5e..2adf6d926f0f 100644 --- a/sc/source/core/data/column2.cxx +++ b/sc/source/core/data/column2.cxx @@ -66,6 +66,7 @@ #include "compiler.hxx" // ScTokenArray GetCodeLen #include "dbcolect.hxx" #include "fillinfo.hxx" +#include "segmenttree.hxx" #include <math.h> @@ -193,6 +194,7 @@ long ScColumn::GetNeededSize( SCROW nRow, OutputDevice* pDev, double nPPT = bWidth ? nPPTX : nPPTY; if (Search(nRow,nIndex)) { + ScBaseCell* pCell = pItems[nIndex].pCell; const ScPatternAttr* pPattern = rOptions.pPattern; if (!pPattern) pPattern = pAttrArray->GetPattern( nRow ); @@ -233,22 +235,26 @@ long ScColumn::GetNeededSize( SCROW nRow, OutputDevice* pDev, else eHorJust = (SvxCellHorJustify)((const SvxHorJustifyItem&) pPattern->GetItem( ATTR_HOR_JUSTIFY )).GetValue(); - BOOL bBreak; + bool bBreak; if ( eHorJust == SVX_HOR_JUSTIFY_BLOCK ) - bBreak = TRUE; + bBreak = true; else if ( pCondSet && pCondSet->GetItemState(ATTR_LINEBREAK, TRUE, &pCondItem) == SFX_ITEM_SET) bBreak = ((const SfxBoolItem*)pCondItem)->GetValue(); else bBreak = ((const SfxBoolItem&)pPattern->GetItem(ATTR_LINEBREAK)).GetValue(); + if (pCell->HasValueData()) + // Cell has a value. Disable line break. + bBreak = false; + // get other attributes from pattern and conditional formatting SvxCellOrientation eOrient = pPattern->GetCellOrientation( pCondSet ); BOOL bAsianVertical = ( eOrient == SVX_ORIENTATION_STACKED && ((const SfxBoolItem&)pPattern->GetItem( ATTR_VERTICAL_ASIAN, pCondSet )).GetValue() ); if ( bAsianVertical ) - bBreak = FALSE; + bBreak = false; if ( bWidth && bBreak ) // after determining bAsianVertical (bBreak may be reset) return 0; @@ -300,7 +306,6 @@ long ScColumn::GetNeededSize( SCROW nRow, OutputDevice* pDev, nIndent = ((const SfxUInt16Item&)pPattern->GetItem(ATTR_INDENT)).GetValue(); } - ScBaseCell* pCell = pItems[nIndex].pCell; BYTE nScript = pDocument->GetScriptType( nCol, nRow, nTab, pCell ); if (nScript == 0) nScript = ScGlobal::GetDefaultScriptType(); @@ -756,8 +761,8 @@ void ScColumn::GetOptimalHeight( SCROW nStartRow, SCROW nEndRow, USHORT* pHeight { ScAttrIterator aIter( pAttrArray, nStartRow, nEndRow ); - SCROW nStart; - SCROW nEnd; + SCROW nStart = -1; + SCROW nEnd = -1; SCROW nEditPos = 0; SCROW nNextEnd = 0; @@ -1403,11 +1408,11 @@ BOOL ScColumn::GetPrevDataPos(SCROW& rRow) const return bFound; } -BOOL ScColumn::GetNextDataPos(SCROW& rRow) const // groesser als rRow +BOOL ScColumn::GetNextDataPos(SCROW& rRow) const // greater than rRow { SCSIZE nIndex; if (Search( rRow, nIndex )) - ++nIndex; // naechste Zelle + ++nIndex; // next cell BOOL bMore = ( nIndex < nCount ); if ( bMore ) @@ -1778,7 +1783,7 @@ void lcl_UpdateSubTotal( ScFunctionData& rData, ScBaseCell* pCell ) // Mehrfachselektion: void ScColumn::UpdateSelectionFunction( const ScMarkData& rMark, ScFunctionData& rData, - const ScBitMaskCompressedArray< SCROW, BYTE>* pRowFlags, + ScFlatBoolRowSegments& rHiddenRows, BOOL bDoExclude, SCROW nExStartRow, SCROW nExEndRow ) { SCSIZE nIndex; @@ -1786,7 +1791,8 @@ void ScColumn::UpdateSelectionFunction( const ScMarkData& rMark, while (aDataIter.Next( nIndex )) { SCROW nRow = pItems[nIndex].nRow; - if ( !pRowFlags || !( pRowFlags->GetValue(nRow) & CR_HIDDEN ) ) + bool bRowHidden = rHiddenRows.getValue(nRow); + if ( !bRowHidden ) if ( !bDoExclude || nRow < nExStartRow || nRow > nExEndRow ) lcl_UpdateSubTotal( rData, pItems[nIndex].pCell ); } @@ -1794,7 +1800,7 @@ void ScColumn::UpdateSelectionFunction( const ScMarkData& rMark, // bei bNoMarked die Mehrfachselektion weglassen void ScColumn::UpdateAreaFunction( ScFunctionData& rData, - const ScBitMaskCompressedArray< SCROW, BYTE>* pRowFlags, + ScFlatBoolRowSegments& rHiddenRows, SCROW nStartRow, SCROW nEndRow ) { SCSIZE nIndex; @@ -1802,7 +1808,8 @@ void ScColumn::UpdateAreaFunction( ScFunctionData& rData, while ( nIndex<nCount && pItems[nIndex].nRow<=nEndRow ) { SCROW nRow = pItems[nIndex].nRow; - if ( !pRowFlags || !( pRowFlags->GetValue(nRow) & CR_HIDDEN ) ) + bool bRowHidden = rHiddenRows.getValue(nRow); + if ( !bRowHidden ) lcl_UpdateSubTotal( rData, pItems[nIndex].pCell ); ++nIndex; } diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx index 22b75b8d4a6a..65e896c7f2c4 100644 --- a/sc/source/core/data/column3.cxx +++ b/sc/source/core/data/column3.cxx @@ -1249,7 +1249,7 @@ void ScColumn::StartListeningInArea( SCROW nRow1, SCROW nRow2 ) // TRUE = Zahlformat gesetzt BOOL ScColumn::SetString( SCROW nRow, SCTAB nTabP, const String& rString, formula::FormulaGrammar::AddressConvention eConv, - SvNumberFormatter* pFormatter, bool bDetectNumberFormat ) + SvNumberFormatter* pLangFormatter, bool bDetectNumberFormat ) { BOOL bNumFmtSet = FALSE; if (VALIDROW(nRow)) @@ -1261,8 +1261,11 @@ BOOL ScColumn::SetString( SCROW nRow, SCTAB nTabP, const String& rString, double nVal; sal_uInt32 nIndex, nOldIndex = 0; sal_Unicode cFirstChar; - if (!pFormatter) - pFormatter = pDocument->GetFormatTable(); + // #i110979# If a different NumberFormatter is passed in (pLangFormatter), + // its formats aren't valid in the document. + // Only use the language / LocaleDataWrapper from pLangFormatter, + // always the document's number formatter for IsNumberFormat. + SvNumberFormatter* pFormatter = pDocument->GetFormatTable(); SfxObjectShell* pDocSh = pDocument->GetDocumentShell(); if ( pDocSh ) bIsLoading = pDocSh->IsLoading(); @@ -1337,9 +1340,23 @@ BOOL ScColumn::SetString( SCROW nRow, SCTAB nTabP, const String& rString, if (bDetectNumberFormat) { + if ( pLangFormatter ) + { + // for number detection: valid format index for selected language + nIndex = pFormatter->GetStandardIndex( pLangFormatter->GetLanguage() ); + } + if (!pFormatter->IsNumberFormat(rString, nIndex, nVal)) break; + if ( pLangFormatter ) + { + // convert back to the original language if a built-in format was detected + const SvNumberformat* pOldFormat = pFormatter->GetEntry( nOldIndex ); + if ( pOldFormat ) + nIndex = pFormatter->GetFormatForLanguageIfBuiltIn( nIndex, pOldFormat->GetLanguage() ); + } + pNewCell = new ScValueCell( nVal ); if ( nIndex != nOldIndex) { @@ -1378,7 +1395,8 @@ BOOL ScColumn::SetString( SCROW nRow, SCTAB nTabP, const String& rString, else { // Only check if the string is a regular number. - const LocaleDataWrapper* pLocale = pFormatter->GetLocaleData(); + SvNumberFormatter* pLocaleSource = pLangFormatter ? pLangFormatter : pFormatter; + const LocaleDataWrapper* pLocale = pLocaleSource->GetLocaleData(); if (!pLocale) break; @@ -1630,8 +1648,8 @@ BOOL ScColumn::GetDataEntries(SCROW nStartRow, TypedScStrCollection& rStrings, B void ScColumn::RemoveProtected( SCROW nStartRow, SCROW nEndRow ) { ScAttrIterator aAttrIter( pAttrArray, nStartRow, nEndRow ); - SCROW nTop; - SCROW nBottom; + SCROW nTop = -1; + SCROW nBottom = -1; SCSIZE nIndex; const ScPatternAttr* pPattern = aAttrIter.Next( nTop, nBottom ); while (pPattern) @@ -1920,11 +1938,15 @@ sal_Int32 ScColumn::GetMaxStringLen( SCROW nRowStart, SCROW nRowEnd, CharSet eCh } -xub_StrLen ScColumn::GetMaxNumberStringLen( USHORT& nPrecision, - SCROW nRowStart, SCROW nRowEnd ) const +xub_StrLen ScColumn::GetMaxNumberStringLen( + sal_uInt16& nPrecision, SCROW nRowStart, SCROW nRowEnd ) const { xub_StrLen nStringLen = 0; nPrecision = pDocument->GetDocOptions().GetStdPrecision(); + if ( nPrecision == SvNumberFormatter::UNLIMITED_PRECISION ) + // In case of unlimited precision, use 2 instead. + nPrecision = 2; + if ( pItems ) { String aString; @@ -1947,8 +1969,8 @@ xub_StrLen ScColumn::GetMaxNumberStringLen( USHORT& nPrecision, { if ( nFormat ) { // more decimals than standard? - USHORT nPrec = pNumFmt->GetFormatPrecision( nFormat ); - if ( nPrec > nPrecision ) + sal_uInt16 nPrec = pNumFmt->GetFormatPrecision( nFormat ); + if ( nPrec != SvNumberFormatter::UNLIMITED_PRECISION && nPrec > nPrecision ) nPrecision = nPrec; } if ( nPrecision ) diff --git a/sc/source/core/data/dociter.cxx b/sc/source/core/data/dociter.cxx index 706783579a24..aa5b011da93b 100644 --- a/sc/source/core/data/dociter.cxx +++ b/sc/source/core/data/dociter.cxx @@ -49,6 +49,7 @@ using ::rtl::math::approxEqual; using ::std::vector; using ::rtl::OUString; +using ::std::set; // STATIC DATA ----------------------------------------------------------- @@ -345,7 +346,7 @@ BOOL ScValueIterator::GetThis(double& rValue, USHORT& rErr) if ( nColRow < pCol->nCount && pCol->pItems[nColRow].nRow <= nEndRow ) { nRow = pCol->pItems[nColRow].nRow + 1; - if ( !bSubTotal || !pDoc->pTab[nTab]->IsFiltered( nRow-1 ) ) + if ( !bSubTotal || !pDoc->pTab[nTab]->RowFiltered( nRow-1 ) ) { ScBaseCell* pCell = pCol->pItems[nColRow].pCell; ++nColRow; @@ -940,11 +941,6 @@ ScDBQueryDataIterator::ScDBQueryDataIterator(ScDocument* pDocument, ScDBQueryPar } } -bool ScDBQueryDataIterator::GetThis(Value& rValue) -{ - return mpData->getCurrent(rValue); -} - bool ScDBQueryDataIterator::GetFirst(Value& rValue) { return mpData->getFirst(rValue); @@ -1071,7 +1067,7 @@ ScBaseCell* ScCellIterator::GetThis() if ( nColRow < pCol->nCount && pCol->pItems[nColRow].nRow <= nEndRow ) { nRow = pCol->pItems[nColRow].nRow; - if ( !bSubTotal || !pDoc->pTab[nTab]->IsFiltered( nRow ) ) + if ( !bSubTotal || !pDoc->pTab[nTab]->RowFiltered( nRow ) ) { ScBaseCell* pCell = pCol->pItems[nColRow].pCell; @@ -1259,14 +1255,6 @@ ScBaseCell* ScQueryCellIterator::GetNext() return GetThis(); } -ULONG ScQueryCellIterator::GetNumberFormat() -{ - ScColumn* pCol = &(pDoc->pTab[nTab])->aCol[nCol]; - lcl_IterGetNumberFormat( nNumFormat, pAttrArray, - nAttrEndRow, pCol->pAttrArray, nRow, pDoc ); - return nNumFormat; -} - void ScQueryCellIterator::AdvanceQueryParamEntryField() { SCSIZE nEntries = aParam.GetEntryCount(); @@ -2147,3 +2135,24 @@ const ScPatternAttr* ScAttrRectIterator::GetNext( SCCOL& rCol1, SCCOL& rCol2, return NULL; // is nix mehr } +// ============================================================================ + +SCROW ScRowBreakIterator::NOT_FOUND = -1; + +ScRowBreakIterator::ScRowBreakIterator(set<SCROW>& rBreaks) : + mrBreaks(rBreaks), + maItr(rBreaks.begin()), maEnd(rBreaks.end()) +{ +} + +SCROW ScRowBreakIterator::first() +{ + maItr = mrBreaks.begin(); + return maItr == maEnd ? NOT_FOUND : *maItr; +} + +SCROW ScRowBreakIterator::next() +{ + ++maItr; + return maItr == maEnd ? NOT_FOUND : *maItr; +} 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 c08fb7a10228..e8ea10f7cf52 100644..100755 --- a/sc/source/core/data/documen2.cxx +++ b/sc/source/core/data/documen2.cxx @@ -93,6 +93,7 @@ #include "tabprotection.hxx" #include "formulaparserpool.hxx" #include "clipparam.hxx" +#include <basic/basmgr.hxx> // pImpl because including lookupcache.hxx in document.hxx isn't wanted, and // dtor plus helpers are convenient. @@ -187,11 +188,11 @@ ScDocument::ScDocument( ScDocumentMode eMode, // bNoSetDirty( TRUE ), bNoSetDirty( FALSE ), bInsertingFromOtherDoc( FALSE ), - bImportingXML( FALSE ), + bLoadingMedium( false ), + bImportingXML( false ), bXMLFromWrapper( FALSE ), bCalcingAfterLoad( FALSE ), bNoListening( FALSE ), - bLoadingDone( TRUE ), bIdleDisabled( FALSE ), bInLinkUpdate( FALSE ), bChartListenerCollectionNeedsUpdate( FALSE ), @@ -803,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; } } @@ -900,6 +897,8 @@ BOOL ScDocument::CopyTab( SCTAB nOldPos, SCTAB nNewPos, const ScMarkData* pOnlyM SetNoListening( TRUE ); // noch nicht bei CopyToTable/Insert pTab[nOldPos]->CopyToTable(0, 0, MAXCOL, MAXROW, IDF_ALL, (pOnlyMarked != NULL), pTab[nNewPos], pOnlyMarked ); + pTab[nNewPos]->SetTabBgColor(pTab[nOldPos]->GetTabBgColor()); + SCsTAB nDz; /* if (nNewPos < nOldPos) nDz = ((short)nNewPos) - (short)nOldPos + 1; @@ -924,16 +923,14 @@ 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 ); return bValid; } +void VBA_InsertModule( ScDocument& rDoc, SCTAB nTab, String& sModuleName, String& sModuleSource ); + ULONG ScDocument::TransferTab( ScDocument* pSrcDoc, SCTAB nSrcPos, SCTAB nDestPos, BOOL bInsertNew, BOOL bResultsOnly ) @@ -1104,6 +1101,43 @@ ULONG ScDocument::TransferTab( ScDocument* pSrcDoc, SCTAB nSrcPos, } if (!bValid) nRetVal = 0; + BOOL bVbaEnabled = IsInVBAMode(); + + if ( bVbaEnabled ) + { + SfxObjectShell* pSrcShell = pSrcDoc ? pSrcDoc->GetDocumentShell() : NULL; + if ( pSrcShell ) + { + StarBASIC* pStarBASIC = pSrcShell ? pSrcShell->GetBasic() : NULL; + String aLibName( RTL_CONSTASCII_USTRINGPARAM( "Standard" ) ); + if ( pSrcShell && pSrcShell->GetBasicManager()->GetName().Len() > 0 ) + { + aLibName = pSrcShell->GetBasicManager()->GetName(); + pStarBASIC = pSrcShell->GetBasicManager()->GetLib( aLibName ); + } + + String sCodeName; + String sSource; + com::sun::star::uno::Reference< com::sun::star::script::XLibraryContainer > xLibContainer = pSrcShell->GetBasicContainer(); + com::sun::star::uno::Reference< com::sun::star::container::XNameContainer > xLib; + if( xLibContainer.is() ) + { + com::sun::star::uno::Any aLibAny = xLibContainer->getByName( aLibName ); + aLibAny >>= xLib; + } + + if( xLib.is() ) + { + String sSrcCodeName; + pSrcDoc->GetCodeName( nSrcPos, sSrcCodeName ); + rtl::OUString sRTLSource; + xLib->getByName( sSrcCodeName ) >>= sRTLSource; + sSource = sRTLSource; + } + VBA_InsertModule( *this, nDestPos, sCodeName, sSource ); + } + } + return nRetVal; } diff --git a/sc/source/core/data/documen3.cxx b/sc/source/core/data/documen3.cxx index 557f181c9d8f..1861988d78aa 100644 --- a/sc/source/core/data/documen3.cxx +++ b/sc/source/core/data/documen3.cxx @@ -83,6 +83,7 @@ #include "tabprotection.hxx" #include "formulaparserpool.hxx" #include "clipparam.hxx" +#include "sheetevents.hxx" #include <memory> @@ -285,6 +286,26 @@ void ScDocument::SetScenarioData( SCTAB nTab, const String& rComment, } } +Color ScDocument::GetTabBgColor( SCTAB nTab ) const +{ + if (ValidTab(nTab) && pTab[nTab]) + return pTab[nTab]->GetTabBgColor(); + return Color(COL_AUTO); +} + +void ScDocument::SetTabBgColor( SCTAB nTab, const Color& rColor ) +{ + if (ValidTab(nTab) && pTab[nTab]) + pTab[nTab]->SetTabBgColor(rColor); +} + +bool ScDocument::IsDefaultTabBgColor( SCTAB nTab ) const +{ + if (ValidTab(nTab) && pTab[nTab]) + return pTab[nTab]->GetTabBgColor() == COL_AUTO; + return true; +} + void ScDocument::GetScenarioData( SCTAB nTab, String& rComment, Color& rColor, USHORT& rFlags ) const { @@ -465,11 +486,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. */ } @@ -481,6 +499,52 @@ ScFormulaParserPool& ScDocument::GetFormulaParserPool() const return *mxFormulaParserPool; } +const ScSheetEvents* ScDocument::GetSheetEvents( SCTAB nTab ) const +{ + if (VALIDTAB(nTab) && pTab[nTab]) + return pTab[nTab]->GetSheetEvents(); + return NULL; +} + +void ScDocument::SetSheetEvents( SCTAB nTab, const ScSheetEvents* pNew ) +{ + if (VALIDTAB(nTab) && pTab[nTab]) + pTab[nTab]->SetSheetEvents( pNew ); +} + +bool ScDocument::HasSheetEventScript( sal_Int32 nEvent ) const +{ + for (SCTAB nTab = 0; nTab <= MAXTAB; nTab++) + if (pTab[nTab]) + { + const ScSheetEvents* pEvents = pTab[nTab]->GetSheetEvents(); + if ( pEvents && pEvents->GetScript( nEvent ) ) + return true; + } + return false; +} + +BOOL ScDocument::HasCalcNotification( SCTAB nTab ) const +{ + if (VALIDTAB(nTab) && pTab[nTab]) + return pTab[nTab]->GetCalcNotification(); + return FALSE; +} + +void ScDocument::SetCalcNotification( SCTAB nTab ) +{ + // set only if not set before + if (VALIDTAB(nTab) && pTab[nTab] && !pTab[nTab]->GetCalcNotification()) + pTab[nTab]->SetCalcNotification(TRUE); +} + +void ScDocument::ResetCalcNotifications() +{ + for (SCTAB nTab = 0; nTab <= MAXTAB; nTab++) + if (pTab[nTab] && pTab[nTab]->GetCalcNotification()) + pTab[nTab]->SetCalcNotification(FALSE); +} + ScOutlineTable* ScDocument::GetOutlineTable( SCTAB nTab, BOOL bCreate ) { ScOutlineTable* pVal = NULL; @@ -1126,15 +1190,6 @@ BOOL ScDocument::SearchAndReplace(const SvxSearchItem& rSearchItem, return bFound; } -BOOL ScDocument::IsFiltered( SCROW nRow, SCTAB nTab ) const -{ - if (VALIDTAB(nTab)) - if (pTab[nTab]) - return pTab[nTab]->IsFiltered( nRow ); - DBG_ERROR("Falsche Tabellennummer"); - return 0; -} - // Outline anpassen BOOL ScDocument::UpdateOutlineCol( SCCOL nStartCol, SCCOL nEndCol, SCTAB nTab, BOOL bShow ) @@ -1547,46 +1602,43 @@ ScRange ScDocument::GetRange( SCTAB nTab, const Rectangle& rMMRect ) nTwips = (long) (aPosRect.Top() / HMM_PER_TWIPS); SCROW nY1 = 0; - ScCoupledCompressedArrayIterator< SCROW, BYTE, USHORT> aIter( - *(pTable->GetRowFlagsArray()), nY1, MAXROW, CR_HIDDEN, 0, - *(pTable->GetRowHeightArray())); bEnd = FALSE; - while (!bEnd && aIter) + for (SCROW i = nY1; i <= MAXROW && !bEnd; ++i) { - nY1 = aIter.GetPos(); - nAdd = (long) *aIter; + if (pTable->RowHidden(i)) + continue; + + nY1 = i; + nAdd = static_cast<long>(pTable->GetRowHeight(i)); if (nSize+nAdd <= nTwips+1 && nY1<MAXROW) { nSize += nAdd; ++nY1; - ++aIter; } else bEnd = TRUE; } - if (!aIter) - nY1 = aIter.GetIterEnd(); // all hidden down to the bottom + if (!bEnd) + nY1 = MAXROW; // all hidden down to the bottom nTwips = (long) (aPosRect.Bottom() / HMM_PER_TWIPS); SCROW nY2 = nY1; - aIter.NewLimits( nY2, MAXROW); bEnd = FALSE; - while (!bEnd && aIter) + for (SCROW i = nY2; i <= MAXROW && !bEnd; ++i) { - nY2 = aIter.GetPos(); - nAdd = (long) *aIter; + nY2 = i; + nAdd = static_cast<long>(pTable->GetRowHeight(i)); if (nSize+nAdd < nTwips && nY2<MAXROW) { nSize += nAdd; ++nY2; - ++aIter; } else bEnd = TRUE; } - if (!aIter) - nY2 = aIter.GetIterEnd(); // all hidden down to the bottom + if (!bEnd) + nY2 = MAXROW; // all hidden down to the bottom return ScRange( nX1,nY1,nTab, nX2,nY2,nTab ); } @@ -1624,24 +1676,33 @@ void lcl_SnapVer( ScTable* pTable, long& rVal, SCROW& rStartRow ) SCROW nRow = 0; long nTwips = (long) (rVal / HMM_PER_TWIPS); long nSnap = 0; - ScCoupledCompressedArrayIterator< SCROW, BYTE, USHORT> aIter( - *(pTable->GetRowFlagsArray()), nRow, MAXROW, CR_HIDDEN, 0, - *(pTable->GetRowHeightArray())); - while ( aIter ) + + bool bFound = false; + for (SCROW i = nRow; i <= MAXROW; ++i) { - nRow = aIter.GetPos(); - long nAdd = *aIter; + SCROW nLastRow; + if (pTable->RowHidden(i, NULL, &nLastRow)) + { + i = nLastRow; + continue; + } + + nRow = i; + long nAdd = pTable->GetRowHeight(i); if ( nSnap + nAdd/2 < nTwips || nRow < rStartRow ) { nSnap += nAdd; ++nRow; - ++aIter; } else + { + bFound = true; break; + } } - if (!aIter) + if (!bFound) nRow = MAXROW; // all hidden down to the bottom + rVal = (long) ( nSnap * HMM_PER_TWIPS ); rStartRow = nRow; } @@ -1799,14 +1860,14 @@ Rectangle ScDocument::GetMMRect( SCCOL nStartCol, SCROW nStartRow, for (i=0; i<nStartCol; i++) aRect.Left() += GetColWidth(i,nTab); - aRect.Top() += FastGetRowHeight( 0, nStartRow-1, nTab); + aRect.Top() += GetRowHeight( 0, nStartRow-1, nTab); aRect.Right() = aRect.Left(); aRect.Bottom() = aRect.Top(); for (i=nStartCol; i<=nEndCol; i++) aRect.Right() += GetColWidth(i,nTab); - aRect.Bottom() += FastGetRowHeight( nStartRow, nEndRow, nTab); + aRect.Bottom() += GetRowHeight( nStartRow, nEndRow, nTab); aRect.Left() = (long)(aRect.Left() * HMM_PER_TWIPS); aRect.Right() = (long)(aRect.Right() * HMM_PER_TWIPS); diff --git a/sc/source/core/data/documen4.cxx b/sc/source/core/data/documen4.cxx index bb6b4cd295ce..148cc367534c 100644 --- a/sc/source/core/data/documen4.cxx +++ b/sc/source/core/data/documen4.cxx @@ -430,7 +430,7 @@ sal_Int32 ScDocument::GetMaxStringLen( SCTAB nTab, SCCOL nCol, return 0; } -xub_StrLen ScDocument::GetMaxNumberStringLen( USHORT& nPrecision, SCTAB nTab, +xub_StrLen ScDocument::GetMaxNumberStringLen( sal_uInt16& nPrecision, SCTAB nTab, SCCOL nCol, SCROW nRowStart, SCROW nRowEnd ) const { 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/documen7.cxx b/sc/source/core/data/documen7.cxx index ad2ec90379df..97aae44f1a7b 100644 --- a/sc/source/core/data/documen7.cxx +++ b/sc/source/core/data/documen7.cxx @@ -52,6 +52,7 @@ #include "scmod.hxx" // SC_MOD #include "inputopt.hxx" // GetExpandRefs #include "conditio.hxx" +#include "sheetevents.hxx" #include <tools/shl.hxx> @@ -452,6 +453,8 @@ void ScDocument::TrackFormulas( ULONG nHintId ) if ( pFormulaTrack ) { erBEEPER(); + // outside the loop, check if any sheet has a "calculate" event script + bool bCalcEvent = HasSheetEventScript( SC_SHEETEVENT_CALCULATE ); SvtBroadcaster* pBC; ScFormulaCell* pTrack; ScFormulaCell* pNext; @@ -465,6 +468,9 @@ void ScDocument::TrackFormulas( ULONG nHintId ) // Repaint fuer bedingte Formate mit relativen Referenzen: if ( pCondFormList ) pCondFormList->SourceChanged( pTrack->aPos ); + // for "calculate" event, keep track of which sheets are affected by tracked formulas + if ( bCalcEvent ) + SetCalcNotification( pTrack->aPos.Tab() ); pTrack = pTrack->GetNextTrack(); } while ( pTrack ); pTrack = pFormulaTrack; diff --git a/sc/source/core/data/documen9.cxx b/sc/source/core/data/documen9.cxx index 9da788fca01c..abef7d53c2af 100644 --- a/sc/source/core/data/documen9.cxx +++ b/sc/source/core/data/documen9.cxx @@ -67,7 +67,7 @@ #include "charthelper.hxx" using namespace ::com::sun::star; - +#include <stdio.h> // ----------------------------------------------------------------------- @@ -722,7 +722,19 @@ void ScDocument::UpdateFontCharSet() } } -void ScDocument::SetImportingXML( BOOL bVal ) +void ScDocument::SetLoadingMedium( bool bVal ) +{ + bLoadingMedium = bVal; + for (SCTAB nTab = 0; nTab <= MAXTAB; ++nTab) + { + if (!pTab[nTab]) + return; + + pTab[nTab]->SetLoadingMedium(bVal); + } +} + +void ScDocument::SetImportingXML( bool bVal ) { bImportingXML = bVal; if (pDrawLayer) @@ -739,6 +751,8 @@ void ScDocument::SetImportingXML( BOOL bVal ) SetLayoutRTL( nTab, TRUE ); // includes mirroring; bImportingXML must be cleared first } } + + SetLoadingMedium(bVal); } void ScDocument::SetXMLFromWrapper( BOOL bVal ) diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx index 3f25ad5a310e..bef4cbf87396 100644 --- a/sc/source/core/data/document.cxx +++ b/sc/source/core/data/document.cxx @@ -51,6 +51,8 @@ #include <tools/tenccvt.hxx> #include <com/sun/star/text/WritingMode2.hpp> +#include <com/sun/star/script/XVBACompat.hpp> +#include <com/sun/star/sheet/TablePageBreakData.hpp> #include "document.hxx" #include "table.hxx" @@ -93,8 +95,12 @@ #include "clipparam.hxx" #include <map> +#include <limits> namespace WritingMode2 = ::com::sun::star::text::WritingMode2; +using ::com::sun::star::uno::Sequence; +using ::com::sun::star::sheet::TablePageBreakData; +using ::std::set; struct ScDefaultAttr { @@ -124,6 +130,7 @@ void ScDocument::MakeTable( SCTAB nTab,bool _bNeedsNameCheck ) CreateValidTabName( aString ); // keine doppelten pTab[nTab] = new ScTable(this, nTab, aString); + pTab[nTab]->SetLoadingMedium(bLoadingMedium); ++nMaxTableNumber; } } @@ -374,10 +381,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; } @@ -466,11 +469,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; } @@ -693,6 +691,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! } @@ -707,11 +709,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 ); } @@ -2014,9 +2015,6 @@ void ScDocument::CopyNonFilteredFromClip( SCCOL nCol1, SCROW nRow1, while ( nFlagTab < MAXTAB && !ppClipTab[nFlagTab] ) ++nFlagTab; - const ScBitMaskCompressedArray< SCROW, BYTE> & rSourceFlags = - pCBFCP->pClipDoc->GetRowFlagsArray( nFlagTab); - SCROW nSourceRow = rClipStartRow; SCROW nSourceEnd = 0; if (pCBFCP->pClipDoc->GetClipParam().maRanges.Count()) @@ -2026,12 +2024,15 @@ void ScDocument::CopyNonFilteredFromClip( SCCOL nCol1, SCROW nRow1, while ( nSourceRow <= nSourceEnd && nDestRow <= nRow2 ) { // skip filtered rows - nSourceRow = rSourceFlags.GetFirstForCondition( nSourceRow, nSourceEnd, CR_FILTERED, 0); + nSourceRow = pCBFCP->pClipDoc->FirstNonFilteredRow(nSourceRow, nSourceEnd, nFlagTab); if ( nSourceRow <= nSourceEnd ) { // look for more non-filtered rows following - SCROW nFollow = rSourceFlags.GetBitStateEnd( nSourceRow, CR_FILTERED, 0) - nSourceRow; + SCROW nLastRow = nSourceRow; + pCBFCP->pClipDoc->RowFiltered(nSourceRow, nFlagTab, NULL, &nLastRow); + SCROW nFollow = nLastRow - nSourceRow; + if (nFollow > nSourceEnd - nSourceRow) nFollow = nSourceEnd - nSourceRow; if (nFollow > nRow2 - nDestRow) @@ -2439,8 +2440,7 @@ void ScDocument::GetClipArea(SCCOL& nClipX, SCROW& nClipY, BOOL bIncludeFiltered while ( nCountTab < MAXTAB && !pTab[nCountTab] ) ++nCountTab; - SCROW nResult = GetRowFlagsArray( nCountTab).CountForCondition( - nStartRow, nEndRow, CR_FILTERED, 0); + SCROW nResult = CountNonFilteredRows(nStartRow, nEndRow, nCountTab); if ( nResult > 0 ) nClipY = nResult - 1; @@ -2479,8 +2479,13 @@ BOOL ScDocument::HasClipFilteredRows() if (!rClipRanges.Count()) return false; - return GetRowFlagsArray( nCountTab).HasCondition( rClipRanges.First()->aStart.Row(), - rClipRanges.First()->aEnd.Row(), CR_FILTERED, CR_FILTERED); + for (ScRange* p = rClipRanges.First(); p; p = rClipRanges.Next()) + { + bool bAnswer = pTab[nCountTab]->HasFilteredRows(p->aStart.Row(), p->aEnd.Row()); + if (bAnswer) + return true; + } + return false; } @@ -3103,6 +3108,11 @@ void ScDocument::SetRowHeightRange( SCROW nStartRow, SCROW nEndRow, SCTAB nTab, ( nStartRow, nEndRow, nNewHeight, 1.0, 1.0 ); } +void ScDocument::SetRowHeightOnly( SCROW nStartRow, SCROW nEndRow, SCTAB nTab, USHORT nNewHeight ) +{ + if ( ValidTab(nTab) && pTab[nTab] ) + pTab[nTab]->SetRowHeightOnly( nStartRow, nEndRow, nNewHeight ); +} void ScDocument::SetManualHeight( SCROW nStartRow, SCROW nEndRow, SCTAB nTab, BOOL bManual ) { @@ -3147,10 +3157,10 @@ USHORT ScDocument::GetOriginalHeight( SCROW nRow, SCTAB nTab ) const } -USHORT ScDocument::GetRowHeight( SCROW nRow, SCTAB nTab ) const +USHORT ScDocument::GetRowHeight( SCROW nRow, SCTAB nTab, bool bHiddenAsZero ) const { if ( ValidTab(nTab) && pTab[nTab] ) - return pTab[nTab]->GetRowHeight( nRow ); + return pTab[nTab]->GetRowHeight( nRow, NULL, NULL, bHiddenAsZero ); DBG_ERROR("Falsche Tabellennummer"); return 0; } @@ -3172,11 +3182,9 @@ ULONG ScDocument::GetRowHeight( SCROW nStartRow, SCROW nEndRow, SCTAB nTab ) con return 0; } -ULONG ScDocument::FastGetRowHeight( SCROW nStartRow, SCROW nEndRow, - SCTAB nTab ) const +SCROW ScDocument::GetRowForHeight( SCTAB nTab, ULONG nHeight ) const { - return pTab[nTab]->pRowFlags->SumCoupledArrayForCondition( nStartRow, - nEndRow, CR_HIDDEN, 0, *(pTab[nTab]->pRowHeight)); + return pTab[nTab]->GetRowForHeight(nHeight); } ULONG ScDocument::GetScaledRowHeight( SCROW nStartRow, SCROW nEndRow, @@ -3197,29 +3205,6 @@ ULONG ScDocument::GetScaledRowHeight( SCROW nStartRow, SCROW nEndRow, return 0; } - -const ScSummableCompressedArray< SCROW, USHORT> & ScDocument::GetRowHeightArray( - SCTAB nTab ) const -{ - const ScSummableCompressedArray< SCROW, USHORT> * pHeight; - if ( ValidTab(nTab) && pTab[nTab] ) - pHeight = pTab[nTab]->GetRowHeightArray(); - else - { - DBG_ERROR("wrong sheet number"); - pHeight = 0; - } - if (!pHeight) - { - DBG_ERROR("no row heights at sheet"); - static ScSummableCompressedArray< SCROW, USHORT> aDummy( MAXROW, - ScGlobal::nStdRowHeight); - pHeight = &aDummy; - } - return *pHeight; -} - - SCROW ScDocument::GetHiddenRowCount( SCROW nRow, SCTAB nTab ) const { if ( ValidTab(nTab) && pTab[nTab] ) @@ -3402,6 +3387,259 @@ const ScBitMaskCompressedArray< SCROW, BYTE> & ScDocument::GetRowFlagsArray( return *pFlags; } +void ScDocument::GetAllRowBreaks(set<SCROW>& rBreaks, SCTAB nTab, bool bPage, bool bManual) const +{ + if (!ValidTab(nTab) || !pTab[nTab]) + return; + + pTab[nTab]->GetAllRowBreaks(rBreaks, bPage, bManual); +} + +void ScDocument::GetAllColBreaks(set<SCCOL>& rBreaks, SCTAB nTab, bool bPage, bool bManual) const +{ + if (!ValidTab(nTab) || !pTab[nTab]) + return; + + pTab[nTab]->GetAllColBreaks(rBreaks, bPage, bManual); +} + +ScBreakType ScDocument::HasRowBreak(SCROW nRow, SCTAB nTab) const +{ + ScBreakType nType = BREAK_NONE; + if (!ValidTab(nTab) || !pTab[nTab] || !ValidRow(nRow)) + return nType; + + if (pTab[nTab]->HasRowPageBreak(nRow)) + nType |= BREAK_PAGE; + + if (pTab[nTab]->HasRowManualBreak(nRow)) + nType |= BREAK_MANUAL; + + return nType; +} + +ScBreakType ScDocument::HasColBreak(SCCOL nCol, SCTAB nTab) const +{ + ScBreakType nType = BREAK_NONE; + if (!ValidTab(nTab) || !pTab[nTab] || !ValidCol(nCol)) + return nType; + + if (pTab[nTab]->HasColPageBreak(nCol)) + nType |= BREAK_PAGE; + + if (pTab[nTab]->HasColManualBreak(nCol)) + nType |= BREAK_MANUAL; + + return nType; +} + +void ScDocument::SetRowBreak(SCROW nRow, SCTAB nTab, bool bPage, bool bManual) +{ + if (!ValidTab(nTab) || !pTab[nTab] || !ValidRow(nRow)) + return; + + pTab[nTab]->SetRowBreak(nRow, bPage, bManual); +} + +void ScDocument::SetColBreak(SCCOL nCol, SCTAB nTab, bool bPage, bool bManual) +{ + if (!ValidTab(nTab) || !pTab[nTab] || !ValidCol(nCol)) + return; + + pTab[nTab]->SetColBreak(nCol, bPage, bManual); +} + +void ScDocument::RemoveRowBreak(SCROW nRow, SCTAB nTab, bool bPage, bool bManual) +{ + if (!ValidTab(nTab) || !pTab[nTab] || !ValidRow(nRow)) + return; + + pTab[nTab]->RemoveRowBreak(nRow, bPage, bManual); +} + +void ScDocument::RemoveColBreak(SCCOL nCol, SCTAB nTab, bool bPage, bool bManual) +{ + if (!ValidTab(nTab) || !pTab[nTab] || !ValidCol(nCol)) + return; + + pTab[nTab]->RemoveColBreak(nCol, bPage, bManual); +} + +Sequence<TablePageBreakData> ScDocument::GetRowBreakData(SCTAB nTab) const +{ + if (!ValidTab(nTab) || !pTab[nTab]) + return Sequence<TablePageBreakData>(); + + return pTab[nTab]->GetRowBreakData(); +} + +bool ScDocument::RowHidden(SCROW nRow, SCTAB nTab, SCROW* pFirstRow, SCROW* pLastRow) +{ + if (!ValidTab(nTab) || !pTab[nTab]) + return false; + + return pTab[nTab]->RowHidden(nRow, pFirstRow, pLastRow); +} + +bool ScDocument::RowHidden(SCROW nRow, SCTAB nTab, SCROW& rLastRow) +{ + if (!ValidTab(nTab) || !pTab[nTab]) + { + rLastRow = nRow; + return false; + } + + return pTab[nTab]->RowHidden(nRow, rLastRow); +} + + +bool ScDocument::HasHiddenRows(SCROW nStartRow, SCROW nEndRow, SCTAB nTab) +{ + if (!ValidTab(nTab) || !pTab[nTab]) + return false; + + return pTab[nTab]->HasHiddenRows(nStartRow, nEndRow); +} + +bool ScDocument::ColHidden(SCCOL nCol, SCTAB nTab, SCCOL& rLastCol) +{ + if (!ValidTab(nTab) || !pTab[nTab]) + { + rLastCol = nCol; + return false; + } + + return pTab[nTab]->ColHidden(nCol, rLastCol); +} + +bool ScDocument::ColHidden(SCCOL nCol, SCTAB nTab, SCCOL* pFirstCol, SCCOL* pLastCol) +{ + if (!ValidTab(nTab) || !pTab[nTab]) + { + if (pFirstCol) + *pFirstCol = nCol; + if (pLastCol) + *pLastCol = nCol; + return false; + } + + return pTab[nTab]->ColHidden(nCol, pFirstCol, pLastCol); +} + +void ScDocument::SetRowHidden(SCROW nStartRow, SCROW nEndRow, SCTAB nTab, bool bHidden) +{ + if (!ValidTab(nTab) || !pTab[nTab]) + return; + + pTab[nTab]->SetRowHidden(nStartRow, nEndRow, bHidden); +} + +void ScDocument::SetColHidden(SCCOL nStartCol, SCCOL nEndCol, SCTAB nTab, bool bHidden) +{ + if (!ValidTab(nTab) || !pTab[nTab]) + return; + + pTab[nTab]->SetColHidden(nStartCol, nEndCol, bHidden); +} + +SCROW ScDocument::FirstVisibleRow(SCROW nStartRow, SCROW nEndRow, SCTAB nTab) +{ + if (!ValidTab(nTab) || !pTab[nTab]) + return ::std::numeric_limits<SCROW>::max();; + + return pTab[nTab]->FirstVisibleRow(nStartRow, nEndRow); +} + +SCROW ScDocument::LastVisibleRow(SCROW nStartRow, SCROW nEndRow, SCTAB nTab) +{ + if (!ValidTab(nTab) || !pTab[nTab]) + return ::std::numeric_limits<SCROW>::max();; + + return pTab[nTab]->LastVisibleRow(nStartRow, nEndRow); +} + +SCROW ScDocument::CountVisibleRows(SCROW nStartRow, SCROW nEndRow, SCTAB nTab) +{ + if (!ValidTab(nTab) || !pTab[nTab]) + return 0; + + return pTab[nTab]->CountVisibleRows(nStartRow, nEndRow); +} + +bool ScDocument::RowFiltered(SCROW nRow, SCTAB nTab, SCROW* pFirstRow, SCROW* pLastRow) +{ + if (!ValidTab(nTab) || !pTab[nTab]) + return false; + + return pTab[nTab]->RowFiltered(nRow, pFirstRow, pLastRow); +} + +bool ScDocument::HasFilteredRows(SCROW nStartRow, SCROW nEndRow, SCTAB nTab) +{ + if (!ValidTab(nTab) || !pTab[nTab]) + return false; + + return pTab[nTab]->HasFilteredRows(nStartRow, nEndRow); +} + +bool ScDocument::ColFiltered(SCCOL nCol, SCTAB nTab, SCCOL* pFirstCol, SCCOL* pLastCol) +{ + if (!ValidTab(nTab) || !pTab[nTab]) + return false; + + return pTab[nTab]->ColFiltered(nCol, pFirstCol, pLastCol); +} + +void ScDocument::SetRowFiltered(SCROW nStartRow, SCROW nEndRow, SCTAB nTab, bool bFiltered) +{ + if (!ValidTab(nTab) || !pTab[nTab]) + return; + + pTab[nTab]->SetRowFiltered(nStartRow, nEndRow, bFiltered); +} + +void ScDocument::SetColFiltered(SCCOL nStartCol, SCCOL nEndCol, SCTAB nTab, bool bFiltered) +{ + if (!ValidTab(nTab) || !pTab[nTab]) + return; + + pTab[nTab]->SetColFiltered(nStartCol, nEndCol, bFiltered); +} + +SCROW ScDocument::FirstNonFilteredRow(SCROW nStartRow, SCROW nEndRow, SCTAB nTab) +{ + if (!ValidTab(nTab) || !pTab[nTab]) + return ::std::numeric_limits<SCROW>::max();; + + return pTab[nTab]->FirstNonFilteredRow(nStartRow, nEndRow); +} + +SCROW ScDocument::LastNonFilteredRow(SCROW nStartRow, SCROW nEndRow, SCTAB nTab) +{ + if (!ValidTab(nTab) || !pTab[nTab]) + return ::std::numeric_limits<SCROW>::max();; + + return pTab[nTab]->LastNonFilteredRow(nStartRow, nEndRow); +} + +SCROW ScDocument::CountNonFilteredRows(SCROW nStartRow, SCROW nEndRow, SCTAB nTab) +{ + if (!ValidTab(nTab) || !pTab[nTab]) + return 0; + + return pTab[nTab]->CountNonFilteredRows(nStartRow, nEndRow); +} + +void ScDocument::SyncColRowFlags() +{ + for (SCTAB i = 0; i <= nMaxTableNumber; ++i) + { + if (!ValidTab(i) || !pTab[i]) + continue; + + pTab[i]->SyncColRowFlags(); + } +} SCROW ScDocument::GetLastFlaggedRow( SCTAB nTab ) const { @@ -3446,7 +3684,7 @@ SCCOL ScDocument::GetNextDifferentChangedCol( SCTAB nTab, SCCOL nStart) const SCROW ScDocument::GetNextDifferentChangedRow( SCTAB nTab, SCROW nStart, bool bCareManualSize) const { - if ( ValidTab(nTab) && pTab[nTab] && pTab[nTab]->GetRowFlagsArray() && pTab[nTab]->GetRowHeightArray() ) + if ( ValidTab(nTab) && pTab[nTab] && pTab[nTab]->GetRowFlagsArray() && pTab[nTab]->mpRowHeights ) { BYTE nStartFlags = pTab[nTab]->GetRowFlags(nStart); USHORT nStartHeight = pTab[nTab]->GetOriginalHeight(nStart); @@ -3456,7 +3694,7 @@ SCROW ScDocument::GetNextDifferentChangedRow( SCTAB nTab, SCROW nStart, bool bCa SCROW nFlagsEndRow; SCROW nHeightEndRow; BYTE nFlags = pTab[nTab]->GetRowFlagsArray()->GetValue( nRow, nIndex, nFlagsEndRow ); - USHORT nHeight = pTab[nTab]->GetRowHeightArray()->GetValue( nRow, nIndex, nHeightEndRow ); + USHORT nHeight = pTab[nTab]->GetRowHeight(nRow, NULL, &nHeightEndRow); if (((nStartFlags & CR_MANUALBREAK) != (nFlags & CR_MANUALBREAK)) || ((nStartFlags & CR_MANUALSIZE) != (nFlags & CR_MANUALSIZE)) || (bCareManualSize && (nStartFlags & CR_MANUALSIZE) && (nStartHeight != nHeight)) || @@ -4786,6 +5024,11 @@ void ScDocument::SetRepeatArea( SCTAB nTab, SCCOL nStartCol, SCCOL nEndCol, SCRO pTab[nTab]->SetRepeatArea( nStartCol, nEndCol, nStartRow, nEndRow ); } +void ScDocument::InvalidatePageBreaks(SCTAB nTab) +{ + if (ValidTab(nTab) && pTab[nTab]) + pTab[nTab]->InvalidatePageBreaks(); +} void ScDocument::UpdatePageBreaks( SCTAB nTab, const ScRange* pUserArea ) { @@ -4965,6 +5208,12 @@ SfxUndoManager* ScDocument::GetUndoManager() return mpUndoManager; } +ScRowBreakIterator* ScDocument::GetRowBreakIterator(SCTAB nTab) const +{ + if (ValidTab(nTab) && pTab[nTab]) + return new ScRowBreakIterator(pTab[nTab]->maRowPageBreaks); + return NULL; +} void ScDocument::EnableUndo( bool bVal ) { @@ -4972,4 +5221,13 @@ void ScDocument::EnableUndo( bool bVal ) mbUndoEnabled = bVal; } - +bool ScDocument::IsInVBAMode() const +{ + bool bResult = false; + if ( pShell ) + { + com::sun::star::uno::Reference< com::sun::star::script::XVBACompat > xVBA( pShell->GetBasicContainer(), com::sun::star::uno::UNO_QUERY ); + bResult = xVBA->getVBACompatModeOn(); + } + return bResult; +} 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 44c998fb4ede..a2a10329cf68 100755 --- a/sc/source/core/data/dpobject.cxx +++ b/sc/source/core/data/dpobject.cxx @@ -410,7 +410,7 @@ void ScDPObject::CreateOutput() nNewRow = 0; ScAddress aStart( aOutRange.aStart ); - aStart.SetRow( (USHORT) nNewRow ); + aStart.SetRow(nNewRow); pOutput->SetPosition( aStart ); //! modify aOutRange? @@ -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()); } @@ -2429,6 +2434,14 @@ void ScDPCollection::WriteRefsTo( ScDPCollection& r ) const } } +ScDPObject* ScDPCollection::GetByName(const String& rName) const +{ + for (USHORT i=0; i<nCount; i++) + if (static_cast<const ScDPObject*>(pItems[i])->GetName() == rName) + return static_cast<ScDPObject*>(pItems[i]); + return NULL; +} + String ScDPCollection::CreateNewName( USHORT nMin ) const { String aBase = String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("DataPilot")); diff --git a/sc/source/core/data/dpoutput.cxx b/sc/source/core/data/dpoutput.cxx index ec384874aa69..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; @@ -1119,9 +1185,9 @@ void ScDPOutput::GetPositionData(const ScAddress& rPos, DataPilotTablePositionDa Reference<beans::XPropertySet> xPropSet(xSource, UNO_QUERY); if (xPropSet.is()) { - sal_Int32 nDataFieldCount = 0; - Any any = xPropSet->getPropertyValue(rtl::OUString::createFromAscii("DataFieldCount")); - if ((any >>= nDataFieldCount) && nDataFieldCount > 0) + sal_Int32 nDataFieldCount = ScUnoHelpFunctions::GetLongProperty( xPropSet, + rtl::OUString::createFromAscii(SC_UNO_DATAFIELDCOUNT) ); + if (nDataFieldCount > 0) aResData.DataFieldIndex = (nRow - nDataStartRow) % nDataFieldCount; } @@ -1201,21 +1267,20 @@ bool ScDPOutput::GetDataResultPositionData(vector<sheet::DataPilotFieldFilter>& if (!xPropSet.is()) return false; - sal_Int32 nDataFieldCount = 0; - Any any = xPropSet->getPropertyValue(rtl::OUString::createFromAscii("DataFieldCount")); - if (!(any >>= nDataFieldCount) || nDataFieldCount == 0) + sal_Int32 nDataFieldCount = ScUnoHelpFunctions::GetLongProperty( xPropSet, + rtl::OUString::createFromAscii(SC_UNO_DATAFIELDCOUNT) ); + if (nDataFieldCount == 0) // No data field is present in this datapilot table. return false; - bool bColGrand = bool(); - 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/dpsave.cxx b/sc/source/core/data/dpsave.cxx index 72cf15285310..dd493bb0df6c 100644 --- a/sc/source/core/data/dpsave.cxx +++ b/sc/source/core/data/dpsave.cxx @@ -1325,6 +1325,8 @@ void ScDPSaveData::Refresh( const uno::Reference<sheet::XDimensionsSupplier>& xS pDim->Refresh( xSource, deletedDims ); } + + mbDimensionMembersBuilt = false; // there may be new members } catch(uno::Exception&) { diff --git a/sc/source/core/data/dpsdbtab.cxx b/sc/source/core/data/dpsdbtab.cxx index aae5797211b0..b966d9d458ea 100644 --- a/sc/source/core/data/dpsdbtab.cxx +++ b/sc/source/core/data/dpsdbtab.cxx @@ -237,15 +237,6 @@ long ScDatabaseDPData::GetColumnCount() // End Comments -void lcl_Reset( const uno::Reference<sdbc::XRowSet>& xRowSet ) - throw(sdbc::SQLException, uno::RuntimeException) -{ - // isBeforeFirst / beforeFirst is not always available - //! query if it is allowed - - xRowSet->execute(); // restart -} - String ScDatabaseDPData::getDimensionName(long nColumn) { if (getIsDataLayoutDimension(nColumn)) diff --git a/sc/source/core/data/dpshttab.cxx b/sc/source/core/data/dpshttab.cxx index 6254e3861db5..a1fa9d2d60a6 100755 --- a/sc/source/core/data/dpshttab.cxx +++ b/sc/source/core/data/dpshttab.cxx @@ -110,12 +110,6 @@ long ScSheetDPData::GetColumnCount() return aCacheTable.getColSize(); } -BOOL lcl_HasQuery( const ScQueryParam& rParam ) -{ - return rParam.GetEntryCount() > 0 && - rParam.GetEntry(0).bDoQuery; -} - String ScSheetDPData::getDimensionName(long nColumn) { CreateCacheTable(); 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/dptablecache.cxx b/sc/source/core/data/dptablecache.cxx index fc9cf2b99a10..8f25b70e41b6 100755 --- a/sc/source/core/data/dptablecache.cxx +++ b/sc/source/core/data/dptablecache.cxx @@ -243,7 +243,7 @@ BOOL ScDPItemData::operator==( const ScDPItemData& r ) const { if ( IsValue() ) { - if( HasDatePart() != r.HasDatePart() || HasDatePart() && mnDatePart != r.mnDatePart ) + if( (HasDatePart() != r.HasDatePart()) || (HasDatePart() && mnDatePart != r.mnDatePart) ) return FALSE; // Wang Xu Ming -- 1/9/2009 diff --git a/sc/source/core/data/dptabres.cxx b/sc/source/core/data/dptabres.cxx index 55f9fb771061..c79f7c1b17a6 100755 --- a/sc/source/core/data/dptabres.cxx +++ b/sc/source/core/data/dptabres.cxx @@ -290,7 +290,7 @@ void ScDPInitState::RemoveMember() --nCount; } -const SCROW ScDPInitState::GetNameIdForIndex( long nIndexValue ) const +SCROW ScDPInitState::GetNameIdForIndex( long nIndexValue ) const { for (long i=0; i<nCount; i++) if ( pIndex[i] == nIndexValue ) @@ -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/dptabresmember.cxx b/sc/source/core/data/dptabresmember.cxx deleted file mode 100644 index 8c3b7b164bc3..000000000000 --- a/sc/source/core/data/dptabresmember.cxx +++ /dev/null @@ -1,831 +0,0 @@ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright IBM Corporation 2009. - * Copyright 2009 by Sun Microsystems, Inc. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * $RCSfile: dptabresmember.cxx,v $ - * $Revision: 1.0 $ - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ -#include "dptabresmember.hxx" -// ----------------------------------------------------------------------- -ScDPResultMember( const ScDPResultData* pData, const ScDPParentDimData& rParentDimData , - BOOL bForceSub ) : - pResultData( pData ), - aParentDimData( rParentDimData ), - /* pParentDim( pDim ), - pParentLevel( pLev ), - pMemberDesc( pDesc ),*/ - pChildDimension( NULL ), - pDataRoot( NULL ), - bHasElements( FALSE ), - bForceSubTotal( bForceSub ), - bHasHiddenDetails( FALSE ), - bInitialized( FALSE ), - nMemberStep( 1 ), - bAutoHidden( FALSE ) -{ - // pParentLevel/pMemberDesc is 0 for root members -} - -ScDPNormalResultMember::ScDPNormalResultMember( const ScDPResultData* pData, - BOOL bForceSub ) : - pResultData( pData ), - pChildDimension( NULL ), - pDataRoot( NULL ), - bHasElements( FALSE ), - bForceSubTotal( bForceSub ), - bHasHiddenDetails( FALSE ), - bInitialized( FALSE ), - nMemberStep( 1 ), - bAutoHidden( FALSE ) -{ -} - -ScDPNormalResultMember::~ScDPNormalResultMember() -{ - delete pChildDimension; - delete pDataRoot; -} - -String ScDPNormalResultMember::GetName() const -{ -// Wang Xu Ming -- 2009-6-10 -// DataPilot Migration - const ScDPMember* pMemberDesc = GetDPMember(); - // End Comments - if (pMemberDesc) - return pMemberDesc->GetNameStr(); - else - return ScGlobal::GetRscString(STR_PIVOT_TOTAL); // root member -} - -void ScDPNormalResultMember::FillItemData( ScDPItemData& rData ) const -{ -// Wang Xu Ming -- 2009-6-10 -// DataPilot Migration - const ScDPMember* pMemberDesc = GetDPMember(); -// End Comments - if (pMemberDesc) - pMemberDesc->FillItemData( rData ); - else - rData.SetString( ScGlobal::GetRscString(STR_PIVOT_TOTAL) ); // root member -} - -BOOL ScDPNormalResultMember::IsNamedItem( /*const ScDPItemData& r */SCROW nIndex ) const -{ - //! store ScDPMember pointer instead of ScDPMember ??? - const ScDPMember* pMemberDesc = GetDPMember(); - if (pMemberDesc) - return ((ScDPMember*)pMemberDesc)->IsNamedItem(/* r*/ nIndex ); - return FALSE; -} - -// Wang Xu Ming -- 2009-5-27 -// DataPilot Migration -bool ScDPNormalResultMember::IsValidEntry( const vector< SCROW >& aMembers ) const -{ - return GetEntryStatus( aMembers ) != ENTRY_INVALID; -} -// End Comments - -ENTRYSTATUS ScDPNormalResultMember::GetEntryStatus( const vector< SCROW >& aMembers ) const -{ - if ( !IsValid() ) - return ENTRY_INVALID; - - const ScDPResultDimension* pChildDim = GetChildDimension(); - if (pChildDim) - { - if (aMembers.size() < 2) - return ENTRY_INVALID; - - vector</*ScDPItemData*/SCROW>::const_iterator itr = aMembers.begin(); - vector</*ScDPItemData*/SCROW> aChildMembers(++itr, aMembers.end()); - return pChildDim->GetEntryStatus(aChildMembers); - } - else if( bHasHiddenDetails ) - return ENTRY_HASHIDDENDETAIL; - else - return ENTRY_VALID; -} - -void ScDPNormalResultMember::InitFrom( const vector<ScDPDimension*>& ppDim, const vector<ScDPLevel*>& ppLev, - size_t nPos, ScDPInitState& rInitState , - BOOL bInitChild /*= TRUE */) - { - // with LateInit, initialize only those members that have data - if ( pResultData->IsLateInit() ) - return; - - bInitialized = TRUE; - - if (nPos >= ppDim.size() ) - return; - - // skip child dimension if details are not shown - if ( GetDPMember() && !GetDPMember()->getShowDetails() ) - { - // Wang Xu Ming -- 2009-6-16 - // Show DataLayout dimention - nMemberStep = 1; - while ( nPos < ppDim.size() ) - { - if ( ppDim[nPos] ->getIsDataLayoutDimension() ) - { - if ( !pChildDimension ) - pChildDimension = new ScDPResultDimension( pResultData ); - pChildDimension->InitFrom( ppDim, ppLev, nPos, rInitState , FALSE ); - return; - } - else - { //find next dim - nPos ++; - nMemberStep ++; - } - } - // End Comments - bHasHiddenDetails = TRUE; // only if there is a next dimension - return; - } - - if ( bInitChild ) - { - pChildDimension = new ScDPResultDimension( pResultData ); - pChildDimension->InitFrom( ppDim, ppLev, nPos, rInitState, TRUE ); - } -} - -// Wang Xu Ming -- 2009-6-10 -// DataPilot Migration -void ScDPNormalResultMember::LateInitFrom( LateInitParams& rParams/*const vector<ScDPDimension*>& ppDim, const vector<ScDPLevel*>& ppLev*/, - const vector< SCROW >& pItemData, size_t nPos, - ScDPInitState& rInitState ) -// End Comments -{ - // without LateInit, everything has already been initialized - if ( !pResultData->IsLateInit() ) - return; - - bInitialized = TRUE; - - if ( rParams.IsEnd( nPos ) /*nPos >= ppDim.size()*/) - // No next dimension. Bail out. - return; - - // skip child dimension if details are not shown - if ( GetDPMember() && !GetDPMember()->getShowDetails() ) - { - // Wang Xu Ming -- 2009-6-16 - // DataPilot Migration - // Show DataLayout dimention - nMemberStep = 1; - while ( !rParams.IsEnd( nPos ) ) - { - if ( rParams.GetDim( nPos ) ->getIsDataLayoutDimension() ) - { - if ( !pChildDimension ) - pChildDimension = new ScDPResultDimension( pResultData ); - rParams.SetInitChild( FALSE ); - pChildDimension->LateInitFrom( rParams, pItemData, nPos, rInitState ); - return; - } - else - { //find next dim - nPos ++; - nMemberStep ++; - } - } - // End Comments - bHasHiddenDetails = TRUE; // only if there is a next dimension - return; - } - - // LateInitFrom is called several times... - if ( rParams.GetInitChild() ) - { - if ( !pChildDimension ) - pChildDimension = new ScDPResultDimension( pResultData ); - pChildDimension->LateInitFrom( rParams, pItemData, nPos, rInitState ); - } -} - -BOOL ScDPNormalResultMember::IsSubTotalInTitle(long nMeasure) const -{ - BOOL bRet = FALSE; - if ( pChildDimension && /*pParentLevel*/GetParentLevel() && - /*pParentLevel*/GetParentLevel()->IsOutlineLayout() && /*pParentLevel*/GetParentLevel()->IsSubtotalsAtTop() ) - { - long nUserSubStart; - long nSubTotals = GetSubTotalCount( &nUserSubStart ); - nSubTotals -= nUserSubStart; // visible count - if ( nSubTotals ) - { - if ( nMeasure == SC_DPMEASURE_ALL ) - nSubTotals *= pResultData->GetMeasureCount(); // number of subtotals that will be inserted - - // only a single subtotal row will be shown in the outline title row - if ( nSubTotals == 1 ) - bRet = TRUE; - } - } - return bRet; -} - -long ScDPNormalResultMember::GetSize(long nMeasure) const -{ - if ( !IsVisible() ) - return 0; - const ScDPLevel* pParentLevel = GetParentLevel(); - long nExtraSpace = 0; - if ( pParentLevel && pParentLevel->IsAddEmpty() ) - ++nExtraSpace; - - if ( pChildDimension ) - { - // outline layout takes up an extra row for the title only if subtotals aren't shown in that row - if ( pParentLevel && pParentLevel->IsOutlineLayout() && !IsSubTotalInTitle( nMeasure ) ) - ++nExtraSpace; - - long nSize = pChildDimension->GetSize(nMeasure); - long nUserSubStart; - long nUserSubCount = GetSubTotalCount( &nUserSubStart ); - nUserSubCount -= nUserSubStart; // for output size, use visible count - if ( nUserSubCount ) - { - if ( nMeasure == SC_DPMEASURE_ALL ) - nSize += pResultData->GetMeasureCount() * nUserSubCount; - else - nSize += nUserSubCount; - } - return nSize + nExtraSpace; - } - else - { - if ( nMeasure == SC_DPMEASURE_ALL ) - return pResultData->GetMeasureCount() + nExtraSpace; - else - return 1 + nExtraSpace; - } -} - - -BOOL ScDPNormalResultMember::IsVisible() const -{ - // not initialized -> shouldn't be there at all - // (allocated only to preserve ordering) - const ScDPLevel* pParentLevel = GetParentLevel(); - return ( bHasElements || ( pParentLevel && pParentLevel->getShowEmpty() ) ) && IsValid() && bInitialized; -} - -BOOL ScDPNormalResultMember::IsValid() const -{ - // non-Valid members are left out of calculation - - // was member set no invisible at the DataPilotSource? - const ScDPMember* pMemberDesc =GetDPMember(); - if ( pMemberDesc && !pMemberDesc->getIsVisible() ) - return FALSE; - - if ( bAutoHidden ) - return FALSE; - - return TRUE; -} - -BOOL ScDPNormalResultMember::HasHiddenDetails() const -{ - // bHasHiddenDetails is set only if the "show details" flag is off, - // and there was a child dimension to skip - - return bHasHiddenDetails; -} - -long ScDPNormalResultMember::GetSubTotalCount( long* pUserSubStart ) const -{ - if ( pUserSubStart ) - *pUserSubStart = 0; // default - - const ScDPLevel* pParentLevel = GetParentLevel(); - - if ( bForceSubTotal ) // set if needed for root members - return 1; // grand total is always "automatic" - else if ( pParentLevel ) - { - //! direct access via ScDPLevel - - uno::Sequence<sheet::GeneralFunction> aSeq = pParentLevel->getSubTotals(); - long nSequence = aSeq.getLength(); - if ( nSequence && aSeq[0] != sheet::GeneralFunction_AUTO ) - { - // For manual subtotals, always add "automatic" as first function - // (used for calculation, but not for display, needed for sorting, see lcl_GetForceFunc) - - ++nSequence; - if ( pUserSubStart ) - *pUserSubStart = 1; // visible subtotals start at 1 - } - return nSequence; - } - else - return 0; -} - -void ScDPNormalResultMember::ProcessData( const vector< SCROW >& aChildMembers, const ScDPResultDimension* pDataDim, - const vector< SCROW >& aDataMembers, const vector<ScDPValueData>& aValues ) -{ - SetHasElements(); - - if (pChildDimension) - pChildDimension->ProcessData( aChildMembers, pDataDim, aDataMembers, aValues ); - - if ( !pDataRoot ) - { - pDataRoot = new ScDPDataMember( pResultData, NULL ); - if ( pDataDim ) - pDataRoot->InitFrom( pDataDim ); // recursive - } - - ScDPSubTotalState aSubState; // initial state - - long nUserSubCount = GetSubTotalCount(); - - // Calculate at least automatic if no subtotals are selected, - // show only own values if there's no child dimension (innermost). - if ( !nUserSubCount || !pChildDimension ) - nUserSubCount = 1; - - const ScDPLevel* pParentLevel = GetParentLevel(); - - for (long nUserPos=0; nUserPos<nUserSubCount; nUserPos++) // including hidden "automatic" - { - // #i68338# if nUserSubCount is 1 (automatic only), don't set nRowSubTotalFunc - if ( pChildDimension && nUserSubCount > 1 ) - { - aSubState.nRowSubTotalFunc = nUserPos; - aSubState.eRowForce = lcl_GetForceFunc( pParentLevel, nUserPos ); - } - - pDataRoot->ProcessData( aDataMembers, aValues, aSubState ); - } -} - -void ScDPNormalResultMember::FillMemberResults( uno::Sequence<sheet::MemberResult>* pSequences, - long& rPos, long nMeasure, BOOL bRoot, - const String* pMemberName, - const String* pMemberCaption ) -{ - // IsVisible() test is in ScDPResultDimension::FillMemberResults - // (not on data layout dimension) - - long nSize = GetSize(nMeasure); - sheet::MemberResult* pArray = pSequences->getArray(); - DBG_ASSERT( rPos+nSize <= pSequences->getLength(), "bumm" ); - - BOOL bIsNumeric = FALSE; - String aName; - if ( pMemberName ) // if pMemberName != NULL, use instead of real member name - aName = *pMemberName; - else - { - ScDPItemData aItemData; - FillItemData( aItemData ); - aName = aItemData.GetString(); - bIsNumeric = aItemData.IsValue(); - } - const ScDPDimension* pParentDim = GetParentDim(); - if ( bIsNumeric && pParentDim && pResultData->IsNumOrDateGroup( pParentDim->GetDimension() ) ) - { - // Numeric group dimensions use numeric entries for proper sorting, - // but the group titles must be output as text. - bIsNumeric = FALSE; - } - - String aCaption = aName; - if ( pMemberCaption ) // use pMemberCaption if != NULL - aCaption = *pMemberCaption; - if (!aCaption.Len()) - aCaption = ScGlobal::GetRscString(STR_EMPTYDATA); - - if ( !bIsNumeric ) - { - // add a "'" character so a string isn't parsed as value in the output cell - //! have a separate bit in Flags (MemberResultFlags) instead? - aCaption.Insert( (sal_Unicode) '\'', 0 ); - } - - if ( nSize && !bRoot ) // root is overwritten by first dimension - { - pArray[rPos].Name = rtl::OUString(aName); - pArray[rPos].Caption = rtl::OUString(aCaption); - pArray[rPos].Flags |= sheet::MemberResultFlags::HASMEMBER; - - // set "continue" flag (removed for subtotals later) - for (long i=1; i<nSize; i++) - pArray[rPos+i].Flags |= sheet::MemberResultFlags::CONTINUE; - } - - const ScDPLevel* pParentLevel = GetParentLevel(); - long nExtraSpace = 0; - if ( pParentLevel && pParentLevel->IsAddEmpty() ) - ++nExtraSpace; - - BOOL bTitleLine = FALSE; - if ( pParentLevel && pParentLevel->IsOutlineLayout() ) - bTitleLine = TRUE; - - // if the subtotals are shown at the top (title row) in outline layout, - // no extra row for the subtotals is needed - BOOL bSubTotalInTitle = IsSubTotalInTitle( nMeasure ); - - BOOL bHasChild = ( pChildDimension != NULL ); - if (bHasChild) - { - if ( bTitleLine ) // in tabular layout the title is on a separate row - ++rPos; // -> fill child dimension one row below - - if (bRoot) // same sequence for root member - pChildDimension->FillMemberResults( pSequences, rPos, nMeasure ); - else - // Wang Xu Ming -- 2009-6-16 - // DataPilot Migration - // for show details - pChildDimension->FillMemberResults( pSequences + nMemberStep/*1*/, rPos, nMeasure ); - // End Comments - - if ( bTitleLine ) // title row is included in GetSize, so the following - --rPos; // positions are calculated with the normal values - } - - rPos += nSize; - - long nUserSubStart; - long nUserSubCount = GetSubTotalCount(&nUserSubStart); - if ( nUserSubCount && pChildDimension && !bSubTotalInTitle ) - { - long nMemberMeasure = nMeasure; - long nSubSize = pResultData->GetCountForMeasure(nMeasure); - - rPos -= nSubSize * (nUserSubCount - nUserSubStart); // GetSize includes space for SubTotal - rPos -= nExtraSpace; // GetSize includes the empty line - - for (long nUserPos=nUserSubStart; nUserPos<nUserSubCount; nUserPos++) - { - for ( long nSubCount=0; nSubCount<nSubSize; nSubCount++ ) - { - if ( nMeasure == SC_DPMEASURE_ALL ) - nMemberMeasure = nSubCount; - - ScSubTotalFunc eForce = SUBTOTAL_FUNC_NONE; - if (bHasChild) - eForce = lcl_GetForceFunc( pParentLevel, nUserPos ); - - String aSubStr = aName; //! caption? - aSubStr += ' '; - aSubStr += pResultData->GetMeasureString(nMemberMeasure, FALSE, eForce); - - pArray[rPos].Name = rtl::OUString(aName); - pArray[rPos].Caption = rtl::OUString(aSubStr); - pArray[rPos].Flags = ( pArray[rPos].Flags | - ( sheet::MemberResultFlags::HASMEMBER | sheet::MemberResultFlags::SUBTOTAL) ) & - ~sheet::MemberResultFlags::CONTINUE; - - if ( nMeasure == SC_DPMEASURE_ALL ) - { - // data layout dimension is (direct/indirect) child of this. - // data layout dimension must have name for all entries. - - uno::Sequence<sheet::MemberResult>* pLayoutSeq = pSequences; - if (!bRoot) - ++pLayoutSeq; - ScDPResultDimension* pLayoutDim = pChildDimension; - while ( pLayoutDim && !pLayoutDim->IsDataLayout() ) - { - pLayoutDim = pLayoutDim->GetFirstChildDimension(); - ++pLayoutSeq; - } - if ( pLayoutDim ) - { - sheet::MemberResult* pLayoutArray = pLayoutSeq->getArray(); - String aDataName = pResultData->GetMeasureDimensionName(nMemberMeasure); - pLayoutArray[rPos].Name = rtl::OUString(aDataName); - } - } - - rPos += 1; - } - } - - rPos += nExtraSpace; // add again (subtracted above) - } -} - -void ScDPNormalResultMember::FillDataResults( const ScDPResultMember* pRefMember, - uno::Sequence< uno::Sequence<sheet::DataResult> >& rSequence, - long& rRow, long nMeasure ) const -{ - // IsVisible() test is in ScDPResultDimension::FillDataResults - // (not on data layout dimension) - const ScDPLevel* pParentLevel = GetParentLevel(); - long nStartRow = rRow; - - long nExtraSpace = 0; - if ( pParentLevel && pParentLevel->IsAddEmpty() ) - ++nExtraSpace; - - BOOL bTitleLine = FALSE; - if ( pParentLevel && pParentLevel->IsOutlineLayout() ) - bTitleLine = TRUE; - - BOOL bSubTotalInTitle = IsSubTotalInTitle( nMeasure ); - - BOOL bHasChild = ( pChildDimension != NULL ); - if (bHasChild) - { - if ( bTitleLine ) // in tabular layout the title is on a separate row - ++rRow; // -> fill child dimension one row below - - pChildDimension->FillDataResults( pRefMember, rSequence, rRow, nMeasure ); // doesn't modify rRow - rRow += (USHORT) GetSize( nMeasure ); - - if ( bTitleLine ) // title row is included in GetSize, so the following - --rRow; // positions are calculated with the normal values - } - - long nUserSubStart; - long nUserSubCount = GetSubTotalCount(&nUserSubStart); - if ( nUserSubCount || !bHasChild ) - { - // Calculate at least automatic if no subtotals are selected, - // show only own values if there's no child dimension (innermost). - if ( !nUserSubCount || !bHasChild ) - { - nUserSubCount = 1; - nUserSubStart = 0; - } - - long nMemberMeasure = nMeasure; - long nSubSize = pResultData->GetCountForMeasure(nMeasure); - if (bHasChild) - { - rRow -= nSubSize * ( nUserSubCount - nUserSubStart ); // GetSize includes space for SubTotal - rRow -= nExtraSpace; // GetSize includes the empty line - } - - long nMoveSubTotal = 0; - if ( bSubTotalInTitle ) - { - nMoveSubTotal = rRow - nStartRow; // force to first (title) row - rRow = nStartRow; - } - - if ( pDataRoot ) - { - ScDPSubTotalState aSubState; // initial state - - for (long nUserPos=nUserSubStart; nUserPos<nUserSubCount; nUserPos++) - { - if ( bHasChild && nUserSubCount > 1 ) - { - aSubState.nRowSubTotalFunc = nUserPos; - aSubState.eRowForce = lcl_GetForceFunc( /*pParentLevel*/GetParentLevel() , nUserPos ); - } - - for ( long nSubCount=0; nSubCount<nSubSize; nSubCount++ ) - { - if ( nMeasure == SC_DPMEASURE_ALL ) - nMemberMeasure = nSubCount; - else if ( pResultData->GetColStartMeasure() == SC_DPMEASURE_ALL ) - nMemberMeasure = SC_DPMEASURE_ALL; - - DBG_ASSERT( rRow < rSequence.getLength(), "bumm" ); - uno::Sequence<sheet::DataResult>& rSubSeq = rSequence.getArray()[rRow]; - long nSeqCol = 0; - pDataRoot->FillDataRow( pRefMember, rSubSeq, nSeqCol, nMemberMeasure, bHasChild, aSubState ); - - rRow += 1; - } - } - } - else - rRow += nSubSize * ( nUserSubCount - nUserSubStart ); // empty rows occur when ShowEmpty is true - - // add extra space again if subtracted from GetSize above, - // add to own size if no children - rRow += nExtraSpace; - - rRow += nMoveSubTotal; - } -} - -void ScDPNormalResultMember::UpdateDataResults( const ScDPResultMember* pRefMember, long nMeasure ) const -{ - // IsVisible() test is in ScDPResultDimension::FillDataResults - // (not on data layout dimension) - - BOOL bHasChild = ( pChildDimension != NULL ); - - long nUserSubCount = GetSubTotalCount(); - // process subtotals even if not shown -// if ( nUserSubCount || !bHasChild ) - { - // Calculate at least automatic if no subtotals are selected, - // show only own values if there's no child dimension (innermost). - if ( !nUserSubCount || !bHasChild ) - nUserSubCount = 1; - - long nMemberMeasure = nMeasure; - long nSubSize = pResultData->GetCountForMeasure(nMeasure); - - if ( pDataRoot ) - { - ScDPSubTotalState aSubState; // initial state - - for (long nUserPos=0; nUserPos<nUserSubCount; nUserPos++) // including hidden "automatic" - { - if ( bHasChild && nUserSubCount > 1 ) - { - aSubState.nRowSubTotalFunc = nUserPos; - aSubState.eRowForce = lcl_GetForceFunc( /*pParentLevel*/GetParentLevel() , nUserPos ); - } - - for ( long nSubCount=0; nSubCount<nSubSize; nSubCount++ ) - { - if ( nMeasure == SC_DPMEASURE_ALL ) - nMemberMeasure = nSubCount; - else if ( pResultData->GetColStartMeasure() == SC_DPMEASURE_ALL ) - nMemberMeasure = SC_DPMEASURE_ALL; - - pDataRoot->UpdateDataRow( pRefMember, nMemberMeasure, bHasChild, aSubState ); - } - } - } - } - - if (bHasChild) // child dimension must be processed last, so the column total is known - { - pChildDimension->UpdateDataResults( pRefMember, nMeasure ); - } -} - -void ScDPNormalResultMember::SortMembers( ScDPResultMember* pRefMember ) -{ - BOOL bHasChild = ( pChildDimension != NULL ); - if (bHasChild) - pChildDimension->SortMembers( pRefMember ); // sorting is done at the dimension - - if ( IsRoot() && pDataRoot ) - { - // use the row root member to sort columns - // sub total count is always 1 - - pDataRoot->SortMembers( pRefMember ); - } -} - -void ScDPNormalResultMember::DoAutoShow( ScDPResultMember* pRefMember ) -{ - BOOL bHasChild = ( pChildDimension != NULL ); - if (bHasChild) - pChildDimension->DoAutoShow( pRefMember ); // sorting is done at the dimension - - if ( IsRoot()&& pDataRoot ) - { - // use the row root member to sort columns - // sub total count is always 1 - - pDataRoot->DoAutoShow( pRefMember ); - } -} - -void ScDPNormalResultMember::ResetResults( BOOL bRoot ) -{ - if (pDataRoot) - pDataRoot->ResetResults(); - - if (pChildDimension) - pChildDimension->ResetResults(); - -// Wang Xu Ming -- 3/4/2009 -// Dim refresh and filter. SODC_19023 - // if (!bRoot) - // bHasElements = FALSE; -// End Comments -} - -void ScDPNormalResultMember::UpdateRunningTotals( const ScDPResultMember* pRefMember, long nMeasure, - ScDPRunningTotalState& rRunning, ScDPRowTotals& rTotals ) const -{ - // IsVisible() test is in ScDPResultDimension::FillDataResults - // (not on data layout dimension) - - rTotals.SetInColRoot( IsRoot() ); - - BOOL bHasChild = ( pChildDimension != NULL ); - - long nUserSubCount = GetSubTotalCount(); - if ( nUserSubCount || !bHasChild ) - { - // Calculate at least automatic if no subtotals are selected, - // show only own values if there's no child dimension (innermost). - if ( !nUserSubCount || !bHasChild ) - nUserSubCount = 1; - - long nMemberMeasure = nMeasure; - long nSubSize = pResultData->GetCountForMeasure(nMeasure); - - if ( pDataRoot ) - { - ScDPSubTotalState aSubState; // initial state - - for (long nUserPos=0; nUserPos<nUserSubCount; nUserPos++) // including hidden "automatic" - { - if ( bHasChild && nUserSubCount > 1 ) - { - aSubState.nRowSubTotalFunc = nUserPos; - aSubState.eRowForce = lcl_GetForceFunc( /*pParentLevel*/GetParentLevel(), nUserPos ); - } - - for ( long nSubCount=0; nSubCount<nSubSize; nSubCount++ ) - { - if ( nMeasure == SC_DPMEASURE_ALL ) - nMemberMeasure = nSubCount; - else if ( pResultData->GetColStartMeasure() == SC_DPMEASURE_ALL ) - nMemberMeasure = SC_DPMEASURE_ALL; - - pDataRoot->UpdateRunningTotals( pRefMember, nMemberMeasure, - bHasChild, aSubState, rRunning, rTotals, *this ); - } - } - } - } - - if (bHasChild) // child dimension must be processed last, so the column total is known - { - pChildDimension->UpdateRunningTotals( pRefMember, nMeasure, rRunning, rTotals ); - } -} - -void ScDPNormalResultMember::DumpState( const ScDPResultMember* pRefMember, ScDocument* pDoc, ScAddress& rPos ) const -{ - lcl_DumpRow( String::CreateFromAscii("ScDPResultMember"), GetName(), NULL, pDoc, rPos ); - SCROW nStartRow = rPos.Row(); - - if (pDataRoot) - pDataRoot->DumpState( pRefMember, pDoc, rPos ); - - if (pChildDimension) - pChildDimension->DumpState( pRefMember, pDoc, rPos ); - - lcl_Indent( pDoc, nStartRow, rPos ); -} - -ScDPAggData* ScDPNormalResultMember::GetColTotal( long nMeasure ) const -{ - return lcl_GetChildTotal( const_cast<ScDPAggData*>(&aColTotal), nMeasure ); -} - -void ScDPNormalResultMember::FillVisibilityData(ScDPResultVisibilityData& rData) const -{ - if (pChildDimension) - pChildDimension->FillVisibilityData(rData); -} -// Wang Xu Ming -- 2009-6-10 -// DataPilot Migration -SCROW ScDPNormalResultMember::GetDataId( ) const -{ -// TODO: - const ScDPMember* pMemberDesc = GetDPMember(); - if (pMemberDesc) - return pMemberDesc->GetItemDataId(); - return -1; -} - -// ----------------------------------------------------------------------- -ScDPHideDetailsMember:: ScDPHideDetailsMember( const ScDPResultData* pData, const ScDPParentDimData& rParentDimData, - BOOL bForceSub ):ScDPResultMember(pData,rParentDimData, bForceSub) -{ - pOrigMember = new ScDPNormalResultMember(pData,rParentDimData, bForceSub); - -}
\ No newline at end of file diff --git a/sc/source/core/data/dptabresmember.hxx b/sc/source/core/data/dptabresmember.hxx deleted file mode 100644 index 72657167d07d..000000000000 --- a/sc/source/core/data/dptabresmember.hxx +++ /dev/null @@ -1,161 +0,0 @@ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright IBM Corporation 2009. - * Copyright 2009 by Sun Microsystems, Inc. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * $RCSfile: dptabresmember.hxx,v $ - * $Revision: 1.0 $ - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -#ifndef DPTABRESMEMBER_HXX -#define DPTABRESMEMBER_HXX - -class ScDPNormalResultMember: public ScDPResultMember -{ -private: - // Wang Xu Ming -- 2009-6-9 - // DataPilot Migration - ScDPParentDimData aParentDimData; - // End Comments - BOOL bHasElements:1; - BOOL bForceSubTotal:1; - BOOL bHasHiddenDetails:1; - BOOL bInitialized:1; - BOOL bAutoHidden:1; - ScDPAggData aColTotal; // to store column totals - -// Wang Xu Ming -- 2009-6-9 -// DataPilot Migration - USHORT nMemberStep; // step to show details -// End Comments -public: - // Wang Xu Ming -- 2009-6-9 - // DataPilot Migration - ScDPNormalResultMember( const ScDPResultData* pData, const ScDPParentDimData& rParentDimData, - BOOL bForceSub ); //! Ref - ScDPNormalResultMember( const ScDPResultData* pData, BOOL bForceSub ); - // End Comments - ~ScDPNormalResultMember(); - - // Wang Xu Ming -- 2009-6-9 - // DataPilot Migration - // Add parameter: BOOL bInitChild - void InitFrom( const ::std::vector<ScDPDimension*>& ppDim, - const ::std::vector<ScDPLevel*>& ppLev, - size_t nPos, - ScDPInitState& rInitState, - BOOL bInitChild = TRUE ); - // End Comments - // Wang Xu Ming -- 2009-6-9 - // DataPilot Migration - void LateInitFrom( - LateInitParams& rParams, - const ::std::vector< SCROW >& pItemData, - size_t nPos, - ScDPInitState& rInitState); - // End Comments - - String GetName() const; - void FillItemData( ScDPItemData& rData ) const; - BOOL IsValid() const; - BOOL IsVisible() const; - long GetSize(long nMeasure) const; - BOOL HasHiddenDetails() const; - BOOL IsSubTotalInTitle(long nMeasure) const; - -// BOOL SubTotalEnabled() const; - long GetSubTotalCount( long* pUserSubStart = NULL ) const; - -// Wang Xu Ming -- 2009-6-9 -// DataPilot Migration -// Use item index -// BOOL IsNamedItem( const ScDPItemData& r ) const; - BOOL IsNamedItem( SCROW nIndex ) const; -// End Comments - bool IsValidEntry( const ::std::vector< SCROW >& aMembers ) const; - ENTRYSTATUS GetEntryStatus( const ::std::vector<SCROW>& aMembers ) const; - - void SetHasElements() { bHasElements = TRUE; } - void SetAutoHidden() { bAutoHidden = TRUE; } - - void ProcessData( const ::std::vector<SCROW>& aChildMembers, - const ScDPResultDimension* pDataDim, - const ::std::vector<SCROW>& aDataMembers, - const ::std::vector<ScDPValueData>& aValues ); - - void FillMemberResults( com::sun::star::uno::Sequence< - com::sun::star::sheet::MemberResult>* pSequences, - long& rPos, long nMeasure, BOOL bRoot, - const String* pMemberName, - const String* pMemberCaption ); - - void FillDataResults( const ScDPResultMember* pRefMember, - com::sun::star::uno::Sequence< - com::sun::star::uno::Sequence< - com::sun::star::sheet::DataResult> >& rSequence, - long& rRow, long nMeasure ) const; - - void UpdateDataResults( const ScDPResultMember* pRefMember, long nMeasure ) const; - void UpdateRunningTotals( const ScDPResultMember* pRefMember, long nMeasure, - ScDPRunningTotalState& rRunning, ScDPRowTotals& rTotals ) const; - - void SortMembers( ScDPResultMember* pRefMember ); - void DoAutoShow( ScDPResultMember* pRefMember ); - - void ResetResults( BOOL bRoot ); - - void DumpState( const ScDPResultMember* pRefMember, ScDocument* pDoc, ScAddress& rPos ) const; - - // Wang Xu Ming -- 2009-6-9 - // DataPilot Migration - const ScDPDimension* GetParentDim() const { return aParentDimData.mpParentDim; } //! Ref - const ScDPLevel* GetParentLevel() const { return aParentDimData.mpParentLevel; } //! Ref - const ScDPMember* GetDPMember()const { return aParentDimData.mpMemberDesc; } //! Ref - inline SCROW GetOrder() const { return aParentDimData.mnOrder; } //! Ref - inline BOOL IsRoot() const { return GetParentLevel() == NULL; } - // End Comments - - ScDPAggData* GetColTotal( long nMeasure ) const; - - void FillVisibilityData(ScDPResultVisibilityData& rData) const; -// Wang Xu Ming -- 2009-6-10 -// DataPilot Migration - SCROW GetDataId( ) const ; -// End Comments -}; - -class ScDPHideDetailsMember: public ScDPResultMember -{ -private: - ScDPNormalResultMember * pOrigMember; -public: - ScDPHideDetailsMember( const ScDPResultData* pData, const ScDPParentDimData& rParentDimData, - BOOL bForceSub ); - - -}; - - -#endif //DPTABRESMEMBER_HXX diff --git a/sc/source/core/data/drwlayer.cxx b/sc/source/core/data/drwlayer.cxx index 3d7fc007818b..4df709768279 100755 --- a/sc/source/core/data/drwlayer.cxx +++ b/sc/source/core/data/drwlayer.cxx @@ -592,12 +592,14 @@ void ScDrawLayer::RecalcPos( SdrObject* pObj, const ScDrawObjData& rData, bool b { //! nicht mehrere Undos fuer ein Objekt erzeugen (hinteres kann dann weggelassen werden) + SCCOL nLastCol; + SCROW nLastRow; if( bValid1 ) { Point aPos( pDoc->GetColOffset( nCol1, nTab1 ), pDoc->GetRowOffset( nRow1, nTab1 ) ); - if( (pDoc->GetColFlags( nCol1, nTab1 ) & CR_HIDDEN) == 0 ) + if (!pDoc->ColHidden(nCol1, nTab1, nLastCol)) aPos.X() += pDoc->GetColWidth( nCol1, nTab1 ) / 4; - if( (pDoc->GetRowFlags( nRow1, nTab1 ) & CR_HIDDEN) == 0 ) + if (!pDoc->RowHidden(nRow1, nTab1, nLastRow)) aPos.Y() += pDoc->GetRowHeight( nRow1, nTab1 ) / 2; TwipsToMM( aPos.X() ); TwipsToMM( aPos.Y() ); @@ -629,9 +631,9 @@ void ScDrawLayer::RecalcPos( SdrObject* pObj, const ScDrawObjData& rData, bool b if( bValid2 ) { Point aPos( pDoc->GetColOffset( nCol2, nTab2 ), pDoc->GetRowOffset( nRow2, nTab2 ) ); - if( (pDoc->GetColFlags( nCol2, nTab2 ) & CR_HIDDEN) == 0 ) + if (!pDoc->ColHidden(nCol2, nTab2, nLastCol)) aPos.X() += pDoc->GetColWidth( nCol2, nTab2 ) / 4; - if( (pDoc->GetRowFlags( nRow2, nTab2 ) & CR_HIDDEN) == 0 ) + if (!pDoc->RowHidden(nRow2, nTab2, nLastRow)) aPos.Y() += pDoc->GetRowHeight( nRow2, nTab2 ) / 2; TwipsToMM( aPos.X() ); TwipsToMM( aPos.Y() ); @@ -735,8 +737,8 @@ BOOL ScDrawLayer::GetPrintArea( ScRange& rRange, BOOL bSetHor, BOOL bSetVer ) co } if (!bSetVer) { - nStartY = pDoc->FastGetRowHeight( 0, rRange.aStart.Row()-1, nTab); - nEndY = nStartY + pDoc->FastGetRowHeight( rRange.aStart.Row(), + nStartY = pDoc->GetRowHeight( 0, rRange.aStart.Row()-1, nTab); + nEndY = nStartY + pDoc->GetRowHeight( rRange.aStart.Row(), rRange.aEnd.Row(), nTab); nStartY = (long)(nStartY * HMM_PER_TWIPS); nEndY = (long)(nEndY * HMM_PER_TWIPS); @@ -817,9 +819,9 @@ BOOL ScDrawLayer::GetPrintArea( ScRange& rRange, BOOL bSetHor, BOOL bSetVer ) co { nStartY = (long) (nStartY / HMM_PER_TWIPS); nEndY = (long) (nEndY / HMM_PER_TWIPS); - SCROW nRow = pDoc->FastGetRowForHeight( nTab, nStartY); + SCROW nRow = pDoc->GetRowForHeight( nTab, nStartY); rRange.aStart.SetRow( nRow>0 ? (nRow-1) : 0); - nRow = pDoc->FastGetRowForHeight( nTab, nEndY); + nRow = pDoc->GetRowForHeight( nTab, nEndY); rRange.aEnd.SetRow( nRow == MAXROW ? MAXROW : (nRow>0 ? (nRow-1) : 0)); } @@ -1041,9 +1043,9 @@ void ScDrawLayer::MoveArea( SCTAB nTab, SCCOL nCol1,SCROW nRow1, SCCOL nCol2,SCR for (SCsCOL s=-1; s>=nDx; s--) aMove.X() -= pDoc->GetColWidth(s+(SCsCOL)nCol1,nTab); if (nDy > 0) - aMove.Y() += pDoc->FastGetRowHeight( nRow1, nRow1+nDy-1, nTab); + aMove.Y() += pDoc->GetRowHeight( nRow1, nRow1+nDy-1, nTab); else - aMove.Y() -= pDoc->FastGetRowHeight( nRow1+nDy, nRow1-1, nTab); + aMove.Y() -= pDoc->GetRowHeight( nRow1+nDy, nRow1-1, nTab); if ( bNegativePage ) aMove.X() = -aMove.X(); @@ -1115,9 +1117,9 @@ void ScDrawLayer::HeightChanged( SCTAB nTab, SCROW nRow, long nDifTwips ) Rectangle aRect; Point aTopLeft; - aRect.Top() += pDoc->FastGetRowHeight( 0, nRow-1, nTab); + aRect.Top() += pDoc->GetRowHeight( 0, nRow-1, nTab); aTopLeft.Y() = aRect.Top(); - aRect.Top() += pDoc->FastGetRowHeight(nRow,nTab); + aRect.Top() += pDoc->GetRowHeight(nRow, nTab); aRect.Bottom() = MAXMM; aRect.Left() = 0; @@ -1143,14 +1145,14 @@ BOOL ScDrawLayer::HasObjectsInRows( SCTAB nTab, SCROW nStartRow, SCROW nEndRow ) Rectangle aTestRect; - aTestRect.Top() += pDoc->FastGetRowHeight( 0, nStartRow-1, nTab); + aTestRect.Top() += pDoc->GetRowHeight( 0, nStartRow-1, nTab); if (nEndRow==MAXROW) aTestRect.Bottom() = MAXMM; else { aTestRect.Bottom() = aTestRect.Top(); - aTestRect.Bottom() += pDoc->FastGetRowHeight( nStartRow, nEndRow, nTab); + aTestRect.Bottom() += pDoc->GetRowHeight( nStartRow, nEndRow, nTab); TwipsToMM( aTestRect.Bottom() ); } @@ -1706,7 +1708,7 @@ Rectangle ScDrawLayer::GetCellRect( ScDocument& rDoc, const ScAddress& rPos, boo for( SCCOL nCol = 0; nCol < rPos.Col(); ++nCol ) aTopLeft.X() += rDoc.GetColWidth( nCol, rPos.Tab() ); if( rPos.Row() > 0 ) - aTopLeft.Y() += rDoc.FastGetRowHeight( 0, rPos.Row() - 1, rPos.Tab() ); + aTopLeft.Y() += rDoc.GetRowHeight( 0, rPos.Row() - 1, rPos.Tab() ); // find bottom-right position of passed cell address ScAddress aEndPos = rPos; @@ -1721,7 +1723,7 @@ Rectangle ScDrawLayer::GetCellRect( ScDocument& rDoc, const ScAddress& rPos, boo Point aBotRight = aTopLeft; for( SCCOL nCol = rPos.Col(); nCol <= aEndPos.Col(); ++nCol ) aBotRight.X() += rDoc.GetColWidth( nCol, rPos.Tab() ); - aBotRight.Y() += rDoc.FastGetRowHeight( rPos.Row(), aEndPos.Row(), rPos.Tab() ); + aBotRight.Y() += rDoc.GetRowHeight( rPos.Row(), aEndPos.Row(), rPos.Tab() ); // twips -> 1/100 mm aTopLeft.X() = static_cast< long >( aTopLeft.X() * HMM_PER_TWIPS ); diff --git a/sc/source/core/data/fillinfo.cxx b/sc/source/core/data/fillinfo.cxx index 05e0d98c9719..8418cb3c3a25 100644 --- a/sc/source/core/data/fillinfo.cxx +++ b/sc/source/core/data/fillinfo.cxx @@ -52,7 +52,6 @@ #include "conditio.hxx" #include "stlpool.hxx" - // ----------------------------------------------------------------------- const USHORT ROWINFO_MAX = 1024; @@ -97,11 +96,13 @@ void lcl_GetMergeRange( SCsCOL nX, SCsROW nY, SCSIZE nArrY, rStartY = nY; BOOL bHOver = pInfo->bHOverlapped; BOOL bVOver = pInfo->bVOverlapped; + SCCOL nLastCol; + SCROW nLastRow; while (bHOver) // nY konstant { --rStartX; - if (rStartX >= (SCsCOL) nX1 && (pDoc->GetColFlags(rStartX,nTab) & CR_HIDDEN) == 0) + if (rStartX >= (SCsCOL) nX1 && !pDoc->ColHidden(rStartX, nTab, nLastCol)) { bHOver = pRowInfo[nArrY].pCellInfo[rStartX+1].bHOverlapped; bVOver = pRowInfo[nArrY].pCellInfo[rStartX+1].bVOverlapped; @@ -123,8 +124,8 @@ void lcl_GetMergeRange( SCsCOL nX, SCsROW nY, SCSIZE nArrY, --nArrY; // lokale Kopie ! if (rStartX >= (SCsCOL) nX1 && rStartY >= (SCsROW) nY1 && - (pDoc->GetColFlags(rStartX,nTab) & CR_HIDDEN) == 0 && - (pDoc->GetRowFlags(rStartY,nTab) & CR_HIDDEN) == 0 && + !pDoc->ColHidden(rStartX, nTab, nLastCol) && + !pDoc->RowHidden(rStartY, nTab, nLastRow) && (SCsROW) pRowInfo[nArrY].nRowNo == rStartY) { bHOver = pRowInfo[nArrY].pCellInfo[rStartX+1].bHOverlapped; @@ -141,8 +142,8 @@ void lcl_GetMergeRange( SCsCOL nX, SCsROW nY, SCSIZE nArrY, const ScMergeAttr* pMerge; if (rStartX >= (SCsCOL) nX1 && rStartY >= (SCsROW) nY1 && - (pDoc->GetColFlags(rStartX,nTab) & CR_HIDDEN) == 0 && - (pDoc->GetRowFlags(rStartY,nTab) & CR_HIDDEN) == 0 && + !pDoc->ColHidden(rStartX, nTab, nLastCol) && + !pDoc->RowHidden(rStartY, nTab, nLastRow) && (SCsROW) pRowInfo[nArrY].nRowNo == rStartY) { pMerge = (const ScMergeAttr*) &pRowInfo[nArrY].pCellInfo[rStartX+1].pPatternAttr-> @@ -155,12 +156,6 @@ void lcl_GetMergeRange( SCsCOL nX, SCsROW nY, SCSIZE nArrY, rEndY = rStartY + pMerge->GetRowMerge() - 1; } -inline BOOL ScDocument::RowHidden( SCROW nRow, SCTAB nTab ) -{ - return ( pTab[nTab]->pRowFlags->GetValue(nRow) & CR_HIDDEN ) != 0; -} - - #define CELLINFO(x,y) pRowInfo[nArrY+y].pCellInfo[nArrX+x] void ScDocument::FillInfo( ScTableInfo& rTabInfo, SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2, @@ -356,7 +351,7 @@ void ScDocument::FillInfo( ScTableInfo& rTabInfo, SCCOL nX1, SCROW nY1, SCCOL nX nX = nArrX-1; if ( ValidCol(nX) ) { - if ( (GetColFlags(nX,nTab) & CR_HIDDEN) == 0 ) // Spalte nicht versteckt + if (!ColHidden(nX, nTab)) { USHORT nThisWidth = (USHORT) (GetColWidth( nX, nTab ) * nScaleX); if (!nThisWidth) @@ -376,7 +371,8 @@ void ScDocument::FillInfo( ScTableInfo& rTabInfo, SCCOL nX1, SCROW nY1, SCCOL nX // #i58049#, #i57939# Hidden columns must be skipped here, or their attributes // will disturb the output - if ( (GetColFlags(nX,nTab) & CR_HIDDEN) == 0 ) // column not hidden + // TODO: Optimize this loop. + if (!ColHidden(nX, nTab)) { USHORT nThisWidth = (USHORT) (GetColWidth( nX, nTab ) * nScaleX); if (!nThisWidth) @@ -481,7 +477,9 @@ void ScDocument::FillInfo( ScTableInfo& rTabInfo, SCCOL nX1, SCROW nY1, SCCOL nX do { - if ( nArrY==0 || !RowHidden( nCurRow,nTab ) ) + SCROW nLastHiddenRow = -1; + bool bRowHidden = RowHidden(nCurRow, nTab, nLastHiddenRow); + if ( nArrY==0 || !bRowHidden ) { RowInfo* pThisRowInfo = &pRowInfo[nArrY]; if (pBackground != pDefBackground) // Spalten-HG == Standard ? @@ -551,6 +549,12 @@ void ScDocument::FillInfo( ScTableInfo& rTabInfo, SCCOL nX1, SCROW nY1, SCCOL nX ++nArrY; } + else if (bRowHidden && nLastHiddenRow >= 0) + { + nCurRow = nLastHiddenRow; + if (nCurRow > nThisRow) + nCurRow = nThisRow; + } ++nCurRow; } while (nCurRow <= nThisRow && nCurRow <= nYExtra); diff --git a/sc/source/core/data/global.cxx b/sc/source/core/data/global.cxx index e38dc73eeac5..10aacc678d74 100644 --- a/sc/source/core/data/global.cxx +++ b/sc/source/core/data/global.cxx @@ -144,15 +144,6 @@ long ScGlobal::nLastColWidthExtra = STD_EXTRA_WIDTH; static USHORT nPPTZoom = 0; // ScreenZoom used to determine nScreenPPTX/Y -// ... oder so? - -BOOL bOderSo; - -bool SC_DLLPUBLIC ScGetWriteTeamInfo() -{ - return bOderSo; -} - class SfxViewShell; SfxViewShell* pScActiveViewShell = NULL; //! als Member !!!!! USHORT nScClickMouseModifier = 0; //! dito @@ -517,12 +508,6 @@ String ScGlobal::GetLongErrorString(USHORT nErrNumber) break; } String aRes( GetRscString( nErrNumber ) ); - if( bOderSo ) - { - String aOderSo( GetRscString( STR_ODER_SO ) ); - aOderSo.SearchAndReplace( String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("%s")), aRes ); - aRes = aOderSo; - } return aRes; } diff --git a/sc/source/core/data/makefile.mk b/sc/source/core/data/makefile.mk index cf51e1e543a4..95ce6bcec179 100755 --- a/sc/source/core/data/makefile.mk +++ b/sc/source/core/data/makefile.mk @@ -98,9 +98,12 @@ SLOFILES = \ $(SLO)$/patattr.obj \ $(SLO)$/pivot2.obj \ $(SLO)$/poolhelp.obj \ + $(SLO)$/sheetevents.obj \ + $(SLO)$/segmenttree.obj \ $(SLO)$/sortparam.obj \ $(SLO)$/stlpool.obj \ $(SLO)$/stlsheet.obj \ + $(SLO)$/tabbgcolor.obj \ $(SLO)$/table1.obj \ $(SLO)$/table2.obj \ $(SLO)$/table3.obj \ @@ -128,6 +131,7 @@ EXCEPTIONSFILES= \ $(SLO)$/dptabres.obj \ $(SLO)$/dptabdat.obj \ $(SLO)$/global2.obj \ + $(SLO)$/tabbgcolor.obj \ $(SLO)$/table1.obj \ $(SLO)$/table2.obj \ $(SLO)$/table3.obj \ @@ -148,7 +152,8 @@ EXCEPTIONSFILES= \ $(SLO)$/dbdocutl.obj \ $(SLO)$/dptabsrc.obj \ $(SLO)$/drwlayer.obj \ - $(SLO)$/globalx.obj + $(SLO)$/globalx.obj \ + $(SLO)$/segmenttree.obj .IF "$(OS)$(COM)$(CPUNAME)"=="LINUXGCCSPARC" NOOPTFILES= \ @@ -164,7 +169,8 @@ EXCEPTIONSNOOPTFILES= \ .ELSE EXCEPTIONSFILES+= \ $(SLO)$/cell.obj \ - $(SLO)$/global.obj + $(SLO)$/global.obj \ + $(SLO)$/table5.obj .ENDIF # --- Tagets ------------------------------------------------------- diff --git a/sc/source/core/data/olinetab.cxx b/sc/source/core/data/olinetab.cxx index 55f7ba46b898..af444c4b2123 100644 --- a/sc/source/core/data/olinetab.cxx +++ b/sc/source/core/data/olinetab.cxx @@ -41,10 +41,11 @@ #include "global.hxx" #include "rechead.hxx" #include "address.hxx" +#include "table.hxx" //------------------------------------------------------------------------ -ScOutlineEntry::ScOutlineEntry( SCCOLROW nNewStart, SCCOLROW nNewSize, BOOL bNewHidden ) : +ScOutlineEntry::ScOutlineEntry( SCCOLROW nNewStart, SCCOLROW nNewSize, bool bNewHidden ) : nStart ( nNewStart ), nSize ( nNewSize ), bHidden ( bNewHidden ), @@ -93,12 +94,12 @@ void ScOutlineEntry::SetPosSize( SCCOLROW nNewPos, SCSIZE nNewSize ) SetSize( nNewSize ); } -void ScOutlineEntry::SetHidden( BOOL bNewHidden ) +void ScOutlineEntry::SetHidden( bool bNewHidden ) { bHidden = bNewHidden; } -void ScOutlineEntry::SetVisible( BOOL bNewVisible ) +void ScOutlineEntry::SetVisible( bool bNewVisible ) { bVisible = bNewVisible; } @@ -637,10 +638,9 @@ BOOL ScOutlineArray::DeleteSpace( SCCOLROW nStartPos, SCSIZE nSize ) return bNeedSave; } -BOOL ScOutlineArray::ManualAction( SCCOLROW nStartPos, SCCOLROW nEndPos, - BOOL bShow, const ScBitMaskCompressedArray< SCCOLROW, BYTE>& rHiddenFlags ) +bool ScOutlineArray::ManualAction( SCCOLROW nStartPos, SCCOLROW nEndPos, bool bShow, ScTable& rTable, bool bCol ) { - BOOL bModified = FALSE; + bool bModified = false; ScSubOutlineIterator aIter( this ); ScOutlineEntry* pEntry; while((pEntry=aIter.GetNext())!=NULL) @@ -654,18 +654,16 @@ BOOL ScOutlineArray::ManualAction( SCCOLROW nStartPos, SCCOLROW nEndPos, { // #i12341# hide if all columns/rows are hidden, show if at least one // is visible - - SCCOLROW nEnd = rHiddenFlags.GetBitStateEnd( nEntryStart, - CR_HIDDEN, CR_HIDDEN); - BOOL bAllHidden = (nEntryEnd <= nEnd && nEnd < + SCCOLROW nEnd = rTable.LastHiddenColRow(nEntryStart, bCol); + bool bAllHidden = (nEntryEnd <= nEnd && nEnd < ::std::numeric_limits<SCCOLROW>::max()); - BOOL bToggle = ( bShow != bAllHidden ); + bool bToggle = ( bShow != bAllHidden ); if ( bToggle ) { pEntry->SetHidden( !bShow ); SetVisibleBelow( aIter.LastLevel(), aIter.LastEntry(), bShow, bShow ); - bModified = TRUE; + bModified = true; } } } diff --git a/sc/source/core/data/segmenttree.cxx b/sc/source/core/data/segmenttree.cxx new file mode 100644 index 000000000000..86b53582d1d4 --- /dev/null +++ b/sc/source/core/data/segmenttree.cxx @@ -0,0 +1,582 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + +#include "segmenttree.hxx" + +#include <mdds/flat_segment_tree.hpp> + +#include <limits> + +using ::std::numeric_limits; + +// ============================================================================ + +template<typename _ValueType, typename _ExtValueType = _ValueType> +class ScFlatSegmentsImpl +{ +public: + typedef _ValueType ValueType; + typedef _ExtValueType ExtValueType; + + struct RangeData + { + SCCOLROW mnPos1; + SCCOLROW mnPos2; + ValueType mnValue; + }; + + ScFlatSegmentsImpl(SCCOLROW nMax, ValueType nDefault); + ScFlatSegmentsImpl(const ScFlatSegmentsImpl& r); + ~ScFlatSegmentsImpl(); + + void setValue(SCCOLROW nPos1, SCCOLROW nPos2, ValueType nValue); + ValueType getValue(SCCOLROW nPos); + ExtValueType getSumValue(SCCOLROW nPos1, SCCOLROW nPos2); + bool getRangeData(SCCOLROW nPos, RangeData& rData); + void removeSegment(SCCOLROW nPos1, SCCOLROW nPos2); + void insertSegment(SCCOLROW nPos, SCCOLROW nSize, bool bSkipStartBoundary); + + SCROW findLastNotOf(ValueType nValue) const; + + // range iteration + bool getFirst(RangeData& rData); + bool getNext(RangeData& rData); + + void enableTreeSearch(bool b) + { + mbTreeSearchEnabled = b; + } + + void setInsertFromBack(bool b) + { + mbInsertFromBack = b; + } + +private: + typedef ::mdds::flat_segment_tree<SCCOLROW, ValueType> fst_type; + fst_type maSegments; + typename fst_type::const_iterator maItr; + + bool mbTreeSearchEnabled:1; + bool mbInsertFromBack:1; +}; + +template<typename _ValueType, typename _ExtValueType> +ScFlatSegmentsImpl<_ValueType, _ExtValueType>::ScFlatSegmentsImpl(SCCOLROW nMax, ValueType nDefault) : + maSegments(0, nMax+1, nDefault), + mbTreeSearchEnabled(true), + mbInsertFromBack(false) +{ +} + +template<typename _ValueType, typename _ExtValueType> +ScFlatSegmentsImpl<_ValueType, _ExtValueType>::ScFlatSegmentsImpl(const ScFlatSegmentsImpl<_ValueType, _ExtValueType>& r) : + maSegments(r.maSegments), + mbTreeSearchEnabled(r.mbTreeSearchEnabled), + mbInsertFromBack(r.mbInsertFromBack) +{ +} + +template<typename _ValueType, typename _ExtValueType> +ScFlatSegmentsImpl<_ValueType, _ExtValueType>::~ScFlatSegmentsImpl() +{ +} + +template<typename _ValueType, typename _ExtValueType> +void ScFlatSegmentsImpl<_ValueType, _ExtValueType>::setValue(SCCOLROW nPos1, SCCOLROW nPos2, ValueType nValue) +{ + if (mbInsertFromBack) + maSegments.insert_back(nPos1, nPos2+1, nValue); + else + maSegments.insert_front(nPos1, nPos2+1, nValue); +} + +template<typename _ValueType, typename _ExtValueType> +typename ScFlatSegmentsImpl<_ValueType, _ExtValueType>::ValueType ScFlatSegmentsImpl<_ValueType, _ExtValueType>::getValue(SCCOLROW nPos) +{ + ValueType nValue = 0; + if (!mbTreeSearchEnabled) + { + maSegments.search(nPos, nValue); + return nValue; + } + + if (!maSegments.is_tree_valid()) + maSegments.build_tree(); + + maSegments.search_tree(nPos, nValue); + return nValue; +} + +template<typename _ValueType, typename _ExtValueType> +typename ScFlatSegmentsImpl<_ValueType, _ExtValueType>::ExtValueType +ScFlatSegmentsImpl<_ValueType, _ExtValueType>::getSumValue(SCCOLROW nPos1, SCCOLROW nPos2) +{ + RangeData aData; + if (!getRangeData(nPos1, aData)) + return 0; + + sal_uInt32 nValue = 0; + + SCROW nCurPos = nPos1; + SCROW nEndPos = aData.mnPos2; + while (nEndPos <= nPos2) + { + nValue += aData.mnValue * (nEndPos - nCurPos + 1); + nCurPos = nEndPos + 1; + if (!getRangeData(nCurPos, aData)) + break; + + nEndPos = aData.mnPos2; + } + if (nCurPos <= nPos2) + { + nEndPos = ::std::min(nEndPos, nPos2); + nValue += aData.mnValue * (nEndPos - nCurPos + 1); + } + return nValue; +} + +template<typename _ValueType, typename _ExtValueType> +bool ScFlatSegmentsImpl<_ValueType, _ExtValueType>::getRangeData(SCCOLROW nPos, RangeData& rData) +{ + ValueType nValue; + SCCOLROW nPos1, nPos2; + + if (mbTreeSearchEnabled) + { + if (!maSegments.is_tree_valid()) + maSegments.build_tree(); + + if (!maSegments.search_tree(nPos, nValue, &nPos1, &nPos2)) + return false; + } + else + { + // Conduct leaf-node only search. Faster when searching between range insertion. + if (!maSegments.search(nPos, nValue, &nPos1, &nPos2)) + return false; + } + + rData.mnPos1 = nPos1; + rData.mnPos2 = nPos2-1; // end point is not inclusive. + rData.mnValue = nValue; + return true; +} + +template<typename _ValueType, typename _ExtValueType> +void ScFlatSegmentsImpl<_ValueType, _ExtValueType>::removeSegment(SCCOLROW nPos1, SCCOLROW nPos2) +{ + maSegments.shift_left(nPos1, nPos2); +} + +template<typename _ValueType, typename _ExtValueType> +void ScFlatSegmentsImpl<_ValueType, _ExtValueType>::insertSegment(SCCOLROW nPos, SCCOLROW nSize, bool bSkipStartBoundary) +{ + maSegments.shift_right(nPos, nSize, bSkipStartBoundary); +} + +template<typename _ValueType, typename _ExtValueType> +SCCOLROW ScFlatSegmentsImpl<_ValueType, _ExtValueType>::findLastNotOf(ValueType nValue) const +{ + SCCOLROW nPos = numeric_limits<SCCOLROW>::max(); // position not found. + typename fst_type::const_reverse_iterator itr = maSegments.rbegin(), itrEnd = maSegments.rend(); + // Note that when searching in reverse direction, we need to skip the first + // node, since the right-most leaf node does not store a valid value. + for (++itr; itr != itrEnd; ++itr) + { + if (itr->second != nValue) + { + nPos = (--itr)->first - 1; + break; + } + } + return nPos; +} + +template<typename _ValueType, typename _ExtValueType> +bool ScFlatSegmentsImpl<_ValueType, _ExtValueType>::getFirst(RangeData& rData) +{ + maItr = maSegments.begin(); + return getNext(rData); +} + +template<typename _ValueType, typename _ExtValueType> +bool ScFlatSegmentsImpl<_ValueType, _ExtValueType>::getNext(RangeData& rData) +{ + typename fst_type::const_iterator itrEnd = maSegments.end(); + if (maItr == itrEnd) + return false; + + rData.mnPos1 = maItr->first; + rData.mnValue = maItr->second; + + ++maItr; + if (maItr == itrEnd) + return false; + + rData.mnPos2 = maItr->first - 1; + return true; +} + +// ============================================================================ + +class ScFlatUInt16SegmentsImpl : public ScFlatSegmentsImpl<sal_uInt16, sal_uInt32> +{ +public: + explicit ScFlatUInt16SegmentsImpl(SCCOLROW nMax, sal_uInt16 nDefault) : + ScFlatSegmentsImpl<sal_uInt16, sal_uInt32>(nMax, nDefault) + { + } +}; + +// ---------------------------------------------------------------------------- + +class ScFlatBoolSegmentsImpl : public ScFlatSegmentsImpl<bool> +{ +public: + explicit ScFlatBoolSegmentsImpl(SCCOLROW nMax) : + ScFlatSegmentsImpl<bool>(nMax, false) + { + } + + void setTrue(SCCOLROW nPos1, SCCOLROW nPos2); + void setFalse(SCCOLROW nPos1, SCCOLROW nPos2); +}; + +void ScFlatBoolSegmentsImpl::setTrue(SCCOLROW nPos1, SCCOLROW nPos2) +{ + setValue(nPos1, nPos2, true); +} + +void ScFlatBoolSegmentsImpl::setFalse(SCCOLROW nPos1, SCCOLROW nPos2) +{ + setValue(nPos1, nPos2, false); +} + +// ============================================================================ + +ScFlatBoolRowSegments::ForwardIterator::ForwardIterator(ScFlatBoolRowSegments& rSegs) : + mrSegs(rSegs), mnCurPos(0), mnLastPos(-1), mbCurValue(false) +{ +} + +bool ScFlatBoolRowSegments::ForwardIterator::getValue(SCROW nPos, bool& rVal) +{ + if (nPos >= mnCurPos) + // It can only go in a forward direction. + mnCurPos = nPos; + + if (mnCurPos > mnLastPos) + { + // position not in the current segment. Update the current value. + ScFlatBoolRowSegments::RangeData aData; + if (!mrSegs.getRangeData(mnCurPos, aData)) + return false; + + mbCurValue = aData.mbValue; + mnLastPos = aData.mnRow2; + } + + rVal = mbCurValue; + return true; +} + +SCROW ScFlatBoolRowSegments::ForwardIterator::getLastPos() const +{ + return mnLastPos; +} + +// ---------------------------------------------------------------------------- + +ScFlatBoolRowSegments::RangeIterator::RangeIterator(ScFlatBoolRowSegments& rSegs) : + mrSegs(rSegs) +{ +} + +bool ScFlatBoolRowSegments::RangeIterator::getFirst(RangeData& rRange) +{ + ScFlatBoolSegmentsImpl::RangeData aData; + if (!mrSegs.mpImpl->getFirst(aData)) + return false; + + rRange.mnRow1 = static_cast<SCROW>(aData.mnPos1); + rRange.mnRow2 = static_cast<SCROW>(aData.mnPos2); + rRange.mbValue = static_cast<bool>(aData.mnValue); + return true; +} + +bool ScFlatBoolRowSegments::RangeIterator::getNext(RangeData& rRange) +{ + ScFlatBoolSegmentsImpl::RangeData aData; + if (!mrSegs.mpImpl->getNext(aData)) + return false; + + rRange.mnRow1 = static_cast<SCROW>(aData.mnPos1); + rRange.mnRow2 = static_cast<SCROW>(aData.mnPos2); + rRange.mbValue = static_cast<bool>(aData.mnValue); + return true; +} + +// ---------------------------------------------------------------------------- + +ScFlatBoolRowSegments::ScFlatBoolRowSegments() : + mpImpl(new ScFlatBoolSegmentsImpl(static_cast<SCCOLROW>(MAXROW))) +{ +} + +ScFlatBoolRowSegments::ScFlatBoolRowSegments(const ScFlatBoolRowSegments& r) : + mpImpl(new ScFlatBoolSegmentsImpl(*r.mpImpl)) +{ +} + +ScFlatBoolRowSegments::~ScFlatBoolRowSegments() +{ +} + +void ScFlatBoolRowSegments::setTrue(SCROW nRow1, SCROW nRow2) +{ + mpImpl->setTrue(static_cast<SCCOLROW>(nRow1), static_cast<SCCOLROW>(nRow2)); +} + +void ScFlatBoolRowSegments::setFalse(SCROW nRow1, SCROW nRow2) +{ + mpImpl->setFalse(static_cast<SCCOLROW>(nRow1), static_cast<SCCOLROW>(nRow2)); +} + +bool ScFlatBoolRowSegments::getValue(SCROW nRow) +{ + return mpImpl->getValue(static_cast<SCCOLROW>(nRow)); +} + +bool ScFlatBoolRowSegments::getRangeData(SCROW nRow, RangeData& rData) +{ + ScFlatBoolSegmentsImpl::RangeData aData; + if (!mpImpl->getRangeData(static_cast<SCCOLROW>(nRow), aData)) + return false; + + rData.mbValue = aData.mnValue; + rData.mnRow1 = static_cast<SCROW>(aData.mnPos1); + rData.mnRow2 = static_cast<SCROW>(aData.mnPos2); + return true; +} + +void ScFlatBoolRowSegments::removeSegment(SCROW nRow1, SCROW nRow2) +{ + mpImpl->removeSegment(static_cast<SCCOLROW>(nRow1), static_cast<SCCOLROW>(nRow2)); +} + +void ScFlatBoolRowSegments::insertSegment(SCROW nRow, SCROW nSize, bool bSkipStartBoundary) +{ + mpImpl->insertSegment(static_cast<SCCOLROW>(nRow), static_cast<SCCOLROW>(nSize), bSkipStartBoundary); +} + +SCROW ScFlatBoolRowSegments::findLastNotOf(bool bValue) const +{ + return static_cast<SCROW>(mpImpl->findLastNotOf(bValue)); +} + +void ScFlatBoolRowSegments::enableTreeSearch(bool bEnable) +{ + mpImpl->enableTreeSearch(bEnable); +} + +void ScFlatBoolRowSegments::setInsertFromBack(bool bInsertFromBack) +{ + mpImpl->setInsertFromBack(bInsertFromBack); +} + +// ============================================================================ + +ScFlatBoolColSegments::ScFlatBoolColSegments() : + mpImpl(new ScFlatBoolSegmentsImpl(static_cast<SCCOLROW>(MAXCOL))) +{ +} + +ScFlatBoolColSegments::ScFlatBoolColSegments(const ScFlatBoolColSegments& r) : + mpImpl(new ScFlatBoolSegmentsImpl(*r.mpImpl)) +{ +} + +ScFlatBoolColSegments::~ScFlatBoolColSegments() +{ +} + +void ScFlatBoolColSegments::setTrue(SCCOL nCol1, SCCOL nCol2) +{ + mpImpl->setTrue(static_cast<SCCOLROW>(nCol1), static_cast<SCCOLROW>(nCol2)); +} + +void ScFlatBoolColSegments::setFalse(SCCOL nCol1, SCCOL nCol2) +{ + mpImpl->setFalse(static_cast<SCCOLROW>(nCol1), static_cast<SCCOLROW>(nCol2)); +} + +bool ScFlatBoolColSegments::getValue(SCCOL nCol) +{ + return mpImpl->getValue(static_cast<SCCOLROW>(nCol)); +} + +bool ScFlatBoolColSegments::getRangeData(SCCOL nCol, RangeData& rData) +{ + ScFlatBoolSegmentsImpl::RangeData aData; + if (!mpImpl->getRangeData(static_cast<SCCOLROW>(nCol), aData)) + return false; + + rData.mbValue = aData.mnValue; + rData.mnCol1 = static_cast<SCCOL>(aData.mnPos1); + rData.mnCol2 = static_cast<SCCOL>(aData.mnPos2); + return true; +} + +void ScFlatBoolColSegments::removeSegment(SCCOL nCol1, SCCOL nCol2) +{ + mpImpl->removeSegment(static_cast<SCCOLROW>(nCol1), static_cast<SCCOLROW>(nCol2)); +} + +void ScFlatBoolColSegments::insertSegment(SCCOL nCol, SCCOL nSize, bool bSkipStartBoundary) +{ + mpImpl->insertSegment(static_cast<SCCOLROW>(nCol), static_cast<SCCOLROW>(nSize), bSkipStartBoundary); +} + +void ScFlatBoolColSegments::enableTreeSearch(bool bEnable) +{ + mpImpl->enableTreeSearch(bEnable); +} + +void ScFlatBoolColSegments::setInsertFromBack(bool bInsertFromBack) +{ + mpImpl->setInsertFromBack(bInsertFromBack); +} + +// ============================================================================ + + +// ============================================================================ + +ScFlatUInt16RowSegments::ForwardIterator::ForwardIterator(ScFlatUInt16RowSegments& rSegs) : + mrSegs(rSegs), mnCurPos(0), mnLastPos(-1), mnCurValue(0) +{ +} + +bool ScFlatUInt16RowSegments::ForwardIterator::getValue(SCROW nPos, sal_uInt16& rVal) +{ + if (nPos >= mnCurPos) + // It can only go in a forward direction. + mnCurPos = nPos; + + if (mnCurPos > mnLastPos) + { + // position not in the current segment. Update the current value. + ScFlatUInt16RowSegments::RangeData aData; + if (!mrSegs.getRangeData(mnCurPos, aData)) + return false; + + mnCurValue = aData.mnValue; + mnLastPos = aData.mnRow2; + } + + rVal = mnCurValue; + return true; +} + +SCROW ScFlatUInt16RowSegments::ForwardIterator::getLastPos() const +{ + return mnLastPos; +} + +// ---------------------------------------------------------------------------- + +ScFlatUInt16RowSegments::ScFlatUInt16RowSegments(sal_uInt16 nDefault) : + mpImpl(new ScFlatUInt16SegmentsImpl(static_cast<SCCOLROW>(MAXROW), nDefault)) +{ +} + +ScFlatUInt16RowSegments::ScFlatUInt16RowSegments(const ScFlatUInt16RowSegments& r) : + mpImpl(new ScFlatUInt16SegmentsImpl(*r.mpImpl)) +{ +} + +ScFlatUInt16RowSegments::~ScFlatUInt16RowSegments() +{ +} + +void ScFlatUInt16RowSegments::setValue(SCROW nRow1, SCROW nRow2, sal_uInt16 nValue) +{ + mpImpl->setValue(static_cast<SCCOLROW>(nRow1), static_cast<SCCOLROW>(nRow2), nValue); +} + +sal_uInt16 ScFlatUInt16RowSegments::getValue(SCROW nRow) +{ + return mpImpl->getValue(static_cast<SCCOLROW>(nRow)); +} + +sal_uInt32 ScFlatUInt16RowSegments::getSumValue(SCROW nRow1, SCROW nRow2) +{ + return mpImpl->getSumValue(static_cast<SCCOLROW>(nRow1), static_cast<SCCOLROW>(nRow2)); +} + +bool ScFlatUInt16RowSegments::getRangeData(SCROW nRow, RangeData& rData) +{ + ScFlatUInt16SegmentsImpl::RangeData aData; + if (!mpImpl->getRangeData(static_cast<SCCOLROW>(nRow), aData)) + return false; + + rData.mnRow1 = aData.mnPos1; + rData.mnRow2 = aData.mnPos2; + rData.mnValue = aData.mnValue; + return true; +} + +void ScFlatUInt16RowSegments::removeSegment(SCROW nRow1, SCROW nRow2) +{ + mpImpl->removeSegment(static_cast<SCCOLROW>(nRow1), static_cast<SCCOLROW>(nRow2)); +} + +void ScFlatUInt16RowSegments::insertSegment(SCROW nRow, SCROW nSize, bool bSkipStartBoundary) +{ + mpImpl->insertSegment(static_cast<SCCOLROW>(nRow), static_cast<SCCOLROW>(nSize), bSkipStartBoundary); +} + +SCROW ScFlatUInt16RowSegments::findLastNotOf(sal_uInt16 nValue) const +{ + return static_cast<SCROW>(mpImpl->findLastNotOf(nValue)); +} + +void ScFlatUInt16RowSegments::enableTreeSearch(bool bEnable) +{ + mpImpl->enableTreeSearch(bEnable); +} + +void ScFlatUInt16RowSegments::setInsertFromBack(bool bInsertFromBack) +{ + mpImpl->setInsertFromBack(bInsertFromBack); +} + diff --git a/sc/source/core/data/sheetevents.cxx b/sc/source/core/data/sheetevents.cxx new file mode 100755 index 000000000000..e9e430ef85d9 --- /dev/null +++ b/sc/source/core/data/sheetevents.cxx @@ -0,0 +1,141 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: sheetdata.cxx,v $ + * $Revision: 1.69.32.3 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + +// INCLUDE --------------------------------------------------------------- + +#include <tools/debug.hxx> + +#include "sheetevents.hxx" + +// ----------------------------------------------------------------------- + +// static +rtl::OUString ScSheetEvents::GetEventName(sal_Int32 nEvent) +{ + if (nEvent<0 || nEvent>=SC_SHEETEVENT_COUNT) + { + DBG_ERRORFILE("invalid event number"); + return rtl::OUString(); + } + + static const sal_Char* aEventNames[] = + { + "OnFocus", // SC_SHEETEVENT_FOCUS + "OnUnfocus", // SC_SHEETEVENT_UNFOCUS + "OnSelect", // SC_SHEETEVENT_SELECT + "OnDoubleClick", // SC_SHEETEVENT_DOUBLECLICK + "OnRightClick", // SC_SHEETEVENT_RIGHTCLICK + "OnChange", // SC_SHEETEVENT_CHANGE + "OnCalculate" // SC_SHEETEVENT_CALCULATE + }; + return rtl::OUString::createFromAscii(aEventNames[nEvent]); +} + +// ----------------------------------------------------------------------- + +ScSheetEvents::ScSheetEvents() : + mpScriptNames(NULL) +{ +} + +ScSheetEvents::~ScSheetEvents() +{ + Clear(); +} + +void ScSheetEvents::Clear() +{ + if (mpScriptNames) + { + for (sal_Int32 nEvent=0; nEvent<SC_SHEETEVENT_COUNT; ++nEvent) + delete mpScriptNames[nEvent]; + delete[] mpScriptNames; + mpScriptNames = NULL; + } +} + +ScSheetEvents::ScSheetEvents(const ScSheetEvents& rOther) : + mpScriptNames(NULL) +{ + *this = rOther; +} + +const ScSheetEvents& ScSheetEvents::operator=(const ScSheetEvents& rOther) +{ + Clear(); + if (rOther.mpScriptNames) + { + mpScriptNames = new rtl::OUString*[SC_SHEETEVENT_COUNT]; + for (sal_Int32 nEvent=0; nEvent<SC_SHEETEVENT_COUNT; ++nEvent) + if (rOther.mpScriptNames[nEvent]) + mpScriptNames[nEvent] = new rtl::OUString(*rOther.mpScriptNames[nEvent]); + else + mpScriptNames[nEvent] = NULL; + } + return *this; +} + +const rtl::OUString* ScSheetEvents::GetScript(sal_Int32 nEvent) const +{ + if (nEvent<0 || nEvent>=SC_SHEETEVENT_COUNT) + { + DBG_ERRORFILE("invalid event number"); + return NULL; + } + + if (mpScriptNames) + return mpScriptNames[nEvent]; + return NULL; +} + +void ScSheetEvents::SetScript(sal_Int32 nEvent, const rtl::OUString* pNew) +{ + if (nEvent<0 || nEvent>=SC_SHEETEVENT_COUNT) + { + DBG_ERRORFILE("invalid event number"); + return; + } + + if (!mpScriptNames) + { + mpScriptNames = new rtl::OUString*[SC_SHEETEVENT_COUNT]; + for (sal_Int32 nEventIdx=0; nEventIdx<SC_SHEETEVENT_COUNT; ++nEventIdx) + mpScriptNames[nEventIdx] = NULL; + } + delete mpScriptNames[nEvent]; + if (pNew) + mpScriptNames[nEvent] = new rtl::OUString(*pNew); + else + mpScriptNames[nEvent] = NULL; +} + diff --git a/sc/source/core/data/stlsheet.cxx b/sc/source/core/data/stlsheet.cxx index 4a4210a7925c..a3319eafd3fd 100644 --- a/sc/source/core/data/stlsheet.cxx +++ b/sc/source/core/data/stlsheet.cxx @@ -171,7 +171,7 @@ SfxItemSet& __EXPORT ScStyleSheet::GetItemSet() // gespeicherte Printer noch nicht geladen ist! ScDocument* pDoc = ((ScStyleSheetPool&)GetPool()).GetDocument(); - if ( pDoc && pDoc->IsLoadingDone() ) + if ( pDoc ) { // Setzen von sinnvollen Default-Werten: SvxPageItem aPageItem( ATTR_PAGE ); diff --git a/sc/source/core/data/tabbgcolor.cxx b/sc/source/core/data/tabbgcolor.cxx new file mode 100644 index 000000000000..a3d9eec16d99 --- /dev/null +++ b/sc/source/core/data/tabbgcolor.cxx @@ -0,0 +1,62 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: tabbgcolor.hxx,v $ + * $Revision: 1.00 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + + + +// INCLUDE --------------------------------------------------------------- + +#include "tabbgcolor.hxx" + +bool ScUndoTabColorInfo::IsDefaultOldTabBgColor() const +{ + return maOldTabBgColor == Color(COL_AUTO); +} + +bool ScUndoTabColorInfo::IsDefaultNewTabBgColor() const +{ + return maOldTabBgColor == Color(COL_AUTO); +} + +ScUndoTabColorInfo::ScUndoTabColorInfo(SCTAB nTab) : + mnTabId(nTab), + maOldTabBgColor(COL_AUTO), + maNewTabBgColor(COL_AUTO) +{ +} + +ScUndoTabColorInfo::ScUndoTabColorInfo(const ScUndoTabColorInfo& r) : + mnTabId(r.mnTabId), + maOldTabBgColor(r.maOldTabBgColor), + maNewTabBgColor(r.maNewTabBgColor) +{ +} diff --git a/sc/source/core/data/table1.cxx b/sc/source/core/data/table1.cxx index f8cf1489f3aa..87561abf1513 100644 --- a/sc/source/core/data/table1.cxx +++ b/sc/source/core/data/table1.cxx @@ -112,11 +112,11 @@ #include "hints.hxx" // fuer Paint-Broadcast #include "prnsave.hxx" #include "tabprotection.hxx" +#include "sheetevents.hxx" +#include "segmenttree.hxx" // STATIC DATA ----------------------------------------------------------- -extern BOOL bIsOlk, bOderSo; - // ----------------------------------------------------------------------- ScTable::ScTable( ScDocument* pDoc, SCTAB nNewTab, const String& rNewName, @@ -133,14 +133,20 @@ ScTable::ScTable( ScDocument* pDoc, SCTAB nNewTab, const String& rNewName, nRepeatStartY( SCROW_REPEAT_NONE ), pTabProtection( NULL ), pColWidth( NULL ), - pRowHeight( NULL ), + mpRowHeights( static_cast<ScFlatUInt16RowSegments*>(NULL) ), pColFlags( NULL ), pRowFlags( NULL ), + mpHiddenCols(new ScFlatBoolColSegments), + mpHiddenRows(new ScFlatBoolRowSegments), + mpFilteredCols(new ScFlatBoolColSegments), + mpFilteredRows(new ScFlatBoolRowSegments), pOutlineTable( NULL ), + pSheetEvents( NULL ), bTableAreaValid( FALSE ), bVisible( TRUE ), bStreamValid( FALSE ), bPendingRowHeights( FALSE ), + bCalcNotification( FALSE ), nTab( nNewTab ), nRecalcLvl( 0 ), pDocument( pDoc ), @@ -153,8 +159,10 @@ ScTable::ScTable( ScDocument* pDoc, SCTAB nNewTab, const String& rNewName, nLockCount( 0 ), pScenarioRanges( NULL ), aScenarioColor( COL_LIGHTGRAY ), + aTabBgColor( COL_AUTO ), nScenarioFlags( 0 ), - bActiveScenario( FALSE ) + bActiveScenario( FALSE ), + mbPageBreaksValid(false) { if (bColInfo) @@ -171,7 +179,7 @@ ScTable::ScTable( ScDocument* pDoc, SCTAB nNewTab, const String& rNewName, if (bRowInfo) { - pRowHeight = new ScSummableCompressedArray< SCROW, USHORT>( MAXROW, ScGlobal::nStdRowHeight); + mpRowHeights.reset(new ScFlatUInt16RowSegments(ScGlobal::nStdRowHeight)); pRowFlags = new ScBitMaskCompressedArray< SCROW, BYTE>( MAXROW, 0); } @@ -213,8 +221,8 @@ ScTable::~ScTable() delete[] pColWidth; delete[] pColFlags; - delete pRowHeight; delete pRowFlags; + delete pSheetEvents; delete pOutlineTable; delete pSearchParam; delete pSearchText; @@ -231,9 +239,6 @@ void ScTable::GetName( String& rName ) const void ScTable::SetName( const String& rNewName ) { - String aMd( "D\344umling", RTL_TEXTENCODING_MS_1252 ); // ANSI - if( rNewName == aMd ) - bIsOlk = bOderSo = TRUE; aName = rNewName; aUpperName.Erase(); // invalidated if the name is changed @@ -276,6 +281,22 @@ void ScTable::SetLoadingRTL( BOOL bSet ) bLoadingRTL = bSet; } +const Color& ScTable::GetTabBgColor() const +{ + return aTabBgColor; +} + +void ScTable::SetTabBgColor(const Color& rColor) +{ + if (aTabBgColor != rColor) + { + // The tab color has changed. Set this table 'modified'. + aTabBgColor = rColor; + if (IsStreamValid()) + SetStreamValid(false); + } +} + void ScTable::SetScenario( BOOL bFlag ) { bScenario = bFlag; @@ -683,7 +704,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; @@ -974,9 +995,10 @@ BOOL ScTable::ValidNextPos( SCCOL nCol, SCROW nRow, const ScMarkData& rMark, // auf der naechsten Zelle landet, auch wenn die geschuetzt/nicht markiert ist. //! per Extra-Parameter steuern, nur fuer Cursor-Bewegung ??? - if ( pRowFlags && ( pRowFlags->GetValue(nRow) & CR_HIDDEN ) ) + if (RowHidden(nRow)) return FALSE; - if ( pColFlags && ( pColFlags[nCol] & CR_HIDDEN ) ) + + if (ColHidden(nCol)) return FALSE; } @@ -1003,8 +1025,8 @@ void ScTable::GetNextPos( SCCOL& rCol, SCROW& rRow, SCsCOL nMovX, SCsROW nMovY, { BOOL bUp = ( nMovY < 0 ); nRow = rMark.GetNextMarked( nCol, nRow, bUp ); - while ( VALIDROW(nRow) && ((pRowFlags && (pRowFlags->GetValue(nRow) & CR_HIDDEN)) || - pDocument->HasAttrib(nCol, nRow, nTab, nCol, nRow, nTab, HASATTR_OVERLAPPED)) ) + while ( VALIDROW(nRow) && + (RowHidden(nRow) || pDocument->HasAttrib(nCol, nRow, nTab, nCol, nRow, nTab, HASATTR_OVERLAPPED)) ) { // #53697# ausgeblendete ueberspringen (s.o.) nRow += nMovY; @@ -1014,7 +1036,7 @@ void ScTable::GetNextPos( SCCOL& rCol, SCROW& rRow, SCsCOL nMovX, SCsROW nMovY, while ( nRow < 0 || nRow > MAXROW ) { nCol = sal::static_int_cast<SCsCOL>( nCol + static_cast<SCsCOL>(nMovY) ); - while ( VALIDCOL(nCol) && pColFlags && (pColFlags[nCol] & CR_HIDDEN) ) + while ( VALIDCOL(nCol) && ColHidden(nCol) ) nCol = sal::static_int_cast<SCsCOL>( nCol + static_cast<SCsCOL>(nMovY) ); // #53697# skip hidden rows (see above) if (nCol < 0) { @@ -1033,8 +1055,8 @@ void ScTable::GetNextPos( SCCOL& rCol, SCROW& rRow, SCsCOL nMovX, SCsROW nMovY, else if (nRow > MAXROW) nRow = 0; nRow = rMark.GetNextMarked( nCol, nRow, bUp ); - while ( VALIDROW(nRow) && ((pRowFlags && (pRowFlags->GetValue(nRow) & CR_HIDDEN)) || - pDocument->HasAttrib(nCol, nRow, nTab, nCol, nRow, nTab, HASATTR_OVERLAPPED)) ) + while ( VALIDROW(nRow) && + (RowHidden(nRow) || pDocument->HasAttrib(nCol, nRow, nTab, nCol, nRow, nTab, HASATTR_OVERLAPPED)) ) { // #53697# ausgeblendete ueberspringen (s.o.) nRow += nMovY; @@ -1425,93 +1447,140 @@ void ScTable::ExtendPrintArea( OutputDevice* pDev, double nPPTX = aPix1000.X() / 1000.0; double nPPTY = aPix1000.Y() / 1000.0; - BOOL bEmpty[MAXCOLCOUNT]; - for (SCCOL i=0; i<=MAXCOL; i++) - bEmpty[i] = ( aCol[i].GetCellCount() == 0 ); - - SCSIZE nIndex; - SCCOL nPrintCol = rEndCol; - SCSIZE nRowFlagsIndex; - SCROW nRowFlagsEndRow; - BYTE nRowFlag = pRowFlags->GetValue( nStartRow, nRowFlagsIndex, nRowFlagsEndRow); - for (SCROW nRow = nStartRow; nRow<=nEndRow; nRow++) + // First, mark those columns that we need to skip i.e. hidden and empty columns. + + ScFlatBoolColSegments aSkipCols; + aSkipCols.setInsertFromBack(true); // speed optimazation. + aSkipCols.setFalse(0, MAXCOL); + for (SCCOL i = 0; i <= MAXCOL; ++i) { - if (nRow > nRowFlagsEndRow) - nRowFlag = pRowFlags->GetNextValue( nRowFlagsIndex, nRowFlagsEndRow); - if ( ( nRowFlag & CR_HIDDEN ) == 0 ) + SCCOL nLastCol = i; + if (ColHidden(i, NULL, &nLastCol)) { - SCCOL nDataCol = rEndCol; - while (nDataCol > 0 && ( bEmpty[nDataCol] || !aCol[nDataCol].Search(nRow,nIndex) ) ) - --nDataCol; - if ( ( pColFlags[nDataCol] & CR_HIDDEN ) == 0 ) + // Columns are hidden in this range. + aSkipCols.setTrue(i, nLastCol); + } + else + { + // These columns are visible. Check for empty columns. + for (SCCOL j = i; j <= nLastCol; ++j) { - ScBaseCell* pCell = aCol[nDataCol].GetCell(nRow); - if (pCell) - { - CellType eType = pCell->GetCellType(); - if (eType == CELLTYPE_STRING || eType == CELLTYPE_EDIT - || (eType == CELLTYPE_FORMULA && !((ScFormulaCell*)pCell)->IsValue()) ) - { - BOOL bFormula = FALSE; //! uebergeben - long nPixel = pCell->GetTextWidth(); - - // Breite bereits im Idle-Handler berechnet? - if ( TEXTWIDTH_DIRTY == nPixel ) - { - ScNeededSizeOptions aOptions; - aOptions.bTotalSize = TRUE; - aOptions.bFormula = bFormula; - aOptions.bSkipMerged = FALSE; - - Fraction aZoom(1,1); - nPixel = aCol[nDataCol].GetNeededSize( nRow, - pDev,nPPTX,nPPTY,aZoom,aZoom, - TRUE, aOptions ); - pCell->SetTextWidth( (USHORT)nPixel ); - } + if (aCol[j].GetCellCount() == 0) + // empty + aSkipCols.setTrue(j,j); + } + } + i = nLastCol; + } - long nTwips = (long) (nPixel / nPPTX); - long nDocW = GetColWidth( nDataCol ); + ScFlatBoolColSegments::RangeData aColData; + for (SCCOL nCol = rEndCol; nCol >= 0; --nCol) + { + if (!aSkipCols.getRangeData(nCol, aColData)) + // Failed to get the data. This should never happen! + return; - long nMissing = nTwips - nDocW; - if ( nMissing > 0 ) - { - // look at alignment - - const ScPatternAttr* pPattern = GetPattern( nDataCol, nRow ); - const SfxItemSet* pCondSet = NULL; - if ( ((const SfxUInt32Item&)pPattern->GetItem(ATTR_CONDITIONAL)).GetValue() ) - pCondSet = pDocument->GetCondResult( nDataCol, nRow, nTab ); - - SvxCellHorJustify eHorJust = (SvxCellHorJustify)((const SvxHorJustifyItem&) - pPattern->GetItem( ATTR_HOR_JUSTIFY, pCondSet )).GetValue(); - if ( eHorJust == SVX_HOR_JUSTIFY_CENTER ) - nMissing /= 2; // distributed into both directions - else - { - // STANDARD is LEFT (only text is handled here) - BOOL bRight = ( eHorJust == SVX_HOR_JUSTIFY_RIGHT ); - if ( IsLayoutRTL() ) - bRight = !bRight; - if ( bRight ) - nMissing = 0; // extended only to the left (logical) - } - } + if (aColData.mbValue) + { + // Skip these columns. + nCol = aColData.mnCol1; // move toward 0. + continue; + } - SCCOL nCol = nDataCol; - while (nMissing > 0 && nCol < MAXCOL) - { - ++nCol; - nMissing -= GetColWidth( nCol ); - } - if (nCol>nPrintCol) - nPrintCol = nCol; - } - } + // These are visible and non-empty columns. + for (SCCOL nDataCol = nCol; 0 <= nDataCol && nDataCol >= aColData.mnCol1; --nDataCol) + { + SCCOL nPrintCol = nDataCol; + VisibleDataCellIterator aIter(*mpHiddenRows, aCol[nDataCol]); + ScBaseCell* pCell = aIter.reset(nStartRow); + if (!pCell) + // No visible cells found in this column. Skip it. + continue; + + while (pCell) + { + SCCOL nNewCol = nDataCol; + SCROW nRow = aIter.getRow(); + if (nRow > nEndRow) + // Went past the last row position. Bail out. + break; + + MaybeAddExtraColumn(nNewCol, nRow, pDev, nPPTX, nPPTY); + if (nNewCol > nPrintCol) + nPrintCol = nNewCol; + pCell = aIter.next(); } + + if (nPrintCol > rEndCol) + // Make sure we don't shrink the print area. + rEndCol = nPrintCol; } + nCol = aColData.mnCol1; // move toward 0. } - rEndCol = nPrintCol; +} + +void ScTable::MaybeAddExtraColumn(SCCOL& rCol, SCROW nRow, OutputDevice* pDev, double nPPTX, double nPPTY) +{ + ScBaseCell* pCell = aCol[rCol].GetCell(nRow); + if (!pCell || !pCell->HasStringData()) + return; + + bool bFormula = false; //! ueberge + long nPixel = pCell->GetTextWidth(); + + // Breite bereits im Idle-Handler berechnet? + if ( TEXTWIDTH_DIRTY == nPixel ) + { + ScNeededSizeOptions aOptions; + aOptions.bTotalSize = TRUE; + aOptions.bFormula = bFormula; + aOptions.bSkipMerged = FALSE; + + Fraction aZoom(1,1); + nPixel = aCol[rCol].GetNeededSize( + nRow, pDev, nPPTX, nPPTY, aZoom, aZoom, true, aOptions ); + pCell->SetTextWidth( (USHORT)nPixel ); + } + + long nTwips = (long) (nPixel / nPPTX); + long nDocW = GetColWidth( rCol ); + + long nMissing = nTwips - nDocW; + if ( nMissing > 0 ) + { + // look at alignment + + const ScPatternAttr* pPattern = GetPattern( rCol, nRow ); + const SfxItemSet* pCondSet = NULL; + if ( ((const SfxUInt32Item&)pPattern->GetItem(ATTR_CONDITIONAL)).GetValue() ) + pCondSet = pDocument->GetCondResult( rCol, nRow, nTab ); + + SvxCellHorJustify eHorJust = (SvxCellHorJustify)((const SvxHorJustifyItem&) + pPattern->GetItem( ATTR_HOR_JUSTIFY, pCondSet )).GetValue(); + if ( eHorJust == SVX_HOR_JUSTIFY_CENTER ) + nMissing /= 2; // distributed into both directions + else + { + // STANDARD is LEFT (only text is handled here) + bool bRight = ( eHorJust == SVX_HOR_JUSTIFY_RIGHT ); + if ( IsLayoutRTL() ) + bRight = !bRight; + if ( bRight ) + nMissing = 0; // extended only to the left (logical) + } + } + + SCCOL nNewCol = rCol; + while (nMissing > 0 && nNewCol < MAXCOL) + { + ScBaseCell* pNextCell = aCol[nNewCol+1].GetCell(nRow); + if (pNextCell && pNextCell->GetCellType() != CELLTYPE_NOTE) + // Cell content in a next column ends display of this string. + nMissing = 0; + else + nMissing -= GetColWidth(++nNewCol); + } + rCol = nNewCol; } void ScTable::DoColResize( SCCOL nCol1, SCCOL nCol2, SCSIZE nAdd ) @@ -1602,7 +1671,104 @@ void ScTable::RestorePrintRanges( const ScPrintSaverTab& rSaveTab ) UpdatePageBreaks(NULL); } +SCROW ScTable::VisibleDataCellIterator::ROW_NOT_FOUND = -1; + +ScTable::VisibleDataCellIterator::VisibleDataCellIterator(ScFlatBoolRowSegments& rRowSegs, ScColumn& rColumn) : + mrRowSegs(rRowSegs), + mrColumn(rColumn), + mpCell(NULL), + mnCurRow(ROW_NOT_FOUND), + mnUBound(ROW_NOT_FOUND) +{ +} + +ScTable::VisibleDataCellIterator::~VisibleDataCellIterator() +{ +} +ScBaseCell* ScTable::VisibleDataCellIterator::reset(SCROW nRow) +{ + if (nRow > MAXROW) + { + mnCurRow = ROW_NOT_FOUND; + return NULL; + } + ScFlatBoolRowSegments::RangeData aData; + if (!mrRowSegs.getRangeData(nRow, aData)) + { + mnCurRow = ROW_NOT_FOUND; + return NULL; + } + if (!aData.mbValue) + { + // specified row is visible. Take it. + mnCurRow = nRow; + mnUBound = aData.mnRow2; + } + else + { + // specified row is not-visible. The first visible row is the start of + // the next segment. + mnCurRow = aData.mnRow2 + 1; + mnUBound = mnCurRow; // get range data on the next iteration. + if (mnCurRow > MAXROW) + { + // Make sure the row doesn't exceed our current limit. + mnCurRow = ROW_NOT_FOUND; + return NULL; + } + } + + mpCell = mrColumn.GetCell(mnCurRow); + if (mpCell) + // First visible cell found. + return mpCell; + + // Find a first visible cell below this row (if any). + return next(); +} + +ScBaseCell* ScTable::VisibleDataCellIterator::next() +{ + if (mnCurRow == ROW_NOT_FOUND) + return NULL; + + while (mrColumn.GetNextDataPos(mnCurRow)) + { + if (mnCurRow > mnUBound) + { + // We don't know the visibility of this row range. Query it. + ScFlatBoolRowSegments::RangeData aData; + if (!mrRowSegs.getRangeData(mnCurRow, aData)) + { + mnCurRow = ROW_NOT_FOUND; + return NULL; + } + + if (aData.mbValue) + { + // This row is invisible. Skip to the last invisible row and + // try again. + mnCurRow = mnUBound = aData.mnRow2; + continue; + } + + // This row is visible. + mnUBound = aData.mnRow2; + } + + mpCell = mrColumn.GetCell(mnCurRow); + if (mpCell) + return mpCell; + } + mnCurRow = ROW_NOT_FOUND; + return NULL; +} + +SCROW ScTable::VisibleDataCellIterator::getRow() const +{ + return mnCurRow; +} diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx index 4dc7dddcaba1..9bd5b031fde5 100644 --- a/sc/source/core/data/table2.cxx +++ b/sc/source/core/data/table2.cxx @@ -56,7 +56,9 @@ #include "fillinfo.hxx" #include "bcaslot.hxx" #include "postit.hxx" +#include "sheetevents.hxx" #include "globstr.hrc" +#include "segmenttree.hxx" #include <math.h> @@ -97,6 +99,27 @@ void ScTable::StartOutlineTable() } +void ScTable::SetSheetEvents( const ScSheetEvents* pNew ) +{ + delete pSheetEvents; + if (pNew) + pSheetEvents = new ScSheetEvents(*pNew); + else + pSheetEvents = NULL; + + SetCalcNotification( FALSE ); // discard notifications before the events were set + + if (IsStreamValid()) + SetStreamValid(FALSE); +} + + +void ScTable::SetCalcNotification( BOOL bSet ) +{ + bCalcNotification = bSet; +} + + BOOL ScTable::TestInsertRow( SCCOL nStartCol, SCCOL nEndCol, SCSIZE nSize ) { BOOL bTest = TRUE; @@ -117,22 +140,28 @@ void ScTable::InsertRow( SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCSIZE InitializeNoteCaptions(); if (nStartCol==0 && nEndCol==MAXCOL) { - if (pRowHeight && pRowFlags) + if (mpRowHeights && pRowFlags) { - pRowHeight->Insert( nStartRow, nSize); + mpRowHeights->insertSegment(nStartRow, nSize, false); BYTE nNewFlags = pRowFlags->Insert( nStartRow, nSize); // only copy manual size flag, clear all others if (nNewFlags && (nNewFlags != CR_MANUALSIZE)) pRowFlags->SetValue( nStartRow, nStartRow + nSize - 1, nNewFlags & CR_MANUALSIZE); } + if (pOutlineTable) pOutlineTable->InsertRow( nStartRow, nSize ); + + mpFilteredRows->insertSegment(nStartRow, nSize, true); + mpHiddenRows->insertSegment(nStartRow, nSize, true); } for (SCCOL j=nStartCol; j<=nEndCol; j++) aCol[j].InsertRow( nStartRow, nSize ); DecRecalcLevel( false ); + + InvalidatePageBreaks(); } @@ -143,15 +172,19 @@ void ScTable::DeleteRow( SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCSIZE InitializeNoteCaptions(); if (nStartCol==0 && nEndCol==MAXCOL) { - if (pRowHeight && pRowFlags) - { - pRowHeight->Remove( nStartRow, nSize); + if (pRowFlags) pRowFlags->Remove( nStartRow, nSize); - } + + if (mpRowHeights) + mpRowHeights->removeSegment(nStartRow, nStartRow+nSize); + if (pOutlineTable) if (pOutlineTable->DeleteRow( nStartRow, nSize )) if (pUndoOutline) *pUndoOutline = TRUE; + + mpFilteredRows->removeSegment(nStartRow, nStartRow+nSize); + mpHiddenRows->removeSegment(nStartRow, nStartRow+nSize); } { // scope for bulk broadcast @@ -160,6 +193,8 @@ void ScTable::DeleteRow( SCCOL nStartCol, SCCOL nEndCol, SCROW nStartRow, SCSIZE aCol[j].DeleteRow( nStartRow, nSize ); } DecRecalcLevel(); + + InvalidatePageBreaks(); } @@ -195,6 +230,9 @@ void ScTable::InsertCol( SCCOL nStartCol, SCROW nStartRow, SCROW nEndRow, SCSIZE } if (pOutlineTable) pOutlineTable->InsertCol( nStartCol, nSize ); + + mpHiddenCols->insertSegment(nStartCol, static_cast<SCCOL>(nSize), true); + mpFilteredCols->insertSegment(nStartCol, static_cast<SCCOL>(nSize), true); } @@ -226,6 +264,8 @@ void ScTable::InsertCol( SCCOL nStartCol, SCROW nStartRow, SCROW nEndRow, SCSIZE } } DecRecalcLevel(); + + InvalidatePageBreaks(); } @@ -247,6 +287,10 @@ void ScTable::DeleteCol( SCCOL nStartCol, SCROW nStartRow, SCROW nEndRow, SCSIZE if (pOutlineTable->DeleteCol( nStartCol, nSize )) if (pUndoOutline) *pUndoOutline = TRUE; + + SCCOL nRmSize = nStartCol + static_cast<SCCOL>(nSize); + mpHiddenCols->removeSegment(nStartCol, nRmSize); + mpFilteredCols->removeSegment(nStartCol, nRmSize); } @@ -268,6 +312,8 @@ void ScTable::DeleteCol( SCCOL nStartCol, SCROW nStartRow, SCROW nEndRow, SCSIZE aCol[nStartCol + nSize + i].MoveTo(nStartRow, nEndRow, aCol[nStartCol + i]); } DecRecalcLevel(); + + InvalidatePageBreaks(); } @@ -339,20 +385,21 @@ void ScTable::CopyToClip(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, // copy widths/heights, and only "hidden", "filtered" and "manual" flags // also for all preceding columns/rows, to have valid positions for drawing objects - if (pColFlags && pTable->pColFlags && pColWidth && pTable->pColWidth) + if (pColWidth && pTable->pColWidth) for (i=0; i<=nCol2; i++) - { - pTable->pColFlags[i] = pColFlags[i] & CR_HIDDEN; pTable->pColWidth[i] = pColWidth[i]; - } - if (pRowFlags && pTable->pRowFlags && pRowHeight && pTable->pRowHeight) + pTable->CopyColHidden(*this, 0, nCol2); + pTable->CopyColFiltered(*this, 0, nCol2); + + if (pRowFlags && pTable->pRowFlags && mpRowHeights && pTable->mpRowHeights) { - pTable->pRowFlags->CopyFromAnded( *pRowFlags, 0, nRow2, - (CR_HIDDEN | CR_FILTERED | CR_MANUALSIZE)); - pTable->pRowHeight->CopyFrom( *pRowHeight, 0, nRow2); + pTable->pRowFlags->CopyFromAnded( *pRowFlags, 0, nRow2, CR_MANUALSIZE); + pTable->CopyRowHeight(*this, 0, nRow2, 0); } + pTable->CopyRowHidden(*this, 0, nRow2); + pTable->CopyRowFiltered(*this, 0, nRow2); // ggf. Formeln durch Werte ersetzen @@ -393,10 +440,10 @@ void ScTable::CopyFromClip(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, for (i=nCol1; i<=nCol2; i++) pColWidth[i] = pTable->pColWidth[i-nDx]; - if (nCol1==0 && nCol2==MAXCOL && pRowHeight && pTable->pRowHeight && + if (nCol1==0 && nCol2==MAXCOL && mpRowHeights && pTable->mpRowHeights && pRowFlags && pTable->pRowFlags) { - pRowHeight->CopyFrom( *pTable->pRowHeight, nRow1, nRow2, -nDy); + CopyRowHeight(*pTable, nRow1, nRow2, -nDy); // Must copy CR_MANUALSIZE bit too, otherwise pRowHeight doesn't make sense for (SCROW j=nRow1; j<=nRow2; j++) { @@ -631,8 +678,10 @@ void ScTable::CopyToTable(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, // Charts muessen beim Ein-/Ausblenden angepasst werden ScChartListenerCollection* pCharts = pDestTab->pDocument->GetChartListenerCollection(); + bool bFlagChange = false; + BOOL bWidth = (nRow1==0 && nRow2==MAXROW && pColWidth && pDestTab->pColWidth); - BOOL bHeight = (nCol1==0 && nCol2==MAXCOL && pRowHeight && pDestTab->pRowHeight); + BOOL bHeight = (nCol1==0 && nCol2==MAXCOL && mpRowHeights && pDestTab->mpRowHeights); if (bWidth||bHeight) { @@ -641,33 +690,77 @@ void ScTable::CopyToTable(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, if (bWidth) for (SCCOL i=nCol1; i<=nCol2; i++) { - BOOL bChange = pCharts && - ( pDestTab->pColFlags[i] & CR_HIDDEN ) != ( pColFlags[i] & CR_HIDDEN ); + bool bThisHidden = ColHidden(i); + bool bHiddenChange = (pDestTab->ColHidden(i) != bThisHidden); + bool bChange = bHiddenChange || (pDestTab->pColWidth[i] != pColWidth[i]); pDestTab->pColWidth[i] = pColWidth[i]; pDestTab->pColFlags[i] = pColFlags[i]; + pDestTab->SetColHidden(i, i, bThisHidden); //! Aenderungen zusammenfassen? - if (bChange) + if (bHiddenChange && pCharts) pCharts->SetRangeDirty(ScRange( i, 0, nTab, i, MAXROW, nTab )); + + if (bChange) + bFlagChange = true; } if (bHeight) { - pDestTab->pRowHeight->CopyFrom( *pRowHeight, nRow1, nRow2); - for (SCROW i=nRow1; i<=nRow2; i++) + bool bChange = pDestTab->GetRowHeight(nRow1, nRow2) != GetRowHeight(nRow1, nRow2); + + if (bChange) + bFlagChange = true; + + pDestTab->CopyRowHeight(*this, nRow1, nRow2, 0); + pDestTab->pRowFlags->CopyFrom(*pRowFlags, nRow1, nRow2); + + // Hidden flags. + for (SCROW i = nRow1; i <= nRow2; ++i) { - // TODO: might need some performance improvement, block - // operations instead of single GetValue()/SetValue() calls. - BYTE nThisRowFlags = pRowFlags->GetValue(i); - BOOL bChange = pCharts && - ( pDestTab->pRowFlags->GetValue(i) & CR_HIDDEN ) != ( nThisRowFlags & CR_HIDDEN ); - pDestTab->pRowFlags->SetValue( i, nThisRowFlags ); - //! Aenderungen zusammenfassen? - if (bChange) - pCharts->SetRangeDirty(ScRange( 0, i, nTab, MAXCOL, i, nTab )); + SCROW nThisLastRow, nDestLastRow; + bool bThisHidden = RowHidden(i, NULL, &nThisLastRow); + bool bDestHidden = pDestTab->RowHidden(i, NULL, &nDestLastRow); + + // If the segment sizes differ, we take the shorter segment of the two. + SCROW nLastRow = ::std::min(nThisLastRow, nDestLastRow); + if (nLastRow >= nRow2) + // the last row shouldn't exceed the upper bound the caller specified. + nLastRow = nRow2; + + pDestTab->SetRowHidden(i, nLastRow, bThisHidden); + + bool bThisHiddenChange = (bThisHidden != bDestHidden); + if (bThisHiddenChange && pCharts) + { + // Hidden flags differ. + pCharts->SetRangeDirty(ScRange(0, i, nTab, MAXCOL, nLastRow, nTab)); + } + + if (bThisHiddenChange) + bFlagChange = true; + + // Jump to the last row of the identical flag segment. + i = nLastRow; + } + + // Filtered flags. + for (SCROW i = nRow1; i <= nRow2; ++i) + { + SCROW nLastRow; + bool bFiltered = RowFiltered(i, NULL, &nLastRow); + if (nLastRow >= nRow2) + // the last row shouldn't exceed the upper bound the caller specified. + nLastRow = nRow2; + pDestTab->SetRowFiltered(i, nLastRow, bFiltered); + i = nLastRow; } } pDestTab->DecRecalcLevel(); } + + if (bFlagChange) + pDestTab->InvalidatePageBreaks(); + pDestTab->SetOutlineTable( pOutlineTable ); // auch nur wenn bColRowFlags } } @@ -681,7 +774,7 @@ void ScTable::UndoToTable(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, if (ValidColRow(nCol1, nRow1) && ValidColRow(nCol2, nRow2)) { BOOL bWidth = (nRow1==0 && nRow2==MAXROW && pColWidth && pDestTab->pColWidth); - BOOL bHeight = (nCol1==0 && nCol2==MAXCOL && pRowHeight && pDestTab->pRowHeight); + BOOL bHeight = (nCol1==0 && nCol2==MAXCOL && mpRowHeights && pDestTab->mpRowHeights); if (bWidth||bHeight) IncRecalcLevel(); @@ -701,8 +794,8 @@ void ScTable::UndoToTable(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, for (SCCOL i=nCol1; i<=nCol2; i++) pDestTab->pColWidth[i] = pColWidth[i]; if (bHeight) - pDestTab->pRowHeight->CopyFrom( *pRowHeight, nRow1, nRow2); - DecRecalcLevel(); + pDestTab->CopyRowHeight(*this, nRow1, nRow2, 0); + DecRecalcLevel(); } } } @@ -714,6 +807,16 @@ void ScTable::CopyUpdated( const ScTable* pPosTab, ScTable* pDestTab ) const aCol[i].CopyUpdated( pPosTab->aCol[i], pDestTab->aCol[i] ); } +void ScTable::InvalidateTableArea() +{ + bTableAreaValid = FALSE; +} + +void ScTable::InvalidatePageBreaks() +{ + mbPageBreaksValid = false; +} + void ScTable::CopyScenarioTo( ScTable* pDestTab ) const { DBG_ASSERT( bScenario, "bScenario == FALSE" ); @@ -1093,6 +1196,17 @@ void ScTable::SetRelNameDirty() } +void ScTable::SetLoadingMedium(bool bLoading) +{ + mpRowHeights->enableTreeSearch(!bLoading); + + // When loading a medium, prefer inserting row heights from the back + // position since the row heights are stored and read in ascending order + // during import. + mpRowHeights->setInsertFromBack(bLoading); +} + + void ScTable::CalcAll() { for (SCCOL i=0; i<=MAXCOL; i++) aCol[i].CalcAll(); @@ -1119,17 +1233,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(); @@ -1251,7 +1354,7 @@ BOOL ScTable::IsBlockEmpty( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, SCSIZE ScTable::FillMaxRot( RowInfo* pRowInfo, SCSIZE nArrCount, SCCOL nX1, SCCOL nX2, SCCOL nCol, SCROW nAttrRow1, SCROW nAttrRow2, SCSIZE nArrY, - const ScPatternAttr* pPattern, const SfxItemSet* pCondSet ) const + const ScPatternAttr* pPattern, const SfxItemSet* pCondSet ) { // Rueckgabe = neues nArrY @@ -1284,7 +1387,7 @@ SCSIZE ScTable::FillMaxRot( RowInfo* pRowInfo, SCSIZE nArrCount, SCCOL nX1, SCCO for ( SCROW nRow = nAttrRow1; nRow <= nAttrRow2; nRow++ ) { - if ( !(pRowFlags->GetValue(nRow) & CR_HIDDEN) ) + if (!RowHidden(nRow)) { BOOL bHitOne = TRUE; if ( nCol > nX2+1 ) @@ -1292,7 +1395,7 @@ SCSIZE ScTable::FillMaxRot( RowInfo* pRowInfo, SCSIZE nArrCount, SCCOL nX1, SCCO // reicht die gedrehte Zelle bis in den sichtbaren Bereich? SCCOL nTouchedCol = nCol; - long nWidth = (long) ( pRowHeight->GetValue(nRow) * nFactor ); + long nWidth = static_cast<long>(mpRowHeights->getValue(nRow) * nFactor); DBG_ASSERT(nWidth <= 0, "Richtung falsch"); while ( nWidth < 0 && nTouchedCol > 0 ) { @@ -1318,9 +1421,9 @@ SCSIZE ScTable::FillMaxRot( RowInfo* pRowInfo, SCSIZE nArrCount, SCCOL nX1, SCCO return nArrY; } -void ScTable::FindMaxRotCol( RowInfo* pRowInfo, SCSIZE nArrCount, SCCOL nX1, SCCOL nX2 ) const +void ScTable::FindMaxRotCol( RowInfo* pRowInfo, SCSIZE nArrCount, SCCOL nX1, SCCOL nX2 ) { - if ( !pColWidth || !pRowHeight || !pColFlags || !pRowFlags ) + if ( !pColWidth || !mpRowHeights || !pColFlags || !pRowFlags ) { DBG_ERROR( "Spalten-/Zeileninfo fehlt" ); return; @@ -1333,7 +1436,7 @@ void ScTable::FindMaxRotCol( RowInfo* pRowInfo, SCSIZE nArrCount, SCCOL nX1, SCC for (SCCOL nCol=0; nCol<=MAXCOL; nCol++) { - if ( !(pColFlags[nCol] & CR_HIDDEN) ) + if (!ColHidden(nCol)) { SCSIZE nArrY = 0; ScDocAttrIterator aIter( pDocument, nTab, nCol, nY1, nCol, nY2 ); @@ -1848,36 +1951,24 @@ void ScTable::StyleSheetChanged( const SfxStyleSheetBase* pStyleSheet, BOOL bRem double nPPTX, double nPPTY, const Fraction& rZoomX, const Fraction& rZoomY ) { - BOOL* pUsed = new BOOL[MAXROWCOUNT]; - memset( pUsed, 0, sizeof(BOOL) * (MAXROWCOUNT) ); - - SCCOL nCol; - for (nCol=0; nCol<=MAXCOL; nCol++) - aCol[nCol].FindStyleSheet( pStyleSheet, pUsed, bRemoved ); + ScFlatBoolRowSegments aUsedRows; + for (SCCOL i = 0; i <= MAXCOL; ++i) + aCol[i].FindStyleSheet(pStyleSheet, aUsedRows, bRemoved); - BOOL bFound = FALSE; - SCROW nStart = 0, nEnd = 0; - for (SCROW i=0; i<=MAXROW; i++) + SCROW nRow = 0; + while (nRow <= MAXROW) { - if (pUsed[i]) - { - if (!bFound) - { - nStart = i; - bFound = TRUE; - } - nEnd = i; - } - else if (bFound) - { - SetOptimalHeight( nStart, nEnd, 0, pDev, nPPTX, nPPTY, rZoomX, rZoomY, FALSE ); - bFound = FALSE; - } - } - if (bFound) - SetOptimalHeight( nStart, nEnd, 0, pDev, nPPTX, nPPTY, rZoomX, rZoomY, FALSE ); + ScFlatBoolRowSegments::RangeData aData; + if (!aUsedRows.getRangeData(nRow, aData)) + // search failed! + return; - delete[] pUsed; + SCROW nEndRow = aData.mnRow2; + if (aData.mbValue) + SetOptimalHeight(nRow, nEndRow, 0, pDev, nPPTX, nPPTY, rZoomX, rZoomY, FALSE); + + nRow = nEndRow + 1; + } } @@ -1959,6 +2050,8 @@ void ScTable::SetColWidth( SCCOL nCol, USHORT nNewWidth ) pDrawLayer->WidthChanged( nTab, nCol, ((long) nNewWidth) - (long) pColWidth[nCol] ); pColWidth[nCol] = nNewWidth; DecRecalcLevel(); + + InvalidatePageBreaks(); } } else @@ -1970,7 +2063,7 @@ void ScTable::SetColWidth( SCCOL nCol, USHORT nNewWidth ) void ScTable::SetRowHeight( SCROW nRow, USHORT nNewHeight ) { - if (VALIDROW(nRow) && pRowHeight) + if (VALIDROW(nRow) && mpRowHeights) { if (!nNewHeight) { @@ -1978,7 +2071,7 @@ void ScTable::SetRowHeight( SCROW nRow, USHORT nNewHeight ) nNewHeight = ScGlobal::nStdRowHeight; } - USHORT nOldHeight = pRowHeight->GetValue(nRow); + sal_uInt16 nOldHeight = mpRowHeights->getValue(nRow); if ( nNewHeight != nOldHeight ) { IncRecalcLevel(); @@ -1986,8 +2079,10 @@ void ScTable::SetRowHeight( SCROW nRow, USHORT nNewHeight ) ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer(); if (pDrawLayer) pDrawLayer->HeightChanged( nTab, nRow, ((long) nNewHeight) - (long) nOldHeight ); - pRowHeight->SetValue( nRow, nNewHeight); + mpRowHeights->setValue(nRow, nRow, nNewHeight); DecRecalcLevel(); + + InvalidatePageBreaks(); } } else @@ -1996,12 +2091,45 @@ void ScTable::SetRowHeight( SCROW nRow, USHORT nNewHeight ) } } +namespace { + +/** + * Check if the new pixel size is different from the old size between + * specified ranges. + */ +bool lcl_pixelSizeChanged( + ScFlatUInt16RowSegments& rRowHeights, SCROW nStartRow, SCROW nEndRow, + sal_uInt16 nNewHeight, double nPPTY) +{ + long nNewPix = static_cast<long>(nNewHeight * nPPTY); + + ScFlatUInt16RowSegments::ForwardIterator aFwdIter(rRowHeights); + for (SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow) + { + sal_uInt16 nHeight; + if (!aFwdIter.getValue(nRow, nHeight)) + break; + + if (nHeight != nNewHeight) + { + bool bChanged = (nNewPix != static_cast<long>(nHeight * nPPTY)); + if (bChanged) + return true; + } + + // Skip ahead to the last position of the current range. + nRow = aFwdIter.getLastPos(); + } + return false; +} + +} BOOL ScTable::SetRowHeightRange( SCROW nStartRow, SCROW nEndRow, USHORT nNewHeight, double /* nPPTX */, double nPPTY ) { BOOL bChanged = FALSE; - if (VALIDROW(nStartRow) && VALIDROW(nEndRow) && pRowHeight) + if (VALIDROW(nStartRow) && VALIDROW(nEndRow) && mpRowHeights) { IncRecalcLevel(); InitializeNoteCaptions(); @@ -2011,8 +2139,6 @@ BOOL ScTable::SetRowHeightRange( SCROW nStartRow, SCROW nEndRow, USHORT nNewHeig nNewHeight = ScGlobal::nStdRowHeight; } - long nNewPix = (long) ( nNewHeight * nPPTY ); - BOOL bSingle = FALSE; // TRUE = process every row for its own ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer(); if (pDrawLayer) @@ -2021,24 +2147,17 @@ BOOL ScTable::SetRowHeightRange( SCROW nStartRow, SCROW nEndRow, USHORT nNewHeig if (bSingle) { - size_t nIndex; - SCROW nRegionEndRow; - USHORT nOldHeight = pRowHeight->GetValue( nStartRow, nIndex, nRegionEndRow); - if (nNewHeight == nOldHeight && nEndRow <= nRegionEndRow) + ScFlatUInt16RowSegments::RangeData aData; + mpRowHeights->getRangeData(nStartRow, aData); + if (nNewHeight == aData.mnValue && nEndRow <= aData.mnRow2) bSingle = FALSE; // no difference in this range } if (bSingle) { if (nEndRow-nStartRow < 20) { - // Whether new pixel size will differ from old pixel size in any row. - ScCompressedArrayIterator< SCROW, USHORT> aIter( *pRowHeight, - nStartRow, nEndRow); - do - { - if (*aIter != nNewHeight) - bChanged = (nNewPix != (long) (*aIter * nPPTY)); - } while (!bChanged && aIter.NextRange()); + if (!bChanged) + bChanged = lcl_pixelSizeChanged(*mpRowHeights, nStartRow, nEndRow, nNewHeight, nPPTY); /* #i94028# #i94991# If drawing objects are involved, each row has to be changed for its own, because each call to @@ -2050,12 +2169,12 @@ BOOL ScTable::SetRowHeightRange( SCROW nStartRow, SCROW nEndRow, USHORT nNewHeig for( SCROW nRow = nStartRow; nRow <= nEndRow ; ++nRow ) { pDrawLayer->HeightChanged( nTab, nRow, - ((long) nNewHeight) - ((long) pRowHeight->GetValue( nRow ))); - pRowHeight->SetValue( nRow, nNewHeight ); + static_cast<long>(nNewHeight) - static_cast<long>(mpRowHeights->getValue(nRow))); + mpRowHeights->setValue(nRow, nRow, nNewHeight); } } else - pRowHeight->SetValue( nStartRow, nEndRow, nNewHeight); + mpRowHeights->setValue(nStartRow, nEndRow, nNewHeight); } else { @@ -2070,23 +2189,22 @@ BOOL ScTable::SetRowHeightRange( SCROW nStartRow, SCROW nEndRow, USHORT nNewHeig { if (pDrawLayer) { - unsigned long nOldHeights = pRowHeight->SumValues( nStartRow, nEndRow); + unsigned long nOldHeights = GetRowHeight(nStartRow, nEndRow); // FIXME: should we test for overflows? long nHeightDif = (long) (unsigned long) nNewHeight * (nEndRow - nStartRow + 1) - nOldHeights; pDrawLayer->HeightChanged( nTab, nEndRow, nHeightDif ); } - // Whether new pixel size will differ from old pixel size in any row. - ScCompressedArrayIterator< SCROW, USHORT> aIter( *pRowHeight, - nStartRow, nEndRow); - do - { - if (*aIter != nNewHeight) - bChanged = (nNewPix != (long) (*aIter * nPPTY)); - } while (!bChanged && aIter.NextRange()); - pRowHeight->SetValue( nStartRow, nEndRow, nNewHeight); + + if (!bChanged) + bChanged = lcl_pixelSizeChanged(*mpRowHeights, nStartRow, nEndRow, nNewHeight, nPPTY); + + mpRowHeights->setValue(nStartRow, nEndRow, nNewHeight); } DecRecalcLevel(); + + if (bChanged) + InvalidatePageBreaks(); } else { @@ -2096,6 +2214,16 @@ BOOL ScTable::SetRowHeightRange( SCROW nStartRow, SCROW nEndRow, USHORT nNewHeig return bChanged; } +void ScTable::SetRowHeightOnly( SCROW nStartRow, SCROW nEndRow, USHORT nNewHeight ) +{ + if (!ValidRow(nStartRow) || !ValidRow(nEndRow) || !mpRowHeights) + return; + + if (!nNewHeight) + nNewHeight = ScGlobal::nStdRowHeight; + + mpRowHeights->setValue(nStartRow, nEndRow, nNewHeight); +} void ScTable::SetManualHeight( SCROW nStartRow, SCROW nEndRow, BOOL bManual ) { @@ -2113,13 +2241,13 @@ void ScTable::SetManualHeight( SCROW nStartRow, SCROW nEndRow, BOOL bManual ) } -USHORT ScTable::GetColWidth( SCCOL nCol ) const +USHORT ScTable::GetColWidth( SCCOL nCol ) { DBG_ASSERT(VALIDCOL(nCol),"Falsche Spaltennummer"); if (VALIDCOL(nCol) && pColFlags && pColWidth) { - if ( pColFlags[nCol] & CR_HIDDEN ) + if (ColHidden(nCol)) return 0; else return pColWidth[nCol]; @@ -2140,7 +2268,7 @@ USHORT ScTable::GetOriginalWidth( SCCOL nCol ) const // immer die eingest } -USHORT ScTable::GetCommonWidth( SCCOL nEndCol ) const +USHORT ScTable::GetCommonWidth( SCCOL nEndCol ) { // get the width that is used in the largest continuous column range (up to nEndCol) @@ -2152,24 +2280,24 @@ USHORT ScTable::GetCommonWidth( SCCOL nEndCol ) const USHORT nMaxWidth = 0; USHORT nMaxCount = 0; - USHORT nRangeStart = 0; + SCCOL nRangeStart = 0; while ( nRangeStart <= nEndCol ) { // skip hidden columns - while ( nRangeStart <= nEndCol && (pColFlags[nRangeStart] & CR_HIDDEN) ) + while ( nRangeStart <= nEndCol && ColHidden(nRangeStart) ) ++nRangeStart; if ( nRangeStart <= nEndCol ) { USHORT nThisCount = 0; USHORT nThisWidth = pColWidth[nRangeStart]; - USHORT nRangeEnd = nRangeStart; + SCCOL nRangeEnd = nRangeStart; while ( nRangeEnd <= nEndCol && pColWidth[nRangeEnd] == nThisWidth ) { ++nThisCount; ++nRangeEnd; // skip hidden columns - while ( nRangeEnd <= nEndCol && (pColFlags[nRangeEnd] & CR_HIDDEN) ) + while ( nRangeEnd <= nEndCol && ColHidden(nRangeEnd) ) ++nRangeEnd; } @@ -2187,44 +2315,80 @@ USHORT ScTable::GetCommonWidth( SCCOL nEndCol ) const } -USHORT ScTable::GetRowHeight( SCROW nRow ) const +USHORT ScTable::GetRowHeight( SCROW nRow, SCROW* pStartRow, SCROW* pEndRow, bool bHiddenAsZero ) { DBG_ASSERT(VALIDROW(nRow),"Falsche Zeilennummer"); - if (VALIDROW(nRow) && pRowFlags && pRowHeight) + if (VALIDROW(nRow) && mpRowHeights) { - if ( pRowFlags->GetValue(nRow) & CR_HIDDEN ) + if (bHiddenAsZero && RowHidden(nRow)) return 0; else - return pRowHeight->GetValue(nRow); + { + ScFlatUInt16RowSegments::RangeData aData; + if (!mpRowHeights->getRangeData(nRow, aData)) + // TODO: What should we return in case the search fails? + return 0; + + if (pStartRow) + *pStartRow = aData.mnRow1; + if (pEndRow) + *pEndRow = aData.mnRow2; + return aData.mnValue; + } } else return (USHORT) ScGlobal::nStdRowHeight; } -ULONG ScTable::GetRowHeight( SCROW nStartRow, SCROW nEndRow ) const +ULONG ScTable::GetRowHeight( SCROW nStartRow, SCROW nEndRow ) { DBG_ASSERT(VALIDROW(nStartRow) && VALIDROW(nEndRow),"Falsche Zeilennummer"); - if (VALIDROW(nStartRow) && VALIDROW(nEndRow) && pRowFlags && pRowHeight) + if (VALIDROW(nStartRow) && VALIDROW(nEndRow) && mpRowHeights) { - return pRowFlags->SumCoupledArrayForCondition( nStartRow, nEndRow, - CR_HIDDEN, 0, *pRowHeight); + ULONG nHeight = 0; + SCROW nRow = nStartRow; + while (nRow <= nEndRow) + { + SCROW nLastRow = -1; + if (!RowHidden(nRow, nLastRow)) + { + if (nLastRow > nEndRow) + nLastRow = nEndRow; + nHeight += mpRowHeights->getSumValue(nRow, nLastRow); + } + nRow = nLastRow + 1; + } + return nHeight; } else return (ULONG) ((nEndRow - nStartRow + 1) * ScGlobal::nStdRowHeight); } -ULONG ScTable::GetScaledRowHeight( SCROW nStartRow, SCROW nEndRow, double fScale ) const +ULONG ScTable::GetScaledRowHeight( SCROW nStartRow, SCROW nEndRow, double fScale ) { DBG_ASSERT(VALIDROW(nStartRow) && VALIDROW(nEndRow),"Falsche Zeilennummer"); - if (VALIDROW(nStartRow) && VALIDROW(nEndRow) && pRowFlags && pRowHeight) + if (VALIDROW(nStartRow) && VALIDROW(nEndRow) && mpRowHeights) { - return pRowFlags->SumScaledCoupledArrayForCondition( nStartRow, - nEndRow, CR_HIDDEN, 0, *pRowHeight, fScale); + ULONG nHeight = 0; + SCROW nRow = nStartRow; + while (nRow <= nEndRow) + { + SCROW nLastRow = -1; + if (!RowHidden(nRow, nLastRow)) + { + if (nLastRow > nEndRow) + nLastRow = nEndRow; + sal_uInt32 nThisHeight = mpRowHeights->getSumValue(nRow, nLastRow); + nHeight += static_cast<ULONG>(nThisHeight * fScale); + } + nRow = nLastRow + 1; + } + return nHeight; } else return (ULONG) ((nEndRow - nStartRow + 1) * ScGlobal::nStdRowHeight * fScale); @@ -2235,8 +2399,8 @@ USHORT ScTable::GetOriginalHeight( SCROW nRow ) const // non-0 even if hid { DBG_ASSERT(VALIDROW(nRow),"wrong row number"); - if (VALIDROW(nRow) && pRowHeight) - return pRowHeight->GetValue(nRow); + if (VALIDROW(nRow) && mpRowHeights) + return mpRowHeights->getValue(nRow); else return (USHORT) ScGlobal::nStdRowHeight; } @@ -2245,28 +2409,26 @@ USHORT ScTable::GetOriginalHeight( SCROW nRow ) const // non-0 even if hid // Spalten-/Zeilen-Flags -SCROW ScTable::GetHiddenRowCount( SCROW nRow ) const +SCROW ScTable::GetHiddenRowCount( SCROW nRow ) { - SCROW nEndRow = nRow; - if ( pRowFlags ) - { - nEndRow = pRowFlags->GetBitStateEnd( nRow, CR_HIDDEN, CR_HIDDEN); - if (ValidRow(nEndRow)) - ++nEndRow; - else - nEndRow = nRow; - } - return nEndRow - nRow; + if (!ValidRow(nRow)) + return 0; + + SCROW nLastRow = -1; + if (!RowHidden(nRow, nLastRow) || !ValidRow(nLastRow)) + return 0; + + return nLastRow - nRow + 1; } //! ShowRows / DBShowRows zusammenfassen -void ScTable::ShowCol(SCCOL nCol, BOOL bShow) +void ScTable::ShowCol(SCCOL nCol, bool bShow) { - if (VALIDCOL(nCol) && pColFlags) + if (VALIDCOL(nCol)) { - BOOL bWasVis = ( pColFlags[nCol] & CR_HIDDEN ) == 0; + bool bWasVis = !ColHidden(nCol); if (bWasVis != bShow) { IncRecalcLevel(); @@ -2280,11 +2442,8 @@ void ScTable::ShowCol(SCCOL nCol, BOOL bShow) pDrawLayer->WidthChanged( nTab, nCol, -(long) pColWidth[nCol] ); } - if (bShow) - pColFlags[nCol] &= ~CR_HIDDEN; - else - pColFlags[nCol] |= CR_HIDDEN; - DecRecalcLevel(); + SetColHidden(nCol, nCol, !bShow); + DecRecalcLevel(); ScChartListenerCollection* pCharts = pDocument->GetChartListenerCollection(); if ( pCharts ) @@ -2298,12 +2457,11 @@ void ScTable::ShowCol(SCCOL nCol, BOOL bShow) } -void ScTable::ShowRow(SCROW nRow, BOOL bShow) +void ScTable::ShowRow(SCROW nRow, bool bShow) { if (VALIDROW(nRow) && pRowFlags) { - BYTE nFlags = pRowFlags->GetValue(nRow); - BOOL bWasVis = ( nFlags & CR_HIDDEN ) == 0; + bool bWasVis = !RowHidden(nRow); if (bWasVis != bShow) { IncRecalcLevel(); @@ -2312,20 +2470,23 @@ void ScTable::ShowRow(SCROW nRow, BOOL bShow) if (pDrawLayer) { if (bShow) - pDrawLayer->HeightChanged( nTab, nRow, (long) pRowHeight->GetValue(nRow) ); + pDrawLayer->HeightChanged( + nTab, nRow, static_cast<long>(mpRowHeights->getValue(nRow))); else - pDrawLayer->HeightChanged( nTab, nRow, -(long) pRowHeight->GetValue(nRow) ); + pDrawLayer->HeightChanged( + nTab, nRow, -static_cast<long>(mpRowHeights->getValue(nRow))); } + SetRowHidden(nRow, nRow, !bShow); if (bShow) - pRowFlags->SetValue( nRow, nFlags & ~(CR_HIDDEN | CR_FILTERED)); - else - pRowFlags->SetValue( nRow, nFlags | CR_HIDDEN); - DecRecalcLevel(); + SetRowFiltered(nRow, nRow, false); + DecRecalcLevel(); ScChartListenerCollection* pCharts = pDocument->GetChartListenerCollection(); if ( pCharts ) pCharts->SetRangeDirty(ScRange( 0, nRow, nTab, MAXCOL, nRow, nTab )); + + InvalidatePageBreaks(); } } else @@ -2335,12 +2496,11 @@ void ScTable::ShowRow(SCROW nRow, BOOL bShow) } -void ScTable::DBShowRow(SCROW nRow, BOOL bShow) +void ScTable::DBShowRow(SCROW nRow, bool bShow) { if (VALIDROW(nRow) && pRowFlags) { - BYTE nFlags = pRowFlags->GetValue(nRow); - BOOL bWasVis = ( nFlags & CR_HIDDEN ) == 0; + bool bWasVis = !RowHidden(nRow); IncRecalcLevel(); InitializeNoteCaptions(); if (bWasVis != bShow) @@ -2349,18 +2509,18 @@ void ScTable::DBShowRow(SCROW nRow, BOOL bShow) if (pDrawLayer) { if (bShow) - pDrawLayer->HeightChanged( nTab, nRow, (long) pRowHeight->GetValue(nRow) ); + pDrawLayer->HeightChanged( + nTab, nRow, static_cast<long>(mpRowHeights->getValue(nRow))); else - pDrawLayer->HeightChanged( nTab, nRow, -(long) pRowHeight->GetValue(nRow) ); + pDrawLayer->HeightChanged( + nTab, nRow, -static_cast<long>(mpRowHeights->getValue(nRow))); } } // Filter-Flag immer setzen, auch wenn Hidden unveraendert - if (bShow) - pRowFlags->SetValue( nRow, nFlags & ~(CR_HIDDEN | CR_FILTERED)); - else - pRowFlags->SetValue( nRow, nFlags | (CR_HIDDEN | CR_FILTERED)); - DecRecalcLevel(); + SetRowHidden(nRow, nRow, !bShow); + SetRowFiltered(nRow, nRow, !bShow); + DecRecalcLevel(); if (bWasVis != bShow) { @@ -2370,6 +2530,8 @@ void ScTable::DBShowRow(SCROW nRow, BOOL bShow) if (pOutlineTable) UpdateOutlineRow( nRow, nRow, bShow ); + + InvalidatePageBreaks(); } } else @@ -2379,26 +2541,25 @@ void ScTable::DBShowRow(SCROW nRow, BOOL bShow) } -void ScTable::DBShowRows(SCROW nRow1, SCROW nRow2, BOOL bShow) +void ScTable::DBShowRows(SCROW nRow1, SCROW nRow2, bool bShow) { SCROW nStartRow = nRow1; IncRecalcLevel(); InitializeNoteCaptions(); while (nStartRow <= nRow2) { - BYTE nOldFlag = pRowFlags->GetValue(nStartRow) & CR_HIDDEN; - SCROW nEndRow = pRowFlags->GetBitStateEnd( nStartRow, CR_HIDDEN, nOldFlag); + SCROW nEndRow = -1; + bool bWasVis = !RowHidden(nStartRow, nEndRow); if (nEndRow > nRow2) nEndRow = nRow2; - BOOL bWasVis = ( nOldFlag == 0 ); BOOL bChanged = ( bWasVis != bShow ); if ( bChanged ) { ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer(); if (pDrawLayer) { - long nHeight = (long) pRowHeight->SumValues( nStartRow, nEndRow); + long nHeight = static_cast<long>(mpRowHeights->getSumValue(nStartRow, nEndRow)); if (bShow) pDrawLayer->HeightChanged( nTab, nStartRow, nHeight ); else @@ -2406,10 +2567,8 @@ void ScTable::DBShowRows(SCROW nRow1, SCROW nRow2, BOOL bShow) } } - if (bShow) - pRowFlags->AndValue( nStartRow, nEndRow, sal::static_int_cast<BYTE>(~(CR_HIDDEN | CR_FILTERED)) ); - else - pRowFlags->OrValue( nStartRow, nEndRow, (CR_HIDDEN | CR_FILTERED)); + SetRowHidden(nStartRow, nEndRow, !bShow); + SetRowFiltered(nStartRow, nEndRow, !bShow); if ( bChanged ) { @@ -2431,26 +2590,25 @@ void ScTable::DBShowRows(SCROW nRow1, SCROW nRow2, BOOL bShow) } -void ScTable::ShowRows(SCROW nRow1, SCROW nRow2, BOOL bShow) +void ScTable::ShowRows(SCROW nRow1, SCROW nRow2, bool bShow) { SCROW nStartRow = nRow1; IncRecalcLevel(); InitializeNoteCaptions(); while (nStartRow <= nRow2) { - BYTE nOldFlag = pRowFlags->GetValue(nStartRow) & CR_HIDDEN; - SCROW nEndRow = pRowFlags->GetBitStateEnd( nStartRow, CR_HIDDEN, nOldFlag); + SCROW nEndRow = -1; + bool bWasVis = !RowHidden(nStartRow, nEndRow); if (nEndRow > nRow2) nEndRow = nRow2; - BOOL bWasVis = ( nOldFlag == 0 ); BOOL bChanged = ( bWasVis != bShow ); if ( bChanged ) { ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer(); if (pDrawLayer) { - long nHeight = (long) pRowHeight->SumValues( nStartRow, nEndRow); + long nHeight = static_cast<long>(mpRowHeights->getSumValue(nStartRow, nEndRow)); if (bShow) pDrawLayer->HeightChanged( nTab, nStartRow, nHeight ); else @@ -2458,16 +2616,17 @@ void ScTable::ShowRows(SCROW nRow1, SCROW nRow2, BOOL bShow) } } + SetRowHidden(nStartRow, nEndRow, !bShow); if (bShow) - pRowFlags->AndValue( nStartRow, nEndRow, sal::static_int_cast<BYTE>(~(CR_HIDDEN | CR_FILTERED)) ); - else - pRowFlags->OrValue( nStartRow, nEndRow, CR_HIDDEN); + SetRowFiltered(nStartRow, nEndRow, false); if ( bChanged ) { ScChartListenerCollection* pCharts = pDocument->GetChartListenerCollection(); if ( pCharts ) pCharts->SetRangeDirty(ScRange( 0, nStartRow, nTab, MAXCOL, nEndRow, nTab )); + + InvalidatePageBreaks(); } nStartRow = nEndRow + 1; @@ -2476,16 +2635,6 @@ void ScTable::ShowRows(SCROW nRow1, SCROW nRow2, BOOL bShow) } -BOOL ScTable::IsFiltered(SCROW nRow) const -{ - if (VALIDROW(nRow) && pRowFlags) - return ( pRowFlags->GetValue(nRow) & CR_FILTERED ) != 0; - - DBG_ERROR("Falsche Zeilennummer oder keine Flags"); - return FALSE; -} - - void ScTable::SetColFlags( SCCOL nCol, BYTE nNewFlags ) { if (VALIDCOL(nCol) && pColFlags) @@ -2539,11 +2688,32 @@ BYTE ScTable::GetRowFlags( SCROW nRow ) const SCROW ScTable::GetLastFlaggedRow() const { - if ( !pRowFlags ) - return 0; + SCROW nLastFound = 0; + if (pRowFlags) + { + SCROW nRow = pRowFlags->GetLastAnyBitAccess( 0, sal::static_int_cast<BYTE>(CR_ALL) ); + if (ValidRow(nRow)) + nLastFound = nRow; + } + + if (!maRowManualBreaks.empty()) + nLastFound = ::std::max(nLastFound, *maRowManualBreaks.rbegin()); + + if (mpHiddenRows) + { + SCROW nRow = mpHiddenRows->findLastNotOf(false); + if (ValidRow(nRow)) + nLastFound = ::std::max(nLastFound, nRow); + } + + if (mpFilteredRows) + { + SCROW nRow = mpFilteredRows->findLastNotOf(false); + if (ValidRow(nRow)) + nLastFound = ::std::max(nLastFound, nRow); + } - SCROW nLastFound = pRowFlags->GetLastAnyBitAccess( 0, sal::static_int_cast<BYTE>(~CR_PAGEBREAK) ); - return ValidRow(nLastFound) ? nLastFound : 0; + return nLastFound; } @@ -2554,7 +2724,7 @@ SCCOL ScTable::GetLastChangedCol() const SCCOL nLastFound = 0; for (SCCOL nCol = 1; nCol <= MAXCOL; nCol++) - if ((pColFlags[nCol] & ~CR_PAGEBREAK) || (pColWidth[nCol] != STD_COL_WIDTH)) + if ((pColFlags[nCol] & CR_ALL) || (pColWidth[nCol] != STD_COL_WIDTH)) nLastFound = nCol; return nLastFound; @@ -2566,11 +2736,12 @@ SCROW ScTable::GetLastChangedRow() const if ( !pRowFlags ) return 0; - SCROW nLastFlags = pRowFlags->GetLastAnyBitAccess( 0, sal::static_int_cast<BYTE>(~CR_PAGEBREAK) ); - if (!ValidRow(nLastFlags)) - nLastFlags = 0; + SCROW nLastFlags = GetLastFlaggedRow(); - SCROW nLastHeight = pRowHeight->GetLastUnequalAccess( 0, ScGlobal::nStdRowHeight); + // Find the last row position where the height is NOT the standard row + // height. + // KOHEI: Test this to make sure it does what it's supposed to. + SCROW nLastHeight = mpRowHeights->findLastNotOf(ScGlobal::nStdRowHeight); if (!ValidRow(nLastHeight)) nLastHeight = 0; @@ -2583,7 +2754,7 @@ BOOL ScTable::UpdateOutlineCol( SCCOL nStartCol, SCCOL nEndCol, BOOL bShow ) if (pOutlineTable && pColFlags) { ScBitMaskCompressedArray< SCCOLROW, BYTE> aArray( MAXCOL, pColFlags, MAXCOLCOUNT); - return pOutlineTable->GetColArray()->ManualAction( nStartCol, nEndCol, bShow, aArray ); + return pOutlineTable->GetColArray()->ManualAction( nStartCol, nEndCol, bShow, *this, true ); } else return FALSE; @@ -2593,7 +2764,7 @@ BOOL ScTable::UpdateOutlineCol( SCCOL nStartCol, SCCOL nEndCol, BOOL bShow ) BOOL ScTable::UpdateOutlineRow( SCROW nStartRow, SCROW nEndRow, BOOL bShow ) { if (pOutlineTable && pRowFlags) - return pOutlineTable->GetRowArray()->ManualAction( nStartRow, nEndRow, bShow, *pRowFlags ); + return pOutlineTable->GetRowArray()->ManualAction( nStartRow, nEndRow, bShow, *this, false ); else return FALSE; } @@ -2601,54 +2772,58 @@ BOOL ScTable::UpdateOutlineRow( SCROW nStartRow, SCROW nEndRow, BOOL bShow ) void ScTable::ExtendHidden( SCCOL& rX1, SCROW& rY1, SCCOL& rX2, SCROW& rY2 ) { - if (pColFlags) - { - while ( rX1>0 ? (pColFlags[rX1-1] & CR_HIDDEN) : FALSE ) - --rX1; - while ( rX2<MAXCOL ? (pColFlags[rX2+1] & CR_HIDDEN) : FALSE ) - ++rX2; - } - if (pRowFlags) + // Column-wise expansion + + while (rX1 > 0 && ColHidden(rX1-1)) + --rX1; + + while (rX2 < MAXCOL && ColHidden(rX2+1)) + ++rX2; + + // Row-wise expansion + + if (rY1 > 0) { - if (rY1 > 0) + ScFlatBoolRowSegments::RangeData aData; + if (mpHiddenRows->getRangeData(rY1-1, aData) && aData.mbValue) { - SCROW nStartRow = pRowFlags->GetBitStateStart( rY1-1, CR_HIDDEN, CR_HIDDEN); + SCROW nStartRow = aData.mnRow1; if (ValidRow(nStartRow)) rY1 = nStartRow; } - if (rY2 < MAXROW) - { - SCROW nEndRow = pRowFlags->GetBitStateEnd( rY2+1, CR_HIDDEN, CR_HIDDEN); - if (ValidRow(nEndRow)) - rY2 = nEndRow; - } + } + if (rY2 < MAXROW) + { + SCROW nEndRow = -1; + if (RowHidden(rY2+1, nEndRow) && ValidRow(nEndRow)) + rY2 = nEndRow; } } void ScTable::StripHidden( SCCOL& rX1, SCROW& rY1, SCCOL& rX2, SCROW& rY2 ) { - if (pColFlags) - { - while ( rX2>rX1 && (pColFlags[rX2] & CR_HIDDEN) ) - --rX2; - while ( rX2>rX1 && (pColFlags[rX1] & CR_HIDDEN) ) - ++rX1; - } - if (pRowFlags) + while ( rX2>rX1 && ColHidden(rX2) ) + --rX2; + while ( rX2>rX1 && ColHidden(rX1) ) + ++rX1; + + if (rY1 < rY2) { - if (rY1 < rY2) + ScFlatBoolRowSegments::RangeData aData; + if (mpHiddenRows->getRangeData(rY2, aData) && aData.mbValue) { - SCROW nStartRow = pRowFlags->GetBitStateStart( rY2, CR_HIDDEN, CR_HIDDEN); + SCROW nStartRow = aData.mnRow1; if (ValidRow(nStartRow) && nStartRow >= rY1) rY2 = nStartRow; } - if (rY1 < rY2) - { - SCROW nEndRow = pRowFlags->GetBitStateEnd( rY1, CR_HIDDEN, CR_HIDDEN); - if (ValidRow(nEndRow) && nEndRow <= rY2) - rY1 = nEndRow; - } + } + + if (rY1 < rY2) + { + SCROW nEndRow = -1; + if (RowHidden(rY1, nEndRow) && ValidRow(nEndRow) && nEndRow <= rY2) + rY1 = nEndRow; } } @@ -2810,16 +2985,16 @@ BOOL ScTable::RefVisible(ScFormulaCell* pCell) if (pCell->HasOneReference(aRef)) { - if (aRef.aStart.Col()==aRef.aEnd.Col() && aRef.aStart.Tab()==aRef.aEnd.Tab() && pRowFlags) + if (aRef.aStart.Col()==aRef.aEnd.Col() && aRef.aStart.Tab()==aRef.aEnd.Tab()) { - // while ((value & CR_FILTERED) == CR_FILTERED) - // most times will be faster than - // while ((value & CR_FILTERED) == 0) - SCROW nEndRow = pRowFlags->GetBitStateEnd( aRef.aStart.Row(), - CR_FILTERED, CR_FILTERED); + SCROW nEndRow; + if (!RowFiltered(aRef.aStart.Row(), NULL, &nEndRow)) + // row not filtered. + nEndRow = ::std::numeric_limits<SCROW>::max(); + if (!ValidRow(nEndRow) || nEndRow < aRef.aEnd.Row()) return TRUE; // at least partly visible - return FALSE; // completely unvisible + return FALSE; // completely invisible } } @@ -2861,18 +3036,17 @@ void ScTable::SetDrawPageSize(bool bResetStreamValid, bool bUpdateNoteCaptionPos } -ULONG ScTable::GetRowOffset( SCROW nRow ) const +ULONG ScTable::GetRowOffset( SCROW nRow ) { ULONG n = 0; - if ( pRowFlags && pRowHeight ) + if ( mpHiddenRows && mpRowHeights ) { if (nRow == 0) return 0; else if (nRow == 1) return GetRowHeight(0); - n = pRowFlags->SumCoupledArrayForCondition( 0, nRow-1, CR_HIDDEN, 0, - *pRowHeight); + n = GetTotalRowHeight(0, nRow-1); #ifdef DBG_UTIL if (n == ::std::numeric_limits<unsigned long>::max()) DBG_ERRORFILE("ScTable::GetRowOffset: row heights overflow"); @@ -2885,18 +3059,42 @@ ULONG ScTable::GetRowOffset( SCROW nRow ) const return n; } +SCROW ScTable::GetRowForHeight(ULONG nHeight) +{ + sal_uInt32 nSum = 0; + + ScFlatBoolRowSegments::RangeData aData; + for (SCROW nRow = 0; nRow <= MAXROW; ++nRow) + { + if (!mpHiddenRows->getRangeData(nRow, aData)) + break; + + if (aData.mbValue) + { + nRow = aData.mnRow2; + continue; + } + + sal_uInt32 nNew = mpRowHeights->getValue(nRow); + nSum += nNew; + if (nSum > nHeight) + { + return nRow < MAXROW ? nRow + 1 : MAXROW; + } + } + return -1; +} + -ULONG ScTable::GetColOffset( SCCOL nCol ) const +ULONG ScTable::GetColOffset( SCCOL nCol ) { ULONG n = 0; - if ( pColFlags && pColWidth ) + if ( pColWidth ) { SCCOL i; - BYTE* pFlags = pColFlags; - USHORT* pWidth = pColWidth; - for( i = 0; i < nCol; i++, pFlags++, pWidth++ ) - if( !( *pFlags & CR_HIDDEN ) ) - n += *pWidth; + for( i = 0; i < nCol; i++ ) + if (!ColHidden(i)) + n += pColWidth[i]; } else { diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx index 90993367dde6..bd6a2c92c442 100644 --- a/sc/source/core/data/table3.cxx +++ b/sc/source/core/data/table3.cxx @@ -208,17 +208,14 @@ void ScTable::SortReorder( ScSortInfoArray* pArray, ScProgress& rProgress ) { BOOL bByRow = aSortParam.bByRow; SCSIZE nCount = pArray->GetCount(); + SCCOLROW nStart = pArray->GetStart(); ScSortInfo** ppInfo = pArray->GetFirstArray(); - // hngngn.. Win16 legacy? Table has ULONG count but can only be initialized using USHORT :-/ - // FIXME: use std::vector instead, would be better anyway (type safe) - USHORT nArghl = (nCount > USHRT_MAX ? USHRT_MAX : static_cast<USHORT>(nCount)); - Table aTable( nArghl ); + ::std::vector<ScSortInfo*> aTable(nCount); SCSIZE nPos; for ( nPos = 0; nPos < nCount; nPos++ ) - { - aTable.Insert( ppInfo[nPos]->nOrg, (void*) ppInfo[nPos] ); - } - SCCOLROW nDest = pArray->GetStart(); + aTable[ppInfo[nPos]->nOrg - nStart] = ppInfo[nPos]; + + SCCOLROW nDest = nStart; for ( nPos = 0; nPos < nCount; nPos++, nDest++ ) { SCCOLROW nOrg = ppInfo[nPos]->nOrg; @@ -231,9 +228,9 @@ void ScTable::SortReorder( ScSortInfoArray* pArray, ScProgress& rProgress ) // neue Position des weggeswapten eintragen ScSortInfo* p = ppInfo[nPos]; p->nOrg = nDest; - p = (ScSortInfo*) aTable.Replace( nDest, (void*) p ); + ::std::swap(p, aTable[nDest-nStart]); p->nOrg = nOrg; - p = (ScSortInfo*) aTable.Replace( nOrg, (void*) p ); + ::std::swap(p, aTable[nOrg-nStart]); DBG_ASSERT( p == ppInfo[nPos], "SortReorder: nOrg MisMatch" ); } rProgress.SetStateOnPercent( nPos ); @@ -449,14 +446,17 @@ void ScTable::SwapRow(SCROW nRow1, SCROW nRow2) } } } - if (bGlobalKeepQuery && pRowFlags) + if (bGlobalKeepQuery) { - BYTE nRow1Flags = pRowFlags->GetValue(nRow1); - BYTE nRow2Flags = pRowFlags->GetValue(nRow2); - BYTE nFlags1 = nRow1Flags & ( CR_HIDDEN | CR_FILTERED ); - BYTE nFlags2 = nRow2Flags & ( CR_HIDDEN | CR_FILTERED ); - pRowFlags->SetValue( nRow1, (nRow1Flags & ~( CR_HIDDEN | CR_FILTERED )) | nFlags2); - pRowFlags->SetValue( nRow2, (nRow2Flags & ~( CR_HIDDEN | CR_FILTERED )) | nFlags1); + bool bRow1Hidden = RowHidden(nRow1); + bool bRow2Hidden = RowHidden(nRow2); + SetRowHidden(nRow1, nRow1, bRow2Hidden); + SetRowHidden(nRow2, nRow2, bRow1Hidden); + + bool bRow1Filtered = RowFiltered(nRow1); + bool bRow2Filtered = RowFiltered(nRow2); + SetRowFiltered(nRow1, nRow1, bRow2Filtered); + SetRowFiltered(nRow2, nRow2, bRow1Filtered); } } @@ -616,7 +616,7 @@ void ScTable::RemoveSubTotals( ScSubTotalParam& rParam ) if ( pCell->GetCellType() == CELLTYPE_FORMULA ) if (((ScFormulaCell*)pCell)->IsSubTotal()) { - SetRowFlags(nRow+1,GetRowFlags(nRow+1)&(~CR_MANUALBREAK)); + RemoveRowBreak(nRow+1, false, true); pDocument->DeleteRow( 0,nTab, MAXCOL,nTab, nRow, 1 ); --nEndRow; aIter = ScColumnIterator( &aCol[nCol],nRow,nEndRow ); @@ -784,9 +784,7 @@ BOOL ScTable::DoSubTotals( ScSubTotalParam& rParam ) bBlockVis = FALSE; if ( rParam.bPagebreak && nRow < MAXROW && aRowEntry.nSubStartRow != nStartRow && nLevel == 0) - SetRowFlags( aRowEntry.nSubStartRow, - GetRowFlags(aRowEntry.nSubStartRow) | - CR_MANUALBREAK); + SetRowBreak(aRowEntry.nSubStartRow, false, true); if (bSpaceLeft) { @@ -839,13 +837,6 @@ BOOL ScTable::DoSubTotals( ScSubTotalParam& rParam ) SetString( nGroupCol[aRowEntry.nGroupNo], aRowEntry.nDestRow, nTab, aOutString ); ApplyStyle( nGroupCol[aRowEntry.nGroupNo], aRowEntry.nDestRow, *pStyle ); -/* if (rParam.bPagebreak && nRow < MAXROW) - { - BYTE nFlags = GetRowFlags( nRow+1 ); - nFlags |= CR_MANUALBREAK; - SetRowFlags( nRow+1, nFlags ); - } -*/ ++nRow; ++nEndRow; aRowEntry.nSubStartRow = nRow; @@ -859,11 +850,7 @@ BOOL ScTable::DoSubTotals( ScSubTotalParam& rParam ) } } } - if (!pRowFlags) - bBlockVis = TRUE; - else - if ( (pRowFlags->GetValue(nRow) & CR_FILTERED) == 0 ) - bBlockVis = TRUE; + bBlockVis = !RowFiltered(nRow); } } else @@ -1913,8 +1900,8 @@ sal_Int32 ScTable::GetMaxStringLen( SCCOL nCol, SCROW nRowStart, return 0; } -xub_StrLen ScTable::GetMaxNumberStringLen( USHORT& nPrecision, SCCOL nCol, - SCROW nRowStart, SCROW nRowEnd ) const +xub_StrLen ScTable::GetMaxNumberStringLen( + sal_uInt16& nPrecision, SCCOL nCol, SCROW nRowStart, SCROW nRowEnd ) const { if ( ValidCol(nCol) ) return aCol[nCol].GetMaxNumberStringLen( nPrecision, nRowStart, nRowEnd ); @@ -1935,8 +1922,8 @@ void ScTable::UpdateSelectionFunction( ScFunctionData& rData, SCCOL nCol; if ( rMark.IsMultiMarked() ) for (nCol=0; nCol<=MAXCOL && !rData.bError; nCol++) - if ( !pColFlags || !( pColFlags[nCol] & CR_HIDDEN ) ) - aCol[nCol].UpdateSelectionFunction( rMark, rData, pRowFlags, + if ( !pColFlags || !ColHidden(nCol) ) + aCol[nCol].UpdateSelectionFunction( rMark, rData, *mpHiddenRows, bSingle && ( nCol >= nStartCol && nCol <= nEndCol ), nStartRow, nEndRow ); @@ -1944,8 +1931,8 @@ void ScTable::UpdateSelectionFunction( ScFunctionData& rData, if ( bSingle && !rMark.IsMarkNegative() ) for (nCol=nStartCol; nCol<=nEndCol && !rData.bError; nCol++) - if ( !pColFlags || !( pColFlags[nCol] & CR_HIDDEN ) ) - aCol[nCol].UpdateAreaFunction( rData, pRowFlags, nStartRow, nEndRow ); + if ( !pColFlags || !ColHidden(nCol) ) + aCol[nCol].UpdateAreaFunction( rData, *mpHiddenRows, nStartRow, nEndRow ); } void ScTable::FindConditionalFormat( ULONG nKey, ScRangeList& rList ) 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..2635b5821e4f 100644 --- a/sc/source/core/data/table5.cxx +++ b/sc/source/core/data/table5.cxx @@ -50,8 +50,15 @@ #include "brdcst.hxx" #include "tabprotection.hxx" #include "globstr.hrc" +#include "segmenttree.hxx" +#include <com/sun/star/sheet/TablePageBreakData.hpp> + +#include <algorithm> +#include <limits> using ::com::sun::star::uno::Sequence; +using ::com::sun::star::sheet::TablePageBreakData; +using ::std::set; // STATIC DATA ----------------------------------------------------------- @@ -62,8 +69,18 @@ void ScTable::UpdatePageBreaks( const ScRange* pUserArea ) { if ( pDocument->IsImportingXML() ) return; - if ( !pUserArea && !bPageSizeValid ) - return; + + // pUserArea != NULL -> print area is specified. We need to force-update + // the page breaks. + + if (!pUserArea) + { + if (!bPageSizeValid) + return; + + if (mbPageBreaksValid) + return; + } SfxStyleSheetBase* pStyle = pDocument->GetStyleSheetPool()-> Find( aPageStyle, SFX_STYLE_FAMILY_PAGE ); @@ -76,7 +93,6 @@ void ScTable::UpdatePageBreaks( const ScRange* pUserArea ) const SfxPoolItem* pItem; SCCOL nX; - SCROW nY; SCCOL nStartCol = 0; SCROW nStartRow = 0; SCCOL nEndCol = MAXCOL; @@ -96,8 +112,9 @@ void ScTable::UpdatePageBreaks( const ScRange* pUserArea ) // bei mehreren Bereichen nichts anzeigen: for (nX=0; nX<MAXCOL; nX++) - pColFlags[nX] &= ~CR_PAGEBREAK; - pRowFlags->AndValue( 0, MAXROW-1, sal::static_int_cast<BYTE>(~CR_PAGEBREAK) ); + RemoveColBreak(nX, true, false); + + RemoveRowPageBreaks(0, MAXROW-1); return; } @@ -114,14 +131,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; } //-------------------------------------------------------------------------- @@ -132,13 +160,13 @@ void ScTable::UpdatePageBreaks( const ScRange* pUserArea ) // Anfang: Breaks loeschen for (nX=0; nX<nStartCol; nX++) - pColFlags[nX] &= ~CR_PAGEBREAK; - pRowFlags->AndValue( 0, nStartRow-1, sal::static_int_cast<BYTE>(~CR_PAGEBREAK) ); + RemoveColBreak(nX, true, false); + RemoveRowPageBreaks(0, nStartRow-1); if (nStartCol > 0) - pColFlags[nStartCol] |= CR_PAGEBREAK; //! AREABREAK + SetColBreak(nStartCol, true, false); // AREABREAK if (nStartRow > 0) - pRowFlags->OrValue( nStartRow, CR_PAGEBREAK); //! AREABREAK + SetRowBreak(nStartRow, true, false); // AREABREAK // Mittelteil: Breaks verteilen @@ -148,15 +176,16 @@ void ScTable::UpdatePageBreaks( const ScRange* pUserArea ) for (nX=nStartCol; nX<=nEndCol; nX++) { BOOL bStartOfPage = FALSE; - long nThisX = ( pColFlags[nX] & CR_HIDDEN ) ? 0 : pColWidth[nX]; - if ( (nSizeX+nThisX > nPageSizeX) || ((pColFlags[nX] & CR_MANUALBREAK) && !bSkipBreaks) ) + long nThisX = ColHidden(nX) ? 0 : pColWidth[nX]; + bool bManualBreak = HasColManualBreak(nX); + if ( (nSizeX+nThisX > nPageSizeX) || (bManualBreak && !bSkipColBreaks) ) { - pColFlags[nX] |= CR_PAGEBREAK; + SetColBreak(nX, true, false); nSizeX = 0; bStartOfPage = TRUE; } else if (nX != nStartCol) - pColFlags[nX] &= ~CR_PAGEBREAK; + RemoveColBreak(nX, true, false); else bStartOfPage = TRUE; @@ -164,9 +193,9 @@ void ScTable::UpdatePageBreaks( const ScRange* pUserArea ) { // subtract size of repeat columns from page size for (SCCOL i=nRepeatStartX; i<=nRepeatEndX; i++) - nPageSizeX -= ( pColFlags[i] & CR_HIDDEN ) ? 0 : pColWidth[i]; + nPageSizeX -= ColHidden(i) ? 0 : pColWidth[i]; while (nX<=nRepeatEndX) - pColFlags[++nX] &= ~CR_PAGEBREAK; + RemoveColBreak(++nX, true, false); bColFound = TRUE; } @@ -174,23 +203,40 @@ void ScTable::UpdatePageBreaks( const ScRange* pUserArea ) } // Remove all page breaks in range. - pRowFlags->AndValue( nStartRow+1, nEndRow, sal::static_int_cast<BYTE>(~CR_PAGEBREAK) ); + RemoveRowPageBreaks(nStartRow+1, nEndRow); + // And set new page breaks. BOOL bRepeatRow = ( nRepeatStartY != SCROW_REPEAT_NONE ); BOOL bRowFound = FALSE; long nSizeY = 0; - ScCompressedArrayIterator< SCROW, BYTE> aFlagsIter( *pRowFlags, nStartRow, nEndRow); - ScCompressedArrayIterator< SCROW, USHORT> aHeightIter( *pRowHeight, nStartRow, nEndRow); - for ( ; aFlagsIter; ++aFlagsIter, ++aHeightIter) + ScFlatBoolRowSegments::ForwardIterator aIterHidden(*mpHiddenRows); + ScFlatUInt16RowSegments::ForwardIterator aIterHeights(*mpRowHeights); + SCROW nNextManualBreak = GetNextManualBreak(nStartRow); // -1 => no more manual breaks + for (SCROW nY = nStartRow; nY <= nEndRow; ++nY) { - nY = aFlagsIter.GetPos(); BOOL bStartOfPage = FALSE; - BYTE nFlags = *aFlagsIter; - long nThisY = (nFlags & CR_HIDDEN) ? 0 : *aHeightIter; - if ( (nSizeY+nThisY > nPageSizeY) || ((nFlags & CR_MANUALBREAK) && !bSkipBreaks) ) + bool bThisRowHidden = false; + aIterHidden.getValue(nY, bThisRowHidden); + long nThisY = 0; + if (!bThisRowHidden) + { + sal_uInt16 nTmp; + aIterHeights.getValue(nY, nTmp); + nThisY = static_cast<long>(nTmp); + } + + bool bManualBreak = false; + if (nNextManualBreak >= 0) + { + bManualBreak = (nY == nNextManualBreak); + if (nY >= nNextManualBreak) + // Query the next menual break position. + nNextManualBreak = GetNextManualBreak(nY+1); + } + + if ( (nSizeY+nThisY > nPageSizeY) || (bManualBreak && !bSkipRowBreaks) ) { - pRowFlags->SetValue( nY, nFlags | CR_PAGEBREAK); - aFlagsIter.Resync( nY); + SetRowBreak(nY, true, false); nSizeY = 0; bStartOfPage = TRUE; } @@ -202,21 +248,47 @@ void ScTable::UpdatePageBreaks( const ScRange* pUserArea ) if ( bStartOfPage && bRepeatRow && nY>nRepeatStartY && !bRowFound ) { // subtract size of repeat rows from page size - unsigned long nHeights = pRowFlags->SumCoupledArrayForCondition( - nRepeatStartY, nRepeatEndY, CR_HIDDEN, 0, *pRowHeight); + unsigned long nHeights = GetTotalRowHeight(nRepeatStartY, nRepeatEndY); #ifdef DBG_UTIL if (nHeights == ::std::numeric_limits<unsigned long>::max()) DBG_ERRORFILE("ScTable::UpdatePageBreaks: row heights overflow"); #endif nPageSizeY -= nHeights; if (nY <= nRepeatEndY) + RemoveRowPageBreaks(nY, nRepeatEndY); + bRowFound = TRUE; + } + + if (bThisRowHidden) + { + // Hidden row range. Skip them unless there is a manual break. + SCROW nLastCommon = aIterHidden.getLastPos(); + if (nNextManualBreak >= 0) + nLastCommon = ::std::min(nLastCommon, nNextManualBreak-1); + nY = nLastCommon; + } + else + { + // Visible row range. + + SCROW nLastHidden = aIterHidden.getLastPos(); + SCROW nLastHeight = aIterHeights.getLastPos(); + SCROW nLastCommon = ::std::min(nLastHidden, nLastHeight); + if (nNextManualBreak >= 0) + nLastCommon = ::std::min(nLastCommon, nNextManualBreak-1); + + if (nLastCommon > nY) { - pRowFlags->AndValue( nY, nRepeatEndY, sal::static_int_cast<BYTE>(~CR_PAGEBREAK) ); - nY = nRepeatEndY + 1; - aFlagsIter.Resync( nY); - aHeightIter.Resync( nY); + long nMaxMultiple = static_cast<long>(nLastCommon - nY); + long nMultiple = (nPageSizeY - nSizeY) / nThisY; + if (nMultiple > nMaxMultiple) + nMultiple = nMaxMultiple; + if (nMultiple > 1) + { + nSizeY += nThisY * (nMultiple - 1); + nY += nMultiple - 1; + } } - bRowFound = TRUE; } nSizeY += nThisY; @@ -226,26 +298,24 @@ void ScTable::UpdatePageBreaks( const ScRange* pUserArea ) if (nEndCol < MAXCOL) { - pColFlags[nEndCol+1] |= CR_PAGEBREAK; //! AREABREAK + SetColBreak(nEndCol+1, true, false); // AREABREAK for (nX=nEndCol+2; nX<=MAXCOL; nX++) - pColFlags[nX] &= ~CR_PAGEBREAK; + RemoveColBreak(nX, true, false); } if (nEndRow < MAXROW) { - pRowFlags->OrValue( nEndRow+1, CR_PAGEBREAK); //! AREABREAK + SetRowBreak(nEndRow+1, true, false); // AREABREAK if (nEndRow+2 <= MAXROW) - pRowFlags->AndValue( nEndRow+2, MAXROW, sal::static_int_cast<BYTE>(~CR_PAGEBREAK) ); + RemoveRowPageBreaks(nEndRow+2, MAXROW); } + mbPageBreaksValid = true; } void ScTable::RemoveManualBreaks() { - if (pColFlags) - for (SCCOL nCol = 0; nCol <= MAXCOL; nCol++) - pColFlags[nCol] &= ~CR_MANUALBREAK; - - if (pRowFlags) - pRowFlags->AndValue( 0, MAXROW, sal::static_int_cast<BYTE>(~CR_MANUALBREAK) ); + maRowManualBreaks.clear(); + maColManualBreaks.clear(); + InvalidatePageBreaks(); if (IsStreamValid()) SetStreamValid(FALSE); @@ -253,22 +323,673 @@ void ScTable::RemoveManualBreaks() BOOL ScTable::HasManualBreaks() const { - if (pColFlags) - for (SCCOL nCol = 0; nCol <= MAXCOL; nCol++) - if ( pColFlags[nCol] & CR_MANUALBREAK ) - return TRUE; + return !maRowManualBreaks.empty() || !maColManualBreaks.empty(); +} + +void ScTable::GetAllRowBreaks(set<SCROW>& rBreaks, bool bPage, bool bManual) const +{ + if (bPage) + rBreaks = maRowPageBreaks; + + if (bManual) + { + using namespace std; + copy(maRowManualBreaks.begin(), maRowManualBreaks.end(), inserter(rBreaks, rBreaks.begin())); + } +} + +void ScTable::GetAllColBreaks(set<SCCOL>& rBreaks, bool bPage, bool bManual) const +{ + if (bPage) + rBreaks = maColPageBreaks; + + if (bManual) + { + using namespace std; + copy(maColManualBreaks.begin(), maColManualBreaks.end(), inserter(rBreaks, rBreaks.begin())); + } +} + +bool ScTable::HasRowPageBreak(SCROW nRow) const +{ + if (!ValidRow(nRow)) + return false; + + return maRowPageBreaks.count(nRow) > 0; +} + +bool ScTable::HasColPageBreak(SCCOL nCol) const +{ + if (!ValidCol(nCol)) + return false; + + return maColPageBreaks.count(nCol) > 0; +} + +bool ScTable::HasRowManualBreak(SCROW nRow) const +{ + if (!ValidRow(nRow)) + return false; + + return maRowManualBreaks.count(nRow) > 0; +} + +bool ScTable::HasColManualBreak(SCCOL nCol) const +{ + if (!ValidCol(nCol)) + return false; + + return (maColManualBreaks.count(nCol) > 0); +} + +SCROW ScTable::GetNextManualBreak(SCROW nRow) const +{ + set<SCROW>::const_iterator itr = maRowManualBreaks.lower_bound(nRow); + return itr == maRowManualBreaks.end() ? -1 : *itr; +} + +void ScTable::RemoveRowPageBreaks(SCROW nStartRow, SCROW nEndRow) +{ + using namespace std; + + if (!ValidRow(nStartRow) || !ValidRow(nEndRow)) + return; + + set<SCROW>::iterator low = maRowPageBreaks.lower_bound(nStartRow); + set<SCROW>::iterator high = maRowPageBreaks.upper_bound(nEndRow); + maRowPageBreaks.erase(low, high); +} + +void ScTable::RemoveRowBreak(SCROW nRow, bool bPage, bool bManual) +{ + if (!ValidRow(nRow)) + return; + + if (bPage) + maRowPageBreaks.erase(nRow); + + if (bManual) + { + maRowManualBreaks.erase(nRow); + InvalidatePageBreaks(); + } +} + +void ScTable::RemoveColBreak(SCCOL nCol, bool bPage, bool bManual) +{ + if (!ValidCol(nCol)) + return; + + if (bPage) + maColPageBreaks.erase(nCol); + + if (bManual) + { + maColManualBreaks.erase(nCol); + InvalidatePageBreaks(); + } +} + +void ScTable::SetRowBreak(SCROW nRow, bool bPage, bool bManual) +{ + if (!ValidRow(nRow)) + return; + + if (bPage) + maRowPageBreaks.insert(nRow); + + if (bManual) + { + maRowManualBreaks.insert(nRow); + InvalidatePageBreaks(); + } +} + +void ScTable::SetColBreak(SCCOL nCol, bool bPage, bool bManual) +{ + if (!ValidCol(nCol)) + return; + + if (bPage) + maColPageBreaks.insert(nCol); + + if (bManual) + { + maColManualBreaks.insert(nCol); + InvalidatePageBreaks(); + } +} + +Sequence<TablePageBreakData> ScTable::GetRowBreakData() const +{ + using ::std::copy; + using ::std::inserter; + + set<SCROW> aRowBreaks = maRowPageBreaks; + copy(maRowManualBreaks.begin(), maRowManualBreaks.end(), inserter(aRowBreaks, aRowBreaks.begin())); + + set<SCROW>::const_iterator itr = aRowBreaks.begin(), itrEnd = aRowBreaks.end(); + Sequence<TablePageBreakData> aSeq(aRowBreaks.size()); + + for (sal_Int32 i = 0; itr != itrEnd; ++itr, ++i) + { + SCROW nRow = *itr; + TablePageBreakData aData; + aData.Position = nRow; + aData.ManualBreak = HasRowManualBreak(nRow); + aSeq[i] = aData; + } + + return aSeq; +} + +bool ScTable::RowHidden(SCROW nRow, SCROW* pFirstRow, SCROW* pLastRow) +{ + if (!ValidRow(nRow)) + return true; + + ScFlatBoolRowSegments::RangeData aData; + if (!mpHiddenRows->getRangeData(nRow, aData)) + // search failed. + return true; + + if (pFirstRow) + *pFirstRow = aData.mnRow1; + if (pLastRow) + *pLastRow = aData.mnRow2; + + return aData.mbValue; +} + + +bool ScTable::RowHidden(SCROW nRow, SCROW& rLastRow) +{ + rLastRow = nRow; + if (!ValidRow(nRow)) + return true; + + ScFlatBoolRowSegments::RangeData aData; + if (!mpHiddenRows->getRangeData(nRow, aData)) + // search failed. + return true; + + rLastRow = aData.mnRow2; + return aData.mbValue; +} + +bool ScTable::HasHiddenRows(SCROW nStartRow, SCROW nEndRow) +{ + SCROW nRow = nStartRow; + while (nRow <= nEndRow) + { + SCROW nLastRow = -1; + bool bHidden = RowHidden(nRow, nLastRow); + if (bHidden) + return true; + + nRow = nLastRow + 1; + } + return false; +} + +bool ScTable::ColHidden(SCCOL nCol, SCCOL& rLastCol) +{ + rLastCol = nCol; + if (!ValidCol(nCol)) + return true; + + ScFlatBoolColSegments::RangeData aData; + if (!mpHiddenCols->getRangeData(nCol, aData)) + return true; + + rLastCol = aData.mnCol2; + return aData.mbValue; +} + +bool ScTable::ColHidden(SCCOL nCol, SCCOL* pFirstCol, SCCOL* pLastCol) +{ + if (!ValidCol(nCol)) + return true; + + ScFlatBoolColSegments::RangeData aData; + if (!mpHiddenCols->getRangeData(nCol, aData)) + return true; + + if (pFirstCol) + *pFirstCol = aData.mnCol1; + if (pLastCol) + *pLastCol = aData.mnCol2; + + return aData.mbValue; +} + +void ScTable::SetRowHidden(SCROW nStartRow, SCROW nEndRow, bool bHidden) +{ + if (bHidden) + mpHiddenRows->setTrue(nStartRow, nEndRow); + else + mpHiddenRows->setFalse(nStartRow, nEndRow); +} + +void ScTable::SetColHidden(SCCOL nStartCol, SCCOL nEndCol, bool bHidden) +{ + if (bHidden) + mpHiddenCols->setTrue(nStartCol, nEndCol); + else + mpHiddenCols->setFalse(nStartCol, nEndCol); +} + +void ScTable::CopyColHidden(ScTable& rTable, SCCOL nStartCol, SCCOL nEndCol) +{ + SCCOL nCol = nStartCol; + while (nCol <= nEndCol) + { + SCCOL nLastCol; + bool bHidden = rTable.ColHidden(nCol, NULL, &nLastCol); + if (nLastCol > nEndCol) + nLastCol = nEndCol; + + SetColHidden(nCol, nLastCol, bHidden); + nCol = nLastCol + 1; + } +} + +void ScTable::CopyRowHidden(ScTable& rTable, SCROW nStartRow, SCROW nEndRow) +{ + SCROW nRow = nStartRow; + while (nRow <= nEndRow) + { + SCROW nLastRow = -1; + bool bHidden = rTable.RowHidden(nRow, nLastRow); + if (nLastRow > nEndRow) + nLastRow = nEndRow; + SetRowHidden(nRow, nLastRow, bHidden); + nRow = nLastRow + 1; + } +} + +void ScTable::CopyRowHeight(ScTable& rSrcTable, SCROW nStartRow, SCROW nEndRow, SCROW nSrcOffset) +{ + SCROW nRow = nStartRow; + ScFlatUInt16RowSegments::RangeData aSrcData; + while (nRow <= nEndRow) + { + if (!rSrcTable.mpRowHeights->getRangeData(nRow + nSrcOffset, aSrcData)) + // Something is wrong ! + return; + + SCROW nLastRow = aSrcData.mnRow2 - nSrcOffset; + if (nLastRow > nEndRow) + nLastRow = nEndRow; + + mpRowHeights->setValue(nRow, nLastRow, aSrcData.mnValue); + nRow = nLastRow + 1; + } +} + +SCROW ScTable::FirstVisibleRow(SCROW nStartRow, SCROW nEndRow) +{ + SCROW nRow = nStartRow; + ScFlatBoolRowSegments::RangeData aData; + while (nRow <= nEndRow) + { + if (!ValidRow(nRow)) + break; + + if (!mpHiddenRows->getRangeData(nRow, aData)) + // failed to get range data. + break; + + if (!aData.mbValue) + // visible row found + return nRow; + + nRow = aData.mnRow2 + 1; + } + + return ::std::numeric_limits<SCROW>::max(); +} + +SCROW ScTable::LastVisibleRow(SCROW nStartRow, SCROW nEndRow) +{ + SCROW nRow = nEndRow; + ScFlatBoolRowSegments::RangeData aData; + while (nRow >= nStartRow) + { + if (!ValidRow(nRow)) + break; + + if (!mpHiddenRows->getRangeData(nRow, aData)) + // failed to get range data. + break; + + if (!aData.mbValue) + // visible row found + return nRow; + + nRow = aData.mnRow1 - 1; + } + + return ::std::numeric_limits<SCROW>::max(); +} + +SCROW ScTable::CountVisibleRows(SCROW nStartRow, SCROW nEndRow) +{ + SCROW nCount = 0; + SCROW nRow = nStartRow; + ScFlatBoolRowSegments::RangeData aData; + while (nRow <= nEndRow) + { + if (!mpHiddenRows->getRangeData(nRow, aData)) + break; + + if (aData.mnRow2 > nEndRow) + aData.mnRow2 = nEndRow; + + if (!aData.mbValue) + nCount += aData.mnRow2 - nRow + 1; + + nRow = aData.mnRow2 + 1; + } + return nCount; +} + +sal_uInt32 ScTable::GetTotalRowHeight(SCROW nStartRow, SCROW nEndRow) +{ + sal_uInt32 nHeight = 0; + SCROW nRow = nStartRow; + ScFlatBoolRowSegments::RangeData aData; + while (nRow <= nEndRow) + { + if (!mpHiddenRows->getRangeData(nRow, aData)) + break; + + if (aData.mnRow2 > nEndRow) + aData.mnRow2 = nEndRow; + + if (!aData.mbValue) + // visible row range. + nHeight += mpRowHeights->getSumValue(nRow, aData.mnRow2); + + nRow = aData.mnRow2 + 1; + } + + return nHeight; +} + +SCCOLROW ScTable::LastHiddenColRow(SCCOLROW nPos, bool bCol) +{ + if (bCol) + { + SCCOL nCol = static_cast<SCCOL>(nPos); + if (ColHidden(nCol)) + { + for (SCCOL i = nCol+1; i <= MAXCOL; ++i) + { + if (!ColHidden(nCol)) + return nCol - 1; + } + } + } + else + { + SCROW nRow = static_cast<SCROW>(nPos); + SCROW nLastRow; + if (RowHidden(nRow, NULL, &nLastRow)) + return static_cast<SCCOLROW>(nLastRow); + } + return ::std::numeric_limits<SCCOLROW>::max(); +} + +bool ScTable::RowFiltered(SCROW nRow, SCROW* pFirstRow, SCROW* pLastRow) +{ + if (!ValidRow(nRow)) + return false; + + ScFlatBoolRowSegments::RangeData aData; + if (!mpFilteredRows->getRangeData(nRow, aData)) + // search failed. + return false; + + if (pFirstRow) + *pFirstRow = aData.mnRow1; + if (pLastRow) + *pLastRow = aData.mnRow2; + + return aData.mbValue; +} + +bool ScTable::ColFiltered(SCCOL nCol, SCCOL* pFirstCol, SCCOL* pLastCol) +{ + if (!ValidCol(nCol)) + return false; + + ScFlatBoolColSegments::RangeData aData; + if (!mpFilteredCols->getRangeData(nCol, aData)) + // search failed. + return false; + + if (pFirstCol) + *pFirstCol = aData.mnCol1; + if (pLastCol) + *pLastCol = aData.mnCol2; + + return aData.mbValue; +} + +bool ScTable::HasFilteredRows(SCROW nStartRow, SCROW nEndRow) +{ + SCROW nRow = nStartRow; + while (nRow <= nEndRow) + { + SCROW nLastRow = nRow; + bool bFiltered = RowFiltered(nRow, NULL, &nLastRow); + if (bFiltered) + return true; + + nRow = nLastRow + 1; + } + return false; +} + +void ScTable::CopyColFiltered(ScTable& rTable, SCCOL nStartCol, SCCOL nEndCol) +{ + SCCOL nCol = nStartCol; + while (nCol <= nEndCol) + { + SCCOL nLastCol; + bool bFiltered = rTable.ColFiltered(nCol, NULL, &nLastCol); + if (nLastCol > nEndCol) + nLastCol = nEndCol; + + SetColFiltered(nCol, nLastCol, bFiltered); + nCol = nLastCol + 1; + } +} + +void ScTable::CopyRowFiltered(ScTable& rTable, SCROW nStartRow, SCROW nEndRow) +{ + SCROW nRow = nStartRow; + while (nRow <= nEndRow) + { + SCROW nLastRow = -1; + bool bFiltered = rTable.RowFiltered(nRow, NULL, &nLastRow); + if (nLastRow > nEndRow) + nLastRow = nEndRow; + SetRowFiltered(nRow, nLastRow, bFiltered); + nRow = nLastRow + 1; + } +} + +void ScTable::SetRowFiltered(SCROW nStartRow, SCROW nEndRow, bool bFiltered) +{ + if (bFiltered) + mpFilteredRows->setTrue(nStartRow, nEndRow); + else + mpFilteredRows->setFalse(nStartRow, nEndRow); +} + +void ScTable::SetColFiltered(SCCOL nStartCol, SCCOL nEndCol, bool bFiltered) +{ + if (bFiltered) + mpFilteredCols->setTrue(nStartCol, nEndCol); + else + mpFilteredCols->setFalse(nStartCol, nEndCol); +} + +SCROW ScTable::FirstNonFilteredRow(SCROW nStartRow, SCROW nEndRow) +{ + SCROW nRow = nStartRow; + ScFlatBoolRowSegments::RangeData aData; + while (nRow <= nEndRow) + { + if (!ValidRow(nRow)) + break; + + if (!mpFilteredRows->getRangeData(nRow, aData)) + // failed to get range data. + break; + + if (!aData.mbValue) + // non-filtered row found + return nRow; + + nRow = aData.mnRow2 + 1; + } + + return ::std::numeric_limits<SCROW>::max(); +} + +SCROW ScTable::LastNonFilteredRow(SCROW nStartRow, SCROW nEndRow) +{ + SCROW nRow = nEndRow; + ScFlatBoolRowSegments::RangeData aData; + while (nRow >= nStartRow) + { + if (!ValidRow(nRow)) + break; + + if (!mpFilteredRows->getRangeData(nRow, aData)) + // failed to get range data. + break; + + if (!aData.mbValue) + // non-filtered row found + return nRow; + + nRow = aData.mnRow1 - 1; + } + + return ::std::numeric_limits<SCROW>::max(); +} + +SCROW ScTable::CountNonFilteredRows(SCROW nStartRow, SCROW nEndRow) +{ + SCROW nCount = 0; + SCROW nRow = nStartRow; + ScFlatBoolRowSegments::RangeData aData; + while (nRow <= nEndRow) + { + if (!mpFilteredRows->getRangeData(nRow, aData)) + break; + + if (aData.mnRow2 > nEndRow) + aData.mnRow2 = nEndRow; + + if (!aData.mbValue) + nCount += aData.mnRow2 - nRow + 1; + + nRow = aData.mnRow2 + 1; + } + return nCount; +} + +namespace { + +void lcl_syncFlags(ScFlatBoolColSegments& rColSegments, ScFlatBoolRowSegments& rRowSegments, + BYTE* pColFlags, ScBitMaskCompressedArray< SCROW, BYTE>* pRowFlags, const BYTE nFlagMask) +{ + using ::sal::static_int_cast; + + pRowFlags->AndValue(0, MAXROW, static_int_cast<BYTE>(~nFlagMask)); + for (SCCOL i = 0; i <= MAXCOL; ++i) + pColFlags[i] &= static_int_cast<BYTE>(~nFlagMask); + + { + // row hidden flags. + + SCROW nRow = 0; + ScFlatBoolRowSegments::RangeData aData; + while (nRow <= MAXROW) + { + if (!rRowSegments.getRangeData(nRow, aData)) + break; + + if (aData.mbValue) + pRowFlags->OrValue(nRow, aData.mnRow2, static_int_cast<BYTE>(nFlagMask)); + + nRow = aData.mnRow2 + 1; + } + } - if (pRowFlags) - if (ValidRow( pRowFlags->GetLastAnyBitAccess( 0, CR_MANUALBREAK))) - return TRUE; + { + // column hidden flags. + + SCCOL nCol = 0; + ScFlatBoolColSegments::RangeData aData; + while (nCol <= MAXCOL) + { + if (!rColSegments.getRangeData(nCol, aData)) + break; - return FALSE; + if (aData.mbValue) + { + for (SCCOL i = nCol; i <= aData.mnCol2; ++i) + pColFlags[i] |= nFlagMask; + } + + nCol = aData.mnCol2 + 1; + } + } +} + +} + +void ScTable::SyncColRowFlags() +{ + using ::sal::static_int_cast; + + // Manual breaks. + pRowFlags->AndValue(0, MAXROW, static_int_cast<BYTE>(~CR_MANUALBREAK)); + for (SCCOL i = 0; i <= MAXCOL; ++i) + pColFlags[i] &= static_int_cast<BYTE>(~CR_MANUALBREAK); + + if (!maRowManualBreaks.empty()) + { + for (set<SCROW>::const_iterator itr = maRowManualBreaks.begin(), itrEnd = maRowManualBreaks.end(); + itr != itrEnd; ++itr) + pRowFlags->OrValue(*itr, static_int_cast<BYTE>(CR_MANUALBREAK)); + } + + if (!maColManualBreaks.empty()) + { + for (set<SCCOL>::const_iterator itr = maColManualBreaks.begin(), itrEnd = maColManualBreaks.end(); + itr != itrEnd; ++itr) + pColFlags[*itr] |= CR_MANUALBREAK; + } + + // Hidden flags. + lcl_syncFlags(*mpHiddenCols, *mpHiddenRows, pColFlags, pRowFlags, CR_HIDDEN); + lcl_syncFlags(*mpFilteredCols, *mpFilteredRows, pColFlags, pRowFlags, CR_FILTERED); } void ScTable::SetPageSize( const Size& rSize ) { if ( rSize.Width() != 0 && rSize.Height() != 0 ) { + if (aPageSizeTwips != rSize) + InvalidatePageBreaks(); + bPageSizeValid = TRUE; aPageSizeTwips = rSize; } diff --git a/sc/source/core/data/tabprotection.cxx b/sc/source/core/data/tabprotection.cxx index 5b87fef3151a..2709dd54d1fb 100644 --- a/sc/source/core/data/tabprotection.cxx +++ b/sc/source/core/data/tabprotection.cxx @@ -33,6 +33,7 @@ #include "tabprotection.hxx" #include "tools/debug.hxx" #include "svl/PasswordHelper.hxx" +#include <comphelper/docpasswordhelper.hxx> #include "document.hxx" #define DEBUG_TAB_PROTECTION 0 @@ -75,40 +76,6 @@ ScPassHashProtectable::~ScPassHashProtectable() // ============================================================================ -static sal_uInt16 lcl_getXLHashFromChar(const sal_Char* szPassword) -{ - sal_uInt16 cchPassword = static_cast< sal_uInt16 >( strlen(szPassword) ); - sal_uInt16 wPasswordHash = 0; - if (!cchPassword) - return wPasswordHash; - - const char* pch = &szPassword[cchPassword]; - while (pch-- != szPassword) - { - wPasswordHash = ((wPasswordHash >> 14) & 0x01) | - ((wPasswordHash << 1) & 0x7fff); - wPasswordHash ^= *pch; - } - - wPasswordHash = ((wPasswordHash >> 14) & 0x01) | - ((wPasswordHash << 1) & 0x7fff); - - wPasswordHash ^= (0x8000 | ('N' << 8) | 'K'); - wPasswordHash ^= cchPassword; - - return wPasswordHash; -} - -static Sequence<sal_Int8> lcl_getXLHash(const String& aPassText) -{ - const sal_Char* szBuf = OUStringToOString(OUString(aPassText), RTL_TEXTENCODING_UTF8).getStr(); - sal_uInt16 nHash = lcl_getXLHashFromChar(szBuf); - Sequence<sal_Int8> aHash(2); - aHash[0] = (nHash >> 8) & 0xFF; - aHash[1] = nHash & 0xFF; - return aHash; -} - class ScTableProtectionImpl { public: @@ -146,7 +113,7 @@ Sequence<sal_Int8> ScTableProtectionImpl::hashPassword(const String& aPassText, switch (eHash) { case PASSHASH_XL: - aHash = lcl_getXLHash(aPassText); + aHash = ::comphelper::DocPasswordHelper::GetXLHashAsSequence( aPassText, RTL_TEXTENCODING_UTF8 ); break; case PASSHASH_OOO: default: diff --git a/sc/source/core/inc/bcaslot.hxx b/sc/source/core/inc/bcaslot.hxx index 1ecbefe4a9b1..13384b033628 100644 --- a/sc/source/core/inc/bcaslot.hxx +++ b/sc/source/core/inc/bcaslot.hxx @@ -214,10 +214,6 @@ private: +---+---+ */ - /* TODO: When going for 1M rows this will definitely need some change, or - * with lots of referred sheets even the reservation of NULL pointers would - * be a memory hog. */ - class TableSlots { public: @@ -227,7 +223,8 @@ private: /** Obtain slot pointer, no check on validity! It is assumed that - all calls are made with the result of ComputeSlotOfsset() + all calls are made with the results of ComputeSlotOffset(), + ComputeAreaPoints() and ComputeNextSlot() */ inline ScBroadcastAreaSlot* getAreaSlot( SCSIZE nOff ) { return *(ppSlots + nOff); } diff --git a/sc/source/core/inc/doubleref.hxx b/sc/source/core/inc/doubleref.hxx index e7bd2dfa6ae1..10221d942c9c 100644 --- a/sc/source/core/inc/doubleref.hxx +++ b/sc/source/core/inc/doubleref.hxx @@ -47,11 +47,10 @@ struct ScQueryParamBase; class ScDBRangeBase { public: - enum RefType { INTERNAL, EXTERNAL }; + enum RefType { INTERNAL, EXTERNAL }; // TODO: We may not need this after all... (kohei) virtual ~ScDBRangeBase() = 0; - RefType getType() const; bool fillQueryEntries(ScQueryParamBase* pParam, const ScDBRangeBase* pDBRef) const; virtual SCCOL getColSize() const = 0; diff --git a/sc/source/core/inc/interpre.hxx b/sc/source/core/inc/interpre.hxx index 2075129e4f6e..edecaadb39f0 100644 --- a/sc/source/core/inc/interpre.hxx +++ b/sc/source/core/inc/interpre.hxx @@ -28,8 +28,6 @@ #ifndef SC_INTERPRE_HXX #define SC_INTERPRE_HXX -#define SC_SPEW_ENABLED 0 - #include <math.h> #include <rtl/math.hxx> #include "formula/errorcodes.hxx" @@ -38,10 +36,6 @@ #include "document.hxx" #include "scmatrix.hxx" -#if SC_SPEW_ENABLED -#include "scspew.hxx" -#endif - #include <math.h> #include <map> @@ -126,9 +120,6 @@ class ScInterpreter public: DECL_FIXEDMEMPOOL_NEWDEL( ScInterpreter ) -#if SC_SPEW_ENABLED - static ScSpew theSpew; -#endif static void GlobalExit(); // aus ScGlobal::Clear() gerufen @@ -540,11 +531,7 @@ void ScExternalRef(); void ScGetPivotData(); void ScHyperLink(); void ScBahtText(); -void ScCalcTeam(); -void ScAnswer(); void ScTTT(); -void ScSpewFunc(); -void ScGame(); //----------------Funktionen in interpr2.cxx--------------- diff --git a/sc/source/core/inc/sctictac.hxx b/sc/source/core/inc/sctictac.hxx deleted file mode 100644 index 1c8242150369..000000000000 --- a/sc/source/core/inc/sctictac.hxx +++ /dev/null @@ -1,131 +0,0 @@ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -#ifndef SC_SCTICTAC_HXX -#define SC_SCTICTAC_HXX - -//#define TICTACTOE_MAIN -#ifdef TICTACTOE_MAIN -#define TICTACTOE_STDOUT -#else -//#define TICTACTOE_STDOUT -#endif -#ifndef TICTACTOE_STDOUT -#define TICTACTOE_SC -#endif - -#ifdef TICTACTOE_SC -class ScDocument; -#include "global.hxx" -#include "address.hxx" -#else -#include <tools/string.hxx> -#endif - -static const int ScTicTacToe_Squares = 9; -static const int ScTicTacToe_Possible_Wins = 8; -typedef sal_Unicode Square_Type; -typedef Square_Type Board_Type[ScTicTacToe_Squares]; - -class ScTicTacToe -{ -private: - /* Structure to hold a move and its heuristic */ - typedef struct { - int Square; - int Heuristic; - } Move_Heuristic_Type; - - static const Square_Type Empty; - static const Square_Type Human; - static const Square_Type Compi; - static const int Infinity; /* Higher value than any score */ - static const int Maximum_Moves; /* Maximum moves in a game */ - - Board_Type Board; -#ifdef TICTACTOE_SC - ScAddress aPos; // linke obere Ecke des Boards - ScDocument* pDoc; -#endif - ByteString aStdOut; - int Total_Nodes; /* Nodes searched with minimax */ - int nMove; - Square_Type aPlayer; - BOOL bInitialized; - - /* Array describing the eight combinations of three squares in a row */ - static const int Three_in_a_Row[ScTicTacToe_Possible_Wins][3]; - - /* Array used in heuristic formula for each move. */ - static const int Heuristic_Array[4][4]; - - - Square_Type Winner(); - inline Square_Type Other( Square_Type Player ); - inline void Play( int Square, Square_Type Player ); - int Evaluate( Square_Type Player ); - int BestMove( Square_Type Player, int *Square, - int Move_Nbr, int Alpha, int Beta ); - void Describe( int Score ); - void Move( int& Square ); - Square_Type TryMove( int& Square ); // return Winner() - void PromptHuman(); -#ifdef TICTACTOE_SC - // -1 == Fehler/Redraw, 0 == keine Aenderung, >0 == UserMoveSquare+1 - int GetStatus(); - void DrawBoard(); - void DrawPos( int nSquare, const String& rStr ); -#endif -#ifdef TICTACTOE_STDOUT - void Print(); -#endif - - ScTicTacToe( const ScTicTacToe& ); - ScTicTacToe& operator=( const ScTicTacToe& ); - -public: -#ifdef TICTACTOE_SC - ScTicTacToe( ScDocument* pDoc, const ScAddress& ); -#else - ScTicTacToe(); -#endif - ~ScTicTacToe() {} - void Initialize( BOOL bHumanFirst ); - Square_Type GetEmpty() { return Empty; } -#ifdef TICTACTOE_SC - Square_Type CalcMove(); // return Winner() -#endif -#ifdef TICTACTOE_STDOUT - void Game(); - void GetOutput( ByteString& rStr ); -#else - void GetOutput( String& rStr ); -#endif -}; - -#endif - diff --git a/sc/source/core/tool/addincol.cxx b/sc/source/core/tool/addincol.cxx index 9fc1a7aa25cc..aadd3e101d02 100644 --- a/sc/source/core/tool/addincol.cxx +++ b/sc/source/core/tool/addincol.cxx @@ -51,6 +51,7 @@ #include <com/sun/star/table/XCellRange.hpp> #include <com/sun/star/lang/Locale.hpp> #include <com/sun/star/sheet/XCompatibilityNames.hpp> +#include <com/sun/star/sheet/NoConvergenceException.hpp> #include "addincol.hxx" #include "addinhelpid.hxx" @@ -1582,9 +1583,13 @@ void ScUnoAddInCall::ExecuteCallWithArgs(uno::Sequence<uno::Any>& rCallArgs) if ( rWrapped.TargetException.getValueType().equals( getCppuType( (lang::IllegalArgumentException*)0 ) ) ) nErrCode = errIllegalArgument; + else if ( rWrapped.TargetException.getValueType().equals( + getCppuType( (sheet::NoConvergenceException*)0 ) ) ) + nErrCode = errNoConvergence; else nErrCode = errNoValue; } + catch(uno::Exception&) { nErrCode = errNoValue; diff --git a/sc/source/core/tool/chartarr.cxx b/sc/source/core/tool/chartarr.cxx index 9e4e77b7c1d4..573763141b18 100644 --- a/sc/source/core/tool/chartarr.cxx +++ b/sc/source/core/tool/chartarr.cxx @@ -44,6 +44,9 @@ #include "cell.hxx" #include "docoptio.hxx" +#include <vector> + +using ::std::vector; // ----------------------------------------------------------------------- @@ -163,11 +166,17 @@ ScMemChart* ScChartArray::CreateMemChartSingle() SCCOL nStrCol = nCol1; // fuer Beschriftung merken SCROW nStrRow = nRow1; - // Beschriftungen auch nach HiddenCols finden - while ( (pDocument->GetColFlags( nCol1, nTab1) & CR_HIDDEN) != 0 ) - nCol1++; - nRow1 = pDocument->GetRowFlagsArray( nTab1).GetFirstForCondition( nRow1, - nRow2, CR_HIDDEN, 0); + // Skip hidden columns. + // TODO: make use of last column value once implemented. + SCCOL nLastCol = -1; + while (pDocument->ColHidden(nCol1, nTab1, nLastCol)) + ++nCol1; + + // Skip hidden rows. + SCROW nLastRow = -1; + if (pDocument->RowHidden(nRow1, nTab1, nLastRow)) + nRow1 = nLastRow + 1; + // falls alles hidden ist, bleibt die Beschriftung am Anfang if ( nCol1 <= nCol2 ) { @@ -181,17 +190,33 @@ ScMemChart* ScChartArray::CreateMemChartSingle() } SCSIZE nTotalCols = ( nCol1 <= nCol2 ? nCol2 - nCol1 + 1 : 0 ); - SCCOL* pCols = new SCCOL[nTotalCols > 0 ? nTotalCols : 1]; - SCSIZE nColCount = 0; + vector<SCCOL> aCols; + aCols.reserve(nTotalCols); for (SCSIZE i=0; i<nTotalCols; i++) - if ((pDocument->GetColFlags(sal::static_int_cast<SCCOL>(nCol1+i),nTab1)&CR_HIDDEN)==0) - pCols[nColCount++] = sal::static_int_cast<SCCOL>(nCol1+i); + { + SCCOL nThisCol = sal::static_int_cast<SCCOL>(nCol1+i); + if (!pDocument->ColHidden(nThisCol, nTab1, nLastCol)) + aCols.push_back(nThisCol); + } + SCSIZE nColCount = aCols.size(); SCSIZE nTotalRows = ( nRow1 <= nRow2 ? nRow2 - nRow1 + 1 : 0 ); - SCROW* pRows = new SCROW[nTotalRows > 0 ? nTotalRows : 1]; - SCSIZE nRowCount = (nTotalRows ? - pDocument->GetRowFlagsArray( nTab1).FillArrayForCondition( nRow1, - nRow2, CR_HIDDEN, 0, pRows, nTotalRows) : 0); + vector<SCROW> aRows; + aRows.reserve(nTotalRows); + if (nRow1 <= nRow2) + { + // Get all visible rows between nRow1 and nRow2. + SCROW nThisRow = nRow1; + while (nThisRow <= nRow2) + { + if (pDocument->RowHidden(nThisRow, nTab1, nLastRow)) + nThisRow = nLastRow; + else + aRows.push_back(nThisRow); + ++nThisRow; + } + } + SCSIZE nRowCount = aRows.size(); // May happen at least with more than 32k rows. if (nColCount > SHRT_MAX || nRowCount > SHRT_MAX) @@ -205,13 +230,13 @@ ScMemChart* ScChartArray::CreateMemChartSingle() { bValidData = FALSE; nColCount = 1; - pCols[0] = nStrCol; + aCols.push_back(nStrCol); } if ( !nRowCount ) { bValidData = FALSE; nRowCount = 1; - pRows[0] = nStrRow; + aRows.push_back(nStrRow); } // @@ -234,7 +259,7 @@ ScMemChart* ScChartArray::CreateMemChartSingle() { double nVal = DBL_MIN; // Hack fuer Chart, um leere Zellen zu erkennen - pDocument->GetCell( pCols[nCol], pRows[nRow], nTab1, pCell ); + pDocument->GetCell( aCols[nCol], aRows[nRow], nTab1, pCell ); if (pCell) { CellType eType = pCell->GetCellType(); @@ -244,8 +269,8 @@ ScMemChart* ScChartArray::CreateMemChartSingle() if ( bCalcAsShown && nVal != 0.0 ) { sal_uInt32 nFormat; - pDocument->GetNumberFormat( pCols[nCol], - pRows[nRow], nTab1, nFormat ); + pDocument->GetNumberFormat( aCols[nCol], + aRows[nRow], nTab1, nFormat ); nVal = pDocument->RoundValueAsShown( nVal, nFormat ); } } @@ -277,13 +302,13 @@ ScMemChart* ScChartArray::CreateMemChartSingle() { String aString, aColStr; if (HasColHeaders()) - pDocument->GetString( pCols[nCol], nStrRow, nTab1, aString ); + pDocument->GetString( aCols[nCol], nStrRow, nTab1, aString ); if ( !aString.Len() ) { aString = ScGlobal::GetRscString(STR_COLUMN); aString += ' '; // aString += String::CreateFromInt32( pCols[nCol]+1 ); - ScAddress aPos( pCols[ nCol ], 0, 0 ); + ScAddress aPos( aCols[ nCol ], 0, 0 ); aPos.Format( aColStr, SCA_VALID_COL, NULL ); aString += aColStr; } @@ -303,14 +328,14 @@ ScMemChart* ScChartArray::CreateMemChartSingle() String aString; if (HasRowHeaders()) { - ScAddress aAddr( nStrCol, pRows[nRow], nTab1 ); - pDocument->GetString( nStrCol, pRows[nRow], nTab1, aString ); + ScAddress aAddr( nStrCol, aRows[nRow], nTab1 ); + pDocument->GetString( nStrCol, aRows[nRow], nTab1, aString ); } if ( !aString.Len() ) { aString = ScGlobal::GetRscString(STR_ROW); aString += ' '; - aString += String::CreateFromInt32( pRows[nRow]+1 ); + aString += String::CreateFromInt32( aRows[nRow]+1 ); } pMemChart->SetRowText( static_cast<short>(nRow), aString); @@ -346,11 +371,6 @@ ScMemChart* ScChartArray::CreateMemChartSingle() // SetExtraStrings( *pMemChart ); } - // Aufraeumen - - delete[] pRows; - delete[] pCols; - return pMemChart; } diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx index d2b1963c544d..c28d295275ae 100644 --- a/sc/source/core/tool/compiler.cxx +++ b/sc/source/core/tool/compiler.cxx @@ -121,7 +121,25 @@ enum ScanState ssStop }; -static const sal_Char* pInternal[ 5 ] = { "GAME", "SPEW", "TTT", "STARCALCTEAM", "ANTWORT" }; +// ODFF names that are not written in the current mapping but to be recognized. +// New names will be written in a future relase, then exchange (!) with the +// names in formula/source/core/resource/core_resource.src to be able to still +// read the old names as well. +struct FunctionName +{ + const sal_Char* pName; + OpCode eOp; +}; +static const FunctionName aOdffAliases[] = { + // Renamed old names: + // XXX none yet. + // Renamed new names: + { "BINOM.DIST.RANGE", ocB }, // B -> BINOM.DIST.RANGE + { "LEGACY.TDIST", ocTDist } // TDIST -> LEGACY.TDIST +}; +static const size_t nOdffAliases = sizeof(aOdffAliases) / sizeof(aOdffAliases[0]); + +static const sal_Char* pInternal[ 1 ] = { "TTT" }; using namespace ::com::sun::star::i18n; @@ -2504,7 +2522,21 @@ BOOL ScCompiler::IsOpCode( const String& rName, bool bInArray ) aToken.SetOpCode(eOp); pRawToken = aToken.Clone(); } - else + else if (mxSymbols->isODFF()) + { + for (size_t i=0; i<nOdffAliases; ++i) + { + if (rName.EqualsIgnoreCaseAscii( aOdffAliases[i].pName)) + { + ScRawToken aToken; + aToken.SetOpCode( aOdffAliases[i].eOp); + pRawToken = aToken.Clone(); + bFound = TRUE; + break; // for + } + } + } + if (!bFound) { String aIntName; if (mxSymbols->hasExternals()) @@ -2887,6 +2919,7 @@ BOOL ScCompiler::IsReference( const String& rName ) BOOL ScCompiler::IsMacro( const String& rName ) { + String aName( rName); StarBASIC* pObj = 0; SfxObjectShell* pDocSh = pDoc->GetDocumentShell(); @@ -2898,7 +2931,14 @@ BOOL ScCompiler::IsMacro( const String& rName ) else pObj = pSfxApp->GetBasic(); - SbxMethod* pMeth = (SbxMethod*) pObj->Find( rName, SbxCLASS_METHOD ); + // ODFF recommends to store user-defined functions prefixed with "USER.", + // use only unprefixed name if encountered. BASIC doesn't allow '.' in a + // function name so a function "USER.FOO" could not exist, and macro check + // is assigned the lowest priority in function name check. + if (FormulaGrammar::isODFF( GetGrammar()) && aName.EqualsIgnoreCaseAscii( "USER.", 0, 5)) + aName.Erase( 0, 5); + + SbxMethod* pMeth = (SbxMethod*) pObj->Find( aName, SbxCLASS_METHOD ); if( !pMeth ) { pSfxApp->LeaveBasicCall(); @@ -2913,7 +2953,7 @@ BOOL ScCompiler::IsMacro( const String& rName ) return FALSE; } ScRawToken aToken; - aToken.SetExternal( rName.GetBuffer() ); + aToken.SetExternal( aName.GetBuffer() ); aToken.eOp = ocMacro; pRawToken = aToken.Clone(); pSfxApp->LeaveBasicCall(); diff --git a/sc/source/core/tool/detfunc.cxx b/sc/source/core/tool/detfunc.cxx index 1f257512ae50..e86bb22646c8 100644 --- a/sc/source/core/tool/detfunc.cxx +++ b/sc/source/core/tool/detfunc.cxx @@ -359,7 +359,7 @@ Point ScDetectiveFunc::GetDrawPos( SCCOL nCol, SCROW nRow, DrawPosMode eMode ) c for ( SCCOL i = 0; i < nCol; ++i ) aPos.X() += pDoc->GetColWidth( i, nTab ); - aPos.Y() += pDoc->FastGetRowHeight( 0, nRow - 1, nTab ); + aPos.Y() += pDoc->GetRowHeight( 0, nRow - 1, nTab ); aPos.X() = static_cast< long >( aPos.X() * HMM_PER_TWIPS ); aPos.Y() = static_cast< long >( aPos.Y() * HMM_PER_TWIPS ); diff --git a/sc/source/core/tool/docoptio.cxx b/sc/source/core/tool/docoptio.cxx index a99b3c01dd1f..95ce357b3217 100644 --- a/sc/source/core/tool/docoptio.cxx +++ b/sc/source/core/tool/docoptio.cxx @@ -115,7 +115,7 @@ void ScDocOptions::ResetDocOptions() bIsIter = FALSE; nIterCount = 100; fIterEps = 1.0E-3; - nPrecStandardFormat = 2; + nPrecStandardFormat = SvNumberFormatter::UNLIMITED_PRECISION; nDay = 30; nMonth = 12; nYear = 1899; diff --git a/sc/source/core/tool/doubleref.cxx b/sc/source/core/tool/doubleref.cxx index 5c2d3f575654..740413ea8533 100644 --- a/sc/source/core/tool/doubleref.cxx +++ b/sc/source/core/tool/doubleref.cxx @@ -268,11 +268,6 @@ ScDBRangeBase::~ScDBRangeBase() { } -ScDBRangeBase::RefType ScDBRangeBase::getType() const -{ - return meType; -} - bool ScDBRangeBase::fillQueryEntries(ScQueryParamBase* pParam, const ScDBRangeBase* pDBRef) const { if (!pDBRef) diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx index c576cd5ca6c3..5c326001ff02 100644 --- a/sc/source/core/tool/interpr4.cxx +++ b/sc/source/core/tool/interpr4.cxx @@ -80,18 +80,8 @@ using ::std::auto_ptr; #define ADDIN_MAXSTRLEN 256 -// Implementiert in ui\miscdlgs\teamdlg.cxx - -extern void ShowTheTeam(); - -extern BOOL bOderSo; // in GLOBAL.CXX - //-----------------------------static data ----------------- -#if SC_SPEW_ENABLED -ScSpew ScInterpreter::theSpew; -#endif - //------------------------------------------------------------------------- // Funktionen fuer den Zugriff auf das Document //------------------------------------------------------------------------- @@ -547,9 +537,14 @@ BOOL ScInterpreter::CreateDoubleArr(SCCOL nCol1, SCROW nRow1, SCTAB nTab1, SCCOL nCol2, SCROW nRow2, SCTAB nTab2, BYTE* pCellArr) { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::CreateDoubleArr" ); -#if SC_ROWLIMIT_MORE_THAN_64K -#error row limit 64k + + // Old Add-Ins are hard limited to USHORT values. +#if MAXCOLCOUNT_DEFINE > USHRT_MAX +#error Add check for columns > USHRT_MAX! #endif + if (nRow1 > USHRT_MAX || nRow2 > USHRT_MAX) + return FALSE; + USHORT nCount = 0; USHORT* p = (USHORT*) pCellArr; *p++ = static_cast<USHORT>(nCol1); @@ -628,9 +623,14 @@ BOOL ScInterpreter::CreateStringArr(SCCOL nCol1, SCROW nRow1, SCTAB nTab1, BYTE* pCellArr) { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::CreateStringArr" ); -#if SC_ROWLIMIT_MORE_THAN_64K -#error row limit 64k + + // Old Add-Ins are hard limited to USHORT values. +#if MAXCOLCOUNT_DEFINE > USHRT_MAX +#error Add check for columns > USHRT_MAX! #endif + if (nRow1 > USHRT_MAX || nRow2 > USHRT_MAX) + return FALSE; + USHORT nCount = 0; USHORT* p = (USHORT*) pCellArr; *p++ = static_cast<USHORT>(nCol1); @@ -723,9 +723,14 @@ BOOL ScInterpreter::CreateCellArr(SCCOL nCol1, SCROW nRow1, SCTAB nTab1, BYTE* pCellArr) { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::CreateCellArr" ); -#if SC_ROWLIMIT_MORE_THAN_64K -#error row limit 64k + + // Old Add-Ins are hard limited to USHORT values. +#if MAXCOLCOUNT_DEFINE > USHRT_MAX +#error Add check for columns > USHRT_MAX! #endif + if (nRow1 > USHRT_MAX || nRow2 > USHRT_MAX) + return FALSE; + USHORT nCount = 0; USHORT* p = (USHORT*) pCellArr; *p++ = static_cast<USHORT>(nCol1); @@ -2135,7 +2140,7 @@ void ScInterpreter::ScExternal() if (ScGlobal::GetFuncCollection()->SearchFunc(aFuncName, nIndex)) { FuncData* pFuncData = (FuncData*)ScGlobal::GetFuncCollection()->At(nIndex); - if (nParamCount == pFuncData->GetParamCount() - 1) + if (nParamCount <= MAXFUNCPARAM && nParamCount == pFuncData->GetParamCount() - 1) { ParamType eParamType[MAXFUNCPARAM]; void* ppParam[MAXFUNCPARAM]; @@ -3253,288 +3258,15 @@ void ScInterpreter::ScExternalRef() // --- internals ------------------------------------------------------------ -void ScInterpreter::ScAnswer() -{ - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScAnswer" ); - String aStr( GetString() ); - if( aStr.EqualsIgnoreCaseAscii( "Das Leben, das Universum und der ganze Rest" ) ) - { - PushInt( 42 ); - bOderSo = TRUE; - } - else - PushNoValue(); -} - - -void ScInterpreter::ScCalcTeam() -{ - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScCalcTeam" ); - static BOOL bShown = FALSE; - if( !bShown ) - { - ShowTheTeam(); - String aTeam( RTL_CONSTASCII_USTRINGPARAM( "Nebel, Benisch, Rentz, Rathke" ) ); - if ( (GetByte() == 1) && ::rtl::math::approxEqual( GetDouble(), 1996) ) - aTeam.AppendAscii( " (a word with 'B': -Olk, -Nietsch, -Daeumling)" ); - PushString( aTeam ); - bShown = TRUE; - } - else - PushInt( 42 ); -} - - -void ScInterpreter::ScSpewFunc() -{ - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScSpewFunc" ); - BOOL bRefresh = FALSE; - BOOL bClear = FALSE; - // Stack aufraeumen - BYTE nParamCount = GetByte(); - while ( nParamCount-- > 0) - { - switch ( GetStackType() ) - { - case svString: - case svSingleRef: - case svDoubleRef: - { - const sal_Unicode ch = GetString().GetChar(0); - if ( !bRefresh && ch < 256 ) - bRefresh = (tolower( (sal_uChar) ch ) == 'r'); - if ( !bClear && ch < 256 ) - bClear = (tolower( (sal_uChar) ch ) == 'c'); - } - break; - default: - PopError(); - } - } - String aStr; -#if SC_SPEW_ENABLED - if ( bRefresh ) - theSpew.Clear(); // GetSpew liest SpewRulesFile neu - theSpew.GetSpew( aStr ); - if ( bClear ) - theSpew.Clear(); // release Memory - xub_StrLen nPos = 0; - while ( (nPos = aStr.SearchAndReplace( '\n', ' ', nPos )) != STRING_NOTFOUND ) - nPos++; -#else - aStr.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "spitted out all spew :-(" ) ); -#endif - PushString( aStr ); -} - - -#include "sctictac.hxx" -#include "scmod.hxx" - -//extern "C" { static void SAL_CALL thisModule() {} } - -void ScInterpreter::ScGame() -{ - RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::ScGame" ); - enum GameType { - SC_GAME_NONE, - SC_GAME_ONCE, - SC_GAME_START, - SC_GAME_TICTACTOE = SC_GAME_START, - SC_GAME_STARWARS, - SC_GAME_FROGGER, - SC_GAME_COUNT - }; - // ein grep im binary laeuft ins leere - static sal_Char sGameNone[] = "\14\36\6\137\10\27\36\13\100"; - static sal_Char sGameOnce[] = "\20\27\137\21\20\123\137\21\20\13\137\36\30\36\26\21\136"; - static sal_Char sGameTicTacToe[] = "\53\26\34\53\36\34\53\20\32"; - static sal_Char sGameStarWars[] = "\54\13\36\15\50\36\15\14"; - static sal_Char sGameFrogger[] = "\71\15\20\30\30\26\32"; - sal_Char* const pGames[SC_GAME_COUNT] = { - sGameNone, - sGameOnce, - sGameTicTacToe, - sGameStarWars, - sGameFrogger - }; -#if 0 -say what? -oh no, not again! -TicTacToe -StarWars -Froggie -// Routine um Datenblock zu erzeugen: -#include <stdio.h> -int main() -{ - int b = 1; - int c; - while ( (c = getchar()) != EOF ) - { - if ( b == 1 ) - { - printf( "\"" ); - b = 0; - } - if ( c != 10 ) - { - c ^= 0x7F; - printf( "\\%o", c ); - - } - else - { - printf( "\";\n" ); - b = 1; - } - } - return 0; -} -#endif - static BOOL bRun[SC_GAME_COUNT] = { FALSE }; - static BOOL bFirst = TRUE; - if ( bFirst ) - { - bFirst = FALSE; - for ( int j = SC_GAME_NONE; j < SC_GAME_COUNT; j++ ) - { - sal_Char* p = pGames[j]; - while ( *p ) - *p++ ^= 0x7F; - } - } - String aFuncResult; - GameType eGame = SC_GAME_NONE; - BYTE nParamCount = GetByte(); - if ( nParamCount >= 1 ) - { - String aStr( GetString() ); - nParamCount--; - for ( int j = SC_GAME_START; j < SC_GAME_COUNT; j++ ) - { - if ( aStr.EqualsAscii( pGames[j] ) ) - { - eGame = (GameType) j; - break; // for - } - } - if ( eGame != SC_GAME_NONE ) - { - // jedes Game nur ein einziges Mal starten, um nicht durch Recalc - // o.ae. mehrere Instanzen zu haben, ideal waere eine Abfrage an den - // Games, ob sie bereits laufen ... - if ( bRun[ eGame ] && eGame != SC_GAME_TICTACTOE ) - eGame = SC_GAME_ONCE; - else - { - bRun[ eGame ] = TRUE; - switch ( eGame ) - { - case SC_GAME_TICTACTOE : - { - static ScTicTacToe* pTicTacToe = NULL; - static ScRange aTTTrange; - static BOOL bHumanFirst = FALSE; - if ( nParamCount >= 1 ) - { - if ( GetStackType() == svDoubleRef ) - { - ScRange aRange; - PopDoubleRef( aRange ); - nParamCount--; - if ( aRange.aEnd.Col() - aRange.aStart.Col() == 2 - && aRange.aEnd.Row() - aRange.aStart.Row() == 2 ) - { - BOOL bOk; - if ( pTicTacToe ) - bOk = (aRange == aTTTrange); - else - { - bOk =TRUE; - aTTTrange = aRange; - pTicTacToe = new ScTicTacToe( pDok, - aRange.aStart ); - pTicTacToe->Initialize( bHumanFirst ); - } - // nur einmal und das auf dem gleichen Range - if ( !bOk ) - eGame = SC_GAME_ONCE; - else - { - Square_Type aWinner = pTicTacToe->CalcMove(); - pTicTacToe->GetOutput( aFuncResult ); - if ( aWinner != pTicTacToe->GetEmpty() ) - { - delete pTicTacToe; - pTicTacToe = NULL; - bRun[ eGame ] = FALSE; - bHumanFirst = !bHumanFirst; - } - pDok->GetDocumentShell()->Broadcast( - SfxSimpleHint( FID_DATACHANGED ) ); - pDok->ResetChanged( aRange ); - } - } - else - SetError( errIllegalArgument ); - } - else - SetError( errIllegalParameter ); - } - else - SetError( errIllegalParameter ); - } - break; - default: - { - // added to avoid warnings - } - } - } - } - } - // Stack aufraeumen - while ( nParamCount-- > 0) - Pop(); - if ( !aFuncResult.Len() ) - PushString( String( pGames[ eGame ], RTL_TEXTENCODING_ASCII_US ) ); - else - PushString( aFuncResult ); -} - void ScInterpreter::ScTTT() { // Temporaerer Test-Tanz, zum auspropieren von Funktionen etc. - BOOL bOk = TRUE; BYTE nParamCount = GetByte(); // do something, nParamCount bei Pops runterzaehlen! - if ( bOk && nParamCount ) - { - bOk = GetBool(); - --nParamCount; - } // Stack aufraeumen while ( nParamCount-- > 0) Pop(); - static const sal_Unicode __FAR_DATA sEyes[] = { ',',';',':','|','8','B', 0 }; - static const sal_Unicode __FAR_DATA sGoods[] = { ')',']','}', 0 }; - static const sal_Unicode __FAR_DATA sBads[] = { '(','[','{','/', 0 }; - sal_Unicode aFace[4]; - if ( bOk ) - { - aFace[0] = sEyes[ rand() % ((sizeof( sEyes )/sizeof(sal_Unicode)) - 1) ]; - aFace[1] = '-'; - aFace[2] = sGoods[ rand() % ((sizeof( sGoods )/sizeof(sal_Unicode)) - 1) ]; - } - else - { - aFace[0] = ':'; - aFace[1] = '-'; - aFace[2] = sBads[ rand() % ((sizeof( sBads )/sizeof(sal_Unicode)) - 1) ]; - } - aFace[3] = 0; - PushStringBuffer( aFace ); + PushError(errNoValue); } // ------------------------------------------------------------------------- @@ -3983,11 +3715,7 @@ StackVar ScInterpreter::Interpret() case ocAsc : ScAsc(); break; case ocUnicode : ScUnicode(); break; case ocUnichar : ScUnichar(); break; - case ocAnswer : ScAnswer(); break; - case ocTeam : ScCalcTeam(); break; case ocTTT : ScTTT(); break; - case ocSpew : ScSpewFunc(); break; - case ocGame : ScGame(); break; case ocNone : nFuncFmtType = NUMBERFORMAT_UNDEFINED; break; default : PushError( errUnknownOpCode); break; } diff --git a/sc/source/core/tool/makefile.mk b/sc/source/core/tool/makefile.mk index 6c730f3a1743..c0258e6f0575 100644 --- a/sc/source/core/tool/makefile.mk +++ b/sc/source/core/tool/makefile.mk @@ -104,7 +104,6 @@ SLOFILES = \ $(SLO)$/reftokenhelper.obj \ $(SLO)$/refupdat.obj \ $(SLO)$/scmatrix.obj \ - $(SLO)$/sctictac.obj \ $(SLO)$/stringutil.obj \ $(SLO)$/subtotal.obj \ $(SLO)$/token.obj \ 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/core/tool/sctictac.cxx b/sc/source/core/tool/sctictac.cxx deleted file mode 100644 index d784f45deb87..000000000000 --- a/sc/source/core/tool/sctictac.cxx +++ /dev/null @@ -1,551 +0,0 @@ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -// MARKER(update_precomp.py): autogen include statement, do not remove -#include "precompiled_sc.hxx" - -/* Tic-Tac-Toe program by Steve Chapel schapel@cs.ucsb.edu - Uses alpha-beta pruning minimax search to play a "perfect" game. - The alpha-beta pruning can be removed, but will increase search time. - The heuristic and move ordering in BestMove() can also be removed with - an increase in search time. */ - -#include <stdio.h> -#include <ctype.h> - - -#include "sctictac.hxx" - -#ifdef TICTACTOE_SC -#include "document.hxx" -#include "cell.hxx" -#endif - -const Square_Type ScTicTacToe::Empty = ' '; -const Square_Type ScTicTacToe::Human = 'X'; -const Square_Type ScTicTacToe::Compi = 'O'; -const int ScTicTacToe::Infinity = 10; /* Higher value than any score */ -const int ScTicTacToe::Maximum_Moves = ScTicTacToe_Squares; /* Maximum moves in a game */ - -/* Array describing the eight combinations of three squares in a row */ -const int ScTicTacToe::Three_in_a_Row[ScTicTacToe_Possible_Wins][3] = { - { 0, 1, 2 }, - { 3, 4, 5 }, - { 6, 7, 8 }, - { 0, 3, 6 }, - { 1, 4, 7 }, - { 2, 5, 8 }, - { 0, 4, 8 }, - { 2, 4, 6 } -}; - -/* Array used in heuristic formula for each move. */ -const int ScTicTacToe::Heuristic_Array[4][4] = { - { 0, -10, -100, -1000 }, - { 10, 0, 0, 0 }, - { 100, 0, 0, 0 }, - { 1000, 0, 0, 0 } -}; - - -#ifdef TICTACTOE_SC -ScTicTacToe::ScTicTacToe( ScDocument* pDocP, const ScAddress& rPos ) : - aPos( rPos ), - pDoc( pDocP ), - aStdOut( "Computer plays O, you play X. " ), - bInitialized( FALSE ) -{ -} -#else -ScTicTacToe::ScTicTacToe() : - bInitialized( FALSE ), - aStdOut( "Computer plays O, you play X. " ) -{ -} -#endif - - -/* Return the other player */ -inline Square_Type ScTicTacToe::Other(Square_Type Player) -{ - return Player == Human ? Compi : Human; -} - - -/* Make a move on the board */ -inline void ScTicTacToe::Play(int Square, Square_Type Player) -{ - Board[Square] = Player; -} - - -#ifdef TICTACTOE_STDOUT - -void ScTicTacToe::GetOutput( ByteString& rStr ) -{ - rStr = aStdOut; - aStdOut.Erase(); -} - -#else // !TICTACTOE_STDOUT - -void ScTicTacToe::GetOutput( String& rStr ) -{ - rStr = String( aStdOut, gsl_getSystemTextEncoding() ); - aStdOut.Erase(); -} - -#endif // TICTACTOE_STDOUT - - -/* Clear the board */ -void ScTicTacToe::Initialize( BOOL bHumanFirst ) -{ - bInitialized = TRUE; - aPlayer = (bHumanFirst ? Human : Compi); - nMove = 1; - for (int i = 0; i < ScTicTacToe_Squares; i++) - Board[i] = Empty; -} - - -/* If a player has won, return the winner. If the game is a tie, - return 'C' (for cat). If the game is not over, return Empty. */ -Square_Type ScTicTacToe::Winner() -{ - int i; - for (i = 0; i < ScTicTacToe_Possible_Wins; i++) - { - Square_Type Possible_Winner = Board[Three_in_a_Row[i][0]]; - if (Possible_Winner != Empty && - Possible_Winner == Board[Three_in_a_Row[i][1]] && - Possible_Winner == Board[Three_in_a_Row[i][2]]) - return Possible_Winner; - } - - for (i = 0; i < ScTicTacToe_Squares; i++) - { - if (Board[i] == Empty) - return Empty; - } - - return 'C'; -} - - -/* Return a heuristic used to determine the order in which the - children of a node are searched */ -int ScTicTacToe::Evaluate(Square_Type Player) -{ - int i; - int Heuristic = 0; - for (i = 0; i < ScTicTacToe_Possible_Wins; i++) - { - int j; - int Players = 0, Others = 0; - for (j = 0; j < 3; j++) - { - Square_Type Piece = Board[Three_in_a_Row[i][j]]; - if (Piece == Player) - Players++; - else if (Piece == Other(Player)) - Others++; - } - Heuristic += Heuristic_Array[Players][Others]; - } - return Heuristic; -} - - -/* Return the score of the best move found for a board - The square to move to is returned in *Square */ -int ScTicTacToe::BestMove(Square_Type Player, int *Square, - int Move_Nbr, int Alpha, int Beta) -{ - int Best_Square = -1; - int Moves = 0; - int i; - Move_Heuristic_Type Move_Heuristic[ScTicTacToe_Squares]; - - Total_Nodes++; - - /* Find the heuristic for each move and sort moves in descending order */ - for (i = 0; i < ScTicTacToe_Squares; i++) - { - if (Board[i] == Empty) - { - int Heuristic; - int j; - Play(i, Player); - Heuristic = Evaluate(Player); - Play(i, Empty); - for (j = Moves-1; j >= 0 && - Move_Heuristic[j].Heuristic < Heuristic; j--) - { - Move_Heuristic[j + 1].Heuristic = Move_Heuristic[j].Heuristic; - Move_Heuristic[j + 1].Square = Move_Heuristic[j].Square; - } - Move_Heuristic[j + 1].Heuristic = Heuristic; - Move_Heuristic[j + 1].Square = i; - Moves++; - } - } - - for (i = 0; i < Moves; i++) - { - int Score; - int Sq = Move_Heuristic[i].Square; - Square_Type W; - - /* Make a move and get its score */ - Play(Sq, Player); - - W = Winner(); - if (W == Compi) - Score = (Maximum_Moves + 1) - Move_Nbr; - else if (W == Human) - Score = Move_Nbr - (Maximum_Moves + 1); - else if (W == 'C') - Score = 0; - else - Score = BestMove(Other(Player), Square, Move_Nbr + 1, - Alpha, Beta); - - Play(Sq, Empty); - - /* Perform alpha-beta pruning */ - if (Player == Compi) - { - if (Score >= Beta) - { - *Square = Sq; - return Score; - } - else if (Score > Alpha) - { - Alpha = Score; - Best_Square = Sq; - } - } - else - { - if (Score <= Alpha) - { - *Square = Sq; - return Score; - } - else if (Score < Beta) - { - Beta = Score; - Best_Square = Sq; - } - } - } - *Square = Best_Square; - if (Player == Compi) - return Alpha; - else - return Beta; -} - - -/* Provide an English description of the score returned by BestMove */ -void ScTicTacToe::Describe(int Score) -{ - if (Score < 0) - aStdOut += "You have a guaranteed win. "; - else if (Score == 0) - aStdOut += "I can guarantee a tie. "; - else - { - aStdOut += "I have a guaranteed win by move "; - aStdOut += ByteString::CreateFromInt32( Maximum_Moves - Score + 1 ); - aStdOut += ". "; - } -} - - -/* Have the human or the computer move */ -void ScTicTacToe::Move( int& Square ) -{ - if (aPlayer == Compi) - { - Total_Nodes = 0; - Describe(BestMove(aPlayer, &Square, nMove, -Infinity, Infinity)); - aStdOut += ByteString::CreateFromInt32( Total_Nodes ); - aStdOut += " nodes examined. "; - Play(Square, aPlayer); - aStdOut += "Move #"; - aStdOut += ByteString::CreateFromInt32( nMove ); - aStdOut += " - O moves to "; - aStdOut += ByteString::CreateFromInt32( Square + 1 ); - aStdOut += ". "; - aPlayer = Other( aPlayer ); - nMove++; - } - else - { - if ( Square < 0 || Square >= ScTicTacToe_Squares - || Board[Square] != Empty ) - Square = -1; - else - { - Play(Square, aPlayer); - aPlayer = Other( aPlayer ); - nMove++; - } - } -} - - -// Try a move -Square_Type ScTicTacToe::TryMove( int& Square ) -{ - if ( !bInitialized ) - Initialize( FALSE ); - - Square_Type W = Winner(); - if ( W == Empty ) - { - Move( Square ); -#ifdef TICTACTOE_STDOUT - if ( aStdOut.Len() ) - { - puts( aStdOut.GetBuffer() ); - aStdOut.Erase(); - } -#endif - W = Winner(); - } - if ( W == Empty ) - { - if ( aPlayer == Human ) - PromptHuman(); - } - else - { - if (W != 'C') - { - aStdOut += static_cast< char >(W); - aStdOut += " wins!"; - } - else - aStdOut += "It's a tie."; - } - return W; -} - - -void ScTicTacToe::PromptHuman() -{ - aStdOut += "Move #"; - aStdOut += ByteString::CreateFromInt32( nMove ); - aStdOut += " - What is X's move?"; -} - - -#ifdef TICTACTOE_SC - -void ScTicTacToe::DrawPos( int nSquare, const String& rStr ) -{ - pDoc->SetString( sal::static_int_cast<SCCOL>( aPos.Col()+(nSquare%3) ), - sal::static_int_cast<SCROW>( aPos.Row()+(nSquare/3) ), aPos.Tab(), rStr ); -} - - -void ScTicTacToe::DrawBoard() -{ - String aStr; - for ( USHORT j = 0; j < ScTicTacToe_Squares; j++ ) - { - aStr = Board[j]; - DrawPos( j, aStr ); - } -} - - -// -1 == Fehler/Redraw, 0 == keine Aenderung, >0 == UserMoveSquare+1 -int ScTicTacToe::GetStatus() -{ - SCCOL nCol; - SCROW nRow; - SCTAB nTab; - nCol = aPos.Col(); - nRow = aPos.Row(); - nTab = aPos.Tab(); - String aStr; - int nDiffs = 0; - int nSquare = 0; - for ( USHORT j = 0; j < ScTicTacToe_Squares; j++ ) - { - pDoc->GetString( nCol+(j%3), nRow+(j/3), nTab, aStr ); - if ( !aStr.Len() ) - { - if ( Board[j] != Empty ) - return -1; // wo was sein muss muss was sein - } - else - { - aStr.ToUpperAscii(); - if ( aStr.GetChar(0) != Board[j] ) - { - if ( Board[j] != Empty ) - return -1; // bestehendes ueberschrieben - // bei erstem Move hat Human angefangen - if ( ++nDiffs > 1 ) - return -1; // mehr als eine Aenderung - nSquare = j; - } - } - } - if ( nDiffs == 1 ) - return nSquare + 1; - return 0; -} - - -Square_Type ScTicTacToe::CalcMove() -{ - Square_Type W = Winner(); - int nStat = GetStatus(); - if ( nStat || (W == Empty && aPlayer == Compi) ) - { - if ( nStat == -1 || (nStat > 0 && aPlayer == Compi) ) - DrawBoard(); - if ( W == Empty && aPlayer == Human ) - { - if ( nStat > 0 ) - { - int nSquare = --nStat; - W = TryMove( nStat ); - if ( nStat == -1 ) - DrawPos( nSquare, String( ' ' ) ); - else - DrawPos( nStat, String( Human ) ); - } - else - PromptHuman(); - } - if ( W == Empty && aPlayer == Compi ) - { - W = TryMove( nStat ); // ComputerMove, nStat egal - DrawPos( nStat, String( Compi ) ); - } - } - else if ( W == Empty && aPlayer == Human ) - PromptHuman(); - return W; -} - -#endif // TICTACTOE_SC - - -#ifdef TICTACTOE_STDOUT -/* Print the board */ -void ScTicTacToe::Print() -{ - int i; - for (i = 0; i < ScTicTacToe_Squares; i += 3) - { - if (i > 0) - printf("---+---+---\n"); - printf(" %c | %c | %c \n", Board[i], Board[i + 1], Board[i + 2]); - } - printf("\n"); -} - - -/* Play a game of tic-tac-toe */ -void ScTicTacToe::Game() -{ - if ( !bInitialized ) - Initialize( FALSE ); - - int Square = (aPlayer == Compi ? 0 : -1); - Square_Type W = Winner(); - while( W == Empty ) - { - Print(); - W = TryMove( Square ); - if ( W == Empty ) - { - if ( aPlayer == Human ) - { - if ( Square != -1 ) - Print(); // empty board already printed if human moves first - do - { - puts( aStdOut.GetBuffer() ); - aStdOut.Erase(); - scanf("%d", &Square); - Square--; - W = TryMove( Square ); - } while ( Square == -1 ); - } - } - } - Print(); - puts( aStdOut.GetBuffer() ); - aStdOut.Erase(); -} -#endif // TICTACTOE_STDOUT - - -#ifdef TICTACTOE_MAIN -int main() -{ - char Answer[80]; - - printf("Welcome to Tic-Tac-Toe!\n\n"); - printf("Here is the board numbering:\n"); - printf(" 1 | 2 | 3\n"); - printf("---+---+---\n"); - printf(" 4 | 5 | 6\n"); - printf("---+---+---\n"); - printf(" 7 | 8 | 9\n"); - printf("\n"); -// printf("Computer plays X, you play O.\n"); - - ScTicTacToe aTTT; - ByteString aStr; - aTTT.GetOutput( aStr ); - puts( aStr.GetBuffer() ); - - do - { - printf("\nDo you want to move first? "); - scanf("%s", Answer); - aTTT.Initialize( toupper(Answer[0]) == 'Y' ); - aTTT.Game(); - printf("\nDo you want to play again? "); - scanf("%s", Answer); - } while (toupper(Answer[0]) == 'Y'); - - return 0; -} -#endif // TICTACTOE_MAIN - diff --git a/sc/source/filter/excel/colrowst.cxx b/sc/source/filter/excel/colrowst.cxx index 3a48aa6b96ba..01587c036dea 100644 --- a/sc/source/filter/excel/colrowst.cxx +++ b/sc/source/filter/excel/colrowst.cxx @@ -207,7 +207,7 @@ void XclImpColRowSettings::Convert( SCTAB nScTab ) // row heights ------------------------------------------------------------ // #i54252# set default row height - rDoc.SetRowHeightRange( 0, MAXROW, nScTab, mnDefHeight ); + rDoc.SetRowHeightOnly( 0, MAXROW, nScTab, mnDefHeight ); if( ::get_flag( mnDefRowFlags, EXC_DEFROW_UNSYNCED ) ) // first access to row flags, do not ask for old flags rDoc.SetRowFlags( 0, MAXROW, nScTab, CR_MANUALSIZE ); @@ -258,7 +258,7 @@ void XclImpColRowSettings::Convert( SCTAB nScTab ) { DBG_ASSERT( (nScRow == 0) || (nFirstScRow >= 0), "XclImpColRowSettings::Convert - algorithm error" ); if( nScRow > 0 ) - rDoc.SetRowHeightRange( nFirstScRow, nScRow - 1, nScTab, nLastHeight ); + rDoc.SetRowHeightOnly( nFirstScRow, nScRow - 1, nScTab, nLastHeight ); nFirstScRow = nScRow; nLastHeight = nHeight; @@ -267,7 +267,7 @@ void XclImpColRowSettings::Convert( SCTAB nScTab ) // set row height of last portion if( mnLastScRow >= 0 ) - rDoc.SetRowHeightRange( nFirstScRow, mnLastScRow, nScTab, nLastHeight ); + rDoc.SetRowHeightOnly( nFirstScRow, mnLastScRow, nScTab, nLastHeight ); // ------------------------------------------------------------------------ @@ -307,7 +307,7 @@ void XclImpColRowSettings::ConvertHiddenFlags( SCTAB nScTab ) rDoc.ShowRow( nScRow, nScTab, FALSE ); // #i38093# rows hidden by filter need extra flag if( (nFirstFilterScRow <= nScRow) && (nScRow <= nLastFilterScRow) ) - rDoc.SetRowFlags( nScRow, nScTab, rDoc.GetRowFlags( nScRow, nScTab ) | CR_FILTERED ); + rDoc.SetRowFiltered(nScRow, nScRow, nScTab, true); } } diff --git a/sc/source/filter/excel/excdoc.cxx b/sc/source/filter/excel/excdoc.cxx index bba1543dd403..2cf2d8f580c0 100644 --- a/sc/source/filter/excel/excdoc.cxx +++ b/sc/source/filter/excel/excdoc.cxx @@ -200,17 +200,12 @@ void ExcTable::FillAsHeader( ExcBoundsheetList& rBoundsheetList ) UINT16 nExcTabCount = rTabInfo.GetXclTabCount(); UINT16 nCodenames = static_cast< UINT16 >( GetExtDocOptions().GetCodeNameCount() ); - sal_uInt16 nWriteProtHash = 0; - if( SfxObjectShell* pDocShell = GetDocShell() ) - { - ScfPropertySet aPropSet( pDocShell->GetModel() ); - sal_Int32 nApiHash = 0; - if( aPropSet.GetProperty( nApiHash, CREATE_OUSTRING( "WriteProtectionPassword" ) ) && (0 < nApiHash) && (nApiHash <= SAL_MAX_UINT16) ) - { - nWriteProtHash = static_cast< sal_uInt16 >( nApiHash ); - Add( new XclExpEmptyRecord( EXC_ID_WRITEPROT ) ); - } - } + SfxObjectShell* pShell = GetDocShell(); + sal_uInt16 nWriteProtHash = pShell ? pShell->GetModifyPasswordHash() : 0; + bool bRecommendReadOnly = pShell && pShell->IsLoadReadonly(); + + if( (nWriteProtHash > 0) || bRecommendReadOnly ) + Add( new XclExpEmptyRecord( EXC_ID_WRITEPROT ) ); // TODO: correct codepage for BIFF5? sal_uInt16 nCodePage = XclTools::GetXclCodePage( (GetBiff() <= EXC_BIFF5) ? RTL_TEXTENCODING_MS_1252 : RTL_TEXTENCODING_UNICODE ); @@ -234,7 +229,7 @@ void ExcTable::FillAsHeader( ExcBoundsheetList& rBoundsheetList ) Add( new XclExpWriteAccess ); } - Add( new XclExpFileSharing( GetRoot(), nWriteProtHash ) ); + Add( new XclExpFileSharing( GetRoot(), nWriteProtHash, bRecommendReadOnly ) ); Add( new XclExpUInt16Record( EXC_ID_CODEPAGE, nCodePage ) ); if( GetBiff() == EXC_BIFF8 ) @@ -437,7 +432,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/excimp8.cxx b/sc/source/filter/excel/excimp8.cxx index 45959130defc..9608804da9f9 100644 --- a/sc/source/filter/excel/excimp8.cxx +++ b/sc/source/filter/excel/excimp8.cxx @@ -30,6 +30,7 @@ #include "excimp8.hxx" +#include <com/sun/star/sheet/XSpreadsheetDocument.hpp> #include <scitems.hxx> #include <comphelper/processfactory.hxx> @@ -54,6 +55,8 @@ #include <editeng/flditem.hxx> #include <svx/xflclit.hxx> #include <filter/msfilter/svxmsbas.hxx> +#include <basic/basmgr.hxx> +#include <oox/xls/excelvbaproject.hxx> #include <vcl/graph.hxx> #include <vcl/bmpacc.hxx> @@ -64,6 +67,7 @@ #include <tools/string.hxx> #include <tools/urlobj.hxx> #include <rtl/math.hxx> +#include <rtl/ustrbuf.hxx> #include <unotools/localedatawrapper.hxx> #include <unotools/charclass.hxx> #include <drwlayer.hxx> @@ -99,28 +103,19 @@ #include <com/sun/star/document/XDocumentProperties.hpp> #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp> -#include <basic/basmgr.hxx> #include <cppuhelper/component_context.hxx> -#include <com/sun/star/container/XNameContainer.hpp> #include <sfx2/app.hxx> - using namespace com::sun::star; - - -#define INVALID_POS 0xFFFFFFFF - - +using ::rtl::OUString; ImportExcel8::ImportExcel8( XclImpRootData& rImpData, SvStream& rStrm ) : - ImportExcel( rImpData, rStrm ), mnTab(0) + ImportExcel( rImpData, rStrm ) { + // replace BIFF2-BIFF5 formula importer with BIFF8 formula importer delete pFormConv; - pFormConv = pExcRoot->pFmlaConverter = new ExcelToSc8( GetRoot() ); - - bHasBasic = FALSE; } @@ -229,27 +224,6 @@ void ImportExcel8::Labelsst( void ) } -void ImportExcel8::Codename( BOOL bWorkbookGlobals ) -{ - if( bHasBasic ) - { - String aName( aIn.ReadUniString() ); - if( aName.Len() ) - { - if( bWorkbookGlobals ) - { - GetExtDocOptions().GetDocSettings().maGlobCodeName = aName; - GetDoc().SetCodeName( aName ); - } - else - { - GetExtDocOptions().AppendCodeName( aName ); - GetDoc().SetCodeName( mnTab++, aName ); - } - } - } -} - void ImportExcel8::SheetProtection( void ) { GetSheetProtectBuffer().ReadOptions( aIn, GetCurrScTab() ); @@ -257,8 +231,6 @@ void ImportExcel8::SheetProtection( void ) void ImportExcel8::ReadBasic( void ) { - bHasBasic = TRUE; - SfxObjectShell* pShell = GetDocShell(); SotStorageRef xRootStrg = GetRootStorage(); SvtFilterOptions* pFilterOpt = SvtFilterOptions::Get(); @@ -270,14 +242,14 @@ void ImportExcel8::ReadBasic( void ) if( bLoadCode || bLoadStrg ) { SvxImportMSVBasic aBasicImport( *pShell, *xRootStrg, bLoadCode, bLoadStrg ); - bool bAsComment = !bLoadExecutable; + bool bAsComment = !bLoadExecutable; if ( !bAsComment ) { - uno::Any aGlobs; + uno::Any aGlobs; uno::Sequence< uno::Any > aArgs(1); aArgs[ 0 ] <<= pShell->GetModel(); - aGlobs <<= ::comphelper::getProcessServiceFactory()->createInstanceWithArguments( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.excel.Globals" ) ), aArgs ); - pShell->GetBasicManager()->SetGlobalUNOConstant( "VBAGlobals", aGlobs ); + aGlobs <<= ::comphelper::getProcessServiceFactory()->createInstanceWithArguments( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.excel.Globals" ) ), aArgs ); + pShell->GetBasicManager()->SetGlobalUNOConstant( "VBAGlobals", aGlobs ); BasicManager* pAppMgr = SFX_APP()->GetBasicManager(); if ( pAppMgr ) pAppMgr->SetGlobalUNOConstant( "ThisExcelDoc", aArgs[ 0 ] ); @@ -297,6 +269,9 @@ void ImportExcel8::EndSheet( void ) void ImportExcel8::PostDocLoad( void ) { + // reading basic has been delayed until sheet objects (codenames etc.) are read + if( HasBasic() ) + ReadBasic(); // #i11776# filtered ranges before outlines and hidden rows if( pExcRoot->pAutoFilterBuffer ) pExcRoot->pAutoFilterBuffer->Apply(); @@ -316,24 +291,47 @@ void ImportExcel8::PostDocLoad( void ) } // read doc info (no docshell while pasting from clipboard) + LoadDocumentProperties(); + // attach document events to VBA macros + AttachDocumentEvents(); + + // #i45843# Pivot tables are now handled outside of PostDocLoad, so they are available + // when formula cells are calculated, for the GETPIVOTDATA function. +} + +void ImportExcel8::LoadDocumentProperties() +{ + // no docshell while pasting from clipboard if( SfxObjectShell* pShell = GetDocShell() ) { // BIFF5+ without storage is possible SotStorageRef xRootStrg = GetRootStorage(); - if( xRootStrg.Is() ) + if( xRootStrg.Is() ) try + { + uno::Reference< document::XDocumentPropertiesSupplier > xDPS( pShell->GetModel(), uno::UNO_QUERY_THROW ); + uno::Reference< document::XDocumentProperties > xDocProps( xDPS->getDocumentProperties(), uno::UNO_SET_THROW ); + sfx2::LoadOlePropertySet( xDocProps, xRootStrg ); + } + catch( uno::Exception& ) { - uno::Reference<document::XDocumentPropertiesSupplier> xDPS( - pShell->GetModel(), uno::UNO_QUERY_THROW); - uno::Reference<document::XDocumentProperties> xDocProps - = xDPS->getDocumentProperties(); - sfx2::LoadOlePropertySet(xDocProps, GetRootStorage()); } } - - // #i45843# Pivot tables are now handled outside of PostDocLoad, so they are available - // when formula cells are calculated, for the GETPIVOTDATA function. } +void ImportExcel8::AttachDocumentEvents() +{ + SfxObjectShell* pShell = GetDocShell(); + if( HasBasic() && pShell ) + { + uno::Reference< lang::XMultiServiceFactory > xGlobalFactory = ::comphelper::getProcessServiceFactory(); + uno::Reference< sheet::XSpreadsheetDocument > xDocument( pShell->GetModel(), uno::UNO_QUERY ); + if( xGlobalFactory.is() && xDocument.is() ) + { + ::oox::xls::VbaProject aVbaProject( xGlobalFactory, xDocument ); + aVbaProject.attachToEvents(); + } + } +} //___________________________________________________________________ // autofilter diff --git a/sc/source/filter/excel/impop.cxx b/sc/source/filter/excel/impop.cxx index e62f050f2351..209d24ac043d 100644 --- a/sc/source/filter/excel/impop.cxx +++ b/sc/source/filter/excel/impop.cxx @@ -122,7 +122,8 @@ ImportExcel::ImportExcel( XclImpRootData& rImpData, SvStream& rStrm ): ImportTyp( &rImpData.mrDoc, rImpData.meTextEnc ), XclImpRoot( rImpData ), maStrm( rStrm, GetRoot() ), - aIn( maStrm ) + aIn( maStrm ), + maScOleSize( ScAddress::INITIALIZE_INVALID ) { mnLastRefIdx = 0; nBdshtTab = 0; @@ -178,15 +179,16 @@ void ImportExcel::ReadFileSharing() maStrm >> nRecommendReadOnly >> nPasswordHash; if( (nRecommendReadOnly != 0) || (nPasswordHash != 0) ) + { if( SfxItemSet* pItemSet = GetMedium().GetItemSet() ) pItemSet->Put( SfxBoolItem( SID_DOC_READONLY, TRUE ) ); - if( nPasswordHash != 0 ) - { - if( SfxObjectShell* pDocShell = GetDocShell() ) + if( SfxObjectShell* pShell = GetDocShell() ) { - ScfPropertySet aPropSet( pDocShell->GetModel() ); - aPropSet.SetProperty( CREATE_OUSTRING( "WriteProtectionPassword" ), static_cast< sal_Int32 >( nPasswordHash ) ); + if( nRecommendReadOnly != 0 ) + pShell->SetLoadReadonly( sal_True ); + if( nPasswordHash != 0 ) + pShell->SetModifyPasswordHash( nPasswordHash ); } } } @@ -919,8 +921,7 @@ void ImportExcel::Olesize( void ) aXclOleSize.Read( maStrm, false ); SCTAB nScTab = GetCurrScTab(); - ScRange& rOleSize = GetExtDocOptions().GetDocSettings().maOleSize; - GetAddressConverter().ConvertRange( rOleSize, aXclOleSize, nScTab, nScTab, false ); + GetAddressConverter().ConvertRange( maScOleSize, aXclOleSize, nScTab, nScTab, false ); } @@ -1204,45 +1205,40 @@ void ImportExcel::PostDocLoad( void ) // process all drawing objects (including OLE, charts, controls; after hiding rows/columns; before visible OLE area) GetObjectManager().ConvertObjects(); - // visible area if embedded OLE - if( ScModelObj* pDocObj = GetDocModelObj() ) + // visible area (used if this document is an embedded OLE object) + if( SfxObjectShell* pDocShell = GetDocShell() ) { - if( SfxObjectShell* pEmbObj = pDocObj->GetEmbeddedObject() ) + // visible area if embedded + const ScExtDocSettings& rDocSett = GetExtDocOptions().GetDocSettings(); + SCTAB nDisplScTab = rDocSett.mnDisplTab; + + /* #i44077# If a new OLE object is inserted from file, there is no + OLESIZE record in the Excel file. Calculate used area from file + contents (used cells and drawing objects). */ + if( !maScOleSize.IsValid() ) { - // visible area if embedded - const ScExtDocSettings& rDocSett = GetExtDocOptions().GetDocSettings(); - SCTAB nDisplScTab = rDocSett.mnDisplTab; - - // first try if there was an OLESIZE record - ScRange aScOleSize = rDocSett.maOleSize; - - /* #i44077# If a new OLE object is inserted from file, there - is no OLESIZE record in the Excel file. Calculate used area - from file contents (used cells and drawing objects). */ - if( !aScOleSize.IsValid() ) - { - // used area of displayed sheet (cell contents) - if( const ScExtTabSettings* pTabSett = GetExtDocOptions().GetTabSettings( nDisplScTab ) ) - aScOleSize = pTabSett->maUsedArea; - // add all valid drawing objects - ScRange aScObjArea = GetObjectManager().GetUsedArea( nDisplScTab ); - if( aScObjArea.IsValid() ) - aScOleSize.ExtendTo( aScObjArea ); - } + // used area of displayed sheet (cell contents) + if( const ScExtTabSettings* pTabSett = GetExtDocOptions().GetTabSettings( nDisplScTab ) ) + maScOleSize = pTabSett->maUsedArea; + // add all valid drawing objects + ScRange aScObjArea = GetObjectManager().GetUsedArea( nDisplScTab ); + if( aScObjArea.IsValid() ) + maScOleSize.ExtendTo( aScObjArea ); + } - // valid size found - set it at the document - if( aScOleSize.IsValid() ) - { - pEmbObj->SetVisArea( GetDoc().GetMMRect( - aScOleSize.aStart.Col(), aScOleSize.aStart.Row(), - aScOleSize.aEnd.Col(), aScOleSize.aEnd.Row(), nDisplScTab ) ); - GetDoc().SetVisibleTab( nDisplScTab ); - } + // valid size found - set it at the document + if( maScOleSize.IsValid() ) + { + pDocShell->SetVisArea( GetDoc().GetMMRect( + maScOleSize.aStart.Col(), maScOleSize.aStart.Row(), + maScOleSize.aEnd.Col(), maScOleSize.aEnd.Row(), nDisplScTab ) ); + GetDoc().SetVisibleTab( nDisplScTab ); } + } - // #111099# open forms in alive mode (has no effect, if no controls in document) + // #111099# open forms in alive mode (has no effect, if no controls in document) + if( ScModelObj* pDocObj = GetDocModelObj() ) pDocObj->setPropertyValue( CREATE_OUSTRING( SC_UNO_APPLYFMDES ), uno::Any( false ) ); - } // enables extended options to be set to the view after import GetExtDocOptions().SetChanged( true ); diff --git a/sc/source/filter/excel/read.cxx b/sc/source/filter/excel/read.cxx index 637a4777c8ed..cfe5aedb867e 100644 --- a/sc/source/filter/excel/read.cxx +++ b/sc/source/filter/excel/read.cxx @@ -986,10 +986,10 @@ FltError ImportExcel8::Read( void ) case 0x22: Rec1904(); break; // 1904 [ 2345 ] case 0x56: Builtinfmtcnt(); break; // BUILTINFMTCNT[ 34 ] case 0x8D: Hideobj(); break; // HIDEOBJ [ 345 ] - case 0xD3: ReadBasic(); break; + case 0xD3: SetHasBasic(); break; case 0xDE: Olesize(); break; - case 0x01BA: Codename( TRUE ); break; + case EXC_ID_CODENAME: ReadCodeName( aIn, true ); break; case EXC_ID_USESELFS: ReadUsesElfs(); break; case EXC_ID2_FONT: rFontBfr.ReadFont( maStrm ); break; @@ -1082,6 +1082,8 @@ FltError ImportExcel8::Read( void ) case EXC_ID2_DIMENSIONS: case EXC_ID3_DIMENSIONS: ReadDimensions(); break; + case EXC_ID_CODENAME: ReadCodeName( aIn, false ); break; + case 0x0A: // EOF [ 2345 ] eAkt = EXC_STATE_SHEET; aIn.SeekGlobalPosition(); // und zurueck an alte Position @@ -1097,7 +1099,6 @@ FltError ImportExcel8::Read( void ) case 0x9B: FilterMode(); break; // FILTERMODE case 0x9D: AutoFilterInfo(); break;// AUTOFILTERINFO case 0x9E: AutoFilter(); break; // AUTOFILTER - case 0x01BA: Codename( FALSE ); break; case 0x0208: Row34(); break; // ROW [ 34 ] case 0x0021: case 0x0221: Array34(); break; // ARRAY [ 34 ] @@ -1192,6 +1193,7 @@ FltError ImportExcel8::Read( void ) case EXC_ID_SXDI: rPTableMgr.ReadSxdi( maStrm ); break; case EXC_ID_SXVDEX: rPTableMgr.ReadSxvdex( maStrm ); break; case EXC_ID_SXEX: rPTableMgr.ReadSxex( maStrm ); break; + case EXC_ID_SHEETEXT: rTabViewSett.ReadTabBgColor( maStrm, rPal ); break; case EXC_ID_SXVIEWEX9: rPTableMgr.ReadSxViewEx9( maStrm ); break; } } @@ -1211,7 +1213,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..0509f2afa5fa 100644 --- a/sc/source/filter/excel/xeescher.cxx +++ b/sc/source/filter/excel/xeescher.cxx @@ -146,7 +146,7 @@ void XclExpDffSheetAnchor::ImplSetFlags( const SdrObject& rSdrObj ) void XclExpDffSheetAnchor::ImplCalcAnchorRect( const Rectangle& rRect, MapUnit eMapUnit ) { - maAnchor.SetRect( GetDoc(), mnScTab, rRect, eMapUnit ); + maAnchor.SetRect( GetRoot(), mnScTab, rRect, eMapUnit ); } // ---------------------------------------------------------------------------- @@ -175,7 +175,7 @@ void XclExpDffEmbeddedAnchor::ImplCalcAnchorRect( const Rectangle& rRect, MapUni XclExpDffNoteAnchor::XclExpDffNoteAnchor( const XclExpRoot& rRoot, const Rectangle& rRect ) : XclExpDffAnchorBase( rRoot, EXC_ESC_ANCHOR_SIZELOCKED ) { - maAnchor.SetRect( GetDoc(), rRoot.GetCurrScTab(), rRect, MAP_100TH_MM ); + maAnchor.SetRect( rRoot, rRoot.GetCurrScTab(), rRect, MAP_100TH_MM ); } // ---------------------------------------------------------------------------- @@ -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/xepage.cxx b/sc/source/filter/excel/xepage.cxx index 753d43e8d584..6194a04c27f6 100644 --- a/sc/source/filter/excel/xepage.cxx +++ b/sc/source/filter/excel/xepage.cxx @@ -45,9 +45,14 @@ #include "xehelper.hxx" #include "xeescher.hxx" +#include <set> +#include <limits> + #include <oox/core/tokens.hxx> using ::rtl::OString; +using ::std::set; +using ::std::numeric_limits; // Page settings records ====================================================== @@ -299,17 +304,23 @@ XclExpPageSettings::XclExpPageSettings( const XclExpRoot& rRoot ) : // *** page breaks *** - ScCompressedArrayIterator< SCROW, BYTE> aIter( rDoc.GetRowFlagsArray( nScTab), 1, GetMaxPos().Row()); - do + set<SCROW> aRowBreaks; + rDoc.GetAllRowBreaks(aRowBreaks, nScTab, false, true); + + SCROW nMaxRow = numeric_limits<sal_uInt16>::max(); + for (set<SCROW>::const_iterator itr = aRowBreaks.begin(), itrEnd = aRowBreaks.end(); itr != itrEnd; ++itr) { - if (*aIter & CR_MANUALBREAK) - for (SCROW j=aIter.GetRangeStart(); j<=aIter.GetRangeEnd(); ++j) - maData.maHorPageBreaks.push_back( static_cast< sal_uInt16 >( j ) ); - } while (aIter.NextRange()); - - for( SCCOL nScCol = 1, nScMaxCol = GetMaxPos().Col(); nScCol <= nScMaxCol; ++nScCol ) - if( rDoc.GetColFlags( nScCol, nScTab ) & CR_MANUALBREAK ) - maData.maVerPageBreaks.push_back( static_cast< sal_uInt16 >( nScCol ) ); + SCROW nRow = *itr; + if (nRow > nMaxRow) + break; + + maData.maHorPageBreaks.push_back(nRow); + } + + set<SCCOL> aColBreaks; + rDoc.GetAllColBreaks(aColBreaks, nScTab, false, true); + for (set<SCCOL>::const_iterator itr = aColBreaks.begin(), itrEnd = aColBreaks.end(); itr != itrEnd; ++itr) + maData.maVerPageBreaks.push_back(*itr); } static void lcl_WriteHeaderFooter( XclExpXmlStream& rStrm ) diff --git a/sc/source/filter/excel/xeroot.cxx b/sc/source/filter/excel/xeroot.cxx index 834873740d68..50e07ae1f2ed 100644 --- a/sc/source/filter/excel/xeroot.cxx +++ b/sc/source/filter/excel/xeroot.cxx @@ -33,6 +33,7 @@ #include <unotools/saveopt.hxx> #include <svl/itemset.hxx> #include <svl/stritem.hxx> +#include <svl/intitem.hxx> #include <svl/eitem.hxx> #include "xecontent.hxx" #include "xltracer.hxx" @@ -247,24 +248,16 @@ bool XclExpRoot::IsDocumentEncrypted() const return false; } -const String XclExpRoot::GetPassword() const +String XclExpRoot::GetPassword() const { - SfxItemSet* pSet = GetMedium().GetItemSet(); - if (!pSet) - return String(); - - const SfxPoolItem* pItem = NULL; - if (SFX_ITEM_SET == pSet->GetItemState(SID_PASSWORD, sal_True, &pItem)) + if( SfxItemSet* pItemSet = GetMedium().GetItemSet() ) { - const SfxStringItem* pStrItem = dynamic_cast<const SfxStringItem*>(pItem); - if (pStrItem) - { - // Password from the save dialog. - return pStrItem->GetValue(); - } + const SfxPoolItem* pItem = 0; + if( pItemSet->GetItemState( SID_PASSWORD, TRUE, &pItem ) == SFX_ITEM_SET ) + if( const SfxStringItem* pStrItem = dynamic_cast< const SfxStringItem* >( pItem ) ) + return pStrItem->GetValue(); } - - return String(); + return String::EmptyString(); } XclExpRootData::XclExpLinkMgrRef XclExpRoot::GetLocalLinkMgrRef() const diff --git a/sc/source/filter/excel/xestyle.cxx b/sc/source/filter/excel/xestyle.cxx index 315282098cec..ccebe9a4280f 100644 --- a/sc/source/filter/excel/xestyle.cxx +++ b/sc/source/filter/excel/xestyle.cxx @@ -74,6 +74,7 @@ sal_uInt32 lclGetWeighting( XclExpColorType eType ) case EXC_COLOR_CELLTEXT: case EXC_COLOR_CHARTTEXT: case EXC_COLOR_CTRLTEXT: return 10; + case EXC_COLOR_TABBG: case EXC_COLOR_CELLAREA: return 20; case EXC_COLOR_GRID: return 50; default: DBG_ERRORFILE( "lclGetWeighting - unknown color type" ); diff --git a/sc/source/filter/excel/xetable.cxx b/sc/source/filter/excel/xetable.cxx index e9aaa70bceba..b5ca318a91b4 100644 --- a/sc/source/filter/excel/xetable.cxx +++ b/sc/source/filter/excel/xetable.cxx @@ -1601,8 +1601,7 @@ XclExpColinfo::XclExpColinfo( const XclExpRoot& rRoot, mnWidth = XclTools::GetXclColumnWidth( nScWidth, GetCharWidth() ); // column flags - BYTE nScColFlags = rDoc.GetColFlags( nScCol, nScTab ); - ::set_flag( mnFlags, EXC_COLINFO_HIDDEN, (nScColFlags & CR_HIDDEN) != 0 ); + ::set_flag( mnFlags, EXC_COLINFO_HIDDEN, rDoc.ColHidden(nScCol, nScTab) ); // outline data rOutlineBfr.Update( nScCol ); @@ -1827,23 +1826,17 @@ XclExpRow::XclExpRow( const XclExpRoot& rRoot, sal_uInt16 nXclRow, BYTE nRowFlags = GetDoc().GetRowFlags( nScRow, nScTab ); bool bUserHeight = ::get_flag< BYTE >( nRowFlags, CR_MANUALSIZE ); - bool bHidden = ::get_flag< BYTE >( nRowFlags, CR_HIDDEN ); + bool bHidden = GetDoc().RowHidden(nScRow, nScTab); ::set_flag( mnFlags, EXC_ROW_UNSYNCED, bUserHeight ); ::set_flag( mnFlags, EXC_ROW_HIDDEN, bHidden ); // *** Row height *** ----------------------------------------------------- - USHORT nScHeight = GetDoc().GetRowHeight( nScRow, nScTab ); - if( nScHeight == 0 ) - { - ::set_flag( mnFlags, EXC_ROW_HIDDEN ); - mnHeight = EXC_ROW_DEFAULTHEIGHT; - } + if (bUserHeight) + mnHeight = GetDoc().GetRowHeight(nScRow, nScTab, false); else - { - // Calc and Excel use twips - mnHeight = static_cast< sal_uInt16 >( nScHeight ); - } + mnHeight = EXC_ROW_DEFAULTHEIGHT; + // #76250# not usable in Applix // ::set_flag( mnHeight, EXC_ROW_FLAGDEFHEIGHT, !bUserHeight ); diff --git a/sc/source/filter/excel/xeview.cxx b/sc/source/filter/excel/xeview.cxx index c342b5a40ea1..035afd0a5830 100644 --- a/sc/source/filter/excel/xeview.cxx +++ b/sc/source/filter/excel/xeview.cxx @@ -256,6 +256,35 @@ void XclExpSelection::WriteBody( XclExpStream& rStrm ) maSelData.maXclSelection.Write( rStrm, false ); } +// ---------------------------------------------------------------------------- + +XclExpTabBgColor::XclExpTabBgColor( const XclTabViewData& rTabViewData ) : + XclExpRecord( EXC_ID_SHEETEXT, 18 ), + mrTabViewData( rTabViewData ) +{ +} +//TODO Fix savexml... +/*void XclExpTabBgColor::SaveXml( XclExpXmlStream& rStrm ) +{ +}*/ + +void XclExpTabBgColor::WriteBody( XclExpStream& rStrm ) +{ + if ( mrTabViewData.IsDefaultTabBgColor() ) + return; + sal_uInt16 rt = 0x0862; //rt + sal_uInt16 grbitFrt = 0x0000; //grbit must be set to 0 + sal_uInt32 unused = 0x00000000; //Use twice... + sal_uInt32 cb = 0x00000014; // Record Size, may be larger in future... + sal_uInt16 reserved = 0x0000; //trailing bits are 0 + sal_uInt16 TabBgColorIndex; + XclExpPalette& rPal = rStrm.GetRoot().GetPalette(); + TabBgColorIndex = rPal.GetColorIndex(mrTabViewData.mnTabBgColorId); + if (TabBgColorIndex < 8 || TabBgColorIndex > 63 ) // only numbers 8 - 63 are valid numbers + TabBgColorIndex = 127; //Excel specs: 127 makes excel ignore tab color information. + rStrm << rt << grbitFrt << unused << unused << cb << TabBgColorIndex << reserved; +} + // Sheet view settings ======================================================== namespace { @@ -366,6 +395,14 @@ XclExpTabViewSettings::XclExpTabViewSettings( const XclExpRoot& rRoot, SCTAB nSc maData.mnPageZoom = lclGetXclZoom( rTabSett.mnPageZoom, EXC_WIN2_PAGEZOOM_DEF ); maData.mnCurrentZoom = maData.mbPageMode ? maData.mnPageZoom : maData.mnNormalZoom; } + + // Tab Bg Color + if ( GetBiff() == EXC_BIFF8 && !GetDoc().IsDefaultTabBgColor(nScTab) ) + { + XclExpPalette& rPal = GetPalette(); + maData.maTabBgColor = GetDoc().GetTabBgColor(nScTab); + maData.mnTabBgColorId = rPal.InsertColor(maData.maTabBgColor, EXC_COLOR_TABBG, EXC_COLOR_NOTABBG ); + } } void XclExpTabViewSettings::Save( XclExpStream& rStrm ) @@ -377,6 +414,7 @@ void XclExpTabViewSettings::Save( XclExpStream& rStrm ) WriteSelection( rStrm, EXC_PANE_TOPRIGHT ); WriteSelection( rStrm, EXC_PANE_BOTTOMLEFT ); WriteSelection( rStrm, EXC_PANE_BOTTOMRIGHT ); + WriteTabBgColor( rStrm ); } static void lcl_WriteSelection( XclExpXmlStream& rStrm, const XclTabViewData& rData, sal_uInt8 nPane ) @@ -491,5 +529,10 @@ void XclExpTabViewSettings::WriteSelection( XclExpStream& rStrm, sal_uInt8 nPane XclExpSelection( maData, nPane ).Save( rStrm ); } +void XclExpTabViewSettings::WriteTabBgColor( XclExpStream& rStrm ) const +{ + if ( !maData.IsDefaultTabBgColor() ) + XclExpTabBgColor( maData ).Save( rStrm ); +} // ============================================================================ diff --git a/sc/source/filter/excel/xichart.cxx b/sc/source/filter/excel/xichart.cxx index 6734f90948e4..7cbd74a836d2 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 ); - - /** Returns a reference to the parent chart data object. */ - inline XclImpChChart& GetChartData() const { return *mpChartData; } + XclImpChChart& mrChartData; /// The chart data object. -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 ) @@ -3831,6 +4053,16 @@ void XclImpChart::ReadChartSubStream( XclImpStream& rStrm ) case EXC_ID_WINDOW2: rTabViewSett.ReadWindow2( rStrm, true );break; case EXC_ID_SCL: rTabViewSett.ReadScl( rStrm ); break; + + case EXC_ID_SHEETEXT: //0x0862 + { + // FIXME: do not need to pass palette, XclImpTabVieSettings is derived from root + XclImpPalette& rPal = GetPalette(); + rTabViewSett.ReadTabBgColor( rStrm, rPal); + } + break; + + case EXC_ID_CODENAME: ReadCodeName( rStrm, false ); break; } // common records @@ -3892,7 +4124,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/xiescher.cxx b/sc/source/filter/excel/xiescher.cxx index 64ed79e3d3b2..dc87bba4c050 100644 --- a/sc/source/filter/excel/xiescher.cxx +++ b/sc/source/filter/excel/xiescher.cxx @@ -62,10 +62,6 @@ #include <basegfx/point/b2dpoint.hxx> #include <basegfx/polygon/b2dpolygon.hxx> -#include <basic/sbstar.hxx> -#include <basic/sbmod.hxx> -#include <basic/sbmeth.hxx> - #include <svx/svdopath.hxx> #include <svx/svdocirc.hxx> #include <svx/svdoedge.hxx> @@ -478,14 +474,14 @@ void XclImpDrawObjBase::PreProcessSdrObject( XclImpDffConverter& rDffConv, SdrOb { if( ScMacroInfo* pInfo = ScDrawLayer::GetMacroInfo( &rSdrObj, TRUE ) ) { - pInfo->SetMacro( XclControlHelper::GetScMacroName( maMacroName ) ); + pInfo->SetMacro( XclTools::GetSbMacroUrl( maMacroName, GetDocShell() ) ); pInfo->SetHlink( maHyperlink ); } } #else if( mbSimpleMacro && (maMacroName.Len() > 0) ) if( ScMacroInfo* pInfo = ScDrawLayer::GetMacroInfo( &rSdrObj, TRUE ) ) - pInfo->SetMacro( XclControlHelper::GetScMacroName( maMacroName ) ); + pInfo->SetMacro( XclTools::GetSbMacroUrl( maMacroName, GetDocShell() ) ); #endif // call virtual function for object type specific processing @@ -550,16 +546,7 @@ void XclImpDrawObjBase::ReadMacro8( XclImpStream& rStrm ) DBG_ASSERT( nTokenId == XclTokenArrayHelper::GetTokenId( EXC_TOKID_NAMEX, EXC_TOKCLASS_REF ), "XclImpDrawObjBase::ReadMacro - tNameXR token expected" ); if( nTokenId == XclTokenArrayHelper::GetTokenId( EXC_TOKID_NAMEX, EXC_TOKCLASS_REF ) ) - { maMacroName = GetLinkManager().GetMacroName( nExtSheet, nExtName ); - // #i38718# missing module name - try to find the macro in the imported modules - if( maMacroName.Len() && (maMacroName.Search( '.' ) == STRING_NOTFOUND) ) - if( SfxObjectShell* pDocShell = GetDocShell() ) - if( StarBASIC* pBasic = pDocShell->GetBasic() ) - if( SbMethod* pMethod = dynamic_cast< SbMethod* >( pBasic->Find( maMacroName, SbxCLASS_METHOD ) ) ) - if( SbModule* pModule = pMethod->GetModule() ) - maMacroName.Insert( '.', 0 ).Insert( pModule->GetName(), 0 ); - } } } } @@ -1709,7 +1696,7 @@ void XclImpChartObj::FinalizeTabChart() // create the object anchor XclObjAnchor aAnchor; - aAnchor.SetRect( GetDoc(), GetCurrScTab(), Rectangle( 1000, 500, nWidth, nHeight ), MAP_100TH_MM ); + aAnchor.SetRect( GetRoot(), GetCurrScTab(), Rectangle( 1000, 500, nWidth, nHeight ), MAP_100TH_MM ); SetAnchor( aAnchor ); } @@ -1947,7 +1934,7 @@ void XclImpTbxObjBase::SetDffProperties( const DffPropSet& rDffPropSet ) bool XclImpTbxObjBase::FillMacroDescriptor( ScriptEventDescriptor& rDescriptor ) const { - return XclControlHelper::FillMacroDescriptor( rDescriptor, DoGetEventType(), GetMacroName() ); + return XclControlHelper::FillMacroDescriptor( rDescriptor, DoGetEventType(), GetMacroName(), GetDocShell() ); } void XclImpTbxObjBase::ConvertFont( ScfPropertySet& rPropSet ) const @@ -3939,7 +3926,7 @@ void XclImpSheetDrawing::ConvertObjects( XclImpDffConverter& rDffConv ) Rectangle XclImpSheetDrawing::CalcAnchorRect( const XclObjAnchor& rAnchor, bool /*bDffAnchor*/ ) const { - return rAnchor.GetRect( GetDoc(), maScUsedArea.aStart.Tab(), MAP_100TH_MM ); + return rAnchor.GetRect( GetRoot(), maScUsedArea.aStart.Tab(), MAP_100TH_MM ); } void XclImpSheetDrawing::OnObjectInserted( const XclImpDrawObjBase& rDrawObj ) 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/xipage.cxx b/sc/source/filter/excel/xipage.cxx index c689d0eb7feb..38cebc2e6ca8 100644 --- a/sc/source/filter/excel/xipage.cxx +++ b/sc/source/filter/excel/xipage.cxx @@ -375,14 +375,14 @@ void XclImpPageSettings::Finalize() { SCROW nScRow = static_cast< SCROW >( *aIt ); if( nScRow <= MAXROW ) - rDoc.SetRowFlags( nScRow, nScTab, rDoc.GetRowFlags( nScRow, nScTab ) | CR_MANUALBREAK ); + rDoc.SetRowBreak(nScRow, nScTab, false, true); } for( aIt = maData.maVerPageBreaks.begin(), aEnd = maData.maVerPageBreaks.end(); aIt != aEnd; ++aIt ) { SCCOL nScCol = static_cast< SCCOL >( *aIt ); if( nScCol <= MAXCOL ) - rDoc.SetColFlags( nScCol, nScTab, rDoc.GetColFlags( nScCol, nScTab ) | CR_MANUALBREAK ); + rDoc.SetColBreak(nScCol, nScTab, false, true); } } diff --git a/sc/source/filter/excel/xiroot.cxx b/sc/source/filter/excel/xiroot.cxx index 3384cf248c87..3fd2650cf2ff 100644 --- a/sc/source/filter/excel/xiroot.cxx +++ b/sc/source/filter/excel/xiroot.cxx @@ -29,6 +29,8 @@ #include "precompiled_sc.hxx" #include "xiroot.hxx" #include "addincol.hxx" +#include "document.hxx" +#include "scextopt.hxx" #include "xltracer.hxx" #include "xihelper.hxx" #include "xiformula.hxx" @@ -49,7 +51,8 @@ XclImpRootData::XclImpRootData( XclBiff eBiff, SfxMedium& rMedium, SotStorageRef xRootStrg, ScDocument& rDoc, rtl_TextEncoding eTextEnc ) : XclRootData( eBiff, rMedium, xRootStrg, rDoc, eTextEnc, false ), - mbHasCodePage( false ) + mbHasCodePage( false ), + mbHasBasic( false ) { } @@ -272,5 +275,25 @@ String XclImpRoot::GetScAddInName( const String& rXclName ) const return rXclName; } -// ============================================================================ +void XclImpRoot::ReadCodeName( XclImpStream& rStrm, bool bGlobals ) +{ + if( mrImpData.mbHasBasic && (GetBiff() == EXC_BIFF8) ) + { + String aName = rStrm.ReadUniString(); + if( aName.Len() > 0 ) + { + if( bGlobals ) + { + GetExtDocOptions().GetDocSettings().maGlobCodeName = aName; + GetDoc().SetCodeName( aName ); + } + else + { + GetExtDocOptions().AppendCodeName( aName ); + GetDoc().SetCodeName( GetCurrScTab(), aName ); + } + } + } +} +// ============================================================================ diff --git a/sc/source/filter/excel/xiview.cxx b/sc/source/filter/excel/xiview.cxx index 6eeee8e04839..f75032ff461e 100644 --- a/sc/source/filter/excel/xiview.cxx +++ b/sc/source/filter/excel/xiview.cxx @@ -106,6 +106,24 @@ void XclImpTabViewSettings::Initialize() maData.SetDefaults(); } +void XclImpTabViewSettings::ReadTabBgColor( XclImpStream& rStrm, XclImpPalette& rPal ) +{ + DBG_ASSERT_BIFF( GetBiff() >= EXC_BIFF8 ); + if( GetBiff() < EXC_BIFF8 ) + return; + + sal_uInt8 ColorIndex; + Color TabBgColor; + + rStrm.Ignore( 16 ); + ColorIndex = rStrm.ReaduInt8() & EXC_SHEETEXT_TABCOLOR; //0x7F + if ( ColorIndex >= 8 && ColorIndex <= 63 ) //only accept valid index values + { + TabBgColor = rPal.GetColor( ColorIndex ); + maData.maTabBgColor = TabBgColor; + } +} + void XclImpTabViewSettings::ReadWindow2( XclImpStream& rStrm, bool bChart ) { if( GetBiff() == EXC_BIFF2 ) @@ -276,6 +294,10 @@ void XclImpTabViewSettings::Finalize() aViewOpt.SetOption( VOPT_OUTLINER, maData.mbShowOutline ); rDoc.SetViewOptions( aViewOpt ); } + + // *** set tab bg color + if ( !maData.IsDefaultTabBgColor() ) + rDoc.SetTabBgColor(nScTab, maData.maTabBgColor); } // ============================================================================ 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/xlescher.cxx b/sc/source/filter/excel/xlescher.cxx index 538fd7fd7242..bb77fac2be73 100644 --- a/sc/source/filter/excel/xlescher.cxx +++ b/sc/source/filter/excel/xlescher.cxx @@ -28,13 +28,16 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sc.hxx" +#include "xlescher.hxx" + #include <com/sun/star/drawing/XControlShape.hpp> #include <com/sun/star/script/ScriptEventDescriptor.hpp> #include <svx/unoapi.hxx> -#include "xestream.hxx" #include "document.hxx" +#include "xestream.hxx" #include "xistream.hxx" -#include "xlescher.hxx" +#include "xltools.hxx" +#include "xlroot.hxx" using ::rtl::OUString; using ::com::sun::star::uno::Reference; @@ -108,15 +111,15 @@ long lclGetYFromRow( ScDocument& rDoc, SCTAB nScTab, sal_uInt16 nXclRow, sal_uIn /** Calculates an object column position from a drawing layer X position (in twips). */ void lclGetColFromX( ScDocument& rDoc, SCTAB nScTab, sal_uInt16& rnXclCol, - sal_uInt16& rnOffset, sal_uInt16 nXclStartCol, + sal_uInt16& rnOffset, sal_uInt16 nXclStartCol, sal_uInt16 nXclMaxCol, long& rnStartW, long nX, double fScale ) { // rnStartW in conjunction with nXclStartCol is used as buffer for previously calculated width long nTwipsX = static_cast< long >( nX / fScale + 0.5 ); long nColW = 0; - for( rnXclCol = nXclStartCol; rnXclCol <= MAXCOL; ++rnXclCol ) + for( rnXclCol = nXclStartCol; rnXclCol <= nXclMaxCol; ++rnXclCol ) { - nColW = rDoc.GetColWidth( static_cast<SCCOL>(rnXclCol), nScTab ); + nColW = rDoc.GetColWidth( static_cast< SCCOL >( rnXclCol ), nScTab ); if( rnStartW + nColW > nTwipsX ) break; rnStartW += nColW; @@ -126,28 +129,27 @@ void lclGetColFromX( /** Calculates an object row position from a drawing layer Y position (in twips). */ void lclGetRowFromY( - ScDocument& rDoc, SCTAB nScTab, - sal_uInt16& rnXclRow, sal_uInt16& rnOffset, sal_uInt16 nXclStartRow, + ScDocument& rDoc, SCTAB nScTab, sal_uInt16& rnXclRow, + sal_uInt16& rnOffset, sal_uInt16 nXclStartRow, sal_uInt16 nXclMaxRow, long& rnStartH, long nY, double fScale ) { // rnStartH in conjunction with nXclStartRow is used as buffer for previously calculated height long nTwipsY = static_cast< long >( nY / fScale + 0.5 ); long nRowH = 0; - ScCoupledCompressedArrayIterator< SCROW, BYTE, USHORT> aIter( - rDoc.GetRowFlagsArray( nScTab), static_cast<SCROW>(nXclStartRow), - MAXROW, CR_HIDDEN, 0, rDoc.GetRowHeightArray( nScTab)); - for ( ; aIter; ++aIter ) + bool bFound = false; + for( SCROW nRow = static_cast< SCROW >( nXclStartRow ); nRow <= nXclMaxRow; ++nRow ) { - nRowH = *aIter; + nRowH = rDoc.GetRowHeight( nRow, nScTab ); if( rnStartH + nRowH > nTwipsY ) { - rnXclRow = static_cast< sal_uInt16 >( aIter.GetPos() ); + rnXclRow = static_cast< sal_uInt16 >( nRow ); + bFound = true; break; } rnStartH += nRowH; } - if (!aIter) - rnXclRow = static_cast< sal_uInt16 >( aIter.GetIterEnd() ); // down to the bottom.. + if( !bFound ) + rnXclRow = nXclMaxRow; rnOffset = static_cast< sal_uInt16 >( nRowH ? ((nTwipsY - rnStartH) * 256.0 / nRowH + 0.5) : 0 ); } @@ -176,8 +178,9 @@ XclObjAnchor::XclObjAnchor() : { } -Rectangle XclObjAnchor::GetRect( ScDocument& rDoc, SCTAB nScTab, MapUnit eMapUnit ) const +Rectangle XclObjAnchor::GetRect( const XclRoot& rRoot, SCTAB nScTab, MapUnit eMapUnit ) const { + ScDocument& rDoc = rRoot.GetDoc(); double fScale = lclGetTwipsScale( eMapUnit ); Rectangle aRect( lclGetXFromCol( rDoc, nScTab, maFirst.mnCol, mnLX, fScale ), @@ -191,20 +194,24 @@ Rectangle XclObjAnchor::GetRect( ScDocument& rDoc, SCTAB nScTab, MapUnit eMapUni return aRect; } -void XclObjAnchor::SetRect( ScDocument& rDoc, SCTAB nScTab, const Rectangle& rRect, MapUnit eMapUnit ) +void XclObjAnchor::SetRect( const XclRoot& rRoot, SCTAB nScTab, const Rectangle& rRect, MapUnit eMapUnit ) { - Rectangle aRect( rRect ); + ScDocument& rDoc = rRoot.GetDoc(); + sal_uInt16 nXclMaxCol = rRoot.GetXclMaxPos().Col(); + sal_uInt16 nXclMaxRow = static_cast<sal_uInt16>( rRoot.GetXclMaxPos().Row()); + // #106948# adjust coordinates in mirrored sheets + Rectangle aRect( rRect ); if( rDoc.IsLayoutRTL( nScTab ) ) lclMirrorRectangle( aRect ); double fScale = lclGetTwipsScale( eMapUnit ); long nDummy = 0; - lclGetColFromX( rDoc, nScTab, maFirst.mnCol, mnLX, 0, nDummy, aRect.Left(), fScale ); - lclGetColFromX( rDoc, nScTab, maLast.mnCol, mnRX, maFirst.mnCol, nDummy, aRect.Right(), fScale ); + lclGetColFromX( rDoc, nScTab, maFirst.mnCol, mnLX, 0, nXclMaxCol, nDummy, aRect.Left(), fScale ); + lclGetColFromX( rDoc, nScTab, maLast.mnCol, mnRX, maFirst.mnCol, nXclMaxCol, nDummy, aRect.Right(), fScale ); nDummy = 0; - lclGetRowFromY( rDoc, nScTab, maFirst.mnRow, mnTY, 0, nDummy, aRect.Top(), fScale ); - lclGetRowFromY( rDoc, nScTab, maLast.mnRow, mnBY, maFirst.mnRow, nDummy, aRect.Bottom(), fScale ); + lclGetRowFromY( rDoc, nScTab, maFirst.mnRow, mnTY, 0, nXclMaxRow, nDummy, aRect.Top(), fScale ); + lclGetRowFromY( rDoc, nScTab, maLast.mnRow, mnBY, maFirst.mnRow, nXclMaxRow, nDummy, aRect.Bottom(), fScale ); } void XclObjAnchor::SetRect( const Size& rPageSize, sal_Int32 nScaleX, sal_Int32 nScaleY, @@ -325,27 +332,7 @@ Reference< XControlModel > XclControlHelper::GetControlModel( Reference< XShape return xCtrlModel; } -#define EXC_MACRONAME_PRE "vnd.sun.star.script:Standard." -#define EXC_MACRONAME_SUF "?language=Basic&location=document" - -OUString XclControlHelper::GetScMacroName( const String& rXclMacroName ) -{ - if( rXclMacroName.Len() > 0 ) - return CREATE_OUSTRING( EXC_MACRONAME_PRE ) + rXclMacroName + CREATE_OUSTRING( EXC_MACRONAME_SUF ); - return OUString(); -} - -String XclControlHelper::GetXclMacroName( const OUString& rScMacroName ) -{ - const OUString saMacroNamePre = CREATE_OUSTRING( EXC_MACRONAME_PRE ); - const OUString saMacroNameSuf = CREATE_OUSTRING( EXC_MACRONAME_SUF ); - sal_Int32 snScMacroNameLen = rScMacroName.getLength(); - sal_Int32 snXclMacroNameLen = snScMacroNameLen - saMacroNamePre.getLength() - saMacroNameSuf.getLength(); - if( (snXclMacroNameLen > 0) && rScMacroName.matchIgnoreAsciiCase( saMacroNamePre, 0 ) && - rScMacroName.matchIgnoreAsciiCase( saMacroNameSuf, snScMacroNameLen - saMacroNameSuf.getLength() ) ) - return rScMacroName.copy( saMacroNamePre.getLength(), snXclMacroNameLen ); - return String::EmptyString(); -} +namespace { static const struct { @@ -362,17 +349,17 @@ spTbxListenerData[] = /*EXC_TBX_EVENT_CHANGE*/ { "XChangeListener", "changed" } }; -#define EXC_MACROSCRIPT "Script" +} // namespace bool XclControlHelper::FillMacroDescriptor( ScriptEventDescriptor& rDescriptor, - XclTbxEventType eEventType, const String& rXclMacroName ) + XclTbxEventType eEventType, const String& rXclMacroName, SfxObjectShell* pDocShell ) { if( rXclMacroName.Len() > 0 ) { rDescriptor.ListenerType = OUString::createFromAscii( spTbxListenerData[ eEventType ].mpcListenerType ); rDescriptor.EventMethod = OUString::createFromAscii( spTbxListenerData[ eEventType ].mpcEventMethod ); - rDescriptor.ScriptType = CREATE_OUSTRING( EXC_MACROSCRIPT ); - rDescriptor.ScriptCode = GetScMacroName( rXclMacroName ); + rDescriptor.ScriptType = CREATE_OUSTRING( "Script" ); + rDescriptor.ScriptCode = XclTools::GetSbMacroUrl( rXclMacroName, pDocShell ); return true; } return false; @@ -382,12 +369,11 @@ String XclControlHelper::ExtractFromMacroDescriptor( const ScriptEventDescriptor& rDescriptor, XclTbxEventType eEventType ) { if( (rDescriptor.ScriptCode.getLength() > 0) && - rDescriptor.ScriptType.equalsIgnoreAsciiCaseAscii( EXC_MACROSCRIPT ) && + rDescriptor.ScriptType.equalsIgnoreAsciiCaseAscii( "Script" ) && rDescriptor.ListenerType.equalsAscii( spTbxListenerData[ eEventType ].mpcListenerType ) && rDescriptor.EventMethod.equalsAscii( spTbxListenerData[ eEventType ].mpcEventMethod ) ) - return GetXclMacroName( rDescriptor.ScriptCode ); + return XclTools::GetXclMacroName( rDescriptor.ScriptCode ); return String::EmptyString(); } // ============================================================================ - 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/excel/xltools.cxx b/sc/source/filter/excel/xltools.cxx index 90393ae6a787..0dd988d67586 100644 --- a/sc/source/filter/excel/xltools.cxx +++ b/sc/source/filter/excel/xltools.cxx @@ -34,6 +34,7 @@ #include <unotools/fontcvt.hxx> #include <sfx2/objsh.hxx> #include <editeng/editstat.hxx> +#include <filter/msfilter/msvbahelper.hxx> #include "xestream.hxx" #include "document.hxx" #include "docuno.hxx" @@ -46,6 +47,8 @@ #include "xiroot.hxx" #include "xltools.hxx" +using ::rtl::OUString; + // GUID import/export ========================================================= XclGuid::XclGuid() @@ -684,6 +687,37 @@ void XclTools::SkipSubStream( XclImpStream& rStrm ) } } +// Basic macro names ---------------------------------------------------------- + +const OUString XclTools::maSbMacroPrefix( RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.script:Standard." ) ); +const OUString XclTools::maSbMacroSuffix( RTL_CONSTASCII_USTRINGPARAM( "?language=Basic&location=document" ) ); + +OUString XclTools::GetSbMacroUrl( const String& rMacroName, SfxObjectShell* pDocShell ) +{ + OSL_ENSURE( rMacroName.Len() > 0, "XclTools::GetSbMacroUrl - macro name is empty" ); + ::ooo::vba::VBAMacroResolvedInfo aMacroInfo = ::ooo::vba::resolveVBAMacro( pDocShell, rMacroName, false ); + if( aMacroInfo.IsResolved() ) + return ::ooo::vba::makeMacroURL( aMacroInfo.ResolvedMacro() ); + return OUString(); +} + +OUString XclTools::GetSbMacroUrl( const String& rModuleName, const String& rMacroName, SfxObjectShell* pDocShell ) +{ + OSL_ENSURE( rModuleName.Len() > 0, "XclTools::GetSbMacroUrl - module name is empty" ); + OSL_ENSURE( rMacroName.Len() > 0, "XclTools::GetSbMacroUrl - macro name is empty" ); + return GetSbMacroUrl( rModuleName + OUString( sal_Unicode( '.' ) ) + rMacroName, pDocShell ); +} + +String XclTools::GetXclMacroName( const OUString& rSbMacroUrl ) +{ + sal_Int32 nSbMacroUrlLen = rSbMacroUrl.getLength(); + sal_Int32 nMacroNameLen = nSbMacroUrlLen - maSbMacroPrefix.getLength() - maSbMacroSuffix.getLength(); + if( (nMacroNameLen > 0) && rSbMacroUrl.matchIgnoreAsciiCase( maSbMacroPrefix, 0 ) && + rSbMacroUrl.matchIgnoreAsciiCase( maSbMacroSuffix, nSbMacroUrlLen - maSbMacroSuffix.getLength() ) ) + return rSbMacroUrl.copy( maSbMacroPrefix.getLength(), nMacroNameLen ); + return String::EmptyString(); +} + // read/write colors ---------------------------------------------------------- XclImpStream& operator>>( XclImpStream& rStrm, Color& rColor ) @@ -700,4 +734,3 @@ XclExpStream& operator<<( XclExpStream& rStrm, const Color& rColor ) } // ============================================================================ - diff --git a/sc/source/filter/excel/xlview.cxx b/sc/source/filter/excel/xlview.cxx index d9cbbbb4b7c0..8e9df7e0ac1f 100644 --- a/sc/source/filter/excel/xlview.cxx +++ b/sc/source/filter/excel/xlview.cxx @@ -76,6 +76,7 @@ void XclTabViewData::SetDefaults() mbDefGridColor = true; mbShowFormulas = false; mbShowGrid = mbShowHeadings = mbShowZeros = mbShowOutline = true; + maTabBgColor.SetColor( COL_AUTO ); } bool XclTabViewData::IsSplit() const diff --git a/sc/source/filter/html/htmlexp.cxx b/sc/source/filter/html/htmlexp.cxx index e8c71d20af11..b4d764dc74a7 100644 --- a/sc/source/filter/html/htmlexp.cxx +++ b/sc/source/filter/html/htmlexp.cxx @@ -148,8 +148,6 @@ const sal_Char __FAR_DATA ScHTMLExport::sIndentSource[nIndentMax+1] = #define OUT_SP_CSTR_ASS( s ) rStrm << ' ' << s << '=' #define APPEND_SPACE( s ) s.AppendAscii(" ") -extern BOOL bOderSo; - #define GLOBSTR(id) ScGlobal::GetRscString( id ) @@ -234,30 +232,6 @@ void lcl_AppendHTMLColorTripel( ByteString& rStr, const Color& rColor ) } */ -bool SC_DLLPUBLIC ScGetWriteTeamInfo(); - -void lcl_WriteTeamInfo( SvStream& rStrm, rtl_TextEncoding eDestEnc ) -{ - if ( !ScGetWriteTeamInfo() ) return; - lcl_OUT_LF(); - lcl_OUT_COMMENT( CREATE_STRING( "Sascha Ballach " ) ); - lcl_OUT_COMMENT( CREATE_STRING( "Michael Daeumling (aka Bitsau) " ) ); - lcl_OUT_COMMENT( CREATE_STRING( "Michael Hagen " ) ); - lcl_OUT_COMMENT( CREATE_STRING( "Roland Jakobs " ) ); - lcl_OUT_COMMENT( CREATE_STRING( "Andreas Krebs " ) ); - lcl_OUT_COMMENT( CREATE_STRING( "John Marmion " ) ); - lcl_OUT_COMMENT( CREATE_STRING( "Niklas Nebel " ) ); - lcl_OUT_COMMENT( CREATE_STRING( "Jacques Nietsch " ) ); - lcl_OUT_COMMENT( CREATE_STRING( "Marcus Olk " ) ); - lcl_OUT_COMMENT( CREATE_STRING( "Eike Rathke " ) ); - lcl_OUT_COMMENT( CREATE_STRING( "Daniel Rentz " ) ); - lcl_OUT_COMMENT( CREATE_STRING( "Stephan Templin " ) ); - lcl_OUT_COMMENT( CREATE_STRING( "Gunnar Timm " ) ); - lcl_OUT_COMMENT( CREATE_STRING( "*** Man kann nicht ALLES haben! ***" ) ); - lcl_OUT_LF(); -} - - ////////////////////////////////////////////////////////////////////////////// ScHTMLExport::ScHTMLExport( SvStream& rStrmP, const String& rBaseURL, ScDocument* pDocP, @@ -416,8 +390,6 @@ void ScHTMLExport::WriteHeader() OUT_COMMENT( aStrOut ); } //---------------------------------------------------------- - - lcl_WriteTeamInfo( rStrm, eDestEnc ); } OUT_LF(); @@ -746,7 +718,7 @@ void ScHTMLExport::WriteTables() SCCOL nCol; for ( nCol=nStartCol; nCol<=nEndCol; nCol++ ) { - if ( !(pDoc->GetColFlags( nCol, nTab ) & CR_HIDDEN) ) + if ( !pDoc->ColHidden(nCol, nTab) ) ++nColCnt; } (((aByteStrOut += ' ') += OOO_STRING_SVTOOLS_HTML_O_cols) += '=') += ByteString::CreateFromInt32( nColCnt ); @@ -767,7 +739,7 @@ void ScHTMLExport::WriteTables() aByteStr += '='; for ( nCol=nStartCol; nCol<=nEndCol; nCol++ ) { - if ( pDoc->GetColFlags( nCol, nTab ) & CR_HIDDEN ) + if ( pDoc->ColHidden(nCol, nTab) ) continue; // for aByteStrOut = aByteStr; @@ -782,14 +754,12 @@ void ScHTMLExport::WriteTables() // At least old (3.x, 4.x?) Netscape doesn't follow <TABLE COLS=n> and // <COL WIDTH=x> specified, but needs a width at every column. bTableDataWidth = TRUE; // widths in first row - bool bHasHiddenRows = pDoc->GetRowFlagsArray( nTab).HasCondition( - nStartRow, nEndRow, CR_HIDDEN, CR_HIDDEN); + bool bHasHiddenRows = pDoc->HasHiddenRows(nStartRow, nEndRow, nTab); for ( SCROW nRow=nStartRow; nRow<=nEndRow; nRow++ ) { - if ( bHasHiddenRows && (pDoc->GetRowFlags( nRow, nTab ) & CR_HIDDEN) ) + if ( bHasHiddenRows && pDoc->RowHidden(nRow, nTab) ) { - nRow = pDoc->GetRowFlagsArray( nTab).GetFirstForCondition( - nRow+1, nEndRow, CR_HIDDEN, 0); + nRow = pDoc->FirstVisibleRow(nRow+1, nEndRow, nTab); --nRow; continue; // for } @@ -798,7 +768,7 @@ void ScHTMLExport::WriteTables() bTableDataHeight = TRUE; // height at every first cell of each row for ( SCCOL nCol2=nStartCol; nCol2<=nEndCol; nCol2++ ) { - if ( pDoc->GetColFlags( nCol2, nTab ) & CR_HIDDEN ) + if ( pDoc->ColHidden(nCol2, nTab) ) continue; // for if ( nCol2 == nEndCol ) diff --git a/sc/source/filter/html/htmlpars.cxx b/sc/source/filter/html/htmlpars.cxx index 7b0652e7cce9..85e77fc3124b 100644 --- a/sc/source/filter/html/htmlpars.cxx +++ b/sc/source/filter/html/htmlpars.cxx @@ -2424,12 +2424,15 @@ void ScHTMLTable::InsertNewCell( const ScHTMLSize& rSpanSize ) { ScRange* pRange; - // find an unused cell - while( (pRange = maVMergedCells.Find( maCurrCell.MakeAddr() )) != 0 ) + /* Find an unused cell by skipping all merged ranges that cover the + current cell position stored in maCurrCell. */ + while( ((pRange = maVMergedCells.Find( maCurrCell.MakeAddr() )) != 0) || ((pRange = maHMergedCells.Find( maCurrCell.MakeAddr() )) != 0) ) maCurrCell.mnCol = pRange->aEnd.Col() + 1; mpCurrEntryList = &maEntryMap[ maCurrCell ]; - // try to find collisions, shrink existing ranges + /* If the new cell is merged horizontally, try to find collisions with + other vertically merged ranges. In this case, shrink existing + vertically merged ranges (do not shrink the new cell). */ SCCOL nColEnd = maCurrCell.mnCol + rSpanSize.mnCols; for( ScAddress aAddr( maCurrCell.MakeAddr() ); aAddr.Col() < nColEnd; aAddr.IncCol() ) if( (pRange = maVMergedCells.Find( aAddr )) != 0 ) @@ -2438,14 +2441,19 @@ void ScHTMLTable::InsertNewCell( const ScHTMLSize& rSpanSize ) // insert the new range into the cell lists ScRange aNewRange( maCurrCell.MakeAddr() ); aNewRange.aEnd.Move( rSpanSize.mnCols - 1, rSpanSize.mnRows - 1, 0 ); - if( rSpanSize.mnCols > 1 ) + if( rSpanSize.mnRows > 1 ) { maVMergedCells.Append( aNewRange ); + /* Do not insert vertically merged ranges into maUsedCells yet, + because they may be shrunken (see above). The final vertically + merged ranges are inserted in FillEmptyCells(). */ } else { - if( rSpanSize.mnRows > 1 ) + if( rSpanSize.mnCols > 1 ) maHMergedCells.Append( aNewRange ); + /* Insert horizontally merged ranges and single cells into + maUsedCells, they will not be changed anymore. */ maUsedCells.Join( aNewRange ); } @@ -2592,6 +2600,7 @@ void ScHTMLTable::FillEmptyCells() for( ScHTMLTableIterator aIter( mxNestedTables.get() ); aIter.is(); ++aIter ) aIter->FillEmptyCells(); + // insert the final vertically merged ranges into maUsedCells for( const ScRange* pRange = maVMergedCells.First(); pRange; pRange = maVMergedCells.Next() ) maUsedCells.Join( *pRange ); diff --git a/sc/source/filter/inc/excimp8.hxx b/sc/source/filter/inc/excimp8.hxx index 1340f7c6f8be..5b2bbe2e7b5d 100644 --- a/sc/source/filter/inc/excimp8.hxx +++ b/sc/source/filter/inc/excimp8.hxx @@ -50,37 +50,38 @@ class XclImpStream; class ImportExcel8 : public ImportExcel { - SCTAB mnTab; - protected: - ExcScenarioList aScenList; - - BOOL bHasBasic; - - void Calccount( void ); // 0x0C - void Precision( void ); // 0x0E - void Delta( void ); // 0x10 - void Iteration( void ); // 0x11 - void Boundsheet( void ); // 0x85 - void FilterMode( void ); // 0x9B - void AutoFilterInfo( void ); // 0x9D - void AutoFilter( void ); // 0x9E - void Scenman( void ); // 0xAE - void Scenario( void ); // 0xAF - void ReadBasic( void ); // 0xD3 - void Labelsst( void ); // 0xFD - - void Hlink( void ); // 0x01B8 - void Codename( BOOL bWBGlobals ); // 0x01BA - void SheetProtection( void ); // 0x0867 - - virtual void EndSheet( void ); - virtual void PostDocLoad( void ); - - public: - ImportExcel8( XclImpRootData& rImpData, SvStream& rStrm ); - virtual ~ImportExcel8( void ); - - virtual FltError Read( void ); +public: + ImportExcel8( XclImpRootData& rImpData, SvStream& rStrm ); + virtual ~ImportExcel8( void ); + + virtual FltError Read( void ); + +protected: + ExcScenarioList aScenList; + + void Calccount( void ); // 0x0C + void Precision( void ); // 0x0E + void Delta( void ); // 0x10 + void Iteration( void ); // 0x11 + void Boundsheet( void ); // 0x85 + void FilterMode( void ); // 0x9B + void AutoFilterInfo( void ); // 0x9D + void AutoFilter( void ); // 0x9E + void Scenman( void ); // 0xAE + void Scenario( void ); // 0xAF + void ReadBasic( void ); // 0xD3 + void Labelsst( void ); // 0xFD + + void Hlink( void ); // 0x01B8 + void Codename( BOOL bWBGlobals ); // 0x01BA + void SheetProtection( void ); // 0x0867 + + virtual void EndSheet( void ); + virtual void PostDocLoad( void ); + +private: + void LoadDocumentProperties(); + void AttachDocumentEvents(); }; diff --git a/sc/source/filter/inc/imp_op.hxx b/sc/source/filter/inc/imp_op.hxx index 065678d5c792..2df58173a63a 100644 --- a/sc/source/filter/inc/imp_op.hxx +++ b/sc/source/filter/inc/imp_op.hxx @@ -97,6 +97,7 @@ protected: XclImpStream& aIn; // input stream ScfUInt32Vec maSheetOffsets; + ScRange maScOleSize; /// Visible range if embedded. NameBuffer* pExtNameBuff; // ... externe Namen (Ind.-Basis=1) ExcelToSc* pFormConv; // Formel-Konverter diff --git a/sc/source/filter/inc/xcl97rec.hxx b/sc/source/filter/inc/xcl97rec.hxx index 7a2a33795520..201562fa752c 100644 --- a/sc/source/filter/inc/xcl97rec.hxx +++ b/sc/source/filter/inc/xcl97rec.hxx @@ -535,7 +535,7 @@ private: class XclExpFileSharing : public XclExpRecord { public: - explicit XclExpFileSharing( const XclExpRoot& rRoot, sal_uInt16 nPasswordHash ); + explicit XclExpFileSharing( const XclExpRoot& rRoot, sal_uInt16 nPasswordHash, bool bRecommendReadOnly ); virtual void Save( XclExpStream& rStrm ); @@ -545,6 +545,7 @@ private: private: XclExpString maUserName; sal_uInt16 mnPasswordHash; + bool mbRecommendReadOnly; }; // ============================================================================ 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/xeroot.hxx b/sc/source/filter/inc/xeroot.hxx index f9d3a6ab2f95..980590f9d4ff 100644 --- a/sc/source/filter/inc/xeroot.hxx +++ b/sc/source/filter/inc/xeroot.hxx @@ -158,7 +158,7 @@ public: bool IsDocumentEncrypted() const; - const String GetPassword() const; + String GetPassword() const; private: diff --git a/sc/source/filter/inc/xestyle.hxx b/sc/source/filter/inc/xestyle.hxx index cb12e03b21ad..fd7303509688 100644 --- a/sc/source/filter/inc/xestyle.hxx +++ b/sc/source/filter/inc/xestyle.hxx @@ -58,7 +58,8 @@ enum XclExpColorType EXC_COLOR_CHARTLINE, /// Line in a chart. EXC_COLOR_CHARTAREA, /// Area in a chart. EXC_COLOR_CTRLTEXT, /// Text color in a form control. - EXC_COLOR_GRID /// Spreadsheet grid color. + EXC_COLOR_GRID, /// Spreadsheet grid color. + EXC_COLOR_TABBG /// Spreadsheet tab bg color. }; // ---------------------------------------------------------------------------- diff --git a/sc/source/filter/inc/xeview.hxx b/sc/source/filter/inc/xeview.hxx index ca94e6eae3f9..61e349ab1e86 100644 --- a/sc/source/filter/inc/xeview.hxx +++ b/sc/source/filter/inc/xeview.hxx @@ -131,6 +131,20 @@ private: sal_uInt8 mnPane; /// Pane identifier of this selection. }; +class XclExpTabBgColor : public XclExpRecord +{ +public: + explicit XclExpTabBgColor( const XclTabViewData& rTabViewData ); + + /* virtual void SaveXml( XclExpXmlStream& rStrm ); TODO Fix XML Saving Stream */ +private: + /** Writes the contents of the SHEETEXT record. */ + virtual void WriteBody( XclExpStream& rStrm ); + +private: + const XclTabViewData& mrTabViewData; /// view settings data of current sheet. +}; + // View settings ============================================================== /** Contains all view settings records for a single sheet. */ @@ -153,6 +167,7 @@ private: void WriteScl( XclExpStream& rStrm ) const; void WritePane( XclExpStream& rStrm ) const; void WriteSelection( XclExpStream& rStrm, sal_uInt8 nPane ) const; + void WriteTabBgColor( XclExpStream& rStrm ) const; private: XclTabViewData maData; /// All view settings for a sheet. 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/xiroot.hxx b/sc/source/filter/inc/xiroot.hxx index 0e06b31b650d..c5cf284d2d2e 100644 --- a/sc/source/filter/inc/xiroot.hxx +++ b/sc/source/filter/inc/xiroot.hxx @@ -116,6 +116,7 @@ struct XclImpRootData : public XclRootData XclImpDocProtectRef mxDocProtect; /// Document protection options. bool mbHasCodePage; /// true = CODEPAGE record exists. + bool mbHasBasic; /// true = document contains VB project. explicit XclImpRootData( XclBiff eBiff, SfxMedium& rMedium, SotStorageRef xRootStrg, ScDocument& rDoc, rtl_TextEncoding eTextEnc ); @@ -202,6 +203,13 @@ public: /** Returns the Calc add-in function name for an Excel function name. */ String GetScAddInName( const String& rXclName ) const; + /** Returns true, if the document contains a VB project. */ + inline bool HasBasic() const { return mrImpData.mbHasBasic; } + /** Called to indicate that the document contains a VB project. */ + inline void SetHasBasic() { mrImpData.mbHasBasic = true; } + /** Reads the CODENAME record and inserts the codename into the document. */ + void ReadCodeName( XclImpStream& rStrm, bool bGlobals ); + private: mutable XclImpRootData& mrImpData; /// Reference to the global import data struct. }; @@ -209,4 +217,3 @@ private: // ============================================================================ #endif - diff --git a/sc/source/filter/inc/xiview.hxx b/sc/source/filter/inc/xiview.hxx index 5f6d11c3439d..2451d69ee01c 100644 --- a/sc/source/filter/inc/xiview.hxx +++ b/sc/source/filter/inc/xiview.hxx @@ -80,7 +80,8 @@ public: void ReadPane( XclImpStream& rStrm ); /** Reads a SELECTION record. */ void ReadSelection( XclImpStream& rStrm ); - + /** Reads a SHEETEXT record (Tab Color). */ + void ReadTabBgColor( XclImpStream& rStrm, XclImpPalette& rPal ); /** Sets the view settings at the current sheet or the extended sheet options object. */ void Finalize(); 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/xlconst.hxx b/sc/source/filter/inc/xlconst.hxx index 0ffdcc3f1a6d..42160aae7529 100644 --- a/sc/source/filter/inc/xlconst.hxx +++ b/sc/source/filter/inc/xlconst.hxx @@ -250,7 +250,11 @@ const sal_uInt16 EXC_ID_DSF = 0x0161; const sal_uInt16 EXC_ID_USERSVIEWBEGIN = 0x01AA; const sal_uInt16 EXC_ID_USERSVIEWEND = 0x01AB; -// (0x01C0) XL9FILE -------------------------------------------------------- +// (0x01BA) CODENAME ---------------------------------------------------------- + +const sal_uInt16 EXC_ID_CODENAME = 0x01BA; + +// (0x01C0) XL9FILE ----------------------------------------------------------- const sal_uInt16 EXC_ID_XL9FILE = 0x01C0; diff --git a/sc/source/filter/inc/xlescher.hxx b/sc/source/filter/inc/xlescher.hxx index 33b75af8cd2c..921da6b8741b 100644 --- a/sc/source/filter/inc/xlescher.hxx +++ b/sc/source/filter/inc/xlescher.hxx @@ -28,6 +28,7 @@ #ifndef SC_XLESCHER_HXX #define SC_XLESCHER_HXX +#include <tools/gen.hxx> #include <vcl/mapunit.hxx> #include "fapihelper.hxx" #include "xladdress.hxx" @@ -320,9 +321,9 @@ struct XclObjAnchor : public XclRange explicit XclObjAnchor(); /** Calculates a rectangle from the contained coordinates. */ - Rectangle GetRect( ScDocument& rDoc, SCTAB nScTab, MapUnit eMapUnit ) const; + Rectangle GetRect( const XclRoot& rRoot, SCTAB nScTab, MapUnit eMapUnit ) const; /** Initializes the anchor coordinates for a sheet. */ - void SetRect( ScDocument& rDoc, SCTAB nScTab, const Rectangle& rRect, MapUnit eMapUnit ); + void SetRect( const XclRoot& rRoot, SCTAB nScTab, const Rectangle& rRect, MapUnit eMapUnit ); /** Initializes the anchor coordinates for an embedded draw page. */ void SetRect( const Size& rPageSize, sal_Int32 nScaleX, sal_Int32 nScaleY, @@ -431,16 +432,12 @@ public: static ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlModel > GetControlModel( ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > xShape ); - /** Returns the Calc macro name from an Excel macro name. */ - static ::rtl::OUString GetScMacroName( const String& rXclMacroName ); - /** Returns the Excel macro name from a Calc macro name. */ - static String GetXclMacroName( const ::rtl::OUString& rScMacroName ); - /** Fills the macro descriptor according to the passed macro name. */ static bool FillMacroDescriptor( ::com::sun::star::script::ScriptEventDescriptor& rDescriptor, XclTbxEventType eEventType, - const String& rXclMacroName ); + const String& rXclMacroName, + SfxObjectShell* pDocShell = 0 ); /** Tries to extract an Excel macro name from the passed macro descriptor. */ static String ExtractFromMacroDescriptor( const ::com::sun::star::script::ScriptEventDescriptor& rDescriptor, 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/inc/xltools.hxx b/sc/source/filter/inc/xltools.hxx index e8ceed8248d6..efe20a583104 100644 --- a/sc/source/filter/inc/xltools.hxx +++ b/sc/source/filter/inc/xltools.hxx @@ -31,6 +31,8 @@ #include "address.hxx" #include "ftools.hxx" +class SfxObjectShell; + // BIFF versions ============================================================== #define DBG_ERROR_BIFF() DBG_ERRORFILE( "Unknown BIFF type!" ) @@ -229,13 +231,24 @@ public: /** Skips a substream (BOF/EOF record block). Includes all embedded substreams. */ static void SkipSubStream( XclImpStream& rStrm ); - // ------------------------------------------------------------------------ + // Basic macro names ------------------------------------------------------ + + /** Returns the full StarBasic macro URL from an Excel macro name. */ + static ::rtl::OUString GetSbMacroUrl( const String& rMacroName, SfxObjectShell* pDocShell = 0 ); + /** Returns the full StarBasic macro URL from an Excel module and macro name. */ + static ::rtl::OUString GetSbMacroUrl( const String& rModuleName, const String& rMacroName, SfxObjectShell* pDocShell = 0 ); + /** Returns the Excel macro name from a full StarBasic macro URL. */ + static String GetXclMacroName( const ::rtl::OUString& rSbMacroUrl ); + +// ------------------------------------------------------------------------ private: - static const String maDefNamePrefix; /// Prefix for built-in defined names. - static const String maStyleNamePrefix1; /// Prefix for built-in cell style names. - static const String maStyleNamePrefix2; /// Prefix for built-in cell style names from OOX filter. - static const String maCFStyleNamePrefix1; /// Prefix for cond. formatting style names. - static const String maCFStyleNamePrefix2; /// Prefix for cond. formatting style names from OOX filter. + static const String maDefNamePrefix; /// Prefix for built-in defined names. + static const String maStyleNamePrefix1; /// Prefix for built-in cell style names. + static const String maStyleNamePrefix2; /// Prefix for built-in cell style names from OOX filter. + static const String maCFStyleNamePrefix1; /// Prefix for cond. formatting style names. + static const String maCFStyleNamePrefix2; /// Prefix for cond. formatting style names from OOX filter. + static const ::rtl::OUString maSbMacroPrefix; /// Prefix for StarBasic macros. + static const ::rtl::OUString maSbMacroSuffix; /// Suffix for StarBasic macros. }; // read/write colors ---------------------------------------------------------- diff --git a/sc/source/filter/inc/xlview.hxx b/sc/source/filter/inc/xlview.hxx index 1a116c84c08e..c0c9d4b3d6e1 100644 --- a/sc/source/filter/inc/xlview.hxx +++ b/sc/source/filter/inc/xlview.hxx @@ -86,6 +86,11 @@ const sal_uInt8 EXC_PANE_TOPLEFT = 3; /// Single, top, left, o const sal_uInt16 EXC_ID_SCL = 0x00A0; +// (0x0862) SHEETEXT ---------------------------------------------------------- + +const sal_uInt16 EXC_ID_SHEETEXT = 0x0862; /// header id for sheetext +const sal_uInt8 EXC_SHEETEXT_TABCOLOR = 0x7F; /// mask for tab color +const sal_uInt16 EXC_COLOR_NOTABBG = 0x7F; /// Excel ignores Tab color when set to this value... // Structs ==================================================================== /** Contains all view settings for the entire document. */ @@ -146,6 +151,9 @@ struct XclTabViewData bool mbShowHeadings; /// true = Show column/row headings. bool mbShowZeros; /// true = Show zero value zells. bool mbShowOutline; /// true = Show outlines. + Color maTabBgColor; /// Tab Color default = (COL_AUTO ) + bool IsDefaultTabBgColor() const { return maTabBgColor == Color(COL_AUTO) ? TRUE : FALSE; }; + sal_uInt32 mnTabBgColorId; /// pallette color id explicit XclTabViewData(); ~XclTabViewData(); diff --git a/sc/source/filter/lotus/lotimpop.cxx b/sc/source/filter/lotus/lotimpop.cxx index 5173d5303321..2f6f81b7279c 100644 --- a/sc/source/filter/lotus/lotimpop.cxx +++ b/sc/source/filter/lotus/lotimpop.cxx @@ -180,8 +180,7 @@ void ImportLotus::Hiddencolumn( UINT16 nRecLen ) { Read( nCol ); - pD->SetColFlags( static_cast<SCCOL> (nCol), static_cast<SCTAB> (nLTab), pD->GetColFlags( static_cast<SCCOL> (nCol), static_cast<SCTAB> (nLTab) ) | CR_HIDDEN ); - + pD->SetColHidden(static_cast<SCCOL>(nCol), static_cast<SCCOL>(nCol), static_cast<SCTAB>(nLTab), true); nCnt--; } } diff --git a/sc/source/filter/lotus/op.cxx b/sc/source/filter/lotus/op.cxx index 0306bdc6315b..4ab0c8bb3b14 100644 --- a/sc/source/filter/lotus/op.cxx +++ b/sc/source/filter/lotus/op.cxx @@ -226,7 +226,7 @@ void OP_ColumnWidth( SvStream& r, UINT16 /*n*/ ) nBreite = ( UINT16 ) ( TWIPS_PER_CHAR * nWidthSpaces ); else { - pDoc->SetColFlags( static_cast<SCCOL> (nCol), 0, pDoc->GetColFlags( static_cast<SCCOL> (nCol), 0 ) | CR_HIDDEN ); + pDoc->SetColHidden(static_cast<SCCOL>(nCol), static_cast<SCCOL>(nCol), 0, true); nBreite = nDefWidth; } @@ -335,7 +335,7 @@ void OP_HiddenCols( SvStream& r, UINT16 /*n*/ ) { if( nAkt & 0x01 ) // unterstes Bit gesetzt? // -> Hidden Col - pDoc->SetColFlags( nCount, 0, pDoc->GetColFlags( nCount, 0 ) | CR_HIDDEN ); + pDoc->SetColHidden(nCount, nCount, 0, true); nCount++; nAkt = nAkt / 2; // der Naechste bitte... diff --git a/sc/source/filter/rtf/eeimpars.cxx b/sc/source/filter/rtf/eeimpars.cxx index 86a347970ff6..7fb3d16c6c8d 100644 --- a/sc/source/filter/rtf/eeimpars.cxx +++ b/sc/source/filter/rtf/eeimpars.cxx @@ -435,7 +435,7 @@ void ScEEImport::WriteToDocument( BOOL bSizeColsRows, double nOutputFactor, SvNu for ( SCROW nRow = nStartRow; nRow <= nEndRow; nRow++ ) { USHORT nHeight = (USHORT)(ULONG) mpRowHeights->Get( nRow ); - if ( nHeight > mpDoc->FastGetRowHeight( nRow, nTab ) ) + if ( nHeight > mpDoc->GetRowHeight( nRow, nTab ) ) mpDoc->SetRowHeight( nRow, nTab, nHeight ); } } diff --git a/sc/source/filter/rtf/expbase.cxx b/sc/source/filter/rtf/expbase.cxx index 3188b4f920e7..cd3f30ef9c9f 100644 --- a/sc/source/filter/rtf/expbase.cxx +++ b/sc/source/filter/rtf/expbase.cxx @@ -75,16 +75,13 @@ BOOL ScExportBase::GetDataArea( SCTAB nTab, SCCOL& nStartCol, BOOL ScExportBase::TrimDataArea( SCTAB nTab, SCCOL& nStartCol, SCROW& nStartRow, SCCOL& nEndCol, SCROW& nEndRow ) const { - while ( nStartCol <= nEndCol && - pDoc->GetColFlags( nStartCol, nTab ) & CR_HIDDEN ) + SCCOL nLastCol; + while ( nStartCol <= nEndCol && pDoc->ColHidden(nStartCol, nTab, nLastCol)) ++nStartCol; - while ( nStartCol <= nEndCol && - pDoc->GetColFlags( nEndCol, nTab ) & CR_HIDDEN ) + while ( nStartCol <= nEndCol && pDoc->ColHidden(nEndCol, nTab, nLastCol)) --nEndCol; - nStartRow = pDoc->GetRowFlagsArray( nTab).GetFirstForCondition( nStartRow, - nEndRow, CR_HIDDEN, 0); - nEndRow = pDoc->GetRowFlagsArray( nTab).GetLastForCondition( nStartRow, - nEndRow, CR_HIDDEN, 0); + nStartRow = pDoc->FirstVisibleRow(nStartRow, nEndRow, nTab); + nEndRow = pDoc->LastVisibleRow(nStartRow, nEndRow, nTab); return nStartCol <= nEndCol && nStartRow <= nEndRow && nEndRow != ::std::numeric_limits<SCROW>::max(); } diff --git a/sc/source/filter/starcalc/scflt.cxx b/sc/source/filter/starcalc/scflt.cxx index 104d0d7fe192..c9bf2a90a7a5 100644 --- a/sc/source/filter/starcalc/scflt.cxx +++ b/sc/source/filter/starcalc/scflt.cxx @@ -1548,14 +1548,14 @@ void Sc10Import::LoadTables() rStream >> DataValue; if (DataValue != 0) { - BYTE nFlags = 0; - if ((DataValue & crfSoftBreak) == crfSoftBreak) - nFlags |= CR_PAGEBREAK; - if ((DataValue & crfHardBreak) == crfHardBreak) - nFlags |= CR_MANUALBREAK; - if ((DataValue & crfHidden) == crfHidden) - nFlags |= CR_HIDDEN; - for (SCCOL k = static_cast<SCCOL>(DataStart); k <= static_cast<SCCOL>(DataEnd); k++) pDoc->SetColFlags(k, static_cast<SCTAB> (TabNo), nFlags); + bool bPageBreak = ((DataValue & crfSoftBreak) == crfSoftBreak); + bool bManualBreak = ((DataValue & crfHardBreak) == crfHardBreak); + bool bHidden = ((DataValue & crfHidden) == crfHidden); + for (SCCOL k = static_cast<SCCOL>(DataStart); k <= static_cast<SCCOL>(DataEnd); k++) + { + pDoc->SetColHidden(k, k, static_cast<SCTAB>(TabNo), bHidden); + pDoc->SetColBreak(k, static_cast<SCTAB> (TabNo), bPageBreak, bManualBreak); + } } DataStart = DataEnd + 1; } @@ -1598,14 +1598,14 @@ void Sc10Import::LoadTables() rStream >> DataValue; if (DataValue != 0) { - BYTE nFlags = 0; - if ((DataValue & crfSoftBreak) == crfSoftBreak) - nFlags |= CR_PAGEBREAK; - if ((DataValue & crfHardBreak) == crfHardBreak) - nFlags |= CR_MANUALBREAK; - if ((DataValue & crfHidden) == crfHidden) - nFlags |= CR_HIDDEN; - for (SCROW l = static_cast<SCROW>(DataStart); l <= static_cast<SCROW>(DataEnd); l++) pDoc->SetRowFlags(l, static_cast<SCTAB> (TabNo), nFlags); + bool bPageBreak = ((DataValue & crfSoftBreak) == crfSoftBreak); + bool bManualBreak = ((DataValue & crfHardBreak) == crfHardBreak); + bool bHidden = ((DataValue & crfHidden) == crfHidden); + for (SCROW l = static_cast<SCROW>(DataStart); l <= static_cast<SCROW>(DataEnd); l++) + { + pDoc->SetRowHidden(l, l, static_cast<SCTAB> (TabNo), bHidden); + pDoc->SetRowBreak(l, static_cast<SCTAB> (TabNo), bPageBreak, bManualBreak); + } } DataStart = DataEnd + 1; } @@ -2396,7 +2396,7 @@ void Sc10Import::LoadObjects() nStartX = (long) ( nStartX * HMM_PER_TWIPS ); nStartX += (long) ( GraphHeader.x / nPPTX * HMM_PER_TWIPS ); long nSizeX = (long) ( GraphHeader.w / nPPTX * HMM_PER_TWIPS ); - long nStartY = pDoc->FastGetRowHeight( 0, + long nStartY = pDoc->GetRowHeight( 0, static_cast<SCsROW>(GraphHeader.CarretY) - 1, static_cast<SCTAB>(GraphHeader.CarretZ)); nStartY = (long) ( nStartY * HMM_PER_TWIPS ); diff --git a/sc/source/filter/xcl97/xcl97rec.cxx b/sc/source/filter/xcl97/xcl97rec.cxx index 67a295ccec8b..df6bdcbbe671 100644 --- a/sc/source/filter/xcl97/xcl97rec.cxx +++ b/sc/source/filter/xcl97/xcl97rec.cxx @@ -1354,9 +1354,10 @@ void XclExpWriteAccess::WriteBody( XclExpStream& rStrm ) // ============================================================================ -XclExpFileSharing::XclExpFileSharing( const XclExpRoot& rRoot, sal_uInt16 nPasswordHash ) : +XclExpFileSharing::XclExpFileSharing( const XclExpRoot& rRoot, sal_uInt16 nPasswordHash, bool bRecommendReadOnly ) : XclExpRecord( EXC_ID_FILESHARING ), - mnPasswordHash( nPasswordHash ) + mnPasswordHash( nPasswordHash ), + mbRecommendReadOnly( bRecommendReadOnly ) { if( rRoot.GetBiff() <= EXC_BIFF5 ) maUserName.AssignByte( rRoot.GetUserName(), rRoot.GetTextEncoding(), EXC_STR_8BITLENGTH ); @@ -1366,13 +1367,13 @@ XclExpFileSharing::XclExpFileSharing( const XclExpRoot& rRoot, sal_uInt16 nPassw void XclExpFileSharing::Save( XclExpStream& rStrm ) { - if( mnPasswordHash != 0 ) + if( (mnPasswordHash != 0) || mbRecommendReadOnly ) XclExpRecord::Save( rStrm ); } void XclExpFileSharing::WriteBody( XclExpStream& rStrm ) { - rStrm << sal_uInt16( 0 ) << mnPasswordHash << maUserName; + rStrm << sal_uInt16( mbRecommendReadOnly ? 1 : 0 ) << mnPasswordHash << maUserName; } // ============================================================================ diff --git a/sc/source/filter/xml/XMLCodeNameProvider.cxx b/sc/source/filter/xml/XMLCodeNameProvider.cxx new file mode 100755 index 000000000000..ca4bac7eb511 --- /dev/null +++ b/sc/source/filter/xml/XMLCodeNameProvider.cxx @@ -0,0 +1,204 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + +// INCLUDE --------------------------------------------------------------- + +#include "XMLCodeNameProvider.hxx" +#include "document.hxx" + +using namespace rtl; +using namespace com::sun::star; + +sal_Bool XMLCodeNameProvider::_getCodeName( const uno::Any& aAny, String& rCodeName ) +{ + uno::Sequence<beans::PropertyValue> aProps; + if( !(aAny >>= aProps) ) + return sal_False; + + OUString sCodeNameProp( RTL_CONSTASCII_USTRINGPARAM("CodeName") ); + sal_Int32 nPropCount = aProps.getLength(); + for( sal_Int32 i=0; i<nPropCount; i++ ) + { + if( aProps[i].Name == sCodeNameProp ) + { + OUString sCodeName; + if( aProps[i].Value >>= sCodeName ) + { + rCodeName = sCodeName; + return sal_True; + } + } + } + + return sal_False; +} + + +XMLCodeNameProvider::XMLCodeNameProvider( ScDocument* pDoc ) : + mpDoc( pDoc ), + msDocName( RTL_CONSTASCII_USTRINGPARAM("*doc*") ), + msCodeNameProp( RTL_CONSTASCII_USTRINGPARAM("CodeName") ) +{ +} + +XMLCodeNameProvider::~XMLCodeNameProvider() +{ +} + +::sal_Bool SAL_CALL XMLCodeNameProvider::hasByName( const OUString& aName ) + throw (uno::RuntimeException ) +{ + if( aName == msDocName ) + return mpDoc->GetCodeName().Len() > 0; + + SCTAB nCount = mpDoc->GetTableCount(); + String sName( aName ); + String sSheetName, sCodeName; + for( SCTAB i = 0; i < nCount; i++ ) + { + if( mpDoc->GetName( i, sSheetName ) && sSheetName == sName ) + { + mpDoc->GetCodeName( i, sCodeName ); + return sCodeName.Len() > 0; + } + } + + return sal_False; +} + +uno::Any SAL_CALL XMLCodeNameProvider::getByName( const OUString& aName ) + throw (container::NoSuchElementException, + lang::WrappedTargetException, uno::RuntimeException) +{ + uno::Any aRet; + uno::Sequence<beans::PropertyValue> aProps(1); + aProps[0].Name = msCodeNameProp; + if( aName == msDocName ) + { + OUString sUCodeName( mpDoc->GetCodeName() ); + aProps[0].Value <<= sUCodeName; + aRet <<= aProps; + return aRet; + } + + SCTAB nCount = mpDoc->GetTableCount(); + String sName( aName ); + String sSheetName, sCodeName; + for( SCTAB i = 0; i < nCount; i++ ) + { + if( mpDoc->GetName( i, sSheetName ) && sSheetName == sName ) + { + mpDoc->GetCodeName( i, sCodeName ); + OUString sUCodeName( sCodeName ); + aProps[0].Value <<= sUCodeName; + aRet <<= aProps; + return aRet; + } + } + + return aRet; +} + +uno::Sequence< OUString > SAL_CALL XMLCodeNameProvider::getElementNames( ) + throw (uno::RuntimeException) +{ + SCTAB nCount = mpDoc->GetTableCount() + 1; + uno::Sequence< rtl::OUString > aNames( nCount ); + sal_Int32 nRealCount = 0; + + if( mpDoc->GetCodeName().Len() ) + aNames[nRealCount++] = msDocName; + + String sSheetName, sCodeName; + for( SCTAB i = 0; i < nCount; i++ ) + { + mpDoc->GetCodeName( i, sCodeName ); + if( sCodeName.Len() > 0 ) + { + if( mpDoc->GetName( i, sSheetName ) ) + aNames[nRealCount++] = sSheetName; + } + } + + if( nCount != nRealCount ) + aNames.realloc( nRealCount ); + + return aNames; +} + +uno::Type SAL_CALL XMLCodeNameProvider::getElementType( ) + throw (uno::RuntimeException) +{ + return uno::Type(); +} + +::sal_Bool SAL_CALL XMLCodeNameProvider::hasElements() + throw (uno::RuntimeException ) +{ + if( mpDoc->GetCodeName().Len() > 0 ) + return sal_True; + + SCTAB nCount = mpDoc->GetTableCount(); + String sSheetName, sCodeName; + for( SCTAB i = 0; i < nCount; i++ ) + { + mpDoc->GetCodeName( i, sCodeName ); + if( sCodeName.Len() > 0 && mpDoc->GetName( i, sSheetName ) ) + return sal_True; + } + + return sal_False; +} + +void XMLCodeNameProvider::set( const uno::Reference< container::XNameAccess>& xNameAccess, ScDocument *pDoc ) +{ + uno::Any aAny; + OUString sDocName( RTL_CONSTASCII_USTRINGPARAM("*doc*") ); + String sCodeName; + if( xNameAccess->hasByName( sDocName ) ) + { + aAny = xNameAccess->getByName( sDocName ); + if( _getCodeName( aAny, sCodeName ) ) + pDoc->SetCodeName( sCodeName ); + } + + SCTAB nCount = pDoc->GetTableCount(); + String sSheetName; + for( SCTAB i = 0; i < nCount; i++ ) + { + if( pDoc->GetName( i, sSheetName ) && + xNameAccess->hasByName( sSheetName ) ) + { + aAny = xNameAccess->getByName( sSheetName ); + if( _getCodeName( aAny, sCodeName ) ) + pDoc->SetCodeName( i, sCodeName ); + } + } +} diff --git a/sc/source/filter/xml/XMLCodeNameProvider.hxx b/sc/source/filter/xml/XMLCodeNameProvider.hxx new file mode 100755 index 000000000000..39d84409c555 --- /dev/null +++ b/sc/source/filter/xml/XMLCodeNameProvider.hxx @@ -0,0 +1,70 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SC_XMLCODENAMEPROVIDER_HXX +#define SC_XMLCODENAMEPROVIDER_HXX + +#include <com/sun/star/container/XNameAccess.hpp> +#include <cppuhelper/implbase1.hxx> + +class ScDocument; +class String; + +class XMLCodeNameProvider : public ::cppu::WeakImplHelper1< ::com::sun::star::container::XNameAccess > +{ + ScDocument* mpDoc; + ::rtl::OUString msDocName; + ::rtl::OUString msCodeNameProp; + + static sal_Bool _getCodeName( const ::com::sun::star::uno::Any& aAny, + String& rCodeName ); + +public: + XMLCodeNameProvider( ScDocument* pDoc ); + virtual ~XMLCodeNameProvider(); + + virtual ::sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName ) + throw (::com::sun::star::uno::RuntimeException ); + + virtual ::com::sun::star::uno::Any SAL_CALL getByName( const ::rtl::OUString& aName ) + throw (::com::sun::star::container::NoSuchElementException, + ::com::sun::star::lang::WrappedTargetException, + ::com::sun::star::uno::RuntimeException); + + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getElementNames( ) + throw (::com::sun::star::uno::RuntimeException); + + virtual ::com::sun::star::uno::Type SAL_CALL getElementType( ) + throw (::com::sun::star::uno::RuntimeException); + + virtual ::sal_Bool SAL_CALL hasElements() + throw (::com::sun::star::uno::RuntimeException ); + + static void set( const ::com::sun::star::uno::Reference< ::com::sun::star::container::XNameAccess>& xNameAccess, ScDocument *pDoc ); +}; + +#endif 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/makefile.mk b/sc/source/filter/xml/makefile.mk index 360148d38244..7f9f2d529a90 100644 --- a/sc/source/filter/xml/makefile.mk +++ b/sc/source/filter/xml/makefile.mk @@ -96,7 +96,8 @@ SLOFILES = \ $(SLO)$/XMLChangeTrackingImportHelper.obj \ $(SLO)$/XMLTrackedChangesContext.obj \ $(SLO)$/XMLExportSharedData.obj \ - $(SLO)$/XMLEmptyContext.obj + $(SLO)$/XMLEmptyContext.obj \ + $(SLO)$/XMLCodeNameProvider.obj NOOPTFILES= \ diff --git a/sc/source/filter/xml/xmldpimp.cxx b/sc/source/filter/xml/xmldpimp.cxx index 93e529c4ceca..ba107347b46a 100644 --- a/sc/source/filter/xml/xmldpimp.cxx +++ b/sc/source/filter/xml/xmldpimp.cxx @@ -464,6 +464,11 @@ void ScXMLDataPilotTableContext::EndElement() if (pDoc) { ScDPCollection* pDPCollection = pDoc->GetDPCollection(); + + // #i94570# Names have to be unique, or the tables can't be accessed by API. + if ( pDPCollection->GetByName(pDPObject->GetName()) ) + pDPObject->SetName( String() ); // ignore the invalid name, create a new name in AfterXMLLoading + pDPObject->SetAlive(sal_True); pDPCollection->InsertNewTable(pDPObject); } diff --git a/sc/source/filter/xml/xmlexprt.cxx b/sc/source/filter/xml/xmlexprt.cxx index d53f26a5e887..0563f6430063 100644 --- a/sc/source/filter/xml/xmlexprt.cxx +++ b/sc/source/filter/xml/xmlexprt.cxx @@ -80,10 +80,12 @@ #include <xmloff/txtparae.hxx> #include <xmloff/xmlcnitm.hxx> #include <xmloff/xmlerror.hxx> +#include <xmloff/XMLEventExport.hxx> #include <rtl/ustring.hxx> #include <tools/debug.hxx> +#include "tools/color.hxx" #include <rtl/math.hxx> #include <svl/zforlist.hxx> #include <svx/unoshape.hxx> @@ -124,6 +126,7 @@ #include <com/sun/star/form/XFormsSupplier2.hpp> #include <com/sun/star/io/XActiveDataSource.hpp> #include <com/sun/star/io/XSeekable.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> #include <com/sun/star/chart2/XChartDocument.hpp> #include <com/sun/star/chart2/data/XRangeXMLConversion.hpp> @@ -132,6 +135,8 @@ #include <com/sun/star/document/XDocumentProperties.hpp> #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp> +#include "XMLCodeNameProvider.hxx" + #include <sfx2/objsh.hxx> #include <vector> @@ -161,6 +166,7 @@ using namespace formula; using namespace com::sun::star; using namespace xmloff::token; using ::std::vector; +using ::com::sun::star::uno::UNO_QUERY; //---------------------------------------------------------------------------- @@ -1705,132 +1711,140 @@ void ScXMLExport::_ExportContent() } else { - //! indent after rebasing to m52 - - uno::Reference<sheet::XSpreadsheet> xTable(xIndex->getByIndex(nTable), uno::UNO_QUERY); - if (xTable.is()) - { - xCurrentTable.set(xTable); - xCurrentTableCellRange.set(xTable, uno::UNO_QUERY); - uno::Reference<container::XNamed> xName (xTable, uno::UNO_QUERY ); - if ( xName.is() ) + uno::Reference<sheet::XSpreadsheet> xTable(xIndex->getByIndex(nTable), uno::UNO_QUERY); + if (xTable.is()) { - nCurrentTable = sal::static_int_cast<sal_uInt16>( nTable ); - rtl::OUString sOUTableName(xName->getName()); - AddAttribute(sAttrName, sOUTableName); - AddAttribute(sAttrStyleName, aTableStyles[nTable]); - uno::Reference<util::XProtectable> xProtectable (xTable, uno::UNO_QUERY); - if (xProtectable.is() && xProtectable->isProtected()) + xCurrentTable.set(xTable); + xCurrentTableCellRange.set(xTable, uno::UNO_QUERY); + uno::Reference<container::XNamed> xName (xTable, uno::UNO_QUERY ); + if ( xName.is() ) { - AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTED, XML_TRUE); - rtl::OUStringBuffer aBuffer; - if (pDoc) + nCurrentTable = sal::static_int_cast<sal_uInt16>( nTable ); + rtl::OUString sOUTableName(xName->getName()); + AddAttribute(sAttrName, sOUTableName); + AddAttribute(sAttrStyleName, aTableStyles[nTable]); + + uno::Reference<util::XProtectable> xProtectable (xTable, uno::UNO_QUERY); + if (xProtectable.is() && xProtectable->isProtected()) { - ScTableProtection* pProtect = pDoc->GetTabProtection(static_cast<SCTAB>(nTable)); - if (pProtect) - SvXMLUnitConverter::encodeBase64(aBuffer, pProtect->getPasswordHash(PASSHASH_OOO)); + AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTED, XML_TRUE); + rtl::OUStringBuffer aBuffer; + if (pDoc) + { + ScTableProtection* pProtect = pDoc->GetTabProtection(static_cast<SCTAB>(nTable)); + if (pProtect) + SvXMLUnitConverter::encodeBase64(aBuffer, pProtect->getPasswordHash(PASSHASH_OOO)); + } + if (aBuffer.getLength()) + AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTION_KEY, aBuffer.makeStringAndClear()); } - if (aBuffer.getLength()) - AddAttribute(XML_NAMESPACE_TABLE, XML_PROTECTION_KEY, aBuffer.makeStringAndClear()); - } - rtl::OUString sPrintRanges; - table::CellRangeAddress aColumnHeaderRange; - sal_Bool bHasColumnHeader; - GetColumnRowHeader(bHasColumnHeader, aColumnHeaderRange, bHasRowHeader, aRowHeaderRange, sPrintRanges); - if( sPrintRanges.getLength() ) - AddAttribute( XML_NAMESPACE_TABLE, XML_PRINT_RANGES, sPrintRanges ); - else if (!pDoc->IsPrintEntireSheet(static_cast<SCTAB>(nTable))) - AddAttribute( XML_NAMESPACE_TABLE, XML_PRINT, XML_FALSE); - SvXMLElementExport aElemT(*this, sElemTab, sal_True, sal_True); - CheckAttrList(); - WriteTableSource(); - WriteScenario(); - uno::Reference<drawing::XDrawPage> xDrawPage; - if (pSharedData->HasForm(nTable, xDrawPage) && xDrawPage.is()) - { - ::xmloff::OOfficeFormsExport aForms(*this); - GetFormExport()->exportForms( xDrawPage ); - sal_Bool bRet(GetFormExport()->seekPage( xDrawPage )); - DBG_ASSERT( bRet, "OFormLayerXMLExport::seekPage failed!" ); - (void)bRet; // avoid warning in product version - } - if (pSharedData->HasDrawPage()) - { - GetShapeExport()->seekShapes(uno::Reference<drawing::XShapes>(pSharedData->GetDrawPage(nTable), uno::UNO_QUERY)); - WriteTableShapes(); - } - table::CellRangeAddress aRange(GetEndAddress(xTable, nTable)); - pSharedData->SetLastColumn(nTable, aRange.EndColumn); - pSharedData->SetLastRow(nTable, aRange.EndRow); - pCellsItr->SetCurrentTable(static_cast<SCTAB>(nTable), xCurrentTable); - pGroupColumns->NewTable(); - pGroupRows->NewTable(); - FillColumnRowGroups(); - if (bHasColumnHeader) - pSharedData->SetLastColumn(nTable, aColumnHeaderRange.EndColumn); - bRowHeaderOpen = sal_False; - if (bHasRowHeader) - pSharedData->SetLastRow(nTable, aRowHeaderRange.EndRow); - pDefaults->FillDefaultStyles(nTable, pSharedData->GetLastRow(nTable), - pSharedData->GetLastColumn(nTable), pCellStyles, pDoc); - pRowFormatRanges->SetRowDefaults(pDefaults->GetRowDefaults()); - pRowFormatRanges->SetColDefaults(pDefaults->GetColDefaults()); - pCellStyles->SetRowDefaults(pDefaults->GetRowDefaults()); - pCellStyles->SetColDefaults(pDefaults->GetColDefaults()); - ExportColumns(nTable, aColumnHeaderRange, bHasColumnHeader); - sal_Bool bIsFirst(sal_True); - sal_Int32 nEqualCells(0); - ScMyCell aCell; - ScMyCell aPrevCell; - while(pCellsItr->GetNext(aCell, pCellStyles)) - { - if (bIsFirst) + rtl::OUString sPrintRanges; + table::CellRangeAddress aColumnHeaderRange; + sal_Bool bHasColumnHeader; + GetColumnRowHeader(bHasColumnHeader, aColumnHeaderRange, bHasRowHeader, aRowHeaderRange, sPrintRanges); + if( sPrintRanges.getLength() ) + AddAttribute( XML_NAMESPACE_TABLE, XML_PRINT_RANGES, sPrintRanges ); + else if (!pDoc->IsPrintEntireSheet(static_cast<SCTAB>(nTable))) + AddAttribute( XML_NAMESPACE_TABLE, XML_PRINT, XML_FALSE); + SvXMLElementExport aElemT(*this, sElemTab, sal_True, sal_True); + CheckAttrList(); + + if ( pDoc && pDoc->GetSheetEvents( static_cast<SCTAB>(nTable) ) && + getDefaultVersion() == SvtSaveOptions::ODFVER_LATEST ) { - ExportFormatRanges(0, 0, aCell.aCellAddress.Column - 1, aCell.aCellAddress.Row, nTable); - aPrevCell = aCell; - bIsFirst = sal_False; + // store sheet events + uno::Reference<document::XEventsSupplier> xSupplier(xTable, uno::UNO_QUERY); + uno::Reference<container::XNameAccess> xEvents(xSupplier->getEvents(), uno::UNO_QUERY); + GetEventExport().ExportExt( xEvents ); } - else + + WriteTableSource(); + WriteScenario(); + uno::Reference<drawing::XDrawPage> xDrawPage; + if (pSharedData->HasForm(nTable, xDrawPage) && xDrawPage.is()) + { + ::xmloff::OOfficeFormsExport aForms(*this); + GetFormExport()->exportForms( xDrawPage ); + sal_Bool bRet(GetFormExport()->seekPage( xDrawPage )); + DBG_ASSERT( bRet, "OFormLayerXMLExport::seekPage failed!" ); + (void)bRet; // avoid warning in product version + } + if (pSharedData->HasDrawPage()) + { + GetShapeExport()->seekShapes(uno::Reference<drawing::XShapes>(pSharedData->GetDrawPage(nTable), uno::UNO_QUERY)); + WriteTableShapes(); + } + table::CellRangeAddress aRange(GetEndAddress(xTable, nTable)); + pSharedData->SetLastColumn(nTable, aRange.EndColumn); + pSharedData->SetLastRow(nTable, aRange.EndRow); + pCellsItr->SetCurrentTable(static_cast<SCTAB>(nTable), xCurrentTable); + pGroupColumns->NewTable(); + pGroupRows->NewTable(); + FillColumnRowGroups(); + if (bHasColumnHeader) + pSharedData->SetLastColumn(nTable, aColumnHeaderRange.EndColumn); + bRowHeaderOpen = sal_False; + if (bHasRowHeader) + pSharedData->SetLastRow(nTable, aRowHeaderRange.EndRow); + pDefaults->FillDefaultStyles(nTable, pSharedData->GetLastRow(nTable), + pSharedData->GetLastColumn(nTable), pCellStyles, pDoc); + pRowFormatRanges->SetRowDefaults(pDefaults->GetRowDefaults()); + pRowFormatRanges->SetColDefaults(pDefaults->GetColDefaults()); + pCellStyles->SetRowDefaults(pDefaults->GetRowDefaults()); + pCellStyles->SetColDefaults(pDefaults->GetColDefaults()); + ExportColumns(nTable, aColumnHeaderRange, bHasColumnHeader); + sal_Bool bIsFirst(sal_True); + sal_Int32 nEqualCells(0); + ScMyCell aCell; + ScMyCell aPrevCell; + while(pCellsItr->GetNext(aCell, pCellStyles)) { - if ((aPrevCell.aCellAddress.Row == aCell.aCellAddress.Row) && - (aPrevCell.aCellAddress.Column + nEqualCells + 1 == aCell.aCellAddress.Column)) + if (bIsFirst) + { + ExportFormatRanges(0, 0, aCell.aCellAddress.Column - 1, aCell.aCellAddress.Row, nTable); + aPrevCell = aCell; + bIsFirst = sal_False; + } + else { - if(IsCellEqual(aPrevCell, aCell)) - ++nEqualCells; + if ((aPrevCell.aCellAddress.Row == aCell.aCellAddress.Row) && + (aPrevCell.aCellAddress.Column + nEqualCells + 1 == aCell.aCellAddress.Column)) + { + if(IsCellEqual(aPrevCell, aCell)) + ++nEqualCells; + else + { + SetRepeatAttribute(nEqualCells); + WriteCell(aPrevCell); + nEqualCells = 0; + aPrevCell = aCell; + } + } else { SetRepeatAttribute(nEqualCells); WriteCell(aPrevCell); + ExportFormatRanges(aPrevCell.aCellAddress.Column + nEqualCells + 1, aPrevCell.aCellAddress.Row, + aCell.aCellAddress.Column - 1, aCell.aCellAddress.Row, nTable); nEqualCells = 0; aPrevCell = aCell; } } - else - { - SetRepeatAttribute(nEqualCells); - WriteCell(aPrevCell); - ExportFormatRanges(aPrevCell.aCellAddress.Column + nEqualCells + 1, aPrevCell.aCellAddress.Row, - aCell.aCellAddress.Column - 1, aCell.aCellAddress.Row, nTable); - nEqualCells = 0; - aPrevCell = aCell; - } } + if (!bIsFirst) + { + SetRepeatAttribute(nEqualCells); + WriteCell(aPrevCell); + ExportFormatRanges(aPrevCell.aCellAddress.Column + nEqualCells + 1, aPrevCell.aCellAddress.Row, + pSharedData->GetLastColumn(nTable), pSharedData->GetLastRow(nTable), nTable); + } + else + ExportFormatRanges(0, 0, pSharedData->GetLastColumn(nTable), pSharedData->GetLastRow(nTable), nTable); + CloseRow(pSharedData->GetLastRow(nTable)); + nEqualCells = 0; } - if (!bIsFirst) - { - SetRepeatAttribute(nEqualCells); - WriteCell(aPrevCell); - ExportFormatRanges(aPrevCell.aCellAddress.Column + nEqualCells + 1, aPrevCell.aCellAddress.Row, - pSharedData->GetLastColumn(nTable), pSharedData->GetLastRow(nTable), nTable); - } - else - ExportFormatRanges(0, 0, pSharedData->GetLastColumn(nTable), pSharedData->GetLastRow(nTable), nTable); - CloseRow(pSharedData->GetLastRow(nTable)); - nEqualCells = 0; } } - - } IncrementProgressBar(sal_False); } } @@ -2148,498 +2162,507 @@ uno::Any lcl_GetEnumerated( uno::Reference<container::XEnumerationAccess> xEnumA void ScXMLExport::_ExportAutoStyles() { - if (GetModel().is()) + if (!GetModel().is()) + return; + + uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( GetModel(), uno::UNO_QUERY ); + if (!xSpreadDoc.is()) + return; + + uno::Reference<container::XIndexAccess> xIndex( xSpreadDoc->getSheets(), uno::UNO_QUERY ); + if (!xIndex.is()) + return; + + if (getExportFlags() & EXPORT_CONTENT) { - uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( GetModel(), uno::UNO_QUERY ); - if ( xSpreadDoc.is() ) + // re-create automatic styles with old names from stored data + ScSheetSaveData* pSheetData = ScModelObj::getImplementation(xSpreadDoc)->GetSheetSaveData(); + if (pSheetData && pDoc) { - uno::Reference<container::XIndexAccess> xIndex( xSpreadDoc->getSheets(), uno::UNO_QUERY ); - if ( xIndex.is() ) - { - if (getExportFlags() & EXPORT_CONTENT) + // formulas have to be calculated now, to detect changed results + // (during normal save, they will be calculated anyway) + SCTAB nTabCount = pDoc->GetTableCount(); + for (SCTAB nTab=0; nTab<nTabCount; ++nTab) + if (pDoc->IsStreamValid(nTab)) { - // re-create automatic styles with old names from stored data - ScSheetSaveData* pSheetData = ScModelObj::getImplementation(xSpreadDoc)->GetSheetSaveData(); - if (pSheetData && pDoc) + ScCellIterator aIter( pDoc, 0,0,nTab, MAXCOL,MAXROW,nTab ); + ScBaseCell* pCell = aIter.GetFirst(); + while (pCell) { - // formulas have to be calculated now, to detect changed results - // (during normal save, they will be calculated anyway) - SCTAB nTabCount = pDoc->GetTableCount(); - for (SCTAB nTab=0; nTab<nTabCount; ++nTab) - if (pDoc->IsStreamValid(nTab)) - { - ScCellIterator aIter( pDoc, 0,0,nTab, MAXCOL,MAXROW,nTab ); - ScBaseCell* pCell = aIter.GetFirst(); - while (pCell) - { - if (pCell->GetCellType() == CELLTYPE_FORMULA) - static_cast<ScFormulaCell*>(pCell)->IsValue(); // interpret if dirty - pCell = aIter.GetNext(); - } - } + if (pCell->GetCellType() == CELLTYPE_FORMULA) + static_cast<ScFormulaCell*>(pCell)->IsValue(); // interpret if dirty + pCell = aIter.GetNext(); + } + } - // stored cell styles - const std::vector<ScCellStyleEntry>& rCellEntries = pSheetData->GetCellStyles(); - std::vector<ScCellStyleEntry>::const_iterator aCellIter = rCellEntries.begin(); - std::vector<ScCellStyleEntry>::const_iterator aCellEnd = rCellEntries.end(); - while (aCellIter != aCellEnd) - { - ScAddress aPos = aCellIter->maCellPos; - sal_Int32 nTable = aPos.Tab(); - bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) ); - if (bCopySheet) - { - uno::Reference <sheet::XSpreadsheet> xTable(xIndex->getByIndex(nTable), uno::UNO_QUERY); - uno::Reference <beans::XPropertySet> xProperties( - xTable->getCellByPosition( aPos.Col(), aPos.Row() ), uno::UNO_QUERY ); + // stored cell styles + const std::vector<ScCellStyleEntry>& rCellEntries = pSheetData->GetCellStyles(); + std::vector<ScCellStyleEntry>::const_iterator aCellIter = rCellEntries.begin(); + std::vector<ScCellStyleEntry>::const_iterator aCellEnd = rCellEntries.end(); + while (aCellIter != aCellEnd) + { + ScAddress aPos = aCellIter->maCellPos; + sal_Int32 nTable = aPos.Tab(); + bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) ); + if (bCopySheet) + { + uno::Reference <sheet::XSpreadsheet> xTable(xIndex->getByIndex(nTable), uno::UNO_QUERY); + uno::Reference <beans::XPropertySet> xProperties( + xTable->getCellByPosition( aPos.Col(), aPos.Row() ), uno::UNO_QUERY ); - AddStyleFromCells(xProperties, xTable, nTable, &aCellIter->maName); - } - ++aCellIter; - } + AddStyleFromCells(xProperties, xTable, nTable, &aCellIter->maName); + } + ++aCellIter; + } - // stored column styles - const std::vector<ScCellStyleEntry>& rColumnEntries = pSheetData->GetColumnStyles(); - std::vector<ScCellStyleEntry>::const_iterator aColumnIter = rColumnEntries.begin(); - std::vector<ScCellStyleEntry>::const_iterator aColumnEnd = rColumnEntries.end(); - while (aColumnIter != aColumnEnd) - { - ScAddress aPos = aColumnIter->maCellPos; - sal_Int32 nTable = aPos.Tab(); - bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) ); - if (bCopySheet) - { - uno::Reference<table::XColumnRowRange> xColumnRowRange(xIndex->getByIndex(nTable), uno::UNO_QUERY); - uno::Reference<table::XTableColumns> xTableColumns(xColumnRowRange->getColumns()); - uno::Reference<beans::XPropertySet> xColumnProperties(xTableColumns->getByIndex( aPos.Col() ), uno::UNO_QUERY); + // stored column styles + const std::vector<ScCellStyleEntry>& rColumnEntries = pSheetData->GetColumnStyles(); + std::vector<ScCellStyleEntry>::const_iterator aColumnIter = rColumnEntries.begin(); + std::vector<ScCellStyleEntry>::const_iterator aColumnEnd = rColumnEntries.end(); + while (aColumnIter != aColumnEnd) + { + ScAddress aPos = aColumnIter->maCellPos; + sal_Int32 nTable = aPos.Tab(); + bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) ); + if (bCopySheet) + { + uno::Reference<table::XColumnRowRange> xColumnRowRange(xIndex->getByIndex(nTable), uno::UNO_QUERY); + uno::Reference<table::XTableColumns> xTableColumns(xColumnRowRange->getColumns()); + uno::Reference<beans::XPropertySet> xColumnProperties(xTableColumns->getByIndex( aPos.Col() ), uno::UNO_QUERY); - sal_Int32 nIndex(-1); - sal_Bool bIsVisible(sal_True); - AddStyleFromColumn( xColumnProperties, &aColumnIter->maName, nIndex, bIsVisible ); - } - ++aColumnIter; - } + sal_Int32 nIndex(-1); + sal_Bool bIsVisible(sal_True); + AddStyleFromColumn( xColumnProperties, &aColumnIter->maName, nIndex, bIsVisible ); + } + ++aColumnIter; + } - // stored row styles - const std::vector<ScCellStyleEntry>& rRowEntries = pSheetData->GetRowStyles(); - std::vector<ScCellStyleEntry>::const_iterator aRowIter = rRowEntries.begin(); - std::vector<ScCellStyleEntry>::const_iterator aRowEnd = rRowEntries.end(); - while (aRowIter != aRowEnd) - { - ScAddress aPos = aRowIter->maCellPos; - sal_Int32 nTable = aPos.Tab(); - bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) ); - if (bCopySheet) - { - uno::Reference<table::XColumnRowRange> xColumnRowRange(xIndex->getByIndex(nTable), uno::UNO_QUERY); - uno::Reference<table::XTableRows> xTableRows(xColumnRowRange->getRows()); - uno::Reference<beans::XPropertySet> xRowProperties(xTableRows->getByIndex( aPos.Row() ), uno::UNO_QUERY); + // stored row styles + const std::vector<ScCellStyleEntry>& rRowEntries = pSheetData->GetRowStyles(); + std::vector<ScCellStyleEntry>::const_iterator aRowIter = rRowEntries.begin(); + std::vector<ScCellStyleEntry>::const_iterator aRowEnd = rRowEntries.end(); + while (aRowIter != aRowEnd) + { + ScAddress aPos = aRowIter->maCellPos; + sal_Int32 nTable = aPos.Tab(); + bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) ); + if (bCopySheet) + { + uno::Reference<table::XColumnRowRange> xColumnRowRange(xIndex->getByIndex(nTable), uno::UNO_QUERY); + uno::Reference<table::XTableRows> xTableRows(xColumnRowRange->getRows()); + uno::Reference<beans::XPropertySet> xRowProperties(xTableRows->getByIndex( aPos.Row() ), uno::UNO_QUERY); - sal_Int32 nIndex(-1); - AddStyleFromRow( xRowProperties, &aRowIter->maName, nIndex ); - } - ++aRowIter; - } + sal_Int32 nIndex(-1); + AddStyleFromRow( xRowProperties, &aRowIter->maName, nIndex ); + } + ++aRowIter; + } - // stored table styles - const std::vector<ScCellStyleEntry>& rTableEntries = pSheetData->GetTableStyles(); - std::vector<ScCellStyleEntry>::const_iterator aTableIter = rTableEntries.begin(); - std::vector<ScCellStyleEntry>::const_iterator aTableEnd = rTableEntries.end(); - while (aTableIter != aTableEnd) - { - ScAddress aPos = aTableIter->maCellPos; - sal_Int32 nTable = aPos.Tab(); - bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) ); - if (bCopySheet) - { - //! separate method AddStyleFromTable needed? - uno::Reference<beans::XPropertySet> xTableProperties(xIndex->getByIndex(nTable), uno::UNO_QUERY); - if (xTableProperties.is()) - { - std::vector<XMLPropertyState> xPropStates(xTableStylesExportPropertySetMapper->Filter(xTableProperties)); - rtl::OUString sParent; - rtl::OUString sName( aTableIter->maName ); - GetAutoStylePool()->AddNamed(sName, XML_STYLE_FAMILY_TABLE_TABLE, sParent, xPropStates); - GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TABLE_TABLE, sName); - } - } - ++aTableIter; - } + // stored table styles + const std::vector<ScCellStyleEntry>& rTableEntries = pSheetData->GetTableStyles(); + std::vector<ScCellStyleEntry>::const_iterator aTableIter = rTableEntries.begin(); + std::vector<ScCellStyleEntry>::const_iterator aTableEnd = rTableEntries.end(); + while (aTableIter != aTableEnd) + { + ScAddress aPos = aTableIter->maCellPos; + sal_Int32 nTable = aPos.Tab(); + bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) ); + if (bCopySheet) + { + //! separate method AddStyleFromTable needed? + uno::Reference<beans::XPropertySet> xTableProperties(xIndex->getByIndex(nTable), uno::UNO_QUERY); + if (xTableProperties.is()) + { + std::vector<XMLPropertyState> xPropStates(xTableStylesExportPropertySetMapper->Filter(xTableProperties)); + rtl::OUString sParent; + rtl::OUString sName( aTableIter->maName ); + GetAutoStylePool()->AddNamed(sName, XML_STYLE_FAMILY_TABLE_TABLE, sParent, xPropStates); + GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TABLE_TABLE, sName); + } + } + ++aTableIter; + } - // stored styles for notes + // stored styles for notes - UniReference<SvXMLExportPropertyMapper> xShapeMapper = XMLShapeExport::CreateShapePropMapper( *this ); - GetShapeExport(); // make sure the graphics styles family is added + UniReference<SvXMLExportPropertyMapper> xShapeMapper = XMLShapeExport::CreateShapePropMapper( *this ); + GetShapeExport(); // make sure the graphics styles family is added - const std::vector<ScNoteStyleEntry>& rNoteEntries = pSheetData->GetNoteStyles(); - std::vector<ScNoteStyleEntry>::const_iterator aNoteIter = rNoteEntries.begin(); - std::vector<ScNoteStyleEntry>::const_iterator aNoteEnd = rNoteEntries.end(); - while (aNoteIter != aNoteEnd) + const std::vector<ScNoteStyleEntry>& rNoteEntries = pSheetData->GetNoteStyles(); + std::vector<ScNoteStyleEntry>::const_iterator aNoteIter = rNoteEntries.begin(); + std::vector<ScNoteStyleEntry>::const_iterator aNoteEnd = rNoteEntries.end(); + while (aNoteIter != aNoteEnd) + { + ScAddress aPos = aNoteIter->maCellPos; + sal_Int32 nTable = aPos.Tab(); + bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) ); + if (bCopySheet) + { + //! separate method AddStyleFromNote needed? + + ScPostIt* pNote = pDoc->GetNote( aPos ); + DBG_ASSERT( pNote, "note not found" ); + if (pNote) + { + SdrCaptionObj* pDrawObj = pNote->GetOrCreateCaption( aPos ); + // all uno shapes are created anyway in CollectSharedData + uno::Reference<beans::XPropertySet> xShapeProperties( pDrawObj->getUnoShape(), uno::UNO_QUERY ); + if (xShapeProperties.is()) { - ScAddress aPos = aNoteIter->maCellPos; - sal_Int32 nTable = aPos.Tab(); - bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) ); - if (bCopySheet) + if ( aNoteIter->maStyleName.getLength() ) { - //! separate method AddStyleFromNote needed? - - ScPostIt* pNote = pDoc->GetNote( aPos ); - DBG_ASSERT( pNote, "note not found" ); - if (pNote) - { - SdrCaptionObj* pDrawObj = pNote->GetOrCreateCaption( aPos ); - // all uno shapes are created anyway in CollectSharedData - uno::Reference<beans::XPropertySet> xShapeProperties( pDrawObj->getUnoShape(), uno::UNO_QUERY ); - if (xShapeProperties.is()) - { - if ( aNoteIter->maStyleName.getLength() ) - { - std::vector<XMLPropertyState> xPropStates(xShapeMapper->Filter(xShapeProperties)); - rtl::OUString sParent; - rtl::OUString sName( aNoteIter->maStyleName ); - GetAutoStylePool()->AddNamed(sName, XML_STYLE_FAMILY_SD_GRAPHICS_ID, sParent, xPropStates); - GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_SD_GRAPHICS_ID, sName); - } - if ( aNoteIter->maTextStyle.getLength() ) - { - std::vector<XMLPropertyState> xPropStates( - GetTextParagraphExport()->GetParagraphPropertyMapper()->Filter(xShapeProperties)); - rtl::OUString sParent; - rtl::OUString sName( aNoteIter->maTextStyle ); - GetAutoStylePool()->AddNamed(sName, XML_STYLE_FAMILY_TEXT_PARAGRAPH, sParent, xPropStates); - GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TEXT_PARAGRAPH, sName); - } - } - } + std::vector<XMLPropertyState> xPropStates(xShapeMapper->Filter(xShapeProperties)); + rtl::OUString sParent; + rtl::OUString sName( aNoteIter->maStyleName ); + GetAutoStylePool()->AddNamed(sName, XML_STYLE_FAMILY_SD_GRAPHICS_ID, sParent, xPropStates); + GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_SD_GRAPHICS_ID, sName); + } + if ( aNoteIter->maTextStyle.getLength() ) + { + std::vector<XMLPropertyState> xPropStates( + GetTextParagraphExport()->GetParagraphPropertyMapper()->Filter(xShapeProperties)); + rtl::OUString sParent; + rtl::OUString sName( aNoteIter->maTextStyle ); + GetAutoStylePool()->AddNamed(sName, XML_STYLE_FAMILY_TEXT_PARAGRAPH, sParent, xPropStates); + GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TEXT_PARAGRAPH, sName); } - ++aNoteIter; } + } + } + ++aNoteIter; + } - // note paragraph styles + // note paragraph styles - //UniReference<SvXMLExportPropertyMapper> xParaPropMapper = XMLTextParagraphExport::CreateParaExtPropMapper( *this ); - UniReference<SvXMLExportPropertyMapper> xParaPropMapper = GetTextParagraphExport()->GetParagraphPropertyMapper(); + //UniReference<SvXMLExportPropertyMapper> xParaPropMapper = XMLTextParagraphExport::CreateParaExtPropMapper( *this ); + UniReference<SvXMLExportPropertyMapper> xParaPropMapper = GetTextParagraphExport()->GetParagraphPropertyMapper(); - const std::vector<ScTextStyleEntry>& rNoteParaEntries = pSheetData->GetNoteParaStyles(); - std::vector<ScTextStyleEntry>::const_iterator aNoteParaIter = rNoteParaEntries.begin(); - std::vector<ScTextStyleEntry>::const_iterator aNoteParaEnd = rNoteParaEntries.end(); - while (aNoteParaIter != aNoteParaEnd) + const std::vector<ScTextStyleEntry>& rNoteParaEntries = pSheetData->GetNoteParaStyles(); + std::vector<ScTextStyleEntry>::const_iterator aNoteParaIter = rNoteParaEntries.begin(); + std::vector<ScTextStyleEntry>::const_iterator aNoteParaEnd = rNoteParaEntries.end(); + while (aNoteParaIter != aNoteParaEnd) + { + ScAddress aPos = aNoteParaIter->maCellPos; + sal_Int32 nTable = aPos.Tab(); + bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) ); + if (bCopySheet) + { + ScPostIt* pNote = pDoc->GetNote( aPos ); + DBG_ASSERT( pNote, "note not found" ); + if (pNote) + { + SdrCaptionObj* pDrawObj = pNote->GetOrCreateCaption( aPos ); + uno::Reference<container::XEnumerationAccess> xCellText(pDrawObj->getUnoShape(), uno::UNO_QUERY); + uno::Reference<beans::XPropertySet> xParaProp( + lcl_GetEnumerated( xCellText, aNoteParaIter->maSelection.nStartPara ), uno::UNO_QUERY ); + if ( xParaProp.is() ) { - ScAddress aPos = aNoteParaIter->maCellPos; - sal_Int32 nTable = aPos.Tab(); - bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) ); - if (bCopySheet) - { - ScPostIt* pNote = pDoc->GetNote( aPos ); - DBG_ASSERT( pNote, "note not found" ); - if (pNote) - { - SdrCaptionObj* pDrawObj = pNote->GetOrCreateCaption( aPos ); - uno::Reference<container::XEnumerationAccess> xCellText(pDrawObj->getUnoShape(), uno::UNO_QUERY); - uno::Reference<beans::XPropertySet> xParaProp( - lcl_GetEnumerated( xCellText, aNoteParaIter->maSelection.nStartPara ), uno::UNO_QUERY ); - if ( xParaProp.is() ) - { - std::vector<XMLPropertyState> xPropStates(xParaPropMapper->Filter(xParaProp)); - rtl::OUString sParent; - rtl::OUString sName( aNoteParaIter->maName ); - GetAutoStylePool()->AddNamed(sName, XML_STYLE_FAMILY_TEXT_PARAGRAPH, sParent, xPropStates); - GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TEXT_PARAGRAPH, sName); - } - } - } - ++aNoteParaIter; + std::vector<XMLPropertyState> xPropStates(xParaPropMapper->Filter(xParaProp)); + rtl::OUString sParent; + rtl::OUString sName( aNoteParaIter->maName ); + GetAutoStylePool()->AddNamed(sName, XML_STYLE_FAMILY_TEXT_PARAGRAPH, sParent, xPropStates); + GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TEXT_PARAGRAPH, sName); } + } + } + ++aNoteParaIter; + } - // note text styles + // note text styles - UniReference<SvXMLExportPropertyMapper> xTextPropMapper = XMLTextParagraphExport::CreateCharExtPropMapper( *this ); + UniReference<SvXMLExportPropertyMapper> xTextPropMapper = XMLTextParagraphExport::CreateCharExtPropMapper( *this ); - const std::vector<ScTextStyleEntry>& rNoteTextEntries = pSheetData->GetNoteTextStyles(); - std::vector<ScTextStyleEntry>::const_iterator aNoteTextIter = rNoteTextEntries.begin(); - std::vector<ScTextStyleEntry>::const_iterator aNoteTextEnd = rNoteTextEntries.end(); - while (aNoteTextIter != aNoteTextEnd) + const std::vector<ScTextStyleEntry>& rNoteTextEntries = pSheetData->GetNoteTextStyles(); + std::vector<ScTextStyleEntry>::const_iterator aNoteTextIter = rNoteTextEntries.begin(); + std::vector<ScTextStyleEntry>::const_iterator aNoteTextEnd = rNoteTextEntries.end(); + while (aNoteTextIter != aNoteTextEnd) + { + ScAddress aPos = aNoteTextIter->maCellPos; + sal_Int32 nTable = aPos.Tab(); + bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) ); + if (bCopySheet) + { + ScPostIt* pNote = pDoc->GetNote( aPos ); + DBG_ASSERT( pNote, "note not found" ); + if (pNote) + { + SdrCaptionObj* pDrawObj = pNote->GetOrCreateCaption( aPos ); + uno::Reference<text::XSimpleText> xCellText(pDrawObj->getUnoShape(), uno::UNO_QUERY); + uno::Reference<beans::XPropertySet> xCursorProp(xCellText->createTextCursor(), uno::UNO_QUERY); + ScDrawTextCursor* pCursor = ScDrawTextCursor::getImplementation( xCursorProp ); + if (pCursor) { - ScAddress aPos = aNoteTextIter->maCellPos; - sal_Int32 nTable = aPos.Tab(); - bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) ); - if (bCopySheet) - { - ScPostIt* pNote = pDoc->GetNote( aPos ); - DBG_ASSERT( pNote, "note not found" ); - if (pNote) - { - SdrCaptionObj* pDrawObj = pNote->GetOrCreateCaption( aPos ); - uno::Reference<text::XSimpleText> xCellText(pDrawObj->getUnoShape(), uno::UNO_QUERY); - uno::Reference<beans::XPropertySet> xCursorProp(xCellText->createTextCursor(), uno::UNO_QUERY); - ScDrawTextCursor* pCursor = ScDrawTextCursor::getImplementation( xCursorProp ); - if (pCursor) - { - pCursor->SetSelection( aNoteTextIter->maSelection ); + pCursor->SetSelection( aNoteTextIter->maSelection ); - std::vector<XMLPropertyState> xPropStates(xTextPropMapper->Filter(xCursorProp)); - rtl::OUString sParent; - rtl::OUString sName( aNoteTextIter->maName ); - GetAutoStylePool()->AddNamed(sName, XML_STYLE_FAMILY_TEXT_TEXT, sParent, xPropStates); - GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TEXT_TEXT, sName); - } - } - } - ++aNoteTextIter; + std::vector<XMLPropertyState> xPropStates(xTextPropMapper->Filter(xCursorProp)); + rtl::OUString sParent; + rtl::OUString sName( aNoteTextIter->maName ); + GetAutoStylePool()->AddNamed(sName, XML_STYLE_FAMILY_TEXT_TEXT, sParent, xPropStates); + GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TEXT_TEXT, sName); } + } + } + ++aNoteTextIter; + } - // stored text styles + // stored text styles - //UniReference<SvXMLExportPropertyMapper> xTextPropMapper = XMLTextParagraphExport::CreateCharExtPropMapper( *this ); + //UniReference<SvXMLExportPropertyMapper> xTextPropMapper = XMLTextParagraphExport::CreateCharExtPropMapper( *this ); - const std::vector<ScTextStyleEntry>& rTextEntries = pSheetData->GetTextStyles(); - std::vector<ScTextStyleEntry>::const_iterator aTextIter = rTextEntries.begin(); - std::vector<ScTextStyleEntry>::const_iterator aTextEnd = rTextEntries.end(); - while (aTextIter != aTextEnd) - { - ScAddress aPos = aTextIter->maCellPos; - sal_Int32 nTable = aPos.Tab(); - bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) ); - if (bCopySheet) - { - //! separate method AddStyleFromText needed? - //! cache sheet object - - uno::Reference<table::XCellRange> xCellRange(xIndex->getByIndex(nTable), uno::UNO_QUERY); - uno::Reference<text::XSimpleText> xCellText(xCellRange->getCellByPosition(aPos.Col(), aPos.Row()), uno::UNO_QUERY); - uno::Reference<beans::XPropertySet> xCursorProp(xCellText->createTextCursor(), uno::UNO_QUERY); - ScCellTextCursor* pCursor = ScCellTextCursor::getImplementation( xCursorProp ); - if (pCursor) - { - pCursor->SetSelection( aTextIter->maSelection ); + const std::vector<ScTextStyleEntry>& rTextEntries = pSheetData->GetTextStyles(); + std::vector<ScTextStyleEntry>::const_iterator aTextIter = rTextEntries.begin(); + std::vector<ScTextStyleEntry>::const_iterator aTextEnd = rTextEntries.end(); + while (aTextIter != aTextEnd) + { + ScAddress aPos = aTextIter->maCellPos; + sal_Int32 nTable = aPos.Tab(); + bool bCopySheet = pDoc->IsStreamValid( static_cast<SCTAB>(nTable) ); + if (bCopySheet) + { + //! separate method AddStyleFromText needed? + //! cache sheet object + + uno::Reference<table::XCellRange> xCellRange(xIndex->getByIndex(nTable), uno::UNO_QUERY); + uno::Reference<text::XSimpleText> xCellText(xCellRange->getCellByPosition(aPos.Col(), aPos.Row()), uno::UNO_QUERY); + uno::Reference<beans::XPropertySet> xCursorProp(xCellText->createTextCursor(), uno::UNO_QUERY); + ScCellTextCursor* pCursor = ScCellTextCursor::getImplementation( xCursorProp ); + if (pCursor) + { + pCursor->SetSelection( aTextIter->maSelection ); - std::vector<XMLPropertyState> xPropStates(xTextPropMapper->Filter(xCursorProp)); - rtl::OUString sParent; - rtl::OUString sName( aTextIter->maName ); - GetAutoStylePool()->AddNamed(sName, XML_STYLE_FAMILY_TEXT_TEXT, sParent, xPropStates); - GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TEXT_TEXT, sName); - } - } - ++aTextIter; - } + std::vector<XMLPropertyState> xPropStates(xTextPropMapper->Filter(xCursorProp)); + rtl::OUString sParent; + rtl::OUString sName( aTextIter->maName ); + GetAutoStylePool()->AddNamed(sName, XML_STYLE_FAMILY_TEXT_TEXT, sParent, xPropStates); + GetAutoStylePool()->RegisterName(XML_STYLE_FAMILY_TEXT_TEXT, sName); } + } + ++aTextIter; + } + } + + ExportExternalRefCacheStyles(); - ExportExternalRefCacheStyles(); + if (!pSharedData) + { + sal_Int32 nTableCount(0); + sal_Int32 nShapesCount(0); + sal_Int32 nCellCount(pDoc ? pDoc->GetCellCount() : 0); + CollectSharedData(nTableCount, nShapesCount, nCellCount); + //DBG_ERROR("no shared data setted"); + } + sal_Int32 nTableCount(xIndex->getCount()); + pCellStyles->AddNewTable(nTableCount - 1); + CollectShapesAutoStyles(nTableCount); + for (sal_Int32 nTable = 0; nTable < nTableCount; ++nTable) + { + bool bUseStream = pSheetData && pDoc && pDoc->IsStreamValid((SCTAB)nTable) && + pSheetData->HasStreamPos(nTable) && xSourceStream.is(); - if (!pSharedData) + uno::Reference <sheet::XSpreadsheet> xTable(xIndex->getByIndex(nTable), uno::UNO_QUERY); + if (xTable.is()) + { + // table styles array must be complete, including copied tables - Add should find the stored style + uno::Reference<beans::XPropertySet> xTableProperties(xTable, uno::UNO_QUERY); + if (xTableProperties.is()) + { + std::vector<XMLPropertyState> xPropStates(xTableStylesExportPropertySetMapper->Filter(xTableProperties)); + if(xPropStates.size()) { - sal_Int32 nTableCount(0); - sal_Int32 nShapesCount(0); - sal_Int32 nCellCount(pDoc ? pDoc->GetCellCount() : 0); - CollectSharedData(nTableCount, nShapesCount, nCellCount); - //DBG_ERROR("no shared data setted"); + rtl::OUString sParent; + rtl::OUString sName; + GetAutoStylePool()->Add(sName, XML_STYLE_FAMILY_TABLE_TABLE, sParent, xPropStates); + aTableStyles.push_back(sName); } - sal_Int32 nTableCount(xIndex->getCount()); - pCellStyles->AddNewTable(nTableCount - 1); - CollectShapesAutoStyles(nTableCount); - for (sal_Int32 nTable = 0; nTable < nTableCount; ++nTable) + } + } + // collect other auto-styles only for non-copied sheets + if (xTable.is() && !bUseStream) + { + uno::Reference<sheet::XUniqueCellFormatRangesSupplier> xCellFormatRanges ( xTable, uno::UNO_QUERY ); + if ( xCellFormatRanges.is() ) + { + uno::Reference<container::XIndexAccess> xFormatRangesIndex(xCellFormatRanges->getUniqueCellFormatRanges()); + if (xFormatRangesIndex.is()) { - bool bUseStream = pSheetData && pDoc && pDoc->IsStreamValid((SCTAB)nTable) && - pSheetData->HasStreamPos(nTable) && xSourceStream.is(); - - uno::Reference <sheet::XSpreadsheet> xTable(xIndex->getByIndex(nTable), uno::UNO_QUERY); - if (xTable.is()) + sal_Int32 nFormatRangesCount(xFormatRangesIndex->getCount()); + GetProgressBarHelper()->ChangeReference(GetProgressBarHelper()->GetReference() + nFormatRangesCount); + for (sal_Int32 nFormatRange = 0; nFormatRange < nFormatRangesCount; ++nFormatRange) { - // table styles array must be complete, including copied tables - Add should find the stored style - uno::Reference<beans::XPropertySet> xTableProperties(xTable, uno::UNO_QUERY); - if (xTableProperties.is()) + uno::Reference< sheet::XSheetCellRanges> xCellRanges(xFormatRangesIndex->getByIndex(nFormatRange), uno::UNO_QUERY); + if (xCellRanges.is()) { - std::vector<XMLPropertyState> xPropStates(xTableStylesExportPropertySetMapper->Filter(xTableProperties)); - if(xPropStates.size()) + uno::Reference <beans::XPropertySet> xProperties (xCellRanges, uno::UNO_QUERY); + if (xProperties.is()) { - rtl::OUString sParent; - rtl::OUString sName; - GetAutoStylePool()->Add(sName, XML_STYLE_FAMILY_TABLE_TABLE, sParent, xPropStates); - aTableStyles.push_back(sName); + AddStyleFromCells(xProperties, xTable, nTable, NULL); + IncrementProgressBar(sal_False); } } } - // collect other auto-styles only for non-copied sheets - if (xTable.is() && !bUseStream) + } + } + uno::Reference<table::XColumnRowRange> xColumnRowRange (xTable, uno::UNO_QUERY); + if (xColumnRowRange.is()) + { + if (pDoc) + { + pDoc->SyncColRowFlags(); + uno::Reference<table::XTableColumns> xTableColumns(xColumnRowRange->getColumns()); + if (xTableColumns.is()) { - uno::Reference<sheet::XUniqueCellFormatRangesSupplier> xCellFormatRanges ( xTable, uno::UNO_QUERY ); - if ( xCellFormatRanges.is() ) + sal_Int32 nColumns(pDoc->GetLastChangedCol(sal::static_int_cast<SCTAB>(nTable))); + pSharedData->SetLastColumn(nTable, nColumns); + table::CellRangeAddress aCellAddress(GetEndAddress(xTable, nTable)); + if (aCellAddress.EndColumn > nColumns) { - uno::Reference<container::XIndexAccess> xFormatRangesIndex(xCellFormatRanges->getUniqueCellFormatRanges()); - if (xFormatRangesIndex.is()) - { - sal_Int32 nFormatRangesCount(xFormatRangesIndex->getCount()); - GetProgressBarHelper()->ChangeReference(GetProgressBarHelper()->GetReference() + nFormatRangesCount); - for (sal_Int32 nFormatRange = 0; nFormatRange < nFormatRangesCount; ++nFormatRange) - { - uno::Reference< sheet::XSheetCellRanges> xCellRanges(xFormatRangesIndex->getByIndex(nFormatRange), uno::UNO_QUERY); - if (xCellRanges.is()) - { - uno::Reference <beans::XPropertySet> xProperties (xCellRanges, uno::UNO_QUERY); - if (xProperties.is()) - { - AddStyleFromCells(xProperties, xTable, nTable, NULL); - IncrementProgressBar(sal_False); - } - } - } - } + ++nColumns; + pColumnStyles->AddNewTable(nTable, aCellAddress.EndColumn); } - uno::Reference<table::XColumnRowRange> xColumnRowRange (xTable, uno::UNO_QUERY); - if (xColumnRowRange.is()) +// else if (nColumns < MAXCOL) +// pColumnStyles->AddNewTable(nTable, ++nColumns); + else + pColumnStyles->AddNewTable(nTable, nColumns); + sal_Int32 nColumn = 0; + while (/*nColumn <= nColumns && */nColumn <= MAXCOL) { - if (pDoc) + sal_Int32 nIndex(-1); + sal_Bool bIsVisible(sal_True); + uno::Reference <beans::XPropertySet> xColumnProperties(xTableColumns->getByIndex(nColumn), uno::UNO_QUERY); + if (xColumnProperties.is()) { - uno::Reference<table::XTableColumns> xTableColumns(xColumnRowRange->getColumns()); - if (xTableColumns.is()) - { - sal_Int32 nColumns(pDoc->GetLastChangedCol(sal::static_int_cast<SCTAB>(nTable))); - pSharedData->SetLastColumn(nTable, nColumns); - table::CellRangeAddress aCellAddress(GetEndAddress(xTable, nTable)); - if (aCellAddress.EndColumn > nColumns) - { - ++nColumns; - pColumnStyles->AddNewTable(nTable, aCellAddress.EndColumn); - } - // else if (nColumns < MAXCOL) - // pColumnStyles->AddNewTable(nTable, ++nColumns); - else - pColumnStyles->AddNewTable(nTable, nColumns); - sal_Int32 nColumn = 0; - while (/*nColumn <= nColumns && */nColumn <= MAXCOL) - { - sal_Int32 nIndex(-1); - sal_Bool bIsVisible(sal_True); - uno::Reference <beans::XPropertySet> xColumnProperties(xTableColumns->getByIndex(nColumn), uno::UNO_QUERY); - if (xColumnProperties.is()) - { - AddStyleFromColumn( xColumnProperties, NULL, nIndex, bIsVisible ); - //if(xPropStates.size()) - pColumnStyles->AddFieldStyleName(nTable, nColumn, nIndex, bIsVisible); - } - sal_Int32 nOld(nColumn); - nColumn = pDoc->GetNextDifferentChangedCol(sal::static_int_cast<SCTAB>(nTable), static_cast<USHORT>(nColumn)); - for (sal_Int32 i = nOld + 1; i < nColumn; ++i) - pColumnStyles->AddFieldStyleName(nTable, i, nIndex, bIsVisible); - } - if (aCellAddress.EndColumn > nColumns) - { - sal_Bool bIsVisible(sal_True); - sal_Int32 nIndex(pColumnStyles->GetStyleNameIndex(nTable, nColumns, bIsVisible)); - for (sal_Int32 i = nColumns + 1; i <= aCellAddress.EndColumn; ++i) - pColumnStyles->AddFieldStyleName(nTable, i, nIndex, bIsVisible); - } - } - uno::Reference<table::XTableRows> xTableRows(xColumnRowRange->getRows()); - if (xTableRows.is()) - { - sal_Int32 nRows(pDoc->GetLastChangedRow(sal::static_int_cast<SCTAB>(nTable))); - pSharedData->SetLastRow(nTable, nRows); - table::CellRangeAddress aCellAddress(GetEndAddress(xTable, nTable)); - if (aCellAddress.EndRow > nRows) - { - ++nRows; - pRowStyles->AddNewTable(nTable, aCellAddress.EndRow); - } - // else if (nRows < MAXROW) - // pRowStyles->AddNewTable(nTable, ++nRows); - else - pRowStyles->AddNewTable(nTable, nRows); - sal_Int32 nRow = 0; - while ( /*nRow <= nRows && */nRow <= MAXROW) - { - sal_Int32 nIndex = 0; - uno::Reference <beans::XPropertySet> xRowProperties(xTableRows->getByIndex(nRow), uno::UNO_QUERY); - if(xRowProperties.is()) - { - AddStyleFromRow( xRowProperties, NULL, nIndex ); - //if(xPropStates.size()) - pRowStyles->AddFieldStyleName(nTable, nRow, nIndex); - } - sal_Int32 nOld(nRow); - nRow = pDoc->GetNextDifferentChangedRow(sal::static_int_cast<SCTAB>(nTable), static_cast<USHORT>(nRow), false); - for (sal_Int32 i = nOld + 1; i < nRow; ++i) - pRowStyles->AddFieldStyleName(nTable, i, nIndex); - } - if (aCellAddress.EndRow > nRows) - { - sal_Int32 nIndex(pRowStyles->GetStyleNameIndex(nTable, nRows)); - for (sal_Int32 i = nRows + 1; i <= aCellAddress.EndRow; ++i) - pRowStyles->AddFieldStyleName(nTable, i, nIndex); - } - } + AddStyleFromColumn( xColumnProperties, NULL, nIndex, bIsVisible ); + //if(xPropStates.size()) + pColumnStyles->AddFieldStyleName(nTable, nColumn, nIndex, bIsVisible); } + sal_Int32 nOld(nColumn); + nColumn = pDoc->GetNextDifferentChangedCol(sal::static_int_cast<SCTAB>(nTable), static_cast<SCCOL>(nColumn)); + for (sal_Int32 i = nOld + 1; i < nColumn; ++i) + pColumnStyles->AddFieldStyleName(nTable, i, nIndex, bIsVisible); + } + if (aCellAddress.EndColumn > nColumns) + { + sal_Bool bIsVisible(sal_True); + sal_Int32 nIndex(pColumnStyles->GetStyleNameIndex(nTable, nColumns, bIsVisible)); + for (sal_Int32 i = nColumns + 1; i <= aCellAddress.EndColumn; ++i) + pColumnStyles->AddFieldStyleName(nTable, i, nIndex, bIsVisible); } - uno::Reference<sheet::XCellRangesQuery> xCellRangesQuery (xTable, uno::UNO_QUERY); - if (xCellRangesQuery.is()) + } + uno::Reference<table::XTableRows> xTableRows(xColumnRowRange->getRows()); + if (xTableRows.is()) + { + sal_Int32 nRows(pDoc->GetLastChangedRow(sal::static_int_cast<SCTAB>(nTable))); + pSharedData->SetLastRow(nTable, nRows); + table::CellRangeAddress aCellAddress(GetEndAddress(xTable, nTable)); + if (aCellAddress.EndRow > nRows) { - uno::Reference<sheet::XSheetCellRanges> xSheetCellRanges(xCellRangesQuery->queryContentCells(sheet::CellFlags::FORMATTED)); - uno::Reference<sheet::XSheetOperation> xSheetOperation(xSheetCellRanges, uno::UNO_QUERY); - if (xSheetCellRanges.is() && xSheetOperation.is()) + ++nRows; + pRowStyles->AddNewTable(nTable, aCellAddress.EndRow); + } +// else if (nRows < MAXROW) +// pRowStyles->AddNewTable(nTable, ++nRows); + else + pRowStyles->AddNewTable(nTable, nRows); + sal_Int32 nRow = 0; + while (nRow <= nRows && nRow <= MAXROW) + { + sal_Int32 nIndex = 0; + uno::Reference <beans::XPropertySet> xRowProperties(xTableRows->getByIndex(nRow), uno::UNO_QUERY); + if(xRowProperties.is()) { - sal_uInt32 nCount(sal_uInt32(xSheetOperation->computeFunction(sheet::GeneralFunction_COUNT))); - uno::Reference<container::XEnumerationAccess> xCellsAccess(xSheetCellRanges->getCells()); - if (xCellsAccess.is()) - { - GetProgressBarHelper()->ChangeReference(GetProgressBarHelper()->GetReference() + nCount); - uno::Reference<container::XEnumeration> xCells(xCellsAccess->createEnumeration()); - if (xCells.is()) - { - sal_uInt32 nCount2(0); - while (xCells->hasMoreElements()) - { - uno::Reference<text::XText> xText(xCells->nextElement(), uno::UNO_QUERY); - if (xText.is()) - GetTextParagraphExport()->collectTextAutoStyles(xText, sal_False, sal_False); - ++nCount2; - IncrementProgressBar(sal_False); - } - if(nCount2 > nCount) - GetProgressBarHelper()->SetReference(GetProgressBarHelper()->GetReference() + nCount2 - nCount); - } - } + AddStyleFromRow( xRowProperties, NULL, nIndex ); + //if(xPropStates.size()) + pRowStyles->AddFieldStyleName(nTable, nRow, nIndex); } + sal_Int32 nOld(nRow); + nRow = pDoc->GetNextDifferentChangedRow(sal::static_int_cast<SCTAB>(nTable), static_cast<SCROW>(nRow), false); + for (sal_Int32 i = nOld + 1; i < nRow; ++i) + pRowStyles->AddFieldStyleName(nTable, i, nIndex); + } + if (aCellAddress.EndRow > nRows) + { + sal_Int32 nIndex(pRowStyles->GetStyleNameIndex(nTable, nRows)); + for (sal_Int32 i = nRows + 1; i <= aCellAddress.EndRow; ++i) + pRowStyles->AddFieldStyleName(nTable, i, nIndex); } } - IncrementProgressBar(sal_False); - } - pChangeTrackingExportHelper->CollectAutoStyles(); - - GetAutoStylePool()->exportXML(XML_STYLE_FAMILY_TABLE_COLUMN, - GetDocHandler(), GetMM100UnitConverter(), GetNamespaceMap()); - GetAutoStylePool()->exportXML(XML_STYLE_FAMILY_TABLE_ROW, - GetDocHandler(), GetMM100UnitConverter(), GetNamespaceMap()); - GetAutoStylePool()->exportXML(XML_STYLE_FAMILY_TABLE_TABLE, - GetDocHandler(), GetMM100UnitConverter(), GetNamespaceMap()); - exportAutoDataStyles(); - GetAutoStylePool()->exportXML(XML_STYLE_FAMILY_TABLE_CELL, - GetDocHandler(), GetMM100UnitConverter(), GetNamespaceMap()); - - GetShapeExport()->exportAutoStyles(); - GetFormExport()->exportAutoStyles( ); - - { - // Special table style for the external ref cache tables. - AddAttribute(XML_NAMESPACE_STYLE, XML_NAME, sExternalRefTabStyleName); - AddAttribute(XML_NAMESPACE_STYLE, XML_FAMILY, XML_TABLE); - SvXMLElementExport aElemStyle(*this, XML_NAMESPACE_STYLE, XML_STYLE, sal_True, sal_True); - AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY, XML_FALSE); - SvXMLElementExport aElemStyleTabProps(*this, XML_NAMESPACE_STYLE, XML_TABLE_PROPERTIES, sal_True, sal_True); } } - if (getExportFlags() & EXPORT_MASTERSTYLES) + uno::Reference<sheet::XCellRangesQuery> xCellRangesQuery (xTable, uno::UNO_QUERY); + if (xCellRangesQuery.is()) { - GetPageExport()->collectAutoStyles(sal_True); - GetPageExport()->exportAutoStyles(); + uno::Reference<sheet::XSheetCellRanges> xSheetCellRanges(xCellRangesQuery->queryContentCells(sheet::CellFlags::FORMATTED)); + uno::Reference<sheet::XSheetOperation> xSheetOperation(xSheetCellRanges, uno::UNO_QUERY); + if (xSheetCellRanges.is() && xSheetOperation.is()) + { + sal_uInt32 nCount(sal_uInt32(xSheetOperation->computeFunction(sheet::GeneralFunction_COUNT))); + uno::Reference<container::XEnumerationAccess> xCellsAccess(xSheetCellRanges->getCells()); + if (xCellsAccess.is()) + { + GetProgressBarHelper()->ChangeReference(GetProgressBarHelper()->GetReference() + nCount); + uno::Reference<container::XEnumeration> xCells(xCellsAccess->createEnumeration()); + if (xCells.is()) + { + sal_uInt32 nCount2(0); + while (xCells->hasMoreElements()) + { + uno::Reference<text::XText> xText(xCells->nextElement(), uno::UNO_QUERY); + if (xText.is()) + GetTextParagraphExport()->collectTextAutoStyles(xText, sal_False, sal_False); + ++nCount2; + IncrementProgressBar(sal_False); + } + if(nCount2 > nCount) + GetProgressBarHelper()->SetReference(GetProgressBarHelper()->GetReference() + nCount2 - nCount); + } + } + } } + } + IncrementProgressBar(sal_False); + } + pChangeTrackingExportHelper->CollectAutoStyles(); + + GetAutoStylePool()->exportXML(XML_STYLE_FAMILY_TABLE_COLUMN, + GetDocHandler(), GetMM100UnitConverter(), GetNamespaceMap()); + GetAutoStylePool()->exportXML(XML_STYLE_FAMILY_TABLE_ROW, + GetDocHandler(), GetMM100UnitConverter(), GetNamespaceMap()); + GetAutoStylePool()->exportXML(XML_STYLE_FAMILY_TABLE_TABLE, + GetDocHandler(), GetMM100UnitConverter(), GetNamespaceMap()); + exportAutoDataStyles(); + GetAutoStylePool()->exportXML(XML_STYLE_FAMILY_TABLE_CELL, + GetDocHandler(), GetMM100UnitConverter(), GetNamespaceMap()); - // #i30251#; only write Text Styles once + GetShapeExport()->exportAutoStyles(); + GetFormExport()->exportAutoStyles( ); - if ((getExportFlags() & EXPORT_CONTENT) || (getExportFlags() & EXPORT_MASTERSTYLES)) - GetTextParagraphExport()->exportTextAutoStyles(); + if (pDoc) + { + ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager(); + // #i100879# write the table style for cached tables only if there are cached tables + // (same logic as in ExportExternalRefCacheStyles) + if (pRefMgr->hasExternalData()) + { + // Special table style for the external ref cache tables. + AddAttribute(XML_NAMESPACE_STYLE, XML_NAME, sExternalRefTabStyleName); + AddAttribute(XML_NAMESPACE_STYLE, XML_FAMILY, XML_TABLE); + SvXMLElementExport aElemStyle(*this, XML_NAMESPACE_STYLE, XML_STYLE, sal_True, sal_True); + AddAttribute(XML_NAMESPACE_TABLE, XML_DISPLAY, XML_FALSE); + SvXMLElementExport aElemStyleTabProps(*this, XML_NAMESPACE_STYLE, XML_TABLE_PROPERTIES, sal_True, sal_True); } } } + + if (getExportFlags() & EXPORT_MASTERSTYLES) + { + GetPageExport()->collectAutoStyles(sal_True); + GetPageExport()->exportAutoStyles(); + } + + // #i30251#; only write Text Styles once + + if ((getExportFlags() & EXPORT_CONTENT) || (getExportFlags() & EXPORT_MASTERSTYLES)) + GetTextParagraphExport()->exportTextAutoStyles(); } void ScXMLExport::_ExportMasterStyles() @@ -3057,32 +3080,69 @@ void ScXMLExport::ExportShape(const uno::Reference < drawing::XShape >& xShape, if ( sCLSID.equalsIgnoreAsciiCase(GetChartExport()->getChartCLSID()) ) { // we have a chart - uno::Reference< frame::XModel > xChartModel; - if( ( xShapeProps->getPropertyValue( sPropModel ) >>= xChartModel ) && - xChartModel.is()) + ::rtl::OUString sRanges; + if ( pDoc ) { - uno::Reference< chart2::XChartDocument > xChartDoc( xChartModel, uno::UNO_QUERY ); - uno::Reference< chart2::data::XDataReceiver > xReceiver( xChartModel, uno::UNO_QUERY ); - if( xChartDoc.is() && xReceiver.is() && - ! xChartDoc->hasInternalDataProvider()) + ::rtl::OUString aChartName; + xShapeProps->getPropertyValue( sPersistName ) >>= aChartName; + ScRange aEmptyRange; + ScChartListener aSearcher( aChartName, pDoc, aEmptyRange ); + USHORT nIndex = 0; + ScChartListenerCollection* pCollection = pDoc->GetChartListenerCollection(); + if ( pCollection && pCollection->Search( &aSearcher, nIndex ) ) { - // we have a chart that gets its data from Calc - bIsChart = true; - uno::Sequence< ::rtl::OUString > aRepresentations( - xReceiver->getUsedRangeRepresentations()); - SvXMLAttributeList* pAttrList = 0; - if(aRepresentations.getLength()) + ScChartListener* pListener = static_cast< ScChartListener* >( pCollection->At( nIndex ) ); + if ( pListener ) { - // add the ranges used by the chart to the shape - // element to be able to start listening after - // load (when the chart is not yet loaded) - uno::Reference< chart2::data::XRangeXMLConversion > xRangeConverter( xChartDoc->getDataProvider(), uno::UNO_QUERY ); - ::rtl::OUString sRanges( lcl_RangeSequenceToString( aRepresentations, xRangeConverter )); - pAttrList = new SvXMLAttributeList(); - pAttrList->AddAttribute( - GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_DRAW, GetXMLToken(XML_NOTIFY_ON_UPDATE_OF_RANGES) ), sRanges ); + const ScRangeListRef& rRangeList = pListener->GetRangeList(); + if ( rRangeList.Is() ) + { + ScRangeStringConverter::GetStringFromRangeList( sRanges, rRangeList, pDoc, FormulaGrammar::CONV_OOO ); + if ( sRanges.getLength() > 0 ) + { + bIsChart = true; + SvXMLAttributeList* pAttrList = new SvXMLAttributeList(); + if ( pAttrList ) + { + pAttrList->AddAttribute( + GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_DRAW, GetXMLToken( XML_NOTIFY_ON_UPDATE_OF_RANGES ) ), sRanges ); + } + GetShapeExport()->exportShape( xShape, SEF_EXPORT_NO_CHART_DATA | SEF_DEFAULT, pPoint, pAttrList ); + } + } + } + } + } + + if ( sRanges.getLength() == 0 ) + { + uno::Reference< frame::XModel > xChartModel; + if( ( xShapeProps->getPropertyValue( sPropModel ) >>= xChartModel ) && + xChartModel.is()) + { + uno::Reference< chart2::XChartDocument > xChartDoc( xChartModel, uno::UNO_QUERY ); + uno::Reference< chart2::data::XDataReceiver > xReceiver( xChartModel, uno::UNO_QUERY ); + if( xChartDoc.is() && xReceiver.is() && + ! xChartDoc->hasInternalDataProvider()) + { + // we have a chart that gets its data from Calc + bIsChart = true; + uno::Sequence< ::rtl::OUString > aRepresentations( + xReceiver->getUsedRangeRepresentations()); + SvXMLAttributeList* pAttrList = 0; + if(aRepresentations.getLength()) + { + // add the ranges used by the chart to the shape + // element to be able to start listening after + // load (when the chart is not yet loaded) + uno::Reference< chart2::data::XRangeXMLConversion > xRangeConverter( xChartDoc->getDataProvider(), uno::UNO_QUERY ); + sRanges = lcl_RangeSequenceToString( aRepresentations, xRangeConverter ); + pAttrList = new SvXMLAttributeList(); + pAttrList->AddAttribute( + GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_DRAW, GetXMLToken(XML_NOTIFY_ON_UPDATE_OF_RANGES) ), sRanges ); + } + GetShapeExport()->exportShape(xShape, SEF_EXPORT_NO_CHART_DATA | SEF_DEFAULT, pPoint, pAttrList); } - GetShapeExport()->exportShape(xShape, SEF_EXPORT_NO_CHART_DATA | SEF_DEFAULT, pPoint, pAttrList); } } @@ -3237,6 +3297,7 @@ void ScXMLExport::WriteAreaLink( const ScMyCell& rMyCell ) { const ScMyAreaLink& rAreaLink = rMyCell.aAreaLink; AddAttribute( XML_NAMESPACE_TABLE, XML_NAME, rAreaLink.sSourceStr ); + AddAttribute( XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE ); AddAttribute( XML_NAMESPACE_XLINK, XML_HREF, GetRelativeReference(rAreaLink.sURL) ); AddAttribute( XML_NAMESPACE_TABLE, XML_FILTER_NAME, rAreaLink.sFilter ); if( rAreaLink.sFilterOptions.getLength() ) @@ -3546,8 +3607,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)) { @@ -3720,6 +3781,7 @@ void ScXMLExport::WriteTableSource() xLinkProps->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_REFDELAY))) >>= nRefresh; if (sLink.getLength()) { + AddAttribute(XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE); AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, GetRelativeReference(sLink)); if (sTableName.getLength()) AddAttribute(XML_NAMESPACE_TABLE, XML_TABLE_NAME, sTableName); @@ -3958,6 +4020,7 @@ void ScXMLExport::WriteExternalRefCaches() aRelUrl = pExtFileData->maRelativeName; else aRelUrl = GetRelativeReference(pExtFileData->maRelativeName); + AddAttribute(XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE); AddAttribute(XML_NAMESPACE_XLINK, XML_HREF, aRelUrl); AddAttribute(XML_NAMESPACE_TABLE, XML_TABLE_NAME, *itr); if (pExtFileData->maFilterName.Len()) @@ -3987,6 +4050,14 @@ void ScXMLExport::WriteExternalRefCaches() } } + // Column definitions have to be present to make a valid file + { + if (nMaxColsUsed > 1) + AddAttribute(XML_NAMESPACE_TABLE, XML_NUMBER_COLUMNS_REPEATED, + OUString::valueOf(static_cast<sal_Int32>(nMaxColsUsed))); + SvXMLElementExport aElemColumn(*this, XML_NAMESPACE_TABLE, XML_TABLE_COLUMN, sal_True, sal_True); + } + // Write cache content for this table. SCROW nLastRow = 0; bool bFirstRow = true; @@ -4245,6 +4316,9 @@ void ScXMLExport::GetViewSettings(uno::Sequence<beans::PropertyValue>& rProps) GetChangeTrackViewSettings(rProps); } + + + void ScXMLExport::GetConfigurationSettings(uno::Sequence<beans::PropertyValue>& rProps) { if (GetModel().is()) @@ -4255,16 +4329,41 @@ void ScXMLExport::GetConfigurationSettings(uno::Sequence<beans::PropertyValue>& uno::Reference <beans::XPropertySet> xProperties(xMultiServiceFactory->createInstance(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.SpreadsheetSettings"))), uno::UNO_QUERY); if (xProperties.is()) SvXMLUnitConverter::convertPropertySet(rProps, xProperties); + + sal_Int32 nPropsToAdd = 0; + rtl::OUStringBuffer aTrackedChangesKey; if (GetDocument() && GetDocument()->GetChangeTrack() && GetDocument()->GetChangeTrack()->IsProtected()) { - rtl::OUStringBuffer aBuffer; - SvXMLUnitConverter::encodeBase64(aBuffer, GetDocument()->GetChangeTrack()->GetProtection()); - if (aBuffer.getLength()) + SvXMLUnitConverter::encodeBase64(aTrackedChangesKey, GetDocument()->GetChangeTrack()->GetProtection()); + if (aTrackedChangesKey.getLength()) + ++nPropsToAdd; + } + + uno::Reference <container::XNameAccess> xCodeNameAccess; + DBG_ASSERT( pDoc, "ScXMLExport::GetConfigurationSettings - no ScDocument!" ); + if( pDoc ) + { + xCodeNameAccess = new XMLCodeNameProvider( pDoc ); + if( xCodeNameAccess.is() && xCodeNameAccess->hasElements() ) + ++nPropsToAdd; + else + xCodeNameAccess = 0; + } + + if( nPropsToAdd > 0 ) + { + sal_Int32 nCount(rProps.getLength()); + rProps.realloc(nCount + nPropsToAdd); + if (aTrackedChangesKey.getLength()) { - sal_Int32 nCount(rProps.getLength()); - rProps.realloc(nCount + 1); rProps[nCount].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("TrackedChangesProtectionKey")); - rProps[nCount].Value <<= aBuffer.makeStringAndClear(); + rProps[nCount].Value <<= aTrackedChangesKey.makeStringAndClear(); + ++nCount; + } + if( xCodeNameAccess.is() ) + { + rProps[nCount].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("ScriptConfiguration")); + rProps[nCount].Value <<= xCodeNameAccess; } } } @@ -4352,6 +4451,22 @@ sal_uInt32 ScXMLExport::exportDoc( enum XMLTokenEnum eClass ) CollectUserDefinedNamespaces(&pDrawLayer->GetItemPool(), EE_CHAR_XMLATTRIBS); CollectUserDefinedNamespaces(&pDrawLayer->GetItemPool(), SDRATTR_XMLATTRIBUTES); } + + // sheet events use officeooo namespace + if( (getExportFlags() & EXPORT_CONTENT) != 0 && + getDefaultVersion() == SvtSaveOptions::ODFVER_LATEST ) + { + bool bAnySheetEvents = false; + SCTAB nTabCount = pDoc->GetTableCount(); + for (SCTAB nTab=0; nTab<nTabCount; ++nTab) + if (pDoc->GetSheetEvents(nTab)) + bAnySheetEvents = true; + if (bAnySheetEvents) + _GetNamespaceMap().Add( + GetXMLToken( XML_NP_OFFICE_EXT ), + GetXMLToken( XML_N_OFFICE_EXT ), + XML_NAMESPACE_OFFICE_EXT ); + } } } return SvXMLExport::exportDoc( eClass ); 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..269e1dd9a7e4 100644 --- a/sc/source/filter/xml/xmlimprt.cxx +++ b/sc/source/filter/xml/xmlimprt.cxx @@ -645,6 +645,8 @@ const SvXMLTokenMap& ScXMLImport::GetTableElemTokenMap() { XML_NAMESPACE_TABLE, XML_SCENARIO, XML_TOK_TABLE_SCENARIO }, { XML_NAMESPACE_TABLE, XML_SHAPES, XML_TOK_TABLE_SHAPES }, { XML_NAMESPACE_OFFICE, XML_FORMS, XML_TOK_TABLE_FORMS }, + { XML_NAMESPACE_OFFICE, XML_EVENT_LISTENERS, XML_TOK_TABLE_EVENT_LISTENERS }, + { XML_NAMESPACE_OFFICE_EXT, XML_EVENT_LISTENERS, XML_TOK_TABLE_EVENT_LISTENERS_EXT }, XML_TOKEN_MAP_END }; @@ -698,12 +700,12 @@ const SvXMLTokenMap& ScXMLImport::GetTableAttrTokenMap() { static __FAR_DATA SvXMLTokenMapEntry aTableAttrTokenMap[] = { - { XML_NAMESPACE_TABLE, XML_NAME, XML_TOK_TABLE_NAME }, - { XML_NAMESPACE_TABLE, XML_STYLE_NAME, XML_TOK_TABLE_STYLE_NAME }, - { XML_NAMESPACE_TABLE, XML_PROTECTED, XML_TOK_TABLE_PROTECTION }, - { XML_NAMESPACE_TABLE, XML_PRINT_RANGES, XML_TOK_TABLE_PRINT_RANGES }, - { XML_NAMESPACE_TABLE, XML_PROTECTION_KEY, XML_TOK_TABLE_PASSWORD }, - { XML_NAMESPACE_TABLE, XML_PRINT, XML_TOK_TABLE_PRINT }, + { XML_NAMESPACE_TABLE, XML_NAME, XML_TOK_TABLE_NAME }, + { XML_NAMESPACE_TABLE, XML_STYLE_NAME, XML_TOK_TABLE_STYLE_NAME }, + { XML_NAMESPACE_TABLE, XML_PROTECTED, XML_TOK_TABLE_PROTECTION }, + { XML_NAMESPACE_TABLE, XML_PRINT_RANGES, XML_TOK_TABLE_PRINT_RANGES }, + { XML_NAMESPACE_TABLE, XML_PROTECTION_KEY, XML_TOK_TABLE_PASSWORD }, + { XML_NAMESPACE_TABLE, XML_PRINT, XML_TOK_TABLE_PRINT }, XML_TOKEN_MAP_END }; @@ -1368,7 +1370,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 }; @@ -2216,10 +2218,11 @@ void ScXMLImport::SetConfigurationSettings(const uno::Sequence<beans::PropertyVa if (xMultiServiceFactory.is()) { sal_Int32 nCount(aConfigProps.getLength()); - rtl::OUString sName(RTL_CONSTASCII_USTRINGPARAM("TrackedChangesProtectionKey")); + rtl::OUString sCTName(RTL_CONSTASCII_USTRINGPARAM("TrackedChangesProtectionKey")); + rtl::OUString sSCName(RTL_CONSTASCII_USTRINGPARAM("ScriptConfiguration")); for (sal_Int32 i = nCount - 1; i >= 0; --i) { - if (aConfigProps[i].Name == sName) + if (aConfigProps[i].Name == sCTName) { rtl::OUString sKey; if (aConfigProps[i].Value >>= sKey) @@ -2240,6 +2243,28 @@ void ScXMLImport::SetConfigurationSettings(const uno::Sequence<beans::PropertyVa } } } + else if (aConfigProps[i].Name == sSCName) + { + uno::Type aType = aConfigProps[i].Value.getValueType(); + uno::Reference<beans::XPropertySet> xImportInfo = + getImportInfo(); + + if (xImportInfo.is() && + (aType.equals(getCppuType( + (uno::Reference<container::XNameContainer> *)0 ) ) || + aType.equals(getCppuType( + (uno::Reference<container::XNameAccess> *)0 ) ) ) ) + { + uno::Reference< beans::XPropertySetInfo > xPropertySetInfo = + xImportInfo->getPropertySetInfo(); + if (xPropertySetInfo.is() && + xPropertySetInfo->hasPropertyByName(sSCName) ) + { + xImportInfo->setPropertyValue(sSCName, + aConfigProps[i].Value ); + } + } + } } uno::Reference <uno::XInterface> xInterface = xMultiServiceFactory->createInstance(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.comp.SpreadsheetSettings"))); uno::Reference <beans::XPropertySet> xProperties(xInterface, uno::UNO_QUERY); diff --git a/sc/source/filter/xml/xmlimprt.hxx b/sc/source/filter/xml/xmlimprt.hxx index e2cea5ae9609..9771655ebd4b 100644 --- a/sc/source/filter/xml/xmlimprt.hxx +++ b/sc/source/filter/xml/xmlimprt.hxx @@ -174,7 +174,9 @@ enum ScXMLTableTokens XML_TOK_TABLE_SOURCE, XML_TOK_TABLE_SCENARIO, XML_TOK_TABLE_SHAPES, - XML_TOK_TABLE_FORMS + XML_TOK_TABLE_FORMS, + XML_TOK_TABLE_EVENT_LISTENERS, + XML_TOK_TABLE_EVENT_LISTENERS_EXT }; enum ScXMLTableRowsTokens diff --git a/sc/source/filter/xml/xmlstyle.cxx b/sc/source/filter/xml/xmlstyle.cxx index f9f0d063a843..4127f5246428 100644 --- a/sc/source/filter/xml/xmlstyle.cxx +++ b/sc/source/filter/xml/xmlstyle.cxx @@ -66,6 +66,7 @@ using namespace ::formula; using ::rtl::OUString; #define MAP(name,prefix,token,type,context) { name, sizeof(name)-1, prefix, token, type, context, SvtSaveOptions::ODFVER_010 } +#define MAP_EXT(name,prefix,token,type,context) { name, sizeof(name)-1, prefix, token, type, context, SvtSaveOptions::ODFVER_LATEST } #define MAP_END() { NULL, 0, 0, XML_TOKEN_INVALID, 0, 0, SvtSaveOptions::ODFVER_010 } const XMLPropertyMapEntry aXMLScCellStylesProperties[] = @@ -161,6 +162,8 @@ const XMLPropertyMapEntry aXMLScTableStylesImportProperties[] = MAP( "IsVisible", XML_NAMESPACE_TABLE, XML_DISPLAY, XML_TYPE_PROP_TABLE|XML_TYPE_BOOL, 0 ), MAP( "PageStyle", XML_NAMESPACE_STYLE, XML_MASTER_PAGE_NAME, XML_TYPE_PROP_TABLE|XML_TYPE_STRING|MID_FLAG_SPECIAL_ITEM, CTF_SC_MASTERPAGENAME ), MAP( "TableLayout", XML_NAMESPACE_STYLE, XML_WRITING_MODE, XML_TYPE_PROP_TABLE|XML_TYPE_TEXT_WRITING_MODE, 0 ), + MAP( "TabColor", XML_NAMESPACE_TABLE, XML_TAB_COLOR, XML_TYPE_PROP_TABLE|XML_TYPE_COLORAUTO, 0 ), + MAP_EXT( "TabColor", XML_NAMESPACE_TABLE_EXT, XML_TAB_COLOR, XML_TYPE_PROP_TABLE|XML_TYPE_COLORAUTO, 0 ), MAP_END() }; @@ -169,6 +172,7 @@ const XMLPropertyMapEntry aXMLScTableStylesProperties[] = MAP( "IsVisible", XML_NAMESPACE_TABLE, XML_DISPLAY, XML_TYPE_PROP_TABLE|XML_TYPE_BOOL, 0 ), MAP( "PageStyle", XML_NAMESPACE_STYLE, XML_MASTER_PAGE_NAME, XML_TYPE_PROP_TABLE|XML_TYPE_STRING|MID_FLAG_SPECIAL_ITEM, CTF_SC_MASTERPAGENAME ), MAP( "TableLayout", XML_NAMESPACE_STYLE, XML_WRITING_MODE, XML_TYPE_PROP_TABLE|XML_TYPE_TEXT_WRITING_MODE, 0 ), + MAP_EXT( "TabColor", XML_NAMESPACE_TABLE_EXT, XML_TAB_COLOR, XML_TYPE_PROP_TABLE|XML_TYPE_COLORAUTO, 0 ), MAP_END() }; @@ -1039,8 +1043,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..69f00106b7c7 100644 --- a/sc/source/filter/xml/xmltabi.cxx +++ b/sc/source/filter/xml/xmltabi.cxx @@ -53,6 +53,7 @@ #include <xmloff/nmspmap.hxx> #include <xmloff/formsimp.hxx> #include <xmloff/xmltoken.hxx> +#include <xmloff/XMLEventsImportContext.hxx> #include <com/sun/star/sheet/XSpreadsheetDocument.hpp> #include <com/sun/star/sheet/XSpreadsheets.hpp> @@ -98,21 +99,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 +213,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 @@ -316,6 +324,14 @@ SvXMLImportContext *ScXMLTableContext::CreateChildContext( USHORT nPrefix, pContext = GetScImport().GetFormImport()->createOfficeFormsContext( GetScImport(), nPrefix, rLName ); } break; + case XML_TOK_TABLE_EVENT_LISTENERS: + case XML_TOK_TABLE_EVENT_LISTENERS_EXT: + { + // use XEventsSupplier interface of the sheet + uno::Reference<document::XEventsSupplier> xSupplier( GetScImport().GetTables().GetCurrentXSheet(), uno::UNO_QUERY ); + pContext = new XMLEventsImportContext( GetImport(), nPrefix, rLName, xSupplier ); + } + break; default: ; } diff --git a/sc/source/filter/xml/xmlwrap.cxx b/sc/source/filter/xml/xmlwrap.cxx index f21ed7d55ac2..dbe647bc433f 100644 --- a/sc/source/filter/xml/xmlwrap.cxx +++ b/sc/source/filter/xml/xmlwrap.cxx @@ -80,6 +80,7 @@ #include "XMLExportSharedData.hxx" #include "docuno.hxx" #include "sheetdata.hxx" +#include "XMLCodeNameProvider.hxx" #define MAP_LEN(x) x, sizeof(x) - 1 @@ -425,6 +426,7 @@ sal_Bool ScXMLImportWrapper::Import(sal_Bool bStylesOnly, ErrCode& nError) { MAP_LEN( "StreamRelPath" ), 0, &::getCppuType( (rtl::OUString *)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 }, { MAP_LEN( "StreamName" ), 0, &::getCppuType( (rtl::OUString *)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 }, { MAP_LEN( "BuildId" ), 0, &::getCppuType( (OUString *)0 ), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0 }, + { MAP_LEN( "ScriptConfiguration" ), 0, &::getCppuType((uno::Reference<container::XNameAccess> *)0), ::com::sun::star::beans::PropertyAttribute::MAYBEVOID, 0}, { NULL, 0, 0, NULL, 0, 0 } }; @@ -635,6 +637,12 @@ sal_Bool ScXMLImportWrapper::Import(sal_Bool bStylesOnly, ErrCode& nError) xModelSet->setPropertyValue( sBuildPropName, xInfoSet->getPropertyValue(sBuildPropName) ); } } + + // Set Code Names + uno::Any aAny = xInfoSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("ScriptConfiguration") )); + uno::Reference <container::XNameAccess> xCodeNameAccess; + if( aAny >>= xCodeNameAccess ) + XMLCodeNameProvider::set( xCodeNameAccess, &rDoc ); } // Don't test bStylesRetval and bMetaRetval, because it could be an older file which not contain such streams diff --git a/sc/source/ui/Accessibility/AccessibleCellBase.cxx b/sc/source/ui/Accessibility/AccessibleCellBase.cxx index 92ff551f2724..cc93d0a93350 100644 --- a/sc/source/ui/Accessibility/AccessibleCellBase.cxx +++ b/sc/source/ui/Accessibility/AccessibleCellBase.cxx @@ -92,10 +92,12 @@ sal_Bool SAL_CALL ScAccessibleCellBase::isVisible( ) sal_Bool bVisible(sal_True); if (mpDoc) { - BYTE nColFlags = mpDoc->GetColFlags(maCellAddress.Col(), maCellAddress.Tab()); - BYTE nRowFlags = mpDoc->GetRowFlags(maCellAddress.Row(), maCellAddress.Tab()); - if (((nColFlags & CR_HIDDEN) == CR_HIDDEN) || ((nColFlags & CR_FILTERED) == CR_FILTERED) || - ((nRowFlags & CR_HIDDEN) == CR_HIDDEN) || ((nRowFlags & CR_FILTERED) == CR_FILTERED)) + bool bColHidden = mpDoc->ColHidden(maCellAddress.Col(), maCellAddress.Tab()); + bool bRowHidden = mpDoc->RowHidden(maCellAddress.Row(), maCellAddress.Tab()); + bool bColFiltered = mpDoc->ColFiltered(maCellAddress.Col(), maCellAddress.Tab()); + bool bRowFiltered = mpDoc->RowFiltered(maCellAddress.Row(), maCellAddress.Tab()); + + if (bColHidden || bColFiltered || bRowHidden || bRowFiltered) bVisible = sal_False; } return bVisible; diff --git a/sc/source/ui/Accessibility/AccessibleContextBase.cxx b/sc/source/ui/Accessibility/AccessibleContextBase.cxx index e438224ecfb6..0f1fcfa337a5 100644 --- a/sc/source/ui/Accessibility/AccessibleContextBase.cxx +++ b/sc/source/ui/Accessibility/AccessibleContextBase.cxx @@ -626,7 +626,3 @@ void ScAccessibleContextBase::IsObjectValid() const throw lang::DisposedException(); } -void ScAccessibleContextBase::SetRole(sal_Int16 nRole) -{ - maRole = nRole; -} diff --git a/sc/source/ui/Accessibility/AccessibleFilterTopWindow.cxx b/sc/source/ui/Accessibility/AccessibleFilterTopWindow.cxx index f536b8b9a8f7..2af69faa33c8 100644 --- a/sc/source/ui/Accessibility/AccessibleFilterTopWindow.cxx +++ b/sc/source/ui/Accessibility/AccessibleFilterTopWindow.cxx @@ -99,13 +99,6 @@ OUString ScAccessibleFilterTopWindow::getImplementationName() throw (RuntimeExce return OUString::createFromAscii("ScAccessibleFilterTopWindow"); } -Reference<XAccessible> ScAccessibleFilterTopWindow::getAccessibleChildMenu() -{ - if (!mxAccMenu.is()) - mxAccMenu.set(new ScAccessibleFilterMenu(this, mpWindow, getAccessibleName(), ScMenuFloatingWindow::MENU_NOT_SELECTED, mpDoc)); - return mxAccMenu; -} - void ScAccessibleFilterTopWindow::setAccessibleChild( const Reference<XAccessible>& rAccessible, ChildControlType eType) { diff --git a/sc/source/ui/app/inputhdl.cxx b/sc/source/ui/app/inputhdl.cxx index 40b65ce401ad..55aa0986d2ec 100644 --- a/sc/source/ui/app/inputhdl.cxx +++ b/sc/source/ui/app/inputhdl.cxx @@ -429,7 +429,9 @@ ScInputHandler::ScInputHandler() pColumnData( NULL ), pFormulaData( NULL ), pFormulaDataPara( NULL ), + pTipVisibleParent( NULL ), nTipVisible( 0 ), + pTipVisibleSecParent( NULL ), nTipVisibleSec( 0 ), nAutoPos( SCPOS_INVALID ), bUseTab( FALSE ), @@ -691,12 +693,29 @@ void ScInputHandler::GetFormulaData() } } +IMPL_LINK( ScInputHandler, ShowHideTipVisibleParentListener, VclWindowEvent*, pEvent ) +{ + if( pEvent->GetId() == VCLEVENT_OBJECT_DYING || pEvent->GetId() == VCLEVENT_WINDOW_HIDE ) + HideTip(); + return 0; +} + +IMPL_LINK( ScInputHandler, ShowHideTipVisibleSecParentListener, VclWindowEvent*, pEvent ) +{ + if( pEvent->GetId() == VCLEVENT_OBJECT_DYING || pEvent->GetId() == VCLEVENT_WINDOW_HIDE ) + HideTipBelow(); + return 0; +} + void ScInputHandler::HideTip() { if ( nTipVisible ) { + if (pTipVisibleParent) + pTipVisibleParent->RemoveEventListener( LINK( this, ScInputHandler, ShowHideTipVisibleParentListener ) ); Help::HideTip( nTipVisible ); nTipVisible = 0; + pTipVisibleParent = NULL; } aManualTip.Erase(); } @@ -704,8 +723,11 @@ void ScInputHandler::HideTipBelow() { if ( nTipVisibleSec ) { + if (pTipVisibleSecParent) + pTipVisibleSecParent->RemoveEventListener( LINK( this, ScInputHandler, ShowHideTipVisibleSecParentListener ) ); Help::HideTip( nTipVisibleSec ); nTipVisibleSec = 0; + pTipVisibleSecParent = NULL; } aManualTip.Erase(); } @@ -897,15 +919,16 @@ void ScInputHandler::ShowTip( const String& rText ) if (pActiveView) { Point aPos; - Window* pWin = pActiveView->GetWindow(); + pTipVisibleParent = pActiveView->GetWindow(); Cursor* pCur = pActiveView->GetCursor(); if (pCur) - aPos = pWin->LogicToPixel( pCur->GetPos() ); - aPos = pWin->OutputToScreenPixel( aPos ); + aPos = pTipVisibleParent->LogicToPixel( pCur->GetPos() ); + aPos = pTipVisibleParent->OutputToScreenPixel( aPos ); Rectangle aRect( aPos, aPos ); USHORT nAlign = QUICKHELP_LEFT|QUICKHELP_BOTTOM; - nTipVisible = Help::ShowTip(pWin, aRect, rText, nAlign); + nTipVisible = Help::ShowTip(pTipVisibleParent, aRect, rText, nAlign); + pTipVisibleParent->AddEventListener( LINK( this, ScInputHandler, ShowHideTipVisibleParentListener ) ); } } @@ -917,18 +940,19 @@ void ScInputHandler::ShowTipBelow( const String& rText ) if ( pActiveView ) { Point aPos; - Window* pWin = pActiveView->GetWindow(); + pTipVisibleSecParent = pActiveView->GetWindow(); Cursor* pCur = pActiveView->GetCursor(); if ( pCur ) { Point aLogicPos = pCur->GetPos(); aLogicPos.Y() += pCur->GetHeight(); - aPos = pWin->LogicToPixel( aLogicPos ); + aPos = pTipVisibleSecParent->LogicToPixel( aLogicPos ); } - aPos = pWin->OutputToScreenPixel( aPos ); + aPos = pTipVisibleSecParent->OutputToScreenPixel( aPos ); Rectangle aRect( aPos, aPos ); - USHORT nAlign = QUICKHELP_LEFT | QUICKHELP_TOP; - nTipVisibleSec = Help::ShowTip(pWin, aRect, rText, nAlign); + USHORT nAlign = QUICKHELP_LEFT | QUICKHELP_TOP | QUICKHELP_NOEVADEPOINTER; + nTipVisibleSec = Help::ShowTip(pTipVisibleSecParent, aRect, rText, nAlign); + pTipVisibleSecParent->AddEventListener( LINK( this, ScInputHandler, ShowHideTipVisibleSecParentListener ) ); } } @@ -2690,6 +2714,7 @@ void ScInputHandler::EnterHandler( BYTE nBlockMode ) delete pObject; HideTip(); + HideTipBelow(); nFormSelStart = nFormSelEnd = 0; aFormText.Erase(); diff --git a/sc/source/ui/app/inputwin.cxx b/sc/source/ui/app/inputwin.cxx index f6fc2cb27b71..2cabe7f9f2d6 100644 --- a/sc/source/ui/app/inputwin.cxx +++ b/sc/source/ui/app/inputwin.cxx @@ -289,7 +289,7 @@ sal_Bool ScInputWindow::UseSubTotal(ScRangeList* pRangeList) const SCROW nRow(pRange->aStart.Row()); while (!bSubTotal && nRow <= nRowEnd) { - if (pDoc->IsFiltered(nRow, nTab)) + if (pDoc->RowFiltered(nRow, nTab)) bSubTotal = sal_True; else ++nRow; 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/app/scdll.cxx b/sc/source/ui/app/scdll.cxx index 4a460eb7e4ad..8051399d06fa 100644 --- a/sc/source/ui/app/scdll.cxx +++ b/sc/source/ui/app/scdll.cxx @@ -40,6 +40,7 @@ #include <svx/tbxcolor.hxx> #include <sot/clsids.hxx> +#include <sfx2/taskpane.hxx> #include <sfx2/docfilt.hxx> #include <sfx2/fcontnr.hxx> #include <sfx2/docfile.hxx> @@ -47,7 +48,7 @@ #include <avmedia/mediaplayer.hxx> #include <avmedia/mediatoolbox.hxx> #include <comphelper/types.hxx> -#include <svx/extrusioncontrols.hxx> +#include <svx/extrusioncolorcontrol.hxx> #include <svx/fontworkgallery.hxx> #include <svx/tbxcustomshapes.hxx> @@ -263,6 +264,9 @@ void ScDLL::Init() //Media Controller ::avmedia::MediaToolBoxControl::RegisterControl( SID_AVMEDIA_TOOLBOX, pMod ); + // common SFX controller + ::sfx2::TaskPaneWrapper::RegisterChildWindow( FALSE, pMod ); + // Svx-StatusBar-Controller SvxInsertStatusBarControl ::RegisterControl(SID_ATTR_INSERT, pMod); SvxSelectionModeControl ::RegisterControl(SID_STATUS_SELMODE, pMod); @@ -278,15 +282,8 @@ void ScDLL::Init() SvxFontSizeMenuControl ::RegisterControl(SID_ATTR_CHAR_FONTHEIGHT, pMod); // CustomShape extrusion controller - svx::ExtrusionDepthControl::RegisterControl( SID_EXTRUSION_DEPTH_FLOATER, pMod ); - svx::ExtrusionDirectionControl::RegisterControl( SID_EXTRUSION_DIRECTION_FLOATER, pMod ); - svx::ExtrusionLightingControl::RegisterControl( SID_EXTRUSION_LIGHTING_FLOATER, pMod ); - svx::ExtrusionSurfaceControl::RegisterControl( SID_EXTRUSION_SURFACE_FLOATER, pMod ); svx::ExtrusionColorControl::RegisterControl( SID_EXTRUSION_3D_COLOR, pMod ); - svx::FontWorkShapeTypeControl::RegisterControl( SID_FONTWORK_SHAPE_TYPE, pMod ); - svx::FontWorkAlignmentControl::RegisterControl( SID_FONTWORK_ALIGNMENT_FLOATER, pMod ); - svx::FontWorkCharacterSpacingControl::RegisterControl( SID_FONTWORK_CHARACTER_SPACING_FLOATER, pMod ); // Child-Windows diff --git a/sc/source/ui/app/scmod.cxx b/sc/source/ui/app/scmod.cxx index 9c3ae8ce805e..f7a02e1577f7 100644 --- a/sc/source/ui/app/scmod.cxx +++ b/sc/source/ui/app/scmod.cxx @@ -98,7 +98,6 @@ #include "msgpool.hxx" #include "scresid.hxx" #include "anyrefdg.hxx" -#include "teamdlg.hxx" #include "dwfunctr.hxx" #include "formdata.hxx" //CHINA001 #include "tpview.hxx" @@ -142,7 +141,6 @@ ScModule::ScModule( SfxObjectFactory* pFact ) : pSelTransfer( NULL ), pMessagePool( NULL ), pRefInputHandler( NULL ), - pTeamDlg( NULL ), pViewCfg( NULL ), pDocCfg( NULL ), pAppCfg( NULL ), @@ -1445,11 +1443,6 @@ void ScModule::ViewShellGone( ScTabViewShell* pViewSh ) ScInputHandler* pHdl = GetInputHdl(); if (pHdl) pHdl->ViewShellGone( pViewSh ); - - // Team dialog is opened with the window from a view as parent - // -> close it if any view is closed - if (pTeamDlg) - pTeamDlg->Close(); // resets variable pTeamDlg } void ScModule::SetRefInputHdl( ScInputHandler* pNew ) @@ -1573,21 +1566,6 @@ void ScModule::SetRefDialog( USHORT nId, BOOL bVis, SfxViewFrame* pViewFrm ) } } -void ScModule::OpenTeamDlg() -{ - if ( !pTeamDlg ) - { - // team dialog needs an existing parent window - // -> use window from active view (dialog is closed in ViewShellGone) - - ScTabViewShell* pShell = ScTabViewShell::GetActiveViewShell(); - if (pShell) - pTeamDlg = new ScTeamDlg( pShell->GetActiveWin() ); - } - else - pTeamDlg->Center(); -} - SfxChildWindow* lcl_GetChildWinFromAnyView( USHORT nId ) { // first try the current view @@ -1868,21 +1846,19 @@ IMPL_LINK( ScModule, IdleHandler, Timer*, EMPTYARG ) if ( pDocSh ) { ScDocument* pDoc = pDocSh->GetDocument(); - if ( pDoc->IsLoadingDone() ) - { - BOOL bLinks = pDoc->IdleCheckLinks(); - BOOL bWidth = pDoc->IdleCalcTextWidth(); - BOOL bSpell = pDoc->ContinueOnlineSpelling(); - if ( bSpell ) - aSpellTimer.Start(); // da ist noch was - - bMore = bLinks || bWidth || bSpell; // ueberhaupt noch was? - - // While calculating a Basic formula, a paint event may have occured, - // so check the bNeedsRepaint flags for this document's views - if (bWidth) - lcl_CheckNeedsRepaint( pDocSh ); - } + + BOOL bLinks = pDoc->IdleCheckLinks(); + BOOL bWidth = pDoc->IdleCalcTextWidth(); + BOOL bSpell = pDoc->ContinueOnlineSpelling(); + if ( bSpell ) + aSpellTimer.Start(); // da ist noch was + + bMore = bLinks || bWidth || bSpell; // ueberhaupt noch was? + + // While calculating a Basic formula, a paint event may have occured, + // so check the bNeedsRepaint flags for this document's views + if (bWidth) + lcl_CheckNeedsRepaint( pDocSh ); } ULONG nOldTime = aIdleTimer.GetTimeout(); @@ -2152,9 +2128,6 @@ IMPL_LINK( ScModule, CalcFieldValueHdl, EditFieldInfo*, pInfo ) return 0; } - - -//<!--Added by PengYunQuan for Validity Cell Range Picker BOOL ScModule::RegisterRefWindow( USHORT nSlotId, Window *pWnd ) { std::list<Window*> & rlRefWindow = m_mapRefWindow[nSlotId]; @@ -2204,10 +2177,13 @@ BOOL ScModule::IsAliveRefDlg( USHORT nSlotId, Window *pWnd ) Window * ScModule::Find1RefWindow( USHORT nSlotId, Window *pWndAncestor ) { + if (!pWndAncestor) + return NULL; + std::map<USHORT, std::list<Window*> >::iterator iSlot = m_mapRefWindow.find( nSlotId ); if( iSlot == m_mapRefWindow.end() ) - return FALSE; + return NULL; std::list<Window*> & rlRefWindow = iSlot->second; @@ -2222,6 +2198,9 @@ Window * ScModule::Find1RefWindow( USHORT nSlotId, Window *pWndAncestor ) Window * ScModule::Find1RefWindow( Window *pWndAncestor ) { + if (!pWndAncestor) + return NULL; + while( Window *pParent = pWndAncestor->GetParent() ) pWndAncestor = pParent; for( std::map<USHORT, std::list<Window*> >::iterator i = m_mapRefWindow.begin(); @@ -2232,4 +2211,4 @@ Window * ScModule::Find1RefWindow( Window *pWndAncestor ) return NULL; } -//<!--Added by PengYunQuan for Validity Cell Range Picker + diff --git a/sc/source/ui/app/transobj.cxx b/sc/source/ui/app/transobj.cxx index a5b286e8a9ea..4b268b9da791 100644 --- a/sc/source/ui/app/transobj.cxx +++ b/sc/source/ui/app/transobj.cxx @@ -602,25 +602,23 @@ void ScTransferObj::InitDocShell() // widths / heights // (must be copied before CopyFromClip, for drawing objects) - SCCOL nCol; - SCROW nRow; + SCCOL nCol, nLastCol; SCTAB nSrcTab = aBlock.aStart.Tab(); pDestDoc->SetLayoutRTL(0, pDoc->IsLayoutRTL(nSrcTab)); for (nCol=nStartX; nCol<=nEndX; nCol++) - if ( pDoc->GetColFlags( nCol, nSrcTab ) & CR_HIDDEN ) + if ( pDoc->ColHidden(nCol, nSrcTab, nLastCol) ) pDestDoc->ShowCol( nCol, 0, FALSE ); else pDestDoc->SetColWidth( nCol, 0, pDoc->GetColWidth( nCol, nSrcTab ) ); ScBitMaskCompressedArray< SCROW, BYTE> & rDestRowFlags = pDestDoc->GetRowFlagsArrayModifiable(0); - ScCompressedArrayIterator< SCROW, BYTE> aIter( pDoc->GetRowFlagsArray( - nSrcTab), nStartY, nEndY); - for ( ; aIter; ++aIter ) + + for (SCROW nRow = nStartY; nRow <= nEndY; ++nRow) { - nRow = aIter.GetPos(); - BYTE nSourceFlags = *aIter; - if ( nSourceFlags & CR_HIDDEN ) + BYTE nSourceFlags = pDoc->GetRowFlags(nRow, nSrcTab); + SCROW nLastRow = -1; + if ( pDoc->RowHidden(nRow, nSrcTab, nLastRow) ) pDestDoc->ShowRow( nRow, 0, FALSE ); else { @@ -684,7 +682,7 @@ void ScTransferObj::InitDocShell() for (nCol=0; nCol<nStartX; nCol++) nPosX += pDestDoc->GetColWidth( nCol, 0 ); - nPosY += pDestDoc->FastGetRowHeight( 0, nStartY-1, 0 ); + nPosY += pDestDoc->GetRowHeight( 0, nStartY-1, 0 ); nPosX = (long) ( nPosX * HMM_PER_TWIPS ); nPosY = (long) ( nPosY * HMM_PER_TWIPS ); @@ -701,9 +699,9 @@ void ScTransferObj::InitDocShell() break; nSizeX += nAdd; } - for (nRow=nStartY; nRow<=nEndY; nRow++) + for (SCROW nRow=nStartY; nRow<=nEndY; nRow++) { - long nAdd = pDestDoc->FastGetRowHeight( nRow, 0 ); + long nAdd = pDestDoc->GetRowHeight( nRow, 0 ); if ( nSizeY+nAdd > aPaperSize.Height() && nSizeY ) // above limit? break; nSizeY += nAdd; diff --git a/sc/source/ui/attrdlg/scdlgfact.cxx b/sc/source/ui/attrdlg/scdlgfact.cxx index 7bb0a94c9d58..812b43645fc4 100644 --- a/sc/source/ui/attrdlg/scdlgfact.cxx +++ b/sc/source/ui/attrdlg/scdlgfact.cxx @@ -62,6 +62,7 @@ #include "scendlg.hxx" //add for ScNewScenarioDlg #include "shtabdlg.hxx" //add for ScShowTabDlg #include "strindlg.hxx" //add for ScStringInputDlg +#include "tabbgcolordlg.hxx"//add for ScTabBgColorDlg #include "scuiimoptdlg.hxx" //add for ScImportOptionsDlg #include "attrdlg.hxx" //add for ScAttrDlg #include "hfedtdlg.hxx" //add for ScHFEditDlg @@ -112,6 +113,7 @@ IMPL_ABSTDLG_BASE(AbstractScDPShowDetailDlg_Impl); //add for ScDPShowDetailDlg IMPL_ABSTDLG_BASE(AbstractScNewScenarioDlg_Impl); //add for ScNewScenarioDlg IMPL_ABSTDLG_BASE(AbstractScShowTabDlg_Impl); //add for ScShowTabDlg IMPL_ABSTDLG_BASE(AbstractScStringInputDlg_Impl); //add for ScStringInputDlg +IMPL_ABSTDLG_BASE(AbstractScTabBgColorDlg_Impl); //add for ScTabBgColorDlg IMPL_ABSTDLG_BASE(AbstractScImportOptionsDlg_Impl); //add for ScImportOptionsDlg IMPL_ABSTDLG_BASE(AbstractScTextImportOptionsDlg_Impl); IMPL_ABSTDLG_BASE(AbstractTabDialog_Impl); //add for ScAttrDlg, ScHFEditDlg, ScStyleDlg, ScSubTotalDlg,ScCharDlg, ScParagraphDlg, ScValidationDlg, ScSortDlg @@ -618,6 +620,14 @@ void AbstractScStringInputDlg_Impl::GetInputString( String& rString ) const //a } //add for AbstractScStringInputDlg_Impl end +//add for AbstractScTabBgColorDlg_Impl begin +void AbstractScTabBgColorDlg_Impl::GetSelectedColor( Color& rColor ) const //add for ScTabBgColorDlg +{ + pDlg->GetSelectedColor( rColor ); +} +//add for AbstractScTabBgColorDlg_Impl end + + //add for AbstractScImportOptionsDlg_Impl begin void AbstractScImportOptionsDlg_Impl::GetImportOptions( ScImportOptions& rOptions ) const //add for ScImportOptionsDlg { @@ -1293,6 +1303,31 @@ AbstractScShowTabDlg * ScAbstractDialogFactory_Impl::CreateScShowTabDlg ( Window } //add for ScStringInputDlg end +//add for ScTabBgColorDlg begin +AbstractScTabBgColorDlg * ScAbstractDialogFactory_Impl::CreateScTabBgColorDlg ( + Window* pParent, + const String& rTitle, + const String& rTabBgColorNoColorText, + const Color& rDefaultColor, + const rtl::OString& sHelpId , + int nId ) +{ +ScTabBgColorDlg * pDlg=NULL; +switch ( nId ) +{ + case RID_SCDLG_TAB_BG_COLOR : + pDlg = new ScTabBgColorDlg( pParent, rTitle, rTabBgColorNoColorText, rDefaultColor, sHelpId ); + break; + default: + break; +} + +if ( pDlg ) + return new AbstractScTabBgColorDlg_Impl( pDlg ); +return 0; +} +//add for ScTabBgColorDlg end + //add for ScImportOptionsDlg begin AbstractScImportOptionsDlg * ScAbstractDialogFactory_Impl::CreateScImportOptionsDlg ( Window* pParent, int nId, diff --git a/sc/source/ui/attrdlg/scdlgfact.hxx b/sc/source/ui/attrdlg/scdlgfact.hxx index 9cd77cc61878..b121e82cb58d 100644 --- a/sc/source/ui/attrdlg/scdlgfact.hxx +++ b/sc/source/ui/attrdlg/scdlgfact.hxx @@ -58,6 +58,7 @@ class ScDPShowDetailDlg; class ScNewScenarioDlg; class ScShowTabDlg; class ScStringInputDlg; +class ScTabBgColorDlg; class ScImportOptionsDlg; class SfxTabDialog; class ScSortWarningDlg; @@ -336,6 +337,12 @@ class AbstractScStringInputDlg_Impl : public AbstractScStringInputDlg //add fo virtual void GetInputString( String& rString ) const; }; +class AbstractScTabBgColorDlg_Impl : public AbstractScTabBgColorDlg //add for ScTabBgColorDlg +{ + DECL_ABSTDLG_BASE( AbstractScTabBgColorDlg_Impl, ScTabBgColorDlg ) + virtual void GetSelectedColor( Color& rColor ) const; +}; + class AbstractScImportOptionsDlg_Impl : public AbstractScImportOptionsDlg //add for ScImportOptionsDlg { DECL_ABSTDLG_BASE( AbstractScImportOptionsDlg_Impl, ScImportOptionsDlg) @@ -519,6 +526,14 @@ public: const String& rDefault, const rtl::OString& sHelpId, const rtl::OString& sEditHelpId, int nId ); + + virtual AbstractScTabBgColorDlg * CreateScTabBgColorDlg ( Window* pParent, //add for ScStringInputDlg + const String& rTitle, //Dialog Title + const String& rTabBgColorNoColorText, //Label for no tab color + const Color& rDefaultColor, //Currently selected Color + const rtl::OString& sHelpId , + int nId ); + virtual AbstractScImportOptionsDlg * CreateScImportOptionsDlg ( Window* pParent, //add for ScImportOptionsDlg int nId, BOOL bAscii = TRUE, diff --git a/sc/source/ui/cctrl/dpcontrol.cxx b/sc/source/ui/cctrl/dpcontrol.cxx index fa14a5497826..52aae575b7d7 100644 --- a/sc/source/ui/cctrl/dpcontrol.cxx +++ b/sc/source/ui/cctrl/dpcontrol.cxx @@ -169,11 +169,6 @@ void ScDPFieldButton::getPopupBoundingBox(Point& rPos, Size& rSize) const rSize.setHeight(nH); } -bool ScDPFieldButton::isPopupButton() const -{ - return mbPopupButton; -} - void ScDPFieldButton::drawPopupButton() { Point aPos; @@ -732,27 +727,6 @@ ScMenuFloatingWindow* ScMenuFloatingWindow::getSubMenuWindow(size_t nPos) const return maMenuItems[nPos].mpSubMenuWin.get(); } -size_t ScMenuFloatingWindow::getMenuItemCount() const -{ - return maMenuItems.size(); -} - -OUString ScMenuFloatingWindow::getMenuItemName(size_t nPos) const -{ - if (maMenuItems.size() <= nPos) - return ScGlobal::GetEmptyString(); - - return maMenuItems[nPos].maText; -} - -bool ScMenuFloatingWindow::isMenuItemEnabled(size_t nPos) const -{ - if (maMenuItems.size() <= nPos) - return false; - - return maMenuItems[nPos].mbEnabled; -} - bool ScMenuFloatingWindow::isMenuItemSelected(size_t nPos) const { return nPos == mnSelectedMenu; 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/dbgui/asciiopt.cxx b/sc/source/ui/dbgui/asciiopt.cxx index cd1f85fb99cc..a22953ade25b 100644 --- a/sc/source/ui/dbgui/asciiopt.cxx +++ b/sc/source/ui/dbgui/asciiopt.cxx @@ -253,20 +253,13 @@ void ScAsciiOptions::ReadFromString( const String& rString ) eCharSet = ScGlobal::GetCharsetValue( aToken ); } - // Language - if (nCount >= 4) - { - aToken = rString.GetToken(3, ','); - eLang = static_cast<LanguageType>(aToken.ToInt32()); - } - // // Startzeile // - if ( nCount >= 5 ) + if ( nCount >= 4 ) { - aToken = rString.GetToken(4,','); + aToken = rString.GetToken(3,','); nStartRow = aToken.ToInt32(); } @@ -274,12 +267,12 @@ void ScAsciiOptions::ReadFromString( const String& rString ) // Spalten-Infos // - if ( nCount >= 6 ) + if ( nCount >= 5 ) { delete[] pColStart; delete[] pColFormat; - aToken = rString.GetToken(5,','); + aToken = rString.GetToken(4,','); nSub = aToken.GetTokenCount('/'); nInfoCount = nSub / 2; if (nInfoCount) @@ -299,6 +292,13 @@ void ScAsciiOptions::ReadFromString( const String& rString ) } } + // Language + if (nCount >= 6) + { + aToken = rString.GetToken(5, ','); + eLang = static_cast<LanguageType>(aToken.ToInt32()); + } + // Import quoted field as text. if (nCount >= 7) { @@ -362,10 +362,6 @@ String ScAsciiOptions::WriteToString() const aOutStr += ScGlobal::GetCharsetString( eCharSet ); aOutStr += ','; // Token-Ende - // Language - aOutStr += String::CreateFromInt32(eLang); - aOutStr += ','; - // // Startzeile // @@ -387,6 +383,13 @@ String ScAsciiOptions::WriteToString() const aOutStr += String::CreateFromInt32(pColFormat[nInfo]); } + // #i112025# the options string is used in macros and linked sheets, + // so new options must be added at the end, to remain compatible + + aOutStr += ','; + + // Language + aOutStr += String::CreateFromInt32(eLang); aOutStr += ','; // Import quoted field as text. diff --git a/sc/source/ui/docshell/dbdocfun.cxx b/sc/source/ui/docshell/dbdocfun.cxx index 9895f0f43610..cf149d258062 100644 --- a/sc/source/ui/docshell/dbdocfun.cxx +++ b/sc/source/ui/docshell/dbdocfun.cxx @@ -937,7 +937,10 @@ BOOL ScDBDocFunc::Query( SCTAB nTab, const ScQueryParam& rQueryParam, } if (!bCopy) + { + pDoc->InvalidatePageBreaks(nTab); pDoc->UpdatePageBreaks( nTab ); + } // #i23299# because of Subtotal functions, the whole rows must be set dirty ScRange aDirtyRange( 0 , aLocalParam.nRow1, nDestTab, @@ -1275,6 +1278,13 @@ BOOL ScDBDocFunc::DataPilotUpdate( ScDPObject* pOldObj, const ScDPObject* pNewOb // output range must be set at pNewObj pDestObj = new ScDPObject( *pNewObj ); + + // #i94570# When changing the output position in the dialog, a new table is created + // with the settings from the old table, including the name. + // So we have to check for duplicate names here (before inserting). + if ( pDoc->GetDPCollection()->GetByName(pDestObj->GetName()) ) + pDestObj->SetName( String() ); // ignore the invalid name, create a new name below + pDestObj->SetAlive(TRUE); if ( !pDoc->GetDPCollection()->InsertNewTable(pDestObj) ) { diff --git a/sc/source/ui/docshell/docfunc.cxx b/sc/source/ui/docshell/docfunc.cxx index cd28daa99401..27b8eef7bbd6 100644 --- a/sc/source/ui/docshell/docfunc.cxx +++ b/sc/source/ui/docshell/docfunc.cxx @@ -48,6 +48,12 @@ #include <svl/zforlist.hxx> #include <svl/PasswordHelper.hxx> +#include <basic/sbstar.hxx> +#include <com/sun/star/container/XNameContainer.hpp> +#include <com/sun/star/script/XLibraryContainer.hpp> +#include <com/sun/star/script/XVBAModuleInfo.hpp> +#include <com/sun/star/script/ModuleType.hpp> + #include <list> #include "docfunc.hxx" @@ -92,8 +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; @@ -1035,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 @@ -2576,6 +2589,106 @@ BOOL ScDocFunc::MoveBlock( const ScRange& rSource, const ScAddress& rDestPos, } //------------------------------------------------------------------------ +uno::Reference< uno::XInterface > GetDocModuleObject( SfxObjectShell& rDocSh, String& sCodeName ) +{ + uno::Reference< lang::XMultiServiceFactory> xSF(rDocSh.GetModel(), uno::UNO_QUERY); + uno::Reference< container::XNameAccess > xVBACodeNamedObjectAccess; + uno::Reference< uno::XInterface > xDocModuleApiObject; + if ( xSF.is() ) + { + xVBACodeNamedObjectAccess.set( xSF->createInstance( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "ooo.vba.VBAObjectModuleObjectProvider"))), uno::UNO_QUERY ); + xDocModuleApiObject.set( xVBACodeNamedObjectAccess->getByName( sCodeName ), uno::UNO_QUERY ); + } + return xDocModuleApiObject; + +} + +script::ModuleInfo lcl_InitModuleInfo( SfxObjectShell& rDocSh, String& sModule ) +{ + ::rtl::OUString sVbaOption( RTL_CONSTASCII_USTRINGPARAM( "Rem Attribute VBA_ModuleType=VBADocumentModule\nOption VBASupport 1\n" )); + script::ModuleInfo sModuleInfo; + sModuleInfo.ModuleType = script::ModuleType::DOCUMENT; + sModuleInfo.ModuleObject = GetDocModuleObject( rDocSh, sModule ); + return sModuleInfo; +} + +void VBA_InsertModule( ScDocument& rDoc, SCTAB nTab, String& sModuleName, String& sSource ) +{ + SFX_APP()->EnterBasicCall(); + SfxObjectShell& rDocSh = *rDoc.GetDocumentShell(); + uno::Reference< script::XLibraryContainer > xLibContainer = rDocSh.GetBasicContainer(); + DBG_ASSERT( xLibContainer.is(), "No BasicContainer!" ); + + uno::Reference< container::XNameContainer > xLib; + if( xLibContainer.is() ) + { + String aLibName( RTL_CONSTASCII_USTRINGPARAM( "Standard" ) ); + if ( rDocSh.GetBasicManager() && rDocSh.GetBasicManager()->GetName().Len() ) + aLibName = rDocSh.GetBasicManager()->GetName(); + uno::Any aLibAny = xLibContainer->getByName( aLibName ); + aLibAny >>= xLib; + } + if( xLib.is() ) + { + // if the Module with codename exists then find a new name + sal_Int32 nNum = 0; + String genModuleName; + if ( sModuleName.Len() ) + sModuleName = sModuleName; + else + { + genModuleName = String::CreateFromAscii( "Sheet1" ); + nNum = 1; + } + while( xLib->hasByName( genModuleName ) ) + genModuleName = rtl::OUString::createFromAscii( "Sheet" ) + rtl::OUString::valueOf( ++nNum ); + + uno::Any aSourceAny; + rtl::OUString sTmpSource = sSource; + if ( sTmpSource.getLength() == 0 ) + sTmpSource = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Rem Attribute VBA_ModuleType=VBADocumentModule\nOption VBASupport 1\n" )); + aSourceAny <<= sTmpSource; + uno::Reference< script::XVBAModuleInfo > xVBAModuleInfo( xLib, uno::UNO_QUERY ); + if ( xVBAModuleInfo.is() ) + { + String sCodeName( genModuleName ); + rDoc.SetCodeName( nTab, sCodeName ); + script::ModuleInfo sModuleInfo = lcl_InitModuleInfo( rDocSh, genModuleName ); + xVBAModuleInfo->insertModuleInfo( genModuleName, sModuleInfo ); + xLib->insertByName( genModuleName, aSourceAny ); + } + + } + SFX_APP()->LeaveBasicCall(); +} + +void VBA_DeleteModule( ScDocShell& rDocSh, String& sModuleName ) +{ + SFX_APP()->EnterBasicCall(); + uno::Reference< script::XLibraryContainer > xLibContainer = rDocSh.GetBasicContainer(); + DBG_ASSERT( xLibContainer.is(), "No BasicContainer!" ); + + uno::Reference< container::XNameContainer > xLib; + if( xLibContainer.is() ) + { + String aLibName( RTL_CONSTASCII_USTRINGPARAM( "Standard" ) ); + if ( rDocSh.GetBasicManager() && rDocSh.GetBasicManager()->GetName().Len() ) + aLibName = rDocSh.GetBasicManager()->GetName(); + uno::Any aLibAny = xLibContainer->getByName( aLibName ); + aLibAny >>= xLib; + } + if( xLib.is() ) + { + uno::Reference< script::XVBAModuleInfo > xVBAModuleInfo( xLib, uno::UNO_QUERY ); + if( xLib->hasByName( sModuleName ) ) + xLib->removeByName( sModuleName ); + if ( xVBAModuleInfo.is() ) + xVBAModuleInfo->removeModuleInfo( sModuleName ); + + } + SFX_APP()->LeaveBasicCall(); +} + BOOL ScDocFunc::InsertTable( SCTAB nTab, const String& rName, BOOL bRecord, BOOL bApi ) { @@ -2585,8 +2698,19 @@ BOOL ScDocFunc::InsertTable( SCTAB nTab, const String& rName, BOOL bRecord, BOOL ScDocShellModificator aModificator( rDocShell ); ScDocument* pDoc = rDocShell.GetDocument(); - if (bRecord && !pDoc->IsUndoEnabled()) + + + // Strange loop, also basic is loaded too early ( InsertTable ) + // is called via the xml import for sheets in described in odf + BOOL bInsertDocModule = false; + + if( !rDocShell.GetDocument()->IsImportingXML() ) + { + bInsertDocModule = pDoc ? pDoc->IsInVBAMode() : false; + } + if ( bInsertDocModule || ( bRecord && !pDoc->IsUndoEnabled() ) ) bRecord = FALSE; + if (bRecord) pDoc->BeginDrawUndo(); // InsertTab erzeugt ein SdrUndoNewPage @@ -2597,10 +2721,17 @@ BOOL ScDocFunc::InsertTable( SCTAB nTab, const String& rName, BOOL bRecord, BOOL if (pDoc->InsertTab( nTab, rName )) { + String sCodeName; if (bRecord) rDocShell.GetUndoManager()->AddUndoAction( new ScUndoInsertTab( &rDocShell, nTab, bAppend, rName)); // Views updaten: + // Only insert vba modules if vba mode ( and not currently importing XML ) + if( bInsertDocModule ) + { + String sSource; + VBA_InsertModule( *pDoc, nTab, sCodeName, sSource ); + } rDocShell.Broadcast( ScTablesHint( SC_TAB_INSERTED, nTab ) ); rDocShell.PostPaintExtras(); @@ -2622,8 +2753,11 @@ BOOL ScDocFunc::DeleteTable( SCTAB nTab, BOOL bRecord, BOOL /* bApi */ ) BOOL bSuccess = FALSE; ScDocument* pDoc = rDocShell.GetDocument(); + BOOL bVbaEnabled = pDoc ? pDoc->IsInVBAMode() : false; if (bRecord && !pDoc->IsUndoEnabled()) bRecord = FALSE; + if ( bVbaEnabled ) + bRecord = FALSE; BOOL bWasLinked = pDoc->IsLinked(nTab); ScDocument* pUndoDoc = NULL; ScRefUndoData* pUndoData = NULL; @@ -2657,6 +2791,8 @@ BOOL ScDocFunc::DeleteTable( SCTAB nTab, BOOL bRecord, BOOL /* bApi */ ) pUndoDoc->SetActiveScenario( nTab, bActive ); } pUndoDoc->SetVisible( nTab, pDoc->IsVisible( nTab ) ); + pUndoDoc->SetTabBgColor( nTab, pDoc->GetTabBgColor(nTab) ); + pUndoDoc->SetSheetEvents( nTab, pDoc->GetSheetEvents( nTab ) ); // Drawing-Layer muss sein Undo selbst in der Hand behalten !!! pDoc->BeginDrawUndo(); // DeleteTab erzeugt ein SdrUndoDelPage @@ -2664,6 +2800,8 @@ BOOL ScDocFunc::DeleteTable( SCTAB nTab, BOOL bRecord, BOOL /* bApi */ ) pUndoData = new ScRefUndoData( pDoc ); } + String sCodeName; + BOOL bHasCodeName = pDoc->GetCodeName( nTab, sCodeName ); if (pDoc->DeleteTab( nTab, pUndoDoc )) { if (bRecord) @@ -2674,6 +2812,13 @@ BOOL ScDocFunc::DeleteTable( SCTAB nTab, BOOL bRecord, BOOL /* bApi */ ) new ScUndoDeleteTab( &rDocShell, theTabs, pUndoDoc, pUndoData )); } // Views updaten: + if( bVbaEnabled ) + { + if( bHasCodeName ) + { + VBA_DeleteModule( rDocShell, sCodeName ); + } + } rDocShell.Broadcast( ScTablesHint( SC_TAB_DELETED, nTab ) ); if (bWasLinked) @@ -2852,6 +2997,104 @@ BOOL ScDocFunc::RenameTable( SCTAB nTab, const String& rName, BOOL bRecord, BOOL return bSuccess; } +bool ScDocFunc::SetTabBgColor( SCTAB nTab, const Color& rColor, bool bRecord, bool bApi ) +{ + + ScDocument* pDoc = rDocShell.GetDocument(); + if (bRecord && !pDoc->IsUndoEnabled()) + bRecord = false; + if ( !pDoc->IsDocEditable() || pDoc->IsTabProtected(nTab) ) + { + if (!bApi) + rDocShell.ErrorMessage(STR_PROTECTIONERR); //TODO Check to see what this string is... + return false; + } + + Color aOldTabBgColor; + aOldTabBgColor = pDoc->GetTabBgColor(nTab); + + bool bSuccess = false; + pDoc->SetTabBgColor(nTab, rColor); + if ( pDoc->GetTabBgColor(nTab) == rColor) + bSuccess = true; + if (bSuccess) + { + if (bRecord) + { + rDocShell.GetUndoManager()->AddUndoAction( + new ScUndoTabColor( &rDocShell, nTab, aOldTabBgColor, rColor)); + } + rDocShell.PostPaintExtras(); + ScDocShellModificator aModificator( rDocShell ); + aModificator.SetDocumentModified(); + SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) ); + + bSuccess = true; + } + return bSuccess; +} + +bool ScDocFunc::SetTabBgColor( + ScUndoTabColorInfo::List& rUndoTabColorList, bool bRecord, bool bApi ) +{ + ScDocument* pDoc = rDocShell.GetDocument(); + if (bRecord && !pDoc->IsUndoEnabled()) + bRecord = false; + + if ( !pDoc->IsDocEditable() ) + { + if (!bApi) + rDocShell.ErrorMessage(STR_PROTECTIONERR); //TODO Get a better String Error... + return false; + } + + USHORT nTab; + Color aNewTabBgColor; + bool bSuccess = true; + size_t nTabProtectCount = 0; + size_t nTabListCount = rUndoTabColorList.size(); + for ( size_t i = 0; i < nTabListCount; ++i ) + { + ScUndoTabColorInfo& rInfo = rUndoTabColorList[i]; + nTab = rInfo.mnTabId; + if ( !pDoc->IsTabProtected(nTab) ) + { + aNewTabBgColor = rInfo.maNewTabBgColor; + rInfo.maOldTabBgColor = pDoc->GetTabBgColor(nTab); + pDoc->SetTabBgColor(nTab, aNewTabBgColor); + if ( pDoc->GetTabBgColor(nTab) != aNewTabBgColor) + { + bSuccess = false; + break; + } + } + else + { + nTabProtectCount++; + } + } + + if ( nTabProtectCount == nTabListCount ) + { + if (!bApi) + rDocShell.ErrorMessage(STR_PROTECTIONERR); //TODO Get a better String Error... + return false; + } + + if (bSuccess) + { + if (bRecord) + { + rDocShell.GetUndoManager()->AddUndoAction( + new ScUndoTabColor( &rDocShell, rUndoTabColorList)); + } + rDocShell.PostPaintExtras(); + ScDocShellModificator aModificator( rDocShell ); + aModificator.SetDocumentModified(); + } + return bSuccess; +} + //------------------------------------------------------------------------ //! SetWidthOrHeight - noch doppelt zu ViewFunc !!!!!! @@ -2954,7 +3197,9 @@ BOOL ScDocFunc::SetWidthOrHeight( BOOL bWidth, SCCOLROW nRangeCnt, SCCOLROW* pRa for (SCROW nRow=nStartNo; nRow<=nEndNo; nRow++) { BYTE nOld = pDoc->GetRowFlags(nRow,nTab); - if ( (nOld & CR_HIDDEN) == 0 && ( nOld & CR_MANUALSIZE ) ) + SCROW nLastRow = -1; + bool bHidden = pDoc->RowHidden(nRow, nTab, nLastRow); + if ( !bHidden && ( nOld & CR_MANUALSIZE ) ) pDoc->SetRowFlags( nRow, nTab, nOld & ~CR_MANUALSIZE ); } } @@ -2989,8 +3234,8 @@ BOOL ScDocFunc::SetWidthOrHeight( BOOL bWidth, SCCOLROW nRangeCnt, SCCOLROW* pRa { for (SCCOL nCol=static_cast<SCCOL>(nStartNo); nCol<=static_cast<SCCOL>(nEndNo); nCol++) { - if ( eMode != SC_SIZE_VISOPT || - (pDoc->GetColFlags( nCol, nTab ) & CR_HIDDEN) == 0 ) + SCCOL nLastCol = -1; + if ( eMode != SC_SIZE_VISOPT || !pDoc->ColHidden(nCol, nTab, nLastCol) ) { USHORT nThisSize = nSizeTwips; @@ -3060,20 +3305,22 @@ BOOL ScDocFunc::InsertPageBreak( BOOL bColumn, const ScAddress& rPos, if (nPos == 0) return FALSE; // erste Spalte / Zeile - BYTE nFlags = bColumn ? pDoc->GetColFlags( static_cast<SCCOL>(nPos), nTab ) - : pDoc->GetRowFlags( static_cast<SCROW>(nPos), nTab ); - if (nFlags & CR_MANUALBREAK) - return TRUE; // Umbruch schon gesetzt + ScBreakType nBreak = bColumn ? + pDoc->HasColBreak(static_cast<SCCOL>(nPos), nTab) : + pDoc->HasRowBreak(static_cast<SCROW>(nPos), nTab); + if (nBreak & BREAK_MANUAL) + return true; if (bRecord) rDocShell.GetUndoManager()->AddUndoAction( new ScUndoPageBreak( &rDocShell, rPos.Col(), rPos.Row(), nTab, bColumn, TRUE ) ); - nFlags |= CR_MANUALBREAK; if (bColumn) - pDoc->SetColFlags( static_cast<SCCOL>(nPos), nTab, nFlags ); + pDoc->SetColBreak(static_cast<SCCOL>(nPos), nTab, false, true); else - pDoc->SetRowFlags( static_cast<SCROW>(nPos), nTab, nFlags ); + pDoc->SetRowBreak(static_cast<SCROW>(nPos), nTab, false, true); + + pDoc->InvalidatePageBreaks(nTab); pDoc->UpdatePageBreaks( nTab ); if (pDoc->IsStreamValid(nTab)) @@ -3119,20 +3366,25 @@ BOOL ScDocFunc::RemovePageBreak( BOOL bColumn, const ScAddress& rPos, SCCOLROW nPos = bColumn ? static_cast<SCCOLROW>(rPos.Col()) : static_cast<SCCOLROW>(rPos.Row()); - BYTE nFlags = bColumn ? pDoc->GetColFlags( static_cast<SCCOL>(nPos), nTab ) - : pDoc->GetRowFlags( static_cast<SCROW>(nPos), nTab ); - if ((nFlags & CR_MANUALBREAK)==0) - return FALSE; // kein Umbruch gesetzt + + ScBreakType nBreak; + if (bColumn) + nBreak = pDoc->HasColBreak(static_cast<SCCOL>(nPos), nTab); + else + nBreak = pDoc->HasRowBreak(static_cast<SCROW>(nPos), nTab); + if ((nBreak & BREAK_MANUAL) == 0) + // There is no manual break. + return false; if (bRecord) rDocShell.GetUndoManager()->AddUndoAction( new ScUndoPageBreak( &rDocShell, rPos.Col(), rPos.Row(), nTab, bColumn, FALSE ) ); - nFlags &= ~CR_MANUALBREAK; if (bColumn) - pDoc->SetColFlags( static_cast<SCCOL>(nPos), nTab, nFlags ); + pDoc->RemoveColBreak(static_cast<SCCOL>(nPos), nTab, false, true); else - pDoc->SetRowFlags( static_cast<SCROW>(nPos), nTab, nFlags ); + pDoc->RemoveRowBreak(static_cast<SCROW>(nPos), nTab, false, true); + pDoc->UpdatePageBreaks( nTab ); if (pDoc->IsStreamValid(nTab)) diff --git a/sc/source/ui/docshell/docsh.cxx b/sc/source/ui/docshell/docsh.cxx index 135bbcdace49..a446c86b4d1b 100644..100755 --- a/sc/source/ui/docshell/docsh.cxx +++ b/sc/source/ui/docshell/docsh.cxx @@ -49,6 +49,7 @@ #include <svtools/ctrltool.hxx> #include <svtools/sfxecode.hxx> #include <svl/zforlist.hxx> +#include <svl/PasswordHelper.hxx> #include <sfx2/app.hxx> #include <sfx2/bindings.hxx> #include <sfx2/dinfdlg.hxx> @@ -68,6 +69,9 @@ #include "chgviset.hxx" #include <sfx2/request.hxx> #include <com/sun/star/document/UpdateDocMode.hpp> +#include <com/sun/star/container/XContentEnumerationAccess.hpp> +#include <com/sun/star/sheet/XSpreadsheetView.hpp> +#include <com/sun/star/task/XJob.hpp> #include "scabstdlg.hxx" //CHINA001 @@ -351,6 +355,20 @@ void ScDocShell::AfterXMLLoading(sal_Bool bRet) // else; nothing has to happen, because it is a user given name } } + + // #i94570# DataPilot table names have to be unique, or the tables can't be accessed by API. + // If no name (or an invalid name, skipped in ScXMLDataPilotTableContext::EndElement) was set, create a new name. + ScDPCollection* pDPCollection = aDocument.GetDPCollection(); + if ( pDPCollection ) + { + USHORT nDPCount = pDPCollection->GetCount(); + for (USHORT nDP=0; nDP<nDPCount; nDP++) + { + ScDPObject* pDPObj = (*pDPCollection)[nDP]; + if ( !pDPObj->GetName().Len() ) + pDPObj->SetName( pDPCollection->CreateNewName() ); + } + } } ScColumn::bDoubleAlloc = sal_False; } @@ -457,7 +475,7 @@ BOOL __EXPORT ScDocShell::Load( SfxMedium& rMedium ) // only the latin script language is loaded // -> initialize the others from options (before loading) - InitOptions(); + InitOptions(true); GetUndoManager()->Clear(); @@ -581,6 +599,46 @@ void __EXPORT ScDocShell::Notify( SfxBroadcaster&, const SfxHint& rHint ) } } } + + try + { + uno::Reference< uno::XComponentContext > xContext; + uno::Reference< lang::XMultiServiceFactory > xServiceManager = ::comphelper::getProcessServiceFactory(); + uno::Reference< beans::XPropertySet > xProp( xServiceManager, uno::UNO_QUERY_THROW ); + xProp->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ) ) ) >>= xContext; + if ( xContext.is() ) + { + uno::Reference< container::XContentEnumerationAccess > xEnumAccess( xServiceManager, uno::UNO_QUERY_THROW ); + uno::Reference< container::XEnumeration> xEnum = xEnumAccess->createContentEnumeration( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sheet.SpreadsheetDocumentJob" ) ) ); + if ( xEnum.is() ) + { + while ( xEnum->hasMoreElements() ) + { + uno::Any aAny = xEnum->nextElement(); + uno::Reference< lang::XSingleComponentFactory > xFactory; + aAny >>= xFactory; + if ( xFactory.is() ) + { + uno::Reference< task::XJob > xJob( xFactory->createInstanceWithContext( xContext ), uno::UNO_QUERY_THROW ); + uno::Sequence< beans::NamedValue > aArgsForJob(1); + ScViewData* pViewData = GetViewData(); + SfxViewShell* pViewShell = ( pViewData ? pViewData->GetViewShell() : NULL ); + SfxViewFrame* pViewFrame = ( pViewShell ? pViewShell->GetViewFrame() : NULL ); + SfxFrame* pFrame = ( pViewFrame ? &pViewFrame->GetFrame() : NULL ); + uno::Reference< frame::XController > xController = ( pFrame ? pFrame->GetController() : 0 ); + uno::Reference< sheet::XSpreadsheetView > xSpreadsheetView( xController, uno::UNO_QUERY_THROW ); + aArgsForJob[0] = beans::NamedValue( ::rtl::OUString::createFromAscii( "SpreadsheetView" ), + uno::makeAny( xSpreadsheetView ) ); + xJob->execute( aArgsForJob ); + } + } + } + } + } + catch ( uno::Exception & ) + { + } } break; case SFX_EVENT_SAVEDOC: @@ -867,10 +925,33 @@ static void lcl_parseHtmlFilterOption(const OUString& rOption, LanguageType& rLa rDateConvert = static_cast<bool>(aTokens[1].toInt32()); } +namespace { + +class LoadMediumGuard +{ +public: + explicit LoadMediumGuard(ScDocument* pDoc) : + mpDoc(pDoc) + { + mpDoc->SetLoadingMedium(true); + } + + ~LoadMediumGuard() + { + mpDoc->SetLoadingMedium(false); + } +private: + ScDocument* mpDoc; +}; + +} + BOOL __EXPORT ScDocShell::ConvertFrom( SfxMedium& rMedium ) { RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScDocShell::ConvertFrom" ); + LoadMediumGuard aLoadGuard(&aDocument); + BOOL bRet = FALSE; // FALSE heisst Benutzerabbruch !! // bei Fehler: Fehler am Stream setzen!! @@ -1937,7 +2018,7 @@ BOOL __EXPORT ScDocShell::ConvertTo( SfxMedium &rMed ) /* #115980# #i104990# If the imported document contains a medium password, determine if we can save it, otherwise ask the users whether they want to save without it. */ - if( !::sfx2::CheckMSPasswordCapabilityForExport( aFltName ) ) + if( (rMed.GetFilter()->GetFilterFlags() & SFX_FILTER_ENCRYPTION) == 0 ) { SfxItemSet* pItemSet = rMed.GetItemSet(); const SfxPoolItem* pItem = 0; @@ -2652,3 +2733,97 @@ sal_Bool ScDocShell::AcceptStateUpdate() const return sal_False; } //-->Added by PengYunQuan for Validity Cell Range Picker + + +bool ScDocShell::IsChangeRecording() const +{ + ScChangeTrack* pChangeTrack = aDocument.GetChangeTrack(); + return pChangeTrack != NULL; +} + + +bool ScDocShell::HasChangeRecordProtection() const +{ + bool bRes = false; + ScChangeTrack* pChangeTrack = aDocument.GetChangeTrack(); + if (pChangeTrack) + bRes = pChangeTrack->IsProtected(); + return bRes; +} + + +void ScDocShell::SetChangeRecording( bool bActivate ) +{ + bool bOldChangeRecording = IsChangeRecording(); + + if (bActivate) + { + aDocument.StartChangeTracking(); + ScChangeViewSettings aChangeViewSet; + aChangeViewSet.SetShowChanges(TRUE); + aDocument.SetChangeViewSettings(aChangeViewSet); + } + else + { + aDocument.EndChangeTracking(); + PostPaintGridAll(); + } + + if (bOldChangeRecording != IsChangeRecording()) + { + UpdateAcceptChangesDialog(); + // Slots invalidieren + SfxBindings* pBindings = GetViewBindings(); + if (pBindings) + pBindings->InvalidateAll(FALSE); + } +} + + +bool ScDocShell::SetProtectionPassword( const String &rNewPassword ) +{ + bool bRes = false; + ScChangeTrack* pChangeTrack = aDocument.GetChangeTrack(); + if (pChangeTrack) + { + sal_Bool bProtected = pChangeTrack->IsProtected(); + + if (rNewPassword.Len()) + { + // when password protection is applied change tracking must always be active + SetChangeRecording( true ); + + ::com::sun::star::uno::Sequence< sal_Int8 > aProtectionHash; + SvPasswordHelper::GetHashPassword( aProtectionHash, rNewPassword ); + pChangeTrack->SetProtection( aProtectionHash ); + } + else + { + pChangeTrack->SetProtection( ::com::sun::star::uno::Sequence< sal_Int8 >() ); + } + bRes = true; + + if ( bProtected != pChangeTrack->IsProtected() ) + { + UpdateAcceptChangesDialog(); + SetDocumentModified(); + } + } + + return bRes; +} + + +bool ScDocShell::GetProtectionHash( /*out*/ ::com::sun::star::uno::Sequence< sal_Int8 > &rPasswordHash ) +{ + bool bRes = false; + ScChangeTrack* pChangeTrack = aDocument.GetChangeTrack(); + if (pChangeTrack && pChangeTrack->IsProtected()) + { + rPasswordHash = pChangeTrack->GetProtection(); + bRes = true; + } + return bRes; +} + + diff --git a/sc/source/ui/docshell/docsh2.cxx b/sc/source/ui/docshell/docsh2.cxx index 9e3ed217382f..14ff7622818c 100644 --- a/sc/source/ui/docshell/docsh2.cxx +++ b/sc/source/ui/docshell/docsh2.cxx @@ -93,7 +93,7 @@ BOOL __EXPORT ScDocShell::InitNew( const uno::Reference < embed::XStorage >& xSt aDocument.SetDrawDefaults(); // drawing layer defaults that are set only in InitNew // InitOptions sets the document languages, must be called before CreateStandardStyles - InitOptions(); + InitOptions(false); aDocument.GetStyleSheetPool()->CreateStandardStyles(); aDocument.UpdStlShtPtrsFrmNms(); diff --git a/sc/source/ui/docshell/docsh3.cxx b/sc/source/ui/docshell/docsh3.cxx index 4709a065792f..233843935bbd 100644 --- a/sc/source/ui/docshell/docsh3.cxx +++ b/sc/source/ui/docshell/docsh3.cxx @@ -424,7 +424,7 @@ double ScDocShell::GetOutputFactor() const //--------------------------------------------------------------------- -void ScDocShell::InitOptions() // Fortsetzung von InitNew (CLOOKs) +void ScDocShell::InitOptions(bool bForLoading) // called from InitNew and Load { // Einstellungen aus dem SpellCheckCfg kommen in Doc- und ViewOptions @@ -440,6 +440,14 @@ void ScDocShell::InitOptions() // Fortsetzung von InitNew (CLOOKs) // zweistellige Jahreszahleneingabe aus Extras->Optionen->Allgemein->Sonstiges aDocOpt.SetYear2000( sal::static_int_cast<USHORT>( ::utl::MiscCfg().GetYear2000() ) ); + if (bForLoading) + { + // #i112123# No style:decimal-places attribute means automatic decimals, not the configured default, + // so it must not be taken from the global options. + // Calculation settings are handled separately in ScXMLBodyContext::EndElement. + aDocOpt.SetStdPrecision( SvNumberFormatter::UNLIMITED_PRECISION ); + } + aDocument.SetDocOptions( aDocOpt ); aDocument.SetViewOptions( aViewOpt ); diff --git a/sc/source/ui/docshell/docsh4.cxx b/sc/source/ui/docshell/docsh4.cxx index 3ab0cc62bdd2..d335865fc435 100644..100755 --- a/sc/source/ui/docshell/docsh4.cxx +++ b/sc/source/ui/docshell/docsh4.cxx @@ -66,6 +66,7 @@ using namespace ::com::sun::star; #include <svx/svditer.hxx> #include <svx/svdpage.hxx> #include <svx/fmshell.hxx> +#include <svtools/xwindowitem.hxx> #include <sfx2/passwd.hxx> #include <sfx2/filedlghelper.hxx> #include <sfx2/docinsert.hxx> @@ -120,9 +121,9 @@ using namespace ::com::sun::star; #include "scresid.hxx" //add by CHINA001 #include "scabstdlg.hxx" //CHINA001 #include "externalrefmgr.hxx" - #include "sharedocdlg.hxx" #include "conditio.hxx" +#include "sheetevents.hxx" //------------------------------------------------------------------ @@ -623,8 +624,8 @@ void ScDocShell::Execute( SfxRequest& rReq ) // getting real parent window when called from Security-Options TP Window* pParent = NULL; const SfxPoolItem* pParentItem; - if( pReqArgs && SFX_ITEM_SET == pReqArgs->GetItemState( SID_ATTR_PARENTWINDOW, FALSE, &pParentItem ) ) - pParent = ( Window* ) ( ( const OfaPtrItem* ) pParentItem )->GetValue(); + if( pReqArgs && SFX_ITEM_SET == pReqArgs->GetItemState( SID_ATTR_XWINDOW, FALSE, &pParentItem ) ) + pParent = ( ( const XWindowItem* ) pParentItem )->GetWindowPtr(); // desired state ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack(); @@ -664,17 +665,7 @@ void ScDocShell::Execute( SfxRequest& rReq ) if ( bDo ) { - // update "accept changes" dialog - //! notify all views - SfxViewFrame* pViewFrm = SfxViewFrame::Current(); - if ( pViewFrm && pViewFrm->HasChildWindow(FID_CHG_ACCEPT) ) - { - SfxChildWindow* pChild = pViewFrm->GetChildWindow(FID_CHG_ACCEPT); - if (pChild) - { - ((ScAcceptChgDlgWrapper*)pChild)->ReInitDlg(); - } - } + UpdateAcceptChangesDialog(); // Slots invalidieren if (pBindings) @@ -693,8 +684,8 @@ void ScDocShell::Execute( SfxRequest& rReq ) { Window* pParent = NULL; const SfxPoolItem* pParentItem; - if( pReqArgs && SFX_ITEM_SET == pReqArgs->GetItemState( SID_ATTR_PARENTWINDOW, FALSE, &pParentItem ) ) - pParent = ( Window* ) ( ( const OfaPtrItem* ) pParentItem )->GetValue(); + if( pReqArgs && SFX_ITEM_SET == pReqArgs->GetItemState( SID_ATTR_XWINDOW, FALSE, &pParentItem ) ) + pParent = ( ( const XWindowItem* ) pParentItem )->GetWindowPtr(); if ( ExecuteChangeProtectionDialog( pParent ) ) { rReq.Done(); @@ -1164,6 +1155,21 @@ void ScDocShell::Execute( SfxRequest& rReq ) //------------------------------------------------------------------ +void UpdateAcceptChangesDialog() +{ + // update "accept changes" dialog + //! notify all views + SfxViewFrame* pViewFrm = SfxViewFrame::Current(); + if ( pViewFrm && pViewFrm->HasChildWindow( FID_CHG_ACCEPT ) ) + { + SfxChildWindow* pChild = pViewFrm->GetChildWindow( FID_CHG_ACCEPT ); + if ( pChild ) + ((ScAcceptChgDlgWrapper*)pChild)->ReInitDlg(); + } +} + +//------------------------------------------------------------------ + BOOL ScDocShell::ExecuteChangeProtectionDialog( Window* _pParent, BOOL bJustQueryIfProtected ) { BOOL bDone = FALSE; @@ -1217,15 +1223,7 @@ BOOL ScDocShell::ExecuteChangeProtectionDialog( Window* _pParent, BOOL bJustQuer } if ( bProtected != pChangeTrack->IsProtected() ) { - // update "accept changes" dialog - //! notify all views - SfxViewFrame* pViewFrm = SfxViewFrame::Current(); - if ( pViewFrm && pViewFrm->HasChildWindow( FID_CHG_ACCEPT ) ) - { - SfxChildWindow* pChild = pViewFrm->GetChildWindow( FID_CHG_ACCEPT ); - if ( pChild ) - ((ScAcceptChgDlgWrapper*)pChild)->ReInitDlg(); - } + UpdateAcceptChangesDialog(); bDone = TRUE; } } @@ -1291,6 +1289,14 @@ void ScDocShell::DoHardRecalc( BOOL /* bApi */ ) if ( pSh ) pSh->UpdateCharts(TRUE); + // set notification flags for "calculate" event (used in SFX_HINT_DATACHANGED broadcast) + // (might check for the presence of any formulas on each sheet) + SCTAB nTabCount = aDocument.GetTableCount(); + SCTAB nTab; + if (aDocument.HasSheetEventScript( SC_SHEETEVENT_CALCULATE )) + for (nTab=0; nTab<nTabCount; nTab++) + aDocument.SetCalcNotification(nTab); + // CalcAll doesn't broadcast value changes, so SC_HINT_CALCALL is broadcasted globally // in addition to SFX_HINT_DATACHANGED. aDocument.BroadcastUno( SfxSimpleHint( SC_HINT_CALCALL ) ); @@ -1298,8 +1304,7 @@ void ScDocShell::DoHardRecalc( BOOL /* bApi */ ) // use hard recalc also to disable stream-copying of all sheets // (somewhat consistent with charts) - SCTAB nTabCount = aDocument.GetTableCount(); - for (SCTAB nTab=0; nTab<nTabCount; nTab++) + for (nTab=0; nTab<nTabCount; nTab++) if (aDocument.IsStreamValid(nTab)) aDocument.SetStreamValid(nTab, FALSE); @@ -1484,12 +1489,12 @@ BOOL ScDocShell::AdjustPrintZoom( const ScRange& rRange ) SCROW nEndRow = rRange.aEnd.Row(); if ( pRepeatRow && nStartRow >= pRepeatRow->aStart.Row() ) { - nBlkTwipsY += aDocument.FastGetRowHeight( pRepeatRow->aStart.Row(), + nBlkTwipsY += aDocument.GetRowHeight( pRepeatRow->aStart.Row(), pRepeatRow->aEnd.Row(), nTab ); if ( nStartRow <= pRepeatRow->aEnd.Row() ) nStartRow = pRepeatRow->aEnd.Row() + 1; } - nBlkTwipsY += aDocument.FastGetRowHeight( nStartRow, nEndRow, nTab ); + nBlkTwipsY += aDocument.GetRowHeight( nStartRow, nEndRow, nTab ); Size aPhysPage; long nHdr, nFtr; diff --git a/sc/source/ui/docshell/docsh5.cxx b/sc/source/ui/docshell/docsh5.cxx index 061ece5efc90..84979e3dbcdf 100644 --- a/sc/source/ui/docshell/docsh5.cxx +++ b/sc/source/ui/docshell/docsh5.cxx @@ -65,6 +65,11 @@ #include "sc.hrc" #include "waitoff.hxx" #include "sizedev.hxx" +#include <basic/sbstar.hxx> +#include <basic/basmgr.hxx> + +// defined in docfunc.cxx +void VBA_InsertModule( ScDocument& rDoc, SCTAB nTab, String& sModuleName, String& sModuleSource ); // --------------------------------------------------------------------------- @@ -866,6 +871,8 @@ BOOL ScDocShell::MoveTable( SCTAB nSrcTab, SCTAB nDestTab, BOOL bCopy, BOOL bRec if (bRecord) aDocument.BeginDrawUndo(); // drawing layer must do its own undo actions + String sSrcCodeName; + aDocument.GetCodeName( nSrcTab, sSrcCodeName ); if (!aDocument.CopyTab( nSrcTab, nDestTab )) { //! EndDrawUndo? @@ -889,8 +896,38 @@ BOOL ScDocShell::MoveTable( SCTAB nSrcTab, SCTAB nDestTab, BOOL bCopy, BOOL bRec GetUndoManager()->AddUndoAction( new ScUndoCopyTab( this, aSrcList, aDestList ) ); } - } + BOOL bVbaEnabled = aDocument.IsInVBAMode(); + if ( bVbaEnabled ) + { + StarBASIC* pStarBASIC = GetBasic(); + String aLibName( RTL_CONSTASCII_USTRINGPARAM( "Standard" ) ); + if ( GetBasicManager()->GetName().Len() > 0 ) + { + aLibName = GetBasicManager()->GetName(); + pStarBASIC = GetBasicManager()->GetLib( aLibName ); + } + SCTAB nTabToUse = nDestTab; + if ( nDestTab == SC_TAB_APPEND ) + nTabToUse = aDocument.GetMaxTableNumber() - 1; + String sCodeName; + String sSource; + com::sun::star::uno::Reference< com::sun::star::script::XLibraryContainer > xLibContainer = GetBasicContainer(); + com::sun::star::uno::Reference< com::sun::star::container::XNameContainer > xLib; + if( xLibContainer.is() ) + { + com::sun::star::uno::Any aLibAny = xLibContainer->getByName( aLibName ); + aLibAny >>= xLib; + } + if( xLib.is() ) + { + rtl::OUString sRTLSource; + xLib->getByName( sSrcCodeName ) >>= sRTLSource; + sSource = sRTLSource; + } + VBA_InsertModule( aDocument, nTabToUse, sCodeName, sSource ); + } + } Broadcast( ScTablesHint( SC_TAB_COPIED, nSrcTab, nDestTab ) ); } else diff --git a/sc/source/ui/docshell/docsh8.cxx b/sc/source/ui/docshell/docsh8.cxx index b761dd75d9df..cb9d625da70c 100644 --- a/sc/source/ui/docshell/docsh8.cxx +++ b/sc/source/ui/docshell/docsh8.cxx @@ -597,7 +597,7 @@ void lcl_GetColumnTypes( ScDocShell& rDocShell, else if ( nDbType == sdbc::DataType::DECIMAL ) { // maximale Feldbreite und Nachkommastellen bestimmen xub_StrLen nLen; - USHORT nPrec; + sal_uInt16 nPrec; nLen = pDoc->GetMaxNumberStringLen( nPrec, nTab, nCol, nFirstDataRow, nLastRow ); // dBaseIII Limit Nachkommastellen: 15 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/docshell/impex.cxx b/sc/source/ui/docshell/impex.cxx index 46b6b7af3a63..a17279f409a9 100644 --- a/sc/source/ui/docshell/impex.cxx +++ b/sc/source/ui/docshell/impex.cxx @@ -1441,7 +1441,7 @@ BOOL ScImportExport::Doc2Text( SvStream& rStrm ) for (nRow = nStartRow; nRow <= nEndRow; nRow++) { - if (bIncludeFiltered || !pDoc->IsFiltered( nRow, aRange.aStart.Tab() )) + if (bIncludeFiltered || !pDoc->RowFiltered( nRow, aRange.aStart.Tab() )) { for (nCol = nStartCol; nCol <= nEndCol; nCol++) { diff --git a/sc/source/ui/docshell/olinefun.cxx b/sc/source/ui/docshell/olinefun.cxx index 2f42c77ed5f4..822c74800ab2 100644 --- a/sc/source/ui/docshell/olinefun.cxx +++ b/sc/source/ui/docshell/olinefun.cxx @@ -420,7 +420,7 @@ BOOL ScOutlineDocFunc::SelectLevel( SCTAB nTab, BOOL bColumns, USHORT nLevel, if ( bColumns ) pDoc->ShowCol( static_cast<SCCOL>(i), nTab, bShow ); else - if ( !bShow || !pDoc->IsFiltered( i,nTab ) ) + if ( !bShow || !pDoc->RowFiltered( i,nTab ) ) pDoc->ShowRow( i, nTab, bShow ); } } @@ -518,7 +518,7 @@ BOOL ScOutlineDocFunc::ShowMarkedOutlines( const ScRange& rRange, BOOL bRecord, } } for ( i=nMin; i<=nMax; i++ ) - if ( !pDoc->IsFiltered( i,nTab ) ) // weggefilterte nicht einblenden + if ( !pDoc->RowFiltered( i,nTab ) ) // weggefilterte nicht einblenden pDoc->ShowRow( i, nTab, TRUE ); pDoc->UpdatePageBreaks( nTab ); @@ -678,7 +678,7 @@ BOOL ScOutlineDocFunc::ShowOutline( SCTAB nTab, BOOL bColumns, USHORT nLevel, US if ( bColumns ) pDoc->ShowCol( static_cast<SCCOL>(i), nTab, TRUE ); else - if ( !pDoc->IsFiltered( i,nTab ) ) // weggefilterte nicht einblenden + if ( !pDoc->RowFiltered( i,nTab ) ) // weggefilterte nicht einblenden pDoc->ShowRow( i, nTab, TRUE ); } @@ -701,6 +701,7 @@ BOOL ScOutlineDocFunc::ShowOutline( SCTAB nTab, BOOL bColumns, USHORT nLevel, US pArray->SetVisibleBelow( nLevel, nEntry, TRUE, TRUE ); + pDoc->InvalidatePageBreaks(nTab); pDoc->UpdatePageBreaks( nTab ); if (bPaint) @@ -766,6 +767,7 @@ BOOL ScOutlineDocFunc::HideOutline( SCTAB nTab, BOOL bColumns, USHORT nLevel, US pArray->SetVisibleBelow( nLevel, nEntry, FALSE ); + pDoc->InvalidatePageBreaks(nTab); pDoc->UpdatePageBreaks( nTab ); if (bPaint) diff --git a/sc/source/ui/docshell/tablink.cxx b/sc/source/ui/docshell/tablink.cxx index 4d18f9f18c37..697b39052b9f 100644 --- a/sc/source/ui/docshell/tablink.cxx +++ b/sc/source/ui/docshell/tablink.cxx @@ -485,6 +485,11 @@ BOOL ScDocumentLoader::GetFilterName( const String& rFileName, pDocSh = SfxObjectShell::GetNext( *pDocSh, &aScType ); } + INetURLObject aUrl( rFileName ); + INetProtocol eProt = aUrl.GetProtocol(); + if ( eProt == INET_PROT_NOT_VALID ) // invalid URL? + return FALSE; // abort without creating a medium + // Filter-Detection const SfxFilter* pSfxFilter = NULL; diff --git a/sc/source/ui/drawfunc/drformsh.src b/sc/source/ui/drawfunc/drformsh.src index a00665b58189..3fc8699c9dbf 100644 --- a/sc/source/ui/drawfunc/drformsh.src +++ b/sc/source/ui/drawfunc/drformsh.src @@ -117,12 +117,14 @@ {\ MenuItem\ {\ + RadioCheck = TRUE ; \ Identifier = SID_ANCHOR_PAGE ; \ HelpId = CMD_SID_ANCHOR_PAGE ; \ Text [ en-US ] = "To P~age" ; \ };\ MenuItem\ {\ + RadioCheck = TRUE ; \ Identifier = SID_ANCHOR_CELL ; \ HelpId = CMD_SID_ANCHOR_CELL ; \ Text [ en-US ] = "To ~Cell" ; \ 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/drawfunc/objdraw.src b/sc/source/ui/drawfunc/objdraw.src index 4eda5beca4c3..4b417b28e59b 100644 --- a/sc/source/ui/drawfunc/objdraw.src +++ b/sc/source/ui/drawfunc/objdraw.src @@ -339,6 +339,7 @@ {\ MenuItem\ {\ + RadioCheck = TRUE ; \ Identifier = SID_ANCHOR_PAGE ; \ HelpId = CMD_SID_ANCHOR_PAGE ; \ Text [ en-US ] = "To P~age" ; \ @@ -346,6 +347,7 @@ };\ MenuItem\ {\ + RadioCheck = TRUE ; \ Identifier = SID_ANCHOR_CELL ; \ HelpId = CMD_SID_ANCHOR_CELL ; \ Text [ en-US ] = "To ~Cell" ; \ diff --git a/sc/source/ui/inc/AccessibleContextBase.hxx b/sc/source/ui/inc/AccessibleContextBase.hxx index 191f56c22d3d..ecfeff96af39 100644 --- a/sc/source/ui/inc/AccessibleContextBase.hxx +++ b/sc/source/ui/inc/AccessibleContextBase.hxx @@ -316,8 +316,6 @@ protected: /// Use this method to set initial Description without notification void SetDescription(const rtl::OUString& rDesc) { msDescription = rDesc; } - void SetRole(sal_Int16 nRole); - /// Reference to the parent object. ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible> mxParent; diff --git a/sc/source/ui/inc/docfunc.hxx b/sc/source/ui/inc/docfunc.hxx index df4ff685816f..c92cc082986d 100644 --- a/sc/source/ui/inc/docfunc.hxx +++ b/sc/source/ui/inc/docfunc.hxx @@ -31,6 +31,7 @@ #include <tools/link.hxx> #include "global.hxx" #include "formula/grammar.hxx" +#include "tabbgcolor.hxx" class ScEditEngineDefaulter; class SdrUndoAction; @@ -117,6 +118,9 @@ public: BOOL RenameTable( SCTAB nTab, const String& rName, BOOL bRecord, BOOL bApi ); BOOL DeleteTable( SCTAB nTab, BOOL bRecord, BOOL bApi ); + bool SetTabBgColor( SCTAB nTab, const Color& rColor, bool bRecord, bool bApi ); + bool SetTabBgColor( ScUndoTabColorInfo::List& rUndoTabColorList, bool bRecord, bool bApi ); + BOOL SetTableVisible( SCTAB nTab, BOOL bVisible, BOOL bApi ); BOOL SetLayoutRTL( SCTAB nTab, BOOL bRTL, BOOL bApi ); diff --git a/sc/source/ui/inc/docsh.hxx b/sc/source/ui/inc/docsh.hxx index 09d34c661995..5b4fc6227225 100644..100755 --- a/sc/source/ui/inc/docsh.hxx +++ b/sc/source/ui/inc/docsh.hxx @@ -125,7 +125,7 @@ class SC_DLLPUBLIC ScDocShell: public SfxObjectShell, public SfxListener SC_DLLPRIVATE void InitItems(); SC_DLLPRIVATE void DoEnterHandler(); - SC_DLLPRIVATE void InitOptions(); + SC_DLLPRIVATE void InitOptions(bool bForLoading); SC_DLLPRIVATE void ResetDrawObjectShell(); // SUNWS needs a forward declared friend, otherwise types and members @@ -418,8 +418,20 @@ public: sal_Bool AcceptStateUpdate() const; //-->Added by PengYunQuan for Validity Cell Range Picker ScSheetSaveData* GetSheetSaveData(); + + // passwword protection for Calc (derived from SfxObjectShell) + // see also: FID_CHG_RECORD, SID_CHG_PROTECT + virtual bool IsChangeRecording() const; + virtual bool HasChangeRecordProtection() const; + virtual void SetChangeRecording( bool bActivate ); + virtual bool SetProtectionPassword( const String &rPassword ); + virtual bool GetProtectionHash( /*out*/ ::com::sun::star::uno::Sequence< sal_Int8 > &rPasswordHash ); }; + +void UpdateAcceptChangesDialog(); + + SO2_DECL_REF(ScDocShell) SO2_IMPL_REF(ScDocShell) diff --git a/sc/source/ui/inc/dpcontrol.hxx b/sc/source/ui/inc/dpcontrol.hxx index 40e6167aee48..15f0c9174cc8 100644 --- a/sc/source/ui/inc/dpcontrol.hxx +++ b/sc/source/ui/inc/dpcontrol.hxx @@ -76,7 +76,6 @@ public: void draw(); void getPopupBoundingBox(Point& rPos, Size& rSize) const; - bool isPopupButton() const; private: void drawPopupButton(); @@ -127,9 +126,6 @@ public: void selectMenuItem(size_t nPos, bool bSelected, bool bSubMenuTimer); void clearSelectedMenuItem(); ScMenuFloatingWindow* getSubMenuWindow(size_t nPos) const; - size_t getMenuItemCount() const; - ::rtl::OUString getMenuItemName(size_t nPos) const; - bool isMenuItemEnabled(size_t nPos) const; bool isMenuItemSelected(size_t nPos) const; size_t getSelectedMenuItem() const; diff --git a/sc/source/ui/inc/gridwin.hxx b/sc/source/ui/inc/gridwin.hxx index 4d6ef782aed6..a2283bf2b7de 100644 --- a/sc/source/ui/inc/gridwin.hxx +++ b/sc/source/ui/inc/gridwin.hxx @@ -39,6 +39,7 @@ #include <vector> #include <memory> +#include <boost/shared_ptr.hpp> // --------------------------------------------------------------------------- @@ -112,6 +113,25 @@ private: ::sdr::overlay::OverlayObjectList* mpOOHeader; ::sdr::overlay::OverlayObjectList* mpOOShrink; + ::boost::shared_ptr<Rectangle> mpAutoFillRect; + + /** + * Stores current visible column and row ranges, used to avoid expensive + * operations on objects that are outside visible area. + */ + struct VisibleRange + { + SCCOL mnCol1; + SCCOL mnCol2; + SCROW mnRow1; + SCROW mnRow2; + + VisibleRange(); + + bool isInside(SCCOL nCol, SCROW nRow) const; + }; + VisibleRange maVisibleRange; + private: ScViewData* pViewData; ScSplitPos eWhich; diff --git a/sc/source/ui/inc/inputhdl.hxx b/sc/source/ui/inc/inputhdl.hxx index bcc5ba0dd396..61974cf7464d 100644 --- a/sc/source/ui/inc/inputhdl.hxx +++ b/sc/source/ui/inc/inputhdl.hxx @@ -68,7 +68,9 @@ private: TypedScStrCollection* pColumnData; TypedScStrCollection* pFormulaData; TypedScStrCollection* pFormulaDataPara; + Window* pTipVisibleParent; ULONG nTipVisible; + Window* pTipVisibleSecParent; ULONG nTipVisibleSec; String aManualTip; String aAutoSearch; @@ -149,6 +151,8 @@ private: BOOL CursorAtClosingPar(); void SkipClosingPar(); DECL_LINK( ModifyHdl, void* ); + DECL_LINK( ShowHideTipVisibleParentListener, VclWindowEvent* ); + DECL_LINK( ShowHideTipVisibleSecParentListener, VclWindowEvent* ); #endif public: diff --git a/sc/source/ui/inc/miscdlgs.hrc b/sc/source/ui/inc/miscdlgs.hrc index 908a6bd2221c..becd05165a4e 100644 --- a/sc/source/ui/inc/miscdlgs.hrc +++ b/sc/source/ui/inc/miscdlgs.hrc @@ -181,3 +181,9 @@ #define BTN_GROUP_ROWS 3 #define STR_GROUP 1 #define STR_UNGROUP 2 + +// Tab Bg Color +#define TAB_BG_COLOR_CT_BORDER 1 +#define TAB_BG_COLOR_SET_BGDCOLOR 2 +#define TAB_BG_COLOR_GB_BGDCOLOR 3 + diff --git a/sc/source/ui/inc/optdlg.hrc b/sc/source/ui/inc/optdlg.hrc index 00cfdb2c6d5a..27b8976e3541 100644 --- a/sc/source/ui/inc/optdlg.hrc +++ b/sc/source/ui/inc/optdlg.hrc @@ -70,6 +70,7 @@ #define BTN_MATCH 18 #define BTN_LOOKUP 19 #define BTN_REGEX 20 +#define BTN_GENERAL_PREC 21 // TP_VIEW: #define BTN_VSCROLL 1 diff --git a/sc/source/ui/inc/output.hxx b/sc/source/ui/inc/output.hxx index 8d512898afd3..42844513af92 100644 --- a/sc/source/ui/inc/output.hxx +++ b/sc/source/ui/inc/output.hxx @@ -73,6 +73,15 @@ class ScOutputData { friend class ScDrawStringsVars; private: + struct OutputAreaParam + { + Rectangle maAlignRect; + Rectangle maClipRect; + long mnColWidth; + bool mbLeftClip; + bool mbRightClip; + }; + OutputDevice* pDev; // Device OutputDevice* pRefDevice; // printer if used for preview OutputDevice* pFmtDevice; // reference for text formatting @@ -152,19 +161,19 @@ private: void GetVisibleCell( SCCOL nCol, SCROW nRow, SCTAB nTab, ScBaseCell*& rpCell ); BOOL IsAvailable( SCCOL nX, SCROW nY ); + void GetOutputArea( SCCOL nX, SCSIZE nArrY, long nPosX, long nPosY, - SCCOL nCellX, SCROW nCellY, long nNeeded, - const ScPatternAttr& rPattern, - USHORT nHorJustify, BOOL bCellIsValue, - BOOL bBreak, BOOL bOverwrite, - Rectangle& rAlignRect, Rectangle& rClipRect, - BOOL& rLeftClip, BOOL& rRightClip ); + SCCOL nCellX, SCROW nCellY, long nNeeded, + const ScPatternAttr& rPattern, + USHORT nHorJustify, bool bCellIsValue, + bool bBreak, bool bOverwrite, + OutputAreaParam& rParam ); void ShrinkEditEngine( EditEngine& rEngine, const Rectangle& rAlignRect, long nLeftM, long nTopM, long nRightM, long nBottomM, BOOL bWidth, USHORT nOrient, long nAttrRotate, BOOL bPixelToLogic, long& rEngineWidth, long& rEngineHeight, long& rNeededPixel, - BOOL& rLeftClip, BOOL& rRightClip ); + bool& rLeftClip, bool& rRightClip ); void SetSyntaxColor( Font* pFont, ScBaseCell* pCell ); void SetEditSyntaxColor( EditEngine& rEngine, ScBaseCell* pCell ); 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/inc/tabbgcolordlg.hxx b/sc/source/ui/inc/tabbgcolordlg.hxx new file mode 100644 index 000000000000..8f26395937b5 --- /dev/null +++ b/sc/source/ui/inc/tabbgcolordlg.hxx @@ -0,0 +1,80 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: tabbgcolordlg.hxx,v $ + * $Revision: 1.0 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SC_TABBGCOLORDLG_HXX +#define SC_TABBGCOLORDLG_HXX + +#include <vcl/dialog.hxx> +#include <vcl/fixed.hxx> +#include <vcl/imagebtn.hxx> +#include <svtools/valueset.hxx> + +//------------------------------------------------------------------------ + +class ScTabBgColorDlg : public ModalDialog +{ +public: + ScTabBgColorDlg( Window* pParent, + const String& rTitle, + const String& rTabBgColorNoColorText, + const Color& rDefaultColor, + const rtl::OString& nHelpId ); + ~ScTabBgColorDlg(); + + void GetSelectedColor( Color& rColor ) const; + +private: + class ScTabBgColorValueSet : public ValueSet + { + public: + ScTabBgColorValueSet(Control* pParent, const ResId& rResId, ScTabBgColorDlg* pTabBgColorDlg); + + virtual void KeyInput( const KeyEvent& rKEvt ); + private: + ScTabBgColorDlg* aTabBgColorDlg; + }; + + Control aBorderWin; + ScTabBgColorValueSet aTabBgColorSet; + FixedLine aTabBgColorBox; + OKButton aBtnOk; + CancelButton aBtnCancel; + HelpButton aBtnHelp; + Color aTabBgColor; + const String aTabBgColorNoColorText; + rtl::OString msHelpId; + + void FillColorValueSets_Impl(); + + DECL_LINK( TabBgColorDblClickHdl_Impl, ValueSet* ); + DECL_LINK( TabBgColorOKHdl_Impl, OKButton* pBtn ); +}; + +#endif // SC_TABBGCOLORDLG_HXX diff --git a/sc/source/ui/inc/tpcalc.hxx b/sc/source/ui/inc/tpcalc.hxx index ea9e53a23ee4..31f2c9458c83 100644 --- a/sc/source/ui/inc/tpcalc.hxx +++ b/sc/source/ui/inc/tpcalc.hxx @@ -76,6 +76,7 @@ private: CheckBox aBtnMatch; CheckBox aBtnRegex; CheckBox aBtnLookUp; + CheckBox aBtnGeneralPrec; FixedText aFtPrec; NumericField aEdPrec; diff --git a/sc/source/ui/inc/undotab.hxx b/sc/source/ui/inc/undotab.hxx index 276ea3d7e204..c8d135070ab1 100644 --- a/sc/source/ui/inc/undotab.hxx +++ b/sc/source/ui/inc/undotab.hxx @@ -32,6 +32,7 @@ #include "markdata.hxx" #include "formula/grammar.hxx" #include <tools/color.hxx> +#include "tabbgcolor.hxx" #ifndef _SVSTDARR_SHORTS @@ -223,6 +224,33 @@ private: void DoChange() const; }; +class ScUndoTabColor: public ScSimpleUndo +{ +public: + TYPEINFO(); + ScUndoTabColor( + ScDocShell* pNewDocShell, + SCTAB nT, + const Color& aOTabBgColor, + const Color& aNTabBgColor); + ScUndoTabColor( + ScDocShell* pNewDocShell, + const ScUndoTabColorInfo::List& rUndoTabColorList); + virtual ~ScUndoTabColor(); + + virtual void Undo(); + virtual void Redo(); + virtual void Repeat(SfxRepeatTarget& rTarget); + virtual BOOL CanRepeat(SfxRepeatTarget& rTarget) const; + +virtual String GetComment() const; + +private: + ScUndoTabColorInfo::List aTabColorList; + bool bIsMultipleUndo; + + void DoChange(bool bUndoType) const; +}; class ScUndoMakeScenario: public ScSimpleUndo { diff --git a/sc/source/ui/inc/viewfunc.hxx b/sc/source/ui/inc/viewfunc.hxx index 21feb272c339..59da2966cc60 100644 --- a/sc/source/ui/inc/viewfunc.hxx +++ b/sc/source/ui/inc/viewfunc.hxx @@ -29,6 +29,8 @@ #include "tabview.hxx" +#include "tabbgcolor.hxx" + #ifndef _SVSTDARR_SHORTS #define _SVSTDARR_SHORTS #include <svl/svstdarr.hxx> @@ -273,6 +275,9 @@ public: SCTAB nCount, const SCTAB* pSrcTabs, BOOL bLink,SCTAB nTab); + bool SetTabBgColor( const Color& rColor, SCTAB nTabNr ); + bool SetTabBgColor( ScUndoTabColorInfo::List& rUndoSetTabBgColorInfoList ); + void InsertTableLink( const String& rFile, const String& rFilter, const String& rOptions, const String& rTabName ); diff --git a/sc/source/ui/inc/viewutil.hxx b/sc/source/ui/inc/viewutil.hxx index 8b103d3761d8..eb1c6df2f902 100644 --- a/sc/source/ui/inc/viewutil.hxx +++ b/sc/source/ui/inc/viewutil.hxx @@ -68,10 +68,10 @@ public: static sal_Int32 GetTransliterationType( USHORT nSlotID ); - static bool HasFiltered( const ScRange& rRange, const ScDocument* pDoc ); + static bool HasFiltered( const ScRange& rRange, ScDocument* pDoc ); /** Fit a range to cover nRows number of unfiltered rows. @return <TRUE/> if the resulting range covers nRows unfiltered rows. */ - static bool FitToUnfilteredRows( ScRange & rRange, const ScDocument * pDoc, size_t nRows ); + static bool FitToUnfilteredRows( ScRange & rRange, ScDocument * pDoc, size_t nRows ); static void UnmarkFiltered( ScMarkData& rMark, ScDocument* pDoc ); static void HideDisabledSlot( SfxItemSet& rSet, SfxBindings& rBindings, USHORT nSlotId ); diff --git a/sc/source/ui/miscdlgs/acredlin.src b/sc/source/ui/miscdlgs/acredlin.src index 87bec60a63b5..a39377061474 100644 --- a/sc/source/ui/miscdlgs/acredlin.src +++ b/sc/source/ui/miscdlgs/acredlin.src @@ -170,7 +170,6 @@ Menu RID_POPUP_CHANGES MenuItem { Identifier = SC_SUB_SORT ; - RadioCheck = TRUE ; SubMenu = Menu { ItemList = diff --git a/sc/source/ui/miscdlgs/autofmt.cxx b/sc/source/ui/miscdlgs/autofmt.cxx index 940856775c07..6ce65ab914be 100644 --- a/sc/source/ui/miscdlgs/autofmt.cxx +++ b/sc/source/ui/miscdlgs/autofmt.cxx @@ -68,8 +68,6 @@ #define FRAME_OFFSET 4 -BOOL bIsOlk = FALSE; - //CHINA001 //======================================================================== //CHINA001 // AutoFormat-Dialog: @@ -508,8 +506,6 @@ ScAutoFmtPreview::ScAutoFmtPreview( Window* pParent, const ResId& rRes, ScDocume pNumFmt ( new SvNumberFormatter( ::comphelper::getProcessServiceFactory(), ScGlobal::eLnge ) ) { Init(); - if( bIsOlk ) - ((String&)aStrMar).AssignAscii(RTL_CONSTASCII_STRINGPARAM( "Olk" )); } //------------------------------------------------------------------------ diff --git a/sc/source/ui/miscdlgs/makefile.mk b/sc/source/ui/miscdlgs/makefile.mk index 9f5bb1dbc498..d34994341ade 100644 --- a/sc/source/ui/miscdlgs/makefile.mk +++ b/sc/source/ui/miscdlgs/makefile.mk @@ -46,6 +46,7 @@ SLOFILES = \ $(SLO)$/delcodlg.obj \ $(SLO)$/inscodlg.obj \ $(SLO)$/strindlg.obj \ + $(SLO)$/tabbgcolordlg.obj \ $(SLO)$/mtrindlg.obj \ $(SLO)$/lbseldlg.obj \ $(SLO)$/filldlg.obj \ @@ -60,7 +61,6 @@ SLOFILES = \ $(SLO)$/crdlg.obj \ $(SLO)$/namecrea.obj \ $(SLO)$/namepast.obj \ - $(SLO)$/teamdlg.obj \ $(SLO)$/textdlgs.obj \ $(SLO)$/anyrefdg.obj \ $(SLO)$/crnrdlg.obj \ @@ -109,7 +109,6 @@ LIB1OBJFILES = \ $(SLO)$/solveroptions.obj \ $(SLO)$/solverutil.obj \ $(SLO)$/tabopdlg.obj \ - $(SLO)$/teamdlg.obj \ $(SLO)$/anyrefdg.obj \ $(SLO)$/crnrdlg.obj \ $(SLO)$/acredlin.obj \ diff --git a/sc/source/ui/miscdlgs/tabbgcolordlg.cxx b/sc/source/ui/miscdlgs/tabbgcolordlg.cxx new file mode 100644 index 000000000000..7a751918a563 --- /dev/null +++ b/sc/source/ui/miscdlgs/tabbgcolordlg.cxx @@ -0,0 +1,199 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: tabbgcolordlg.cxx,v $ + * $Revision: 1.0 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + +#undef SC_DLLIMPLEMENTATION + +//------------------------------------------------------------------ + +#include "tabbgcolordlg.hxx" +#include "scresid.hxx" +#include "miscdlgs.hrc" + +#include "tools/debug.hxx" +#include "tools/color.hxx" +#include "sfx2/objsh.hxx" +#include "svx/xtable.hxx" +#include "svx/drawitem.hxx" +#include "unotools/pathoptions.hxx" +#include "tools/resid.hxx" +#include "editeng/editrids.hrc" + +#include <boost/scoped_ptr.hpp> + +//================================================================== + +#define HDL(hdl) LINK(this,ScTabBgColorDlg,hdl) + +ScTabBgColorDlg::ScTabBgColorDlg( Window* pParent, + const String& rTitle, + const String& rTabBgColorNoColorText, + const Color& rDefaultColor, + const rtl::OString& sHelpId ) : + ModalDialog ( pParent, ScResId( RID_SCDLG_TAB_BG_COLOR ) ), + aBorderWin ( this, ScResId( TAB_BG_COLOR_CT_BORDER ) ), + aTabBgColorSet ( &aBorderWin, ScResId( TAB_BG_COLOR_SET_BGDCOLOR ), this ), + aTabBgColorBox ( this, ScResId( TAB_BG_COLOR_GB_BGDCOLOR ) ), + aBtnOk ( this, ScResId( BTN_OK ) ), + aBtnCancel ( this, ScResId( BTN_CANCEL ) ), + aBtnHelp ( this, ScResId( BTN_HELP ) ), + aTabBgColor ( rDefaultColor ), + aTabBgColorNoColorText ( rTabBgColorNoColorText ), + msHelpId ( sHelpId ) + +{ + SetHelpId( sHelpId ); + this->SetText( rTitle ); + this->SetStyle(GetStyle() | WB_BORDER | WB_STDFLOATWIN | WB_3DLOOK | WB_DIALOGCONTROL | WB_SYSTEMWINDOW | WB_STANDALONE | WB_HIDE); + + aTabBgColorBox.SetText(rTitle); + FillColorValueSets_Impl(); + aTabBgColorSet.SetDoubleClickHdl( HDL(TabBgColorDblClickHdl_Impl) ); + aBtnOk.SetClickHdl( HDL(TabBgColorOKHdl_Impl) ); + FreeResource(); +} + +//------------------------------------------------------------------------ + +void ScTabBgColorDlg::GetSelectedColor( Color& rColor ) const +{ + rColor = this->aTabBgColor; +} + +ScTabBgColorDlg::~ScTabBgColorDlg() +{ +} + +void ScTabBgColorDlg::FillColorValueSets_Impl() +{ + SfxObjectShell* pDocSh = SfxObjectShell::Current(); + const SfxPoolItem* pItem = NULL; + XColorTable* pColorTable = NULL; + ::boost::scoped_ptr<XColorTable> pOwnColorTable; // locally instantiated in case the doc shell doesn't have one. + + const Size aSize15x15 = Size( 15, 15 ); + const Size aSize10x10 = Size( 10, 10 ); + const Size aSize5x5 = Size( 5, 5 ); + USHORT nSelectedItem = 0; + + DBG_ASSERT( pDocSh, "DocShell not found!" ); + + if ( pDocSh && ( 0 != ( pItem = pDocSh->GetItem(SID_COLOR_TABLE) ) ) ) + pColorTable = ( (SvxColorTableItem*)pItem )->GetColorTable(); + if ( !pColorTable ) + { + pOwnColorTable.reset(new XColorTable(SvtPathOptions().GetPalettePath())); + pColorTable = pOwnColorTable.get(); + } + if ( pColorTable ) + { + sal_uInt16 i = 0; + long nCount = pColorTable->Count(); + XColorEntry* pEntry = NULL; + Color aColWhite( COL_WHITE ); + String aStrWhite( ScResId( RID_SVXITEMS_COLOR_WHITE ) ); + WinBits nBits = ( aTabBgColorSet.GetStyle() | WB_NAMEFIELD | WB_ITEMBORDER | WB_NONEFIELD | WB_3DLOOK | WB_NO_DIRECTSELECT | WB_NOPOINTERFOCUS); + aTabBgColorSet.SetText( aTabBgColorNoColorText ); + aTabBgColorSet.SetStyle( nBits ); + for ( i = 0; i < nCount; i++ ) + { + pEntry = pColorTable->GetColor(i); + aTabBgColorSet.InsertItem( i + 1, pEntry->GetColor(), pEntry->GetName() ); + if (pEntry->GetColor() == aTabBgColor) + nSelectedItem = (i + 1); + } + + while ( i < 80 ) + { + aTabBgColorSet.InsertItem( i + 1, aColWhite, aStrWhite ); + i++; + } + + if ( nCount > 80 ) + { + aTabBgColorSet.SetStyle( nBits | WB_VSCROLL ); + } + } + aTabBgColorSet.SetColCount( 10 ); + aTabBgColorSet.SetLineCount( 10 ); + aTabBgColorSet.CalcWindowSizePixel( aSize15x15 ); + aTabBgColorSet.Format(); + aTabBgColorSet.SelectItem(nSelectedItem); + aTabBgColorSet.Resize(); +} + +IMPL_LINK( ScTabBgColorDlg, TabBgColorDblClickHdl_Impl, ValueSet*, EMPTYARG ) +/* + Handler, called when color selection is changed +*/ +{ + USHORT nItemId = aTabBgColorSet.GetSelectItemId(); + Color aColor = nItemId ? ( aTabBgColorSet.GetItemColor( nItemId ) ) : Color( COL_AUTO ); + aTabBgColor = aColor; + EndDialog( TRUE ); + return 0; +} + +IMPL_LINK( ScTabBgColorDlg, TabBgColorOKHdl_Impl, OKButton*, EMPTYARG ) +{ + +// Handler, called when the OK button is pushed + + USHORT nItemId = aTabBgColorSet.GetSelectItemId(); + Color aColor = nItemId ? ( aTabBgColorSet.GetItemColor( nItemId ) ) : Color( COL_AUTO ); + aTabBgColor = aColor; + EndDialog( TRUE ); + return 0; +} + +ScTabBgColorDlg::ScTabBgColorValueSet::ScTabBgColorValueSet( Control* pParent, const ResId& rResId, ScTabBgColorDlg* pTabBgColorDlg ) : + ValueSet(pParent, rResId) +{ + aTabBgColorDlg = pTabBgColorDlg; +} + +void ScTabBgColorDlg::ScTabBgColorValueSet::KeyInput( const KeyEvent& rKEvt ) +{ + switch ( rKEvt.GetKeyCode().GetCode() ) + { + case KEY_SPACE: + case KEY_RETURN: + { + USHORT nItemId = GetSelectItemId(); + const Color& aColor = nItemId ? ( GetItemColor( nItemId ) ) : Color( COL_AUTO ); + aTabBgColorDlg->aTabBgColor = aColor; + aTabBgColorDlg->EndDialog(TRUE); + } + break; + } + ValueSet::KeyInput(rKEvt); +} diff --git a/sc/source/ui/miscdlgs/teamdlg.cxx b/sc/source/ui/miscdlgs/teamdlg.cxx deleted file mode 100644 index a9f1bf2a17cf..000000000000 --- a/sc/source/ui/miscdlgs/teamdlg.cxx +++ /dev/null @@ -1,116 +0,0 @@ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2000, 2010 Oracle and/or its affiliates. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ - -// MARKER(update_precomp.py): autogen include statement, do not remove -#include "precompiled_sc.hxx" - - - -//------------------------------------------------------------------ - -#include <tools/shl.hxx> - -#include "teamdlg.hxx" -#include "scmod.hxx" -#include "scresid.hxx" -#include "sc.hrc" - - -//------------------------------------------------------------------ - -void ShowTheTeam() -{ - SC_MOD()->OpenTeamDlg(); -} - -//======================================================================== -// ScTeamDlg -//======================================================================== - -ScTeamDlg::ScTeamDlg( Window* pParent ) - : FloatingWindow( pParent, ScResId( RID_SCDLG_TEAM ) ), - aBmpTeam ( this, ScResId( 1 ) ) -{ - FreeResource(); - SC_MOD()->SetTeamDlg( this ); - - Bitmap aBmp( ScResId( RID_SCTEAMDLGBMP1 ) ); - - Size aSize = aBmp.GetSizePixel(); - USHORT nOff = (USHORT)aBmpTeam.GetPosPixel().X(); - - aBmpTeam.SetSizePixel( aSize ); - aBmpTeam.SetBitmap( aBmp ); - aSize.Width() += (2*nOff); - aSize.Height() += (2*nOff); - SetOutputSizePixel( aSize ); - Center(); - Point aPos = GetPosPixel(); - if (aPos.Y() < 0) - { - // #87164# title bar must be visible - aPos.Y() = 0; - SetPosPixel(aPos); - } - Show(); -} - -//------------------------------------------------------------------------ - -__EXPORT ScTeamDlg::~ScTeamDlg() -{ -} - -//------------------------------------------------------------------------ - -BOOL __EXPORT ScTeamDlg::Close() -{ - BOOL bReturn = FloatingWindow::Close(); - - SC_MOD()->SetTeamDlg( NULL ); - delete this; - - return bReturn; -} - -//------------------------------------------------------------------------ - -void ScTeamDlg::Center() -{ - if ( IsRollUp() ) RollDown(); - - Size aSizeDesktop = GetParent()->GetSizePixel(); - Size aSize = GetSizePixel(); - Point aNewPos; - - aNewPos.X() = (aSizeDesktop.Width() - aSize.Width()) / 2; - aNewPos.Y() = (aSizeDesktop.Height() - aSize.Height()) / 2; - SetPosPixel( aNewPos ); -} - - - diff --git a/sc/source/ui/optdlg/tpcalc.cxx b/sc/source/ui/optdlg/tpcalc.cxx index c6423ea73b23..5b5920e904fc 100644 --- a/sc/source/ui/optdlg/tpcalc.cxx +++ b/sc/source/ui/optdlg/tpcalc.cxx @@ -88,6 +88,7 @@ ScTpCalcOptions::ScTpCalcOptions( Window* pParent, aBtnMatch ( this, ScResId( BTN_MATCH ) ), aBtnRegex ( this, ScResId( BTN_REGEX ) ), aBtnLookUp ( this, ScResId( BTN_LOOKUP ) ), + aBtnGeneralPrec ( this, ScResId( BTN_GENERAL_PREC ) ), aFtPrec ( this, ScResId( FT_PREC ) ), aEdPrec ( this, ScResId( ED_PREC ) ), pOldOptions ( new ScDocOptions( @@ -116,6 +117,7 @@ __EXPORT ScTpCalcOptions::~ScTpCalcOptions() void ScTpCalcOptions::Init() { aBtnIterate .SetClickHdl( LINK( this, ScTpCalcOptions, CheckClickHdl ) ); + aBtnGeneralPrec.SetClickHdl( LINK(this, ScTpCalcOptions, CheckClickHdl) ); aBtnDateStd .SetClickHdl( LINK( this, ScTpCalcOptions, RadioClickHdl ) ); aBtnDateSc10.SetClickHdl( LINK( this, ScTpCalcOptions, RadioClickHdl ) ); aBtnDate1904.SetClickHdl( LINK( this, ScTpCalcOptions, RadioClickHdl ) ); @@ -150,7 +152,6 @@ void __EXPORT ScTpCalcOptions::Reset( const SfxItemSet& /* rCoreAttrs */ ) aBtnLookUp .Check( pLocalOptions->IsLookUpColRowNames() ); aBtnIterate.Check( pLocalOptions->IsIter() ); aEdSteps .SetValue( pLocalOptions->GetIterCount() ); - aEdPrec .SetValue( pLocalOptions->GetStdPrecision() ); aEdEps .SetValue( pLocalOptions->GetIterEps(), 6 ); pLocalOptions->GetDate( d, m, y ); @@ -168,6 +169,21 @@ void __EXPORT ScTpCalcOptions::Reset( const SfxItemSet& /* rCoreAttrs */ ) break; } + sal_uInt16 nPrec = pLocalOptions->GetStdPrecision(); + if (nPrec == SvNumberFormatter::UNLIMITED_PRECISION) + { + aFtPrec.Disable(); + aEdPrec.Disable(); + aBtnGeneralPrec.Check(false); + } + else + { + aBtnGeneralPrec.Check(); + aFtPrec.Enable(); + aEdPrec.Enable(); + aEdPrec.SetValue(nPrec); + } + CheckClickHdl( &aBtnIterate ); } @@ -178,13 +194,18 @@ BOOL __EXPORT ScTpCalcOptions::FillItemSet( SfxItemSet& rCoreAttrs ) { // alle weiteren Optionen werden in den Handlern aktualisiert pLocalOptions->SetIterCount( (USHORT)aEdSteps.GetValue() ); - pLocalOptions->SetStdPrecision( (USHORT)aEdPrec.GetValue() ); pLocalOptions->SetIgnoreCase( !aBtnCase.IsChecked() ); pLocalOptions->SetCalcAsShown( aBtnCalc.IsChecked() ); pLocalOptions->SetMatchWholeCell( aBtnMatch.IsChecked() ); pLocalOptions->SetFormulaRegexEnabled( aBtnRegex.IsChecked() ); pLocalOptions->SetLookUpColRowNames( aBtnLookUp.IsChecked() ); + if (aBtnGeneralPrec.IsChecked()) + pLocalOptions->SetStdPrecision( + static_cast<sal_uInt16>(aEdPrec.GetValue()) ); + else + pLocalOptions->SetStdPrecision( SvNumberFormatter::UNLIMITED_PRECISION ); + if ( *pLocalOptions != *pOldOptions ) { rCoreAttrs.Put( ScTpCalcItem( nWhichCalc, *pLocalOptions ) ); @@ -245,19 +266,35 @@ IMPL_LINK( ScTpCalcOptions, RadioClickHdl, RadioButton*, pBtn ) //----------------------------------------------------------------------- -IMPL_LINK( ScTpCalcOptions, CheckClickHdl, CheckBox*, pBtn ) +IMPL_LINK( ScTpCalcOptions, CheckClickHdl, CheckBox*, pBtn ) { - if ( pBtn->IsChecked() ) + if (pBtn == &aBtnGeneralPrec) { - pLocalOptions->SetIter( TRUE ); - aFtSteps.Enable(); aEdSteps.Enable(); - aFtEps .Enable(); aEdEps .Enable(); + if (pBtn->IsChecked()) + { + aEdPrec.Enable(); + aFtPrec.Enable(); + } + else + { + aEdPrec.Disable(); + aFtPrec.Disable(); + } } - else + else if (pBtn == &aBtnIterate) { - pLocalOptions->SetIter( FALSE ); - aFtSteps.Disable(); aEdSteps.Disable(); - aFtEps .Disable(); aEdEps .Disable(); + if ( pBtn->IsChecked() ) + { + pLocalOptions->SetIter( TRUE ); + aFtSteps.Enable(); aEdSteps.Enable(); + aFtEps .Enable(); aEdEps .Enable(); + } + else + { + pLocalOptions->SetIter( FALSE ); + aFtSteps.Disable(); aEdSteps.Disable(); + aFtEps .Disable(); aEdEps .Disable(); + } } return 0; diff --git a/sc/source/ui/src/globstr.src b/sc/source/ui/src/globstr.src index 1cc66ca13af6..6c15762bda6a 100644 --- a/sc/source/ui/src/globstr.src +++ b/sc/source/ui/src/globstr.src @@ -927,10 +927,6 @@ Resource RID_GLOBSTR /* END error constants and error strings. */ - String STR_ODER_SO - { - Text [ en-US ] = "%s or similar" ; - }; String STR_GRIDCOLOR { Text [ en-US ] = "Grid color" ; @@ -1127,6 +1123,14 @@ Resource RID_GLOBSTR { Text [ en-US ] = "Rename Sheet" ; }; + String STR_UNDO_SET_TAB_BG_COLOR + { + Text [ en-US ] = "Color Tab" ; + }; + String STR_UNDO_SET_MULTI_TAB_BG_COLOR + { + Text [ en-US ] = "Color Tabs" ; + }; String STR_UNDO_MOVE_TAB { Text [ en-US ] = "Move Sheets" ; diff --git a/sc/source/ui/src/miscdlgs.src b/sc/source/ui/src/miscdlgs.src index efa6760d5079..b60e7f54b8d6 100644 --- a/sc/source/ui/src/miscdlgs.src +++ b/sc/source/ui/src/miscdlgs.src @@ -154,11 +154,6 @@ ModalDialog RID_SCDLG_INSCELL }; }; -Bitmap RID_SCTEAMDLGBMP1 -{ - File = "calcteam.bmp"; -}; - ModalDialog RID_SCDLG_DELCONT { OutputSize = TRUE ; @@ -543,6 +538,96 @@ ModalDialog RID_SCDLG_STRINPUT Size = MAP_APPFONT ( 110 , 8 ) ; }; }; +ModalDialog RID_SCDLG_TAB_BG_COLOR +{ + OutputSize = TRUE ; + SVLook = TRUE ; + Size = MAP_APPFONT ( 118 , 167 ) ; + Moveable = TRUE ; + Closeable = TRUE ; + Control TAB_BG_COLOR_CT_BORDER + { + Border = TRUE ; + Pos = MAP_APPFONT ( 1 , 1 ) ; //12, 32 + Size = MAP_APPFONT ( 116+2 , 145+2 ) ; + DialogControl = TRUE; + }; + Control TAB_BG_COLOR_SET_BGDCOLOR + { + // * HelpId = HID_BACKGROUND_CTL_BGDCOLORSET ; + Hide = FALSE ; + Pos = MAP_APPFONT ( 0 , 0 ) ; + Size = MAP_APPFONT ( 116 , 145 ) ; + TabStop = TRUE ; + }; + CancelButton BTN_CANCEL + { + Pos = MAP_APPFONT ( 82 , 151 ) ; + Size = MAP_APPFONT ( 35 , 14 ) ; + TabStop = TRUE ; + DefButton = FALSE ; + }; + OKButton BTN_OK + { + Pos = MAP_APPFONT ( 45 , 151 ) ; + Size = MAP_APPFONT ( 35 , 14 ) ; + TabStop = TRUE ; + DefButton = TRUE ; + }; + HelpButton BTN_HELP + { + Pos = MAP_APPFONT ( 2 , 151 ) ; + Size = MAP_APPFONT ( 35 , 14 ) ; + TabStop = TRUE ; + DefButton = FALSE ; + }; +}; +/* +ModalDialog RID_SCDLG_TAB_BG_COLOR +{ + OutputSize = TRUE ; + SVLook = TRUE ; + Size = MAP_APPFONT ( 180 , 150 ) ; + Moveable = TRUE ; + Closeable = TRUE ; + Control TAB_BG_COLOR_CT_BORDER + { + Border = TRUE ; + Pos = MAP_APPFONT ( 1 , 1 ) ; //12, 32 + Size = MAP_APPFONT ( 116+2 , 145+2 ) ; + DialogControl = TRUE; + }; + Control TAB_BG_COLOR_SET_BGDCOLOR + { + // * HelpId = HID_BACKGROUND_CTL_BGDCOLORSET ; + Hide = FALSE ; + Pos = MAP_APPFONT ( 0 , 0 ) ; + Size = MAP_APPFONT ( 116 , 145 ) ; + TabStop = TRUE ; + }; + OKButton BTN_OK + { + Pos = MAP_APPFONT ( 125 , 50 ) ; + Size = MAP_APPFONT ( 50 , 14 ) ; + TabStop = TRUE ; + DefButton = TRUE ; + }; + CancelButton BTN_CANCEL + { + Pos = MAP_APPFONT ( 125 , 67 ) ; + Size = MAP_APPFONT ( 50 , 14 ) ; + TabStop = TRUE ; + DefButton = FALSE ; + }; + HelpButton BTN_HELP + { + Pos = MAP_APPFONT ( 125 , 84 ) ; + Size = MAP_APPFONT ( 50 , 14 ) ; + TabStop = TRUE ; + DefButton = FALSE ; + }; +}; +*/ /* ModalDialog RID_SCDLG_MTRINPUT { @@ -1331,18 +1416,6 @@ ModalDialog RID_SCDLG_NAMES_PASTE Text [ en-US ] = "Insert Name" ; }; -FloatingWindow RID_SCDLG_TEAM -{ - Hide = TRUE ; - OutputSize = TRUE ; - SVLook = TRUE ; - Moveable = TRUE ; - Closeable = TRUE ; - Zoomable = TRUE ; - FixedBitmap 1 { Pos = MAP_APPFONT ( 1 , 1 ) ; }; - Text [ en-US ] = "The %PRODUCTNAME Calc Team" ; -}; - ModalDialog RID_SCDLG_CHARTCOLROW { OutputSize = TRUE ; diff --git a/sc/source/ui/src/optdlg.src b/sc/source/ui/src/optdlg.src index 856463e27e40..ea7cabf7716d 100644 --- a/sc/source/ui/src/optdlg.src +++ b/sc/source/ui/src/optdlg.src @@ -119,22 +119,6 @@ TabPage RID_SCPAGE_CALC Pos = MAP_APPFONT ( 6 , 64 ) ; Size = MAP_APPFONT ( 248 , 8 ) ; }; - FixedText FT_PREC - { - Pos = MAP_APPFONT ( 150 , 77 ) ; - Size = MAP_APPFONT ( 72 , 8 ) ; - Text [ en-US ] = "~Decimal places" ; - Right = TRUE ; - }; - NumericField ED_PREC - { - Border = TRUE ; - Pos = MAP_APPFONT ( 226 , 75 ) ; - Size = MAP_APPFONT ( 25 , 12 ) ; - Maximum = 20 ; - Spin = TRUE ; - Repeat = TRUE ; - }; CheckBox BTN_CASE { Pos = MAP_APPFONT ( 12 , 77 ) ; @@ -165,6 +149,28 @@ TabPage RID_SCPAGE_CALC Size = MAP_APPFONT ( 239 , 10 ) ; Text [ en-US ] = "~Automatically find column and row labels " ; }; + CheckBox BTN_GENERAL_PREC + { + Pos = MAP_APPFONT ( 12 , 147 ) ; + Size = MAP_APPFONT ( 136 , 10 ) ; + Text [ en-US ] = "Limit decimals for general number format" ; + }; + FixedText FT_PREC + { + Pos = MAP_APPFONT ( 150 , 148 ) ; + Size = MAP_APPFONT ( 72 , 8 ) ; + Text [ en-US ] = "~Decimal places" ; + Right = TRUE ; + }; + NumericField ED_PREC + { + Border = TRUE ; + Pos = MAP_APPFONT ( 226 , 146 ) ; + Size = MAP_APPFONT ( 25 , 12 ) ; + Maximum = 20 ; + Spin = TRUE ; + Repeat = TRUE ; + }; }; /**************************************************************************/ diff --git a/sc/source/ui/src/popup.src b/sc/source/ui/src/popup.src index 079c4d538c4c..a466823581bf 100644 --- a/sc/source/ui/src/popup.src +++ b/sc/source/ui/src/popup.src @@ -190,6 +190,21 @@ Menu RID_POPUP_TAB HelpId = CMD_FID_TAB_RTL ; Text [ en-US ] = "S~heet Right-To-Left" ; }; + MenuItem + { + Identifier = FID_TAB_EVENTS ; + HelpId = CMD_FID_TAB_EVENTS ; + Text [ en-US ] = "Sheet E~vents..." ; + }; + //------------------------------ + MenuItem { Separator = TRUE ; }; + //------------------------------ + MenuItem + { + Identifier = FID_TAB_MENU_SET_TAB_BG_COLOR ; + HelpId = CMD_FID_TAB_MENU_SET_TAB_BG_COLOR ; + Text [ en-US ] = "~Tab Color..." ; + }; }; }; diff --git a/sc/source/ui/src/scstring.src b/sc/source/ui/src/scstring.src index 7f5337e11b89..9c47a42239cc 100644 --- a/sc/source/ui/src/scstring.src +++ b/sc/source/ui/src/scstring.src @@ -280,6 +280,14 @@ String SCSTR_RENAMETAB { Text [ en-US ] = "Rename Sheet" ; }; +String SCSTR_SET_TAB_BG_COLOR +{ + Text [ en-US ] = "Tab Color" ; +}; +String SCSTR_NO_TAB_BG_COLOR +{ + Text [ en-US ] = "Default" ; +}; String SCSTR_RENAMEOBJECT { Text [ en-US ] = "Name Object"; diff --git a/sc/source/ui/undo/makefile.mk b/sc/source/ui/undo/makefile.mk index 01edd92f8553..50fab82972ca 100644 --- a/sc/source/ui/undo/makefile.mk +++ b/sc/source/ui/undo/makefile.mk @@ -76,7 +76,8 @@ SLOFILES = \ EXCEPTIONSFILES= \ $(SLO)$/undoblk3.obj \ $(SLO)$/undocell.obj \ - $(SLO)$/undostyl.obj + $(SLO)$/undostyl.obj \ + $(SLO)$/undotab.obj # --- Tagets ------------------------------------------------------- diff --git a/sc/source/ui/undo/undoblk.cxx b/sc/source/ui/undo/undoblk.cxx index a35ba96112e3..c284045c5b11 100644 --- a/sc/source/ui/undo/undoblk.cxx +++ b/sc/source/ui/undo/undoblk.cxx @@ -1148,10 +1148,10 @@ ScUndoDragDrop::ScUndoDragDrop( ScDocShell* pNewDocShell, BOOL bIncludeFiltered = bCut; if ( !bIncludeFiltered ) { - // manually find number of non-filtered rows - SCROW nPastedCount = pDocShell->GetDocument()->GetRowFlagsArray( - aSrcRange.aStart.Tab()).CountForCondition( - aSrcRange.aStart.Row(), aSrcRange.aEnd.Row(), CR_FILTERED, 0); + // find number of non-filtered rows + SCROW nPastedCount = pDocShell->GetDocument()->CountNonFilteredRows( + aSrcRange.aStart.Row(), aSrcRange.aEnd.Row(), aSrcRange.aStart.Tab()); + if ( nPastedCount == 0 ) nPastedCount = 1; aDestEnd.SetRow( aNewDestPos.Row() + nPastedCount - 1 ); diff --git a/sc/source/ui/undo/undoblk3.cxx b/sc/source/ui/undo/undoblk3.cxx index 4011d4755ab1..506afeac138e 100644 --- a/sc/source/ui/undo/undoblk3.cxx +++ b/sc/source/ui/undo/undoblk3.cxx @@ -1028,17 +1028,20 @@ void __EXPORT ScUndoAutoFormat::Redo() aDestMark.MarkToMulti(); // wie SC_SIZE_VISOPT + SCROW nLastRow = -1; for (SCROW nRow=nStartY; nRow<=nEndY; nRow++) { BYTE nOld = pDoc->GetRowFlags(nRow,nTab); - if ( (nOld & CR_HIDDEN) == 0 && ( nOld & CR_MANUALSIZE ) ) + bool bHidden = pDoc->RowHidden(nRow, nTab, nLastRow); + if ( !bHidden && ( nOld & CR_MANUALSIZE ) ) pDoc->SetRowFlags( nRow, nTab, nOld & ~CR_MANUALSIZE ); } pDoc->SetOptimalHeight( nStartY, nEndY, nTab, 0, &aVirtDev, nPPTX, nPPTY, aZoomX, aZoomY, FALSE ); + SCCOL nLastCol = -1; for (SCCOL nCol=nStartX; nCol<=nEndX; nCol++) - if ((pDoc->GetColFlags( nCol, nTab ) & CR_HIDDEN) == 0) + if (!pDoc->ColHidden(nCol, nTab, nLastCol)) { USHORT nThisSize = STD_EXTRA_WIDTH + pDoc->GetOptimalColWidth( nCol, nTab, &aVirtDev, nPPTX, nPPTY, aZoomX, aZoomY, bFormula, diff --git a/sc/source/ui/undo/undocell.cxx b/sc/source/ui/undo/undocell.cxx index 77142bb13799..cc13ce9f1412 100644 --- a/sc/source/ui/undo/undocell.cxx +++ b/sc/source/ui/undo/undocell.cxx @@ -568,6 +568,8 @@ void ScUndoPageBreak::DoChange( BOOL bInsertP ) const pViewShell->InsertPageBreak(bColumn, FALSE); else pViewShell->DeletePageBreak(bColumn, FALSE); + + pDocShell->GetDocument()->InvalidatePageBreaks(nTab); } } diff --git a/sc/source/ui/undo/undodat.cxx b/sc/source/ui/undo/undodat.cxx index d550d54f1aea..0f7834b2a8df 100644 --- a/sc/source/ui/undo/undodat.cxx +++ b/sc/source/ui/undo/undodat.cxx @@ -1027,7 +1027,10 @@ void __EXPORT ScUndoQuery::Undo() pDoc->SetDBCollection( new ScDBCollection( *pUndoDB ), TRUE ); if (!bCopy) + { + pDoc->InvalidatePageBreaks(nTab); pDoc->UpdatePageBreaks( nTab ); + } ScRange aDirtyRange( 0 , aQueryParam.nRow1, nTab, MAXCOL, aQueryParam.nRow2, nTab ); diff --git a/sc/source/ui/undo/undotab.cxx b/sc/source/ui/undo/undotab.cxx index 17f15af54701..2d8340ad030b 100644 --- a/sc/source/ui/undo/undotab.cxx +++ b/sc/source/ui/undo/undotab.cxx @@ -59,6 +59,7 @@ #include "printfun.hxx" #include "chgtrack.hxx" #include "tabprotection.hxx" +#include "viewdata.hxx" // for ScUndoRenameObject - might me moved to another file later #include <svx/svditer.hxx> @@ -90,6 +91,7 @@ TYPEINIT1(ScUndoScenarioFlags, SfxUndoAction); TYPEINIT1(ScUndoRenameObject, SfxUndoAction); TYPEINIT1(ScUndoLayoutRTL, SfxUndoAction); //UNUSED2009-05 TYPEINIT1(ScUndoSetGrammar, SfxUndoAction); +TYPEINIT1(ScUndoTabColor, SfxUndoAction); // ----------------------------------------------------------------------- @@ -411,6 +413,8 @@ void ScUndoDeleteTab::Undo() pDoc->SetActiveScenario( nTab, bActive ); } pDoc->SetVisible( nTab, pRefUndoDoc->IsVisible( nTab ) ); + pDoc->SetTabBgColor( nTab, pRefUndoDoc->GetTabBgColor(nTab) ); + pDoc->SetSheetEvents( nTab, pRefUndoDoc->GetSheetEvents( nTab ) ); if ( pRefUndoDoc->IsTabProtected( nTab ) ) pDoc->SetTabProtection(nTab, pRefUndoDoc->GetTabProtection(nTab)); @@ -776,6 +780,78 @@ BOOL ScUndoCopyTab::CanRepeat(SfxRepeatTarget& /* rTarget */) const return FALSE; } +//--------------------------------------------------------------------------------- +// +// Tab Bg Color +// + +ScUndoTabColor::ScUndoTabColor( + ScDocShell* pNewDocShell, SCTAB nT, const Color& aOTabBgColor, const Color& aNTabBgColor) : + ScSimpleUndo( pNewDocShell ) +{ + ScUndoTabColorInfo aInfo(nT); + aInfo.maOldTabBgColor = aOTabBgColor; + aInfo.maNewTabBgColor = aNTabBgColor; + aTabColorList.push_back(aInfo); +} + +ScUndoTabColor::ScUndoTabColor( + ScDocShell* pNewDocShell, + const ScUndoTabColorInfo::List& rUndoTabColorList) : + ScSimpleUndo(pNewDocShell), + aTabColorList(rUndoTabColorList) +{ +} + +ScUndoTabColor::~ScUndoTabColor() +{ +} + +String ScUndoTabColor::GetComment() const +{ + if (aTabColorList.size() > 1) + return ScGlobal::GetRscString(STR_UNDO_SET_MULTI_TAB_BG_COLOR); + return ScGlobal::GetRscString(STR_UNDO_SET_TAB_BG_COLOR); +} + +void ScUndoTabColor::DoChange(bool bUndoType) const +{ + ScDocument* pDoc = pDocShell->GetDocument(); + if (!pDoc) + return; + + size_t nTabColorCount = aTabColorList.size(); + for (size_t i = 0; i < nTabColorCount; ++i) + { + const ScUndoTabColorInfo& rTabColor = aTabColorList[i]; + pDoc->SetTabBgColor(rTabColor.mnTabId, + bUndoType ? rTabColor.maOldTabBgColor : rTabColor.maNewTabBgColor); + } + + pDocShell->PostPaintExtras(); + ScDocShellModificator aModificator( *pDocShell ); + aModificator.SetDocumentModified(); +} + +void ScUndoTabColor::Undo() +{ + DoChange(true); +} + +void ScUndoTabColor::Redo() +{ + DoChange(false); +} + +void ScUndoTabColor::Repeat(SfxRepeatTarget& /* rTarget */) +{ + // No Repeat +} + +BOOL ScUndoTabColor::CanRepeat(SfxRepeatTarget& /* rTarget */) const +{ + return FALSE; +} // ----------------------------------------------------------------------- // diff --git a/sc/source/ui/unoobj/cellsuno.cxx b/sc/source/ui/unoobj/cellsuno.cxx index d563dea095dd..dea7cc056756 100644 --- a/sc/source/ui/unoobj/cellsuno.cxx +++ b/sc/source/ui/unoobj/cellsuno.cxx @@ -84,6 +84,7 @@ #include "srchuno.hxx" #include "targuno.hxx" #include "tokenuno.hxx" +#include "eventuno.hxx" #include "docsh.hxx" #include "markdata.hxx" #include "patattr.hxx" @@ -769,6 +770,8 @@ const SfxItemPropertySet* lcl_GetSheetPropertySet() {MAP_CHAR_LEN(SC_UNONAME_VALIXML), SC_WID_UNO_VALIXML, &getCppuType((uno::Reference<beans::XPropertySet>*)0), 0, 0 }, {MAP_CHAR_LEN(SC_UNONAME_CELLVJUS), ATTR_VER_JUSTIFY, &getCppuType((table::CellVertJustify*)0), 0, 0 }, {MAP_CHAR_LEN(SC_UNONAME_WRITING), ATTR_WRITINGDIR, &getCppuType((sal_Int16*)0), 0, 0 }, + {MAP_CHAR_LEN(SC_UNONAME_TABCOLOR), SC_WID_UNO_TABCOLOR, &getCppuType((sal_Int32*)0), 0, 0 }, + {MAP_CHAR_LEN(SC_UNO_CODENAME), SC_WID_UNO_CODENAME, &getCppuType(static_cast< const rtl::OUString * >(0)), 0, 0}, {0,0,0,0,0,0} }; static SfxItemPropertySet aSheetPropertySet( aSheetPropertyMap_Impl ); @@ -3374,18 +3377,25 @@ uno::Reference<sheet::XSheetCellRanges> SAL_CALL ScCellRangesBase::queryVisibleC ScMarkData aMarkData(*GetMarkData()); ScDocument* pDoc = pDocShell->GetDocument(); - for (SCCOL nCol=0; nCol<=MAXCOL; nCol++) - if (pDoc->GetColFlags(nCol,nTab) & CR_HIDDEN) - aMarkData.SetMultiMarkArea( ScRange( nCol,0,nTab, nCol,MAXROW,nTab ), FALSE ); + SCCOL nCol = 0, nLastCol; + while (nCol <= MAXCOL) + { + if (pDoc->ColHidden(nCol, nTab, nLastCol)) + // hidden columns. Unselect them. + aMarkData.SetMultiMarkArea(ScRange(nCol, 0, nTab, nLastCol, MAXROW, nTab), false); - //! nur bis zur letzten selektierten Zeile testen? - ScCompressedArrayIterator< SCROW, BYTE> aIter( pDoc->GetRowFlagsArray( nTab), 0, MAXROW); - do + nCol = nLastCol + 1; + } + + SCROW nRow = 0, nLastRow; + while (nRow <= MAXROW) { - if (*aIter & CR_HIDDEN) - aMarkData.SetMultiMarkArea( ScRange( 0, aIter.GetRangeStart(), - nTab, MAXCOL, aIter.GetRangeEnd(), nTab ), FALSE ); - } while (aIter.NextRange()); + if (pDoc->RowHidden(nRow, nTab, nLastRow)) + // These rows are hidden. Unselect them. + aMarkData.SetMultiMarkArea(ScRange(0, nRow, nTab, MAXCOL, nLastRow, nTab), false); + + nRow = nLastRow + 1; + } ScRangeList aNewRanges; aMarkData.FillRangeListWithMarks( &aNewRanges, FALSE ); @@ -5264,6 +5274,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 ); } @@ -6834,6 +6846,7 @@ uno::Any SAL_CALL ScTableSheetObj::queryInterface( const uno::Type& rType ) thro SC_QUERYINTERFACE( sheet::XScenarioEnhanced ) SC_QUERYINTERFACE( sheet::XSheetLinkable ) SC_QUERYINTERFACE( sheet::XExternalSheetName ) + SC_QUERYINTERFACE( document::XEventsSupplier ) return ScCellRangeObj::queryInterface( rType ); } @@ -6857,7 +6870,7 @@ uno::Sequence<uno::Type> SAL_CALL ScTableSheetObj::getTypes() throw(uno::Runtime long nParentLen = aParentTypes.getLength(); const uno::Type* pParentPtr = aParentTypes.getConstArray(); - aTypes.realloc( nParentLen + 17 ); + aTypes.realloc( nParentLen + 18 ); uno::Type* pPtr = aTypes.getArray(); pPtr[nParentLen + 0] = getCppuType((const uno::Reference<sheet::XSpreadsheet>*)0); pPtr[nParentLen + 1] = getCppuType((const uno::Reference<container::XNamed>*)0); @@ -6876,6 +6889,7 @@ uno::Sequence<uno::Type> SAL_CALL ScTableSheetObj::getTypes() throw(uno::Runtime pPtr[nParentLen +14] = getCppuType((const uno::Reference<sheet::XScenarioEnhanced>*)0); pPtr[nParentLen +15] = getCppuType((const uno::Reference<sheet::XSheetLinkable>*)0); pPtr[nParentLen +16] = getCppuType((const uno::Reference<sheet::XExternalSheetName>*)0); + pPtr[nParentLen +17] = getCppuType((const uno::Reference<document::XEventsSupplier>*)0); for (long i=0; i<nParentLen; i++) pPtr[i] = pParentPtr[i]; // parent types first @@ -7047,7 +7061,7 @@ uno::Sequence<sheet::TablePageBreakData> SAL_CALL ScTableSheetObj::getColumnPage SCCOL nCount = 0; SCCOL nCol; for (nCol=0; nCol<=MAXCOL; nCol++) - if (pDoc->GetColFlags( nCol, nTab ) & ( CR_PAGEBREAK | CR_MANUALBREAK )) + if (pDoc->HasColBreak(nCol, nTab)) ++nCount; sheet::TablePageBreakData aData; @@ -7056,11 +7070,11 @@ uno::Sequence<sheet::TablePageBreakData> SAL_CALL ScTableSheetObj::getColumnPage USHORT nPos = 0; for (nCol=0; nCol<=MAXCOL; nCol++) { - BYTE nFlags = pDoc->GetColFlags( nCol, nTab ); - if (nFlags & ( CR_PAGEBREAK | CR_MANUALBREAK )) + ScBreakType nBreak = pDoc->HasColBreak(nCol, nTab); + if (nBreak) { aData.Position = nCol; - aData.ManualBreak = ( nFlags & CR_MANUALBREAK ) != 0; + aData.ManualBreak = (nBreak & BREAK_MANUAL); pAry[nPos] = aData; ++nPos; } @@ -7089,33 +7103,7 @@ uno::Sequence<sheet::TablePageBreakData> SAL_CALL ScTableSheetObj::getRowPageBre ScPrintFunc aPrintFunc( pDocSh, pDocSh->GetPrinter(), nTab ); aPrintFunc.UpdatePages(); } - - SCROW nCount = pDoc->GetRowFlagsArray( nTab).CountForAnyBitCondition( - 0, MAXROW, (CR_PAGEBREAK | CR_MANUALBREAK)); - - uno::Sequence<sheet::TablePageBreakData> aSeq(nCount); - if (nCount) - { - sheet::TablePageBreakData aData; - sheet::TablePageBreakData* pAry = aSeq.getArray(); - size_t nPos = 0; - ScCompressedArrayIterator< SCROW, BYTE> aIter( pDoc->GetRowFlagsArray( nTab), 0, MAXROW); - do - { - BYTE nFlags = *aIter; - if (nFlags & ( CR_PAGEBREAK | CR_MANUALBREAK )) - { - for (SCROW nRow = aIter.GetRangeStart(); nRow <= aIter.GetRangeEnd(); ++nRow) - { - aData.Position = nRow; - aData.ManualBreak = ( nFlags & CR_MANUALBREAK ) != 0; - pAry[nPos] = aData; - ++nPos; - } - } - } while (aIter.NextRange()); - } - return aSeq; + return pDoc->GetRowBreakData(nTab); } return uno::Sequence<sheet::TablePageBreakData>(0); } @@ -8157,6 +8145,18 @@ void ScTableSheetObj::setExternalName( const ::rtl::OUString& aUrl, const ::rtl: } } +// XEventsSupplier + +uno::Reference<container::XNameReplace> SAL_CALL ScTableSheetObj::getEvents() throw (uno::RuntimeException) +{ + ScUnoGuard aGuard; + ScDocShell* pDocSh = GetDocShell(); + if ( pDocSh ) + return new ScSheetEventsObj( pDocSh, GetTab_Impl() ); + + return NULL; +} + // XPropertySet erweitert fuer Sheet-Properties uno::Reference<beans::XPropertySetInfo> SAL_CALL ScTableSheetObj::getPropertySetInfo() @@ -8468,6 +8468,24 @@ void ScTableSheetObj::SetOnePropertyValue( const SfxItemPropertySimpleEntry* pEn pDoc->ClearPrintRanges( nTab ); // if this flag is true, there are no PrintRanges, so Clear clears only the flag. } } + else if ( pEntry->nWID == SC_WID_UNO_TABCOLOR ) + { + sal_Int32 nColor = COL_AUTO; + if (aValue >>= nColor) + { + if (static_cast<ColorData>(nColor) != COL_AUTO) + pDoc->SetTabBgColor(nTab, Color(static_cast<ColorData>(nColor))); + } + } + else if ( pEntry->nWID == SC_WID_UNO_CODENAME ) + { + rtl::OUString aCodeName; + if ( pDocSh && ( aValue >>= aCodeName ) ) + { + String sNewName( aCodeName ); + pDocSh->GetDocument()->SetCodeName( GetTab_Impl(), sNewName ); + } + } else ScCellRangeObj::SetOnePropertyValue(pEntry, aValue); // base class, no Item WID } @@ -8606,6 +8624,17 @@ void ScTableSheetObj::GetOnePropertyValue( const SfxItemPropertySimpleEntry* pEn BOOL bAutoPrint = pDoc->IsPrintEntireSheet( nTab ); ScUnoHelpFunctions::SetBoolInAny( rAny, bAutoPrint ); } + else if ( pEntry->nWID == SC_WID_UNO_TABCOLOR ) + { + rAny <<= sal_Int32(pDoc->GetTabBgColor(nTab).GetColor()); + } + else if ( pEntry->nWID == SC_WID_UNO_CODENAME ) + { + String aCodeName; + if ( pDocSh ) + pDocSh->GetDocument()->GetCodeName( GetTab_Impl(), aCodeName ); + rAny <<= rtl::OUString( aCodeName ); + } else ScCellRangeObj::GetOnePropertyValue(pEntry, rAny); } @@ -8874,8 +8903,9 @@ void ScTableColumnObj::GetOnePropertyValue( const SfxItemPropertySimpleEntry* pE } else if ( pEntry->nWID == SC_WID_UNO_CELLVIS ) { - BOOL bVis = !(pDoc->GetColFlags( nCol, nTab ) & CR_HIDDEN); - ScUnoHelpFunctions::SetBoolInAny( rAny, bVis ); + SCCOL nDummy; + bool bHidden = pDoc->ColHidden(nCol, nTab, nDummy); + ScUnoHelpFunctions::SetBoolInAny( rAny, !bHidden ); } else if ( pEntry->nWID == SC_WID_UNO_OWIDTH ) { @@ -8885,13 +8915,13 @@ void ScTableColumnObj::GetOnePropertyValue( const SfxItemPropertySimpleEntry* pE } else if ( pEntry->nWID == SC_WID_UNO_NEWPAGE ) { - BOOL bBreak = ( 0 != (pDoc->GetColFlags( nCol, nTab ) & (CR_PAGEBREAK|CR_MANUALBREAK)) ); - ScUnoHelpFunctions::SetBoolInAny( rAny, bBreak ); + ScBreakType nBreak = pDoc->HasColBreak(nCol, nTab); + ScUnoHelpFunctions::SetBoolInAny( rAny, nBreak ); } else if ( pEntry->nWID == SC_WID_UNO_MANPAGE ) { - BOOL bBreak = ( 0 != (pDoc->GetColFlags( nCol, nTab ) & (CR_MANUALBREAK)) ); - ScUnoHelpFunctions::SetBoolInAny( rAny, bBreak ); + ScBreakType nBreak = pDoc->HasColBreak(nCol, nTab); + ScUnoHelpFunctions::SetBoolInAny(rAny, (nBreak & BREAK_MANUAL)); } else ScCellRangeObj::GetOnePropertyValue(pEntry, rAny); @@ -8977,12 +9007,7 @@ void ScTableRowObj::SetOnePropertyValue( const SfxItemPropertySimpleEntry* pEntr // ScSizeMode eMode = bVis ? SC_SIZE_SHOW : SC_SIZE_DIRECT; // aFunc.SetWidthOrHeight( FALSE, 1, nRowArr, nTab, eMode, 0, TRUE, TRUE ); // SC_SIZE_DIRECT mit Groesse 0 blendet aus - BYTE nFlags = pDoc->GetRowFlags(nRow, nTab); - if (bFil) - nFlags |= CR_FILTERED; - else - nFlags &= ~CR_FILTERED; - pDoc->SetRowFlags(nRow, nTab, nFlags); + pDoc->SetRowFiltered(nRow, nRow, nTab, bFil); } else if ( pEntry->nWID == SC_WID_UNO_OHEIGHT ) { @@ -9034,12 +9059,13 @@ void ScTableRowObj::GetOnePropertyValue( const SfxItemPropertySimpleEntry* pEntr } else if ( pEntry->nWID == SC_WID_UNO_CELLVIS ) { - BOOL bVis = !(pDoc->GetRowFlags( nRow, nTab ) & CR_HIDDEN); - ScUnoHelpFunctions::SetBoolInAny( rAny, bVis ); + SCROW nDummy; + bool bHidden = pDoc->RowHidden(nRow, nTab, nDummy); + ScUnoHelpFunctions::SetBoolInAny( rAny, !bHidden ); } else if ( pEntry->nWID == SC_WID_UNO_CELLFILT ) { - BOOL bVis = ((pDoc->GetRowFlags( nRow, nTab ) & CR_FILTERED) != 0); + bool bVis = pDoc->RowFiltered(nRow, nTab); ScUnoHelpFunctions::SetBoolInAny( rAny, bVis ); } else if ( pEntry->nWID == SC_WID_UNO_OHEIGHT ) @@ -9049,13 +9075,13 @@ void ScTableRowObj::GetOnePropertyValue( const SfxItemPropertySimpleEntry* pEntr } else if ( pEntry->nWID == SC_WID_UNO_NEWPAGE ) { - BOOL bBreak = ( 0 != (pDoc->GetRowFlags( nRow, nTab ) & (CR_PAGEBREAK|CR_MANUALBREAK)) ); - ScUnoHelpFunctions::SetBoolInAny( rAny, bBreak ); + ScBreakType nBreak = pDoc->HasRowBreak(nRow, nTab); + ScUnoHelpFunctions::SetBoolInAny( rAny, nBreak ); } else if ( pEntry->nWID == SC_WID_UNO_MANPAGE ) { - BOOL bBreak = ( 0 != (pDoc->GetRowFlags( nRow, nTab ) & (CR_MANUALBREAK)) ); - ScUnoHelpFunctions::SetBoolInAny( rAny, bBreak ); + ScBreakType nBreak = (pDoc->HasRowBreak(nRow, nTab) & BREAK_MANUAL); + ScUnoHelpFunctions::SetBoolInAny( rAny, nBreak ); } else ScCellRangeObj::GetOnePropertyValue(pEntry, rAny); diff --git a/sc/source/ui/unoobj/chart2uno.cxx b/sc/source/ui/unoobj/chart2uno.cxx index 8654de8a429e..8a8081e412d3 100644 --- a/sc/source/ui/unoobj/chart2uno.cxx +++ b/sc/source/ui/unoobj/chart2uno.cxx @@ -2569,14 +2569,17 @@ void ScChart2DataSequence::BuildDataCache() if (!ScRefTokenHelper::getRangeFromToken(aRange, *itr)) continue; + SCCOL nLastCol = -1; + SCROW nLastRow = -1; for (SCTAB nTab = aRange.aStart.Tab(); nTab <= aRange.aEnd.Tab(); ++nTab) { for (SCCOL nCol = aRange.aStart.Col(); nCol <= aRange.aEnd.Col(); ++nCol) { for (SCROW nRow = aRange.aStart.Row(); nRow <= aRange.aEnd.Row(); ++nRow) { - bool bColHidden = (m_pDocument->GetColFlags(nCol, nTab) & CR_HIDDEN); - bool bRowHidden = (m_pDocument->GetRowFlags(nRow, nTab) & CR_HIDDEN); + bool bColHidden = m_pDocument->ColHidden(nCol, nTab, nLastCol); + bool bRowHidden = m_pDocument->RowHidden(nRow, nTab, nLastRow); + if (bColHidden || bRowHidden) { // hidden cell diff --git a/sc/source/ui/unoobj/chartuno.cxx b/sc/source/ui/unoobj/chartuno.cxx index 201c411ea45c..86f59d66a7a4 100644 --- a/sc/source/ui/unoobj/chartuno.cxx +++ b/sc/source/ui/unoobj/chartuno.cxx @@ -31,10 +31,12 @@ #include <com/sun/star/embed/Aspects.hpp> #include <com/sun/star/awt/Size.hpp> +#include <com/sun/star/beans/PropertyAttribute.hpp> #include <com/sun/star/chart2/data/XDataReceiver.hpp> #include <com/sun/star/chart/ChartDataRowSource.hpp> #include <com/sun/star/chart2/XChartDocument.hpp> #include <com/sun/star/embed/Aspects.hpp> +#include <com/sun/star/table/CellRangeAddress.hpp> #include <svx/svditer.hxx> #include <svx/svdoole2.hxx> @@ -54,9 +56,12 @@ #include "chartlis.hxx" #include "unoguard.hxx" #include "chart2uno.hxx" +#include "convuno.hxx" using namespace com::sun::star; +#define PROP_HANDLE_RELATED_CELLRANGES 1 + //------------------------------------------------------------------------ SC_SIMPLE_SERVICE_INFO( ScChartObj, "ScChartObj", "com.sun.star.table.TableChart" ) @@ -222,7 +227,7 @@ void SAL_CALL ScChartsObj::addNewByName( const rtl::OUString& aName, xObj = pDocShell->GetEmbeddedObjectContainer().CreateEmbeddedObject( SvGlobalName( SO3_SCH_CLASSID ).GetByteSequence(), aTmp ); if ( xObj.is() ) { - String aObjName = aNameString; // wirklich eingefuegter Name... + String aObjName = aTmp; // wirklich eingefuegter Name... // Rechteck anpassen //! Fehler/Exception, wenn leer/ungueltig ??? @@ -451,12 +456,19 @@ sal_Bool SAL_CALL ScChartsObj::hasByName( const rtl::OUString& aName ) //------------------------------------------------------------------------ -ScChartObj::ScChartObj(ScDocShell* pDocSh, SCTAB nT, const String& rN) : - pDocShell( pDocSh ), - nTab( nT ), - aChartName( rN ) +ScChartObj::ScChartObj(ScDocShell* pDocSh, SCTAB nT, const String& rN) + :ScChartObj_Base( m_aMutex ) + ,ScChartObj_PBase( ScChartObj_Base::rBHelper ) + ,pDocShell( pDocSh ) + ,nTab( nT ) + ,aChartName( rN ) { pDocShell->GetDocument()->AddUnoObject(*this); + + uno::Sequence< table::CellRangeAddress > aInitialPropValue; + registerPropertyNoMember( ::rtl::OUString::createFromAscii( "RelatedCellRanges" ), + PROP_HANDLE_RELATED_CELLRANGES, beans::PropertyAttribute::MAYBEVOID, + ::getCppuType( &aInitialPropValue ), &aInitialPropValue ); } ScChartObj::~ScChartObj() @@ -552,6 +564,117 @@ void ScChartObj::Update_Impl( const ScRangeListRef& rRanges, bool bColHeaders, b } } +// ::comphelper::OPropertySetHelper + +::cppu::IPropertyArrayHelper& ScChartObj::getInfoHelper() +{ + return *ScChartObj_PABase::getArrayHelper(); +} + +void ScChartObj::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const uno::Any& rValue ) throw (uno::Exception) +{ + switch ( nHandle ) + { + case PROP_HANDLE_RELATED_CELLRANGES: + { + uno::Sequence< table::CellRangeAddress > aCellRanges; + if ( rValue >>= aCellRanges ) + { + ScRangeListRef rRangeList = new ScRangeList(); + const table::CellRangeAddress* pCellRanges = aCellRanges.getArray(); + sal_Int32 nCount = aCellRanges.getLength(); + for ( sal_Int32 i = 0; i < nCount; ++i ) + { + table::CellRangeAddress aCellRange = pCellRanges[ i ]; + ScRange aRange; + ScUnoConversion::FillScRange( aRange, aCellRange ); + rRangeList->Append( aRange ); + } + ScDocument* pDoc = ( pDocShell ? pDocShell->GetDocument() : NULL ); + ScChartListenerCollection* pCollection = ( pDoc ? pDoc->GetChartListenerCollection() : NULL ); + if ( pCollection ) + { + pCollection->ChangeListening( aChartName, rRangeList ); + } + } + } + break; + default: + { + } + break; + } +} + +void ScChartObj::getFastPropertyValue( uno::Any& rValue, sal_Int32 nHandle ) const +{ + switch ( nHandle ) + { + case PROP_HANDLE_RELATED_CELLRANGES: + { + ScDocument* pDoc = ( pDocShell ? pDocShell->GetDocument() : NULL ); + if ( pDoc ) + { + ScRange aEmptyRange; + USHORT nIndex = 0; + ScChartListener aSearcher( aChartName, pDoc, aEmptyRange ); + ScChartListenerCollection* pCollection = pDoc->GetChartListenerCollection(); + if ( pCollection && pCollection->Search( &aSearcher, nIndex ) ) + { + ScChartListener* pListener = static_cast< ScChartListener* >( pCollection->At( nIndex ) ); + if ( pListener ) + { + const ScRangeListRef& rRangeList = pListener->GetRangeList(); + if ( rRangeList.Is() ) + { + ULONG nCount = rRangeList->Count(); + uno::Sequence< table::CellRangeAddress > aCellRanges( nCount ); + table::CellRangeAddress* pCellRanges = aCellRanges.getArray(); + for ( USHORT i = 0; i < nCount; ++i ) + { + ScRange aRange( *rRangeList->GetObject( i ) ); + table::CellRangeAddress aCellRange; + ScUnoConversion::FillApiRange( aCellRange, aRange ); + pCellRanges[ i ] = aCellRange; + } + rValue <<= aCellRanges; + } + } + } + } + } + break; + default: + { + } + break; + } +} + +// ::comphelper::OPropertyArrayUsageHelper + +::cppu::IPropertyArrayHelper* ScChartObj::createArrayHelper() const +{ + uno::Sequence< beans::Property > aProps; + describeProperties( aProps ); + return new ::cppu::OPropertyArrayHelper( aProps ); +} + +// XInterface + +IMPLEMENT_FORWARD_XINTERFACE2( ScChartObj, ScChartObj_Base, ScChartObj_PBase ) + +// XTypeProvider + +IMPLEMENT_FORWARD_XTYPEPROVIDER2( ScChartObj, ScChartObj_Base, ScChartObj_PBase ) + +// XComponent + +void ScChartObj::disposing() +{ + ScChartObj_Base::disposing(); +} + // XTableChart sal_Bool SAL_CALL ScChartObj::getHasColumnHeaders() throw(uno::RuntimeException) @@ -681,6 +804,13 @@ void SAL_CALL ScChartObj::setName( const rtl::OUString& /* aName */ ) throw(uno: throw uno::RuntimeException(); // name cannot be changed } +// XPropertySet + +uno::Reference< beans::XPropertySetInfo > ScChartObj::getPropertySetInfo() throw (uno::RuntimeException) +{ + return createPropertySetInfo( getInfoHelper() ) ; +} + //------------------------------------------------------------------------ diff --git a/sc/source/ui/unoobj/confuno.cxx b/sc/source/ui/unoobj/confuno.cxx index dd8f15359559..75e415b8f018 100644 --- a/sc/source/ui/unoobj/confuno.cxx +++ b/sc/source/ui/unoobj/confuno.cxx @@ -88,6 +88,7 @@ const SfxItemPropertyMapEntry* lcl_GetConfigPropertyMap() {MAP_CHAR_LEN(SC_UNO_LOADREADONLY), 0, &getBooleanCppuType(), 0, 0}, // <-- {MAP_CHAR_LEN(SC_UNO_SHAREDOC), 0, &getBooleanCppuType(), 0, 0}, + {MAP_CHAR_LEN(SC_UNO_MODIFYPASSWORDINFO), 0, &getCppuType((uno::Sequence< beans::PropertyValue >*)0), 0, 0}, {0,0,0,0,0,0} }; return aConfigPropertyMap_Impl; @@ -274,6 +275,20 @@ void SAL_CALL ScDocumentConfiguration::setPropertyValue( pDocShell->SetSharedXMLFlag( bDocShared ); } } + else if ( aPropertyName.compareToAscii( SC_UNO_MODIFYPASSWORDINFO ) == 0 ) + { + uno::Sequence< beans::PropertyValue > aInfo; + if ( !( aValue >>= aInfo ) ) + throw lang::IllegalArgumentException( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Value of type Sequence<PropertyValue> expected!" ) ), + uno::Reference< uno::XInterface >(), + 2 ); + + if ( !pDocShell->SetModifyPasswordInfo( aInfo ) ) + throw beans::PropertyVetoException( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "The hash is not allowed to be changed now!" ) ), + uno::Reference< uno::XInterface >() ); + } else { ScGridOptions aGridOpt(aViewOpt.GetGridOptions()); @@ -407,6 +422,8 @@ uno::Any SAL_CALL ScDocumentConfiguration::getPropertyValue( const rtl::OUString { ScUnoHelpFunctions::SetBoolInAny( aRet, pDocShell->HasSharedXMLFlagSet() ); } + else if ( aPropertyName.compareToAscii( SC_UNO_MODIFYPASSWORDINFO ) == 0 ) + aRet <<= pDocShell->GetModifyPasswordInfo(); else { const ScGridOptions& aGridOpt = aViewOpt.GetGridOptions(); diff --git a/sc/source/ui/unoobj/defltuno.cxx b/sc/source/ui/unoobj/defltuno.cxx index 141a7d0abb73..f3f76685e5cb 100644 --- a/sc/source/ui/unoobj/defltuno.cxx +++ b/sc/source/ui/unoobj/defltuno.cxx @@ -46,6 +46,8 @@ #include "unonames.hxx" #include "docoptio.hxx" +#include <limits> + using namespace ::com::sun::star; //------------------------------------------------------------------------ @@ -157,7 +159,7 @@ void SAL_CALL ScDocDefaultsObj::setPropertyValue( sal_Int16 nValue = 0; if (aValue >>= nValue) { - aDocOpt.SetStdPrecision(static_cast<sal_uInt8> (nValue)); + aDocOpt.SetStdPrecision(static_cast<sal_uInt16> (nValue)); pDoc->SetDocOptions(aDocOpt); } } @@ -250,7 +252,12 @@ uno::Any SAL_CALL ScDocDefaultsObj::getPropertyValue( const rtl::OUString& aProp if (pDoc) { const ScDocOptions& aDocOpt = pDoc->GetDocOptions(); - aRet <<= static_cast<sal_Int16> (aDocOpt.GetStdPrecision()); + sal_uInt16 nPrec = aDocOpt.GetStdPrecision(); + // the max value of unsigned 16-bit integer is used as the flag + // value for unlimited precision, c.f. + // SvNumberFormatter::UNLIMITED_PRECISION. + if (nPrec <= ::std::numeric_limits<sal_Int16>::max()) + aRet <<= static_cast<sal_Int16> (nPrec); } else throw uno::RuntimeException(); diff --git a/sc/source/ui/unoobj/docuno.cxx b/sc/source/ui/unoobj/docuno.cxx index 85c17f868b0a..6d267d4098ff 100644 --- a/sc/source/ui/unoobj/docuno.cxx +++ b/sc/source/ui/unoobj/docuno.cxx @@ -96,6 +96,7 @@ #include "scmod.hxx" #include "rangeutl.hxx" #include "ViewSettingsSequenceDefines.hxx" +#include "sheetevents.hxx" #include "sc.hrc" #include "scresid.hxx" @@ -152,6 +153,7 @@ const SfxItemPropertyMapEntry* lcl_GetDocOptPropertyMap() {MAP_CHAR_LEN(SC_UNO_ISCHANGEREADONLYENABLED), 0, &getBooleanCppuType(), 0, 0}, {MAP_CHAR_LEN(SC_UNO_REFERENCEDEVICE), 0, &getCppuType((uno::Reference<awt::XDevice>*)0), beans::PropertyAttribute::READONLY, 0}, {MAP_CHAR_LEN("BuildId"), 0, &::getCppuType(static_cast< const rtl::OUString * >(0)), 0, 0}, + {MAP_CHAR_LEN(SC_UNO_CODENAME), 0, &getCppuType(static_cast< const rtl::OUString * >(0)), 0, 0}, {0,0,0,0,0,0} }; @@ -366,8 +368,7 @@ ScModelObj::ScModelObj( ScDocShell* pDocSh ) : pDocShell( pDocSh ), pPrintFuncCache( NULL ), pPrinterOptions( NULL ), - maChangesListeners( m_aMutex ), - mnXlsWriteProtPass( 0 ) + maChangesListeners( m_aMutex ) { // pDocShell may be NULL if this is the base of a ScDocOptionsObj if ( pDocShell ) @@ -590,6 +591,10 @@ void ScModelObj::Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) // (if a broadcast is added to SetDrawModified, is has to be tested here, too) DELETEZ( pPrintFuncCache ); + + // handle "OnCalculate" sheet events + if ( pDocShell && pDocShell->GetDocument()->HasSheetEventScript( SC_SHEETEVENT_CALCULATE ) ) + HandleCalculateEvents(); } } else if ( rHint.ISA( ScPointerChangedHint ) ) @@ -1039,18 +1044,21 @@ uno::Sequence<beans::PropertyValue> SAL_CALL ScModelObj::getRenderer( sal_Int32 Size aTwips = aFunc.GetPageSize(); awt::Size aPageSize( TwipsToHMM( aTwips.Width() ), TwipsToHMM( aTwips.Height() ) ); - long nPropCount = bWasCellRange ? 2 : 1; + long nPropCount = bWasCellRange ? 3 : 2; uno::Sequence<beans::PropertyValue> aSequence(nPropCount); beans::PropertyValue* pArray = aSequence.getArray(); pArray[0].Name = rtl::OUString::createFromAscii( SC_UNONAME_PAGESIZE ); pArray[0].Value <<= aPageSize; + // #i111158# all positions are relative to the whole page, including non-printable area + pArray[1].Name = rtl::OUString::createFromAscii( SC_UNONAME_INC_NP_AREA ); + pArray[1].Value = uno::makeAny( sal_True ); if ( bWasCellRange ) { table::CellRangeAddress aRangeAddress( nTab, aCellRange.aStart.Col(), aCellRange.aStart.Row(), aCellRange.aEnd.Col(), aCellRange.aEnd.Row() ); - pArray[1].Name = rtl::OUString::createFromAscii( SC_UNONAME_SOURCERANGE ); - pArray[1].Value <<= aRangeAddress; + pArray[2].Name = rtl::OUString::createFromAscii( SC_UNONAME_SOURCERANGE ); + pArray[2].Value <<= aRangeAddress; } #if 0 @@ -1652,6 +1660,12 @@ void SAL_CALL ScModelObj::setPropertyValue( pDoc->SetLanguage( eLatin, eCjk, eCtl ); } } + else if ( aString.EqualsAscii( SC_UNO_CODENAME ) ) + { + rtl::OUString sCodeName; + if ( aValue >>= sCodeName ) + pDoc->SetCodeName( sCodeName ); + } else if ( aString.EqualsAscii( SC_UNO_CJK_CLOCAL ) ) { lang::Locale aLocale; @@ -1736,14 +1750,6 @@ void SAL_CALL ScModelObj::setPropertyValue( if ( aObjName.getLength() ) pDoc->RestoreChartListener( aObjName ); } - else if ( aString.EqualsAscii( "WriteProtectionPassword" ) ) - { - /* This is a hack for #160550# to preserve the write-protection - password in an XLS roundtrip. This property MUST NOT be used - for any other purpose. This property will be deleted when the - feature "Write Protection With Password" will be implemented. */ - aValue >>= mnXlsWriteProtPass; - } if ( aNewOpt != rOldOpt ) { @@ -1784,6 +1790,12 @@ uno::Any SAL_CALL ScModelObj::getPropertyValue( const rtl::OUString& aPropertyNa ScUnoConversion::FillLocale( aLocale, eLatin ); aRet <<= aLocale; } + else if ( aString.EqualsAscii( SC_UNO_CODENAME ) ) + { + rtl::OUString sCodeName = pDoc->GetCodeName(); + aRet <<= sCodeName; + } + else if ( aString.EqualsAscii( SC_UNO_CJK_CLOCAL ) ) { LanguageType eLatin, eCjk, eCtl; @@ -1906,14 +1918,6 @@ uno::Any SAL_CALL ScModelObj::getPropertyValue( const rtl::OUString& aPropertyNa { ScUnoHelpFunctions::SetBoolInAny( aRet, (pDocShell->GetCreateMode() == SFX_CREATE_MODE_INTERNAL) ); } - else if ( aString.EqualsAscii( "WriteProtectionPassword" ) ) - { - /* This is a hack for #160550# to preserve the write-protection - password in an XLS roundtrip. This property MUST NOT be used - for any other purpose. This property will be deleted when the - feature "Write Protection With Password" will be implemented. */ - aRet <<= mnXlsWriteProtPass; - } } return aRet; @@ -2076,11 +2080,11 @@ sal_Int64 SAL_CALL ScModelObj::getSomething( } if ( rId.getLength() == 16 && - 0 == rtl_compareMemory( SfxObjectShell::getUnoTunnelId().getConstArray(), + 0 == rtl_compareMemory( SfxObjectShell::getUnoTunnelId().getConstArray(), rId.getConstArray(), 16 ) ) - { - return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(pDocShell )); - } + { + return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(pDocShell )); + } // aggregated number formats supplier has XUnoTunnel, too // interface from aggregated object must be obtained via queryAggregation @@ -2149,7 +2153,23 @@ void ScModelObj::removeChangesListener( const uno::Reference< util::XChangesList bool ScModelObj::HasChangesListeners() const { - return ( maChangesListeners.getLength() > 0 ); + if ( maChangesListeners.getLength() > 0 ) + return true; + + if ( pDocShell ) + { + // "change" event set in any sheet? + ScDocument* pDoc = pDocShell->GetDocument(); + SCTAB nTabCount = pDoc->GetTableCount(); + for (SCTAB nTab = 0; nTab < nTabCount; nTab++) + { + const ScSheetEvents* pEvents = pDoc->GetSheetEvents(nTab); + if (pEvents && pEvents->GetScript(SC_SHEETEVENT_CHANGE)) + return true; + } + } + + return false; } void ScModelObj::NotifyChanges( const ::rtl::OUString& rOperation, const ScRangeList& rRanges, @@ -2195,6 +2215,91 @@ void ScModelObj::NotifyChanges( const ::rtl::OUString& rOperation, const ScRange } } } + + // handle sheet events + //! separate method with ScMarkData? Then change HasChangesListeners back. + if ( rOperation.compareToAscii("cell-change") == 0 && pDocShell ) + { + ScMarkData aMarkData; + aMarkData.MarkFromRangeList( rRanges, FALSE ); + ScDocument* pDoc = pDocShell->GetDocument(); + SCTAB nTabCount = pDoc->GetTableCount(); + for (SCTAB nTab = 0; nTab < nTabCount; nTab++) + if (aMarkData.GetTableSelect(nTab)) + { + const ScSheetEvents* pEvents = pDoc->GetSheetEvents(nTab); + if (pEvents) + { + const rtl::OUString* pScript = pEvents->GetScript(SC_SHEETEVENT_CHANGE); + if (pScript) + { + ScRangeList aTabRanges; // collect ranges on this sheet + ULONG nRangeCount = rRanges.Count(); + for ( ULONG nIndex = 0; nIndex < nRangeCount; ++nIndex ) + { + ScRange aRange( *rRanges.GetObject( nIndex ) ); + if ( aRange.aStart.Tab() == nTab ) + aTabRanges.Append( aRange ); + } + ULONG nTabRangeCount = aTabRanges.Count(); + if ( nTabRangeCount > 0 ) + { + uno::Reference<uno::XInterface> xTarget; + if ( nTabRangeCount == 1 ) + { + ScRange aRange( *aTabRanges.GetObject( 0 ) ); + if ( aRange.aStart == aRange.aEnd ) + xTarget.set( static_cast<cppu::OWeakObject*>( new ScCellObj( pDocShell, aRange.aStart ) ) ); + else + xTarget.set( static_cast<cppu::OWeakObject*>( new ScCellRangeObj( pDocShell, aRange ) ) ); + } + else + xTarget.set( static_cast<cppu::OWeakObject*>( new ScCellRangesObj( pDocShell, aTabRanges ) ) ); + + uno::Sequence<uno::Any> aParams(1); + aParams[0] <<= xTarget; + + uno::Any aRet; + uno::Sequence<sal_Int16> aOutArgsIndex; + uno::Sequence<uno::Any> aOutArgs; + + /*ErrCode eRet =*/ pDocShell->CallXScript( *pScript, aParams, aRet, aOutArgsIndex, aOutArgs ); + } + } + } + } + } +} + +void ScModelObj::HandleCalculateEvents() +{ + if (pDocShell) + { + ScDocument* pDoc = pDocShell->GetDocument(); + // don't call events before the document is visible + // (might also set a flag on SFX_EVENT_LOADFINISHED and only disable while loading) + if ( pDoc->IsDocVisible() ) + { + SCTAB nTabCount = pDoc->GetTableCount(); + for (SCTAB nTab = 0; nTab < nTabCount; nTab++) + { + const ScSheetEvents* pEvents = pDoc->GetSheetEvents(nTab); + if (pEvents) + { + const rtl::OUString* pScript = pEvents->GetScript(SC_SHEETEVENT_CALCULATE); + if (pScript && pDoc->HasCalcNotification(nTab)) + { + uno::Any aRet; + uno::Sequence<uno::Any> aParams; + uno::Sequence<sal_Int16> aOutArgsIndex; + uno::Sequence<uno::Any> aOutArgs; + pDocShell->CallXScript( *pScript, aParams, aRet, aOutArgsIndex, aOutArgs ); + } + } + } + } + pDoc->ResetCalcNotifications(); + } } //------------------------------------------------------------------------ @@ -2949,7 +3054,8 @@ uno::Any SAL_CALL ScTableColumnsObj::getPropertyValue( const rtl::OUString& aPro } else if ( aNameString.EqualsAscii( SC_UNONAME_CELLVIS ) ) { - BOOL bVis = !(pDoc->GetColFlags( nStartCol, nTab ) & CR_HIDDEN); + SCCOL nLastCol; + bool bVis = !pDoc->ColHidden(nStartCol, nTab, nLastCol); ScUnoHelpFunctions::SetBoolInAny( aAny, bVis ); } else if ( aNameString.EqualsAscii( SC_UNONAME_OWIDTH ) ) @@ -2959,13 +3065,13 @@ uno::Any SAL_CALL ScTableColumnsObj::getPropertyValue( const rtl::OUString& aPro } else if ( aNameString.EqualsAscii( SC_UNONAME_NEWPAGE ) ) { - BOOL bBreak = ( 0 != (pDoc->GetColFlags( nStartCol, nTab ) & (CR_PAGEBREAK|CR_MANUALBREAK)) ); - ScUnoHelpFunctions::SetBoolInAny( aAny, bBreak ); + ScBreakType nBreak = pDoc->HasColBreak(nStartCol, nTab); + ScUnoHelpFunctions::SetBoolInAny( aAny, nBreak ); } else if ( aNameString.EqualsAscii( SC_UNONAME_MANPAGE ) ) { - BOOL bBreak = ( 0 != (pDoc->GetColFlags( nStartCol, nTab ) & (CR_MANUALBREAK)) ); - ScUnoHelpFunctions::SetBoolInAny( aAny, bBreak ); + ScBreakType nBreak = pDoc->HasColBreak(nStartCol, nTab); + ScUnoHelpFunctions::SetBoolInAny( aAny, (nBreak & BREAK_MANUAL) ); } return aAny; @@ -3125,8 +3231,11 @@ void SAL_CALL ScTableRowsObj::setPropertyValue( sal_Int32 nNewHeight = 0; if ( pDoc->IsImportingXML() && ( aValue >>= nNewHeight ) ) { - // used to set the stored row height for rows with optimal height when loading - pDoc->SetRowHeightRange( nStartRow, nEndRow, nTab, (USHORT)HMMToTwips(nNewHeight) ); + // used to set the stored row height for rows with optimal height when loading. + + // TODO: It's probably cleaner to use a different property name + // for this. + pDoc->SetRowHeightOnly( nStartRow, nEndRow, nTab, (USHORT)HMMToTwips(nNewHeight) ); } else { @@ -3157,9 +3266,9 @@ void SAL_CALL ScTableRowsObj::setPropertyValue( { //! undo etc. if (ScUnoHelpFunctions::GetBoolFromAny( aValue )) - pDoc->GetRowFlagsArrayModifiable( nTab).OrValue( nStartRow, nEndRow, CR_FILTERED); + pDoc->SetRowFiltered(nStartRow, nEndRow, nTab, true); else - pDoc->GetRowFlagsArrayModifiable( nTab).AndValue( nStartRow, nEndRow, sal::static_int_cast<BYTE>(~CR_FILTERED) ); + pDoc->SetRowFiltered(nStartRow, nEndRow, nTab, false); } else if ( aNameString.EqualsAscii( SC_UNONAME_NEWPAGE) || aNameString.EqualsAscii( SC_UNONAME_MANPAGE) ) { @@ -3207,12 +3316,13 @@ uno::Any SAL_CALL ScTableRowsObj::getPropertyValue( const rtl::OUString& aProper } else if ( aNameString.EqualsAscii( SC_UNONAME_CELLVIS ) ) { - BOOL bVis = !(pDoc->GetRowFlags( nStartRow, nTab ) & CR_HIDDEN); + SCROW nLastRow; + bool bVis = !pDoc->RowHidden(nStartRow, nTab, nLastRow); ScUnoHelpFunctions::SetBoolInAny( aAny, bVis ); } else if ( aNameString.EqualsAscii( SC_UNONAME_CELLFILT ) ) { - BOOL bVis = ((pDoc->GetRowFlags( nStartRow, nTab ) & CR_FILTERED) != 0); + bool bVis = pDoc->RowFiltered(nStartRow, nTab); ScUnoHelpFunctions::SetBoolInAny( aAny, bVis ); } else if ( aNameString.EqualsAscii( SC_UNONAME_OHEIGHT ) ) @@ -3222,13 +3332,13 @@ uno::Any SAL_CALL ScTableRowsObj::getPropertyValue( const rtl::OUString& aProper } else if ( aNameString.EqualsAscii( SC_UNONAME_NEWPAGE ) ) { - BOOL bBreak = ( 0 != (pDoc->GetRowFlags( nStartRow, nTab ) & (CR_PAGEBREAK|CR_MANUALBREAK)) ); - ScUnoHelpFunctions::SetBoolInAny( aAny, bBreak ); + ScBreakType nBreak = pDoc->HasRowBreak(nStartRow, nTab); + ScUnoHelpFunctions::SetBoolInAny( aAny, nBreak ); } else if ( aNameString.EqualsAscii( SC_UNONAME_MANPAGE ) ) { - BOOL bBreak = ( 0 != (pDoc->GetRowFlags( nStartRow, nTab ) & (CR_MANUALBREAK)) ); - ScUnoHelpFunctions::SetBoolInAny( aAny, bBreak ); + ScBreakType nBreak = pDoc->HasRowBreak(nStartRow, nTab); + ScUnoHelpFunctions::SetBoolInAny( aAny, (nBreak & BREAK_MANUAL) ); } else if ( aNameString.EqualsAscii( SC_UNONAME_CELLBACK ) || aNameString.EqualsAscii( SC_UNONAME_CELLTRAN ) ) { diff --git a/sc/source/ui/unoobj/eventuno.cxx b/sc/source/ui/unoobj/eventuno.cxx new file mode 100755 index 000000000000..d7de00f4cc56 --- /dev/null +++ b/sc/source/ui/unoobj/eventuno.cxx @@ -0,0 +1,201 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: tokenuno.cxx,v $ + * $Revision: 1.6.108.8 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + +#include "eventuno.hxx" +#include "miscuno.hxx" +#include "unoguard.hxx" +#include "docsh.hxx" +#include "sheetevents.hxx" +#include "unonames.hxx" + +using namespace ::com::sun::star; + +//------------------------------------------------------------------------ + +SC_SIMPLE_SERVICE_INFO( ScSheetEventsObj, "ScSheetEventsObj", "com.sun.star.document.Events" ) + +//------------------------------------------------------------------------ + +ScSheetEventsObj::ScSheetEventsObj(ScDocShell* pDocSh, SCTAB nT) : + mpDocShell( pDocSh ), + mnTab( nT ) +{ + mpDocShell->GetDocument()->AddUnoObject(*this); +} + +ScSheetEventsObj::~ScSheetEventsObj() +{ + if (mpDocShell) + mpDocShell->GetDocument()->RemoveUnoObject(*this); +} + +void ScSheetEventsObj::Notify( SfxBroadcaster&, const SfxHint& rHint ) +{ + //! reference update + if ( rHint.ISA( SfxSimpleHint ) && + ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING ) + { + mpDocShell = NULL; + } +} + +sal_Int32 lcl_GetEventFromName( const rtl::OUString& aName ) +{ + for (sal_Int32 nEvent=0; nEvent<SC_SHEETEVENT_COUNT; ++nEvent) + if ( aName == ScSheetEvents::GetEventName(nEvent) ) + return nEvent; + + return -1; // not found +} + +// XNameReplace + +void SAL_CALL ScSheetEventsObj::replaceByName( const rtl::OUString& aName, const uno::Any& aElement ) + throw(lang::IllegalArgumentException, container::NoSuchElementException, + lang::WrappedTargetException, uno::RuntimeException) +{ + ScUnoGuard aGuard; + if (!mpDocShell) + throw uno::RuntimeException(); + + sal_Int32 nEvent = lcl_GetEventFromName(aName); + if (nEvent < 0) + throw container::NoSuchElementException(); + + ScSheetEvents aNewEvents; + const ScSheetEvents* pOldEvents = mpDocShell->GetDocument()->GetSheetEvents(mnTab); + if (pOldEvents) + aNewEvents = *pOldEvents; + + rtl::OUString aScript; + if ( aElement.hasValue() ) // empty Any -> reset event + { + uno::Sequence<beans::PropertyValue> aPropSeq; + if ( aElement >>= aPropSeq ) + { + sal_Int32 nPropCount = aPropSeq.getLength(); + for (sal_Int32 nPos=0; nPos<nPropCount; ++nPos) + { + const beans::PropertyValue& rProp = aPropSeq[nPos]; + if ( rProp.Name.compareToAscii( SC_UNO_EVENTTYPE ) == 0 ) + { + rtl::OUString aEventType; + if ( rProp.Value >>= aEventType ) + { + // only "Script" is supported + if ( aEventType.compareToAscii( SC_UNO_SCRIPT ) != 0 ) + throw lang::IllegalArgumentException(); + } + } + else if ( rProp.Name.compareToAscii( SC_UNO_SCRIPT ) == 0 ) + rProp.Value >>= aScript; + } + } + } + if (aScript.getLength()) + aNewEvents.SetScript( nEvent, &aScript ); + else + aNewEvents.SetScript( nEvent, NULL ); // reset + + mpDocShell->GetDocument()->SetSheetEvents( mnTab, &aNewEvents ); + mpDocShell->SetDocumentModified(); +} + +// XNameAccess + +uno::Any SAL_CALL ScSheetEventsObj::getByName( const rtl::OUString& aName ) + throw(container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) +{ + ScUnoGuard aGuard; + sal_Int32 nEvent = lcl_GetEventFromName(aName); + if (nEvent < 0) + throw container::NoSuchElementException(); + + const rtl::OUString* pScript = NULL; + if (mpDocShell) + { + const ScSheetEvents* pEvents = mpDocShell->GetDocument()->GetSheetEvents(mnTab); + if (pEvents) + pScript = pEvents->GetScript(nEvent); + } + + uno::Any aRet; + if (pScript) + { + uno::Sequence<beans::PropertyValue> aPropSeq( 2 ); + aPropSeq[0] = beans::PropertyValue( + rtl::OUString::createFromAscii("EventType"), -1, + uno::makeAny( rtl::OUString::createFromAscii("Script") ), beans::PropertyState_DIRECT_VALUE ); + aPropSeq[1] = beans::PropertyValue( + rtl::OUString::createFromAscii("Script"), -1, + uno::makeAny( *pScript ), beans::PropertyState_DIRECT_VALUE ); + aRet <<= aPropSeq; + } + // empty Any if nothing was set + return aRet; +} + +uno::Sequence<rtl::OUString> SAL_CALL ScSheetEventsObj::getElementNames() throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + uno::Sequence<rtl::OUString> aNames(SC_SHEETEVENT_COUNT); + for (sal_Int32 nEvent=0; nEvent<SC_SHEETEVENT_COUNT; ++nEvent) + aNames[nEvent] = ScSheetEvents::GetEventName(nEvent); + return aNames; +} + +sal_Bool SAL_CALL ScSheetEventsObj::hasByName( const ::rtl::OUString& aName ) throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + sal_Int32 nEvent = lcl_GetEventFromName(aName); + return (nEvent >= 0); +} + +// XElementAccess + +uno::Type SAL_CALL ScSheetEventsObj::getElementType() throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + return getCppuType((uno::Sequence<beans::PropertyValue>*)0); +} + +sal_Bool SAL_CALL ScSheetEventsObj::hasElements() throw(uno::RuntimeException) +{ + ScUnoGuard aGuard; + if (mpDocShell) + return sal_True; + return sal_False; +} + + + diff --git a/sc/source/ui/unoobj/filtuno.cxx b/sc/source/ui/unoobj/filtuno.cxx index 8591f2fc0801..efe804784a40 100644 --- a/sc/source/ui/unoobj/filtuno.cxx +++ b/sc/source/ui/unoobj/filtuno.cxx @@ -185,7 +185,9 @@ sal_Int16 SAL_CALL ScFilterOptionsObj::execute() throw(uno::RuntimeException) } else if ( aFilterString == ScDocShell::GetWebQueryFilterName() || aFilterString == ScDocShell::GetHtmlFilterName() ) { - if (!bExport) + if (bExport) + nRet = ui::dialogs::ExecutableDialogResults::OK; // export HTML without dialog + else { // HTML import. ::std::auto_ptr<AbstractScTextImportOptionsDlg> pDlg( diff --git a/sc/source/ui/unoobj/funcuno.cxx b/sc/source/ui/unoobj/funcuno.cxx index 0c197a8b738d..7012b477050c 100644 --- a/sc/source/ui/unoobj/funcuno.cxx +++ b/sc/source/ui/unoobj/funcuno.cxx @@ -34,6 +34,7 @@ #include <sfx2/app.hxx> #include <svl/itemprop.hxx> +#include "scitems.hxx" #include "funcuno.hxx" #include "miscuno.hxx" #include "cellsuno.hxx" @@ -55,6 +56,7 @@ #include "docpool.hxx" #include "attrib.hxx" #include "clipparam.hxx" +#include "dociter.hxx" using namespace com::sun::star; @@ -185,6 +187,32 @@ BOOL lcl_CopyData( ScDocument* pSrcDoc, const ScRange& rSrcRange, pClipDoc->ApplyPatternAreaTab( 0,0, MAXCOL,MAXROW, nSrcTab, aPattern ); } + // If the range contains formula cells with default number format, + // apply a number format for the formula result + ScCellIterator aIter( pClipDoc, rSrcRange ); + ScBaseCell* pCell = aIter.GetFirst(); + while (pCell) + { + if (pCell->GetCellType() == CELLTYPE_FORMULA) + { + ScAddress aCellPos = aIter.GetPos(); + sal_uInt32 nFormat = pClipDoc->GetNumberFormat(aCellPos); + if ( (nFormat % SV_COUNTRY_LANGUAGE_OFFSET) == 0 ) + { + ScFormulaCell* pFCell = static_cast<ScFormulaCell*>(pCell); + USHORT nErrCode = pFCell->GetErrCode(); + if ( nErrCode == 0 && pFCell->IsValue() ) + { + sal_uInt32 nNewFormat = pFCell->GetStandardFormat( *pClipDoc->GetFormatTable(), nFormat ); + if ( nNewFormat != nFormat ) + pClipDoc->ApplyAttr( aCellPos.Col(), aCellPos.Row(), aCellPos.Tab(), + SfxUInt32Item( ATTR_VALUE_FORMAT, nNewFormat ) ); + } + } + } + pCell = aIter.GetNext(); + } + ScMarkData aDestMark; aDestMark.SelectOneTable( nDestTab ); aDestMark.SetMarkArea( aNewRange ); @@ -199,7 +227,8 @@ BOOL lcl_CopyData( ScDocument* pSrcDoc, const ScRange& rSrcRange, ScFunctionAccess::ScFunctionAccess() : pOptions( NULL ), aPropertyMap( ScDocOptionsHelper::GetPropertyMap() ), - bInvalid( FALSE ) + mbArray( true ), // default according to behaviour of older Office versions + mbValid( true ) { StartListening( *SFX_APP() ); // for SFX_HINT_DEINITIALIZING } @@ -216,7 +245,7 @@ void ScFunctionAccess::Notify( SfxBroadcaster&, const SfxHint& rHint ) { // document must not be used anymore aDocCache.Clear(); - bInvalid = TRUE; + mbValid = false; } } @@ -288,14 +317,22 @@ void SAL_CALL ScFunctionAccess::setPropertyValue( { ScUnoGuard aGuard; - if ( !pOptions ) - pOptions = new ScDocOptions(); + if( aPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsArrayFunction" ) ) ) + { + if( !(aValue >>= mbArray) ) + throw lang::IllegalArgumentException(); + } + else + { + if ( !pOptions ) + pOptions = new ScDocOptions(); - // options aren't initialized from configuration - always get the same default behaviour + // options aren't initialized from configuration - always get the same default behaviour - BOOL bDone = ScDocOptionsHelper::setPropertyValue( *pOptions, aPropertyMap, aPropertyName, aValue ); - if (!bDone) - throw beans::UnknownPropertyException(); + BOOL bDone = ScDocOptionsHelper::setPropertyValue( *pOptions, aPropertyMap, aPropertyName, aValue ); + if (!bDone) + throw beans::UnknownPropertyException(); + } } uno::Any SAL_CALL ScFunctionAccess::getPropertyValue( const rtl::OUString& aPropertyName ) @@ -304,6 +341,9 @@ uno::Any SAL_CALL ScFunctionAccess::getPropertyValue( const rtl::OUString& aProp { ScUnoGuard aGuard; + if( aPropertyName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "IsArrayFunction" ) ) ) + return uno::Any( mbArray ); + if ( !pOptions ) pOptions = new ScDocOptions(); @@ -497,7 +537,7 @@ uno::Any SAL_CALL ScFunctionAccess::callFunction( const rtl::OUString& aName, { ScUnoGuard aGuard; - if (bInvalid) + if (!mbValid) throw uno::RuntimeException(); // use cached document if not in use, temporary document otherwise @@ -556,12 +596,13 @@ uno::Any SAL_CALL ScFunctionAccess::callFunction( const rtl::OUString& aName, uno::TypeClass eClass = rArg.getValueTypeClass(); uno::Type aType = rArg.getValueType(); if ( eClass == uno::TypeClass_BYTE || - eClass == uno::TypeClass_SHORT || - eClass == uno::TypeClass_UNSIGNED_SHORT || - eClass == uno::TypeClass_LONG || - eClass == uno::TypeClass_UNSIGNED_LONG || - eClass == uno::TypeClass_FLOAT || - eClass == uno::TypeClass_DOUBLE ) + eClass == uno::TypeClass_BOOLEAN || + eClass == uno::TypeClass_SHORT || + eClass == uno::TypeClass_UNSIGNED_SHORT || + eClass == uno::TypeClass_LONG || + eClass == uno::TypeClass_UNSIGNED_LONG || + eClass == uno::TypeClass_FLOAT || + eClass == uno::TypeClass_DOUBLE ) { // #87871# accept integer types because Basic passes a floating point // variable as byte, short or long if it's an integer number. @@ -650,13 +691,13 @@ uno::Any SAL_CALL ScFunctionAccess::callFunction( const rtl::OUString& aName, // GRAM_PODF_A1 doesn't really matter for the token array but fits with // other API compatibility grammars. ScFormulaCell* pFormula = new ScFormulaCell( pDoc, aFormulaPos, - &aTokenArr,formula::FormulaGrammar::GRAM_PODF_A1, MM_FORMULA ); + &aTokenArr, formula::FormulaGrammar::GRAM_PODF_A1, (BYTE)(mbArray ? MM_FORMULA : MM_NONE) ); pDoc->PutCell( aFormulaPos, pFormula ); //! necessary? // call GetMatrix before GetErrCode because GetMatrix always recalculates // if there is no matrix result - const ScMatrix* pMat = pFormula->GetMatrix(); + const ScMatrix* pMat = mbArray ? pFormula->GetMatrix() : 0; USHORT nErrCode = pFormula->GetErrCode(); if ( nErrCode == 0 ) { 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/makefile.mk b/sc/source/ui/unoobj/makefile.mk index 35fdf164bf92..36c3493ceefc 100644 --- a/sc/source/ui/unoobj/makefile.mk +++ b/sc/source/ui/unoobj/makefile.mk @@ -79,6 +79,7 @@ SLO1FILES = \ $(SLO)$/filtuno.obj \ $(SLO)$/unodoc.obj \ $(SLO)$/addruno.obj \ + $(SLO)$/eventuno.obj \ $(SLO)$/listenercalls.obj \ $(SLO)$/cellvaluebinding.obj \ $(SLO)$/celllistsource.obj \ diff --git a/sc/source/ui/unoobj/nameuno.cxx b/sc/source/ui/unoobj/nameuno.cxx index 474d07764127..75686df460d6 100644 --- a/sc/source/ui/unoobj/nameuno.cxx +++ b/sc/source/ui/unoobj/nameuno.cxx @@ -340,7 +340,7 @@ uno::Reference<table::XCellRange> SAL_CALL ScNamedRangeObj::getReferredCells() ScUnoGuard aGuard; ScRange aRange; ScRangeData* pData = GetRangeData_Impl(); - if ( pData && pData->IsReference( aRange ) ) + if ( pData && pData->IsValidReference( aRange ) ) { //! static Funktion um ScCellObj/ScCellRangeObj zu erzeugen am ScCellRangeObj ??? diff --git a/sc/source/ui/unoobj/scdetect.cxx b/sc/source/ui/unoobj/scdetect.cxx index cded62efa3a8..03d6d14a3ac7 100644..100755 --- a/sc/source/ui/unoobj/scdetect.cxx +++ b/sc/source/ui/unoobj/scdetect.cxx @@ -256,6 +256,7 @@ static BOOL lcl_IsAnyXMLFilter( const SfxFilter* pFilter ) sal_Int32 nIndexOfReadOnlyFlag = -1; sal_Int32 nIndexOfTemplateFlag = -1; sal_Int32 nIndexOfDocumentTitle = -1; + bool bFakeXLS = false; for( sal_Int32 nProperty=0; nProperty<nPropertyCount; ++nProperty ) { @@ -297,7 +298,7 @@ static BOOL lcl_IsAnyXMLFilter( const SfxFilter* pFilter ) } else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("InteractionHandler")) ) lDescriptor[nProperty].Value >>= xInteraction; - else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("RapairPackage")) ) + else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("RepairPackage")) ) lDescriptor[nProperty].Value >>= bRepairPackage; else if( lDescriptor[nProperty].Name == OUString(RTL_CONSTASCII_USTRINGPARAM("DocumentTitle")) ) nIndexOfDocumentTitle = nProperty; @@ -436,8 +437,11 @@ static BOOL lcl_IsAnyXMLFilter( const SfxFilter* pFilter ) } else { + bool bIsXLS = false; SvStream* pStream = aMedium.GetInStream(); const SfxFilter* pPreselectedFilter = pFilter; + if ( pPreselectedFilter && pPreselectedFilter->GetName().SearchAscii("Excel") != STRING_NOTFOUND ) + bIsXLS = true; pFilter = 0; if ( pStream ) { @@ -718,7 +722,8 @@ static BOOL lcl_IsAnyXMLFilter( const SfxFilter* pFilter ) // further checks for filters only if they are preselected: ASCII, HTML, RTF, DBase // without the preselection other filters (Writer) take precedence // DBase can't be detected reliably, so it also needs preselection - if ( pPreselectedFilter->GetFilterName().EqualsAscii(pFilterAscii) && lcl_MayBeAscii( rStr ) ) + bool bMaybeText = lcl_MayBeAscii( rStr ); + if ( pPreselectedFilter->GetFilterName().EqualsAscii(pFilterAscii) && bMaybeText ) { // Text filter is accepted if preselected pFilter = pPreselectedFilter; @@ -747,8 +752,15 @@ static BOOL lcl_IsAnyXMLFilter( const SfxFilter* pFilter ) else { pFilter = aMatcher.GetFilter4FilterName( String::CreateFromAscii(pFilterHtmlWeb) ); + if ( bIsXLS ) + bFakeXLS = true; } } + else if ( bIsXLS && bMaybeText ) + { + pFilter = aMatcher.GetFilter4FilterName( String::CreateFromAscii(pFilterAscii) ); + bFakeXLS = true; + } else if ( aHeader.CompareTo( "{\\rtf", 5 ) == COMPARE_EQUAL ) { // test for RTF @@ -834,6 +846,19 @@ static BOOL lcl_IsAnyXMLFilter( const SfxFilter* pFilter ) lDescriptor[nIndexOfDocumentTitle].Value <<= aDocumentTitle; } + if ( bFakeXLS ) + { + if ( nIndexOfFilterName == -1 ) + { + lDescriptor.realloc( nPropertyCount + 1 ); + lDescriptor[nPropertyCount].Name = ::rtl::OUString::createFromAscii("FilterName"); + lDescriptor[nPropertyCount].Value <<= rtl::OUString(pFilter->GetName()); + nPropertyCount++; + } + else + lDescriptor[nIndexOfFilterName].Value <<= rtl::OUString(pFilter->GetName()); + } + if ( pFilter ) aTypeName = pFilter->GetTypeName(); else diff --git a/sc/source/ui/unoobj/servuno.cxx b/sc/source/ui/unoobj/servuno.cxx index 956c659f9b15..0b3a6f01f9ea 100644 --- a/sc/source/ui/unoobj/servuno.cxx +++ b/sc/source/ui/unoobj/servuno.cxx @@ -37,6 +37,7 @@ #include <com/sun/star/sheet/XSpreadsheetDocument.hpp> #include "servuno.hxx" +#include "unoguard.hxx" #include "unonames.hxx" #include "cellsuno.hxx" #include "fielduno.hxx" @@ -71,6 +72,121 @@ using namespace ::com::sun::star; +#ifndef CWS_NPOWER14MISCFIXES +uno::Reference< uno::XInterface > lcl_createVBAUnoAPIServiceWithArgs( SfxObjectShell* pShell, const sal_Char* _pAsciiName, const uno::Sequence< uno::Any >& aArgs ) throw (uno::RuntimeException) +{ + uno::Any aUnoVar; + if ( !pShell || !pShell->GetBasicManager()->GetGlobalUNOConstant( "VBAGlobals", aUnoVar ) ) + throw lang::IllegalArgumentException(); + uno::Reference< lang::XMultiServiceFactory > xVBAFactory( aUnoVar, uno::UNO_QUERY_THROW ); + ::rtl::OUString sVarName( ::rtl::OUString::createFromAscii( _pAsciiName ) ); + uno::Reference< uno::XInterface > xIf = xVBAFactory->createInstanceWithArguments( sVarName, aArgs ); + return xIf; +} +#endif + +class ScVbaObjectForCodeNameProvider : public ::cppu::WeakImplHelper1< container::XNameAccess > +{ + uno::Any maWorkbook; + uno::Any maCachedObject; + ScDocShell* mpDocShell; +public: + ScVbaObjectForCodeNameProvider( ScDocShell* pDocShell ) : mpDocShell( pDocShell ) + { + ScDocument* pDoc = mpDocShell->GetDocument(); + if ( !pDoc ) + throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("")), uno::Reference< uno::XInterface >() ); + + uno::Sequence< uno::Any > aArgs(2); + aArgs[0] = uno::Any( uno::Reference< uno::XInterface >() ); + aArgs[1] = uno::Any( mpDocShell->GetModel() ); +#ifdef CWS_NPOWER14MISCFIXES + maWorkbook <<= ooo::vba::createVBAUnoAPIServiceWithArgs( mpDocShell, "ooo.vba.excel.Workbook", aArgs ); +#else + maWorkbook <<= lcl_createVBAUnoAPIServiceWithArgs( mpDocShell, "ooo.vba.excel.Workbook", aArgs ); +#endif + } + + virtual ::sal_Bool SAL_CALL hasByName( const ::rtl::OUString& aName ) throw (::com::sun::star::uno::RuntimeException ) + { + ScUnoGuard aGuard; + maCachedObject = uno::Any(); // clear cached object + String sName = aName; + + ScDocument* pDoc = mpDocShell->GetDocument(); + if ( !pDoc ) + throw uno::RuntimeException(); + if ( sName == pDoc->GetCodeName() ) + maCachedObject = maWorkbook; + else + { + String sCodeName; + SCTAB nCount = pDoc->GetTableCount(); + for( SCTAB i = 0; i < nCount; i++ ) + { + pDoc->GetCodeName( i, sCodeName ); + if( sCodeName == sName ) + { + String sSheetName; + if( pDoc->GetName( i, sSheetName ) ) + { + uno::Reference< frame::XModel > xModel( mpDocShell->GetModel() ); + uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( xModel, uno::UNO_QUERY_THROW ); + uno::Reference<sheet::XSpreadsheets > xSheets( xSpreadDoc->getSheets(), uno::UNO_QUERY_THROW ); + uno::Reference< container::XIndexAccess > xIndexAccess( xSheets, uno::UNO_QUERY_THROW ); + uno::Reference< sheet::XSpreadsheet > xSheet( xIndexAccess->getByIndex( i ), uno::UNO_QUERY_THROW ); + uno::Sequence< uno::Any > aArgs(3); + aArgs[0] = maWorkbook; + aArgs[1] = uno::Any( xModel ); + aArgs[2] = uno::Any( rtl::OUString( sSheetName ) ); +#ifdef CWS_NPOWER14MISCFIXES + // use the convience function + maCachedObject <<= ooo::vba::createVBAUnoAPIServiceWithArgs( mpDocShell, "ooo.vba.excel.Worksheet", aArgs ); +#else + // use the temp function + maCachedObject <<= lcl_createVBAUnoAPIServiceWithArgs( mpDocShell, "ooo.vba.excel.Worksheet", aArgs ); +#endif + break; + } + } + } + } + return maCachedObject.hasValue(); + + } + ::com::sun::star::uno::Any SAL_CALL getByName( const ::rtl::OUString& aName ) throw (::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException) + { + ScUnoGuard aGuard; + OSL_TRACE("ScVbaObjectForCodeNameProvider::getByName( %s )", + rtl::OUStringToOString( aName, RTL_TEXTENCODING_UTF8 ).getStr() ); + if ( !hasByName( aName ) ) + throw ::com::sun::star::container::NoSuchElementException(); + return maCachedObject; + } + virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getElementNames( ) throw (::com::sun::star::uno::RuntimeException) + { + ScUnoGuard aGuard; + ScDocument* pDoc = mpDocShell->GetDocument(); + if ( !pDoc ) + throw uno::RuntimeException(); + SCTAB nCount = pDoc->GetTableCount(); + uno::Sequence< rtl::OUString > aNames( nCount + 1 ); + SCTAB index = 0; + String sCodeName; + for( ; index < nCount; ++index ) + { + pDoc->GetCodeName( index, sCodeName ); + aNames[ index ] = sCodeName; + } + aNames[ index ] = pDoc->GetCodeName(); + return aNames; + } + // XElemenAccess + virtual ::com::sun::star::uno::Type SAL_CALL getElementType( ) throw (::com::sun::star::uno::RuntimeException){ return uno::Type(); } + virtual ::sal_Bool SAL_CALL hasElements( ) throw (::com::sun::star::uno::RuntimeException ) { return sal_True; } + +}; + class ScVbaCodeNameProvider : public ::cppu::WeakImplHelper1< document::XCodeNameQuery > { ScDocShell* mpDocShell; @@ -79,6 +195,7 @@ public: // XCodeNameQuery rtl::OUString SAL_CALL getCodeNameForObject( const uno::Reference< uno::XInterface >& xIf ) throw( uno::RuntimeException ) { + ScUnoGuard aGuard; rtl::OUString sCodeName; if ( mpDocShell ) { @@ -176,7 +293,9 @@ static const ProvNamesId_Type __FAR_DATA aProvNamesId[] = { SC_SERVICENAME_CHDATAPROV, SC_SERVICE_CHDATAPROV }, { SC_SERVICENAME_FORMULAPARS, SC_SERVICE_FORMULAPARS }, { SC_SERVICENAME_OPCODEMAPPER, SC_SERVICE_OPCODEMAPPER }, + { "ooo.vba.VBAObjectModuleObjectProvider", SC_SERVICE_VBAOBJECTPROVIDER }, { "ooo.vba.VBACodeNameProvider", SC_SERVICE_VBACODENAMEPROVIDER }, + { "ooo.vba.VBAGlobals", SC_SERVICE_VBAGLOBALS }, // case-correct versions of the service names (#i102468#) { "com.sun.star.text.textfield.URL", SC_SERVICE_URLFIELD }, @@ -186,8 +305,7 @@ static const ProvNamesId_Type __FAR_DATA aProvNamesId[] = { "com.sun.star.text.textfield.Time", SC_SERVICE_TIMEFIELD }, { "com.sun.star.text.textfield.DocumentTitle", SC_SERVICE_TITLEFIELD }, { "com.sun.star.text.textfield.FileName", SC_SERVICE_FILEFIELD }, - { "com.sun.star.text.textfield.SheetName", SC_SERVICE_SHEETFIELD }, - { "ooo.vba.VBAGlobals", SC_SERVICE_VBAGLOBALS }, + { "com.sun.star.text.textfield.SheetName", SC_SERVICE_SHEETFIELD } }; // @@ -240,6 +358,7 @@ static const sal_Char* __FAR_DATA aOldNames[SC_SERVICE_COUNT] = "", // SC_SERVICE_CHDATAPROV "", // SC_SERVICE_FORMULAPARS "", // SC_SERVICE_OPCODEMAPPER + "", // SC_SERVICE_VBAOBJECTPROVIDER "", // SC_SERVICE_VBACODENAMEPROVIDER "", // SC_SERVICE_VBAGLOBALS }; @@ -446,6 +565,13 @@ uno::Reference<uno::XInterface> ScServiceProvider::MakeInstance( xRet.set(static_cast<sheet::XFormulaOpCodeMapper*>(new ScFormulaOpCodeMapperObj(::std::auto_ptr<formula::FormulaCompiler> (pComp)))); break; } + case SC_SERVICE_VBAOBJECTPROVIDER: + if ( pDocShell ) + { + OSL_TRACE("**** creating VBA Object mapper"); + xRet.set(static_cast<container::XNameAccess*>(new ScVbaObjectForCodeNameProvider( pDocShell ))); + } + break; case SC_SERVICE_VBACODENAMEPROVIDER: { // Only create the excel faking service for excel docs 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/unoobj/viewuno.cxx b/sc/source/ui/unoobj/viewuno.cxx index 15fb8183a88f..d10d3ba54f86 100644 --- a/sc/source/ui/unoobj/viewuno.cxx +++ b/sc/source/ui/unoobj/viewuno.cxx @@ -66,7 +66,9 @@ #include "scmod.hxx" #include "appoptio.hxx" #include "gridwin.hxx" +#include "sheetevents.hxx" #include <com/sun/star/view/DocumentZoomType.hpp> +#include <com/sun/star/awt/MouseButton.hpp> #include "AccessibilityHints.hxx" #include <svx/sdrhittesthelper.hxx> @@ -476,9 +478,11 @@ ScTabViewObj::ScTabViewObj( ScTabViewShell* pViewSh ) : aPropSet( lcl_GetViewOptPropertyMap() ), aMouseClickHandlers( 0 ), aActivationListeners( 0 ), + nPreviousTab( 0 ), bDrawSelModeSet(sal_False) { - //! Listening oder so + if (pViewSh) + nPreviousTab = pViewSh->GetViewData()->GetTabNo(); } ScTabViewObj::~ScTabViewObj() @@ -529,15 +533,44 @@ void SAL_CALL ScTabViewObj::release() throw() SfxBaseController::release(); } +void lcl_CallActivate( ScDocShell* pDocSh, SCTAB nTab, sal_Int32 nEvent ) +{ + ScDocument* pDoc = pDocSh->GetDocument(); + // when deleting a sheet, nPreviousTab can be invalid + // (could be handled with reference updates) + if (!pDoc->HasTable(nTab)) + return; + + const ScSheetEvents* pEvents = pDoc->GetSheetEvents(nTab); + if (pEvents) + { + const rtl::OUString* pScript = pEvents->GetScript(nEvent); + if (pScript) + { + uno::Any aRet; + uno::Sequence<uno::Any> aParams; + uno::Sequence<sal_Int16> aOutArgsIndex; + uno::Sequence<uno::Any> aOutArgs; + + /*ErrCode eRet =*/ pDocSh->CallXScript( *pScript, aParams, aRet, aOutArgsIndex, aOutArgs ); + } + } +} + void ScTabViewObj::SheetChanged() { - if (aActivationListeners.Count() > 0 && GetViewShell()) + if ( !GetViewShell() ) + return; + + ScViewData* pViewData = GetViewShell()->GetViewData(); + ScDocShell* pDocSh = pViewData->GetDocShell(); + if (aActivationListeners.Count() > 0) { sheet::ActivationEvent aEvent; uno::Reference< sheet::XSpreadsheetView > xView(this); uno::Reference< uno::XInterface > xSource(xView, uno::UNO_QUERY); aEvent.Source = xSource; - aEvent.ActiveSheet = new ScTableSheetObj(GetViewShell()->GetViewData()->GetDocShell(), GetViewShell()->GetViewData()->GetTabNo()); + aEvent.ActiveSheet = new ScTableSheetObj(pDocSh, pViewData->GetTabNo()); for ( USHORT n=0; n<aActivationListeners.Count(); n++ ) { try @@ -551,6 +584,15 @@ void ScTabViewObj::SheetChanged() } } } + + // handle sheet events + SCTAB nNewTab = pViewData->GetTabNo(); + if ( nNewTab != nPreviousTab ) + { + lcl_CallActivate( pDocSh, nPreviousTab, SC_SHEETEVENT_UNFOCUS ); + lcl_CallActivate( pDocSh, nNewTab, SC_SHEETEVENT_FOCUS ); + } + nPreviousTab = nNewTab; } uno::Sequence<uno::Type> SAL_CALL ScTabViewObj::getTypes() throw(uno::RuntimeException) @@ -1194,6 +1236,22 @@ uno::Reference< uno::XInterface > ScTabViewObj::GetClickedObject(const Point& rP return xTarget; } +bool ScTabViewObj::IsMouseListening() const +{ + if ( aMouseClickHandlers.Count() > 0 ) + return true; + + // also include sheet events, because MousePressed must be called for them + ScTabViewShell* pViewSh = GetViewShell(); + ScViewData* pViewData = pViewSh->GetViewData(); + const ScSheetEvents* pEvents = pViewData->GetDocument()->GetSheetEvents(pViewData->GetTabNo()); + if ( pEvents && ( pEvents->GetScript(SC_SHEETEVENT_RIGHTCLICK) != NULL || + pEvents->GetScript(SC_SHEETEVENT_DOUBLECLICK) != NULL ) ) + return true; + + return false; +} + sal_Bool ScTabViewObj::MousePressed( const awt::MouseEvent& e ) throw (::uno::RuntimeException) { @@ -1229,6 +1287,50 @@ sal_Bool ScTabViewObj::MousePressed( const awt::MouseEvent& e ) } } } + + // handle sheet events + bool bDoubleClick = ( e.Buttons == awt::MouseButton::LEFT && e.ClickCount == 2 ); + bool bRightClick = ( e.Buttons == awt::MouseButton::RIGHT && e.ClickCount == 1 ); + if ( ( bDoubleClick || bRightClick ) && !bReturn ) + { + sal_Int32 nEvent = bDoubleClick ? SC_SHEETEVENT_DOUBLECLICK : SC_SHEETEVENT_RIGHTCLICK; + + ScTabViewShell* pViewSh = GetViewShell(); + ScViewData* pViewData = pViewSh->GetViewData(); + ScDocShell* pDocSh = pViewData->GetDocShell(); + ScDocument* pDoc = pDocSh->GetDocument(); + SCTAB nTab = pViewData->GetTabNo(); + const ScSheetEvents* pEvents = pDoc->GetSheetEvents(nTab); + if (pEvents) + { + const rtl::OUString* pScript = pEvents->GetScript(nEvent); + if (pScript) + { + // the macro parameter is the clicked object, as in the mousePressed call above + uno::Reference< uno::XInterface > xTarget = GetClickedObject(Point(e.X, e.Y)); + if (xTarget.is()) + { + uno::Sequence<uno::Any> aParams(1); + aParams[0] <<= xTarget; + + uno::Any aRet; + uno::Sequence<sal_Int16> aOutArgsIndex; + uno::Sequence<uno::Any> aOutArgs; + + /*ErrCode eRet =*/ pDocSh->CallXScript( *pScript, aParams, aRet, aOutArgsIndex, aOutArgs ); + + // look for a boolean return value of true + sal_Bool bRetValue = sal_False; + if (aRet >>= bRetValue) + { + if (bRetValue) + bReturn = sal_True; + } + } + } + } + } + return bReturn; } @@ -1702,6 +1804,30 @@ void ScTabViewObj::SelectionChanged() aEvent.Source.set(static_cast<cppu::OWeakObject*>(this)); for ( USHORT n=0; n<aSelectionListeners.Count(); n++ ) (*aSelectionListeners[n])->selectionChanged( aEvent ); + + // handle sheet events + ScTabViewShell* pViewSh = GetViewShell(); + ScViewData* pViewData = pViewSh->GetViewData(); + ScDocShell* pDocSh = pViewData->GetDocShell(); + ScDocument* pDoc = pDocSh->GetDocument(); + SCTAB nTab = pViewData->GetTabNo(); + const ScSheetEvents* pEvents = pDoc->GetSheetEvents(nTab); + if (pEvents) + { + const rtl::OUString* pScript = pEvents->GetScript(SC_SHEETEVENT_SELECT); + if (pScript) + { + // the macro parameter is the selection as returned by getSelection + uno::Sequence<uno::Any> aParams(1); + aParams[0] = getSelection(); + + uno::Any aRet; + uno::Sequence<sal_Int16> aOutArgsIndex; + uno::Sequence<uno::Any> aOutArgs; + + /*ErrCode eRet =*/ pDocSh->CallXScript( *pScript, aParams, aRet, aOutArgsIndex, aOutArgs ); + } + } } diff --git a/sc/source/ui/vba/excelvbahelper.cxx b/sc/source/ui/vba/excelvbahelper.cxx index 4912863a446e..b1c4db637434 100644 --- a/sc/source/ui/vba/excelvbahelper.cxx +++ b/sc/source/ui/vba/excelvbahelper.cxx @@ -208,12 +208,11 @@ getViewFrame( const uno::Reference< frame::XModel >& xModel ) } SfxItemSet* -ScVbaCellRangeAccess::GetDataSet( ScCellRangeObj* pRangeObj ) +ScVbaCellRangeAccess::GetDataSet( ScCellRangesBase* pRangeObj ) { - SfxItemSet* pDataSet = pRangeObj ? pRangeObj->GetCurrentDataSet( true ) : NULL ; - return pDataSet; - + return pRangeObj ? pRangeObj->GetCurrentDataSet( true ) : 0; } + } //excel } //vba } //ooo diff --git a/sc/source/ui/vba/excelvbahelper.hxx b/sc/source/ui/vba/excelvbahelper.hxx index 34b099e6db46..9af804ab169f 100644 --- a/sc/source/ui/vba/excelvbahelper.hxx +++ b/sc/source/ui/vba/excelvbahelper.hxx @@ -30,7 +30,7 @@ #include<vbahelper/vbahelper.hxx> #include <docsh.hxx> -class ScCellRangeObj; +class ScCellRangesBase; namespace ooo { @@ -51,7 +51,7 @@ namespace ooo class ScVbaCellRangeAccess { public: - static SfxItemSet* GetDataSet( ScCellRangeObj* pRangeObj ); + static SfxItemSet* GetDataSet( ScCellRangesBase* pRangeObj ); }; } } diff --git a/sc/source/ui/vba/makefile.mk b/sc/source/ui/vba/makefile.mk index 00a26e2f94de..0a84b8dd12a5 100644 --- a/sc/source/ui/vba/makefile.mk +++ b/sc/source/ui/vba/makefile.mk @@ -78,28 +78,31 @@ SLOFILES= \ $(SLO)$/vbaborders.obj \ $(SLO)$/vbacharacters.obj \ $(SLO)$/vbavalidation.obj \ - $(SLO)$/vbaoleobject.obj \ - $(SLO)$/vbaoleobjects.obj \ - $(SLO)$/vbatextboxshape.obj \ - $(SLO)$/vbapane.obj \ - $(SLO)$/vbatextframe.obj \ - $(SLO)$/vbacharttitle.obj \ - $(SLO)$/vbacharts.obj \ - $(SLO)$/vbaaxistitle.obj \ - $(SLO)$/vbaaxes.obj \ - $(SLO)$/vbaaxis.obj \ - $(SLO)$/vbaformat.obj \ - $(SLO)$/vbacondition.obj \ - $(SLO)$/vbaformatcondition.obj \ - $(SLO)$/vbaformatconditions.obj \ - $(SLO)$/vbastyle.obj \ - $(SLO)$/vbastyles.obj \ - $(SLO)$/vbaassistant.obj \ - $(SLO)$/vbahyperlink.obj \ - $(SLO)$/vbapagesetup.obj \ - $(SLO)$/vbapagebreak.obj \ - $(SLO)$/vbapagebreaks.obj \ - $(SLO)$/service.obj + $(SLO)$/vbasheetobject.obj \ + $(SLO)$/vbasheetobjects.obj \ + $(SLO)$/vbaoleobject.obj \ + $(SLO)$/vbaoleobjects.obj \ + $(SLO)$/vbatextboxshape.obj \ + $(SLO)$/vbapane.obj \ + $(SLO)$/vbatextframe.obj \ + $(SLO)$/vbacharttitle.obj \ + $(SLO)$/vbacharts.obj \ + $(SLO)$/vbaaxistitle.obj \ + $(SLO)$/vbaaxes.obj \ + $(SLO)$/vbaaxis.obj \ + $(SLO)$/vbaformat.obj \ + $(SLO)$/vbacondition.obj \ + $(SLO)$/vbaformatcondition.obj \ + $(SLO)$/vbaformatconditions.obj \ + $(SLO)$/vbastyle.obj \ + $(SLO)$/vbastyles.obj \ + $(SLO)$/vbaassistant.obj \ + $(SLO)$/vbahyperlink.obj \ + $(SLO)$/vbahyperlinks.obj \ + $(SLO)$/vbapagesetup.obj \ + $(SLO)$/vbapagebreak.obj \ + $(SLO)$/vbapagebreaks.obj \ + $(SLO)$/service.obj .ENDIF # --- Targets ------------------------------------------------------ diff --git a/sc/source/ui/vba/testvba/runTests.pl b/sc/source/ui/vba/testvba/runTests.pl index f5051516a9c4..e686a1d4cb89 100644..100755 --- a/sc/source/ui/vba/testvba/runTests.pl +++ b/sc/source/ui/vba/testvba/runTests.pl @@ -20,7 +20,7 @@ my $theResult; my $officepath = shift || die "please specify path to office installation program dir"; my $DocName = shift || ""; my $programpath = "$officepath"."3/program:$officepath/program:"; -my $basiclibrarypath = "$officepath/basis3.2/program"; +my $basiclibrarypath = "$officepath/basis3.3/program"; my $urelibpath = "$officepath/ure/lib"; my $binext = ""; my $testDocDir = "$binDir/TestDocuments"; diff --git a/sc/source/ui/vba/testvba/testclient b/sc/source/ui/vba/testvba/testclient Binary files differindex 12e9ca1659f4..c9cde8c5b052 100755 --- a/sc/source/ui/vba/testvba/testclient +++ b/sc/source/ui/vba/testvba/testclient diff --git a/sc/source/ui/vba/vbaapplication.cxx b/sc/source/ui/vba/vbaapplication.cxx index 5d9e513dabeb..aea8d8bc11d4 100644 --- a/sc/source/ui/vba/vbaapplication.cxx +++ b/sc/source/ui/vba/vbaapplication.cxx @@ -114,7 +114,10 @@ public: ActiveWorkbook( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext) : ScVbaWorkbook( xParent, xContext ){} }; -ScVbaApplication::ScVbaApplication( const uno::Reference<uno::XComponentContext >& xContext ): ScVbaApplication_BASE( xContext ), m_xCalculation( excel::XlCalculation::xlCalculationAutomatic ) +ScVbaApplication::ScVbaApplication( const uno::Reference<uno::XComponentContext >& xContext ) : + ScVbaApplication_BASE( xContext ), + m_xCalculation( excel::XlCalculation::xlCalculationAutomatic ), + m_xDisplayAlerts( sal_True) { } @@ -127,15 +130,81 @@ SfxObjectShell* ScVbaApplication::GetDocShell( const uno::Reference< frame::XMod return static_cast< SfxObjectShell* >( excel::getDocShell( xModel ) ); } +::rtl::OUString SAL_CALL +ScVbaApplication::getExactName( const ::rtl::OUString& aApproximateName ) throw (uno::RuntimeException) +{ + uno::Reference< beans::XExactName > xWSF( new ScVbaWSFunction( this, mxContext ) ); + return xWSF->getExactName( aApproximateName ); +} + +uno::Reference< beans::XIntrospectionAccess > SAL_CALL +ScVbaApplication::getIntrospection() throw(css::uno::RuntimeException) +{ + uno::Reference< script::XInvocation > xWSF( new ScVbaWSFunction( this, mxContext ) ); + return xWSF->getIntrospection(); +} + +uno::Any SAL_CALL +ScVbaApplication::invoke( const ::rtl::OUString& FunctionName, const uno::Sequence< uno::Any >& Params, uno::Sequence< sal_Int16 >& OutParamIndex, uno::Sequence< uno::Any >& OutParam) throw(lang::IllegalArgumentException, script::CannotConvertException, reflection::InvocationTargetException, uno::RuntimeException) +{ + /* When calling the functions directly at the Application object, no runtime + errors are thrown, but the error is inserted into the return value. */ + uno::Any aAny; + try + { + uno::Reference< script::XInvocation > xWSF( new ScVbaWSFunction( this, mxContext ) ); + aAny = xWSF->invoke( FunctionName, Params, OutParamIndex, OutParam ); + } + catch( uno::Exception& ) + { + aAny <<= script::BasicErrorException( ::rtl::OUString(), uno::Reference< uno::XInterface >(), 1000, ::rtl::OUString() ); + } + return aAny; +} + +void SAL_CALL +ScVbaApplication::setValue( const ::rtl::OUString& PropertyName, const uno::Any& Value ) throw(beans::UnknownPropertyException, script::CannotConvertException, reflection::InvocationTargetException, uno::RuntimeException) +{ + uno::Reference< script::XInvocation > xWSF( new ScVbaWSFunction( this, mxContext ) ); + xWSF->setValue( PropertyName, Value ); +} + +uno::Any SAL_CALL +ScVbaApplication::getValue( const ::rtl::OUString& PropertyName ) throw(beans::UnknownPropertyException, uno::RuntimeException) +{ + uno::Reference< script::XInvocation > xWSF( new ScVbaWSFunction( this, mxContext ) ); + return xWSF->getValue( PropertyName ); +} + +sal_Bool SAL_CALL +ScVbaApplication::hasMethod( const ::rtl::OUString& Name ) throw(uno::RuntimeException) +{ + uno::Reference< script::XInvocation > xWSF( new ScVbaWSFunction( this, mxContext ) ); + return xWSF->hasMethod( Name ); +} + +sal_Bool SAL_CALL +ScVbaApplication::hasProperty( const ::rtl::OUString& Name ) throw(uno::RuntimeException) +{ + uno::Reference< script::XInvocation > xWSF( new ScVbaWSFunction( this, mxContext ) ); + return xWSF->hasProperty( Name ); +} + uno::Reference< excel::XWorkbook > ScVbaApplication::getActiveWorkbook() throw (uno::RuntimeException) { return new ActiveWorkbook( this, mxContext ); } + uno::Reference< excel::XWorkbook > SAL_CALL ScVbaApplication::getThisWorkbook() throw (uno::RuntimeException) { - return getActiveWorkbook(); + uno::Reference< frame::XModel > xModel = getThisExcelDoc(mxContext); + if( !xModel.is() ) + return uno::Reference< excel::XWorkbook >(); + + ScVbaWorkbook *pWb = new ScVbaWorkbook( this, mxContext, xModel ); + return uno::Reference< excel::XWorkbook > (pWb); } uno::Reference< XAssistant > SAL_CALL @@ -184,7 +253,7 @@ ScVbaApplication::getSelection() throw (uno::RuntimeException) } else { - throw uno::RuntimeException( sImpementaionName + rtl::OUString::createFromAscii(" donot be surpported"), uno::Reference< uno::XInterface >() ); + throw uno::RuntimeException( sImpementaionName + rtl::OUString::createFromAscii(" not suported"), uno::Reference< uno::XInterface >() ); } } @@ -238,7 +307,7 @@ ScVbaApplication::Worksheets( const uno::Any& aIndex ) throw (uno::RuntimeExcept uno::Any SAL_CALL ScVbaApplication::WorksheetFunction( ) throw (::com::sun::star::uno::RuntimeException) { - return uno::makeAny( uno::Reference< script::XInvocation >( new ScVbaWSFunction( this, mxContext) ) ); + return uno::makeAny( uno::Reference< script::XInvocation >( new ScVbaWSFunction( this, mxContext ) ) ); } uno::Any SAL_CALL @@ -264,7 +333,10 @@ uno::Reference< excel::XWindow > SAL_CALL ScVbaApplication::getActiveWindow() throw (uno::RuntimeException) { // #FIXME sofar can't determine Parent - return new ScVbaWindow( uno::Reference< XHelperInterface >(), mxContext, getCurrentDocument() ); + uno::Reference< frame::XModel > xModel = getCurrentDocument(); + ScVbaWindow* pWin = new ScVbaWindow( uno::Reference< XHelperInterface >(), mxContext, xModel ); + uno::Reference< excel::XWindow > xWin( pWin ); + return xWin; } uno::Any SAL_CALL @@ -315,23 +387,6 @@ ScVbaApplication::setStatusBar( const uno::Any& _statusbar ) throw (uno::Runtime uno::Reference< uno::XInterface >() ); } -double SAL_CALL -ScVbaApplication::CountA( const uno::Any& arg1 ) throw (uno::RuntimeException) -{ - double result = 0; - uno::Reference< script::XInvocation > xInvoc( WorksheetFunction(), uno::UNO_QUERY_THROW ); - if ( xInvoc.is() ) - { - static rtl::OUString FunctionName( RTL_CONSTASCII_USTRINGPARAM("CountA" ) ); - uno::Sequence< uno::Any > Params(1); - Params[0] = arg1; - uno::Sequence< sal_Int16 > OutParamIndex; - uno::Sequence< uno::Any > OutParam; - xInvoc->invoke( FunctionName, Params, OutParamIndex, OutParam ) >>= result; - } - return result; -} - ::sal_Int32 SAL_CALL ScVbaApplication::getCalculation() throw (uno::RuntimeException) { @@ -476,8 +531,11 @@ ScVbaApplication::GoTo( const uno::Any& Reference, const uno::Any& Scroll ) thro ScGridWindow* gridWindow = (ScGridWindow*)pShell->GetWindow(); try { - uno::Reference< excel::XRange > xVbaSheetRange = ScVbaRange::getRangeObjectForName( mxContext, sRangeName, excel::getDocShell( xModel ), formula::FormulaGrammar::CONV_XL_R1C1 ); -; + // FIXME: pass proper Worksheet parent + uno::Reference< excel::XRange > xVbaSheetRange = ScVbaRange::getRangeObjectForName( + uno::Reference< XHelperInterface >(), mxContext, sRangeName, + excel::getDocShell( xModel ), formula::FormulaGrammar::CONV_XL_R1C1 ); + if( bScroll ) { xVbaSheetRange->Select(); @@ -615,15 +673,21 @@ ScVbaApplication::getName() throw (uno::RuntimeException) } // #TODO #FIXME get/setDisplayAlerts are just stub impl +// here just the status of the switch is set +// the function that throws an error message needs to +// evaluate this switch in order to know whether it has to disable the +// error message thrown by OpenOffice + void SAL_CALL -ScVbaApplication::setDisplayAlerts(sal_Bool /*displayAlerts*/) throw (uno::RuntimeException) +ScVbaApplication::setDisplayAlerts(sal_Bool displayAlerts) throw (uno::RuntimeException) { + m_xDisplayAlerts = displayAlerts; } sal_Bool SAL_CALL ScVbaApplication::getDisplayAlerts() throw (uno::RuntimeException) { - return sal_True; + return m_xDisplayAlerts; } void SAL_CALL ScVbaApplication::Calculate() throw( script::BasicErrorException , uno::RuntimeException ) @@ -769,46 +833,74 @@ bool lcl_canJoin( ScRange& r1, ScRange& r2 ) void lcl_strip_containedRanges( Ranges& vRanges ) { // get rid of ranges that are surrounded by other ranges - for( Ranges::iterator it = vRanges.begin(); it != vRanges.end(); ++it ) + Ranges::iterator it_outer = vRanges.begin(); + while( it_outer != vRanges.end() ) { - for( Ranges::iterator it_inner = vRanges.begin(); it_inner != vRanges.end(); ++it_inner ) + bool it_outer_erased = false; // true = it_outer erased from vRanges + Ranges::iterator it_inner = vRanges.begin(); + /* Exit the inner loop if outer iterator has been erased in its last + iteration (this means it has been joined to last it_inner, or that + the it_inner contains it completely). The inner loop will restart + with next element of the outer loop, and all elements (from the + beginning of the list) will be checked against that new element. */ + while( !it_outer_erased && (it_inner != vRanges.end()) ) { - if ( it != it_inner ) + bool it_inner_erased = false; // true = it_inner erased from vRanges + if ( it_outer != it_inner ) { #ifdef DEBUG - String r1; - String r2; - it->Format( r1, SCA_VALID ) ; - it_inner->Format( r2, SCA_VALID ) ; - OSL_TRACE( "try strip/join address %s with %s ", - rtl::OUStringToOString( r1, RTL_TEXTENCODING_UTF8 ).getStr(), - rtl::OUStringToOString( r2, RTL_TEXTENCODING_UTF8 ).getStr() ); + String r1; + String r2; + it_outer->Format( r1, SCA_VALID ) ; + it_inner->Format( r2, SCA_VALID ) ; + OSL_TRACE( "try strip/join address %s with %s ", + rtl::OUStringToOString( r1, RTL_TEXTENCODING_UTF8 ).getStr(), + rtl::OUStringToOString( r2, RTL_TEXTENCODING_UTF8 ).getStr() ); #endif - if ( it->In( *it_inner ) ) + if ( it_outer->In( *it_inner ) ) + { it_inner = vRanges.erase( it_inner ); - else if ( it_inner->In( *it ) ) - it = vRanges.erase( it ); + it_inner_erased = true; + } + else if ( it_inner->In( *it_outer ) ) + { + it_outer = vRanges.erase( it_outer ); + it_outer_erased = true; + } #ifndef OWN_JOIN - else if ( (*it_inner).aStart.Row() == (*it).aStart.Row() - && (*it_inner).aEnd.Row() == (*it).aEnd.Row() ) + else if ( (*it_inner).aStart.Row() == (*it_outer).aStart.Row() + && (*it_inner).aEnd.Row() == (*it_outer).aEnd.Row() ) { - it->ExtendTo( *it_inner ); + it_outer->ExtendTo( *it_inner ); it_inner = vRanges.erase( it_inner ); + it_inner_erased = true; } #else - else if ( lcl_canJoin( *it, *it_inner ) ) + else if ( lcl_canJoin( *it_outer, *it_inner ) ) { - it->ExtendTo( *it_inner ); + it_outer->ExtendTo( *it_inner ); it_inner = vRanges.erase( it_inner ); + it_inner_erased = true; } - else if ( lcl_canJoin( *it_inner, *it) ) + else if ( lcl_canJoin( *it_inner, *it_outer) ) { - it_inner->ExtendTo( *it ); - it = vRanges.erase( it ); + it_inner->ExtendTo( *it_outer ); + it_outer = vRanges.erase( it_outer ); + it_outer_erased = true; } #endif } + /* If it_inner has not been erased from vRanges, continue inner + loop with next element. Otherwise, it_inner already points to + the next element (return value of list::erase()). */ + if( !it_inner_erased ) + ++it_inner; } + /* If it_outer has not been erased from vRanges, continue outer loop + with next element. Otherwise, it_outer already points to the next + element (return value of list::erase()). */ + if( !it_outer_erased ) + ++it_outer; } } @@ -855,7 +947,8 @@ lcl_intersectionImpl( ScRangeList& rl1, ScRangeList& rl2 ) RangesList lcl_intersections( RangesList& vRanges ) { RangesList intersections; - for( RangesList::iterator it = vRanges.begin(); it != vRanges.end(); ++it ) + RangesList::iterator it = vRanges.begin(); + while( it != vRanges.end() ) { Ranges intermediateList; for( RangesList::iterator it_inner = vRanges.begin(); it_inner != vRanges.end(); ++it_inner ) @@ -868,6 +961,7 @@ RangesList lcl_intersections( RangesList& vRanges ) } } it = vRanges.erase( it ); // remove it so we don't include it in the next pass. + // 'it' is removed uncontidionally from vRanges, so the while loop will terminate ScRangeList argIntersect; lcl_strip_containedRanges( intermediateList ); diff --git a/sc/source/ui/vba/vbaapplication.hxx b/sc/source/ui/vba/vbaapplication.hxx index 02822e9f18ad..96638651bcd1 100644 --- a/sc/source/ui/vba/vbaapplication.hxx +++ b/sc/source/ui/vba/vbaapplication.hxx @@ -43,15 +43,29 @@ class ScVbaApplication : public ScVbaApplication_BASE { private: sal_Int32 m_xCalculation; + sal_Bool m_xDisplayAlerts; rtl::OUString getOfficePath( const rtl::OUString& sPath ) throw ( css::uno::RuntimeException ); + protected: - virtual css::uno::Reference< css::frame::XModel > getCurrentDocument() throw (css::uno::RuntimeException); + virtual css::uno::Reference< css::frame::XModel > getCurrentDocument() throw (css::uno::RuntimeException); + public: ScVbaApplication( const css::uno::Reference< css::uno::XComponentContext >& m_xContext ); virtual ~ScVbaApplication(); virtual SfxObjectShell* GetDocShell( const css::uno::Reference< css::frame::XModel >& xModel ) throw (css::uno::RuntimeException); + // XExactName + virtual ::rtl::OUString SAL_CALL getExactName( const ::rtl::OUString& aApproximateName ) throw (css::uno::RuntimeException); + + // XInvocation + virtual css::uno::Reference< css::beans::XIntrospectionAccess > SAL_CALL getIntrospection(void) throw(css::uno::RuntimeException); + virtual css::uno::Any SAL_CALL invoke(const rtl::OUString& FunctionName, const css::uno::Sequence< css::uno::Any >& Params, css::uno::Sequence< sal_Int16 >& OutParamIndex, css::uno::Sequence< css::uno::Any >& OutParam) throw(css::lang::IllegalArgumentException, css::script::CannotConvertException, css::reflection::InvocationTargetException, css::uno::RuntimeException); + virtual void SAL_CALL setValue(const rtl::OUString& PropertyName, const css::uno::Any& Value) throw(css::beans::UnknownPropertyException, css::script::CannotConvertException, css::reflection::InvocationTargetException, css::uno::RuntimeException); + virtual css::uno::Any SAL_CALL getValue(const rtl::OUString& PropertyName) throw(css::beans::UnknownPropertyException, css::uno::RuntimeException); + virtual sal_Bool SAL_CALL hasMethod(const rtl::OUString& Name) throw(css::uno::RuntimeException); + virtual sal_Bool SAL_CALL hasProperty(const rtl::OUString& Name) throw(css::uno::RuntimeException); + // XApplication virtual ::rtl::OUString SAL_CALL PathSeparator( ) throw (css::script::BasicErrorException, css::uno::RuntimeException); virtual void SAL_CALL setDefaultFilePath( const ::rtl::OUString& DefaultFilePath ) throw (css::script::BasicErrorException, css::uno::RuntimeException); @@ -67,8 +81,8 @@ public: virtual css::uno::Any SAL_CALL getSelection() throw (css::uno::RuntimeException); virtual css::uno::Reference< ov::excel::XWorkbook > SAL_CALL getActiveWorkbook() throw (css::uno::RuntimeException); virtual css::uno::Reference< ov::excel::XRange > SAL_CALL getActiveCell() throw ( css::uno::RuntimeException); - virtual css::uno::Reference< ov::excel::XWindow > SAL_CALL getActiveWindow() throw (css::uno::RuntimeException); - virtual css::uno::Reference< ov::excel::XWorksheet > SAL_CALL getActiveSheet() throw (css::uno::RuntimeException); + virtual css::uno::Reference< ov::excel::XWindow > SAL_CALL getActiveWindow() throw (css::uno::RuntimeException); + virtual css::uno::Reference< ov::excel::XWorksheet > SAL_CALL getActiveSheet() throw (css::uno::RuntimeException); virtual ::sal_Bool SAL_CALL getDisplayFormulaBar() throw ( css::uno::RuntimeException ); virtual void SAL_CALL setDisplayFormulaBar( ::sal_Bool _displayformulabar ) throw ( css::uno::RuntimeException ); @@ -86,8 +100,6 @@ public: virtual ::sal_Int32 SAL_CALL getCursor() throw (css::uno::RuntimeException); virtual void SAL_CALL setCursor( ::sal_Int32 _cursor ) throw (css::uno::RuntimeException); - virtual double SAL_CALL CountA( const css::uno::Any& arg1 ) throw (css::uno::RuntimeException) ; - virtual css::uno::Any SAL_CALL Windows( const css::uno::Any& aIndex ) throw (css::uno::RuntimeException); virtual void SAL_CALL wait( double time ) throw (css::uno::RuntimeException); virtual css::uno::Any SAL_CALL Range( const css::uno::Any& Cell1, const css::uno::Any& Cell2 ) throw (css::uno::RuntimeException); diff --git a/sc/source/ui/vba/vbacomment.cxx b/sc/source/ui/vba/vbacomment.cxx index a8026f151c79..9c50a25b8b7c 100644 --- a/sc/source/ui/vba/vbacomment.cxx +++ b/sc/source/ui/vba/vbacomment.cxx @@ -27,14 +27,17 @@ #include "vbacomment.hxx" #include <ooo/vba/excel/XlCreator.hpp> +#include <com/sun/star/drawing/XDrawPageSupplier.hpp> #include <com/sun/star/sheet/XSpreadsheet.hpp> #include <com/sun/star/sheet/XSheetAnnotationAnchor.hpp> #include <com/sun/star/sheet/XSheetAnnotationsSupplier.hpp> +#include <com/sun/star/sheet/XSheetAnnotationShapeSupplier.hpp> #include <com/sun/star/sheet/XSheetCellRange.hpp> #include <com/sun/star/table/CellAddress.hpp> #include <com/sun/star/table/XCell.hpp> #include <com/sun/star/text/XText.hpp> +#include <vbahelper/vbashape.hxx> #include "vbaglobals.hxx" #include "vbacomments.hxx" @@ -42,8 +45,14 @@ using namespace ::ooo::vba; using namespace ::com::sun::star; -ScVbaComment::ScVbaComment( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< table::XCellRange >& xRange ) throw( lang::IllegalArgumentException ) -: ScVbaComment_BASE( xParent, xContext ), mxRange( xRange ) +ScVbaComment::ScVbaComment( + const uno::Reference< XHelperInterface >& xParent, + const uno::Reference< uno::XComponentContext >& xContext, + const uno::Reference< frame::XModel >& xModel, + const uno::Reference< table::XCellRange >& xRange ) throw( lang::IllegalArgumentException ) : + ScVbaComment_BASE( xParent, xContext ), + mxModel( xModel, uno::UNO_SET_THROW ), + mxRange( xRange ) { if ( !xRange.is() ) throw lang::IllegalArgumentException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "range is not set " ) ), uno::Reference< uno::XInterface >() , 1 ); @@ -100,7 +109,7 @@ ScVbaComment::getCommentByIndex( sal_Int32 Index ) throw (uno::RuntimeException) { uno::Reference< container::XIndexAccess > xIndexAccess( getAnnotations(), uno::UNO_QUERY_THROW ); // parent is sheet ( parent of the range which is the parent of the comment ) - uno::Reference< XCollection > xColl( new ScVbaComments( getParent()->getParent(), mxContext, xIndexAccess ) ); + uno::Reference< XCollection > xColl( new ScVbaComments( getParent()->getParent(), mxContext, mxModel, xIndexAccess ) ); return uno::Reference< excel::XComment > ( xColl->Item( uno::makeAny( Index ), uno::Any() ), uno::UNO_QUERY_THROW ); } @@ -119,6 +128,17 @@ ScVbaComment::setAuthor( const rtl::OUString& /*_author*/ ) throw (uno::RuntimeE // #TODO #FIXME implementation needed } +uno::Reference< msforms::XShape > SAL_CALL +ScVbaComment::getShape() throw (uno::RuntimeException) +{ + uno::Reference< sheet::XSheetAnnotationShapeSupplier > xAnnoShapeSupp( getAnnotation(), uno::UNO_QUERY_THROW ); + uno::Reference< drawing::XShape > xAnnoShape( xAnnoShapeSupp->getAnnotationShape(), uno::UNO_SET_THROW ); + uno::Reference< sheet::XSheetCellRange > xCellRange( mxRange, uno::UNO_QUERY_THROW ); + uno::Reference< drawing::XDrawPageSupplier > xDrawPageSupp( xCellRange->getSpreadsheet(), uno::UNO_QUERY_THROW ); + uno::Reference< drawing::XShapes > xShapes( xDrawPageSupp->getDrawPage(), uno::UNO_QUERY_THROW ); + return new ScVbaShape( this, mxContext, xAnnoShape, xShapes, mxModel, office::MsoShapeType::msoComment ); +} + sal_Bool SAL_CALL ScVbaComment::getVisible() throw (uno::RuntimeException) { @@ -186,12 +206,15 @@ ScVbaComment::Text( const uno::Any& aText, const uno::Any& aStart, const uno::An uno::Reference< text::XTextRange > xRange( xTextCursor, uno::UNO_QUERY_THROW ); xAnnoText->insertString( xRange, sText, bOverwrite ); + return xAnnoText->getString(); } - else - throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ScVbaComment::Text - bad Start value " ) ), uno::Reference< uno::XInterface >() ); + throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ScVbaComment::Text - bad Start value " ) ), uno::Reference< uno::XInterface >() ); } else if ( aText.hasValue() ) + { xAnnoText->setString( sText ); + return sText; + } return sAnnoText; } diff --git a/sc/source/ui/vba/vbacomment.hxx b/sc/source/ui/vba/vbacomment.hxx index 91d8a8a8e437..4a7d2fab91ef 100644 --- a/sc/source/ui/vba/vbacomment.hxx +++ b/sc/source/ui/vba/vbacomment.hxx @@ -31,6 +31,7 @@ #include <ooo/vba/excel/XComment.hpp> #include <ooo/vba/excel/XApplication.hpp> +#include <ooo/vba/msforms/XShape.hpp> #include <com/sun/star/sheet/XSheetAnnotations.hpp> #include <com/sun/star/sheet/XSheetAnnotation.hpp> #include <com/sun/star/table/XCellRange.hpp> @@ -42,6 +43,7 @@ typedef InheritedHelperInterfaceImpl1< ov::excel::XComment > ScVbaComment_BASE; class ScVbaComment : public ScVbaComment_BASE { + css::uno::Reference< css::frame::XModel > mxModel; css::uno::Reference< css::table::XCellRange > mxRange; private: @@ -50,13 +52,18 @@ private: sal_Int32 SAL_CALL getAnnotationIndex() throw (css::uno::RuntimeException); css::uno::Reference< ov::excel::XComment > SAL_CALL getCommentByIndex( sal_Int32 Index ) throw (css::uno::RuntimeException); public: - ScVbaComment( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::table::XCellRange >& xRange ) throw ( css::lang::IllegalArgumentException ); + ScVbaComment( + const css::uno::Reference< ov::XHelperInterface >& xParent, + const css::uno::Reference< css::uno::XComponentContext >& xContext, + const css::uno::Reference< css::frame::XModel >& xModel, + const css::uno::Reference< css::table::XCellRange >& xRange ) throw ( css::lang::IllegalArgumentException ); virtual ~ScVbaComment() {} // Attributes virtual rtl::OUString SAL_CALL getAuthor() throw (css::uno::RuntimeException); virtual void SAL_CALL setAuthor( const rtl::OUString& _author ) throw (css::uno::RuntimeException); + virtual css::uno::Reference< ov::msforms::XShape > SAL_CALL getShape() throw (css::uno::RuntimeException); virtual sal_Bool SAL_CALL getVisible() throw (css::uno::RuntimeException); virtual void SAL_CALL setVisible( sal_Bool _visible ) throw (css::uno::RuntimeException); diff --git a/sc/source/ui/vba/vbacomments.cxx b/sc/source/ui/vba/vbacomments.cxx index 5090fa6f5ee6..a68dd4245741 100644 --- a/sc/source/ui/vba/vbacomments.cxx +++ b/sc/source/ui/vba/vbacomments.cxx @@ -34,30 +34,43 @@ using namespace ::ooo::vba; using namespace ::com::sun::star; -uno::Any AnnotationToComment( const uno::Any& aSource, uno::Reference< uno::XComponentContext > & xContext ) +uno::Any AnnotationToComment( const uno::Any& aSource, uno::Reference< uno::XComponentContext > & xContext, const uno::Reference< frame::XModel >& xModel ) { uno::Reference< sheet::XSheetAnnotation > xAnno( aSource, uno::UNO_QUERY_THROW ); uno::Reference< container::XChild > xChild( xAnno, uno::UNO_QUERY_THROW ); uno::Reference< table::XCellRange > xCellRange( xChild->getParent(), uno::UNO_QUERY_THROW ); // #FIXME needs to find the correct Parent - return uno::makeAny( uno::Reference< excel::XComment > ( new ScVbaComment( uno::Reference< XHelperInterface >(), xContext, xCellRange ) ) ); + return uno::makeAny( uno::Reference< excel::XComment > ( + new ScVbaComment( uno::Reference< XHelperInterface >(), xContext, xModel, xCellRange ) ) ); } class CommentEnumeration : public EnumerationHelperImpl { + css::uno::Reference< css::frame::XModel > mxModel; public: - CommentEnumeration( const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< container::XEnumeration >& xEnumeration ) throw ( uno::RuntimeException ) : EnumerationHelperImpl( xContext, xEnumeration ) {} + CommentEnumeration( + const uno::Reference< uno::XComponentContext >& xContext, + const uno::Reference< container::XEnumeration >& xEnumeration, + const uno::Reference< frame::XModel >& xModel ) throw ( uno::RuntimeException ) : + EnumerationHelperImpl( xContext, xEnumeration ), + mxModel( xModel, uno::UNO_SET_THROW ) + {} virtual uno::Any SAL_CALL nextElement() throw (container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException) { - return AnnotationToComment( m_xEnumeration->nextElement(), m_xContext ); + return AnnotationToComment( m_xEnumeration->nextElement(), m_xContext, mxModel ); } }; -ScVbaComments::ScVbaComments( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, const uno::Reference< container::XIndexAccess >& xIndexAccess ) -: ScVbaComments_BASE( xParent, xContext, xIndexAccess ) +ScVbaComments::ScVbaComments( + const uno::Reference< XHelperInterface >& xParent, + const uno::Reference< uno::XComponentContext > & xContext, + const uno::Reference< frame::XModel >& xModel, + const uno::Reference< container::XIndexAccess >& xIndexAccess ) : + ScVbaComments_BASE( xParent, xContext, xIndexAccess ), + mxModel( xModel, uno::UNO_SET_THROW ) { } @@ -68,13 +81,13 @@ ScVbaComments::createEnumeration() throw (uno::RuntimeException) { uno::Reference< container::XEnumerationAccess > xEnumAccess( m_xIndexAccess, uno::UNO_QUERY_THROW ); - return new CommentEnumeration( mxContext, xEnumAccess->createEnumeration() ); + return new CommentEnumeration( mxContext, xEnumAccess->createEnumeration(), mxModel ); } uno::Any ScVbaComments::createCollectionObject( const css::uno::Any& aSource ) { - return AnnotationToComment( aSource, mxContext ); + return AnnotationToComment( aSource, mxContext, mxModel ); } uno::Type diff --git a/sc/source/ui/vba/vbacomments.hxx b/sc/source/ui/vba/vbacomments.hxx index 0ab11e8d5e97..2f98e5b71897 100644 --- a/sc/source/ui/vba/vbacomments.hxx +++ b/sc/source/ui/vba/vbacomments.hxx @@ -40,7 +40,11 @@ typedef CollTestImplHelper< ov::excel::XComments > ScVbaComments_BASE; class ScVbaComments : public ScVbaComments_BASE { public: - ScVbaComments( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::container::XIndexAccess >& xIndexAccess ); + ScVbaComments( + const css::uno::Reference< ov::XHelperInterface >& xParent, + const css::uno::Reference< css::uno::XComponentContext > & xContext, + const css::uno::Reference< css::frame::XModel >& xModel, + const css::uno::Reference< css::container::XIndexAccess >& xIndexAccess ); virtual ~ScVbaComments() {} @@ -53,6 +57,8 @@ public: virtual rtl::OUString& getServiceImplName(); virtual css::uno::Sequence<rtl::OUString> getServiceNames(); +private: + css::uno::Reference< css::frame::XModel > mxModel; }; #endif /* SC_VBA_COMMENTS_HXX */ diff --git a/sc/source/ui/vba/vbafont.cxx b/sc/source/ui/vba/vbafont.cxx index a8aac44770a9..5894d3ea8c71 100644 --- a/sc/source/ui/vba/vbafont.cxx +++ b/sc/source/ui/vba/vbafont.cxx @@ -36,6 +36,7 @@ #include <ooo/vba/excel/XlColorIndex.hpp> #include <ooo/vba/excel/XlUnderlineStyle.hpp> #include <svl/itemset.hxx> +#include "excelvbahelper.hxx" #include "vbafont.hxx" #include "scitems.hxx" #include "cellsuno.hxx" @@ -43,15 +44,22 @@ using namespace ::ooo::vba; using namespace ::com::sun::star; -ScVbaFont::ScVbaFont( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const ScVbaPalette& dPalette, uno::Reference< beans::XPropertySet > xPropertySet, ScCellRangeObj* pRangeObj ) throw ( uno::RuntimeException ) : ScVbaFont_BASE( xParent, xContext, dPalette.getPalette(), xPropertySet ), mPalette( dPalette ), mpRangeObj( pRangeObj ) +ScVbaFont::ScVbaFont( + const uno::Reference< XHelperInterface >& xParent, + const uno::Reference< uno::XComponentContext >& xContext, + const ScVbaPalette& dPalette, + const uno::Reference< beans::XPropertySet >& xPropertySet, + ScCellRangeObj* pRangeObj, bool bFormControl ) throw ( uno::RuntimeException ) : + ScVbaFont_BASE( xParent, xContext, dPalette.getPalette(), xPropertySet, bFormControl ), + mPalette( dPalette ), + mpRangeObj( pRangeObj ) { } SfxItemSet* ScVbaFont::GetDataSet() { - SfxItemSet* pDataSet = excel::ScVbaCellRangeAccess::GetDataSet( mpRangeObj ); - return pDataSet; + return mpRangeObj ? excel::ScVbaCellRangeAccess::GetDataSet( mpRangeObj ) : 0; } ScVbaFont::~ScVbaFont() diff --git a/sc/source/ui/vba/vbafont.hxx b/sc/source/ui/vba/vbafont.hxx index 4cbcd483b2d8..3ef52c6d240f 100644 --- a/sc/source/ui/vba/vbafont.hxx +++ b/sc/source/ui/vba/vbafont.hxx @@ -46,7 +46,12 @@ class ScVbaFont : public ScVbaFont_BASE ScCellRangeObj* mpRangeObj; SfxItemSet* GetDataSet(); public: - ScVbaFont( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const ScVbaPalette& dPalette, css::uno::Reference< css::beans::XPropertySet > xPropertySet, ScCellRangeObj* pRangeObj = NULL ) throw ( css::uno::RuntimeException ); + ScVbaFont( + const css::uno::Reference< ov::XHelperInterface >& xParent, + const css::uno::Reference< css::uno::XComponentContext >& xContext, + const ScVbaPalette& dPalette, + const css::uno::Reference< css::beans::XPropertySet >& xPropertySet, + ScCellRangeObj* pRangeObj = 0, bool bFormControl = false ) throw ( css::uno::RuntimeException ); virtual ~ScVbaFont();// {} // Attributes diff --git a/sc/source/ui/vba/vbaformat.cxx b/sc/source/ui/vba/vbaformat.cxx index c98029fb1292..d08451af63f4 100644 --- a/sc/source/ui/vba/vbaformat.cxx +++ b/sc/source/ui/vba/vbaformat.cxx @@ -40,12 +40,16 @@ #include <rtl/math.hxx> +#include "excelvbahelper.hxx" #include "vbaborders.hxx" #include "vbapalette.hxx" #include "vbafont.hxx" #include "vbainterior.hxx" -#include "unonames.hxx" +#include <unonames.hxx> +#include <cellsuno.hxx> +#include <scitems.hxx> +#include <attrib.hxx> using namespace ::ooo::vba; using namespace ::com::sun::star; @@ -571,14 +575,24 @@ ScVbaFormat<Ifc1>::getLocked( ) throw (script::BasicErrorException, uno::Runtim uno::Any aCellProtection = aNULL(); try { - rtl::OUString sCellProt( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_CELLPRO ) ); + if (!isAmbiguous(sCellProt)) { - util::CellProtection cellProtection; - mxPropertySet->getPropertyValue(sCellProt) >>= cellProtection; - - aCellProtection = uno::makeAny( cellProtection.IsLocked ); + SfxItemSet* pDataSet = getCurrentDataSet(); + if ( pDataSet ) + { + const ScProtectionAttr& rProtAttr = (const ScProtectionAttr &) pDataSet->Get(ATTR_PROTECTION, TRUE); + SfxItemState eState = pDataSet->GetItemState(ATTR_PROTECTION, TRUE, NULL); + if(eState != SFX_ITEM_DONTCARE) + aCellProtection = uno::makeAny(rProtAttr.GetProtection()); + } + else // fallback to propertyset + { + util::CellProtection cellProtection; + mxPropertySet->getPropertyValue(sCellProt) >>= aCellProtection; + aCellProtection = uno::makeAny( cellProtection.IsLocked ); + } } } catch (uno::Exception& ) @@ -598,9 +612,20 @@ ScVbaFormat<Ifc1>::getFormulaHidden( ) throw (script::BasicErrorException, uno: rtl::OUString sCellProt( RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_CELLPRO ) ); if (!isAmbiguous(sCellProt)) { - util::CellProtection aCellProtection; - mxPropertySet->getPropertyValue(sCellProt) >>= aCellProtection; - aBoolRet = uno::makeAny( aCellProtection.IsFormulaHidden ); + SfxItemSet* pDataSet = getCurrentDataSet(); + if ( pDataSet ) + { + const ScProtectionAttr& rProtAttr = (const ScProtectionAttr &) pDataSet->Get(ATTR_PROTECTION, TRUE); + SfxItemState eState = pDataSet->GetItemState(ATTR_PROTECTION, TRUE, NULL); + if(eState != SFX_ITEM_DONTCARE) + aBoolRet = uno::makeAny(rProtAttr.GetHideFormula()); + } + else + { + util::CellProtection aCellProtection; + mxPropertySet->getPropertyValue(sCellProt) >>= aCellProtection; + aBoolRet = uno::makeAny( aCellProtection.IsFormulaHidden ); + } } } catch (uno::Exception e) @@ -794,6 +819,24 @@ ScVbaFormat<Ifc1>::getServiceNames() return aServiceNames; } +template< typename Ifc1 > +ScCellRangesBase* +ScVbaFormat<Ifc1>::getCellRangesBase() throw ( ::uno::RuntimeException ) +{ + return ScCellRangesBase::getImplementation( mxPropertySet ); +} + +template< typename Ifc1 > +SfxItemSet* +ScVbaFormat<Ifc1>::getCurrentDataSet( ) throw ( uno::RuntimeException ) +{ + SfxItemSet* pDataSet = excel::ScVbaCellRangeAccess::GetDataSet( getCellRangesBase() ); + if ( !pDataSet ) + throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Can't access Itemset for XPropertySet" ) ), uno::Reference< uno::XInterface >() ); + return pDataSet; +} + + template class ScVbaFormat< excel::XStyle >; template class ScVbaFormat< excel::XRange >; diff --git a/sc/source/ui/vba/vbaformat.hxx b/sc/source/ui/vba/vbaformat.hxx index e024cd68b9ad..bfa88d6c7cb8 100644 --- a/sc/source/ui/vba/vbaformat.hxx +++ b/sc/source/ui/vba/vbaformat.hxx @@ -38,6 +38,8 @@ #include <com/sun/star/beans/XPropertyState.hpp> #include <vbahelper/vbahelperinterface.hxx> +class ScCellRangesBase; + template< typename Ifc1 > class ScVbaFormat : public InheritedHelperInterfaceImpl1< Ifc1 > { @@ -60,6 +62,9 @@ protected: css::uno::Reference< css::beans::XPropertyState > getXPropertyState() throw ( css::uno::RuntimeException ); void initializeNumberFormats() throw ( css::script::BasicErrorException ); void setNumberFormat( css::lang::Locale _aLocale, const rtl::OUString& _sFormatString) throw( css::script::BasicErrorException ); + SfxItemSet* getCurrentDataSet( ) throw ( css::uno::RuntimeException ); +protected: + virtual ScCellRangesBase* getCellRangesBase() throw ( css::uno::RuntimeException ); public: ScVbaFormat( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext > & xContext, const css::uno::Reference< css::beans::XPropertySet >& _xPropertySet, const css::uno::Reference< css::frame::XModel >& xModel, bool bCheckAmbiguoity ) throw ( css::script::BasicErrorException ); virtual ~ScVbaFormat() {} diff --git a/sc/source/ui/vba/vbahelper.cxx b/sc/source/ui/vba/vbahelper.cxx index 4bc57e150c8f..cc76b1e60125 100644 --- a/sc/source/ui/vba/vbahelper.cxx +++ b/sc/source/ui/vba/vbahelper.cxx @@ -160,73 +160,6 @@ public: } }; -void -dispatchRequests (uno::Reference< frame::XModel>& xModel,rtl::OUString & aUrl, uno::Sequence< beans::PropertyValue >& sProps ) -{ - - util::URL url ; - url.Complete = aUrl; - rtl::OUString emptyString = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "" )); - uno::Reference<frame::XController> xController = xModel->getCurrentController(); - uno::Reference<frame::XFrame> xFrame = xController->getFrame(); - uno::Reference<frame::XDispatchProvider> xDispatchProvider (xFrame,uno::UNO_QUERY_THROW); - try - { - uno::Reference< beans::XPropertySet > xProps( ::comphelper::getProcessServiceFactory(), uno::UNO_QUERY_THROW ); - uno::Reference<uno::XComponentContext > xContext( xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))), uno::UNO_QUERY_THROW ); - if ( !xContext.is() ) - { - return ; - } - - uno::Reference<lang::XMultiComponentFactory > xServiceManager( - xContext->getServiceManager() ); - if ( !xServiceManager.is() ) - { - return ; - } - uno::Reference<util::XURLTransformer> xParser( xServiceManager->createInstanceWithContext( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.util.URLTransformer" ) ) - ,xContext), uno::UNO_QUERY_THROW ); - if (!xParser.is()) - return; - xParser->parseStrict (url); - } - catch ( uno::Exception & /*e*/ ) - { - return ; - } - - uno::Reference<frame::XDispatch> xDispatcher = xDispatchProvider->queryDispatch(url,emptyString,0); - - uno::Sequence<beans::PropertyValue> dispatchProps(1); - - sal_Int32 nProps = sProps.getLength(); - beans::PropertyValue* pDest = dispatchProps.getArray(); - if ( nProps ) - { - dispatchProps.realloc( nProps + 1 ); - // need to reaccquire pDest after realloc - pDest = dispatchProps.getArray(); - beans::PropertyValue* pSrc = sProps.getArray(); - for ( sal_Int32 index=0; index<nProps; ++index, ++pSrc, ++pDest ) - *pDest = *pSrc; - } - - (*pDest).Name = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Silent" )); - (*pDest).Value <<= (sal_Bool)sal_True; - - if (xDispatcher.is()) - xDispatcher->dispatch( url, dispatchProps ); -} - -void -dispatchRequests (uno::Reference< frame::XModel>& xModel,rtl::OUString & aUrl) -{ - uno::Sequence<beans::PropertyValue> dispatchProps; - dispatchRequests( xModel, aUrl, dispatchProps ); -} - - void dispatchExecute(css::uno::Reference< css::frame::XModel>& xModel, USHORT nSlot, SfxCallMode nCall) { ScTabViewShell* pViewShell = getBestViewShell( xModel ); @@ -821,7 +754,5 @@ ScVbaCellRangeAccess::GetDataSet( ScCellRangeObj* pRangeObj ) } -} // openoffice -} //org -======= ->>>>>>> other +} // vba +} // ooo diff --git a/sc/source/ui/vba/vbahyperlink.cxx b/sc/source/ui/vba/vbahyperlink.cxx index f3203b130bf2..e37df1e118b4 100644 --- a/sc/source/ui/vba/vbahyperlink.cxx +++ b/sc/source/ui/vba/vbahyperlink.cxx @@ -24,100 +24,213 @@ * for a copy of the LGPLv3 License. * ************************************************************************/ -#include <vbahelper/helperdecl.hxx> + #include "vbahyperlink.hxx" +#include <vbahelper/helperdecl.hxx> #include <com/sun/star/container/XIndexAccess.hpp> +#include <com/sun/star/text/XText.hpp> #include <com/sun/star/text/XTextFieldsSupplier.hpp> #include <com/sun/star/container/XEnumerationAccess.hpp> +#include <ooo/vba/office/MsoHyperlinkType.hpp> +#include <ooo/vba/msforms/XShape.hpp> #include "vbarange.hxx" using namespace ::ooo::vba; using namespace ::com::sun::star; +using ::rtl::OUString; +using ::rtl::OUStringBuffer; -ScVbaHyperlink::ScVbaHyperlink( uno::Sequence< uno::Any> const & args, - uno::Reference< uno::XComponentContext> const & xContext ) throw ( lang::IllegalArgumentException ) : HyperlinkImpl_BASE( getXSomethingFromArgs< XHelperInterface >( args, 0 ), xContext ), mxCell( getXSomethingFromArgs< table::XCell >( args, 1, false ) ) +// ============================================================================ + +ScVbaHyperlink::ScVbaHyperlink( const uno::Sequence< uno::Any >& rArgs, + const uno::Reference< uno::XComponentContext >& rxContext ) throw (lang::IllegalArgumentException) : + HyperlinkImpl_BASE( getXSomethingFromArgs< XHelperInterface >( rArgs, 0 ), rxContext ), + mxCell( getXSomethingFromArgs< table::XCell >( rArgs, 1, false ) ), + mnType( office::MsoHyperlinkType::msoHyperlinkRange ) { - mxCell = getXSomethingFromArgs< table::XCell >( args, 1, false ); uno::Reference< text::XTextFieldsSupplier > xTextFields( mxCell, uno::UNO_QUERY_THROW ); uno::Reference< container::XIndexAccess > xIndex( xTextFields->getTextFields(), uno::UNO_QUERY_THROW ); mxTextField.set( xIndex->getByIndex(0), uno::UNO_QUERY_THROW ); } -ScVbaHyperlink::~ScVbaHyperlink() +ScVbaHyperlink::ScVbaHyperlink( const uno::Reference< XHelperInterface >& rxAnchor, + const uno::Reference< uno::XComponentContext >& rxContext, + const uno::Any& rAddress, const uno::Any& rSubAddress, + const uno::Any& rScreenTip, const uno::Any& rTextToDisplay ) throw (uno::RuntimeException) : + HyperlinkImpl_BASE( rxAnchor, rxContext ) // parent of Hyperlink is the anchor object { -} + // extract parameters, Address must not be empty + UrlComponents aUrlComp; + OUString aTextToDisplay; + if( !(rAddress >>= aUrlComp.first) || (aUrlComp.first.getLength() == 0) ) + throw uno::RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM( "Cannot get address" ) ), uno::Reference< uno::XInterface >() ); + rSubAddress >>= aUrlComp.second; + rScreenTip >>= maScreenTip; + rTextToDisplay >>= aTextToDisplay; -::rtl::OUString -ScVbaHyperlink::getAddress() throw (css::uno::RuntimeException) -{ - rtl::OUString aAddress; - uno::Any aValue = mxTextField->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) ) ); - aValue >>= aAddress; - return aAddress; + // get anchor range or anchor shape + uno::Reference< excel::XRange > xAnchorRange( rxAnchor, uno::UNO_QUERY ); + if( xAnchorRange.is() ) + { + mnType = office::MsoHyperlinkType::msoHyperlinkRange; + // only single ranges are allowed + uno::Reference< table::XCellRange > xUnoRange( ScVbaRange::getCellRange( xAnchorRange ), uno::UNO_QUERY_THROW ); + // insert the hyperlink into the top-left cell only + mxCell.set( xUnoRange->getCellByPosition( 0, 0 ), uno::UNO_SET_THROW ); + uno::Reference< text::XText > xText( mxCell, uno::UNO_QUERY_THROW ); + // use cell text or URL if no TextToDisplay has been passed + if( aTextToDisplay.getLength() == 0 ) + { + aTextToDisplay = xText->getString(); + if( aTextToDisplay.getLength() == 0 ) + { + OUStringBuffer aBuffer( aUrlComp.first ); + if( aUrlComp.second.getLength() > 0 ) + aBuffer.appendAscii( RTL_CONSTASCII_STRINGPARAM( " - " ) ).append( aUrlComp.second ); + aTextToDisplay = aBuffer.makeStringAndClear(); + } + } + // create and initialize a new URL text field + uno::Reference< lang::XMultiServiceFactory > xFactory( ScVbaRange::getUnoModel( xAnchorRange ), uno::UNO_QUERY_THROW ); + uno::Reference< text::XTextContent > xUrlField( xFactory->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.text.TextField.URL" ) ) ), uno::UNO_QUERY_THROW ); + mxTextField.set( xUrlField, uno::UNO_QUERY_THROW ); + setUrlComponents( aUrlComp ); + setTextToDisplay( aTextToDisplay ); + // insert the text field into the document + xText->setString( OUString() ); + uno::Reference< text::XTextRange > xRange( xText->createTextCursor(), uno::UNO_QUERY_THROW ); + xText->insertTextContent( xRange, xUrlField, sal_False ); + } + else + { + uno::Reference< msforms::XShape > xAnchorShape( rxAnchor, uno::UNO_QUERY_THROW ); + mnType = office::MsoHyperlinkType::msoHyperlinkShape; + // FIXME: insert hyperlink into shape + throw uno::RuntimeException(); + } } -void -ScVbaHyperlink::setAddress( const ::rtl::OUString & rAddress ) throw (css::uno::RuntimeException) +ScVbaHyperlink::~ScVbaHyperlink() { - uno::Any aValue; - aValue <<= rAddress; - mxTextField->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) ), aValue ); } -::rtl::OUString -ScVbaHyperlink::getName() throw (css::uno::RuntimeException) +OUString ScVbaHyperlink::getName() throw (uno::RuntimeException) { // it seems this attribute is same as TextToDisplay return getTextToDisplay(); } -void -ScVbaHyperlink::setName( const ::rtl::OUString & rName ) throw (css::uno::RuntimeException) +void ScVbaHyperlink::setName( const OUString& rName ) throw (uno::RuntimeException) { setTextToDisplay( rName ); } -::rtl::OUString -ScVbaHyperlink::getTextToDisplay() throw (css::uno::RuntimeException) +OUString ScVbaHyperlink::getAddress() throw (uno::RuntimeException) { - rtl::OUString aTextToDisplay; - uno::Any aValue = mxTextField->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Representation" ) ) ); - aValue >>= aTextToDisplay; - return aTextToDisplay; + return getUrlComponents().first; +} + +void ScVbaHyperlink::setAddress( const OUString& rAddress ) throw (uno::RuntimeException) +{ + UrlComponents aUrlComp = getUrlComponents(); + aUrlComp.first = rAddress; + setUrlComponents( aUrlComp ); +} + +OUString ScVbaHyperlink::getSubAddress() throw (uno::RuntimeException) +{ + return getUrlComponents().second; +} + +void ScVbaHyperlink::setSubAddress( const OUString& rSubAddress ) throw (uno::RuntimeException) +{ + UrlComponents aUrlComp = getUrlComponents(); + aUrlComp.second = rSubAddress; + setUrlComponents( aUrlComp ); } -void -ScVbaHyperlink::setTextToDisplay( const ::rtl::OUString & rTextToDisplay ) throw (css::uno::RuntimeException) +OUString SAL_CALL ScVbaHyperlink::getScreenTip() throw (uno::RuntimeException) { - uno::Any aValue; - aValue <<= rTextToDisplay; - mxTextField->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Representation" ) ), aValue ); + return maScreenTip; } -css::uno::Reference< ov::excel::XRange > SAL_CALL ScVbaHyperlink::Range() throw (css::uno::RuntimeException) +void SAL_CALL ScVbaHyperlink::setScreenTip( const OUString& rScreenTip ) throw (uno::RuntimeException) { - uno::Reference< table::XCellRange > xRange( mxCell,uno::UNO_QUERY_THROW ); - // FIXME: need to pass current worksheet as the parent of XRange. - return uno::Reference< excel::XRange >( new ScVbaRange( uno::Reference< XHelperInterface > (), mxContext, xRange ) ); + maScreenTip = rScreenTip; } -rtl::OUString& -ScVbaHyperlink::getServiceImplName() +OUString ScVbaHyperlink::getTextToDisplay() throw (uno::RuntimeException) { - static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaHyperlink") ); - return sImplName; + ensureTextField(); + OUString aTextToDisplay; + mxTextField->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "Representation" ) ) ) >>= aTextToDisplay; + return aTextToDisplay; +} + +void ScVbaHyperlink::setTextToDisplay( const OUString& rTextToDisplay ) throw (uno::RuntimeException) +{ + ensureTextField(); + mxTextField->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "Representation" ) ), uno::Any( rTextToDisplay ) ); } -uno::Sequence< rtl::OUString > -ScVbaHyperlink::getServiceNames() +sal_Int32 SAL_CALL ScVbaHyperlink::getType() throw (uno::RuntimeException) { - static uno::Sequence< rtl::OUString > aServiceNames; - if ( aServiceNames.getLength() == 0 ) + return mnType; +} + +uno::Reference< excel::XRange > SAL_CALL ScVbaHyperlink::getRange() throw (uno::RuntimeException) +{ + if( mnType == office::MsoHyperlinkType::msoHyperlinkRange ) { - aServiceNames.realloc( 1 ); - aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.Hyperlink" ) ); + // if constructed from Hyperlinks object, range has been passed as parent + uno::Reference< excel::XRange > xAnchorRange( getParent(), uno::UNO_QUERY ); + if( !xAnchorRange.is() ) + { + // if constructed via service c'tor, create new range based on cell + uno::Reference< table::XCellRange > xRange( mxCell, uno::UNO_QUERY_THROW ); + // FIXME: need to pass current worksheet as the parent of XRange. + xAnchorRange.set( new ScVbaRange( uno::Reference< XHelperInterface >(), mxContext, xRange ) ); + } + return xAnchorRange; } - return aServiceNames; + // error if called at a shape Hyperlink object + throw uno::RuntimeException(); +} + +uno::Reference< msforms::XShape > SAL_CALL ScVbaHyperlink::getShape() throw (uno::RuntimeException) +{ + // error if called at a range Hyperlink object + return uno::Reference< msforms::XShape >( getParent(), uno::UNO_QUERY_THROW ); +} + +VBAHELPER_IMPL_XHELPERINTERFACE( ScVbaHyperlink, "ooo.vba.excel.Hyperlink" ) + +// private -------------------------------------------------------------------- + +void ScVbaHyperlink::ensureTextField() throw (uno::RuntimeException) +{ + if( !mxTextField.is() ) + throw uno::RuntimeException(); +} + +ScVbaHyperlink::UrlComponents ScVbaHyperlink::getUrlComponents() throw (uno::RuntimeException) +{ + ensureTextField(); + OUString aUrl; + mxTextField->getPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) ) ) >>= aUrl; + sal_Int32 nHashPos = aUrl.indexOf( '#' ); + if( nHashPos < 0 ) + return UrlComponents( aUrl, OUString() ); + return UrlComponents( aUrl.copy( 0, nHashPos ), aUrl.copy( nHashPos + 1 ) ); +} + +void ScVbaHyperlink::setUrlComponents( const UrlComponents& rUrlComp ) throw (uno::RuntimeException) +{ + ensureTextField(); + OUStringBuffer aUrl( rUrlComp.first ); + if( rUrlComp.second.getLength() > 0 ) + aUrl.append( sal_Unicode( '#' ) ).append( rUrlComp.second ); + mxTextField->setPropertyValue( OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) ), uno::Any( aUrl.makeStringAndClear() ) ); } namespace hyperlink @@ -129,3 +242,5 @@ extern sdecl::ServiceDecl const serviceDecl( "ScVbaHyperlink", "ooo.vba.excel.Hyperlink" ); } + +// ============================================================================ diff --git a/sc/source/ui/vba/vbahyperlink.hxx b/sc/source/ui/vba/vbahyperlink.hxx index 570ecdcc2f45..e1520b59c15a 100644 --- a/sc/source/ui/vba/vbahyperlink.hxx +++ b/sc/source/ui/vba/vbahyperlink.hxx @@ -24,6 +24,7 @@ * for a copy of the LGPLv3 License. * ************************************************************************/ + #ifndef SC_VBA_HYPERLINK_HXX #define SC_VBA_HYPERLINK_HXX @@ -38,27 +39,50 @@ typedef InheritedHelperInterfaceImpl1< ov::excel::XHyperlink > HyperlinkImpl_BAS class ScVbaHyperlink : public HyperlinkImpl_BASE { - css::uno::Reference< css::table::XCell > mxCell; - css::uno::Reference< css::beans::XPropertySet > mxTextField; - public: - ScVbaHyperlink( css::uno::Sequence< css::uno::Any > const& aArgs, css::uno::Reference< css::uno::XComponentContext > const& xContext ) throw ( css::lang::IllegalArgumentException ); + ScVbaHyperlink( + const css::uno::Sequence< css::uno::Any >& rArgs, + const css::uno::Reference< css::uno::XComponentContext >& rxContext ) throw (css::lang::IllegalArgumentException); + + ScVbaHyperlink( + const css::uno::Reference< ov::XHelperInterface >& rxAnchor, + const css::uno::Reference< css::uno::XComponentContext >& rxContext, + const css::uno::Any& rAddress, const css::uno::Any& rSubAddress, + const css::uno::Any& rScreenTip, const css::uno::Any& rTextToDisplay ) throw (css::uno::RuntimeException); + virtual ~ScVbaHyperlink(); // Attributes - virtual ::rtl::OUString SAL_CALL getAddress() throw (css::uno::RuntimeException); - virtual void SAL_CALL setAddress( const ::rtl::OUString &rAddress ) throw (css::uno::RuntimeException); virtual ::rtl::OUString SAL_CALL getName() throw (css::uno::RuntimeException); - virtual void SAL_CALL setName( const ::rtl::OUString &rName ) throw (css::uno::RuntimeException); + virtual void SAL_CALL setName( const ::rtl::OUString& rName ) throw (css::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getAddress() throw (css::uno::RuntimeException); + virtual void SAL_CALL setAddress( const ::rtl::OUString& rAddress ) throw (css::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getSubAddress() throw (css::uno::RuntimeException); + virtual void SAL_CALL setSubAddress( const ::rtl::OUString& rSubAddress ) throw (css::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getScreenTip() throw (css::uno::RuntimeException); + virtual void SAL_CALL setScreenTip( const ::rtl::OUString& rScreenTip ) throw (css::uno::RuntimeException); virtual ::rtl::OUString SAL_CALL getTextToDisplay() throw (css::uno::RuntimeException); - virtual void SAL_CALL setTextToDisplay( const ::rtl::OUString &rTextToDisplay ) throw (css::uno::RuntimeException); - - // Methods - virtual css::uno::Reference< ov::excel::XRange > SAL_CALL Range() throw (css::uno::RuntimeException); + virtual void SAL_CALL setTextToDisplay( const ::rtl::OUString& rTextToDisplay ) throw (css::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getType() throw (css::uno::RuntimeException); + virtual css::uno::Reference< ov::excel::XRange > SAL_CALL getRange() throw (css::uno::RuntimeException); + virtual css::uno::Reference< ov::msforms::XShape > SAL_CALL getShape() throw (css::uno::RuntimeException); // XHelperInterface - virtual rtl::OUString& getServiceImplName(); - virtual css::uno::Sequence<rtl::OUString> getServiceNames(); + VBAHELPER_DECL_XHELPERINTERFACE + +private: + typedef ::std::pair< ::rtl::OUString, ::rtl::OUString > UrlComponents; + + void ensureTextField() throw (css::uno::RuntimeException); + UrlComponents getUrlComponents() throw (css::uno::RuntimeException); + void setUrlComponents( const UrlComponents& rUrlComp ) throw (css::uno::RuntimeException); + +private: + css::uno::Reference< css::table::XCell > mxCell; + css::uno::Reference< css::beans::XPropertySet > mxTextField; + ::rtl::OUString maScreenTip; + long mnType; }; + #endif /* SC_VBA_HYPERLINK_HXX */ diff --git a/sc/source/ui/vba/vbahyperlinks.cxx b/sc/source/ui/vba/vbahyperlinks.cxx new file mode 100755 index 000000000000..89a8109e6aa2 --- /dev/null +++ b/sc/source/ui/vba/vbahyperlinks.cxx @@ -0,0 +1,293 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "vbahyperlinks.hxx" +#include <algorithm> +#include <vector> +#include <ooo/vba/office/MsoHyperlinkType.hpp> +#include "rangelst.hxx" +#include "vbahyperlink.hxx" +#include "vbarange.hxx" + +using namespace ::ooo::vba; +using namespace ::com::sun::star; +using ::rtl::OUString; + +// ============================================================================ + +namespace { + +/** Returns true, if every range of rxInner is contained in any range of rScOuter. */ +bool lclContains( const ScRangeList& rScOuter, const uno::Reference< excel::XRange >& rxInner ) throw (uno::RuntimeException) +{ + const ScRangeList& rScInner = ScVbaRange::getScRangeList( rxInner ); + if( (rScInner.Count() == 0) || (rScOuter.Count() == 0) ) + throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Empty range objects" ) ), uno::Reference< uno::XInterface >() ); + + for( ULONG nIndex = 0, nCount = rScInner.Count(); nIndex < nCount; ++nIndex ) + if( !rScOuter.In( *rScInner.GetObject( nIndex ) ) ) + return false; + return true; +} + +// ---------------------------------------------------------------------------- + +/** Functor to decide whether the anchors of two Hyperlink objects are equal. */ +struct EqualAnchorFunctor +{ + uno::Reference< excel::XRange > mxAnchorRange; + uno::Reference< msforms::XShape > mxAnchorShape; + sal_Int32 mnType; + EqualAnchorFunctor( const uno::Reference< excel::XHyperlink >& rxHlink ) throw (uno::RuntimeException); + bool operator()( const uno::Reference< excel::XHyperlink >& rxHlink ) const throw (uno::RuntimeException); +}; + +EqualAnchorFunctor::EqualAnchorFunctor( const uno::Reference< excel::XHyperlink >& rxHlink ) throw (uno::RuntimeException) : + mnType( rxHlink->getType() ) +{ + switch( mnType ) + { + case office::MsoHyperlinkType::msoHyperlinkRange: + mxAnchorRange.set( rxHlink->getRange(), uno::UNO_QUERY_THROW ); + break; + case office::MsoHyperlinkType::msoHyperlinkShape: + case office::MsoHyperlinkType::msoHyperlinkInlineShape: + mxAnchorShape.set( rxHlink->getShape(), uno::UNO_QUERY_THROW ); + break; + default: + throw uno::RuntimeException(); + } +} + +bool EqualAnchorFunctor::operator()( const uno::Reference< excel::XHyperlink >& rxHlink ) const throw (uno::RuntimeException) +{ + sal_Int32 nType = rxHlink->getType(); + if( nType != mnType ) + return false; + + switch( nType ) + { + case office::MsoHyperlinkType::msoHyperlinkRange: + { + uno::Reference< excel::XRange > xAnchorRange( rxHlink->getRange(), uno::UNO_QUERY_THROW ); + const ScRangeList& rScRanges1 = ScVbaRange::getScRangeList( xAnchorRange ); + const ScRangeList& rScRanges2 = ScVbaRange::getScRangeList( mxAnchorRange ); + return (rScRanges1.Count() == 1) && (rScRanges2.Count() == 1) && (*rScRanges1.GetObject( 0 ) == *rScRanges2.GetObject( 0 )); + } + case office::MsoHyperlinkType::msoHyperlinkShape: + case office::MsoHyperlinkType::msoHyperlinkInlineShape: + { + uno::Reference< msforms::XShape > xAnchorShape( rxHlink->getShape(), uno::UNO_QUERY_THROW ); + return xAnchorShape.get() == mxAnchorShape.get(); + } + default: + throw uno::RuntimeException(); + } +} + +} // namespace + +// ============================================================================ + +namespace detail { + +class ScVbaHlinkContainer : public ::cppu::WeakImplHelper1< container::XIndexAccess > +{ +public: + explicit ScVbaHlinkContainer() throw (uno::RuntimeException); + explicit ScVbaHlinkContainer( const ScVbaHlinkContainerRef& rxSheetContainer, const ScRangeList& rScRanges ) throw (uno::RuntimeException); + virtual ~ScVbaHlinkContainer(); + + /** Inserts the passed hyperlink into the collection. Will remove a + Hyperlink object with the same anchor as the passed Hyperlink object. */ + void insertHyperlink( const uno::Reference< excel::XHyperlink >& rxHlink ) throw (uno::RuntimeException); + + // XIndexAccess + virtual sal_Int32 SAL_CALL getCount() throw (uno::RuntimeException); + virtual uno::Any SAL_CALL getByIndex( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException); + + // XElementAccess + virtual uno::Type SAL_CALL getElementType() throw (uno::RuntimeException); + virtual sal_Bool SAL_CALL hasElements() throw (uno::RuntimeException); + +private: + typedef ::std::vector< uno::Reference< excel::XHyperlink > > HyperlinkVector; + HyperlinkVector maHlinks; +}; + +// ---------------------------------------------------------------------------- + +ScVbaHlinkContainer::ScVbaHlinkContainer() throw (uno::RuntimeException) +{ + // TODO FIXME: fill with existing hyperlinks +} + +ScVbaHlinkContainer::ScVbaHlinkContainer( const ScVbaHlinkContainerRef& rxSheetContainer, + const ScRangeList& rScRanges ) throw (uno::RuntimeException) +{ + for( sal_Int32 nIndex = 0, nCount = rxSheetContainer->getCount(); nIndex < nCount; ++nIndex ) + { + uno::Reference< excel::XHyperlink > xHlink( rxSheetContainer->getByIndex( nIndex ), uno::UNO_QUERY_THROW ); + uno::Reference< excel::XRange > xHlinkRange( xHlink->getRange(), uno::UNO_QUERY_THROW ); + if( lclContains( rScRanges, xHlinkRange ) ) + maHlinks.push_back( xHlink ); + } +} + +ScVbaHlinkContainer::~ScVbaHlinkContainer() +{ +} + +void ScVbaHlinkContainer::insertHyperlink( const uno::Reference< excel::XHyperlink >& rxHlink ) throw (uno::RuntimeException) +{ + HyperlinkVector::iterator aIt = ::std::find_if( maHlinks.begin(), maHlinks.end(), EqualAnchorFunctor( rxHlink ) ); + if( aIt == maHlinks.end() ) + maHlinks.push_back( rxHlink ); + else + *aIt = rxHlink; +} + +sal_Int32 SAL_CALL ScVbaHlinkContainer::getCount() throw (uno::RuntimeException) +{ + return static_cast< sal_Int32 >( maHlinks.size() ); +} + +uno::Any SAL_CALL ScVbaHlinkContainer::getByIndex( sal_Int32 nIndex ) + throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException) +{ + if( (0 <= nIndex) && (nIndex < getCount()) ) + return uno::Any( maHlinks[ static_cast< size_t >( nIndex ) ] ); + throw lang::IndexOutOfBoundsException(); +} + +uno::Type SAL_CALL ScVbaHlinkContainer::getElementType() throw (uno::RuntimeException) +{ + return excel::XHyperlink::static_type( 0 ); +} + +sal_Bool SAL_CALL ScVbaHlinkContainer::hasElements() throw (uno::RuntimeException) +{ + return !maHlinks.empty(); +} + +// ============================================================================ + +ScVbaHlinkContainerMember::ScVbaHlinkContainerMember( ScVbaHlinkContainer* pContainer ) : + mxContainer( pContainer ) +{ +} + +ScVbaHlinkContainerMember::~ScVbaHlinkContainerMember() +{ +} + +} // namespace detail + +// ============================================================================ + +ScVbaHyperlinks::ScVbaHyperlinks( const uno::Reference< XHelperInterface >& rxParent, + const uno::Reference< uno::XComponentContext >& rxContext ) throw (uno::RuntimeException) : + detail::ScVbaHlinkContainerMember( new detail::ScVbaHlinkContainer ), + ScVbaHyperlinks_BASE( rxParent, rxContext, uno::Reference< container::XIndexAccess >( mxContainer.get() ) ) +{ +} + +ScVbaHyperlinks::ScVbaHyperlinks( const uno::Reference< XHelperInterface >& rxParent, + const uno::Reference< uno::XComponentContext >& rxContext, + const ScVbaHyperlinksRef& rxSheetHlinks, const ScRangeList& rScRanges ) throw (uno::RuntimeException) : + detail::ScVbaHlinkContainerMember( new detail::ScVbaHlinkContainer( rxSheetHlinks->mxContainer, rScRanges ) ), + ScVbaHyperlinks_BASE( rxParent, rxContext, uno::Reference< container::XIndexAccess >( mxContainer.get() ) ), + mxSheetHlinks( rxSheetHlinks ) +{ +} + +ScVbaHyperlinks::~ScVbaHyperlinks() +{ +} + +// XHyperlinks ---------------------------------------------------------------- + +uno::Reference< excel::XHyperlink > SAL_CALL ScVbaHyperlinks::Add( + const uno::Any& rAnchor, const uno::Any& rAddress, const uno::Any& rSubAddress, + const uno::Any& rScreenTip, const uno::Any& rTextToDisplay ) throw (uno::RuntimeException) +{ + /* If this Hyperlinks object has been craeted from a Range object, the + call to Add() is passed to the Hyperlinks object of the parent + worksheet. This container will not be modified (it will not contain the + inserted hyperlink). + For details, see documentation in hyperlinks.hxx. + */ + if( mxSheetHlinks.is() ) + return mxSheetHlinks->Add( rAnchor, rAddress, rSubAddress, rScreenTip, rTextToDisplay ); + + // get anchor object (can be a Range or a Shape object) + uno::Reference< XHelperInterface > xAnchor( rAnchor, uno::UNO_QUERY_THROW ); + + /* Create the Hyperlink object, this tries to insert the hyperlink into + the spreadsheet document. Parent of the Hyperlink is the anchor object. */ + uno::Reference< excel::XHyperlink > xHlink( new ScVbaHyperlink( + xAnchor, mxContext, rAddress, rSubAddress, rScreenTip, rTextToDisplay ) ); + + /* If creation of the hyperlink did not throw, insert it into the + collection. */ + mxContainer->insertHyperlink( xHlink ); + return xHlink; +} + +void SAL_CALL ScVbaHyperlinks::Delete() throw (uno::RuntimeException) +{ + // FIXME not implemented + throw uno::RuntimeException(); +} + +// XEnumerationAccess --------------------------------------------------------- + +uno::Reference< container::XEnumeration > SAL_CALL ScVbaHyperlinks::createEnumeration() throw (uno::RuntimeException) +{ + return new SimpleIndexAccessToEnumeration( m_xIndexAccess ); +} + +// XElementAccess ------------------------------------------------------------- + +uno::Type SAL_CALL ScVbaHyperlinks::getElementType() throw (uno::RuntimeException) +{ + return excel::XHyperlink::static_type( 0 ); +} + +// ScVbaCollectionBase -------------------------------------------------------- + +uno::Any ScVbaHyperlinks::createCollectionObject( const uno::Any& rSource ) +{ + // container stores XHyperlink objects, just return the passed object + return rSource; +} + +// XHelperInterface ----------------------------------------------------------- + +VBAHELPER_IMPL_XHELPERINTERFACE( ScVbaHyperlinks, "ooo.vba.excel.Hyperlinks" ) + +// ============================================================================ diff --git a/sc/source/ui/vba/vbahyperlinks.hxx b/sc/source/ui/vba/vbahyperlinks.hxx new file mode 100755 index 000000000000..ca7d990ad6a8 --- /dev/null +++ b/sc/source/ui/vba/vbahyperlinks.hxx @@ -0,0 +1,150 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SC_VBA_HYPERLINKS_HXX +#define SC_VBA_HYPERLINKS_HXX + +#include <ooo/vba/excel/XHyperlinks.hpp> +#include <rtl/ref.hxx> +#include <vbahelper/vbacollectionimpl.hxx> + +class ScRangeList; + +// ============================================================================ + +namespace detail { + +class ScVbaHlinkContainer; +typedef ::rtl::Reference< ScVbaHlinkContainer > ScVbaHlinkContainerRef; + +/** Base class for ScVbaHyperlinks to get an initialized ScVbaHlinkContainer + class member before the ScVbaHyperlinks_BASE base class will be constructed. + */ +struct ScVbaHlinkContainerMember +{ + ScVbaHlinkContainerRef mxContainer; + + explicit ScVbaHlinkContainerMember( ScVbaHlinkContainer* pContainer ); + ~ScVbaHlinkContainerMember(); +}; + +} // namespace detail + +// ============================================================================ + +class ScVbaHyperlinks; +typedef ::rtl::Reference< ScVbaHyperlinks > ScVbaHyperlinksRef; + +typedef CollTestImplHelper< ov::excel::XHyperlinks > ScVbaHyperlinks_BASE; + +/** Represents a collection of hyperlinks of a worksheet or of a range. + + When a Hyperlinks collection object has been constructed from a VBA + Worksheet object, it will always represent the current set of all + hyperlinks existing in the sheet. Insertion and deletion of hyperlinks will + be reflected by the instance. + + When a Hyperlinks collection object has been constructed from a VBA Range + object, it will represent the set of hyperlinks that have existed at its + construction time, and that are located completely inside the range(s) + represented by the Range object. Insertion and deletion of hyperlinks will + *not* be reflected by that instance. The instance will always offer all + hyperlinks it has been constructed with, even if they no longer exist. + Furthermore, the instance will not offer hyperlinks inserted later, even if + the instance itself has been used to insert the new hyperlinks. + + VBA code example: + + With ThisWorkbook.Worksheets(1) + + Set hlinks = .Hyperlinks ' global Hyperlinks object + Set myrange = .Range("A1:C3") + Set rangelinks1 = myrange.Hyperlinks ' hyperlinks of range A1:C3 + + MsgBox hlinks.Count ' 0 + MsgBox rangelinks1.Count ' 0 + + hlinks.Add .Range("A1"), "http://example.com" + ' a new hyperlink has been added in cell A1 + + MsgBox hlinks.Count ' 1 + MsgBox rangelinks1.Count ' still 0! + Set rangelinks2 = myrange.Hyperlinks ' hyperlinks of range A1:C3 + MsgBox rangelinks2.Count ' 1 (constructed after Add) + + rangelinks1.Add .Range("A2"), "http://example.com" + ' a new hyperlink has been constructed via the rangelinks1 object + ' but this addition has been done by the worksheet Hyperlinks object + + MsgBox hlinks.Count ' 2 + MsgBox rangelinks1.Count ' still 0!!! + MsgBox rangelinks2.Count ' still 1!!! + MsgBox myrange.Hyperlinks.Count ' 2 (constructed after Add) + + End With + */ +class ScVbaHyperlinks : private detail::ScVbaHlinkContainerMember, public ScVbaHyperlinks_BASE +{ +public: + explicit ScVbaHyperlinks( + const css::uno::Reference< ov::XHelperInterface >& rxParent, + const css::uno::Reference< css::uno::XComponentContext >& rxContext ) throw (css::uno::RuntimeException); + + explicit ScVbaHyperlinks( + const css::uno::Reference< ov::XHelperInterface >& rxParent, + const css::uno::Reference< css::uno::XComponentContext >& rxContext, + const ScVbaHyperlinksRef& rxSheetHlinks, const ScRangeList& rScRanges ) throw (css::uno::RuntimeException); + + virtual ~ScVbaHyperlinks(); + + // XHyperlinks + virtual css::uno::Reference< ov::excel::XHyperlink > SAL_CALL Add( + const css::uno::Any& rAnchor, const css::uno::Any& rAddress, const css::uno::Any& rSubAddress, + const css::uno::Any& rScreenTip, const css::uno::Any& rTextToDisplay ) + throw (css::uno::RuntimeException); + + virtual void SAL_CALL Delete() throw (css::uno::RuntimeException); + + // XEnumerationAccess + virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() throw (css::uno::RuntimeException); + + // XElementAccess + virtual css::uno::Type SAL_CALL getElementType() throw (css::uno::RuntimeException); + + // ScVbaCollectionBase + virtual css::uno::Any createCollectionObject( const css::uno::Any& rSource ); + + // XHelperInterface + VBAHELPER_DECL_XHELPERINTERFACE + +private: + ScVbaHyperlinksRef mxSheetHlinks; +}; + +// ============================================================================ + +#endif diff --git a/sc/source/ui/vba/vbainterior.cxx b/sc/source/ui/vba/vbainterior.cxx index 3af6243e0fa7..face47767bdc 100644 --- a/sc/source/ui/vba/vbainterior.cxx +++ b/sc/source/ui/vba/vbainterior.cxx @@ -40,10 +40,13 @@ #include <comphelper/processfactory.hxx> #include <cppuhelper/queryinterface.hxx> +#include <map> + #include <svx/xtable.hxx> #include "vbainterior.hxx" #include "vbapalette.hxx" +#include "document.hxx" #define STATIC_TABLE_SIZE( array ) (sizeof(array)/sizeof(*(array))) #define COLORMAST 0xFFFFFF diff --git a/sc/source/ui/vba/vbainterior.hxx b/sc/source/ui/vba/vbainterior.hxx index f0d4db1334fd..027d06040af9 100644 --- a/sc/source/ui/vba/vbainterior.hxx +++ b/sc/source/ui/vba/vbainterior.hxx @@ -36,6 +36,8 @@ #include <com/sun/star/script/XInvocation.hpp> #include <vbahelper/vbahelperinterface.hxx> +#include <tools/color.hxx> + class ScDocument; typedef InheritedHelperInterfaceImpl1< ov::excel::XInterior > ScVbaInterior_BASE; diff --git a/sc/source/ui/vba/vbaname.cxx b/sc/source/ui/vba/vbaname.cxx index bc0b016177c7..a6e8a402425f 100644 --- a/sc/source/ui/vba/vbaname.cxx +++ b/sc/source/ui/vba/vbaname.cxx @@ -232,7 +232,10 @@ ScVbaName::setRefersToR1C1Local( const ::rtl::OUString & rRefersTo ) throw (css: css::uno::Reference< ov::excel::XRange > ScVbaName::getRefersToRange() throw (css::uno::RuntimeException) { - uno::Reference< ov::excel::XRange > xRange = ScVbaRange::getRangeObjectForName( mxContext, mxNamedRange->getName(), excel::getDocShell( mxModel ), formula::FormulaGrammar::CONV_XL_R1C1 ); + // FIXME: pass proper Worksheet parent + uno::Reference< ov::excel::XRange > xRange = ScVbaRange::getRangeObjectForName( + uno::Reference< XHelperInterface >(), mxContext, + mxNamedRange->getName(), excel::getDocShell( mxModel ), formula::FormulaGrammar::CONV_XL_R1C1 ); return xRange; } diff --git a/sc/source/ui/vba/vbapalette.cxx b/sc/source/ui/vba/vbapalette.cxx index 0ce55547d4a1..c6ae5c488a20 100644 --- a/sc/source/ui/vba/vbapalette.cxx +++ b/sc/source/ui/vba/vbapalette.cxx @@ -24,10 +24,12 @@ * for a copy of the LGPLv3 License. * ************************************************************************/ + #include "vbapalette.hxx" #include <cppuhelper/implbase1.hxx> #include <com/sun/star/beans/XPropertySet.hpp> - +#include <com/sun/star/container/XIndexAccess.hpp> +#include "excelvbahelper.hxx" using namespace ::com::sun::star; using namespace ::ooo::vba; @@ -82,6 +84,11 @@ public: }; +ScVbaPalette::ScVbaPalette( const uno::Reference< frame::XModel >& rxModel ) : + m_pShell( excel::getDocShell( rxModel ) ) +{ +} + uno::Reference< container::XIndexAccess > ScVbaPalette::getDefaultPalette() { diff --git a/sc/source/ui/vba/vbapalette.hxx b/sc/source/ui/vba/vbapalette.hxx index 9c7ea2ebc3f1..b51483772674 100644 --- a/sc/source/ui/vba/vbapalette.hxx +++ b/sc/source/ui/vba/vbapalette.hxx @@ -24,19 +24,26 @@ * for a copy of the LGPLv3 License. * ************************************************************************/ + #ifndef SC_VBAPALETTE_HXX #define SC_VBAPALETTE_HXX -#include "excelvbahelper.hxx" -#include <document.hxx> -#include <com/sun/star/container/XIndexAccess.hpp> +#include <vbahelper/vbahelper.hxx> + +namespace com { namespace sun { namespace star { + namespace container { class XIndexAccess; } + namespace frame { class XModel; } +} } } + +class SfxObjectShell; class ScVbaPalette { private: SfxObjectShell* m_pShell; public: - ScVbaPalette( SfxObjectShell* pShell = NULL ) : m_pShell( pShell ){} + ScVbaPalette( SfxObjectShell* pShell = 0 ) : m_pShell( pShell ) {} + ScVbaPalette( const css::uno::Reference< css::frame::XModel >& rxModel ); // if no palette available e.g. because the document doesn't have a // palette defined then a default palette will be returned. css::uno::Reference< css::container::XIndexAccess > getPalette() const; diff --git a/sc/source/ui/vba/vbapane.cxx b/sc/source/ui/vba/vbapane.cxx index 263529dde145..29d7a286b402 100644 --- a/sc/source/ui/vba/vbapane.cxx +++ b/sc/source/ui/vba/vbapane.cxx @@ -24,18 +24,26 @@ * for a copy of the LGPLv3 License. * ************************************************************************/ -#include<com/sun/star/table/CellRangeAddress.hpp> -#include<vbapane.hxx> + +#include "vbapane.hxx" +#include <com/sun/star/sheet/XSpreadsheet.hpp> +#include <com/sun/star/sheet/XSpreadsheetDocument.hpp> +#include <com/sun/star/table/CellRangeAddress.hpp> +#include "vbarange.hxx" using namespace com::sun::star; using namespace ooo::vba; -/* -ScVbaPane::ScVbaPane( uno::Reference< uno::XComponentContext > xContext, uno::Refrence< sheet::XViewPane > xViewPane ) - : m_xContext( xContext ), m_xViewPane( xViewPane ) +ScVbaPane::ScVbaPane( + const css::uno::Reference< ov::XHelperInterface >& xParent, + const uno::Reference< uno::XComponentContext >& xContext, + const uno::Reference< frame::XModel >& xModel, + const uno::Reference< sheet::XViewPane > xViewPane ) throw (uno::RuntimeException) : + ScVbaPane_BASE( xParent, xContext ), + m_xModel( xModel, uno::UNO_SET_THROW ), + m_xViewPane( xViewPane, uno::UNO_SET_THROW ) { } -*/ sal_Int32 SAL_CALL ScVbaPane::getScrollColumn() throw (uno::RuntimeException) @@ -71,6 +79,19 @@ ScVbaPane::setScrollRow( sal_Int32 _scrollrow ) throw (uno::RuntimeException) m_xViewPane->setFirstVisibleRow( _scrollrow - 1 ); } +uno::Reference< excel::XRange > SAL_CALL +ScVbaPane::getVisibleRange() throw (uno::RuntimeException) +{ + // TODO: Excel includes partly visible rows/columns, Calc does not + table::CellRangeAddress aRangeAddr = m_xViewPane->getVisibleRange(); + uno::Reference< sheet::XSpreadsheetDocument > xDoc( m_xModel, uno::UNO_QUERY_THROW ); + uno::Reference< container::XIndexAccess > xSheetsIA( xDoc->getSheets(), uno::UNO_QUERY_THROW ); + uno::Reference< sheet::XSpreadsheet > xSheet( xSheetsIA->getByIndex( aRangeAddr.Sheet ), uno::UNO_QUERY_THROW ); + uno::Reference< table::XCellRange > xRange( xSheet->getCellRangeByPosition( aRangeAddr.StartColumn, aRangeAddr.StartRow, aRangeAddr.EndColumn, aRangeAddr.EndRow ), uno::UNO_SET_THROW ); + // TODO: getParent() returns the window, Range needs the worksheet + return new ScVbaRange( getParent(), mxContext, xRange ); +} + //Method void SAL_CALL ScVbaPane::SmallScroll( const uno::Any& Down, const uno::Any& Up, const uno::Any& ToRight, const uno::Any& ToLeft ) throw (uno::RuntimeException) @@ -83,54 +104,34 @@ ScVbaPane::SmallScroll( const uno::Any& Down, const uno::Any& Up, const uno::Any if( Down.hasValue() ) { sal_Int32 down = 0; - try - { - Down >>= down; + if( Down >>= down ) downRows += down; - } - catch ( uno::Exception ) - { + else messageBuffer += rtl::OUString::createFromAscii( "Error getting parameter: Down\n" ); - } } if( Up.hasValue() ) { sal_Int32 up = 0; - try - { - Up >>= up; + if( Up >>= up ) downRows -= up; - } - catch ( uno::Exception ) - { + else messageBuffer += rtl::OUString::createFromAscii( "Error getting parameter: Up\n" ); - } } if( ToRight.hasValue() ) { sal_Int32 right = 0; - try - { - ToRight >>= right; + if( ToRight >>= right ) rightCols += right; - } - catch ( uno::Exception ) - { + else messageBuffer += rtl::OUString::createFromAscii( "Error getting parameter: ToRight\n" ); - } } if( ToLeft.hasValue() ) { sal_Int32 left = 0; - try - { - ToLeft >>= left; + if( ToLeft >>= left ) rightCols -= left; - } - catch ( uno::Exception ) - { + else messageBuffer += rtl::OUString::createFromAscii( "Error getting parameter: ToLeft\n" ); - } } if( messageBuffer.getLength() > 0 ) throw(uno::RuntimeException( messageBuffer, uno::Reference< uno::XInterface >() ) ); @@ -158,56 +159,35 @@ ScVbaPane::LargeScroll( const uno::Any& Down, const uno::Any& Up, const uno::Any if( Down.hasValue() ) { sal_Int32 down = 0; - try - { - Down >>= down; + if( Down >>= down ) downPages += down; - } - catch ( uno::Exception ) - { + else messageBuffer += rtl::OUString::createFromAscii( "Error getting parameter: Down\n" ); - } } if( Up.hasValue() ) { sal_Int32 up = 0; - try - { - Up >>= up; + if( Up >>= up ) downPages -= up; - } - catch ( uno::Exception ) - { + else messageBuffer += rtl::OUString::createFromAscii( "Error getting parameter: Up\n" ); - } } if( ToRight.hasValue() ) { sal_Int32 right = 0; - try - { - ToRight >>= right; + if( ToRight >>= right ) acrossPages += right; - } - catch ( uno::Exception ) - { + else messageBuffer += rtl::OUString::createFromAscii( "Error getting parameter: ToRight\n" ); - } } if( ToLeft.hasValue() ) { sal_Int32 left = 0; - try - { - ToLeft >>= left; + if( ToLeft >>= left ) acrossPages -= left; - } - catch ( uno::Exception ) - { + else messageBuffer += rtl::OUString::createFromAscii( "Error getting parameter: ToLeft\n" ); - } } - if( messageBuffer.getLength() > 0 ) throw(uno::RuntimeException( messageBuffer, uno::Reference< uno::XInterface >() ) ); @@ -220,3 +200,7 @@ ScVbaPane::LargeScroll( const uno::Any& Down, const uno::Any& Up, const uno::Any m_xViewPane->setFirstVisibleRow( newStartRow ); m_xViewPane->setFirstVisibleColumn( newStartCol ); } + +// XHelperInterface + +VBAHELPER_IMPL_XHELPERINTERFACE( ScVbaPane, "ooo.vba.excel.Pane" ) diff --git a/sc/source/ui/vba/vbapane.hxx b/sc/source/ui/vba/vbapane.hxx index 0fa1d49709de..ff87a9966d80 100644 --- a/sc/source/ui/vba/vbapane.hxx +++ b/sc/source/ui/vba/vbapane.hxx @@ -27,34 +27,41 @@ #ifndef SC_VBA_PANE_HXX #define SC_VBA_PANE_HXX -#include<cppuhelper/implbase1.hxx> -#include<com/sun/star/sheet/XViewPane.hpp> -#include<ooo/vba/excel/XPane.hpp> +#include <com/sun/star/sheet/XViewPane.hpp> +#include <ooo/vba/excel/XPane.hpp> +#include <vbahelper/vbahelperinterface.hxx> +#include "excelvbahelper.hxx" -#include"excelvbahelper.hxx" +typedef InheritedHelperInterfaceImpl1< ov::excel::XPane > ScVbaPane_BASE; -typedef cppu::WeakImplHelper1< ov::excel::XPane > PaneImpl_Base; - -class ScVbaPane : public PaneImpl_Base +class ScVbaPane : public ScVbaPane_BASE { -protected: - css::uno::Reference< css::uno::XComponentContext > m_xContext; - css::uno::Reference< css::sheet::XViewPane > m_xViewPane; public: - ScVbaPane( const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::sheet::XViewPane > xViewPane ) : m_xContext( xContext ), m_xViewPane( xViewPane ) {} + ScVbaPane( + const css::uno::Reference< ov::XHelperInterface >& xParent, + const css::uno::Reference< css::uno::XComponentContext >& xContext, + const css::uno::Reference< css::frame::XModel >& xModel, + const css::uno::Reference< css::sheet::XViewPane > xViewPane ) throw (css::uno::RuntimeException); css::uno::Reference< css::sheet::XViewPane > getViewPane() { return m_xViewPane; } - //Attribute + // XPane attributes virtual sal_Int32 SAL_CALL getScrollColumn() throw (css::uno::RuntimeException); virtual void SAL_CALL setScrollColumn( sal_Int32 _scrollcolumn ) throw (css::uno::RuntimeException); virtual sal_Int32 SAL_CALL getScrollRow() throw (css::uno::RuntimeException); virtual void SAL_CALL setScrollRow( sal_Int32 _scrollrow ) throw (css::uno::RuntimeException); + virtual css::uno::Reference< ov::excel::XRange > SAL_CALL getVisibleRange() throw (css::uno::RuntimeException); - //Method + // XPane methods virtual void SAL_CALL SmallScroll( const css::uno::Any& Down, const css::uno::Any& Up, const css::uno::Any& ToRight, const css::uno::Any& ToLeft ) throw (css::uno::RuntimeException); virtual void SAL_CALL LargeScroll( const css::uno::Any& Down, const css::uno::Any& Up, const css::uno::Any& ToRight, const css::uno::Any& ToLeft ) throw (css::uno::RuntimeException); + // XHelperInterface + VBAHELPER_DECL_XHELPERINTERFACE + +protected: + css::uno::Reference< css::frame::XModel > m_xModel; + css::uno::Reference< css::sheet::XViewPane > m_xViewPane; }; -#endif//SC_VBA_PANE_HXX +#endif //SC_VBA_PANE_HXX diff --git a/sc/source/ui/vba/vbarange.cxx b/sc/source/ui/vba/vbarange.cxx index b3307ffdc55d..ccf5a3bc5b54 100644 --- a/sc/source/ui/vba/vbarange.cxx +++ b/sc/source/ui/vba/vbarange.cxx @@ -81,6 +81,7 @@ #include <com/sun/star/sheet/XSheetFilterable.hpp> #include <com/sun/star/sheet/FilterConnection.hpp> #include <com/sun/star/util/CellProtection.hpp> +#include <com/sun/star/util/TriState.hpp> #include <com/sun/star/style/XStyleFamiliesSupplier.hpp> #include <com/sun/star/awt/XDevice.hpp> @@ -141,6 +142,7 @@ #include "vbaborders.hxx" #include "vbaworksheet.hxx" #include "vbavalidation.hxx" +#include "vbahyperlinks.hxx" #include "tabvwsh.hxx" #include "rangelst.hxx" @@ -238,21 +240,28 @@ uno::Reference< excel::XRange > lcl_makeXRangeFromSheetCellRanges( const uno::Re return xRange; } -ScCellRangeObj* ScVbaRange::getCellRangeObj() throw ( uno::RuntimeException ) +ScCellRangesBase* ScVbaRange::getCellRangesBase() throw ( uno::RuntimeException ) { - uno::Reference< uno::XInterface > xIf; - if ( mxRanges.is() ) - xIf.set( mxRanges, uno::UNO_QUERY_THROW ); - else - xIf.set( mxRange, uno::UNO_QUERY_THROW ); - ScCellRangeObj* pUnoCellRange = dynamic_cast< ScCellRangeObj* >( xIf.get() ); - return pUnoCellRange; + if( mxRanges.is() ) + return ScCellRangesBase::getImplementation( mxRanges ); + if( mxRange.is() ) + return ScCellRangesBase::getImplementation( mxRange ); + throw uno::RuntimeException( rtl::OUString::createFromAscii("General Error creating range - Unknown" ), uno::Reference< uno::XInterface >() ); +} + +ScCellRangeObj* ScVbaRange::getCellRangeObj() throw ( uno::RuntimeException ) +{ + return dynamic_cast< ScCellRangeObj* >( getCellRangesBase() ); +} + +ScCellRangesObj* ScVbaRange::getCellRangesObj() throw ( uno::RuntimeException ) +{ + return dynamic_cast< ScCellRangesObj* >( getCellRangesBase() ); } SfxItemSet* ScVbaRange::getCurrentDataSet( ) throw ( uno::RuntimeException ) { - ScCellRangeObj* pUnoCellRange = getCellRangeObj(); - SfxItemSet* pDataSet = excel::ScVbaCellRangeAccess::GetDataSet( pUnoCellRange ); + SfxItemSet* pDataSet = excel::ScVbaCellRangeAccess::GetDataSet( getCellRangesBase() ); if ( !pDataSet ) throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Can't access Itemset for range" ) ), uno::Reference< uno::XInterface >() ); return pDataSet; @@ -360,7 +369,7 @@ ScVbaRangeAreas::createCollectionObject( const uno::Any& aSource ) ScDocShell* getDocShellFromIf( const uno::Reference< uno::XInterface >& xIf ) throw ( uno::RuntimeException ) { - ScCellRangesBase* pUno= dynamic_cast< ScCellRangesBase* >( xIf.get() ); + ScCellRangesBase* pUno = ScCellRangesBase::getImplementation( xIf ); if ( !pUno ) throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Failed to access underlying uno range object" ) ), uno::Reference< uno::XInterface >() ); return pUno->GetDocShell(); @@ -374,6 +383,14 @@ getDocShellFromRange( const uno::Reference< table::XCellRange >& xRange ) throw return getDocShellFromIf(xIf ); } +ScDocShell* +getDocShellFromRanges( const uno::Reference< sheet::XSheetCellRangeContainer >& xRanges ) throw ( uno::RuntimeException ) +{ + // need the ScCellRangesBase to get docshell + uno::Reference< uno::XInterface > xIf( xRanges, uno::UNO_QUERY_THROW ); + return getDocShellFromIf(xIf ); +} + uno::Reference< frame::XModel > getModelFromXIf( const uno::Reference< uno::XInterface >& xIf ) throw ( uno::RuntimeException ) { ScDocShell* pDocShell = getDocShellFromIf(xIf ); @@ -398,7 +415,7 @@ getDocumentFromRange( const uno::Reference< table::XCellRange >& xRange ) ScDocument* -ScVbaRange::getScDocument() +ScVbaRange::getScDocument() throw (uno::RuntimeException) { if ( mxRanges.is() ) { @@ -410,7 +427,7 @@ ScVbaRange::getScDocument() } ScDocShell* -ScVbaRange::getScDocShell() +ScVbaRange::getScDocShell() throw (uno::RuntimeException) { if ( mxRanges.is() ) { @@ -421,6 +438,41 @@ ScVbaRange::getScDocShell() return getDocShellFromRange( mxRange ); } +/*static*/ ScVbaRange* ScVbaRange::getImplementation( const uno::Reference< excel::XRange >& rxRange ) +{ + // FIXME: always save to use dynamic_cast? Or better to (implement and) use XTunnel? + return dynamic_cast< ScVbaRange* >( rxRange.get() ); +} + +uno::Reference< frame::XModel > ScVbaRange::getUnoModel() throw (uno::RuntimeException) +{ + if( ScDocShell* pDocShell = getScDocShell() ) + return pDocShell->GetModel(); + throw uno::RuntimeException(); +} + +/*static*/ uno::Reference< frame::XModel > ScVbaRange::getUnoModel( const uno::Reference< excel::XRange >& rxRange ) throw (uno::RuntimeException) +{ + if( ScVbaRange* pScVbaRange = getImplementation( rxRange ) ) + return pScVbaRange->getUnoModel(); + throw uno::RuntimeException(); +} + +const ScRangeList& ScVbaRange::getScRangeList() throw (uno::RuntimeException) +{ + if( ScCellRangesBase* pScRangesBase = getCellRangesBase() ) + return pScRangesBase->GetRangeList(); + throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Cannot obtain UNO range implementation object" ) ), uno::Reference< uno::XInterface >() ); +} + +/*static*/ const ScRangeList& ScVbaRange::getScRangeList( const uno::Reference< excel::XRange >& rxRange ) throw (uno::RuntimeException) +{ + if( ScVbaRange* pScVbaRange = getImplementation( rxRange ) ) + return pScVbaRange->getScRangeList(); + throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Cannot obtain VBA range implementation object" ) ), uno::Reference< uno::XInterface >() ); +} + + class NumFormatHelper { uno::Reference< util::XNumberFormatsSupplier > mxSupplier; @@ -465,7 +517,7 @@ public: rtl::OUString getNumberFormatString() { uno::Reference< uno::XInterface > xIf( mxRangeProps, uno::UNO_QUERY_THROW ); - ScCellRangeObj* pUnoCellRange = dynamic_cast< ScCellRangeObj* >( xIf.get() ); + ScCellRangesBase* pUnoCellRange = ScCellRangesBase::getImplementation( xIf ); if ( pUnoCellRange ) { @@ -570,20 +622,17 @@ class CellsEnumeration : public CellsEnumeration_BASE uno::Reference< XCollection > m_xAreas; vCellPos m_CellPositions; vCellPos::const_iterator m_it; + uno::Reference< table::XCellRange > getArea( sal_Int32 nVBAIndex ) throw ( uno::RuntimeException ) { if ( nVBAIndex < 1 || nVBAIndex > m_xAreas->getCount() ) throw uno::RuntimeException(); uno::Reference< excel::XRange > xRange( m_xAreas->Item( uno::makeAny(nVBAIndex), uno::Any() ), uno::UNO_QUERY_THROW ); - ScVbaRange* pRange = dynamic_cast< ScVbaRange* >( xRange.get() ); - uno::Reference< table::XCellRange > xCellRange; - if ( !pRange ) - throw uno::RuntimeException(); - xCellRange.set( pRange->getCellRange(), uno::UNO_QUERY_THROW );; + uno::Reference< table::XCellRange > xCellRange( ScVbaRange::getCellRange( xRange ), uno::UNO_QUERY_THROW ); return xCellRange; - } - void populateArea( sal_Int32 nVBAIndex ) + + void populateArea( sal_Int32 nVBAIndex ) { uno::Reference< table::XCellRange > xRange = getArea( nVBAIndex ); uno::Reference< table::XColumnRowRange > xColumnRowRange(xRange, uno::UNO_QUERY_THROW ); @@ -1129,7 +1178,7 @@ bool getScRangeListForAddress( const rtl::OUString& sName, ScDocShell* pDocSh, S ScVbaRange* -getRangeForName( const uno::Reference< uno::XComponentContext >& xContext, const rtl::OUString& sName, ScDocShell* pDocSh, table::CellRangeAddress& pAddr, formula::FormulaGrammar::AddressConvention eConv = formula::FormulaGrammar::CONV_XL_A1 ) throw ( uno::RuntimeException ) +getRangeForName( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const rtl::OUString& sName, ScDocShell* pDocSh, table::CellRangeAddress& pAddr, formula::FormulaGrammar::AddressConvention eConv = formula::FormulaGrammar::CONV_XL_A1 ) throw ( uno::RuntimeException ) { ScRangeList aCellRanges; ScRange refRange; @@ -1140,20 +1189,107 @@ getRangeForName( const uno::Reference< uno::XComponentContext >& xContext, const if ( aCellRanges.First() == aCellRanges.Last() ) { uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( pDocSh, *aCellRanges.First() ) ); - // #FIXME need proper (WorkSheet) parent - return new ScVbaRange( uno::Reference< XHelperInterface >(), xContext, xRange ); + return new ScVbaRange( xParent, xContext, xRange ); } uno::Reference< sheet::XSheetCellRangeContainer > xRanges( new ScCellRangesObj( pDocSh, aCellRanges ) ); + return new ScVbaRange( xParent, xContext, xRanges ); +} - // #FIXME need proper (WorkSheet) parent - return new ScVbaRange( uno::Reference< XHelperInterface >(), xContext, xRanges ); +// ---------------------------------------------------------------------------- + +namespace { + +template< typename RangeType > +inline table::CellRangeAddress lclGetRangeAddress( const uno::Reference< RangeType >& rxCellRange ) throw (uno::RuntimeException) +{ + return uno::Reference< sheet::XCellRangeAddressable >( rxCellRange, uno::UNO_QUERY_THROW )->getRangeAddress(); } +uno::Reference< sheet::XSheetCellRange > lclExpandToMerged( const uno::Reference< table::XCellRange >& rxCellRange, bool bRecursive ) throw (uno::RuntimeException) +{ + uno::Reference< sheet::XSheetCellRange > xNewCellRange( rxCellRange, uno::UNO_QUERY_THROW ); + uno::Reference< sheet::XSpreadsheet > xSheet( xNewCellRange->getSpreadsheet(), uno::UNO_SET_THROW ); + table::CellRangeAddress aNewAddress = lclGetRangeAddress( xNewCellRange ); + table::CellRangeAddress aOldAddress; + // expand as long as there are new merged ranges included + do + { + aOldAddress = aNewAddress; + uno::Reference< sheet::XSheetCellCursor > xCursor( xSheet->createCursorByRange( xNewCellRange ), uno::UNO_SET_THROW ); + xCursor->collapseToMergedArea(); + xNewCellRange.set( xCursor, uno::UNO_QUERY_THROW ); + aNewAddress = lclGetRangeAddress( xNewCellRange ); + } + while( bRecursive && (aOldAddress != aNewAddress) ); + return xNewCellRange; +} + +uno::Reference< sheet::XSheetCellRangeContainer > lclExpandToMerged( const uno::Reference< sheet::XSheetCellRangeContainer >& rxCellRanges, bool bRecursive ) throw (uno::RuntimeException) +{ + if( !rxCellRanges.is() ) + throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Missing cell ranges object" ) ), uno::Reference< uno::XInterface >() ); + sal_Int32 nCount = rxCellRanges->getCount(); + if( nCount < 1 ) + throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Missing cell ranges object" ) ), uno::Reference< uno::XInterface >() ); + + ScRangeList aScRanges; + for( sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex ) + { + uno::Reference< table::XCellRange > xRange( rxCellRanges->getByIndex( nIndex ), uno::UNO_QUERY_THROW ); + table::CellRangeAddress aRangeAddr = lclGetRangeAddress( lclExpandToMerged( xRange, bRecursive ) ); + ScRange aScRange; + ScUnoConversion::FillScRange( aScRange, aRangeAddr ); + aScRanges.Append( aScRange ); + } + return new ScCellRangesObj( getDocShellFromRanges( rxCellRanges ), aScRanges ); +} + +void lclExpandAndMerge( const uno::Reference< table::XCellRange >& rxCellRange, bool bMerge ) throw (uno::RuntimeException) +{ + uno::Reference< util::XMergeable > xMerge( lclExpandToMerged( rxCellRange, true ), uno::UNO_QUERY_THROW ); + // Calc cannot merge over merged ranges, always unmerge first + xMerge->merge( sal_False ); + if( bMerge ) + xMerge->merge( sal_True ); + // FIXME need to check whether all the cell contents are retained or lost by popping up a dialog +} + +util::TriState lclGetMergedState( const uno::Reference< table::XCellRange >& rxCellRange ) throw (uno::RuntimeException) +{ + /* 1) Check if range is completely inside one single merged range. To do + this, try to extend from top-left cell only (not from entire range). + This will excude cases where this range consists of several merged + ranges (or parts of them). */ + table::CellRangeAddress aRangeAddr = lclGetRangeAddress( rxCellRange ); + uno::Reference< table::XCellRange > xTopLeft( rxCellRange->getCellRangeByPosition( 0, 0, 0, 0 ), uno::UNO_SET_THROW ); + uno::Reference< sheet::XSheetCellRange > xExpanded( lclExpandToMerged( xTopLeft, false ), uno::UNO_SET_THROW ); + table::CellRangeAddress aExpAddr = lclGetRangeAddress( xExpanded ); + // check that expanded range has more than one cell (really merged) + if( ((aExpAddr.StartColumn < aExpAddr.EndColumn) || (aExpAddr.StartRow < aExpAddr.EndRow)) && ScUnoConversion::Contains( aExpAddr, aRangeAddr ) ) + return util::TriState_YES; + + /* 2) Check if this range contains any merged cells (completely or + partly). This seems to be hardly possible via API, as + XMergeable::getIsMerged() returns only true, if the top-left cell of a + merged range is part of this range, so cases where just the lower part + of a merged range is part of this range are not covered. */ + ScRange aScRange; + ScUnoConversion::FillScRange( aScRange, aRangeAddr ); + bool bHasMerged = getDocumentFromRange( rxCellRange )->HasAttrib( aScRange, HASATTR_MERGED | HASATTR_OVERLAPPED ); + return bHasMerged ? util::TriState_INDETERMINATE : util::TriState_NO; +} + +} // namespace + +// ---------------------------------------------------------------------------- + css::uno::Reference< excel::XRange > -ScVbaRange::getRangeObjectForName( const uno::Reference< uno::XComponentContext >& xContext, const rtl::OUString& sRangeName, ScDocShell* pDocSh, formula::FormulaGrammar::AddressConvention eConv ) throw ( uno::RuntimeException ) +ScVbaRange::getRangeObjectForName( const css::uno::Reference< ov::XHelperInterface >& xParent, + const uno::Reference< uno::XComponentContext >& xContext, const rtl::OUString& sRangeName, + ScDocShell* pDocSh, formula::FormulaGrammar::AddressConvention eConv ) throw ( uno::RuntimeException ) { table::CellRangeAddress refAddr; - return getRangeForName( xContext, sRangeName, pDocSh, refAddr, eConv ); + return getRangeForName( xParent, xContext, sRangeName, pDocSh, refAddr, eConv ); } @@ -1189,9 +1325,7 @@ table::CellRangeAddress getCellRangeAddressForVBARange( const uno::Any& aParam, default: throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Can't extact CellRangeAddress from type" ) ), uno::Reference< uno::XInterface >() ); } - uno::Reference< sheet::XCellRangeAddressable > xAddressable( xRangeParam, uno::UNO_QUERY_THROW ); - return xAddressable->getRangeAddress(); - + return lclGetRangeAddress( xRangeParam ); } uno::Reference< XCollection > @@ -1391,7 +1525,7 @@ ScVbaRange::ClearContents( sal_Int32 nFlags ) throw (uno::RuntimeException) for ( sal_Int32 index=1; index <= nItems; ++index ) { uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny(index), uno::Any() ), uno::UNO_QUERY_THROW ); - ScVbaRange* pRange = dynamic_cast< ScVbaRange* >( xRange.get() ); + ScVbaRange* pRange = getImplementation( xRange ); if ( pRange ) pRange->ClearContents( nFlags ); } @@ -1588,7 +1722,7 @@ ScVbaRange::fillSeries( sheet::FillDirection nFillDirection, sheet::FillMode nFi for ( sal_Int32 index = 1; index <= xCollection->getCount(); ++index ) { uno::Reference< excel::XRange > xRange( xCollection->Item( uno::makeAny( index ), uno::Any() ), uno::UNO_QUERY_THROW ); - ScVbaRange* pThisRange = dynamic_cast< ScVbaRange* >( xRange.get() ); + ScVbaRange* pThisRange = getImplementation( xRange ); pThisRange->fillSeries( nFillDirection, nFillMode, nFillDateMode, fStep, fEndValue ); } @@ -1968,9 +2102,9 @@ ScVbaRange::Select() throw (uno::RuntimeException) uno::Reference< frame::XModel > xModel( pShell->GetModel(), uno::UNO_QUERY_THROW ); uno::Reference< view::XSelectionSupplier > xSelection( xModel->getCurrentController(), uno::UNO_QUERY_THROW ); if ( mxRanges.is() ) - xSelection->select( uno::makeAny( mxRanges ) ); + xSelection->select( uno::Any( lclExpandToMerged( mxRanges, true ) ) ); else - xSelection->select( uno::makeAny( mxRange ) ); + xSelection->select( uno::Any( lclExpandToMerged( mxRange, true ) ) ); // set focus on document e.g. // ThisComponent.CurrentController.Frame.getContainerWindow.SetFocus try @@ -1983,7 +2117,6 @@ ScVbaRange::Select() throw (uno::RuntimeException) catch( uno::Exception& ) { } - } } @@ -2161,36 +2294,65 @@ ScVbaRange::Columns(const uno::Any& aIndex ) throw (uno::RuntimeException) void ScVbaRange::setMergeCells( const uno::Any& aIsMerged ) throw (script::BasicErrorException, uno::RuntimeException) { - sal_Bool bIsMerged = sal_False; - aIsMerged >>= bIsMerged; - uno::Reference< util::XMergeable > xMerge( mxRange, ::uno::UNO_QUERY_THROW ); - //FIXME need to check whether all the cell contents are retained or lost by popping up a dialog - xMerge->merge( bIsMerged ); + bool bMerge = false; + aIsMerged >>= bMerge; + + if( mxRanges.is() ) + { + sal_Int32 nCount = mxRanges->getCount(); + + // VBA does nothing (no error) if the own ranges overlap somehow + ::std::vector< table::CellRangeAddress > aList; + for( sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex ) + { + uno::Reference< sheet::XCellRangeAddressable > xRangeAddr( mxRanges->getByIndex( nIndex ), uno::UNO_QUERY_THROW ); + table::CellRangeAddress aAddress = xRangeAddr->getRangeAddress(); + for( ::std::vector< table::CellRangeAddress >::const_iterator aIt = aList.begin(), aEnd = aList.end(); aIt != aEnd; ++aIt ) + if( ScUnoConversion::Intersects( *aIt, aAddress ) ) + return; + aList.push_back( aAddress ); + } + + // (un)merge every range after it has been extended to intersecting merged ranges from sheet + for( sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex ) + { + uno::Reference< table::XCellRange > xRange( mxRanges->getByIndex( nIndex ), uno::UNO_QUERY_THROW ); + lclExpandAndMerge( xRange, bMerge ); + } + return; + } + + // otherwise, merge single range + lclExpandAndMerge( mxRange, bMerge ); } uno::Any ScVbaRange::getMergeCells() throw (script::BasicErrorException, uno::RuntimeException) { - sal_Int32 nItems = m_Areas->getCount(); - - if ( nItems > 1 ) + if( mxRanges.is() ) { - uno::Any aResult = aNULL(); - for ( sal_Int32 index=1; index != nItems; ++index ) + sal_Int32 nCount = mxRanges->getCount(); + for( sal_Int32 nIndex = 0; nIndex < nCount; ++nIndex ) { - uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny(index), uno::Any() ), uno::UNO_QUERY_THROW ); - if ( index > 1 ) - if ( aResult != xRange->getMergeCells() ) - return aNULL(); - aResult = xRange->getMergeCells(); - if ( aNULL() == aResult ) + uno::Reference< table::XCellRange > xRange( mxRanges->getByIndex( nIndex ), uno::UNO_QUERY_THROW ); + util::TriState eMerged = lclGetMergedState( xRange ); + /* Excel always returns NULL, if one range of the range list is + partly or completely merged. Even if all ranges are completely + merged, the return value is still NULL. */ + if( eMerged != util::TriState_NO ) return aNULL(); } - return aResult; + // no range is merged anyhow, return false + return uno::Any( false ); + } + // otherwise, check single range + switch( lclGetMergedState( mxRange ) ) + { + case util::TriState_YES: return uno::Any( true ); + case util::TriState_NO: return uno::Any( false ); + default: return aNULL(); } - uno::Reference< util::XMergeable > xMerge( mxRange, ::uno::UNO_QUERY_THROW ); - return uno::makeAny( xMerge->getIsMerged() ); } void @@ -2418,7 +2580,7 @@ ScVbaRange::Range( const uno::Any &Cell1, const uno::Any &Cell2, bool bForceUseI Cell1 >>= sName; RangeHelper referRange( xReferrer ); table::CellRangeAddress referAddress = referRange.getCellRangeAddressable()->getRangeAddress(); - return getRangeForName( mxContext, sName, getScDocShell(), referAddress ); + return getRangeForName( getParent(), mxContext, sName, getScDocShell(), referAddress ); } else @@ -2481,8 +2643,7 @@ ScVbaRange::Range( const uno::Any &Cell1, const uno::Any &Cell2, bool bForceUseI // Allow access to underlying openoffice uno api ( useful for debugging // with openoffice basic ) -::com::sun::star::uno::Any SAL_CALL -ScVbaRange::getCellRange( ) throw (::com::sun::star::uno::RuntimeException) +uno::Any SAL_CALL ScVbaRange::getCellRange( ) throw (uno::RuntimeException) { uno::Any aAny; if ( mxRanges.is() ) @@ -2492,6 +2653,13 @@ ScVbaRange::getCellRange( ) throw (::com::sun::star::uno::RuntimeException) return aAny; } +/*static*/ uno::Any ScVbaRange::getCellRange( const uno::Reference< excel::XRange >& rxRange ) throw (uno::RuntimeException) +{ + if( ScVbaRange* pVbaRange = getImplementation( rxRange ) ) + return pVbaRange->getCellRange(); + throw uno::RuntimeException(); +} + static USHORT getPasteFlags (sal_Int32 Paste) { @@ -2625,14 +2793,25 @@ ScVbaRange::getEntireColumn() throw (uno::RuntimeException) uno::Reference< excel::XComment > SAL_CALL ScVbaRange::AddComment( const uno::Any& Text ) throw (uno::RuntimeException) { + // if there is already a comment in the top-left cell then throw + if( getComment().is() ) + throw uno::RuntimeException(); - uno::Reference< excel::XComment > xComment( new ScVbaComment( this, mxContext, mxRange ) ); - // if you don't pass a valid text or if there is already a comment - // associated with the range then return NULL - if ( !xComment->Text( Text, uno::Any(), uno::Any() ).getLength() - || xComment->Text( uno::Any(), uno::Any(), uno::Any() ).getLength() ) - return NULL; - return xComment; + // workaround: Excel allows to create empty comment, Calc does not + ::rtl::OUString aNoteText; + if( Text.hasValue() && !(Text >>= aNoteText) ) + throw uno::RuntimeException(); + if( aNoteText.getLength() == 0 ) + aNoteText = ::rtl::OUString( sal_Unicode( ' ' ) ); + + // try to create a new annotation + table::CellRangeAddress aRangePos = lclGetRangeAddress( mxRange ); + table::CellAddress aNotePos( aRangePos.Sheet, aRangePos.StartColumn, aRangePos.StartRow ); + uno::Reference< sheet::XSheetCellRange > xCellRange( mxRange, uno::UNO_QUERY_THROW ); + uno::Reference< sheet::XSheetAnnotationsSupplier > xAnnosSupp( xCellRange->getSpreadsheet(), uno::UNO_QUERY_THROW ); + uno::Reference< sheet::XSheetAnnotations > xAnnos( xAnnosSupp->getAnnotations(), uno::UNO_SET_THROW ); + xAnnos->insertNew( aNotePos, aNoteText ); + return new ScVbaComment( this, mxContext, getUnoModel(), mxRange ); } uno::Reference< excel::XComment > SAL_CALL @@ -2640,7 +2819,7 @@ ScVbaRange::getComment() throw (uno::RuntimeException) { // intentional behavior to return a null object if no // comment defined - uno::Reference< excel::XComment > xComment( new ScVbaComment( this, mxContext, mxRange ) ); + uno::Reference< excel::XComment > xComment( new ScVbaComment( this, mxContext, getUnoModel(), mxRange ) ); if ( !xComment->Text( uno::Any(), uno::Any(), uno::Any() ).getLength() ) return NULL; return xComment; @@ -2969,7 +3148,7 @@ uno::Reference< table::XCellRange > processKey( const uno::Any& Key, uno::Refere table::CellRangeAddress aRefAddr; if ( !pDocSh ) throw uno::RuntimeException( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Range::Sort no docshell to calculate key param")), uno::Reference< uno::XInterface >() ); - xKeyRange = getRangeForName( xContext, sRangeName, pDocSh, aRefAddr ); + xKeyRange = getRangeForName( uno::Reference< XHelperInterface >(), xContext, sRangeName, pDocSh, aRefAddr ); } else throw uno::RuntimeException( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("Range::Sort illegal type value for key param")), uno::Reference< uno::XInterface >() ); @@ -3727,16 +3906,16 @@ ScVbaRange::getPageBreak() throw (uno::RuntimeException) { ScDocument* pDoc = getDocumentFromRange( mxRange ); - BYTE nFlag = 0; + ScBreakType nBreak = BREAK_NONE; if ( !bColumn ) - nFlag = pDoc -> GetRowFlags(thisAddress.StartRow, thisAddress.Sheet); + nBreak = pDoc->HasRowBreak(thisAddress.StartRow, thisAddress.Sheet); else - nFlag = pDoc -> GetColFlags(static_cast<SCCOL>(thisAddress.StartColumn), thisAddress.Sheet); + nBreak = pDoc->HasColBreak(thisAddress.StartColumn, thisAddress.Sheet); - if ( nFlag & CR_PAGEBREAK) + if (nBreak & BREAK_PAGE) nPageBreak = excel::XlPageBreak::xlPageBreakAutomatic; - if ( nFlag & CR_MANUALBREAK) + if (nBreak & BREAK_MANUAL) nPageBreak = excel::XlPageBreak::xlPageBreakManual; } } @@ -3852,25 +4031,6 @@ ScVbaRange::getWorksheet() throw (uno::RuntimeException) return xSheet; } -ScCellRangesBase* -ScVbaRange::getCellRangesBase() throw( uno::RuntimeException ) -{ - ScCellRangesBase* pUnoRangesBase = NULL; - if ( mxRanges.is() ) - { - uno::Reference< uno::XInterface > xIf( mxRanges, uno::UNO_QUERY_THROW ); - pUnoRangesBase = dynamic_cast< ScCellRangesBase* >( xIf.get() ); - } - else if ( mxRange.is() ) - { - uno::Reference< uno::XInterface > xIf( mxRange, uno::UNO_QUERY_THROW ); - pUnoRangesBase = dynamic_cast< ScCellRangesBase* >( xIf.get() ); - } - else - throw uno::RuntimeException( rtl::OUString::createFromAscii("General Error creating range - Unknown" ), uno::Reference< uno::XInterface >() ); - return pUnoRangesBase; -} - // #TODO remove this ugly application processing // Process an application Range request e.g. 'Range("a1,b2,a4:b6") uno::Reference< excel::XRange > @@ -4159,7 +4319,7 @@ ScVbaRange::AutoFilter( const uno::Any& Field, const uno::Any& Criteria1, const uno::Reference< excel::XRange > xCurrent( CurrentRegion() ); if ( xCurrent.is() ) { - ScVbaRange* pRange = dynamic_cast< ScVbaRange* >( xCurrent.get() ); + ScVbaRange* pRange = getImplementation( xCurrent ); if ( pRange->isSingleCellRange() ) throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Can't create AutoFilter") ), uno::Reference< uno::XInterface >() ); if ( pRange ) @@ -4581,6 +4741,27 @@ ScVbaRange::TextToColumns( const css::uno::Any& Destination, const css::uno::Any //TODO* TrailingMinusNumbers Optional Variant. Numbers that begin with a minus character. } +uno::Any SAL_CALL +ScVbaRange::Hyperlinks( const uno::Any& aIndex ) throw (uno::RuntimeException) +{ + /* The range object always returns a new Hyperlinks object containing a + fixed list of existing hyperlinks in the range. + See vbahyperlinks.hxx for more details. */ + + // get the global hyperlink object of the sheet (sheet should always be the parent of a Range object) + uno::Reference< excel::XWorksheet > xWorksheet( getParent(), uno::UNO_QUERY_THROW ); + uno::Reference< excel::XHyperlinks > xSheetHlinks( xWorksheet->Hyperlinks( uno::Any() ), uno::UNO_QUERY_THROW ); + ScVbaHyperlinksRef xScSheetHlinks( dynamic_cast< ScVbaHyperlinks* >( xSheetHlinks.get() ) ); + if( !xScSheetHlinks.is() ) + throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Cannot obtain hyperlinks implementation object" ) ), uno::Reference< uno::XInterface >() ); + + // create a new local hyperlinks object based on the sheet hyperlinks + ScVbaHyperlinksRef xHlinks( new ScVbaHyperlinks( getParent(), mxContext, xScSheetHlinks, getScRangeList() ) ); + if( aIndex.hasValue() ) + return xHlinks->Item( aIndex, uno::Any() ); + return uno::Any( uno::Reference< excel::XHyperlinks >( xHlinks.get() ) ); +} + css::uno::Reference< excel::XValidation > SAL_CALL ScVbaRange::getValidation() throw (css::uno::RuntimeException) { @@ -4589,24 +4770,95 @@ ScVbaRange::getValidation() throw (css::uno::RuntimeException) return m_xValidation; } -uno::Any ScVbaRange::getFormulaHidden() throw ( script::BasicErrorException, css::uno::RuntimeException) +namespace { + +sal_Unicode lclGetPrefixChar( const uno::Reference< table::XCell >& rxCell ) throw (uno::RuntimeException) { - SfxItemSet* pDataSet = getCurrentDataSet(); - const ScProtectionAttr& rProtAttr = (const ScProtectionAttr &) - pDataSet->Get(ATTR_PROTECTION, TRUE); - SfxItemState eState = pDataSet->GetItemState(ATTR_PROTECTION, TRUE, NULL); - if(eState == SFX_ITEM_DONTCARE) - return aNULL(); - return uno::makeAny(rProtAttr.GetHideFormula()); + /* TODO/FIXME: We need an apostroph-prefix property at the cell to + implement this correctly. For now, return an apostroph for every text + cell. + TODO/FIXME: When Application.TransitionNavigKeys is supported and true, + this function needs to inspect the cell formatting and return different + prefixes according to the horizontal cell alignment. + */ + return (rxCell->getType() == table::CellContentType_TEXT) ? '\'' : 0; } -void ScVbaRange::setFormulaHidden(const uno::Any& Hidden) throw ( script::BasicErrorException, css::uno::RuntimeException) + +sal_Unicode lclGetPrefixChar( const uno::Reference< table::XCellRange >& rxRange ) throw (uno::RuntimeException) { - uno::Reference< beans::XPropertySet > xProps(mxRange, ::uno::UNO_QUERY_THROW); - util::CellProtection rCellAttr; - xProps->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_CELLPRO))) >>= rCellAttr; - Hidden >>= rCellAttr.IsFormulaHidden; - xProps->setPropertyValue(rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_CELLPRO)), uno::makeAny(rCellAttr)); + /* This implementation is able to handle different prefixes (needed if + Application.TransitionNavigKeys is true). The function lclGetPrefixChar + for single cells called from here may return any prefix. If that + function returns an empty prefix (NUL character) or different non-empty + prefixes for two cells, this function returns 0. + */ + sal_Unicode cCurrPrefix = 0; + table::CellRangeAddress aRangeAddr = lclGetRangeAddress( rxRange ); + sal_Int32 nEndCol = aRangeAddr.EndColumn - aRangeAddr.StartColumn; + sal_Int32 nEndRow = aRangeAddr.EndRow - aRangeAddr.StartRow; + for( sal_Int32 nRow = 0; nRow <= nEndRow; ++nRow ) + { + for( sal_Int32 nCol = 0; nCol <= nEndCol; ++nCol ) + { + uno::Reference< table::XCell > xCell( rxRange->getCellByPosition( nCol, nRow ), uno::UNO_SET_THROW ); + sal_Unicode cNewPrefix = lclGetPrefixChar( xCell ); + if( (cNewPrefix == 0) || ((cCurrPrefix != 0) && (cNewPrefix != cCurrPrefix)) ) + return 0; + cCurrPrefix = cNewPrefix; + } + } + // all cells contain the same prefix - return it + return cCurrPrefix; +} + +sal_Unicode lclGetPrefixChar( const uno::Reference< sheet::XSheetCellRangeContainer >& rxRanges ) throw (uno::RuntimeException) +{ + sal_Unicode cCurrPrefix = 0; + uno::Reference< container::XEnumerationAccess > xRangesEA( rxRanges, uno::UNO_QUERY_THROW ); + uno::Reference< container::XEnumeration > xRangesEnum( xRangesEA->createEnumeration(), uno::UNO_SET_THROW ); + while( xRangesEnum->hasMoreElements() ) + { + uno::Reference< table::XCellRange > xRange( xRangesEnum->nextElement(), uno::UNO_QUERY_THROW ); + sal_Unicode cNewPrefix = lclGetPrefixChar( xRange ); + if( (cNewPrefix == 0) || ((cCurrPrefix != 0) && (cNewPrefix != cCurrPrefix)) ) + return 0; + cCurrPrefix = cNewPrefix; + } + // all ranges contain the same prefix - return it + return cCurrPrefix; +} + +inline uno::Any lclGetPrefixVariant( sal_Unicode cPrefixChar ) +{ + return uno::Any( (cPrefixChar == 0) ? ::rtl::OUString() : ::rtl::OUString( cPrefixChar ) ); +} + +} // namespace + +uno::Any SAL_CALL ScVbaRange::getPrefixCharacter() throw (uno::RuntimeException) +{ + /* (1) If Application.TransitionNavigKeys is false, this function returns + an apostroph character if the text cell begins with an apostroph + character (formula return values are not taken into account); otherwise + an empty string. + + (2) If Application.TransitionNavigKeys is true, this function returns + an apostroph character, if the cell is left-aligned; a double-quote + character, if the cell is right-aligned; a circumflex character, if the + cell is centered; a backslash character, if the cell is set to filled; + or an empty string, if nothing of the above. + + If a range or a list of ranges contains texts with leading apostroph + character as well as other cells, this function returns an empty + string. + */ + + if( mxRange.is() ) + return lclGetPrefixVariant( lclGetPrefixChar( mxRange ) ); + if( mxRanges.is() ) + return lclGetPrefixVariant( lclGetPrefixChar( mxRanges ) ); + throw uno::RuntimeException( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Unexpected empty Range object" ) ), uno::Reference< uno::XInterface >() ); } uno::Any ScVbaRange::getShowDetail() throw ( css::uno::RuntimeException) @@ -4733,7 +4985,7 @@ ScVbaRange::PrintOut( const uno::Any& From, const uno::Any& To, const uno::Any& table::CellRangeAddress rangeAddress = thisRange.getCellRangeAddressable()->getRangeAddress(); if ( index == 1 ) { - ScVbaRange* pRange = dynamic_cast< ScVbaRange* >( xRange.get() ); + ScVbaRange* pRange = getImplementation( xRange ); // initialise the doc shell and the printareas pShell = getDocShellFromRange( pRange->mxRange ); xPrintAreas.set( thisRange.getSpreadSheet(), uno::UNO_QUERY_THROW ); @@ -4755,7 +5007,7 @@ void SAL_CALL ScVbaRange::AutoFill( const uno::Reference< excel::XRange >& Destination, const uno::Any& Type ) throw (uno::RuntimeException) { uno::Reference< excel::XRange > xDest( Destination, uno::UNO_QUERY_THROW ); - ScVbaRange* pRange = dynamic_cast< ScVbaRange* >( xDest.get() ); + ScVbaRange* pRange = getImplementation( xDest ); RangeHelper destRangeHelper( pRange->mxRange ); table::CellRangeAddress destAddress = destRangeHelper.getCellRangeAddressable()->getRangeAddress(); @@ -5165,7 +5417,7 @@ ScVbaRange::SpecialCells( const uno::Any& _oType, const uno::Any& _oValue) throw { uno::Reference< excel::XRange > xRange( m_Areas->Item( uno::makeAny(index), uno::Any() ), uno::UNO_QUERY_THROW ); xRange = xRange->SpecialCells( _oType, _oValue); - ScVbaRange* pRange = dynamic_cast< ScVbaRange* >( xRange.get() ); + ScVbaRange* pRange = getImplementation( xRange ); if ( xRange.is() && pRange ) { sal_Int32 nElems = ( pRange->m_Areas->getCount() + 1 ); diff --git a/sc/source/ui/vba/vbarange.hxx b/sc/source/ui/vba/vbarange.hxx index 89ae741c7535..a9147a0d7840 100644 --- a/sc/source/ui/vba/vbarange.hxx +++ b/sc/source/ui/vba/vbarange.hxx @@ -57,8 +57,10 @@ class ScTableSheetsObj; class ScCellRangesBase; class ScCellRangeObj; +class ScCellRangesObj; class ScDocShell; class ScDocument; +class ScRangeList; //typedef InheritedHelperInterfaceImpl1< ov::excel::XRange > ScVbaRange_BASE; typedef ScVbaFormat< ov::excel::XRange > ScVbaRange_BASE; @@ -111,26 +113,42 @@ class ScVbaRange : public ScVbaRange_BASE virtual css::uno::Any getFormulaValue( formula::FormulaGrammar::Grammar ) throw (css::uno::RuntimeException); virtual void setFormulaValue( const css::uno::Any& aValue, formula::FormulaGrammar::Grammar ) throw ( css::uno::RuntimeException); css::uno::Reference< ov::excel::XRange > getArea( sal_Int32 nIndex ) throw( css::uno::RuntimeException ); - ScCellRangesBase* getCellRangesBase() throw ( css::uno::RuntimeException ); ScCellRangeObj* getCellRangeObj( ) throw ( css::uno::RuntimeException ); - SfxItemSet* getCurrentDataSet( ) throw ( css::uno::RuntimeException ); + ScCellRangesObj* getCellRangesObj() throw ( css::uno::RuntimeException ); css::uno::Reference< ov::XCollection >& getBorders(); void groupUnGroup( bool bUnGroup = false ) throw ( css::script::BasicErrorException, css::uno::RuntimeException ); css::uno::Reference< ov::excel::XRange > PreviousNext( bool bIsPrevious ); css::uno::Reference< ov::excel::XRange > SpecialCellsImpl( sal_Int32 nType, const css::uno::Any& _oValue) throw ( css::script::BasicErrorException ); css::awt::Point getPosition() throw ( css::uno::RuntimeException ); +protected: + virtual ScCellRangesBase* getCellRangesBase() throw ( css::uno::RuntimeException ); + virtual SfxItemSet* getCurrentDataSet( ) throw ( css::uno::RuntimeException ); public: ScVbaRange( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::table::XCellRange >& xRange, sal_Bool bIsRows = false, sal_Bool bIsColumns = false ) throw ( css::lang::IllegalArgumentException ); ScVbaRange( const css::uno::Reference< ov::XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext, const css::uno::Reference< css::sheet::XSheetCellRangeContainer >& xRanges, sal_Bool bIsRows = false, sal_Bool bIsColumns = false ) throw ( css::lang::IllegalArgumentException ); ScVbaRange( css::uno::Sequence< css::uno::Any > const& aArgs, css::uno::Reference< css::uno::XComponentContext >const& xContext ) throw ( css::lang::IllegalArgumentException ); - ScDocument* getScDocument(); - ScDocShell* getScDocShell(); + ScDocument* getScDocument() throw (css::uno::RuntimeException); + ScDocShell* getScDocShell() throw (css::uno::RuntimeException); + + /** Returns the ScVbaRange implementation object for the passed VBA Range object. */ + static ScVbaRange* getImplementation( const css::uno::Reference< ov::excel::XRange >& rxRange ); + + css::uno::Reference< css::frame::XModel > getUnoModel() throw (css::uno::RuntimeException); + static css::uno::Reference< css::frame::XModel > getUnoModel( const css::uno::Reference< ov::excel::XRange >& rxRange ) throw (css::uno::RuntimeException); + + const ScRangeList& getScRangeList() throw (css::uno::RuntimeException); + static const ScRangeList& getScRangeList( const css::uno::Reference< ov::excel::XRange >& rxRange ) throw (css::uno::RuntimeException); virtual ~ScVbaRange(); virtual css::uno::Reference< ov::XHelperInterface > thisHelperIface() { return this; } bool isSingleCellRange(); - static css::uno::Reference< ov::excel::XRange > getRangeObjectForName( const css::uno::Reference< css::uno::XComponentContext >& xContext, const rtl::OUString& sRangeName, ScDocShell* pDocSh, formula::FormulaGrammar::AddressConvention eConv = formula::FormulaGrammar::CONV_XL_A1 ) throw ( css::uno::RuntimeException ); + + static css::uno::Reference< ov::excel::XRange > getRangeObjectForName( + const css::uno::Reference< ov::XHelperInterface >& xParent, + const css::uno::Reference< css::uno::XComponentContext >& xContext, + const rtl::OUString& sRangeName, ScDocShell* pDocSh, + formula::FormulaGrammar::AddressConvention eConv = formula::FormulaGrammar::CONV_XL_A1 ) throw ( css::uno::RuntimeException ); // Attributes virtual css::uno::Any SAL_CALL getValue() throw (css::uno::RuntimeException); @@ -170,10 +188,7 @@ public: virtual css::uno::Any SAL_CALL getPageBreak() throw (css::uno::RuntimeException); virtual void SAL_CALL setPageBreak( const css::uno::Any& _pagebreak ) throw (css::uno::RuntimeException); virtual css::uno::Reference< ov::excel::XValidation > SAL_CALL getValidation() throw (css::uno::RuntimeException); - virtual css::uno::Any SAL_CALL getFormulaHidden() throw (css::script::BasicErrorException, css::uno::RuntimeException); - virtual void SAL_CALL setFormulaHidden(const css::uno::Any& aHidden) throw (css::script::BasicErrorException, css::uno::RuntimeException); - //virtual css::uno::Any SAL_CALL getLocked() throw (css::script::BasicErrorException, css::uno::RuntimeException); - //virtual void SAL_CALL setLocked(const css::uno::Any& aLocked) throw (css::script::BasicErrorException, css::uno::RuntimeException); + virtual css::uno::Any SAL_CALL getPrefixCharacter() throw (css::uno::RuntimeException); virtual css::uno::Any SAL_CALL getShowDetail() throw (css::uno::RuntimeException); virtual void SAL_CALL setShowDetail(const css::uno::Any& aShowDetail) throw (css::uno::RuntimeException); // Methods @@ -213,6 +228,7 @@ public: virtual css::uno::Reference< ov::excel::XRange > SAL_CALL Range( const css::uno::Any &Cell1, const css::uno::Any &Cell2 ) throw (css::uno::RuntimeException); virtual css::uno::Reference< ov::excel::XRange > Range( const css::uno::Any &Cell1, const css::uno::Any &Cell2, bool bForceUseInpuRangeTab ) throw (css::uno::RuntimeException); virtual css::uno::Any SAL_CALL getCellRange( ) throw (css::uno::RuntimeException); + static css::uno::Any getCellRange( const css::uno::Reference< ov::excel::XRange >& rxRange ) throw (css::uno::RuntimeException); virtual void SAL_CALL PasteSpecial( const css::uno::Any& Paste, const css::uno::Any& Operation, const css::uno::Any& SkipBlanks, const css::uno::Any& Transpose ) throw (css::uno::RuntimeException); virtual ::sal_Bool SAL_CALL Replace( const ::rtl::OUString& What, const ::rtl::OUString& Replacement, const css::uno::Any& LookAt, const css::uno::Any& SearchOrder, const css::uno::Any& MatchCase, const css::uno::Any& MatchByte, const css::uno::Any& SearchFormat, const css::uno::Any& ReplaceFormat ) throw (css::uno::RuntimeException); virtual css::uno::Reference< ov::excel::XRange > SAL_CALL Find( const css::uno::Any& What, const css::uno::Any& After, const css::uno::Any& LookIn, const css::uno::Any& LookAt, const css::uno::Any& SearchOrder, const css::uno::Any& SearchDirection, const css::uno::Any& MatchCase, const css::uno::Any& MatchByte, const css::uno::Any& SearchFormat ) throw (css::uno::RuntimeException); @@ -228,6 +244,7 @@ public: const css::uno::Any& ConsecutinveDelimiter, const css::uno::Any& Tab, const css::uno::Any& Semicolon, const css::uno::Any& Comma, const css::uno::Any& Space, const css::uno::Any& Other, const css::uno::Any& OtherChar, const css::uno::Any& FieldInfo, const css::uno::Any& DecimalSeparator, const css::uno::Any& ThousandsSeparator, const css::uno::Any& TrailingMinusNumbers ) throw (css::uno::RuntimeException); + virtual css::uno::Any SAL_CALL Hyperlinks( const css::uno::Any& aIndex ) throw (css::uno::RuntimeException); virtual void SAL_CALL AutoFilter( const css::uno::Any& Field, const css::uno::Any& Criteria1, const css::uno::Any& Operator, const css::uno::Any& Criteria2, const css::uno::Any& VisibleDropDown ) throw (css::uno::RuntimeException); virtual void SAL_CALL Insert( const css::uno::Any& Shift, const css::uno::Any& CopyOrigin ) throw (css::uno::RuntimeException); diff --git a/sc/source/ui/vba/vbasheetobject.cxx b/sc/source/ui/vba/vbasheetobject.cxx new file mode 100755 index 000000000000..4bd0f1d60547 --- /dev/null +++ b/sc/source/ui/vba/vbasheetobject.cxx @@ -0,0 +1,517 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "vbasheetobject.hxx" +#include <com/sun/star/awt/TextAlign.hpp> +#include <com/sun/star/container/XIndexContainer.hpp> +#include <com/sun/star/drawing/XControlShape.hpp> +#include <com/sun/star/script/ScriptEventDescriptor.hpp> +#include <com/sun/star/script/XEventAttacherManager.hpp> +#include <com/sun/star/style/VerticalAlignment.hpp> +#include <ooo/vba/excel/Constants.hpp> +#include <ooo/vba/excel/XlOrientation.hpp> +#include <ooo/vba/excel/XlPlacement.hpp> +#include <rtl/ustrbuf.hxx> +#include <filter/msfilter/msvbahelper.hxx> +#include <oox/helper/helper.hxx> +#include "vbafont.hxx" + +using ::rtl::OUString; +using namespace ::com::sun::star; +using namespace ::ooo::vba; + +// ============================================================================ + +ScVbaButtonCharacters::ScVbaButtonCharacters( + const uno::Reference< XHelperInterface >& rxParent, + const uno::Reference< uno::XComponentContext >& rxContext, + const uno::Reference< beans::XPropertySet >& rxPropSet, + const ScVbaPalette& rPalette, + const uno::Any& rStart, + const uno::Any& rLength ) throw (uno::RuntimeException) : + ScVbaButtonCharacters_BASE( rxParent, rxContext ), + maPalette( rPalette ), + mxPropSet( rxPropSet, uno::UNO_SET_THROW ) +{ + // extract optional start parameter (missing or invalid -> from beginning) + if( !(rStart >>= mnStart) || (mnStart < 1) ) + mnStart = 1; + --mnStart; // VBA is 1-based, rtl string is 0-based + + // extract optional length parameter (missing or invalid -> to end) + if( !(rLength >>= mnLength) || (mnLength < 1) ) + mnLength = SAL_MAX_INT32; +} + +ScVbaButtonCharacters::~ScVbaButtonCharacters() +{ +} + +// XCharacters attributes + +OUString SAL_CALL ScVbaButtonCharacters::getCaption() throw (uno::RuntimeException) +{ + // ignore invalid mnStart and/or mnLength members + OUString aString = getFullString(); + sal_Int32 nStart = ::std::min( mnStart, aString.getLength() ); + sal_Int32 nLength = ::std::min( mnLength, aString.getLength() - nStart ); + return aString.copy( nStart, nLength ); +} + +void SAL_CALL ScVbaButtonCharacters::setCaption( const OUString& rCaption ) throw (uno::RuntimeException) +{ + /* Replace the covered text with the passed text, ignore invalid mnStart + and/or mnLength members. This operation does not affect the mnLength + parameter. If the inserted text is longer than mnLength, the additional + characters are not covered by this object. If the inserted text is + shorter than mnLength, other uncovered characters from the original + string will be covered now, thus may be changed with subsequent + operations. */ + OUString aString = getFullString(); + sal_Int32 nStart = ::std::min( mnStart, aString.getLength() ); + sal_Int32 nLength = ::std::min( mnLength, aString.getLength() - nStart ); + setFullString( aString.replaceAt( nStart, nLength, rCaption ) ); +} + +sal_Int32 SAL_CALL ScVbaButtonCharacters::getCount() throw (uno::RuntimeException) +{ + // always return the total length of the caption + return getFullString().getLength(); +} + +OUString SAL_CALL ScVbaButtonCharacters::getText() throw (uno::RuntimeException) +{ + // Text attribute same as Caption attribute? + return getCaption(); +} + +void SAL_CALL ScVbaButtonCharacters::setText( const OUString& rText ) throw (uno::RuntimeException) +{ + // Text attribute same as Caption attribute? + setCaption( rText ); +} + +uno::Reference< excel::XFont > SAL_CALL ScVbaButtonCharacters::getFont() throw (uno::RuntimeException) +{ + return new ScVbaFont( this, mxContext, maPalette, mxPropSet, 0, true ); +} + +void SAL_CALL ScVbaButtonCharacters::setFont( const uno::Reference< excel::XFont >& /*rxFont*/ ) throw (uno::RuntimeException) +{ + // TODO +} + +// XCharacters methods + +void SAL_CALL ScVbaButtonCharacters::Insert( const OUString& rString ) throw (uno::RuntimeException) +{ + /* The Insert() operation is in fact "replace covered characters", at + least for buttons... It seems there is no easy way to really insert a + substring. This operation does not affect the mnLength parameter. */ + setCaption( rString ); +} + +void SAL_CALL ScVbaButtonCharacters::Delete() throw (uno::RuntimeException) +{ + /* The Delete() operation is nothing else than "replace with empty string". + This does not affect the mnLength parameter, multiple calls of Delete() + will remove characters as long as there are some more covered by this + object. */ + setCaption( OUString() ); +} + +// XHelperInterface + +VBAHELPER_IMPL_XHELPERINTERFACE( ScVbaButtonCharacters, "ooo.vba.excel.Characters" ) + +// private + +OUString ScVbaButtonCharacters::getFullString() const throw (uno::RuntimeException) +{ + return mxPropSet->getPropertyValue( CREATE_OUSTRING( "Label" ) ).get< OUString >(); +} + +void ScVbaButtonCharacters::setFullString( const OUString& rString ) throw (uno::RuntimeException) +{ + mxPropSet->setPropertyValue( CREATE_OUSTRING( "Label" ), uno::Any( rString ) ); +} + +// ============================================================================ + +ScVbaSheetObjectBase::ScVbaSheetObjectBase( + const uno::Reference< XHelperInterface >& rxParent, + const uno::Reference< uno::XComponentContext >& rxContext, + const uno::Reference< frame::XModel >& rxModel, + const uno::Reference< drawing::XShape >& rxShape ) throw (uno::RuntimeException) : + ScVbaSheetObject_BASE( rxParent, rxContext ), + maPalette( rxModel ), + mxModel( rxModel, uno::UNO_SET_THROW ), + mxShape( rxShape, uno::UNO_SET_THROW ), + mxShapeProps( rxShape, uno::UNO_QUERY_THROW ) +{ +} + +// XSheetObject attributes + +double SAL_CALL ScVbaSheetObjectBase::getLeft() throw (uno::RuntimeException) +{ + return HmmToPoints( mxShape->getPosition().X ); +} + +void SAL_CALL ScVbaSheetObjectBase::setLeft( double fLeft ) throw (uno::RuntimeException) +{ + if( fLeft < 0.0 ) + throw uno::RuntimeException(); + mxShape->setPosition( awt::Point( PointsToHmm( fLeft ), mxShape->getPosition().Y ) ); +} + +double SAL_CALL ScVbaSheetObjectBase::getTop() throw (uno::RuntimeException) +{ + return HmmToPoints( mxShape->getPosition().Y ); +} + +void SAL_CALL ScVbaSheetObjectBase::setTop( double fTop ) throw (uno::RuntimeException) +{ + if( fTop < 0.0 ) + throw uno::RuntimeException(); + mxShape->setPosition( awt::Point( mxShape->getPosition().X, PointsToHmm( fTop ) ) ); +} + +double SAL_CALL ScVbaSheetObjectBase::getWidth() throw (uno::RuntimeException) +{ + return HmmToPoints( mxShape->getSize().Width ); +} + +void SAL_CALL ScVbaSheetObjectBase::setWidth( double fWidth ) throw (uno::RuntimeException) +{ + if( fWidth <= 0.0 ) + throw uno::RuntimeException(); + mxShape->setSize( awt::Size( PointsToHmm( fWidth ), mxShape->getSize().Height ) ); +} + +double SAL_CALL ScVbaSheetObjectBase::getHeight() throw (uno::RuntimeException) +{ + return HmmToPoints( mxShape->getSize().Height ); +} + +void SAL_CALL ScVbaSheetObjectBase::setHeight( double fHeight ) throw (uno::RuntimeException) +{ + if( fHeight <= 0.0 ) + throw uno::RuntimeException(); + mxShape->setSize( awt::Size( mxShape->getSize().Width, PointsToHmm( fHeight ) ) ); +} + +OUString SAL_CALL ScVbaSheetObjectBase::getName() throw (uno::RuntimeException) +{ + return mxShapeProps->getPropertyValue( CREATE_OUSTRING( "Name" ) ).get< OUString >(); +} + +void SAL_CALL ScVbaSheetObjectBase::setName( const OUString& rName ) throw (uno::RuntimeException) +{ + mxShapeProps->setPropertyValue( CREATE_OUSTRING( "Name" ), uno::Any( rName ) ); +} + +sal_Int32 SAL_CALL ScVbaSheetObjectBase::getPlacement() throw (uno::RuntimeException) +{ + // TODO + return excel::XlPlacement::xlMoveAndSize; +} + +void SAL_CALL ScVbaSheetObjectBase::setPlacement( sal_Int32 /*nPlacement*/ ) throw (uno::RuntimeException) +{ + // TODO +} + +sal_Bool SAL_CALL ScVbaSheetObjectBase::getPrintObject() throw (uno::RuntimeException) +{ + // not supported + return sal_True; +} + +void SAL_CALL ScVbaSheetObjectBase::setPrintObject( sal_Bool /*bPrintObject*/ ) throw (uno::RuntimeException) +{ + // not supported +} + +// private + +void ScVbaSheetObjectBase::setDefaultProperties( sal_Int32 nIndex ) throw (uno::RuntimeException) +{ + OUString aName = ::rtl::OUStringBuffer( implGetBaseName() ).append( sal_Unicode( ' ' ) ).append( nIndex + 1 ).makeStringAndClear(); + setName( aName ); + implSetDefaultProperties(); +} + +void ScVbaSheetObjectBase::implSetDefaultProperties() throw (uno::RuntimeException) +{ +} + +// ============================================================================ + +ScVbaControlObjectBase::ScVbaControlObjectBase( + const uno::Reference< XHelperInterface >& rxParent, + const uno::Reference< uno::XComponentContext >& rxContext, + const uno::Reference< frame::XModel >& rxModel, + const uno::Reference< container::XIndexContainer >& rxFormIC, + const uno::Reference< drawing::XControlShape >& rxControlShape, + ListenerType eListenerType ) throw (uno::RuntimeException) : + ScVbaControlObject_BASE( rxParent, rxContext, rxModel, uno::Reference< drawing::XShape >( rxControlShape, uno::UNO_QUERY_THROW ) ), + mxFormIC( rxFormIC, uno::UNO_SET_THROW ), + mxControlProps( rxControlShape->getControl(), uno::UNO_QUERY_THROW ) +{ + // set listener and event name to be used for OnAction attribute + switch( eListenerType ) + { + case LISTENER_ACTION: + maListenerType = CREATE_OUSTRING( "XActionListener" ); + maEventMethod = CREATE_OUSTRING( "actionPerformed" ); + break; + case LISTENER_MOUSE: + maListenerType = CREATE_OUSTRING( "XMouseListener" ); + maEventMethod = CREATE_OUSTRING( "mouseReleased" ); + break; + case LISTENER_TEXT: + maListenerType = CREATE_OUSTRING( "XTextListener" ); + maEventMethod = CREATE_OUSTRING( "textChanged" ); + break; + case LISTENER_VALUE: + maListenerType = CREATE_OUSTRING( "XAdjustmentListener" ); + maEventMethod = CREATE_OUSTRING( "adjustmentValueChanged" ); + break; + case LISTENER_CHANGE: + maListenerType = CREATE_OUSTRING( "XChangeListener" ); + maEventMethod = CREATE_OUSTRING( "changed" ); + break; + // no default, to let the compiler complain about missing case + } +} + +// XSheetObject attributes + +OUString SAL_CALL ScVbaControlObjectBase::getName() throw (uno::RuntimeException) +{ + return mxControlProps->getPropertyValue( CREATE_OUSTRING( "Name" ) ).get< OUString >(); +} + +void SAL_CALL ScVbaControlObjectBase::setName( const OUString& rName ) throw (uno::RuntimeException) +{ + mxControlProps->setPropertyValue( CREATE_OUSTRING( "Name" ), uno::Any( rName ) ); +} + +OUString SAL_CALL ScVbaControlObjectBase::getOnAction() throw (uno::RuntimeException) +{ + uno::Reference< script::XEventAttacherManager > xEventMgr( mxFormIC, uno::UNO_QUERY_THROW ); + sal_Int32 nIndex = getModelIndexInForm(); + uno::Sequence< script::ScriptEventDescriptor > aEvents = xEventMgr->getScriptEvents( nIndex ); + if( aEvents.hasElements() ) + { + const script::ScriptEventDescriptor* pEvent = aEvents.getConstArray(); + const script::ScriptEventDescriptor* pEventEnd = pEvent + aEvents.getLength(); + const OUString aScriptType = CREATE_OUSTRING( "Script" ); + for( ; pEvent < pEventEnd; ++pEvent ) + if( (pEvent->ListenerType == maListenerType) && (pEvent->EventMethod == maEventMethod) && (pEvent->ScriptType == aScriptType) ) + return extractMacroName( pEvent->ScriptCode ); + } + return OUString(); +} + +void SAL_CALL ScVbaControlObjectBase::setOnAction( const OUString& rMacroName ) throw (uno::RuntimeException) +{ + uno::Reference< script::XEventAttacherManager > xEventMgr( mxFormIC, uno::UNO_QUERY_THROW ); + sal_Int32 nIndex = getModelIndexInForm(); + + // first, remove a registered event (try/catch just in case implementation throws) + try { xEventMgr->revokeScriptEvent( nIndex, maListenerType, maEventMethod, OUString() ); } catch( uno::Exception& ) {} + + // if a macro name has been passed, try to attach it to the event + if( rMacroName.getLength() > 0 ) + { + VBAMacroResolvedInfo aResolvedMacro = resolveVBAMacro( getSfxObjShell( mxModel ), rMacroName ); + if( !aResolvedMacro.IsResolved() ) + throw uno::RuntimeException(); + script::ScriptEventDescriptor aDescriptor; + aDescriptor.ListenerType = maListenerType; + aDescriptor.EventMethod = maEventMethod; + aDescriptor.ScriptType = CREATE_OUSTRING( "Script" ); + aDescriptor.ScriptCode = makeMacroURL( aResolvedMacro.ResolvedMacro() ); + xEventMgr->registerScriptEvent( nIndex, aDescriptor ); + } +} + +sal_Bool SAL_CALL ScVbaControlObjectBase::getPrintObject() throw (uno::RuntimeException) +{ + return mxControlProps->getPropertyValue( CREATE_OUSTRING( "Printable" ) ).get< sal_Bool >(); +} + +void SAL_CALL ScVbaControlObjectBase::setPrintObject( sal_Bool bPrintObject ) throw (uno::RuntimeException) +{ + mxControlProps->setPropertyValue( CREATE_OUSTRING( "Printable" ), uno::Any( bPrintObject ) ); +} + +// XControlObject attributes + +sal_Bool SAL_CALL ScVbaControlObjectBase::getAutoSize() throw (uno::RuntimeException) +{ + // not supported + return sal_False; +} + +void SAL_CALL ScVbaControlObjectBase::setAutoSize( sal_Bool /*bAutoSize*/ ) throw (uno::RuntimeException) +{ + // not supported +} + +// private + +sal_Int32 ScVbaControlObjectBase::getModelIndexInForm() const throw (uno::RuntimeException) +{ + for( sal_Int32 nIndex = 0, nCount = mxFormIC->getCount(); nIndex < nCount; ++nIndex ) + { + uno::Reference< beans::XPropertySet > xProps( mxFormIC->getByIndex( nIndex ), uno::UNO_QUERY_THROW ); + if( mxControlProps.get() == xProps.get() ) + return nIndex; + } + throw uno::RuntimeException(); +} + +// ============================================================================ + +ScVbaButton::ScVbaButton( + const uno::Reference< XHelperInterface >& rxParent, + const uno::Reference< uno::XComponentContext >& rxContext, + const uno::Reference< frame::XModel >& rxModel, + const uno::Reference< container::XIndexContainer >& rxFormIC, + const uno::Reference< drawing::XControlShape >& rxControlShape ) throw (uno::RuntimeException) : + ScVbaButton_BASE( rxParent, rxContext, rxModel, rxFormIC, rxControlShape, LISTENER_ACTION ) +{ +} + +// XButton attributes + +OUString SAL_CALL ScVbaButton::getCaption() throw (uno::RuntimeException) +{ + return mxControlProps->getPropertyValue( CREATE_OUSTRING( "Label" ) ).get< OUString >(); +} + +void SAL_CALL ScVbaButton::setCaption( const OUString& rCaption ) throw (uno::RuntimeException) +{ + mxControlProps->setPropertyValue( CREATE_OUSTRING( "Label" ), uno::Any( rCaption ) ); +} + +uno::Reference< excel::XFont > SAL_CALL ScVbaButton::getFont() throw (uno::RuntimeException) +{ + return new ScVbaFont( this, mxContext, maPalette, mxControlProps, 0, true ); +} + +void SAL_CALL ScVbaButton::setFont( const uno::Reference< excel::XFont >& /*rxFont*/ ) throw (uno::RuntimeException) +{ + // TODO +} + +sal_Int32 SAL_CALL ScVbaButton::getHorizontalAlignment() throw (uno::RuntimeException) +{ + switch( mxControlProps->getPropertyValue( CREATE_OUSTRING( "Align" ) ).get< sal_Int16 >() ) + { + case awt::TextAlign::LEFT: return excel::Constants::xlLeft; + case awt::TextAlign::RIGHT: return excel::Constants::xlRight; + case awt::TextAlign::CENTER: return excel::Constants::xlCenter; + } + return excel::Constants::xlCenter; +} + +void SAL_CALL ScVbaButton::setHorizontalAlignment( sal_Int32 nAlign ) throw (uno::RuntimeException) +{ + sal_Int32 nAwtAlign = awt::TextAlign::CENTER; + switch( nAlign ) + { + case excel::Constants::xlLeft: nAwtAlign = awt::TextAlign::LEFT; break; + case excel::Constants::xlRight: nAwtAlign = awt::TextAlign::RIGHT; break; + case excel::Constants::xlCenter: nAwtAlign = awt::TextAlign::CENTER; break; + } + // form controls expect short value + mxControlProps->setPropertyValue( CREATE_OUSTRING( "Align" ), uno::Any( static_cast< sal_Int16 >( nAwtAlign ) ) ); +} + +sal_Int32 SAL_CALL ScVbaButton::getVerticalAlignment() throw (uno::RuntimeException) +{ + switch( mxControlProps->getPropertyValue( CREATE_OUSTRING( "VerticalAlign" ) ).get< style::VerticalAlignment >() ) + { + case style::VerticalAlignment_TOP: return excel::Constants::xlTop; + case style::VerticalAlignment_BOTTOM: return excel::Constants::xlBottom; + case style::VerticalAlignment_MIDDLE: return excel::Constants::xlCenter; + default:; + } + return excel::Constants::xlCenter; +} + +void SAL_CALL ScVbaButton::setVerticalAlignment( sal_Int32 nAlign ) throw (uno::RuntimeException) +{ + style::VerticalAlignment eAwtAlign = style::VerticalAlignment_MIDDLE; + switch( nAlign ) + { + case excel::Constants::xlTop: eAwtAlign = style::VerticalAlignment_TOP; break; + case excel::Constants::xlBottom: eAwtAlign = style::VerticalAlignment_BOTTOM; break; + case excel::Constants::xlCenter: eAwtAlign = style::VerticalAlignment_MIDDLE; break; + } + mxControlProps->setPropertyValue( CREATE_OUSTRING( "VerticalAlign" ), uno::Any( eAwtAlign ) ); +} + +sal_Int32 SAL_CALL ScVbaButton::getOrientation() throw (uno::RuntimeException) +{ + // not supported + return excel::XlOrientation::xlHorizontal; +} + +void SAL_CALL ScVbaButton::setOrientation( sal_Int32 /*nOrientation*/ ) throw (uno::RuntimeException) +{ + // not supported +} + +// XButton methods + +uno::Reference< excel::XCharacters > SAL_CALL ScVbaButton::Characters( const uno::Any& rStart, const uno::Any& rLength ) throw (uno::RuntimeException) +{ + return new ScVbaButtonCharacters( this, mxContext, mxControlProps, maPalette, rStart, rLength ); +} + +// XHelperInterface + +VBAHELPER_IMPL_XHELPERINTERFACE( ScVbaButton, "ooo.vba.excel.Button" ) + +// private + +OUString ScVbaButton::implGetBaseName() const +{ + return CREATE_OUSTRING( "Button" ); +} + +void ScVbaButton::implSetDefaultProperties() throw (uno::RuntimeException) +{ + setCaption( getName() ); +} + +// ============================================================================ diff --git a/sc/source/ui/vba/vbasheetobject.hxx b/sc/source/ui/vba/vbasheetobject.hxx new file mode 100755 index 000000000000..b2546ca09c93 --- /dev/null +++ b/sc/source/ui/vba/vbasheetobject.hxx @@ -0,0 +1,220 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SC_VBA_SHEETOBJECT_HXX +#define SC_VBA_SHEETOBJECT_HXX + +#include <memory> +#include <ooo/vba/excel/XButton.hpp> +#include <ooo/vba/excel/XControlObject.hpp> +#include <ooo/vba/excel/XSheetObject.hpp> +#include <vbahelper/vbahelperinterface.hxx> +#include "vbapalette.hxx" + +namespace com { namespace sun { namespace star { + namespace container { class XIndexContainer; } + namespace drawing { class XControlShape; } +} } } + +// ============================================================================ + +typedef InheritedHelperInterfaceImpl1< ov::excel::XCharacters > ScVbaButtonCharacters_BASE; + +/** Simple implementation of the Characters symbol for drawing button objects. */ +class ScVbaButtonCharacters : public ScVbaButtonCharacters_BASE +{ +public: + explicit ScVbaButtonCharacters( + const css::uno::Reference< ov::XHelperInterface >& rxParent, + const css::uno::Reference< css::uno::XComponentContext >& rxContext, + const css::uno::Reference< css::beans::XPropertySet >& rxPropSet, + const ScVbaPalette& rPalette, + const css::uno::Any& rStart, + const css::uno::Any& rLength ) throw (css::uno::RuntimeException); + virtual ~ScVbaButtonCharacters(); + + // XCharacters attributes + virtual ::rtl::OUString SAL_CALL getCaption() throw (css::uno::RuntimeException); + virtual void SAL_CALL setCaption( const ::rtl::OUString& rCaption ) throw (css::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getText() throw (css::uno::RuntimeException); + virtual void SAL_CALL setText( const ::rtl::OUString& rText ) throw (css::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getCount() throw (css::uno::RuntimeException); + virtual css::uno::Reference< ov::excel::XFont > SAL_CALL getFont() throw (css::uno::RuntimeException); + virtual void SAL_CALL setFont( const css::uno::Reference< ov::excel::XFont >& rxFont ) throw (css::uno::RuntimeException); + + // XCharacters methods + virtual void SAL_CALL Insert( const ::rtl::OUString& rString ) throw (css::uno::RuntimeException); + virtual void SAL_CALL Delete() throw (css::uno::RuntimeException); + + // XHelperInterface + VBAHELPER_DECL_XHELPERINTERFACE + +private: + ::rtl::OUString getFullString() const throw (css::uno::RuntimeException); + void setFullString( const ::rtl::OUString& rString ) throw (css::uno::RuntimeException); + +private: + ScVbaPalette maPalette; + css::uno::Reference< css::beans::XPropertySet > mxPropSet; + sal_Int32 mnStart; + sal_Int32 mnLength; +}; + +// ============================================================================ + +typedef InheritedHelperInterfaceImpl1< ov::excel::XSheetObject > ScVbaSheetObject_BASE; + +/** Base class for drawing objects embedded in sheets. */ +class ScVbaSheetObjectBase : public ScVbaSheetObject_BASE +{ +public: + explicit ScVbaSheetObjectBase( + const css::uno::Reference< ov::XHelperInterface >& rxParent, + const css::uno::Reference< css::uno::XComponentContext >& rxContext, + const css::uno::Reference< css::frame::XModel >& rxModel, + const css::uno::Reference< css::drawing::XShape >& rxShape ) throw (css::uno::RuntimeException); + + // XSheetObject attributes + virtual double SAL_CALL getLeft() throw (css::uno::RuntimeException); + virtual void SAL_CALL setLeft( double fLeft ) throw (css::uno::RuntimeException); + virtual double SAL_CALL getTop() throw (css::uno::RuntimeException); + virtual void SAL_CALL setTop( double fTop ) throw (css::uno::RuntimeException); + virtual double SAL_CALL getWidth() throw (css::uno::RuntimeException); + virtual void SAL_CALL setWidth( double fWidth ) throw (css::uno::RuntimeException); + virtual double SAL_CALL getHeight() throw (css::uno::RuntimeException); + virtual void SAL_CALL setHeight( double fHeight ) throw (css::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getName() throw (css::uno::RuntimeException); + virtual void SAL_CALL setName( const ::rtl::OUString& rName ) throw (css::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getPlacement() throw (css::uno::RuntimeException); + virtual void SAL_CALL setPlacement( sal_Int32 nPlacement ) throw (css::uno::RuntimeException); + virtual sal_Bool SAL_CALL getPrintObject() throw (css::uno::RuntimeException); + virtual void SAL_CALL setPrintObject( sal_Bool bPrintObject ) throw (css::uno::RuntimeException); + + /** Sets default properties after a new object has been created. */ + void setDefaultProperties( sal_Int32 nIndex ) throw (css::uno::RuntimeException); + +protected: + /** Derived classes return the base name used for new objects. */ + virtual ::rtl::OUString implGetBaseName() const = 0; + /** Derived classes set default properties for new drawing objects. */ + virtual void implSetDefaultProperties() throw (css::uno::RuntimeException); + +protected: + ScVbaPalette maPalette; + css::uno::Reference< css::frame::XModel > mxModel; + css::uno::Reference< css::drawing::XShape > mxShape; + css::uno::Reference< css::beans::XPropertySet > mxShapeProps; +}; + +// ============================================================================ + +typedef ::cppu::ImplInheritanceHelper1< ScVbaSheetObjectBase, ov::excel::XControlObject > ScVbaControlObject_BASE; + +class ScVbaControlObjectBase : public ScVbaControlObject_BASE +{ +public: + /** Specifies the listener used for OnAction events. */ + enum ListenerType + { + LISTENER_ACTION, /// XActionListener.actionPerformed + LISTENER_MOUSE, /// XMouseListener.mouseReleased + LISTENER_TEXT, /// XTextListener.textChanged + LISTENER_VALUE, /// XAdjustmentListener.adjustmentValueChanged + LISTENER_CHANGE /// XChangeListener.changed + }; + + explicit ScVbaControlObjectBase( + const css::uno::Reference< ov::XHelperInterface >& rxParent, + const css::uno::Reference< css::uno::XComponentContext >& rxContext, + const css::uno::Reference< css::frame::XModel >& rxModel, + const css::uno::Reference< css::container::XIndexContainer >& rxFormIC, + const css::uno::Reference< css::drawing::XControlShape >& rxControlShape, + ListenerType eListenerType ) throw (css::uno::RuntimeException); + + // XSheetObject attributes + virtual ::rtl::OUString SAL_CALL getName() throw (css::uno::RuntimeException); + virtual void SAL_CALL setName( const ::rtl::OUString& rName ) throw (css::uno::RuntimeException); + virtual ::rtl::OUString SAL_CALL getOnAction() throw (css::uno::RuntimeException); + virtual void SAL_CALL setOnAction( const ::rtl::OUString& rMacroName ) throw (css::uno::RuntimeException); + virtual sal_Bool SAL_CALL getPrintObject() throw (css::uno::RuntimeException); + virtual void SAL_CALL setPrintObject( sal_Bool bPrintObject ) throw (css::uno::RuntimeException); + + // XControlObject attributes + virtual sal_Bool SAL_CALL getAutoSize() throw (css::uno::RuntimeException); + virtual void SAL_CALL setAutoSize( sal_Bool bAutoSize ) throw (css::uno::RuntimeException); + +protected: + sal_Int32 getModelIndexInForm() const throw (css::uno::RuntimeException); + +protected: + css::uno::Reference< css::container::XIndexContainer > mxFormIC; + css::uno::Reference< css::beans::XPropertySet > mxControlProps; + ::rtl::OUString maListenerType; + ::rtl::OUString maEventMethod; +}; + +// ============================================================================ + +typedef ::cppu::ImplInheritanceHelper1< ScVbaControlObjectBase, ov::excel::XButton > ScVbaButton_BASE; + +class ScVbaButton : public ScVbaButton_BASE +{ +public: + explicit ScVbaButton( + const css::uno::Reference< ov::XHelperInterface >& rxParent, + const css::uno::Reference< css::uno::XComponentContext >& rxContext, + const css::uno::Reference< css::frame::XModel >& rxModel, + const css::uno::Reference< css::container::XIndexContainer >& rxFormIC, + const css::uno::Reference< css::drawing::XControlShape >& rxControlShape ) throw (css::uno::RuntimeException); + + // XButton attributes + virtual ::rtl::OUString SAL_CALL getCaption() throw (css::uno::RuntimeException); + virtual void SAL_CALL setCaption( const ::rtl::OUString& rCaption ) throw (css::uno::RuntimeException); + virtual css::uno::Reference< ov::excel::XFont > SAL_CALL getFont() throw (css::uno::RuntimeException); + virtual void SAL_CALL setFont( const css::uno::Reference< ov::excel::XFont >& rxFont ) throw (css::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getHorizontalAlignment() throw (css::uno::RuntimeException); + virtual void SAL_CALL setHorizontalAlignment( sal_Int32 nAlign ) throw (css::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getVerticalAlignment() throw (css::uno::RuntimeException); + virtual void SAL_CALL setVerticalAlignment( sal_Int32 nAlign ) throw (css::uno::RuntimeException); + virtual sal_Int32 SAL_CALL getOrientation() throw (css::uno::RuntimeException); + virtual void SAL_CALL setOrientation( sal_Int32 nOrientation ) throw (css::uno::RuntimeException); + + // XButton methods + css::uno::Reference< ov::excel::XCharacters > SAL_CALL Characters( + const css::uno::Any& rStart, const css::uno::Any& rLength ) throw (css::uno::RuntimeException); + + // XHelperInterface + VBAHELPER_DECL_XHELPERINTERFACE + +protected: + virtual ::rtl::OUString implGetBaseName() const; + virtual void implSetDefaultProperties() throw (css::uno::RuntimeException); +}; + +// ============================================================================ + +#endif diff --git a/sc/source/ui/vba/vbasheetobjects.cxx b/sc/source/ui/vba/vbasheetobjects.cxx new file mode 100755 index 000000000000..ced94db5ba76 --- /dev/null +++ b/sc/source/ui/vba/vbasheetobjects.cxx @@ -0,0 +1,534 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "vbasheetobjects.hxx" +#include <vector> +#include <rtl/math.hxx> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/container/XIndexContainer.hpp> +#include <com/sun/star/container/XNamed.hpp> +#include <com/sun/star/drawing/XControlShape.hpp> +#include <com/sun/star/drawing/XDrawPageSupplier.hpp> +#include <com/sun/star/drawing/XShapes.hpp> +#include <com/sun/star/form/FormComponentType.hpp> +#include <com/sun/star/form/XForm.hpp> +#include <com/sun/star/form/XFormComponent.hpp> +#include <com/sun/star/form/XFormsSupplier.hpp> +#include <oox/helper/helper.hxx> +#include "vbasheetobject.hxx" + +using ::rtl::OUString; +using namespace ::com::sun::star; +using namespace ::ooo::vba; + +// ============================================================================ + +namespace { + +template< typename Type > +inline bool lclGetProperty( Type& orValue, const uno::Reference< beans::XPropertySet >& rxPropSet, const OUString& rPropName ) +{ + try + { + return rxPropSet->getPropertyValue( rPropName ) >>= orValue; + } + catch( uno::Exception& ) + { + } + return false; +} + +/** Rounds the passed value to a multiple of 0.75 and converts it to 1/100 mm. */ +inline double lclPointsToHmm( const uno::Any& rPoints ) throw (uno::RuntimeException) +{ + return PointsToHmm( ::rtl::math::approxFloor( rPoints.get< double >() / 0.75 ) * 0.75 ); +} + +} // namespace + +// ============================================================================ +// Base implementations +// ============================================================================ + +/** Container for a specific type of drawing object in a spreadsheet. + + Derived classes provide all required functionality specific to the type of + shapes covered by the container. + */ +class ScVbaObjectContainer : public ::cppu::WeakImplHelper1< container::XIndexAccess > +{ +public: + explicit ScVbaObjectContainer( + const uno::Reference< XHelperInterface >& rxParent, + const uno::Reference< uno::XComponentContext >& rxContext, + const uno::Reference< frame::XModel >& rxModel, + const uno::Reference< sheet::XSpreadsheet >& rxSheet, + const uno::Type& rVbaType ) throw (uno::RuntimeException); + + /** Returns the VBA helper interface of the VBA collection object. */ + inline const uno::Reference< XHelperInterface >& getParent() const { return mxParent; } + /** Returns the component context of the VBA collection object. */ + inline const uno::Reference< uno::XComponentContext >& getContext() const { return mxContext; } + /** Returns the VBA type information of the objects in this container. */ + inline const uno::Type& getVbaType() const { return maVbaType; } + + /** Collects all shapes supported by this instance and inserts them into + the internal shape vector. */ + void collectShapes() throw (uno::RuntimeException); + /** Creates and returns a new UNO shape. */ + uno::Reference< drawing::XShape > createShape( const awt::Point& rPos, const awt::Size& rSize ) throw (uno::RuntimeException); + /** Inserts the passed shape into the draw page and into this container, and returns its index in the draw page. */ + sal_Int32 insertShape( const uno::Reference< drawing::XShape >& rxShape ) throw (uno::RuntimeException); + /** Creates and returns a new VBA implementation object for the passed shape. */ + ::rtl::Reference< ScVbaSheetObjectBase > createVbaObject( const uno::Reference< drawing::XShape >& rxShape ) throw (uno::RuntimeException); + /** Creates and returns a new VBA implementation object for the passed shape in an Any. */ + uno::Any createCollectionObject( const uno::Any& rSource ) throw (uno::RuntimeException); + /** Returns the VBA implementation object with the specified name. */ + uno::Any getItemByStringIndex( const OUString& rIndex ) throw (uno::RuntimeException); + + // XIndexAccess + virtual sal_Int32 SAL_CALL getCount() throw (uno::RuntimeException); + virtual uno::Any SAL_CALL getByIndex( sal_Int32 nIndex ) throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException); + + // XElementAccess + virtual uno::Type SAL_CALL getElementType() throw (uno::RuntimeException); + virtual sal_Bool SAL_CALL hasElements() throw (uno::RuntimeException); + +protected: + /** Derived classes return true, if the passed shape is supported by the instance. */ + virtual bool implPickShape( const uno::Reference< drawing::XShape >& rxShape ) const = 0; + /** Derived classes create and return a new VBA implementation object for the passed shape. */ + virtual ScVbaSheetObjectBase* implCreateVbaObject( const uno::Reference< drawing::XShape >& rxShape ) throw (uno::RuntimeException) = 0; + /** Derived classes return the service name of the UNO shape. */ + virtual OUString implGetShapeServiceName() const = 0; + + /** Returns the shape name via 'Name' property of the UNO shape. May be overwritten. */ + virtual OUString implGetShapeName( const uno::Reference< drawing::XShape >& rxShape ) const throw (uno::RuntimeException); + /** Is called when a new UNO shape has been created but not yet inserted into the drawing page. */ + virtual void implOnShapeCreated( const uno::Reference< drawing::XShape >& rxShape ) throw (uno::RuntimeException); + /** Is called when a new UNO shape has been inserted into the drawing page. */ + virtual void implOnShapeInserted( const uno::Reference< drawing::XShape >& rxShape ) throw (uno::RuntimeException); + +protected: + uno::Reference< XHelperInterface > mxParent; + uno::Reference< uno::XComponentContext > mxContext; + uno::Reference< frame::XModel > mxModel; + uno::Reference< lang::XMultiServiceFactory > mxFactory; + uno::Reference< drawing::XShapes > mxShapes; + +private: + typedef ::std::vector< uno::Reference< drawing::XShape > > ShapeVector; + const uno::Type maVbaType; + ShapeVector maShapes; +}; + +// ---------------------------------------------------------------------------- + +ScVbaObjectContainer::ScVbaObjectContainer( + const uno::Reference< XHelperInterface >& rxParent, + const uno::Reference< uno::XComponentContext >& rxContext, + const uno::Reference< frame::XModel >& rxModel, + const uno::Reference< sheet::XSpreadsheet >& rxSheet, + const uno::Type& rVbaType ) throw (uno::RuntimeException) : + mxParent( rxParent ), + mxContext( rxContext ), + mxModel( rxModel, uno::UNO_SET_THROW ), + mxFactory( rxModel, uno::UNO_QUERY_THROW ), + maVbaType( rVbaType ) +{ + uno::Reference< drawing::XDrawPageSupplier > xDrawPageSupp( rxSheet, uno::UNO_QUERY_THROW ); + mxShapes.set( xDrawPageSupp->getDrawPage(), uno::UNO_QUERY_THROW ); +} + +void ScVbaObjectContainer::collectShapes() throw (uno::RuntimeException) +{ + maShapes.clear(); + for( sal_Int32 nIndex = 0, nCount = mxShapes->getCount(); nIndex < nCount; ++nIndex ) + { + uno::Reference< drawing::XShape > xShape( mxShapes->getByIndex( nIndex ), uno::UNO_QUERY_THROW ); + if( implPickShape( xShape ) ) + maShapes.push_back( xShape ); + } +} + +uno::Reference< drawing::XShape > ScVbaObjectContainer::createShape( const awt::Point& rPos, const awt::Size& rSize ) throw (uno::RuntimeException) +{ + uno::Reference< drawing::XShape > xShape( mxFactory->createInstance( implGetShapeServiceName() ), uno::UNO_QUERY_THROW ); + xShape->setPosition( rPos ); + xShape->setSize( rSize ); + implOnShapeCreated( xShape ); + return xShape; +} + +sal_Int32 ScVbaObjectContainer::insertShape( const uno::Reference< drawing::XShape >& rxShape ) throw (uno::RuntimeException) +{ + mxShapes->add( rxShape ); + maShapes.push_back( rxShape ); + implOnShapeInserted( rxShape ); + return mxShapes->getCount() - 1; +} + +::rtl::Reference< ScVbaSheetObjectBase > ScVbaObjectContainer::createVbaObject( + const uno::Reference< drawing::XShape >& rxShape ) throw (uno::RuntimeException) +{ + return implCreateVbaObject( rxShape ); +} + +uno::Any ScVbaObjectContainer::createCollectionObject( const uno::Any& rSource ) throw (uno::RuntimeException) +{ + uno::Reference< drawing::XShape > xShape( rSource, uno::UNO_QUERY_THROW ); + uno::Reference< excel::XSheetObject > xSheetObject( implCreateVbaObject( xShape ) ); + return uno::Any( xSheetObject ); +} + +uno::Any ScVbaObjectContainer::getItemByStringIndex( const OUString& rIndex ) throw (uno::RuntimeException) +{ + for( ShapeVector::iterator aIt = maShapes.begin(), aEnd = maShapes.end(); aIt != aEnd; ++aIt ) + if( rIndex == implGetShapeName( *aIt ) ) + return createCollectionObject( uno::Any( *aIt ) ); + throw uno::RuntimeException(); +} + +// XIndexAccess + +sal_Int32 SAL_CALL ScVbaObjectContainer::getCount() throw (uno::RuntimeException) +{ + return static_cast< sal_Int32 >( maShapes.size() ); +} + +uno::Any SAL_CALL ScVbaObjectContainer::getByIndex( sal_Int32 nIndex ) + throw (lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException) +{ + if( (0 <= nIndex) && (nIndex < getCount()) ) + return uno::Any( maShapes[ static_cast< size_t >( nIndex ) ] ); + throw lang::IndexOutOfBoundsException(); +} + +// XElementAccess + +uno::Type SAL_CALL ScVbaObjectContainer::getElementType() throw (uno::RuntimeException) +{ + return drawing::XShape::static_type( 0 ); +} + +sal_Bool SAL_CALL ScVbaObjectContainer::hasElements() throw (uno::RuntimeException) +{ + return !maShapes.empty(); +} + +// private + +OUString ScVbaObjectContainer::implGetShapeName( const uno::Reference< drawing::XShape >& rxShape ) const throw (uno::RuntimeException) +{ + uno::Reference< beans::XPropertySet > xPropSet( rxShape, uno::UNO_QUERY_THROW ); + return xPropSet->getPropertyValue( CREATE_OUSTRING( "Name" ) ).get< OUString >(); +} + +void ScVbaObjectContainer::implOnShapeCreated( const uno::Reference< drawing::XShape >& /*rxShape*/ ) throw (uno::RuntimeException) +{ +} + +void ScVbaObjectContainer::implOnShapeInserted( const uno::Reference< drawing::XShape >& /*rxShape*/ ) throw (uno::RuntimeException) +{ +} + +// ============================================================================ + +class ScVbaObjectEnumeration : public SimpleEnumerationBase +{ +public: + explicit ScVbaObjectEnumeration( const ScVbaObjectContainerRef& rxContainer ); + virtual uno::Any createCollectionObject( const uno::Any& rSource ); + +private: + ScVbaObjectContainerRef mxContainer; +}; + +// ---------------------------------------------------------------------------- + +ScVbaObjectEnumeration::ScVbaObjectEnumeration( const ScVbaObjectContainerRef& rxContainer ) : + SimpleEnumerationBase( rxContainer->getParent(), rxContainer->getContext(), rxContainer.get() ), + mxContainer( rxContainer ) +{ +} + +uno::Any ScVbaObjectEnumeration::createCollectionObject( const uno::Any& rSource ) +{ + return mxContainer->createCollectionObject( rSource ); +} + +// ============================================================================ + +ScVbaSheetObjectsBase::ScVbaSheetObjectsBase( const ScVbaObjectContainerRef& rxContainer ) throw (css::uno::RuntimeException) : + ScVbaSheetObjects_BASE( rxContainer->getParent(), rxContainer->getContext(), rxContainer.get() ), + mxContainer( rxContainer ) +{ + mxContainer->collectShapes(); +} + +ScVbaSheetObjectsBase::~ScVbaSheetObjectsBase() +{ +} + +void ScVbaSheetObjectsBase::collectShapes() throw (uno::RuntimeException) +{ + mxContainer->collectShapes(); +} + +// XEnumerationAccess + +uno::Reference< container::XEnumeration > SAL_CALL ScVbaSheetObjectsBase::createEnumeration() throw (uno::RuntimeException) +{ + return new ScVbaObjectEnumeration( mxContainer ); +} + +// XElementAccess + +uno::Type SAL_CALL ScVbaSheetObjectsBase::getElementType() throw (uno::RuntimeException) +{ + return mxContainer->getVbaType(); +} + +// ScVbaCollectionBase + +uno::Any ScVbaSheetObjectsBase::createCollectionObject( const uno::Any& rSource ) +{ + return mxContainer->createCollectionObject( rSource ); +} + +uno::Any ScVbaSheetObjectsBase::getItemByStringIndex( const OUString& rIndex ) throw (uno::RuntimeException) +{ + return mxContainer->getItemByStringIndex( rIndex ); +} + +// ============================================================================ +// Graphic object containers supporting ooo.vba.excel.XGraphicObject +// ============================================================================ + +ScVbaGraphicObjectsBase::ScVbaGraphicObjectsBase( const ScVbaObjectContainerRef& rxContainer ) throw (uno::RuntimeException) : + ScVbaGraphicObjects_BASE( rxContainer ) +{ +} + +// XGraphicObjects + +uno::Any SAL_CALL ScVbaGraphicObjectsBase::Add( const uno::Any& rLeft, const uno::Any& rTop, const uno::Any& rWidth, const uno::Any& rHeight ) throw (uno::RuntimeException) +{ + /* Extract double values from passed Anys (the lclPointsToHmm() helper + function will throw a RuntimeException on any error), and convert from + points to 1/100 mm. */ + awt::Point aPos( lclPointsToHmm( rLeft ), lclPointsToHmm( rTop ) ); + awt::Size aSize( lclPointsToHmm( rWidth ), lclPointsToHmm( rHeight ) ); + // TODO: translate coordinates for RTL sheets + if( (aPos.X < 0) || (aPos.Y < 0) || (aSize.Width <= 0) || (aSize.Height <= 0) ) + throw uno::RuntimeException(); + + // create the UNO shape + uno::Reference< drawing::XShape > xShape( mxContainer->createShape( aPos, aSize ), uno::UNO_SET_THROW ); + sal_Int32 nIndex = mxContainer->insertShape( xShape ); + + // create and return the VBA object + ::rtl::Reference< ScVbaSheetObjectBase > xVbaObject = mxContainer->createVbaObject( xShape ); + xVbaObject->setDefaultProperties( nIndex ); + return uno::Any( uno::Reference< excel::XSheetObject >( xVbaObject.get() ) ); +} + +// ============================================================================ +// Drawing controls +// ============================================================================ + +class ScVbaControlContainer : public ScVbaObjectContainer +{ +public: + explicit ScVbaControlContainer( + const uno::Reference< XHelperInterface >& rxParent, + const uno::Reference< uno::XComponentContext >& rxContext, + const uno::Reference< frame::XModel >& rxModel, + const uno::Reference< sheet::XSpreadsheet >& rxSheet, + const uno::Type& rVbaType, + const OUString& rModelServiceName, + sal_Int16 nComponentType ) throw (uno::RuntimeException); + +protected: + uno::Reference< container::XIndexContainer > createForm() throw (uno::RuntimeException); + + virtual bool implPickShape( const uno::Reference< drawing::XShape >& rxShape ) const; + virtual OUString implGetShapeServiceName() const; + virtual bool implCheckProperties( const uno::Reference< beans::XPropertySet >& rxModelProps ) const; + virtual OUString implGetShapeName( const uno::Reference< drawing::XShape >& rxShape ) const throw (uno::RuntimeException); + virtual void implOnShapeCreated( const uno::Reference< drawing::XShape >& rxShape ) throw (uno::RuntimeException); + +protected: + uno::Reference< container::XIndexContainer > mxFormIC; + OUString maModelServiceName; + sal_Int16 mnComponentType; +}; + +// ---------------------------------------------------------------------------- + +ScVbaControlContainer::ScVbaControlContainer( + const uno::Reference< XHelperInterface >& rxParent, + const uno::Reference< uno::XComponentContext >& rxContext, + const uno::Reference< frame::XModel >& rxModel, + const uno::Reference< sheet::XSpreadsheet >& rxSheet, + const uno::Type& rVbaType, + const OUString& rModelServiceName, + sal_Int16 nComponentType ) throw (uno::RuntimeException) : + ScVbaObjectContainer( rxParent, rxContext, rxModel, rxSheet, rVbaType ), + maModelServiceName( rModelServiceName ), + mnComponentType( nComponentType ) +{ +} + +uno::Reference< container::XIndexContainer > ScVbaControlContainer::createForm() throw (uno::RuntimeException) +{ + if( !mxFormIC.is() ) + { + uno::Reference< form::XFormsSupplier > xFormsSupp( mxShapes, uno::UNO_QUERY_THROW ); + uno::Reference< container::XNameContainer > xFormsNC( xFormsSupp->getForms(), uno::UNO_SET_THROW ); + OUString aFormName = CREATE_OUSTRING( "Standard" ); + if( xFormsNC->hasByName( aFormName ) ) + { + mxFormIC.set( xFormsNC->getByName( aFormName ), uno::UNO_QUERY_THROW ); + } + else + { + uno::Reference< form::XForm > xForm( mxFactory->createInstance( CREATE_OUSTRING( "com.sun.star.form.component.Form" ) ), uno::UNO_QUERY_THROW ); + xFormsNC->insertByName( aFormName, uno::Any( xForm ) ); + mxFormIC.set( xForm, uno::UNO_QUERY_THROW ); + } + } + return mxFormIC; +} + +bool ScVbaControlContainer::implPickShape( const uno::Reference< drawing::XShape >& rxShape ) const +{ + try + { + uno::Reference< drawing::XControlShape > xControlShape( rxShape, uno::UNO_QUERY_THROW ); + uno::Reference< beans::XPropertySet > xModelProps( xControlShape->getControl(), uno::UNO_QUERY_THROW ); + sal_Int16 nClassId = -1; + return lclGetProperty( nClassId, xModelProps, CREATE_OUSTRING( "ClassId" ) ) && + (nClassId == mnComponentType) && implCheckProperties( xModelProps ); + } + catch( uno::Exception& ) + { + } + return false; +} + +OUString ScVbaControlContainer::implGetShapeServiceName() const +{ + return CREATE_OUSTRING( "com.sun.star.drawing.ControlShape" ); +} + +bool ScVbaControlContainer::implCheckProperties( const uno::Reference< beans::XPropertySet >& /*rxModelProps*/ ) const +{ + return true; +} + +OUString ScVbaControlContainer::implGetShapeName( const uno::Reference< drawing::XShape >& rxShape ) const throw (uno::RuntimeException) +{ + uno::Reference< drawing::XControlShape > xControlShape( rxShape, uno::UNO_QUERY_THROW ); + return uno::Reference< container::XNamed >( xControlShape->getControl(), uno::UNO_QUERY_THROW )->getName(); +} + +void ScVbaControlContainer::implOnShapeCreated( const uno::Reference< drawing::XShape >& rxShape ) throw (uno::RuntimeException) +{ + // passed shape must be a control shape + uno::Reference< drawing::XControlShape > xControlShape( rxShape, uno::UNO_QUERY_THROW ); + + // create the UNO control model + uno::Reference< form::XFormComponent > xFormComponent( mxFactory->createInstance( maModelServiceName ), uno::UNO_QUERY_THROW ); + uno::Reference< awt::XControlModel > xControlModel( xFormComponent, uno::UNO_QUERY_THROW ); + + // insert the control model into the form and the shape + createForm(); + mxFormIC->insertByIndex( mxFormIC->getCount(), uno::Any( xFormComponent ) ); + xControlShape->setControl( xControlModel ); +} + +// ============================================================================ +// Push button +// ============================================================================ + +class ScVbaButtonContainer : public ScVbaControlContainer +{ +public: + explicit ScVbaButtonContainer( + const uno::Reference< XHelperInterface >& rxParent, + const uno::Reference< uno::XComponentContext >& rxContext, + const uno::Reference< frame::XModel >& rxModel, + const uno::Reference< sheet::XSpreadsheet >& rxSheet ) throw (uno::RuntimeException); + +protected: + virtual ScVbaSheetObjectBase* implCreateVbaObject( const uno::Reference< drawing::XShape >& rxShape ) throw (uno::RuntimeException); + virtual bool implCheckProperties( const uno::Reference< beans::XPropertySet >& rxModelProps ) const; +}; + +// ---------------------------------------------------------------------------- + +ScVbaButtonContainer::ScVbaButtonContainer( + const uno::Reference< XHelperInterface >& rxParent, + const uno::Reference< uno::XComponentContext >& rxContext, + const uno::Reference< frame::XModel >& rxModel, + const uno::Reference< sheet::XSpreadsheet >& rxSheet ) throw (uno::RuntimeException) : + ScVbaControlContainer( + rxParent, rxContext, rxModel, rxSheet, + excel::XButton::static_type( 0 ), + CREATE_OUSTRING( "com.sun.star.form.component.CommandButton" ), + form::FormComponentType::COMMANDBUTTON ) +{ +} + +ScVbaSheetObjectBase* ScVbaButtonContainer::implCreateVbaObject( const uno::Reference< drawing::XShape >& rxShape ) throw (uno::RuntimeException) +{ + uno::Reference< drawing::XControlShape > xControlShape( rxShape, uno::UNO_QUERY_THROW ); + return new ScVbaButton( mxParent, mxContext, mxModel, createForm(), xControlShape ); +} + +bool ScVbaButtonContainer::implCheckProperties( const uno::Reference< beans::XPropertySet >& rxModelProps ) const +{ + // do not insert toggle buttons into the 'Buttons' collection + bool bToggle = false; + return lclGetProperty( bToggle, rxModelProps, CREATE_OUSTRING( "Toggle" ) ) && !bToggle; +} + +// ============================================================================ + +ScVbaButtons::ScVbaButtons( + const uno::Reference< XHelperInterface >& rxParent, + const uno::Reference< uno::XComponentContext >& rxContext, + const uno::Reference< frame::XModel >& rxModel, + const uno::Reference< sheet::XSpreadsheet >& rxSheet ) throw (uno::RuntimeException) : + ScVbaGraphicObjectsBase( new ScVbaButtonContainer( rxParent, rxContext, rxModel, rxSheet ) ) +{ +} + +VBAHELPER_IMPL_XHELPERINTERFACE( ScVbaButtons, "ooo.vba.excel.Buttons" ) + +// ============================================================================ diff --git a/sc/source/ui/vba/vbasheetobjects.hxx b/sc/source/ui/vba/vbasheetobjects.hxx new file mode 100755 index 000000000000..fd69d4927a20 --- /dev/null +++ b/sc/source/ui/vba/vbasheetobjects.hxx @@ -0,0 +1,113 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef SC_VBA_SHEETOBJECTS_HXX +#define SC_VBA_SHEETOBJECTS_HXX + +#include <ooo/vba/excel/XGraphicObjects.hpp> +#include <vbahelper/vbacollectionimpl.hxx> +#include <rtl/ref.hxx> + +namespace com { namespace sun { namespace star { + namespace container { class XEnumeration; } + namespace frame { class XModel; } + namespace sheet { class XSpreadsheet; } +} } } + +// ============================================================================ + +class ScVbaObjectContainer; +typedef ::rtl::Reference< ScVbaObjectContainer > ScVbaObjectContainerRef; + +// ============================================================================ + +typedef CollTestImplHelper< ov::XCollection > ScVbaSheetObjects_BASE; + +/** Base class for collections containing a specific type of drawing object + embedded in a sheet (worksheet, chart sheet, or dialog sheet). + */ +class ScVbaSheetObjectsBase : public ScVbaSheetObjects_BASE +{ +public: + explicit ScVbaSheetObjectsBase( const ScVbaObjectContainerRef& rxContainer ) throw (css::uno::RuntimeException); + virtual ~ScVbaSheetObjectsBase(); + + /** Updates the collection by fetching all shapes from the draw page. */ + void collectShapes() throw (css::uno::RuntimeException); + + // XEnumerationAccess + virtual css::uno::Reference< css::container::XEnumeration > SAL_CALL createEnumeration() throw (css::uno::RuntimeException); + + // XElementAccess + virtual css::uno::Type SAL_CALL getElementType() throw (css::uno::RuntimeException); + + // ScVbaCollectionBase + virtual css::uno::Any createCollectionObject( const css::uno::Any& rSource ); + virtual css::uno::Any getItemByStringIndex( const ::rtl::OUString& rIndex ) throw (css::uno::RuntimeException); + +protected: + ScVbaObjectContainerRef mxContainer; +}; + +// ============================================================================ + +typedef ::cppu::ImplInheritanceHelper1< ScVbaSheetObjectsBase, ov::excel::XGraphicObjects > ScVbaGraphicObjects_BASE; + +/** Base class for collections containing a specific type of graphic object + from a sheet. + */ +class ScVbaGraphicObjectsBase : public ScVbaGraphicObjects_BASE +{ +public: + explicit ScVbaGraphicObjectsBase( const ScVbaObjectContainerRef& rxContainer ) throw (css::uno::RuntimeException); + + // XGraphicObjects + virtual css::uno::Any SAL_CALL Add( + const css::uno::Any& rLeft, + const css::uno::Any& rTop, + const css::uno::Any& rWidth, + const css::uno::Any& rHeight ) throw (css::uno::RuntimeException); +}; + +// ============================================================================ + +/** Collection containing all button controls from a sheet (not ActiveX controls). */ +class ScVbaButtons : public ScVbaGraphicObjectsBase +{ +public: + explicit ScVbaButtons( + const css::uno::Reference< ov::XHelperInterface >& rxParent, + const css::uno::Reference< css::uno::XComponentContext >& rxContext, + const css::uno::Reference< css::frame::XModel >& rxModel, + const css::uno::Reference< css::sheet::XSpreadsheet >& rxSheet ) throw (css::uno::RuntimeException); + + VBAHELPER_DECL_XHELPERINTERFACE +}; + +// ============================================================================ + +#endif diff --git a/sc/source/ui/vba/vbawindow.cxx b/sc/source/ui/vba/vbawindow.cxx index f0aafe83908b..10dad39341b7 100644 --- a/sc/source/ui/vba/vbawindow.cxx +++ b/sc/source/ui/vba/vbawindow.cxx @@ -55,9 +55,6 @@ using namespace ::com::sun::star; using namespace ::ooo::vba; using namespace ::ooo::vba::excel::XlWindowState; -// nameExists defined in vbaworksheet.cxx -bool nameExists( uno::Reference <sheet::XSpreadsheetDocument>& xSpreadDoc, ::rtl::OUString & name, SCTAB& nTab ) throw ( lang::IllegalArgumentException ); - typedef std::hash_map< rtl::OUString, SCTAB, ::rtl::OUStringHash, ::std::equal_to< ::rtl::OUString > > NameIndexHash; @@ -213,18 +210,25 @@ ScVbaWindow::ScVbaWindow( uno::Sequence< uno::Any > const & args, uno::Reference { init(); } + void ScVbaWindow::init() { + /* This method is called from the constructor, thus the own refcount is + still zero. The implementation of ActivePane() uses a UNO reference of + this (to set this window as parent of the pane obejct). This requires + the own refcount to be non-zero, otherwise this instance will be + desctructed immediately! */ + osl_incrementInterlockedCount( &m_refCount ); uno::Reference< frame::XController > xController( m_xModel->getCurrentController(), uno::UNO_QUERY_THROW ); m_xViewPane.set( xController, uno::UNO_QUERY_THROW ); m_xViewFreezable.set( xController, uno::UNO_QUERY_THROW ); m_xViewSplitable.set( xController, uno::UNO_QUERY_THROW ); m_xPane.set( ActivePane(), uno::UNO_QUERY_THROW ); m_xDevice.set( xController->getFrame()->getComponentWindow(), uno::UNO_QUERY_THROW ); + osl_decrementInterlockedCount( &m_refCount ); } - void ScVbaWindow::Scroll( const uno::Any& Down, const uno::Any& Up, const uno::Any& ToRight, const uno::Any& ToLeft, bool bLargeScroll ) throw (uno::RuntimeException) { @@ -233,11 +237,13 @@ ScVbaWindow::Scroll( const uno::Any& Down, const uno::Any& Up, const uno::Any& T else m_xPane->SmallScroll( Down, Up, ToRight, ToLeft ); } + void SAL_CALL ScVbaWindow::SmallScroll( const uno::Any& Down, const uno::Any& Up, const uno::Any& ToRight, const uno::Any& ToLeft ) throw (uno::RuntimeException) { Scroll( Down, Up, ToRight, ToLeft ); } + void SAL_CALL ScVbaWindow::LargeScroll( const uno::Any& Down, const uno::Any& Up, const uno::Any& ToRight, const uno::Any& ToLeft ) throw (uno::RuntimeException) { @@ -450,7 +456,7 @@ ScVbaWindow::Close( const uno::Any& SaveChanges, const uno::Any& FileName, const uno::Reference< excel::XPane > SAL_CALL ScVbaWindow::ActivePane() throw (script::BasicErrorException, uno::RuntimeException) { - return new ScVbaPane( mxContext, m_xViewPane ); + return new ScVbaPane( this, mxContext, m_xModel, m_xViewPane ); } uno::Reference< excel::XRange > SAL_CALL @@ -467,6 +473,14 @@ ScVbaWindow::Selection( ) throw (script::BasicErrorException, uno::RuntimeExcep return xApplication->getSelection(); } +uno::Reference< excel::XRange > SAL_CALL +ScVbaWindow::RangeSelection() throw (script::BasicErrorException, uno::RuntimeException) +{ + /* TODO / FIXME: According to documentation, this method returns the range + selection even if shapes are selected. */ + return uno::Reference< excel::XRange >( Selection(), uno::UNO_QUERY_THROW ); +} + ::sal_Bool SAL_CALL ScVbaWindow::getDisplayGridlines() throw (uno::RuntimeException) { @@ -732,9 +746,7 @@ ScVbaWindow::setZoom( const uno::Any& _zoom ) throw (uno::RuntimeException) uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( m_xModel, uno::UNO_QUERY_THROW ); uno::Reference< excel::XWorksheet > xActiveSheet = ActiveSheet(); SCTAB nTab = 0; - rtl::OUString sName = xActiveSheet->getName(); - bool bSheetExists = nameExists (xSpreadDoc, sName, nTab); - if ( !bSheetExists ) + if ( !ScVbaWorksheets::nameExists (xSpreadDoc, xActiveSheet->getName(), nTab) ) throw uno::RuntimeException(); std::vector< SCTAB > vTabs; vTabs.push_back( nTab ); @@ -778,6 +790,15 @@ ScVbaWindow::setView( const uno::Any& _view) throw (uno::RuntimeException) dispatchExecute( pViewShell, nSlot ); } +uno::Reference< excel::XRange > SAL_CALL +ScVbaWindow::getVisibleRange() throw (uno::RuntimeException) +{ + uno::Reference< container::XIndexAccess > xPanesIA( m_xViewPane, uno::UNO_QUERY_THROW ); + uno::Reference< sheet::XViewPane > xTopLeftPane( xPanesIA->getByIndex( 0 ), uno::UNO_QUERY_THROW ); + uno::Reference< excel::XPane > xPane( new ScVbaPane( this, mxContext, m_xModel, xTopLeftPane ) ); + return xPane->getVisibleRange(); +} + sal_Int32 SAL_CALL ScVbaWindow::PointsToScreenPixelsX(sal_Int32 _points) throw (css::script::BasicErrorException, css::uno::RuntimeException) { diff --git a/sc/source/ui/vba/vbawindow.hxx b/sc/source/ui/vba/vbawindow.hxx index e72401a2baac..d58d2a07cb4b 100644 --- a/sc/source/ui/vba/vbawindow.hxx +++ b/sc/source/ui/vba/vbawindow.hxx @@ -26,6 +26,7 @@ ************************************************************************/ #ifndef SC_VBA_WINDOW_HXX #define SC_VBA_WINDOW_HXX + #include <cppuhelper/implbase1.hxx> #include <ooo/vba/excel/XWindow.hpp> #include <com/sun/star/uno/XComponentContext.hpp> @@ -40,7 +41,6 @@ #include <vbahelper/vbawindowbase.hxx> #include "vbaworkbook.hxx" -//typedef InheritedHelperInterfaceImpl1<ov::excel::XWindow > WindowImpl_BASE; typedef cppu::ImplInheritanceHelper1< VbaWindowBase, ov::excel::XWindow > WindowImpl_BASE; class ScVbaWindow : public WindowImpl_BASE @@ -96,6 +96,7 @@ public: virtual void SAL_CALL setScrollColumn( const css::uno::Any& _scrollcolumn ) throw (css::uno::RuntimeException) ; virtual css::uno::Any SAL_CALL getView() throw (css::uno::RuntimeException); virtual void SAL_CALL setView( const css::uno::Any& _view ) throw (css::uno::RuntimeException); + virtual css::uno::Reference< ov::excel::XRange > SAL_CALL getVisibleRange() throw (css::uno::RuntimeException); virtual css::uno::Any SAL_CALL getWindowState() throw (css::uno::RuntimeException); virtual void SAL_CALL setWindowState( const css::uno::Any& _windowstate ) throw (css::uno::RuntimeException); virtual css::uno::Any SAL_CALL getZoom() throw (css::uno::RuntimeException); @@ -108,11 +109,12 @@ public: virtual void SAL_CALL ScrollWorkbookTabs( const css::uno::Any& Sheets, const css::uno::Any& Position ) throw (css::uno::RuntimeException); virtual void SAL_CALL Activate( ) throw (css::uno::RuntimeException); virtual void SAL_CALL Close( const css::uno::Any& SaveChanges, const css::uno::Any& FileName, const css::uno::Any& RouteWorkBook ) throw (css::uno::RuntimeException); - virtual css::uno::Any SAL_CALL Selection( ) throw (css::script::BasicErrorException, css::uno::RuntimeException); - virtual sal_Int32 SAL_CALL PointsToScreenPixelsX(sal_Int32 _points) throw (css::script::BasicErrorException, css::uno::RuntimeException); - virtual sal_Int32 SAL_CALL PointsToScreenPixelsY(sal_Int32 _points) throw (css::script::BasicErrorException, css::uno::RuntimeException); - virtual void SAL_CALL PrintOut( const css::uno::Any& From, const css::uno::Any&To, const css::uno::Any& Copies, const css::uno::Any& Preview, const css::uno::Any& ActivePrinter, const css::uno::Any& PrintToFile, const css::uno::Any& Collate, const css::uno::Any& PrToFileName ) throw (css::script::BasicErrorException, css::uno::RuntimeException); - virtual void SAL_CALL PrintPreview( const css::uno::Any& EnableChanges ) throw (css::script::BasicErrorException, css::uno::RuntimeException); + virtual css::uno::Any SAL_CALL Selection( ) throw (css::script::BasicErrorException, css::uno::RuntimeException); + virtual css::uno::Reference< ov::excel::XRange > SAL_CALL RangeSelection() throw (css::script::BasicErrorException, css::uno::RuntimeException); + virtual sal_Int32 SAL_CALL PointsToScreenPixelsX(sal_Int32 _points) throw (css::script::BasicErrorException, css::uno::RuntimeException); + virtual sal_Int32 SAL_CALL PointsToScreenPixelsY(sal_Int32 _points) throw (css::script::BasicErrorException, css::uno::RuntimeException); + virtual void SAL_CALL PrintOut( const css::uno::Any& From, const css::uno::Any&To, const css::uno::Any& Copies, const css::uno::Any& Preview, const css::uno::Any& ActivePrinter, const css::uno::Any& PrintToFile, const css::uno::Any& Collate, const css::uno::Any& PrToFileName ) throw (css::script::BasicErrorException, css::uno::RuntimeException); + virtual void SAL_CALL PrintPreview( const css::uno::Any& EnableChanges ) throw (css::script::BasicErrorException, css::uno::RuntimeException); // XHelperInterface virtual rtl::OUString& getServiceImplName(); virtual css::uno::Sequence<rtl::OUString> getServiceNames(); diff --git a/sc/source/ui/vba/vbaworkbook.cxx b/sc/source/ui/vba/vbaworkbook.cxx index 6694f4e5e135..365c8b35a00c 100644 --- a/sc/source/ui/vba/vbaworkbook.cxx +++ b/sc/source/ui/vba/vbaworkbook.cxx @@ -345,32 +345,8 @@ ScVbaWorkbook::getServiceNames() ::rtl::OUString SAL_CALL ScVbaWorkbook::getCodeName() throw (css::uno::RuntimeException) { -#ifdef VBA_OOBUILD_HACK - uno::Reference< frame::XModel > xModel( getModel(), uno::UNO_QUERY_THROW ); - ScDocument* pDoc = excel::getDocShell( xModel )->GetDocument(); - ScExtDocOptions* pExtOptions = pDoc->GetExtDocOptions(); - ScExtDocSettings pExtSettings = pExtOptions->GetDocSettings(); - ::rtl::OUString sGlobCodeName = pExtSettings.maGlobCodeName; - return sGlobCodeName; -#else - throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Not implemented") ), uno::Reference< uno::XInterface >() ); -#endif -} -#ifdef VBA_OOBUILD_HACK -void SAL_CALL -ScVbaWorkbook::setCodeName( const ::rtl::OUString& sGlobCodeName ) throw (css::uno::RuntimeException) -{ - uno::Reference< frame::XModel > xModel( getModel(), uno::UNO_QUERY_THROW ); - ScDocument* pDoc = excel::getDocShell( xModel )->GetDocument(); - ScExtDocOptions* pExtOptions = pDoc->GetExtDocOptions(); - ScExtDocSettings pExtSettings = pExtOptions->GetDocSettings(); - pExtSettings.maGlobCodeName = sGlobCodeName; -#else -void SAL_CALL -ScVbaWorkbook::setCodeName( const ::rtl::OUString& ) throw (css::uno::RuntimeException) -{ - throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Not implemented") ), uno::Reference< uno::XInterface >() ); -#endif + uno::Reference< beans::XPropertySet > xModelProp( getModel(), uno::UNO_QUERY_THROW ); + return xModelProp->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CodeName" ) ) ).get< ::rtl::OUString >(); } namespace workbook diff --git a/sc/source/ui/vba/vbaworkbook.hxx b/sc/source/ui/vba/vbaworkbook.hxx index 40234aca21d7..4aff58078403 100644 --- a/sc/source/ui/vba/vbaworkbook.hxx +++ b/sc/source/ui/vba/vbaworkbook.hxx @@ -71,7 +71,6 @@ public: virtual void SAL_CALL SaveCopyAs( const rtl::OUString& Filename ) throw ( css::uno::RuntimeException); // code name virtual ::rtl::OUString SAL_CALL getCodeName() throw ( css::uno::RuntimeException); - virtual void SAL_CALL setCodeName( const ::rtl::OUString& sGlobCodeName ) throw (css::uno::RuntimeException); // XHelperInterface virtual rtl::OUString& getServiceImplName(); diff --git a/sc/source/ui/vba/vbaworksheet.cxx b/sc/source/ui/vba/vbaworksheet.cxx index be988509aa68..5b1963e3d242 100644 --- a/sc/source/ui/vba/vbaworksheet.cxx +++ b/sc/source/ui/vba/vbaworksheet.cxx @@ -24,9 +24,12 @@ * for a copy of the LGPLv3 License. * ************************************************************************/ + #include <vbahelper/helperdecl.hxx> #include <cppuhelper/queryinterface.hxx> +#include "vbaworksheet.hxx" + #include <com/sun/star/beans/XPropertySet.hpp> #include <com/sun/star/beans/XIntrospectionAccess.hpp> #include <com/sun/star/beans/XIntrospection.hpp> @@ -60,14 +63,15 @@ #include <ooo/vba/XControlProvider.hpp> #include <comphelper/processfactory.hxx> +#include <vbahelper/vbashapes.hxx> #include <tools/string.hxx> //zhangyun showdataform #include <sfx2/sfxdlg.hxx> -#include <scabstdlg.hxx> -#include <tabvwsh.hxx> -#include <scitems.hxx> +#include "scabstdlg.hxx" +#include "tabvwsh.hxx" +#include "scitems.hxx" #include <svx/svdouno.hxx> #include <svx/svdpage.hxx> @@ -79,43 +83,22 @@ #include "vbaoutline.hxx" #include "vbarange.hxx" #include "vbacomments.hxx" -#include "vbaworksheet.hxx" #include "vbachartobjects.hxx" #include "vbapivottables.hxx" #include "vbaoleobject.hxx" #include "vbaoleobjects.hxx" -#include <vbahelper/vbashapes.hxx> #include "vbapagesetup.hxx" #include "vbapagebreaks.hxx" +#include "vbaworksheets.hxx" +#include "vbahyperlinks.hxx" +#include "vbasheetobjects.hxx" #define STANDARDWIDTH 2267 #define STANDARDHEIGHT 427 #define DOESNOTEXIST -1 + using namespace com::sun::star; using namespace ooo::vba; -bool -nameExists( uno::Reference <sheet::XSpreadsheetDocument>& xSpreadDoc, ::rtl::OUString & name, SCTAB& nTab ) throw ( lang::IllegalArgumentException ) -{ - if (!xSpreadDoc.is()) - throw lang::IllegalArgumentException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "nameExists() xSpreadDoc is null" ) ), uno::Reference< uno::XInterface >(), 1 ); - uno::Reference <sheet::XSpreadsheets> xSheets = xSpreadDoc->getSheets(); - uno::Reference <container::XIndexAccess> xIndex( xSheets, uno::UNO_QUERY ); - if ( xIndex.is() ) - { - SCTAB nCount = static_cast< SCTAB >( xIndex->getCount() ); - for (SCTAB i=0; i < nCount; i++) - { - uno::Reference< sheet::XSpreadsheet > xSheet(xIndex->getByIndex(i), uno::UNO_QUERY); - uno::Reference< container::XNamed > xNamed( xSheet, uno::UNO_QUERY_THROW ); - if (xNamed->getName() == name) - { - nTab = i; - return true; - } - } - } - return false; -} static void getNewSpreadsheetName (rtl::OUString &aNewName, rtl::OUString aOldName, uno::Reference <sheet::XSpreadsheetDocument>& xSpreadDoc ) { @@ -125,7 +108,7 @@ static void getNewSpreadsheetName (rtl::OUString &aNewName, rtl::OUString aOldNa int currentNum =2; aNewName = aOldName + aUnderScre+ String::CreateFromInt32(currentNum) ; SCTAB nTab = 0; - while ( nameExists(xSpreadDoc,aNewName, nTab ) ) + while ( ScVbaWorksheets::nameExists(xSpreadDoc,aNewName, nTab ) ) { aNewName = aOldName + aUnderScre + String::CreateFromInt32(++currentNum) ; @@ -152,7 +135,8 @@ static void removeAllSheets( uno::Reference <sheet::XSpreadsheetDocument>& xSpre } } - uno::Reference< sheet::XSpreadsheet > xSheet(xIndex->getByIndex(0), uno::UNO_QUERY); uno::Reference< container::XNamed > xNamed( xSheet, uno::UNO_QUERY_THROW ); + uno::Reference< sheet::XSpreadsheet > xSheet(xIndex->getByIndex(0), uno::UNO_QUERY); + uno::Reference< container::XNamed > xNamed( xSheet, uno::UNO_QUERY_THROW ); if (xNamed.is()) { xNamed->setName(aSheetName); @@ -196,6 +180,7 @@ openNewDoc(rtl::OUString aSheetName ) ScVbaWorksheet::ScVbaWorksheet( const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext ) : WorksheetImpl_BASE( xParent, xContext ) { } + ScVbaWorksheet::ScVbaWorksheet(const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext >& xContext, const uno::Reference< sheet::XSpreadsheet >& xSheet, const uno::Reference< frame::XModel >& xModel ) throw (uno::RuntimeException) : WorksheetImpl_BASE( xParent, xContext ), mxSheet( xSheet ), mxModel(xModel) @@ -216,6 +201,10 @@ ScVbaWorksheet::ScVbaWorksheet( uno::Sequence< uno::Any> const & args, mxSheet.set( xNameAccess->getByName( sSheetName ), uno::UNO_QUERY_THROW ); } +ScVbaWorksheet::~ScVbaWorksheet() +{ +} + ::rtl::OUString ScVbaWorksheet::getName() throw (uno::RuntimeException) { @@ -261,9 +250,7 @@ ScVbaWorksheet::getEnableSelection() throw (uno::RuntimeException) { uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( getModel(), uno::UNO_QUERY_THROW ); SCTAB nTab = 0; - rtl::OUString aSheetName = getName(); - bool bSheetExists = nameExists (xSpreadDoc, aSheetName, nTab); - if ( bSheetExists ) + if ( ScVbaWorksheets::nameExists(xSpreadDoc, getName(), nTab) ) { uno::Reference< frame::XModel > xModel( getModel(), uno::UNO_QUERY_THROW ); ScDocument* pDoc = excel::getDocShell( xModel )->GetDocument(); @@ -301,9 +288,7 @@ ScVbaWorksheet::setEnableSelection( sal_Int32 nSelection ) throw (uno::RuntimeEx uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( getModel(), uno::UNO_QUERY_THROW ); SCTAB nTab = 0; - rtl::OUString aSheetName = getName(); - bool bSheetExists = nameExists (xSpreadDoc, aSheetName, nTab); - if ( bSheetExists ) + if ( ScVbaWorksheets::nameExists(xSpreadDoc, getName(), nTab) ) { uno::Reference< frame::XModel > xModel( getModel(), uno::UNO_QUERY_THROW ); ScDocument* pDoc = excel::getDocShell( xModel )->GetDocument(); @@ -426,9 +411,8 @@ ScVbaWorksheet::Select() throw (uno::RuntimeException) void ScVbaWorksheet::Move( const uno::Any& Before, const uno::Any& After ) throw (uno::RuntimeException) { - rtl::OUString aSheetName; uno::Reference<excel::XWorksheet> xSheet; - rtl::OUString aCurrSheetName =getName(); + rtl::OUString aCurrSheetName = getName(); if (!(Before >>= xSheet) && !(After >>=xSheet)&& !(Before.hasValue()) && !(After.hasValue())) { @@ -451,9 +435,7 @@ ScVbaWorksheet::Move( const uno::Any& Before, const uno::Any& After ) throw (uno uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( getModel(), uno::UNO_QUERY_THROW ); SCTAB nDest = 0; - aSheetName = xSheet->getName(); - bool bSheetExists = nameExists (xSpreadDoc, aSheetName, nDest); - if ( bSheetExists ) + if ( ScVbaWorksheets::nameExists (xSpreadDoc, xSheet->getName(), nDest) ) { sal_Bool bAfter = After.hasValue(); if (bAfter) @@ -466,7 +448,6 @@ ScVbaWorksheet::Move( const uno::Any& Before, const uno::Any& After ) throw (uno void ScVbaWorksheet::Copy( const uno::Any& Before, const uno::Any& After ) throw (uno::RuntimeException) { - rtl::OUString aSheetName; uno::Reference<excel::XWorksheet> xSheet; rtl::OUString aCurrSheetName =getName(); if (!(Before >>= xSheet) && !(After >>=xSheet)&& !(Before.hasValue()) && !(After.hasValue())) @@ -488,10 +469,8 @@ ScVbaWorksheet::Copy( const uno::Any& Before, const uno::Any& After ) throw (uno uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( getModel(), uno::UNO_QUERY ); SCTAB nDest = 0; - aSheetName = xSheet->getName(); - bool bSheetExists = nameExists (xSpreadDoc, aSheetName, nDest ); - - if ( bSheetExists ) + rtl::OUString aSheetName = xSheet->getName(); + if ( ScVbaWorksheets::nameExists (xSpreadDoc, aSheetName, nDest ) ) { sal_Bool bAfter = After.hasValue(); if(bAfter) @@ -521,7 +500,7 @@ ScVbaWorksheet::Delete() throw (uno::RuntimeException) if ( xSpreadDoc.is() ) { SCTAB nTab = 0; - if (!nameExists(xSpreadDoc, aSheetName, nTab )) + if (!ScVbaWorksheets::nameExists(xSpreadDoc, aSheetName, nTab )) { return; } @@ -539,11 +518,8 @@ ScVbaWorksheet::getSheetAtOffset(SCTAB offset) throw (uno::RuntimeException) uno::Reference <sheet::XSpreadsheets> xSheets( xSpreadDoc->getSheets(), uno::UNO_QUERY_THROW ); uno::Reference <container::XIndexAccess> xIndex( xSheets, uno::UNO_QUERY_THROW ); - rtl::OUString aName = getName(); SCTAB nIdx = 0; - bool bSheetExists = nameExists (xSpreadDoc, aName, nIdx ); - - if ( !bSheetExists ) + if ( !ScVbaWorksheets::nameExists (xSpreadDoc, getName(), nIdx ) ) return uno::Reference< excel::XWorksheet >(); nIdx = nIdx + offset; uno::Reference< sheet::XSpreadsheet > xSheet(xIndex->getByIndex(nIdx), uno::UNO_QUERY_THROW); @@ -677,13 +653,25 @@ ScVbaWorksheet::Comments( const uno::Any& Index ) throw (uno::RuntimeException) uno::Reference< sheet::XSheetAnnotationsSupplier > xAnnosSupp( xSheet, uno::UNO_QUERY_THROW ); uno::Reference< sheet::XSheetAnnotations > xAnnos( xAnnosSupp->getAnnotations(), uno::UNO_QUERY_THROW ); uno::Reference< container::XIndexAccess > xIndexAccess( xAnnos, uno::UNO_QUERY_THROW ); - uno::Reference< XCollection > xColl( new ScVbaComments( this, mxContext, xIndexAccess ) ); + uno::Reference< XCollection > xColl( new ScVbaComments( this, mxContext, mxModel, xIndexAccess ) ); if ( Index.hasValue() ) return xColl->Item( Index, uno::Any() ); return uno::makeAny( xColl ); } uno::Any SAL_CALL +ScVbaWorksheet::Hyperlinks( const uno::Any& aIndex ) throw (uno::RuntimeException) +{ + /* The worksheet always returns the same Hyperlinks object. + See vbahyperlinks.hxx for more details. */ + if( !mxHlinks.is() ) + mxHlinks.set( new ScVbaHyperlinks( this, mxContext ) ); + if( aIndex.hasValue() ) + return uno::Reference< XCollection >( mxHlinks, uno::UNO_QUERY_THROW )->Item( aIndex, uno::Any() ); + return uno::Any( mxHlinks ); +} + +uno::Any SAL_CALL ScVbaWorksheet::OLEObjects( const uno::Any& Index ) throw (uno::RuntimeException) { ScVbaOLEObjects* aOleObjects; @@ -716,6 +704,66 @@ ScVbaWorksheet::Shapes( const uno::Any& aIndex ) throw (uno::RuntimeException) return uno::makeAny( xVbaShapes ); } +uno::Any SAL_CALL +ScVbaWorksheet::Buttons( const uno::Any& rIndex ) throw (uno::RuntimeException) +{ + if( !mxButtons.is() ) + mxButtons.set( new ScVbaButtons( this, mxContext, mxModel, mxSheet ) ); + else + mxButtons->collectShapes(); + if( rIndex.hasValue() ) + return mxButtons->Item( rIndex, uno::Any() ); + return uno::Any( uno::Reference< XCollection >( mxButtons.get() ) ); +} + +uno::Any SAL_CALL +ScVbaWorksheet::CheckBoxes( const uno::Any& /*rIndex*/ ) throw (uno::RuntimeException) +{ + throw uno::RuntimeException(); +} + +uno::Any SAL_CALL +ScVbaWorksheet::DropDowns( const uno::Any& /*rIndex*/ ) throw (uno::RuntimeException) +{ + throw uno::RuntimeException(); +} + +uno::Any SAL_CALL +ScVbaWorksheet::GroupBoxes( const uno::Any& /*rIndex*/ ) throw (uno::RuntimeException) +{ + throw uno::RuntimeException(); +} + +uno::Any SAL_CALL +ScVbaWorksheet::Labels( const uno::Any& /*rIndex*/ ) throw (uno::RuntimeException) +{ + throw uno::RuntimeException(); +} + +uno::Any SAL_CALL +ScVbaWorksheet::ListBoxes( const uno::Any& /*rIndex*/ ) throw (uno::RuntimeException) +{ + throw uno::RuntimeException(); +} + +uno::Any SAL_CALL +ScVbaWorksheet::OptionButtons( const uno::Any& /*rIndex*/ ) throw (uno::RuntimeException) +{ + throw uno::RuntimeException(); +} + +uno::Any SAL_CALL +ScVbaWorksheet::ScrollBars( const uno::Any& /*rIndex*/ ) throw (uno::RuntimeException) +{ + throw uno::RuntimeException(); +} + +uno::Any SAL_CALL +ScVbaWorksheet::Spinners( const uno::Any& /*rIndex*/ ) throw (uno::RuntimeException) +{ + throw uno::RuntimeException(); +} + void SAL_CALL ScVbaWorksheet::ShowDataForm( ) throw (uno::RuntimeException) { @@ -882,52 +930,8 @@ ScVbaWorksheet::getServiceNames() rtl::OUString SAL_CALL ScVbaWorksheet::getCodeName() throw (css::uno::RuntimeException) { -#ifdef VBA_OOBUILD_HACK - uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( getModel(), uno::UNO_QUERY_THROW ); - SCTAB nTab = 0; - rtl::OUString aSheetName = getName(); - bool bSheetExists = nameExists (xSpreadDoc, aSheetName, nTab); - if ( bSheetExists ) - { - uno::Reference< frame::XModel > xModel( getModel(), uno::UNO_QUERY_THROW ); - ScDocument* pDoc = getDocShell( xModel )->GetDocument(); - ScExtDocOptions* pExtOptions = pDoc->GetExtDocOptions(); - rtl::OUString sCodeName = pExtOptions->GetCodeName( nTab ); - return sCodeName; - } - else - throw uno::RuntimeException(::rtl::OUString( - RTL_CONSTASCII_USTRINGPARAM( "Sheet Name does not exist. ") ), - uno::Reference< XInterface >() ); -#else - throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Not implemented") ), uno::Reference< uno::XInterface >() ); -#endif -} -#ifdef VBA_OOBUILD_HACK -void SAL_CALL -ScVbaWorksheet::setCodeName( const rtl::OUString& sCodeName ) throw (css::uno::RuntimeException) -{ - uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( getModel(), uno::UNO_QUERY_THROW ); - SCTAB nTab = 0; - rtl::OUString aSheetName = getName(); - bool bSheetExists = nameExists (xSpreadDoc, aSheetName, nTab); - if ( bSheetExists ) - { - uno::Reference< frame::XModel > xModel( getModel(), uno::UNO_QUERY_THROW ); - ScDocument* pDoc = getDocShell( xModel )->GetDocument(); - ScExtDocOptions* pExtOptions = pDoc->GetExtDocOptions(); - pExtOptions->SetCodeName( sCodeName, nTab ); - } - else - throw uno::RuntimeException(::rtl::OUString( - RTL_CONSTASCII_USTRINGPARAM( "Sheet Name does not exist. ") ), - uno::Reference< XInterface >() ); -#else -void SAL_CALL -ScVbaWorksheet::setCodeName( const rtl::OUString& ) throw (css::uno::RuntimeException) -{ - throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("Not implemented") ), uno::Reference< uno::XInterface >() ); -#endif + uno::Reference< beans::XPropertySet > xSheetProp( mxSheet, uno::UNO_QUERY_THROW ); + return xSheetProp->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "CodeName" ) ) ).get< ::rtl::OUString >(); } sal_Int16 diff --git a/sc/source/ui/vba/vbaworksheet.hxx b/sc/source/ui/vba/vbaworksheet.hxx index 5fe1343f9237..d07cc1a8d55c 100644 --- a/sc/source/ui/vba/vbaworksheet.hxx +++ b/sc/source/ui/vba/vbaworksheet.hxx @@ -42,11 +42,17 @@ #include <ooo/vba/excel/XPageSetup.hpp> #include <ooo/vba/excel/XHPageBreaks.hpp> #include <ooo/vba/excel/XVPageBreaks.hpp> -#include <ooo/vba/excel/XChartObjects.hpp> #include <vbahelper/vbahelperinterface.hxx> #include "address.hxx" +namespace ooo { namespace vba { namespace excel { + class XChartObjects; + class XHyperlinks; +} } } + +class ScVbaSheetObjectsBase; + typedef InheritedHelperInterfaceImpl1< ov::excel::XWorksheet > WorksheetImpl_BASE; class ScVbaWorksheet : public WorksheetImpl_BASE @@ -54,6 +60,8 @@ class ScVbaWorksheet : public WorksheetImpl_BASE css::uno::Reference< css::sheet::XSpreadsheet > mxSheet; css::uno::Reference< css::frame::XModel > mxModel; css::uno::Reference< ov::excel::XChartObjects > mxCharts; + css::uno::Reference< ov::excel::XHyperlinks > mxHlinks; + ::rtl::Reference< ScVbaSheetObjectsBase > mxButtons; css::uno::Reference< ov::excel::XWorksheet > getSheetAtOffset(SCTAB offset) throw (css::uno::RuntimeException); css::uno::Reference< ov::excel::XRange > getSheetRange() throw (css::uno::RuntimeException); @@ -70,7 +78,7 @@ public: const css::uno::Reference< css::frame::XModel >& xModel )throw (css::uno::RuntimeException) ; ScVbaWorksheet( css::uno::Sequence< css::uno::Any > const& aArgs, css::uno::Reference< css::uno::XComponentContext >const& xContext ) throw ( css::lang::IllegalArgumentException ); - virtual ~ScVbaWorksheet() {} + virtual ~ScVbaWorksheet(); virtual css::uno::Reference< css::frame::XModel > getModel() { return mxModel; } @@ -120,9 +128,21 @@ public: virtual css::uno::Any SAL_CALL Evaluate( const ::rtl::OUString& Name ) throw (css::uno::RuntimeException); virtual css::uno::Any SAL_CALL PivotTables( const css::uno::Any& Index ) throw (css::uno::RuntimeException); virtual css::uno::Any SAL_CALL Comments( const css::uno::Any& Index ) throw (css::uno::RuntimeException); + virtual css::uno::Any SAL_CALL Hyperlinks( const css::uno::Any& aIndex ) throw (css::uno::RuntimeException); virtual css::uno::Any SAL_CALL OLEObjects( const css::uno::Any& Index ) throw (css::uno::RuntimeException); virtual css::uno::Any SAL_CALL Shapes( const css::uno::Any& aIndex ) throw (css::uno::RuntimeException); + + virtual css::uno::Any SAL_CALL Buttons( const css::uno::Any& rIndex ) throw (css::uno::RuntimeException); + virtual css::uno::Any SAL_CALL CheckBoxes( const css::uno::Any& rIndex ) throw (css::uno::RuntimeException); + virtual css::uno::Any SAL_CALL DropDowns( const css::uno::Any& rIndex ) throw (css::uno::RuntimeException); + virtual css::uno::Any SAL_CALL GroupBoxes( const css::uno::Any& rIndex ) throw (css::uno::RuntimeException); + virtual css::uno::Any SAL_CALL Labels( const css::uno::Any& rIndex ) throw (css::uno::RuntimeException); + virtual css::uno::Any SAL_CALL ListBoxes( const css::uno::Any& rIndex ) throw (css::uno::RuntimeException); + virtual css::uno::Any SAL_CALL OptionButtons( const css::uno::Any& rIndex ) throw (css::uno::RuntimeException); + virtual css::uno::Any SAL_CALL ScrollBars( const css::uno::Any& rIndex ) throw (css::uno::RuntimeException); + virtual css::uno::Any SAL_CALL Spinners( const css::uno::Any& rIndex ) throw (css::uno::RuntimeException); + virtual void SAL_CALL setEnableCalculation( ::sal_Bool EnableCalculation ) throw ( css::script::BasicErrorException, css::uno::RuntimeException); virtual ::sal_Bool SAL_CALL getEnableCalculation( ) throw (css::script::BasicErrorException, css::uno::RuntimeException); virtual void SAL_CALL ShowDataForm( ) throw (css::uno::RuntimeException); @@ -135,7 +155,6 @@ public: virtual ::sal_Bool SAL_CALL hasProperty( const ::rtl::OUString& aName ) throw (css::uno::RuntimeException); // CodeName virtual rtl::OUString SAL_CALL getCodeName() throw (css::uno::RuntimeException); - virtual void SAL_CALL setCodeName( const rtl::OUString& sCodeName ) throw (css::uno::RuntimeException); sal_Int16 getSheetID() throw (css::uno::RuntimeException); virtual void SAL_CALL PrintOut( const css::uno::Any& From, const css::uno::Any& To, const css::uno::Any& Copies, const css::uno::Any& Preview, const css::uno::Any& ActivePrinter, const css::uno::Any& PrintToFile, const css::uno::Any& Collate, const css::uno::Any& PrToFileName, const css::uno::Any& IgnorePrintAreas ) throw (css::uno::RuntimeException); diff --git a/sc/source/ui/vba/vbaworksheets.cxx b/sc/source/ui/vba/vbaworksheets.cxx index e7de0b82fcaa..60cf7b904026 100644 --- a/sc/source/ui/vba/vbaworksheets.cxx +++ b/sc/source/ui/vba/vbaworksheets.cxx @@ -435,3 +435,24 @@ ScVbaWorksheets::getServiceNames() } return sNames; } + +/*static*/ bool ScVbaWorksheets::nameExists( uno::Reference <sheet::XSpreadsheetDocument>& xSpreadDoc, const ::rtl::OUString & name, SCTAB& nTab ) throw ( lang::IllegalArgumentException ) +{ + if (!xSpreadDoc.is()) + throw lang::IllegalArgumentException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "nameExists() xSpreadDoc is null" ) ), uno::Reference< uno::XInterface >(), 1 ); + uno::Reference <container::XIndexAccess> xIndex( xSpreadDoc->getSheets(), uno::UNO_QUERY ); + if ( xIndex.is() ) + { + SCTAB nCount = static_cast< SCTAB >( xIndex->getCount() ); + for (SCTAB i=0; i < nCount; i++) + { + uno::Reference< container::XNamed > xNamed( xIndex->getByIndex(i), uno::UNO_QUERY_THROW ); + if (xNamed->getName() == name) + { + nTab = i; + return true; + } + } + } + return false; +} diff --git a/sc/source/ui/vba/vbaworksheets.hxx b/sc/source/ui/vba/vbaworksheets.hxx index 4c8120084b02..2ced68bc9e27 100644 --- a/sc/source/ui/vba/vbaworksheets.hxx +++ b/sc/source/ui/vba/vbaworksheets.hxx @@ -31,11 +31,14 @@ #include <ooo/vba/excel/XWorksheets.hpp> #include <com/sun/star/sheet/XSpreadsheets.hpp> +#include <com/sun/star/sheet/XSpreadsheetDocument.hpp> #include <com/sun/star/container/XEnumerationAccess.hpp> #include <com/sun/star/uno/XComponentContext.hpp> #include <vbahelper/vbacollectionimpl.hxx> +#include "address.hxx" + class ScModelObj; @@ -74,6 +77,7 @@ public: virtual rtl::OUString& getServiceImplName(); virtual css::uno::Sequence<rtl::OUString> getServiceNames(); + static bool nameExists( css::uno::Reference <css::sheet::XSpreadsheetDocument>& xSpreadDoc, const ::rtl::OUString & name, SCTAB& nTab ) throw ( css::lang::IllegalArgumentException ); }; #endif /* SC_VBA_WORKSHEETS_HXX */ diff --git a/sc/source/ui/vba/vbawsfunction.cxx b/sc/source/ui/vba/vbawsfunction.cxx index c355244f6815..60daa7303f2e 100644 --- a/sc/source/ui/vba/vbawsfunction.cxx +++ b/sc/source/ui/vba/vbawsfunction.cxx @@ -31,6 +31,7 @@ #include <com/sun/star/beans/XIntrospectionAccess.hpp> #include <com/sun/star/sheet/XFunctionAccess.hpp> #include <com/sun/star/sheet/XCellRangesQuery.hpp> +#include <com/sun/star/sheet/XCellRangeAddressable.hpp> #include <com/sun/star/sheet/CellFlags.hpp> #include <com/sun/star/reflection/XIdlMethod.hpp> #include <com/sun/star/beans/MethodConcept.hpp> @@ -44,10 +45,27 @@ using namespace com::sun::star; using namespace ooo::vba; -ScVbaWSFunction::ScVbaWSFunction( const uno::Reference< XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext): ScVbaWSFunction_BASE( xParent, xContext ) +namespace { + +void lclConvertDoubleToBoolean( uno::Any& rAny ) { + if( rAny.has< double >() ) + { + double fValue = rAny.get< double >(); + if( fValue == 0.0 ) + rAny <<= false; + else if( fValue == 1.0 ) + rAny <<= true; + // do nothing for other values or types + } } +} // namespace + +ScVbaWSFunction::ScVbaWSFunction( const uno::Reference< XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext ) : + ScVbaWSFunction_BASE( xParent, xContext ) +{ +} uno::Reference< beans::XIntrospectionAccess > ScVbaWSFunction::getIntrospection(void) throw(uno::RuntimeException) @@ -58,33 +76,101 @@ ScVbaWSFunction::getIntrospection(void) throw(uno::RuntimeException) uno::Any SAL_CALL ScVbaWSFunction::invoke(const rtl::OUString& FunctionName, const uno::Sequence< uno::Any >& Params, uno::Sequence< sal_Int16 >& /*OutParamIndex*/, uno::Sequence< uno::Any >& /*OutParam*/) throw(lang::IllegalArgumentException, script::CannotConvertException, reflection::InvocationTargetException, uno::RuntimeException) { - uno::Reference< lang::XMultiComponentFactory > xSMgr( mxContext->getServiceManager(), uno::UNO_QUERY_THROW ); - uno::Reference< sheet::XFunctionAccess > xFunctionAccess( - xSMgr->createInstanceWithContext(::rtl::OUString::createFromAscii( - "com.sun.star.sheet.FunctionAccess"), mxContext), - ::uno::UNO_QUERY_THROW); - uno::Sequence< uno::Any > aParamTemp; - sal_Int32 nParamCount = Params.getLength(); - aParamTemp.realloc(nParamCount); - const uno::Any* aArray = Params.getConstArray(); - uno::Any* aArrayTemp = aParamTemp.getArray(); - - for (int i=0; i < Params.getLength();i++) + // create copy of parameters, replace Excel range objects with UNO range objects + uno::Sequence< uno::Any > aParamTemp( Params ); + if( aParamTemp.hasElements() ) + { + uno::Any* pArray = aParamTemp.getArray(); + uno::Any* pArrayEnd = pArray + aParamTemp.getLength(); + for( ; pArray < pArrayEnd; ++pArray ) + { + uno::Reference< excel::XRange > myRange( *pArray, uno::UNO_QUERY ); + if( myRange.is() ) + *pArray = myRange->getCellRange(); + OSL_TRACE("Param[%d] is %s", (int)(pArray - aParamTemp.getConstArray()), rtl::OUStringToOString( comphelper::anyToString( *pArray ), RTL_TEXTENCODING_UTF8 ).getStr() ); + } + } + + uno::Any aRet; + bool bAsArray = true; + + // special handing for some functions that don't work correctly in FunctionAccess + ScCompiler aCompiler( 0, ScAddress() ); + OpCode eOpCode = aCompiler.GetEnglishOpCode( FunctionName.toAsciiUpperCase() ); + switch( eOpCode ) { - uno::Reference<excel::XRange> myRange( aArray[ i ], uno::UNO_QUERY ); - if ( myRange.is() ) + // ISLOGICAL does not work in array formula mode + case ocIsLogical: { - aArrayTemp[i] = myRange->getCellRange(); - continue; + if( aParamTemp.getLength() != 1 ) + throw lang::IllegalArgumentException(); + const uno::Any& rParam = aParamTemp[ 0 ]; + if( rParam.has< bool >() ) + { + aRet <<= true; + } + else if( rParam.has< uno::Reference< table::XCellRange > >() ) try + { + uno::Reference< sheet::XCellRangeAddressable > xRangeAddr( rParam, uno::UNO_QUERY_THROW ); + table::CellRangeAddress aRangeAddr = xRangeAddr->getRangeAddress(); + bAsArray = (aRangeAddr.StartColumn != aRangeAddr.EndColumn) || (aRangeAddr.StartRow != aRangeAddr.EndRow); + } + catch( uno::Exception& ) + { + } } - aArrayTemp[i]= aArray[i]; + break; + default:; } - for ( int count=0; count < aParamTemp.getLength(); ++count ) - OSL_TRACE("Param[%d] is %s", - count, rtl::OUStringToOString( comphelper::anyToString( aParamTemp[count] ), RTL_TEXTENCODING_UTF8 ).getStr() ); + if( !aRet.hasValue() ) + { + uno::Reference< lang::XMultiComponentFactory > xSMgr( mxContext->getServiceManager(), uno::UNO_QUERY_THROW ); + uno::Reference< sheet::XFunctionAccess > xFunctionAccess( xSMgr->createInstanceWithContext( + ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sheet.FunctionAccess" ) ), mxContext ), + uno::UNO_QUERY_THROW ); + uno::Reference< beans::XPropertySet > xPropSet( xFunctionAccess, uno::UNO_QUERY_THROW ); + xPropSet->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsArrayFunction" ) ), uno::Any( bAsArray ) ); + aRet = xFunctionAccess->callFunction( FunctionName, aParamTemp ); + } - uno::Any aRet = xFunctionAccess->callFunction(FunctionName,aParamTemp); + /* Convert return value from double to to Boolean for some functions that + return Booleans. */ + typedef uno::Sequence< uno::Sequence< uno::Any > > AnySeqSeq; + if( (eOpCode == ocIsEmpty) || (eOpCode == ocIsString) || (eOpCode == ocIsNonString) || (eOpCode == ocIsLogical) || + (eOpCode == ocIsRef) || (eOpCode == ocIsValue) || (eOpCode == ocIsFormula) || (eOpCode == ocIsNA) || + (eOpCode == ocIsErr) || (eOpCode == ocIsError) || (eOpCode == ocIsEven) || (eOpCode == ocIsOdd) || + (eOpCode == ocAnd) || (eOpCode == ocOr) || (eOpCode == ocNot) || (eOpCode == ocTrue) || (eOpCode == ocFalse) ) + { + if( aRet.has< AnySeqSeq >() ) + { + AnySeqSeq aAnySeqSeq = aRet.get< AnySeqSeq >(); + for( sal_Int32 nRow = 0; nRow < aAnySeqSeq.getLength(); ++nRow ) + for( sal_Int32 nCol = 0; nCol < aAnySeqSeq[ nRow ].getLength(); ++nCol ) + lclConvertDoubleToBoolean( aAnySeqSeq[ nRow ][ nCol ] ); + aRet <<= aAnySeqSeq; + } + else + { + lclConvertDoubleToBoolean( aRet ); + } + } + + /* Hack/workaround (?): shorten single-row matrix to simple array, shorten + 1x1 matrix to single value. */ + if( aRet.has< AnySeqSeq >() ) + { + AnySeqSeq aAnySeqSeq = aRet.get< AnySeqSeq >(); + if( aAnySeqSeq.getLength() == 1 ) + { + if( aAnySeqSeq[ 0 ].getLength() == 1 ) + aRet = aAnySeqSeq[ 0 ][ 0 ]; + else + aRet <<= aAnySeqSeq[ 0 ]; + } + } + +#if 0 // MATCH function should alwayse return a double value, but currently if the first argument is XCellRange, MATCH function returns an array instead of a double value. Don't know why? // To fix this issue in safe, current solution is to convert this array to a double value just for MATCH function. String aUpper( FunctionName ); @@ -101,6 +187,8 @@ ScVbaWSFunction::invoke(const rtl::OUString& FunctionName, const uno::Sequence< throw uno::RuntimeException(); aRet <<= fVal; } +#endif + return aRet; } @@ -122,7 +210,7 @@ ScVbaWSFunction::hasMethod(const rtl::OUString& Name) throw(uno::RuntimeExcepti sal_Bool bIsFound = sal_False; try { - // the function name contained in the com.sun.star.sheet.FunctionDescription service is alwayse localized. + // the function name contained in the com.sun.star.sheet.FunctionDescription service is alwayse localized. // but the function name used in WorksheetFunction is a programmatic name (seems English). // So m_xNameAccess->hasByName( Name ) may fail to find name when a function name has a localized name. ScCompiler aCompiler( NULL, ScAddress() ); diff --git a/sc/source/ui/vba/vbawsfunction.hxx b/sc/source/ui/vba/vbawsfunction.hxx index 58a895f6d47b..ffd33849afe5 100644 --- a/sc/source/ui/vba/vbawsfunction.hxx +++ b/sc/source/ui/vba/vbawsfunction.hxx @@ -52,7 +52,6 @@ public: // XHelperInterface virtual rtl::OUString& getServiceImplName(); virtual css::uno::Sequence<rtl::OUString> getServiceNames(); - }; #endif diff --git a/sc/source/ui/view/cellsh.cxx b/sc/source/ui/view/cellsh.cxx index a461c54f255e..c880a29f8067 100644 --- a/sc/source/ui/view/cellsh.cxx +++ b/sc/source/ui/view/cellsh.cxx @@ -715,22 +715,22 @@ void ScCellShell::GetState(SfxItemSet &rSet) break; case FID_INS_ROWBRK: - if ( nPosY==0 || (pDoc->GetRowFlags(nPosY,nTab) & CR_MANUALBREAK) ) + if ( nPosY==0 || (pDoc->HasRowBreak(nPosY, nTab) & BREAK_MANUAL) ) rSet.DisableItem( nWhich ); break; case FID_INS_COLBRK: - if ( nPosX==0 || (pDoc->GetColFlags(nPosX,nTab) & CR_MANUALBREAK) ) + if ( nPosX==0 || (pDoc->HasColBreak(nPosX, nTab) & BREAK_MANUAL) ) rSet.DisableItem( nWhich ); break; case FID_DEL_ROWBRK: - if ( nPosY==0 || (pDoc->GetRowFlags(nPosY,nTab) & CR_MANUALBREAK)==0 ) + if ( nPosY==0 || (pDoc->HasRowBreak(nPosY, nTab) & BREAK_MANUAL) == 0 ) rSet.DisableItem( nWhich ); break; case FID_DEL_COLBRK: - if ( nPosX==0 || (pDoc->GetColFlags(nPosX,nTab) & CR_MANUALBREAK)==0 ) + if ( nPosX==0 || (pDoc->HasColBreak(nPosX, nTab) & BREAK_MANUAL) == 0 ) rSet.DisableItem( nWhich ); break; diff --git a/sc/source/ui/view/colrowba.cxx b/sc/source/ui/view/colrowba.cxx index 8916624fdb52..d802c08f642f 100644 --- a/sc/source/ui/view/colrowba.cxx +++ b/sc/source/ui/view/colrowba.cxx @@ -98,7 +98,8 @@ USHORT ScColBar::GetEntrySize( SCCOLROW nEntryNo ) { ScDocument* pDoc = pViewData->GetDocument(); SCTAB nTab = pViewData->GetTabNo(); - if ( pDoc->GetColFlags( static_cast<SCCOL>(nEntryNo), nTab ) & CR_HIDDEN ) + SCCOL nLastCol = -1; + if (pDoc->ColHidden(static_cast<SCCOL>(nEntryNo), nTab, nLastCol)) return 0; else return (USHORT) ScViewData::ToPixel( pDoc->GetColWidth( static_cast<SCCOL>(nEntryNo), nTab ), pViewData->GetPPTX() ); @@ -265,7 +266,8 @@ USHORT ScRowBar::GetEntrySize( SCCOLROW nEntryNo ) { ScDocument* pDoc = pViewData->GetDocument(); SCTAB nTab = pViewData->GetTabNo(); - if ( pDoc->GetRowFlags( nEntryNo, nTab ) & CR_HIDDEN ) + SCROW nLastRow = -1; + if (pDoc->RowHidden(nEntryNo, nTab, nLastRow)) return 0; else return (USHORT) ScViewData::ToPixel( pDoc->GetOriginalHeight( nEntryNo, diff --git a/sc/source/ui/view/dbfunc3.cxx b/sc/source/ui/view/dbfunc3.cxx index 406fdab9c824..dbdeae1ae0b1 100755 --- a/sc/source/ui/view/dbfunc3.cxx +++ b/sc/source/ui/view/dbfunc3.cxx @@ -694,6 +694,9 @@ ULONG RefreshDPObject( ScDPObject *pDPObj, ScDocument *pDoc, ScDocShell *pDocSh, if( !pDPObj ) return STR_PIVOT_NOTFOUND; + if ( pDocSh && !pDoc ) + pDoc = pDocSh->GetDocument(); + if( !pDoc ) return static_cast<ULONG>(-1); @@ -1739,6 +1742,18 @@ void lcl_MoveToEnd( ScDPSaveDimension& rDim, const String& rItemName ) // puts it to the end of the list even if it was in the list before. } +struct ScOUStringCollate +{ + CollatorWrapper* mpCollator; + + ScOUStringCollate(CollatorWrapper* pColl) : mpCollator(pColl) {} + + bool operator()(const rtl::OUString& rStr1, const rtl::OUString& rStr2) const + { + return ( mpCollator->compareString(rStr1, rStr2) < 0 ); + } +}; + bool ScDBFunc::DataPilotSort( const ScAddress& rPos, bool bAscending, sal_uInt16* pUserListId ) { ScDocument* pDoc = GetViewData()->GetDocument(); @@ -1747,7 +1762,8 @@ bool ScDBFunc::DataPilotSort( const ScAddress& rPos, bool bAscending, sal_uInt16 return false; // We need to run this to get all members later. - pDPObj->BuildAllDimensionMembers(); + if ( pUserListId ) + pDPObj->BuildAllDimensionMembers(); USHORT nOrientation; long nDimIndex = pDPObj->GetHeaderDim(rPos, nOrientation); @@ -1766,97 +1782,111 @@ bool ScDBFunc::DataPilotSort( const ScAddress& rPos, bool bAscending, sal_uInt16 if (!pSaveDim) return false; - typedef ScDPSaveDimension::MemberList MemList; - const MemList& rDimMembers = pSaveDim->GetMembers(); - list<OUString> aMembers; - hash_set<OUString, ::rtl::OUStringHash> aMemberSet; - size_t nMemberCount = 0; - for (MemList::const_iterator itr = rDimMembers.begin(), itrEnd = rDimMembers.end(); - itr != itrEnd; ++itr) + // manual evaluation of sort order is only needed if a user list id is given + if ( pUserListId ) { - ScDPSaveMember* pMem = *itr; - aMembers.push_back(pMem->GetName()); - aMemberSet.insert(pMem->GetName()); - ++nMemberCount; - } - - // Sort the member list in ascending order. - aMembers.sort(); + typedef ScDPSaveDimension::MemberList MemList; + const MemList& rDimMembers = pSaveDim->GetMembers(); + list<OUString> aMembers; + hash_set<OUString, ::rtl::OUStringHash> aMemberSet; + size_t nMemberCount = 0; + for (MemList::const_iterator itr = rDimMembers.begin(), itrEnd = rDimMembers.end(); + itr != itrEnd; ++itr) + { + ScDPSaveMember* pMem = *itr; + aMembers.push_back(pMem->GetName()); + aMemberSet.insert(pMem->GetName()); + ++nMemberCount; + } - // Collect and rank those custom sort strings that also exist in the member name list. + // Sort the member list in ascending order. + ScOUStringCollate aCollate( ScGlobal::GetCollator() ); + aMembers.sort(aCollate); - typedef hash_map<OUString, sal_uInt16, OUStringHash> UserSortMap; - UserSortMap aSubStrs; - sal_uInt16 nSubCount = 0; - if (pUserListId) - { - ScUserList* pUserList = ScGlobal::GetUserList(); - if (!pUserList) - return false; + // Collect and rank those custom sort strings that also exist in the member name list. + typedef hash_map<OUString, sal_uInt16, OUStringHash> UserSortMap; + UserSortMap aSubStrs; + sal_uInt16 nSubCount = 0; + if (pUserListId) { - sal_uInt16 n = pUserList->GetCount(); - if (!n || *pUserListId >= n) + ScUserList* pUserList = ScGlobal::GetUserList(); + if (!pUserList) return false; - } - ScUserListData* pData = static_cast<ScUserListData*>((*pUserList)[*pUserListId]); - if (pData) - { - sal_uInt16 n = pData->GetSubCount(); - for (sal_uInt16 i = 0; i < n; ++i) { - OUString aSub = pData->GetSubStr(i); - if (!aMemberSet.count(aSub)) - // This string doesn't exist in the member name set. Don't add this. - continue; + sal_uInt16 n = pUserList->GetCount(); + if (!n || *pUserListId >= n) + return false; + } + + ScUserListData* pData = static_cast<ScUserListData*>((*pUserList)[*pUserListId]); + if (pData) + { + sal_uInt16 n = pData->GetSubCount(); + for (sal_uInt16 i = 0; i < n; ++i) + { + OUString aSub = pData->GetSubStr(i); + if (!aMemberSet.count(aSub)) + // This string doesn't exist in the member name set. Don't add this. + continue; - aSubStrs.insert(UserSortMap::value_type(aSub, nSubCount++)); + aSubStrs.insert(UserSortMap::value_type(aSub, nSubCount++)); + } } } - } - // Rank all members. + // Rank all members. - vector<OUString> aRankedNames(nMemberCount); - sal_uInt16 nCurStrId = 0; - for (list<OUString>::const_iterator itr = aMembers.begin(), itrEnd = aMembers.end(); - itr != itrEnd; ++itr) - { - OUString aName = *itr; - sal_uInt16 nRank = 0; - UserSortMap::const_iterator itrSub = aSubStrs.find(aName); - if (itrSub == aSubStrs.end()) - nRank = nSubCount + nCurStrId++; - else - nRank = itrSub->second; + vector<OUString> aRankedNames(nMemberCount); + sal_uInt16 nCurStrId = 0; + for (list<OUString>::const_iterator itr = aMembers.begin(), itrEnd = aMembers.end(); + itr != itrEnd; ++itr) + { + OUString aName = *itr; + sal_uInt16 nRank = 0; + UserSortMap::const_iterator itrSub = aSubStrs.find(aName); + if (itrSub == aSubStrs.end()) + nRank = nSubCount + nCurStrId++; + else + nRank = itrSub->second; - if (!bAscending) - nRank = static_cast< sal_uInt16 >( nMemberCount - nRank - 1 ); + if (!bAscending) + nRank = static_cast< sal_uInt16 >( nMemberCount - nRank - 1 ); - aRankedNames[nRank] = aName; - } + aRankedNames[nRank] = aName; + } - // Re-order ScDPSaveMember instances with the new ranks. + // Re-order ScDPSaveMember instances with the new ranks. - for (vector<OUString>::const_iterator itr = aRankedNames.begin(), itrEnd = aRankedNames.end(); - itr != itrEnd; ++itr) - { - const ScDPSaveMember* pOldMem = pSaveDim->GetExistingMemberByName(*itr); - if (!pOldMem) - // All members are supposed to be present. - continue; + for (vector<OUString>::const_iterator itr = aRankedNames.begin(), itrEnd = aRankedNames.end(); + itr != itrEnd; ++itr) + { + const ScDPSaveMember* pOldMem = pSaveDim->GetExistingMemberByName(*itr); + if (!pOldMem) + // All members are supposed to be present. + continue; - ScDPSaveMember* pNewMem = new ScDPSaveMember(*pOldMem); - pSaveDim->AddMember(pNewMem); - } + ScDPSaveMember* pNewMem = new ScDPSaveMember(*pOldMem); + pSaveDim->AddMember(pNewMem); + } - // Set the sorting mode to manual for now. We may introduce a new sorting - // mode later on. + // Set the sorting mode to manual for now. We may introduce a new sorting + // mode later on. - sheet::DataPilotFieldSortInfo aSortInfo; - aSortInfo.Mode = sheet::DataPilotFieldSortMode::MANUAL; - pSaveDim->SetSortInfo(&aSortInfo); + sheet::DataPilotFieldSortInfo aSortInfo; + aSortInfo.Mode = sheet::DataPilotFieldSortMode::MANUAL; + pSaveDim->SetSortInfo(&aSortInfo); + } + else + { + // without user list id, just apply sorting mode + + sheet::DataPilotFieldSortInfo aSortInfo; + aSortInfo.Mode = sheet::DataPilotFieldSortMode::NAME; + aSortInfo.IsAscending = bAscending; + pSaveDim->SetSortInfo(&aSortInfo); + } // Update the datapilot with the newly sorted field members. diff --git a/sc/source/ui/view/drawutil.cxx b/sc/source/ui/view/drawutil.cxx index 3885b0adc752..ba250767c169 100644 --- a/sc/source/ui/view/drawutil.cxx +++ b/sc/source/ui/view/drawutil.cxx @@ -66,14 +66,19 @@ void ScDrawUtil::CalcScale( ScDocument* pDoc, SCTAB nTab, nTwipsX += (long) nWidth; nPixelX += ScViewData::ToPixel( nWidth, nPPTX ); } - ScCoupledCompressedArrayIterator< SCROW, BYTE, USHORT> aIter( - pDoc->GetRowFlagsArray( nTab), nStartRow, nEndRow-1, CR_HIDDEN, 0, - pDoc->GetRowHeightArray( nTab)); - for ( ; aIter; ++aIter ) + + for (SCROW nRow = nStartRow; nRow <= nEndRow-1; ++nRow) { - USHORT nHeight = *aIter; - nTwipsY += (long) nHeight; - nPixelY += ScViewData::ToPixel( nHeight, nPPTY ); + SCROW nLastRow = nRow; + if (pDoc->RowHidden(nRow, nTab, NULL, &nLastRow)) + { + nRow = nLastRow; + continue; + } + + USHORT nHeight = pDoc->GetRowHeight(nRow, nTab); + nTwipsY += static_cast<long>(nHeight); + nPixelY += ScViewData::ToPixel(nHeight, nPPTY); } MapMode aHMMMode( MAP_100TH_MM, Point(), rZoomX, rZoomY ); @@ -100,10 +105,10 @@ void ScDrawUtil::CalcScale( ScDocument* pDoc, SCTAB nTab, else rScaleY = Fraction( 1, 1 ); - // 17 bits of accuracy are needed to always hit the right part of - // cells in the last rows - rScaleX.ReduceInaccurate( 17 ); - rScaleY.ReduceInaccurate( 17 ); + // 25 bits of accuracy are needed to always hit the right part of + // cells in the last rows (was 17 before 1M rows). + rScaleX.ReduceInaccurate( 25 ); + rScaleY.ReduceInaccurate( 25 ); } diff --git a/sc/source/ui/view/drawvie4.cxx b/sc/source/ui/view/drawvie4.cxx index 8b9debdabfae..3a28096d2853 100644 --- a/sc/source/ui/view/drawvie4.cxx +++ b/sc/source/ui/view/drawvie4.cxx @@ -282,8 +282,8 @@ void ScDrawView::CalcNormScale( Fraction& rFractX, Fraction& rFractY ) const pDoc->GetTableArea( nTab, nEndCol, nEndRow ); if (nEndCol<20) nEndCol = 20; - if (nEndRow<20) - nEndRow = 20; + if (nEndRow<1000) + nEndRow = 1000; Fraction aZoom(1,1); ScDrawUtil::CalcScale( pDoc, nTab, 0,0, nEndCol,nEndRow, pDev, aZoom,aZoom, diff --git a/sc/source/ui/view/drawview.cxx b/sc/source/ui/view/drawview.cxx index 311bcf8c24b2..1d2b797b3a9b 100644 --- a/sc/source/ui/view/drawview.cxx +++ b/sc/source/ui/view/drawview.cxx @@ -187,7 +187,7 @@ void ScDrawView::AddCustomHdl() if(nCol > 0) --nCol; - SCROW nRow = nPosY <= 0 ? 0 : pDoc->FastGetRowForHeight( nTab, + SCROW nRow = nPosY <= 0 ? 0 : pDoc->GetRowForHeight( nTab, (ULONG) nPosY); if(nRow > 0) --nRow; @@ -376,8 +376,8 @@ void ScDrawView::RecalcScale() pDoc->GetTableArea( nTab, nEndCol, nEndRow ); if (nEndCol<20) nEndCol = 20; - if (nEndRow<20) - nEndRow = 20; + if (nEndRow<1000) + nEndRow = 1000; ScDrawUtil::CalcScale( pDoc, nTab, 0,0, nEndCol,nEndRow, pDev,aZoomX,aZoomY,nPPTX,nPPTY, aScaleX,aScaleY ); @@ -397,13 +397,13 @@ void ScDrawView::MarkListHasChanged() ScTabViewShell* pViewSh = pViewData->GetViewShell(); - if (!bInConstruct) // nicht wenn die View gerade angelegt wird + // #i110829# remove the cell selection only if drawing objects are selected + if ( !bInConstruct && GetMarkedObjectList().GetMarkCount() ) { - pViewSh->Unmark(); // Selektion auff'm Doc entfernen + pViewSh->Unmark(); // remove cell selection // #65379# end cell edit mode if drawing objects are selected - if ( GetMarkedObjectList().GetMarkCount() ) - SC_MOD()->InputEnterHandler(); + SC_MOD()->InputEnterHandler(); } // IP deaktivieren 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/gridwin.cxx b/sc/source/ui/view/gridwin.cxx index 87740a88e4df..db72d87f30a2 100644 --- a/sc/source/ui/view/gridwin.cxx +++ b/sc/source/ui/view/gridwin.cxx @@ -153,7 +153,19 @@ extern USHORT nScFillModeMouseModifier; // global.cxx #define SC_FILTERLISTBOX_LINES 12 -//================================================================== +// ============================================================================ + +ScGridWindow::VisibleRange::VisibleRange() : + mnCol1(0), mnCol2(MAXCOL), mnRow1(0), mnRow2(MAXROW) +{ +} + +bool ScGridWindow::VisibleRange::isInside(SCCOL nCol, SCROW nRow) const +{ + return mnCol1 <= nCol && nCol <= mnCol2 && mnRow1 <= nRow && nRow <= mnRow2; +} + +// ============================================================================ class ScFilterListBox : public ListBox { @@ -366,6 +378,7 @@ ScGridWindow::ScGridWindow( Window* pParent, ScViewData* pData, ScSplitPos eWhic mpOODragRect( NULL ), mpOOHeader( NULL ), mpOOShrink( NULL ), + mpAutoFillRect(static_cast<Rectangle*>(NULL)), pViewData( pData ), eWhich( eWhichPos ), pNoteMarker( NULL ), @@ -1323,37 +1336,23 @@ BOOL ScGridWindow::TestMouse( const MouseEvent& rMEvt, BOOL bAction ) ScDocument* pDoc = pViewData->GetDocument(); SCTAB nTab = pViewData->GetTabNo(); BOOL bLayoutRTL = pDoc->IsLayoutRTL( nTab ); - long nLayoutSign = bLayoutRTL ? -1 : 1; // Auto-Fill ScRange aMarkRange; if (pViewData->GetSimpleArea( aMarkRange ) == SC_MARK_SIMPLE) { - if ( aMarkRange.aStart.Tab() == pViewData->GetTabNo() ) + if (aMarkRange.aStart.Tab() == pViewData->GetTabNo() && mpAutoFillRect) { - // Block-Ende wie in DrawAutoFillMark - SCCOL nX = aMarkRange.aEnd.Col(); - SCROW nY = aMarkRange.aEnd.Row(); - - Point aFillPos = pViewData->GetScrPos( nX, nY, eWhich, TRUE ); - long nSizeXPix; - long nSizeYPix; - pViewData->GetMergeSizePixel( nX, nY, nSizeXPix, nSizeYPix ); - aFillPos.X() += nSizeXPix * nLayoutSign; - aFillPos.Y() += nSizeYPix; - if ( bLayoutRTL ) - aFillPos.X() -= 1; - Point aMousePos = rMEvt.GetPosPixel(); - // Abfrage hier passend zu DrawAutoFillMark - // (ein Pixel mehr als markiert) - if ( aMousePos.X() >= aFillPos.X()-3 && aMousePos.X() <= aFillPos.X()+4 && - aMousePos.Y() >= aFillPos.Y()-3 && aMousePos.Y() <= aFillPos.Y()+4 ) + if (mpAutoFillRect->IsInside(aMousePos)) { SetPointer( Pointer( POINTER_CROSS ) ); //! dickeres Kreuz ? if (bAction) { + SCCOL nX = aMarkRange.aEnd.Col(); + SCROW nY = aMarkRange.aEnd.Row(); + if ( lcl_IsEditableMatrix( pViewData->GetDocument(), aMarkRange ) ) pViewData->SetDragMode( aMarkRange.aStart.Col(), aMarkRange.aStart.Row(), nX, nY, SC_FILL_MATRIX ); @@ -2405,6 +2404,7 @@ void lcl_InitMouseEvent( ::com::sun::star::awt::MouseEvent& rEvent, const MouseE long ScGridWindow::PreNotify( NotifyEvent& rNEvt ) { + bool bDone = false; USHORT nType = rNEvt.GetType(); if ( nType == EVENT_MOUSEBUTTONUP || nType == EVENT_MOUSEBUTTONDOWN ) { @@ -2425,16 +2425,31 @@ long ScGridWindow::PreNotify( NotifyEvent& rNEvt ) if ( rNEvt.GetWindow() ) aEvent.Source = rNEvt.GetWindow()->GetComponentInterface(); if ( nType == EVENT_MOUSEBUTTONDOWN) - pImp->MousePressed( aEvent ); + bDone = pImp->MousePressed( aEvent ); else - pImp->MouseReleased( aEvent ); + bDone = pImp->MouseReleased( aEvent ); } } } } } + if (bDone) // event consumed by a listener + { + if ( nType == EVENT_MOUSEBUTTONDOWN ) + { + const MouseEvent* pMouseEvent = rNEvt.GetMouseEvent(); + if ( pMouseEvent->IsRight() && pMouseEvent->GetClicks() == 1 ) + { + // If a listener returned true for a right-click call, also prevent opening the context menu + // (this works only if the context menu is opened on mouse-down) + nMouseStatus = SC_GM_IGNORE; + } + } - return Window::PreNotify( rNEvt ); + return 1; + } + else + return Window::PreNotify( rNEvt ); } void ScGridWindow::Tracking( const TrackingEvent& rTEvt ) @@ -2678,6 +2693,10 @@ void __EXPORT ScGridWindow::Command( const CommandEvent& rCEvt ) if ( nCmd == COMMAND_CONTEXTMENU && !SC_MOD()->GetIsWaterCan() ) { + BOOL bMouse = rCEvt.IsMouseEvent(); + if ( bMouse && nMouseStatus == SC_GM_IGNORE ) + return; + if (pViewData->IsAnyFillMode()) { pViewData->GetView()->StopRefMode(); @@ -2688,7 +2707,6 @@ void __EXPORT ScGridWindow::Command( const CommandEvent& rCEvt ) Point aPosPixel = rCEvt.GetMousePosPixel(); Point aMenuPos = aPosPixel; - BOOL bMouse = rCEvt.IsMouseEvent(); if ( bMouse ) { @@ -2934,7 +2952,7 @@ void ScGridWindow::SelectForContextMenu( const Point& rPosPixel, SCsCOL nCellX, // clicked on selected object -> don't change anything bHitSelected = TRUE; } - else if ( pViewData->GetMarkData().IsCellMarked( (USHORT) nCellX, (USHORT) nCellY ) ) + else if ( pViewData->GetMarkData().IsCellMarked(nCellX, nCellY) ) { // clicked on selected cell -> don't change anything bHitSelected = TRUE; @@ -2958,7 +2976,7 @@ void ScGridWindow::SelectForContextMenu( const Point& rPosPixel, SCsCOL nCellX, if ( !bHitDraw ) { pView->Unmark(); - pView->SetCursor( (USHORT) nCellX, (USHORT) nCellY ); + pView->SetCursor(nCellX, nCellY); if ( bWasDraw ) pViewData->GetViewShell()->SetDrawShell( FALSE ); // switch shells } @@ -4533,18 +4551,17 @@ void lcl_PaintOneRange( ScDocShell* pDocSh, const ScRange& rRange, USHORT nEdges SCROW nTmp; ScDocument* pDoc = pDocSh->GetDocument(); - while ( nCol1 > 0 && ( pDoc->GetColFlags( nCol1, nTab1 ) & CR_HIDDEN ) ) + while ( nCol1 > 0 && pDoc->ColHidden(nCol1, nTab1) ) { --nCol1; bHiddenEdge = TRUE; } - while ( nCol2 < MAXCOL && ( pDoc->GetColFlags( nCol2, nTab1 ) & CR_HIDDEN ) ) + while ( nCol2 < MAXCOL && pDoc->ColHidden(nCol2, nTab1) ) { ++nCol2; bHiddenEdge = TRUE; } - nTmp = pDoc->GetRowFlagsArray( nTab1).GetLastForCondition( 0, nRow1, - CR_HIDDEN, 0); + nTmp = pDoc->FirstVisibleRow(0, nRow1, nTab1); if (!ValidRow(nTmp)) nTmp = 0; if (nTmp < nRow1) @@ -4552,8 +4569,7 @@ void lcl_PaintOneRange( ScDocShell* pDocSh, const ScRange& rRange, USHORT nEdges nRow1 = nTmp; bHiddenEdge = TRUE; } - nTmp = pDoc->GetRowFlagsArray( nTab1).GetFirstForCondition( nRow2, MAXROW, - CR_HIDDEN, 0); + nTmp = pDoc->FirstVisibleRow(nRow2, MAXROW, nTab1); if (!ValidRow(nTmp)) nTmp = MAXROW; if (nTmp > nRow2) @@ -5123,6 +5139,9 @@ void ScGridWindow::UpdateCursorOverlay() SCCOL nX = pViewData->GetCurX(); SCROW nY = pViewData->GetCurY(); + if (!maVisibleRange.isInside(nX, nY)) + return; + // don't show the cursor in overlapped cells ScDocument* pDoc = pViewData->GetDocument(); @@ -5298,6 +5317,7 @@ void ScGridWindow::UpdateSelectionOverlay() void ScGridWindow::DeleteAutoFillOverlay() { DELETEZ( mpOOAutoFill ); + mpAutoFillRect.reset(); } void ScGridWindow::UpdateAutoFillOverlay() @@ -5318,6 +5338,11 @@ void ScGridWindow::UpdateAutoFillOverlay() { SCCOL nX = aAutoMarkPos.Col(); SCROW nY = aAutoMarkPos.Row(); + + if (!maVisibleRange.isInside(nX, nY)) + // Autofill mark is not visible. Bail out. + return; + SCTAB nTab = pViewData->GetTabNo(); ScDocument* pDoc = pViewData->GetDocument(); BOOL bLayoutRTL = pDoc->IsLayoutRTL( nTab ); @@ -5333,7 +5358,7 @@ void ScGridWindow::UpdateAutoFillOverlay() aFillPos.Y() += nSizeYPix; aFillPos.Y() -= 2; - Rectangle aFillRect( aFillPos, Size(6,6) ); + mpAutoFillRect.reset(new Rectangle(aFillPos, Size(6, 6))); // #i70788# get the OverlayManager safely ::sdr::overlay::OverlayManager* pOverlayManager = getOverlayManager(); @@ -5343,7 +5368,7 @@ void ScGridWindow::UpdateAutoFillOverlay() const Color aHandleColor( SC_MOD()->GetColorConfig().GetColorValue(svtools::FONTCOLOR).nColor ); std::vector< basegfx::B2DRange > aRanges; const basegfx::B2DHomMatrix aTransform(GetInverseViewTransformation()); - basegfx::B2DRange aRB(aFillRect.Left(), aFillRect.Top(), aFillRect.Right() + 1, aFillRect.Bottom() + 1); + basegfx::B2DRange aRB(mpAutoFillRect->Left(), mpAutoFillRect->Top(), mpAutoFillRect->Right() + 1, mpAutoFillRect->Bottom() + 1); aRB.transform(aTransform); aRanges.push_back(aRB); @@ -5358,10 +5383,10 @@ void ScGridWindow::UpdateAutoFillOverlay() mpOOAutoFill = new ::sdr::overlay::OverlayObjectList; mpOOAutoFill->append(*pOverlay); } - } - if ( aOldMode != aDrawMode ) - SetMapMode( aOldMode ); + if ( aOldMode != aDrawMode ) + SetMapMode( aOldMode ); + } } void ScGridWindow::DeleteDragRectOverlay() diff --git a/sc/source/ui/view/gridwin2.cxx b/sc/source/ui/view/gridwin2.cxx index 6d9bb94eb76b..f8b5c25c4a70 100644 --- a/sc/source/ui/view/gridwin2.cxx +++ b/sc/source/ui/view/gridwin2.cxx @@ -933,7 +933,7 @@ void ScGridWindow::PagebreakMove( const MouseEvent& rMEvt, BOOL bUp ) BOOL bGrow = !bHide && nNew > nPagebreakBreak; if ( bColumn ) { - if ( pDoc->GetColFlags( static_cast<SCCOL>(nPagebreakBreak), nTab ) & CR_MANUALBREAK ) + if (pDoc->HasColBreak(static_cast<SCCOL>(nPagebreakBreak), nTab) & BREAK_MANUAL) { ScAddress aOldAddr( static_cast<SCCOL>(nPagebreakBreak), nPosY, nTab ); pViewFunc->DeletePageBreak( TRUE, TRUE, &aOldAddr, FALSE ); @@ -946,8 +946,8 @@ void ScGridWindow::PagebreakMove( const MouseEvent& rMEvt, BOOL bUp ) if ( bGrow ) { // vorigen Break auf hart, und Skalierung aendern - if ( static_cast<SCCOL>(nPagebreakPrev) > aPagebreakSource.aStart.Col() && - !(pDoc->GetColFlags( static_cast<SCCOL>(nPagebreakPrev), nTab ) & CR_MANUALBREAK) ) + bool bManualBreak = (pDoc->HasColBreak(static_cast<SCCOL>(nPagebreakPrev), nTab) & BREAK_MANUAL); + if ( static_cast<SCCOL>(nPagebreakPrev) > aPagebreakSource.aStart.Col() && !bManualBreak ) { ScAddress aPrev( static_cast<SCCOL>(nPagebreakPrev), nPosY, nTab ); pViewFunc->InsertPageBreak( TRUE, TRUE, &aPrev, FALSE ); @@ -960,7 +960,7 @@ void ScGridWindow::PagebreakMove( const MouseEvent& rMEvt, BOOL bUp ) } else { - if ( pDoc->GetRowFlags( nPagebreakBreak, nTab ) & CR_MANUALBREAK ) + if (pDoc->HasRowBreak(nPagebreakBreak, nTab) & BREAK_MANUAL) { ScAddress aOldAddr( nPosX, nPagebreakBreak, nTab ); pViewFunc->DeletePageBreak( FALSE, TRUE, &aOldAddr, FALSE ); @@ -973,8 +973,8 @@ void ScGridWindow::PagebreakMove( const MouseEvent& rMEvt, BOOL bUp ) if ( bGrow ) { // vorigen Break auf hart, und Skalierung aendern - if ( nPagebreakPrev > aPagebreakSource.aStart.Row() && - !(pDoc->GetRowFlags( nPagebreakPrev, nTab ) & CR_MANUALBREAK) ) + bool bManualBreak = (pDoc->HasRowBreak(nPagebreakPrev, nTab) & BREAK_MANUAL); + if ( nPagebreakPrev > aPagebreakSource.aStart.Row() && !bManualBreak ) { ScAddress aPrev( nPosX, nPagebreakPrev, nTab ); pViewFunc->InsertPageBreak( FALSE, TRUE, &aPrev, FALSE ); diff --git a/sc/source/ui/view/gridwin3.cxx b/sc/source/ui/view/gridwin3.cxx index 5bfc0483b553..f16c2fe1ada7 100644..100755 --- a/sc/source/ui/view/gridwin3.cxx +++ b/sc/source/ui/view/gridwin3.cxx @@ -265,7 +265,7 @@ MapMode ScGridWindow::GetDrawMapMode( BOOL bForce ) SCROW nEndRow = 0; pDoc->GetTableArea( nTab, nEndCol, nEndRow ); if (nEndCol<20) nEndCol = 20; - if (nEndRow<20) nEndRow = 20; + if (nEndRow<1000) nEndRow = 1000; ScDrawUtil::CalcScale( pDoc, nTab, 0,0, nEndCol,nEndRow, this, pViewData->GetZoomX(),pViewData->GetZoomY(), pViewData->GetPPTX(),pViewData->GetPPTY(), diff --git a/sc/source/ui/view/gridwin4.cxx b/sc/source/ui/view/gridwin4.cxx index f698913ea758..d8024e439173 100644 --- a/sc/source/ui/view/gridwin4.cxx +++ b/sc/source/ui/view/gridwin4.cxx @@ -449,6 +449,12 @@ void ScGridWindow::Draw( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2, ScUpdateMod SCROW nYBottom = nPosY + pViewData->VisibleCellsY(eVWhich); if (nYBottom > MAXROW) nYBottom = MAXROW; + // Store the current visible range. + maVisibleRange.mnCol1 = nPosX; + maVisibleRange.mnCol2 = nXRight; + maVisibleRange.mnRow1 = nPosY; + maVisibleRange.mnRow2 = nYBottom; + if (nX1 > nXRight || nY1 > nYBottom) return; // unsichtbar if (nX2 > nXRight) nX2 = nXRight; @@ -1086,7 +1092,7 @@ void ScGridWindow::DrawPagePreview( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2, if ( nBreak >= nX1 && nBreak <= nX2+1 ) { //! hidden suchen - if ( pDoc->GetColFlags( nBreak, nTab ) & CR_MANUALBREAK ) + if (pDoc->HasColBreak(nBreak, nTab) & BREAK_MANUAL) pContentDev->SetFillColor( aManual ); else pContentDev->SetFillColor( aAutomatic ); @@ -1105,7 +1111,7 @@ void ScGridWindow::DrawPagePreview( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2, if ( nBreak >= nY1 && nBreak <= nY2+1 ) { //! hidden suchen - if ( pDoc->GetRowFlags( nBreak, nTab ) & CR_MANUALBREAK ) + if (pDoc->HasRowBreak(nBreak, nTab) & BREAK_MANUAL) pContentDev->SetFillColor( aManual ); else pContentDev->SetFillColor( aAutomatic ); @@ -1374,7 +1380,7 @@ Rectangle ScGridWindow::GetListValButtonRect( const ScAddress& rButtonPos ) const ScMergeAttr* pMerge = static_cast<const ScMergeAttr*>(pDoc->GetAttr( nCol,nRow,nTab, ATTR_MERGE )); if ( pMerge->GetColMerge() > 1 ) nNextCol = nCol + pMerge->GetColMerge(); // next cell after the merged area - while ( nNextCol <= MAXCOL && (pDoc->GetColFlags( nNextCol, nTab ) & CR_HIDDEN) ) + while ( nNextCol <= MAXCOL && pDoc->ColHidden(nNextCol, nTab) ) ++nNextCol; BOOL bNextCell = ( nNextCol <= MAXCOL ); if ( bNextCell ) @@ -1577,7 +1583,7 @@ void ScGridWindow::InvertSimple( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2, if ( pMergeFlag->IsVerOverlapped() && ( bDoHidden || bFirstRow ) ) { while ( pMergeFlag->IsVerOverlapped() && nThisY > 0 && - ( (pDoc->GetRowFlags( nThisY-1, nTab ) & CR_HIDDEN) || bFirstRow ) ) + (pDoc->RowHidden(nThisY-1, nTab) || bFirstRow) ) { --nThisY; pPattern = pDoc->GetPattern( nX, nThisY, nTab ); @@ -1764,7 +1770,7 @@ void ScGridWindow::GetSelectionRects( ::std::vector< Rectangle >& rPixelRects ) if ( pMergeFlag->IsVerOverlapped() && ( bDoHidden || bFirstRow ) ) { while ( pMergeFlag->IsVerOverlapped() && nThisY > 0 && - ( (pDoc->GetRowFlags( nThisY-1, nTab ) & CR_HIDDEN) || bFirstRow ) ) + (pDoc->RowHidden(nThisY-1, nTab) || bFirstRow) ) { --nThisY; pPattern = pDoc->GetPattern( nX, nThisY, nTab ); diff --git a/sc/source/ui/view/hdrcont.cxx b/sc/source/ui/view/hdrcont.cxx index 6c389d496b73..25f3c1c8f10a 100644 --- a/sc/source/ui/view/hdrcont.cxx +++ b/sc/source/ui/view/hdrcont.cxx @@ -102,7 +102,7 @@ ScHeaderControl::ScHeaderControl( Window* pParent, SelectionEngine* pSelectionEn nWidth = nSmallWidth = aSize.Width(); nBigWidth = LogicToPixel( Size( GetTextWidth( - String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("88888")) ), 0 ) ).Width() + 4; + String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("8888888")) ), 0 ) ).Width() + 5; SetBackground(); // sonst Probleme auf OS/2 !?!?! } diff --git a/sc/source/ui/view/makefile.mk b/sc/source/ui/view/makefile.mk index feeacc865fba..1b2fef913fc2 100644 --- a/sc/source/ui/view/makefile.mk +++ b/sc/source/ui/view/makefile.mk @@ -155,6 +155,7 @@ EXCEPTIONSFILES= \ $(SLO)$/gridwin2.obj \ $(SLO)$/scextopt.obj \ $(SLO)$/tabvwshb.obj \ + $(SLO)$/tabvwshf.obj \ $(SLO)$/viewdata.obj \ $(SLO)$/viewfunc.obj \ $(SLO)$/viewfun2.obj \ diff --git a/sc/source/ui/view/olinewin.cxx b/sc/source/ui/view/olinewin.cxx index bec88920f989..b1e82fd9217f 100644 --- a/sc/source/ui/view/olinewin.cxx +++ b/sc/source/ui/view/olinewin.cxx @@ -183,16 +183,15 @@ const ScOutlineEntry* ScOutlineWindow::GetOutlineEntry( size_t nLevel, size_t nE bool ScOutlineWindow::IsHidden( SCCOLROW nColRowIndex ) const { - sal_uInt8 nFlags = mbHoriz ? - GetDoc().GetColFlags( static_cast<SCCOL>(nColRowIndex), GetTab() ) : - GetDoc().GetRowFlags( static_cast<SCROW>(nColRowIndex), GetTab() ); - return (nFlags & CR_HIDDEN) != 0; + return mbHoriz ? + GetDoc().ColHidden(static_cast<SCCOL>(nColRowIndex), GetTab()) : + GetDoc().RowHidden(static_cast<SCROW>(nColRowIndex), GetTab()); } bool ScOutlineWindow::IsFiltered( SCCOLROW nColRowIndex ) const { // columns cannot be filtered - return !mbHoriz && GetDoc().IsFiltered( static_cast<SCROW>(nColRowIndex), GetTab() ); + return !mbHoriz && GetDoc().RowFiltered( static_cast<SCROW>(nColRowIndex), GetTab() ); } bool ScOutlineWindow::IsFirstVisible( SCCOLROW nColRowIndex ) const diff --git a/sc/source/ui/view/output.cxx b/sc/source/ui/view/output.cxx index 265e54fe0e12..961572fc0185 100644 --- a/sc/source/ui/view/output.cxx +++ b/sc/source/ui/view/output.cxx @@ -322,8 +322,9 @@ void ScOutputData::DrawGrid( BOOL bGrid, BOOL bPage ) long nPosX; long nPosY; SCSIZE nArrY; - BYTE nOldFlags = 0; - BYTE nFlags; + ScBreakType nBreak = BREAK_NONE; + ScBreakType nBreakOld = BREAK_NONE; + BOOL bSingle; Color aPageColor; Color aManualColor; @@ -378,27 +379,27 @@ void ScOutputData::DrawGrid( BOOL bGrid, BOOL bPage ) if ( bPage ) { // Seitenumbrueche auch in ausgeblendeten suchen - nFlags = 0; SCCOL nCol = nXplus1; while (nCol <= MAXCOL) { - BYTE nDocFl = pDoc->GetColFlags( nCol, nTab ); - nFlags = nDocFl & ( CR_PAGEBREAK | CR_MANUALBREAK ); - if ( nFlags || !(nDocFl & CR_HIDDEN) ) + nBreak = pDoc->HasColBreak(nCol, nTab); + bool bHidden = pDoc->ColHidden(nCol, nTab); + + if ( nBreak || !bHidden ) break; ++nCol; } - if (nFlags != nOldFlags) + if (nBreak != nBreakOld) { aGrid.Flush(); - pDev->SetLineColor( (nFlags & CR_MANUALBREAK) ? aManualColor : - (nFlags) ? aPageColor : aGridColor ); - nOldFlags = nFlags; + pDev->SetLineColor( (nBreak & BREAK_MANUAL) ? aManualColor : + nBreak ? aPageColor : aGridColor ); + nBreakOld = nBreak; } } - BOOL bDraw = bGrid || nOldFlags; // einfaches Gitter nur wenn eingestellt + BOOL bDraw = bGrid || nBreakOld; // einfaches Gitter nur wenn eingestellt //! Mit dieser Abfrage wird zuviel weggelassen, wenn ein automatischer //! Umbruch mitten in den Wiederholungsspalten liegt. @@ -409,7 +410,7 @@ void ScOutputData::DrawGrid( BOOL bGrid, BOOL bPage ) { if ( nX == MAXCOL ) bDraw = FALSE; - else if (pDoc->GetColFlags(nXplus1,nTab) & ( CR_PAGEBREAK | CR_MANUALBREAK )) + else if (pDoc->HasColBreak(nXplus1, nTab)) bDraw = FALSE; } #endif @@ -500,28 +501,24 @@ void ScOutputData::DrawGrid( BOOL bGrid, BOOL bPage ) { if ( bPage ) { - // Seitenumbrueche auch in ausgeblendeten suchen - nFlags = 0; - ScCompressedArrayIterator< SCROW, BYTE > aIter( - pDoc->GetRowFlagsArray( nTab), nYplus1, MAXROW); - do + for (SCROW i = nYplus1; i <= MAXROW; ++i) { - BYTE nDocFl = *aIter; - nFlags = nDocFl & ( CR_PAGEBREAK | CR_MANUALBREAK ); - if ( nFlags || !(nDocFl & CR_HIDDEN) ) + nBreak = pDoc->HasRowBreak(i, nTab); + bool bHidden = pDoc->RowHidden(i, nTab); + if (nBreak || !bHidden) break; - } while (aIter.NextRange()); + } - if (nFlags != nOldFlags) + if (nBreakOld != nBreak) { aGrid.Flush(); - pDev->SetLineColor( (nFlags & CR_MANUALBREAK) ? aManualColor : - (nFlags) ? aPageColor : aGridColor ); - nOldFlags = nFlags; + pDev->SetLineColor( (nBreak & BREAK_MANUAL) ? aManualColor : + (nBreak) ? aPageColor : aGridColor ); + nBreakOld = nBreak; } } - BOOL bDraw = bGrid || nOldFlags; // einfaches Gitter nur wenn eingestellt + BOOL bDraw = bGrid || nBreakOld; // einfaches Gitter nur wenn eingestellt //! Mit dieser Abfrage wird zuviel weggelassen, wenn ein automatischer //! Umbruch mitten in den Wiederholungszeilen liegt. @@ -532,7 +529,7 @@ void ScOutputData::DrawGrid( BOOL bGrid, BOOL bPage ) { if ( nY == MAXROW ) bDraw = FALSE; - else if (pDoc->GetRowFlags(nYplus1,nTab) & ( CR_PAGEBREAK | CR_MANUALBREAK )) + else if (pDoc->HasRowBreak(nYplus1, nTab)) bDraw = FALSE; } #endif @@ -654,7 +651,7 @@ void ScOutputData::FindRotated() const ScPatternAttr* pPattern = pInfo->pPatternAttr; const SfxItemSet* pCondSet = pInfo->pConditionSet; - if ( !pPattern && (pDoc->GetColFlags(nX,nTab) & CR_HIDDEN) == 0 ) + if ( !pPattern && !pDoc->ColHidden(nX, nTab) ) { pPattern = pDoc->GetPattern( nX, nY, nTab ); pCondSet = pDoc->GetCondResult( nX, nY, nTab ); diff --git a/sc/source/ui/view/output2.cxx b/sc/source/ui/view/output2.cxx index 53851f0e3cf0..b0b040f9b5e0 100644 --- a/sc/source/ui/view/output2.cxx +++ b/sc/source/ui/view/output2.cxx @@ -53,6 +53,7 @@ #include <editeng/udlnitem.hxx> #include <editeng/unolingu.hxx> #include <svl/zforlist.hxx> +#include <svl/zformat.hxx> #include <vcl/svapp.hxx> #include <vcl/metric.hxx> #include <vcl/outdev.hxx> @@ -74,6 +75,8 @@ #include "scmod.hxx" #include "fillinfo.hxx" +#include <boost/ptr_container/ptr_vector.hpp> + #include <math.h> //! Autofilter-Breite mit column.cxx zusammenfassen @@ -108,6 +111,10 @@ class ScDrawStringsVars String aString; // Inhalte Size aTextSize; long nOriginalWidth; + long nMaxDigitWidth; + long nSignWidth; + long nDotWidth; + long nExpWidth; ScBaseCell* pLastCell; ULONG nValueFormat; @@ -132,7 +139,7 @@ public: void SetPatternSimple( const ScPatternAttr* pNew, const SfxItemSet* pSet ); BOOL SetText( ScBaseCell* pCell ); // TRUE -> pOldPattern vergessen - void SetHashText(); + void SetTextToWidthOrHash( ScBaseCell* pCell, long nWidth ); void SetAutoText( const String& rAutoText ); const ScPatternAttr* GetPattern() const { return pPattern; } @@ -161,6 +168,15 @@ public: pCondSet->GetItemState( ATTR_FONT_HEIGHT, TRUE ); } BOOL HasEditCharacters() const; + +private: + void SetHashText(); + long GetMaxDigitWidth(); + long GetSignWidth(); + long GetDotWidth(); + long GetExpWidth(); + void TextChanged(); + long ConvertWidthLogicToPixel( long nWidth ) const; }; //================================================================== @@ -176,6 +192,10 @@ ScDrawStringsVars::ScDrawStringsVars(ScOutputData* pData, BOOL bPTL) : nIndent ( 0 ), bRotated ( FALSE ), nOriginalWidth( 0 ), + nMaxDigitWidth( 0 ), + nSignWidth( 0 ), + nDotWidth( 0 ), + nExpWidth( 0 ), pLastCell ( NULL ), nValueFormat( 0 ), bLineBreak ( FALSE ), @@ -242,6 +262,11 @@ void ScDrawStringsVars::SetShrinkScale( long nScale, BYTE nScript ) void ScDrawStringsVars::SetPattern( const ScPatternAttr* pNew, const SfxItemSet* pSet, ScBaseCell* pCell, BYTE nScript ) { + nMaxDigitWidth = 0; + nSignWidth = 0; + nDotWidth = 0; + nExpWidth = 0; + pPattern = pNew; pCondSet = pSet; @@ -393,6 +418,10 @@ void ScDrawStringsVars::SetPattern( const ScPatternAttr* pNew, const SfxItemSet* void ScDrawStringsVars::SetPatternSimple( const ScPatternAttr* pNew, const SfxItemSet* pSet ) { + nMaxDigitWidth = 0; + nSignWidth = 0; + nDotWidth = 0; + nExpWidth = 0; // wird gerufen, wenn sich die Font-Variablen nicht aendern (!StringDiffer) pPattern = pNew; @@ -467,28 +496,7 @@ BOOL ScDrawStringsVars::SetText( ScBaseCell* pCell ) pLastCell = NULL; // naechstes Mal wieder hierherkommen } - OutputDevice* pRefDevice = pOutput->pRefDevice; - OutputDevice* pFmtDevice = pOutput->pFmtDevice; - aTextSize.Width() = pFmtDevice->GetTextWidth( aString ); - aTextSize.Height() = pFmtDevice->GetTextHeight(); - - if ( !pRefDevice->GetConnectMetaFile() || pRefDevice->GetOutDevType() == OUTDEV_PRINTER ) - { - double fMul = pOutput->GetStretch(); - aTextSize.Width() = (long)(aTextSize.Width() / fMul + 0.5); - } - - aTextSize.Height() = aMetric.GetAscent() + aMetric.GetDescent(); - if ( GetOrient() != SVX_ORIENTATION_STANDARD ) - { - long nTemp = aTextSize.Height(); - aTextSize.Height() = aTextSize.Width(); - aTextSize.Width() = nTemp; - } - - nOriginalWidth = aTextSize.Width(); - if ( bPixelToLogic ) - aTextSize = pRefDevice->LogicToPixel( aTextSize ); + TextChanged(); } // sonst String/Groesse behalten } @@ -508,6 +516,86 @@ void ScDrawStringsVars::SetHashText() SetAutoText( String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("###")) ); } +void ScDrawStringsVars::SetTextToWidthOrHash( ScBaseCell* pCell, long nWidth ) +{ + if (!pCell) + return; + + CellType eType = pCell->GetCellType(); + if (eType != CELLTYPE_VALUE && eType != CELLTYPE_FORMULA) + // must be a value or formula cell. + return; + + if (eType == CELLTYPE_FORMULA && !static_cast<ScFormulaCell*>(pCell)->IsValue()) + // If it's formula, the result must be a value. + return; + + ULONG nFormat = GetValueFormat(); + if ((nFormat % SV_COUNTRY_LANGUAGE_OFFSET) != 0) + { + // Not 'General' number format. Set hash text and bail out. + SetHashText(); + return; + } + + double fVal = (eType == CELLTYPE_VALUE) ? + static_cast<ScValueCell*>(pCell)->GetValue() : static_cast<ScFormulaCell*>(pCell)->GetValue(); + + const SvNumberformat* pNumFormat = pOutput->pDoc->GetFormatTable()->GetEntry(nFormat); + if (!pNumFormat) + return; + + long nMaxDigit = GetMaxDigitWidth(); + sal_uInt16 nNumDigits = static_cast<sal_uInt16>(nWidth / nMaxDigit); + + if (!pNumFormat->GetOutputString(fVal, nNumDigits, aString)) + // Failed to get output string. Bail out. + return; + + sal_uInt8 nSignCount = 0, nDecimalCount = 0, nExpCount = 0; + xub_StrLen nLen = aString.Len(); + sal_Unicode cDecSep = ScGlobal::GetpLocaleData()->getLocaleItem().decimalSeparator.getStr()[0]; + for (xub_StrLen i = 0; i < nLen; ++i) + { + sal_Unicode c = aString.GetChar(i); + if (c == sal_Unicode('-')) + ++nSignCount; + else if (c == cDecSep) + ++nDecimalCount; + else if (c == sal_Unicode('E')) + ++nExpCount; + } + if (nDecimalCount) + nWidth += (nMaxDigit - GetDotWidth()) * nDecimalCount; + if (nSignCount) + nWidth += (nMaxDigit - GetSignWidth()) * nSignCount; + if (nExpCount) + nWidth += (nMaxDigit - GetExpWidth()) * nExpCount; + + if (nDecimalCount || nSignCount || nExpCount) + { + // Re-calculate. + nNumDigits = static_cast<sal_uInt16>(nWidth / nMaxDigit); + if (!pNumFormat->GetOutputString(fVal, nNumDigits, aString)) + // Failed to get output string. Bail out. + return; + } + + long nActualTextWidth = pOutput->pFmtDevice->GetTextWidth(aString); + + if (bPixelToLogic) + nActualTextWidth = ConvertWidthLogicToPixel(nActualTextWidth); + + if (nActualTextWidth > nWidth) + { + // Even after the decimal adjustment the text doesn't fit. Give up. + SetHashText(); + return; + } + + TextChanged(); +} + void ScDrawStringsVars::SetAutoText( const String& rAutoText ) { aString = rAutoText; @@ -538,6 +626,91 @@ void ScDrawStringsVars::SetAutoText( const String& rAutoText ) pLastCell = NULL; // derselbe Text kann in der naechsten Zelle wieder passen } +long ScDrawStringsVars::GetMaxDigitWidth() +{ + if (nMaxDigitWidth > 0) + return nMaxDigitWidth; + + sal_Char cZero = '0'; + for (sal_Char i = 0; i < 10; ++i) + { + sal_Char cDigit = cZero + i; + long n = pOutput->pFmtDevice->GetTextWidth(String(cDigit)); + nMaxDigitWidth = ::std::max(nMaxDigitWidth, n); + } + + if (bPixelToLogic) + nMaxDigitWidth = ConvertWidthLogicToPixel(nMaxDigitWidth); + return nMaxDigitWidth; +} + +long ScDrawStringsVars::GetSignWidth() +{ + if (nSignWidth > 0) + return nSignWidth; + + nSignWidth = pOutput->pFmtDevice->GetTextWidth(String('-')); + if (bPixelToLogic) + nSignWidth = ConvertWidthLogicToPixel(nSignWidth); + return nSignWidth; +} + +long ScDrawStringsVars::GetDotWidth() +{ + if (nDotWidth > 0) + return nDotWidth; + + const ::rtl::OUString& sep = ScGlobal::GetpLocaleData()->getLocaleItem().decimalSeparator; + nDotWidth = pOutput->pFmtDevice->GetTextWidth(sep); + if (bPixelToLogic) + nDotWidth = ConvertWidthLogicToPixel(nDotWidth); + return nDotWidth; +} + +long ScDrawStringsVars::GetExpWidth() +{ + if (nExpWidth > 0) + return nExpWidth; + + nExpWidth = pOutput->pFmtDevice->GetTextWidth(String('E')); + if (bPixelToLogic) + nExpWidth = ConvertWidthLogicToPixel(nExpWidth); + return nExpWidth; +} + +void ScDrawStringsVars::TextChanged() +{ + OutputDevice* pRefDevice = pOutput->pRefDevice; + OutputDevice* pFmtDevice = pOutput->pFmtDevice; + aTextSize.Width() = pFmtDevice->GetTextWidth( aString ); + aTextSize.Height() = pFmtDevice->GetTextHeight(); + + if ( !pRefDevice->GetConnectMetaFile() || pRefDevice->GetOutDevType() == OUTDEV_PRINTER ) + { + double fMul = pOutput->GetStretch(); + aTextSize.Width() = (long)(aTextSize.Width() / fMul + 0.5); + } + + aTextSize.Height() = aMetric.GetAscent() + aMetric.GetDescent(); + if ( GetOrient() != SVX_ORIENTATION_STANDARD ) + { + long nTemp = aTextSize.Height(); + aTextSize.Height() = aTextSize.Width(); + aTextSize.Width() = nTemp; + } + + nOriginalWidth = aTextSize.Width(); + if ( bPixelToLogic ) + aTextSize = pRefDevice->LogicToPixel( aTextSize ); +} + +long ScDrawStringsVars::ConvertWidthLogicToPixel( long nWidth ) const +{ + Size aSize(nWidth, pOutput->pFmtDevice->GetTextHeight()); + aSize = pOutput->pRefDevice->LogicToPixel(aSize); + return aSize.Width(); +} + BOOL ScDrawStringsVars::HasEditCharacters() const { static const sal_Unicode pChars[] = @@ -691,7 +864,7 @@ BOOL ScOutputData::GetMergeOrigin( SCCOL nX, SCROW nY, SCSIZE nArrY, while (bHOver) // nY konstant { --rOverX; - bHidden = ( (pDoc->GetColFlags(rOverX,nTab) & CR_HIDDEN) != 0 ); + bHidden = pDoc->ColHidden(rOverX, nTab); if ( !bDoMerge && !bHidden ) return FALSE; @@ -715,7 +888,7 @@ BOOL ScOutputData::GetMergeOrigin( SCCOL nX, SCROW nY, SCSIZE nArrY, while (bVOver) { --rOverY; - bHidden = ( (pDoc->GetRowFlags(rOverY,nTab) & CR_HIDDEN) != 0 ); + bHidden = pDoc->RowHidden(rOverY, nTab); if ( !bDoMerge && !bHidden ) return FALSE; @@ -723,8 +896,8 @@ BOOL ScOutputData::GetMergeOrigin( SCCOL nX, SCROW nY, SCSIZE nArrY, --nArrY; // lokale Kopie ! if (rOverX >= nX1 && rOverY >= nY1 && - (pDoc->GetColFlags(rOverX,nTab) & CR_HIDDEN) == 0 && - (pDoc->GetRowFlags(rOverY,nTab) & CR_HIDDEN) == 0 && + !pDoc->ColHidden(rOverX, nTab) && + !pDoc->RowHidden(rOverY, nTab) && pRowInfo[nArrY].nRowNo == rOverY) { // rVirtPosY -= pRowInfo[nArrY].nHeight; @@ -919,18 +1092,14 @@ BOOL ScOutputData::IsAvailable( SCCOL nX, SCROW nY ) // bCellIsValue: if set, don't extend into empty cells // bBreak: if set, don't extend, and don't set clip marks (but rLeftClip/rRightClip is set) // bOverwrite: if set, also extend into non-empty cells (for rotated text) -// rAlignRect: output: single or merged cell, used for alignment (visual rectangle) -// rClipRect: output: total output area, for clipping (visual) -// rLeftClip: output: need to clip at rClipRect left (visual) edge -// rRightClip: output: same for right +// rParam output: various area parameters. void ScOutputData::GetOutputArea( SCCOL nX, SCSIZE nArrY, long nPosX, long nPosY, - SCCOL nCellX, SCROW nCellY, long nNeeded, - const ScPatternAttr& rPattern, - USHORT nHorJustify, BOOL bCellIsValue, - BOOL bBreak, BOOL bOverwrite, - Rectangle& rAlignRect, Rectangle& rClipRect, - BOOL& rLeftClip, BOOL& rRightClip ) + SCCOL nCellX, SCROW nCellY, long nNeeded, + const ScPatternAttr& rPattern, + USHORT nHorJustify, bool bCellIsValue, + bool bBreak, bool bOverwrite, + OutputAreaParam& rParam ) { // rThisRowInfo may be for a different row than nCellY, is still used for clip marks RowInfo& rThisRowInfo = pRowInfo[nArrY]; @@ -1009,21 +1178,23 @@ void ScOutputData::GetOutputArea( SCCOL nX, SCSIZE nArrY, long nPosX, long nPosY --nMergeSizeX; // leave out the grid horizontally, also for alignment (align between grid lines) + rParam.mnColWidth = nMergeSizeX; // store the actual column width. + // // construct the rectangles using logical left/right values (justify is called at the end) // // rAlignRect is the single cell or merged area, used for alignment. - rAlignRect.Left() = nCellPosX; - rAlignRect.Right() = nCellPosX + ( nMergeSizeX - 1 ) * nLayoutSign; - rAlignRect.Top() = nCellPosY; - rAlignRect.Bottom() = nCellPosY + nMergeSizeY - 1; + rParam.maAlignRect.Left() = nCellPosX; + rParam.maAlignRect.Right() = nCellPosX + ( nMergeSizeX - 1 ) * nLayoutSign; + rParam.maAlignRect.Top() = nCellPosY; + rParam.maAlignRect.Bottom() = nCellPosY + nMergeSizeY - 1; // rClipRect is all cells that are used for output. // For merged cells this is the same as rAlignRect, otherwise neighboring cells can also be used. - rClipRect = rAlignRect; + rParam.maClipRect = rParam.maAlignRect; if ( nNeeded > nMergeSizeX ) { SvxCellHorJustify eHorJust = (SvxCellHorJustify)nHorJustify; @@ -1064,7 +1235,7 @@ void ScOutputData::GetOutputArea( SCCOL nX, SCSIZE nArrY, long nPosX, long nPosY ++nRightX; long nAdd = (long) ( pDoc->GetColWidth( nRightX, nTab ) * nPPTX ); nRightMissing -= nAdd; - rClipRect.Right() += nAdd * nLayoutSign; + rParam.maClipRect.Right() += nAdd * nLayoutSign; if ( rThisRowInfo.nRowNo == nCellY && nRightX >= nX1 && nRightX <= nX2 ) rThisRowInfo.pCellInfo[nRightX].bHideGrid = TRUE; @@ -1078,7 +1249,7 @@ void ScOutputData::GetOutputArea( SCCOL nX, SCSIZE nArrY, long nPosX, long nPosY --nLeftX; long nAdd = (long) ( pDoc->GetColWidth( nLeftX, nTab ) * nPPTX ); nLeftMissing -= nAdd; - rClipRect.Left() -= nAdd * nLayoutSign; + rParam.maClipRect.Left() -= nAdd * nLayoutSign; } } @@ -1089,22 +1260,22 @@ void ScOutputData::GetOutputArea( SCCOL nX, SCSIZE nArrY, long nPosX, long nPosY rThisRowInfo.pCellInfo[nRightX+1].nClipMark |= SC_CLIPMARK_RIGHT; bAnyClipped = TRUE; long nMarkPixel = (long)( SC_CLIPMARK_SIZE * nPPTX ); - rClipRect.Right() -= nMarkPixel * nLayoutSign; + rParam.maClipRect.Right() -= nMarkPixel * nLayoutSign; } if ( nLeftMissing > 0 && bMarkClipped && nLeftX >= nX1 && nLeftX <= nX2 && !bBreak && !bCellIsValue ) { rThisRowInfo.pCellInfo[nLeftX+1].nClipMark |= SC_CLIPMARK_LEFT; bAnyClipped = TRUE; long nMarkPixel = (long)( SC_CLIPMARK_SIZE * nPPTX ); - rClipRect.Left() += nMarkPixel * nLayoutSign; + rParam.maClipRect.Left() += nMarkPixel * nLayoutSign; } - rLeftClip = ( nLeftMissing > 0 ); - rRightClip = ( nRightMissing > 0 ); + rParam.mbLeftClip = ( nLeftMissing > 0 ); + rParam.mbRightClip = ( nRightMissing > 0 ); } else { - rLeftClip = rRightClip = FALSE; + rParam.mbLeftClip = rParam.mbRightClip = FALSE; // leave space for AutoFilter on screen // (for automatic line break: only if not formatting for printer, as in ScColumn::GetNeededSize) @@ -1120,30 +1291,30 @@ void ScOutputData::GetOutputArea( SCCOL nX, SCSIZE nArrY, long nPosX, long nPosY // content fits even in the remaining area without the filter button // -> align within that remaining area - rAlignRect.Right() -= nFilter * nLayoutSign; - rClipRect.Right() -= nFilter * nLayoutSign; + rParam.maAlignRect.Right() -= nFilter * nLayoutSign; + rParam.maClipRect.Right() -= nFilter * nLayoutSign; // if a number doesn't fit, don't hide part of the number behind the button // -> set clip flags, so "###" replacement is used (but also within the smaller area) if ( !bFit ) - rLeftClip = rRightClip = TRUE; + rParam.mbLeftClip = rParam.mbRightClip = TRUE; } } } // justify both rectangles for alignment calculation, use with DrawText etc. - rAlignRect.Justify(); - rClipRect.Justify(); + rParam.maAlignRect.Justify(); + rParam.maClipRect.Justify(); #if 0 //! Test !!! pDev->Push(); pDev->SetLineColor(); pDev->SetFillColor( COL_LIGHTGREEN ); - pDev->DrawRect( pDev->PixelToLogic(rClipRect) ); - pDev->DrawRect( rClipRect ); // print preview + pDev->DrawRect( pDev->PixelToLogic(rParam.maClipRect) ); + pDev->DrawRect( rParam.maClipRect ); // print preview pDev->Pop(); //! Test !!! #endif @@ -1164,10 +1335,6 @@ void ScOutputData::DrawStrings( BOOL bPixelToLogic ) ScDrawStringsVars aVars( this, bPixelToLogic ); - const ScPatternAttr* pOldPattern = NULL; - const SfxItemSet* pOldCondSet = NULL; - BYTE nOldScript = 0; - BOOL bProgress = FALSE; long nInitPosX = nScrX; @@ -1184,15 +1351,19 @@ void ScOutputData::DrawStrings( BOOL bPixelToLogic ) --nLoopStartX; // start before nX1 for rest of long text to the left // variables for GetOutputArea + OutputAreaParam aAreaParam; BOOL bCellIsValue = FALSE; - BOOL bLeftClip = FALSE; - BOOL bRightClip = FALSE; long nNeededWidth = 0; - Rectangle aAlignRect; - Rectangle aClipRect; SvxCellHorJustify eOutHorJust = SVX_HOR_JUSTIFY_STANDARD; const ScPatternAttr* pPattern = NULL; const SfxItemSet* pCondSet = NULL; + const ScPatternAttr* pOldPattern = NULL; + const SfxItemSet* pOldCondSet = NULL; + BYTE nOldScript = 0; + + // alternative pattern instances in case we need to modify the pattern + // before processing the cell value. + ::boost::ptr_vector<ScPatternAttr> aAltPatterns; long nPosY = nScrY; for (SCSIZE nArrY=1; nArrY+1<nArrCount; nArrY++) @@ -1330,6 +1501,18 @@ void ScOutputData::DrawStrings( BOOL bPixelToLogic ) pCondSet = pDoc->GetCondResult( nCellX, nCellY, nTab ); } + if (pCell->HasValueData() && + static_cast<const SfxBoolItem&>( + pPattern->GetItem(ATTR_LINEBREAK, pCondSet)).GetValue()) + { + // Disable line break when the cell content is numeric. + aAltPatterns.push_back(new ScPatternAttr(*pPattern)); + ScPatternAttr* pAltPattern = &aAltPatterns.back(); + SfxBoolItem aLineBreak(ATTR_LINEBREAK, false); + pAltPattern->GetItemSet().Put(aLineBreak); + pPattern = pAltPattern; + } + BYTE nScript = GetScriptType( pDoc, pCell, pPattern, pCondSet ); if (nScript == 0) nScript = ScGlobal::GetDefaultScriptType(); if ( pPattern != pOldPattern || pCondSet != pOldCondSet || @@ -1360,6 +1543,7 @@ void ScOutputData::DrawStrings( BOOL bPixelToLogic ) bNeedEdit = aVars.HasEditCharacters() || (bFormulaCell && ((ScFormulaCell*)pCell)->IsMultilineResult()); } + long nTotalMargin = 0; if (bDoCell && !bNeedEdit) { CellType eCellType = pCell->GetCellType(); @@ -1381,14 +1565,17 @@ void ScOutputData::DrawStrings( BOOL bPixelToLogic ) BOOL bRepeat = aVars.IsRepeat() && !bBreak; BOOL bShrink = aVars.IsShrink() && !bBreak && !bRepeat; - long nTotalMargin = (long) ( aVars.GetLeftTotal() * nPPTX ) + - (long) ( aVars.GetMargin()->GetRightMargin() * nPPTX ); + nTotalMargin = + static_cast<long>(aVars.GetLeftTotal() * nPPTX) + + static_cast<long>(aVars.GetMargin()->GetRightMargin() * nPPTX); + nNeededWidth = aVars.GetTextSize().Width() + nTotalMargin; + // GetOutputArea gives justfied rectangles GetOutputArea( nX, nArrY, nPosX, nPosY, nCellX, nCellY, nNeededWidth, - *pPattern, sal::static_int_cast<USHORT>(eOutHorJust), - bCellIsValue || bRepeat || bShrink, bBreak, FALSE, - aAlignRect, aClipRect, bLeftClip, bRightClip ); + *pPattern, sal::static_int_cast<USHORT>(eOutHorJust), + bCellIsValue || bRepeat || bShrink, bBreak, FALSE, + aAreaParam ); if ( bShrink ) { @@ -1398,9 +1585,9 @@ void ScOutputData::DrawStrings( BOOL bPixelToLogic ) // DrawEdit is used to vertically scale 90 deg rotated text. bNeedEdit = TRUE; } - else if ( bLeftClip || bRightClip ) // horizontal + else if ( aAreaParam.mbLeftClip || aAreaParam.mbRightClip ) // horizontal { - long nAvailable = aAlignRect.GetWidth() - nTotalMargin; + long nAvailable = aAreaParam.maAlignRect.GetWidth() - nTotalMargin; long nScaleSize = aVars.GetTextSize().Width(); // without margin if ( nScaleSize > 0 ) // 0 if the text is empty (formulas, number formats) @@ -1424,16 +1611,16 @@ void ScOutputData::DrawStrings( BOOL bPixelToLogic ) // If even at half the size the font still isn't rendered smaller, // fall back to normal clipping (showing ### for numbers). if ( nNewSize <= nAvailable ) - bLeftClip = bRightClip = FALSE; + aAreaParam.mbLeftClip = aAreaParam.mbRightClip = FALSE; pOldPattern = NULL; } } } - if ( bRepeat && !bLeftClip && !bRightClip ) + if ( bRepeat && !aAreaParam.mbLeftClip && !aAreaParam.mbRightClip ) { - long nAvailable = aAlignRect.GetWidth() - nTotalMargin; + long nAvailable = aAreaParam.maAlignRect.GetWidth() - nTotalMargin; long nRepeatSize = aVars.GetTextSize().Width(); // without margin // When formatting for the printer, the text sizes don't always add up. // Round down (too few repetitions) rather than exceeding the cell size then: @@ -1457,13 +1644,13 @@ void ScOutputData::DrawStrings( BOOL bPixelToLogic ) if ( bBreak ) { if ( aVars.GetOrient() == SVX_ORIENTATION_STANDARD ) - bNeedEdit = ( bLeftClip || bRightClip ); + bNeedEdit = ( aAreaParam.mbLeftClip || aAreaParam.mbRightClip ); else { long nHeight = aVars.GetTextSize().Height() + (long)(aVars.GetMargin()->GetTopMargin()*nPPTY) + (long)(aVars.GetMargin()->GetBottomMargin()*nPPTY); - bNeedEdit = ( nHeight > aClipRect.GetHeight() ); + bNeedEdit = ( nHeight > aAreaParam.maClipRect.GetHeight() ); } } } @@ -1479,48 +1666,49 @@ void ScOutputData::DrawStrings( BOOL bPixelToLogic ) } if ( bDoCell ) { - if ( bCellIsValue && ( bLeftClip || bRightClip ) ) + if ( bCellIsValue && ( aAreaParam.mbLeftClip || aAreaParam.mbRightClip ) ) { - aVars.SetHashText(); + // Adjust the decimals to fit the available column width. + aVars.SetTextToWidthOrHash(pCell, aAreaParam.mnColWidth - nTotalMargin); nNeededWidth = aVars.GetTextSize().Width() + (long) ( aVars.GetLeftTotal() * nPPTX ) + (long) ( aVars.GetMargin()->GetRightMargin() * nPPTX ); - if ( nNeededWidth <= aClipRect.GetWidth() ) - bLeftClip = bRightClip = FALSE; + if ( nNeededWidth <= aAreaParam.maClipRect.GetWidth() ) + aAreaParam.mbLeftClip = aAreaParam.mbRightClip = FALSE; // If the "###" replacement doesn't fit into the cells, no clip marks // are shown, as the "###" already denotes too little space. // The rectangles from the first GetOutputArea call remain valid. } - long nJustPosX = aAlignRect.Left(); // "justified" - effect of alignment will be added - long nJustPosY = aAlignRect.Top(); - long nAvailWidth = aAlignRect.GetWidth(); - long nOutHeight = aAlignRect.GetHeight(); + long nJustPosX = aAreaParam.maAlignRect.Left(); // "justified" - effect of alignment will be added + long nJustPosY = aAreaParam.maAlignRect.Top(); + long nAvailWidth = aAreaParam.maAlignRect.GetWidth(); + long nOutHeight = aAreaParam.maAlignRect.GetHeight(); - BOOL bOutside = ( aClipRect.Right() < nScrX || aClipRect.Left() >= nScrX + nScrW ); - if ( aClipRect.Left() < nScrX ) + BOOL bOutside = ( aAreaParam.maClipRect.Right() < nScrX || aAreaParam.maClipRect.Left() >= nScrX + nScrW ); + if ( aAreaParam.maClipRect.Left() < nScrX ) { - aClipRect.Left() = nScrX; - bLeftClip = TRUE; + aAreaParam.maClipRect.Left() = nScrX; + aAreaParam.mbLeftClip = TRUE; } - if ( aClipRect.Right() > nScrX + nScrW ) + if ( aAreaParam.maClipRect.Right() > nScrX + nScrW ) { - aClipRect.Right() = nScrX + nScrW; //! minus one? - bRightClip = TRUE; + aAreaParam.maClipRect.Right() = nScrX + nScrW; //! minus one? + aAreaParam.mbRightClip = TRUE; } - BOOL bHClip = bLeftClip || bRightClip; + BOOL bHClip = aAreaParam.mbLeftClip || aAreaParam.mbRightClip; BOOL bVClip = FALSE; - if ( aClipRect.Top() < nScrY ) + if ( aAreaParam.maClipRect.Top() < nScrY ) { - aClipRect.Top() = nScrY; + aAreaParam.maClipRect.Top() = nScrY; bVClip = TRUE; } - if ( aClipRect.Bottom() > nScrY + nScrH ) + if ( aAreaParam.maClipRect.Bottom() > nScrY + nScrH ) { - aClipRect.Bottom() = nScrY + nScrH; //! minus one? + aAreaParam.maClipRect.Bottom() = nScrY + nScrH; //! minus one? bVClip = TRUE; } @@ -1603,27 +1791,27 @@ void ScOutputData::DrawStrings( BOOL bPixelToLogic ) if (!bHClip) { - aClipRect.Left() = nScrX; - aClipRect.Right() = nScrX+nScrW; + aAreaParam.maClipRect.Left() = nScrX; + aAreaParam.maClipRect.Right() = nScrX+nScrW; } if (!bVClip) { - aClipRect.Top() = nScrY; - aClipRect.Bottom() = nScrY+nScrH; + aAreaParam.maClipRect.Top() = nScrY; + aAreaParam.maClipRect.Bottom() = nScrY+nScrH; } // aClipRect is not used after SetClipRegion/IntersectClipRegion, // so it can be modified here if (bPixelToLogic) - aClipRect = pRefDevice->PixelToLogic( aClipRect ); + aAreaParam.maClipRect = pRefDevice->PixelToLogic( aAreaParam.maClipRect ); if (bMetaFile) { pDev->Push(); - pDev->IntersectClipRegion( aClipRect ); + pDev->IntersectClipRegion( aAreaParam.maClipRect ); } else - pDev->SetClipRegion( Region( aClipRect ) ); + pDev->SetClipRegion( Region( aAreaParam.maClipRect ) ); } Point aURLStart( nJustPosX, nJustPosY ); // copy before modifying for orientation @@ -1827,7 +2015,7 @@ long lcl_GetEditSize( EditEngine& rEngine, BOOL bWidth, BOOL bSwap, long nAttrRo void ScOutputData::ShrinkEditEngine( EditEngine& rEngine, const Rectangle& rAlignRect, long nLeftM, long nTopM, long nRightM, long nBottomM, BOOL bWidth, USHORT nOrient, long nAttrRotate, BOOL bPixelToLogic, - long& rEngineWidth, long& rEngineHeight, long& rNeededPixel, BOOL& rLeftClip, BOOL& rRightClip ) + long& rEngineWidth, long& rEngineHeight, long& rNeededPixel, bool& rLeftClip, bool& rRightClip ) { if ( !bWidth ) { @@ -2008,7 +2196,7 @@ void ScOutputData::DrawEdit(BOOL bPixelToLogic) if (bDoCell) { if ( nCellY == nY && nCellX >= nX1 && nCellX <= nX2 && - (pDoc->GetColFlags(nCellX,nTab) & CR_HIDDEN) == 0 ) + !pDoc->ColHidden(nCellX, nTab) ) { CellInfo& rCellInfo = pThisRowInfo->pCellInfo[nCellX+1]; pPattern = rCellInfo.pPatternAttr; @@ -2149,10 +2337,7 @@ void ScOutputData::DrawEdit(BOOL bPixelToLogic) nPosY = nScrY; } - Rectangle aAlignRect; - Rectangle aClipRect; - BOOL bLeftClip = FALSE; - BOOL bRightClip = FALSE; + OutputAreaParam aAreaParam; // // Initial page size - large for normal text, cell size for automatic line breaks @@ -2167,27 +2352,39 @@ void ScOutputData::DrawEdit(BOOL bPixelToLogic) //! handle nArrY == 0 GetOutputArea( nXForPos, nArrYForPos, nPosX, nPosY, nCellX, nCellY, 0, - *pPattern, sal::static_int_cast<USHORT>(eOutHorJust), - bCellIsValue, TRUE, FALSE, - aAlignRect, aClipRect, bLeftClip, bRightClip ); + *pPattern, sal::static_int_cast<USHORT>(eOutHorJust), + bCellIsValue, true, false, aAreaParam ); //! special ScEditUtil handling if formatting for printer if ( eOrient == SVX_ORIENTATION_TOPBOTTOM || eOrient == SVX_ORIENTATION_BOTTOMTOP ) - aPaperSize.Width() = aAlignRect.GetHeight() - nTopM - nBottomM; + aPaperSize.Width() = aAreaParam.maAlignRect.GetHeight() - nTopM - nBottomM; else - aPaperSize.Width() = aAlignRect.GetWidth() - nLeftM - nRightM; + aPaperSize.Width() = aAreaParam.maAlignRect.GetWidth() - nLeftM - nRightM; if (bAsianVertical && bBreak) { // add some extra height (default margin value) for safety // as long as GetEditArea isn't used below long nExtraHeight = (long)( 20 * nPPTY ); - aPaperSize.Height() = aAlignRect.GetHeight() - nTopM - nBottomM + nExtraHeight; + aPaperSize.Height() = aAreaParam.maAlignRect.GetHeight() - nTopM - nBottomM + nExtraHeight; } } if (bPixelToLogic) - pEngine->SetPaperSize(pRefDevice->PixelToLogic(aPaperSize)); + { + Size aLogicSize = pRefDevice->PixelToLogic(aPaperSize); + if ( bBreak && !bAsianVertical && pRefDevice != pFmtDevice ) + { + // #i85342# screen display and formatting for printer, + // use same GetEditArea call as in ScViewData::SetEditEngine + + Fraction aFract(1,1); + Rectangle aUtilRect = ScEditUtil( pDoc, nCellX, nCellY, nTab, Point(0,0), pFmtDevice, + HMM_PER_TWIPS, HMM_PER_TWIPS, aFract, aFract ).GetEditArea( pPattern, FALSE ); + aLogicSize.Width() = aUtilRect.GetWidth(); + } + pEngine->SetPaperSize(aLogicSize); + } else pEngine->SetPaperSize(aPaperSize); @@ -2372,26 +2569,26 @@ void ScOutputData::DrawEdit(BOOL bPixelToLogic) { // for break, the first GetOutputArea call is sufficient GetOutputArea( nXForPos, nArrYForPos, nPosX, nPosY, nCellX, nCellY, nNeededPixel, - *pPattern, sal::static_int_cast<USHORT>(eOutHorJust), - bCellIsValue || bRepeat || bShrink, FALSE, FALSE, - aAlignRect, aClipRect, bLeftClip, bRightClip ); + *pPattern, sal::static_int_cast<USHORT>(eOutHorJust), + bCellIsValue || bRepeat || bShrink, false, false, aAreaParam ); if ( bShrink ) { BOOL bWidth = ( eOrient == SVX_ORIENTATION_STANDARD && !bAsianVertical ); - ShrinkEditEngine( *pEngine, aAlignRect, + ShrinkEditEngine( *pEngine, aAreaParam.maAlignRect, nLeftM, nTopM, nRightM, nBottomM, bWidth, sal::static_int_cast<USHORT>(eOrient), 0, bPixelToLogic, - nEngineWidth, nEngineHeight, nNeededPixel, bLeftClip, bRightClip ); + nEngineWidth, nEngineHeight, nNeededPixel, + aAreaParam.mbLeftClip, aAreaParam.mbRightClip ); } - if ( bRepeat && !bLeftClip && !bRightClip && pEngine->GetParagraphCount() == 1 ) + if ( bRepeat && !aAreaParam.mbLeftClip && !aAreaParam.mbRightClip && pEngine->GetParagraphCount() == 1 ) { // First check if twice the space for the formatted text is available // (otherwise just keep it unchanged). long nFormatted = nNeededPixel - nLeftM - nRightM; // without margin - long nAvailable = aAlignRect.GetWidth() - nLeftM - nRightM; + long nAvailable = aAreaParam.maAlignRect.GetWidth() - nLeftM - nRightM; if ( nAvailable >= 2 * nFormatted ) { // "repeat" is handled with unformatted text (for performance reasons) @@ -2425,7 +2622,7 @@ void ScOutputData::DrawEdit(BOOL bPixelToLogic) } } - if ( bCellIsValue && ( bLeftClip || bRightClip ) ) + if ( bCellIsValue && ( aAreaParam.mbLeftClip || aAreaParam.mbRightClip ) ) { pEngine->SetText( String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("###")) ); nEngineWidth = (long) pEngine->CalcTextWidth(); @@ -2448,11 +2645,11 @@ void ScOutputData::DrawEdit(BOOL bPixelToLogic) } } - long nStartX = aAlignRect.Left(); - long nStartY = aAlignRect.Top(); - long nCellWidth = aAlignRect.GetWidth(); + long nStartX = aAreaParam.maAlignRect.Left(); + long nStartY = aAreaParam.maAlignRect.Top(); + long nCellWidth = aAreaParam.maAlignRect.GetWidth(); long nOutWidth = nCellWidth - 1 - nLeftM - nRightM; - long nOutHeight = aAlignRect.GetHeight() - nTopM - nBottomM; + long nOutHeight = aAreaParam.maAlignRect.GetHeight() - nTopM - nBottomM; if ( bBreak || eOrient != SVX_ORIENTATION_STANDARD || bAsianVertical ) { @@ -2472,21 +2669,21 @@ void ScOutputData::DrawEdit(BOOL bPixelToLogic) nStartX += nLeftM; } - BOOL bOutside = ( aClipRect.Right() < nScrX || aClipRect.Left() >= nScrX + nScrW ); - if ( aClipRect.Left() < nScrX ) + BOOL bOutside = ( aAreaParam.maClipRect.Right() < nScrX || aAreaParam.maClipRect.Left() >= nScrX + nScrW ); + if ( aAreaParam.maClipRect.Left() < nScrX ) { - aClipRect.Left() = nScrX; - bLeftClip = TRUE; + aAreaParam.maClipRect.Left() = nScrX; + aAreaParam.mbLeftClip = true; } - if ( aClipRect.Right() > nScrX + nScrW ) + if ( aAreaParam.maClipRect.Right() > nScrX + nScrW ) { - aClipRect.Right() = nScrX + nScrW; //! minus one? - bRightClip = TRUE; + aAreaParam.maClipRect.Right() = nScrX + nScrW; //! minus one? + aAreaParam.mbRightClip = true; } if ( !bHidden && !bOutside ) { - BOOL bClip = bLeftClip || bRightClip; + bool bClip = aAreaParam.mbLeftClip || aAreaParam.mbRightClip; BOOL bSimClip = FALSE; if ( bWrapFields ) @@ -2495,14 +2692,14 @@ void ScOutputData::DrawEdit(BOOL bPixelToLogic) bClip = TRUE; } - if ( aClipRect.Top() < nScrY ) + if ( aAreaParam.maClipRect.Top() < nScrY ) { - aClipRect.Top() = nScrY; + aAreaParam.maClipRect.Top() = nScrY; bClip = TRUE; } - if ( aClipRect.Bottom() > nScrY + nScrH ) + if ( aAreaParam.maClipRect.Bottom() > nScrY + nScrH ) { - aClipRect.Bottom() = nScrY + nScrH; //! minus one? + aAreaParam.maClipRect.Bottom() = nScrY + nScrH; //! minus one? bClip = TRUE; } @@ -2554,8 +2751,8 @@ void ScOutputData::DrawEdit(BOOL bPixelToLogic) bAnyClipped = TRUE; long nMarkPixel = (long)( SC_CLIPMARK_SIZE * nPPTX ); - if ( aClipRect.Right() - nMarkPixel > aClipRect.Left() ) - aClipRect.Right() -= nMarkPixel; + if ( aAreaParam.maClipRect.Right() - nMarkPixel > aAreaParam.maClipRect.Left() ) + aAreaParam.maClipRect.Right() -= nMarkPixel; } } @@ -2579,9 +2776,9 @@ void ScOutputData::DrawEdit(BOOL bPixelToLogic) // Clip marks are already handled in GetOutputArea if (bPixelToLogic) - aLogicClip = pRefDevice->PixelToLogic( aClipRect ); + aLogicClip = pRefDevice->PixelToLogic( aAreaParam.maClipRect ); else - aLogicClip = aClipRect; + aLogicClip = aAreaParam.maClipRect; if (bClip) // bei bSimClip nur aClipRect initialisieren { @@ -3215,10 +3412,7 @@ void ScOutputData::DrawRotated(BOOL bPixelToLogic) // use GetOutputArea to hide the grid // (clip region is done manually below) - BOOL bLeftClip = FALSE; - BOOL bRightClip = FALSE; - Rectangle aAlignRect; - Rectangle aClipRect; + OutputAreaParam aAreaParam; SCCOL nCellX = nX; SCROW nCellY = nY; @@ -3231,8 +3425,7 @@ void ScOutputData::DrawRotated(BOOL bPixelToLogic) GetOutputArea( nX, nArrY, nCellStartX, nPosY, nCellX, nCellY, nNeededWidth, *pPattern, sal::static_int_cast<USHORT>(eOutHorJust), - FALSE, FALSE, TRUE, - aAlignRect, aClipRect, bLeftClip, bRightClip ); + FALSE, FALSE, TRUE, aAreaParam ); if ( bShrink ) { @@ -3240,19 +3433,19 @@ void ScOutputData::DrawRotated(BOOL bPixelToLogic) pRefDevice->LogicToPixel(Size(nEngineWidth,0)).Width() : nEngineWidth; long nNeededPixel = nPixelWidth + nLeftM + nRightM; - bLeftClip = bRightClip = TRUE; + aAreaParam.mbLeftClip = aAreaParam.mbRightClip = TRUE; // always do height - ShrinkEditEngine( *pEngine, aAlignRect, nLeftM, nTopM, nRightM, nBottomM, + ShrinkEditEngine( *pEngine, aAreaParam.maAlignRect, nLeftM, nTopM, nRightM, nBottomM, FALSE, sal::static_int_cast<USHORT>(eOrient), nAttrRotate, bPixelToLogic, - nEngineWidth, nEngineHeight, nNeededPixel, bLeftClip, bRightClip ); + nEngineWidth, nEngineHeight, nNeededPixel, aAreaParam.mbLeftClip, aAreaParam.mbRightClip ); if ( eRotMode == SVX_ROTATE_MODE_STANDARD ) { // do width only if rotating within the cell (standard mode) - ShrinkEditEngine( *pEngine, aAlignRect, nLeftM, nTopM, nRightM, nBottomM, + ShrinkEditEngine( *pEngine, aAreaParam.maAlignRect, nLeftM, nTopM, nRightM, nBottomM, TRUE, sal::static_int_cast<USHORT>(eOrient), nAttrRotate, bPixelToLogic, - nEngineWidth, nEngineHeight, nNeededPixel, bLeftClip, bRightClip ); + nEngineWidth, nEngineHeight, nNeededPixel, aAreaParam.mbLeftClip, aAreaParam.mbRightClip ); } // nEngineWidth/nEngineHeight is updated in ShrinkEditEngine @@ -3306,19 +3499,19 @@ void ScOutputData::DrawRotated(BOOL bPixelToLogic) } if (bPixelToLogic) - aClipRect = pRefDevice->PixelToLogic( Rectangle( + aAreaParam.maClipRect = pRefDevice->PixelToLogic( Rectangle( Point(nClipStartX,nClipStartY), aClipSize ) ); else - aClipRect = Rectangle(Point(nClipStartX, nClipStartY), + aAreaParam.maClipRect = Rectangle(Point(nClipStartX, nClipStartY), aClipSize ); // Scale = 1 if (bMetaFile) { pDev->Push(); - pDev->IntersectClipRegion( aClipRect ); + pDev->IntersectClipRegion( aAreaParam.maClipRect ); } else - pDev->SetClipRegion( Region( aClipRect ) ); + pDev->SetClipRegion( Region( aAreaParam.maClipRect ) ); } Point aLogicStart; diff --git a/sc/source/ui/view/prevloc.cxx b/sc/source/ui/view/prevloc.cxx index 67e1aa86553a..fd36a1b2c1d0 100644 --- a/sc/source/ui/view/prevloc.cxx +++ b/sc/source/ui/view/prevloc.cxx @@ -350,9 +350,9 @@ Rectangle ScPreviewLocationData::GetOffsetPixel( const ScAddress& rCellPos, cons long nSizeX = (long) ( pDoc->GetColWidth( nEndCol, nTab ) * nScaleX ); SCROW nEndRow = rCellPos.Row(); - long nPosY = (long) pDoc->FastGetScaledRowHeight( rRange.aStart.Row(), + long nPosY = (long) pDoc->GetScaledRowHeight( rRange.aStart.Row(), nEndRow, nTab, nScaleY); - long nSizeY = (long) ( pDoc->FastGetRowHeight( nEndRow, nTab ) * nScaleY ); + long nSizeY = (long) ( pDoc->GetRowHeight( nEndRow, nTab ) * nScaleY ); Size aOffsetLogic( nPosX, nPosY ); Size aSizeLogic( nSizeX, nSizeY ); @@ -599,11 +599,11 @@ void ScPreviewLocationData::GetTableInfo( const Rectangle& rVisiblePixel, ScPrev ++nColCount; if ( bHasRepCols ) for ( nCol=nRepeatColStart; nCol<=nRepeatColEnd; nCol++ ) - if ( ( pDoc->GetColFlags( nCol, nTab ) & CR_HIDDEN ) == 0 ) + if (!pDoc->ColHidden(nCol, nTab)) ++nColCount; if ( bHasMainCols ) for ( nCol=nMainColStart; nCol<=nMainColEnd; nCol++ ) - if ( ( pDoc->GetColFlags( nCol, nTab ) & CR_HIDDEN ) == 0 ) + if (!pDoc->ColHidden(nCol, nTab)) ++nColCount; if ( nColCount > 0 ) @@ -620,7 +620,7 @@ void ScPreviewLocationData::GetTableInfo( const Rectangle& rVisiblePixel, ScPrev { long nPosX = 0; for ( nCol=nRepeatColStart; nCol<=nRepeatColEnd; nCol++ ) - if ( ( pDoc->GetColFlags( nCol, nTab ) & CR_HIDDEN ) == 0 ) + if (!pDoc->ColHidden(nCol, nTab)) { USHORT nDocW = pDoc->GetColWidth( nCol, nTab ); long nNextX = nPosX + (long) (nDocW * nScaleX); @@ -639,7 +639,7 @@ void ScPreviewLocationData::GetTableInfo( const Rectangle& rVisiblePixel, ScPrev { long nPosX = 0; for ( nCol=nMainColStart; nCol<=nMainColEnd; nCol++ ) - if ( ( pDoc->GetColFlags( nCol, nTab ) & CR_HIDDEN ) == 0 ) + if (!pDoc->ColHidden(nCol, nTab)) { USHORT nDocW = pDoc->GetColWidth( nCol, nTab ); long nNextX = nPosX + (long) (nDocW * nScaleX); @@ -667,11 +667,9 @@ void ScPreviewLocationData::GetTableInfo( const Rectangle& rVisiblePixel, ScPrev if ( bHasHeaderRow ) ++nRowCount; if ( bHasRepRows ) - nRowCount += pDoc->GetRowFlagsArray( nTab).CountForCondition( - nRepeatRowStart, nRepeatRowEnd, CR_HIDDEN, 0); + nRowCount += pDoc->CountVisibleRows(nRepeatRowStart, nRepeatRowEnd, nTab); if ( bHasMainRows ) - nRowCount += pDoc->GetRowFlagsArray( nTab).CountForCondition( - nMainRowStart, nMainRowEnd, CR_HIDDEN, 0); + nRowCount += pDoc->CountVisibleRows(nMainRowStart, nMainRowEnd, nTab); if ( nRowCount > 0 ) { @@ -686,58 +684,44 @@ void ScPreviewLocationData::GetTableInfo( const Rectangle& rVisiblePixel, ScPrev if ( bHasRepRows ) { long nPosY = 0; - ScCompressedArrayIterator< SCROW, BYTE> aIter( - pDoc->GetRowFlagsArray( nTab), nRepeatRowStart, - nRepeatRowEnd); - do + for (SCROW nRow = nRepeatRowStart; nRow <= nRepeatRowEnd; ++nRow) { - if ((*aIter & CR_HIDDEN) == 0) - { - SCROW nRangeEnd = aIter.GetRangeEnd(); - for (SCROW nRow=aIter.GetRangeStart(); nRow<=nRangeEnd; ++nRow) - { - USHORT nDocH = pDoc->FastGetOriginalRowHeight( nRow, nTab ); - long nNextY = nPosY + (long) (nDocH * nScaleY); - - long nPixelStart = pWindow->LogicToPixel( Size( 0, nPosY ), aCellMapMode ).Height(); - long nPixelEnd = pWindow->LogicToPixel( Size( 0, nNextY ), aCellMapMode ).Height() - 1; - pRowInfo[nRowPos].Set( FALSE, nRow, - aRepeatRect.Top() + nPixelStart, - aRepeatRect.Top() + nPixelEnd ); - - nPosY = nNextY; - ++nRowPos; - } - } - } while (aIter.NextRange()); + if (pDoc->RowHidden(nRow, nTab)) + continue; + + USHORT nDocH = pDoc->GetOriginalHeight( nRow, nTab ); + long nNextY = nPosY + (long) (nDocH * nScaleY); + + long nPixelStart = pWindow->LogicToPixel( Size( 0, nPosY ), aCellMapMode ).Height(); + long nPixelEnd = pWindow->LogicToPixel( Size( 0, nNextY ), aCellMapMode ).Height() - 1; + pRowInfo[nRowPos].Set( FALSE, nRow, + aRepeatRect.Top() + nPixelStart, + aRepeatRect.Top() + nPixelEnd ); + + nPosY = nNextY; + ++nRowPos; + } } if ( bHasMainRows ) { long nPosY = 0; - ScCompressedArrayIterator< SCROW, BYTE> aIter( - pDoc->GetRowFlagsArray( nTab), nMainRowStart, - nMainRowEnd); - do + for (SCROW nRow = nMainRowStart; nRow <= nMainRowEnd; ++nRow) { - if ((*aIter & CR_HIDDEN) == 0) - { - SCROW nRangeEnd = aIter.GetRangeEnd(); - for (SCROW nRow=aIter.GetRangeStart(); nRow<=nRangeEnd; ++nRow) - { - USHORT nDocH = pDoc->FastGetOriginalRowHeight( nRow, nTab ); - long nNextY = nPosY + (long) (nDocH * nScaleY); - - long nPixelStart = pWindow->LogicToPixel( Size( 0, nPosY ), aCellMapMode ).Height(); - long nPixelEnd = pWindow->LogicToPixel( Size( 0, nNextY ), aCellMapMode ).Height() - 1; - pRowInfo[nRowPos].Set( FALSE, nRow, - aMainRect.Top() + nPixelStart, - aMainRect.Top() + nPixelEnd ); - - nPosY = nNextY; - ++nRowPos; - } - } - } while (aIter.NextRange()); + if (pDoc->RowHidden(nRow, nTab)) + continue; + + USHORT nDocH = pDoc->GetOriginalHeight( nRow, nTab ); + long nNextY = nPosY + (long) (nDocH * nScaleY); + + long nPixelStart = pWindow->LogicToPixel( Size( 0, nPosY ), aCellMapMode ).Height(); + long nPixelEnd = pWindow->LogicToPixel( Size( 0, nNextY ), aCellMapMode ).Height() - 1; + pRowInfo[nRowPos].Set( FALSE, nRow, + aMainRect.Top() + nPixelStart, + aMainRect.Top() + nPixelEnd ); + + nPosY = nNextY; + ++nRowPos; + } } rInfo.SetRowInfo( nRowCount, pRowInfo ); } diff --git a/sc/source/ui/view/printfun.cxx b/sc/source/ui/view/printfun.cxx index afe23892e786..378ea1233cf9 100644..100755 --- a/sc/source/ui/view/printfun.cxx +++ b/sc/source/ui/view/printfun.cxx @@ -85,6 +85,8 @@ #include <vcl/lineinfo.hxx> #include <tools/pstm.hxx> +#include <boost/scoped_ptr.hpp> + #define ZOOM_MIN 10 #define GET_BOOL(set,which) ((const SfxBoolItem&)(set)->Get((which))).GetValue() @@ -1501,7 +1503,7 @@ void ScPrintFunc::PrintRowHdr( SCROW nY1, SCROW nY2, long nScrX, long nScrY ) for (SCROW nRow=nY1; nRow<=nY2; nRow++) { - USHORT nDocH = pDoc->FastGetRowHeight( nRow, nPrintTab ); + USHORT nDocH = pDoc->GetRowHeight( nRow, nPrintTab ); if (nDocH) { long nHeight = (long) (nDocH * nScaleY); @@ -1557,7 +1559,7 @@ void ScPrintFunc::LocateRowHdr( SCROW nY1, SCROW nY2, long nScrX, long nScrY, nEndX -= nOneX; long nPosY = nScrY - nOneY; - nPosY += pDoc->FastGetScaledRowHeight( nY1, nY2, nPrintTab, nScaleY); + nPosY += pDoc->GetScaledRowHeight( nY1, nY2, nPrintTab, nScaleY); Rectangle aCellRect( nScrX, nScrY, nEndX, nPosY ); rLocationData.AddRowHeaders( aCellRect, nY1, nY2, bRepRow ); } @@ -1599,7 +1601,7 @@ void ScPrintFunc::LocateArea( SCCOL nX1, SCROW nY1, SCCOL nX2, SCROW nY2, } long nPosY = nScrY - nOneY; - nPosY += pDoc->FastGetScaledRowHeight( nY1, nY2, nPrintTab, nScaleY); + nPosY += pDoc->GetScaledRowHeight( nY1, nY2, nPrintTab, nScaleY); Rectangle aCellRect( nScrX, nScrY, nPosX, nPosY ); rLocationData.AddCellRange( aCellRect, ScRange( nX1,nY1,nPrintTab, nX2,nY2,nPrintTab ), bRepCol, bRepRow, aDrawMapMode ); @@ -2181,9 +2183,9 @@ void ScPrintFunc::PrintPage( long nPageNo, SCCOL nX1, SCROW nY1, SCCOL nX2, SCRO } if ( bCenterVer ) { - long nDataHeight = pDoc->FastGetRowHeight( nY1, nY2, nPrintTab); + long nDataHeight = pDoc->GetRowHeight( nY1, nY2, nPrintTab); if (bDoRepRow) - nDataHeight += pDoc->FastGetRowHeight( nRepeatStartRow, + nDataHeight += pDoc->GetRowHeight( nRepeatStartRow, nRepeatEndRow, nPrintTab); if (aTableParam.bHeaders) nDataHeight += (long) PRINT_HEADER_HEIGHT; @@ -2216,11 +2218,11 @@ void ScPrintFunc::PrintPage( long nPageNo, SCCOL nX1, SCROW nY1, SCCOL nX2, SCRO for (SCCOL i=nRepeatStartCol; i<=nRepeatEndCol; i++) nRepeatWidth += (long) (pDoc->GetColWidth(i,nPrintTab) * nScaleX); if (bDoRepRow) - nRepeatHeight += pDoc->FastGetScaledRowHeight( nRepeatStartRow, + nRepeatHeight += pDoc->GetScaledRowHeight( nRepeatStartRow, nRepeatEndRow, nPrintTab, nScaleY); for (SCCOL i=nX1; i<=nX2; i++) nContentWidth += (long) (pDoc->GetColWidth(i,nPrintTab) * nScaleX); - nContentHeight += pDoc->FastGetScaledRowHeight( nY1, nY2, nPrintTab, + nContentHeight += pDoc->GetScaledRowHeight( nY1, nY2, nPrintTab, nScaleY); // partition the page @@ -2886,30 +2888,84 @@ void ScPrintFunc::CalcZoom( USHORT nRangeNo ) // Zoom bere if (aTableParam.bScalePageNum) { nZoom = 100; - BOOL bFound = FALSE; USHORT nPagesToFit = aTableParam.nScalePageNum; - while (!bFound) + + sal_uInt16 nLastFitZoom = 0, nLastNonFitZoom = 0; + while (true) { + if (nZoom <= ZOOM_MIN) + break; + CalcPages(); - if ( nPagesX * nPagesY <= nPagesToFit || nZoom <= ZOOM_MIN ) - bFound = TRUE; + bool bFitsPage = (nPagesX * nPagesY <= nPagesToFit); + + if (bFitsPage) + { + if (nZoom == 100) + // If it fits at 100 %, it's good enough for me. + break; + + nLastFitZoom = nZoom; + nZoom = (nLastNonFitZoom + nZoom) / 2; + + if (nLastFitZoom == nZoom) + // It converged. Use this zoom level. + break; + } else - --nZoom; + { + if (nZoom - nLastFitZoom <= 1) + { + nZoom = nLastFitZoom; + CalcPages(); + break; + } + + nLastNonFitZoom = nZoom; + nZoom = (nLastFitZoom + nZoom) / 2; + } } } else if (aTableParam.bScaleTo) { nZoom = 100; - BOOL bFound = FALSE; USHORT nW = aTableParam.nScaleWidth; USHORT nH = aTableParam.nScaleHeight; - while (!bFound) + + sal_uInt16 nLastFitZoom = 0, nLastNonFitZoom = 0; + while (true) { + if (nZoom <= ZOOM_MIN) + break; + CalcPages(); - if ( ((!nW || (nPagesX <= nW)) && (!nH || (nPagesY <= nH))) || (nZoom <= ZOOM_MIN) ) - bFound = TRUE; + bool bFitsPage = ((!nW || (nPagesX <= nW)) && (!nH || (nPagesY <= nH))); + + if (bFitsPage) + { + if (nZoom == 100) + // If it fits at 100 %, it's good enough for me. + break; + + nLastFitZoom = nZoom; + nZoom = (nLastNonFitZoom + nZoom) / 2; + + if (nLastFitZoom == nZoom) + // It converged. Use this zoom level. + break; + } else - --nZoom; + { + if (nZoom - nLastFitZoom <= 1) + { + nZoom = nLastFitZoom; + CalcPages(); + break; + } + + nLastNonFitZoom = nZoom; + nZoom = (nLastFitZoom + nZoom) / 2; + } } } else if (aTableParam.bScaleAll) @@ -3029,18 +3085,20 @@ void ScPrintFunc::CalcPages() // berechnet aPageRect und Seiten au nPagesY = 0; nTotalY = 0; - BOOL bVisCol = FALSE; + bool bVisCol = false; + SCCOL nLastCol = -1; for (SCCOL i=nStartCol; i<=nEndCol; i++) { - BYTE nFlags = pDoc->GetColFlags(i,nPrintTab); - if ( i>nStartCol && bVisCol && (nFlags & CR_PAGEBREAK) ) + bool bHidden = pDoc->ColHidden(i, nPrintTab, nLastCol); + bool bPageBreak = (pDoc->HasColBreak(i, nPrintTab) & BREAK_PAGE); + if ( i>nStartCol && bVisCol && bPageBreak ) { pPageEndX[nPagesX] = i-1; ++nPagesX; - bVisCol = FALSE; + bVisCol = false; } - if (!(nFlags & CR_HIDDEN)) - bVisCol = TRUE; + if (!bHidden) + bVisCol = true; } if (bVisCol) // auch am Ende keine leeren Seiten { @@ -3048,39 +3106,60 @@ void ScPrintFunc::CalcPages() // berechnet aPageRect und Seiten au ++nPagesX; } - BOOL bVisRow = FALSE; + bool bVisRow = false; SCROW nPageStartRow = nStartRow; - ScCompressedArrayIterator< SCROW, BYTE> aIter( pDoc->GetRowFlagsArray( - nPrintTab), nStartRow, nEndRow); - do + SCROW nLastVisibleRow = -1; + + ::boost::scoped_ptr<ScRowBreakIterator> pRowBreakIter(pDoc->GetRowBreakIterator(nPrintTab)); + SCROW nNextPageBreak = pRowBreakIter->first(); + while (nNextPageBreak != ScRowBreakIterator::NOT_FOUND && nNextPageBreak < nStartRow) + // Skip until the page break position is at the start row or greater. + nNextPageBreak = pRowBreakIter->next(); + + for (SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow) { - BYTE nFlags = *aIter; - SCROW nRangeEnd = aIter.GetRangeEnd(); - for (SCROW j=aIter.GetRangeStart(); j<=nRangeEnd; ++j) + bool bPageBreak = (nNextPageBreak == nRow); + if (bPageBreak) + nNextPageBreak = pRowBreakIter->next(); + + if (nRow > nStartRow && bVisRow && bPageBreak ) { - if ( j>nStartRow && bVisRow && (nFlags & CR_PAGEBREAK) ) + pPageEndY[nTotalY] = nRow-1; + ++nTotalY; + + if ( !aTableParam.bSkipEmpty || + !pDoc->IsPrintEmpty( nPrintTab, nStartCol, nPageStartRow, nEndCol, nRow-1 ) ) { - pPageEndY[nTotalY] = j-1; - ++nTotalY; + pPageRows[nPagesY].SetStartRow( nPageStartRow ); + pPageRows[nPagesY].SetEndRow( nRow-1 ); + pPageRows[nPagesY].SetPagesX( nPagesX ); + if (aTableParam.bSkipEmpty) + lcl_SetHidden( pDoc, nPrintTab, pPageRows[nPagesY], nStartCol, pPageEndX ); + ++nPagesY; + } - if ( !aTableParam.bSkipEmpty || - !pDoc->IsPrintEmpty( nPrintTab, nStartCol, nPageStartRow, nEndCol, j-1 ) ) - { - pPageRows[nPagesY].SetStartRow( nPageStartRow ); - pPageRows[nPagesY].SetEndRow( j-1 ); - pPageRows[nPagesY].SetPagesX( nPagesX ); - if (aTableParam.bSkipEmpty) - lcl_SetHidden( pDoc, nPrintTab, pPageRows[nPagesY], nStartCol, pPageEndX ); - ++nPagesY; - } + nPageStartRow = nRow; + bVisRow = false; + } - nPageStartRow = j; - bVisRow = FALSE; - } - if (!(nFlags & CR_HIDDEN)) - bVisRow = TRUE; + if (nRow <= nLastVisibleRow) + { + // This row is still visible. Don't bother calling RowHidden() to + // find out, for speed optimization. + bVisRow = true; + continue; + } + + SCROW nLastRow = -1; + if (!pDoc->RowHidden(nRow, nPrintTab, NULL, &nLastRow)) + { + bVisRow = true; + nLastVisibleRow = nLastRow; } - } while (aIter.NextRange()); + else + // skip all hidden rows. + nRow = nLastRow; + } if (bVisRow) { diff --git a/sc/source/ui/view/scextopt.cxx b/sc/source/ui/view/scextopt.cxx index bead62419bb3..1faa105d2bd7 100644 --- a/sc/source/ui/view/scextopt.cxx +++ b/sc/source/ui/view/scextopt.cxx @@ -36,7 +36,6 @@ // ============================================================================ ScExtDocSettings::ScExtDocSettings() : - maOleSize( ScAddress::INITIALIZE_INVALID ), mfTabBarWidth( -1.0 ), mnLinkCnt( 0 ), mnDisplTab( 0 ) diff --git a/sc/source/ui/view/select.cxx b/sc/source/ui/view/select.cxx index 4887895c8e6b..b2c9ffdc1395 100644 --- a/sc/source/ui/view/select.cxx +++ b/sc/source/ui/view/select.cxx @@ -275,12 +275,12 @@ BOOL __EXPORT ScViewFunctionSet::SetCursorAtPoint( const Point& rPointPixel, BOO ScDocument* pDoc = pViewData->GetDocument(); SCTAB nTab = pViewData->GetTabNo(); if ( bLeft && !bRightScroll ) - do --nPosX; while ( nPosX>=0 && ( pDoc->GetColFlags( nPosX, nTab ) & CR_HIDDEN ) ); + do --nPosX; while ( nPosX>=0 && pDoc->ColHidden( nPosX, nTab ) ); if ( bTop && !bBottomScroll ) { if (--nPosY >= 0) { - pDoc->GetRowFlagsArray( nTab).GetLastForCondition( 0, nPosY, CR_HIDDEN, 0); + nPosY = pDoc->LastVisibleRow(0, nPosY, nTab); if (!ValidRow(nPosY)) nPosY = -1; } @@ -476,7 +476,7 @@ BOOL ScViewFunctionSet::SetCursorAtCell( SCsCOL nPosX, SCsROW nPosY, BOOL bScrol { // #94321# in SetCursorAtPoint hidden columns are skipped. // They must be skipped here too, or the result will always be the first hidden column. - do ++nPosX; while ( nPosX<nStartX && ( pDoc->GetColFlags( nPosX, nTab ) & CR_HIDDEN ) ); + do ++nPosX; while ( nPosX<nStartX && pDoc->ColHidden(nPosX, nTab) ); for (SCCOL i=nPosX; i<nStartX; i++) nSizeX += pDoc->GetColWidth( i, nTab ); } @@ -491,8 +491,7 @@ BOOL ScViewFunctionSet::SetCursorAtCell( SCsCOL nPosX, SCsROW nPosY, BOOL bScrol // They must be skipped here too, or the result will always be the first hidden row. if (++nPosY < nStartY) { - nPosY = pDoc->GetRowFlagsArray( nTab).GetFirstForCondition( - nPosY, nStartY-1, CR_HIDDEN, 0); + nPosY = pDoc->FirstVisibleRow(nPosY, nStartY-1, nTab); if (!ValidRow(nPosY)) nPosY = nStartY; } 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/tabcont.cxx b/sc/source/ui/view/tabcont.cxx index c5572fb9844a..6014ded96e1e 100644 --- a/sc/source/ui/view/tabcont.cxx +++ b/sc/source/ui/view/tabcont.cxx @@ -59,13 +59,14 @@ ScTabControl::ScTabControl( Window* pParent, ScViewData* pData ) : DropTargetHelper( this ), DragSourceHelper( this ), pViewData( pData ), - nMouseClickPageId( TABBAR_PAGE_NOTFOUND ), - nSelPageIdByMouse( TABBAR_PAGE_NOTFOUND ), + nMouseClickPageId( TabBar::PAGE_NOT_FOUND ), + nSelPageIdByMouse( TabBar::PAGE_NOT_FOUND ), bErrorShown( FALSE ) { ScDocument* pDoc = pViewData->GetDocument(); String aString; + Color aTabBgColor; SCTAB nCount = pDoc->GetTableCount(); for (SCTAB i=0; i<nCount; i++) { @@ -77,6 +78,11 @@ ScTabControl::ScTabControl( Window* pParent, ScViewData* pData ) : InsertPage( static_cast<sal_uInt16>(i)+1, aString, TPB_SPECIAL ); else InsertPage( static_cast<sal_uInt16>(i)+1, aString ); + if ( !pDoc->IsDefaultTabBgColor(i) ) + { + aTabBgColor = pDoc->GetTabBgColor(i); + SetTabBgColor( static_cast<sal_uInt16>(i)+1, aTabBgColor ); + } } } } @@ -157,7 +163,7 @@ void ScTabControl::MouseButtonDown( const MouseEvent& rMEvt ) if( rMEvt.IsLeft() && (rMEvt.GetModifier() == 0) ) nMouseClickPageId = GetPageId( rMEvt.GetPosPixel() ); else - nMouseClickPageId = TABBAR_PAGE_NOTFOUND; + nMouseClickPageId = TabBar::PAGE_NOT_FOUND; TabBar::MouseButtonDown( rMEvt ); } @@ -168,7 +174,7 @@ void ScTabControl::MouseButtonUp( const MouseEvent& rMEvt ) // mouse button down and up on same page? if( nMouseClickPageId != GetPageId( aPos ) ) - nMouseClickPageId = TABBAR_PAGE_NOTFOUND; + nMouseClickPageId = TabBar::PAGE_NOT_FOUND; if ( rMEvt.GetClicks() == 2 && rMEvt.IsLeft() && nMouseClickPageId != 0 && nMouseClickPageId != TAB_PAGE_NOTFOUND ) { @@ -185,7 +191,7 @@ void ScTabControl::MouseButtonUp( const MouseEvent& rMEvt ) SfxDispatcher* pDispatcher = pViewData->GetViewShell()->GetViewFrame()->GetDispatcher(); pDispatcher->Execute( nSlot, SFX_CALLMODE_SYNCHRON | SFX_CALLMODE_RECORD ); // forget page ID, to be really sure that the dialog is not called twice - nMouseClickPageId = TABBAR_PAGE_NOTFOUND; + nMouseClickPageId = TabBar::PAGE_NOT_FOUND; } TabBar::MouseButtonUp( rMEvt ); @@ -197,7 +203,7 @@ void ScTabControl::Select() nSelPageIdByMouse = nMouseClickPageId; /* Reset nMouseClickPageId, so that next Select() call may invalidate nSelPageIdByMouse (i.e. if called from keyboard). */ - nMouseClickPageId = TABBAR_PAGE_NOTFOUND; + nMouseClickPageId = TabBar::PAGE_NOT_FOUND; ScModule* pScMod = SC_MOD(); ScDocument* pDoc = pViewData->GetDocument(); @@ -262,6 +268,7 @@ void ScTabControl::Select() rBind.Invalidate( FID_DELETE_TABLE ); rBind.Invalidate( FID_TABLE_SHOW ); rBind.Invalidate( FID_TABLE_HIDE ); + rBind.Invalidate( FID_TAB_SET_TAB_BG_COLOR ); // SetReference nur wenn der Konsolidieren-Dialog offen ist // (fuer Referenzen ueber mehrere Tabellen) @@ -288,16 +295,22 @@ void ScTabControl::UpdateStatus() SCTAB i; String aString; SCTAB nMaxCnt = Max( nCount, static_cast<SCTAB>(GetMaxId()) ); + Color aTabBgColor; BOOL bModified = FALSE; // Tabellen-Namen for (i=0; i<nMaxCnt && !bModified; i++) { if (pDoc->IsVisible(i)) + { pDoc->GetName(i,aString); + aTabBgColor = pDoc->GetTabBgColor(i); + } else + { aString.Erase(); + } - if (GetPageText(static_cast<sal_uInt16>(i)+1) != aString) + if ( (GetPageText(static_cast<sal_uInt16>(i)+1) != aString) || (GetTabBgColor(static_cast<sal_uInt16>(i)+1) != aTabBgColor) ) bModified = TRUE; } @@ -314,6 +327,11 @@ void ScTabControl::UpdateStatus() InsertPage( static_cast<sal_uInt16>(i)+1, aString, TPB_SPECIAL ); else InsertPage( static_cast<sal_uInt16>(i)+1, aString ); + if ( !pDoc->IsDefaultTabBgColor(i) ) + { + aTabBgColor = pDoc->GetTabBgColor(i); + SetTabBgColor( static_cast<sal_uInt16>(i)+1, aTabBgColor ); + } } } } @@ -371,7 +389,7 @@ void ScTabControl::ActivateView(BOOL bActivate) void ScTabControl::SetSheetLayoutRTL( BOOL bSheetRTL ) { SetEffectiveRTL( bSheetRTL ); - nSelPageIdByMouse = TABBAR_PAGE_NOTFOUND; + nSelPageIdByMouse = TabBar::PAGE_NOT_FOUND; } @@ -607,12 +625,12 @@ void ScTabControl::EndRenaming() void ScTabControl::Mirror() { TabBar::Mirror(); - if( nSelPageIdByMouse != TABBAR_PAGE_NOTFOUND ) + if( nSelPageIdByMouse != TabBar::PAGE_NOT_FOUND ) { Rectangle aRect( GetPageRect( GetCurPageId() ) ); if( !aRect.IsEmpty() ) SetPointerPosPixel( aRect.Center() ); - nSelPageIdByMouse = TABBAR_PAGE_NOTFOUND; // only once after a Select() + nSelPageIdByMouse = TabBar::PAGE_NOT_FOUND; // only once after a Select() } } diff --git a/sc/source/ui/view/tabview.cxx b/sc/source/ui/view/tabview.cxx index 4938defa437d..0bc4617a9af4 100644 --- a/sc/source/ui/view/tabview.cxx +++ b/sc/source/ui/view/tabview.cxx @@ -1439,7 +1439,7 @@ void ScTabView::ScrollX( long nDeltaX, ScHSplitPos eWhich, BOOL bUpdBars ) SCsCOL nDir = ( nDeltaX > 0 ) ? 1 : -1; ScDocument* pDoc = aViewData.GetDocument(); SCTAB nTab = aViewData.GetTabNo(); - while ( ( pDoc->GetColFlags( nNewX, nTab ) & CR_HIDDEN ) && + while ( pDoc->ColHidden(nNewX, nTab) && nNewX+nDir >= 0 && nNewX+nDir <= MAXCOL ) nNewX = sal::static_int_cast<SCsCOL>( nNewX + nDir ); @@ -1528,7 +1528,7 @@ void ScTabView::ScrollY( long nDeltaY, ScVSplitPos eWhich, BOOL bUpdBars ) SCsROW nDir = ( nDeltaY > 0 ) ? 1 : -1; ScDocument* pDoc = aViewData.GetDocument(); SCTAB nTab = aViewData.GetTabNo(); - while ( ( pDoc->GetRowFlags( nNewY, nTab ) & CR_HIDDEN ) && + while ( pDoc->RowHidden(nNewY, nTab) && nNewY+nDir >= 0 && nNewY+nDir <= MAXROW ) nNewY += nDir; @@ -1615,7 +1615,7 @@ SCROW lcl_LastVisible( ScViewData& rViewData ) SCTAB nTab = rViewData.GetTabNo(); SCROW nVis = MAXROW; - while ( nVis > 0 && pDoc->FastGetRowHeight( nVis, nTab ) == 0 ) + while ( nVis > 0 && pDoc->GetRowHeight( nVis, nTab ) == 0 ) --nVis; return nVis; } diff --git a/sc/source/ui/view/tabview2.cxx b/sc/source/ui/view/tabview2.cxx index b7a773ab2abd..674f6f8ae0ff 100644 --- a/sc/source/ui/view/tabview2.cxx +++ b/sc/source/ui/view/tabview2.cxx @@ -640,13 +640,13 @@ BOOL lcl_FitsInWindow( double fScaleX, double fScaleY, USHORT nZoom, } long nBlockY = 0; - ScCoupledCompressedArrayIterator< SCROW, BYTE, USHORT> aIter( - pDoc->GetRowFlagsArray( nTab), 0, nFixPosY-1, CR_HIDDEN, 0, - pDoc->GetRowHeightArray( nTab)); - for ( ; aIter; ++aIter) + for (SCROW nRow = 0; nRow <= nFixPosY-1; ++nRow) { + if (pDoc->RowHidden(nRow, nTab)) + continue; + // for frozen panes, add both parts - USHORT nRowTwips = *aIter; + USHORT nRowTwips = pDoc->GetRowHeight(nRow, nTab); if (nRowTwips) { nBlockY += (long)(nRowTwips * fScaleY); @@ -654,10 +654,9 @@ BOOL lcl_FitsInWindow( double fScaleX, double fScaleY, USHORT nZoom, return FALSE; } } - aIter.NewLimits( nStartRow, nEndRow); - for ( ; aIter; ++aIter) + for (SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow) { - USHORT nRowTwips = *aIter; + USHORT nRowTwips = pDoc->GetRowHeight(nRow, nTab); if (nRowTwips) { nBlockY += (long)(nRowTwips * fScaleY); diff --git a/sc/source/ui/view/tabview3.cxx b/sc/source/ui/view/tabview3.cxx index 750e49ec2334..86f68a1878cc 100644 --- a/sc/source/ui/view/tabview3.cxx +++ b/sc/source/ui/view/tabview3.cxx @@ -968,8 +968,8 @@ void ScTabView::MoveCursorRel( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode, BOOL bHFlip = FALSE; do { - BYTE nColFlags = pDoc->GetColFlags( nCurX, nTab ); - bSkipCell = (nColFlags & CR_HIDDEN) || pDoc->IsHorOverlapped( nCurX, nCurY, nTab ); + SCCOL nLastCol = -1; + bSkipCell = pDoc->ColHidden(nCurX, nTab, nLastCol) || pDoc->IsHorOverlapped( nCurX, nCurY, nTab ); if (bSkipProtected && !bSkipCell) bSkipCell = pDoc->HasAttrib(nCurX, nCurY, nTab, nCurX, nCurY, nTab, HASATTR_PROTECTED); if (bSkipUnprotected && !bSkipCell) @@ -1010,8 +1010,8 @@ void ScTabView::MoveCursorRel( SCsCOL nMovX, SCsROW nMovY, ScFollowMode eMode, BOOL bVFlip = FALSE; do { - BYTE nRowFlags = pDoc->GetRowFlags( nCurY, nTab ); - bSkipCell = (nRowFlags & CR_HIDDEN) || pDoc->IsVerOverlapped( nCurX, nCurY, nTab ); + SCROW nLastRow = -1; + bSkipCell = pDoc->RowHidden(nCurY, nTab, nLastRow) || pDoc->IsVerOverlapped( nCurX, nCurY, nTab ); if (bSkipProtected && !bSkipCell) bSkipCell = pDoc->HasAttrib(nCurX, nCurY, nTab, nCurX, nCurY, nTab, HASATTR_PROTECTED); if (bSkipUnprotected && !bSkipCell) @@ -2093,17 +2093,18 @@ void ScTabView::PaintRangeFinder( long nNumber ) BOOL bHiddenEdge = FALSE; SCROW nTmp; ScDocument* pDoc = aViewData.GetDocument(); - while ( nCol1 > 0 && ( pDoc->GetColFlags( nCol1, nTab ) & CR_HIDDEN ) ) + SCCOL nLastCol = -1; + while ( nCol1 > 0 && pDoc->ColHidden(nCol1, nTab, nLastCol) ) { --nCol1; bHiddenEdge = TRUE; } - while ( nCol2 < MAXCOL && ( pDoc->GetColFlags( nCol2, nTab ) & CR_HIDDEN ) ) + while ( nCol2 < MAXCOL && pDoc->ColHidden(nCol2, nTab, nLastCol) ) { ++nCol2; bHiddenEdge = TRUE; } - nTmp = pDoc->GetRowFlagsArray( nTab).GetLastForCondition( 0, nRow1, CR_HIDDEN, 0); + nTmp = pDoc->LastVisibleRow(0, nRow1, nTab); if (!ValidRow(nTmp)) nTmp = 0; if (nTmp < nRow1) @@ -2111,7 +2112,7 @@ void ScTabView::PaintRangeFinder( long nNumber ) nRow1 = nTmp; bHiddenEdge = TRUE; } - nTmp = pDoc->GetRowFlagsArray( nTab).GetFirstForCondition( nRow2, MAXROW, CR_HIDDEN, 0); + nTmp = pDoc->FirstVisibleRow(nRow2, MAXROW, nTab); if (!ValidRow(nTmp)) nTmp = MAXROW; if (nTmp > nRow2) diff --git a/sc/source/ui/view/tabview5.cxx b/sc/source/ui/view/tabview5.cxx index bc5c94c271e2..f0ac3fc42869 100644 --- a/sc/source/ui/view/tabview5.cxx +++ b/sc/source/ui/view/tabview5.cxx @@ -666,7 +666,7 @@ void ScTabView::MakeVisible( const Rectangle& rHMMRect ) if (nScrollY > 0) while (nScrollY > 0 && nPosY < MAXROW) { - nScrollY -= (long) ( pDoc->FastGetRowHeight(nPosY, nTab) * nPPTY ); + nScrollY -= (long) ( pDoc->GetRowHeight(nPosY, nTab) * nPPTY ); ++nPosY; ++nLinesY; } @@ -674,7 +674,7 @@ void ScTabView::MakeVisible( const Rectangle& rHMMRect ) while (nScrollY < 0 && nPosY > 0) { --nPosY; - nScrollY += (long) ( pDoc->FastGetRowHeight(nPosY, nTab) * nPPTY ); + nScrollY += (long) ( pDoc->GetRowHeight(nPosY, nTab) * nPPTY ); --nLinesY; } diff --git a/sc/source/ui/view/tabvwsh.cxx b/sc/source/ui/view/tabvwsh.cxx index 06aa294029d9..1733cf2e19b5 100644 --- a/sc/source/ui/view/tabvwsh.cxx +++ b/sc/source/ui/view/tabvwsh.cxx @@ -71,6 +71,7 @@ SFX_IMPL_INTERFACE(ScTabViewShell,SfxViewShell,ScResId(SCSTR_TABVIEWSHELL)) SFX_CHILDWINDOW_REGISTRATION(FID_INPUTLINE_STATUS); SFX_CHILDWINDOW_REGISTRATION(SfxTemplateDialogWrapper::GetChildWindowId()); SFX_CHILDWINDOW_CONTEXT_REGISTRATION(SID_NAVIGATOR); + SFX_CHILDWINDOW_REGISTRATION(SID_TASKPANE); SFX_CHILDWINDOW_REGISTRATION(ScNameDlgWrapper::GetChildWindowId()); SFX_CHILDWINDOW_REGISTRATION(ScSolverDlgWrapper::GetChildWindowId()); SFX_CHILDWINDOW_REGISTRATION(ScOptSolverDlgWrapper::GetChildWindowId()); diff --git a/sc/source/ui/view/tabvwshe.cxx b/sc/source/ui/view/tabvwshe.cxx index a94d73a4b022..c0af39226c3f 100644 --- a/sc/source/ui/view/tabvwshe.cxx +++ b/sc/source/ui/view/tabvwshe.cxx @@ -52,6 +52,7 @@ #include "editsh.hxx" #include "dociter.hxx" #include "inputhdl.hxx" +#include "document.hxx" //================================================================== @@ -88,6 +89,22 @@ String __EXPORT ScTabViewShell::GetSelectionText( BOOL bWholeWord ) else aRange.aEnd = aRange.aStart; } + else + { + // #i111531# with 1M rows it was necessary to limit the range + // to the actually used data area. + SCCOL nCol1, nCol2; + SCROW nRow1, nRow2; + SCTAB nTab1, nTab2; + aRange.GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2); + if (pDoc->ShrinkToUsedDataArea( nTab1, nCol1, nRow1, nCol2, nRow2, false)) + { + aRange.aStart.SetCol( nCol1 ); + aRange.aStart.SetRow( nRow1 ); + aRange.aEnd.SetCol( nCol2 ); + aRange.aEnd.SetRow( nRow2 ); + } + } ScImportExport aObj( pDoc, aRange ); aObj.SetFormulas( GetViewData()->GetOptions().GetOption( VOPT_FORMULAS ) ); diff --git a/sc/source/ui/view/tabvwshf.cxx b/sc/source/ui/view/tabvwshf.cxx index 144e90367252..db1ee8864c7b 100644 --- a/sc/source/ui/view/tabvwshf.cxx +++ b/sc/source/ui/view/tabvwshf.cxx @@ -28,12 +28,11 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sc.hxx" - - -// INCLUDE --------------------------------------------------------------- +#include <boost/scoped_ptr.hpp> #include "scitems.hxx" #include <sfx2/request.hxx> +#include <sfx2/viewfrm.hxx> #include <basic/sbstar.hxx> #include <layout/layout.hxx> #include <svl/languageoptions.hxx> @@ -41,6 +40,9 @@ #include <svl/whiter.hxx> #include <vcl/msgbox.hxx> #include <sfx2/objface.hxx> +#include <svx/svxdlg.hxx> +#include <editeng/colritem.hxx> + #include "tabvwsh.hxx" #include "sc.hrc" #include "docsh.hxx" @@ -52,9 +54,17 @@ //CHINA001 #include "strindlg.hxx" //CHINA001 #include "mvtabdlg.hxx" #include "docfunc.hxx" +#include "eventuno.hxx" #include "scabstdlg.hxx" //CHINA001 +#include "tabbgcolor.hxx" +#include "tabbgcolordlg.hxx" +#include "sccommands.h" + +using ::boost::scoped_ptr; +using namespace com::sun::star; + #define IS_AVAILABLE(WhichId,ppItem) \ (pReqArgs->GetItemState((WhichId), TRUE, ppItem ) == SFX_ITEM_SET) @@ -680,6 +690,135 @@ void ScTabViewShell::ExecuteTable( SfxRequest& rReq ) } break; + case FID_TAB_SET_TAB_BG_COLOR: + case FID_TAB_MENU_SET_TAB_BG_COLOR: + { + if ( nSlot == FID_TAB_MENU_SET_TAB_BG_COLOR ) + nSlot = FID_TAB_SET_TAB_BG_COLOR; + SCTAB nTabNr = pViewData->GetTabNo(); + ScMarkData& rMark = pViewData->GetMarkData(); + SCTAB nTabSelCount = rMark.GetSelectCount(); + if ( !pDoc->IsDocEditable() ) + break; + + if ( pDoc->IsTabProtected( nTabNr ) ) // ||nTabSelCount > 1 + break; + + if( pReqArgs != NULL ) + { + BOOL bDone = FALSE; + const SfxPoolItem* pItem; + Color aColor; + if( IS_AVAILABLE( FN_PARAM_1, &pItem ) ) + nTabNr = ((const SfxUInt16Item*)pItem)->GetValue(); + + if( IS_AVAILABLE( nSlot, &pItem ) ) + aColor = ((const SvxColorItem*)pItem)->GetValue(); + + if ( nTabSelCount > 1 ) + { + scoped_ptr<ScUndoTabColorInfo::List> + pTabColorList(new ScUndoTabColorInfo::List); + for (SCTAB nTab=0; nTab<nTabCount; nTab++) + { + if ( rMark.GetTableSelect(nTab) && !pDoc->IsTabProtected(nTab) ) + { + ScUndoTabColorInfo aTabColorInfo(nTab); + aTabColorInfo.maNewTabBgColor = aColor; + pTabColorList->push_back(aTabColorInfo); + } + } + bDone = SetTabBgColor( *pTabColorList ); + } + else + { + bDone = SetTabBgColor( aColor, nCurrentTab ); //ScViewFunc.SetTabBgColor + } + if( bDone ) + { + rReq.Done( *pReqArgs ); + } + } + else + { + USHORT nRet = RET_OK; /// temp + BOOL bDone = FALSE; /// temp + Color aTabBgColor; + Color aNewTabBgColor; + + aTabBgColor = pDoc->GetTabBgColor( nCurrentTab ); + ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create(); + DBG_ASSERT(pFact, "ScAbstractFactory create fail!"); + AbstractScTabBgColorDlg* pDlg = pFact->CreateScTabBgColorDlg( + GetDialogParent(), + String(ScResId(SCSTR_SET_TAB_BG_COLOR)), + String(ScResId(SCSTR_NO_TAB_BG_COLOR)), + aTabBgColor, + CMD_FID_TAB_SET_TAB_BG_COLOR, + RID_SCDLG_TAB_BG_COLOR); + while ( !bDone && nRet == RET_OK ) + { + nRet = pDlg->Execute(); + if( nRet == RET_OK ) + { + Color aSelectedColor; + pDlg->GetSelectedColor(aSelectedColor); + scoped_ptr<ScUndoTabColorInfo::List> + pTabColorList(new ScUndoTabColorInfo::List); + if ( nTabSelCount > 1 ) + { + for (SCTAB nTab=0; nTab<nTabCount; nTab++) + { + if ( rMark.GetTableSelect(nTab) && !pDoc->IsTabProtected(nTab) ) + { + ScUndoTabColorInfo aTabColorInfo(nTab); + aTabColorInfo.maNewTabBgColor = aSelectedColor; + pTabColorList->push_back(aTabColorInfo); + } + } + bDone = SetTabBgColor( *pTabColorList ); + } + else + { + bDone = SetTabBgColor( aSelectedColor, nCurrentTab ); //ScViewFunc.SetTabBgColor + } + if ( bDone ) + { + rReq.AppendItem( SvxColorItem( aTabBgColor, nSlot ) ); + rReq.Done(); + } + else + { + if( rReq.IsAPI() ) + { + StarBASIC::Error( SbERR_SETPROP_FAILED ); + } + } + } + } + delete( pDlg ); + } + } + break; + + case FID_TAB_EVENTS: + { + ScDocShell* pDocSh = pViewData->GetDocShell(); + uno::Reference<container::XNameReplace> xEvents( new ScSheetEventsObj( pDocSh, nCurrentTab ) ); + uno::Reference<frame::XFrame> xFrame = GetViewFrame()->GetFrame().GetFrameInterface(); + SvxAbstractDialogFactory* pDlgFactory = SvxAbstractDialogFactory::Create(); + if (pDlgFactory) + { + std::auto_ptr<VclAbstractDialog> pDialog( pDlgFactory->CreateSvxMacroAssignDlg( + GetDialogParent(), xFrame, false, xEvents, 0 ) ); + if ( pDialog.get() && pDialog->Execute() == RET_OK ) + { + // the dialog modifies the settings directly + } + } + } + break; + default: DBG_ERROR("Unbekannte Message bei ViewShell"); break; @@ -798,6 +937,23 @@ void ScTabViewShell::GetStateTable( SfxItemSet& rSet ) rSet.Put( SfxBoolItem( nWhich, pDoc->IsLayoutRTL( nTab ) ) ); } break; + + case FID_TAB_MENU_SET_TAB_BG_COLOR: + { + if ( !pDoc->IsDocEditable() + || ( pDocShell && pDocShell->IsDocShared() ) + || pDoc->IsTabProtected(nTab) ) + rSet.DisableItem( nWhich ); + } + break; + + case FID_TAB_SET_TAB_BG_COLOR: + { + Color aColor; + aColor = pDoc->GetTabBgColor( nTab ); + rSet.Put( SvxColorItem( aColor, nWhich ) ); + } + break; } nWhich = aIter.NextWhich(); } diff --git a/sc/source/ui/view/viewdata.cxx b/sc/source/ui/view/viewdata.cxx index 6b13c1bedcbf..c034836d4d4a 100644 --- a/sc/source/ui/view/viewdata.cxx +++ b/sc/source/ui/view/viewdata.cxx @@ -160,9 +160,6 @@ void ScViewDataTable::WriteUserDataSequence(uno::Sequence <beans::PropertyValue> pSettings[SC_TABLE_ZOOM_VALUE].Value <<= nZoomValue; pSettings[SC_TABLE_PAGE_VIEW_ZOOM_VALUE].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_PAGEVIEWZOOMVALUE)); pSettings[SC_TABLE_PAGE_VIEW_ZOOM_VALUE].Value <<= nPageZoomValue; - -// pSettings[SC_TABLE_SELECTED].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_TABLESELECTED)); -// pSettings[SC_TABLE_SELECTED].Value <<= bool(rViewData.GetMarkData().GetTableSelect( nTab )); } } @@ -273,6 +270,17 @@ void ScViewDataTable::ReadUserDataSequence(const uno::Sequence <beans::PropertyV aSettings[i].Value >>= bSelected; rViewData.GetMarkData().SelectTable( nTab, bSelected ); } + else if (sName.compareToAscii(SC_UNONAME_TABCOLOR) == 0) + { + // There are documents out there that have their tab color defined as a view setting. + sal_Int32 nColor = COL_AUTO; + aSettings[i].Value >>= nColor; + if (static_cast<ColorData>(nColor) != COL_AUTO) + { + ScDocument* pDoc = rViewData.GetDocument(); + pDoc->SetTabBgColor(nTab, Color(static_cast<ColorData>(nColor))); + } + } } if (eHSplitMode == SC_SPLIT_FIX) nFixPosX = SanitizeCol( static_cast<SCCOL>( bHasHSplitInTwips ? nTempPosHTw : nTempPosH )); @@ -1595,7 +1603,7 @@ Point ScViewData::GetScrPos( SCCOL nWhereX, SCROW nWhereY, ScSplitPos eWhich, nScrPosY = 65535; else { - nTSize = pDoc->FastGetRowHeight( nY, nTabNo ); + nTSize = pDoc->GetRowHeight( nY, nTabNo ); if (nTSize) { long nSizeYPix = ToPixel( nTSize, nPPTY ); @@ -1604,7 +1612,7 @@ Point ScViewData::GetScrPos( SCCOL nWhereX, SCROW nWhereY, ScSplitPos eWhich, else if ( nY < MAXROW ) { // skip multiple hidden rows (forward only for now) - SCROW nNext = pDoc->FastGetFirstNonHiddenRow( nY + 1, nTabNo ); + SCROW nNext = pDoc->FirstVisibleRow(nY + 1, MAXROW, nTabNo); if ( nNext > MAXROW ) nY = MAXROW; else @@ -1616,7 +1624,7 @@ Point ScViewData::GetScrPos( SCCOL nWhereX, SCROW nWhereY, ScSplitPos eWhich, for (nY=nPosY; nY>nWhereY;) { --nY; - nTSize = pDoc->FastGetRowHeight( nY, nTabNo ); + nTSize = pDoc->GetRowHeight( nY, nTabNo ); if (nTSize) { long nSizeYPix = ToPixel( nTSize, nPPTY ); @@ -1706,8 +1714,7 @@ SCROW ScViewData::CellsAtY( SCsROW nPosY, SCsROW nDir, ScVSplitPos eWhichY, USHO bOut = TRUE; else { -// USHORT nTSize = pDoc->GetRowHeight( nRowNo, nTabNo ); - USHORT nTSize = pDoc->FastGetRowHeight( nRowNo, nTabNo ); + USHORT nTSize = pDoc->GetRowHeight( nRowNo, nTabNo ); if (nTSize) { long nSizeYPix = ToPixel( nTSize, nPPTY ); @@ -1716,7 +1723,7 @@ SCROW ScViewData::CellsAtY( SCsROW nPosY, SCsROW nDir, ScVSplitPos eWhichY, USHO else if ( nDir == 1 && nRowNo < MAXROW ) { // skip multiple hidden rows (forward only for now) - SCROW nNext = pDoc->FastGetFirstNonHiddenRow( nRowNo + 1, nTabNo ); + SCROW nNext = pDoc->FirstVisibleRow(nRowNo + 1, MAXROW, nTabNo); if ( nNext > MAXROW ) { // same behavior as without the optimization: set bOut with nY=MAXROW+1 @@ -1779,11 +1786,19 @@ BOOL ScViewData::GetMergeSizePixel( SCCOL nX, SCROW nY, long& rSizeXPix, long& r for (SCCOL i=0; i<nCountX; i++) nOutWidth += ToPixel( pDoc->GetColWidth(nX+i,nTabNo), nPPTX ); SCROW nCountY = pMerge->GetRowMerge(); - ScCoupledCompressedArrayIterator< SCROW, BYTE, USHORT> aIter( - pDoc->GetRowFlagsArray( nTabNo), nY, nY+nCountY-1, CR_HIDDEN, - 0, pDoc->GetRowHeightArray( nTabNo)); - for ( ; aIter; ++aIter ) - nOutHeight += ToPixel( *aIter, nPPTY ); + + for (SCROW nRow = nY; nRow <= nY+nCountY-1; ++nRow) + { + SCROW nLastRow = nRow; + if (pDoc->RowHidden(nRow, nTabNo, NULL, &nLastRow)) + { + nRow = nLastRow; + continue; + } + + USHORT nHeight = pDoc->GetRowHeight(nRow, nTabNo); + nOutHeight += ToPixel(nHeight, nPPTY); + } rSizeXPix = nOutWidth; rSizeYPix = nOutHeight; @@ -1843,7 +1858,7 @@ BOOL ScViewData::GetPosFromPixel( long nClickX, long nClickY, ScSplitPos eWhich, { while ( rPosY<=MAXROW && nClickY >= nScrY ) { - nScrY += ToPixel( pDoc->FastGetRowHeight( rPosY, nTabNo ), nPPTY ); + nScrY += ToPixel( pDoc->GetRowHeight( rPosY, nTabNo ), nPPTY ); ++rPosY; } --rPosY; @@ -1853,7 +1868,7 @@ BOOL ScViewData::GetPosFromPixel( long nClickX, long nClickY, ScSplitPos eWhich, while ( rPosY>0 && nClickY < nScrY ) { --rPosY; - nScrY -= ToPixel( pDoc->FastGetRowHeight( rPosY, nTabNo ), nPPTY ); + nScrY -= ToPixel( pDoc->GetRowHeight( rPosY, nTabNo ), nPPTY ); } } @@ -1973,14 +1988,14 @@ void ScViewData::SetPosY( ScVSplitPos eWhich, SCROW nNewPosY ) if ( nNewPosY > nOldPosY ) for ( i=nOldPosY; i<nNewPosY; i++ ) { - long nThis = pDoc->FastGetRowHeight( i,nTabNo ); + long nThis = pDoc->GetRowHeight( i,nTabNo ); nTPosY -= nThis; nPixPosY -= ToPixel(sal::static_int_cast<USHORT>(nThis), nPPTY); } else for ( i=nNewPosY; i<nOldPosY; i++ ) { - long nThis = pDoc->FastGetRowHeight( i,nTabNo ); + long nThis = pDoc->GetRowHeight( i,nTabNo ); nTPosY += nThis; nPixPosY += ToPixel(sal::static_int_cast<USHORT>(nThis), nPPTY); } @@ -2010,7 +2025,7 @@ void ScViewData::RecalcPixPos() // nach Zoom-Aenderungen long nPixPosY = 0; SCROW nPosY = pThisTab->nPosY[eWhich]; for (SCROW j=0; j<nPosY; j++) - nPixPosY -= ToPixel(pDoc->FastGetRowHeight(j,nTabNo), nPPTY); + nPixPosY -= ToPixel(pDoc->GetRowHeight(j,nTabNo), nPPTY); pThisTab->nPixPosY[eWhich] = nPixPosY; } } @@ -2053,7 +2068,7 @@ void ScViewData::SetScreen( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 ) for (nRow=nRow1; nRow<=nRow2; nRow++) { - nTSize = pDoc->FastGetRowHeight( nRow, nTabNo ); + nTSize = pDoc->GetRowHeight( nRow, nTabNo ); if (nTSize) { nSizePix = ToPixel( nTSize, nPPTY ); @@ -2095,7 +2110,7 @@ void ScViewData::SetScreenPos( const Point& rVisAreaStart ) bEnd = FALSE; while (!bEnd) { - nAdd = (long) pDoc->FastGetRowHeight(nY1,nTabNo); + nAdd = (long) pDoc->GetRowHeight(nY1,nTabNo); if (nSize+nAdd <= nTwips+1 && nY1<MAXROW) { nSize += nAdd; @@ -3047,7 +3062,7 @@ BOOL ScViewData::UpdateFixY( SCTAB nTab ) // TRUE = Wert geaendert long nNewPos = 0; for (SCROW nY=pTabData[nTab]->nPosY[SC_SPLIT_TOP]; nY<nFix; nY++) { - USHORT nTSize = pLocalDoc->FastGetRowHeight( nY, nTab ); + USHORT nTSize = pLocalDoc->GetRowHeight( nY, nTab ); if (nTSize) { long nPix = ToPixel( nTSize, nPPTY ); diff --git a/sc/source/ui/view/viewfun2.cxx b/sc/source/ui/view/viewfun2.cxx index 5fcd094acffc..34fbbfdad5b5 100644 --- a/sc/source/ui/view/viewfun2.cxx +++ b/sc/source/ui/view/viewfun2.cxx @@ -86,7 +86,15 @@ #include "funcdesc.hxx" #include "docuno.hxx" #include "charthelper.hxx" +#include "tabbgcolor.hxx" +#include <basic/sbstar.hxx> +#include <com/sun/star/container/XNameContainer.hpp> +#include <com/sun/star/script/XLibraryContainer.hpp> +using namespace com::sun::star; + +// helper func defined in docfunc.cxx +void VBA_DeleteModule( ScDocShell& rDocSh, String& sModuleName ); // STATIC DATA --------------------------------------------------------------- @@ -2141,6 +2149,7 @@ BOOL ScViewFunc::DeleteTables(const SvShorts &TheTabs, BOOL bRecord ) { ScDocShell* pDocSh = GetViewData()->GetDocShell(); ScDocument* pDoc = pDocSh->GetDocument(); + BOOL bVbaEnabled = pDoc ? pDoc->IsInVBAMode() : FALSE; SCTAB nNewTab = TheTabs[0]; int i; WaitObject aWait( GetFrameWin() ); @@ -2193,6 +2202,8 @@ BOOL ScViewFunc::DeleteTables(const SvShorts &TheTabs, BOOL bRecord ) pUndoDoc->SetActiveScenario( nTab, bActive ); } pUndoDoc->SetVisible( nTab, pDoc->IsVisible( nTab ) ); + pUndoDoc->SetTabBgColor( nTab, pDoc->GetTabBgColor(nTab) ); + pUndoDoc->SetSheetEvents( nTab, pDoc->GetSheetEvents( nTab ) ); if ( pDoc->IsTabProtected( nTab ) ) pUndoDoc->SetTabProtection(nTab, pDoc->GetTabProtection(nTab)); @@ -2212,9 +2223,18 @@ BOOL ScViewFunc::DeleteTables(const SvShorts &TheTabs, BOOL bRecord ) for(i=TheTabs.Count()-1;i>=0;i--) { + String sCodeName; + BOOL bHasCodeName = pDoc->GetCodeName( TheTabs[sal::static_int_cast<USHORT>(i)], sCodeName ); if (pDoc->DeleteTab( TheTabs[sal::static_int_cast<USHORT>(i)], pUndoDoc )) { bDelDone = TRUE; + if( bVbaEnabled ) + { + if( bHasCodeName ) + { + VBA_DeleteModule( *pDocSh, sCodeName ); + } + } pDocSh->Broadcast( ScTablesHint( SC_TAB_DELETED, TheTabs[sal::static_int_cast<USHORT>(i)] ) ); } } @@ -2274,6 +2294,28 @@ BOOL ScViewFunc::RenameTable( const String& rName, SCTAB nTab ) //---------------------------------------------------------------------------- +bool ScViewFunc::SetTabBgColor( const Color& rColor, SCTAB nTab ) +{ + bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().SetTabBgColor( nTab, rColor, TRUE, FALSE ); + if (bSuccess) + { + GetViewData()->GetViewShell()->UpdateInputHandler(); + } + return bSuccess; +} + +bool ScViewFunc::SetTabBgColor( ScUndoTabColorInfo::List& rUndoSetTabBgColorInfoList ) +{ + bool bSuccess = GetViewData()->GetDocShell()->GetDocFunc().SetTabBgColor( rUndoSetTabBgColorInfoList, TRUE, FALSE ); + if (bSuccess) + { + GetViewData()->GetViewShell()->UpdateInputHandler(); + } + return bSuccess; +} + +//---------------------------------------------------------------------------- + void ScViewFunc::InsertAreaLink( const String& rFile, const String& rFilter, const String& rOptions, const String& rSource, ULONG nRefresh ) diff --git a/sc/source/ui/view/viewfun3.cxx b/sc/source/ui/view/viewfun3.cxx index dacb41cd1aea..24fab9ac2eba 100644 --- a/sc/source/ui/view/viewfun3.cxx +++ b/sc/source/ui/view/viewfun3.cxx @@ -1723,10 +1723,10 @@ BOOL ScViewFunc::MoveBlockTo( const ScRange& rSource, const ScAddress& rDestPos, BOOL bIncludeFiltered = bCut; if ( !bIncludeFiltered ) { - // manually find number of non-filtered rows - SCROW nPastedCount = pDocSh->GetDocument()->GetRowFlagsArray( - rSource.aStart.Tab()).CountForCondition( - rSource.aStart.Row(), rSource.aEnd.Row(), CR_FILTERED, 0); + // find number of non-filtered rows + SCROW nPastedCount = pDocSh->GetDocument()->CountNonFilteredRows( + rSource.aStart.Row(), rSource.aEnd.Row(), rSource.aStart.Tab()); + if ( nPastedCount == 0 ) nPastedCount = 1; aDestEnd.SetRow( rDestPos.Row() + nPastedCount - 1 ); diff --git a/sc/source/ui/view/viewfun5.cxx b/sc/source/ui/view/viewfun5.cxx index 9697cae3a57e..dc4e96bbbf34 100644 --- a/sc/source/ui/view/viewfun5.cxx +++ b/sc/source/ui/view/viewfun5.cxx @@ -110,7 +110,7 @@ BOOL ScViewFunc::PasteDataFormat( ULONG nFormatId, nXT += pDoc->GetColWidth(i,nTab); if (pDoc->IsNegativePage(nTab)) nXT = -nXT; - ULONG nYT = pDoc->FastGetRowHeight( 0, nPosY-1, nTab); + ULONG nYT = pDoc->GetRowHeight( 0, nPosY-1, nTab); aPos = Point( (long)(nXT * HMM_PER_TWIPS), (long)(nYT * HMM_PER_TWIPS) ); } } diff --git a/sc/source/ui/view/viewfunc.cxx b/sc/source/ui/view/viewfunc.cxx index 5d3bf97aa29c..231eb4e67562 100644 --- a/sc/source/ui/view/viewfunc.cxx +++ b/sc/source/ui/view/viewfunc.cxx @@ -2195,28 +2195,19 @@ void ScViewFunc::SetWidthOrHeight( BOOL bWidth, SCCOLROW nRangeCnt, SCCOLROW* pR { // fuer alle eingeblendeten CR_MANUALSIZE loeschen, // dann SetOptimalHeight mit bShrink = FALSE - ScCompressedArrayIterator< SCROW, BYTE> aIter( - pDoc->GetRowFlagsArray( nTab), nStartNo, - nEndNo); - do + for (SCROW nRow = nStartNo; nRow <= nEndNo; ++nRow) { - BYTE nOld = *aIter; - if ( (nOld & CR_HIDDEN) == 0 && ( nOld & CR_MANUALSIZE ) ) + SCROW nLastRow = nRow; + if (pDoc->RowHidden(nRow, nTab, NULL, &nLastRow)) { - SCROW nRangeEnd = aIter.GetRangeEnd(); - pDoc->SetRowFlags( aIter.GetRangeStart(), - nRangeEnd, nTab, - nOld & ~CR_MANUALSIZE); - aIter.Resync( nRangeEnd); - // Range may be extended due to merges and - // now aIter.GetRangeEnd() may point behind - // the previous row, but all flags of this - // range have the CR_MANUALSIZE bit - // removed, so it is safe to continue with - // the next range, not necessary to catch - // up with the remaining rows. + nRow = nLastRow; + continue; } - } while (aIter.NextRange()); + + BYTE nOld = pDoc->GetRowFlags(nRow, nTab); + if (nOld & CR_MANUALSIZE) + pDoc->SetRowFlags(nRow, nTab, nOld & ~CR_MANUALSIZE); + } } double nPPTX = GetViewData()->GetPPTX(); @@ -2258,8 +2249,7 @@ void ScViewFunc::SetWidthOrHeight( BOOL bWidth, SCCOLROW nRangeCnt, SCCOLROW* pR { for (SCCOL nCol=static_cast<SCCOL>(nStartNo); nCol<=static_cast<SCCOL>(nEndNo); nCol++) { - if ( eMode != SC_SIZE_VISOPT || - (pDoc->GetColFlags( nCol, nTab ) & CR_HIDDEN) == 0 ) + if ( eMode != SC_SIZE_VISOPT || !pDoc->ColHidden(nCol, nTab) ) { USHORT nThisSize = nSizeTwips; diff --git a/sc/source/ui/view/viewutil.cxx b/sc/source/ui/view/viewutil.cxx index f73346398ea1..a6b4e320d3ab 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; @@ -260,20 +271,19 @@ void ScViewUtil::UnmarkFiltered( ScMarkData& rMark, ScDocument* pDoc ) for (SCTAB nTab=0; nTab<nTabCount; nTab++) if ( rMark.GetTableSelect(nTab ) ) { - ScCompressedArrayIterator<SCROW, BYTE> aIter(pDoc->GetRowFlagsArray(nTab), nStartRow, nEndRow); - do + for (SCROW nRow = nStartRow; nRow <= nEndRow; ++nRow) { - if (*aIter & CR_FILTERED) + SCROW nLastRow = nRow; + if (pDoc->RowFiltered(nRow, nTab, NULL, &nLastRow)) { // use nStartCol/nEndCol, so the multi mark area isn't extended to all columns // (visible in repaint for indentation) - - rMark.SetMultiMarkArea( ScRange( nStartCol, aIter.GetRangeStart(), nTab, - nEndCol, aIter.GetRangeEnd(), nTab ), FALSE ); + rMark.SetMultiMarkArea( + ScRange(nStartCol, nRow, nTab, nEndCol, nLastRow, nTab), false); bChanged = true; + nRow = nLastRow; } } - while (aIter.NextRange()); } if ( bChanged && !rMark.HasAnyMultiMarks() ) @@ -284,34 +294,29 @@ void ScViewUtil::UnmarkFiltered( ScMarkData& rMark, ScDocument* pDoc ) // static -bool ScViewUtil::FitToUnfilteredRows( ScRange & rRange, const ScDocument * pDoc, size_t nRows ) +bool ScViewUtil::FitToUnfilteredRows( ScRange & rRange, ScDocument * pDoc, size_t nRows ) { SCTAB nTab = rRange.aStart.Tab(); bool bOneTabOnly = (nTab == rRange.aEnd.Tab()); // Always fit the range on its first sheet. DBG_ASSERT( bOneTabOnly, "ScViewUtil::ExtendToUnfilteredRows: works only on one sheet"); SCROW nStartRow = rRange.aStart.Row(); - // FillArrayForCondition() usually is the fastest to determine such a set - // in one pass, even if the array isn't used but the last element. - SCROW* pArr = new SCROW[nRows]; - size_t nCount = pDoc->GetRowFlagsArray( nTab).FillArrayForCondition( - nStartRow, MAXROW, CR_FILTERED, 0, pArr, nRows); - if (nCount) - rRange.aEnd.SetRow( pArr[nCount-1]); - delete [] pArr; - return nCount == nRows && bOneTabOnly; + SCROW nLastRow = pDoc->LastNonFilteredRow(nStartRow, MAXROW, nTab); + if (ValidRow(nLastRow)) + rRange.aEnd.SetRow(nLastRow); + SCROW nCount = pDoc->CountNonFilteredRows(nStartRow, MAXROW, nTab); + return static_cast<size_t>(nCount) == nRows && bOneTabOnly; } // static -bool ScViewUtil::HasFiltered( const ScRange& rRange, const ScDocument* pDoc ) +bool ScViewUtil::HasFiltered( const ScRange& rRange, ScDocument* pDoc ) { SCROW nStartRow = rRange.aStart.Row(); SCROW nEndRow = rRange.aEnd.Row(); for (SCTAB nTab=rRange.aStart.Tab(); nTab<=rRange.aEnd.Tab(); nTab++) { - if ( pDoc->GetRowFlagsArray( nTab).HasCondition( nStartRow, nEndRow, - CR_FILTERED, CR_FILTERED ) ) + if (pDoc->HasFilteredRows(nStartRow, nEndRow, nTab)) return true; } diff --git a/sc/uiconfig/scalc/accelerator/de/default.xml b/sc/uiconfig/scalc/accelerator/de/default.xml deleted file mode 100644 index d14c7294b071..000000000000 --- a/sc/uiconfig/scalc/accelerator/de/default.xml +++ /dev/null @@ -1,101 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<accel:acceleratorlist xmlns:accel="http://openoffice.org/2001/accel" xmlns:xlink="http://www.w3.org/1999/xlink"> - <accel:item accel:code="KEY_SUBTRACT" accel:mod1="true" xlink:href=".uno:DeleteCell"/> - <accel:item accel:code="KEY_ADD" accel:mod1="true" xlink:href=".uno:InsertCell"/> - <accel:item accel:code="KEY_ADD" accel:shift="true" accel:mod1="true" xlink:href=".uno:InsertCell"/> - <accel:item accel:code="KEY_F11" accel:shift="true" xlink:href=".uno:SaveAsTemplate"/> - <accel:item accel:code="KEY_F11" xlink:href=".uno:DesignerDialog"/> - <accel:item accel:code="KEY_F11" accel:mod1="true" xlink:href=".uno:StyleCatalog"/> - <accel:item accel:code="KEY_Y" accel:mod1="true" xlink:href=".uno:Redo"/> - <accel:item accel:code="KEY_Z" accel:mod1="true" xlink:href=".uno:Undo"/> - <accel:item accel:code="KEY_BACKSPACE" accel:mod2="true" xlink:href=".uno:Undo"/> - <accel:item accel:code="KEY_UNDO" xlink:href=".uno:Undo"/> - <accel:item accel:code="KEY_REPEAT" xlink:href=".uno:Repeat"/> - <accel:item accel:code="KEY_DOWN" xlink:href=".uno:GoDown"/> - <accel:item accel:code="KEY_UP" xlink:href=".uno:GoUp"/> - <accel:item accel:code="KEY_LEFT" xlink:href=".uno:GoLeft"/> - <accel:item accel:code="KEY_RIGHT" xlink:href=".uno:GoRight"/> - <accel:item accel:code="KEY_PAGEDOWN" xlink:href=".uno:GoDownBlock"/> - <accel:item accel:code="KEY_PAGEUP" xlink:href=".uno:GoUpBlock"/> - <accel:item accel:code="KEY_END" accel:mod1="true" xlink:href=".uno:GoToEndOfData"/> - <accel:item accel:code="KEY_HOME" accel:mod1="true" xlink:href=".uno:GoToStart"/> - <accel:item accel:code="KEY_HOME" xlink:href=".uno:GoToStartOfRow"/> - <accel:item accel:code="KEY_END" xlink:href=".uno:GoToEndOfRow"/> - <accel:item accel:code="KEY_F4" xlink:href=".uno:ViewDataSourceBrowser"/> - <accel:item accel:code="KEY_K" accel:shift="true" accel:mod1="true" xlink:href=".uno:Italic"/> - <accel:item accel:code="KEY_F" accel:shift="true" accel:mod1="true" xlink:href=".uno:Bold"/> - <accel:item accel:code="KEY_U" accel:shift="true" accel:mod1="true" xlink:href=".uno:Underline"/> - <accel:item accel:code="KEY_1" accel:mod1="true" xlink:href=".uno:FormatCellDialog"/> - <accel:item accel:code="KEY_5" accel:mod1="true" xlink:href=".uno:SpacePara15"/> - <accel:item accel:code="KEY_2" accel:mod1="true" xlink:href=".uno:SpacePara2"/> - <accel:item accel:code="KEY_F7" xlink:href=".uno:SpellDialog"/> - <accel:item accel:code="KEY_F7" accel:mod1="true" xlink:href=".uno:Thesaurus"/> - <accel:item accel:code="KEY_H" accel:mod1="true" xlink:href=".uno:SuperScript"/> - <accel:item accel:code="KEY_T" accel:mod1="true" xlink:href=".uno:SubScript"/> - <accel:item accel:code="KEY_F5" xlink:href=".uno:Navigator"/> - <accel:item accel:code="KEY_R" accel:shift="true" accel:mod1="true" xlink:href=".uno:Repaint"/> - <accel:item accel:code="KEY_4" accel:shift="true" accel:mod1="true" xlink:href=".uno:NumberFormatCurrency"/> - <accel:item accel:code="KEY_5" accel:shift="true" accel:mod1="true" xlink:href=".uno:NumberFormatPercent"/> - <accel:item accel:code="KEY_6" accel:shift="true" accel:mod1="true" xlink:href=".uno:NumberFormatStandard"/> - <accel:item accel:code="KEY_3" accel:shift="true" accel:mod1="true" xlink:href=".uno:NumberFormatDate"/> - <accel:item accel:code="KEY_1" accel:shift="true" accel:mod1="true" xlink:href=".uno:NumberFormatDecimal"/> - <accel:item accel:code="KEY_2" accel:shift="true" accel:mod1="true" xlink:href=".uno:NumberFormatScientific"/> - <accel:item accel:code="KEY_F2" accel:shift="true" accel:mod1="true" xlink:href=".uno:FocusInputLine"/> - <accel:item accel:code="KEY_F8" accel:shift="true" xlink:href=".uno:StatusSelectionModeExp"/> - <accel:item accel:code="KEY_F8" xlink:href=".uno:StatusSelectionModeExt"/> - <accel:item accel:code="KEY_F2" accel:mod1="true" xlink:href=".uno:FunctionDialog"/> - <accel:item accel:code="KEY_V" accel:shift="true" accel:mod1="true" xlink:href=".uno:PasteSpecial"/> - <accel:item accel:code="KEY_F8" accel:mod1="true" xlink:href=".uno:ViewValueHighlighting"/> - <accel:item accel:code="KEY_INSERT" xlink:href=".uno:InsertContents"/> - <accel:item accel:code="KEY_F3" accel:mod1="true" xlink:href=".uno:DefineName"/> - <accel:item accel:code="KEY_F9" xlink:href=".uno:Calculate"/> - <accel:item accel:code="KEY_F9" accel:shift="true" accel:mod1="true" xlink:href=".uno:CalculateHard"/> - <accel:item accel:code="KEY_F12" xlink:href=".uno:Group"/> - <accel:item accel:code="KEY_F12" accel:mod1="true" xlink:href=".uno:Ungroup"/> - <accel:item accel:code="KEY_L" accel:mod1="true" xlink:href=".uno:AlignLeft"/> - <accel:item accel:code="KEY_R" accel:mod1="true" xlink:href=".uno:AlignRight"/> - <accel:item accel:code="KEY_E" accel:mod1="true" xlink:href=".uno:AlignHorizontalCenter"/> - <accel:item accel:code="KEY_B" accel:mod1="true" xlink:href=".uno:AlignBlock"/> - <accel:item accel:code="KEY_F7" accel:shift="true" xlink:href=".uno:ShowPrecedents"/> - <accel:item accel:code="KEY_F5" accel:shift="true" xlink:href=".uno:ShowDependents"/> - <accel:item accel:code="KEY_DOWN" accel:shift="true" xlink:href=".uno:GoDownSel"/> - <accel:item accel:code="KEY_UP" accel:shift="true" xlink:href=".uno:GoUpSel"/> - <accel:item accel:code="KEY_LEFT" accel:shift="true" xlink:href=".uno:GoLeftSel"/> - <accel:item accel:code="KEY_RIGHT" accel:shift="true" xlink:href=".uno:GoRightSel"/> - <accel:item accel:code="KEY_PAGEDOWN" accel:shift="true" xlink:href=".uno:GoDownBlockSel"/> - <accel:item accel:code="KEY_PAGEUP" accel:shift="true" xlink:href=".uno:GoUpBlockSel"/> - <accel:item accel:code="KEY_HOME" accel:shift="true" accel:mod1="true" xlink:href=".uno:GoToStartSel"/> - <accel:item accel:code="KEY_END" accel:shift="true" accel:mod1="true" xlink:href=".uno:GoToEndOfDataSel"/> - <accel:item accel:code="KEY_HOME" accel:shift="true" xlink:href=".uno:GoToStartOfRowSel"/> - <accel:item accel:code="KEY_END" accel:shift="true" xlink:href=".uno:GoToEndOfRowSel"/> - <accel:item accel:code="KEY_UP" accel:mod1="true" xlink:href=".uno:GoUpToStartOfData"/> - <accel:item accel:code="KEY_DOWN" accel:mod1="true" xlink:href=".uno:GoDownToEndOfData"/> - <accel:item accel:code="KEY_LEFT" accel:mod1="true" xlink:href=".uno:GoLeftToStartOfData"/> - <accel:item accel:code="KEY_RIGHT" accel:mod1="true" xlink:href=".uno:GoRightToEndOfData"/> - <accel:item accel:code="KEY_UP" accel:shift="true" accel:mod1="true" xlink:href=".uno:GoUpToStartOfDataSel"/> - <accel:item accel:code="KEY_DOWN" accel:shift="true" accel:mod1="true" xlink:href=".uno:GoDownToEndOfDataSel"/> - <accel:item accel:code="KEY_LEFT" accel:shift="true" accel:mod1="true" xlink:href=".uno:GoLeftToStartOfDataSel"/> - <accel:item accel:code="KEY_RIGHT" accel:shift="true" accel:mod1="true" xlink:href=".uno:GoRightToEndOfDataSel"/> - <accel:item accel:code="KEY_PAGEDOWN" accel:mod1="true" xlink:href=".uno:JumpToNextTable"/> - <accel:item accel:code="KEY_PAGEUP" accel:mod1="true" xlink:href=".uno:JumpToPrevTable"/> - <accel:item accel:code="KEY_TAB" xlink:href=".uno:JumpToNextUnprotected"/> - <accel:item accel:code="KEY_TAB" accel:shift="true" xlink:href=".uno:JumpToPreviousUnprotected"/> - <accel:item accel:code="KEY_SPACE" accel:shift="true" accel:mod1="true" xlink:href=".uno:SelectColumn"/> - <accel:item accel:code="KEY_SPACE" accel:shift="true" xlink:href=".uno:SelectRow"/> - <accel:item accel:code="KEY_BACKSPACE" accel:shift="true" xlink:href=".uno:Deselect"/> - <accel:item accel:code="KEY_BACKSPACE" accel:mod1="true" xlink:href=".uno:GoToCurrentCell"/> - <accel:item accel:code="KEY_MULTIPLY" accel:mod1="true" xlink:href=".uno:SelectData"/> - <accel:item accel:code="KEY_F2" xlink:href=".uno:SetInputMode"/> - <accel:item accel:code="KEY_BACKSPACE" xlink:href=".uno:ClearContents"/> - <accel:item accel:code="KEY_ESCAPE" xlink:href=".uno:Cancel"/> - <accel:item accel:code="KEY_DIVIDE" accel:mod1="true" xlink:href=".uno:SelectArrayFormula"/> - <accel:item accel:code="KEY_PAGEDOWN" accel:shift="true" accel:mod1="true" xlink:href=".uno:JumpToNextTableSel"/> - <accel:item accel:code="KEY_PAGEUP" accel:shift="true" accel:mod1="true" xlink:href=".uno:JumpToPrevTableSel"/> - <accel:item accel:code="KEY_F4" accel:shift="true" xlink:href=".uno:ToggleRelative"/> - <accel:item accel:code="KEY_D" accel:mod1="true" xlink:href=".uno:DataSelect"/> - <accel:item accel:code="KEY_G" accel:mod1="true" xlink:href=".uno:RepeatSearch"/> - <accel:item accel:code="KEY_T" accel:shift="true" accel:mod1="true" xlink:href=".uno:FocusCellAddress"/> - <accel:item accel:code="KEY_F5" accel:shift="true" accel:mod1="true" xlink:href=".uno:FocusCellAddress"/> - <accel:item accel:code="KEY_M" accel:mod1="true" xlink:href=".uno:ResetAttributes"/> - <accel:item accel:code="KEY_J" accel:shift="true" accel:mod1="true" xlink:href=".uno:FullScreen"/> -</accel:acceleratorlist> diff --git a/sc/uiconfig/scalc/accelerator/en-GB/default.xml b/sc/uiconfig/scalc/accelerator/en-GB/default.xml deleted file mode 100644 index c08df67839d8..000000000000 --- a/sc/uiconfig/scalc/accelerator/en-GB/default.xml +++ /dev/null @@ -1,101 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<accel:acceleratorlist xmlns:accel="http://openoffice.org/2001/accel" xmlns:xlink="http://www.w3.org/1999/xlink"> - <accel:item accel:code="KEY_SUBTRACT" accel:mod1="true" xlink:href=".uno:DeleteCell"/> - <accel:item accel:code="KEY_ADD" accel:mod1="true" xlink:href=".uno:InsertCell"/> - <accel:item accel:code="KEY_ADD" accel:shift="true" accel:mod1="true" xlink:href=".uno:InsertCell"/> - <accel:item accel:code="KEY_F11" accel:shift="true" xlink:href=".uno:SaveAsTemplate"/> - <accel:item accel:code="KEY_F11" xlink:href=".uno:DesignerDialog"/> - <accel:item accel:code="KEY_F11" accel:mod1="true" xlink:href=".uno:StyleCatalog"/> - <accel:item accel:code="KEY_Y" accel:mod1="true" xlink:href=".uno:Redo"/> - <accel:item accel:code="KEY_Z" accel:mod1="true" xlink:href=".uno:Undo"/> - <accel:item accel:code="KEY_BACKSPACE" accel:mod2="true" xlink:href=".uno:Undo"/> - <accel:item accel:code="KEY_UNDO" xlink:href=".uno:Undo"/> - <accel:item accel:code="KEY_REPEAT" xlink:href=".uno:Repeat"/> - <accel:item accel:code="KEY_DOWN" xlink:href=".uno:GoDown"/> - <accel:item accel:code="KEY_UP" xlink:href=".uno:GoUp"/> - <accel:item accel:code="KEY_LEFT" xlink:href=".uno:GoLeft"/> - <accel:item accel:code="KEY_RIGHT" xlink:href=".uno:GoRight"/> - <accel:item accel:code="KEY_PAGEDOWN" xlink:href=".uno:GoDownBlock"/> - <accel:item accel:code="KEY_PAGEUP" xlink:href=".uno:GoUpBlock"/> - <accel:item accel:code="KEY_END" accel:mod1="true" xlink:href=".uno:GoToEndOfData"/> - <accel:item accel:code="KEY_HOME" accel:mod1="true" xlink:href=".uno:GoToStart"/> - <accel:item accel:code="KEY_HOME" xlink:href=".uno:GoToStartOfRow"/> - <accel:item accel:code="KEY_END" xlink:href=".uno:GoToEndOfRow"/> - <accel:item accel:code="KEY_F4" xlink:href=".uno:ViewDataSourceBrowser"/> - <accel:item accel:code="KEY_I" accel:mod1="true" xlink:href=".uno:Italic"/> - <accel:item accel:code="KEY_B" accel:mod1="true" xlink:href=".uno:Bold"/> - <accel:item accel:code="KEY_U" accel:mod1="true" xlink:href=".uno:Underline"/> - <accel:item accel:code="KEY_1" accel:mod1="true" xlink:href=".uno:FormatCellDialog"/> - <accel:item accel:code="KEY_5" accel:mod1="true" xlink:href=".uno:SpacePara15"/> - <accel:item accel:code="KEY_2" accel:mod1="true" xlink:href=".uno:SpacePara2"/> - <accel:item accel:code="KEY_F7" xlink:href=".uno:SpellDialog"/> - <accel:item accel:code="KEY_F7" accel:mod1="true" xlink:href=".uno:Thesaurus"/> - <accel:item accel:code="KEY_P" accel:shift="true" accel:mod1="true" xlink:href=".uno:SuperScript"/> - <accel:item accel:code="KEY_B" accel:shift="true" accel:mod1="true" xlink:href=".uno:SubScript"/> - <accel:item accel:code="KEY_F5" xlink:href=".uno:Navigator"/> - <accel:item accel:code="KEY_R" accel:shift="true" accel:mod1="true" xlink:href=".uno:Repaint"/> - <accel:item accel:code="KEY_3" accel:shift="true" accel:mod1="true" xlink:href=".uno:NumberFormatCurrency"/> - <accel:item accel:code="KEY_5" accel:shift="true" accel:mod1="true" xlink:href=".uno:NumberFormatPercent"/> - <accel:item accel:code="KEY_6" accel:shift="true" accel:mod1="true" xlink:href=".uno:NumberFormatStandard"/> - <accel:item accel:code="KEY_4" accel:shift="true" accel:mod1="true" xlink:href=".uno:NumberFormatDate"/> - <accel:item accel:code="KEY_1" accel:shift="true" accel:mod1="true" xlink:href=".uno:NumberFormatDecimal"/> - <accel:item accel:code="KEY_2" accel:shift="true" accel:mod1="true" xlink:href=".uno:NumberFormatScientific"/> - <accel:item accel:code="KEY_F2" accel:shift="true" accel:mod1="true" xlink:href=".uno:FocusInputLine"/> - <accel:item accel:code="KEY_F8" accel:shift="true" xlink:href=".uno:StatusSelectionModeExp"/> - <accel:item accel:code="KEY_F8" xlink:href=".uno:StatusSelectionModeExt"/> - <accel:item accel:code="KEY_F2" accel:mod1="true" xlink:href=".uno:FunctionDialog"/> - <accel:item accel:code="KEY_V" accel:shift="true" accel:mod1="true" xlink:href=".uno:PasteSpecial"/> - <accel:item accel:code="KEY_F8" accel:mod1="true" xlink:href=".uno:ViewValueHighlighting"/> - <accel:item accel:code="KEY_INSERT" xlink:href=".uno:InsertContents"/> - <accel:item accel:code="KEY_F3" accel:mod1="true" xlink:href=".uno:DefineName"/> - <accel:item accel:code="KEY_F9" xlink:href=".uno:Calculate"/> - <accel:item accel:code="KEY_F9" accel:shift="true" accel:mod1="true" xlink:href=".uno:CalculateHard"/> - <accel:item accel:code="KEY_F12" xlink:href=".uno:Group"/> - <accel:item accel:code="KEY_F12" accel:mod1="true" xlink:href=".uno:Ungroup"/> - <accel:item accel:code="KEY_L" accel:mod1="true" xlink:href=".uno:AlignLeft"/> - <accel:item accel:code="KEY_R" accel:mod1="true" xlink:href=".uno:AlignRight"/> - <accel:item accel:code="KEY_E" accel:mod1="true" xlink:href=".uno:AlignHorizontalCenter"/> - <accel:item accel:code="KEY_J" accel:mod1="true" xlink:href=".uno:AlignBlock"/> - <accel:item accel:code="KEY_F7" accel:shift="true" xlink:href=".uno:ShowPrecedents"/> - <accel:item accel:code="KEY_F5" accel:shift="true" xlink:href=".uno:ShowDependents"/> - <accel:item accel:code="KEY_DOWN" accel:shift="true" xlink:href=".uno:GoDownSel"/> - <accel:item accel:code="KEY_UP" accel:shift="true" xlink:href=".uno:GoUpSel"/> - <accel:item accel:code="KEY_LEFT" accel:shift="true" xlink:href=".uno:GoLeftSel"/> - <accel:item accel:code="KEY_RIGHT" accel:shift="true" xlink:href=".uno:GoRightSel"/> - <accel:item accel:code="KEY_PAGEDOWN" accel:shift="true" xlink:href=".uno:GoDownBlockSel"/> - <accel:item accel:code="KEY_PAGEUP" accel:shift="true" xlink:href=".uno:GoUpBlockSel"/> - <accel:item accel:code="KEY_HOME" accel:shift="true" accel:mod1="true" xlink:href=".uno:GoToStartSel"/> - <accel:item accel:code="KEY_END" accel:shift="true" accel:mod1="true" xlink:href=".uno:GoToEndOfDataSel"/> - <accel:item accel:code="KEY_HOME" accel:shift="true" xlink:href=".uno:GoToStartOfRowSel"/> - <accel:item accel:code="KEY_END" accel:shift="true" xlink:href=".uno:GoToEndOfRowSel"/> - <accel:item accel:code="KEY_UP" accel:mod1="true" xlink:href=".uno:GoUpToStartOfData"/> - <accel:item accel:code="KEY_DOWN" accel:mod1="true" xlink:href=".uno:GoDownToEndOfData"/> - <accel:item accel:code="KEY_LEFT" accel:mod1="true" xlink:href=".uno:GoLeftToStartOfData"/> - <accel:item accel:code="KEY_RIGHT" accel:mod1="true" xlink:href=".uno:GoRightToEndOfData"/> - <accel:item accel:code="KEY_UP" accel:shift="true" accel:mod1="true" xlink:href=".uno:GoUpToStartOfDataSel"/> - <accel:item accel:code="KEY_DOWN" accel:shift="true" accel:mod1="true" xlink:href=".uno:GoDownToEndOfDataSel"/> - <accel:item accel:code="KEY_LEFT" accel:shift="true" accel:mod1="true" xlink:href=".uno:GoLeftToStartOfDataSel"/> - <accel:item accel:code="KEY_RIGHT" accel:shift="true" accel:mod1="true" xlink:href=".uno:GoRightToEndOfDataSel"/> - <accel:item accel:code="KEY_PAGEDOWN" accel:mod1="true" xlink:href=".uno:JumpToNextTable"/> - <accel:item accel:code="KEY_PAGEUP" accel:mod1="true" xlink:href=".uno:JumpToPrevTable"/> - <accel:item accel:code="KEY_TAB" xlink:href=".uno:JumpToNextUnprotected"/> - <accel:item accel:code="KEY_TAB" accel:shift="true" xlink:href=".uno:JumpToPreviousUnprotected"/> - <accel:item accel:code="KEY_SPACE" accel:shift="true" accel:mod1="true" xlink:href=".uno:SelectColumn"/> - <accel:item accel:code="KEY_SPACE" accel:shift="true" xlink:href=".uno:SelectRow"/> - <accel:item accel:code="KEY_BACKSPACE" accel:shift="true" xlink:href=".uno:Deselect"/> - <accel:item accel:code="KEY_BACKSPACE" accel:mod1="true" xlink:href=".uno:GoToCurrentCell"/> - <accel:item accel:code="KEY_MULTIPLY" accel:mod1="true" xlink:href=".uno:SelectData"/> - <accel:item accel:code="KEY_F2" xlink:href=".uno:SetInputMode"/> - <accel:item accel:code="KEY_BACKSPACE" xlink:href=".uno:ClearContents"/> - <accel:item accel:code="KEY_ESCAPE" xlink:href=".uno:Cancel"/> - <accel:item accel:code="KEY_DIVIDE" accel:mod1="true" xlink:href=".uno:SelectArrayFormula"/> - <accel:item accel:code="KEY_PAGEDOWN" accel:shift="true" accel:mod1="true" xlink:href=".uno:JumpToNextTableSel"/> - <accel:item accel:code="KEY_PAGEUP" accel:shift="true" accel:mod1="true" xlink:href=".uno:JumpToPrevTableSel"/> - <accel:item accel:code="KEY_F4" accel:shift="true" xlink:href=".uno:ToggleRelative"/> - <accel:item accel:code="KEY_D" accel:mod1="true" xlink:href=".uno:DataSelect"/> - <accel:item accel:code="KEY_F" accel:shift="true" accel:mod1="true" xlink:href=".uno:RepeatSearch"/> - <accel:item accel:code="KEY_T" accel:shift="true" accel:mod1="true" xlink:href=".uno:FocusCellAddress"/> - <accel:item accel:code="KEY_F5" accel:shift="true" accel:mod1="true" xlink:href=".uno:FocusCellAddress"/> - <accel:item accel:code="KEY_M" accel:mod1="true" xlink:href=".uno:ResetAttributes"/> - <accel:item accel:code="KEY_J" accel:shift="true" accel:mod1="true" xlink:href=".uno:FullScreen"/> -</accel:acceleratorlist> diff --git a/sc/uiconfig/scalc/accelerator/en-US/default.xml b/sc/uiconfig/scalc/accelerator/en-US/default.xml deleted file mode 100644 index 1c4dbbd6877e..000000000000 --- a/sc/uiconfig/scalc/accelerator/en-US/default.xml +++ /dev/null @@ -1,102 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<accel:acceleratorlist xmlns:accel="http://openoffice.org/2001/accel" xmlns:xlink="http://www.w3.org/1999/xlink"> - <accel:item accel:code="KEY_SUBTRACT" accel:mod1="true" xlink:href=".uno:DeleteCell"/> - <accel:item accel:code="KEY_ADD" accel:mod1="true" xlink:href=".uno:InsertCell"/> - <accel:item accel:code="KEY_ADD" accel:shift="true" accel:mod1="true" xlink:href=".uno:InsertCell"/> - <accel:item accel:code="KEY_F11" accel:shift="true" xlink:href=".uno:SaveAsTemplate"/> - <accel:item accel:code="KEY_F11" xlink:href=".uno:DesignerDialog"/> - <accel:item accel:code="KEY_F11" accel:mod1="true" xlink:href=".uno:StyleCatalog"/> - <accel:item accel:code="KEY_Y" accel:mod1="true" xlink:href=".uno:Redo"/> - <accel:item accel:code="KEY_Z" accel:mod1="true" xlink:href=".uno:Undo"/> - <accel:item accel:code="KEY_BACKSPACE" accel:mod2="true" xlink:href=".uno:Undo"/> - <accel:item accel:code="KEY_UNDO" xlink:href=".uno:Undo"/> - <accel:item accel:code="KEY_REPEAT" xlink:href=".uno:Repeat"/> - <accel:item accel:code="KEY_DOWN" xlink:href=".uno:GoDown"/> - <accel:item accel:code="KEY_UP" xlink:href=".uno:GoUp"/> - <accel:item accel:code="KEY_LEFT" xlink:href=".uno:GoLeft"/> - <accel:item accel:code="KEY_RIGHT" xlink:href=".uno:GoRight"/> - <accel:item accel:code="KEY_PAGEDOWN" xlink:href=".uno:GoDownBlock"/> - <accel:item accel:code="KEY_PAGEUP" xlink:href=".uno:GoUpBlock"/> - <accel:item accel:code="KEY_END" accel:mod1="true" xlink:href=".uno:GoToEndOfData"/> - <accel:item accel:code="KEY_HOME" accel:mod1="true" xlink:href=".uno:GoToStart"/> - <accel:item accel:code="KEY_HOME" xlink:href=".uno:GoToStartOfRow"/> - <accel:item accel:code="KEY_END" xlink:href=".uno:GoToEndOfRow"/> - <accel:item accel:code="KEY_F4" xlink:href=".uno:ViewDataSourceBrowser"/> - <accel:item accel:code="KEY_I" accel:mod1="true" xlink:href=".uno:Italic"/> - <accel:item accel:code="KEY_B" accel:mod1="true" xlink:href=".uno:Bold"/> - <accel:item accel:code="KEY_U" accel:mod1="true" xlink:href=".uno:Underline"/> - <accel:item accel:code="KEY_1" accel:mod1="true" xlink:href=".uno:FormatCellDialog"/> - <accel:item accel:code="KEY_5" accel:mod1="true" xlink:href=".uno:SpacePara15"/> - <accel:item accel:code="KEY_2" accel:mod1="true" xlink:href=".uno:SpacePara2"/> - <accel:item accel:code="KEY_F7" xlink:href=".uno:SpellDialog"/> - <accel:item accel:code="KEY_F7" accel:mod1="true" xlink:href=".uno:Thesaurus"/> - <accel:item accel:code="KEY_P" accel:shift="true" accel:mod1="true" xlink:href=".uno:SuperScript"/> - <accel:item accel:code="KEY_B" accel:shift="true" accel:mod1="true" xlink:href=".uno:SubScript"/> - <accel:item accel:code="KEY_F5" xlink:href=".uno:Navigator"/> - <accel:item accel:code="KEY_R" accel:shift="true" accel:mod1="true" xlink:href=".uno:Repaint"/> - <accel:item accel:code="KEY_4" accel:shift="true" accel:mod1="true" xlink:href=".uno:NumberFormatCurrency"/> - <accel:item accel:code="KEY_5" accel:shift="true" accel:mod1="true" xlink:href=".uno:NumberFormatPercent"/> - <accel:item accel:code="KEY_6" accel:shift="true" accel:mod1="true" xlink:href=".uno:NumberFormatStandard"/> - <accel:item accel:code="KEY_3" accel:shift="true" accel:mod1="true" xlink:href=".uno:NumberFormatDate"/> - <accel:item accel:code="KEY_1" accel:shift="true" accel:mod1="true" xlink:href=".uno:NumberFormatDecimal"/> - <accel:item accel:code="KEY_2" accel:shift="true" accel:mod1="true" xlink:href=".uno:NumberFormatScientific"/> - <accel:item accel:code="KEY_F2" accel:shift="true" accel:mod1="true" xlink:href=".uno:FocusInputLine"/> - <accel:item accel:code="KEY_F8" accel:shift="true" xlink:href=".uno:StatusSelectionModeExp"/> - <accel:item accel:code="KEY_F8" xlink:href=".uno:StatusSelectionModeExt"/> - <accel:item accel:code="KEY_F2" accel:mod1="true" xlink:href=".uno:FunctionDialog"/> - <accel:item accel:code="KEY_V" accel:shift="true" accel:mod1="true" xlink:href=".uno:PasteSpecial"/> - <accel:item accel:code="KEY_F8" accel:mod1="true" xlink:href=".uno:ViewValueHighlighting"/> - <accel:item accel:code="KEY_INSERT" xlink:href=".uno:InsertContents"/> - <accel:item accel:code="KEY_F3" accel:mod1="true" xlink:href=".uno:DefineName"/> - <accel:item accel:code="KEY_F9" xlink:href=".uno:Calculate"/> - <accel:item accel:code="KEY_F9" accel:shift="true" accel:mod1="true" xlink:href=".uno:CalculateHard"/> - <accel:item accel:code="KEY_F12" xlink:href=".uno:Group"/> - <accel:item accel:code="KEY_F12" accel:mod1="true" xlink:href=".uno:Ungroup"/> - <accel:item accel:code="KEY_L" accel:mod1="true" xlink:href=".uno:AlignLeft"/> - <accel:item accel:code="KEY_R" accel:mod1="true" xlink:href=".uno:AlignRight"/> - <accel:item accel:code="KEY_E" accel:mod1="true" xlink:href=".uno:AlignHorizontalCenter"/> - <accel:item accel:code="KEY_J" accel:mod1="true" xlink:href=".uno:AlignBlock"/> - <accel:item accel:code="KEY_F7" accel:shift="true" xlink:href=".uno:ShowPrecedents"/> - <accel:item accel:code="KEY_F5" accel:shift="true" xlink:href=".uno:ShowDependents"/> - <accel:item accel:code="KEY_DOWN" accel:shift="true" xlink:href=".uno:GoDownSel"/> - <accel:item accel:code="KEY_UP" accel:shift="true" xlink:href=".uno:GoUpSel"/> - <accel:item accel:code="KEY_LEFT" accel:shift="true" xlink:href=".uno:GoLeftSel"/> - <accel:item accel:code="KEY_RIGHT" accel:shift="true" xlink:href=".uno:GoRightSel"/> - <accel:item accel:code="KEY_PAGEDOWN" accel:shift="true" xlink:href=".uno:GoDownBlockSel"/> - <accel:item accel:code="KEY_PAGEUP" accel:shift="true" xlink:href=".uno:GoUpBlockSel"/> - <accel:item accel:code="KEY_HOME" accel:shift="true" accel:mod1="true" xlink:href=".uno:GoToStartSel"/> - <accel:item accel:code="KEY_END" accel:shift="true" accel:mod1="true" xlink:href=".uno:GoToEndOfDataSel"/> - <accel:item accel:code="KEY_HOME" accel:shift="true" xlink:href=".uno:GoToStartOfRowSel"/> - <accel:item accel:code="KEY_END" accel:shift="true" xlink:href=".uno:GoToEndOfRowSel"/> - <accel:item accel:code="KEY_UP" accel:mod1="true" xlink:href=".uno:GoUpToStartOfData"/> - <accel:item accel:code="KEY_DOWN" accel:mod1="true" xlink:href=".uno:GoDownToEndOfData"/> - <accel:item accel:code="KEY_LEFT" accel:mod1="true" xlink:href=".uno:GoLeftToStartOfData"/> - <accel:item accel:code="KEY_RIGHT" accel:mod1="true" xlink:href=".uno:GoRightToEndOfData"/> - <accel:item accel:code="KEY_UP" accel:shift="true" accel:mod1="true" xlink:href=".uno:GoUpToStartOfDataSel"/> - <accel:item accel:code="KEY_DOWN" accel:shift="true" accel:mod1="true" xlink:href=".uno:GoDownToEndOfDataSel"/> - <accel:item accel:code="KEY_LEFT" accel:shift="true" accel:mod1="true" xlink:href=".uno:GoLeftToStartOfDataSel"/> - <accel:item accel:code="KEY_RIGHT" accel:shift="true" accel:mod1="true" xlink:href=".uno:GoRightToEndOfDataSel"/> - <accel:item accel:code="KEY_PAGEDOWN" accel:mod1="true" xlink:href=".uno:JumpToNextTable"/> - <accel:item accel:code="KEY_PAGEUP" accel:mod1="true" xlink:href=".uno:JumpToPrevTable"/> - <accel:item accel:code="KEY_TAB" xlink:href=".uno:JumpToNextUnprotected"/> - <accel:item accel:code="KEY_TAB" accel:shift="true" xlink:href=".uno:JumpToPreviousUnprotected"/> - <accel:item accel:code="KEY_SPACE" accel:shift="true" accel:mod1="true" xlink:href=".uno:SelectColumn"/> - <accel:item accel:code="KEY_SPACE" accel:shift="true" xlink:href=".uno:SelectRow"/> - <accel:item accel:code="KEY_BACKSPACE" accel:shift="true" xlink:href=".uno:Deselect"/> - <accel:item accel:code="KEY_BACKSPACE" accel:mod1="true" xlink:href=".uno:GoToCurrentCell"/> - <accel:item accel:code="KEY_MULTIPLY" accel:mod1="true" xlink:href=".uno:SelectData"/> - <accel:item accel:code="KEY_F2" xlink:href=".uno:SetInputMode"/> - <accel:item accel:code="KEY_BACKSPACE" xlink:href=".uno:ClearContents"/> - <accel:item accel:code="KEY_ESCAPE" xlink:href=".uno:Cancel"/> - <accel:item accel:code="KEY_DIVIDE" accel:mod1="true" xlink:href=".uno:SelectArrayFormula"/> - <accel:item accel:code="KEY_PAGEDOWN" accel:shift="true" accel:mod1="true" xlink:href=".uno:JumpToNextTableSel"/> - <accel:item accel:code="KEY_PAGEUP" accel:shift="true" accel:mod1="true" xlink:href=".uno:JumpToPrevTableSel"/> - <accel:item accel:code="KEY_F4" accel:shift="true" xlink:href=".uno:ToggleRelative"/> - <accel:item accel:code="KEY_D" accel:mod1="true" xlink:href=".uno:DataSelect"/> - <accel:item accel:code="KEY_F" accel:shift="true" accel:mod1="true" xlink:href=".uno:RepeatSearch"/> - <accel:item accel:code="KEY_T" accel:shift="true" accel:mod1="true" xlink:href=".uno:FocusCellAddress"/> - <accel:item accel:code="KEY_F5" accel:shift="true" accel:mod1="true" xlink:href=".uno:FocusCellAddress"/> - <accel:item accel:code="KEY_M" accel:mod1="true" xlink:href=".uno:ResetAttributes"/> - <accel:item accel:code="KEY_J" accel:shift="true" accel:mod1="true" xlink:href=".uno:FullScreen"/> - <accel:item accel:code="KEY_QUOTELEFT" accel:mod1="true" xlink:href=".uno:ToggleFormula"/> -</accel:acceleratorlist> diff --git a/sc/uiconfig/scalc/accelerator/es/default.xml b/sc/uiconfig/scalc/accelerator/es/default.xml deleted file mode 100644 index 359be420a6d1..000000000000 --- a/sc/uiconfig/scalc/accelerator/es/default.xml +++ /dev/null @@ -1,101 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<accel:acceleratorlist xmlns:accel="http://openoffice.org/2001/accel" xmlns:xlink="http://www.w3.org/1999/xlink"> - <accel:item accel:code="KEY_SUBTRACT" accel:mod1="true" xlink:href=".uno:DeleteCell"/> - <accel:item accel:code="KEY_ADD" accel:mod1="true" xlink:href=".uno:InsertCell"/> - <accel:item accel:code="KEY_ADD" accel:shift="true" accel:mod1="true" xlink:href=".uno:InsertCell"/> - <accel:item accel:code="KEY_F11" accel:shift="true" xlink:href=".uno:SaveAsTemplate"/> - <accel:item accel:code="KEY_F11" xlink:href=".uno:DesignerDialog"/> - <accel:item accel:code="KEY_F11" accel:mod1="true" xlink:href=".uno:StyleCatalog"/> - <accel:item accel:code="KEY_Y" accel:mod1="true" xlink:href=".uno:Redo"/> - <accel:item accel:code="KEY_Z" accel:mod1="true" xlink:href=".uno:Undo"/> - <accel:item accel:code="KEY_BACKSPACE" accel:mod2="true" xlink:href=".uno:Undo"/> - <accel:item accel:code="KEY_UNDO" xlink:href=".uno:Undo"/> - <accel:item accel:code="KEY_REPEAT" xlink:href=".uno:Repeat"/> - <accel:item accel:code="KEY_DOWN" xlink:href=".uno:GoDown"/> - <accel:item accel:code="KEY_UP" xlink:href=".uno:GoUp"/> - <accel:item accel:code="KEY_LEFT" xlink:href=".uno:GoLeft"/> - <accel:item accel:code="KEY_RIGHT" xlink:href=".uno:GoRight"/> - <accel:item accel:code="KEY_PAGEDOWN" xlink:href=".uno:GoDownBlock"/> - <accel:item accel:code="KEY_PAGEUP" xlink:href=".uno:GoUpBlock"/> - <accel:item accel:code="KEY_END" accel:mod1="true" xlink:href=".uno:GoToEndOfData"/> - <accel:item accel:code="KEY_HOME" accel:mod1="true" xlink:href=".uno:GoToStart"/> - <accel:item accel:code="KEY_HOME" xlink:href=".uno:GoToStartOfRow"/> - <accel:item accel:code="KEY_END" xlink:href=".uno:GoToEndOfRow"/> - <accel:item accel:code="KEY_F4" xlink:href=".uno:ViewDataSourceBrowser"/> - <accel:item accel:code="KEY_K" accel:mod1="true" xlink:href=".uno:Italic"/> - <accel:item accel:code="KEY_N" accel:mod1="true" xlink:href=".uno:Bold"/> - <accel:item accel:code="KEY_S" accel:mod1="true" xlink:href=".uno:Underline"/> - <accel:item accel:code="KEY_1" accel:mod1="true" xlink:href=".uno:FormatCellDialog"/> - <accel:item accel:code="KEY_5" accel:mod1="true" xlink:href=".uno:SpacePara15"/> - <accel:item accel:code="KEY_2" accel:mod1="true" xlink:href=".uno:SpacePara2"/> - <accel:item accel:code="KEY_F7" xlink:href=".uno:SpellDialog"/> - <accel:item accel:code="KEY_F7" accel:mod1="true" xlink:href=".uno:Thesaurus"/> - <accel:item accel:code="KEY_P" accel:shift="true" accel:mod1="true" xlink:href=".uno:SuperScript"/> - <accel:item accel:code="KEY_B" accel:shift="true" accel:mod1="true" xlink:href=".uno:SubScript"/> - <accel:item accel:code="KEY_F5" xlink:href=".uno:Navigator"/> - <accel:item accel:code="KEY_R" accel:shift="true" accel:mod1="true" xlink:href=".uno:Repaint"/> - <accel:item accel:code="KEY_4" accel:shift="true" accel:mod1="true" xlink:href=".uno:NumberFormatCurrency"/> - <accel:item accel:code="KEY_5" accel:shift="true" accel:mod1="true" xlink:href=".uno:NumberFormatPercent"/> - <accel:item accel:code="KEY_6" accel:shift="true" accel:mod1="true" xlink:href=".uno:NumberFormatStandard"/> - <accel:item accel:code="KEY_3" accel:shift="true" accel:mod1="true" xlink:href=".uno:NumberFormatDate"/> - <accel:item accel:code="KEY_1" accel:shift="true" accel:mod1="true" xlink:href=".uno:NumberFormatDecimal"/> - <accel:item accel:code="KEY_2" accel:shift="true" accel:mod1="true" xlink:href=".uno:NumberFormatScientific"/> - <accel:item accel:code="KEY_F2" accel:shift="true" accel:mod1="true" xlink:href=".uno:FocusInputLine"/> - <accel:item accel:code="KEY_F8" accel:shift="true" xlink:href=".uno:StatusSelectionModeExp"/> - <accel:item accel:code="KEY_F8" xlink:href=".uno:StatusSelectionModeExt"/> - <accel:item accel:code="KEY_F2" accel:mod1="true" xlink:href=".uno:FunctionDialog"/> - <accel:item accel:code="KEY_V" accel:shift="true" accel:mod1="true" xlink:href=".uno:PasteSpecial"/> - <accel:item accel:code="KEY_F8" accel:mod1="true" xlink:href=".uno:ViewValueHighlighting"/> - <accel:item accel:code="KEY_INSERT" xlink:href=".uno:InsertContents"/> - <accel:item accel:code="KEY_F3" accel:mod1="true" xlink:href=".uno:DefineName"/> - <accel:item accel:code="KEY_F9" xlink:href=".uno:Calculate"/> - <accel:item accel:code="KEY_F9" accel:shift="true" accel:mod1="true" xlink:href=".uno:CalculateHard"/> - <accel:item accel:code="KEY_F12" xlink:href=".uno:Group"/> - <accel:item accel:code="KEY_F12" accel:mod1="true" xlink:href=".uno:Ungroup"/> - <accel:item accel:code="KEY_L" accel:mod1="true" xlink:href=".uno:AlignLeft"/> - <accel:item accel:code="KEY_R" accel:mod1="true" xlink:href=".uno:AlignRight"/> - <accel:item accel:code="KEY_T" accel:mod1="true" xlink:href=".uno:AlignHorizontalCenter"/> - <accel:item accel:code="KEY_J" accel:mod1="true" xlink:href=".uno:AlignBlock"/> - <accel:item accel:code="KEY_F7" accel:shift="true" xlink:href=".uno:ShowPrecedents"/> - <accel:item accel:code="KEY_F5" accel:shift="true" xlink:href=".uno:ShowDependents"/> - <accel:item accel:code="KEY_DOWN" accel:shift="true" xlink:href=".uno:GoDownSel"/> - <accel:item accel:code="KEY_UP" accel:shift="true" xlink:href=".uno:GoUpSel"/> - <accel:item accel:code="KEY_LEFT" accel:shift="true" xlink:href=".uno:GoLeftSel"/> - <accel:item accel:code="KEY_RIGHT" accel:shift="true" xlink:href=".uno:GoRightSel"/> - <accel:item accel:code="KEY_PAGEDOWN" accel:shift="true" xlink:href=".uno:GoDownBlockSel"/> - <accel:item accel:code="KEY_PAGEUP" accel:shift="true" xlink:href=".uno:GoUpBlockSel"/> - <accel:item accel:code="KEY_HOME" accel:shift="true" accel:mod1="true" xlink:href=".uno:GoToStartSel"/> - <accel:item accel:code="KEY_END" accel:shift="true" accel:mod1="true" xlink:href=".uno:GoToEndOfDataSel"/> - <accel:item accel:code="KEY_HOME" accel:shift="true" xlink:href=".uno:GoToStartOfRowSel"/> - <accel:item accel:code="KEY_END" accel:shift="true" xlink:href=".uno:GoToEndOfRowSel"/> - <accel:item accel:code="KEY_UP" accel:mod1="true" xlink:href=".uno:GoUpToStartOfData"/> - <accel:item accel:code="KEY_DOWN" accel:mod1="true" xlink:href=".uno:GoDownToEndOfData"/> - <accel:item accel:code="KEY_LEFT" accel:mod1="true" xlink:href=".uno:GoLeftToStartOfData"/> - <accel:item accel:code="KEY_RIGHT" accel:mod1="true" xlink:href=".uno:GoRightToEndOfData"/> - <accel:item accel:code="KEY_UP" accel:shift="true" accel:mod1="true" xlink:href=".uno:GoUpToStartOfDataSel"/> - <accel:item accel:code="KEY_DOWN" accel:shift="true" accel:mod1="true" xlink:href=".uno:GoDownToEndOfDataSel"/> - <accel:item accel:code="KEY_LEFT" accel:shift="true" accel:mod1="true" xlink:href=".uno:GoLeftToStartOfDataSel"/> - <accel:item accel:code="KEY_RIGHT" accel:shift="true" accel:mod1="true" xlink:href=".uno:GoRightToEndOfDataSel"/> - <accel:item accel:code="KEY_PAGEDOWN" accel:mod1="true" xlink:href=".uno:JumpToNextTable"/> - <accel:item accel:code="KEY_PAGEUP" accel:mod1="true" xlink:href=".uno:JumpToPrevTable"/> - <accel:item accel:code="KEY_TAB" xlink:href=".uno:JumpToNextUnprotected"/> - <accel:item accel:code="KEY_TAB" accel:shift="true" xlink:href=".uno:JumpToPreviousUnprotected"/> - <accel:item accel:code="KEY_SPACE" accel:shift="true" accel:mod1="true" xlink:href=".uno:SelectColumn"/> - <accel:item accel:code="KEY_SPACE" accel:shift="true" xlink:href=".uno:SelectRow"/> - <accel:item accel:code="KEY_BACKSPACE" accel:shift="true" xlink:href=".uno:Deselect"/> - <accel:item accel:code="KEY_BACKSPACE" accel:mod1="true" xlink:href=".uno:GoToCurrentCell"/> - <accel:item accel:code="KEY_MULTIPLY" accel:mod1="true" xlink:href=".uno:SelectData"/> - <accel:item accel:code="KEY_F2" xlink:href=".uno:SetInputMode"/> - <accel:item accel:code="KEY_BACKSPACE" xlink:href=".uno:ClearContents"/> - <accel:item accel:code="KEY_ESCAPE" xlink:href=".uno:Cancel"/> - <accel:item accel:code="KEY_DIVIDE" accel:mod1="true" xlink:href=".uno:SelectArrayFormula"/> - <accel:item accel:code="KEY_PAGEDOWN" accel:shift="true" accel:mod1="true" xlink:href=".uno:JumpToNextTableSel"/> - <accel:item accel:code="KEY_PAGEUP" accel:shift="true" accel:mod1="true" xlink:href=".uno:JumpToPrevTableSel"/> - <accel:item accel:code="KEY_F4" accel:shift="true" xlink:href=".uno:ToggleRelative"/> - <accel:item accel:code="KEY_D" accel:mod1="true" xlink:href=".uno:DataSelect"/> - <accel:item accel:code="KEY_F" accel:shift="true" accel:mod1="true" xlink:href=".uno:RepeatSearch"/> - <accel:item accel:code="KEY_T" accel:shift="true" accel:mod1="true" xlink:href=".uno:FocusCellAddress"/> - <accel:item accel:code="KEY_F5" accel:shift="true" accel:mod1="true" xlink:href=".uno:FocusCellAddress"/> - <accel:item accel:code="KEY_M" accel:mod1="true" xlink:href=".uno:ResetAttributes"/> - <accel:item accel:code="KEY_J" accel:shift="true" accel:mod1="true" xlink:href=".uno:FullScreen"/> -</accel:acceleratorlist> diff --git a/sc/uiconfig/scalc/accelerator/fr/default.xml b/sc/uiconfig/scalc/accelerator/fr/default.xml deleted file mode 100644 index 58b35dd80243..000000000000 --- a/sc/uiconfig/scalc/accelerator/fr/default.xml +++ /dev/null @@ -1,101 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<accel:acceleratorlist xmlns:accel="http://openoffice.org/2001/accel" xmlns:xlink="http://www.w3.org/1999/xlink"> - <accel:item accel:code="KEY_SUBTRACT" accel:mod1="true" xlink:href=".uno:DeleteCell"/> - <accel:item accel:code="KEY_ADD" accel:mod1="true" xlink:href=".uno:InsertCell"/> - <accel:item accel:code="KEY_ADD" accel:shift="true" accel:mod1="true" xlink:href=".uno:InsertCell"/> - <accel:item accel:code="KEY_F11" accel:shift="true" xlink:href=".uno:SaveAsTemplate"/> - <accel:item accel:code="KEY_F11" xlink:href=".uno:DesignerDialog"/> - <accel:item accel:code="KEY_F11" accel:mod1="true" xlink:href=".uno:StyleCatalog"/> - <accel:item accel:code="KEY_Y" accel:mod1="true" xlink:href=".uno:Redo"/> - <accel:item accel:code="KEY_Z" accel:mod1="true" xlink:href=".uno:Undo"/> - <accel:item accel:code="KEY_BACKSPACE" accel:mod2="true" xlink:href=".uno:Undo"/> - <accel:item accel:code="KEY_UNDO" xlink:href=".uno:Undo"/> - <accel:item accel:code="KEY_REPEAT" xlink:href=".uno:Repeat"/> - <accel:item accel:code="KEY_DOWN" xlink:href=".uno:GoDown"/> - <accel:item accel:code="KEY_UP" xlink:href=".uno:GoUp"/> - <accel:item accel:code="KEY_LEFT" xlink:href=".uno:GoLeft"/> - <accel:item accel:code="KEY_RIGHT" xlink:href=".uno:GoRight"/> - <accel:item accel:code="KEY_PAGEDOWN" xlink:href=".uno:GoDownBlock"/> - <accel:item accel:code="KEY_PAGEUP" xlink:href=".uno:GoUpBlock"/> - <accel:item accel:code="KEY_END" accel:mod1="true" xlink:href=".uno:GoToEndOfData"/> - <accel:item accel:code="KEY_HOME" accel:mod1="true" xlink:href=".uno:GoToStart"/> - <accel:item accel:code="KEY_HOME" xlink:href=".uno:GoToStartOfRow"/> - <accel:item accel:code="KEY_END" xlink:href=".uno:GoToEndOfRow"/> - <accel:item accel:code="KEY_F4" xlink:href=".uno:ViewDataSourceBrowser"/> - <accel:item accel:code="KEY_I" accel:mod1="true" xlink:href=".uno:Italic"/> - <accel:item accel:code="KEY_G" accel:mod1="true" xlink:href=".uno:Bold"/> - <accel:item accel:code="KEY_U" accel:mod1="true" xlink:href=".uno:Underline"/> - <accel:item accel:code="KEY_1" accel:mod1="true" xlink:href=".uno:FormatCellDialog"/> - <accel:item accel:code="KEY_5" accel:mod1="true" xlink:href=".uno:SpacePara15"/> - <accel:item accel:code="KEY_2" accel:mod1="true" xlink:href=".uno:SpacePara2"/> - <accel:item accel:code="KEY_F7" xlink:href=".uno:SpellDialog"/> - <accel:item accel:code="KEY_F7" accel:mod1="true" xlink:href=".uno:Thesaurus"/> - <accel:item accel:code="KEY_P" accel:shift="true" accel:mod1="true" xlink:href=".uno:SuperScript"/> - <accel:item accel:code="KEY_B" accel:shift="true" accel:mod1="true" xlink:href=".uno:SubScript"/> - <accel:item accel:code="KEY_F5" xlink:href=".uno:Navigator"/> - <accel:item accel:code="KEY_R" accel:shift="true" accel:mod1="true" xlink:href=".uno:Repaint"/> - <accel:item accel:code="KEY_4" accel:shift="true" accel:mod1="true" xlink:href=".uno:NumberFormatCurrency"/> - <accel:item accel:code="KEY_5" accel:shift="true" accel:mod1="true" xlink:href=".uno:NumberFormatPercent"/> - <accel:item accel:code="KEY_6" accel:shift="true" accel:mod1="true" xlink:href=".uno:NumberFormatStandard"/> - <accel:item accel:code="KEY_3" accel:shift="true" accel:mod1="true" xlink:href=".uno:NumberFormatDate"/> - <accel:item accel:code="KEY_1" accel:shift="true" accel:mod1="true" xlink:href=".uno:NumberFormatDecimal"/> - <accel:item accel:code="KEY_2" accel:shift="true" accel:mod1="true" xlink:href=".uno:NumberFormatScientific"/> - <accel:item accel:code="KEY_F2" accel:shift="true" accel:mod1="true" xlink:href=".uno:FocusInputLine"/> - <accel:item accel:code="KEY_F8" accel:shift="true" xlink:href=".uno:StatusSelectionModeExp"/> - <accel:item accel:code="KEY_F8" xlink:href=".uno:StatusSelectionModeExt"/> - <accel:item accel:code="KEY_F2" accel:mod1="true" xlink:href=".uno:FunctionDialog"/> - <accel:item accel:code="KEY_V" accel:shift="true" accel:mod1="true" xlink:href=".uno:PasteSpecial"/> - <accel:item accel:code="KEY_F8" accel:mod1="true" xlink:href=".uno:ViewValueHighlighting"/> - <accel:item accel:code="KEY_INSERT" xlink:href=".uno:InsertContents"/> - <accel:item accel:code="KEY_F3" accel:mod1="true" xlink:href=".uno:DefineName"/> - <accel:item accel:code="KEY_F9" xlink:href=".uno:Calculate"/> - <accel:item accel:code="KEY_F9" accel:shift="true" accel:mod1="true" xlink:href=".uno:CalculateHard"/> - <accel:item accel:code="KEY_F12" xlink:href=".uno:Group"/> - <accel:item accel:code="KEY_F12" accel:mod1="true" xlink:href=".uno:Ungroup"/> - <accel:item accel:code="KEY_L" accel:mod1="true" xlink:href=".uno:AlignLeft"/> - <accel:item accel:code="KEY_R" accel:mod1="true" xlink:href=".uno:AlignRight"/> - <accel:item accel:code="KEY_E" accel:mod1="true" xlink:href=".uno:AlignHorizontalCenter"/> - <accel:item accel:code="KEY_J" accel:mod1="true" xlink:href=".uno:AlignBlock"/> - <accel:item accel:code="KEY_F7" accel:shift="true" xlink:href=".uno:ShowPrecedents"/> - <accel:item accel:code="KEY_F5" accel:shift="true" xlink:href=".uno:ShowDependents"/> - <accel:item accel:code="KEY_DOWN" accel:shift="true" xlink:href=".uno:GoDownSel"/> - <accel:item accel:code="KEY_UP" accel:shift="true" xlink:href=".uno:GoUpSel"/> - <accel:item accel:code="KEY_LEFT" accel:shift="true" xlink:href=".uno:GoLeftSel"/> - <accel:item accel:code="KEY_RIGHT" accel:shift="true" xlink:href=".uno:GoRightSel"/> - <accel:item accel:code="KEY_PAGEDOWN" accel:shift="true" xlink:href=".uno:GoDownBlockSel"/> - <accel:item accel:code="KEY_PAGEUP" accel:shift="true" xlink:href=".uno:GoUpBlockSel"/> - <accel:item accel:code="KEY_HOME" accel:shift="true" accel:mod1="true" xlink:href=".uno:GoToStartSel"/> - <accel:item accel:code="KEY_END" accel:shift="true" accel:mod1="true" xlink:href=".uno:GoToEndOfDataSel"/> - <accel:item accel:code="KEY_HOME" accel:shift="true" xlink:href=".uno:GoToStartOfRowSel"/> - <accel:item accel:code="KEY_END" accel:shift="true" xlink:href=".uno:GoToEndOfRowSel"/> - <accel:item accel:code="KEY_UP" accel:mod1="true" xlink:href=".uno:GoUpToStartOfData"/> - <accel:item accel:code="KEY_DOWN" accel:mod1="true" xlink:href=".uno:GoDownToEndOfData"/> - <accel:item accel:code="KEY_LEFT" accel:mod1="true" xlink:href=".uno:GoLeftToStartOfData"/> - <accel:item accel:code="KEY_RIGHT" accel:mod1="true" xlink:href=".uno:GoRightToEndOfData"/> - <accel:item accel:code="KEY_UP" accel:shift="true" accel:mod1="true" xlink:href=".uno:GoUpToStartOfDataSel"/> - <accel:item accel:code="KEY_DOWN" accel:shift="true" accel:mod1="true" xlink:href=".uno:GoDownToEndOfDataSel"/> - <accel:item accel:code="KEY_LEFT" accel:shift="true" accel:mod1="true" xlink:href=".uno:GoLeftToStartOfDataSel"/> - <accel:item accel:code="KEY_RIGHT" accel:shift="true" accel:mod1="true" xlink:href=".uno:GoRightToEndOfDataSel"/> - <accel:item accel:code="KEY_PAGEDOWN" accel:mod1="true" xlink:href=".uno:JumpToNextTable"/> - <accel:item accel:code="KEY_PAGEUP" accel:mod1="true" xlink:href=".uno:JumpToPrevTable"/> - <accel:item accel:code="KEY_TAB" xlink:href=".uno:JumpToNextUnprotected"/> - <accel:item accel:code="KEY_TAB" accel:shift="true" xlink:href=".uno:JumpToPreviousUnprotected"/> - <accel:item accel:code="KEY_SPACE" accel:shift="true" accel:mod1="true" xlink:href=".uno:SelectColumn"/> - <accel:item accel:code="KEY_SPACE" accel:shift="true" xlink:href=".uno:SelectRow"/> - <accel:item accel:code="KEY_BACKSPACE" accel:shift="true" xlink:href=".uno:Deselect"/> - <accel:item accel:code="KEY_BACKSPACE" accel:mod1="true" xlink:href=".uno:GoToCurrentCell"/> - <accel:item accel:code="KEY_MULTIPLY" accel:mod1="true" xlink:href=".uno:SelectData"/> - <accel:item accel:code="KEY_F2" xlink:href=".uno:SetInputMode"/> - <accel:item accel:code="KEY_BACKSPACE" xlink:href=".uno:ClearContents"/> - <accel:item accel:code="KEY_ESCAPE" xlink:href=".uno:Cancel"/> - <accel:item accel:code="KEY_DIVIDE" accel:mod1="true" xlink:href=".uno:SelectArrayFormula"/> - <accel:item accel:code="KEY_PAGEDOWN" accel:shift="true" accel:mod1="true" xlink:href=".uno:JumpToNextTableSel"/> - <accel:item accel:code="KEY_PAGEUP" accel:shift="true" accel:mod1="true" xlink:href=".uno:JumpToPrevTableSel"/> - <accel:item accel:code="KEY_F4" accel:shift="true" xlink:href=".uno:ToggleRelative"/> - <accel:item accel:code="KEY_D" accel:mod1="true" xlink:href=".uno:DataSelect"/> - <accel:item accel:code="KEY_F" accel:shift="true" accel:mod1="true" xlink:href=".uno:RepeatSearch"/> - <accel:item accel:code="KEY_T" accel:shift="true" accel:mod1="true" xlink:href=".uno:FocusCellAddress"/> - <accel:item accel:code="KEY_F5" accel:shift="true" accel:mod1="true" xlink:href=".uno:FocusCellAddress"/> - <accel:item accel:code="KEY_M" accel:mod1="true" xlink:href=".uno:ResetAttributes"/> - <accel:item accel:code="KEY_J" accel:shift="true" accel:mod1="true" xlink:href=".uno:FullScreen"/> -</accel:acceleratorlist> diff --git a/sc/uiconfig/scalc/menubar/menubar.xml b/sc/uiconfig/scalc/menubar/menubar.xml index ab3f121809fa..855db09ff50c 100644 --- a/sc/uiconfig/scalc/menubar/menubar.xml +++ b/sc/uiconfig/scalc/menubar/menubar.xml @@ -109,8 +109,8 @@ </menu:menu> <menu:menu menu:id=".uno:ViewMenu"> <menu:menupopup> - <menu:menuitem menu:id=".uno:NormalViewMode"/> - <menu:menuitem menu:id=".uno:PagebreakMode"/> + <menu:menuitem menu:id=".uno:NormalViewMode" menu:style="radio"/> + <menu:menuitem menu:id=".uno:PagebreakMode" menu:style="radio"/> <menu:menuseparator/> <menu:menuitem menu:id=".uno:AvailableToolbars"/> <menu:menuitem menu:id=".uno:InputLineVisible"/> @@ -122,7 +122,8 @@ <menu:menuseparator/> <menu:menuitem menu:id=".uno:ViewDataSourceBrowser"/> <menu:menuitem menu:id=".uno:Navigator"/> - <menu:menuseparator/> + <menu:menuitem menu:id=".uno:TaskPane"/> + <menu:menuseparator/> <menu:menuitem menu:id=".uno:FullScreen"/> <menu:menuitem menu:id=".uno:Zoom"/> </menu:menupopup> @@ -214,6 +215,8 @@ <menu:menuitem menu:id=".uno:Hide"/> <menu:menuitem menu:id=".uno:Show"/> <menu:menuitem menu:id=".uno:SheetRightToLeft"/> + <menu:menuseparator/> + <menu:menuitem menu:id=".uno:SetTabBgColor"/> </menu:menupopup> </menu:menu> <menu:menuitem menu:id=".uno:ToggleMergeCells"/> @@ -233,8 +236,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"/> @@ -247,21 +253,21 @@ <menu:menuseparator/> <menu:menu menu:id=".uno:AnchorMenu"> <menu:menupopup> - <menu:menuitem menu:id=".uno:SetAnchorToPage"/> - <menu:menuitem menu:id=".uno:SetAnchorToCell"/> + <menu:menuitem menu:id=".uno:SetAnchorToPage" menu:style="radio"/> + <menu:menuitem menu:id=".uno:SetAnchorToCell" menu:style="radio"/> </menu:menupopup> </menu:menu> <menu:menu menu:id=".uno:ObjectAlign"> <menu:menupopup> - <menu:menuitem menu:id=".uno:CommonAlignHorizontalDefault"/> - <menu:menuitem menu:id=".uno:CommonAlignLeft"/> - <menu:menuitem menu:id=".uno:CommonAlignHorizontalCenter"/> - <menu:menuitem menu:id=".uno:CommonAlignRight"/> - <menu:menuitem menu:id=".uno:CommonAlignJustified"/> + <menu:menuitem menu:id=".uno:CommonAlignHorizontalDefault" menu:style="radio"/> + <menu:menuitem menu:id=".uno:CommonAlignLeft" menu:style="radio"/> + <menu:menuitem menu:id=".uno:CommonAlignHorizontalCenter" menu:style="radio"/> + <menu:menuitem menu:id=".uno:CommonAlignRight" menu:style="radio"/> + <menu:menuitem menu:id=".uno:CommonAlignJustified" menu:style="radio"/> <menu:menuseparator/> - <menu:menuitem menu:id=".uno:CommonAlignTop"/> - <menu:menuitem menu:id=".uno:CommonAlignVerticalCenter"/> - <menu:menuitem menu:id=".uno:CommonAlignBottom"/> + <menu:menuitem menu:id=".uno:CommonAlignTop" menu:style="radio"/> + <menu:menuitem menu:id=".uno:CommonAlignVerticalCenter" menu:style="radio"/> + <menu:menuitem menu:id=".uno:CommonAlignBottom" menu:style="radio"/> </menu:menupopup> </menu:menu> <menu:menu menu:id=".uno:ArrangeMenu"> @@ -310,7 +316,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/extrusionobjectbar.xml b/sc/uiconfig/scalc/toolbar/extrusionobjectbar.xml index 1f212226cf52..148849db6ee7 100644 --- a/sc/uiconfig/scalc/toolbar/extrusionobjectbar.xml +++ b/sc/uiconfig/scalc/toolbar/extrusionobjectbar.xml @@ -8,9 +8,9 @@ <toolbar:toolbaritem xlink:href=".uno:ExtrusionTiltLeft" toolbar:helpid="10963"/> <toolbar:toolbaritem xlink:href=".uno:ExtrusionTiltRight" toolbar:helpid="10964"/> <toolbar:toolbarseparator/> - <toolbar:toolbaritem xlink:href=".uno:ExtrusionDepthFloater" toolbar:helpid="10965"/> - <toolbar:toolbaritem xlink:href=".uno:ExtrusionDirectionFloater" toolbar:helpid="10966"/> - <toolbar:toolbaritem xlink:href=".uno:ExtrusionLightingFloater" toolbar:helpid="10967"/> - <toolbar:toolbaritem xlink:href=".uno:ExtrusionSurfaceFloater" toolbar:helpid="10968"/> - <toolbar:toolbaritem xlink:href=".uno:Extrusion3DColor" toolbar:helpid="10969"/> + <toolbar:toolbaritem xlink:href=".uno:ExtrusionDepthFloater" toolbar:helpid="10965" toolbar:style="dropdownonly"/> + <toolbar:toolbaritem xlink:href=".uno:ExtrusionDirectionFloater" toolbar:helpid="10966" toolbar:style="dropdownonly"/> + <toolbar:toolbaritem xlink:href=".uno:ExtrusionLightingFloater" toolbar:helpid="10967" toolbar:style="dropdownonly"/> + <toolbar:toolbaritem xlink:href=".uno:ExtrusionSurfaceFloater" toolbar:helpid="10968" toolbar:style="dropdownonly"/> + <toolbar:toolbaritem xlink:href=".uno:Extrusion3DColor" toolbar:helpid="10969" toolbar:style="dropdownonly"/> </toolbar:toolbar>
\ No newline at end of file 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/fontworkobjectbar.xml b/sc/uiconfig/scalc/toolbar/fontworkobjectbar.xml index 3ac334e0e920..32de621477dc 100644 --- a/sc/uiconfig/scalc/toolbar/fontworkobjectbar.xml +++ b/sc/uiconfig/scalc/toolbar/fontworkobjectbar.xml @@ -3,9 +3,9 @@ <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:FontworkGalleryFloater" toolbar:helpid="helpid:10977" /> <toolbar:toolbarseparator/> - <toolbar:toolbaritem xlink:href=".uno:FontworkShapeType" toolbar:helpid="helpid:10978" toolbar:style="radio dropdown" /> + <toolbar:toolbaritem xlink:href=".uno:FontworkShapeType" toolbar:helpid="helpid:10978" toolbar:style="dropdownonly"/> <toolbar:toolbaritem xlink:href=".uno:FontworkSameLetterHeights" toolbar:helpid="helpid:10979" /> <toolbar:toolbarseparator/> - <toolbar:toolbaritem xlink:href=".uno:FontworkAlignmentFloater" toolbar:helpid="helpid:10981" toolbar:style="dropdown" /> - <toolbar:toolbaritem xlink:href=".uno:FontworkCharacterSpacingFloater" toolbar:helpid="helpid:10982" toolbar:style="dropdown" /> + <toolbar:toolbaritem xlink:href=".uno:FontworkAlignmentFloater" toolbar:helpid="helpid:10981" toolbar:style="dropdownonly"/> + <toolbar:toolbaritem xlink:href=".uno:FontworkCharacterSpacingFloater" toolbar:helpid="helpid:10982" toolbar:style="dropdownonly"/> </toolbar:toolbar>
\ No newline at end of file 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> diff --git a/sc/util/makefile.mk b/sc/util/makefile.mk index b7b12e07ee6a..980d271ae7c0 100644 --- a/sc/util/makefile.mk +++ b/sc/util/makefile.mk @@ -255,6 +255,7 @@ LIB8OBJFILES = \ $(SLO)$/attrdlg.obj \ $(SLO)$/scuiimoptdlg.obj \ $(SLO)$/strindlg.obj \ + $(SLO)$/tabbgcolordlg.obj \ $(SLO)$/shtabdlg.obj \ $(SLO)$/scendlg.obj \ $(SLO)$/pvfundlg.obj \ @@ -314,7 +315,7 @@ SHL9STDLIBS= \ $(ISCLIB) \ $(VCLLIB) \ $(TKLIB) \ - $(SVXMSFILTERLIB) \ + $(MSFILTERLIB) \ $(FORLIB) SHL9DEPN=$(SHL1TARGETN) $(SHL8TARGETN) diff --git a/scaddins/source/analysis/analysis.cxx b/scaddins/source/analysis/analysis.cxx index bbc58ed27c9c..0d206d0286dd 100644 --- a/scaddins/source/analysis/analysis.cxx +++ b/scaddins/source/analysis/analysis.cxx @@ -915,21 +915,21 @@ double SAL_CALL AnalysisAddIn::getLcm( constREFXPS& xOpt, const SEQSEQ( double ) } -double SAL_CALL AnalysisAddIn::getBesseli( double fNum, sal_Int32 nOrder ) THROWDEF_RTE_IAE +double SAL_CALL AnalysisAddIn::getBesseli( double fNum, sal_Int32 nOrder ) THROWDEF_RTE_IAE_NCE { double fRet = sca::analysis::BesselI( fNum, nOrder ); RETURN_FINITE( fRet ); } -double SAL_CALL AnalysisAddIn::getBesselj( double fNum, sal_Int32 nOrder ) THROWDEF_RTE_IAE +double SAL_CALL AnalysisAddIn::getBesselj( double fNum, sal_Int32 nOrder ) THROWDEF_RTE_IAE_NCE { double fRet = sca::analysis::BesselJ( fNum, nOrder ); RETURN_FINITE( fRet ); } -double SAL_CALL AnalysisAddIn::getBesselk( double fNum, sal_Int32 nOrder ) THROWDEF_RTE_IAE +double SAL_CALL AnalysisAddIn::getBesselk( double fNum, sal_Int32 nOrder ) THROWDEF_RTE_IAE_NCE { if( nOrder < 0 || fNum <= 0.0 ) THROW_IAE; @@ -939,7 +939,7 @@ double SAL_CALL AnalysisAddIn::getBesselk( double fNum, sal_Int32 nOrder ) THROW } -double SAL_CALL AnalysisAddIn::getBessely( double fNum, sal_Int32 nOrder ) THROWDEF_RTE_IAE +double SAL_CALL AnalysisAddIn::getBessely( double fNum, sal_Int32 nOrder ) THROWDEF_RTE_IAE_NCE { if( nOrder < 0 || fNum <= 0.0 ) THROW_IAE; diff --git a/scaddins/source/analysis/analysis.hxx b/scaddins/source/analysis/analysis.hxx index fbf7dd012050..ff789838b299 100644 --- a/scaddins/source/analysis/analysis.hxx +++ b/scaddins/source/analysis/analysis.hxx @@ -36,6 +36,7 @@ #include <com/sun/star/sheet/addin/XAnalysis.hpp> #include <com/sun/star/sheet/LocalizedName.hpp> #include <com/sun/star/sheet/XCompatibilityNames.hpp> +#include <com/sun/star/sheet/NoConvergenceException.hpp> #include <cppuhelper/implbase5.hxx> // helper for implementations @@ -143,10 +144,10 @@ public: virtual double SAL_CALL getGcd( constREFXPS& xOpt, const SEQSEQ( double )& aVLst, const SEQ( ANY )& aOptVLst ) THROWDEF_RTE_IAE; virtual double SAL_CALL getLcm( constREFXPS& xOpt, const SEQSEQ( double )& aVLst, const SEQ( ANY )& aOptVLst ) THROWDEF_RTE_IAE; - virtual double SAL_CALL getBesseli( double fNum, sal_Int32 nOrder ) THROWDEF_RTE_IAE; - virtual double SAL_CALL getBesselj( double fNum, sal_Int32 nOrder ) THROWDEF_RTE_IAE; - virtual double SAL_CALL getBesselk( double fNum, sal_Int32 nOrder ) THROWDEF_RTE_IAE; - virtual double SAL_CALL getBessely( double fNum, sal_Int32 nOrder ) THROWDEF_RTE_IAE; + virtual double SAL_CALL getBesseli( double fNum, sal_Int32 nOrder ) THROWDEF_RTE_IAE_NCE; + virtual double SAL_CALL getBesselj( double fNum, sal_Int32 nOrder ) THROWDEF_RTE_IAE_NCE; + virtual double SAL_CALL getBesselk( double fNum, sal_Int32 nOrder ) THROWDEF_RTE_IAE_NCE; + virtual double SAL_CALL getBessely( double fNum, sal_Int32 nOrder ) THROWDEF_RTE_IAE_NCE; virtual STRING SAL_CALL getBin2Oct( constREFXPS& xOpt, const STRING& aNum, const ANY& rPlaces ) THROWDEF_RTE_IAE; virtual double SAL_CALL getBin2Dec( const STRING& aNum ) THROWDEF_RTE_IAE; diff --git a/scaddins/source/analysis/analysisadd.idl b/scaddins/source/analysis/analysisadd.idl index 14b47ac256fc..6245bff9ad5a 100644 --- a/scaddins/source/analysis/analysisadd.idl +++ b/scaddins/source/analysis/analysisadd.idl @@ -25,6 +25,9 @@ * ************************************************************************/ +#ifndef __com_sun_star_sheet_NoConvergenceException_idl__ +#include <com/sun/star/sheet/NoConvergenceException.idl> +#endif #include <com/sun/star/uno/XInterface.idl> #include <com/sun/star/beans/XPropertySet.idl> @@ -145,19 +148,23 @@ module addin /// besseli. double getBesseli( [in] double Num, [in] long Order ) - raises( com::sun::star::lang::IllegalArgumentException ); + raises( com::sun::star::lang::IllegalArgumentException, + com::sun::star::sheet::NoConvergenceException ); /// besselj. double getBesselj( [in] double Num, [in] long Order ) - raises( com::sun::star::lang::IllegalArgumentException ); + raises( com::sun::star::lang::IllegalArgumentException, + com::sun::star::sheet::NoConvergenceException ); /// besselk. double getBesselk( [in] double Num, [in] long Order ) - raises( com::sun::star::lang::IllegalArgumentException ); + raises( com::sun::star::lang::IllegalArgumentException, + com::sun::star::sheet::NoConvergenceException ); /// bessely. double getBessely( [in] double Num, [in] long Order ) - raises( com::sun::star::lang::IllegalArgumentException ); + raises( com::sun::star::lang::IllegalArgumentException, + com::sun::star::sheet::NoConvergenceException ); /// bin2oct. string getBin2Oct( diff --git a/scaddins/source/analysis/analysisdefs.hxx b/scaddins/source/analysis/analysisdefs.hxx index 81f7435abc19..dae4205e2d84 100644 --- a/scaddins/source/analysis/analysisdefs.hxx +++ b/scaddins/source/analysis/analysisdefs.hxx @@ -44,6 +44,8 @@ #define THROW_RTE throw CSS::uno::RuntimeException() #define THROWDEF_RTE_IAE throw(CSS::uno::RuntimeException,CSS::lang::IllegalArgumentException) #define THROW_IAE throw CSS::lang::IllegalArgumentException() +#define THROWDEF_RTE_IAE_NCE throw(CSS::uno::RuntimeException,CSS::lang::IllegalArgumentException,CSS::sheet::NoConvergenceException) +#define THROW_NCE throw CSS::sheet::NoConvergenceException() #define CHK_Freq ( nFreq != 1 && nFreq != 2 && nFreq != 4 ) #define CHK_FINITE(d) if( !::rtl::math::isFinite( d ) ) THROW_IAE diff --git a/scaddins/source/analysis/analysishelper.cxx b/scaddins/source/analysis/analysishelper.cxx index 417d30c24d9b..d47c02a4e961 100644 --- a/scaddins/source/analysis/analysishelper.cxx +++ b/scaddins/source/analysis/analysishelper.cxx @@ -2530,8 +2530,8 @@ ConvertDataList::ConvertDataList( void ) NEWD( "ly3", 1.1810108125623799E-51, CDC_Volume ); // *** Cubic light-year NEWD( "MTON", 1.4125866688595436E00, CDC_Volume ); // *** Measurement ton NEWD( "tspm", 5.0000000000000000E02, CDC_Volume ); // *** Modern teaspoon - NEWD( "uk_gal", 2.6411458333333333E-01, CDC_Volume ); // U.K. / Imperial gallon ?? - NEWD( "uk_qt", 1.0564583333333333E00, CDC_Volume ); // U.K. / Imperial quart ?? + NEWD( "uk_gal", 2.199694619402070E-01, CDC_Volume ); // U.K. / Imperial gallon + NEWD( "uk_qt", 8.798778477608300E-01, CDC_Volume ); // U.K. / Imperial quart // 1 Square Meter is... NEWDP( "m2", 1.0000000000000000E00, CDC_Area ); // *** Square Meter diff --git a/scaddins/source/analysis/bessel.cxx b/scaddins/source/analysis/bessel.cxx index 9b1f79b6d405..f853b49eb443 100644 --- a/scaddins/source/analysis/bessel.cxx +++ b/scaddins/source/analysis/bessel.cxx @@ -31,6 +31,7 @@ #include <rtl/math.hxx> using ::com::sun::star::lang::IllegalArgumentException; +using ::com::sun::star::sheet::NoConvergenceException; namespace sca { namespace analysis { @@ -47,93 +48,129 @@ const double THRESHOLD = 30.0; // Threshold for usage of approximation form const double MAXEPSILON = 1e-10; // Maximum epsilon for end of iteration. const sal_Int32 MAXITER = 100; // Maximum number of iterations. - // ============================================================================ // BESSEL J // ============================================================================ /* The BESSEL function, first kind, unmodified: - - inf (-1)^k (x/2)^(n+2k) - J_n(x) = SUM TERM(n,k) with TERM(n,k) := --------------------- - k=0 k! (n+k)! - - Approximation for the BESSEL function, first kind, unmodified, for great x: - - J_n(x) ~ sqrt( 2 / (PI x) ) cos( x - n PI/2 - PI/4 ) for x>=0. - */ + The algorithm follows + http://www.reference-global.com/isbn/978-3-11-020354-7 + Numerical Mathematics 1 / Numerische Mathematik 1, + An algorithm-based introduction / Eine algorithmisch orientierte Einführung + Deuflhard, Peter; Hohmann, Andreas + Berlin, New York (Walter de Gruyter) 2008 + 4. überarb. u. erw. Aufl. 2008 + eBook ISBN: 978-3-11-020355-4 + Chapter 6.3.2 , algorithm 6.24 + The source is in German. + The BesselJ-function is a special case of the adjoint summation with + a_k = 2*(k-1)/x for k=1,... + b_k = -1, for all k, directly substituted + m_0=1, m_k=2 for k even, and m_k=0 for k odd, calculated on the fly + alpha_k=1 for k=N and alpha_k=0 otherwise +*/ // ---------------------------------------------------------------------------- -double BesselJ( double x, sal_Int32 n ) throw( IllegalArgumentException ) +double BesselJ( double x, sal_Int32 N ) throw (IllegalArgumentException, NoConvergenceException) + { - if( n < 0 ) + if( N < 0 ) throw IllegalArgumentException(); - - double fResult = 0.0; - if( fabs( x ) <= THRESHOLD ) + if (x==0.0) + return (N==0) ? 1.0 : 0.0; + + /* The algorithm works only for x>0, therefore remember sign. BesselJ + with integer order N is an even function for even N (means J(-x)=J(x)) + and an odd function for odd N (means J(-x)=-J(x)).*/ + double fSign = (N % 2 == 1 && x < 0) ? -1.0 : 1.0; + double fX = fabs(x); + + const double fMaxIteration = 9000000.0; //experimental, for to return in < 3 seconds + double fEstimateIteration = fX * 1.5 + N; + bool bAsymptoticPossible = pow(fX,0.4) > N; + if (fEstimateIteration > fMaxIteration) { - /* Start the iteration without TERM(n,0), which is set here. - - TERM(n,0) = (x/2)^n / n! - */ - double fTerm = pow( x / 2.0, (double)n ) / Fak( n ); - sal_Int32 nK = 1; // Start the iteration with k=1. - fResult = fTerm; // Start result with TERM(n,0). - - const double fSqrX = x * x / -4.0; + if (bAsymptoticPossible) + return fSign * sqrt(f_2_DIV_PI/fX)* cos(fX-N*f_PI_DIV_2-f_PI_DIV_4); + else + throw NoConvergenceException(); + } - do + double epsilon = 1.0e-15; // relative error + bool bHasfound = false; + double k= 0.0; + // e_{-1} = 0; e_0 = alpha_0 / b_2 + double u ; // u_0 = e_0/f_0 = alpha_0/m_0 = alpha_0 + + // first used with k=1 + double m_bar; // m_bar_k = m_k * f_bar_{k-1} + double g_bar; // g_bar_k = m_bar_k - a_{k+1} + g_{k-1} + double g_bar_delta_u; // g_bar_delta_u_k = f_bar_{k-1} * alpha_k + // - g_{k-1} * delta_u_{k-1} - m_bar_k * u_{k-1} + // f_{-1} = 0.0; f_0 = m_0 / b_2 = 1/(-1) = -1 + double g = 0.0; // g_0= f_{-1} / f_0 = 0/(-1) = 0 + double delta_u = 0.0; // dummy initialize, first used with * 0 + double f_bar = -1.0; // f_bar_k = 1/f_k, but only used for k=0 + + if (N==0) + { + //k=0; alpha_0 = 1.0 + u = 1.0; // u_0 = alpha_0 + // k = 1.0; at least one step is necessary + // m_bar_k = m_k * f_bar_{k-1} ==> m_bar_1 = 0.0 + g_bar_delta_u = 0.0; // alpha_k = 0.0, m_bar = 0.0; g= 0.0 + g_bar = - 2.0/fX; // k = 1.0, g = 0.0 + delta_u = g_bar_delta_u / g_bar; + u = u + delta_u ; // u_k = u_{k-1} + delta_u_k + g = -1.0 / g_bar; // g_k=b_{k+2}/g_bar_k + f_bar = f_bar * g; // f_bar_k = f_bar_{k-1}* g_k + k = 2.0; + // From now on all alpha_k = 0.0 and k > N+1 + } + else + { // N >= 1 and alpha_k = 0.0 for k<N + u=0.0; // u_0 = alpha_0 + for (k =1.0; k<= N-1; k = k + 1.0) { - /* Calculation of TERM(n,k) from TERM(n,k-1): - - (-1)^k (x/2)^(n+2k) - TERM(n,k) = --------------------- - k! (n+k)! - - (-1)(-1)^(k-1) (x/2)^2 (x/2)^(n+2(k-1)) - = ----------------------------------------- - k (k-1)! (n+k) (n+k-1)! - - -(x/2)^2 (-1)^(k-1) (x/2)^(n+2(k-1)) - = ---------- * ----------------------------- - k(n+k) (k-1)! (n+k-1)! - - -(x^2/4) - = ---------- TERM(n,k-1) - k(n+k) - */ - fTerm *= fSqrX; // defined above as -(x^2/4) - fTerm /= (nK * (nK + n)); - fResult += fTerm; + m_bar=2.0 * fmod(k-1.0, 2.0) * f_bar; + g_bar_delta_u = - g * delta_u - m_bar * u; // alpha_k = 0.0 + g_bar = m_bar - 2.0*k/fX + g; + delta_u = g_bar_delta_u / g_bar; + u = u + delta_u; + g = -1.0/g_bar; + f_bar=f_bar * g; } - while( (fabs( fTerm ) > MAXEPSILON) && (++nK < MAXITER) ); + // Step alpha_N = 1.0 + m_bar=2.0 * fmod(k-1.0, 2.0) * f_bar; + g_bar_delta_u = f_bar - g * delta_u - m_bar * u; // alpha_k = 1.0 + g_bar = m_bar - 2.0*k/fX + g; + delta_u = g_bar_delta_u / g_bar; + u = u + delta_u; + g = -1.0/g_bar; + f_bar = f_bar * g; + k = k + 1.0; } - else + // Loop until desired accuracy, always alpha_k = 0.0 + do { - /* Approximation for the BESSEL function, first kind, unmodified: - - J_n(x) ~ sqrt( 2 / (PI x) ) cos( x - n PI/2 - PI/4 ) for x>=0. - - The BESSEL function J_n with n IN {0,2,4,...} is axially symmetric at - x=0, means J_n(x) = J_n(-x). Therefore the approximation for x<0 is: - - J_n(x) = J_n(|x|) for x<0 and n IN {0,2,4,...}. - - The BESSEL function J_n with n IN {1,3,5,...} is point-symmetric at - x=0, means J_n(x) = -J_n(-x). Therefore the approximation for x<0 is: - - J_n(x) = -J_n(|x|) for x<0 and n IN {1,3,5,...}. - */ - double fXAbs = fabs( x ); - fResult = sqrt( f_2_DIV_PI / fXAbs ) * cos( fXAbs - n * f_PI_DIV_2 - f_PI_DIV_4 ); - if( (n & 1) && (x < 0.0) ) - fResult = -fResult; + m_bar = 2.0 * fmod(k-1.0, 2.0) * f_bar; + g_bar_delta_u = - g * delta_u - m_bar * u; + g_bar = m_bar - 2.0*k/fX + g; + delta_u = g_bar_delta_u / g_bar; + u = u + delta_u; + g = -1.0/g_bar; + f_bar = f_bar * g; + bHasfound = (fabs(delta_u)<=fabs(u)*epsilon); + k = k + 1.0; } - return fResult; + while (!bHasfound && k <= fMaxIteration); + if (bHasfound) + return u * fSign; + else + throw NoConvergenceException(); // unlikely to happen } - // ============================================================================ // BESSEL I // ============================================================================ @@ -151,7 +188,7 @@ double BesselJ( double x, sal_Int32 n ) throw( IllegalArgumentException ) // ---------------------------------------------------------------------------- -double BesselI( double x, sal_Int32 n ) throw( IllegalArgumentException ) +double BesselI( double x, sal_Int32 n ) throw( IllegalArgumentException, NoConvergenceException ) { if( n < 0 ) throw IllegalArgumentException(); @@ -222,7 +259,7 @@ double BesselI( double x, sal_Int32 n ) throw( IllegalArgumentException ) // ============================================================================ -double Besselk0( double fNum ) throw( IllegalArgumentException ) +double Besselk0( double fNum ) throw( IllegalArgumentException, NoConvergenceException ) { double fRet; @@ -248,7 +285,7 @@ double Besselk0( double fNum ) throw( IllegalArgumentException ) } -double Besselk1( double fNum ) throw( IllegalArgumentException ) +double Besselk1( double fNum ) throw( IllegalArgumentException, NoConvergenceException ) { double fRet; @@ -275,7 +312,7 @@ double Besselk1( double fNum ) throw( IllegalArgumentException ) } -double BesselK( double fNum, sal_Int32 nOrder ) throw( IllegalArgumentException ) +double BesselK( double fNum, sal_Int32 nOrder ) throw( IllegalArgumentException, NoConvergenceException ) { switch( nOrder ) { @@ -301,87 +338,136 @@ double BesselK( double fNum, sal_Int32 nOrder ) throw( IllegalArgumentException } } +// ============================================================================ +// BESSEL Y +// ============================================================================ -double Bessely0( double fNum ) throw( IllegalArgumentException ) +/* The BESSEL function, second kind, unmodified: + The algorithm for order 0 and for order 1 follows + http://www.reference-global.com/isbn/978-3-11-020354-7 + Numerical Mathematics 1 / Numerische Mathematik 1, + An algorithm-based introduction / Eine algorithmisch orientierte Einführung + Deuflhard, Peter; Hohmann, Andreas + Berlin, New York (Walter de Gruyter) 2008 + 4. überarb. u. erw. Aufl. 2008 + eBook ISBN: 978-3-11-020355-4 + Chapter 6.3.2 , algorithm 6.24 + The source is in German. + See #i31656# for a commented version of the implementation, attachment #desc6 + http://www.openoffice.org/nonav/issues/showattachment.cgi/63609/Comments%20to%20the%20implementation%20of%20the%20Bessel%20functions.odt +*/ + +double Bessely0( double fX ) throw( IllegalArgumentException, NoConvergenceException ) { - double fRet; - - if( fNum < 8.0 ) + if (fX <= 0) + throw IllegalArgumentException(); + const double fMaxIteration = 9000000.0; // should not be reached + if (fX > 5.0e+6) // iteration is not considerable better then approximation + return sqrt(1/f_PI/fX) + *(rtl::math::sin(fX)-rtl::math::cos(fX)); + const double epsilon = 1.0e-15; + const double EulerGamma = 0.57721566490153286060; + double alpha = log(fX/2.0)+EulerGamma; + double u = alpha; + + double k = 1.0; + double m_bar = 0.0; + double g_bar_delta_u = 0.0; + double g_bar = -2.0 / fX; + double delta_u = g_bar_delta_u / g_bar; + double g = -1.0/g_bar; + double f_bar = -1 * g; + + double sign_alpha = 1.0; + double km1mod2; + bool bHasFound = false; + k = k + 1; + do { - double y = fNum * fNum; - - double f1 = -2957821389.0 + y * ( 7062834065.0 + y * ( -512359803.6 + - y * ( 10879881.29 + y * ( -86327.92757 + y * 228.4622733 ) ) ) ); - - double f2 = 40076544269.0 + y * ( 745249964.8 + y * ( 7189466.438 + - y * ( 47447.26470 + y * ( 226.1030244 + y ) ) ) ); - - fRet = f1 / f2 + 0.636619772 * BesselJ( fNum, 0 ) * log( fNum ); + km1mod2 = fmod(k-1.0,2.0); + m_bar=(2.0*km1mod2) * f_bar; + if (km1mod2 == 0.0) + alpha = 0.0; + else + { + alpha = sign_alpha * (4.0/k); + sign_alpha = -sign_alpha; + } + g_bar_delta_u = f_bar * alpha - g * delta_u - m_bar * u; + g_bar = m_bar - (2.0*k)/fX + g; + delta_u = g_bar_delta_u / g_bar; + u = u+delta_u; + g = -1.0 / g_bar; + f_bar = f_bar*g; + bHasFound = (fabs(delta_u)<=fabs(u)*epsilon); + k=k+1; } + while (!bHasFound && k<fMaxIteration); + if (bHasFound) + return u*f_2_DIV_PI; else - { - double z = 8.0 / fNum; - double y = z * z; - double xx = fNum - 0.785398164; - - double f1 = 1.0 + y * ( -0.1098628627e-2 + y * ( 0.2734510407e-4 + - y * ( -0.2073370639e-5 + y * 0.2093887211e-6 ) ) ); - - double f2 = -0.1562499995e-1 + y * ( 0.1430488765e-3 + - y * ( -0.6911147651e-5 + y * ( 0.7621095161e-6 + - y * ( -0.934945152e-7 ) ) ) ); - - fRet = sqrt( 0.636619772 / fNum ) * ( sin( xx ) * f1 + z * cos( xx ) * f2 ); - } - - return fRet; + throw NoConvergenceException(); // not likely to happen } - -double Bessely1( double fNum ) throw( IllegalArgumentException ) +// See #i31656# for a commented version of this implementation, attachment #desc6 +// http://www.openoffice.org/nonav/issues/showattachment.cgi/63609/Comments%20to%20the%20implementation%20of%20the%20Bessel%20functions.odt +double Bessely1( double fX ) throw( IllegalArgumentException, NoConvergenceException ) { - double fRet; - - if( fNum < 8.0 ) + if (fX <= 0) + throw IllegalArgumentException(); + const double fMaxIteration = 9000000.0; // should not be reached + if (fX > 5.0e+6) // iteration is not considerable better then approximation + return - sqrt(1/f_PI/fX) + *(rtl::math::sin(fX)+rtl::math::cos(fX)); + const double epsilon = 1.0e-15; + const double EulerGamma = 0.57721566490153286060; + double alpha = 1.0/fX; + double f_bar = -1.0; + double g = 0.0; + double u = alpha; + double k = 1.0; + double m_bar = 0.0; + alpha = 1.0 - EulerGamma - log(fX/2.0); + double g_bar_delta_u = -alpha; + double g_bar = -2.0 / fX; + double delta_u = g_bar_delta_u / g_bar; + u = u + delta_u; + g = -1.0/g_bar; + f_bar = f_bar * g; + double sign_alpha = -1.0; + double km1mod2; //will be (k-1) mod 2 + double q; // will be (k-1) div 2 + bool bHasFound = false; + k = k + 1.0; + do { - double y = fNum * fNum; - - double f1 = fNum * ( -0.4900604943e13 + y * ( 0.1275274390e13 + - y * ( -0.5153438139e11 + y * ( 0.7349264551e9 + - y * ( -0.4237922726e7 + y * 0.8511937935e4 ) ) ) ) ); - - double f2 = 0.2499580570e14 + y * ( 0.4244419664e12 + - y * ( 0.3733650367e10 + y * ( 0.2245904002e8 + - y * ( 0.1020426050e6 + y * ( 0.3549632885e3 + y ) ) ) ) ); - - fRet = f1 / f2 + 0.636619772 * ( BesselJ( fNum, 1 ) * log( fNum ) - 1.0 / fNum ); + km1mod2 = fmod(k-1.0,2.0); + m_bar=(2.0*km1mod2) * f_bar; + q = (k-1.0)/2.0; + if (km1mod2 == 0.0) // k is odd + { + alpha = sign_alpha * (1.0/q + 1.0/(q+1.0)); + sign_alpha = -sign_alpha; + } + else + alpha = 0.0; + g_bar_delta_u = f_bar * alpha - g * delta_u - m_bar * u; + g_bar = m_bar - (2.0*k)/fX + g; + delta_u = g_bar_delta_u / g_bar; + u = u+delta_u; + g = -1.0 / g_bar; + f_bar = f_bar*g; + bHasFound = (fabs(delta_u)<=fabs(u)*epsilon); + k=k+1; } + while (!bHasFound && k<fMaxIteration); + if (bHasFound) + return -u*2.0/f_PI; else - { -#if 0 - // #i12430# don't know the intention of this piece of code... - double z = 8.0 / fNum; - double y = z * z; - double xx = fNum - 2.356194491; - - double f1 = 1.0 + y * ( 0.183105e-2 + y * ( -0.3516396496e-4 + - y * ( 0.2457520174e-5 + y * ( -0.240337019e6 ) ) ) ); - - double f2 = 0.04687499995 + y * ( -0.2002690873e-3 + - y * ( 0.8449199096e-5 + y * ( -0.88228987e-6 + - y * 0.105787412e-6 ) ) ); - - fRet = sqrt( 0.636619772 / fNum ) * ( sin( xx ) * f1 + z * cos( xx ) * f2 ); -#endif - // #i12430# ...but this seems to work much better. - fRet = sqrt( 0.636619772 / fNum ) * sin( fNum - 2.356194491 ); - } - - return fRet; + throw NoConvergenceException(); } - -double BesselY( double fNum, sal_Int32 nOrder ) throw( IllegalArgumentException ) +double BesselY( double fNum, sal_Int32 nOrder ) throw( IllegalArgumentException, NoConvergenceException ) { switch( nOrder ) { @@ -407,7 +493,6 @@ double BesselY( double fNum, sal_Int32 nOrder ) throw( IllegalArgumentException } } - // ============================================================================ } // namespace analysis diff --git a/scaddins/source/analysis/bessel.hxx b/scaddins/source/analysis/bessel.hxx index 24e8217537d5..c94b4f1a9b77 100644 --- a/scaddins/source/analysis/bessel.hxx +++ b/scaddins/source/analysis/bessel.hxx @@ -29,6 +29,7 @@ #define SCA_BESSEL_HXX #include <com/sun/star/lang/IllegalArgumentException.hpp> +#include <com/sun/star/sheet/NoConvergenceException.hpp> #include <sal/types.h> namespace sca { @@ -39,16 +40,16 @@ namespace analysis { // ============================================================================ /** Returns the result for the unmodified BESSEL function of first kind (J), n-th order, at point x. */ -double BesselJ( double x, sal_Int32 n ) throw( ::com::sun::star::lang::IllegalArgumentException ); +double BesselJ( double x, sal_Int32 n ) throw( ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::sheet::NoConvergenceException ); /** Returns the result for the modified BESSEL function of first kind (I), n-th order, at point x. */ -double BesselI( double x, sal_Int32 n ) throw( ::com::sun::star::lang::IllegalArgumentException ); +double BesselI( double x, sal_Int32 n ) throw( ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::sheet::NoConvergenceException ); /** Returns the result for the unmodified BESSEL function of second kind (Y), n-th order, at point x. */ -double BesselY( double x, sal_Int32 n ) throw( ::com::sun::star::lang::IllegalArgumentException ); +double BesselY( double x, sal_Int32 n ) throw( ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::sheet::NoConvergenceException ); /** Returns the result for the modified BESSEL function of second kind (K), n-th order, at point x. */ -double BesselK( double x, sal_Int32 n ) throw( ::com::sun::star::lang::IllegalArgumentException ); +double BesselK( double x, sal_Int32 n ) throw( ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::sheet::NoConvergenceException ); // ============================================================================ diff --git a/scaddins/source/analysis/makefile.mk b/scaddins/source/analysis/makefile.mk index d837d644dc21..a23f9886b9b1 100644 --- a/scaddins/source/analysis/makefile.mk +++ b/scaddins/source/analysis/makefile.mk @@ -73,7 +73,8 @@ UNOTYPES=\ com.sun.star.uno.XComponentContext \ com.sun.star.util.Date \ com.sun.star.util.XNumberFormatter \ - com.sun.star.util.XNumberFormatTypes + com.sun.star.util.XNumberFormatTypes \ + com.sun.star.sheet.NoConvergenceException # --- Files ------------------------------------- |