diff options
192 files changed, 8572 insertions, 3212 deletions
diff --git a/chart2/source/controller/chartapiwrapper/ChartDocumentWrapper.cxx b/chart2/source/controller/chartapiwrapper/ChartDocumentWrapper.cxx index 67f537c49b98..14a20e133ff1 100644 --- a/chart2/source/controller/chartapiwrapper/ChartDocumentWrapper.cxx +++ b/chart2/source/controller/chartapiwrapper/ChartDocumentWrapper.cxx @@ -45,6 +45,8 @@ #include "DataSourceHelper.hxx" #include "ChartModelHelper.hxx" #include "ContainerHelper.hxx" +#include "AxisHelper.hxx" +#include "ThreeDHelper.hxx" #include "TitleWrapper.hxx" #include "ChartDataWrapper.hxx" @@ -64,6 +66,8 @@ #include <svx/unoshcol.hxx> // header for define DBG_ASSERT #include <tools/debug.hxx> +#include <vcl/svapp.hxx> + #include <com/sun/star/drawing/XDrawPagesSupplier.hpp> #include <com/sun/star/beans/PropertyAttribute.hpp> #include <com/sun/star/lang/DisposedException.hpp> @@ -1308,8 +1312,19 @@ uno::Reference< uno::XInterface > SAL_CALL ChartDocumentWrapper::createInstance( if( xDia.is()) { // /-- locked controllers - ControllerLockGuard aCtrlLockGuard( Reference< frame::XModel >( xChartDoc, uno::UNO_QUERY )); - xTemplate->changeDiagram( xDia ); + Reference< frame::XModel > xModel( xChartDoc, uno::UNO_QUERY ); + ControllerLockGuard aCtrlLockGuard( xModel ); + Reference< chart2::XDiagram > xDiagram = ChartModelHelper::findDiagram( xModel ); + ThreeDLookScheme e3DScheme = ThreeDHelper::detectScheme( xDiagram ); + Reference< lang::XMultiServiceFactory > xTemplateManager( xChartDoc->getChartTypeManager(), uno::UNO_QUERY ); + DiagramHelper::tTemplateWithServiceName aTemplateWithService( + DiagramHelper::getTemplateForDiagram( xDiagram, xTemplateManager )); + if( aTemplateWithService.first.is()) + aTemplateWithService.first->resetStyles( xDiagram );//#i109371# + xTemplate->changeDiagram( xDiagram ); + if( Application::GetSettings().GetLayoutRTL() ) + AxisHelper::setRTLAxisLayout( AxisHelper::getCoordinateSystemByIndex( xDiagram, 0 ) ); + ThreeDHelper::setScheme( xDiagram, e3DScheme ); // \-- locked controllers } else diff --git a/chart2/source/controller/chartapiwrapper/DataSeriesPointWrapper.cxx b/chart2/source/controller/chartapiwrapper/DataSeriesPointWrapper.cxx index f099eaa8499a..d69212512ebe 100644 --- a/chart2/source/controller/chartapiwrapper/DataSeriesPointWrapper.cxx +++ b/chart2/source/controller/chartapiwrapper/DataSeriesPointWrapper.cxx @@ -285,7 +285,7 @@ void WrappedAttachedAxisProperty::setPropertyValue( const Any& rOuterValue, cons { Reference< chart2::XDiagram > xDiagram( m_spChart2ModelContact->getChart2Diagram() ); if( xDiagram.is() ) - ::chart::DiagramHelper::attachSeriesToAxis( bNewAttachedToMainAxis, xDataSeries, xDiagram, m_spChart2ModelContact->m_xContext ); + ::chart::DiagramHelper::attachSeriesToAxis( bNewAttachedToMainAxis, xDataSeries, xDiagram, m_spChart2ModelContact->m_xContext, false ); } } @@ -746,7 +746,7 @@ const std::vector< WrappedProperty* > DataSeriesPointWrapper::createWrappedPrope aWrappedProperties.push_back( new WrappedProperty( C2U( "FillStyle" ), C2U( "FillStyle" ) ) ); aWrappedProperties.push_back( new WrappedProperty( C2U( "FillTransparence" ), C2U( "Transparency" ) ) ); - aWrappedProperties.push_back( new WrappedIgnoreProperty( C2U( "LineJoint" ), uno::makeAny( drawing::LineJoint_NONE ) ) ); + aWrappedProperties.push_back( new WrappedIgnoreProperty( C2U( "LineJoint" ), uno::makeAny( drawing::LineJoint_ROUND ) ) ); aWrappedProperties.push_back( new WrappedProperty( C2U( "FillTransparenceGradientName" ), C2U( "TransparencyGradientName" ) ) ); aWrappedProperties.push_back( new WrappedProperty( C2U( "FillGradientName" ), C2U( "GradientName" ) ) ); aWrappedProperties.push_back( new WrappedProperty( C2U( "FillGradientStepCount" ), C2U( "GradientStepCount" ) ) ); diff --git a/chart2/source/controller/dialogs/ChangingResource.cxx b/chart2/source/controller/dialogs/ChangingResource.cxx index e7461325e3be..22886c9b6108 100644 --- a/chart2/source/controller/dialogs/ChangingResource.cxx +++ b/chart2/source/controller/dialogs/ChangingResource.cxx @@ -35,6 +35,10 @@ namespace chart { //............................................................................. +ResourceChangeListener::~ResourceChangeListener() +{ +} + ChangingResource::ChangingResource() : m_pChangeListener(0) { diff --git a/chart2/source/controller/dialogs/ChangingResource.hxx b/chart2/source/controller/dialogs/ChangingResource.hxx index df69358b00b7..ed6be33b912e 100644 --- a/chart2/source/controller/dialogs/ChangingResource.hxx +++ b/chart2/source/controller/dialogs/ChangingResource.hxx @@ -42,6 +42,7 @@ class ResourceChangeListener { public: virtual void stateChanged( ChangingResource* pResource ) = 0; + virtual ~ResourceChangeListener(); }; class ChangingResource diff --git a/chart2/source/controller/dialogs/ChartTypeTemplateProvider.hxx b/chart2/source/controller/dialogs/ChartTypeTemplateProvider.hxx index 6462d4897945..b2790a1678bb 100644 --- a/chart2/source/controller/dialogs/ChartTypeTemplateProvider.hxx +++ b/chart2/source/controller/dialogs/ChartTypeTemplateProvider.hxx @@ -44,6 +44,7 @@ class ChartTypeTemplateProvider public: virtual ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartTypeTemplate > getCurrentTemplate() const =0; + virtual ~ChartTypeTemplateProvider() {} }; //............................................................................. diff --git a/chart2/source/controller/dialogs/tp_ChartType.cxx b/chart2/source/controller/dialogs/tp_ChartType.cxx index f4b314de8a40..244d23ed8eff 100644 --- a/chart2/source/controller/dialogs/tp_ChartType.cxx +++ b/chart2/source/controller/dialogs/tp_ChartType.cxx @@ -987,8 +987,8 @@ IMPL_LINK( ChartTypeTabPage, SelectMainTypeHdl, void *, EMPTYARG ) commitToModel( aParameter ); //detect the new ThreeDLookScheme aParameter.eThreeDLookScheme = ThreeDHelper::detectScheme( ChartModelHelper::findDiagram( m_xChartModel ) ); - if(!aParameter.b3DLook && aParameter.eThreeDLookScheme!=ThreeDLookScheme_Simple ) - aParameter.eThreeDLookScheme=ThreeDLookScheme_Simple; + if(!aParameter.b3DLook && aParameter.eThreeDLookScheme!=ThreeDLookScheme_Realistic ) + aParameter.eThreeDLookScheme=ThreeDLookScheme_Realistic; aParameter.bSortByXValues = lcl_getSortByXValues( m_xChartModel ); this->fillAllControls( aParameter ); @@ -1109,8 +1109,8 @@ void ChartTypeTabPage::initializePage() //set ThreeDLookScheme aParameter.eThreeDLookScheme = ThreeDHelper::detectScheme( xDiagram ); - if(!aParameter.b3DLook && aParameter.eThreeDLookScheme!=ThreeDLookScheme_Simple ) - aParameter.eThreeDLookScheme=ThreeDLookScheme_Simple; + if(!aParameter.b3DLook && aParameter.eThreeDLookScheme!=ThreeDLookScheme_Realistic ) + aParameter.eThreeDLookScheme=ThreeDLookScheme_Realistic; aParameter.bSortByXValues = lcl_getSortByXValues( m_xChartModel ); diff --git a/chart2/source/controller/main/ChartController_Tools.cxx b/chart2/source/controller/main/ChartController_Tools.cxx index 352a7e1279cc..ff567636ba0e 100644 --- a/chart2/source/controller/main/ChartController_Tools.cxx +++ b/chart2/source/controller/main/ChartController_Tools.cxx @@ -49,6 +49,7 @@ #include "AxisHelper.hxx" #include "RegressionCurveHelper.hxx" #include "ShapeController.hxx" +#include "DiagramHelper.hxx" #include <com/sun/star/chart2/DataPointLabel.hpp> #include <com/sun/star/beans/XPropertyState.hpp> @@ -115,7 +116,14 @@ bool lcl_deleteDataSeries( ActionDescriptionProvider::createDescription( ActionDescriptionProvider::DELETE, ::rtl::OUString( String( ::chart::SchResId( STR_OBJECT_DATASERIES )))), xUndoManager, xModel ); + + Reference< chart2::XDiagram > xDiagram( ::chart::ChartModelHelper::findDiagram( xModel ) ); + uno::Reference< chart2::XAxis > xAxis( ::chart::DiagramHelper::getAttachedAxis( xSeries, xDiagram ) ); + ::chart::DataSeriesHelper::deleteSeries( xSeries, xChartType ); + + ::chart::AxisHelper::hideAxisIfNoDataIsAttached( xAxis, xDiagram ); + bResult = true; aUndoGuard.commitAction(); } @@ -575,8 +583,7 @@ bool ChartController::isObjectDeleteable( const uno::Any& rSelection ) { OUString aSelObjCID( aSelOID.getObjectCID() ); ObjectType aObjectType(ObjectIdentifier::getObjectType( aSelObjCID )); - if( (OBJECTTYPE_TITLE == aObjectType) || (OBJECTTYPE_LEGEND == aObjectType) - || (OBJECTTYPE_DATA_SERIES == aObjectType) ) + if( (OBJECTTYPE_TITLE == aObjectType) || (OBJECTTYPE_LEGEND == aObjectType) ) return true; if( (OBJECTTYPE_DATA_SERIES == aObjectType) || (OBJECTTYPE_LEGEND_ENTRY == aObjectType) ) return true; @@ -585,6 +592,8 @@ bool ChartController::isObjectDeleteable( const uno::Any& rSelection ) return true; if( (OBJECTTYPE_DATA_LABELS == aObjectType) || (OBJECTTYPE_DATA_LABEL == aObjectType) ) return true; + if( (OBJECTTYPE_AXIS == aObjectType) || (OBJECTTYPE_GRID == aObjectType) || (OBJECTTYPE_SUBGRID == aObjectType) ) + return true; } else if ( aSelOID.isAdditionalShape() ) { @@ -628,8 +637,6 @@ bool ChartController::executeDispatch_Delete() return false; //remove chart object - impl_ClearSelection(); - uno::Reference< chart2::XChartDocument > xChartDoc( m_aModel->getModel(), uno::UNO_QUERY ); if( !xChartDoc.is() ) return false; @@ -786,6 +793,24 @@ bool ChartController::executeDispatch_Delete() } break; } + case OBJECTTYPE_AXIS: + { + executeDispatch_DeleteAxis(); + bReturn = true; + break; + } + case OBJECTTYPE_GRID: + { + executeDispatch_DeleteMajorGrid(); + bReturn = true; + break; + } + case OBJECTTYPE_SUBGRID: + { + executeDispatch_DeleteMinorGrid(); + bReturn = true; + break; + } default: { diff --git a/chart2/source/inc/AxisHelper.hxx b/chart2/source/inc/AxisHelper.hxx index be2a60bb63f7..75e69436a784 100644 --- a/chart2/source/inc/AxisHelper.hxx +++ b/chart2/source/inc/AxisHelper.hxx @@ -101,6 +101,9 @@ public: static void makeAxisInvisible( const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XAxis >& xAxis ); static void makeGridInvisible( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& xGridProperties ); + static void hideAxisIfNoDataIsAttached( const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XAxis >& xAxis + , const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDiagram >& xDiagram); + SAL_DLLPRIVATE static sal_Bool areAxisLabelsVisible( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& xAxisProperties ); static sal_Bool isAxisVisible( const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XAxis >& xAxis ); static sal_Bool isGridVisible( const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& xGridProperties ); diff --git a/chart2/source/inc/ChartModelHelper.hxx b/chart2/source/inc/ChartModelHelper.hxx index 7cd205b83fb5..fb087abf15fd 100644 --- a/chart2/source/inc/ChartModelHelper.hxx +++ b/chart2/source/inc/ChartModelHelper.hxx @@ -89,6 +89,8 @@ public: , const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDataSeries >& xGivenDataSeries ); + static ::com::sun::star::awt::Size getDefaultPageSize(); + static ::com::sun::star::awt::Size getPageSize( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >& xModel ); diff --git a/chart2/source/inc/DiagramHelper.hxx b/chart2/source/inc/DiagramHelper.hxx index c685b99b974f..14113e7396ca 100644 --- a/chart2/source/inc/DiagramHelper.hxx +++ b/chart2/source/inc/DiagramHelper.hxx @@ -172,7 +172,8 @@ public: const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XDiagram >& xDiagram, const ::com::sun::star::uno::Reference< - ::com::sun::star::uno::XComponentContext > & xContext ); + ::com::sun::star::uno::XComponentContext > & xContext, + bool bAdaptAxes=true ); static ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XAxis > getAttachedAxis( diff --git a/chart2/source/model/main/Axis.cxx b/chart2/source/model/main/Axis.cxx index 17d8fe9f3989..cab49e8d0149 100644 --- a/chart2/source/model/main/Axis.cxx +++ b/chart2/source/model/main/Axis.cxx @@ -207,7 +207,7 @@ void lcl_AddDefaultsToMap( ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_AXIS_TEXT_STACKED, false ); ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_AXIS_TEXT_ARRANGE_ORDER, ::com::sun::star::chart::ChartAxisArrangeOrderType_AUTO ); - float fDefaultCharHeight = 8.0; + float fDefaultCharHeight = 10.0; ::chart::PropertyHelper::setPropertyValue( rOutMap, ::chart::CharacterProperties::PROP_CHAR_CHAR_HEIGHT, fDefaultCharHeight ); ::chart::PropertyHelper::setPropertyValue( rOutMap, ::chart::CharacterProperties::PROP_CHAR_ASIAN_CHAR_HEIGHT, fDefaultCharHeight ); ::chart::PropertyHelper::setPropertyValue( rOutMap, ::chart::CharacterProperties::PROP_CHAR_COMPLEX_CHAR_HEIGHT, fDefaultCharHeight ); diff --git a/chart2/source/model/main/ChartModel.cxx b/chart2/source/model/main/ChartModel.cxx index 6d848e8c5c9c..2a34844c169d 100755..100644 --- a/chart2/source/model/main/ChartModel.cxx +++ b/chart2/source/model/main/ChartModel.cxx @@ -106,8 +106,7 @@ ChartModel::ChartModel(uno::Reference<uno::XComponentContext > const & xContext) , m_aControllers( m_aModelMutex ) , m_nControllerLockCount(0) , m_xContext( xContext ) - // default visual area is 8 x 7 cm - , m_aVisualAreaSize( 8000, 7000 ) + , m_aVisualAreaSize( ChartModelHelper::getDefaultPageSize() ) , m_xDataProvider( 0 ) , m_xInternalDataProvider( 0 ) , m_xPageBackground( new PageBackground( m_xContext ) ) diff --git a/chart2/source/model/main/ChartModel_Persistence.cxx b/chart2/source/model/main/ChartModel_Persistence.cxx index dba8ea930b9f..113be99915cb 100644 --- a/chart2/source/model/main/ChartModel_Persistence.cxx +++ b/chart2/source/model/main/ChartModel_Persistence.cxx @@ -464,7 +464,7 @@ void SAL_CALL ChartModel::initNew() { xDiagramProperties->setPropertyValue( C2U("RightAngledAxes"), uno::makeAny( sal_True )); xDiagramProperties->setPropertyValue( C2U("D3DScenePerspective"), uno::makeAny( drawing::ProjectionMode_PARALLEL )); - ThreeDHelper::setScheme( xDiagram, ThreeDLookScheme_Simple ); + ThreeDHelper::setScheme( xDiagram, ThreeDLookScheme_Realistic ); } //set some new 'defaults' for wall and floor diff --git a/chart2/source/model/main/DataSeries.cxx b/chart2/source/model/main/DataSeries.cxx index e1ff3d7121cb..bdb46665004f 100644 --- a/chart2/source/model/main/DataSeries.cxx +++ b/chart2/source/model/main/DataSeries.cxx @@ -255,7 +255,7 @@ uno::Any DataSeries::GetDefaultValue( sal_Int32 nHandle ) const DataSeriesProperties::AddDefaultsToMap( aStaticDefaults ); CharacterProperties::AddDefaultsToMap( aStaticDefaults ); - float fDefaultCharHeight = 6.0; + float fDefaultCharHeight = 10.0; ::chart::PropertyHelper::setPropertyValue( aStaticDefaults, ::chart::CharacterProperties::PROP_CHAR_CHAR_HEIGHT, fDefaultCharHeight ); ::chart::PropertyHelper::setPropertyValue( aStaticDefaults, ::chart::CharacterProperties::PROP_CHAR_ASIAN_CHAR_HEIGHT, fDefaultCharHeight ); ::chart::PropertyHelper::setPropertyValue( aStaticDefaults, ::chart::CharacterProperties::PROP_CHAR_COMPLEX_CHAR_HEIGHT, fDefaultCharHeight ); diff --git a/chart2/source/model/main/Legend.cxx b/chart2/source/model/main/Legend.cxx index e3d8a3107d4c..c1143ecdf77a 100644 --- a/chart2/source/model/main/Legend.cxx +++ b/chart2/source/model/main/Legend.cxx @@ -114,7 +114,7 @@ void lcl_AddDefaultsToMap( ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_LEGEND_PREFERRED_EXPANSION, chart2::LegendExpansion_HIGH ); ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_LEGEND_SHOW, true ); - float fDefaultCharHeight = 8.0; + float fDefaultCharHeight = 10.0; ::chart::PropertyHelper::setPropertyValue( rOutMap, ::chart::CharacterProperties::PROP_CHAR_CHAR_HEIGHT, fDefaultCharHeight ); ::chart::PropertyHelper::setPropertyValue( rOutMap, ::chart::CharacterProperties::PROP_CHAR_ASIAN_CHAR_HEIGHT, fDefaultCharHeight ); ::chart::PropertyHelper::setPropertyValue( rOutMap, ::chart::CharacterProperties::PROP_CHAR_COMPLEX_CHAR_HEIGHT, fDefaultCharHeight ); diff --git a/chart2/source/model/template/AreaChartTypeTemplate.cxx b/chart2/source/model/template/AreaChartTypeTemplate.cxx index 072b16a07d26..5fe21cfb25e0 100644 --- a/chart2/source/model/template/AreaChartTypeTemplate.cxx +++ b/chart2/source/model/template/AreaChartTypeTemplate.cxx @@ -31,6 +31,7 @@ #include "macros.hxx" #include "servicenames_charttypes.hxx" #include "DiagramHelper.hxx" +#include "DataSeriesHelper.hxx" #include "ContainerHelper.hxx" #include "PropertyHelper.hxx" #include <com/sun/star/beans/PropertyAttribute.hpp> @@ -208,41 +209,26 @@ void SAL_CALL AreaChartTypeTemplate::applyStyle( throw (uno::RuntimeException) { ChartTypeTemplate::applyStyle( xSeries, nChartTypeIndex, nSeriesIndex, nSeriesCount ); - if( getDimension() == 3 ) - { - try - { - uno::Reference< beans::XPropertySet > xProp( xSeries, uno::UNO_QUERY_THROW ); - xProp->setPropertyValue( C2U("BorderStyle"), - uno::makeAny( drawing::LineStyle_NONE )); - } - catch( uno::Exception & ex ) - { - ASSERT_EXCEPTION( ex ); - } - } + DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints( xSeries, C2U( "BorderStyle" ), uno::makeAny( drawing::LineStyle_NONE ) ); } void SAL_CALL AreaChartTypeTemplate::resetStyles( const Reference< chart2::XDiagram >& xDiagram ) throw (uno::RuntimeException) { ChartTypeTemplate::resetStyles( xDiagram ); - if( getDimension() == 3 ) + ::std::vector< Reference< chart2::XDataSeries > > aSeriesVec( + DiagramHelper::getDataSeriesFromDiagram( xDiagram )); + uno::Any aLineStyleAny( uno::makeAny( drawing::LineStyle_NONE )); + for( ::std::vector< Reference< chart2::XDataSeries > >::iterator aIt( aSeriesVec.begin()); + aIt != aSeriesVec.end(); ++aIt ) { - ::std::vector< Reference< chart2::XDataSeries > > aSeriesVec( - DiagramHelper::getDataSeriesFromDiagram( xDiagram )); - uno::Any aLineStyleAny( uno::makeAny( drawing::LineStyle_NONE )); - for( ::std::vector< Reference< chart2::XDataSeries > >::iterator aIt( aSeriesVec.begin()); - aIt != aSeriesVec.end(); ++aIt ) + Reference< beans::XPropertyState > xState( *aIt, uno::UNO_QUERY ); + Reference< beans::XPropertySet > xProp( *aIt, uno::UNO_QUERY ); + if( xState.is() && + xProp.is() && + xProp->getPropertyValue( C2U("BorderStyle")) == aLineStyleAny ) { - Reference< beans::XPropertyState > xState( *aIt, uno::UNO_QUERY ); - Reference< beans::XPropertySet > xProp( *aIt, uno::UNO_QUERY ); - if( xState.is() && - xProp.is() && - xProp->getPropertyValue( C2U("BorderStyle")) == aLineStyleAny ) - { - xState->setPropertyToDefault( C2U("BorderStyle")); - } + xState->setPropertyToDefault( C2U("BorderStyle")); } } } diff --git a/chart2/source/model/template/BarChartTypeTemplate.cxx b/chart2/source/model/template/BarChartTypeTemplate.cxx index 81f1337ccb29..01dc4c253d2b 100644 --- a/chart2/source/model/template/BarChartTypeTemplate.cxx +++ b/chart2/source/model/template/BarChartTypeTemplate.cxx @@ -279,6 +279,7 @@ void SAL_CALL BarChartTypeTemplate::applyStyle( throw (uno::RuntimeException) { ChartTypeTemplate::applyStyle( xSeries, nChartTypeIndex, nSeriesIndex, nSeriesCount ); + DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints( xSeries, C2U( "BorderStyle" ), uno::makeAny( drawing::LineStyle_NONE ) ); if( getDimension() == 3 ) { try @@ -300,24 +301,22 @@ void SAL_CALL BarChartTypeTemplate::resetStyles( throw (uno::RuntimeException) { ChartTypeTemplate::resetStyles( xDiagram ); - if( getDimension() == 3 ) + ::std::vector< Reference< chart2::XDataSeries > > aSeriesVec( + DiagramHelper::getDataSeriesFromDiagram( xDiagram )); + uno::Any aLineStyleAny( uno::makeAny( drawing::LineStyle_NONE )); + for( ::std::vector< Reference< chart2::XDataSeries > >::iterator aIt( aSeriesVec.begin()); + aIt != aSeriesVec.end(); ++aIt ) { - ::std::vector< Reference< chart2::XDataSeries > > aSeriesVec( - DiagramHelper::getDataSeriesFromDiagram( xDiagram )); - uno::Any aLineStyleAny( uno::makeAny( drawing::LineStyle_NONE )); - for( ::std::vector< Reference< chart2::XDataSeries > >::iterator aIt( aSeriesVec.begin()); - aIt != aSeriesVec.end(); ++aIt ) + Reference< beans::XPropertyState > xState( *aIt, uno::UNO_QUERY ); + if( xState.is()) { - Reference< beans::XPropertyState > xState( *aIt, uno::UNO_QUERY ); - if( xState.is()) - { + if( getDimension() == 3 ) xState->setPropertyToDefault( C2U("Geometry3D")); - Reference< beans::XPropertySet > xProp( xState, uno::UNO_QUERY ); - if( xProp.is() && - xProp->getPropertyValue( C2U("BorderStyle")) == aLineStyleAny ) - { - xState->setPropertyToDefault( C2U("BorderStyle")); - } + Reference< beans::XPropertySet > xProp( xState, uno::UNO_QUERY ); + if( xProp.is() && + xProp->getPropertyValue( C2U("BorderStyle")) == aLineStyleAny ) + { + xState->setPropertyToDefault( C2U("BorderStyle")); } } } diff --git a/chart2/source/model/template/BubbleChartTypeTemplate.cxx b/chart2/source/model/template/BubbleChartTypeTemplate.cxx index 3f297d1e2e27..59b552cc8995 100644 --- a/chart2/source/model/template/BubbleChartTypeTemplate.cxx +++ b/chart2/source/model/template/BubbleChartTypeTemplate.cxx @@ -186,6 +186,7 @@ void SAL_CALL BubbleChartTypeTemplate::applyStyle( throw (uno::RuntimeException) { ChartTypeTemplate::applyStyle( xSeries, nChartTypeIndex, nSeriesIndex, nSeriesCount ); + DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints( xSeries, C2U( "BorderStyle" ), uno::makeAny( drawing::LineStyle_NONE ) ); try { diff --git a/chart2/source/model/template/ColumnLineChartTypeTemplate.cxx b/chart2/source/model/template/ColumnLineChartTypeTemplate.cxx index 70a0a633836a..663cad4c2fe4 100644 --- a/chart2/source/model/template/ColumnLineChartTypeTemplate.cxx +++ b/chart2/source/model/template/ColumnLineChartTypeTemplate.cxx @@ -39,6 +39,7 @@ #include <com/sun/star/beans/PropertyAttribute.hpp> #include <com/sun/star/chart2/XChartTypeContainer.hpp> #include <com/sun/star/chart2/XDataSeriesContainer.hpp> +#include <com/sun/star/drawing/LineStyle.hpp> #include <algorithm> @@ -270,7 +271,11 @@ void SAL_CALL ColumnLineChartTypeTemplate::applyStyle( { ChartTypeTemplate::applyStyle( xSeries, nChartTypeIndex, nSeriesIndex, nSeriesCount ); - if( nChartTypeIndex==1 ) // lines + if( nChartTypeIndex==0 ) // columns + { + DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints( xSeries, C2U( "BorderStyle" ), uno::makeAny( drawing::LineStyle_NONE ) ); + } + else if( nChartTypeIndex==1 ) // lines { Reference< beans::XPropertySet > xProp( xSeries, uno::UNO_QUERY ); if( xProp.is() ) diff --git a/chart2/source/model/template/PieChartTypeTemplate.cxx b/chart2/source/model/template/PieChartTypeTemplate.cxx index a8f2fc12720a..c16682846d53 100644 --- a/chart2/source/model/template/PieChartTypeTemplate.cxx +++ b/chart2/source/model/template/PieChartTypeTemplate.cxx @@ -554,12 +554,7 @@ void SAL_CALL PieChartTypeTemplate::applyStyle( } // line style - drawing::LineStyle eStyle = (getDimension() == 2) - ? drawing::LineStyle_SOLID - : drawing::LineStyle_NONE; - - xProp->setPropertyValue( C2U("BorderStyle"), - uno::makeAny( eStyle )); + DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints( xSeries, C2U( "BorderStyle" ), uno::makeAny( drawing::LineStyle_NONE ) ); // vary colors by point xProp->setPropertyValue( C2U("VaryColorsByPoint"), uno::makeAny( true )); @@ -616,10 +611,7 @@ void SAL_CALL PieChartTypeTemplate::resetStyles( const Reference< chart2::XDiagr // line style ::std::vector< Reference< chart2::XDataSeries > > aSeriesVec( DiagramHelper::getDataSeriesFromDiagram( xDiagram )); - drawing::LineStyle eStyle = (getDimension() == 2) - ? drawing::LineStyle_SOLID - : drawing::LineStyle_NONE; - uno::Any aLineStyleAny( uno::makeAny( eStyle )); + uno::Any aLineStyleAny( uno::makeAny( drawing::LineStyle_NONE )); for( ::std::vector< Reference< chart2::XDataSeries > >::iterator aIt( aSeriesVec.begin()); aIt != aSeriesVec.end(); ++aIt ) { diff --git a/chart2/source/model/template/ScatterChartTypeTemplate.cxx b/chart2/source/model/template/ScatterChartTypeTemplate.cxx index f952abaa3611..a83d9a8a4ea3 100644 --- a/chart2/source/model/template/ScatterChartTypeTemplate.cxx +++ b/chart2/source/model/template/ScatterChartTypeTemplate.cxx @@ -235,6 +235,8 @@ void SAL_CALL ScatterChartTypeTemplate::applyStyle( DataSeriesHelper::switchSymbolsOnOrOff( xProp, m_bHasSymbols, nSeriesIndex ); DataSeriesHelper::switchLinesOnOrOff( xProp, m_bHasLines ); DataSeriesHelper::makeLinesThickOrThin( xProp, m_nDim==2 ); + if( m_nDim==3 ) + DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints( xSeries, C2U( "BorderStyle" ), uno::makeAny( drawing::LineStyle_NONE ) ); } catch( uno::Exception & ex ) { diff --git a/chart2/source/model/template/StockChartTypeTemplate.cxx b/chart2/source/model/template/StockChartTypeTemplate.cxx index 90a313b78c8a..00ace6c330ad 100644 --- a/chart2/source/model/template/StockChartTypeTemplate.cxx +++ b/chart2/source/model/template/StockChartTypeTemplate.cxx @@ -265,10 +265,14 @@ void SAL_CALL StockChartTypeTemplate::applyStyle( if( xProp.is() ) xProp->setPropertyValue( C2U("AttachedAxisIndex"), uno::makeAny( nNewAxisIndex ) ); - - //ensure that lines are on - if( !bHasVolume || nChartTypeIndex==0 ) + if( bHasVolume && nChartTypeIndex==0 ) { + //switch lines off for volume bars + DataSeriesHelper::setPropertyAlsoToAllAttributedDataPoints( xSeries, C2U( "BorderStyle" ), uno::makeAny( drawing::LineStyle_NONE ) ); + } + else + { + //ensure that lines are on if( xProp.is() ) { drawing::LineStyle eStyle = drawing::LineStyle_NONE; @@ -277,6 +281,7 @@ void SAL_CALL StockChartTypeTemplate::applyStyle( xProp->setPropertyValue( C2U("LineStyle"), uno::makeAny( drawing::LineStyle_SOLID )); } } + } catch( uno::Exception & ex ) { diff --git a/chart2/source/tools/AxisHelper.cxx b/chart2/source/tools/AxisHelper.cxx index b2f7fb24e6f2..8cdd24e4dc05 100644 --- a/chart2/source/tools/AxisHelper.cxx +++ b/chart2/source/tools/AxisHelper.cxx @@ -284,6 +284,26 @@ void AxisHelper::makeAxisInvisible( const Reference< XAxis >& xAxis ) } } +//static +void AxisHelper::hideAxisIfNoDataIsAttached( const Reference< XAxis >& xAxis, const Reference< XDiagram >& xDiagram ) +{ + //axis is hidden if no data is attached anymore but data is available + bool bOtherSeriesAttachedToThisAxis = false; + ::std::vector< Reference< chart2::XDataSeries > > aSeriesVector( DiagramHelper::getDataSeriesFromDiagram( xDiagram ) ); + ::std::vector< Reference< chart2::XDataSeries > >::const_iterator aIt = aSeriesVector.begin(); + for( ; aIt != aSeriesVector.end(); ++aIt) + { + uno::Reference< chart2::XAxis > xCurrentAxis( DiagramHelper::getAttachedAxis( *aIt, xDiagram ), uno::UNO_QUERY ); + if( xCurrentAxis==xAxis ) + { + bOtherSeriesAttachedToThisAxis = true; + break; + } + } + if(!bOtherSeriesAttachedToThisAxis && !aSeriesVector.empty() ) + AxisHelper::makeAxisInvisible( xAxis ); +} + void AxisHelper::hideGrid( sal_Int32 nDimensionIndex, sal_Int32 nCooSysIndex, bool bMainGrid , const Reference< XDiagram >& xDiagram ) { diff --git a/chart2/source/tools/ChartModelHelper.cxx b/chart2/source/tools/ChartModelHelper.cxx index ed8c36e08c8d..a49b2abeac98 100644 --- a/chart2/source/tools/ChartModelHelper.cxx +++ b/chart2/source/tools/ChartModelHelper.cxx @@ -134,9 +134,14 @@ uno::Reference< XChartType > ChartModelHelper::getChartTypeOfSeries( return DiagramHelper::getChartTypeOfSeries( ChartModelHelper::findDiagram( xModel ), xGivenDataSeries ); } +awt::Size ChartModelHelper::getDefaultPageSize() +{ + return awt::Size( 16000, 9000 ); +} + awt::Size ChartModelHelper::getPageSize( const uno::Reference< frame::XModel >& xModel ) { - awt::Size aPageSize( 8000, 7000 ); + awt::Size aPageSize( ChartModelHelper::getDefaultPageSize() ); uno::Reference< embed::XVisualObject > xVisualObject(xModel,uno::UNO_QUERY); DBG_ASSERT(xVisualObject.is(),"need xVisualObject for page size"); if( xVisualObject.is() ) diff --git a/chart2/source/tools/ChartTypeHelper.cxx b/chart2/source/tools/ChartTypeHelper.cxx index 9e0b22ba75ac..b851a3864b97 100644 --- a/chart2/source/tools/ChartTypeHelper.cxx +++ b/chart2/source/tools/ChartTypeHelper.cxx @@ -441,44 +441,45 @@ bool ChartTypeHelper::noBordersForSimpleScheme( const uno::Reference< chart2::XC //static sal_Int32 ChartTypeHelper::getDefaultDirectLightColor( bool bSimple, const uno::Reference< chart2::XChartType >& xChartType ) { - if( bSimple ) + sal_Int32 nRet = static_cast< sal_Int32 >( 0x808080 ); // grey + if( xChartType .is() ) { - sal_Int32 nRet = static_cast< sal_Int32 >( 0x999999 ); // grey40 - if( xChartType .is() ) + rtl::OUString aChartType = xChartType->getChartType(); + if( aChartType.equals(CHART2_SERVICE_NAME_CHARTTYPE_PIE) ) { - rtl::OUString aChartType = xChartType->getChartType(); - if( aChartType.equals(CHART2_SERVICE_NAME_CHARTTYPE_PIE) ) + if( bSimple ) nRet = static_cast< sal_Int32 >( 0x333333 ); // grey80 - else if( aChartType.equals(CHART2_SERVICE_NAME_CHARTTYPE_LINE) - || aChartType.equals(CHART2_SERVICE_NAME_CHARTTYPE_SCATTER) ) - nRet = static_cast< sal_Int32 >( 0x666666 ); // grey60 + else + nRet = static_cast< sal_Int32 >( 0xb3b3b3 ); // grey30 } - return nRet; + else if( aChartType.equals(CHART2_SERVICE_NAME_CHARTTYPE_LINE) + || aChartType.equals(CHART2_SERVICE_NAME_CHARTTYPE_SCATTER) ) + nRet = static_cast< sal_Int32 >( 0x666666 ); // grey60 } - return static_cast< sal_Int32 >( 0xb3b3b3 ); // grey30 + return nRet; } //static sal_Int32 ChartTypeHelper::getDefaultAmbientLightColor( bool bSimple, const uno::Reference< chart2::XChartType >& xChartType ) { - if( bSimple ) + sal_Int32 nRet = static_cast< sal_Int32 >( 0x999999 ); // grey40 + if( xChartType .is() ) { - sal_Int32 nRet = static_cast< sal_Int32 >( 0x999999 ); // grey40 - if( xChartType .is() ) + rtl::OUString aChartType = xChartType->getChartType(); + if( aChartType.equals(CHART2_SERVICE_NAME_CHARTTYPE_PIE) ) { - rtl::OUString aChartType = xChartType->getChartType(); - if( aChartType.equals(CHART2_SERVICE_NAME_CHARTTYPE_PIE) ) + if( bSimple ) nRet = static_cast< sal_Int32 >( 0xcccccc ); // grey20 + else + nRet = static_cast< sal_Int32 >( 0x666666 ); // grey60 } - return nRet; } - return static_cast< sal_Int32 >( 0x666666 ); // grey60 + return nRet; } drawing::Direction3D ChartTypeHelper::getDefaultSimpleLightDirection( const uno::Reference< chart2::XChartType >& xChartType ) { - //drawing::Direction3D aRet(0.0, 0.0, 1.0); - drawing::Direction3D aRet(-0.2, 0.7, 0.6); + drawing::Direction3D aRet(0.0, 0.0, 1.0); if( xChartType .is() ) { rtl::OUString aChartType = xChartType->getChartType(); @@ -493,7 +494,7 @@ drawing::Direction3D ChartTypeHelper::getDefaultSimpleLightDirection( const uno: drawing::Direction3D ChartTypeHelper::getDefaultRealisticLightDirection( const uno::Reference< chart2::XChartType >& xChartType ) { - drawing::Direction3D aRet(-0.1, 0.6, 0.8); + drawing::Direction3D aRet(0.0, 0.0, 1.0); if( xChartType .is() ) { rtl::OUString aChartType = xChartType->getChartType(); diff --git a/chart2/source/tools/DataSeriesHelper.cxx b/chart2/source/tools/DataSeriesHelper.cxx index 538f2966105f..acff332d4229 100644 --- a/chart2/source/tools/DataSeriesHelper.cxx +++ b/chart2/source/tools/DataSeriesHelper.cxx @@ -595,7 +595,7 @@ void makeLinesThickOrThin( const Reference< beans::XPropertySet > & xSeriesPrope if( !xSeriesProperties.is() ) return; - sal_Int32 nNewValue = bThick ? 88 : 0; + sal_Int32 nNewValue = bThick ? 80 : 0; sal_Int32 nOldValue = 0; if( (xSeriesProperties->getPropertyValue( C2U( "LineWidth" )) >>= nOldValue ) && nOldValue != nNewValue ) diff --git a/chart2/source/tools/DiagramHelper.cxx b/chart2/source/tools/DiagramHelper.cxx index a8da65e5133d..b95e7522943e 100644 --- a/chart2/source/tools/DiagramHelper.cxx +++ b/chart2/source/tools/DiagramHelper.cxx @@ -599,7 +599,7 @@ bool DiagramHelper::attachSeriesToAxis( bool bAttachToMainAxis , const uno::Reference< chart2::XDataSeries >& xDataSeries , const uno::Reference< chart2::XDiagram >& xDiagram , const uno::Reference< uno::XComponentContext > & xContext - ) + , bool bAdaptAxes ) { bool bChanged = false; @@ -610,6 +610,7 @@ bool DiagramHelper::attachSeriesToAxis( bool bAttachToMainAxis sal_Int32 nNewAxisIndex = bAttachToMainAxis ? 0 : 1; sal_Int32 nOldAxisIndex = DataSeriesHelper::getAttachedAxisIndex(xDataSeries); + uno::Reference< chart2::XAxis > xOldAxis( DiagramHelper::getAttachedAxis( xDataSeries, xDiagram ) ); if( nOldAxisIndex != nNewAxisIndex ) { @@ -629,6 +630,11 @@ bool DiagramHelper::attachSeriesToAxis( bool bAttachToMainAxis uno::Reference< XAxis > xAxis( AxisHelper::getAxis( 1, bAttachToMainAxis, xDiagram ) ); if(!xAxis.is()) //create an axis if necessary xAxis = AxisHelper::createAxis( 1, bAttachToMainAxis, xDiagram, xContext ); + if( bAdaptAxes ) + { + AxisHelper::makeAxisVisible( xAxis ); + AxisHelper::hideAxisIfNoDataIsAttached( xOldAxis, xDiagram ); + } } return bChanged; diff --git a/chart2/source/tools/LineProperties.cxx b/chart2/source/tools/LineProperties.cxx index cb72d4336faa..95cf95e21a86 100644 --- a/chart2/source/tools/LineProperties.cxx +++ b/chart2/source/tools/LineProperties.cxx @@ -105,7 +105,7 @@ void LineProperties::AddDefaultsToMap( ::chart::PropertyHelper::setPropertyValueDefault< sal_Int32 >( rOutMap, PROP_LINE_WIDTH, 0 ); ::chart::PropertyHelper::setPropertyValueDefault< sal_Int32 >( rOutMap, PROP_LINE_COLOR, 0x000000 ); // black ::chart::PropertyHelper::setPropertyValueDefault< sal_Int16 >( rOutMap, PROP_LINE_TRANSPARENCE, 0 ); - ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_LINE_JOINT, drawing::LineJoint_NONE ); + ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_LINE_JOINT, drawing::LineJoint_ROUND ); } //static diff --git a/chart2/source/tools/WrappedIgnoreProperty.cxx b/chart2/source/tools/WrappedIgnoreProperty.cxx index bebbf77ceeef..aaa6c545a799 100644 --- a/chart2/source/tools/WrappedIgnoreProperty.cxx +++ b/chart2/source/tools/WrappedIgnoreProperty.cxx @@ -101,7 +101,7 @@ void WrappedIgnoreProperties::addIgnoreLineProperties( std::vector< WrappedPrope rList.push_back( new WrappedIgnoreProperty( C2U( "LineColor" ), uno::makeAny( sal_Int32(0) ) ) ); rList.push_back( new WrappedIgnoreProperty( C2U( "LineTransparence" ), uno::makeAny( sal_Int16(0) ) ) ); rList.push_back( new WrappedIgnoreProperty( C2U( "LineWidth" ), uno::makeAny( sal_Int32(0) ) ) ); - rList.push_back( new WrappedIgnoreProperty( C2U( "LineJoint" ), uno::makeAny( drawing::LineJoint_NONE ) ) ); + rList.push_back( new WrappedIgnoreProperty( C2U( "LineJoint" ), uno::makeAny( drawing::LineJoint_ROUND ) ) ); } //static diff --git a/chart2/source/view/axes/VAxisProperties.cxx b/chart2/source/view/axes/VAxisProperties.cxx index 436541ef27ee..1e3e62894741 100644 --- a/chart2/source/view/axes/VAxisProperties.cxx +++ b/chart2/source/view/axes/VAxisProperties.cxx @@ -33,6 +33,7 @@ #include "CommonConverters.hxx" #include "AxisHelper.hxx" #include "DiagramHelper.hxx" +#include "ChartModelHelper.hxx" #include <tools/color.hxx> #include <com/sun/star/beans/XPropertySet.hpp> @@ -390,8 +391,8 @@ void AxisProperties::init( bool bCartesian ) //----------------------------------------------------------------------------- AxisLabelProperties::AxisLabelProperties() - : m_aFontReferenceSize( 8000, 7000 ) - , m_aMaximumSpaceForLabels( 0 , 0, 8000, 7000 ) + : m_aFontReferenceSize( ChartModelHelper::getDefaultPageSize() ) + , m_aMaximumSpaceForLabels( 0 , 0, m_aFontReferenceSize.Width, m_aFontReferenceSize.Height ) , nNumberFormatKey(0) , eStaggering( SIDE_BY_SIDE ) , bLineBreakAllowed( false ) diff --git a/chart2/source/view/charttypes/AreaChart.cxx b/chart2/source/view/charttypes/AreaChart.cxx index 67914f47bac0..fd1aaa81c3a0 100644 --- a/chart2/source/view/charttypes/AreaChart.cxx +++ b/chart2/source/view/charttypes/AreaChart.cxx @@ -403,7 +403,7 @@ bool AreaChart::impl_createLine( VDataSeries* pSeries m_pShapeFactory->createStripe(xSeriesGroupShape_Shapes , Stripe( aPoint1, aPoint2, fDepth ) - , pSeries->getPropertiesOfSeries(), PropertyMapper::getPropertyNameMapForFilledSeriesProperties(), true ); + , pSeries->getPropertiesOfSeries(), PropertyMapper::getPropertyNameMapForFilledSeriesProperties(), true, 1 ); } } } diff --git a/chart2/source/view/charttypes/BarChart.cxx b/chart2/source/view/charttypes/BarChart.cxx index 470796f8fc1e..0d7ef403f87d 100644..100755 --- a/chart2/source/view/charttypes/BarChart.cxx +++ b/chart2/source/view/charttypes/BarChart.cxx @@ -110,9 +110,16 @@ drawing::Direction3D BarChart::getPreferredDiagramAspectRatio() const if( m_nDimension == 3 ) { aRet = drawing::Direction3D(1.0,-1.0,1.0); - drawing::Direction3D aScale( this->getPlottingPositionHelper(MAIN_AXIS_INDEX).getScaledLogicWidth() ); + BarPositionHelper* pPosHelper = dynamic_cast<BarPositionHelper*>(&( this->getPlottingPositionHelper( MAIN_AXIS_INDEX) ) ); + drawing::Direction3D aScale( pPosHelper->getScaledLogicWidth() ); if(aScale.DirectionX!=0.0) - aRet.DirectionZ = aScale.DirectionZ/aScale.DirectionX; + { + double fXSlotCount = 1.0; + if(!m_aZSlots.empty()) + fXSlotCount = m_aZSlots.begin()->size(); + + aRet.DirectionZ = aScale.DirectionZ/(aScale.DirectionX + aScale.DirectionX*(fXSlotCount-1.0)*pPosHelper->getSlotWidth()); + } else return VSeriesPlotter::getPreferredDiagramAspectRatio(); if(aRet.DirectionZ<0.05) @@ -357,7 +364,8 @@ uno::Reference< drawing::XShape > BarChart::createDataPoint3D_Bar( xShape = m_pShapeFactory->createCone( xTarget, rPosition, rSize, fTopHeight, nRotateZAngleHundredthDegree ); break; case DataPointGeometry3D::PYRAMID: - xShape = m_pShapeFactory->createPyramid( xTarget, rPosition, rSize, fTopHeight, nRotateZAngleHundredthDegree ); + xShape = m_pShapeFactory->createPyramid( xTarget, rPosition, rSize, fTopHeight, nRotateZAngleHundredthDegree>0 + , xObjectProperties, PropertyMapper::getPropertyNameMapForFilledSeriesProperties() ); break; case DataPointGeometry3D::CUBOID: default: @@ -366,7 +374,8 @@ uno::Reference< drawing::XShape > BarChart::createDataPoint3D_Bar( , PropertyMapper::getPropertyNameMapForFilledSeriesProperties(), bRoundedEdges ); return xShape; } - this->setMappedProperties( xShape, xObjectProperties, PropertyMapper::getPropertyNameMapForFilledSeriesProperties() ); + if( nGeometry3D != DataPointGeometry3D::PYRAMID ) + this->setMappedProperties( xShape, xObjectProperties, PropertyMapper::getPropertyNameMapForFilledSeriesProperties() ); return xShape; } @@ -734,6 +743,7 @@ void BarChart::createShapes() double fMiddleHeight = fUpperYValue-fLowerYValue; if(!bPositive) fMiddleHeight*=-1.0; + double fLogicBarDepth = 0.5; if(m_nDimension==3) { if( lcl_hasGeometry3DVariableWidth(nGeometry3D) && fCompleteHeight!=0.0 ) @@ -744,9 +754,11 @@ void BarChart::createShapes() fLogicBarWidth = fLogicBaseWidth*fHeight/(fCompleteHeight); if(fLogicBarWidth<=0.0) fLogicBarWidth=fLogicBaseWidth; + fLogicBarDepth = fLogicBarDepth*fHeight/(fCompleteHeight); + if(fLogicBarDepth<=0.0) + fLogicBarDepth*=-1.0; } } - double fLogicBarDepth = fLogicBarWidth; //better performance for big data FormerBarPoint aFormerPoint( aSeriesFormerPointMap[pSeries] ); diff --git a/chart2/source/view/charttypes/VSeriesPlotter.cxx b/chart2/source/view/charttypes/VSeriesPlotter.cxx index ccba1fdc4106..37888c8f0a9b 100644 --- a/chart2/source/view/charttypes/VSeriesPlotter.cxx +++ b/chart2/source/view/charttypes/VSeriesPlotter.cxx @@ -560,11 +560,17 @@ uno::Reference< drawing::XShape > VSeriesPlotter::createDataLabel( const uno::Re sal_Int32 nYDiff = aTextSize.Height/nLineCountForSymbolsize; sal_Int32 nXDiff = aSymbolSize.Width * nYDiff/aSymbolSize.Height; + // #i109336# Improve auto positioning in chart + nXDiff = nXDiff * 80 / 100; + nYDiff = nYDiff * 80 / 100; + aSymbolSize.Width = nXDiff * 75/100; aSymbolSize.Height = nYDiff * 75/100; awt::Point aSymbolPosition( aUnrotatedTextPos ); - aSymbolPosition.Y += (nYDiff * 25/200); + + // #i109336# Improve auto positioning in chart + aSymbolPosition.Y += ( nYDiff / 4 ); if(LABEL_ALIGN_LEFT==eAlignment || LABEL_ALIGN_LEFT_TOP==eAlignment diff --git a/chart2/source/view/diagram/VDiagram.cxx b/chart2/source/view/diagram/VDiagram.cxx index 51775cdde85b..5ffec22969a0 100644 --- a/chart2/source/view/diagram/VDiagram.cxx +++ b/chart2/source/view/diagram/VDiagram.cxx @@ -534,6 +534,9 @@ void VDiagram::createShapes_3d() bool bAddFloorAndWall = DiagramHelper::isSupportingFloorAndWall( m_xDiagram ); + const bool bDoubleSided = false; + const bool bFlatNormals = true; + //add walls { uno::Reference< beans::XPropertySet > xWallProp( NULL ); @@ -544,19 +547,31 @@ void VDiagram::createShapes_3d() if( !bAddFloorAndWall ) aWallCID = rtl::OUString(); uno::Reference< drawing::XShapes > xWallGroup_Shapes( m_pShapeFactory->createGroup3D( xOuterGroup_Shapes, aWallCID ) ); + + CuboidPlanePosition eLeftWallPos( ThreeDHelper::getAutomaticCuboidPlanePositionForStandardLeftWall( uno::Reference< beans::XPropertySet >( m_xDiagram, uno::UNO_QUERY ) ) ); + CuboidPlanePosition eBackWallPos( ThreeDHelper::getAutomaticCuboidPlanePositionForStandardBackWall( uno::Reference< beans::XPropertySet >( m_xDiagram, uno::UNO_QUERY ) ) ); + //add left wall { + short nRotatedTexture = ( CuboidPlanePosition_Front==eBackWallPos ) ? 3 : 1; double xPos = 0.0; - CuboidPlanePosition eLeftWallPos( ThreeDHelper::getAutomaticCuboidPlanePositionForStandardLeftWall( uno::Reference< beans::XPropertySet >( m_xDiagram, uno::UNO_QUERY ) ) ); if( CuboidPlanePosition_Right==eLeftWallPos ) xPos = FIXED_SIZE_FOR_3D_CHART_VOLUME; Stripe aStripe( drawing::Position3D(xPos,FIXED_SIZE_FOR_3D_CHART_VOLUME,0) - , drawing::Direction3D(0,-FIXED_SIZE_FOR_3D_CHART_VOLUME,0) - , drawing::Direction3D(0,0,FIXED_SIZE_FOR_3D_CHART_VOLUME) ); + , drawing::Direction3D(0,0,FIXED_SIZE_FOR_3D_CHART_VOLUME) + , drawing::Direction3D(0,-FIXED_SIZE_FOR_3D_CHART_VOLUME,0) ); + if( CuboidPlanePosition_Right==eLeftWallPos ) + { + nRotatedTexture = ( CuboidPlanePosition_Front==eBackWallPos ) ? 2 : 0; + aStripe = Stripe( drawing::Position3D(xPos,FIXED_SIZE_FOR_3D_CHART_VOLUME,0) + , drawing::Direction3D(0,-FIXED_SIZE_FOR_3D_CHART_VOLUME,0) + , drawing::Direction3D(0,0,FIXED_SIZE_FOR_3D_CHART_VOLUME) ); + } + aStripe.InvertNormal(true); uno::Reference< drawing::XShape > xShape = m_pShapeFactory->createStripe( xWallGroup_Shapes, aStripe - , xWallProp, PropertyMapper::getPropertyNameMapForFillAndLineProperties(), true, true ); + , xWallProp, PropertyMapper::getPropertyNameMapForFillAndLineProperties(), bDoubleSided, nRotatedTexture, bFlatNormals ); if( !bAddFloorAndWall ) { //we always need this object as dummy object for correct scene dimensions @@ -566,17 +581,25 @@ void VDiagram::createShapes_3d() } //add back wall { + short nRotatedTexture = 0; double zPos = 0.0; - CuboidPlanePosition eBackWallPos( ThreeDHelper::getAutomaticCuboidPlanePositionForStandardBackWall( uno::Reference< beans::XPropertySet >( m_xDiagram, uno::UNO_QUERY ) ) ); if( CuboidPlanePosition_Front==eBackWallPos ) zPos = FIXED_SIZE_FOR_3D_CHART_VOLUME; Stripe aStripe( drawing::Position3D(0,FIXED_SIZE_FOR_3D_CHART_VOLUME,zPos) + , drawing::Direction3D(0,-FIXED_SIZE_FOR_3D_CHART_VOLUME,0) + , drawing::Direction3D(FIXED_SIZE_FOR_3D_CHART_VOLUME,0,0) ); + if( CuboidPlanePosition_Front==eBackWallPos ) + { + aStripe = Stripe( drawing::Position3D(0,FIXED_SIZE_FOR_3D_CHART_VOLUME,zPos) , drawing::Direction3D(FIXED_SIZE_FOR_3D_CHART_VOLUME,0,0) , drawing::Direction3D(0,-FIXED_SIZE_FOR_3D_CHART_VOLUME,0) ); + nRotatedTexture = 3; + } + aStripe.InvertNormal(true); uno::Reference< drawing::XShape > xShape = m_pShapeFactory->createStripe(xWallGroup_Shapes, aStripe - , xWallProp, PropertyMapper::getPropertyNameMapForFillAndLineProperties(), true ); + , xWallProp, PropertyMapper::getPropertyNameMapForFillAndLineProperties(), bDoubleSided, nRotatedTexture, bFlatNormals ); if( !bAddFloorAndWall ) { //we always need this object as dummy object for correct scene dimensions @@ -643,44 +666,14 @@ void VDiagram::createShapes_3d() if( m_xDiagram.is() ) xFloorProp=uno::Reference< beans::XPropertySet >( m_xDiagram->getFloor()); - uno::Reference< drawing::XShape > xShape( - m_xShapeFactory->createInstance( C2U( - "com.sun.star.drawing.Shape3DExtrudeObject") ), uno::UNO_QUERY ); - xOuterGroup_Shapes->add(xShape); - uno::Reference< beans::XPropertySet > xShapeProp( xShape, uno::UNO_QUERY ); - if( xShapeProp.is()) - { - //depth - xShapeProp->setPropertyValue( C2U( UNO_NAME_3D_EXTRUDE_DEPTH ) - , uno::makeAny((sal_Int32)FLOOR_THICKNESS) ); - //PercentDiagonal - xShapeProp->setPropertyValue( C2U( UNO_NAME_3D_PERCENT_DIAGONAL ) - , uno::makeAny( sal_Int32(0) ) ); - - drawing::Direction3D aSize(FIXED_SIZE_FOR_3D_CHART_VOLUME,FIXED_SIZE_FOR_3D_CHART_VOLUME,FLOOR_THICKNESS); - - //Polygon - drawing::PolyPolygonShape3D aPoly; - AddPointToPoly( aPoly, drawing::Position3D(0,0,0) ); - AddPointToPoly( aPoly, drawing::Position3D(FIXED_SIZE_FOR_3D_CHART_VOLUME,0,0) ); - AddPointToPoly( aPoly, drawing::Position3D(FIXED_SIZE_FOR_3D_CHART_VOLUME,FIXED_SIZE_FOR_3D_CHART_VOLUME,0) ); - AddPointToPoly( aPoly, drawing::Position3D(0,FIXED_SIZE_FOR_3D_CHART_VOLUME,0) ); - AddPointToPoly( aPoly, drawing::Position3D(0,0,0) ); - xShapeProp->setPropertyValue( C2U( UNO_NAME_3D_POLYPOLYGON3D ), uno::makeAny( aPoly ) ); - - //Matrix for position - { - ::basegfx::B3DHomMatrix aM; - aM.rotate(F_PI/2.0,0.0,0.0); - aM.translate(0.0,FLOOR_THICKNESS, 0.0); - drawing::HomogenMatrix aHM = B3DHomMatrixToHomogenMatrix(aM); - E3DModifySceneSnapRectUpdater aUpdater(lcl_getE3dScene( m_xOuterGroupShape )); - xShapeProp->setPropertyValue( C2U( UNO_NAME_3D_TRANSFORM_MATRIX ) - , uno::makeAny(aHM) ); - } + Stripe aStripe( drawing::Position3D(0,0,0) + , drawing::Direction3D(0,0,FIXED_SIZE_FOR_3D_CHART_VOLUME) + , drawing::Direction3D(FIXED_SIZE_FOR_3D_CHART_VOLUME,0,0) ); + aStripe.InvertNormal(true); - PropertyMapper::setMappedProperties( xShapeProp, xFloorProp, PropertyMapper::getPropertyNameMapForFillAndLineProperties() ); - } + uno::Reference< drawing::XShape > xShape = + m_pShapeFactory->createStripe(xOuterGroup_Shapes, aStripe + , xFloorProp, PropertyMapper::getPropertyNameMapForFillAndLineProperties(), bDoubleSided, 0, bFlatNormals ); CuboidPlanePosition eBottomPos( ThreeDHelper::getAutomaticCuboidPlanePositionForStandardBottom( uno::Reference< beans::XPropertySet >( m_xDiagram, uno::UNO_QUERY ) ) ); if( !bAddFloorAndWall || (CuboidPlanePosition_Bottom!=eBottomPos) ) @@ -709,11 +702,11 @@ void VDiagram::createShapes_3d() try { double fXScale = (FIXED_SIZE_FOR_3D_CHART_VOLUME -GRID_TO_WALL_DISTANCE) /FIXED_SIZE_FOR_3D_CHART_VOLUME; - double fYScale = (FIXED_SIZE_FOR_3D_CHART_VOLUME -FLOOR_THICKNESS-GRID_TO_WALL_DISTANCE ) /FIXED_SIZE_FOR_3D_CHART_VOLUME; + double fYScale = (FIXED_SIZE_FOR_3D_CHART_VOLUME -GRID_TO_WALL_DISTANCE) /FIXED_SIZE_FOR_3D_CHART_VOLUME; double fZScale = (FIXED_SIZE_FOR_3D_CHART_VOLUME -GRID_TO_WALL_DISTANCE) /FIXED_SIZE_FOR_3D_CHART_VOLUME; ::basegfx::B3DHomMatrix aM; - aM.translate(GRID_TO_WALL_DISTANCE/fXScale, (FLOOR_THICKNESS+GRID_TO_WALL_DISTANCE)/fYScale, GRID_TO_WALL_DISTANCE/fZScale); + aM.translate(GRID_TO_WALL_DISTANCE/fXScale, GRID_TO_WALL_DISTANCE/fYScale, GRID_TO_WALL_DISTANCE/fZScale); aM.scale( fXScale, fYScale, fZScale ); E3DModifySceneSnapRectUpdater aUpdater(lcl_getE3dScene( m_xOuterGroupShape )); xShapeProp->setPropertyValue( C2U( UNO_NAME_3D_TRANSFORM_MATRIX ) diff --git a/chart2/source/view/inc/ShapeFactory.hxx b/chart2/source/view/inc/ShapeFactory.hxx index e16310a71ce7..ef75f3a323af 100644 --- a/chart2/source/view/inc/ShapeFactory.hxx +++ b/chart2/source/view/inc/ShapeFactory.hxx @@ -90,7 +90,11 @@ public: ::com::sun::star::drawing::XShapes >& xTarget , const ::com::sun::star::drawing::Position3D& rPosition , const ::com::sun::star::drawing::Direction3D& rSize - , double fTopHeight, sal_Int32 nRotateZAngleHundredthDegree ); + , double fTopHeight + , bool bRotateZ + , const ::com::sun::star::uno::Reference< + ::com::sun::star::beans::XPropertySet >& xSourceProp + , const tPropertyNameMap& rPropertyNameMap); ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > createCone( const ::com::sun::star::uno::Reference< @@ -119,7 +123,9 @@ public: , const Stripe& rStripe , const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& xSourceProp , const tPropertyNameMap& rPropertyNameMap - , sal_Bool bDoubleSided = true, bool bRotatedTexture=false ); + , sal_Bool bDoubleSided = true + , short nRotatedTexture = 0 //0 to 7 are the different possibilities + , bool bFlatNormals=true ); ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > createArea3D( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& xTarget @@ -235,7 +241,6 @@ private: , const ::com::sun::star::drawing::Position3D& rPosition , const ::com::sun::star::drawing::Direction3D& rSize , double fTopHeight, sal_Int32 nRotateZAngleHundredthDegree - , sal_Int32 nSegments , bool bCylinder = false); //member: diff --git a/chart2/source/view/inc/Stripe.hxx b/chart2/source/view/inc/Stripe.hxx index b176685aefb5..ca1aaf155d1e 100644 --- a/chart2/source/view/inc/Stripe.hxx +++ b/chart2/source/view/inc/Stripe.hxx @@ -53,16 +53,19 @@ public: , const ::com::sun::star::drawing::Position3D& rPoint2 , double fDepth ); -/* Stripe( const ::com::sun::star::drawing::Position3D& rPoint1 , const ::com::sun::star::drawing::Position3D& rPoint2 , const ::com::sun::star::drawing::Position3D& rPoint3 - , const ::com::sun::star::drawing::Position3D& rPoint4 );*/ + , const ::com::sun::star::drawing::Position3D& rPoint4 ); + void SetManualNormal( const ::com::sun::star::drawing::Direction3D& rNormal ); + ::com::sun::star::drawing::Direction3D getNormal() const; + + void InvertNormal( bool bInvertNormal ); ::com::sun::star::uno::Any getPolyPolygonShape3D() const; ::com::sun::star::uno::Any getNormalsPolygon() const; - ::com::sun::star::uno::Any getTexturePolygon( bool bRotatedTexture ) const; + ::com::sun::star::uno::Any getTexturePolygon( short nRotatedTexture ) const; //0 to 7 are the different possibilities ::com::sun::star::drawing::Position3D GetPosition1() const { return m_aPoint1; } ::com::sun::star::drawing::Position3D GetPosition2() const { return m_aPoint2; } @@ -75,8 +78,9 @@ private: ::com::sun::star::drawing::Position3D m_aPoint3; ::com::sun::star::drawing::Position3D m_aPoint4; - ::com::sun::star::drawing::Direction3D - getNormal() const; + bool m_bInvertNormal; + bool m_bManualNormalSet; + ::com::sun::star::drawing::Direction3D m_aManualNormal; }; //............................................................................. diff --git a/chart2/source/view/inc/ViewDefines.hxx b/chart2/source/view/inc/ViewDefines.hxx index e520522e2389..623e46e64fb7 100644 --- a/chart2/source/view/inc/ViewDefines.hxx +++ b/chart2/source/view/inc/ViewDefines.hxx @@ -37,7 +37,6 @@ namespace chart #define FIXED_SIZE_FOR_3D_CHART_VOLUME (10000.0) //There needs to be a little distance betweengrid lines and walls in 3D, otherwise the lines are partly hidden by the walls #define GRID_TO_WALL_DISTANCE (1.0) -#define FLOOR_THICKNESS (100.0) const double ZDIRECTION = 1.0; const sal_Int32 AXIS2D_TICKLENGTH = 150;//value like in old chart diff --git a/chart2/source/view/main/ChartView.cxx b/chart2/source/view/main/ChartView.cxx index 9e39ffae0fe4..c5ba0c38ab05 100644 --- a/chart2/source/view/main/ChartView.cxx +++ b/chart2/source/view/main/ChartView.cxx @@ -218,13 +218,15 @@ ChartView::~ChartView() void ChartView::impl_deleteCoordinateSystems() { //delete all coordinate systems - ::std::vector< VCoordinateSystem* >::const_iterator aIter = m_aVCooSysList.begin(); - const ::std::vector< VCoordinateSystem* >::const_iterator aEnd = m_aVCooSysList.end(); + ::std::vector< VCoordinateSystem* > aVectorToDeleteObjects; + ::std::swap( aVectorToDeleteObjects, m_aVCooSysList );//#i109770# + ::std::vector< VCoordinateSystem* >::const_iterator aIter = aVectorToDeleteObjects.begin(); + const ::std::vector< VCoordinateSystem* >::const_iterator aEnd = aVectorToDeleteObjects.end(); for( ; aIter != aEnd; aIter++ ) { delete *aIter; } - m_aVCooSysList.clear(); + aVectorToDeleteObjects.clear(); } @@ -2155,7 +2157,7 @@ void changePositionOfAxisTitle( VTitle* pVTitle, TitleAlignment eAlignment pVTitle->changePosition( aNewPosition ); } -std::auto_ptr<VTitle> lcl_createTitle( const uno::Reference< XTitle >& xTitle +std::auto_ptr<VTitle> lcl_createTitle( TitleHelper::eTitleType eType , const uno::Reference< drawing::XShapes>& xPageShapes , const uno::Reference< lang::XMultiServiceFactory>& xShapeFactory , const uno::Reference< frame::XModel >& xChartModel @@ -2165,10 +2167,32 @@ std::auto_ptr<VTitle> lcl_createTitle( const uno::Reference< XTitle >& xTitle , bool& rbAutoPosition ) { std::auto_ptr<VTitle> apVTitle; + + // #i109336# Improve auto positioning in chart + double fPercentage = lcl_getPageLayoutDistancePercentage(); + sal_Int32 nXDistance = static_cast< sal_Int32 >( rPageSize.Width * fPercentage ); + sal_Int32 nYDistance = static_cast< sal_Int32 >( rPageSize.Height * fPercentage ); + if ( eType == TitleHelper::MAIN_TITLE ) + { + sal_Int32 nYOffset = 135; // 1/100 mm + nYDistance += nYOffset; + } + else if ( eType == TitleHelper::TITLE_AT_STANDARD_X_AXIS_POSITION ) + { + sal_Int32 nYOffset = 420; // 1/100 mm + nYDistance = nYOffset; + } + else if ( eType == TitleHelper::TITLE_AT_STANDARD_Y_AXIS_POSITION ) + { + sal_Int32 nXOffset = 450; // 1/100 mm + nXDistance = nXOffset; + } + + uno::Reference< XTitle > xTitle( TitleHelper::getTitle( eType, xChartModel ) ); if(xTitle.is()) { rtl::OUString aCompleteString( TitleHelper::getCompleteString( xTitle ) ); - if( aCompleteString.getLength()==0 ) + if ( aCompleteString.getLength() == 0 ) return apVTitle;//don't create empty titles as the resulting diagram position is wrong then //create title @@ -2182,8 +2206,6 @@ std::auto_ptr<VTitle> lcl_createTitle( const uno::Reference< XTitle >& xTitle //position rbAutoPosition=true; awt::Point aNewPosition(0,0); - sal_Int32 nYDistance = static_cast<sal_Int32>(rPageSize.Height*lcl_getPageLayoutDistancePercentage()); - sal_Int32 nXDistance = static_cast<sal_Int32>(rPageSize.Width*lcl_getPageLayoutDistancePercentage()); chart2::RelativePosition aRelativePosition; uno::Reference< beans::XPropertySet > xProp(xTitle, uno::UNO_QUERY); if( xProp.is() && (xProp->getPropertyValue( C2U( "RelativePosition" ) )>>=aRelativePosition) ) @@ -2247,6 +2269,37 @@ std::auto_ptr<VTitle> lcl_createTitle( const uno::Reference< XTitle >& xTitle break; } } + else + { + // #i109336# Improve auto positioning in chart + switch ( eAlignment ) + { + case ALIGN_TOP: + { + rRemainingSpace.Y += nYDistance; + rRemainingSpace.Height -= nYDistance; + } + break; + case ALIGN_BOTTOM: + { + rRemainingSpace.Height -= nYDistance; + } + break; + case ALIGN_LEFT: + { + rRemainingSpace.X += nXDistance; + rRemainingSpace.Width -= nXDistance; + } + break; + case ALIGN_RIGHT: + { + rRemainingSpace.Width -= nXDistance; + } + break; + default: + break; + } + } return apVTitle; } @@ -2476,13 +2529,13 @@ void ChartView::createShapes() bool bAutoPositionDummy = true; //------------ create main title shape - lcl_createTitle( TitleHelper::getTitle( TitleHelper::MAIN_TITLE, m_xChartModel ), xPageShapes, m_xShapeFactory, m_xChartModel + lcl_createTitle( TitleHelper::MAIN_TITLE, xPageShapes, m_xShapeFactory, m_xChartModel , aRemainingSpace, aPageSize, ALIGN_TOP, bAutoPositionDummy ); if(aRemainingSpace.Width<=0||aRemainingSpace.Height<=0) return; //------------ create sub title shape - lcl_createTitle( TitleHelper::getTitle( TitleHelper::SUB_TITLE, m_xChartModel ), xPageShapes, m_xShapeFactory, m_xChartModel + lcl_createTitle( TitleHelper::SUB_TITLE, xPageShapes, m_xShapeFactory, m_xChartModel , aRemainingSpace, aPageSize, ALIGN_TOP, bAutoPositionDummy ); if(aRemainingSpace.Width<=0||aRemainingSpace.Height<=0) return; @@ -2506,7 +2559,7 @@ void ChartView::createShapes() bool bAutoPosition_XTitle = true; std::auto_ptr<VTitle> apVTitle_X; if( ChartTypeHelper::isSupportingMainAxis( xChartType, nDimension, 0 ) ) - apVTitle_X = lcl_createTitle( TitleHelper::getTitle( TitleHelper::TITLE_AT_STANDARD_X_AXIS_POSITION, m_xChartModel ), xPageShapes, m_xShapeFactory, m_xChartModel + apVTitle_X = lcl_createTitle( TitleHelper::TITLE_AT_STANDARD_X_AXIS_POSITION, xPageShapes, m_xShapeFactory, m_xChartModel , aRemainingSpace, aPageSize, ALIGN_BOTTOM, bAutoPosition_XTitle ); if(aRemainingSpace.Width<=0||aRemainingSpace.Height<=0) return; @@ -2515,7 +2568,7 @@ void ChartView::createShapes() bool bAutoPosition_YTitle = true; std::auto_ptr<VTitle> apVTitle_Y; if( ChartTypeHelper::isSupportingMainAxis( xChartType, nDimension, 1 ) ) - apVTitle_Y = lcl_createTitle( TitleHelper::getTitle( TitleHelper::TITLE_AT_STANDARD_Y_AXIS_POSITION, m_xChartModel ), xPageShapes, m_xShapeFactory, m_xChartModel + apVTitle_Y = lcl_createTitle( TitleHelper::TITLE_AT_STANDARD_Y_AXIS_POSITION, xPageShapes, m_xShapeFactory, m_xChartModel , aRemainingSpace, aPageSize, ALIGN_LEFT, bAutoPosition_YTitle ); if(aRemainingSpace.Width<=0||aRemainingSpace.Height<=0) return; @@ -2524,7 +2577,7 @@ void ChartView::createShapes() bool bAutoPosition_ZTitle = true; std::auto_ptr<VTitle> apVTitle_Z; if( ChartTypeHelper::isSupportingMainAxis( xChartType, nDimension, 2 ) ) - apVTitle_Z = lcl_createTitle( TitleHelper::getTitle( TitleHelper::Z_AXIS_TITLE, m_xChartModel ), xPageShapes, m_xShapeFactory, m_xChartModel + apVTitle_Z = lcl_createTitle( TitleHelper::Z_AXIS_TITLE, xPageShapes, m_xShapeFactory, m_xChartModel , aRemainingSpace, aPageSize, ALIGN_RIGHT, bAutoPosition_ZTitle ); if(aRemainingSpace.Width<=0||aRemainingSpace.Height<=0) return; @@ -2536,7 +2589,7 @@ void ChartView::createShapes() bool bAutoPosition_SecondXTitle = true; std::auto_ptr<VTitle> apVTitle_SecondX; if( ChartTypeHelper::isSupportingSecondaryAxis( xChartType, nDimension, 0 ) ) - apVTitle_SecondX = lcl_createTitle( TitleHelper::getTitle( TitleHelper::SECONDARY_X_AXIS_TITLE, m_xChartModel ), xPageShapes, m_xShapeFactory, m_xChartModel + apVTitle_SecondX = lcl_createTitle( TitleHelper::SECONDARY_X_AXIS_TITLE, xPageShapes, m_xShapeFactory, m_xChartModel , aRemainingSpace, aPageSize, bIsVertical? ALIGN_RIGHT : ALIGN_TOP, bAutoPosition_SecondXTitle ); if(aRemainingSpace.Width<=0||aRemainingSpace.Height<=0) return; @@ -2545,7 +2598,7 @@ void ChartView::createShapes() bool bAutoPosition_SecondYTitle = true; std::auto_ptr<VTitle> apVTitle_SecondY; if( ChartTypeHelper::isSupportingSecondaryAxis( xChartType, nDimension, 1 ) ) - apVTitle_SecondY = lcl_createTitle( TitleHelper::getTitle( TitleHelper::SECONDARY_Y_AXIS_TITLE, m_xChartModel ), xPageShapes, m_xShapeFactory, m_xChartModel + apVTitle_SecondY = lcl_createTitle( TitleHelper::SECONDARY_Y_AXIS_TITLE, xPageShapes, m_xShapeFactory, m_xChartModel , aRemainingSpace, aPageSize, bIsVertical? ALIGN_TOP : ALIGN_RIGHT, bAutoPosition_SecondYTitle ); if(aRemainingSpace.Width<=0||aRemainingSpace.Height<=0) return; diff --git a/chart2/source/view/main/PropertyMapper.cxx b/chart2/source/view/main/PropertyMapper.cxx index 6e53ce22aff7..1979582763fa 100644 --- a/chart2/source/view/main/PropertyMapper.cxx +++ b/chart2/source/view/main/PropertyMapper.cxx @@ -529,7 +529,7 @@ void PropertyMapper::getPreparedTextShapePropertyLists( // use a line-joint showing the border of thick lines like two rectangles // filled in between. - aValueMap[C2U("LineJoint")] <<= drawing::LineJoint_MITER; + aValueMap[C2U("LineJoint")] <<= drawing::LineJoint_ROUND; PropertyMapper::getMultiPropertyListsFromValueMap( rPropNames, rPropValues, aValueMap ); } diff --git a/chart2/source/view/main/ShapeFactory.cxx b/chart2/source/view/main/ShapeFactory.cxx index 0be0c04c18d9..721cabd15d83 100644 --- a/chart2/source/view/main/ShapeFactory.cxx +++ b/chart2/source/view/main/ShapeFactory.cxx @@ -67,6 +67,7 @@ #include <algorithm> using namespace ::com::sun::star; +using ::com::sun::star::uno::Reference; //............................................................................. namespace chart @@ -268,110 +269,99 @@ uno::Any createPolyPolygon_Cube( uno::Any createPolyPolygon_Cylinder( double fHeight , double fRadius - , double fRoundedEdge , sal_Int32& nVerticalSegmentCount ) { - //@todo consider offset if Height is negative - -// DBG_ASSERT(fHeight>0, "The height of a cylinder needs to be > 0"); + //fHeight may be negative DBG_ASSERT(fRadius>0, "The radius of a cylinder needs to be > 0"); - DBG_ASSERT(fRoundedEdge>=0, "fRoundedEdge needs to be >= 0"); - - // always use extra points, so set percent diagonal to 0.4 which is 0% in the UI (old Chart comment) - if( fRoundedEdge == 0.0 ) - fRoundedEdge = 0.4 / 200.0; - -// const double fWidth = fRadius; - - fRoundedEdge = 0.0; - const double fOffset = (fRadius * 2.0 * fRoundedEdge) * 1.05; // increase by 5% for safety - const bool bRoundEdges = fRoundedEdge && fOffset < fRadius && 2.0 * fOffset < fHeight; - const sal_Int32 nPointCount = bRoundEdges ? 8 : 4; - nVerticalSegmentCount = nPointCount-1; //-------------------------------------- drawing::PolyPolygonShape3D aPP; - aPP.SequenceX.realloc(1); - aPP.SequenceY.realloc(1); - aPP.SequenceZ.realloc(1); + nVerticalSegmentCount=1; + + aPP.SequenceX.realloc(3); + aPP.SequenceY.realloc(3); + aPP.SequenceZ.realloc(3); drawing::DoubleSequence* pOuterSequenceX = aPP.SequenceX.getArray(); drawing::DoubleSequence* pOuterSequenceY = aPP.SequenceY.getArray(); drawing::DoubleSequence* pOuterSequenceZ = aPP.SequenceZ.getArray(); - pOuterSequenceX->realloc(nPointCount); - pOuterSequenceY->realloc(nPointCount); - pOuterSequenceZ->realloc(nPointCount); + pOuterSequenceX->realloc(2); + pOuterSequenceY->realloc(2); + pOuterSequenceZ->realloc(2); double* pInnerSequenceX = pOuterSequenceX->getArray(); double* pInnerSequenceY = pOuterSequenceY->getArray(); double* pInnerSequenceZ = pOuterSequenceZ->getArray(); - for(sal_Int32 nN = nPointCount; nN--;) + double fY1 = 0.0; + double fY2 = fHeight; + + if( fHeight<0.0 ) + ::std::swap(fY1,fY2); + + //---------------------------- + for(sal_Int32 nN = 2; nN--;) *pInnerSequenceZ++ = 0.0; - if(nPointCount == 4) - { - *pInnerSequenceY++ = 0.0; - *pInnerSequenceY++ = 0.0; - *pInnerSequenceY++ = fHeight; - *pInnerSequenceY++ = fHeight; + *pInnerSequenceX++ = 0.0; + *pInnerSequenceY++ = fY1; - *pInnerSequenceX++ = 0.0; - *pInnerSequenceX++ = fRadius; - *pInnerSequenceX++ = fRadius; - *pInnerSequenceX++ = 0.0; - } - else - { - *pInnerSequenceY++ = 0.0; //1. - *pInnerSequenceY++ = 0.0; - *pInnerSequenceY++ = 0.0; - *pInnerSequenceY++ = fOffset; - *pInnerSequenceY++ = fHeight - fOffset; - *pInnerSequenceY++ = fHeight; //6. - *pInnerSequenceY++ = fHeight; - *pInnerSequenceY++ = fHeight; + *pInnerSequenceX++ = fRadius; + *pInnerSequenceY++ = fY1; + //---------------------------- + + pOuterSequenceX++;pOuterSequenceY++;pOuterSequenceZ++; + pOuterSequenceX->realloc(2); + pOuterSequenceY->realloc(2); + pOuterSequenceZ->realloc(2); + + pInnerSequenceX = pOuterSequenceX->getArray(); + pInnerSequenceY = pOuterSequenceY->getArray(); + pInnerSequenceZ = pOuterSequenceZ->getArray(); + + //---------------------------- + for(sal_Int32 nN = 2; nN--;) + *pInnerSequenceZ++ = 0.0; + + *pInnerSequenceX++ = fRadius; + *pInnerSequenceY++ = fY1; + + *pInnerSequenceX++ = fRadius; + *pInnerSequenceY++ = fY2; + //---------------------------- + + pOuterSequenceX++;pOuterSequenceY++;pOuterSequenceZ++; + pOuterSequenceX->realloc(2); + pOuterSequenceY->realloc(2); + pOuterSequenceZ->realloc(2); + + pInnerSequenceX = pOuterSequenceX->getArray(); + pInnerSequenceY = pOuterSequenceY->getArray(); + pInnerSequenceZ = pOuterSequenceZ->getArray(); + + //---------------------------- + for(sal_Int32 nN = 2; nN--;) + *pInnerSequenceZ++ = 0.0; + + *pInnerSequenceX++ = fRadius; + *pInnerSequenceY++ = fY2; + + *pInnerSequenceX++ = 0.0; + *pInnerSequenceY++ = fY2; + //---------------------------- - *pInnerSequenceX++ = 0.0; //1. - *pInnerSequenceX++ = fRadius - fOffset; - *pInnerSequenceX++ = fRadius; - *pInnerSequenceX++ = fRadius; - *pInnerSequenceX++ = fRadius; - *pInnerSequenceX++ = fRadius; //6. - *pInnerSequenceX++ = fRadius - fOffset; - *pInnerSequenceX++ = 0.0; - } return uno::Any( &aPP, ::getCppuType((const drawing::PolyPolygonShape3D*)0) ); } -uno::Any createPolyPolygon_Cone( - double fHeight - , double fRadius - , double fTopHeight - , double fRoundedEdge +uno::Any createPolyPolygon_Cone( double fHeight, double fRadius, double fTopHeight , sal_Int32& nVerticalSegmentCount ) { - //@todo consider offset if Height is negative -/* - DBG_ASSERT(fHeight>0, "The height of a cone needs to be > 0"); - DBG_ASSERT(fTopHeight>=0, "The height of the cutted top of a cone needs to be >= 0"); -*/ - DBG_ASSERT(fRadius>0, "The radius of a cone needs to be > 0"); - DBG_ASSERT(fRoundedEdge>=0, "fRoundedEdge needs to be >= 0"); //for stacked charts we need cones without top -> fTopHeight != 0 resp. bTopless == true //fTopHeight indicates the high of the cutted top only (not the full height) - - // always use extra points, so set percent diagonal to 0.4 which is 0% in the UI (old Chart comment) - if( fRoundedEdge == 0.0 ) - fRoundedEdge = 0.4 / 200.0; - - fRoundedEdge = 0.0; - - // ::rtl::math::approxEqual cannot compare to 0.0 bool bTopless = !::rtl::math::approxEqual( fHeight, fHeight + fTopHeight ); double r1= 0.0, r2 = fRadius; @@ -379,82 +369,69 @@ uno::Any createPolyPolygon_Cone( // #i63212# fHeight may be negative, fTopHeight is always positive -> use fabs(fHeight) r1 = fRadius * (fTopHeight)/(fabs(fHeight)+fTopHeight); - const double fMinimumDimension = ::std::min(r2*2.0,fHeight); - const double fOffset = (fMinimumDimension * fRoundedEdge) * 1.05; // increase by 5% for safety - const bool bRoundEdges = fRoundedEdge && fOffset < r2 && 2.0 * fOffset < fHeight - && ( bTopless ? fOffset < r1 : true ); - sal_Int32 nPointCount = 8; - if(bTopless) - { - if(!bRoundEdges) - nPointCount = 4; - } - else - { - if(bRoundEdges) - nPointCount = 6; - else - nPointCount = 3; - } - nVerticalSegmentCount = nPointCount-1; - - //-------------------------------------- + nVerticalSegmentCount=1; drawing::PolyPolygonShape3D aPP; - aPP.SequenceX.realloc(1); - aPP.SequenceY.realloc(1); - aPP.SequenceZ.realloc(1); + aPP.SequenceX.realloc(2); + aPP.SequenceY.realloc(2); + aPP.SequenceZ.realloc(2); drawing::DoubleSequence* pOuterSequenceX = aPP.SequenceX.getArray(); drawing::DoubleSequence* pOuterSequenceY = aPP.SequenceY.getArray(); drawing::DoubleSequence* pOuterSequenceZ = aPP.SequenceZ.getArray(); - pOuterSequenceX->realloc(nPointCount); - pOuterSequenceY->realloc(nPointCount); - pOuterSequenceZ->realloc(nPointCount); + pOuterSequenceX->realloc(2); + pOuterSequenceY->realloc(2); + pOuterSequenceZ->realloc(2); double* pInnerSequenceX = pOuterSequenceX->getArray(); double* pInnerSequenceY = pOuterSequenceY->getArray(); double* pInnerSequenceZ = pOuterSequenceZ->getArray(); - for(sal_Int32 nN = nPointCount; nN--;) - *pInnerSequenceZ++ = 0.0; + double fX1 = 0.0; + double fX2 = r2; + double fX3 = r1; - if(bTopless) - { - *pInnerSequenceY++ = fHeight; //1. - *pInnerSequenceX++ = 0.0; //1. + double fY1 = 0.0; + double fY2 = 0.0; + double fY3 = fHeight; - if(bRoundEdges) - { - *pInnerSequenceY++ = fHeight; //2. - *pInnerSequenceX++ = r1 - fOffset; //2. - } + if( fHeight<0.0 ) + { + ::std::swap(fX1,fX3); + ::std::swap(fY1,fY3); } - *pInnerSequenceY++ = fHeight; //3. - *pInnerSequenceX++ = r1; //3. + //---------------------------- + for(sal_Int32 nN = 2; nN--;) + *pInnerSequenceZ++ = 0.0; - if(bRoundEdges) - { - *pInnerSequenceY++ = fHeight - fOffset; //4. - *pInnerSequenceX++ = r1 + fOffset; //4. + *pInnerSequenceY++ = fY1; + *pInnerSequenceX++ = fX1; - *pInnerSequenceY++ = fOffset; //5. - *pInnerSequenceX++ = r2 - fOffset; //5. - } + *pInnerSequenceY++ = fY2; + *pInnerSequenceX++ = fX2; + //---------------------------- - *pInnerSequenceY++ = 0.0; //6. - *pInnerSequenceX++ = r2; //6. + pOuterSequenceX++;pOuterSequenceY++;pOuterSequenceZ++; + pOuterSequenceX->realloc(2); + pOuterSequenceY->realloc(2); + pOuterSequenceZ->realloc(2); - if(bRoundEdges) - { - *pInnerSequenceY++ = 0.0; //7. - *pInnerSequenceX++ = r2 - fOffset; //7. - } + pInnerSequenceX = pOuterSequenceX->getArray(); + pInnerSequenceY = pOuterSequenceY->getArray(); + pInnerSequenceZ = pOuterSequenceZ->getArray(); - *pInnerSequenceY++ = 0.0; //8. - *pInnerSequenceX++ = 0.0; //8. + //---------------------------- + for(sal_Int32 nN = 2; nN--;) + *pInnerSequenceZ++ = 0.0; + + *pInnerSequenceY++ = fY2; + *pInnerSequenceX++ = fX2; + + *pInnerSequenceY++ = fY3; + *pInnerSequenceX++ = fX3; + //---------------------------- return uno::Any( &aPP, ::getCppuType((const drawing::PolyPolygonShape3D*)0) ); } @@ -567,16 +544,167 @@ uno::Reference<drawing::XShape> , sal_Int32 nRotateZAngleHundredthDegree ) { return impl_createConeOrCylinder( - xTarget, rPosition, rSize, 0.0, nRotateZAngleHundredthDegree, CHART_3DOBJECT_SEGMENTCOUNT, true ); + xTarget, rPosition, rSize, 0.0, nRotateZAngleHundredthDegree, true ); } uno::Reference<drawing::XShape> ShapeFactory::createPyramid( const uno::Reference<drawing::XShapes>& xTarget , const drawing::Position3D& rPosition, const drawing::Direction3D& rSize - , double fTopHeight, sal_Int32 nRotateZAngleHundredthDegree ) + , double fTopHeight, bool bRotateZ + , const uno::Reference< beans::XPropertySet >& xSourceProp + , const tPropertyNameMap& rPropertyNameMap ) { - return impl_createConeOrCylinder( xTarget, rPosition, rSize, fTopHeight, nRotateZAngleHundredthDegree, 4 ); + if( !xTarget.is() ) + return 0; + + Reference< drawing::XShapes > xGroup( ShapeFactory::createGroup3D( xTarget, rtl::OUString() ) ); + + sal_Bool bDoubleSided = false; + short nRotatedTexture = 0; + + const double fWidth = rSize.DirectionX; + const double fDepth = rSize.DirectionZ; + const double fHeight = rSize.DirectionY; + + drawing::Position3D aBottomP1( rPosition.PositionX, rPosition.PositionY, rPosition.PositionZ - fDepth/2.0 ); + if(bRotateZ) + aBottomP1.PositionY -= fWidth/2.0; + else + aBottomP1.PositionX -= fWidth/2.0; + drawing::Position3D aBottomP2( aBottomP1 ); + if(bRotateZ) + aBottomP2.PositionY += fWidth; + else + aBottomP2.PositionX += fWidth; + drawing::Position3D aBottomP3( aBottomP2 ); + drawing::Position3D aBottomP4( aBottomP1 ); + aBottomP3.PositionZ += fDepth; + aBottomP4.PositionZ += fDepth; + + const double fTopFactor = (fTopHeight)/(fabs(fHeight)+fTopHeight); + drawing::Position3D aTopP1( rPosition.PositionX, rPosition.PositionY, rPosition.PositionZ - fDepth*fTopFactor/2.0 ); + if(bRotateZ) + { + aTopP1.PositionY -= fWidth*fTopFactor/2.0; + aTopP1.PositionX += fHeight; + } + else + { + aTopP1.PositionX -= fWidth*fTopFactor/2.0; + aTopP1.PositionY += fHeight; + } + drawing::Position3D aTopP2( aTopP1 ); + if(bRotateZ) + aTopP2.PositionY += fWidth*fTopFactor; + else + aTopP2.PositionX += fWidth*fTopFactor; + drawing::Position3D aTopP3( aTopP2 ); + drawing::Position3D aTopP4( aTopP1 ); + aTopP3.PositionZ += fDepth*fTopFactor; + aTopP4.PositionZ += fDepth*fTopFactor; + + Stripe aStripeBottom( aBottomP1, aBottomP4, aBottomP3, aBottomP2 ); + + drawing::Position3D aNormalsBottomP1( aBottomP1 ); + drawing::Position3D aNormalsBottomP2( aBottomP2 ); + drawing::Position3D aNormalsBottomP3( aBottomP3 ); + drawing::Position3D aNormalsBottomP4( aBottomP4 ); + drawing::Position3D aNormalsTopP1( aBottomP1 ); + drawing::Position3D aNormalsTopP2( aBottomP2 ); + drawing::Position3D aNormalsTopP3( aBottomP3 ); + drawing::Position3D aNormalsTopP4( aBottomP4 ); + if( bRotateZ ) + { + aNormalsTopP1.PositionX += fHeight; + aNormalsTopP2.PositionX += fHeight; + aNormalsTopP3.PositionX += fHeight; + aNormalsTopP4.PositionX += fHeight; + } + else + { + aNormalsTopP1.PositionY += fHeight; + aNormalsTopP2.PositionY += fHeight; + aNormalsTopP3.PositionY += fHeight; + aNormalsTopP4.PositionY += fHeight; + } + + bool bInvertPolygon = false; + bool bInvertNormals = false; + + if(bRotateZ) + { + //bars + if(fHeight>=0.0) + { + nRotatedTexture = 2; + bInvertNormals = true; + aStripeBottom = Stripe( aBottomP1, aBottomP4, aBottomP3, aBottomP2 ); + } + else + { + bInvertPolygon = true; + nRotatedTexture = 1; + aStripeBottom = Stripe( aBottomP2, aBottomP3, aBottomP4, aBottomP1 ); + } + } + else + { + //columns + if(fHeight>=0.0) + { + bInvertPolygon = true; + nRotatedTexture = 2; + aStripeBottom = Stripe( aBottomP2, aBottomP3, aBottomP4, aBottomP1 ); + } + else + { + nRotatedTexture = 3; + bInvertNormals = true; + aStripeBottom = Stripe( aBottomP4, aBottomP3, aBottomP2, aBottomP1 ); + } + } + aStripeBottom.InvertNormal(true); + + Stripe aStripe1( aTopP2, aTopP1, aBottomP1, aBottomP2 ); + Stripe aStripe2( aTopP3, aTopP2, aBottomP2, aBottomP3 ); + Stripe aStripe3( aTopP4, aTopP3, aBottomP3, aBottomP4 ); + Stripe aStripe4( aTopP1, aTopP4, aBottomP4, aBottomP1 ); + + if( bInvertPolygon ) + { + aStripe1 = Stripe( aBottomP1, aTopP1, aTopP2, aBottomP2 ); + aStripe2 = Stripe( aBottomP2, aTopP2, aTopP3, aBottomP3 ); + aStripe3 = Stripe( aBottomP3, aTopP3, aTopP4, aBottomP4 ); + aStripe4 = Stripe( aBottomP4, aTopP4, aTopP1, aBottomP1 ); + } + + Stripe aNormalsStripe1( aNormalsTopP1, aNormalsBottomP1, aNormalsBottomP2, aNormalsTopP2 ); + Stripe aNormalsStripe2( aNormalsTopP2, aNormalsBottomP2, aNormalsBottomP3, aNormalsTopP3 ); + Stripe aNormalsStripe3( aNormalsTopP3, aNormalsBottomP3, aNormalsBottomP4, aNormalsTopP4 ); + Stripe aNormalsStripe4( aNormalsTopP4, aNormalsBottomP4, aNormalsBottomP1, aNormalsTopP1 ); + + if( bInvertNormals ) + { + aNormalsStripe1 = Stripe( aNormalsTopP2, aNormalsBottomP2, aNormalsBottomP1, aNormalsTopP1 ); + aNormalsStripe2 = Stripe( aNormalsTopP3, aNormalsBottomP3, aNormalsBottomP2, aNormalsTopP2 ); + aNormalsStripe3 = Stripe( aNormalsTopP4, aNormalsBottomP4, aNormalsBottomP3, aNormalsTopP3 ); + aNormalsStripe4 = Stripe( aNormalsTopP1, aNormalsBottomP1, aNormalsBottomP4, aNormalsTopP4 ); + } + + aStripe1.SetManualNormal( aNormalsStripe1.getNormal() ); + aStripe2.SetManualNormal( aNormalsStripe2.getNormal() ); + aStripe3.SetManualNormal( aNormalsStripe3.getNormal() ); + aStripe4.SetManualNormal( aNormalsStripe4.getNormal() ); + + const bool bFlatNormals = false; + ShapeFactory::createStripe( xGroup, aStripe1, xSourceProp, rPropertyNameMap, bDoubleSided, nRotatedTexture, bFlatNormals ); + ShapeFactory::createStripe( xGroup, aStripe2, xSourceProp, rPropertyNameMap, bDoubleSided, nRotatedTexture, bFlatNormals ); + ShapeFactory::createStripe( xGroup, aStripe3, xSourceProp, rPropertyNameMap, bDoubleSided, nRotatedTexture, bFlatNormals ); + ShapeFactory::createStripe( xGroup, aStripe4, xSourceProp, rPropertyNameMap, bDoubleSided, nRotatedTexture, bFlatNormals ); + ShapeFactory::createStripe( xGroup, aStripeBottom, xSourceProp, rPropertyNameMap, bDoubleSided, nRotatedTexture, bFlatNormals ); + + return Reference< drawing::XShape >( xGroup, uno::UNO_QUERY ); } uno::Reference<drawing::XShape> @@ -585,7 +713,7 @@ uno::Reference<drawing::XShape> , const drawing::Position3D& rPosition, const drawing::Direction3D& rSize , double fTopHeight, sal_Int32 nRotateZAngleHundredthDegree ) { - return impl_createConeOrCylinder( xTarget, rPosition, rSize, fTopHeight, nRotateZAngleHundredthDegree, CHART_3DOBJECT_SEGMENTCOUNT ); + return impl_createConeOrCylinder( xTarget, rPosition, rSize, fTopHeight, nRotateZAngleHundredthDegree ); } uno::Reference<drawing::XShape> @@ -593,7 +721,6 @@ uno::Reference<drawing::XShape> const uno::Reference<drawing::XShapes>& xTarget , const drawing::Position3D& rPosition, const drawing::Direction3D& rSize , double fTopHeight, sal_Int32 nRotateZAngleHundredthDegree - , sal_Int32 nSegments , bool bCylinder ) { if( !xTarget.is() ) @@ -605,19 +732,8 @@ uno::Reference<drawing::XShape> "com.sun.star.drawing.Shape3DLatheObject") ), uno::UNO_QUERY ); xTarget->add(xShape); - - double fYRotateAnglePi = -ZDIRECTION*(F_PI/2.0 - F_PI/(double)nSegments); // alwayas rotate edge to front (important for pyramids) - //or: ZDIRECTION*(F_PI/2.0 - F_PI/(double)nSegments); // rotate edge to front for even segment count otherwise rotate corner to front - double fAngle = fYRotateAnglePi; - { - while(fAngle<0.0) - fAngle+=F_PI/2.0; - while(fAngle>F_PI/2.0) - fAngle-=F_PI/2.0; - } double fWidth = rSize.DirectionX/2.0; //The depth will be corrrected within Matrix double fRadius = fWidth; //!!!!!!!! problem in drawing layer: rotation object calculates wrong needed size -> wrong camera (it's a problem with bounding boxes) -// double fRadius = fWidth/cos(fAngle); llllllllllllllllllll double fHeight = rSize.DirectionY; //set properties @@ -635,15 +751,14 @@ uno::Reference<drawing::XShape> //Polygon sal_Int32 nVerticalSegmentCount = 0; uno::Any aPPolygon = bCylinder ? createPolyPolygon_Cylinder( - fHeight, fRadius, double(nPercentDiagonal)/200.0, nVerticalSegmentCount) + fHeight, fRadius, nVerticalSegmentCount) : createPolyPolygon_Cone( - fHeight, fRadius, fTopHeight, double(nPercentDiagonal)/200.0, nVerticalSegmentCount); + fHeight, fRadius, fTopHeight, nVerticalSegmentCount); xProp->setPropertyValue( C2U( UNO_NAME_3D_POLYPOLYGON3D ), aPPolygon ); //Matrix for position { ::basegfx::B3DHomMatrix aM; - //aM.RotateY( fYRotateAnglePi ); if(nRotateZAngleHundredthDegree!=0) aM.rotate(0.0,0.0,-nRotateZAngleHundredthDegree/18000.00*F_PI); //stretch the symmetric objects to given depth @@ -656,7 +771,7 @@ uno::Reference<drawing::XShape> //Segments xProp->setPropertyValue( C2U( UNO_NAME_3D_HORZ_SEGS ) - , uno::makeAny(nSegments) ); + , uno::makeAny(CHART_3DOBJECT_SEGMENTCOUNT) ); xProp->setPropertyValue( C2U( UNO_NAME_3D_VERT_SEGS ) , uno::makeAny((sal_Int32)nVerticalSegmentCount) );//depends on point count of the used polygon @@ -1021,7 +1136,8 @@ uno::Reference< drawing::XShape > , const uno::Reference< beans::XPropertySet >& xSourceProp , const tPropertyNameMap& rPropertyNameMap , sal_Bool bDoubleSided - , bool bRotatedTexture ) + , short nRotatedTexture + , bool bFlatNormals ) { if( !xTarget.is() ) return 0; @@ -1045,16 +1161,15 @@ uno::Reference< drawing::XShape > //TexturePolygon xProp->setPropertyValue( C2U( UNO_NAME_3D_TEXTUREPOLYGON3D ) - , rStripe.getTexturePolygon( bRotatedTexture ) ); - + , rStripe.getTexturePolygon( nRotatedTexture ) ); //Normals Polygon xProp->setPropertyValue( C2U( UNO_NAME_3D_NORMALSPOLYGON3D ) , rStripe.getNormalsPolygon() ); - //NormalsKind - xProp->setPropertyValue( C2U( UNO_NAME_3D_NORMALS_KIND ) - , uno::makeAny( drawing::NormalsKind_FLAT ) ); + if(bFlatNormals) + xProp->setPropertyValue( C2U( UNO_NAME_3D_NORMALS_KIND ) + , uno::makeAny( drawing::NormalsKind_FLAT ) ); //LineOnly xProp->setPropertyValue( C2U( UNO_NAME_3D_LINEONLY ) diff --git a/chart2/source/view/main/Stripe.cxx b/chart2/source/view/main/Stripe.cxx index 7f282e3d5559..2df78e2a8e91 100644 --- a/chart2/source/view/main/Stripe.cxx +++ b/chart2/source/view/main/Stripe.cxx @@ -48,8 +48,9 @@ Stripe::Stripe( const drawing::Position3D& rPoint1 , m_aPoint2(rPoint1+rDirectionToPoint2) , m_aPoint3(m_aPoint2+rDirectionToPoint4) , m_aPoint4(rPoint1+rDirectionToPoint4) + , m_bInvertNormal(false) + , m_bManualNormalSet(false) { - } Stripe::Stripe( const drawing::Position3D& rPoint1 @@ -59,12 +60,13 @@ Stripe::Stripe( const drawing::Position3D& rPoint1 , m_aPoint2(rPoint2) , m_aPoint3(rPoint2) , m_aPoint4(rPoint1) + , m_bInvertNormal(false) + , m_bManualNormalSet(false) { m_aPoint3.PositionZ += fDepth; m_aPoint4.PositionZ += fDepth; } -/* Stripe::Stripe( const drawing::Position3D& rPoint1 , const drawing::Position3D& rPoint2 , const drawing::Position3D& rPoint3 @@ -73,10 +75,21 @@ Stripe::Stripe( const drawing::Position3D& rPoint1 , m_aPoint2(rPoint2) , m_aPoint3(rPoint3) , m_aPoint4(rPoint4) + , m_bInvertNormal(false) + , m_bManualNormalSet(false) +{ +} + +void Stripe::SetManualNormal( const drawing::Direction3D& rNormal ) { + m_aManualNormal = rNormal; + m_bManualNormalSet = true; +} +void Stripe::InvertNormal( bool bInvertNormal ) +{ + m_bInvertNormal = bInvertNormal; } -*/ uno::Any Stripe::getPolyPolygonShape3D() const { @@ -119,12 +132,28 @@ uno::Any Stripe::getPolyPolygonShape3D() const drawing::Direction3D Stripe::getNormal() const { - ::basegfx::B3DPolygon aPolygon3D; - aPolygon3D.append(Position3DToB3DPoint( m_aPoint1 )); - aPolygon3D.append(Position3DToB3DPoint( m_aPoint2 )); - aPolygon3D.append(Position3DToB3DPoint( m_aPoint3 )); - ::basegfx::B3DVector aNormal(::basegfx::tools::getNormal(aPolygon3D)); - return B3DVectorToDirection3D(aNormal); + drawing::Direction3D aRet(1.0,0.0,0.0); + + if( m_bManualNormalSet ) + aRet = m_aManualNormal; + else + { + ::basegfx::B3DPolygon aPolygon3D; + aPolygon3D.append(Position3DToB3DPoint( m_aPoint1 )); + aPolygon3D.append(Position3DToB3DPoint( m_aPoint2 )); + aPolygon3D.append(Position3DToB3DPoint( m_aPoint3 )); + aPolygon3D.append(Position3DToB3DPoint( m_aPoint4 )); + ::basegfx::B3DVector aNormal(::basegfx::tools::getNormal(aPolygon3D)); + aRet = B3DVectorToDirection3D(aNormal); + } + + if( m_bInvertNormal ) + { + aRet.DirectionX *= -1.0; + aRet.DirectionY *= -1.0; + aRet.DirectionZ *= -1.0; + } + return aRet; } uno::Any Stripe::getNormalsPolygon() const @@ -158,7 +187,7 @@ uno::Any Stripe::getNormalsPolygon() const return uno::Any( &aPP, ::getCppuType((const drawing::PolyPolygonShape3D*)0) ); } -uno::Any Stripe::getTexturePolygon( bool bRotatedTexture ) const +uno::Any Stripe::getTexturePolygon( short nRotatedTexture ) const { drawing::PolyPolygonShape3D aPP; @@ -178,26 +207,124 @@ uno::Any Stripe::getTexturePolygon( bool bRotatedTexture ) const double* pInnerSequenceY = pOuterSequenceY->getArray(); double* pInnerSequenceZ = pOuterSequenceZ->getArray(); - if( !bRotatedTexture ) + if( nRotatedTexture==0 ) { *pInnerSequenceX++ = 0.0; *pInnerSequenceY++ = 0.0; *pInnerSequenceZ++ = 0.0; + *pInnerSequenceX++ = 0.0; + *pInnerSequenceY++ = 1.0; + *pInnerSequenceZ++ = 0.0; + + *pInnerSequenceX++ = 1.0; + *pInnerSequenceY++ = 1.0; + *pInnerSequenceZ++ = 0.0; + + *pInnerSequenceX++ = 1.0; + *pInnerSequenceY++ = 0.0; + *pInnerSequenceZ++ = 0.0; + } + else if( nRotatedTexture==1 ) + { *pInnerSequenceX++ = 1.0; *pInnerSequenceY++ = 0.0; *pInnerSequenceZ++ = 0.0; + *pInnerSequenceX++ = 0.0; + *pInnerSequenceY++ = 0.0; + *pInnerSequenceZ++ = 0.0; + + *pInnerSequenceX++ = 0.0; + *pInnerSequenceY++ = 1.0; + *pInnerSequenceZ++ = 0.0; + + *pInnerSequenceX++ = 1.0; + *pInnerSequenceY++ = 1.0; + *pInnerSequenceZ++ = 0.0; + } + else if( nRotatedTexture==2 ) + { *pInnerSequenceX++ = 1.0; *pInnerSequenceY++ = 1.0; *pInnerSequenceZ++ = 0.0; + *pInnerSequenceX++ = 1.0; + *pInnerSequenceY++ = 0.0; + *pInnerSequenceZ++ = 0.0; + + *pInnerSequenceX++ = 0.0; + *pInnerSequenceY++ = 0.0; + *pInnerSequenceZ++ = 0.0; + *pInnerSequenceX++ = 0.0; *pInnerSequenceY++ = 1.0; *pInnerSequenceZ++ = 0.0; } - else + else if( nRotatedTexture==3 ) + { + *pInnerSequenceX++ = 0.0; + *pInnerSequenceY++ = 1.0; + *pInnerSequenceZ++ = 0.0; + + *pInnerSequenceX++ = 1.0; + *pInnerSequenceY++ = 1.0; + *pInnerSequenceZ++ = 0.0; + + *pInnerSequenceX++ = 1.0; + *pInnerSequenceY++ = 0.0; + *pInnerSequenceZ++ = 0.0; + + *pInnerSequenceX++ = 0.0; + *pInnerSequenceY++ = 0.0; + *pInnerSequenceZ++ = 0.0; + } + else if( nRotatedTexture==4 ) + { + *pInnerSequenceX++ = 1.0; + *pInnerSequenceY++ = 0.0; + *pInnerSequenceZ++ = 0.0; + + *pInnerSequenceX++ = 1.0; + *pInnerSequenceY++ = 1.0; + *pInnerSequenceZ++ = 0.0; + + *pInnerSequenceX++ = 0.0; + *pInnerSequenceY++ = 1.0; + *pInnerSequenceZ++ = 0.0; + + *pInnerSequenceX++ = 0.0; + *pInnerSequenceY++ = 0.0; + *pInnerSequenceZ++ = 0.0; + } + else if( nRotatedTexture==5 ) + { + *pInnerSequenceX++ = 0.0; + *pInnerSequenceY++ = 0.0; + *pInnerSequenceZ++ = 0.0; + + *pInnerSequenceX++ = 1.0; + *pInnerSequenceY++ = 0.0; + *pInnerSequenceZ++ = 0.0; + + *pInnerSequenceX++ = 1.0; + *pInnerSequenceY++ = 1.0; + *pInnerSequenceZ++ = 0.0; + + *pInnerSequenceX++ = 0.0; + *pInnerSequenceY++ = 1.0; + *pInnerSequenceZ++ = 0.0; + } + else if( nRotatedTexture==6 ) { + *pInnerSequenceX++ = 0.0; + *pInnerSequenceY++ = 1.0; + *pInnerSequenceZ++ = 0.0; + + *pInnerSequenceX++ = 0.0; + *pInnerSequenceY++ = 0.0; + *pInnerSequenceZ++ = 0.0; + *pInnerSequenceX++ = 1.0; *pInnerSequenceY++ = 0.0; *pInnerSequenceZ++ = 0.0; @@ -205,6 +332,12 @@ uno::Any Stripe::getTexturePolygon( bool bRotatedTexture ) const *pInnerSequenceX++ = 1.0; *pInnerSequenceY++ = 1.0; *pInnerSequenceZ++ = 0.0; + } + else if( nRotatedTexture==7 ) + { + *pInnerSequenceX++ = 1.0; + *pInnerSequenceY++ = 1.0; + *pInnerSequenceZ++ = 0.0; *pInnerSequenceX++ = 0.0; *pInnerSequenceY++ = 1.0; @@ -213,6 +346,10 @@ uno::Any Stripe::getTexturePolygon( bool bRotatedTexture ) const *pInnerSequenceX++ = 0.0; *pInnerSequenceY++ = 0.0; *pInnerSequenceZ++ = 0.0; + + *pInnerSequenceX++ = 1.0; + *pInnerSequenceY++ = 0.0; + *pInnerSequenceZ++ = 0.0; } return uno::Any( &aPP, ::getCppuType((const drawing::PolyPolygonShape3D*)0) ); diff --git a/chart2/source/view/main/VDataSeries.cxx b/chart2/source/view/main/VDataSeries.cxx index c94193c5a7c8..8bb6a11b4baf 100644 --- a/chart2/source/view/main/VDataSeries.cxx +++ b/chart2/source/view/main/VDataSeries.cxx @@ -734,10 +734,10 @@ double VDataSeries::getYMeanValue() const { if( xProp->getPropertyValue( C2U( "Symbol" ) ) >>= *apSymbolProps ) { - // border of symbols always black - apSymbolProps->BorderColor = 0x000000; //use main color to fill symbols xProp->getPropertyValue( C2U( "Color" ) ) >>= apSymbolProps->FillColor; + // border of symbols always same as fill color + apSymbolProps->BorderColor = apSymbolProps->FillColor; } else apSymbolProps.reset(); diff --git a/chart2/source/view/main/VLegend.cxx b/chart2/source/view/main/VLegend.cxx index b7af20e1e64d..7101a984ee24 100644 --- a/chart2/source/view/main/VLegend.cxx +++ b/chart2/source/view/main/VLegend.cxx @@ -258,10 +258,11 @@ void lcl_placeLegendEntries( double fViewFontSize = lcl_CalcViewFontSize( xProperties, rPageSize ); // padding as percentage of the font height - double fXPadding = (1.0 / 5.0); - double fYPadding = (1.0 / 3.0); - double fXOffset = (1.0 / 5.0); - double fYOffset = (1.0 / 5.0); + // #i109336# Improve auto positioning in chart + double fXPadding = 0.1; + double fYPadding = 0.2; + double fXOffset = 0.15; + double fYOffset = 0.15; const sal_Int32 nXPadding = static_cast< sal_Int32 >( fViewFontSize * fXPadding ); const sal_Int32 nYPadding = static_cast< sal_Int32 >( fViewFontSize * fYPadding ); @@ -273,8 +274,11 @@ void lcl_placeLegendEntries( rEntries, xShapeFactory, xTarget, aTextShapes, rTextProperties ); OSL_ASSERT( aTextShapes.size() == rEntries.size()); - awt::Size aMaxSymbolExtent( static_cast< sal_Int32 >( fViewFontSize * 3.0 / 2.0 ), - static_cast< sal_Int32 >( fViewFontSize )); + // #i109336# Improve auto positioning in chart + double fSymbolSizeFraction = 0.8; + awt::Size aMaxSymbolExtent( static_cast< sal_Int32 >( fViewFontSize * fSymbolSizeFraction * 3.0 / 2.0 ), + static_cast< sal_Int32 >( fViewFontSize * fSymbolSizeFraction ) ); + sal_Int32 nCurrentXPos = nXPadding; sal_Int32 nCurrentYPos = nYPadding; sal_Int32 nMaxEntryWidth = 2 * nXOffset + aMaxSymbolExtent.Width + aMaxEntryExtent.Width; @@ -391,8 +395,13 @@ void lcl_placeLegendEntries( sal_Int32 nSymbolXPos = nCurrentXPos + ((aMaxSymbolExtent.Width - aSymbolSize.Width) / 2); if( !bSymbolsLeftSide ) nSymbolXPos = nSymbolXPos - aMaxSymbolExtent.Width; - xSymbol->setPosition( awt::Point( nSymbolXPos, - nCurrentYPos + ((aMaxSymbolExtent.Height - aSymbolSize.Height) / 2))); + + // #i109336# Improve auto positioning in chart + sal_Int32 nTextHeight = nMaxHeights[ nRow ] - nYOffset; + sal_Int32 nFontSize = static_cast< sal_Int32 >( fViewFontSize ); + sal_Int32 nMaxRowHeight = ( ( ( nTextHeight / nFontSize ) <= 1 ) ? nTextHeight : nFontSize ); + sal_Int32 nSymbolYPos = nCurrentYPos + ( ( nMaxRowHeight - aSymbolSize.Height ) / 2 ); + xSymbol->setPosition( awt::Point( nSymbolXPos, nSymbolYPos ) ); } // position text shape @@ -435,37 +444,60 @@ void lcl_placeLegendEntries( rOutLegendSize.Height = nMaxYPos + nYPadding; } -double lcl_getPageLayoutDistancePercentage() +// #i109336# Improve auto positioning in chart +sal_Int32 lcl_getLegendLeftRightMargin() { - return 0.02; + return 210; // 1/100 mm +} + +// #i109336# Improve auto positioning in chart +sal_Int32 lcl_getLegendTopBottomMargin() +{ + return 185; // 1/100 mm } chart2::RelativePosition lcl_getDefaultPosition( LegendPosition ePos, const awt::Rectangle& rOutAvailableSpace, const awt::Size & rPageSize ) { - // shift legend about 2% of page size into the primary direction by default - const double fDefaultDistance = lcl_getPageLayoutDistancePercentage(); chart2::RelativePosition aResult; switch( ePos ) { case LegendPosition_LINE_START: - aResult = chart2::RelativePosition( - fDefaultDistance, 0.5, drawing::Alignment_LEFT ); + { + // #i109336# Improve auto positioning in chart + const double fDefaultDistance = ( static_cast< double >( lcl_getLegendLeftRightMargin() ) / + static_cast< double >( rPageSize.Width ) ); + aResult = chart2::RelativePosition( + fDefaultDistance, 0.5, drawing::Alignment_LEFT ); + } break; case LegendPosition_LINE_END: - aResult = chart2::RelativePosition( - 1.0 - fDefaultDistance, 0.5, drawing::Alignment_RIGHT ); + { + // #i109336# Improve auto positioning in chart + const double fDefaultDistance = ( static_cast< double >( lcl_getLegendLeftRightMargin() ) / + static_cast< double >( rPageSize.Width ) ); + aResult = chart2::RelativePosition( + 1.0 - fDefaultDistance, 0.5, drawing::Alignment_RIGHT ); + } break; case LegendPosition_PAGE_START: { + // #i109336# Improve auto positioning in chart + const double fDefaultDistance = ( static_cast< double >( lcl_getLegendTopBottomMargin() ) / + static_cast< double >( rPageSize.Height ) ); double fDistance = (static_cast<double>(rOutAvailableSpace.Y)/static_cast<double>(rPageSize.Height)) + fDefaultDistance; aResult = chart2::RelativePosition( 0.5, fDistance, drawing::Alignment_TOP ); } break; case LegendPosition_PAGE_END: - aResult = chart2::RelativePosition( - 0.5, 1.0 - fDefaultDistance, drawing::Alignment_BOTTOM ); + { + // #i109336# Improve auto positioning in chart + const double fDefaultDistance = ( static_cast< double >( lcl_getLegendTopBottomMargin() ) / + static_cast< double >( rPageSize.Height ) ); + aResult = chart2::RelativePosition( + 0.5, 1.0 - fDefaultDistance, drawing::Alignment_BOTTOM ); + } break; case LegendPosition_CUSTOM: @@ -498,31 +530,34 @@ awt::Point lcl_calculatePositionAndRemainingSpace( aResult, aLegendSize, aRelPos.Anchor ); // adapt rRemainingSpace if LegendPosition is not CUSTOM - sal_Int32 nYDistance = static_cast<sal_Int32>(rPageSize.Height*lcl_getPageLayoutDistancePercentage()); - sal_Int32 nXDistance = static_cast<sal_Int32>(rPageSize.Width*lcl_getPageLayoutDistancePercentage()); - rRemainingSpace.Width-=nXDistance; - rRemainingSpace.Height-=nYDistance; + // #i109336# Improve auto positioning in chart + sal_Int32 nXDistance = lcl_getLegendLeftRightMargin(); + sal_Int32 nYDistance = lcl_getLegendTopBottomMargin(); switch( ePos ) { case LegendPosition_LINE_START: - { - sal_Int32 nExtent = aLegendSize.Width; - rRemainingSpace.Width -= nExtent; - rRemainingSpace.X += ( nExtent + nXDistance ); - } + { + sal_Int32 nExtent = aLegendSize.Width; + rRemainingSpace.Width -= ( nExtent + nXDistance ); + rRemainingSpace.X += ( nExtent + nXDistance ); + } break; case LegendPosition_LINE_END: - rRemainingSpace.Width -= ( aLegendSize.Width ); + { + rRemainingSpace.Width -= ( aLegendSize.Width + nXDistance ); + } break; case LegendPosition_PAGE_START: - { - sal_Int32 nExtent = aLegendSize.Height; - rRemainingSpace.Height -= nExtent; - rRemainingSpace.Y += ( nExtent + nYDistance ); - } + { + sal_Int32 nExtent = aLegendSize.Height; + rRemainingSpace.Height -= ( nExtent + nYDistance ); + rRemainingSpace.Y += ( nExtent + nYDistance ); + } break; case LegendPosition_PAGE_END: - rRemainingSpace.Height -= ( aLegendSize.Height ); + { + rRemainingSpace.Height -= ( aLegendSize.Height + nYDistance ); + } break; default: @@ -672,8 +707,9 @@ void VLegend::createShapes( tPropertyValues aLineFillProperties; tPropertyValues aTextProperties; - // limit the width of texts to 20% of the total available width - sal_Int32 nMaxLabelWidth = rAvailableSpace.Width / 5; + // limit the width of texts to 30% of the total available width + // #i109336# Improve auto positioning in chart + sal_Int32 nMaxLabelWidth = rAvailableSpace.Width * 3 / 10; Reference< beans::XPropertySet > xLegendProp( m_xLegend, uno::UNO_QUERY ); LegendExpansion eExpansion = LegendExpansion_HIGH; if( xLegendProp.is()) diff --git a/chart2/source/view/main/VLegendSymbolFactory.cxx b/chart2/source/view/main/VLegendSymbolFactory.cxx index 682ff7fb7a5b..958a8defe0b6 100644 --- a/chart2/source/view/main/VLegendSymbolFactory.cxx +++ b/chart2/source/view/main/VLegendSymbolFactory.cxx @@ -85,6 +85,16 @@ void lcl_setPropetiesToShape( ::chart::tNameSequence aPropNames; ::chart::tAnySequence aPropValues; ::chart::PropertyMapper::getMultiPropertyListsFromValueMap( aPropNames, aPropValues, aValueMap ); + + uno::Any* pLineWidthAny = ::chart::PropertyMapper::getValuePointer(aPropValues,aPropNames,C2U("LineWidth")); + sal_Int32 nLineWidth = 0; + if( pLineWidthAny && (*pLineWidthAny>>=nLineWidth) ) + { + const sal_Int32 nMaxLineWidthForLegend = 50;/*1/100 mm*///todo: make this dependent from legend entry height + if( nLineWidth>nMaxLineWidthForLegend ) + *pLineWidthAny = uno::makeAny( nMaxLineWidthForLegend ); + } + ::chart::PropertyMapper::setMultiProperties( aPropNames, aPropValues, xShapeProp ); } } @@ -316,10 +326,10 @@ Reference< drawing::XShape > VLegendSymbolFactory::createSymbol( ShapeFactory aFactory( xShapeFactory ); if( aSymbol.Style == chart2::SymbolStyle_STANDARD ) { - // border of symbols always black - aSymbol.BorderColor = 0x000000; // take series color as fill color xLegendEntryProperties->getPropertyValue( C2U("Color")) >>= aSymbol.FillColor; + // border of symbols always same as fill color + aSymbol.BorderColor = aSymbol.FillColor; xSymbol.set( aFactory.createSymbol2D( xResultGroup, diff --git a/chart2/source/view/main/VTitle.cxx b/chart2/source/view/main/VTitle.cxx index f804a505219f..f62142735b7c 100644 --- a/chart2/source/view/main/VTitle.cxx +++ b/chart2/source/view/main/VTitle.cxx @@ -253,6 +253,21 @@ void VTitle::createShapes( } } + // #i109336# Improve auto positioning in chart + float fFontHeight = 0.0; + if ( xShapeProp.is() && ( xShapeProp->getPropertyValue( C2U( "CharHeight" ) ) >>= fFontHeight ) ) + { + fFontHeight *= ( 2540. / 72. ); // pt -> 1/100 mm + float fXFraction = 0.18; + sal_Int32 nXDistance = static_cast< sal_Int32 >( ::rtl::math::round( fFontHeight * fXFraction ) ); + float fYFraction = 0.30; + sal_Int32 nYDistance = static_cast< sal_Int32 >( ::rtl::math::round( fFontHeight * fYFraction ) ); + xShapeProp->setPropertyValue( C2U( "TextLeftDistance" ), uno::makeAny( nXDistance ) ); + xShapeProp->setPropertyValue( C2U( "TextRightDistance" ), uno::makeAny( nXDistance ) ); + xShapeProp->setPropertyValue( C2U( "TextUpperDistance" ), uno::makeAny( nYDistance ) ); + xShapeProp->setPropertyValue( C2U( "TextLowerDistance" ), uno::makeAny( nYDistance ) ); + } + try { double fAngleDegree = 0; diff --git a/sc/inc/attarray.hxx b/sc/inc/attarray.hxx index 6d7b7f48c2d7..c82d607577bf 100644 --- a/sc/inc/attarray.hxx +++ b/sc/inc/attarray.hxx @@ -148,7 +148,7 @@ public: BOOL HasLines( SCROW nRow1, SCROW nRow2, Rectangle& rSizes, BOOL bLeft, BOOL bRight ) const; - BOOL HasAttrib( SCROW nRow1, SCROW nRow2, USHORT nMask ) const; + bool HasAttrib( SCROW nRow1, SCROW nRow2, USHORT nMask ) const; BOOL ExtendMerge( SCCOL nThisCol, SCROW nStartRow, SCROW nEndRow, SCCOL& rPaintCol, SCROW& rPaintRow, BOOL bRefresh, BOOL bAttrs ); diff --git a/sc/inc/charthelper.hxx b/sc/inc/charthelper.hxx index b4c677d7c3c6..50b8586bdace 100644 --- a/sc/inc/charthelper.hxx +++ b/sc/inc/charthelper.hxx @@ -29,9 +29,12 @@ #define SC_CHARTHELPER_HXX #include <tools/solar.h> +#include "address.hxx" +#include "global.hxx" -class ScDocument; -class ScAddress; +#include <com/sun/star/chart2/XChartDocument.hpp> + +class SdrObject; /** Use this to handle charts in a calc document */ @@ -40,6 +43,12 @@ class ScChartHelper public: static USHORT DoUpdateAllCharts( ScDocument* pDoc ); static USHORT DoUpdateCharts( const ScAddress& rPos, ScDocument* pDoc ); //use this to replace ScDBFunc::DoUpdateCharts in future + static void AdjustRangesOfChartsOnDestinationPage( ScDocument* pSrcDoc, ScDocument* pDestDoc, const SCTAB nSrcTab, const SCTAB nDestTab ); + static ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartDocument > GetChartFromSdrObject( SdrObject* pObject ); + static void GetChartRanges( const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartDocument >& xChartDoc, + ::com::sun::star::uno::Sequence< rtl::OUString >& rRanges ); + static void SetChartRanges( const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartDocument >& xChartDoc, + const ::com::sun::star::uno::Sequence< rtl::OUString >& rRanges ); }; #endif diff --git a/sc/inc/collect.hxx b/sc/inc/collect.hxx index e8b9bed60865..167ab5929c6a 100644 --- a/sc/inc/collect.hxx +++ b/sc/inc/collect.hxx @@ -184,20 +184,18 @@ private: BOOL bCaseSensitive; public: - TypedScStrCollection( USHORT nLim = 4, USHORT nDel = 4, BOOL bDup = FALSE ) - : ScSortedCollection( nLim, nDel, bDup ) { bCaseSensitive = FALSE; } + TypedScStrCollection( USHORT nLim = 4, USHORT nDel = 4, BOOL bDup = FALSE ); - TypedScStrCollection( const TypedScStrCollection& rCpy ) - : ScSortedCollection( rCpy ) { bCaseSensitive = rCpy.bCaseSensitive; } - ~TypedScStrCollection(); + TypedScStrCollection( const TypedScStrCollection& rCpy ) + : ScSortedCollection( rCpy ) { bCaseSensitive = rCpy.bCaseSensitive; } + ~TypedScStrCollection(); virtual ScDataObject* Clone() const; virtual short Compare( ScDataObject* pKey1, ScDataObject* pKey2 ) const; - TypedStrData* operator[]( const USHORT nIndex) const - { return (TypedStrData*)At(nIndex); } + TypedStrData* operator[]( const USHORT nIndex) const; - void SetCaseSensitive( BOOL bSet ) { bCaseSensitive = bSet; } + void SetCaseSensitive( BOOL bSet ); BOOL FindText( const String& rStart, String& rResult, USHORT& rPos, BOOL bBack ) const; BOOL GetExactMatch( String& rString ) const; diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx index 08f3d1f7b1e3..85567a2a656d 100644 --- a/sc/inc/column.hxx +++ b/sc/inc/column.hxx @@ -142,7 +142,7 @@ public: //UNUSED2009-05 BOOL HasLines( SCROW nRow1, SCROW nRow2, Rectangle& rSizes, //UNUSED2009-05 BOOL bLeft, BOOL bRight ) const; - BOOL HasAttrib( SCROW nRow1, SCROW nRow2, USHORT nMask ) const; + bool HasAttrib( SCROW nRow1, SCROW nRow2, USHORT nMask ) const; BOOL HasAttribSelection( const ScMarkData& rMark, USHORT nMask ) const; BOOL ExtendMerge( SCCOL nThisCol, SCROW nStartRow, SCROW nEndRow, SCCOL& rPaintCol, SCROW& rPaintRow, @@ -235,7 +235,9 @@ public: // TRUE = Zahlformat gesetzt BOOL SetString( SCROW nRow, SCTAB nTab, const String& rString, - formula::FormulaGrammar::AddressConvention conv = formula::FormulaGrammar::CONV_OOO ); + formula::FormulaGrammar::AddressConvention conv = formula::FormulaGrammar::CONV_OOO, + SvNumberFormatter* pFormatter = NULL, + bool bDetectNumberFormat = true ); void SetValue( SCROW nRow, const double& rVal); void SetError( SCROW nRow, const USHORT nError); diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx index 44bda96f8322..1d92962a56db 100644 --- a/sc/inc/document.hxx +++ b/sc/inc/document.hxx @@ -45,6 +45,13 @@ #include <memory> #include <map> +// Wang Xu Ming -- 2009-8-17 +// DataPilot Migration - Cache&&Performance +#include <list> +#include "dpobject.hxx" +#include "dptabdat.hxx" +// End Comments + class KeyEvent; class OutputDevice; class SdrObject; @@ -256,6 +263,11 @@ private: ScRangeName* pRangeName; ScDBCollection* pDBCollection; ScDPCollection* pDPCollection; + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + std::list<ScDPObject> m_listDPObjectsInClip; + std::list<ScDPTableDataCache*> m_listDPObjectsCaches; + // End Comments ScChartCollection* pChartCollection; std::auto_ptr< ScTemporaryChartLock > apTemporaryChartLock; ScPatternAttr* pSelectionAttr; // Attribute eines Blocks @@ -492,6 +504,17 @@ public: SC_DLLPUBLIC ScDPCollection* GetDPCollection(); ScDPObject* GetDPAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab) const; ScDPObject* GetDPAtBlock( const ScRange& rBlock ) const; + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + SC_DLLPUBLIC ScDPTableDataCache* GetDPObjectCache( long nID ); + SC_DLLPUBLIC ScDPTableDataCache* GetUsedDPObjectCache ( ScRange rRange ); + SC_DLLPUBLIC long AddDPObjectCache( ScDPTableDataCache* pData ); + SC_DLLPUBLIC void RemoveDPObjectCache( long nID ); + SC_DLLPUBLIC void RemoveUnusedDPObjectCaches(); + SC_DLLPUBLIC void GetUsedDPObjectCache( std::list<ScDPTableDataCache*>& usedlist ); + SC_DLLPUBLIC long GetNewDPObjectCacheId (); + // End Comments + SC_DLLPUBLIC ScChartCollection* GetChartCollection() const; void StopTemporaryChartLock(); @@ -727,7 +750,9 @@ public: SC_DLLPUBLIC void PutCell(SCCOL nCol, SCROW nRow, SCTAB nTab, ScBaseCell* pCell, ULONG nFormatIndex, BOOL bForceTab = FALSE); // return TRUE = Zahlformat gesetzt - SC_DLLPUBLIC BOOL SetString( SCCOL nCol, SCROW nRow, SCTAB nTab, const String& rString ); + SC_DLLPUBLIC BOOL SetString( + SCCOL nCol, SCROW nRow, SCTAB nTab, const String& rString, + SvNumberFormatter* pFormatter = NULL, bool bDetectNumberFormat = true ); SC_DLLPUBLIC void SetValue( SCCOL nCol, SCROW nRow, SCTAB nTab, const double& rVal ); void SetError( SCCOL nCol, SCROW nRow, SCTAB nTab, const USHORT nError); @@ -822,9 +847,9 @@ public: BOOL IsHorOverlapped( SCCOL nCol, SCROW nRow, SCTAB nTab ) const; BOOL IsVerOverlapped( SCCOL nCol, SCROW nRow, SCTAB nTab ) const; - SC_DLLPUBLIC BOOL HasAttrib( SCCOL nCol1, SCROW nRow1, SCTAB nTab1, - SCCOL nCol2, SCROW nRow2, SCTAB nTab2, USHORT nMask ); - SC_DLLPUBLIC BOOL HasAttrib( const ScRange& rRange, USHORT nMask ); + SC_DLLPUBLIC bool HasAttrib( SCCOL nCol1, SCROW nRow1, SCTAB nTab1, + SCCOL nCol2, SCROW nRow2, SCTAB nTab2, USHORT nMask ); + SC_DLLPUBLIC bool HasAttrib( const ScRange& rRange, USHORT nMask ); void GetBorderLines( SCCOL nCol, SCROW nRow, SCTAB nTab, const SvxBorderLine** ppLeft, diff --git a/sc/inc/dpcachetable.hxx b/sc/inc/dpcachetable.hxx index 60dba0bc27db..eab01d078081 100644 --- a/sc/inc/dpcachetable.hxx +++ b/sc/inc/dpcachetable.hxx @@ -55,33 +55,38 @@ class ScRange; class ScDPDimension; class ScDPCollection; struct ScDPCacheCell; -struct ScDPItemData; struct ScQueryParam; +// Wang Xu Ming -- 2009-8-17 +// DataPilot Migration - Cache&&Performance +class ScDPItemData; +// End Comments class Date; +// Wang Xu Ming -- 2009-8-17 +// DataPilot Migration - Cache&&Performance +class ScDPTableDataCache; +struct ScDPValueData; +// End Comments // ---------------------------------------------------------------------------- -class ScDPCacheTable +class SC_DLLPUBLIC ScDPCacheTable { public: - - struct Cell - { - SCROW mnCategoryRef; - ScDPCacheCell* mpContent; - - Cell(); - ~Cell(); - }; - /** individual filter item used in SingleFilter and GroupFilter. */ struct FilterItem { - sal_Int32 mnMatchStrId; + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + String maString; + // End Comments double mfValue; bool mbHasValue; FilterItem(); +// Wang Xu Ming -- 2009-8-17 +// DataPilot Migration - Cache&&Performance + bool match( const ScDPItemData& rCellData ) const; +// End Comments }; /** interface class used for filtering of rows. */ @@ -90,19 +95,26 @@ public: public: /** returns true if the matching condition is met for a single cell value, or false otherwise. */ - virtual bool match(const ScDPCacheCell& rCell) const = 0; +// Wang Xu Ming -- 2009-8-17 +// DataPilot Migration - Cache&&Performance + virtual bool match( const ScDPItemData& rCellData ) const = 0; +// End Comments }; /** ordinary single-item filter. */ class SingleFilter : public FilterBase { public: - explicit SingleFilter(ScSimpleSharedString& rSharedString, - sal_Int32 nMatchStrId, double fValue, bool bHasValue); + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + explicit SingleFilter(String aString, double fValue, bool bHasValue); + // End Comments virtual ~SingleFilter(){} - virtual bool match(const ScDPCacheCell& rCell) const; - + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + virtual bool match(const ScDPItemData& rCellData) const; + // End Comments const String getMatchString(); double getMatchValue() const; bool hasValue() const; @@ -111,25 +123,27 @@ public: explicit SingleFilter(); FilterItem maItem; - ScSimpleSharedString mrSharedString; }; /** multi-item (group) filter. */ class GroupFilter : public FilterBase { public: - GroupFilter(ScSimpleSharedString& rSharedString); + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + GroupFilter(); + // End Comments virtual ~GroupFilter(){} - virtual bool match(const ScDPCacheCell& rCell) const; - + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + virtual bool match( const ScDPItemData& rCellData ) const; + // End Comments void addMatchItem(const String& rStr, double fVal, bool bHasValue); size_t getMatchItemCount() const; private: - GroupFilter(); ::std::vector<FilterItem> maItems; - ScSimpleSharedString mrSharedString; }; /** single filtering criterion. */ @@ -140,22 +154,26 @@ public: Criterion(); }; - - ScDPCacheTable(ScDPCollection* pCollection); + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + ScDPCacheTable( ScDocument* pDoc,long nId ); + // End Comments ~ScDPCacheTable(); sal_Int32 getRowSize() const; sal_Int32 getColSize() const; + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + ScDPTableDataCache* GetCache() const; /** Fill the internal table from the cell range provided. This function - assumes that the first row is the column header. */ - void fillTable(ScDocument* pDoc, const ScRange& rRange, const ScQueryParam& rQuery, BOOL* pSpecial, - bool bIgnoreEmptyRows); - + assumes that the first row is the column header. */ + void fillTable( const ScQueryParam& rQuery, BOOL* pSpecial, + bool bIgnoreEmptyRows, bool bRepeatIfEmpty ); /** Fill the internal table from database connection object. This function assumes that the first row is the column header. */ - void fillTable(const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRowSet >& xRowSet, - const Date& rNullDate); + void fillTable(); + // End Comments /** Check whether a specified row is active or not. When a row is active, it is used in calculation of the results data. A row becomes inactive @@ -169,15 +187,23 @@ public: /** Get the cell instance at specified location within the data grid. Note that the data grid doesn't include the header row. Don't delete the returned object! */ - const ScDPCacheCell* getCell(SCCOL nCol, SCROW nRow, bool bRepeatIfEmpty) const; - - const String* getFieldName(sal_Int32 nIndex) const; - - /** Get the unique entries for a field specified by index. The caller must + const ScDPItemData* getCell(SCCOL nCol, SCROW nRow, bool bRepeatIfEmpty) const; + void getValue( ScDPValueData& rVal, SCCOL nCol, SCROW nRow, bool bRepeatIfEmpty) const; + String getFieldName( SCCOL nIndex) const; + //End Comments + + /** Get the field index (i.e. column ID in the original data source) based + on the string value that corresponds with the column title. It returns + -1 if no field matching the string value exists. */ + sal_Int32 getFieldIndex(const String& rStr) const; + + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + /** Get the unique entries for a field specified by index. The caller must make sure that the table is filled before calling function, or it will get an empty collection. */ - const TypedScStrCollection& getFieldEntries(sal_Int32 nIndex) const; - + const ::std::vector<SCROW>& getFieldEntries( sal_Int32 nColumn ) const; + // End Comments /** Filter the table based on the specified criteria, and copy the result to rTabData. This method is used, for example, to generate a drill-down data table. */ @@ -186,6 +212,7 @@ public: const ::std::hash_set<sal_Int32>& rRepeatIfEmptyDims); void clear(); + void swap(ScDPCacheTable& rOther); bool empty() const; private: @@ -200,26 +227,23 @@ private: */ bool isRowQualified(sal_Int32 nRow, const ::std::vector<Criterion>& rCriteria, const ::std::hash_set<sal_Int32>& rRepeatIfEmptyDims) const; void getValueData(ScDocument* pDoc, const ScAddress& rPos, ScDPCacheCell& rCell); - + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + void InitNoneCache( ScDocument* pDoc ); + // End Comments private: - typedef ::boost::shared_ptr<TypedScStrCollection> TypedScStrCollectionPtr; - - /** main data table. */ - ::std::vector< ::std::vector< ::ScDPCacheTable::Cell > > maTable; - - /** header string IDs */ - ::std::vector<sal_Int32> maHeader; - + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance /** unique field entires for each field (column). */ - ::std::vector<TypedScStrCollectionPtr> maFieldEntries; - + ::std::vector< ::std::vector<SCROW> > maFieldEntries; + // End Comments /** used to track visibility of rows. The first row below the header row has the index of 0. */ ::std::vector<bool> maRowsVisible; - - ScSimpleSharedString& mrSharedString; - ScDPCollection* mpCollection; + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + ScDPTableDataCache* mpCache; + ScDPTableDataCache* mpNoneCache; + // End Comments }; - - #endif diff --git a/sc/inc/dpglobal.hxx b/sc/inc/dpglobal.hxx new file mode 100755 index 000000000000..7de5947cc969 --- /dev/null +++ b/sc/inc/dpglobal.hxx @@ -0,0 +1,209 @@ +/************************************************************************* + * + * 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: dpglobal.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. + * + ************************************************************************/ +// Wang Xu Ming - DataPilot migration +// Buffer&&Performance +// +#ifndef _SC_DPGLOBAL_HXX +#define _SC_DPGLOBAL_HXX + +#include <algorithm> +#include <list> +#include <tools/gen.hxx> +#include <tools/debug.hxx> +#include <global.hxx> + +#include <com/sun/star/container/XNamed.hpp> +#include <com/sun/star/sheet/XDimensionsSupplier.hpp> + +#include <com/sun/star/sheet/DataPilotFieldFilter.hpp> +#include <com/sun/star/sheet/DataPilotFieldOrientation.hpp> +#include <com/sun/star/sheet/DataPilotTableHeaderData.hpp> +#include <com/sun/star/sheet/DataPilotTablePositionData.hpp> +#include <com/sun/star/sheet/DataPilotTablePositionType.hpp> +#include <com/sun/star/sheet/DataPilotTableResultData.hpp> +#include <com/sun/star/sheet/DataResultFlags.hpp> +#include <com/sun/star/sheet/GeneralFunction.hpp> +#include <com/sun/star/sheet/MemberResultFlags.hpp> +#include <com/sun/star/sheet/TableFilterField.hpp> +#include <com/sun/star/sheet/XDataPilotMemberResults.hpp> +#include <com/sun/star/sheet/XDataPilotResults.hpp> +#include <com/sun/star/sheet/XHierarchiesSupplier.hpp> +#include <com/sun/star/sheet/XLevelsSupplier.hpp> + + +// moved from fieldwnd.hxx, see also SC_DAPI_MAXFIELDS +#define MAX_LABELS 256 + +#define MAX_PAGEFIELDS 10 // maximum count of fields for page area + +#define PIVOT_MAXFUNC 11 +#define PIVOT_FUNC_NONE 0x0000 +#define PIVOT_FUNC_SUM 0x0001 +#define PIVOT_FUNC_COUNT 0x0002 +#define PIVOT_FUNC_AVERAGE 0x0004 +#define PIVOT_FUNC_MAX 0x0008 +#define PIVOT_FUNC_MIN 0x0010 +#define PIVOT_FUNC_PRODUCT 0x0020 +#define PIVOT_FUNC_COUNT_NUM 0x0040 +#define PIVOT_FUNC_STD_DEV 0x0080 +#define PIVOT_FUNC_STD_DEVP 0x0100 +#define PIVOT_FUNC_STD_VAR 0x0200 +#define PIVOT_FUNC_STD_VARP 0x0400 +#define PIVOT_FUNC_AUTO 0x1000 + +#define DATA_RENAME_SEPARATOR "_" +#define __MAX_NUM_LEN 64 +#define __DECIMALPLACE 18 + +#define DP_PROP_COLUMNGRAND "ColumnGrand" +#define DP_PROP_FUNCTION "Function" +#define DP_PROP_IGNOREEMPTY "IgnoreEmptyRows" +#define DP_PROP_ISDATALAYOUT "IsDataLayoutDimension" +#define DP_PROP_ISVISIBLE "IsVisible" +#define DP_PROP_ORIENTATION "Orientation" +#define DP_PROP_REPEATIFEMPTY "RepeatIfEmpty" +#define DP_PROP_ROWGRAND "RowGrand" +#define DP_PROP_SHOWDETAILS "ShowDetails" +#define DP_PROP_SHOWEMPTY "ShowEmpty" +#define DP_PROP_SUBTOTALS "SubTotals" +#define DP_PROP_USEDHIERARCHY "UsedHierarchy" +#define DP_PROP_FILTER "Filter" +#define DP_PROP_POSITION "Position" + +#define DBG_TRACESTR( x ) \ + {\ + ByteString aTemp( x , RTL_TEXTENCODING_UTF8 ); \ + DBG_TRACE( aTemp.GetBuffer() );\ + } + +class TypedStrData; +class ScDPObject; + +class SC_DLLPUBLIC ScDPItemData +{ +public: + enum { MK_VAL = 0x01, MK_DATA = MK_VAL<<1, MK_ERR = MK_DATA<<1, MK_DATE = MK_ERR<<1, MK_DATEPART = MK_DATE<<1 }; +private: + union + { + ULONG nNumFormat; + sal_Int32 mnDatePart; + }; + + String aString; + double fValue; + BYTE mbFlag; + //BOOL bHasValue: 1 ; + //BOOL bHasData: 1; + //BOOL bErr: 1; + + friend class ScDPTableDataCache; +public: + ScDPItemData() : nNumFormat( 0 ), fValue(0.0), mbFlag( 0 ){} + ScDPItemData( ULONG nNF, const String & rS, double fV, BYTE bF ):nNumFormat(nNF), aString(rS), fValue(fV), mbFlag( bF ){} + ScDPItemData( const String& rS, double fV = 0.0, BOOL bHV = FALSE, const ULONG nNumFormat = 0 , BOOL bData = TRUE) ; + ScDPItemData( ScDocument* pDoc, SCROW nRow, USHORT nCol, USHORT nDocTab ); + + void SetString( const String& rS ) { aString = rS; mbFlag &= ~(MK_VAL|MK_DATE); nNumFormat = 0; mbFlag |= MK_DATA; } +// void SetValue ( double value , ULONG nNumFormat = 0 ) { bHasValue = TRUE; nNumFormat = 0;bHasData = TRUE; bDate = FALSE; fValue = value ;} + BOOL IsCaseInsEqual( const ScDPItemData& r ) const; + + size_t Hash() const; + + // exact equality + BOOL operator==( const ScDPItemData& r ) const; + // case insensitive equality + static sal_Int32 Compare( const ScDPItemData& rA, const ScDPItemData& rB ); + +#ifdef DEBUG + void dump() const; +#endif + +public: + BOOL IsHasData() const ; + BOOL IsHasErr() const ; + BOOL IsValue() const; + String GetString() const ; + double GetValue() const ; + ULONG GetNumFormat() const ; + BOOL HasStringData() const ; + BOOL IsDate() const; + BOOL HasDatePart() const; + void SetDate( BOOL b ) ; + + TypedStrData* CreateTypeString( ); + sal_uInt8 GetType() const; + BYTE & GetFlag() throw() { return mbFlag; } + const BYTE & GetFlag() const throw() { return const_cast<ScDPItemData*>(this)->GetFlag(); } +}; + +class SC_DLLPUBLIC ScDPItemDataPool +{ +public: + // construct + ScDPItemDataPool(void); + ScDPItemDataPool(const ScDPItemDataPool& r); + + virtual ~ScDPItemDataPool(void); + virtual const ScDPItemData* getData( sal_Int32 nId ); + virtual sal_Int32 getDataId( const ScDPItemData& aData ); + virtual sal_Int32 insertData( const ScDPItemData& aData ); +protected: + struct DataHashFunc : public std::unary_function< const ScDPItemData &, size_t > + { + size_t operator() (const ScDPItemData &rData) const { return rData.Hash(); } + }; + + typedef ::std::hash_multimap< ScDPItemData, sal_Int32, DataHashFunc > DataHash; + + ::std::vector< ScDPItemData > maItems; + DataHash maItemIds; +}; + +class ScDPInfoWnd; +class ScDocShell; +class ScTabViewShell; +namespace ScDPGlobal +{ +// used for core data + String GetFieldFuncString( const String& rSourceName, USHORT &rFuncMask, BOOL bIsValue ); + String GetFuncString( const String &rString, const USHORT nIndex ); + com::sun::star::uno::Reference<com::sun::star::container::XNameAccess> DP_GetMembers( const com::sun::star::uno::Reference< + com::sun::star::sheet::XDimensionsSupplier>&rSrc, long nField ); +// common operation + String operator + ( const String & rL, const String &rR ); + Rectangle operator *( const Rectangle &rLeft, const std::pair<double,double> & rRight ); +// used for DataPilot Panel + ScDPInfoWnd* GetDPInfoWnd( ScTabViewShell *pViewShell ); + bool ChkDPTableOverlap( ScDocument *pDestDoc, std::list<ScDPObject> & rClipboard, SCCOL nClipStartCol, SCROW nClipStartRow, SCCOL nStartCol, SCROW nStartRow, SCTAB nStartTab, USHORT nEndTab, BOOL bExcludeClip = FALSE ); + +} +#endif diff --git a/sc/inc/dpgroup.hxx b/sc/inc/dpgroup.hxx index 39770d2adffd..2a66f8b45555 100644 --- a/sc/inc/dpgroup.hxx +++ b/sc/inc/dpgroup.hxx @@ -34,7 +34,10 @@ #include "dptabdat.hxx" #include "scdllapi.h" - +// Wang Xu Ming -- 2009-8-17 +// DataPilot Migration - Cache&&Performance +#include "dpglobal.hxx" +// End Comments class ScDocument; class SvNumberFormatter; @@ -73,8 +76,11 @@ public: sal_Int32 GetDatePart() const { return nDatePart; } const ScDPNumGroupInfo& GetNumInfo() const { return aNumInfo; } - void FillColumnEntries( TypedScStrCollection& rEntries, const TypedScStrCollection& rOriginal, - SvNumberFormatter* pFormatter ) const; + // Wang Xu Ming -- 2009-9-8 + // DataPilot Migration - Cache&&Performance + void FillColumnEntries( SCCOL nSourceDim, ScDPTableDataCache* pCahe , std::vector< SCROW >& rEntries, + const std::vector< SCROW >& rOriginal ) const; + // End Comments }; // -------------------------------------------------------------------- @@ -108,8 +114,10 @@ class ScDPGroupDimension String aGroupName; ScDPDateGroupHelper* pDateHelper; ScDPGroupItemVec aItems; - mutable TypedScStrCollection* pCollection; // collection of item names (cached) - + // Wang Xu Ming -- 2009-9-4 + // DataPilot Migration - Cache&&Performance + mutable ::std::vector< SCROW > maMemberEntries; + // End Comments public: ScDPGroupDimension( long nSource, const String& rNewName ); ScDPGroupDimension( const ScDPGroupDimension& rOther ); @@ -122,9 +130,12 @@ public: long GetSourceDim() const { return nSourceDim; } long GetGroupDim() const { return nGroupDim; } - const String& GetName() const { return aGroupName; } + const String& GetName() const { return aGroupName; } - const TypedScStrCollection& GetColumnEntries( const TypedScStrCollection& rOriginal, ScDocument* pDoc ) const; +// Wang Xu Ming -- 2009-9-2 +// DataPilot Migration - Cache&&Performance + const std::vector< SCROW >& GetColumnEntries( const ScDPCacheTable& rCacheTable, const std::vector< SCROW >& rOriginal ) const; +// End Comments const ScDPGroupItem* GetGroupForData( const ScDPItemData& rData ) const; // rData = entry in original dim. const ScDPGroupItem* GetGroupForName( const ScDPItemData& rName ) const; // rName = entry in group dim. const ScDPGroupItem* GetGroupByIndex( size_t nIndex ) const; @@ -146,7 +157,10 @@ class SC_DLLPUBLIC ScDPNumGroupDimension { ScDPNumGroupInfo aGroupInfo; // settings ScDPDateGroupHelper* pDateHelper; - mutable TypedScStrCollection* pCollection; // collection of item names (cached) +// Wang Xu Ming -- 2009-9-4 +// DataPilot Migration - Cache&&Performance + mutable ::std::vector< SCROW > maMemberEntries; +// End Comments mutable bool bHasNonInteger; // initialized in GetNumEntries mutable sal_Unicode cDecSeparator; // initialized in GetNumEntries @@ -158,14 +172,15 @@ public: ScDPNumGroupDimension& operator=( const ScDPNumGroupDimension& rOther ); - const TypedScStrCollection& GetNumEntries( const TypedScStrCollection& rOriginal, ScDocument* pDoc ) const; - const ScDPNumGroupInfo& GetInfo() const { return aGroupInfo; } bool HasNonInteger() const { return bHasNonInteger; } sal_Unicode GetDecSeparator() const { return cDecSeparator; } const ScDPDateGroupHelper* GetDateHelper() const { return pDateHelper; } + const std::vector< SCROW >& GetNumEntries( SCCOL nSourceDim, ScDPTableDataCache* pCache, + const std::vector< SCROW >& rOriginal ) const; + void MakeDateHelper( const ScDPNumGroupInfo& rInfo, sal_Int32 nPart ); void DisposeData(); @@ -187,7 +202,11 @@ class ScDPGroupTableData : public ScDPTableData ScDocument* pDoc; StringHashSet aGroupNames; - void FillGroupValues( ScDPItemData* pItemData, long nCount, const long* pDims ); +// Wang Xu Ming -- 2009-8-17 +// DataPilot Migration - Cache&&Performance + 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; @@ -208,11 +227,18 @@ public: ScDocument* GetDocument() { return pDoc; } virtual long GetColumnCount(); - virtual const TypedScStrCollection& GetColumnEntries(long nColumn); +// Wang Xu Ming -- 2009-8-17 +// DataPilot Migration - Cache&&Performance + virtual long GetMembersCount( long nDim ); + virtual const std::vector< SCROW >& GetColumnEntries( long nColumn ) ; + virtual const ScDPItemData* GetMemberById( long nDim, long nId); + virtual long Compare( long nDim, long nDataId1, long nDataId2); + +// End Comments virtual String getDimensionName(long nColumn); virtual BOOL getIsDataLayoutDimension(long nColumn); virtual BOOL IsDateDimension(long nDim); - virtual UINT32 GetNumberFormat(long nDim); + virtual ULONG GetNumberFormat(long nDim); virtual void DisposeData(); virtual void SetEmptyFlags( BOOL bIgnoreEmptyRows, BOOL bRepeatIfEmpty ); diff --git a/sc/inc/dpobject.hxx b/sc/inc/dpobject.hxx index 917d62f38bfe..65e89ec75d41 100644 --- a/sc/inc/dpobject.hxx +++ b/sc/inc/dpobject.hxx @@ -115,8 +115,18 @@ private: SC_DLLPRIVATE ScDPTableData* GetTableData(); SC_DLLPRIVATE void CreateObjects(); SC_DLLPRIVATE void CreateOutput(); + BOOL bRefresh; + long mnCacheId; public: + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + inline void SetRefresh() { bRefresh = TRUE; } + const ScDPTableDataCache* GetCache() const; + long GetCacheId() const; + void SetCacheId( long nCacheId ); + ULONG RefreshCache(); + // End Comments ScDPObject( ScDocument* pD ); ScDPObject(const ScDPObject& r); virtual ~ScDPObject(); @@ -251,19 +261,6 @@ public: PivotField* pRefPageFields = NULL, SCSIZE nRefPageCount = 0 ); }; -// ============================================================================ - -struct ScDPCacheCell -{ - sal_Int32 mnStrId; - sal_uInt8 mnType; - double mfValue; - bool mbNumeric; - - ScDPCacheCell(); - ScDPCacheCell(const ScDPCacheCell& r); - ~ScDPCacheCell(); -}; // ============================================================================ @@ -271,20 +268,6 @@ class ScDPCollection : public ScCollection { private: ScDocument* pDoc; - ScSimpleSharedString maSharedString; - - struct CacheCellHash - { - size_t operator()(const ScDPCacheCell* pCell) const; - }; - struct CacheCellEqual - { - bool operator()(const ScDPCacheCell* p1, const ScDPCacheCell* p2) const; - }; - typedef ::std::hash_set<ScDPCacheCell*, CacheCellHash, CacheCellEqual> CacheCellPoolType; - - CacheCellPoolType maCacheCellPool; - public: ScDPCollection(ScDocument* pDocument); ScDPCollection(const ScDPCollection& r); @@ -303,15 +286,10 @@ public: String CreateNewName( USHORT nMin = 1 ) const; - ScSimpleSharedString& GetSharedString(); - void FreeTable(ScDPObject* pDPObj); SC_DLLPUBLIC bool InsertNewTable(ScDPObject* pDPObj); bool HasDPTable(SCCOL nCol, SCROW nRow, SCTAB nTab) const; - - ScDPCacheCell* getCacheCellFromPool(const ScDPCacheCell& rCell); - void clearCacheCellPool(); }; diff --git a/sc/inc/dpsave.hxx b/sc/inc/dpsave.hxx index 587e23d8109b..bfff0b97a168 100644 --- a/sc/inc/dpsave.hxx +++ b/sc/inc/dpsave.hxx @@ -88,6 +88,9 @@ public: }; +bool operator == (const ::com::sun::star::sheet::DataPilotFieldSortInfo &l, const ::com::sun::star::sheet::DataPilotFieldSortInfo &r ); +bool operator == (const ::com::sun::star::sheet::DataPilotFieldAutoShowInfo &l, const ::com::sun::star::sheet::DataPilotFieldAutoShowInfo &r ); +bool operator == (const ::com::sun::star::sheet::DataPilotFieldReference &l, const ::com::sun::star::sheet::DataPilotFieldReference &r ); class SC_DLLPUBLIC ScDPSaveDimension { private: @@ -175,6 +178,9 @@ public: void WriteToSource( const com::sun::star::uno::Reference< com::sun::star::uno::XInterface>& xDim ); + void Refresh( const com::sun::star::uno::Reference< + com::sun::star::sheet::XDimensionsSupplier>& xSource , + const std::list<String> & deletedDims); void UpdateMemberVisibility(const ::std::hash_map< ::rtl::OUString, bool, ::rtl::OUStringHash>& rData); @@ -193,6 +199,10 @@ private: USHORT nRepeatEmptyMode; BOOL bFilterButton; // not passed to DataPilotSource BOOL bDrillDown; // not passed to DataPilotSource + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + long mnCacheId; + // End Comments /** if true, all dimensions already have all of their member instances * created. */ @@ -248,10 +258,15 @@ public: BOOL GetDrillDown() const { return bDrillDown; } void WriteToSource( const com::sun::star::uno::Reference< + com::sun::star::sheet::XDimensionsSupplier>& xSource ); + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + void Refresh( const com::sun::star::uno::Reference< com::sun::star::sheet::XDimensionsSupplier>& xSource ); - BOOL IsEmpty() const; - + inline long GetCacheId() const{ return mnCacheId; } + inline void SetCacheId( long nCacheId ){ mnCacheId = nCacheId; } + // End Comments const ScDPDimensionSaveData* GetExistingDimensionData() const { return pDimensionData; } SC_DLLPUBLIC ScDPDimensionSaveData* GetDimensionData(); // create if not there void SetDimensionData( const ScDPDimensionSaveData* pNew ); // copied diff --git a/sc/inc/dpsdbtab.hxx b/sc/inc/dpsdbtab.hxx index 21e23e883da9..732e3d30e8df 100644 --- a/sc/inc/dpsdbtab.hxx +++ b/sc/inc/dpsdbtab.hxx @@ -57,23 +57,25 @@ struct ScImportSourceDesc aObject == rOther.aObject && nType == rOther.nType && bNative == rOther.bNative; } -}; -class ScDatabaseDPData_Impl; + // Wang Xu Ming -- 2009-9-15 + // DataPilot Migration - Cache&&Performance + ScDPTableDataCache* GetExistDPObjectCache( ScDocument* pDoc ) const; + ScDPTableDataCache* CreateCache( ScDocument* pDoc , long nID ) const; + ScDPTableDataCache* GetCache( ScDocument* pDoc, long nID ) const; + long GetCacheId( ScDocument* pDoc, long nID ) const; + // End Comments +}; class ScDatabaseDPData : public ScDPTableData { private: - ScDatabaseDPData_Impl* pImpl; - - BOOL OpenDatabase(); - + ScDPCacheTable aCacheTable; public: - ScDatabaseDPData(ScDocument* pDoc, const ScImportSourceDesc& rImport); + ScDatabaseDPData(ScDocument* pDoc, const ScImportSourceDesc& rImport, long nCacheId = -1); virtual ~ScDatabaseDPData(); virtual long GetColumnCount(); - virtual const TypedScStrCollection& GetColumnEntries(long nColumn); virtual String getDimensionName(long nColumn); virtual BOOL getIsDataLayoutDimension(long nColumn); virtual BOOL IsDateDimension(long nDim); diff --git a/sc/inc/dpshttab.hxx b/sc/inc/dpshttab.hxx index a0e67371eff1..a8d80072c68a 100644 --- a/sc/inc/dpshttab.hxx +++ b/sc/inc/dpshttab.hxx @@ -41,8 +41,10 @@ namespace com { namespace sun { namespace star { namespace sheet { }}}} class ScDPDimension; -struct ScDPItemData; - +// Wang Xu Ming -- 2009-8-17 +// DataPilot Migration - Cache&&Performance +class ScDPItemData; +// End Comments // -------------------------------------------------------------------- // // implementation of ScDPTableData with sheet data @@ -56,25 +58,38 @@ struct ScSheetSourceDesc BOOL operator== ( const ScSheetSourceDesc& rOther ) const { return aSourceRange == rOther.aSourceRange && aQueryParam == rOther.aQueryParam; } +// Wang Xu Ming - DataPilot migration +// Buffer&&Performance + ScDPTableDataCache* CreateCache( ScDocument* pDoc, long nID = -1) const; + ULONG CheckValidate( ScDocument* pDoc ) const; + ScDPTableDataCache* GetCache( ScDocument* pDoc, long nID ) const; + ScDPTableDataCache* GetExistDPObjectCache ( ScDocument* pDoc ) const; + long GetCacheId( ScDocument* pDoc, long nID ) const; + +// End Comments }; -class ScSheetDPData_Impl; - class SC_DLLPUBLIC ScSheetDPData : public ScDPTableData { private: - ScSheetDPData_Impl* pImpl; + ScQueryParam aQuery; + BOOL* pSpecial; + BOOL bIgnoreEmptyRows; + BOOL bRepeatIfEmpty; + + ScDPCacheTable aCacheTable; public: - ScSheetDPData( ScDocument* pD, const ScSheetSourceDesc& rDesc ); + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + ScSheetDPData( ScDocument* pD, const ScSheetSourceDesc& rDesc, long nCacheId = -1 ); virtual ~ScSheetDPData(); - + // End Comments virtual long GetColumnCount(); - virtual const TypedScStrCollection& GetColumnEntries(long nColumn); virtual String getDimensionName(long nColumn); virtual BOOL getIsDataLayoutDimension(long nColumn); virtual BOOL IsDateDimension(long nDim); - virtual UINT32 GetNumberFormat(long nDim); + virtual ULONG GetNumberFormat(long nDim); virtual void DisposeData(); virtual void SetEmptyFlags( BOOL bIgnoreEmptyRows, BOOL bRepeatIfEmpty ); diff --git a/sc/inc/dptabdat.hxx b/sc/inc/dptabdat.hxx index 43c719e9ee16..6323434ca4ad 100644 --- a/sc/inc/dptabdat.hxx +++ b/sc/inc/dptabdat.hxx @@ -31,7 +31,10 @@ #include "address.hxx" #include "dpoutput.hxx" #include "dpcachetable.hxx" - +// Wang Xu Ming -- 2009-8-17 +// DataPilot Migration - Cache&&Performance +#include "dptablecache.hxx" +// End Comments #include <tools/string.hxx> #include <vector> @@ -43,8 +46,6 @@ namespace com { namespace sun { namespace star { namespace sheet { struct DataPilotFieldFilter; }}}} -class TypedScStrCollection; -class ScSimpleSharedString; // ----------------------------------------------------------------------- @@ -71,28 +72,6 @@ class ScSimpleSharedString; // base class ScDPTableData to allow implementation with tabular data // by deriving only of this // - -struct ScDPItemData -{ - String aString; - double fValue; - BOOL bHasValue; - - ScDPItemData() : fValue(0.0), bHasValue(FALSE) {} - ScDPItemData( const String& rS, double fV = 0.0, BOOL bHV = FALSE ) : - aString(rS), fValue(fV), bHasValue( bHV ) {} - - void SetString( const String& rS ) { aString = rS; bHasValue = FALSE; } - BOOL IsCaseInsEqual( const ScDPItemData& r ) const; - - size_t Hash() const; - - // exact equality - BOOL operator==( const ScDPItemData& r ) const; - // case insensitive equality - static sal_Int32 Compare( const ScDPItemData& rA, const ScDPItemData& rB ); -}; - #define SC_VALTYPE_EMPTY 0 #define SC_VALTYPE_VALUE 1 #define SC_VALTYPE_STRING 2 @@ -113,15 +92,18 @@ class ScDPInitState; class ScDPResultMember; class ScDocument; -class ScDPTableData + class SC_DLLPUBLIC ScDPTableData { // cached data for GetDatePart long nLastDateVal; long nLastHier; long nLastLevel; long nLastRet; - ScSimpleSharedString& mrSharedString; - + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + long mnCacheId; + const ScDocument* mpDoc; + // End Comments public: /** This structure stores dimension information used when calculating @@ -147,7 +129,10 @@ public: CalcInfo(); }; - ScDPTableData(ScDocument* pDoc); + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + ScDPTableData(ScDocument* pDoc, long nCacheId ); + // End Comments virtual ~ScDPTableData(); long GetDatePart( long nDateVal, long nHierarchy, long nLevel ); @@ -156,11 +141,16 @@ public: //! or separate Str and ValueCollection virtual long GetColumnCount() = 0; - virtual const TypedScStrCollection& GetColumnEntries(long nColumn) = 0; + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + virtual const std::vector< SCROW >& GetColumnEntries( long nColumn ) ; + long GetCacheId() const; + // End Comments virtual String getDimensionName(long nColumn) = 0; virtual BOOL getIsDataLayoutDimension(long nColumn) = 0; virtual BOOL IsDateDimension(long nDim) = 0; - virtual UINT32 GetNumberFormat(long nDim); + virtual ULONG GetNumberFormat(long nDim); + virtual UINT32 GetNumberFormatByIdx( NfIndexTableOffset ); virtual void DisposeData() = 0; virtual void SetEmptyFlags( BOOL bIgnoreEmptyRows, BOOL bRepeatIfEmpty ) = 0; @@ -176,23 +166,33 @@ public: // overloaded in ScDPGroupTableData: virtual BOOL IsBaseForGroup(long nDim) const; - virtual long GetGroupBase(long nGroupDim) const; + virtual long GetGroupBase(long nGroupDim) const; virtual BOOL IsNumOrDateGroup(long nDim) const; virtual BOOL IsInGroup( const ScDPItemData& rGroupData, long nGroupIndex, const ScDPItemData& rBaseData, long nBaseIndex ) const; virtual BOOL HasCommonElement( const ScDPItemData& rFirstData, long nFirstIndex, const ScDPItemData& rSecondData, long nSecondIndex ) const; - ScSimpleSharedString& GetSharedString(); - + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + virtual long GetMembersCount( long nDim ); + virtual const ScDPItemData* GetMemberByIndex( long nDim, long nIndex ); + virtual const ScDPItemData* GetMemberById( long nDim, long nId); + virtual SCROW GetIdOfItemData( long nDim, const ScDPItemData& rData ); + virtual long GetSourceDim( long nDim ); + virtual long Compare( long nDim, long nDataId1, long nDataId2); + // End Comments protected: /** This structure stores vector arrays that hold intermediate data for each row during cache table iteration. */ struct CalcRowData { - ::std::vector<ScDPItemData> aColData; - ::std::vector<ScDPItemData> aRowData; - ::std::vector<ScDPItemData> aPageData; + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + ::std::vector< SCROW > aColData; + ::std::vector< SCROW > aRowData; + ::std::vector< SCROW > aPageData; + // End Comments ::std::vector<ScDPValueData> aValues; }; @@ -201,10 +201,11 @@ protected: void CalcResultsFromCacheTable(const ScDPCacheTable& rCacheTable, CalcInfo& rInfo, bool bAutoShow); private: + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance void GetItemData(const ScDPCacheTable& rCacheTable, sal_Int32 nRow, - const ::std::vector<long>& rDims, ::std::vector<ScDPItemData>& rItemData); + const ::std::vector<long>& rDims, ::std::vector< SCROW >& rItemData); + // End Comments }; - - #endif diff --git a/sc/inc/dptablecache.hxx b/sc/inc/dptablecache.hxx new file mode 100644 index 000000000000..953c793093be --- /dev/null +++ b/sc/inc/dptablecache.hxx @@ -0,0 +1,122 @@ +/************************************************************************* + * + * 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: dptablecache.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 DPTABLECACHE_HXX +#define DPTABLECACHE_HXX +// Wang Xu Ming -- 12/21/2008 +// Add Data Cache Support. +#ifndef SC_SCGLOB_HXX +#include "global.hxx" +#endif +//Added by PengYunQuan for SODC_16015 +#include <svl/zforlist.hxx> +//end +#include <vector> +#include "dpglobal.hxx" + +#include <com/sun/star/sdbc/DataType.hpp> +#include <com/sun/star/sdbc/XRow.hpp> +#include <com/sun/star/sdbc/XRowSet.hpp> + +class ScDPTableDataCache; +class TypedStrData; +struct ScQueryParam; + +// -------------------------------------------------------------------- +// +// base class ScDPTableData to allow implementation with tabular data +// by deriving only of this +// + +class SC_DLLPUBLIC ScDPTableDataCache +{ + long mnID; + ScDocument* mpDoc; + + long mnColumnCount; // Column count + + std::vector<ScDPItemData*>* mpTableDataValues; //Data Pilot Table's index - value map + std::vector<SCROW>* mpSourceData; //Data Pilot Table's Source data + std::vector<SCROW>* mpGlobalOrder; //Sorted members index + std::vector<SCROW>* mpIndexOrder; //Index the sorted number + std::vector<ScDPItemData*> mrLabelNames; //Source Label data + std::vector<BOOL> mbEmptyRow; //If empty row? + mutable ScDPItemDataPool maAdditionalDatas; +public: + SCROW GetOrder( long nDim, SCROW nIndex ) const; + SCROW GetIdByItemData( long nDim, String sItemData ) const; + SCROW GetIdByItemData( long nDim, const ScDPItemData& rData ) const; + + SCROW GetAdditionalItemID ( String sItemData ); + SCROW GetAdditionalItemID( const ScDPItemData& rData ); + + SCCOL GetDimensionIndex( String sName) const; + const ScDPItemData* GetSortedItemData( SCCOL nDim, SCROW nOrder ) const; + ULONG GetNumType ( ULONG nFormat ) const; + ULONG GetNumberFormat( long nDim ) const; + BOOL IsDateDimension( long nDim ) const ; + ULONG GetDimNumType( SCCOL nDim) const; + SCROW GetDimMemberCount( SCCOL nDim ) const; + + SCROW GetSortedItemDataId( SCCOL nDim, SCROW nOrder ) const; + const std::vector<ScDPItemData*>& GetDimMemberValues( SCCOL nDim )const; + void SetId( long nId ){ mnID = nId;} + void AddRow( ScDPItemData* pRow, USHORT nCount ); + bool InitFromDoc( ScDocument* pDoc, const ScRange& rRange ); + bool InitFromDataBase (const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XRowSet>& xRowSet, const Date& rNullDate); + + SCROW GetRowCount() const; + SCROW GetItemDataId( USHORT nDim, SCROW nRow, BOOL bRepeatIfEmpty ) const; + String GetDimensionName( USHORT nColumn ) const; + bool IsEmptyMember( SCROW nRow, USHORT nColumn ) const; + bool IsRowEmpty( SCROW nRow ) const; + bool IsValid() const; + bool ValidQuery( SCROW nRow, const ScQueryParam& rQueryParam, BOOL* pSpecial ); + + ScDocument* GetDoc() const;//ms-cache-core + long GetColumnCount() const; + long GetId() const; + + const ScDPItemData* GetItemDataById( long nDim, SCROW nId ) const; + + BOOL operator== ( const ScDPTableDataCache& r ) const; + +//construction + ScDPTableDataCache( ScDocument* pDoc ); +//deconstruction + virtual ~ScDPTableDataCache(); + +protected: +private: + void AddLabel( ScDPItemData* pData); + BOOL AddData( long nDim, ScDPItemData* itemData ); +}; + +#endif //DPTABLECACHE_HXX diff --git a/sc/inc/dptabres.hxx b/sc/inc/dptabres.hxx index d4e8807d4a3b..e35975ab170f 100644 --- a/sc/inc/dptabres.hxx +++ b/sc/inc/dptabres.hxx @@ -57,8 +57,10 @@ class ScDPResultMember; class ScDPResultVisibilityData; struct ScDPValueData; -struct ScDPItemData; - +// Wang Xu Ming -- 2009-8-17 +// DataPilot Migration - Cache&&Performance +class ScDPItemData; +// End Comments // // Member names that are being processed for InitFrom/LateInitFrom // (needed for initialization of grouped items) @@ -67,21 +69,26 @@ struct ScDPItemData; class ScDPInitState { long* pIndex; // array - ScDPItemData* pData; // array +// Wang Xu Ming -- 2009-8-17 +// DataPilot Migration - Cache&&Performance + SCROW* pData; // array + // End Comments long nCount; public: ScDPInitState(); ~ScDPInitState(); - void AddMember( long nSourceIndex, const ScDPItemData& rName ); + void AddMember( long nSourceIndex,SCROW nMember); void RemoveMember(); long GetCount() const { return nCount; } const long* GetSource() const { return pIndex; } - const ScDPItemData* GetNames() const { return pData; } - - const ScDPItemData* GetNameForIndex( long nIndexValue ) const; +// Wang Xu Ming -- 2009-8-17 +// DataPilot Migration - Cache&&Performance + const SCROW* GetNameIds() const { return pData; } + const SCROW GetNameIdForIndex( long nIndexValue ) const; +// End Comments }; typedef ::std::vector<sal_Int32> ScMemberSortOrder; @@ -230,6 +237,68 @@ class ScDPDataMember; #define SC_DPMEASURE_ALL -1 #define SC_DPMEASURE_ANY -2 +// Wang Xu Ming -- 2009-8-17 +// DataPilot Migration - Cache&&Performance + +struct MemberHashIndexFunc : public std::unary_function< const SCROW &, size_t > +{ + size_t operator() (const SCROW &rDataIndex) const { return rDataIndex; } +}; + +class ScDPParentDimData +{ +public: + const SCROW mnOrder; //! Ref + const ScDPDimension* mpParentDim; //! Ref + const ScDPLevel* mpParentLevel; //! Ref + const ScDPMember* mpMemberDesc; //! Ref + + ScDPParentDimData():mnOrder(-1), mpParentDim( NULL), mpParentLevel( NULL ), mpMemberDesc( NULL ){} + ScDPParentDimData( const SCROW nIndex, ScDPDimension* pDim, const ScDPLevel* pLev, const ScDPMember* pMember ): mnOrder( nIndex ), mpParentDim( pDim), mpParentLevel( pLev ), mpMemberDesc( pMember ){} +}; + +typedef std::vector <ScDPParentDimData *> DimMemberArray; +typedef std::hash_map < SCROW, ScDPParentDimData *, MemberHashIndexFunc> DimMemberHash; + +class ResultMembers +{ + DimMemberHash maMemberHash; + BOOL mbHasHideDetailsMember; +public: + ScDPParentDimData* FindMember( const SCROW& nIndex ) const; + void InsertMember( ScDPParentDimData* pNew ); + BOOL IsHasHideDetailsMembers() const { return mbHasHideDetailsMember; } + void SetHasHideDetailsMembers( BOOL b ) { mbHasHideDetailsMember=b; } + ResultMembers(); + virtual ~ResultMembers(); +}; + +class LateInitParams +{ +private: + const ::std::vector<ScDPDimension*>& mppDim; + const ::std::vector<ScDPLevel*>& mppLev; + + BOOL mbRow; + BOOL mbInitChild; + BOOL mbAllChildren; +public: + LateInitParams( const ::std::vector<ScDPDimension*>& ppDim, const ::std::vector<ScDPLevel*>& ppLev, + BOOL bRow, BOOL bInitChild = TRUE , BOOL bAllChildren = FALSE); + ~LateInitParams(); + + void SetInitChild( BOOL b ) { mbInitChild = b; } + void SetInitAllChildren( BOOL b ) { mbAllChildren = b; } + + inline ScDPDimension* GetDim( size_t nPos ) const { return mppDim[nPos];} + inline ScDPLevel* GetLevel( size_t nPos ) const { return mppLev[nPos];} + + inline BOOL GetInitChild() const {return mbInitChild; } + inline BOOL GetInitAllChild() const { return mbAllChildren; } + inline BOOL IsRow() const { return mbRow; } + BOOL IsEnd( size_t nPos ) const ; +}; +// End Comments class ScDPResultData { @@ -247,7 +316,7 @@ private: BOOL bDataAtRow; //! add "displayed values" settings - + mutable std::vector< ResultMembers* > mpDimMembers; public: ScDPResultData( ScDPSource* pSrc ); //! Ref ~ScDPResultData(); @@ -278,11 +347,18 @@ public: BOOL IsBaseForGroup( long nDim ) const; // any group long GetGroupBase( long nGroupDim ) const; BOOL IsNumOrDateGroup( long nDim ) const; + // Wang Xu Ming -- 2009-8-17 +// DataPilot Migration - Cache&&Performance BOOL IsInGroup( const ScDPItemData& rGroupData, long nGroupIndex, - const ScDPItemData& rBaseData, long nBaseIndex ) const; - BOOL HasCommonElement( const ScDPItemData& rFirstData, long nFirstIndex, + long nBaseDataId, long nBaseIndex ) const; + BOOL IsInGroup( SCROW nGroupDataId, long nGroupIndex, + const ScDPItemData& rBaseData, long nBaseIndex ) const; + BOOL HasCommonElement( SCROW nFirstDataId, long nFirstIndex, const ScDPItemData& rSecondData, long nSecondIndex ) const; + ResultMembers* GetDimResultMembers( long nDim , ScDPDimension* pDim , ScDPLevel* pLevel) const ; + +// End Comments const ScDPSource* GetSource() const; }; @@ -291,9 +367,10 @@ class ScDPResultMember { private: const ScDPResultData* pResultData; - const ScDPDimension* pParentDim; //! Ref - const ScDPLevel* pParentLevel; //! Ref - const ScDPMember* pMemberDesc; //! Ref + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + ScDPParentDimData aParentDimData; + // End Comments ScDPResultDimension* pChildDimension; ScDPDataMember* pDataRoot; BOOL bHasElements; @@ -303,21 +380,30 @@ private: BOOL bAutoHidden; ScDPAggData aColTotal; // to store column totals + USHORT nMemberStep; // step to show details public: - ScDPResultMember( const ScDPResultData* pData, const ScDPDimension* pDim, - const ScDPLevel* pLev, const ScDPMember* pDesc, - BOOL bForceSub ); //! Ref - ~ScDPResultMember(); - + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + ScDPResultMember( const ScDPResultData* pData, const ScDPParentDimData& rParentDimData, + BOOL bForceSub ); //! Ref + ScDPResultMember( const ScDPResultData* pData, BOOL bForceSub ); + // End Comments + ~ScDPResultMember(); + + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance void InitFrom( const ::std::vector<ScDPDimension*>& ppDim, - const ::std::vector<ScDPLevel*>& ppLev, - size_t nPos, - ScDPInitState& rInitState ); - void LateInitFrom( const ::std::vector<ScDPDimension*>& ppDim, - const ::std::vector<ScDPLevel*>& ppLev, - const ::std::vector<ScDPItemData>& pItemData, - size_t nPos, - ScDPInitState& rInitState ); + const ::std::vector<ScDPLevel*>& ppLev, + size_t nPos, + ScDPInitState& rInitState, + BOOL bInitChild = TRUE ); + void LateInitFrom( + LateInitParams& rParams, + const ::std::vector< SCROW >& pItemData, + size_t nPos, + ScDPInitState& rInitState); + void CheckShowEmpty( BOOL bShow = FALSE ); + // End Comments String GetName() const; void FillItemData( ScDPItemData& rData ) const; BOOL IsValid() const; @@ -329,17 +415,22 @@ public: // BOOL SubTotalEnabled() const; long GetSubTotalCount( long* pUserSubStart = NULL ) const; - BOOL IsNamedItem( const ScDPItemData& r ) const; - bool IsValidEntry( const ::std::vector<ScDPItemData>& aMembers ) const; + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + BOOL IsNamedItem( SCROW nIndex ) const; + bool IsValidEntry( const ::std::vector< SCROW >& aMembers ) const; + // End Comments void SetHasElements() { bHasElements = TRUE; } void SetAutoHidden() { bAutoHidden = TRUE; } - void ProcessData( const ::std::vector<ScDPItemData>& aChildMembers, - const ScDPResultDimension* pDataDim, - const ::std::vector<ScDPItemData>& aDataMembers, - const ::std::vector<ScDPValueData>& aValues ); - + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + void ProcessData( const ::std::vector<SCROW>& aChildMembers, + const ScDPResultDimension* pDataDim, + const ::std::vector<SCROW>& aDataMembers, + const ::std::vector<ScDPValueData>& aValues ); + // End Comments void FillMemberResults( com::sun::star::uno::Sequence< com::sun::star::sheet::MemberResult>* pSequences, long& rPos, long nMeasure, BOOL bRoot, @@ -369,9 +460,15 @@ public: ScDPDataMember* GetDataRoot() const { return pDataRoot; } - const ScDPDimension* GetParentDim() const { return pParentDim; } //! Ref - const ScDPLevel* GetParentLevel() const { return pParentLevel; } //! Ref - + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + 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; } + SCROW GetDataId( ) const ; + // End Comments ScDPAggData* GetColTotal( long nMeasure ) const; void FillVisibilityData(ScDPResultVisibilityData& rData) const; @@ -397,13 +494,17 @@ public: BOOL IsVisible() const; BOOL HasData( long nMeasure, const ScDPSubTotalState& rSubState ) const; - BOOL IsNamedItem( const ScDPItemData& r ) const; - + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + BOOL IsNamedItem( SCROW r ) const; + // End Comments BOOL HasHiddenDetails() const; - void ProcessData( const ::std::vector<ScDPItemData>& aChildMembers, const ::std::vector<ScDPValueData>& aValues, - const ScDPSubTotalState& rSubState ); - + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + void ProcessData( const ::std::vector< SCROW >& aChildMembers, const ::std::vector<ScDPValueData>& aValues, + const ScDPSubTotalState& rSubState ); + // End Comments BOOL HasError( long nMeasure, const ScDPSubTotalState& rSubState ) const; double GetAggregate( long nMeasure, const ScDPSubTotalState& rSubState ) const; const ScDPAggData* GetConstAggData( long nMeasure, const ScDPSubTotalState& rSubState ) const; @@ -443,15 +544,13 @@ SV_DECL_PTRARR_DEL(ScDPDataMembers, ScDPDataMemberPtr, SC_DP_RES_GROW, SC_DP_RES class ScDPResultDimension { public : - struct MemberHashFunc : public std::unary_function< const ScDPItemData &, size_t > - { - size_t operator() (const ScDPItemData &rData) const { return rData.Hash(); } - }; - typedef std::vector <ScDPResultMember *> MemberArray; - typedef std::hash_map <ScDPItemData, ScDPResultMember *, MemberHashFunc> MemberHash; - + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + typedef std::vector <ScDPResultMember *> MemberArray; + typedef std::map < SCROW , ScDPResultMember *> MemberHash; + // End Comments private: - const ScDPResultData* pResultData; + const ScDPResultData* pResultData; MemberArray maMemberArray; MemberHash maMemberHash; BOOL bInitialized; @@ -466,31 +565,47 @@ private: long nAutoMeasure; long nAutoCount; - ScDPResultMember* FindMember( const ScDPItemData& rData ) const; + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + ScDPResultMember* FindMember( SCROW iData ) const; + ScDPResultMember* AddMember( const ScDPParentDimData& aData ); + ScDPResultMember* InsertMember( ScDPParentDimData* pMemberData ); + ResultMembers* GetResultMember( ScDPDimension* pDim, ScDPLevel* pLevel ); + void InitWithMembers( LateInitParams& rParams, + const ::std::vector< SCROW >& pItemData, + size_t nPos, + ScDPInitState& rInitState ); + // End Comments public: - ScDPResultDimension( const ScDPResultData* pData ); - ~ScDPResultDimension(); + ScDPResultDimension( const ScDPResultData* pData ); + ~ScDPResultDimension(); // allocates new members + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance void InitFrom( const ::std::vector<ScDPDimension*>& ppDim, - const ::std::vector<ScDPLevel*>& ppLev, - size_t nPos, - ScDPInitState& rInitState ); - void LateInitFrom( const ::std::vector<ScDPDimension*>& ppDim, - const ::std::vector<ScDPLevel*>& ppLev, - const ::std::vector<ScDPItemData>& pItemData, - size_t nPos, - ScDPInitState& rInitState ); - + const ::std::vector<ScDPLevel*>& ppLev, + size_t nPos, + ScDPInitState& rInitState , BOOL bInitChild = TRUE ); + void LateInitFrom( LateInitParams& rParams, + const ::std::vector< SCROW >& pItemData, + size_t nPos, + ScDPInitState& rInitState ); + void CheckShowEmpty( BOOL bShow = FALSE ); + + // End Comments long GetSize(long nMeasure) const; - bool IsValidEntry( const ::std::vector<ScDPItemData>& aMembers ) const; - // modifies existing members, allocates data dimensions - void ProcessData( const ::std::vector<ScDPItemData>& aMembers, + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + bool IsValidEntry( const ::std::vector<SCROW>& aMembers ) const; + + // modifies existing members, allocates data dimensions + void ProcessData( const ::std::vector<SCROW>& aMembers, const ScDPResultDimension* pDataDim, - const ::std::vector<ScDPItemData>& aDataMembers, + const ::std::vector<SCROW>& aDataMembers, const ::std::vector<ScDPValueData>& aValues ) const; //! Test - + // End Comments void FillMemberResults( com::sun::star::uno::Sequence< com::sun::star::sheet::MemberResult>* pSequences, long nStart, long nMeasure ); @@ -560,9 +675,11 @@ public: ~ScDPDataDimension(); void InitFrom( const ScDPResultDimension* pDim ); // recursive - void ProcessData( const ::std::vector<ScDPItemData>& aDataMembers, const ::std::vector<ScDPValueData>& aValues, - const ScDPSubTotalState& rSubState ); - + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + void ProcessData( const ::std::vector< SCROW >& aDataMembers, const ::std::vector<ScDPValueData>& aValues, + const ScDPSubTotalState& rSubState ); + // End Comments void FillDataRow( const ScDPResultDimension* pRefDim, com::sun::star::uno::Sequence<com::sun::star::sheet::DataResult>& rSequence, long nCol, long nMeasure, BOOL bIsSubTotalRow, @@ -596,7 +713,10 @@ public: class ScDPResultVisibilityData { public: - ScDPResultVisibilityData(ScSimpleSharedString& rSharedString, ScDPSource* pSource); + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + ScDPResultVisibilityData( ScDPSource* pSource); + // End Comments ~ScDPResultVisibilityData(); void addVisibleMember(const String& rDimName, const ScDPItemData& rMemberItem); @@ -611,7 +731,6 @@ private: typedef ::std::hash_map<String, VisibleMemberType, ScStringHashCode> DimMemberType; DimMemberType maDimensions; - ScSimpleSharedString& mrSharedString; ScDPSource* mpSource; }; diff --git a/sc/inc/dptabsrc.hxx b/sc/inc/dptabsrc.hxx index d2884281e1b8..18210f38e80e 100644 --- a/sc/inc/dptabsrc.hxx +++ b/sc/inc/dptabsrc.hxx @@ -30,6 +30,10 @@ #include <vector> #include <hash_map> +// Wang Xu Ming -- 2009-8-17 +// DataPilot Migration - Cache&&Performance +#include <list> +// End Comments #include <memory> #include <tools/string.hxx> #include <tools/list.hxx> @@ -57,7 +61,10 @@ #include <cppuhelper/implbase3.hxx> #include <cppuhelper/implbase5.hxx> #include <cppuhelper/implbase6.hxx> - +// Wang Xu Ming -- 2009-8-17 +// DataPilot Migration - Cache&&Performance +#include "dpglobal.hxx" +// End Comments #include "dptabdat.hxx" namespace com { namespace sun { namespace star { @@ -71,7 +78,10 @@ namespace com { namespace sun { namespace star { class ScDPResultMember; class ScDPResultData; -struct ScDPItemData; +// Wang Xu Ming -- 2009-8-17 +// DataPilot Migration - Cache&&Performance +class ScDPItemData; +// End Comments class ScDPTableData; // ------------------------------------------------------------------------ @@ -172,10 +182,18 @@ public: long GetDataDimensionCount(); ScDPDimension* GetDataDimension(long nIndex); String GetDataDimName(long nIndex); + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + ScDPTableDataCache* GetCache(); + const ScDPItemData* GetItemDataById( long nDim, long nId ); + long GetDataLayoutDim(){ return pData->GetColumnCount(); } + SCROW GetMemberId( long nDim, const ScDPItemData& rData ); + // End Comments BOOL IsDataLayoutDimension(long nDim); USHORT GetDataLayoutOrientation(); BOOL IsDateDimension(long nDim); + UINT32 GetNumberFormat(long nDim); BOOL SubTotalAllowed(long nColumn); //! move to ScDPResultData @@ -439,6 +457,10 @@ public: const ::com::sun::star::sheet::DataPilotFieldReference& GetReferenceValue() const; //UNUSED2009-05 BOOL IsValidPage( const ScDPItemData& rData ); +// Wang Xu Ming -- 2009-8-17 +// DataPilot Migration - Cache&&Performance + BOOL IsVisible( const ScDPItemData& rData ); +// End Comments }; class ScDPHierarchies : public cppu::WeakImplHelper2< @@ -732,6 +754,12 @@ public: long getMinMembers() const; sal_Int32 GetIndexFromName( const ::rtl::OUString& rName ) const; // <0 if not found + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + const std::vector<sal_Int32>& GetGlobalOrder(); + const ScDPItemData* GetSrcItemDataByIndex( SCROW nIndex); + SCROW GetSrcItemsCount(); + // End Comments }; class ScDPMember : public cppu::WeakImplHelper3< @@ -745,7 +773,11 @@ private: long nHier; long nLev; - ScDPItemData maData; + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + SCROW mnDataId; + // End Comments +// String aCaption; // visible name (changeable by user) ::std::auto_ptr<rtl::OUString> mpLayoutName; sal_Int32 nPosition; // manual sorting @@ -753,13 +785,24 @@ private: BOOL bShowDet; public: - ScDPMember( ScDPSource* pSrc, long nD, long nH, long nL, - const String& rN, double fV, BOOL bHV ); + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + ScDPMember( ScDPSource* pSrc, long nD, long nH, long nL, + SCROW nIndex /*const String& rN, double fV, BOOL bHV */); + // End Comments virtual ~ScDPMember(); BOOL IsNamedItem( const ScDPItemData& r ) const; String GetNameStr() const; void FillItemData( ScDPItemData& rData ) const; + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + // const ScDPItemData& GetItemData() const{ return maData; } + const ScDPItemData& GetItemData() const; + inline SCROW GetItemDataId() const { return mnDataId; } + BOOL IsNamedItem( SCROW nIndex ) const; + // End Comments + SC_DLLPUBLIC const ::rtl::OUString* GetLayoutName() const; sal_Int32 Compare( const ScDPMember& rOther ) const; // visible order diff --git a/sc/inc/filter.hxx b/sc/inc/filter.hxx index 8e3e540c9038..ae0fd92f6858 100644 --- a/sc/inc/filter.hxx +++ b/sc/inc/filter.hxx @@ -39,6 +39,7 @@ class SvStream; class ScAddress; class ScDocument; class ScRange; +class SvNumberFormatter; // Return-Werte Im-/Exportfilter (ULONG) @@ -89,7 +90,9 @@ class ScEEAbsImport { virtual ~ScEEAbsImport() {} virtual ULONG Read( SvStream& rStream, const String& rBaseURL ) = 0; virtual ScRange GetRange() = 0; - virtual void WriteToDocument( BOOL bSizeColsRows = FALSE, double nOutputFactor = 1.0 ) = 0; + virtual void WriteToDocument( + BOOL bSizeColsRows = FALSE, double nOutputFactor = 1.0, + SvNumberFormatter* pFormatter = NULL, bool bConvertDate = true ) = 0; }; class ScFormatFilterPlugin { @@ -106,7 +109,8 @@ class ScFormatFilterPlugin { virtual FltError ScImportDif( SvStream&, ScDocument*, const ScAddress& rInsPos, const CharSet eSrc = RTL_TEXTENCODING_DONTKNOW, UINT32 nDifOption = SC_DIFOPT_EXCEL ) = 0; virtual FltError ScImportRTF( SvStream&, const String& rBaseURL, ScDocument*, ScRange& rRange ) = 0; - virtual FltError ScImportHTML( SvStream&, const String& rBaseURL, ScDocument*, ScRange& rRange, double nOutputFactor = 1.0, BOOL bCalcWidthHeight = TRUE ) = 0; + virtual FltError ScImportHTML( SvStream&, const String& rBaseURL, ScDocument*, ScRange& rRange, double nOutputFactor = 1.0, + BOOL bCalcWidthHeight = TRUE, SvNumberFormatter* pFormatter = NULL, bool bConvertDate = true ) = 0; // various import helpers virtual ScEEAbsImport *CreateRTFImport( ScDocument* pDoc, const ScRange& rRange ) = 0; diff --git a/sc/inc/global.hxx b/sc/inc/global.hxx index 8bcbd50b0f3c..185113e77389 100644 --- a/sc/inc/global.hxx +++ b/sc/inc/global.hxx @@ -758,21 +758,6 @@ enum ScSubTotalFunc }; -#define PIVOT_MAXFUNC 11 -#define PIVOT_FUNC_NONE 0x0000 -#define PIVOT_FUNC_SUM 0x0001 -#define PIVOT_FUNC_COUNT 0x0002 -#define PIVOT_FUNC_AVERAGE 0x0004 -#define PIVOT_FUNC_MAX 0x0008 -#define PIVOT_FUNC_MIN 0x0010 -#define PIVOT_FUNC_PRODUCT 0x0020 -#define PIVOT_FUNC_COUNT_NUM 0x0040 -#define PIVOT_FUNC_STD_DEV 0x0080 -#define PIVOT_FUNC_STD_DEVP 0x0100 -#define PIVOT_FUNC_STD_VAR 0x0200 -#define PIVOT_FUNC_STD_VARP 0x0400 -#define PIVOT_FUNC_AUTO 0x1000 - // ----------------------------------------------------------------------- /* @@ -876,46 +861,6 @@ struct ScConsolidateParam }; // ----------------------------------------------------------------------- - -class ScSimpleSharedString -{ -public: - static const sal_Int32 EMPTY = 0; - - ScSimpleSharedString(); - ScSimpleSharedString(const ScSimpleSharedString& r); - ~ScSimpleSharedString(); - - const String* getString(sal_Int32 nId); - sal_Int32 getStringId(const String& aStr); - sal_Int32 insertString(const String& aStr); - -private: - - /** internal shared string table implementation */ - class StringTable - { - public: - sal_Int32 insertString(const String& aStr); - sal_Int32 getStringId(const String& aStr); - const String* getString(sal_Int32 nId) const; - - StringTable(); - StringTable(const StringTable& r); - ~StringTable(); - - private: - typedef ::std::hash_map< String, sal_Int32, ScStringHashCode, ::std::equal_to< String > > SharedStrMap; - - ::std::vector<String> maSharedStrings; - SharedStrMap maSharedStringIds; - sal_Int32 mnStrCount; - }; - - StringTable maStringTable; -}; - -// ----------------------------------------------------------------------- extern ::utl::TransliterationWrapper* GetScGlobalpTransliteration();//CHINA001 extern const LocaleDataWrapper* GetScGlobalpLocaleData(); diff --git a/sc/inc/globstr.hrc b/sc/inc/globstr.hrc index c635877e2ea2..bca93e7aa441 100644 --- a/sc/inc/globstr.hrc +++ b/sc/inc/globstr.hrc @@ -570,7 +570,10 @@ #define STR_STYLE_FAMILY_CELL 433 #define STR_STYLE_FAMILY_PAGE 434 -#define STR_COUNT 435 +#define STR_ERR_DATAPILOTSOURCE 435 +#define STR_PIVOT_FIRSTROWEMPTYERR 436 +#define STR_PIVOT_ONLYONEROWERR 437 +#define STR_COUNT 438 #endif diff --git a/sc/inc/optutil.hxx b/sc/inc/optutil.hxx index c197076ee642..83b23a3c9ef9 100644 --- a/sc/inc/optutil.hxx +++ b/sc/inc/optutil.hxx @@ -30,6 +30,7 @@ #include <unotools/configitem.hxx> #include <tools/link.hxx> +#include "scdllapi.h" class ScOptionsUtil @@ -41,13 +42,13 @@ public: // ConfigItem for classes that use items from several sub trees -class ScLinkConfigItem : public utl::ConfigItem +class SC_DLLPUBLIC ScLinkConfigItem : public utl::ConfigItem { Link aCommitLink; public: - ScLinkConfigItem( const rtl::OUString rSubTree ); - ScLinkConfigItem( const rtl::OUString rSubTree, sal_Int16 nMode ); + ScLinkConfigItem( const rtl::OUString& rSubTree ); + ScLinkConfigItem( const rtl::OUString& rSubTree, sal_Int16 nMode ); void SetCommitLink( const Link& rLink ); virtual void Notify( const com::sun::star::uno::Sequence<rtl::OUString>& aPropertyNames ); diff --git a/sc/inc/pivot.hxx b/sc/inc/pivot.hxx index 2a1f17846afd..915a311411c4 100644 --- a/sc/inc/pivot.hxx +++ b/sc/inc/pivot.hxx @@ -48,6 +48,7 @@ #include "global.hxx" #include "address.hxx" +#include "dpglobal.hxx" #include <vector> #include <boost/shared_ptr.hpp> diff --git a/sc/inc/rangelst.hxx b/sc/inc/rangelst.hxx index 2350cea085f0..51555decaa5b 100644 --- a/sc/inc/rangelst.hxx +++ b/sc/inc/rangelst.hxx @@ -55,10 +55,10 @@ public: USHORT Parse( const String&, ScDocument* = NULL, USHORT nMask = SCA_VALID, formula::FormulaGrammar::AddressConvention eConv = formula::FormulaGrammar::CONV_OOO, - char cDelimiter = 0 ); + sal_Unicode cDelimiter = 0 ); void Format( String&, USHORT nFlags = 0, ScDocument* = NULL, formula::FormulaGrammar::AddressConvention eConv = formula::FormulaGrammar::CONV_OOO, - char cDelimiter = 0 ) const; + sal_Unicode cDelimiter = 0 ) const; void Join( const ScRange&, BOOL bIsInList = FALSE ); BOOL UpdateReference( UpdateRefMode, ScDocument*, const ScRange& rWhere, diff --git a/sc/inc/sc.hrc b/sc/inc/sc.hrc index d9bce97f1bc8..1b6d18e21dbb 100644 --- a/sc/inc/sc.hrc +++ b/sc/inc/sc.hrc @@ -1631,9 +1631,10 @@ #define RID_SCDLG_DOCPROTECTION (SC_DIALOGS_START + 149) #define RID_SCDLG_RETYPEPASS (SC_DIALOGS_START + 150) #define RID_SCDLG_RETYPEPASS_INPUT (SC_DIALOGS_START + 151) -#define RID_POPUP_FILTER (SC_DIALOGS_START + 152) +#define RID_SCDLG_TEXT_IMPORT_OPTIONS (SC_DIALOGS_START + 152) +#define RID_POPUP_FILTER (SC_DIALOGS_START + 153) -#define SC_DIALOGS_END (SC_DIALOGS_START + 153) +#define SC_DIALOGS_END (SC_DIALOGS_START + 154) #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 f33077b3e090..d3c19bb539d5 100644 --- a/sc/inc/scabstdlg.hxx +++ b/sc/inc/scabstdlg.hxx @@ -38,6 +38,7 @@ #include "sc.hrc" #include "global.hxx" #include "pivot.hxx" +#include "i18npool/lang.h" class ScAsciiOptions; class ScAutoFormat; @@ -65,6 +66,7 @@ class AbstractScImportAsciiDlg : public VclAbstractDialog //add for ScImportAsc public: virtual void GetOptions( ScAsciiOptions& rOpt ) = 0; virtual void SetTextToColumnsMode() = 0; + virtual void SaveParameters() = 0; }; @@ -289,6 +291,14 @@ class AbstractScImportOptionsDlg : public VclAbstractDialog //add for ScImportO public: virtual void GetImportOptions( ScImportOptions& rOptions ) const = 0; }; + +class AbstractScTextImportOptionsDlg : public VclAbstractDialog //add for ScLangChooserDlg +{ +public: + virtual LanguageType GetLanguageType() const = 0; + virtual bool IsDateConversionSet() const = 0; +}; + //-------Scabstract fractory --------------------------- class ScAbstractDialogFactory { @@ -299,6 +309,8 @@ public: SvStream* pInStream, int nId, sal_Unicode cSep = '\t') = 0; + virtual AbstractScTextImportOptionsDlg * CreateScTextImportOptionsDlg( Window* pParent, int nId ) = 0; + virtual AbstractScAutoFormatDlg * CreateScAutoFormatDlg( Window* pParent, //add for ScAutoFormatDlg ScAutoFormat* pAutoFormat, const ScAutoFormatData* pSelFormatData, diff --git a/sc/inc/scmatrix.hxx b/sc/inc/scmatrix.hxx index 494ab86b0c74..9857d675b7ab 100644 --- a/sc/inc/scmatrix.hxx +++ b/sc/inc/scmatrix.hxx @@ -103,6 +103,7 @@ class SC_DLLPUBLIC ScMatrix void ResetIsString(); void DeleteIsString(); void CreateMatrix( SCSIZE nC, SCSIZE nR); + void Clear(); // pStr may be NULL, bFlag MUST NOT be 0 void PutStringEntry( const String* pStr, BYTE bFlag, SCSIZE nIndex ); @@ -175,6 +176,12 @@ public: /** Clone the matrix. */ ScMatrix* Clone() const; + /** + * Resize the matrix to specified new dimension. Note that this operation + * clears all stored values. + */ + void Resize( SCSIZE nC, SCSIZE nR); + /** Clone the matrix and extend it to the new size. nNewCols and nNewRows MUST be at least of the size of the original matrix. */ ScMatrix* CloneAndExtend( SCSIZE nNewCols, SCSIZE nNewRows ) const; diff --git a/sc/inc/stringutil.hxx b/sc/inc/stringutil.hxx new file mode 100644 index 000000000000..c50c0d8cf156 --- /dev/null +++ b/sc/inc/stringutil.hxx @@ -0,0 +1,56 @@ +/************************************************************************* + * + * 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: table.hxx,v $ + * $Revision: 1.35 $ + * + * 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_STRINGUTIL_HXX +#define SC_STRINGUTIL_HXX + +#include "rtl/ustring.hxx" + +class ScStringUtil +{ +public: + /** + * Check if a given string is a simple decimal number (e.g. 12.345). We + * don't do any elaborate parsing here; we only check for the simplest + * case of decimal number format. + * + * @param rStr string to parse + * @param dsep decimal separator + * @param gsep group separator (aka thousands separator) + * @param rVal value of successfully parsed number + * + * @return true if the string is a valid number, false otherwise. + */ + static bool parseSimpleNumber( + const ::rtl::OUString& rStr, sal_Unicode dsep, sal_Unicode gsep, double& rVal); +}; + + +#endif diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx index 55d31d30430e..0311c5093c4c 100644 --- a/sc/inc/table.hxx +++ b/sc/inc/table.hxx @@ -265,7 +265,8 @@ public: void PutCell( SCCOL nCol, SCROW nRow, ScBaseCell* pCell ); void PutCell(SCCOL nCol, SCROW nRow, ULONG nFormatIndex, ScBaseCell* pCell); // TRUE = Zahlformat gesetzt - BOOL SetString( SCCOL nCol, SCROW nRow, SCTAB nTab, const String& rString ); + BOOL SetString( SCCOL nCol, SCROW nRow, SCTAB nTab, const String& rString, + SvNumberFormatter* pFormatter = NULL, bool bDetectNumberFormat = true ); void SetValue( SCCOL nCol, SCROW nRow, const double& rVal ); void SetError( SCCOL nCol, SCROW nRow, USHORT nError); @@ -468,7 +469,7 @@ public: const SvxBorderLine** ppRight, const SvxBorderLine** ppBottom ) const; //UNUSED2009-05 BOOL HasLines( const ScRange& rRange, Rectangle& rSizes ) const; - BOOL HasAttrib( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, USHORT nMask ) const; + bool HasAttrib( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, USHORT nMask ) const; BOOL HasAttribSelection( const ScMarkData& rMark, USHORT nMask ) const; BOOL ExtendMerge( SCCOL nStartCol, SCROW nStartRow, SCCOL& rEndCol, SCROW& rEndRow, diff --git a/sc/source/core/data/attarray.cxx b/sc/source/core/data/attarray.cxx index 67be752fd8c8..53df13b4cd62 100644 --- a/sc/source/core/data/attarray.cxx +++ b/sc/source/core/data/attarray.cxx @@ -1228,13 +1228,13 @@ BOOL ScAttrArray::HasLines( SCROW nRow1, SCROW nRow2, Rectangle& rSizes, // Testen, ob Bereich bestimmtes Attribut enthaelt -BOOL ScAttrArray::HasAttrib( SCROW nRow1, SCROW nRow2, USHORT nMask ) const +bool ScAttrArray::HasAttrib( SCROW nRow1, SCROW nRow2, USHORT nMask ) const { SCSIZE nStartIndex; SCSIZE nEndIndex; Search( nRow1, nStartIndex ); Search( nRow2, nEndIndex ); - BOOL bFound = FALSE; + bool bFound = false; for (SCSIZE i=nStartIndex; i<=nEndIndex && !bFound; i++) { @@ -1244,46 +1244,46 @@ BOOL ScAttrArray::HasAttrib( SCROW nRow1, SCROW nRow2, USHORT nMask ) const const ScMergeAttr* pMerge = (const ScMergeAttr*) &pPattern->GetItem( ATTR_MERGE ); if ( pMerge->GetColMerge() > 1 || pMerge->GetRowMerge() > 1 ) - bFound = TRUE; + bFound = true; } if ( nMask & ( HASATTR_OVERLAPPED | HASATTR_NOTOVERLAPPED | HASATTR_AUTOFILTER ) ) { const ScMergeFlagAttr* pMergeFlag = (const ScMergeFlagAttr*) &pPattern->GetItem( ATTR_MERGE_FLAG ); if ( (nMask & HASATTR_OVERLAPPED) && pMergeFlag->IsOverlapped() ) - bFound = TRUE; + bFound = true; if ( (nMask & HASATTR_NOTOVERLAPPED) && !pMergeFlag->IsOverlapped() ) - bFound = TRUE; + bFound = true; if ( (nMask & HASATTR_AUTOFILTER) && pMergeFlag->HasAutoFilter() ) - bFound = TRUE; + bFound = true; } if ( nMask & HASATTR_LINES ) { const SvxBoxItem* pBox = (const SvxBoxItem*) &pPattern->GetItem( ATTR_BORDER ); if ( pBox->GetLeft() || pBox->GetRight() || pBox->GetTop() || pBox->GetBottom() ) - bFound = TRUE; + bFound = true; } if ( nMask & HASATTR_SHADOW ) { const SvxShadowItem* pShadow = (const SvxShadowItem*) &pPattern->GetItem( ATTR_SHADOW ); if ( pShadow->GetLocation() != SVX_SHADOW_NONE ) - bFound = TRUE; + bFound = true; } if ( nMask & HASATTR_CONDITIONAL ) { const SfxUInt32Item* pConditional = (const SfxUInt32Item*) &pPattern->GetItem( ATTR_CONDITIONAL ); if ( pConditional->GetValue() != 0 ) - bFound = TRUE; + bFound = true; } if ( nMask & HASATTR_PROTECTED ) { const ScProtectionAttr* pProtect = (const ScProtectionAttr*) &pPattern->GetItem( ATTR_PROTECTION ); if ( pProtect->GetProtection() || pProtect->GetHideCell() ) - bFound = TRUE; + bFound = true; } if ( nMask & HASATTR_ROTATE ) { @@ -1293,21 +1293,21 @@ BOOL ScAttrArray::HasAttrib( SCROW nRow1, SCROW nRow2, USHORT nMask ) const // (see ScPatternAttr::GetCellOrientation) INT32 nAngle = pRotate->GetValue(); if ( nAngle != 0 && nAngle != 9000 && nAngle != 27000 ) - bFound = TRUE; + bFound = true; } if ( nMask & HASATTR_NEEDHEIGHT ) { if (pPattern->GetCellOrientation() != SVX_ORIENTATION_STANDARD) - bFound = TRUE; + bFound = true; else if (((const SfxBoolItem&)pPattern->GetItem( ATTR_LINEBREAK )).GetValue()) - bFound = TRUE; + bFound = true; else if ((SvxCellHorJustify)((const SvxHorJustifyItem&)pPattern-> GetItem( ATTR_HOR_JUSTIFY )).GetValue() == SVX_HOR_JUSTIFY_BLOCK) - bFound = TRUE; + bFound = true; else if (((const SfxUInt32Item&)pPattern->GetItem( ATTR_CONDITIONAL )).GetValue()) - bFound = TRUE; + bFound = true; else if (((const SfxInt32Item&)pPattern->GetItem( ATTR_ROTATE_VALUE )).GetValue()) - bFound = TRUE; + bFound = true; } if ( nMask & ( HASATTR_SHADOW_RIGHT | HASATTR_SHADOW_DOWN ) ) { @@ -1316,17 +1316,17 @@ BOOL ScAttrArray::HasAttrib( SCROW nRow1, SCROW nRow2, USHORT nMask ) const SvxShadowLocation eLoc = pShadow->GetLocation(); if ( nMask & HASATTR_SHADOW_RIGHT ) if ( eLoc == SVX_SHADOW_TOPRIGHT || eLoc == SVX_SHADOW_BOTTOMRIGHT ) - bFound = TRUE; + bFound = true; if ( nMask & HASATTR_SHADOW_DOWN ) if ( eLoc == SVX_SHADOW_BOTTOMLEFT || eLoc == SVX_SHADOW_BOTTOMRIGHT ) - bFound = TRUE; + bFound = true; } if ( nMask & HASATTR_RTL ) { const SvxFrameDirectionItem& rDirection = (const SvxFrameDirectionItem&) pPattern->GetItem( ATTR_WRITINGDIR ); if ( rDirection.GetValue() == FRMDIR_HORI_RIGHT_TOP ) - bFound = TRUE; + bFound = true; } if ( nMask & HASATTR_RIGHTORCENTER ) { @@ -1334,7 +1334,7 @@ BOOL ScAttrArray::HasAttrib( SCROW nRow1, SCROW nRow2, USHORT nMask ) const SvxCellHorJustify eHorJust = (SvxCellHorJustify) ((const SvxHorJustifyItem&) pPattern->GetItem( ATTR_HOR_JUSTIFY )).GetValue(); if ( eHorJust == SVX_HOR_JUSTIFY_RIGHT || eHorJust == SVX_HOR_JUSTIFY_CENTER ) - bFound = TRUE; + bFound = true; } } diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx index 49ae4a98b1c6..ee670d5ba0ef 100644 --- a/sc/source/core/data/column.cxx +++ b/sc/source/core/data/column.cxx @@ -244,7 +244,7 @@ BOOL ScColumn::HasSelectionMatrixFragment(const ScMarkData& rMark) const //UNUSED2009-05 } -BOOL ScColumn::HasAttrib( SCROW nRow1, SCROW nRow2, USHORT nMask ) const +bool ScColumn::HasAttrib( SCROW nRow1, SCROW nRow2, USHORT nMask ) const { return pAttrArray->HasAttrib( nRow1, nRow2, nMask ); } diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx index 30081a6bf402..dc206950b3ea 100644 --- a/sc/source/core/data/column3.cxx +++ b/sc/source/core/data/column3.cxx @@ -51,6 +51,13 @@ #include "markdata.hxx" #include "detfunc.hxx" // fuer Notizen bei DeleteRange #include "postit.hxx" +#include "stringutil.hxx" + +#include <com/sun/star/i18n/LocaleDataItem.hpp> + +using ::com::sun::star::i18n::LocaleDataItem; +using ::rtl::OUString; +using ::rtl::OUStringBuffer; // Err527 Workaround extern const ScFormulaCell* pLastFormulaTreeTop; // in cellform.cxx @@ -1241,7 +1248,8 @@ void ScColumn::StartListeningInArea( SCROW nRow1, SCROW nRow2 ) // TRUE = Zahlformat gesetzt BOOL ScColumn::SetString( SCROW nRow, SCTAB nTabP, const String& rString, - formula::FormulaGrammar::AddressConvention eConv ) + formula::FormulaGrammar::AddressConvention eConv, + SvNumberFormatter* pFormatter, bool bDetectNumberFormat ) { BOOL bNumFmtSet = FALSE; if (VALIDROW(nRow)) @@ -1253,7 +1261,8 @@ BOOL ScColumn::SetString( SCROW nRow, SCTAB nTabP, const String& rString, double nVal; sal_uInt32 nIndex, nOldIndex = 0; sal_Unicode cFirstChar; - SvNumberFormatter* pFormatter = pDocument->GetFormatTable(); + if (!pFormatter) + pFormatter = pDocument->GetFormatTable(); SfxObjectShell* pDocSh = pDocument->GetDocumentShell(); if ( pDocSh ) bIsLoading = pDocSh->IsLoading(); @@ -1320,46 +1329,78 @@ BOOL ScColumn::SetString( SCROW nRow, SCTAB nTabP, const String& rString, if ( !bIsText ) nIndex = nOldIndex = pFormatter->GetStandardIndex(); } - if ( !bIsText && - pFormatter->IsNumberFormat(rString, nIndex, nVal) ) - { // Zahl - pNewCell = new ScValueCell( nVal ); - if ( nIndex != nOldIndex) + + do + { + if (bIsText) + break; + + if (bDetectNumberFormat) { - // #i22345# New behavior: Apply the detected number format only if - // the old one was the default number, date, time or boolean format. - // Exception: If the new format is boolean, always apply it. + if (!pFormatter->IsNumberFormat(rString, nIndex, nVal)) + break; - BOOL bOverwrite = FALSE; - const SvNumberformat* pOldFormat = pFormatter->GetEntry( nOldIndex ); - if ( pOldFormat ) + pNewCell = new ScValueCell( nVal ); + if ( nIndex != nOldIndex) { - short nOldType = pOldFormat->GetType() & ~NUMBERFORMAT_DEFINED; - if ( nOldType == NUMBERFORMAT_NUMBER || nOldType == NUMBERFORMAT_DATE || - nOldType == NUMBERFORMAT_TIME || nOldType == NUMBERFORMAT_LOGICAL ) + // #i22345# New behavior: Apply the detected number format only if + // the old one was the default number, date, time or boolean format. + // Exception: If the new format is boolean, always apply it. + + BOOL bOverwrite = FALSE; + const SvNumberformat* pOldFormat = pFormatter->GetEntry( nOldIndex ); + if ( pOldFormat ) { - if ( nOldIndex == pFormatter->GetStandardFormat( - nOldType, pOldFormat->GetLanguage() ) ) + short nOldType = pOldFormat->GetType() & ~NUMBERFORMAT_DEFINED; + if ( nOldType == NUMBERFORMAT_NUMBER || nOldType == NUMBERFORMAT_DATE || + nOldType == NUMBERFORMAT_TIME || nOldType == NUMBERFORMAT_LOGICAL ) { - bOverwrite = TRUE; // default of these types can be overwritten + if ( nOldIndex == pFormatter->GetStandardFormat( + nOldType, pOldFormat->GetLanguage() ) ) + { + bOverwrite = TRUE; // default of these types can be overwritten + } } } - } - if ( !bOverwrite && pFormatter->GetType( nIndex ) == NUMBERFORMAT_LOGICAL ) - { - bOverwrite = TRUE; // overwrite anything if boolean was detected - } + if ( !bOverwrite && pFormatter->GetType( nIndex ) == NUMBERFORMAT_LOGICAL ) + { + bOverwrite = TRUE; // overwrite anything if boolean was detected + } - if ( bOverwrite ) - { - ApplyAttr( nRow, SfxUInt32Item( ATTR_VALUE_FORMAT, - (UINT32) nIndex) ); - bNumFmtSet = TRUE; + if ( bOverwrite ) + { + ApplyAttr( nRow, SfxUInt32Item( ATTR_VALUE_FORMAT, + (UINT32) nIndex) ); + bNumFmtSet = TRUE; + } } } + else + { + // Only check if the string is a regular number. + const LocaleDataWrapper* pLocale = pFormatter->GetLocaleData(); + if (!pLocale) + break; + + LocaleDataItem aLocaleItem = pLocale->getLocaleItem(); + const OUString& rDecSep = aLocaleItem.decimalSeparator; + const OUString& rGroupSep = aLocaleItem.thousandSeparator; + if (rDecSep.getLength() != 1 || rGroupSep.getLength() != 1) + break; + + sal_Unicode dsep = rDecSep.getStr()[0]; + sal_Unicode gsep = rGroupSep.getStr()[0]; + + if (!ScStringUtil::parseSimpleNumber(rString, dsep, gsep, nVal)) + break; + + pNewCell = new ScValueCell(nVal); + } } - else // Text - pNewCell = new ScStringCell( rString ); + while (false); + + if (!pNewCell) + pNewCell = new ScStringCell(rString); } } diff --git a/sc/source/core/data/dociter.cxx b/sc/source/core/data/dociter.cxx index b68ad36364f3..706783579a24 100755..100644 --- a/sc/source/core/data/dociter.cxx +++ b/sc/source/core/data/dociter.cxx @@ -591,7 +591,11 @@ bool ScDBQueryDataIterator::DataAccessInternal::getCurrent(Value& rValue) if (ScDBQueryDataIterator::IsQueryValid(*mpDoc, *mpParam, nTab, nRow, pCell)) { - switch (pCell->GetCellType()) + // #i109812# get cell here if it wasn't done above + if (nCol != static_cast<SCCOL>(nFirstQueryField)) + pCell = ScDBQueryDataIterator::GetCellByColEntryIndex(*mpDoc, nTab, nCol, nColRow); + + switch (pCell ? pCell->GetCellType() : CELLTYPE_NONE) { case CELLTYPE_VALUE: { diff --git a/sc/source/core/data/documen3.cxx b/sc/source/core/data/documen3.cxx index cc06d7ac6b32..1bd5b101f691 100644 --- a/sc/source/core/data/documen3.cxx +++ b/sc/source/core/data/documen3.cxx @@ -75,6 +75,11 @@ #include "drwlayer.hxx" #include "unoreflist.hxx" #include "listenercalls.hxx" +// Wang Xu Ming -- 2009-8-17 +// DataPilot Migration - Cache&&Performance +#include "dpshttab.hxx" +#include "dptablecache.hxx" +// End Comments #include "tabprotection.hxx" #include "formulaparserpool.hxx" #include "clipparam.hxx" @@ -1901,6 +1906,119 @@ void ScDocument::DecSizeRecalcLevel( SCTAB nTab ) pTab[nTab]->DecRecalcLevel(); } +// Wang Xu Ming -- 2009-8-17 +// DataPilot Migration - Cache&&Performance +ScDPTableDataCache* ScDocument::GetDPObjectCache( long nID ) +{ + for ( std::list<ScDPTableDataCache*>::iterator iter = m_listDPObjectsCaches.begin(); iter!=m_listDPObjectsCaches.end(); iter++ ) + { // + if ( nID == (*iter)->GetId() ) + return *iter; + } + return NULL; +} + +ScDPTableDataCache* ScDocument::GetUsedDPObjectCache ( ScRange rRange ) +{ + ScDPTableDataCache* pCache = NULL; + USHORT nCount = GetDPCollection()->GetCount(); + for ( short i=nCount-1; i>=0 ; i--) + { + if ( const ScSheetSourceDesc* pUsedSheetDesc = (*pDPCollection)[i]->GetSheetDesc() ) + if ( rRange == pUsedSheetDesc->aSourceRange ) + { + long nID = (*pDPCollection)[i]->GetCacheId(); + if ( nID >= 0 ) + pCache= GetDPObjectCache( nID ); + if ( pCache ) + return pCache; + } + } + return pCache; +} +long ScDocument::AddDPObjectCache( ScDPTableDataCache* pData ) +{ + if ( pData->GetId() < 0 ) + { //create a id for it + pData->SetId( GetNewDPObjectCacheId() ); + } + m_listDPObjectsCaches.push_back( pData ); + return pData->GetId(); +} +long ScDocument::GetNewDPObjectCacheId() +{ + long nID = 0; + bool bFound = false; + std::list<ScDPTableDataCache*>::iterator iter; + do { + for ( iter = m_listDPObjectsCaches.begin(); iter!=m_listDPObjectsCaches.end(); iter++ ) + { //Get a new Id + if ( nID == (*iter)->GetId() ) + { + nID++; + bFound = true; + break; + } + } + if ( iter == m_listDPObjectsCaches.end() ) + bFound = false; + } while ( bFound ); + + return nID; +} + +void ScDocument::RemoveDPObjectCache( long nID ) +{ + for ( std::list<ScDPTableDataCache*>::iterator iter = m_listDPObjectsCaches.begin(); iter!=m_listDPObjectsCaches.end(); iter++ ) + { + if ( nID == (*iter)->GetId() ) + { + ScDPTableDataCache* pCache = *iter; + m_listDPObjectsCaches.erase( iter ); + delete pCache; + break; + } + } + +} + +void ScDocument::RemoveUnusedDPObjectCaches() +{ + for ( std::list<ScDPTableDataCache*>::iterator iter = m_listDPObjectsCaches.begin(); iter!=m_listDPObjectsCaches.end(); iter++ ) + { + long nID = (*iter)->GetId(); + USHORT nCount = GetDPCollection()->GetCount(); + USHORT i ; + for ( i=0; i<nCount; i++) + { + if ( nID == (*pDPCollection)[i]->GetCacheId() ) + break; + } + if ( i == nCount ) + { + ScDPTableDataCache* pCache = *iter; + m_listDPObjectsCaches.erase( iter ); + delete pCache; + continue; + } + } +} + +void ScDocument::GetUsedDPObjectCache( std::list<ScDPTableDataCache*>& usedlist ) +{ + for ( std::list<ScDPTableDataCache*>::iterator iter = m_listDPObjectsCaches.begin(); iter!=m_listDPObjectsCaches.end(); iter++ ) + { + long nID = (*iter)->GetId(); + USHORT nCount = GetDPCollection()->GetCount(); + USHORT i=0; + for ( i=0; i<nCount; i++) + if ( nID == (*pDPCollection)[i]->GetCacheId() ) + break; + if ( i != nCount ) + usedlist.push_back( *iter ); + } +} +// End Comments diff --git a/sc/source/core/data/documen5.cxx b/sc/source/core/data/documen5.cxx index 14a88abd32ca..d6653402c46a 100644 --- a/sc/source/core/data/documen5.cxx +++ b/sc/source/core/data/documen5.cxx @@ -64,107 +64,12 @@ #include "miscuno.hxx" #include "chart2uno.hxx" +#include "charthelper.hxx" using namespace ::com::sun::star; // ----------------------------------------------------------------------- -void lcl_GetChartRanges( const uno::Reference< chart2::XChartDocument >& xChartDoc, - uno::Sequence< rtl::OUString >& rRanges ) -{ - rRanges.realloc(0); - uno::Reference< chart2::data::XDataSource > xDataSource( xChartDoc, uno::UNO_QUERY ); - if( !xDataSource.is() ) - return; - //uno::Reference< chart2::data::XDataProvider > xProvider = xChartDoc->getDataProvider(); - - uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence > > aLabeledDataSequences( xDataSource->getDataSequences() ); - rRanges.realloc(2*aLabeledDataSequences.getLength()); - sal_Int32 nRealCount=0; - for( sal_Int32 nN=0;nN<aLabeledDataSequences.getLength();nN++) - { - uno::Reference< chart2::data::XLabeledDataSequence > xLabeledSequence( aLabeledDataSequences[nN] ); - if(!xLabeledSequence.is()) - continue; - uno::Reference< chart2::data::XDataSequence > xLabel( xLabeledSequence->getLabel()); - uno::Reference< chart2::data::XDataSequence > xValues( xLabeledSequence->getValues()); - - if( xLabel.is()) - rRanges[nRealCount++] = xLabel->getSourceRangeRepresentation(); - if( xValues.is()) - rRanges[nRealCount++] = xValues->getSourceRangeRepresentation(); - } - rRanges.realloc(nRealCount); -} - -void lcl_SetChartRanges( const uno::Reference< chart2::XChartDocument >& xChartDoc, - const uno::Sequence< rtl::OUString >& rRanges ) -{ - uno::Reference< chart2::data::XDataSource > xDataSource( xChartDoc, uno::UNO_QUERY ); - if( !xDataSource.is() ) - return; - uno::Reference< chart2::data::XDataProvider > xDataProvider = xChartDoc->getDataProvider(); - if( !xDataProvider.is() ) - return; - - uno::Reference< frame::XModel > xModel( xChartDoc, uno::UNO_QUERY ); - if( xModel.is() ) - xModel->lockControllers(); - - try - { - rtl::OUString aPropertyNameRole( ::rtl::OUString::createFromAscii("Role") ); - - uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence > > aLabeledDataSequences( xDataSource->getDataSequences() ); - sal_Int32 nRange=0; - for( sal_Int32 nN=0; (nN<aLabeledDataSequences.getLength()) && (nRange<rRanges.getLength()); nN++ ) - { - uno::Reference< chart2::data::XLabeledDataSequence > xLabeledSequence( aLabeledDataSequences[nN] ); - if(!xLabeledSequence.is()) - continue; - uno::Reference< beans::XPropertySet > xLabel( xLabeledSequence->getLabel(), uno::UNO_QUERY ); - uno::Reference< beans::XPropertySet > xValues( xLabeledSequence->getValues(), uno::UNO_QUERY ); - - if( xLabel.is()) - { - // the range string must be in Calc A1 format. - uno::Reference< chart2::data::XDataSequence > xNewSeq( - xDataProvider->createDataSequenceByRangeRepresentation( rRanges[nRange++] )); - - uno::Reference< beans::XPropertySet > xNewProps( xNewSeq, uno::UNO_QUERY ); - if( xNewProps.is() ) - xNewProps->setPropertyValue( aPropertyNameRole, xLabel->getPropertyValue( aPropertyNameRole ) ); - - xLabeledSequence->setLabel( xNewSeq ); - } - - if( !(nRange<rRanges.getLength()) ) - break; - - if( xValues.is()) - { - // the range string must be in Calc A1 format. - uno::Reference< chart2::data::XDataSequence > xNewSeq( - xDataProvider->createDataSequenceByRangeRepresentation( rRanges[nRange++] )); - - uno::Reference< beans::XPropertySet > xNewProps( xNewSeq, uno::UNO_QUERY ); - if( xNewProps.is() ) - xNewProps->setPropertyValue( aPropertyNameRole, xValues->getPropertyValue( aPropertyNameRole ) ); - - xLabeledSequence->setValues( xNewSeq ); - } - } - } - catch ( uno::Exception& ex ) - { - (void)ex; - DBG_ERROR("Exception in lcl_SetChartRanges - invalid range string?"); - } - - if( xModel.is() ) - xModel->unlockControllers(); -} - void lcl_GetChartParameters( const uno::Reference< chart2::XChartDocument >& xChartDoc, rtl::OUString& rRanges, chart::ChartDataRowSource& rDataRowSource, bool& rHasCategories, bool& rFirstCellAsLabel ) @@ -363,14 +268,7 @@ uno::Reference< chart2::XChartDocument > ScDocument::GetChartByName( const Strin if ( pObject->GetObjIdentifier() == OBJ_OLE2 && ((SdrOle2Obj*)pObject)->GetPersistName() == rChartName ) { - uno::Reference< embed::XEmbeddedObject > xIPObj = ((SdrOle2Obj*)pObject)->GetObjRef(); - if ( xIPObj.is() ) - { - svt::EmbeddedObjectRef::TryRunningState( xIPObj ); - - uno::Reference< util::XCloseable > xComponent = xIPObj->getComponent(); - xReturn.set( uno::Reference< chart2::XChartDocument >( xComponent, uno::UNO_QUERY ) ); - } + xReturn.set( ScChartHelper::GetChartFromSdrObject( pObject ) ); return xReturn; } pObject = aIter.Next(); @@ -386,7 +284,7 @@ void ScDocument::GetChartRanges( const String& rChartName, ::std::vector< ScRang if ( xChartDoc.is() ) { uno::Sequence< rtl::OUString > aRangeStrings; - lcl_GetChartRanges( xChartDoc, aRangeStrings ); + ScChartHelper::GetChartRanges( xChartDoc, aRangeStrings ); for( sal_Int32 nN=0; nN<aRangeStrings.getLength(); nN++ ) { ScRangeList aRanges; @@ -410,7 +308,7 @@ void ScDocument::SetChartRanges( const String& rChartName, const ::std::vector< aScRangeList.Format( sRangeStr, SCR_ABS_3D, this ); aRangeStrings[nN]=sRangeStr; } - lcl_SetChartRanges( xChartDoc, aRangeStrings ); + ScChartHelper::SetChartRanges( xChartDoc, aRangeStrings ); } } @@ -435,32 +333,25 @@ void ScDocument::GetOldChartParameters( const String& rName, if ( pObject->GetObjIdentifier() == OBJ_OLE2 && ((SdrOle2Obj*)pObject)->GetPersistName() == rName ) { - uno::Reference< embed::XEmbeddedObject > xIPObj = ((SdrOle2Obj*)pObject)->GetObjRef(); - if ( xIPObj.is() ) + uno::Reference< chart2::XChartDocument > xChartDoc( ScChartHelper::GetChartFromSdrObject( pObject ) ); + if ( xChartDoc.is() ) { - svt::EmbeddedObjectRef::TryRunningState( xIPObj ); - - uno::Reference< util::XCloseable > xComponent = xIPObj->getComponent(); - uno::Reference< chart2::XChartDocument > xChartDoc( xComponent, uno::UNO_QUERY ); - if ( xChartDoc.is() ) + chart::ChartDataRowSource eDataRowSource = chart::ChartDataRowSource_COLUMNS; + bool bHasCategories = false; + bool bFirstCellAsLabel = false; + rtl::OUString aRangesStr; + lcl_GetChartParameters( xChartDoc, aRangesStr, eDataRowSource, bHasCategories, bFirstCellAsLabel ); + + rRanges.Parse( aRangesStr, this ); + if ( eDataRowSource == chart::ChartDataRowSource_COLUMNS ) { - chart::ChartDataRowSource eDataRowSource = chart::ChartDataRowSource_COLUMNS; - bool bHasCategories = false; - bool bFirstCellAsLabel = false; - rtl::OUString aRangesStr; - lcl_GetChartParameters( xChartDoc, aRangesStr, eDataRowSource, bHasCategories, bFirstCellAsLabel ); - - rRanges.Parse( aRangesStr, this ); - if ( eDataRowSource == chart::ChartDataRowSource_COLUMNS ) - { - rRowHeaders = bHasCategories; - rColHeaders = bFirstCellAsLabel; - } - else - { - rColHeaders = bHasCategories; - rRowHeaders = bFirstCellAsLabel; - } + rRowHeaders = bHasCategories; + rColHeaders = bFirstCellAsLabel; + } + else + { + rColHeaders = bHasCategories; + rRowHeaders = bFirstCellAsLabel; } } return; @@ -489,75 +380,68 @@ void ScDocument::UpdateChartArea( const String& rChartName, if ( pObject->GetObjIdentifier() == OBJ_OLE2 && ((SdrOle2Obj*)pObject)->GetPersistName() == rChartName ) { - uno::Reference< embed::XEmbeddedObject > xIPObj = ((SdrOle2Obj*)pObject)->GetObjRef(); - if ( xIPObj.is() ) + uno::Reference< chart2::XChartDocument > xChartDoc( ScChartHelper::GetChartFromSdrObject( pObject ) ); + uno::Reference< chart2::data::XDataReceiver > xReceiver( xChartDoc, uno::UNO_QUERY ); + if ( xChartDoc.is() && xReceiver.is() ) { - svt::EmbeddedObjectRef::TryRunningState( xIPObj ); + ScRangeListRef aNewRanges; + chart::ChartDataRowSource eDataRowSource = chart::ChartDataRowSource_COLUMNS; + bool bHasCategories = false; + bool bFirstCellAsLabel = false; + rtl::OUString aRangesStr; + lcl_GetChartParameters( xChartDoc, aRangesStr, eDataRowSource, bHasCategories, bFirstCellAsLabel ); - uno::Reference< util::XCloseable > xComponent = xIPObj->getComponent(); - uno::Reference< chart2::XChartDocument > xChartDoc( xComponent, uno::UNO_QUERY ); - uno::Reference< chart2::data::XDataReceiver > xReceiver( xComponent, uno::UNO_QUERY ); - if ( xChartDoc.is() && xReceiver.is() ) - { - ScRangeListRef aNewRanges; - chart::ChartDataRowSource eDataRowSource = chart::ChartDataRowSource_COLUMNS; - bool bHasCategories = false; - bool bFirstCellAsLabel = false; - rtl::OUString aRangesStr; - lcl_GetChartParameters( xChartDoc, aRangesStr, eDataRowSource, bHasCategories, bFirstCellAsLabel ); + sal_Bool bInternalData = xChartDoc->hasInternalDataProvider(); - sal_Bool bInternalData = xChartDoc->hasInternalDataProvider(); + if ( bAdd && !bInternalData ) + { + // append to old ranges, keep other settings - if ( bAdd && !bInternalData ) - { - // append to old ranges, keep other settings + aNewRanges = new ScRangeList; + aNewRanges->Parse( aRangesStr, this ); - aNewRanges = new ScRangeList; - aNewRanges->Parse( aRangesStr, this ); + ULONG nAddCount = rNewList->Count(); + for ( ULONG nAdd=0; nAdd<nAddCount; nAdd++ ) + aNewRanges->Append( *rNewList->GetObject(nAdd) ); + } + else + { + // directly use new ranges (only eDataRowSource is used from old settings) - ULONG nAddCount = rNewList->Count(); - for ( ULONG nAdd=0; nAdd<nAddCount; nAdd++ ) - aNewRanges->Append( *rNewList->GetObject(nAdd) ); + if ( eDataRowSource == chart::ChartDataRowSource_COLUMNS ) + { + bHasCategories = bRowHeaders; + bFirstCellAsLabel = bColHeaders; } else { - // directly use new ranges (only eDataRowSource is used from old settings) - - if ( eDataRowSource == chart::ChartDataRowSource_COLUMNS ) - { - bHasCategories = bRowHeaders; - bFirstCellAsLabel = bColHeaders; - } - else - { - bHasCategories = bColHeaders; - bFirstCellAsLabel = bRowHeaders; - } - aNewRanges = rNewList; + bHasCategories = bColHeaders; + bFirstCellAsLabel = bRowHeaders; } + aNewRanges = rNewList; + } - if ( bInternalData && pShell ) - { - // Calc -> DataProvider - uno::Reference< chart2::data::XDataProvider > xDataProvider = new ScChart2DataProvider( this ); - xReceiver->attachDataProvider( xDataProvider ); - uno::Reference< util::XNumberFormatsSupplier > xNumberFormatsSupplier( - pShell->GetModel(), uno::UNO_QUERY ); - xReceiver->attachNumberFormatsSupplier( xNumberFormatsSupplier ); - } + if ( bInternalData && pShell ) + { + // Calc -> DataProvider + uno::Reference< chart2::data::XDataProvider > xDataProvider = new ScChart2DataProvider( this ); + xReceiver->attachDataProvider( xDataProvider ); + uno::Reference< util::XNumberFormatsSupplier > xNumberFormatsSupplier( + pShell->GetModel(), uno::UNO_QUERY ); + xReceiver->attachNumberFormatsSupplier( xNumberFormatsSupplier ); + } - String sRangeStr; - aNewRanges->Format( sRangeStr, SCR_ABS_3D, this, GetAddressConvention() ); + String sRangeStr; + aNewRanges->Format( sRangeStr, SCR_ABS_3D, this, GetAddressConvention() ); - lcl_SetChartParameters( xReceiver, sRangeStr, eDataRowSource, bHasCategories, bFirstCellAsLabel ); + lcl_SetChartParameters( xReceiver, sRangeStr, eDataRowSource, bHasCategories, bFirstCellAsLabel ); - pChartListenerCollection->ChangeListening( rChartName, aNewRanges ); + pChartListenerCollection->ChangeListening( rChartName, aNewRanges ); - // ((SdrOle2Obj*)pObject)->GetNewReplacement(); - // pObject->ActionChanged(); + // ((SdrOle2Obj*)pObject)->GetNewReplacement(); + // pObject->ActionChanged(); - return; // nicht weitersuchen - } + return; // nicht weitersuchen } } pObject = aIter.Next(); @@ -569,124 +453,25 @@ void ScDocument::UpdateChart( const String& rChartName ) { if (!pDrawLayer || bInDtorClear) return; - - for (SCTAB nTab=0; nTab<=MAXTAB && pTab[nTab]; nTab++) + uno::Reference< chart2::XChartDocument > xChartDoc( GetChartByName( rChartName ) ); + if( xChartDoc.is() ) { - SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab)); - DBG_ASSERT(pPage,"Page ?"); - - SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS ); - SdrObject* pObject = aIter.Next(); - while (pObject) + try + { + uno::Reference< util::XModifiable > xModif( xChartDoc, uno::UNO_QUERY_THROW ); + if( apTemporaryChartLock.get() ) + apTemporaryChartLock->AlsoLockThisChart( uno::Reference< frame::XModel >( xModif, uno::UNO_QUERY ) ); + xModif->setModified( sal_True ); + } + catch ( uno::Exception& ) { - if ( pObject->GetObjIdentifier() == OBJ_OLE2 && - ((SdrOle2Obj*)pObject)->GetPersistName() == rChartName ) - { - //@todo?: maybe we need a notification - //from the calc to the chart in future - //that calc content has changed - // ((SdrOle2Obj*)pObject)->GetNewReplacement(); - - // Load the object and set modified - - uno::Reference< embed::XEmbeddedObject > xIPObj = ((SdrOle2Obj*)pObject)->GetObjRef(); - if ( xIPObj.is() ) - { - svt::EmbeddedObjectRef::TryRunningState( xIPObj ); - - try - { - uno::Reference< util::XModifiable > xModif( xIPObj->getComponent(), uno::UNO_QUERY_THROW ); - if( apTemporaryChartLock.get() ) - apTemporaryChartLock->AlsoLockThisChart( uno::Reference< frame::XModel >( xModif, uno::UNO_QUERY ) ); - xModif->setModified( sal_True ); - } - catch ( uno::Exception& ) - { - } - } - - // repaint - - pObject->ActionChanged(); - - // After the update, chart keeps track of its own data source ranges, - // the listener doesn't need to listen anymore. - - pChartListenerCollection->ChangeListening( rChartName, new ScRangeList ); - - return; - - /* old chart: - uno::Reference< embed::XEmbeddedObject > xIPObj = ((SdrOle2Obj*)pObject)->GetObjRef(); - if ( xIPObj.is() ) - { - const SchMemChart* pChartData = SchDLL::GetChartData(xIPObj); - if ( pChartData ) - { - ScChartArray aArray( this, *pChartData ); - - SchMemChart* pMemChart = aArray.CreateMemChart(); - ScChartArray::CopySettings( *pMemChart, *pChartData ); - - // #57655# Chart-Update ohne geaenderte Einstellungen (MemChart) - // soll das Dokument nicht auf modified setzen (z.B. in frisch - // geladenem Dokument durch initiales Recalc) - - // #72576# disable SetModified for readonly documents only - - sal_Bool bEnabled = ( (pShell && pShell->IsReadOnly()) || IsImportingXML() ); - sal_Bool bModified = sal_False; - uno::Reference< util::XModifiable > xModif; - - if ( bEnabled ) - { - try - { - xModif = - uno::Reference< util::XModifiable >( xIPObj->getComponent(), uno::UNO_QUERY_THROW ); - bModified = xModif->isModified(); - } - catch( uno::Exception& ) - { - bEnabled = sal_False; - } - } - - SchDLL::Update( xIPObj, pMemChart, pWindow ); - ((SdrOle2Obj*)pObject)->GetNewReplacement(); - delete pMemChart; - - // Dies veranlaesst Chart zum sofortigen Update - //SvData aEmpty; - //aIPObj->SendDataChanged( aEmpty ); - - // the method below did nothing in SO7 -//REMOVE aIPObj->SendViewChanged(); - - // redraw only - pObject->ActionChanged(); - // pObject->SendRepaintBroadcast(); - - if ( bEnabled && xModif.is() ) - { - try - { - if ( xModif->isModified() != bModified ) - xModif->setModified( bModified ); - } - catch ( uno::Exception& ) - {} - } - - return; // nicht weitersuchen - } - } - */ - } - pObject = aIter.Next(); } } + + // After the update, chart keeps track of its own data source ranges, + // the listener doesn't need to listen anymore. + if(pChartListenerCollection) + pChartListenerCollection->ChangeListening( rChartName, new ScRangeList ); } void ScDocument::RestoreChartListener( const String& rName ) @@ -823,31 +608,24 @@ void ScDocument::SetChartRangeList( const String& rChartName, if ( pObject->GetObjIdentifier() == OBJ_OLE2 && ((SdrOle2Obj*)pObject)->GetPersistName() == rChartName ) { - uno::Reference< embed::XEmbeddedObject > xIPObj = ((SdrOle2Obj*)pObject)->GetObjRef(); - if ( xIPObj.is() ) + uno::Reference< chart2::XChartDocument > xChartDoc( ScChartHelper::GetChartFromSdrObject( pObject ) ); + uno::Reference< chart2::data::XDataReceiver > xReceiver( xChartDoc, uno::UNO_QUERY ); + if ( xChartDoc.is() && xReceiver.is() ) { - svt::EmbeddedObjectRef::TryRunningState( xIPObj ); - - uno::Reference< util::XCloseable > xComponent = xIPObj->getComponent(); - uno::Reference< chart2::XChartDocument > xChartDoc( xComponent, uno::UNO_QUERY ); - uno::Reference< chart2::data::XDataReceiver > xReceiver( xComponent, uno::UNO_QUERY ); - if ( xChartDoc.is() && xReceiver.is() ) - { - ScRangeListRef aNewRanges; - chart::ChartDataRowSource eDataRowSource = chart::ChartDataRowSource_COLUMNS; - bool bHasCategories = false; - bool bFirstCellAsLabel = false; - rtl::OUString aRangesStr; - lcl_GetChartParameters( xChartDoc, aRangesStr, eDataRowSource, bHasCategories, bFirstCellAsLabel ); + ScRangeListRef aNewRanges; + chart::ChartDataRowSource eDataRowSource = chart::ChartDataRowSource_COLUMNS; + bool bHasCategories = false; + bool bFirstCellAsLabel = false; + rtl::OUString aRangesStr; + lcl_GetChartParameters( xChartDoc, aRangesStr, eDataRowSource, bHasCategories, bFirstCellAsLabel ); - String sRangeStr; - rNewRangeListRef->Format( sRangeStr, SCR_ABS_3D, this, GetAddressConvention() ); + String sRangeStr; + rNewRangeListRef->Format( sRangeStr, SCR_ABS_3D, this, GetAddressConvention() ); - lcl_SetChartParameters( xReceiver, sRangeStr, eDataRowSource, bHasCategories, bFirstCellAsLabel ); + lcl_SetChartParameters( xReceiver, sRangeStr, eDataRowSource, bHasCategories, bFirstCellAsLabel ); - // don't modify pChartListenerCollection here, called from there - return; - } + // don't modify pChartListenerCollection here, called from there + return; } } pObject = aIter.Next(); diff --git a/sc/source/core/data/documen9.cxx b/sc/source/core/data/documen9.cxx index b9abe0839279..ec6bba8cc33d 100644 --- a/sc/source/core/data/documen9.cxx +++ b/sc/source/core/data/documen9.cxx @@ -28,10 +28,6 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sc.hxx" -#include <com/sun/star/embed/XEmbeddedObject.hpp> -#include <com/sun/star/embed/XClassifiedObject.hpp> -#include <com/sun/star/chart2/data/XDataReceiver.hpp> - // INCLUDE --------------------------------------------------------------- #include "scitems.hxx" @@ -65,10 +61,10 @@ #include "rechead.hxx" #include "poolhelp.hxx" #include "docpool.hxx" -#include "chartarr.hxx" #include "detfunc.hxx" // for UpdateAllComments #include "editutil.hxx" #include "postit.hxx" +#include "charthelper.hxx" using namespace ::com::sun::star; @@ -102,37 +98,6 @@ XColorTable* ScDocument::GetColorTable() } } -BOOL lcl_AdjustRanges( ScRangeList& rRanges, SCTAB nSource, SCTAB nDest, SCTAB nTabCount ) -{ - //! if multiple sheets are copied, update references into the other copied sheets? - - BOOL bChanged = FALSE; - - ULONG nCount = rRanges.Count(); - for (ULONG i=0; i<nCount; i++) - { - ScRange* pRange = rRanges.GetObject(i); - if ( pRange->aStart.Tab() == nSource && pRange->aEnd.Tab() == nSource ) - { - pRange->aStart.SetTab( nDest ); - pRange->aEnd.SetTab( nDest ); - bChanged = TRUE; - } - if ( pRange->aStart.Tab() >= nTabCount ) - { - pRange->aStart.SetTab( nTabCount > 0 ? ( nTabCount - 1 ) : 0 ); - bChanged = TRUE; - } - if ( pRange->aEnd.Tab() >= nTabCount ) - { - pRange->aEnd.SetTab( nTabCount > 0 ? ( nTabCount - 1 ) : 0 ); - bChanged = TRUE; - } - } - - return bChanged; -} - void ScDocument::TransferDrawPage(ScDocument* pSrcDoc, SCTAB nSrcPos, SCTAB nDestPos) { if (pDrawLayer && pSrcDoc->pDrawLayer) @@ -158,53 +123,14 @@ void ScDocument::TransferDrawPage(ScDocument* pSrcDoc, SCTAB nSrcPos, SCTAB nDes if (pDrawLayer->IsRecording()) pDrawLayer->AddCalcUndo( new SdrUndoInsertObj( *pNewObject ) ); - // #71726# if it's a chart, make sure the data references are valid - // (this must be after InsertObject!) - - if ( pNewObject->GetObjIdentifier() == OBJ_OLE2 ) - { - uno::Reference< embed::XEmbeddedObject > xIPObj = ((SdrOle2Obj*)pNewObject)->GetObjRef(); - uno::Reference< embed::XClassifiedObject > xClassified( xIPObj, uno::UNO_QUERY ); - SvGlobalName aObjectClassName; - if ( xClassified.is() ) - { - try { - aObjectClassName = SvGlobalName( xClassified->getClassID() ); - } catch( uno::Exception& ) - { - // TODO: handle error? - } - } - - if ( xIPObj.is() && SotExchange::IsChart( aObjectClassName ) ) - { - String aChartName = ((SdrOle2Obj*)pNewObject)->GetPersistName(); - - uno::Reference< chart2::XChartDocument > xChartDoc( GetChartByName( aChartName ) ); - uno::Reference< chart2::data::XDataReceiver > xReceiver( xChartDoc, uno::UNO_QUERY ); - if( xChartDoc.is() && xReceiver.is() ) - { - if( !xChartDoc->hasInternalDataProvider() ) - { - ::std::vector< ScRangeList > aRangesVector; - GetChartRanges( aChartName, aRangesVector, pSrcDoc ); - - ::std::vector< ScRangeList >::iterator aIt( aRangesVector.begin() ); - for( ; aIt!=aRangesVector.end(); aIt++ ) - { - ScRangeList& rScRangeList( *aIt ); - lcl_AdjustRanges( rScRangeList, nSrcPos, nDestPos, GetTableCount() ); - } - SetChartRanges( aChartName, aRangesVector ); - } - } - } - } - pOldObject = aIter.Next(); } } } + + // #71726# make sure the data references of charts are adapted + // (this must be after InsertObject!) + ScChartHelper::AdjustRangesOfChartsOnDestinationPage( pSrcDoc, this, nSrcPos, nDestPos ); } void ScDocument::InitDrawLayer( SfxObjectShell* pDocShell ) diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx index fa4fb296d9a7..9cf68e3e309d 100644 --- a/sc/source/core/data/document.cxx +++ b/sc/source/core/data/document.cxx @@ -2644,10 +2644,11 @@ void ScDocument::PutCell( const ScAddress& rPos, ScBaseCell* pCell, BOOL bForceT } -BOOL ScDocument::SetString( SCCOL nCol, SCROW nRow, SCTAB nTab, const String& rString ) +BOOL ScDocument::SetString( SCCOL nCol, SCROW nRow, SCTAB nTab, const String& rString, + SvNumberFormatter* pFormatter, bool bDetectNumberFormat ) { if ( ValidTab(nTab) && pTab[nTab] ) - return pTab[nTab]->SetString( nCol, nRow, nTab, rString ); + return pTab[nTab]->SetString( nCol, nRow, nTab, rString, pFormatter, bDetectNumberFormat ); else return FALSE; } @@ -3906,7 +3907,7 @@ void ScDocument::GetSelectionFrame( const ScMarkData& rMark, } -BOOL ScDocument::HasAttrib( SCCOL nCol1, SCROW nRow1, SCTAB nTab1, +bool ScDocument::HasAttrib( SCCOL nCol1, SCROW nRow1, SCTAB nTab1, SCCOL nCol2, SCROW nRow2, SCTAB nTab2, USHORT nMask ) { if ( nMask & HASATTR_ROTATE ) @@ -3960,16 +3961,16 @@ BOOL ScDocument::HasAttrib( SCCOL nCol1, SCROW nRow1, SCTAB nTab1, } if (!nMask) - return FALSE; + return false; - BOOL bFound = FALSE; + bool bFound = false; for (SCTAB i=nTab1; i<=nTab2 && !bFound; i++) if (pTab[i]) { if ( nMask & HASATTR_RTL ) { if ( GetEditTextDirection(i) == EE_HTEXTDIR_R2L ) // sheet default - bFound = TRUE; + bFound = true; } if ( nMask & HASATTR_RIGHTORCENTER ) { @@ -3978,7 +3979,7 @@ BOOL ScDocument::HasAttrib( SCCOL nCol1, SCROW nRow1, SCTAB nTab1, // That way, ScAttrArray::HasAttrib doesn't have to handle RTL sheets. if ( IsLayoutRTL(i) ) - bFound = TRUE; + bFound = true; } if ( !bFound ) @@ -3988,7 +3989,7 @@ BOOL ScDocument::HasAttrib( SCCOL nCol1, SCROW nRow1, SCTAB nTab1, return bFound; } -BOOL ScDocument::HasAttrib( const ScRange& rRange, USHORT nMask ) +bool ScDocument::HasAttrib( const ScRange& rRange, USHORT nMask ) { return HasAttrib( rRange.aStart.Col(), rRange.aStart.Row(), rRange.aStart.Tab(), rRange.aEnd.Col(), rRange.aEnd.Row(), rRange.aEnd.Tab(), diff --git a/sc/source/core/data/dpcachetable.cxx b/sc/source/core/data/dpcachetable.cxx index 237d7ffd16db..ad5e921cb278 100644 --- a/sc/source/core/data/dpcachetable.cxx +++ b/sc/source/core/data/dpcachetable.cxx @@ -65,7 +65,6 @@ using ::com::sun::star::uno::UNO_QUERY; using ::com::sun::star::uno::UNO_QUERY_THROW; using ::com::sun::star::sheet::DataPilotFieldFilter; -const double D_TIMEFACTOR = 86400.0; static BOOL lcl_HasQueryEntry( const ScQueryParam& rParam ) { @@ -75,56 +74,35 @@ static BOOL lcl_HasQueryEntry( const ScQueryParam& rParam ) // ---------------------------------------------------------------------------- -static ScDPCacheCell EmptyCellContent = ScDPCacheCell(); - -// ---------------------------------------------------------------------------- - -ScDPCacheTable::Cell::Cell() : - mnCategoryRef(0), - mpContent(NULL) -{ -} - -ScDPCacheTable::Cell::~Cell() -{ -} - -// ---------------------------------------------------------------------------- - ScDPCacheTable::FilterItem::FilterItem() : - mnMatchStrId(ScSimpleSharedString::EMPTY), mfValue(0.0), mbHasValue(false) { } - +bool ScDPCacheTable::FilterItem::match( const ScDPItemData& rCellData ) const +{ + if (rCellData.GetString()!= maString && + (!rCellData.IsValue()|| rCellData.GetValue()!= mfValue)) + return false; + return true; +} // ---------------------------------------------------------------------------- -ScDPCacheTable::SingleFilter::SingleFilter(ScSimpleSharedString& rSharedString, - sal_Int32 nMatchStrId, double fValue, bool bHasValue) : - mrSharedString(rSharedString) +ScDPCacheTable::SingleFilter::SingleFilter(String aString, double fValue, bool bHasValue) { - maItem.mnMatchStrId = nMatchStrId; + maItem.maString = aString; maItem.mfValue = fValue; maItem.mbHasValue = bHasValue; } -bool ScDPCacheTable::SingleFilter::match(const ScDPCacheCell& rCell) const +bool ScDPCacheTable::SingleFilter::match( const ScDPItemData& rCellData ) const { - if (rCell.mnStrId != maItem.mnMatchStrId && - (!rCell.mbNumeric || rCell.mfValue != maItem.mfValue)) - return false; - - return true; + return maItem.match(rCellData); } const String ScDPCacheTable::SingleFilter::getMatchString() { - const String* pStr = mrSharedString.getString(maItem.mnMatchStrId); - if (pStr) - return *pStr; - - return String(); + return maItem.maString; } double ScDPCacheTable::SingleFilter::getMatchValue() const @@ -139,33 +117,26 @@ bool ScDPCacheTable::SingleFilter::hasValue() const // ---------------------------------------------------------------------------- -ScDPCacheTable::GroupFilter::GroupFilter(ScSimpleSharedString& rSharedString) : - mrSharedString(rSharedString) +ScDPCacheTable::GroupFilter::GroupFilter() { } -bool ScDPCacheTable::GroupFilter::match(const ScDPCacheCell& rCell) const +bool ScDPCacheTable::GroupFilter::match( const ScDPItemData& rCellData ) const { vector<FilterItem>::const_iterator itrEnd = maItems.end(); - for (vector<FilterItem>::const_iterator itr = maItems.begin(); itr != itrEnd; ++itr) - { - bool bMatch = false; - if (rCell.mbNumeric) - bMatch = (itr->mfValue == rCell.mfValue); - else - bMatch = (itr->mnMatchStrId == rCell.mnStrId); - - if (bMatch) - return true; - } - return false; + for (vector<FilterItem>::const_iterator itr = maItems.begin(); itr != itrEnd; ++itr) + { + bool bMatch = itr->match( rCellData); + if (bMatch) + return true; + } + return false; } void ScDPCacheTable::GroupFilter::addMatchItem(const String& rStr, double fVal, bool bHasValue) { - sal_Int32 nStrId = mrSharedString.getStringId(rStr); FilterItem aItem; - aItem.mnMatchStrId = nStrId; + aItem.maString = rStr; aItem.mfValue = fVal; aItem.mbHasValue = bHasValue; maItems.push_back(aItem); @@ -186,10 +157,16 @@ ScDPCacheTable::Criterion::Criterion() : // ---------------------------------------------------------------------------- -ScDPCacheTable::ScDPCacheTable(ScDPCollection* pCollection) : - mrSharedString(pCollection->GetSharedString()), - mpCollection(pCollection) +ScDPCacheTable::ScDPCacheTable( ScDocument* pDoc,long nId ) : + mpCache( NULL ), + mpNoneCache( NULL ) { + if ( nId >= 0 ) + mpCache = pDoc->GetDPObjectCache( nId ); + else + { //create a temp cache object + InitNoneCache( NULL ); + } } ScDPCacheTable::~ScDPCacheTable() @@ -198,12 +175,12 @@ ScDPCacheTable::~ScDPCacheTable() sal_Int32 ScDPCacheTable::getRowSize() const { - return maTable.size(); + return GetCache()->GetRowCount(); } sal_Int32 ScDPCacheTable::getColSize() const { - return maTable.empty() ? 0 : maTable[0].size(); + return GetCache()->GetColumnCount(); } namespace { @@ -230,276 +207,114 @@ private: } -void ScDPCacheTable::fillTable(ScDocument* pDoc, const ScRange& rRange, const ScQueryParam& rQuery, BOOL* pSpecial, - bool bIgnoreEmptyRows) +void ScDPCacheTable::fillTable( const ScQueryParam& rQuery, BOOL* pSpecial, + bool bIgnoreEmptyRows, bool bRepeatIfEmpty ) { // Make sure the formula cells within the data range are interpreted // during this call, for this method may be called from the interpretation // of GETPIVOTDATA, which disables nested formula interpretation without // increasing the macro level. - MacroInterpretIncrementer aMacroInc(pDoc); - - SCTAB nTab = rRange.aStart.Tab(); - SCCOL nStartCol = rRange.aStart.Col(); - SCROW nStartRow = rRange.aStart.Row(); - SCCOL nColCount = rRange.aEnd.Col() - rRange.aStart.Col() + 1; - SCROW nRowCount = rRange.aEnd.Row() - rRange.aStart.Row() + 1; - - if (nRowCount <= 1 || nColCount <= 0) + MacroInterpretIncrementer aMacroInc(GetCache()->GetDoc()); + + if ( mpCache == NULL ) + InitNoneCache( NULL ); +//check cache + const SCROW nRowCount = getRowSize(); + const SCCOL nColCount = (SCCOL) getColSize(); + if ( nRowCount <= 0 || nColCount <= 0) return; - maTable.clear(); - maTable.reserve(nRowCount); - maHeader.clear(); - maHeader.reserve(nColCount); maRowsVisible.clear(); maRowsVisible.reserve(nRowCount); - // Header row - for (SCCOL nCol = 0; nCol < nColCount; ++nCol) - { - String aStr; - pDoc->GetString(nCol + nStartCol, nStartRow, nTab, aStr); - sal_Int32 nStrId = mrSharedString.insertString(aStr); - maHeader.push_back(nStrId); - } // Initialize field entries container. maFieldEntries.clear(); maFieldEntries.reserve(nColCount); - for (SCCOL nCol = 0; nCol < nColCount; ++nCol) - { - TypedScStrCollectionPtr p(new TypedScStrCollection); - maFieldEntries.push_back(p); - } - - vector<SCROW> aLastNonEmptyRows(nColCount, 0); // Data rows - for (SCROW nRow = 1; nRow < nRowCount; ++nRow) + for (SCCOL nCol = 0; nCol < nColCount; ++nCol) { - if ( lcl_HasQueryEntry(rQuery) && !pDoc->ValidQuery(nRow + nStartRow, nTab, rQuery, pSpecial) ) - // filtered out by standard filter. - continue; - - if ( bIgnoreEmptyRows && - pDoc->IsBlockEmpty(nTab, nStartCol, nRow + nStartRow, - nStartCol + nColCount - 1, nRow + nStartRow) ) - // skip an empty row. - continue; - - // Insert a new row into cache table. - maRowsVisible.push_back(true); - maTable.push_back( vector<Cell>() ); - maTable.back().reserve(nColCount); - - for (SCCOL nCol = 0; nCol < nColCount; ++nCol) + SCROW nMemCount = GetCache()->GetDimMemberCount( nCol ); + if ( nMemCount ) { - maTable.back().push_back( ScDPCacheTable::Cell() ); - Cell& rCell = maTable.back().back(); - rCell.mnCategoryRef = maTable.size()-1; + std::vector< SCROW > pAdded( nMemCount, -1 ); - String aCellStr; - bool bReadCell = nRow == 0 || pDoc->HasData(nStartCol + nCol, nStartRow + nRow, nTab); - if (bReadCell) + for (SCROW nRow = 0; nRow < nRowCount; ++nRow ) { - aLastNonEmptyRows[nCol] = maTable.size()-1; - ScDPCacheCell aCell; - pDoc->GetString(nStartCol + nCol, nStartRow + nRow, nTab, aCellStr); - aCell.mnStrId = mrSharedString.insertString(aCellStr); - aCell.mnType = SC_VALTYPE_STRING; - aCell.mbNumeric = false; - ScAddress aPos(nStartCol + nCol, nStartRow + nRow, nTab); - getValueData(pDoc, aPos, aCell); - rCell.mpContent = mpCollection->getCacheCellFromPool(aCell); + SCROW nIndex = GetCache()->GetItemDataId( nCol, nRow, bRepeatIfEmpty ); + SCROW nOrder = GetCache()->GetOrder( nCol, nIndex ); + + if ( nCol == 0 ) + maRowsVisible.push_back(false); + + if ( lcl_HasQueryEntry(rQuery) && + !GetCache()->ValidQuery( nRow , rQuery, pSpecial ) ) + continue; + if ( bIgnoreEmptyRows && GetCache()->IsRowEmpty( nRow ) ) + continue; + // Insert a new row into cache table. + if ( nCol == 0 ) + maRowsVisible.back() = true; + + pAdded[nOrder] = nIndex; + } + maFieldEntries.push_back( vector<SCROW>() ); + for ( SCROW nRow = 0; nRow < nMemCount; nRow++ ) + { + if ( pAdded[nRow] != -1 ) + maFieldEntries.back().push_back( pAdded[nRow] ); } - else - rCell.mnCategoryRef = aLastNonEmptyRows[nCol]; - - TypedStrData* pNew; - if (rCell.mpContent && rCell.mpContent->mbNumeric) - pNew = new TypedStrData(aCellStr, rCell.mpContent->mfValue, SC_STRTYPE_VALUE); - else - pNew = new TypedStrData(aCellStr); - - if (!maFieldEntries[nCol]->Insert(pNew)) - delete pNew; } } } -void lcl_GetCellValue(const Reference<sdbc::XRow>& xRow, sal_Int32 nType, long nCol, - const Date& rNullDate, ScDPCacheCell& rCell, String& rStr, - ScSimpleSharedString& rSharedString) +void ScDPCacheTable::fillTable() { - short nNumType = NUMBERFORMAT_NUMBER; - BOOL bEmptyFlag = FALSE; - try - { - rStr = xRow->getString(nCol); - rCell.mnStrId = rSharedString.getStringId(rStr); - rCell.mnType = SC_VALTYPE_STRING; - - switch (nType) - { - case sdbc::DataType::BIT: - case sdbc::DataType::BOOLEAN: - { - nNumType = NUMBERFORMAT_LOGICAL; - rCell.mfValue = xRow->getBoolean(nCol) ? 1 : 0; - bEmptyFlag = (rCell.mfValue == 0.0 && xRow->wasNull()); - rCell.mbNumeric = true; - rCell.mnType = SC_VALTYPE_VALUE; - } - break; - - case sdbc::DataType::TINYINT: - case sdbc::DataType::SMALLINT: - case sdbc::DataType::INTEGER: - case sdbc::DataType::BIGINT: - case sdbc::DataType::FLOAT: - case sdbc::DataType::REAL: - case sdbc::DataType::DOUBLE: - case sdbc::DataType::NUMERIC: - case sdbc::DataType::DECIMAL: - { - //! do the conversion here? - rCell.mfValue = xRow->getDouble(nCol); - bEmptyFlag = (rCell.mfValue == 0.0 && xRow->wasNull()); - rCell.mbNumeric = true; - rCell.mnType = SC_VALTYPE_VALUE; - } - break; - - case sdbc::DataType::CHAR: - case sdbc::DataType::VARCHAR: - case sdbc::DataType::LONGVARCHAR: - bEmptyFlag = (rStr.Len() == 0 && xRow->wasNull()); - break; + if ( mpCache == NULL ) + InitNoneCache( NULL ); +//check cache + const SCROW nRowCount = getRowSize(); + const SCCOL nColCount = (SCCOL) getColSize(); + if ( nRowCount <= 0 || nColCount <= 0) + return; - case sdbc::DataType::DATE: - { - nNumType = NUMBERFORMAT_DATE; + maRowsVisible.clear(); + maRowsVisible.reserve(nRowCount); - util::Date aDate = xRow->getDate(nCol); - rCell.mfValue = Date(aDate.Day, aDate.Month, aDate.Year) - rNullDate; - bEmptyFlag = xRow->wasNull(); - rCell.mbNumeric = true; - rCell.mnType = SC_VALTYPE_VALUE; - } - break; - case sdbc::DataType::TIME: - { - nNumType = NUMBERFORMAT_TIME; - - util::Time aTime = xRow->getTime(nCol); - rCell.mfValue = ( aTime.Hours * 3600 + aTime.Minutes * 60 + - aTime.Seconds + aTime.HundredthSeconds / 100.0 ) / D_TIMEFACTOR; - bEmptyFlag = xRow->wasNull(); - rCell.mbNumeric = true; - rCell.mnType = SC_VALTYPE_VALUE; - } - break; + // Initialize field entries container. + maFieldEntries.clear(); + maFieldEntries.reserve(nColCount); - case sdbc::DataType::TIMESTAMP: - { - nNumType = NUMBERFORMAT_DATETIME; - - util::DateTime aStamp = xRow->getTimestamp(nCol); - rCell.mfValue = ( Date( aStamp.Day, aStamp.Month, aStamp.Year ) - rNullDate ) + - ( aStamp.Hours * 3600 + aStamp.Minutes * 60 + - aStamp.Seconds + aStamp.HundredthSeconds / 100.0 ) / D_TIMEFACTOR; - bEmptyFlag = xRow->wasNull(); - rCell.mbNumeric = true; - rCell.mnType = SC_VALTYPE_VALUE; - } - break; - - case sdbc::DataType::SQLNULL: - case sdbc::DataType::BINARY: - case sdbc::DataType::VARBINARY: - case sdbc::DataType::LONGVARBINARY: - default: - break; - } - } - catch (uno::Exception&) + // Data rows + for (SCCOL nCol = 0; nCol < nColCount; ++nCol) { - } -} + SCROW nMemCount = GetCache()->GetDimMemberCount( nCol ); + if ( nMemCount ) + { + std::vector< SCROW > pAdded( nMemCount, -1 ); -void ScDPCacheTable::fillTable(const Reference<sdbc::XRowSet>& xRowSet, const Date& rNullDate) -{ - if (!xRowSet.is()) - // Dont' even waste time to go any further. - return; + for (SCROW nRow = 0; nRow < nRowCount; ++nRow ) + { + SCROW nIndex = GetCache()->GetItemDataId( nCol, nRow, false ); + SCROW nOrder = GetCache()->GetOrder( nCol, nIndex ); - try - { - Reference<sdbc::XResultSetMetaDataSupplier> xMetaSupp(xRowSet, UNO_QUERY_THROW); - Reference<sdbc::XResultSetMetaData> xMeta = xMetaSupp->getMetaData(); - if (!xMeta.is()) - return; - - sal_Int32 nColCount = xMeta->getColumnCount(); - - // Get column titles and types. - vector<sal_Int32> aColTypes(nColCount); - maHeader.clear(); - maHeader.reserve(nColCount); - for (sal_Int32 nCol = 0; nCol < nColCount; ++nCol) - { - String aColTitle = xMeta->getColumnLabel(nCol+1); - aColTypes[nCol] = xMeta->getColumnType(nCol+1); - maHeader.push_back( mrSharedString.getStringId(aColTitle) ); - } + if ( nCol == 0 ) + maRowsVisible.push_back(true); - // Initialize field entries container. - maFieldEntries.clear(); - maFieldEntries.reserve(nColCount); - for (SCCOL nCol = 0; nCol < nColCount; ++nCol) - { - TypedScStrCollectionPtr p(new TypedScStrCollection); - maFieldEntries.push_back(p); - } - // Now get the data rows. - Reference<sdbc::XRow> xRow(xRowSet, UNO_QUERY_THROW); - xRowSet->first(); - maTable.clear(); - maRowsVisible.clear(); - do - { - maRowsVisible.push_back(true); - maTable.push_back( vector<Cell>() ); - maTable.back().reserve(nColCount); - for (sal_Int32 nCol = 0; nCol < nColCount; ++nCol) + pAdded[nOrder] = nIndex; + } + maFieldEntries.push_back( vector<SCROW>() ); + for ( SCROW nRow = 0; nRow < nMemCount; nRow++ ) { - maTable.back().push_back( Cell() ); - Cell& rCell = maTable.back().back(); - ScDPCacheCell aCellContent; - String aStr; - lcl_GetCellValue(xRow, aColTypes[nCol], nCol+1, rNullDate, aCellContent, aStr, mrSharedString); - rCell.mpContent = mpCollection->getCacheCellFromPool(aCellContent); - - TypedStrData* pNew; - if (rCell.mpContent->mbNumeric) - pNew = new TypedStrData(aStr, rCell.mpContent->mfValue, SC_STRTYPE_VALUE); - else - pNew = new TypedStrData(aStr); - - if (!maFieldEntries[nCol]->Insert(pNew)) - delete pNew; + if ( pAdded[nRow] != -1 ) + maFieldEntries.back().push_back( pAdded[nRow] ); } } - while (xRowSet->next()); - - xRowSet->beforeFirst(); - } - catch (const Exception&) - { } + return; } bool ScDPCacheTable::isRowActive(sal_Int32 nRow) const @@ -524,41 +339,43 @@ void ScDPCacheTable::filterByPageDimension(const vector<Criterion>& rCriteria, c maRowsVisible[nRow] = isRowQualified(nRow, rCriteria, rRepeatIfEmptyDims); } -const ScDPCacheCell* ScDPCacheTable::getCell(SCCOL nCol, SCROW nRow, bool bRepeatIfEmpty) const +const ScDPItemData* ScDPCacheTable::getCell(SCCOL nCol, SCROW nRow, bool bRepeatIfEmpty) const { - if ( nRow >= static_cast<SCROW>(maTable.size()) ) - return NULL; - - const vector<Cell>& rRow = maTable[nRow]; - if ( nCol < 0 || static_cast<size_t>(nCol) >= rRow.size() ) - return NULL; + SCROW nId= GetCache()->GetItemDataId(nCol, nRow, bRepeatIfEmpty); + return GetCache()->GetItemDataById( nCol, nId ); +} - const Cell& rCell = rRow[nCol]; - const ScDPCacheCell* pCell = rCell.mpContent; - if (bRepeatIfEmpty && !pCell) - pCell = getCell(nCol, rCell.mnCategoryRef, false); +void ScDPCacheTable::getValue( ScDPValueData& rVal, SCCOL nCol, SCROW nRow, bool bRepeatIfEmpty) const +{ + const ScDPItemData* pData = getCell( nCol, nRow, bRepeatIfEmpty ); - return pCell ? pCell : &EmptyCellContent; + if (pData) + { + rVal.fValue = pData->IsValue() ? pData->GetValue() : 0.0; + rVal.nType = pData->GetType(); + } + else + rVal.Set(0.0, SC_VALTYPE_EMPTY); } - -const String* ScDPCacheTable::getFieldName(sal_Int32 nIndex) const +String ScDPCacheTable::getFieldName(SCCOL nIndex) const { - if (nIndex >= static_cast<sal_Int32>(maHeader.size())) - return NULL; + return (GetCache()->GetDimensionName( nIndex )); +} - return mrSharedString.getString(maHeader[nIndex]); +sal_Int32 ScDPCacheTable::getFieldIndex(const String& rStr) const +{ + return GetCache()->GetDimensionIndex( rStr ); } -const TypedScStrCollection& ScDPCacheTable::getFieldEntries(sal_Int32 nIndex) const +const ::std::vector<SCROW>& ScDPCacheTable::getFieldEntries( sal_Int32 nColumn ) const { - if (nIndex < 0 || static_cast<size_t>(nIndex) >= maFieldEntries.size()) + if (nColumn < 0 || static_cast<size_t>(nColumn) >= maFieldEntries.size()) { // index out of bound. Hopefully this code will never be reached. - static const TypedScStrCollection emptyCollection; - return emptyCollection; + static const ::std::vector<SCROW> emptyEntries; + return emptyEntries; } - - return *maFieldEntries[nIndex].get(); + return maFieldEntries[nColumn]; } void ScDPCacheTable::filterTable(const vector<Criterion>& rCriteria, Sequence< Sequence<Any> >& rTabData, @@ -577,13 +394,10 @@ void ScDPCacheTable::filterTable(const vector<Criterion>& rCriteria, Sequence< S // Header first. Sequence<Any> headerRow(nColSize); - for (sal_Int32 nCol = 0; nCol < nColSize; ++nCol) + for (SCCOL nCol = 0; nCol < nColSize; ++nCol) { OUString str; - const String* pStr = mrSharedString.getString(maHeader[nCol]); - if (pStr) - str = *pStr; - + str = getFieldName( nCol); Any any; any <<= str; headerRow[nCol] = any; @@ -607,26 +421,14 @@ void ScDPCacheTable::filterTable(const vector<Criterion>& rCriteria, Sequence< S { Any any; bool bRepeatIfEmpty = rRepeatIfEmptyDims.count(nCol) > 0; - const ScDPCacheCell* pCell = getCell(nCol, nRow, bRepeatIfEmpty); - if (!pCell) - { - // This should never happen, but in case this happens, just - // stick in an empty string. - OUString str; - any <<= str; - row[nCol] = any; - continue; - } - - if (pCell->mbNumeric) - any <<= pCell->mfValue; + // Wang Xu Ming - DataPilot migration + const ScDPItemData* pData= getCell(nCol, nRow, bRepeatIfEmpty); + if ( pData->IsValue() ) + any <<= pData->GetValue(); else { - OUString str; - const String* pStr = mrSharedString.getString(pCell->mnStrId); - if (pStr) - str = *pStr; - any <<= str; + OUString string (pData->GetString() ); + any <<= string; } row[nCol] = any; } @@ -642,15 +444,19 @@ void ScDPCacheTable::filterTable(const vector<Criterion>& rCriteria, Sequence< S void ScDPCacheTable::clear() { - maTable.clear(); - maHeader.clear(); maFieldEntries.clear(); maRowsVisible.clear(); } +void ScDPCacheTable::swap(ScDPCacheTable& rOther) +{ + maFieldEntries.swap(rOther.maFieldEntries); + maRowsVisible.swap(rOther.maRowsVisible); +} + bool ScDPCacheTable::empty() const { - return maTable.empty(); + return ( mpCache == NULL&& mpNoneCache == NULL ) || maFieldEntries.size()==0; } bool ScDPCacheTable::isRowQualified(sal_Int32 nRow, const vector<Criterion>& rCriteria, @@ -667,52 +473,26 @@ bool ScDPCacheTable::isRowQualified(sal_Int32 nRow, const vector<Criterion>& rCr // Check if the 'repeat if empty' flag is set for this field. bool bRepeatIfEmpty = rRepeatIfEmptyDims.count(itr->mnFieldIndex) > 0; - const ScDPCacheCell* pCell = getCell(static_cast<SCCOL>(itr->mnFieldIndex), nRow, bRepeatIfEmpty); - if (!pCell) - // This should never happen, but just in case... - return false; - - if (!itr->mpFilter->match(*pCell)) + const ScDPItemData* pCellData = getCell(static_cast<SCCOL>(itr->mnFieldIndex), nRow, bRepeatIfEmpty); + if (!itr->mpFilter->match(*pCellData)) return false; } return true; } -void ScDPCacheTable::getValueData(ScDocument* pDoc, const ScAddress& rPos, ScDPCacheCell& rCell) -{ - ScBaseCell* pCell = pDoc->GetCell(rPos); - if (!pCell) - { - rCell.mnType = SC_VALTYPE_EMPTY; - return; - } - - CellType eType = pCell->GetCellType(); - if (eType == CELLTYPE_NOTE) - { - // note cell - rCell.mnType = SC_VALTYPE_EMPTY; - return; - } - if (eType == CELLTYPE_FORMULA && static_cast<ScFormulaCell*>(pCell)->GetErrCode()) - { - // formula cell with error - rCell.mnType = SC_VALTYPE_ERROR; - return; - } - - if ( pCell->HasValueData() ) - { - if (eType == CELLTYPE_VALUE) - // value cell - rCell.mfValue = static_cast<ScValueCell*>(pCell)->GetValue(); - else if (eType == CELLTYPE_FORMULA) - // formula cell - rCell.mfValue = static_cast<ScFormulaCell*>(pCell)->GetValue(); - - rCell.mbNumeric = true; - rCell.mnType = SC_VALTYPE_VALUE; - } +void ScDPCacheTable::InitNoneCache( ScDocument* pDoc ) +{ + mpCache = NULL; + if ( mpNoneCache ) + delete mpNoneCache; + mpNoneCache = new ScDPTableDataCache( pDoc ); } +ScDPTableDataCache* ScDPCacheTable::GetCache() const +{ + if ( mpCache ) + return mpCache; + return mpNoneCache; +} +// End Comments diff --git a/sc/source/core/data/dpglobal.cxx b/sc/source/core/data/dpglobal.cxx new file mode 100755 index 000000000000..6b84d37d8d0f --- /dev/null +++ b/sc/source/core/data/dpglobal.cxx @@ -0,0 +1,150 @@ +/************************************************************************* + * + * 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: dpglobal.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" + +#include "dpglobal.hxx" +#include "document.hxx" + +#include <stdio.h> + +namespace ScDPGlobal +{ + Rectangle operator *( const Rectangle &rLeft, const std::pair<double,double> & rRight ) + { + Rectangle rcResult( rLeft ); + rcResult.Bottom() = rcResult.Top() + static_cast<long>( rcResult.GetHeight() * rRight.second ); + rcResult.Right() = rcResult.Left() + static_cast<long>( rcResult.GetWidth() * rRight.first); + return rcResult; + } + + String GetFuncString( const String &rString, const USHORT nIndex ) + { + if ( nIndex <= 1 ) return rString; + ULONG uch = rString.Len() ? rString.GetChar( rString.Len()-1 ) : (L'9'+1); + bool bEndWithDigital = ( L'0'<=uch && uch<=L'9'); + char szTemp[__MAX_NUM_LEN+1]; + int nLen = sprintf( szTemp, bEndWithDigital ? DATA_RENAME_SEPARATOR"%hu" : "%hu", nIndex ); + String strRet = rString; + strRet.Append( String::CreateFromAscii( szTemp, static_cast<USHORT>(nLen) )); + return strRet; + } + + bool ChkDPTableOverlap( ScDocument *pDestDoc, std::list<ScDPObject> & rClipboard, SCCOL nClipStartCol, SCROW nClipStartRow, SCCOL nStartCol, SCROW nStartRow, SCTAB nStartTab, USHORT nEndTab, BOOL bExcludeClip /*= FALSE*/ ) + { + if ( ScDPCollection* pDPCollection = pDestDoc->GetDPCollection() ) + { + USHORT nCount = pDPCollection->GetCount(); + SCsCOL nOffsetX = nStartCol - nClipStartCol; + SCsROW nOffsetY = nStartRow - nClipStartRow; + + for( std::list<ScDPObject>::iterator iter = rClipboard.begin(); iter!=rClipboard.end(); iter++ ) + { + ScRange aRange = iter->GetOutRange(); + + for( USHORT nCurrTab = nStartTab; nCurrTab<=nEndTab; nCurrTab++ ) + { + SCsTAB nOffsetZ = nCurrTab - aRange.aStart.Tab(); + aRange.Move( nOffsetX, nOffsetY, nOffsetZ ); + + for ( USHORT i = 0; i<nCount; i++) + { + if ( (*pDPCollection)[i] && aRange.Intersects( (*pDPCollection)[i]->GetOutRange())) + { + if ( bExcludeClip && iter->GetOutRange() == (*pDPCollection)[i]->GetOutRange() ) + { + continue; + } + return false; + } + } + } + } + } + return true; +} +//end + +} +// -------------------------------------------------------------------- +// ScDPItemDataPool +// Construct +ScDPItemDataPool::ScDPItemDataPool(void) +{ +} +// +ScDPItemDataPool::ScDPItemDataPool(const ScDPItemDataPool& r): + maItems(r.maItems), + maItemIds(r.maItemIds) +{ +} + +ScDPItemDataPool::~ScDPItemDataPool(void) +{ +} + + +const ScDPItemData* ScDPItemDataPool::getData( sal_Int32 nId ) +{ + if ( nId >= static_cast<sal_Int32>(maItems.size()) ) + return NULL; + else + return &(maItems[nId]); +} + +sal_Int32 ScDPItemDataPool::getDataId( const ScDPItemData& aData ) +{ + DataHash::const_iterator itr = maItemIds.find( aData), + itrEnd = maItemIds.end(); + if ( itr == itrEnd ) + // not exist + return -1; + + else //exist + return itr->second; + +} + +sal_Int32 ScDPItemDataPool::insertData( const ScDPItemData& aData ) +{ + sal_Int32 nResult = getDataId( aData ); + + if( nResult < 0 ) + { + maItemIds.insert( DataHash::value_type( aData, nResult = maItems.size() ) ); + maItems.push_back( aData ); + } + + return nResult; +} + + diff --git a/sc/source/core/data/dpgroup.cxx b/sc/source/core/data/dpgroup.cxx index 1bc888100a9f..e71ec5c8b82c 100644 --- a/sc/source/core/data/dpgroup.cxx +++ b/sc/source/core/data/dpgroup.cxx @@ -47,6 +47,7 @@ #include "dptabsrc.hxx" #include "dptabres.hxx" #include "dpobject.hxx" +#include "dpglobal.hxx" #include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp> #include <com/sun/star/sheet/DataPilotFieldFilter.hpp> @@ -78,6 +79,202 @@ const sal_Int32 SC_DP_DATE_FIRST = -1; const sal_Int32 SC_DP_DATE_LAST = 10000; // ============================================================================ +namespace +{ + BOOL lcl_Search( SCCOL nSourceDim, ScDPTableDataCache* pCache , const std::vector< SCROW >& vIdx, SCROW nNew , SCROW& rIndex) + { + rIndex = vIdx.size(); + BOOL bFound = FALSE; + SCROW nLo = 0; + SCROW nHi = vIdx.size() - 1; + SCROW nIndex; + long nCompare; + while (nLo <= nHi) + { + nIndex = (nLo + nHi) / 2; + + const ScDPItemData* pData = pCache->GetItemDataById( nSourceDim, vIdx[nIndex] ); + const ScDPItemData* pDataInsert = pCache->GetItemDataById( nSourceDim, nNew ); + + nCompare = ScDPItemData::Compare( *pData, *pDataInsert ); + if (nCompare < 0) + nLo = nIndex + 1; + else + { + nHi = nIndex - 1; + if (nCompare == 0) + { + bFound = TRUE; + nLo = nIndex; + } + } + } + rIndex = nLo; + return bFound; + } + + void lcl_Insert( SCCOL nSourceDim, ScDPTableDataCache* pCache , std::vector< SCROW >& vIdx, SCROW nNew ) + { + SCROW nIndex = 0; + if ( !lcl_Search( nSourceDim, pCache, vIdx, nNew ,nIndex ) ) + vIdx.insert( vIdx.begin()+nIndex, nNew ); + } + + template<bool bUpdateData> + SCROW lcl_InsertValue( SCCOL nSourceDim, ScDPTableDataCache* pCache , std::vector< SCROW >& vIdx, const ScDPItemData & rData ); + + template<> + SCROW lcl_InsertValue<false>( SCCOL nSourceDim, ScDPTableDataCache* pCache , std::vector< SCROW >& vIdx, const ScDPItemData & rData ) + { + SCROW nNewID = pCache->GetAdditionalItemID( rData ); + lcl_Insert( nSourceDim, pCache, vIdx, nNewID ); + return nNewID; + } + + template<> + SCROW lcl_InsertValue<true>( SCCOL nSourceDim, ScDPTableDataCache* pCache , std::vector< SCROW >& vIdx, const ScDPItemData & rData ) + { + SCROW nItemId = lcl_InsertValue<false>( nSourceDim, pCache, vIdx, rData ); + + if( const ScDPItemData *pData = pCache->GetItemDataById( nSourceDim, nItemId ) ) + const_cast<ScDPItemData&>(*pData) = rData; + + return nItemId; + } + + template<bool bUpdateData> + void lcl_InsertValue ( SCCOL nSourceDim, ScDPTableDataCache* pCache , std::vector< SCROW >& vIdx, const String& rString, const double& fValue ) + { + lcl_InsertValue<bUpdateData>( nSourceDim, pCache, vIdx, ScDPItemData( rString, fValue, TRUE ) ); + } + + template<bool bUpdateData> + void lcl_InsertValue ( SCCOL nSourceDim, ScDPTableDataCache* pCache , std::vector< SCROW >& vIdx, const String& rString, const double& fValue, sal_Int32 nDatePart ) + { + lcl_InsertValue<bUpdateData>( nSourceDim, pCache, vIdx, ScDPItemData( nDatePart, rString, fValue, ScDPItemData::MK_DATA|ScDPItemData::MK_VAL|ScDPItemData::MK_DATEPART ) ); + } + + void lcl_AppendDateStr( rtl::OUStringBuffer& rBuffer, double fValue, SvNumberFormatter* pFormatter ) + { + ULONG nFormat = pFormatter->GetStandardFormat( NUMBERFORMAT_DATE, ScGlobal::eLnge ); + String aString; + pFormatter->GetInputLineString( fValue, nFormat, aString ); + rBuffer.append( aString ); + } + + String lcl_GetNumGroupName( double fStartValue, const ScDPNumGroupInfo& rInfo, + bool bHasNonInteger, sal_Unicode cDecSeparator, SvNumberFormatter* pFormatter ) + { + DBG_ASSERT( cDecSeparator != 0, "cDecSeparator not initialized" ); + + double fStep = rInfo.Step; + double fEndValue = fStartValue + fStep; + if ( !bHasNonInteger && ( rInfo.DateValues || !rtl::math::approxEqual( fEndValue, rInfo.End ) ) ) + { + // The second number of the group label is + // (first number + size - 1) if there are only integer numbers, + // (first number + size) if any non-integer numbers are involved. + // Exception: The last group (containing the end value) is always + // shown as including the end value (but not for dates). + + fEndValue -= 1.0; + } + + if ( fEndValue > rInfo.End && !rInfo.AutoEnd ) + { + // limit the last group to the end value + + fEndValue = rInfo.End; + } + + rtl::OUStringBuffer aBuffer; + if ( rInfo.DateValues ) + { + lcl_AppendDateStr( aBuffer, fStartValue, pFormatter ); + aBuffer.appendAscii( " - " ); // with spaces + lcl_AppendDateStr( aBuffer, fEndValue, pFormatter ); + } + else + { + rtl::math::doubleToUStringBuffer( aBuffer, fStartValue, rtl_math_StringFormat_Automatic, + rtl_math_DecimalPlaces_Max, cDecSeparator, true ); + aBuffer.append( (sal_Unicode) '-' ); + rtl::math::doubleToUStringBuffer( aBuffer, fEndValue, rtl_math_StringFormat_Automatic, + rtl_math_DecimalPlaces_Max, cDecSeparator, true ); + } + + return aBuffer.makeStringAndClear(); + } + + String lcl_GetSpecialNumGroupName( double fValue, bool bFirst, sal_Unicode cDecSeparator, + bool bDateValues, SvNumberFormatter* pFormatter ) + { + DBG_ASSERT( cDecSeparator != 0, "cDecSeparator not initialized" ); + + rtl::OUStringBuffer aBuffer; + aBuffer.append((sal_Unicode)( bFirst ? '<' : '>' )); + if ( bDateValues ) + lcl_AppendDateStr( aBuffer, fValue, pFormatter ); + else + rtl::math::doubleToUStringBuffer( aBuffer, fValue, rtl_math_StringFormat_Automatic, + rtl_math_DecimalPlaces_Max, cDecSeparator, true ); + return aBuffer.makeStringAndClear(); + } + + inline bool IsInteger( double fValue ) + { + return rtl::math::approxEqual( fValue, rtl::math::approxFloor(fValue) ); + } + + String lcl_GetNumGroupForValue( double fValue, const ScDPNumGroupInfo& rInfo, bool bHasNonInteger, + sal_Unicode cDecSeparator, double& rGroupValue, ScDocument* pDoc ) + { + SvNumberFormatter* pFormatter = pDoc->GetFormatTable(); + + if ( fValue < rInfo.Start && !rtl::math::approxEqual( fValue, rInfo.Start ) ) + { + rGroupValue = rInfo.Start - rInfo.Step; + return lcl_GetSpecialNumGroupName( rInfo.Start, true, cDecSeparator, rInfo.DateValues, pFormatter ); + } + + if ( fValue > rInfo.End && !rtl::math::approxEqual( fValue, rInfo.End ) ) + { + rGroupValue = rInfo.End + rInfo.Step; + return lcl_GetSpecialNumGroupName( rInfo.End, false, cDecSeparator, rInfo.DateValues, pFormatter ); + } + + double fDiff = fValue - rInfo.Start; + double fDiv = rtl::math::approxFloor( fDiff / rInfo.Step ); + double fGroupStart = rInfo.Start + fDiv * rInfo.Step; + + if ( rtl::math::approxEqual( fGroupStart, rInfo.End ) && + !rtl::math::approxEqual( fGroupStart, rInfo.Start ) ) + { + if ( !rInfo.DateValues ) + { + // A group that would consist only of the end value is not created, + // instead the value is included in the last group before. So the + // previous group is used if the calculated group start value is the + // selected end value. + + fDiv -= 1.0; + fGroupStart = rInfo.Start + fDiv * rInfo.Step; + } + else + { + // For date values, the end value is instead treated as above the limit + // if it would be a group of its own. + + rGroupValue = rInfo.End + rInfo.Step; + return lcl_GetSpecialNumGroupName( rInfo.End, false, cDecSeparator, rInfo.DateValues, pFormatter ); + } + } + + rGroupValue = fGroupStart; + + return lcl_GetNumGroupName( fGroupStart, rInfo, bHasNonInteger, cDecSeparator, pFormatter ); + } +} class ScDPGroupDateFilter : public ScDPCacheTable::FilterBase { @@ -85,7 +282,10 @@ public: ScDPGroupDateFilter(double fMatchValue, sal_Int32 nDatePart, const Date* pNullDate, const ScDPNumGroupInfo* pNumInfo); - virtual bool match(const ScDPCacheCell &rCell) const; + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + virtual bool match(const ScDPItemData & rCellData) const; + // End Comments private: ScDPGroupDateFilter(); // disabled @@ -108,26 +308,25 @@ ScDPGroupDateFilter::ScDPGroupDateFilter(double fMatchValue, sal_Int32 nDatePart // fprintf(stdout, "ScDPCacheTable:DateGroupFilter::DateGroupFilter: match value = %g; date part = %ld\n", // mfMatchValue, mnDatePart); } - -bool ScDPGroupDateFilter::match(const ScDPCacheCell& rCell) const +bool ScDPGroupDateFilter::match( const ScDPItemData & rCellData ) const { using namespace ::com::sun::star::sheet; using ::rtl::math::approxFloor; using ::rtl::math::approxEqual; - if (!rCell.mbNumeric) + if ( !rCellData.IsValue() ) return false; - +// ScDPCacheCell rCell( rCellData.fValue ); if (!mpNumInfo) return false; // Start and end dates are inclusive. (An end date without a time value // is included, while an end date with a time value is not.) - if ( rCell.mfValue < mpNumInfo->Start && !approxEqual(rCell.mfValue, mpNumInfo->Start) ) + if ( rCellData.GetValue() < mpNumInfo->Start && !approxEqual(rCellData.GetValue(), mpNumInfo->Start) ) return static_cast<sal_Int32>(mfMatchValue) == SC_DP_DATE_FIRST; - if ( rCell.mfValue > mpNumInfo->End && !approxEqual(rCell.mfValue, mpNumInfo->End) ) + if ( rCellData.GetValue() > mpNumInfo->End && !approxEqual(rCellData.GetValue(), mpNumInfo->End) ) return static_cast<sal_Int32>(mfMatchValue) == SC_DP_DATE_LAST; if (mnDatePart == DataPilotFieldGroupBy::HOURS || mnDatePart == DataPilotFieldGroupBy::MINUTES || @@ -136,7 +335,7 @@ bool ScDPGroupDateFilter::match(const ScDPCacheCell& rCell) const // handle time // (as in the cell functions, ScInterpreter::ScGetHour etc.: seconds are rounded) - double time = rCell.mfValue - approxFloor(rCell.mfValue); + double time = rCellData.GetValue() - approxFloor(rCellData.GetValue()); long seconds = static_cast<long>(approxFloor(time*D_TIMEFACTOR + 0.5)); switch (mnDatePart) @@ -165,7 +364,7 @@ bool ScDPGroupDateFilter::match(const ScDPCacheCell& rCell) const return false; } - Date date = *mpNullDate + static_cast<long>(approxFloor(rCell.mfValue)); + Date date = *mpNullDate + static_cast<long>(approxFloor(rCellData.GetValue())); switch (mnDatePart) { case DataPilotFieldGroupBy::YEARS: @@ -204,17 +403,6 @@ bool ScDPGroupDateFilter::match(const ScDPCacheCell& rCell) const return false; } - -// ============================================================================ - -void lcl_AppendDateStr( rtl::OUStringBuffer& rBuffer, double fValue, SvNumberFormatter* pFormatter ) -{ - ULONG nFormat = pFormatter->GetStandardFormat( NUMBERFORMAT_DATE, ScGlobal::eLnge ); - String aString; - pFormatter->GetInputLineString( fValue, nFormat, aString ); - rBuffer.append( aString ); -} - // ----------------------------------------------------------------------- ScDPDateGroupHelper::ScDPDateGroupHelper( const ScDPNumGroupInfo& rInfo, sal_Int32 nPart ) : @@ -354,15 +542,18 @@ sal_Int32 lcl_GetDatePartValue( double fValue, sal_Int32 nDatePart, SvNumberForm BOOL lcl_DateContained( sal_Int32 nGroupPart, const ScDPItemData& rGroupData, sal_Int32 nBasePart, const ScDPItemData& rBaseData ) { - if ( !rGroupData.bHasValue || !rBaseData.bHasValue ) + if ( !rGroupData.IsValue() || !rBaseData.IsValue() ) { // non-numeric entries involved: only match equal entries return rGroupData.IsCaseInsEqual( rBaseData ); } // no approxFloor needed, values were created from integers - sal_Int32 nGroupValue = (sal_Int32) rGroupData.fValue; - sal_Int32 nBaseValue = (sal_Int32) rBaseData.fValue; +// Wang Xu Ming -- 2009-8-17 +// DataPilot Migration - Cache&&Performance + sal_Int32 nGroupValue = (sal_Int32) rGroupData.GetValue(); + sal_Int32 nBaseValue = (sal_Int32) rBaseData.GetValue(); +// End Comments if ( nBasePart > nGroupPart ) { // switch, so the base part is the smaller (inner) part @@ -417,28 +608,25 @@ String lcl_GetSpecialDateName( double fValue, bool bFirst, SvNumberFormatter* pF return aBuffer.makeStringAndClear(); } -void ScDPDateGroupHelper::FillColumnEntries( TypedScStrCollection& rEntries, const TypedScStrCollection& rOriginal, - SvNumberFormatter* pFormatter ) const +void ScDPDateGroupHelper::FillColumnEntries( SCCOL nSourceDim, ScDPTableDataCache* pCache, std::vector< SCROW >& rEntries, const std::vector< SCROW >& rOriginal ) const { // auto min/max is only used for "Years" part, but the loop is always needed double fSourceMin = 0.0; double fSourceMax = 0.0; bool bFirst = true; - USHORT nOriginalCount = rOriginal.GetCount(); - for (USHORT nOriginalPos=0; nOriginalPos<nOriginalCount; nOriginalPos++) + size_t nOriginalCount = rOriginal.size(); + for (size_t nOriginalPos=0; nOriginalPos<nOriginalCount; nOriginalPos++) { - const TypedStrData& rStrData = *rOriginal[nOriginalPos]; - if ( rStrData.IsStrData() ) + const ScDPItemData* pItemData = pCache->GetItemDataById( nSourceDim, rOriginal[nOriginalPos] ); + if ( pItemData->HasStringData() ) { // string data: just copy - TypedStrData* pNew = new TypedStrData( rStrData ); - if ( !rEntries.Insert( pNew ) ) - delete pNew; + lcl_Insert( nSourceDim, pCache , rEntries, rOriginal[nOriginalPos] ); } else { - double fSourceValue = rStrData.GetValue(); + double fSourceValue = pItemData->GetValue(); if ( bFirst ) { fSourceMin = fSourceMax = fSourceValue; @@ -462,6 +650,7 @@ void ScDPDateGroupHelper::FillColumnEntries( TypedScStrCollection& rEntries, con const_cast<ScDPDateGroupHelper*>(this)->aNumInfo.End = rtl::math::approxFloor( fSourceMax ) + 1; //! if not automatic, limit fSourceMin/fSourceMax for list of year values? + SvNumberFormatter* pFormatter = pCache->GetDoc()->GetFormatTable(); long nStart = 0; long nEnd = 0; // including @@ -485,22 +674,15 @@ void ScDPDateGroupHelper::FillColumnEntries( TypedScStrCollection& rEntries, con for ( sal_Int32 nValue = nStart; nValue <= nEnd; nValue++ ) { String aName = lcl_GetDateGroupName( nDatePart, nValue, pFormatter ); - TypedStrData* pNew = new TypedStrData( aName, nValue, SC_STRTYPE_VALUE ); - if ( !rEntries.Insert( pNew ) ) - delete pNew; + lcl_InsertValue<false>( nSourceDim, pCache, rEntries, aName, nValue, nDatePart ); } // add first/last entry (min/max) - String aFirstName = lcl_GetSpecialDateName( aNumInfo.Start, true, pFormatter ); - TypedStrData* pFirstEntry = new TypedStrData( aFirstName, SC_DP_DATE_FIRST, SC_STRTYPE_VALUE ); - if ( !rEntries.Insert( pFirstEntry ) ) - delete pFirstEntry; + lcl_InsertValue<true>( nSourceDim, pCache, rEntries, aFirstName, SC_DP_DATE_FIRST, nDatePart ); String aLastName = lcl_GetSpecialDateName( aNumInfo.End, false, pFormatter ); - TypedStrData* pLastEntry = new TypedStrData( aLastName, SC_DP_DATE_LAST, SC_STRTYPE_VALUE ); - if ( !rEntries.Insert( pLastEntry ) ) - delete pLastEntry; + lcl_InsertValue<true>( nSourceDim, pCache, rEntries, aLastName, SC_DP_DATE_LAST, nDatePart ); } // ----------------------------------------------------------------------- @@ -541,7 +723,10 @@ void ScDPGroupItem::FillGroupFilter( ScDPCacheTable::GroupFilter& rFilter ) cons { ScDPItemDataVec::const_iterator itrEnd = aElements.end(); for (ScDPItemDataVec::const_iterator itr = aElements.begin(); itr != itrEnd; ++itr) - rFilter.addMatchItem(itr->aString, itr->fValue, itr->bHasValue); +// Wang Xu Ming -- 2009-8-17 +// DataPilot Migration - Cache&&Performance + rFilter.addMatchItem(itr->GetString(), itr->GetValue(), itr->IsValue()); +// End Comments } // ----------------------------------------------------------------------- @@ -550,15 +735,15 @@ ScDPGroupDimension::ScDPGroupDimension( long nSource, const String& rNewName ) : nSourceDim( nSource ), nGroupDim( -1 ), aGroupName( rNewName ), - pDateHelper( NULL ), - pCollection( NULL ) + pDateHelper( NULL )/*, + pCollection( NULL )*/ { } ScDPGroupDimension::~ScDPGroupDimension() { delete pDateHelper; - delete pCollection; + maMemberEntries.clear(); } ScDPGroupDimension::ScDPGroupDimension( const ScDPGroupDimension& rOther ) : @@ -566,8 +751,7 @@ ScDPGroupDimension::ScDPGroupDimension( const ScDPGroupDimension& rOther ) : nGroupDim( rOther.nGroupDim ), aGroupName( rOther.aGroupName ), pDateHelper( NULL ), - aItems( rOther.aItems ), - pCollection( NULL ) // collection isn't copied - allocated on demand + aItems( rOther.aItems ) { if ( rOther.pDateHelper ) pDateHelper = new ScDPDateGroupHelper( *rOther.pDateHelper ); @@ -586,8 +770,6 @@ ScDPGroupDimension& ScDPGroupDimension::operator=( const ScDPGroupDimension& rOt else pDateHelper = NULL; - delete pCollection; // collection isn't copied - allocated on demand - pCollection = NULL; return *this; } @@ -606,44 +788,42 @@ void ScDPGroupDimension::SetGroupDim( long nDim ) { nGroupDim = nDim; } - -const TypedScStrCollection& ScDPGroupDimension::GetColumnEntries( - const TypedScStrCollection& rOriginal, ScDocument* pDoc ) const +// Wang Xu Ming -- 2009-9-2 +// DataPilot Migration - Cache&&Performance +const std::vector< SCROW >& ScDPGroupDimension::GetColumnEntries( const ScDPCacheTable& rCacheTable, const std::vector< SCROW >& rOriginal ) const { - if ( !pCollection ) + if ( maMemberEntries.empty() ) { - pCollection = new TypedScStrCollection(); if ( pDateHelper ) - pDateHelper->FillColumnEntries( *pCollection, rOriginal, pDoc->GetFormatTable() ); + { + pDateHelper->FillColumnEntries( (SCCOL)GetSourceDim(), rCacheTable.GetCache(), maMemberEntries, rOriginal ); + } else { - long nCount = aItems.size(); - for (long i=0; i<nCount; i++) + for (size_t i =0; i < rOriginal.size( ); i ++) { - //! numeric entries? - TypedStrData* pNew = new TypedStrData( aItems[i].GetName().aString ); - if ( !pCollection->Insert( pNew ) ) - delete pNew; - } - - USHORT nOriginalCount = rOriginal.GetCount(); - for (USHORT nOriginalPos=0; nOriginalPos<nOriginalCount; nOriginalPos++) - { - const TypedStrData& rStrData = *rOriginal[nOriginalPos]; - ScDPItemData aItemData( rStrData.GetString(), rStrData.GetValue(), !rStrData.IsStrData() ); - if ( !GetGroupForData( aItemData ) ) + const ScDPItemData* pItemData = rCacheTable.GetCache()->GetItemDataById( (SCCOL)GetSourceDim(), rOriginal[i] ); + if ( !pItemData || !GetGroupForData( *pItemData ) ) { // not in any group -> add as its own group - TypedStrData* pNew = new TypedStrData( rStrData ); - if ( !pCollection->Insert( pNew ) ) - delete pNew; + maMemberEntries.push_back( rOriginal[i] ); } } + + long nCount = aItems.size(); + for (long i=0; i<nCount; i++) + { + SCROW nNew = rCacheTable.GetCache()->GetAdditionalItemID( aItems[i].GetName() ); + lcl_Insert ( (SCCOL)GetSourceDim(), rCacheTable.GetCache(), maMemberEntries, nNew ); + } } } - return *pCollection; + return maMemberEntries; } +// End Comments + + const ScDPGroupItem* ScDPGroupDimension::GetGroupForData( const ScDPItemData& rData ) const { for ( ScDPGroupItemVec::const_iterator aIter(aItems.begin()); aIter != aItems.end(); aIter++ ) @@ -672,15 +852,13 @@ const ScDPGroupItem* ScDPGroupDimension::GetGroupByIndex( size_t nIndex ) const void ScDPGroupDimension::DisposeData() { - delete pCollection; - pCollection = NULL; + maMemberEntries.clear(); } // ----------------------------------------------------------------------- ScDPNumGroupDimension::ScDPNumGroupDimension() : pDateHelper( NULL ), - pCollection( NULL ), bHasNonInteger( false ), cDecSeparator( 0 ) { @@ -689,7 +867,6 @@ ScDPNumGroupDimension::ScDPNumGroupDimension() : ScDPNumGroupDimension::ScDPNumGroupDimension( const ScDPNumGroupInfo& rInfo ) : aGroupInfo( rInfo ), pDateHelper( NULL ), - pCollection( NULL ), bHasNonInteger( false ), cDecSeparator( 0 ) { @@ -698,7 +875,6 @@ ScDPNumGroupDimension::ScDPNumGroupDimension( const ScDPNumGroupInfo& rInfo ) : ScDPNumGroupDimension::ScDPNumGroupDimension( const ScDPNumGroupDimension& rOther ) : aGroupInfo( rOther.aGroupInfo ), pDateHelper( NULL ), - pCollection( NULL ), // collection isn't copied - allocated on demand bHasNonInteger( false ), cDecSeparator( 0 ) { @@ -716,23 +892,19 @@ ScDPNumGroupDimension& ScDPNumGroupDimension::operator=( const ScDPNumGroupDimen else pDateHelper = NULL; - delete pCollection; // collection isn't copied - allocated on demand - pCollection = NULL; bHasNonInteger = false; return *this; } void ScDPNumGroupDimension::DisposeData() { - delete pCollection; - pCollection = NULL; bHasNonInteger = false; + maMemberEntries.clear(); } ScDPNumGroupDimension::~ScDPNumGroupDimension() { delete pDateHelper; - delete pCollection; } void ScDPNumGroupDimension::MakeDateHelper( const ScDPNumGroupInfo& rInfo, sal_Int32 nPart ) @@ -743,80 +915,15 @@ void ScDPNumGroupDimension::MakeDateHelper( const ScDPNumGroupInfo& rInfo, sal_I aGroupInfo.Enable = sal_True; //! or query both? } -String lcl_GetNumGroupName( double fStartValue, const ScDPNumGroupInfo& rInfo, - bool bHasNonInteger, sal_Unicode cDecSeparator, SvNumberFormatter* pFormatter ) -{ - DBG_ASSERT( cDecSeparator != 0, "cDecSeparator not initialized" ); - - double fStep = rInfo.Step; - double fEndValue = fStartValue + fStep; - if ( !bHasNonInteger && ( rInfo.DateValues || !rtl::math::approxEqual( fEndValue, rInfo.End ) ) ) - { - // The second number of the group label is - // (first number + size - 1) if there are only integer numbers, - // (first number + size) if any non-integer numbers are involved. - // Exception: The last group (containing the end value) is always - // shown as including the end value (but not for dates). - - fEndValue -= 1.0; - } - - if ( fEndValue > rInfo.End && !rInfo.AutoEnd ) - { - // limit the last group to the end value - - fEndValue = rInfo.End; - } - - rtl::OUStringBuffer aBuffer; - if ( rInfo.DateValues ) - { - lcl_AppendDateStr( aBuffer, fStartValue, pFormatter ); - aBuffer.appendAscii( " - " ); // with spaces - lcl_AppendDateStr( aBuffer, fEndValue, pFormatter ); - } - else - { - rtl::math::doubleToUStringBuffer( aBuffer, fStartValue, rtl_math_StringFormat_Automatic, - rtl_math_DecimalPlaces_Max, cDecSeparator, true ); - aBuffer.append( (sal_Unicode) '-' ); - rtl::math::doubleToUStringBuffer( aBuffer, fEndValue, rtl_math_StringFormat_Automatic, - rtl_math_DecimalPlaces_Max, cDecSeparator, true ); - } - - return aBuffer.makeStringAndClear(); -} - -String lcl_GetSpecialNumGroupName( double fValue, bool bFirst, sal_Unicode cDecSeparator, - bool bDateValues, SvNumberFormatter* pFormatter ) +const std::vector< SCROW >& ScDPNumGroupDimension::GetNumEntries( SCCOL nSourceDim, ScDPTableDataCache* pCache, + const std::vector< SCROW >& rOriginal ) const { - DBG_ASSERT( cDecSeparator != 0, "cDecSeparator not initialized" ); - - rtl::OUStringBuffer aBuffer; - aBuffer.append((sal_Unicode)( bFirst ? '<' : '>' )); - if ( bDateValues ) - lcl_AppendDateStr( aBuffer, fValue, pFormatter ); - else - rtl::math::doubleToUStringBuffer( aBuffer, fValue, rtl_math_StringFormat_Automatic, - rtl_math_DecimalPlaces_Max, cDecSeparator, true ); - return aBuffer.makeStringAndClear(); -} - -inline bool IsInteger( double fValue ) -{ - return rtl::math::approxEqual( fValue, rtl::math::approxFloor(fValue) ); -} - -const TypedScStrCollection& ScDPNumGroupDimension::GetNumEntries( - const TypedScStrCollection& rOriginal, ScDocument* pDoc ) const -{ - if ( !pCollection ) + if ( maMemberEntries.empty() ) { - SvNumberFormatter* pFormatter = pDoc->GetFormatTable(); + SvNumberFormatter* pFormatter = pCache->GetDoc()->GetFormatTable(); - pCollection = new TypedScStrCollection(); if ( pDateHelper ) - pDateHelper->FillColumnEntries( *pCollection, rOriginal, pFormatter ); + pDateHelper->FillColumnEntries( nSourceDim, pCache, maMemberEntries,rOriginal ); else { // Copy textual entries. @@ -835,39 +942,37 @@ const TypedScStrCollection& ScDPNumGroupDimension::GetNumEntries( double fSourceMax = 0.0; bool bFirst = true; - USHORT nOriginalCount = rOriginal.GetCount(); - for (USHORT nOriginalPos=0; nOriginalPos<nOriginalCount; nOriginalPos++) + size_t nOriginalCount = rOriginal.size(); + for (size_t nOriginalPos=0; nOriginalPos<nOriginalCount; nOriginalPos++) { - const TypedStrData& rStrData = *rOriginal[nOriginalPos]; - if ( rStrData.IsStrData() ) - { - // string data: just copy - TypedStrData* pNew = new TypedStrData( rStrData ); - if ( !pCollection->Insert( pNew ) ) - delete pNew; - } - else - { - double fSourceValue = rStrData.GetValue(); - if ( bFirst ) - { - fSourceMin = fSourceMax = fSourceValue; - bFirst = false; - } - else - { - if ( fSourceValue < fSourceMin ) - fSourceMin = fSourceValue; - if ( fSourceValue > fSourceMax ) - fSourceMax = fSourceValue; - } - if ( !bHasNonInteger && !IsInteger( fSourceValue ) ) - { - // if any non-integer numbers are involved, the group labels are - // shown including their upper limit - bHasNonInteger = true; - } - } + const ScDPItemData* pItemData = pCache->GetItemDataById( nSourceDim , rOriginal[nOriginalPos] ); + + if ( pItemData && pItemData ->HasStringData() ) + { + lcl_Insert( nSourceDim, pCache, maMemberEntries, rOriginal[nOriginalPos] ); + } + else + { + double fSourceValue = pItemData->GetValue(); + if ( bFirst ) + { + fSourceMin = fSourceMax = fSourceValue; + bFirst = false; + } + else + { + if ( fSourceValue < fSourceMin ) + fSourceMin = fSourceValue; + if ( fSourceValue > fSourceMax ) + fSourceMax = fSourceValue; + } + if ( !bHasNonInteger && !IsInteger( fSourceValue ) ) + { + // if any non-integer numbers are involved, the group labels are + // shown including their upper limit + bHasNonInteger = true; + } + } } if ( aGroupInfo.DateValues ) @@ -899,10 +1004,7 @@ const TypedScStrCollection& ScDPNumGroupDimension::GetNumEntries( String aName = lcl_GetNumGroupName( fLoop, aGroupInfo, bHasNonInteger, cDecSeparator, pFormatter ); // create a numerical entry to ensure proper sorting // (in FillMemberResults this needs special handling) - TypedStrData* pNew = new TypedStrData( aName, fLoop, SC_STRTYPE_VALUE ); - if ( !pCollection->Insert( pNew ) ) - delete pNew; - + lcl_InsertValue<true>( nSourceDim, pCache, maMemberEntries, aName, fLoop ); ++nLoopCount; fLoop = aGroupInfo.Start + nLoopCount * aGroupInfo.Step; bFirstGroup = false; @@ -911,72 +1013,17 @@ const TypedScStrCollection& ScDPNumGroupDimension::GetNumEntries( } String aFirstName = lcl_GetSpecialNumGroupName( aGroupInfo.Start, true, cDecSeparator, aGroupInfo.DateValues, pFormatter ); - TypedStrData* pFirstEntry = new TypedStrData( aFirstName, aGroupInfo.Start - aGroupInfo.Step, SC_STRTYPE_VALUE ); - if ( !pCollection->Insert( pFirstEntry ) ) - delete pFirstEntry; + lcl_InsertValue<true>( nSourceDim, pCache, maMemberEntries, aFirstName, aGroupInfo.Start - aGroupInfo.Step ); String aLastName = lcl_GetSpecialNumGroupName( aGroupInfo.End, false, cDecSeparator, aGroupInfo.DateValues, pFormatter ); - TypedStrData* pLastEntry = new TypedStrData( aLastName, aGroupInfo.End + aGroupInfo.Step, SC_STRTYPE_VALUE ); - if ( !pCollection->Insert( pLastEntry ) ) - delete pLastEntry; - } - } - return *pCollection; -} - -// ----------------------------------------------------------------------- - -String lcl_GetNumGroupForValue( double fValue, const ScDPNumGroupInfo& rInfo, bool bHasNonInteger, - sal_Unicode cDecSeparator, double& rGroupValue, ScDocument* pDoc ) -{ - SvNumberFormatter* pFormatter = pDoc->GetFormatTable(); - - if ( fValue < rInfo.Start && !rtl::math::approxEqual( fValue, rInfo.Start ) ) - { - rGroupValue = rInfo.Start - rInfo.Step; - return lcl_GetSpecialNumGroupName( rInfo.Start, true, cDecSeparator, rInfo.DateValues, pFormatter ); - } - - if ( fValue > rInfo.End && !rtl::math::approxEqual( fValue, rInfo.End ) ) - { - rGroupValue = rInfo.End + rInfo.Step; - return lcl_GetSpecialNumGroupName( rInfo.End, false, cDecSeparator, rInfo.DateValues, pFormatter ); - } - - double fDiff = fValue - rInfo.Start; - double fDiv = rtl::math::approxFloor( fDiff / rInfo.Step ); - double fGroupStart = rInfo.Start + fDiv * rInfo.Step; - - if ( rtl::math::approxEqual( fGroupStart, rInfo.End ) && - !rtl::math::approxEqual( fGroupStart, rInfo.Start ) ) - { - if ( !rInfo.DateValues ) - { - // A group that would consist only of the end value is not created, - // instead the value is included in the last group before. So the - // previous group is used if the calculated group start value is the - // selected end value. - - fDiv -= 1.0; - fGroupStart = rInfo.Start + fDiv * rInfo.Step; - } - else - { - // For date values, the end value is instead treated as above the limit - // if it would be a group of its own. - - rGroupValue = rInfo.End + rInfo.Step; - return lcl_GetSpecialNumGroupName( rInfo.End, false, cDecSeparator, rInfo.DateValues, pFormatter ); + lcl_InsertValue<true>( nSourceDim, pCache, maMemberEntries, aLastName, aGroupInfo.End + aGroupInfo.Step ); } } - - rGroupValue = fGroupStart; - - return lcl_GetNumGroupName( fGroupStart, rInfo, bHasNonInteger, cDecSeparator, pFormatter ); + return maMemberEntries; } ScDPGroupTableData::ScDPGroupTableData( const shared_ptr<ScDPTableData>& pSource, ScDocument* pDocument ) : - ScDPTableData(pDocument), + ScDPTableData(pDocument, pSource->GetCacheId() ), pSourceData( pSource ), pDoc( pDocument ) { @@ -1015,7 +1062,6 @@ long ScDPGroupTableData::GetDimensionIndex( const String& rName ) for (long i=0; i<nSourceCount; i++) // nSourceCount excludes data layout if ( pSourceData->getDimensionName(i) == rName ) //! ignore case? return i; - return -1; // none } @@ -1039,36 +1085,53 @@ void ScDPGroupTableData::GetNumGroupInfo( long nDimension, ScDPNumGroupInfo& rIn rDecimal = pNumGroups[nDimension].GetDecSeparator(); } } - -const TypedScStrCollection& ScDPGroupTableData::GetColumnEntries(long nColumn) +// Wang Xu Ming - DataPilot migration +long ScDPGroupTableData::GetMembersCount( long nDim ) +{ + const std::vector< SCROW >& members = GetColumnEntries( nDim ); + return members.size(); +} +const std::vector< SCROW >& ScDPGroupTableData::GetColumnEntries( long nColumn ) { - // date handling is in ScDPGroupDimension::GetColumnEntries / ScDPNumGroupDimension::GetNumEntries - // (to use the pCollection members) - if ( nColumn >= nSourceCount ) { - if ( nColumn == sal::static_int_cast<long>( nSourceCount + aGroups.size() ) ) // data layout dimension? + if ( getIsDataLayoutDimension( nColumn) ) // data layout dimension? nColumn = nSourceCount; // index of data layout in source data else { const ScDPGroupDimension& rGroupDim = aGroups[nColumn - nSourceCount]; long nSourceDim = rGroupDim.GetSourceDim(); // collection is cached at pSourceData, GetColumnEntries can be called every time - const TypedScStrCollection& rOriginal = pSourceData->GetColumnEntries( nSourceDim ); - return rGroupDim.GetColumnEntries( rOriginal, pDoc ); + const std::vector< SCROW >& rOriginal = pSourceData->GetColumnEntries( nSourceDim ); + return rGroupDim.GetColumnEntries( GetCacheTable(), rOriginal ); } } if ( IsNumGroupDimension( nColumn ) ) { // dimension number is unchanged for numerical groups - const TypedScStrCollection& rOriginal = pSourceData->GetColumnEntries( nColumn ); - return pNumGroups[nColumn].GetNumEntries( rOriginal, pDoc ); + const std::vector< SCROW >& rOriginal = pSourceData->GetColumnEntries( nColumn ); + return pNumGroups[nColumn].GetNumEntries( (SCCOL)nColumn, GetCacheTable().GetCache(), rOriginal ); } return pSourceData->GetColumnEntries( nColumn ); } +const ScDPItemData* ScDPGroupTableData::GetMemberById( long nDim, long nId ) +{ + if ( nDim >= nSourceCount ) + { + if ( getIsDataLayoutDimension( nDim) ) + nDim = nSourceCount; + else + { + const ScDPGroupDimension& rGroupDim = aGroups[nDim - nSourceCount]; + nDim = rGroupDim.GetSourceDim(); + } + } + return pSourceData->GetMemberById( nDim, nId ); +} + String ScDPGroupTableData::getDimensionName(long nColumn) { if ( nColumn >= nSourceCount ) @@ -1101,7 +1164,7 @@ BOOL ScDPGroupTableData::IsDateDimension(long nDim) return pSourceData->IsDateDimension( nDim ); } -UINT32 ScDPGroupTableData::GetNumberFormat(long nDim) +ULONG ScDPGroupTableData::GetNumberFormat(long nDim) { if ( nDim >= nSourceCount ) { @@ -1220,16 +1283,19 @@ void ScDPGroupTableData::ModifyFilterCriteria(vector<ScDPCacheTable::Criterion>& for (size_t i = 0; i < nGroupItemCount; ++i) { const ScDPGroupItem* pGrpItem = pGrpDim->GetGroupByIndex(i); - ScDPItemData aName; - aName.aString = pFilter->getMatchString(); + // Wang Xu Ming -- 2009-6-9 + // DataPilot Migration + ScDPItemData aName( pFilter->getMatchString(),pFilter->getMatchValue(),pFilter->hasValue()) ; + /*aName.aString = pFilter->getMatchString(); aName.fValue = pFilter->getMatchValue(); - aName.bHasValue = pFilter->hasValue(); - if (!pGrpItem || !pGrpItem->GetName().IsCaseInsEqual(aName)) + aName.bHasValue = pFilter->hasValue();*/ + // End Comments + if (!pGrpItem || !pGrpItem->GetName().IsCaseInsEqual(aName)) continue; ScDPCacheTable::Criterion aCri; aCri.mnFieldIndex = nSrcDim; - aCri.mpFilter.reset(new ScDPCacheTable::GroupFilter(GetSharedString())); + aCri.mpFilter.reset(new ScDPCacheTable::GroupFilter()); ScDPCacheTable::GroupFilter* pGrpFilter = static_cast<ScDPCacheTable::GroupFilter*>(aCri.mpFilter.get()); @@ -1321,25 +1387,27 @@ void ScDPGroupTableData::CopyFields(const vector<long>& rFieldDims, vector<long> } } -void ScDPGroupTableData::FillGroupValues( ScDPItemData* pItemData, long nCount, const long* pDims ) +void ScDPGroupTableData::FillGroupValues( /*ScDPItemData* pItemData*/ SCROW* pItemDataIndex, long nCount, const long* pDims ) { long nGroupedColumns = aGroups.size(); + ScDPTableDataCache* pCache = GetCacheTable().GetCache(); for (long nDim=0; nDim<nCount; nDim++) { const ScDPDateGroupHelper* pDateHelper = NULL; long nColumn = pDims[nDim]; + long nSourceDim = nColumn; if ( nColumn >= nSourceCount && nColumn < nSourceCount + nGroupedColumns ) { const ScDPGroupDimension& rGroupDim = aGroups[nColumn - nSourceCount]; + nSourceDim= rGroupDim.GetSourceDim(); pDateHelper = rGroupDim.GetDateHelper(); if ( !pDateHelper ) // date is handled below { - const ScDPGroupItem* pGroupItem = rGroupDim.GetGroupForData( pItemData[nDim] ); - if ( pGroupItem ) - pItemData[nDim] = pGroupItem->GetName(); - // if no group is found, keep the original name + const ScDPGroupItem* pGroupItem = rGroupDim.GetGroupForData( *GetMemberById( nSourceDim, pItemDataIndex[nDim] )); + if ( pGroupItem ) + pItemDataIndex[nDim] = pCache->GetAdditionalItemID( pGroupItem->GetName() ); } } else if ( IsNumGroupDimension( nColumn ) ) @@ -1347,18 +1415,18 @@ void ScDPGroupTableData::FillGroupValues( ScDPItemData* pItemData, long nCount, pDateHelper = pNumGroups[nColumn].GetDateHelper(); if ( !pDateHelper ) // date is handled below { - if ( pItemData[nDim].bHasValue ) + const ScDPItemData* pData = pCache->GetItemDataById( (SCCOL)nSourceDim, pItemDataIndex[nDim]); + if ( pData ->IsValue() ) { ScDPNumGroupInfo aNumInfo; bool bHasNonInteger = false; sal_Unicode cDecSeparator = 0; GetNumGroupInfo( nColumn, aNumInfo, bHasNonInteger, cDecSeparator ); double fGroupValue; - String aGroupName = lcl_GetNumGroupForValue( pItemData[nDim].fValue, - aNumInfo, bHasNonInteger, cDecSeparator, fGroupValue, pDoc ); - - // consistent with TypedStrData in GetNumEntries - pItemData[nDim] = ScDPItemData( aGroupName, fGroupValue, TRUE ); + String aGroupName = lcl_GetNumGroupForValue( pData->GetValue(), + aNumInfo, bHasNonInteger, cDecSeparator, fGroupValue, pDoc ); + ScDPItemData aItemData ( aGroupName, fGroupValue, TRUE ) ; + pItemDataIndex[nDim] = pCache->GetAdditionalItemID( aItemData ); } // else (textual) keep original value } @@ -1366,12 +1434,18 @@ void ScDPGroupTableData::FillGroupValues( ScDPItemData* pItemData, long nCount, if ( pDateHelper ) { - if ( pItemData[nDim].bHasValue ) + const ScDPItemData* pData = GetCacheTable().GetCache()->GetItemDataById( (SCCOL)nSourceDim, pItemDataIndex[nDim]); + if ( pData ->IsValue() ) { sal_Int32 nPartValue = lcl_GetDatePartValue( - pItemData[nDim].fValue, pDateHelper->GetDatePart(), pDoc->GetFormatTable(), - &pDateHelper->GetNumInfo() ); - pItemData[nDim] = ScDPItemData( String(), nPartValue, TRUE ); + pData->GetValue(), pDateHelper->GetDatePart(), pDoc->GetFormatTable(), + &pDateHelper->GetNumInfo() ); +// Wang Xu Ming -- 2009-9-7 +// DataPilot Migration - Cache&&Performance + //String aName = lcl_GetDateGroupName( pDateHelper, nPartValue, pDoc->GetFormatTable() ); + ScDPItemData aItemData( pDateHelper->GetDatePart(), String(), nPartValue, ScDPItemData::MK_DATA|ScDPItemData::MK_VAL|ScDPItemData::MK_DATEPART ); + pItemDataIndex[nDim] = GetCacheTable().GetCache()->GetAdditionalItemID( aItemData ); +// End Comments } } } @@ -1527,5 +1601,22 @@ BOOL ScDPGroupTableData::HasCommonElement( const ScDPItemData& rFirstData, long return TRUE; } +long ScDPGroupTableData::GetSourceDim( long nDim ) +{ + if ( getIsDataLayoutDimension( nDim ) ) + return nSourceCount; + if ( nDim >= nSourceCount && nDim < nSourceCount +(long) aGroups.size() ) + { + const ScDPGroupDimension& rGroupDim = aGroups[nDim - nSourceCount]; + return rGroupDim.GetSourceDim(); + } + return nDim; +} + long ScDPGroupTableData::Compare( long nDim, long nDataId1, long nDataId2) +{ + if ( getIsDataLayoutDimension(nDim) ) + return 0; + return ScDPItemData::Compare( *GetMemberById(nDim, nDataId1),*GetMemberById(nDim, nDataId2) ); +} // ----------------------------------------------------------------------- diff --git a/sc/source/core/data/dpobject.cxx b/sc/source/core/data/dpobject.cxx index 7d1dd85c0a25..44c998fb4ede 100644..100755 --- a/sc/source/core/data/dpobject.cxx +++ b/sc/source/core/data/dpobject.cxx @@ -52,7 +52,11 @@ #include "attrib.hxx" #include "scitems.hxx" #include "unonames.hxx" - +// Wang Xu Ming -- 2009-8-17 +// DataPilot Migration - Cache&&Performance +#include "dpglobal.hxx" +#include "globstr.hrc" +// End Comments #include <com/sun/star/beans/XPropertySet.hpp> #include <com/sun/star/sheet/GeneralFunction.hpp> #include <com/sun/star/sheet/DataPilotFieldFilter.hpp> @@ -86,9 +90,6 @@ using ::com::sun::star::sheet::DataPilotTablePositionData; using ::com::sun::star::beans::XPropertySet; using ::rtl::OUString; -// ----------------------------------------------------------------------- - -#define MAX_LABELS 256 //!!! from fieldwnd.hxx, must be moved to global.hxx // ----------------------------------------------------------------------- @@ -168,7 +169,9 @@ ScDPObject::ScDPObject( ScDocument* pD ) : mnAutoFormatIndex( 65535 ), bAllowMove( FALSE ), nHeaderRows( 0 ), - mbHeaderLayout(false) + mbHeaderLayout(false), + bRefresh( FALSE ), // Wang Xu Ming - DataPilot migration + mnCacheId( -1) // Wang Xu Ming - DataPilot migration { } @@ -189,7 +192,9 @@ ScDPObject::ScDPObject(const ScDPObject& r) : mnAutoFormatIndex( r.mnAutoFormatIndex ), bAllowMove( FALSE ), nHeaderRows( r.nHeaderRows ), - mbHeaderLayout( r.mbHeaderLayout ) + mbHeaderLayout( r.mbHeaderLayout ), + bRefresh( r.bRefresh ), // Wang Xu Ming - DataPilot migration + mnCacheId ( r.mnCacheId ) // Wang Xu Ming - DataPilot migration { if (r.pSaveData) pSaveData = new ScDPSaveData(*r.pSaveData); @@ -209,6 +214,7 @@ ScDPObject::~ScDPObject() delete pSheetDesc; delete pImpDesc; delete pServDesc; + mnCacheId = -1; // Wang Xu Ming - DataPilot migration } ScDataObject* ScDPObject::Clone() const @@ -232,6 +238,13 @@ void ScDPObject::SetSaveData(const ScDPSaveData& rData) { delete pSaveData; pSaveData = new ScDPSaveData( rData ); + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + if ( rData.GetCacheId() >= 0 ) + mnCacheId = rData.GetCacheId(); + else if ( mnCacheId >= 0 ) + pSaveData->SetCacheId( mnCacheId ); + // End Comments } InvalidateData(); // re-init source from SaveData @@ -411,10 +424,11 @@ ScDPTableData* ScDPObject::GetTableData() { if (!mpTableData) { + shared_ptr<ScDPTableData> pData; if ( pImpDesc ) { // database data - mpTableData.reset(new ScDatabaseDPData(pDoc, *pImpDesc)); + pData.reset(new ScDatabaseDPData(pDoc, *pImpDesc, GetCacheId())); } else { @@ -424,16 +438,27 @@ ScDPTableData* ScDPObject::GetTableData() DBG_ERROR("no source descriptor"); pSheetDesc = new ScSheetSourceDesc; // dummy defaults } - mpTableData.reset(new ScSheetDPData(pDoc, *pSheetDesc)); + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + pData.reset(new ScSheetDPData(pDoc, *pSheetDesc, GetCacheId())); + // End Comments } // grouping (for cell or database data) if ( pSaveData && pSaveData->GetExistingDimensionData() ) { - shared_ptr<ScDPGroupTableData> pGroupData(new ScDPGroupTableData(mpTableData, pDoc)); + shared_ptr<ScDPGroupTableData> pGroupData(new ScDPGroupTableData(pData, pDoc)); pSaveData->GetExistingDimensionData()->WriteToData(*pGroupData); - mpTableData = pGroupData; + pData = pGroupData; } + + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + if ( pData ) + SetCacheId( pData->GetCacheId()); // resets mpTableData + // End Comments + + mpTableData = pData; // after SetCacheId } return mpTableData.get(); @@ -462,11 +487,17 @@ void ScDPObject::CreateObjects() { DBG_ASSERT( !pServDesc, "DPSource could not be created" ); ScDPTableData* pData = GetTableData(); + ScDPSource* pSource = new ScDPSource( pData ); xSource = pSource; - } - if (pSaveData) + if ( pSaveData && bRefresh ) + { + pSaveData->Refresh( xSource ); + bRefresh = FALSE; + } + } + if (pSaveData ) pSaveData->WriteToSource( xSource ); } else if (bSettingsChanged) @@ -2298,48 +2329,6 @@ uno::Reference<sheet::XDimensionsSupplier> ScDPObject::CreateSource( const ScDPS return xRet; } -// ============================================================================ - -ScDPCacheCell::ScDPCacheCell() : - mnStrId(ScSimpleSharedString::EMPTY), - mnType(SC_VALTYPE_EMPTY), - mfValue(0.0), - mbNumeric(false) -{ -} - -ScDPCacheCell::ScDPCacheCell(const ScDPCacheCell& r) : - mnStrId(r.mnStrId), - mnType(r.mnType), - mfValue(r.mfValue), - mbNumeric(r.mbNumeric) -{ -} - -ScDPCacheCell::~ScDPCacheCell() -{ -} - -// ============================================================================ - -size_t ScDPCollection::CacheCellHash::operator()(const ScDPCacheCell* pCell) const -{ - return pCell->mnStrId + static_cast<size_t>(pCell->mnType) + - static_cast<size_t>(pCell->mfValue) + static_cast<size_t>(pCell->mbNumeric); -} - -bool ScDPCollection::CacheCellEqual::operator()(const ScDPCacheCell* p1, const ScDPCacheCell* p2) const -{ - if (!p1 && !p2) - return true; - - if ((!p1 && p2) || (p1 && !p2)) - return false; - - return p1->mnStrId == p2->mnStrId && p1->mfValue == p2->mfValue && - p1->mbNumeric == p2->mbNumeric && p1->mnType == p2->mnType; -} - // ---------------------------------------------------------------------------- ScDPCollection::ScDPCollection(ScDocument* pDocument) : @@ -2349,15 +2338,12 @@ ScDPCollection::ScDPCollection(ScDocument* pDocument) : ScDPCollection::ScDPCollection(const ScDPCollection& r) : ScCollection(r), - pDoc(r.pDoc), - maSharedString(r.maSharedString), - maCacheCellPool() // #i101725# don't copy hash_set with pointers from the other collection + pDoc(r.pDoc) { } ScDPCollection::~ScDPCollection() { - clearCacheCellPool(); } ScDataObject* ScDPCollection::Clone() const @@ -2462,10 +2448,83 @@ String ScDPCollection::CreateNewName( USHORT nMin ) const return String(); // should not happen } -ScSimpleSharedString& ScDPCollection::GetSharedString() + + +// Wang Xu Ming -- 2009-8-17 +// DataPilot Migration - Cache&&Performance +long ScDPObject::GetCacheId() const +{ + if ( GetSaveData() ) + return GetSaveData()->GetCacheId(); + else + return mnCacheId; +} +ULONG ScDPObject::RefreshCache() +{ + if ( pServDesc ) + { + // cache table isn't used for external service - do nothing, no error + return 0; + } + + CreateObjects(); + ULONG nErrId = 0; + if ( pSheetDesc) + nErrId = pSheetDesc->CheckValidate( pDoc ); + if ( nErrId == 0 ) + { + long nOldId = GetCacheId(); + long nNewId = pDoc->GetNewDPObjectCacheId(); + if ( nOldId >= 0 ) + pDoc->RemoveDPObjectCache( nOldId ); + + ScDPTableDataCache* pCache = NULL; + if ( pSheetDesc ) + pCache = pSheetDesc->CreateCache( pDoc, nNewId ); + else if ( pImpDesc ) + pCache = pImpDesc->CreateCache( pDoc, nNewId ); + + if ( pCache == NULL ) + { + //cache failed + DBG_ASSERT( pCache , " pCache == NULL" ); + return STR_ERR_DATAPILOTSOURCE; + } + + nNewId = pCache->GetId(); + + bRefresh = TRUE; + ScDPCollection* pDPCollection = pDoc->GetDPCollection(); + USHORT nCount = pDPCollection->GetCount(); + for (USHORT i=0; i<nCount; i++) + { //set new cache id + if ( (*pDPCollection)[i]->GetCacheId() == nOldId ) + { + (*pDPCollection)[i]->SetCacheId( nNewId ); + (*pDPCollection)[i]->SetRefresh(); + + } + } + DBG_ASSERT( GetCacheId() >= 0, " GetCacheId() >= 0 " ); + } + return nErrId; +} +void ScDPObject::SetCacheId( long nCacheId ) +{ + if ( GetCacheId() != nCacheId ) + { + InvalidateSource(); + if ( GetSaveData() ) + GetSaveData()->SetCacheId( nCacheId ); + + mnCacheId = nCacheId; + } +} +const ScDPTableDataCache* ScDPObject::GetCache() const { - return maSharedString; + return pDoc->GetDPObjectCache( GetCacheId() ); } +// End Comments void ScDPCollection::FreeTable(ScDPObject* pDPObj) { @@ -2500,54 +2559,4 @@ bool ScDPCollection::HasDPTable(SCCOL nCol, SCROW nRow, SCTAB nTab) const return pMergeAttr->HasDPTable(); } -ScDPCacheCell* ScDPCollection::getCacheCellFromPool(const ScDPCacheCell& rCell) -{ - ScDPCacheCell aCell(rCell); - CacheCellPoolType::iterator itr = maCacheCellPool.find(&aCell); - if (itr == maCacheCellPool.end()) - { - // Insert a new instance. - ScDPCacheCell* p = new ScDPCacheCell(rCell); - ::std::pair<CacheCellPoolType::iterator, bool> r = - maCacheCellPool.insert(p); - if (!r.second) - delete p; - - ScDPCacheCell* p2 = r.second ? *r.first : NULL; - DBG_ASSERT(p == p2, "ScDPCollection::getCacheCellFromPool: pointer addresses differ"); - return p2; - } - return *itr; -} - -namespace { - -class DeleteCacheCells : public ::std::unary_function<ScDPCacheCell*, void> -{ -public: - void operator()(ScDPCacheCell* p) const - { - delete p; - } -}; - -} - -void ScDPCollection::clearCacheCellPool() -{ - // Transferring all stored pointers to a vector first. For some unknown - // reason, deleting cell content instances by directly iterating through - // the hash set causes the iteration to return an identical pointer - // value twice, causing a double-delete. I have no idea why this happens. - - using ::std::copy; - using ::std::back_inserter; - - vector<ScDPCacheCell*> ps; - ps.reserve(maCacheCellPool.size()); - copy(maCacheCellPool.begin(), maCacheCellPool.end(), back_inserter(ps)); - maCacheCellPool.clear(); - // for correctness' sake, delete the elements after clearing the hash_set - for_each(ps.begin(), ps.end(), DeleteCacheCells()); -} diff --git a/sc/source/core/data/dpoutput.cxx b/sc/source/core/data/dpoutput.cxx index 401d9b396bc0..ec384874aa69 100644..100755 --- a/sc/source/core/data/dpoutput.cxx +++ b/sc/source/core/data/dpoutput.cxx @@ -56,22 +56,11 @@ #include "scresid.hxx" #include "unonames.hxx" #include "sc.hrc" - -#include <com/sun/star/container/XNamed.hpp> -#include <com/sun/star/sheet/DataPilotFieldFilter.hpp> -#include <com/sun/star/sheet/DataPilotFieldOrientation.hpp> -#include <com/sun/star/sheet/DataPilotTableHeaderData.hpp> -#include <com/sun/star/sheet/DataPilotTablePositionData.hpp> -#include <com/sun/star/sheet/DataPilotTablePositionType.hpp> -#include <com/sun/star/sheet/DataPilotTableResultData.hpp> -#include <com/sun/star/sheet/DataResultFlags.hpp> -#include <com/sun/star/sheet/GeneralFunction.hpp> -#include <com/sun/star/sheet/MemberResultFlags.hpp> -#include <com/sun/star/sheet/TableFilterField.hpp> -#include <com/sun/star/sheet/XDataPilotMemberResults.hpp> -#include <com/sun/star/sheet/XDataPilotResults.hpp> -#include <com/sun/star/sheet/XHierarchiesSupplier.hpp> -#include <com/sun/star/sheet/XLevelsSupplier.hpp> +// Wang Xu Ming -- 2009-8-17 +// DataPilot Migration - Cache&&Performance +#include "scdpoutputimpl.hxx" +#include "dpglobal.hxx" +// End Comments #include <com/sun/star/beans/XPropertySet.hpp> #include <vector> @@ -651,11 +640,21 @@ void ScDPOutput::HeaderCell( SCCOL nCol, SCROW nRow, SCTAB nTab, if ( nFlags & sheet::MemberResultFlags::SUBTOTAL ) { // SvxWeightItem aItem( WEIGHT_BOLD ); // weight is in the style - + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + OutputImpl outputimp( pDoc, nTab, + nTabStartCol, nTabStartRow, nMemberStartCol, nMemberStartRow, + nDataStartCol, nDataStartRow, nTabEndCol, nTabEndRow ); + // End Comments //! limit frames to horizontal or vertical? if (bColHeader) { - lcl_SetFrame( pDoc,nTab, nCol,nMemberStartRow+(SCROW)nLevel, nCol,nTabEndRow, 20 ); + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + //lcl_SetFrame( pDoc,nTab, nCol,nMemberStartRow+(SCROW)nLevel, nCol,nTabEndRow, SC_DP_FRAME_INNER_BOLD ); + outputimp.OutputBlockFrame( nCol,nMemberStartRow+(SCROW)nLevel, nCol,nDataStartRow-1 ); + // End Comments + lcl_SetStyleById( pDoc,nTab, nCol,nMemberStartRow+(SCROW)nLevel, nCol,nDataStartRow-1, STR_PIVOT_STYLE_TITLE ); lcl_SetStyleById( pDoc,nTab, nCol,nDataStartRow, nCol,nTabEndRow, @@ -663,7 +662,11 @@ void ScDPOutput::HeaderCell( SCCOL nCol, SCROW nRow, SCTAB nTab, } else { - lcl_SetFrame( pDoc,nTab, nMemberStartCol+(SCCOL)nLevel,nRow, nTabEndCol,nRow, 20 ); + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + //lcl_SetFrame( pDoc,nTab, nMemberStartCol+(USHORT)nLevel,nRow, nTabEndCol,nRow, SC_DP_FRAME_INNER_BOLD ); + outputimp.OutputBlockFrame( nMemberStartCol+(SCCOL)nLevel,nRow, nDataStartCol-1,nRow ); + // End Comments lcl_SetStyleById( pDoc,nTab, nMemberStartCol+(SCCOL)nLevel,nRow, nDataStartCol-1,nRow, STR_PIVOT_STYLE_TITLE ); lcl_SetStyleById( pDoc,nTab, nDataStartCol,nRow, nTabEndCol,nRow, @@ -812,6 +815,20 @@ void ScDPOutput::Output() if ( bDoFilter ) lcl_DoFilterButton( pDoc, aStartPos.Col(), aStartPos.Row(), nTab ); + // output data results: + + for (long nRow=0; nRow<nRowCount; nRow++) + { + SCROW nRowPos = nDataStartRow + (SCROW)nRow; //! check for overflow + const sheet::DataResult* pColAry = pRowAry[nRow].getConstArray(); + long nThisColCount = pRowAry[nRow].getLength(); + DBG_ASSERT( nThisColCount == nColCount, "count mismatch" ); //! ??? + for (long nCol=0; nCol<nThisColCount; nCol++) + { + SCCOL nColPos = nDataStartCol + (SCCOL)nCol; //! check for overflow + DataCell( nColPos, nRowPos, nTab, pColAry[nCol] ); + } + } // output page fields: for (nField=0; nField<nPageFieldCount; nField++) @@ -854,7 +871,12 @@ void ScDPOutput::Output() STR_PIVOT_STYLE_INNER ); // output column headers: - + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + OutputImpl outputimp( pDoc, nTab, + nTabStartCol, nTabStartRow, nMemberStartCol, nMemberStartRow, + nDataStartCol, nDataStartRow, nTabEndCol, nTabEndRow ); + // End Comments for (nField=0; nField<nColFieldCount; nField++) { SCCOL nHdrCol = nDataStartCol + (SCCOL)nField; //! check for overflow @@ -869,28 +891,44 @@ void ScDPOutput::Output() { SCCOL nColPos = nDataStartCol + (SCCOL)nCol; //! check for overflow HeaderCell( nColPos, nRowPos, nTab, pArray[nCol], TRUE, nField ); + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance if ( ( pArray[nCol].Flags & sheet::MemberResultFlags::HASMEMBER ) && !( pArray[nCol].Flags & sheet::MemberResultFlags::SUBTOTAL ) ) { + long nEnd = nCol; + while ( nEnd+1 < nThisColCount && ( pArray[nEnd+1].Flags & sheet::MemberResultFlags::CONTINUE ) ) + ++nEnd; + SCCOL nEndColPos = nDataStartCol + (SCCOL)nEnd; //! check for overflow if ( nField+1 < nColFieldCount ) { - long nEnd = nCol; - while ( nEnd+1 < nThisColCount && ( pArray[nEnd+1].Flags & sheet::MemberResultFlags::CONTINUE ) ) - ++nEnd; - SCCOL nEndColPos = nDataStartCol + (SCCOL)nEnd; //! check for overflow - lcl_SetFrame( pDoc,nTab, nColPos,nRowPos, nEndColPos,nRowPos, 20 ); - lcl_SetFrame( pDoc,nTab, nColPos,nRowPos, nEndColPos,nTabEndRow, 20 ); + // lcl_SetFrame( pDoc,nTab, nColPos,nRowPos, nEndColPos,nRowPos, SC_DP_FRAME_INNER_BOLD ); + // lcl_SetFrame( pDoc,nTab, nColPos,nRowPos, nEndColPos,nTabEndRow, SC_DP_FRAME_INNER_BOLD ); + if ( nField == nColFieldCount - 2 ) + { + outputimp.AddCol( nColPos ); + if ( nColPos + 1 == nEndColPos ) + outputimp.OutputBlockFrame( nColPos,nRowPos, nEndColPos,nRowPos+1, TRUE ); + } + else + outputimp.OutputBlockFrame( nColPos,nRowPos, nEndColPos,nRowPos ); lcl_SetStyleById( pDoc, nTab, nColPos,nRowPos, nEndColPos,nDataStartRow-1, STR_PIVOT_STYLE_CATEGORY ); } else lcl_SetStyleById( pDoc, nTab, nColPos,nRowPos, nColPos,nDataStartRow-1, STR_PIVOT_STYLE_CATEGORY ); } + else if ( pArray[nCol].Flags & sheet::MemberResultFlags::SUBTOTAL ) + outputimp.AddCol( nColPos ); } + if ( nField== 0 && nColFieldCount == 1 ) + outputimp.OutputBlockFrame( nDataStartCol,nTabStartRow, nTabEndCol,nRowPos-1 ); + // End Comments } // output row headers: - + std::vector<BOOL> vbSetBorder; + vbSetBorder.resize( nTabEndRow - nDataStartRow + 1, FALSE ); for (nField=0; nField<nRowFieldCount; nField++) { bool bDataLayout = mbHasDataLayout && (nField == nRowFieldCount-1); @@ -918,41 +956,39 @@ void ScDPOutput::Output() while ( nEnd+1 < nThisRowCount && ( pArray[nEnd+1].Flags & sheet::MemberResultFlags::CONTINUE ) ) ++nEnd; SCROW nEndRowPos = nDataStartRow + (SCROW)nEnd; //! check for overflow - lcl_SetFrame( pDoc,nTab, nColPos,nRowPos, nColPos,nEndRowPos, 20 ); - lcl_SetFrame( pDoc,nTab, nColPos,nRowPos, nTabEndCol,nEndRowPos, 20 ); + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + // lcl_SetFrame( pDoc,nTab, nColPos,nRowPos, nColPos,nEndRowPos, SC_DP_FRAME_INNER_BOLD ); + //lcl_SetFrame( pDoc,nTab, nColPos,nRowPos, nTabEndCol,nEndRowPos, SC_DP_FRAME_INNER_BOLD ); + outputimp.AddRow( nRowPos ); + if ( vbSetBorder[ nRow ] == FALSE ) + { + outputimp.OutputBlockFrame( nColPos, nRowPos, nTabEndCol, nEndRowPos ); + vbSetBorder[ nRow ] = TRUE; + } + outputimp.OutputBlockFrame( nColPos, nRowPos, nColPos, nEndRowPos ); + + if ( nField == nRowFieldCount - 2 ) + outputimp.OutputBlockFrame( nColPos+1, nRowPos, nColPos+1, nEndRowPos ); + // End Comments lcl_SetStyleById( pDoc, nTab, nColPos,nRowPos, nDataStartCol-1,nEndRowPos, STR_PIVOT_STYLE_CATEGORY ); } else lcl_SetStyleById( pDoc, nTab, nColPos,nRowPos, nDataStartCol-1,nRowPos, STR_PIVOT_STYLE_CATEGORY ); } + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + else if ( pArray[nRow].Flags & sheet::MemberResultFlags::SUBTOTAL ) + outputimp.AddRow( nRowPos ); + // End Comments } } - // output data results: - - for (long nRow=0; nRow<nRowCount; nRow++) - { - SCROW nRowPos = nDataStartRow + (SCROW)nRow; //! check for overflow - const sheet::DataResult* pColAry = pRowAry[nRow].getConstArray(); - long nThisColCount = pRowAry[nRow].getLength(); - DBG_ASSERT( nThisColCount == nColCount, "count mismatch" ); //! ??? - for (long nCol=0; nCol<nThisColCount; nCol++) - { - SCCOL nColPos = nDataStartCol + (SCCOL)nCol; //! check for overflow - DataCell( nColPos, nRowPos, nTab, pColAry[nCol] ); - } - } - - // frame around the whole table - - lcl_SetFrame( pDoc,nTab, nDataStartCol,nDataStartRow, nTabEndCol,nTabEndRow, 20 ); - if ( nDataStartCol > nMemberStartCol ) - lcl_SetFrame( pDoc,nTab, nMemberStartCol,nDataStartRow, nDataStartCol-1,nTabEndRow, 20 ); - if ( nDataStartRow > nMemberStartRow ) - lcl_SetFrame( pDoc,nTab, nDataStartCol,nMemberStartRow, nTabEndCol,nDataStartRow-1, 20 ); - - lcl_SetFrame( pDoc,nTab, nTabStartCol,nTabStartRow, nTabEndCol,nTabEndRow, 40 ); +// Wang Xu Ming -- 2009-8-17 +// DataPilot Migration - Cache&&Performance + outputimp.OutputDataArea(); +// End Comments } ScRange ScDPOutput::GetOutputRange( sal_Int32 nRegionType ) diff --git a/sc/source/core/data/dpsave.cxx b/sc/source/core/data/dpsave.cxx index 58a9e112ab7d..72cf15285310 100644 --- a/sc/source/core/data/dpsave.cxx +++ b/sc/source/core/data/dpsave.cxx @@ -54,6 +54,19 @@ #include <com/sun/star/sheet/XMembersSupplier.hpp> #include <com/sun/star/container/XNamed.hpp> #include <com/sun/star/util/XCloneable.hpp> +// Wang Xu Ming -- 2009-8-17 +// DataPilot Migration - Cache&&Performance +#include "dptabsrc.hxx" +#include "dpglobal.hxx" +using namespace ScDPGlobal; +#ifndef _COM_SUN_STAR_SHEET_DATAPILOTFIELDREFERENCETYPE_HPP_ +#include <com/sun/star/sheet/DataPilotFieldReferenceType.hpp> +#endif +#ifndef _COM_SUN_STAR_SHEET_DATAPILOTFIELDREFERENCEITEMTYPE_HPP_ +#include <com/sun/star/sheet/DataPilotFieldReferenceItemType.hpp> +#endif +using namespace com::sun::star::sheet; +// End Comments #include <hash_map> @@ -73,25 +86,6 @@ using ::std::auto_ptr; // ----------------------------------------------------------------------- -//! move to a header file -//! use names from unonames.hxx? -#define DP_PROP_COLUMNGRAND "ColumnGrand" -#define DP_PROP_FUNCTION "Function" -#define DP_PROP_IGNOREEMPTY "IgnoreEmptyRows" -#define DP_PROP_ISDATALAYOUT "IsDataLayoutDimension" -#define DP_PROP_ISVISIBLE "IsVisible" -#define DP_PROP_ORIENTATION "Orientation" -#define DP_PROP_REPEATIFEMPTY "RepeatIfEmpty" -#define DP_PROP_ROWGRAND "RowGrand" -#define DP_PROP_SHOWDETAILS "ShowDetails" -#define DP_PROP_SHOWEMPTY "ShowEmpty" -#define DP_PROP_SUBTOTALS "SubTotals" -#define DP_PROP_USEDHIERARCHY "UsedHierarchy" -#define DP_PROP_FILTER "Filter" -#define DP_PROP_POSITION "Position" - -// ----------------------------------------------------------------------- - void lcl_SetBoolProperty( const uno::Reference<beans::XPropertySet>& xProp, const rtl::OUString& rName, sal_Bool bValue ) { @@ -320,6 +314,51 @@ BOOL ScDPSaveDimension::operator== ( const ScDPSaveDimension& r ) const if (!(**a == **b)) return FALSE; + if ( this->HasCurrentPage() && r.HasCurrentPage() ) + { + if ( this->GetCurrentPage() != r.GetCurrentPage() ) + { + return FALSE; + } + } + else if ( this->HasCurrentPage() || r.HasCurrentPage() ) + { + return FALSE; + } + if( pReferenceValue && r.pReferenceValue ) + { + if ( !(*pReferenceValue == *r.pReferenceValue) ) + { + return FALSE; + } + } + else if ( pReferenceValue || r.pReferenceValue ) + { + return FALSE; + } + if( this->pSortInfo && r.pSortInfo ) + { + if ( !(*this->pSortInfo == *r.pSortInfo) ) + { + return FALSE; + } + } + else if ( this->pSortInfo || r.pSortInfo ) + { + return FALSE; + } + if( this->pAutoShowInfo && r.pAutoShowInfo ) + { + if ( !(*this->pAutoShowInfo == *r.pAutoShowInfo) ) + { + return FALSE; + } + } + else if ( this->pAutoShowInfo || r.pAutoShowInfo ) + { + return FALSE; + } + return TRUE; } @@ -709,6 +748,10 @@ ScDPSaveData::ScDPSaveData() : nRepeatEmptyMode( SC_DPSAVEMODE_DONTKNOW ), bFilterButton( TRUE ), bDrillDown( TRUE ), + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + mnCacheId( -1), + // End Comments mbDimensionMembersBuilt(false), mpGrandTotalName(NULL) { @@ -721,6 +764,10 @@ ScDPSaveData::ScDPSaveData(const ScDPSaveData& r) : nRepeatEmptyMode( r.nRepeatEmptyMode ), bFilterButton( r.bFilterButton ), bDrillDown( r.bDrillDown ), + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + mnCacheId( r.mnCacheId ), + // End Comments mbDimensionMembersBuilt(r.mbDimensionMembersBuilt), mpGrandTotalName(NULL) { @@ -744,40 +791,11 @@ ScDPSaveData& ScDPSaveData::operator= ( const ScDPSaveData& r ) { if ( &r != this ) { - delete pDimensionData; - if ( r.pDimensionData ) - pDimensionData = new ScDPDimensionSaveData( *r.pDimensionData ); - else - pDimensionData = NULL; - - nColumnGrandMode = r.nColumnGrandMode; - nRowGrandMode = r.nRowGrandMode; - nIgnoreEmptyMode = r.nIgnoreEmptyMode; - nRepeatEmptyMode = r.nRepeatEmptyMode; - bFilterButton = r.bFilterButton; - bDrillDown = r.bDrillDown; - mbDimensionMembersBuilt = r.mbDimensionMembersBuilt; - - // remove old dimensions - - long nCount = aDimList.Count(); - long i; - for (i=0; i<nCount; i++) - delete (ScDPSaveDimension*)aDimList.GetObject(i); - aDimList.Clear(); - - // copy new dimensions - - nCount = r.aDimList.Count(); - for (i=0; i<nCount; i++) - { - ScDPSaveDimension* pNew = - new ScDPSaveDimension( *(ScDPSaveDimension*)r.aDimList.GetObject(i) ); - aDimList.Insert( pNew, LIST_APPEND ); - } - - if (r.mpGrandTotalName.get()) - mpGrandTotalName.reset(new OUString(*r.mpGrandTotalName)); + // Wang Xu Ming -- 2009-8-17 + // DataPilot Migration - Cache&&Performance + this->~ScDPSaveData(); + new( this ) ScDPSaveData ( r ); + // End Comments } return *this; } @@ -789,6 +807,7 @@ BOOL ScDPSaveData::operator== ( const ScDPSaveData& r ) const nIgnoreEmptyMode != r.nIgnoreEmptyMode || nRepeatEmptyMode != r.nRepeatEmptyMode || bFilterButton != r.bFilterButton || + mnCacheId != r.mnCacheId ||/// Wang Xu Ming -- 2009-6-18 DataPilot Migration bDrillDown != r.bDrillDown || mbDimensionMembersBuilt != r.mbDimensionMembersBuilt) return FALSE; @@ -1089,6 +1108,7 @@ void ScDPSaveData::WriteToSource( const uno::Reference<sheet::XDimensionsSupplie // reset all orientations //! "forgetSettings" or similar at source ????? //! reset all duplicated dimensions, or reuse them below !!! + DBG_TRACE( "ScDPSaveData::WriteToSource" ); lcl_ResetOrient( xSource ); @@ -1097,6 +1117,9 @@ void ScDPSaveData::WriteToSource( const uno::Reference<sheet::XDimensionsSupplie { ScDPSaveDimension* pDim = (ScDPSaveDimension*)aDimList.GetObject(i); rtl::OUString aName = pDim->GetName(); + + DBG_TRACESTR(pDim->GetName()); + BOOL bData = pDim->IsDataLayout(); //! getByName for ScDPSource, including DataLayoutDimension !!!!!!!! @@ -1228,16 +1251,17 @@ void ScDPSaveData::BuildAllDimensionMembers(ScDPTableData* pData) continue; long nDimIndex = itr->second; - const TypedScStrCollection& rMembers = pData->GetColumnEntries(nDimIndex); - sal_uInt16 nMemberCount = rMembers.GetCount(); - for (sal_uInt16 j = 0; j < nMemberCount; ++j) + const std::vector<SCROW>& rMembers = pData->GetColumnEntries(nDimIndex); + size_t mMemberCount = rMembers.size(); + for (size_t j = 0; j < mMemberCount; ++j) { - const String& rMemName = rMembers[j]->GetString(); - if (pDim->GetExistingMemberByName(rMemName)) + const ScDPItemData* pMemberData = pData->GetMemberById( nDimIndex, rMembers[j] ); + String aMemName = pMemberData->GetString(); + if (pDim->GetExistingMemberByName(aMemName)) // this member instance already exists. nothing to do. continue; - auto_ptr<ScDPSaveMember> pNewMember(new ScDPSaveMember(rMemName)); + auto_ptr<ScDPSaveMember> pNewMember(new ScDPSaveMember(aMemName)); pNewMember->SetIsVisible(true); pDim->AddMember(pNewMember.release()); } @@ -1254,3 +1278,196 @@ bool ScDPSaveData::HasInvisibleMember(const OUString& rDimName) const return pDim->HasInvisibleMember(); } + +void ScDPSaveData::Refresh( const uno::Reference<sheet::XDimensionsSupplier>& xSource ) +{ + try + { + long nCount = aDimList.Count(); + std::list<String> deletedDims; + for (long i=nCount-1; i >=0 ; i--) + { + ScDPSaveDimension* pDim = (ScDPSaveDimension*)aDimList.GetObject(i); + + rtl::OUString aName = pDim->GetName(); + if ( pDim->IsDataLayout() ) + continue; + + uno::Reference<container::XNameAccess> xDimsName = xSource->getDimensions(); + uno::Reference<container::XIndexAccess> xIntDims = new ScNameToIndexAccess( xDimsName ); + long nIntCount = xIntDims->getCount(); + BOOL bFound = FALSE; + for (long nIntDim=0; nIntDim<nIntCount && !bFound; nIntDim++) + { + uno::Reference<uno::XInterface> xIntDim = ScUnoHelpFunctions::AnyToInterface( xIntDims->getByIndex(nIntDim) ); + uno::Reference<container::XNamed> xDimName( xIntDim, uno::UNO_QUERY ); + if ( xDimName.is() && xDimName->getName() == aName ) + bFound = TRUE; + } + if ( !bFound ) + { + deletedDims.push_back( aName ); + aDimList.Remove(i); + DBG_TRACE( "\n Remove dim: \t" ); + DBG_TRACESTR( String( aName ) ); + } + + } + + nCount = aDimList.Count(); + for (long i=nCount-1; i >=0 ; i--) //check every dimension ?? + { + ScDPSaveDimension* pDim = (ScDPSaveDimension*)aDimList.GetObject(i); + + rtl::OUString aName = pDim->GetName(); + if ( pDim->IsDataLayout() ) + continue; + pDim->Refresh( xSource, deletedDims ); + + } + } + catch(uno::Exception&) + { + DBG_ERROR("error in ScDPSaveData::Refresh"); + } + +} +void ScDPSaveDimension::Refresh( const com::sun::star::uno::Reference< + com::sun::star::sheet::XDimensionsSupplier>& xSource , + const std::list<String>& deletedDims) +{ + if ( xSource.is() ) + { + ScDPSource* pTabSource = static_cast<ScDPSource*>( xSource.get() ); + ScDPTableDataCache* pCache = pTabSource->GetCache(); + if ( pCache->GetId() == -1 ) + return; + + SCCOL nSrcDim = pCache->GetDimensionIndex( GetName() ); + + if ( nSrcDim == -1 ) + return; + if ( pSelectedPage ) + {//check pSelected page + DBG_TRACESTR( (*pSelectedPage) ); + if ( pCache->GetIdByItemData( nSrcDim, *pSelectedPage ) == -1 ) + { + delete pSelectedPage; + pSelectedPage = NULL; + } + + }; + + if ( pReferenceValue && pReferenceValue->ReferenceItemType == DataPilotFieldReferenceItemType::NAMED ) + {//check pReferenceValue +#ifdef DEBUG + switch( pReferenceValue->ReferenceType) + { + case sheet::DataPilotFieldReferenceType::ITEM_PERCENTAGE: //both + DBG_TRACE( "\n sheet::DataPilotFieldReferenceType::ITEM_PERCENTAGE \n" ); + break; + case sheet::DataPilotFieldReferenceType::ITEM_DIFFERENCE: //both + DBG_TRACE( "\n sheet::DataPilotFieldReferenceType::ITEM_DIFFERENCE \n" ); + break; + case sheet::DataPilotFieldReferenceType::ITEM_PERCENTAGE_DIFFERENCE: //both + DBG_TRACE( "\n sheet::DataPilotFieldReferenceType::ITEM_PERCENTAGE_DIFFERENCE \n" ); + break; + case sheet::DataPilotFieldReferenceType::RUNNING_TOTAL: + DBG_TRACE( "\n sheet::DataPilotFieldReferenceType::RUNNING_TOTAL \n" ); //enable name + break; + } +#endif + switch( pReferenceValue->ReferenceType) + { + case sheet::DataPilotFieldReferenceType::ITEM_PERCENTAGE: + case sheet::DataPilotFieldReferenceType::ITEM_DIFFERENCE: + case sheet::DataPilotFieldReferenceType::ITEM_PERCENTAGE_DIFFERENCE: + case sheet::DataPilotFieldReferenceType::RUNNING_TOTAL: + { + if( pReferenceValue->ReferenceItemType == DataPilotFieldReferenceItemType::NAMED ) + { + const String& sReferenceFieldName = pReferenceValue->ReferenceField; + DBG_TRACESTR( sReferenceFieldName ); + SCCOL nRefDim = pCache->GetDimensionIndex( sReferenceFieldName ); + bool bValid = true; + if ( nRefDim == -1 ) + bValid = false; + else if ( pReferenceValue->ReferenceType != sheet::DataPilotFieldReferenceType::RUNNING_TOTAL ) + { //running total has not reference item + const String& sReferenceItemName = pReferenceValue->ReferenceItemName; + DBG_TRACESTR( sReferenceItemName ); + if ( pCache->GetIdByItemData( nRefDim, sReferenceItemName ) == -1 ) + bValid = false; + } + if ( !bValid ) + { + delete pReferenceValue; + pReferenceValue = NULL; + } + } + } + break; + } + + }; + + if ( pSortInfo ) + { //check sortinfo + if ( pSortInfo->Mode == DataPilotFieldSortMode::DATA ) + { + DBG_TRACE( "\n DataPilotFieldSortMode::DATA \n" ); + const String& sFieldDimName = pSortInfo->Field; + std::list<String>::const_iterator iter = std::find( deletedDims.begin(), deletedDims.end(), sFieldDimName ); + if ( iter != deletedDims.end() && pCache->GetDimensionIndex( sFieldDimName ) == -1 ) + { + pSortInfo->Mode = DataPilotFieldSortMode::MANUAL; + pSortInfo->Field = GetName(); + } + } + + }; + + if ( pAutoShowInfo ) + { //check autoshow + const String& sFieldDimName = pAutoShowInfo->DataField; + std::list<String>::const_iterator iter = std::find( deletedDims.begin(), deletedDims.end(), sFieldDimName ); + if ( iter != deletedDims.end() && pCache->GetDimensionIndex( sFieldDimName ) == -1 ) + { + delete pAutoShowInfo; + pAutoShowInfo = NULL; + } + + }; + + //remove unused members + //SODC_19124 + for (MemberList::iterator i=maMemberList.begin(); i != maMemberList.end() ; ) + { + rtl::OUString aMemberName = (*i)->GetName(); + if ( pCache->GetIdByItemData( nSrcDim, aMemberName ) == -1 ) + i = maMemberList.erase( i ); + else + i++; + } + } +} +// End Comments +bool operator == (const ::com::sun::star::sheet::DataPilotFieldSortInfo &l, const ::com::sun::star::sheet::DataPilotFieldSortInfo &r ) +{ + return l.Field == r.Field && l.IsAscending == r.IsAscending && l.Mode == r.Mode; +} +bool operator == (const ::com::sun::star::sheet::DataPilotFieldAutoShowInfo &l, const ::com::sun::star::sheet::DataPilotFieldAutoShowInfo &r ) +{ + return l.IsEnabled == r.IsEnabled && + l.ShowItemsMode == r.ShowItemsMode && + l.ItemCount == r.ItemCount && + l.DataField == r.DataField; +} +bool operator == (const ::com::sun::star::sheet::DataPilotFieldReference &l, const ::com::sun::star::sheet::DataPilotFieldReference &r ) +{ + return l.ReferenceType == r.ReferenceType && + l.ReferenceField == r.ReferenceField && + l.ReferenceItemType == r.ReferenceItemType && + l.ReferenceItemName == r.ReferenceItemName; +} + diff --git a/sc/source/core/data/dpsdbtab.cxx b/sc/source/core/data/dpsdbtab.cxx index be8eca58ce95..aae5797211b0 100644 --- a/sc/source/core/data/dpsdbtab.cxx +++ b/sc/source/core/data/dpsdbtab.cxx @@ -69,169 +69,181 @@ using ::com::sun::star::uno::Any; using ::com::sun::star::uno::UNO_QUERY; #define SC_SERVICE_ROWSET "com.sun.star.sdb.RowSet" -#define SC_SERVICE_INTHANDLER "com.sun.star.sdb.InteractionHandler" +#define SC_SERVICE_INTHANDLER "com.sun.star.task.InteractionHandler" //! move to a header file? #define SC_DBPROP_DATASOURCENAME "DataSourceName" #define SC_DBPROP_COMMAND "Command" #define SC_DBPROP_COMMANDTYPE "CommandType" - // ----------------------------------------------------------------------- - -class ScDatabaseDPData_Impl +// Wang Xu Ming -- 2009-9-15 +// DataPilot Migration - Cache&&Performance + ScDPTableDataCache* ScImportSourceDesc::GetExistDPObjectCache( ScDocument* pDoc ) const { -public: - ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceManager; - ScImportSourceDesc aDesc; - long nColCount; - uno::Reference<sdbc::XRowSet> xRowSet; - sal_Int32* pTypes; - SvNumberFormatter* pFormatter; - - ScDPCacheTable aCacheTable; - - ScDatabaseDPData_Impl(ScDPCollection* p) : - aCacheTable(p) + ScDPTableDataCache* pCache = NULL; + ScDPCollection* pDPCollection= pDoc->GetDPCollection(); + USHORT nCount = pDPCollection->GetCount(); + + for ( short i=nCount-1; i>=0 ; i--) { + if ( const ScImportSourceDesc* pUsedDesc = (*pDPCollection)[i]->GetImportSourceDesc() ) + if ( *this == *pUsedDesc ) + { + long nID = (*pDPCollection)[i]->GetCacheId(); + if ( nID >= 0 ) + pCache= pDoc->GetDPObjectCache( nID ); + if ( pCache ) + return pCache; + } } -}; - -// ----------------------------------------------------------------------- - -ScDatabaseDPData::ScDatabaseDPData( - ScDocument* pDoc, - const ScImportSourceDesc& rImport ) : - ScDPTableData(pDoc) -{ - pImpl = new ScDatabaseDPData_Impl(pDoc->GetDPCollection()); - pImpl->xServiceManager = pDoc->GetServiceManager(); - pImpl->aDesc = rImport; - pImpl->nColCount = 0; - pImpl->pTypes = NULL; - pImpl->pFormatter = NULL; // created on demand - - OpenDatabase(); - CreateCacheTable(); -} - -ScDatabaseDPData::~ScDatabaseDPData() -{ - ::comphelper::disposeComponent( pImpl->xRowSet ); - - delete[] pImpl->pTypes; - delete pImpl->pFormatter; // NumberFormatter is local for this object - delete pImpl; + return NULL; } -void ScDatabaseDPData::DisposeData() +ScDPTableDataCache* ScImportSourceDesc::CreateCache( ScDocument* pDoc , long nID ) const { - //! use OpenDatabase here? - pImpl->aCacheTable.clear(); -} + if ( !pDoc ) + return NULL; -BOOL ScDatabaseDPData::OpenDatabase() -{ sal_Int32 nSdbType = -1; - switch ( pImpl->aDesc.nType ) + + switch ( nType ) { - case sheet::DataImportMode_SQL: nSdbType = sdb::CommandType::COMMAND; break; - case sheet::DataImportMode_TABLE: nSdbType = sdb::CommandType::TABLE; break; - case sheet::DataImportMode_QUERY: nSdbType = sdb::CommandType::QUERY; break; - default: - return FALSE; + case sheet::DataImportMode_SQL: nSdbType = sdb::CommandType::COMMAND; break; + case sheet::DataImportMode_TABLE: nSdbType = sdb::CommandType::TABLE; break; + case sheet::DataImportMode_QUERY: nSdbType = sdb::CommandType::QUERY; break; + default: + return NULL; } - BOOL bSuccess = FALSE; + + ScDPTableDataCache* pCache = GetExistDPObjectCache( pDoc ); + + if ( pCache && ( nID < 0 || nID == pCache->GetId() ) ) + return pCache; + + if ( pCache == NULL ) + pCache = new ScDPTableDataCache( pDoc ); + + uno::Reference<sdbc::XRowSet> xRowSet ; try { - pImpl->xRowSet = uno::Reference<sdbc::XRowSet>( - comphelper::getProcessServiceFactory()->createInstance( - rtl::OUString::createFromAscii( SC_SERVICE_ROWSET ) ), - uno::UNO_QUERY); - uno::Reference<beans::XPropertySet> xRowProp( pImpl->xRowSet, uno::UNO_QUERY ); + xRowSet = uno::Reference<sdbc::XRowSet>( + comphelper::getProcessServiceFactory()->createInstance( + rtl::OUString::createFromAscii( SC_SERVICE_ROWSET ) ), + uno::UNO_QUERY); + uno::Reference<beans::XPropertySet> xRowProp( xRowSet, uno::UNO_QUERY ); DBG_ASSERT( xRowProp.is(), "can't get RowSet" ); if ( xRowProp.is() ) { // // set source parameters // - uno::Any aAny; - - aAny <<= rtl::OUString( pImpl->aDesc.aDBName ); + aAny <<= rtl::OUString( aDBName ); xRowProp->setPropertyValue( - rtl::OUString::createFromAscii(SC_DBPROP_DATASOURCENAME), aAny ); + rtl::OUString::createFromAscii(SC_DBPROP_DATASOURCENAME), aAny ); - aAny <<= rtl::OUString( pImpl->aDesc.aObject ); + aAny <<= rtl::OUString( aObject ); xRowProp->setPropertyValue( - rtl::OUString::createFromAscii(SC_DBPROP_COMMAND), aAny ); + rtl::OUString::createFromAscii(SC_DBPROP_COMMAND), aAny ); aAny <<= nSdbType; xRowProp->setPropertyValue( - rtl::OUString::createFromAscii(SC_DBPROP_COMMANDTYPE), aAny ); + rtl::OUString::createFromAscii(SC_DBPROP_COMMANDTYPE), aAny ); - uno::Reference<sdb::XCompletedExecution> xExecute( pImpl->xRowSet, uno::UNO_QUERY ); + uno::Reference<sdb::XCompletedExecution> xExecute( xRowSet, uno::UNO_QUERY ); if ( xExecute.is() ) { uno::Reference<task::XInteractionHandler> xHandler( - comphelper::getProcessServiceFactory()->createInstance( - rtl::OUString::createFromAscii( SC_SERVICE_INTHANDLER ) ), - uno::UNO_QUERY); + comphelper::getProcessServiceFactory()->createInstance( + rtl::OUString::createFromAscii( SC_SERVICE_INTHANDLER ) ), + uno::UNO_QUERY); xExecute->executeWithCompletion( xHandler ); } else - pImpl->xRowSet->execute(); - - // - // get column descriptions - // - - pImpl->nColCount = 0; - uno::Reference<sdbc::XResultSetMetaData> xMeta; - uno::Reference<sdbc::XResultSetMetaDataSupplier> xMetaSupp( pImpl->xRowSet, uno::UNO_QUERY ); - if ( xMetaSupp.is() ) - xMeta = xMetaSupp->getMetaData(); - if ( xMeta.is() ) - pImpl->nColCount = xMeta->getColumnCount(); // this is the number of real columns - - uno::Reference<sdbc::XResultSet> xResSet( pImpl->xRowSet, uno::UNO_QUERY ); - if ( pImpl->nColCount > 0 && xResSet.is() ) - { - pImpl->pTypes = new sal_Int32[pImpl->nColCount]; - for (long nCol=0; nCol<pImpl->nColCount; nCol++) - pImpl->pTypes[nCol] = xMeta->getColumnType( nCol+1 ); - - bSuccess = TRUE; - } + xRowSet->execute(); + SvNumberFormatter aFormat( pDoc->GetServiceManager(), ScGlobal::eLnge); + pCache->InitFromDataBase( xRowSet, *aFormat.GetNullDate() ); + pCache->SetId( nID ); + pDoc->AddDPObjectCache( pCache ); + DBG_TRACE1("Create a cache id = %d \n", pCache->GetId() ); } } catch ( sdbc::SQLException& rError ) { //! store error message + delete pCache; + pCache = NULL; InfoBox aInfoBox( 0, String(rError.Message) ); aInfoBox.Execute(); } catch ( uno::Exception& ) { + delete pCache; + pCache = NULL; DBG_ERROR("Unexpected exception in database"); } - if (!bSuccess) - ::comphelper::disposeComponent( pImpl->xRowSet ); + ::comphelper::disposeComponent( xRowSet ); + return pCache; +} - return bSuccess; +ScDPTableDataCache* ScImportSourceDesc::GetCache( ScDocument* pDoc, long nID ) const +{ + ScDPTableDataCache* pCache = pDoc->GetDPObjectCache( nID ); + if ( NULL == pCache && pDoc ) + pCache = GetExistDPObjectCache( pDoc); + if ( NULL == pCache ) + pCache = CreateCache( pDoc , nID ); + return pCache; } -long ScDatabaseDPData::GetColumnCount() +long ScImportSourceDesc:: GetCacheId( ScDocument* pDoc, long nID ) const +{ + ScDPTableDataCache* pCache = GetCache( pDoc, nID); + if ( NULL == pCache ) + return -1; + else + return pCache->GetId(); +} + +// ----------------------------------------------------------------------- + +ScDatabaseDPData::ScDatabaseDPData( + ScDocument* pDoc, + const ScImportSourceDesc& rImport, long nCacheId /*=-1 */ ) : + ScDPTableData(pDoc, rImport.GetCacheId( pDoc, nCacheId) ), + aCacheTable( pDoc, rImport.GetCacheId( pDoc, nCacheId)) +{ + +} + +ScDatabaseDPData::~ScDatabaseDPData() +{ +} + +void ScDatabaseDPData::DisposeData() { - return pImpl->nColCount; + //! use OpenDatabase here? + aCacheTable.clear(); } -const TypedScStrCollection& ScDatabaseDPData::GetColumnEntries(long nColumn) +long ScDatabaseDPData::GetColumnCount() { CreateCacheTable(); - return pImpl->aCacheTable.getFieldEntries(nColumn); + return GetCacheTable().getColSize(); +} + +// 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) @@ -244,17 +256,12 @@ String ScDatabaseDPData::getDimensionName(long nColumn) } CreateCacheTable(); - const String* pStr = pImpl->aCacheTable.getFieldName(nColumn); - if (pStr) - return *pStr; - - DBG_ERROR("getDimensionName: invalid dimension"); - return String(); + return aCacheTable.getFieldName((SCCOL)nColumn); } BOOL ScDatabaseDPData::getIsDataLayoutDimension(long nColumn) { - return ( nColumn == pImpl->nColCount ); + return ( nColumn == GetCacheTable().getColSize()); } BOOL ScDatabaseDPData::IsDateDimension(long /* nDim */) @@ -271,43 +278,39 @@ void ScDatabaseDPData::SetEmptyFlags( BOOL /* bIgnoreEmptyRows */, BOOL /* bRepe void ScDatabaseDPData::CreateCacheTable() { - if (!pImpl->aCacheTable.empty()) + if (!aCacheTable.empty()) return; - // Get null date. - if (!pImpl->pFormatter) - pImpl->pFormatter = new SvNumberFormatter(pImpl->xServiceManager, ScGlobal::eLnge); - - pImpl->aCacheTable.fillTable(pImpl->xRowSet, *pImpl->pFormatter->GetNullDate()); + aCacheTable.fillTable(); } void ScDatabaseDPData::FilterCacheTable(const vector<ScDPCacheTable::Criterion>& rCriteria, const hash_set<sal_Int32>& rCatDims) { CreateCacheTable(); - pImpl->aCacheTable.filterByPageDimension( + aCacheTable.filterByPageDimension( rCriteria, (IsRepeatIfEmpty() ? rCatDims : hash_set<sal_Int32>())); } void ScDatabaseDPData::GetDrillDownData(const vector<ScDPCacheTable::Criterion>& rCriteria, const hash_set<sal_Int32>& rCatDims, Sequence< Sequence<Any> >& rData) { CreateCacheTable(); - sal_Int32 nRowSize = pImpl->aCacheTable.getRowSize(); + sal_Int32 nRowSize = aCacheTable.getRowSize(); if (!nRowSize) return; - pImpl->aCacheTable.filterTable( + aCacheTable.filterTable( rCriteria, rData, IsRepeatIfEmpty() ? rCatDims : hash_set<sal_Int32>()); } void ScDatabaseDPData::CalcResults(CalcInfo& rInfo, bool bAutoShow) { CreateCacheTable(); - CalcResultsFromCacheTable(pImpl->aCacheTable, rInfo, bAutoShow); + CalcResultsFromCacheTable( aCacheTable, rInfo, bAutoShow); } const ScDPCacheTable& ScDatabaseDPData::GetCacheTable() const { - return pImpl->aCacheTable; + return aCacheTable; } // ----------------------------------------------------------------------- diff --git a/sc/source/core/data/dpshttab.cxx b/sc/source/core/data/dpshttab.cxx index c7e75f438ce1..6254e3861db5 100644..100755 --- a/sc/source/core/data/dpshttab.cxx +++ b/sc/source/core/data/dpshttab.cxx @@ -43,7 +43,10 @@ #include "dpcachetable.hxx" #include "dpobject.hxx" #include "globstr.hrc" - +// Wang Xu Ming -- 2009-8-17 +// DataPilot Migration - Cache&&Performance +#include "dpglobal.hxx" +// End Comments #include <com/sun/star/sheet/DataPilotFieldFilter.hpp> #include <vector> @@ -58,55 +61,27 @@ using ::std::hash_set; // ----------------------------------------------------------------------- -class ScSheetDPData_Impl -{ -public: - ScDocument* pDoc; - ScRange aRange; - ScQueryParam aQuery; - BOOL* pSpecial; // to flag special handling of query parameters in ValidQuery. - BOOL bIgnoreEmptyRows; - BOOL bRepeatIfEmpty; - BOOL* pDateDim; - SCROW nNextRow; // for iterator, within range - - ScDPCacheTable aCacheTable; - - ScSheetDPData_Impl(ScDPCollection* p) : - pSpecial(NULL), - aCacheTable(p) - { - } -}; - -// ----------------------------------------------------------------------- - -ScSheetDPData::ScSheetDPData( ScDocument* pD, const ScSheetSourceDesc& rDesc ) : - ScDPTableData(pD) +ScSheetDPData::ScSheetDPData( ScDocument* pD, const ScSheetSourceDesc& rDesc , long nCacheId) : + ScDPTableData(pD, rDesc.GetCacheId( pD, nCacheId) ), // DataPilot Migration - Cache&&Performance + aQuery ( rDesc.aQueryParam ), + pSpecial(NULL), + bIgnoreEmptyRows( FALSE ), + bRepeatIfEmpty(FALSE), + aCacheTable( pD, rDesc.GetCacheId( pD, nCacheId)) { - pImpl = new ScSheetDPData_Impl(pD->GetDPCollection()); - pImpl->pDoc = pD; - pImpl->aRange = rDesc.aSourceRange; - pImpl->aQuery = rDesc.aQueryParam; - pImpl->bIgnoreEmptyRows = FALSE; - pImpl->bRepeatIfEmpty = FALSE; - pImpl->pDateDim = NULL; - - pImpl->nNextRow = pImpl->aRange.aStart.Row() + 1; - - SCSIZE nEntryCount(pImpl->aQuery.GetEntryCount()); - pImpl->pSpecial = new BOOL[nEntryCount]; + SCSIZE nEntryCount( aQuery.GetEntryCount()); + pSpecial = new BOOL[nEntryCount]; for (SCSIZE j = 0; j < nEntryCount; ++j ) { - ScQueryEntry& rEntry = pImpl->aQuery.GetEntry(j); + ScQueryEntry& rEntry = aQuery.GetEntry(j); if (rEntry.bDoQuery) { - pImpl->pSpecial[j] = false; + pSpecial[j] = false; if (!rEntry.bQueryByString) { if (*rEntry.pStr == EMPTY_STRING && ((rEntry.nVal == SC_EMPTYFIELDS) || (rEntry.nVal == SC_NONEMPTYFIELDS))) - pImpl->pSpecial[j] = true; + pSpecial[j] = true; } else { @@ -121,27 +96,24 @@ ScSheetDPData::ScSheetDPData( ScDocument* pD, const ScSheetSourceDesc& rDesc ) : ScSheetDPData::~ScSheetDPData() { - delete[] pImpl->pDateDim; - delete[] pImpl->pSpecial; - delete pImpl; + delete[] pSpecial; } void ScSheetDPData::DisposeData() { - pImpl->aCacheTable.clear(); + aCacheTable.clear(); } long ScSheetDPData::GetColumnCount() { CreateCacheTable(); - return pImpl->aCacheTable.getColSize(); + return aCacheTable.getColSize(); } -const TypedScStrCollection& ScSheetDPData::GetColumnEntries(long nColumn) +BOOL lcl_HasQuery( const ScQueryParam& rParam ) { - DBG_ASSERT(nColumn>=0 && nColumn < pImpl->aCacheTable.getColSize(), "ScSheetDPData: wrong column"); - CreateCacheTable(); - return pImpl->aCacheTable.getFieldEntries(nColumn); + return rParam.GetEntryCount() > 0 && + rParam.GetEntry(0).bDoQuery; } String ScSheetDPData::getDimensionName(long nColumn) @@ -153,35 +125,21 @@ String ScSheetDPData::getDimensionName(long nColumn) //return "Data"; return ScGlobal::GetRscString(STR_PIVOT_DATA); } - else if (nColumn >= pImpl->aCacheTable.getColSize()) + else if (nColumn >= aCacheTable.getColSize()) { DBG_ERROR("getDimensionName: invalid dimension"); return String(); } else { - const String* pStr = pImpl->aCacheTable.getFieldName(nColumn); - if (pStr) - return *pStr; - else return String(); + return aCacheTable.getFieldName((SCCOL)nColumn); } } -BOOL lcl_HasDateFormat( ScDocument* pDoc, const ScRange& rRange ) -{ - //! iterate formats in range? - - ScAddress aPos = rRange.aStart; - aPos.SetRow( aPos.Row() + 1 ); // below title - ULONG nFormat = pDoc->GetNumberFormat( aPos ); - SvNumberFormatter* pFormatter = pDoc->GetFormatTable(); - return ( pFormatter->GetType(nFormat) & NUMBERFORMAT_DATE ) != 0; -} - BOOL ScSheetDPData::IsDateDimension(long nDim) { CreateCacheTable(); - long nColCount = pImpl->aCacheTable.getColSize(); + long nColCount = aCacheTable.getColSize(); if (getIsDataLayoutDimension(nDim)) { return FALSE; @@ -193,101 +151,165 @@ BOOL ScSheetDPData::IsDateDimension(long nDim) } else { - if (!pImpl->pDateDim) - { - pImpl->pDateDim = new BOOL[nColCount]; - ScRange aTestRange = pImpl->aRange; - for (long i = 0; i < nColCount; ++i) - { - SCCOL nCol = (SCCOL)( pImpl->aRange.aStart.Col() + i ); - aTestRange.aStart.SetCol(nCol); - aTestRange.aEnd.SetCol(nCol); - pImpl->pDateDim[i] = lcl_HasDateFormat( pImpl->pDoc, aTestRange ); - } - } - return pImpl->pDateDim[nDim]; + return aCacheTable.GetCache()->IsDateDimension( nDim); } } -UINT32 ScSheetDPData::GetNumberFormat(long nDim) +ULONG ScSheetDPData::GetNumberFormat(long nDim) { CreateCacheTable(); if (getIsDataLayoutDimension(nDim)) { return 0; } - else if (nDim >= pImpl->aCacheTable.getColSize()) + else if (nDim >= GetCacheTable().getColSize()) { DBG_ERROR("GetNumberFormat: invalid dimension"); return 0; } else { - // is queried only once per dimension from ScDPOutput -> no need to cache - - ScAddress aPos = pImpl->aRange.aStart; - aPos.SetCol( sal::static_int_cast<SCCOL>( aPos.Col() + nDim ) ); - aPos.SetRow( aPos.Row() + 1 ); // below title - return pImpl->pDoc->GetNumberFormat( aPos ); + return GetCacheTable().GetCache()->GetNumberFormat( nDim ); } } +UINT32 ScDPTableData::GetNumberFormatByIdx( NfIndexTableOffset eIdx ) +{ + if( !mpDoc ) + return 0; + + if ( SvNumberFormatter* pFormatter = mpDoc->GetFormatTable() ) + return pFormatter->GetFormatIndex( eIdx, LANGUAGE_SYSTEM ); + + return 0; +} BOOL ScSheetDPData::getIsDataLayoutDimension(long nColumn) { CreateCacheTable(); - return (nColumn == pImpl->aCacheTable.getColSize()); + return (nColumn ==(long)( aCacheTable.getColSize())); } -void ScSheetDPData::SetEmptyFlags( BOOL bIgnoreEmptyRows, BOOL bRepeatIfEmpty ) +void ScSheetDPData::SetEmptyFlags( BOOL bIgnoreEmptyRowsP, BOOL bRepeatIfEmptyP ) { - pImpl->bIgnoreEmptyRows = bIgnoreEmptyRows; - pImpl->bRepeatIfEmpty = bRepeatIfEmpty; + bIgnoreEmptyRows = bIgnoreEmptyRowsP; + bRepeatIfEmpty = bRepeatIfEmptyP; } bool ScSheetDPData::IsRepeatIfEmpty() { - return pImpl->bRepeatIfEmpty; + return bRepeatIfEmpty; } void ScSheetDPData::CreateCacheTable() { // Scan and store the data from the source range. - if (!pImpl->aCacheTable.empty()) + if (!aCacheTable.empty()) // already cached. return; - pImpl->aCacheTable.fillTable(pImpl->pDoc, pImpl->aRange, pImpl->aQuery, pImpl->pSpecial, - pImpl->bIgnoreEmptyRows); + aCacheTable.fillTable( aQuery, pSpecial, + bIgnoreEmptyRows, bRepeatIfEmpty ); } void ScSheetDPData::FilterCacheTable(const vector<ScDPCacheTable::Criterion>& rCriteria, const hash_set<sal_Int32>& rCatDims) { CreateCacheTable(); - pImpl->aCacheTable.filterByPageDimension( + aCacheTable.filterByPageDimension( rCriteria, (IsRepeatIfEmpty() ? rCatDims : hash_set<sal_Int32>())); } void ScSheetDPData::GetDrillDownData(const vector<ScDPCacheTable::Criterion>& rCriteria, const hash_set<sal_Int32>& rCatDims, Sequence< Sequence<Any> >& rData) { CreateCacheTable(); - sal_Int32 nRowSize = pImpl->aCacheTable.getRowSize(); + sal_Int32 nRowSize = aCacheTable.getRowSize(); if (!nRowSize) return; - pImpl->aCacheTable.filterTable( + aCacheTable.filterTable( rCriteria, rData, IsRepeatIfEmpty() ? rCatDims : hash_set<sal_Int32>()); } void ScSheetDPData::CalcResults(CalcInfo& rInfo, bool bAutoShow) { CreateCacheTable(); - CalcResultsFromCacheTable(pImpl->aCacheTable, rInfo, bAutoShow); + CalcResultsFromCacheTable(aCacheTable, rInfo, bAutoShow); } const ScDPCacheTable& ScSheetDPData::GetCacheTable() const { - return pImpl->aCacheTable; + return aCacheTable; +} + + +// Wang Xu Ming -- 2009-8-5 +// DataPilot Migration - Cache&&Performance +ScDPTableDataCache* ScSheetSourceDesc::CreateCache( ScDocument* pDoc , long nID ) const +{ + if ( pDoc ) + { + ScDPTableDataCache* pCache = GetExistDPObjectCache( pDoc ); + if ( pCache && ( nID < 0 || nID == pCache->GetId() ) ) + return pCache; + + ULONG nErrId = CheckValidate( pDoc ); + if ( !nErrId ) + { + pCache = new ScDPTableDataCache( pDoc ); + + pCache->InitFromDoc( pDoc, aSourceRange ); + pCache->SetId( nID ); + pDoc->AddDPObjectCache( pCache ); + + DBG_TRACE1("Create a cache id = %d \n", pCache->GetId() ); + } + else + DBG_ERROR( "\n Error Create Cache" ); + return pCache; + } + return NULL; +} + +ScDPTableDataCache* ScSheetSourceDesc::GetExistDPObjectCache ( ScDocument* pDoc ) const +{ + return pDoc->GetUsedDPObjectCache( aSourceRange ); +} +ScDPTableDataCache* ScSheetSourceDesc::GetCache( ScDocument* pDoc, long nID ) const +{ + ScDPTableDataCache* pCache = pDoc->GetDPObjectCache( nID ); + if ( NULL == pCache && pDoc ) + pCache = GetExistDPObjectCache( pDoc ); + if ( NULL == pCache ) + pCache = CreateCache( pDoc ); + return pCache; +} + +long ScSheetSourceDesc:: GetCacheId( ScDocument* pDoc, long nID ) const +{ + ScDPTableDataCache* pCache = GetCache( pDoc, nID); + if ( NULL == pCache ) + return -1; + else + return pCache->GetId(); +} + +ULONG ScSheetSourceDesc::CheckValidate( ScDocument* pDoc ) const +{ + ScRange aSrcRange( aSourceRange); + if ( !pDoc ) + return STR_ERR_DATAPILOTSOURCE; + for(USHORT i= aSrcRange.aStart.Col();i <= aSrcRange.aEnd.Col();i++) + { + if ( pDoc->IsBlockEmpty( aSrcRange.aStart.Tab(), + i, aSrcRange.aStart.Row(),i, aSrcRange.aStart.Row())) + return STR_PIVOT_FIRSTROWEMPTYERR; + } + if( pDoc->IsBlockEmpty( aSrcRange.aStart.Tab(), aSrcRange.aStart.Col(), aSrcRange.aStart.Row()+1, aSrcRange.aEnd.Col(), aSrcRange.aEnd.Row() ) ) + { + return STR_PIVOT_ONLYONEROWERR; + } + return 0; } +// End Comments // ----------------------------------------------------------------------- diff --git a/sc/source/core/data/dptabdat.cxx b/sc/source/core/data/dptabdat.cxx index 530f1c44123f..cff18ef925d9 100644..100755 --- a/sc/source/core/data/dptabdat.cxx +++ b/sc/source/core/data/dptabdat.cxx @@ -52,69 +52,6 @@ using namespace ::com::sun::star; using ::com::sun::star::uno::Sequence; using ::com::sun::star::uno::Any; using ::std::vector; -using ::std::set; -using ::std::hash_map; - -// ----------------------------------------------------------------------- - -BOOL ScDPItemData::IsCaseInsEqual( const ScDPItemData& r ) const -{ - //! pass Transliteration? - //! inline? - return bHasValue ? ( r.bHasValue && rtl::math::approxEqual( fValue, r.fValue ) ) : - ( !r.bHasValue && - ScGlobal::GetpTransliteration()->isEqual( aString, r.aString ) ); -} - -size_t ScDPItemData::Hash() const -{ - if ( bHasValue ) - return (size_t) rtl::math::approxFloor( fValue ); - else - // If we do unicode safe case insensitive hash we can drop - // ScDPItemData::operator== and use ::IsCasInsEqual - return rtl_ustr_hashCode_WithLength( aString.GetBuffer(), aString.Len() ); -} - -BOOL ScDPItemData::operator==( const ScDPItemData& r ) const -{ - if ( bHasValue ) - { - if ( r.bHasValue ) - return rtl::math::approxEqual( fValue, r.fValue ); - else - return FALSE; - } - else if ( r.bHasValue ) - return FALSE; - else - // need exact equality until we have a safe case insensitive string hash - return aString == r.aString; -} - -sal_Int32 ScDPItemData::Compare( const ScDPItemData& rA, - const ScDPItemData& rB ) -{ - if ( rA.bHasValue ) - { - if ( rB.bHasValue ) - { - if ( rtl::math::approxEqual( rA.fValue, rB.fValue ) ) - return 0; - else if ( rA.fValue < rB.fValue ) - return -1; - else - return 1; - } - else - return -1; // values first - } - else if ( rB.bHasValue ) - return 1; // values first - else - return ScGlobal::GetCollator()->compareString( rA.aString, rB.aString ); -} - // --------------------------------------------------------------------------- ScDPTableData::CalcInfo::CalcInfo() : @@ -124,8 +61,9 @@ ScDPTableData::CalcInfo::CalcInfo() : // --------------------------------------------------------------------------- -ScDPTableData::ScDPTableData(ScDocument* pDoc) : - mrSharedString(pDoc->GetDPCollection()->GetSharedString()) +ScDPTableData::ScDPTableData(ScDocument* pDoc, long nCacheId ) : + mnCacheId( nCacheId ), + mpDoc ( pDoc ) { nLastDateVal = nLastHier = nLastLevel = nLastRet = -1; // invalid @@ -186,7 +124,7 @@ bool ScDPTableData::IsRepeatIfEmpty() return false; } -UINT32 ScDPTableData::GetNumberFormat(long) +ULONG ScDPTableData::GetNumberFormat(long) { return 0; // default format } @@ -219,12 +157,6 @@ BOOL ScDPTableData::HasCommonElement( const ScDPItemData&, long, DBG_ERROR("HasCommonElement shouldn't be called for non-group data"); return FALSE; } - -ScSimpleSharedString& ScDPTableData::GetSharedString() -{ - return mrSharedString; -} - void ScDPTableData::FillRowDataFromCacheTable(sal_Int32 nRow, const ScDPCacheTable& rCacheTable, const CalcInfo& rInfo, CalcRowData& rData) { @@ -243,25 +175,28 @@ void ScDPTableData::FillRowDataFromCacheTable(sal_Int32 nRow, const ScDPCacheTab long nDim = rInfo.aDataSrcCols[i]; rData.aValues.push_back( ScDPValueData() ); ScDPValueData& rVal = rData.aValues.back(); - const ScDPCacheCell* pCell = rCacheTable.getCell( - static_cast<SCCOL>(nDim), static_cast<SCROW>(nRow), false); - if (pCell) - { - rVal.fValue = pCell->mbNumeric ? pCell->mfValue : 0.0; - rVal.nType = pCell->mnType; - } - else - rVal.Set(0.0, SC_VALTYPE_EMPTY); + rCacheTable.getValue( rVal, static_cast<SCCOL>(nDim), static_cast<SCROW>(nRow), false); } } void ScDPTableData::ProcessRowData(CalcInfo& rInfo, CalcRowData& rData, bool bAutoShow) { + // Wang Xu Ming -- 2009-6-16 + // DataPilot Migration if (!bAutoShow) { - rInfo.pColRoot->LateInitFrom(rInfo.aColDims, rInfo.aColLevels, rData.aColData, 0, *rInfo.pInitState); - rInfo.pRowRoot->LateInitFrom(rInfo.aRowDims, rInfo.aRowLevels, rData.aRowData, 0, *rInfo.pInitState); + LateInitParams aColParams( rInfo.aColDims, rInfo.aColLevels, FALSE ); + LateInitParams aRowParams ( rInfo.aRowDims, rInfo.aRowLevels, TRUE ); + // root always init child + aColParams.SetInitChild( TRUE ); + aColParams.SetInitAllChildren( FALSE); + aRowParams.SetInitChild( TRUE ); + aRowParams.SetInitAllChildren( FALSE); + + rInfo.pColRoot->LateInitFrom( aColParams, rData.aColData,0, *rInfo.pInitState); + rInfo.pRowRoot->LateInitFrom( aRowParams, rData.aRowData, 0, *rInfo.pInitState); } + // End Comments if ( ( !rInfo.pColRoot->GetChildDimension() || rInfo.pColRoot->GetChildDimension()->IsValidEntry(rData.aColData) ) && ( !rInfo.pRowRoot->GetChildDimension() || rInfo.pRowRoot->GetChildDimension()->IsValidEntry(rData.aRowData) ) ) @@ -269,8 +204,11 @@ void ScDPTableData::ProcessRowData(CalcInfo& rInfo, CalcRowData& rData, bool bAu //! single process method with ColMembers, RowMembers and data !!! if (rInfo.pColRoot->GetChildDimension()) { - vector<ScDPItemData> aEmptyData; +// Wang Xu Ming -- 2009-6-10 +// DataPilot Migration + vector</*ScDPItemData*/ SCROW > aEmptyData; rInfo.pColRoot->GetChildDimension()->ProcessData(rData.aColData, NULL, aEmptyData, rData.aValues); +// End Comments } rInfo.pRowRoot->ProcessData(rData.aRowData, rInfo.pColRoot->GetChildDimension(), @@ -292,42 +230,94 @@ void ScDPTableData::CalcResultsFromCacheTable(const ScDPCacheTable& rCacheTable, } } +// Wang Xu Ming -- 2009-6-10 +// DataPilot Migration void ScDPTableData::GetItemData(const ScDPCacheTable& rCacheTable, sal_Int32 nRow, - const vector<long>& rDims, vector<ScDPItemData>& rItemData) + const vector<long>& rDims, vector< SCROW/*ScDPItemData*/>& rItemData) +// End Comments { sal_Int32 nDimSize = rDims.size(); for (sal_Int32 i = 0; i < nDimSize; ++i) { long nDim = rDims[i]; - rItemData.push_back( ScDPItemData() ); - ScDPItemData& rData = rItemData.back(); + if (getIsDataLayoutDimension(nDim)) { - rData.SetString(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("x"))); + rItemData.push_back( -1 ); continue; } - const ScDPCacheCell* pCell = rCacheTable.getCell( - static_cast<SCCOL>(nDim), static_cast<SCROW>(nRow), IsRepeatIfEmpty()); - if (!pCell || pCell->mnType == SC_VALTYPE_EMPTY) - continue; + nDim = GetSourceDim( nDim ); + if ( nDim >= rCacheTable.GetCache()->GetColumnCount() ) + continue; - const String* pString = GetSharedString().getString(pCell->mnStrId); - if (!pString) - continue; + SCROW nId= rCacheTable.GetCache()->GetItemDataId( static_cast<SCCOL>(nDim), static_cast<SCROW>(nRow), IsRepeatIfEmpty()); + rItemData.push_back( nId ); - rData.aString = *pString; - rData.bHasValue = false; - if (pCell->mbNumeric) - { - rData.bHasValue = true; - rData.fValue = pCell->mfValue; - } } } // ----------------------------------------------------------------------- +// Wang Xu Ming -- 2009-6-8 +// DataPilot Migration +long ScDPTableData::GetMembersCount( long nDim ) +{ + if ( nDim > MAXCOL ) + return 0; + return GetCacheTable().getFieldEntries( nDim ).size(); +} + +long ScDPTableData::GetCacheId() const +{ + return mnCacheId; +} + +const ScDPItemData* ScDPTableData::GetMemberByIndex( long nDim, long nIndex ) +{ + if ( nIndex >= GetMembersCount( nDim ) ) + return NULL; + + const ::std::vector<SCROW>& nMembers = GetCacheTable().getFieldEntries( nDim ); + + return GetCacheTable().GetCache()->GetItemDataById( (SCCOL) nDim, (SCROW)nMembers[nIndex] ); +} + +const ScDPItemData* ScDPTableData::GetMemberById( long nDim, long nId) +{ + + return GetCacheTable().GetCache()->GetItemDataById( (SCCOL) nDim, (SCROW)nId); +} +SCROW ScDPTableData::GetIdOfItemData( long nDim, const ScDPItemData& rData ) +{ + return GetCacheTable().GetCache()->GetIdByItemData((SCCOL) nDim, rData ); + } +const std::vector< SCROW >& ScDPTableData::GetColumnEntries( long nColumn ) +{ + return GetCacheTable().getFieldEntries( nColumn ); +} +long ScDPTableData::GetSourceDim( long nDim ) +{ + return nDim; + +} + + long ScDPTableData::Compare( long nDim, long nDataId1, long nDataId2) +{ + if ( getIsDataLayoutDimension(nDim) ) + return 0; + + long n1 = GetCacheTable().GetCache()->GetOrder( nDim, nDataId1); + long n2 = GetCacheTable().GetCache()->GetOrder( nDim, nDataId2); + if ( n1 > n2 ) + return 1; + else if ( n1 == n2 ) + return 0; + else + return -1; +} +// End Comments +// ----------------------------------------------------------------------- diff --git a/sc/source/core/data/dptablecache.cxx b/sc/source/core/data/dptablecache.cxx new file mode 100755 index 000000000000..42090e5203a2 --- /dev/null +++ b/sc/source/core/data/dptablecache.cxx @@ -0,0 +1,1093 @@ +/************************************************************************* + * + * 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: dptablecache.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" +// INCLUDE --------------------------------------------------------------- +#include "dptablecache.hxx" +#include "document.hxx" +#include "cell.hxx" +#include "globstr.hrc" + +#include <rtl/math.hxx> +#include "queryparam.hxx" +#include "dpglobal.hxx" + +#include "docoptio.hxx" //for ValidQuery +#include <unotools/textsearch.hxx> //for ValidQuery + +#include <com/sun/star/sdbc/DataType.hpp> +#include <com/sun/star/sdbc/XRow.hpp> +#include <com/sun/star/sdbc/XRowSet.hpp> +#include <com/sun/star/sdbc/XResultSetMetaData.hpp> +#include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp> +const double D_TIMEFACTOR = 86400.0; + +using namespace ::com::sun::star; + +using ::com::sun::star::uno::Exception; +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::UNO_QUERY; +using ::com::sun::star::uno::UNO_QUERY_THROW; +// ----------------------------------------------------------------------- +namespace +{ + BOOL lcl_isDate( ULONG nNumType ) + { + return ( (nNumType & NUMBERFORMAT_DATE) != 0 )? 1:0 ; + } + + BOOL lcl_Search( const std::vector<ScDPItemData*>& list, const ::std::vector<SCROW>& rOrder, const ScDPItemData& item, SCROW& rIndex) + { + rIndex = list.size(); + BOOL bFound = FALSE; + SCROW nLo = 0; + SCROW nHi = list.size() - 1; + SCROW nIndex; + long nCompare; + while (nLo <= nHi) + { + nIndex = (nLo + nHi) / 2; + nCompare = ScDPItemData::Compare( *list[rOrder[nIndex]], item ); + if (nCompare < 0) + nLo = nIndex + 1; + else + { + nHi = nIndex - 1; + if (nCompare == 0) + { + bFound = TRUE; + nLo = nIndex; + } + } + } + rIndex = nLo; + return bFound; + } + + ScDPItemData* lcl_GetItemValue(const Reference<sdbc::XRow>& xRow, sal_Int32 nType, long nCol, + const Date& rNullDate ) + { + short nNumType = NUMBERFORMAT_NUMBER; + try + { + String rStr = xRow->getString(nCol); + double fValue = 0.0; + switch (nType) + { + case sdbc::DataType::BIT: + case sdbc::DataType::BOOLEAN: + { + nNumType = NUMBERFORMAT_LOGICAL; + fValue = xRow->getBoolean(nCol) ? 1 : 0; + return new ScDPItemData( rStr, fValue,TRUE,nNumType); + } + //break; + + case sdbc::DataType::TINYINT: + case sdbc::DataType::SMALLINT: + case sdbc::DataType::INTEGER: + case sdbc::DataType::BIGINT: + case sdbc::DataType::FLOAT: + case sdbc::DataType::REAL: + case sdbc::DataType::DOUBLE: + case sdbc::DataType::NUMERIC: + case sdbc::DataType::DECIMAL: + { + //! do the conversion here? + fValue = xRow->getDouble(nCol); + return new ScDPItemData( rStr, fValue,TRUE); + } + //break; + + case sdbc::DataType::DATE: + { + nNumType = NUMBERFORMAT_DATE; + + util::Date aDate = xRow->getDate(nCol); + fValue = Date(aDate.Day, aDate.Month, aDate.Year) - rNullDate; + return new ScDPItemData( rStr, fValue, TRUE, nNumType ); + } + //break; + + case sdbc::DataType::TIME: + { + nNumType = NUMBERFORMAT_TIME; + + util::Time aTime = xRow->getTime(nCol); + fValue = ( aTime.Hours * 3600 + aTime.Minutes * 60 + + aTime.Seconds + aTime.HundredthSeconds / 100.0 ) / D_TIMEFACTOR; + return new ScDPItemData( rStr,fValue, TRUE, nNumType ); + } + //break; + + case sdbc::DataType::TIMESTAMP: + { + nNumType = NUMBERFORMAT_DATETIME; + + util::DateTime aStamp = xRow->getTimestamp(nCol); + fValue = ( Date( aStamp.Day, aStamp.Month, aStamp.Year ) - rNullDate ) + + ( aStamp.Hours * 3600 + aStamp.Minutes * 60 + + aStamp.Seconds + aStamp.HundredthSeconds / 100.0 ) / D_TIMEFACTOR; + return new ScDPItemData( rStr,fValue, TRUE, nNumType ); + } + //break; + case sdbc::DataType::CHAR: + case sdbc::DataType::VARCHAR: + case sdbc::DataType::LONGVARCHAR: + case sdbc::DataType::SQLNULL: + case sdbc::DataType::BINARY: + case sdbc::DataType::VARBINARY: + case sdbc::DataType::LONGVARBINARY: + default: + return new ScDPItemData ( rStr ); + //break; + } + } + catch (uno::Exception&) + { + } + catch ( ... ) + { + + } + return NULL; + } +} +// Wang Xu Ming -- 12/23/2008 +//Refactor cache data +ScDPItemData::ScDPItemData( const String& rS, double fV/* = 0.0*/, BOOL bHV/* = FALSE*/, const ULONG nNumFormatP /*= 0*/ , BOOL bData/* = TRUE*/) : +nNumFormat( nNumFormatP ), aString(rS), fValue(fV), +mbFlag( (MK_VAL*!!bHV) | (MK_DATA*!!bData) | (MK_ERR*!!FALSE) | (MK_DATE*!!lcl_isDate( nNumFormat ) ) ) +{ +} + +ScDPItemData::ScDPItemData( ScDocument* pDoc, SCROW nRow, USHORT nCol, USHORT nDocTab ): + nNumFormat( 0 ), fValue(0.0), mbFlag( 0 ) +{ + String aDocStr; + pDoc->GetString( nCol, nRow, nDocTab, aDocStr ); + + SvNumberFormatter* pFormatter = pDoc->GetFormatTable(); + + ScAddress aPos( nCol, nRow, nDocTab ); + ScBaseCell* pCell = pDoc->GetCell( aPos ); + + if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA && ((ScFormulaCell*)pCell)->GetErrCode() ) + SetString ( aDocStr ); //[SODC_19347] add liyi + //bErr = TRUE; //[SODC_19347] del liyi + else if ( pDoc->HasValueData( nCol, nRow, nDocTab ) ) + { + double fVal = pDoc->GetValue(ScAddress(nCol, nRow, nDocTab)); + ULONG nFormat = NUMBERFORMAT_NUMBER; + if ( pFormatter ) + nFormat = pFormatter->GetType( pDoc->GetNumberFormat( ScAddress( nCol, nRow, nDocTab ) ) ); + aString = aDocStr; + fValue = fVal; + mbFlag |= MK_VAL|MK_DATA; + nNumFormat = pDoc->GetNumberFormat( ScAddress( nCol, nRow, nDocTab ) ); + lcl_isDate( nFormat ) ? ( mbFlag |= MK_DATE ) : (mbFlag &= ~MK_DATE); + } + else if ( pDoc->HasData( nCol,nRow, nDocTab ) ) + SetString ( aDocStr ); +} +// End Comments + +BOOL ScDPItemData::IsCaseInsEqual( const ScDPItemData& r ) const +{ //TODO: indified Date? + //! pass Transliteration? + //! inline? + return IsValue() ? ( r.IsValue() && rtl::math::approxEqual( fValue, r.fValue ) ) : + ( !r.IsValue() && + ScGlobal::GetpTransliteration()->isEqual( aString, r.aString ) ); +} + +size_t ScDPItemData::Hash() const +{ + if ( IsValue() ) + return (size_t) rtl::math::approxFloor( fValue ); + else + // If we do unicode safe case insensitive hash we can drop + // ScDPItemData::operator== and use ::IsCasInsEqual + return rtl_ustr_hashCode_WithLength( aString.GetBuffer(), aString.Len() ); +} + +BOOL ScDPItemData::operator==( const ScDPItemData& r ) const +{ + if ( IsValue() ) + { + if( HasDatePart() != r.HasDatePart() || HasDatePart() && mnDatePart != r.mnDatePart ) + return FALSE; + +// Wang Xu Ming -- 1/9/2009 +// Add Data Cache Support. +// Identify date + if ( IsDate() != r.IsDate() ) + return FALSE; + else + if ( r.IsValue() ) + return rtl::math::approxEqual( fValue, r.fValue ); + else + return FALSE; +// End Comments + } + else if ( r.IsValue() ) + return FALSE; + else + // need exact equality until we have a safe case insensitive string hash + return aString == r.aString; +} + +sal_Int32 ScDPItemData::Compare( const ScDPItemData& rA, + const ScDPItemData& rB ) +{ + if ( rA.IsValue() ) + { + if ( rB.IsValue() ) + { + if ( rtl::math::approxEqual( rA.fValue, rB.fValue ) ) + { +// Wang Xu Ming -- 1/9/2009 +// Add Data Cache Support. +// Date > number + if ( rA.IsDate() == rB.IsDate() ) + return 0; + else + return rA.IsDate() ? 1: -1; +// End Comments + } + else if ( rA.fValue < rB.fValue ) + return -1; + else + return 1; + } + else + return -1; // values first + } + else if ( rB.IsValue() ) + return 1; // values first + else + return ScGlobal::GetCollator()->compareString( rA.aString, rB.aString ); +} +// +//Wang Xu Ming SODC_17561 +#ifdef DEBUG +void ScDPItemData::dump() const +{ + DBG_TRACE1( "Numberformat= %o", nNumFormat ); + DBG_TRACESTR(aString ); + DBG_TRACE1( "fValue= %f", fValue ); + DBG_TRACE1( "bHasValue= %d", bHasValue ? 1:0); +} +#endif +//End + +TypedStrData* ScDPItemData::CreateTypeString( ) +{ + if ( IsValue() ) + return new TypedStrData( aString, fValue, SC_STRTYPE_VALUE ); + else + return new TypedStrData( aString ); +} + +sal_uInt8 ScDPItemData::GetType() const +{ + + if ( IsHasErr() ) + return SC_VALTYPE_ERROR; + else if ( !IsHasData() ) + return SC_VALTYPE_EMPTY; + else if ( IsValue()) + return SC_VALTYPE_VALUE; + else + return SC_VALTYPE_STRING; + +} + +BOOL ScDPItemData::IsHasData() const +{ + return !!(mbFlag&MK_DATA); +} + +BOOL ScDPItemData::IsHasErr() const +{ + return !!(mbFlag&MK_ERR); +} + +BOOL ScDPItemData::IsValue() const +{ + return !!(mbFlag&MK_VAL); +} + +String ScDPItemData::GetString() const +{ + + return aString; +} + +double ScDPItemData::GetValue() const +{ + return fValue; +} +ULONG ScDPItemData::GetNumFormat() const +{ + return nNumFormat; +} + +BOOL ScDPItemData::HasStringData() const + +{ + return IsHasData()&&!IsHasErr()&&!IsValue(); +} +BOOL ScDPItemData::IsDate() const +{ + return !!(mbFlag&MK_DATE); +} +BOOL ScDPItemData::HasDatePart() const +{ + return !!(mbFlag&MK_DATEPART); +} +void ScDPItemData::SetDate( BOOL b ) +{ + b ? ( mbFlag |= MK_DATE ) : ( mbFlag &= ~MK_DATE ); +} + +// ----------------------------------------------------------------------- +//class ScDPTableDataCache +//To cache the pivot table data source + +BOOL ScDPTableDataCache::operator== ( const ScDPTableDataCache& r ) const +{ + if ( GetColumnCount() == r.GetColumnCount() ) + { + for ( SCCOL i = 0 ; i < GetColumnCount(); i++ ) + { //check dim names + if ( GetDimensionName( i ) != r.GetDimensionName( i ) ) + return FALSE; + //check rows count + if ( GetRowCount() != r.GetRowCount() ) + return FALSE; + //check dim member values + size_t nMembersCount = GetDimMemberValues( i ).size(); + if ( GetDimMemberValues( i ).size() == r. GetDimMemberValues( i ).size() ) + { + for ( size_t j = 0; j < nMembersCount; j++ ) + { + if ( *( GetDimMemberValues( i )[j] ) == *( r.GetDimMemberValues( i )[j] ) ) + continue; + else + return FALSE; + } + } + else + return FALSE; + //check source table index + for ( SCROW k=0 ; k < GetRowCount(); k ++ ) + { + if ( GetItemDataId( i, k, FALSE ) == r.GetItemDataId( i,k,FALSE) ) + continue; + else + return FALSE; + } + } + } + return TRUE; +} + +ScDPTableDataCache::ScDPTableDataCache( ScDocument* pDoc ) : +mpDoc( pDoc ), +mnColumnCount ( 0 ), +mpTableDataValues ( NULL ), +mpSourceData ( NULL ), +mpGlobalOrder( NULL ), +mpIndexOrder( NULL) +{ + mnID = -1; +} + +ScDPTableDataCache::~ScDPTableDataCache() +{ + if ( IsValid() ) + { +// Wang Xu Ming -- 2/17/2009 +// Performance issue + USHORT nCol; + for ( nCol=0; nCol < GetColumnCount() ; nCol++ ) + { + for ( ULONG row = 0 ; row < mpTableDataValues[nCol].size(); row++ ) + delete mpTableDataValues[nCol][row]; + } + for ( nCol =0; nCol < mrLabelNames.size(); nCol++ ) + delete mrLabelNames[nCol]; +// End Comments + + mnColumnCount = 0; + delete [] mpTableDataValues; + mpTableDataValues = NULL; + delete [] mpSourceData; + mpSourceData = NULL; + delete [] mpGlobalOrder; + mpGlobalOrder = NULL; + delete [] mpIndexOrder; + mpIndexOrder = NULL; + } +} + +// ----------------------------------------------------------------------- +void ScDPTableDataCache::AddRow( ScDPItemData* pRow, USHORT nCount ) +{ + DBG_ASSERT( pRow , " empty pointer" ); + if ( !mrLabelNames.size() ) + { + mnColumnCount= nCount; + mpTableDataValues = new std::vector<ScDPItemData*>[ mnColumnCount ]; + mpSourceData = new std::vector<SCROW>[ mnColumnCount ]; + mpGlobalOrder = new std::vector<SCROW>[ mnColumnCount ]; + mpIndexOrder = new std::vector<SCROW>[ mnColumnCount ]; + + for ( USHORT i = 0; i < nCount ; i ++ ) + AddLabel( new ScDPItemData( pRow[i] ) ); + } + else + { + for ( USHORT i = 0; i < nCount && i < mnColumnCount; i ++ ) + AddData( i, new ScDPItemData( pRow[i] ) ); + } +} + +// ----------------------------------------------------------------------- +bool ScDPTableDataCache::IsValid() const +{ //TODO: continue check valid + return mpTableDataValues!=NULL && mpSourceData!= NULL && mnColumnCount>0; +} + +// ----------------------------------------------------------------------- +bool ScDPTableDataCache::InitFromDoc( ScDocument* pDoc, const ScRange& rRange ) +{ + // + SCROW nStartRow = rRange.aStart.Row(); // start of data + SCROW nEndRow = rRange.aEnd.Row(); + USHORT nStartCol = rRange.aStart.Col(); + USHORT nEndCol = rRange.aEnd.Col(); + USHORT nDocTab = rRange.aStart.Tab(); + + //init + long nOldColumCount = mnColumnCount; + mnColumnCount = nEndCol - nStartCol + 1; + if ( IsValid() ) + { + for ( USHORT nCol=0; nCol < nOldColumCount ; nCol++ ) + { + for ( ULONG row = 0 ; row < mpTableDataValues[nCol].size(); row++ ) + delete mpTableDataValues[nCol][row]; + delete mrLabelNames[nCol]; + } + delete [] mpTableDataValues; + delete [] mpSourceData; + delete [] mpGlobalOrder; + delete [] mpIndexOrder; + mrLabelNames.clear(); + } + + mpTableDataValues = new std::vector<ScDPItemData*>[ mnColumnCount ]; + mpSourceData = new std::vector<SCROW>[ mnColumnCount ]; + mpGlobalOrder = new std::vector<SCROW>[ mnColumnCount ]; + mpIndexOrder = new std::vector<SCROW>[ mnColumnCount ]; + //check valid + for ( SCROW nRow = nStartRow; nRow <= nEndRow; nRow ++ ) + { + for ( USHORT nCol = nStartCol; nCol <= nEndCol; nCol++ ) + { + if ( nRow == nStartRow ) + AddLabel( new ScDPItemData( pDoc, nRow, nCol, nDocTab ) ); + else + AddData( nCol - nStartCol, new ScDPItemData( pDoc, nRow, nCol, nDocTab ) ); + } + } + return TRUE; +} + +// ----------------------------------------------------------------------- +bool ScDPTableDataCache::InitFromDataBase (const Reference<sdbc::XRowSet>& xRowSet, const Date& rNullDate) +{ + if (!xRowSet.is()) + // Dont' even waste time to go any further. + return false; + try + { + Reference<sdbc::XResultSetMetaDataSupplier> xMetaSupp(xRowSet, UNO_QUERY_THROW); + Reference<sdbc::XResultSetMetaData> xMeta = xMetaSupp->getMetaData(); + if (!xMeta.is()) + return false; + + long nOldColumCount = mnColumnCount; + mnColumnCount = xMeta->getColumnCount(); + if ( IsValid() ) + { + for ( USHORT nCol=0; nCol < nOldColumCount ; nCol++ ) + { + for ( ULONG row = 0 ; row < mpTableDataValues[nCol].size(); row++ ) + delete mpTableDataValues[nCol][row]; + delete mrLabelNames[nCol]; + } + delete [] mpTableDataValues; + delete [] mpSourceData; + delete [] mpGlobalOrder; + delete [] mpIndexOrder; + mrLabelNames.clear(); + } + // Get column titles and types. + mrLabelNames.reserve(mnColumnCount); + mpTableDataValues = new std::vector<ScDPItemData*>[ mnColumnCount ]; + mpSourceData = new std::vector<SCROW>[ mnColumnCount ]; + mpGlobalOrder = new std::vector<SCROW>[ mnColumnCount ]; + mpIndexOrder = new std::vector<SCROW>[ mnColumnCount ]; + + std::vector<sal_Int32> aColTypes(mnColumnCount); + + for (sal_Int32 nCol = 0; nCol < mnColumnCount; ++nCol) + { + String aColTitle = xMeta->getColumnLabel(nCol+1); + aColTypes[nCol] = xMeta->getColumnType(nCol+1); + AddLabel( new ScDPItemData( aColTitle) ); + } + + // Now get the data rows. + Reference<sdbc::XRow> xRow(xRowSet, UNO_QUERY_THROW); + xRowSet->first(); + do + { + for (sal_Int32 nCol = 0; nCol < mnColumnCount; ++nCol) + { + ScDPItemData * pNew = lcl_GetItemValue( xRow, aColTypes[nCol], nCol+1, rNullDate ); + if ( pNew ) + AddData( nCol , pNew ); + } + } + while (xRowSet->next()); + + xRowSet->beforeFirst(); + + return true; + } + catch (const Exception&) + { + return false; + } +} +// ----------------------------------------------------------------------- +ULONG ScDPTableDataCache::GetDimNumType( SCCOL nDim) const +{ + DBG_ASSERT( IsValid(), " IsValid() == false " ); + DBG_ASSERT( nDim < mnColumnCount && nDim >=0, " dimention out of bound " ); + if ( mpTableDataValues[nDim].size()==0 ) + return NUMBERFORMAT_UNDEFINED; + else + return GetNumType(mpTableDataValues[nDim][0]->nNumFormat); +} + +// ----------------------------------------------------------------------- +bool ScDPTableDataCache::ValidQuery( SCROW nRow, const ScQueryParam &rParam, BOOL *pSpecial) +{ //Copied and modified from ScTable::ValidQuery + if (!rParam.GetEntry(0).bDoQuery) + return TRUE; + BOOL bMatchWholeCell = mpDoc->GetDocOptions().IsMatchWholeCell(); + + //--------------------------------------------------------------- + + const SCSIZE nFixedBools = 32; + BOOL aBool[nFixedBools]; + BOOL aTest[nFixedBools]; + SCSIZE nEntryCount = rParam.GetEntryCount(); + BOOL* pPasst = ( nEntryCount <= nFixedBools ? &aBool[0] : new BOOL[nEntryCount] ); + BOOL* pTest = ( nEntryCount <= nFixedBools ? &aTest[0] : new BOOL[nEntryCount] ); + + long nPos = -1; + SCSIZE i = 0; + CollatorWrapper* pCollator = (rParam.bCaseSens ? ScGlobal::GetCaseCollator() : + ScGlobal::GetCollator() ); + ::utl::TransliterationWrapper* pTransliteration = (rParam.bCaseSens ? + ScGlobal::GetCaseTransliteration() : ScGlobal::GetpTransliteration()); + + while ( (i < nEntryCount) && rParam.GetEntry(i).bDoQuery ) + { + ScQueryEntry& rEntry = rParam.GetEntry(i); + // we can only handle one single direct query + SCROW nId = GetItemDataId( (SCCOL)rEntry.nField, nRow, FALSE ); + const ScDPItemData* pCellData = GetItemDataById( (SCCOL)rEntry.nField, nId); + + BOOL bOk = FALSE; + BOOL bTestEqual = FALSE; + + if ( pSpecial && pSpecial[i] ) + { + if (rEntry.nVal == SC_EMPTYFIELDS) + bOk = ! pCellData->IsHasData(); + else // if (rEntry.nVal == SC_NONEMPTYFIELDS) + bOk = pCellData->IsHasData(); + } + else if ( !rEntry.bQueryByString && pCellData->IsValue() ) + { // by Value + double nCellVal = pCellData->GetValue(); + + switch (rEntry.eOp) + { + case SC_EQUAL : + bOk = ::rtl::math::approxEqual( nCellVal, rEntry.nVal ); + break; + case SC_LESS : + bOk = (nCellVal < rEntry.nVal) && !::rtl::math::approxEqual( nCellVal, rEntry.nVal ); + break; + case SC_GREATER : + bOk = (nCellVal > rEntry.nVal) && !::rtl::math::approxEqual( nCellVal, rEntry.nVal ); + break; + case SC_LESS_EQUAL : + bOk = (nCellVal < rEntry.nVal) || ::rtl::math::approxEqual( nCellVal, rEntry.nVal ); + break; + case SC_GREATER_EQUAL : + bOk = (nCellVal > rEntry.nVal) || ::rtl::math::approxEqual( nCellVal, rEntry.nVal ); + break; + case SC_NOT_EQUAL : + bOk = !::rtl::math::approxEqual( nCellVal, rEntry.nVal ); + break; + default: + bOk= FALSE; + break; + } + } + else if ( (rEntry.eOp == SC_EQUAL || rEntry.eOp == SC_NOT_EQUAL) + || (rEntry.bQueryByString + && pCellData->HasStringData() ) + ) + { // by String + String aCellStr = pCellData->GetString(); + + BOOL bRealRegExp = (rParam.bRegExp && ((rEntry.eOp == SC_EQUAL) + || (rEntry.eOp == SC_NOT_EQUAL))); + BOOL bTestRegExp = FALSE; + if ( bRealRegExp || bTestRegExp ) + { + xub_StrLen nStart = 0; + xub_StrLen nEnd = aCellStr.Len(); + BOOL bMatch = (BOOL) rEntry.GetSearchTextPtr( rParam.bCaseSens ) + ->SearchFrwrd( aCellStr, &nStart, &nEnd ); + // from 614 on, nEnd is behind the found text + if ( bMatch && bMatchWholeCell + && (nStart != 0 || nEnd != aCellStr.Len()) ) + bMatch = FALSE; // RegExp must match entire cell string + if ( bRealRegExp ) + bOk = ((rEntry.eOp == SC_NOT_EQUAL) ? !bMatch : bMatch); + else + bTestEqual = bMatch; + } + if ( !bRealRegExp ) + { + if ( rEntry.eOp == SC_EQUAL || rEntry.eOp == SC_NOT_EQUAL ) + { + if ( bMatchWholeCell ) + { + bOk = pTransliteration->isEqual( aCellStr, *rEntry.pStr ); + //Added by zhaosz,for sodc_2702,20060808 + String aStr = *rEntry.pStr;//"f*" + //modified by weihuaw,for SODC_16698 + //use another way to find "*" in aStr + sal_Bool bHasStar = sal_False; + xub_StrLen nIndex; + if( ( nIndex = aStr.Search('*') ) != STRING_NOTFOUND ) + bHasStar = sal_True; + if(bHasStar && (nIndex>0)) + { + for(i=0;(i<nIndex) && (i< aCellStr.Len()) ; i++) + { + if(aCellStr.GetChar( (USHORT)i ) == aStr.GetChar((USHORT) i )) + { + bOk=1; + } + else + { + bOk=0; + break; + } + } + } + //end modified + //Added end,20060808 + } + else + { + ::com::sun::star::uno::Sequence< sal_Int32 > xOff; + String aCell( pTransliteration->transliterate( + aCellStr, ScGlobal::eLnge, 0, aCellStr.Len(), + &xOff ) ); + String aQuer( pTransliteration->transliterate( + *rEntry.pStr, ScGlobal::eLnge, 0, rEntry.pStr->Len(), + &xOff ) ); + bOk = (aCell.Search( aQuer ) != STRING_NOTFOUND); + } + if ( rEntry.eOp == SC_NOT_EQUAL ) + bOk = !bOk; + } + else + { // use collator here because data was probably sorted + sal_Int32 nCompare = pCollator->compareString( + aCellStr, *rEntry.pStr ); + switch (rEntry.eOp) + { + case SC_LESS : + bOk = (nCompare < 0); + break; + case SC_GREATER : + bOk = (nCompare > 0); + break; + case SC_LESS_EQUAL : + bOk = (nCompare <= 0); + break; + case SC_GREATER_EQUAL : + bOk = (nCompare >= 0); + break; + case SC_NOT_EQUAL: + DBG_ASSERT( false , "SC_NOT_EQUAL"); + break; + case SC_TOPVAL: + case SC_BOTVAL: + case SC_TOPPERC: + case SC_BOTPERC: + default: + break; + } + } + } + } + + if (nPos == -1) + { + nPos++; + pPasst[nPos] = bOk; + pTest[nPos] = bTestEqual; + } + else + { + if (rEntry.eConnect == SC_AND) + { + pPasst[nPos] = pPasst[nPos] && bOk; + pTest[nPos] = pTest[nPos] && bTestEqual; + } + else + { + nPos++; + pPasst[nPos] = bOk; + pTest[nPos] = bTestEqual; + } + } + i++; + } + + for ( long j=1; j <= nPos; j++ ) + { + pPasst[0] = pPasst[0] || pPasst[j]; + pTest[0] = pTest[0] || pTest[j]; + } + + BOOL bRet = pPasst[0]; + if ( pPasst != &aBool[0] ) + delete [] pPasst; + if ( pTest != &aTest[0] ) + delete [] pTest; + + return bRet; +} + +// ----------------------------------------------------------------------- +bool ScDPTableDataCache::IsRowEmpty( SCROW nRow ) const +{ + return mbEmptyRow[ nRow ]; + +} + +// ----------------------------------------------------------------------- +bool ScDPTableDataCache::IsEmptyMember( SCROW nRow, USHORT nColumn ) const +{ + return !GetItemDataById( nColumn, GetItemDataId( nColumn, nRow, FALSE ) )->IsHasData(); +} + +BOOL ScDPTableDataCache::AddData(long nDim, ScDPItemData* pitemData) +{ + DBG_ASSERT( IsValid(), " IsValid() == false " ); + DBG_ASSERT( nDim < mnColumnCount && nDim >=0 , "dimension out of bound" ); + SCROW nIndex = 0; + + BOOL bInserted = FALSE; + + pitemData->SetDate( lcl_isDate( GetNumType( pitemData->nNumFormat ) ) ); + + if ( !lcl_Search( mpTableDataValues[nDim], mpGlobalOrder[nDim], *pitemData, nIndex ) ) + { + mpTableDataValues[nDim].push_back( pitemData ); + mpGlobalOrder[nDim].insert( mpGlobalOrder[nDim].begin()+nIndex, mpTableDataValues[nDim].size()-1 ); + DBG_ASSERT( (size_t) mpGlobalOrder[nDim][nIndex] == mpTableDataValues[nDim].size()-1 ,"ScDPTableDataCache::AddData "); + mpSourceData[nDim].push_back( mpTableDataValues[nDim].size()-1 ); + bInserted = TRUE; + } + else + mpSourceData[nDim].push_back( mpGlobalOrder[nDim][nIndex] ); +//init empty row tag + size_t nCurRow = mpSourceData[nDim].size() -1 ; + + while ( mbEmptyRow.size() <= nCurRow ) + mbEmptyRow.push_back( TRUE ); + + if ( pitemData->IsHasData() ) + mbEmptyRow[ nCurRow ] = FALSE; + + if ( !bInserted ) + delete pitemData; + + return TRUE; +} + + +String ScDPTableDataCache::GetDimensionName( USHORT nColumn ) const +{ + DBG_ASSERT( /* nColumn>=0 && */ nColumn < mrLabelNames.size()-1 , "ScDPTableDataCache::GetDimensionName"); + DBG_ASSERT( mrLabelNames.size() == static_cast <USHORT> (mnColumnCount+1), "ScDPTableDataCache::GetDimensionName"); + if ( static_cast<size_t>(nColumn+1) < mrLabelNames.size() ) + { + return mrLabelNames[nColumn+1]->aString; + } + else + return String(); +} + +void ScDPTableDataCache::AddLabel(ScDPItemData *pData) +{ + DBG_ASSERT( IsValid(), " IsValid() == false " ); + + if ( mrLabelNames.size() == 0 ) + mrLabelNames.push_back( new ScDPItemData( ScGlobal::GetRscString(STR_PIVOT_DATA) ) ); + + + //reset name if needed + String strNewName = pData->aString; + BOOL bFound = FALSE; + long nIndex = 1; + do + { + for ( long i= mrLabelNames.size()-1; i>=0; i-- ) + { + if( mrLabelNames[i]->aString == strNewName ) + { + strNewName = pData->aString; + strNewName += String::CreateFromInt32( nIndex ); + nIndex ++ ; + bFound = TRUE; + } + } + bFound = !bFound; + } + while ( !bFound ); + + pData->aString = strNewName; + mrLabelNames.push_back( pData ); +} + +SCROW ScDPTableDataCache::GetItemDataId(USHORT nDim, SCROW nRow, BOOL bRepeatIfEmpty) const +{ // + DBG_ASSERT( IsValid(), " IsValid() == false " ); + DBG_ASSERT( /* nDim >= 0 && */ nDim < mnColumnCount, "ScDPTableDataCache::GetItemDataId " ); + + if ( bRepeatIfEmpty ) + { + while ( nRow >0 && !mpTableDataValues[nDim][ mpSourceData[nDim][nRow] ]->IsHasData() ) + --nRow; + } + + return mpSourceData[nDim][nRow]; +} + +const ScDPItemData* ScDPTableDataCache::GetItemDataById(long nDim, SCROW nId) const +{ + if ( nId >= GetRowCount() ) + return maAdditionalDatas.getData( nId - GetRowCount() ); + + if ( (size_t)nId >= mpTableDataValues[nDim].size() || nDim >= mnColumnCount || nId < 0 ) + return NULL; + else + return mpTableDataValues[nDim][nId]; +} + +SCROW ScDPTableDataCache::GetRowCount() const +{ + if ( IsValid() ) + return mpSourceData[0].size(); + else + return 0; +} + +const std::vector<ScDPItemData*>& ScDPTableDataCache::GetDimMemberValues(SCCOL nDim) const +{ + DBG_ASSERT( nDim>=0 && nDim < mnColumnCount ," nDim < mnColumnCount "); + return mpTableDataValues[nDim]; +} + +SCROW ScDPTableDataCache::GetSortedItemDataId(SCCOL nDim, SCROW nOrder) const +{ + DBG_ASSERT ( IsValid(), "IsValid"); + DBG_ASSERT( nDim>=0 && nDim < mnColumnCount, "nDim < mnColumnCount"); + DBG_ASSERT( nOrder >= 0 && (size_t) nOrder < mpGlobalOrder[nDim].size(), "nOrder < mpGlobalOrder[nDim].size()" ); + + return mpGlobalOrder[nDim][nOrder]; +} + +ULONG ScDPTableDataCache::GetNumType(ULONG nFormat) const +{ + SvNumberFormatter* pFormatter = mpDoc->GetFormatTable(); + ULONG nType = NUMBERFORMAT_NUMBER; + if ( pFormatter ) + nType = pFormatter->GetType( nFormat ); + return nType; +} + +ULONG ScDPTableDataCache::GetNumberFormat( long nDim ) const +{ + if ( nDim >= mnColumnCount ) + return 0; + if ( mpTableDataValues[nDim].size()==0 ) + return 0; + else + return mpTableDataValues[nDim][0]->nNumFormat; +} + +BOOL ScDPTableDataCache::IsDateDimension( long nDim ) const +{ + if ( nDim >= mnColumnCount ) + return false; + else if ( mpTableDataValues[nDim].size()==0 ) + return false; + else + return mpTableDataValues[nDim][0]->IsDate(); + +} + +SCROW ScDPTableDataCache::GetDimMemberCount( SCCOL nDim ) const +{ + DBG_ASSERT( nDim>=0 && nDim < mnColumnCount ," ScDPTableDataCache::GetDimMemberCount : out of bound "); + return mpTableDataValues[nDim].size(); +} + +const ScDPItemData* ScDPTableDataCache::GetSortedItemData(SCCOL nDim, SCROW nOrder) const +{ + SCROW n = GetSortedItemDataId( nDim, nOrder ); + return GetItemDataById( nDim, n ); +} + +SCCOL ScDPTableDataCache::GetDimensionIndex(String sName) const +{ + for ( size_t n = 1; n < mrLabelNames.size(); n ++ ) //defects, label name map wrong SODC_17590, SODC_18932,SODC_18827,SODC_18960,SODC_18923 + { + if ( mrLabelNames[n]->GetString() == sName ) + return (SCCOL)(n-1); + } + return -1; +} + +SCROW ScDPTableDataCache::GetIdByItemData(long nDim, String sItemData ) const +{ + if ( nDim < mnColumnCount && nDim >=0 ) + { + for ( size_t n = 0; n< mpTableDataValues[nDim].size(); n++ ) + { + if ( mpTableDataValues[nDim][n]->GetString() == sItemData ) + return n; + } + } + + ScDPItemData rData ( sItemData ); + return GetRowCount() +maAdditionalDatas.getDataId(rData); +} + +SCROW ScDPTableDataCache::GetIdByItemData( long nDim, const ScDPItemData& rData ) const +{ + if ( nDim < mnColumnCount && nDim >=0 ) + { + for ( size_t n = 0; n< mpTableDataValues[nDim].size(); n++ ) + { + if ( *mpTableDataValues[nDim][n] == rData ) + return n; + } + } + return GetRowCount() + maAdditionalDatas.getDataId(rData); +} + +SCROW ScDPTableDataCache::GetAdditionalItemID ( String sItemData ) +{ + ScDPItemData rData ( sItemData ); + return GetAdditionalItemID( rData ); +} + +SCROW ScDPTableDataCache::GetAdditionalItemID( const ScDPItemData& rData ) +{ + return GetRowCount() + maAdditionalDatas.insertData( rData ); +} + + +SCROW ScDPTableDataCache::GetOrder(long nDim, SCROW nIndex) const +{ + DBG_ASSERT( IsValid(), " IsValid() == false " ); + DBG_ASSERT( nDim >=0 && nDim < mnColumnCount, "ScDPTableDataCache::GetOrder : out of bound" ); + + if ( mpIndexOrder[nDim].size() != mpGlobalOrder[nDim].size() ) + { //not inited + SCROW i = 0; + mpIndexOrder[nDim].resize( mpGlobalOrder[nDim].size(), 0 ); + for ( size_t n = 0 ; n< mpGlobalOrder[nDim].size(); n++ ) + { + i = mpGlobalOrder[nDim][n]; + mpIndexOrder[nDim][ i ] = n; + } + } + + DBG_ASSERT( nIndex>=0 && (size_t)nIndex < mpIndexOrder[nDim].size() , "ScDPTableDataCache::GetOrder"); + return mpIndexOrder[nDim][nIndex]; +} + +ScDocument* ScDPTableDataCache::GetDoc() const +{ + return mpDoc; +}; + +long ScDPTableDataCache::GetColumnCount() const +{ + return mnColumnCount; +} +long ScDPTableDataCache::GetId() const +{ + return mnID; +} + diff --git a/sc/source/core/data/dptabres.cxx b/sc/source/core/data/dptabres.cxx index 63f5da3290d7..55f9fb771061 100644..100755 --- a/sc/source/core/data/dptabres.cxx +++ b/sc/source/core/data/dptabres.cxx @@ -87,7 +87,44 @@ static USHORT nFuncStrIds[12] = // passend zum enum ScSubTotalFunc STR_FUN_TEXT_VAR, // SUBTOTAL_FUNC_VAR STR_FUN_TEXT_VAR // SUBTOTAL_FUNC_VARP }; +namespace { + template < typename T > + void lcl_ResizePointVector( T & vec, size_t nSize ) + { + for ( size_t i = 0 ; i < vec.size(); i++ ) + { + if ( vec[i] ) + delete vec[i]; + } + vec.resize( nSize, NULL ); + } + BOOL lcl_SearchMember( const std::vector <ScDPResultMember *>& list, SCROW nOrder, SCROW& rIndex) + { + rIndex = list.size(); + BOOL bFound = FALSE; + SCROW nLo = 0; + SCROW nHi = list.size() - 1; + SCROW nIndex; + while (nLo <= nHi) + { + nIndex = (nLo + nHi) / 2; + if ( list[nIndex]->GetOrder() < nOrder ) + nLo = nIndex + 1; + else + { + nHi = nIndex - 1; + if ( list[nIndex]->GetOrder() == nOrder ) + { + bFound = TRUE; + nLo = nIndex; + } + } + } + rIndex = nLo; + return bFound; + } +} // ----------------------------------------------------------------------- // @@ -194,12 +231,16 @@ BOOL ScDPRowMembersOrder::operator()( sal_Int32 nIndex1, sal_Int32 nIndex2 ) con { const ScDPResultMember* pMember1 = rDimension.GetMember(nIndex1); const ScDPResultMember* pMember2 = rDimension.GetMember(nIndex2); - +// Wang Xu Ming -- 3/17/2009 + +// make the hide item to the largest order. + if ( !pMember1->IsVisible() || !pMember2->IsVisible() ) + return pMember1->IsVisible(); + const ScDPDataMember* pDataMember1 = pMember1->GetDataRoot() ; + const ScDPDataMember* pDataMember2 = pMember2->GetDataRoot(); +// End Comments // GetDataRoot can be NULL if there was no data. // IsVisible == FALSE can happen after AutoShow. - const ScDPDataMember* pDataMember1 = pMember1->IsVisible() ? pMember1->GetDataRoot() : NULL; - const ScDPDataMember* pDataMember2 = pMember2->IsVisible() ? pMember2->GetDataRoot() : NULL; - return lcl_IsLess( pDataMember1, pDataMember2, nMeasure, bAscending ); } @@ -207,12 +248,12 @@ BOOL ScDPColMembersOrder::operator()( sal_Int32 nIndex1, sal_Int32 nIndex2 ) con { ScDPDataMember* pDataMember1 = rDimension.GetMember(nIndex1); ScDPDataMember* pDataMember2 = rDimension.GetMember(nIndex2); - - if ( pDataMember1 && !pDataMember1->IsVisible() ) //! IsColVisible? - pDataMember1 = NULL; - if ( pDataMember2 && !pDataMember2->IsVisible() ) - pDataMember2 = NULL; - + // Wang Xu Ming -- 2009-6-17 + BOOL bHide1 = pDataMember1 && !pDataMember1->IsVisible(); + BOOL bHide2 = pDataMember2 && !pDataMember2->IsVisible(); + if ( bHide1 || bHide2 ) + return !bHide1; + // End Comments return lcl_IsLess( pDataMember1, pDataMember2, nMeasure, bAscending ); } @@ -222,7 +263,7 @@ ScDPInitState::ScDPInitState() : nCount( 0 ) { pIndex = new long[SC_DAPI_MAXFIELDS]; - pData = new ScDPItemData[SC_DAPI_MAXFIELDS]; + pData = new SCROW[SC_DAPI_MAXFIELDS]; } ScDPInitState::~ScDPInitState() @@ -231,13 +272,13 @@ ScDPInitState::~ScDPInitState() delete[] pData; } -void ScDPInitState::AddMember( long nSourceIndex, const ScDPItemData& rName ) +void ScDPInitState::AddMember( long nSourceIndex, SCROW nMember ) { DBG_ASSERT( nCount < SC_DAPI_MAXFIELDS, "too many InitState members" ); if ( nCount < SC_DAPI_MAXFIELDS ) { pIndex[nCount] = nSourceIndex; - pData[nCount] = rName; + pData[nCount] = nMember; ++nCount; } } @@ -249,13 +290,13 @@ void ScDPInitState::RemoveMember() --nCount; } -const ScDPItemData* ScDPInitState::GetNameForIndex( long nIndexValue ) const +const SCROW ScDPInitState::GetNameIdForIndex( long nIndexValue ) const { for (long i=0; i<nCount; i++) if ( pIndex[i] == nIndexValue ) - return &pData[i]; + return pData[i]; - return NULL; // not found + return -1; // not found } // ----------------------------------------------------------------------- @@ -735,6 +776,8 @@ ScDPResultData::ScDPResultData( ScDPSource* pSrc ) : //! Ref bDataAtCol( FALSE ), bDataAtRow( FALSE ) { + + lcl_ResizePointVector( mpDimMembers , SC_DAPI_MAXFIELDS ); } ScDPResultData::~ScDPResultData() @@ -743,6 +786,8 @@ ScDPResultData::~ScDPResultData() delete[] pMeasRefs; delete[] pMeasRefOrient; delete[] pMeasNames; + + lcl_ResizePointVector( mpDimMembers , 0 ); } void ScDPResultData::SetMeasureData( long nCount, const ScSubTotalFunc* pFunctions, @@ -890,15 +935,32 @@ BOOL ScDPResultData::IsNumOrDateGroup( long nDim ) const } BOOL ScDPResultData::IsInGroup( const ScDPItemData& rGroupData, long nGroupIndex, - const ScDPItemData& rBaseData, long nBaseIndex ) const + long nBaseDataId, long nBaseIndex ) const { - return pSource->GetData()->IsInGroup( rGroupData, nGroupIndex, rBaseData, nBaseIndex ); + const ScDPItemData* pData = pSource->GetItemDataById( nGroupIndex , nBaseDataId); + if ( pData ) + return pSource->GetData()->IsInGroup( rGroupData, nGroupIndex, *pData , nBaseIndex ); + else + return FALSE; +} +BOOL ScDPResultData::IsInGroup( SCROW nGroupDataId, long nGroupIndex, + const ScDPItemData& rBaseData, long nBaseIndex ) const +{ + const ScDPItemData* pGroupData = pSource->GetItemDataById( nGroupIndex , nGroupDataId); + if ( pGroupData ) + return pSource->GetData()->IsInGroup( *pGroupData, nGroupIndex, rBaseData , nBaseIndex ); + else + return FALSE; } -BOOL ScDPResultData::HasCommonElement( const ScDPItemData& rFirstData, long nFirstIndex, +BOOL ScDPResultData::HasCommonElement(/* const ScDPItemData& rFirstData*/SCROW nFirstDataId, long nFirstIndex, const ScDPItemData& rSecondData, long nSecondIndex ) const { - return pSource->GetData()->HasCommonElement( rFirstData, nFirstIndex, rSecondData, nSecondIndex ); + const ScDPItemData* pFirstData = pSource->GetItemDataById( nFirstIndex , nFirstDataId); + if ( pFirstData ) + return pSource->GetData()->HasCommonElement( *pFirstData, nFirstIndex, rSecondData, nSecondIndex ); + else + return FALSE; } const ScDPSource* ScDPResultData::GetSource() const @@ -906,27 +968,68 @@ const ScDPSource* ScDPResultData::GetSource() const return pSource; } +ResultMembers* ScDPResultData::GetDimResultMembers( long nDim , ScDPDimension* pDim, ScDPLevel* pLevel) const +{ + if ( mpDimMembers[ nDim ] == NULL ) + { + + //long nDimSource = pDim->GetDimension(); + + ResultMembers* pResultMembers = new ResultMembers(); + // global order is used to initialize aMembers, so it doesn't have to be looked at later + const ScMemberSortOrder& rGlobalOrder = pLevel->GetGlobalOrder(); + + ScDPMembers* pMembers = pLevel->GetMembersObject(); + long nMembCount = pMembers->getCount(); + for ( long i=0; i<nMembCount; i++ ) + { + long nSorted = rGlobalOrder.empty() ? i : rGlobalOrder[i]; + ScDPMember* pMember = pMembers->getByIndex(nSorted); + if ( NULL == pResultMembers->FindMember( pMember->GetItemDataId() ) ) + { + ScDPParentDimData* pNew = new ScDPParentDimData( i, pDim, pLevel, pMember ); + pResultMembers->InsertMember( pNew ); + } + } + + mpDimMembers[ nDim ] = pResultMembers; + } + return mpDimMembers[ nDim ]; + +} + // ----------------------------------------------------------------------- -ScDPResultMember::ScDPResultMember( const ScDPResultData* pData, const ScDPDimension* pDim, - const ScDPLevel* pLev, const ScDPMember* pDesc, +ScDPResultMember::ScDPResultMember( const ScDPResultData* pData, const ScDPParentDimData& rParentDimData , BOOL bForceSub ) : pResultData( pData ), - pParentDim( pDim ), - pParentLevel( pLev ), - pMemberDesc( pDesc ), + aParentDimData( rParentDimData ), pChildDimension( NULL ), pDataRoot( NULL ), bHasElements( FALSE ), bForceSubTotal( bForceSub ), bHasHiddenDetails( FALSE ), bInitialized( FALSE ), - bAutoHidden( FALSE ) + bAutoHidden( FALSE ), + nMemberStep( 1 ) { // pParentLevel/pMemberDesc is 0 for root members } +ScDPResultMember::ScDPResultMember( const ScDPResultData* pData, + BOOL bForceSub ) : + pResultData( pData ), + pChildDimension( NULL ), + pDataRoot( NULL ), + bHasElements( FALSE ), + bForceSubTotal( bForceSub ), + bHasHiddenDetails( FALSE ), + bInitialized( FALSE ), + bAutoHidden( FALSE ), + nMemberStep( 1 ) +{ +} ScDPResultMember::~ScDPResultMember() { delete pChildDimension; @@ -935,6 +1038,7 @@ ScDPResultMember::~ScDPResultMember() String ScDPResultMember::GetName() const { + const ScDPMember* pMemberDesc = GetDPMember(); if (pMemberDesc) return pMemberDesc->GetNameStr(); else @@ -943,22 +1047,23 @@ String ScDPResultMember::GetName() const void ScDPResultMember::FillItemData( ScDPItemData& rData ) const { + const ScDPMember* pMemberDesc = GetDPMember(); if (pMemberDesc) pMemberDesc->FillItemData( rData ); else rData.SetString( ScGlobal::GetRscString(STR_PIVOT_TOTAL) ); // root member } -BOOL ScDPResultMember::IsNamedItem( const ScDPItemData& r ) const +BOOL ScDPResultMember::IsNamedItem( SCROW nIndex ) const { //! store ScDPMember pointer instead of ScDPMember ??? - + const ScDPMember* pMemberDesc = GetDPMember(); if (pMemberDesc) - return ((ScDPMember*)pMemberDesc)->IsNamedItem( r ); + return ((ScDPMember*)pMemberDesc)->IsNamedItem( nIndex ); return FALSE; } -bool ScDPResultMember::IsValidEntry( const vector<ScDPItemData>& aMembers ) const +bool ScDPResultMember::IsValidEntry( const vector< SCROW >& aMembers ) const { if ( !IsValid() ) return false; @@ -969,8 +1074,8 @@ bool ScDPResultMember::IsValidEntry( const vector<ScDPItemData>& aMembers ) cons if (aMembers.size() < 2) return false; - vector<ScDPItemData>::const_iterator itr = aMembers.begin(); - vector<ScDPItemData> aChildMembers(++itr, aMembers.end()); + vector<SCROW>::const_iterator itr = aMembers.begin(); + vector<SCROW> aChildMembers(++itr, aMembers.end()); return pChildDim->IsValidEntry(aChildMembers); } else @@ -978,7 +1083,8 @@ bool ScDPResultMember::IsValidEntry( const vector<ScDPItemData>& aMembers ) cons } void ScDPResultMember::InitFrom( const vector<ScDPDimension*>& ppDim, const vector<ScDPLevel*>& ppLev, - size_t nPos, ScDPInitState& rInitState ) + size_t nPos, ScDPInitState& rInitState , + BOOL bInitChild /*= TRUE */) { // with LateInit, initialize only those members that have data if ( pResultData->IsLateInit() ) @@ -990,18 +1096,40 @@ void ScDPResultMember::InitFrom( const vector<ScDPDimension*>& ppDim, const vect return; // skip child dimension if details are not shown - if ( pMemberDesc && !pMemberDesc->getShowDetails() ) + 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; } - pChildDimension = new ScDPResultDimension( pResultData ); - pChildDimension->InitFrom( ppDim, ppLev, nPos, rInitState ); + if ( bInitChild ) + { + pChildDimension = new ScDPResultDimension( pResultData ); + pChildDimension->InitFrom( ppDim, ppLev, nPos, rInitState, TRUE ); + } } -void ScDPResultMember::LateInitFrom( const vector<ScDPDimension*>& ppDim, const vector<ScDPLevel*>& ppLev, - const vector<ScDPItemData>& pItemData, size_t nPos, +void ScDPResultMember::LateInitFrom( LateInitParams& rParams/*const vector<ScDPDimension*>& ppDim, const vector<ScDPLevel*>& ppLev*/, + const vector< SCROW >& pItemData, size_t nPos, ScDPInitState& rInitState ) { // without LateInit, everything has already been initialized @@ -1010,29 +1138,52 @@ void ScDPResultMember::LateInitFrom( const vector<ScDPDimension*>& ppDim, const bInitialized = TRUE; - if (nPos >= ppDim.size()) + if ( rParams.IsEnd( nPos ) /*nPos >= ppDim.size()*/) // No next dimension. Bail out. return; // skip child dimension if details are not shown - if ( pMemberDesc && !pMemberDesc->getShowDetails() ) + 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 ( !pChildDimension ) - pChildDimension = new ScDPResultDimension( pResultData ); - - pChildDimension->LateInitFrom( ppDim, ppLev, pItemData, nPos, rInitState ); + if ( rParams.GetInitChild() ) + { + if ( !pChildDimension ) + pChildDimension = new ScDPResultDimension( pResultData ); + pChildDimension->LateInitFrom( rParams, pItemData, nPos, rInitState ); + } } BOOL ScDPResultMember::IsSubTotalInTitle(long nMeasure) const { BOOL bRet = FALSE; - if ( pChildDimension && pParentLevel && - pParentLevel->IsOutlineLayout() && pParentLevel->IsSubtotalsAtTop() ) + if ( pChildDimension && /*pParentLevel*/GetParentLevel() && + /*pParentLevel*/GetParentLevel()->IsOutlineLayout() && /*pParentLevel*/GetParentLevel()->IsSubtotalsAtTop() ) { long nUserSubStart; long nSubTotals = GetSubTotalCount( &nUserSubStart ); @@ -1054,7 +1205,7 @@ long ScDPResultMember::GetSize(long nMeasure) const { if ( !IsVisible() ) return 0; - + const ScDPLevel* pParentLevel = GetParentLevel(); long nExtraSpace = 0; if ( pParentLevel && pParentLevel->IsAddEmpty() ) ++nExtraSpace; @@ -1091,7 +1242,7 @@ BOOL ScDPResultMember::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; } @@ -1100,6 +1251,7 @@ BOOL ScDPResultMember::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; @@ -1122,6 +1274,8 @@ long ScDPResultMember::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 ) @@ -1145,8 +1299,8 @@ long ScDPResultMember::GetSubTotalCount( long* pUserSubStart ) const return 0; } -void ScDPResultMember::ProcessData( const vector<ScDPItemData>& aChildMembers, const ScDPResultDimension* pDataDim, - const vector<ScDPItemData>& aDataMembers, const vector<ScDPValueData>& aValues ) +void ScDPResultMember::ProcessData( const vector< SCROW >& aChildMembers, const ScDPResultDimension* pDataDim, + const vector< SCROW >& aDataMembers, const vector<ScDPValueData>& aValues ) { SetHasElements(); @@ -1169,6 +1323,8 @@ void ScDPResultMember::ProcessData( const vector<ScDPItemData>& aChildMembers, c 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 @@ -1229,10 +1385,10 @@ void ScDPResultMember::FillMemberResults( uno::Sequence<sheet::MemberResult>* pS { ScDPItemData aItemData; FillItemData( aItemData ); - aName = aItemData.aString; - bIsNumeric = aItemData.bHasValue; + 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, @@ -1241,6 +1397,7 @@ void ScDPResultMember::FillMemberResults( uno::Sequence<sheet::MemberResult>* pS } String aCaption = aName; + const ScDPMember* pMemberDesc = GetDPMember(); if (pMemberDesc) { const OUString* pLayoutName = pMemberDesc->GetLayoutName(); @@ -1272,6 +1429,7 @@ void ScDPResultMember::FillMemberResults( uno::Sequence<sheet::MemberResult>* pS pArray[rPos+i].Flags |= sheet::MemberResultFlags::CONTINUE; } + const ScDPLevel* pParentLevel = GetParentLevel(); long nExtraSpace = 0; if ( pParentLevel && pParentLevel->IsAddEmpty() ) ++nExtraSpace; @@ -1293,7 +1451,8 @@ void ScDPResultMember::FillMemberResults( uno::Sequence<sheet::MemberResult>* pS if (bRoot) // same sequence for root member pChildDimension->FillMemberResults( pSequences, rPos, nMeasure ); else - pChildDimension->FillMemberResults( pSequences + 1, rPos, nMeasure ); + //pChildDimension->FillMemberResults( pSequences + 1, rPos, nMeasure ); + pChildDimension->FillMemberResults( pSequences + nMemberStep/*1*/, rPos, nMeasure ); if ( bTitleLine ) // title row is included in GetSize, so the following --rPos; // positions are calculated with the normal values @@ -1389,7 +1548,7 @@ void ScDPResultMember::FillDataResults( const ScDPResultMember* pRefMember, { // IsVisible() test is in ScDPResultDimension::FillDataResults // (not on data layout dimension) - + const ScDPLevel* pParentLevel = GetParentLevel(); long nStartRow = rRow; long nExtraSpace = 0; @@ -1409,7 +1568,7 @@ void ScDPResultMember::FillDataResults( const ScDPResultMember* pRefMember, ++rRow; // -> fill child dimension one row below pChildDimension->FillDataResults( pRefMember, rSequence, rRow, nMeasure ); // doesn't modify rRow - rRow += (USHORT) GetSize( nMeasure ); + rRow += GetSize( nMeasure ); if ( bTitleLine ) // title row is included in GetSize, so the following --rRow; // positions are calculated with the normal values @@ -1451,7 +1610,7 @@ void ScDPResultMember::FillDataResults( const ScDPResultMember* pRefMember, if ( bHasChild && nUserSubCount > 1 ) { aSubState.nRowSubTotalFunc = nUserPos; - aSubState.eRowForce = lcl_GetForceFunc( pParentLevel, nUserPos ); + aSubState.eRowForce = lcl_GetForceFunc( /*pParentLevel*/GetParentLevel() , nUserPos ); } for ( long nSubCount=0; nSubCount<nSubSize; nSubCount++ ) @@ -1509,7 +1668,7 @@ void ScDPResultMember::UpdateDataResults( const ScDPResultMember* pRefMember, lo if ( bHasChild && nUserSubCount > 1 ) { aSubState.nRowSubTotalFunc = nUserPos; - aSubState.eRowForce = lcl_GetForceFunc( pParentLevel, nUserPos ); + aSubState.eRowForce = lcl_GetForceFunc( /*pParentLevel*/GetParentLevel() , nUserPos ); } for ( long nSubCount=0; nSubCount<nSubSize; nSubCount++ ) @@ -1537,8 +1696,7 @@ void ScDPResultMember::SortMembers( ScDPResultMember* pRefMember ) if (bHasChild) pChildDimension->SortMembers( pRefMember ); // sorting is done at the dimension - BOOL bIsRoot = ( pParentLevel == NULL ); - if ( bIsRoot && pDataRoot ) + if ( IsRoot() && pDataRoot ) { // use the row root member to sort columns // sub total count is always 1 @@ -1553,8 +1711,7 @@ void ScDPResultMember::DoAutoShow( ScDPResultMember* pRefMember ) if (bHasChild) pChildDimension->DoAutoShow( pRefMember ); // sorting is done at the dimension - BOOL bIsRoot = ( pParentLevel == NULL ); - if ( bIsRoot && pDataRoot ) + if ( IsRoot()&& pDataRoot ) { // use the row root member to sort columns // sub total count is always 1 @@ -1563,7 +1720,7 @@ void ScDPResultMember::DoAutoShow( ScDPResultMember* pRefMember ) } } -void ScDPResultMember::ResetResults( BOOL bRoot ) +void ScDPResultMember::ResetResults( BOOL /*bRoot*/ ) { if (pDataRoot) pDataRoot->ResetResults(); @@ -1571,8 +1728,8 @@ void ScDPResultMember::ResetResults( BOOL bRoot ) if (pChildDimension) pChildDimension->ResetResults(); - if (!bRoot) - bHasElements = FALSE; + // if (!bRoot) + // bHasElements = FALSE; } void ScDPResultMember::UpdateRunningTotals( const ScDPResultMember* pRefMember, long nMeasure, @@ -1581,13 +1738,12 @@ void ScDPResultMember::UpdateRunningTotals( const ScDPResultMember* pRefMember, // IsVisible() test is in ScDPResultDimension::FillDataResults // (not on data layout dimension) - BOOL bIsRoot = ( pParentLevel == NULL ); - rTotals.SetInColRoot( bIsRoot ); + rTotals.SetInColRoot( IsRoot() ); BOOL bHasChild = ( pChildDimension != NULL ); long nUserSubCount = GetSubTotalCount(); - if ( nUserSubCount || !bHasChild ) + //if ( nUserSubCount || !bHasChild ) { // Calculate at least automatic if no subtotals are selected, // show only own values if there's no child dimension (innermost). @@ -1606,7 +1762,7 @@ void ScDPResultMember::UpdateRunningTotals( const ScDPResultMember* pRefMember, if ( bHasChild && nUserSubCount > 1 ) { aSubState.nRowSubTotalFunc = nUserPos; - aSubState.eRowForce = lcl_GetForceFunc( pParentLevel, nUserPos ); + aSubState.eRowForce = lcl_GetForceFunc( /*pParentLevel*/GetParentLevel(), nUserPos ); } for ( long nSubCount=0; nSubCount<nSubSize; nSubCount++ ) @@ -1685,7 +1841,7 @@ BOOL ScDPDataMember::IsVisible() const return FALSE; } -BOOL ScDPDataMember::IsNamedItem( const ScDPItemData& r ) const +BOOL ScDPDataMember::IsNamedItem( /*const ScDPItemData& r*/SCROW r ) const { if (pResultMember) return pResultMember->IsNamedItem(r); @@ -1752,7 +1908,7 @@ void ScDPDataMember::UpdateValues( const vector<ScDPValueData>& aValues, const S } } -void ScDPDataMember::ProcessData( const vector<ScDPItemData>& aChildMembers, const vector<ScDPValueData>& aValues, +void ScDPDataMember::ProcessData( const vector< SCROW >& aChildMembers, const vector<ScDPValueData>& aValues, const ScDPSubTotalState& rSubState ) { if ( pResultData->IsLateInit() && !pChildDimension && pResultMember && pResultMember->GetChildDimension() ) @@ -2107,7 +2263,7 @@ void ScDPDataMember::UpdateRunningTotals( const ScDPResultMember* pRefMember, BOOL bHasChild = ( pRefChild != NULL ); long nUserSubCount = pRefMember->GetSubTotalCount(); - if ( nUserSubCount || !bHasChild ) + //if ( nUserSubCount || !bHasChild ) { // Calculate at least automatic if no subtotals are selected, // show only own values if there's no child dimension (innermost). @@ -2496,8 +2652,10 @@ private: BOOL bIncludeAll; BOOL bIsBase; long nGroupBase; - const ScDPItemData* pBaseData; - + // Wang Xu Ming -- 2009-8-6 + // DataPilot Migration - Cache&&Performance + SCROW nBaseDataId; + // End Comments public: ScDPGroupCompare( const ScDPResultData* pData, const ScDPInitState& rState, long nDimension ); ~ScDPGroupCompare() {} @@ -2510,12 +2668,12 @@ ScDPGroupCompare::ScDPGroupCompare( const ScDPResultData* pData, const ScDPInitS pResultData( pData ), rInitState( rState ), nDimSource( nDimension ), - pBaseData( NULL ) + nBaseDataId( -1 ) { bIsBase = pResultData->IsBaseForGroup( nDimSource ); nGroupBase = pResultData->GetGroupBase( nDimSource ); //! get together in one call? if ( nGroupBase >= 0 ) - pBaseData = rInitState.GetNameForIndex( nGroupBase ); + nBaseDataId = rInitState.GetNameIdForIndex( nGroupBase ); // if bIncludeAll is set, TestIncluded doesn't need to be called bIncludeAll = !( bIsBase || nGroupBase >= 0 ); @@ -2524,11 +2682,11 @@ ScDPGroupCompare::ScDPGroupCompare( const ScDPResultData* pData, const ScDPInitS BOOL ScDPGroupCompare::TestIncluded( const ScDPMember& rMember ) { BOOL bInclude = TRUE; - if ( pBaseData ) + if ( nBaseDataId >=0 ) { ScDPItemData aMemberData; rMember.FillItemData( aMemberData ); - bInclude = pResultData->IsInGroup( aMemberData, nDimSource, *pBaseData, nGroupBase ); + bInclude = pResultData->IsInGroup( aMemberData, nDimSource, nBaseDataId, nGroupBase ); } else if ( bIsBase ) { @@ -2538,7 +2696,8 @@ BOOL ScDPGroupCompare::TestIncluded( const ScDPMember& rMember ) rMember.FillItemData( aMemberData ); long nInitCount = rInitState.GetCount(); const long* pInitSource = rInitState.GetSource(); - const ScDPItemData* pInitNames = rInitState.GetNames(); + /*const ScDPItemData* pInitNames = rInitState.GetNames();*/ + const SCROW* pInitNames = rInitState.GetNameIds(); for (long nInitPos=0; nInitPos<nInitCount && bInclude; nInitPos++) if ( pResultData->GetGroupBase( pInitSource[nInitPos] ) == nDimSource ) { @@ -2556,7 +2715,8 @@ BOOL ScDPGroupCompare::TestIncluded( const ScDPMember& rMember ) rMember.FillItemData( aMemberData ); long nInitCount = rInitState.GetCount(); const long* pInitSource = rInitState.GetSource(); - const ScDPItemData* pInitNames = rInitState.GetNames(); + /*const ScDPItemData* pInitNames = rInitState.GetNames();*/ + const SCROW* pInitNames = rInitState.GetNameIds(); for (long nInitPos=0; nInitPos<nInitCount && bInclude; nInitPos++) if ( pResultData->GetGroupBase( pInitSource[nInitPos] ) == nGroupBase ) { @@ -2591,14 +2751,14 @@ ScDPResultDimension::~ScDPResultDimension() delete maMemberArray[i]; } -ScDPResultMember *ScDPResultDimension::FindMember( const ScDPItemData& rData ) const +ScDPResultMember *ScDPResultDimension::FindMember( SCROW iData ) const { if( bIsDataLayout ) return maMemberArray[0]; - MemberHash::const_iterator aRes = maMemberHash.find( rData ); + MemberHash::const_iterator aRes = maMemberHash.find( iData ); if( aRes != maMemberHash.end()) { - if ( aRes->second->IsNamedItem( rData ) ) + if ( aRes->second->IsNamedItem( iData ) ) return aRes->second; DBG_ERROR("problem! hash result is not the same as IsNamedItem"); } @@ -2609,14 +2769,14 @@ ScDPResultMember *ScDPResultDimension::FindMember( const ScDPItemData& rData ) c for( i = 0; i < nCount ; i++ ) { pResultMember = maMemberArray[i]; - if ( pResultMember->IsNamedItem( rData ) ) + if ( pResultMember->IsNamedItem( iData ) ) return pResultMember; } return NULL; } void ScDPResultDimension::InitFrom( const vector<ScDPDimension*>& ppDim, const vector<ScDPLevel*>& ppLev, - size_t nPos, ScDPInitState& rInitState ) + size_t nPos, ScDPInitState& rInitState, BOOL bInitChild /*= TRUE */ ) { if (nPos >= ppDim.size() || nPos >= ppLev.size()) { @@ -2671,46 +2831,41 @@ void ScDPResultDimension::InitFrom( const vector<ScDPDimension*>& ppDim, const v ScDPMember* pMember = pMembers->getByIndex(nSorted); if ( aCompare.IsIncluded( *pMember ) ) { - ScDPResultMember* pNew = new ScDPResultMember( pResultData, pThisDim, - pThisLevel, pMember, FALSE ); - maMemberArray.push_back( pNew ); + ScDPParentDimData aData( i, pThisDim, pThisLevel, pMember); + ScDPResultMember* pNew = AddMember( aData ); - ScDPItemData aMemberData; - pMember->FillItemData( aMemberData ); - - // honour order of maMemberArray and only insert if it does not - // already exist - if ( maMemberHash.end() == maMemberHash.find( aMemberData ) ) - maMemberHash.insert( std::pair< const ScDPItemData, ScDPResultMember *>( aMemberData, pNew ) ); - - rInitState.AddMember( nDimSource, aMemberData ); - pNew->InitFrom( ppDim, ppLev, nPos+1, rInitState ); + rInitState.AddMember( nDimSource, /*aMemberData*/pNew->GetDataId() ); + pNew->InitFrom( ppDim, ppLev, nPos+1, rInitState, bInitChild ); rInitState.RemoveMember(); } } bInitialized = TRUE; } -void ScDPResultDimension::LateInitFrom( const vector<ScDPDimension*>& ppDim, const vector<ScDPLevel*>& ppLev, - const vector<ScDPItemData>& pItemData, size_t nPos, +void ScDPResultDimension::LateInitFrom( LateInitParams& rParams/* const vector<ScDPDimension*>& ppDim, const vector<ScDPLevel*>& ppLev*/, + const vector<SCROW>& pItemData, size_t nPos, ScDPInitState& rInitState ) +// End Comments { - if (nPos >= ppDim.size() || nPos >= ppLev.size() || nPos >= pItemData.size()) + if ( rParams.IsEnd( nPos ) ) return; - - ScDPDimension* pThisDim = ppDim[nPos]; - ScDPLevel* pThisLevel = ppLev[nPos]; - const ScDPItemData& rThisData = pItemData[nPos]; +#ifdef DBG_UTIL + DBG_ASSERT( nPos <= pItemData.size(), ByteString::CreateFromInt32( pItemData.size()).GetBuffer() ); +#endif + ScDPDimension* pThisDim = rParams.GetDim( nPos ); + ScDPLevel* pThisLevel = rParams.GetLevel( nPos ); + SCROW rThisData = pItemData[nPos]; if (!pThisDim || !pThisLevel) return; long nDimSource = pThisDim->GetDimension(); //! check GetSourceDim? - if ( !bInitialized ) - { - // create all members at the first call (preserve order) + BOOL bShowEmpty = pThisLevel->getShowEmpty(); + if ( !bInitialized ) + { // init some values + // create all members at the first call (preserve order) bIsDataLayout = pThisDim->getIsDataLayoutDimension(); aDimensionName = pThisDim->getName(); @@ -2730,65 +2885,86 @@ void ScDPResultDimension::LateInitFrom( const vector<ScDPDimension*>& ppDim, con bSortAscending = rSortInfo.IsAscending; nSortMeasure = pThisLevel->GetSortMeasure(); } + } - // global order is used to initialize aMembers, so it doesn't have to be looked at later - const ScMemberSortOrder& rGlobalOrder = pThisLevel->GetGlobalOrder(); + bool bLateInitAllMembers= bIsDataLayout || rParams.GetInitAllChild() || bShowEmpty; - ScDPGroupCompare aCompare( pResultData, rInitState, nDimSource ); + if ( !bLateInitAllMembers ) + { + ResultMembers* pMembers = pResultData->GetDimResultMembers(nDimSource, pThisDim, pThisLevel); + bLateInitAllMembers = pMembers->IsHasHideDetailsMembers(); +#ifdef DBG_UTIL + DBG_TRACESTR( aDimensionName ) + if ( pMembers->IsHasHideDetailsMembers() ) + DBG_TRACE ( "HasHideDetailsMembers" ); +#endif + pMembers->SetHasHideDetailsMembers( FALSE ); + } - ScDPMembers* pMembers = pThisLevel->GetMembersObject(); - long nMembCount = pMembers->getCount(); - for ( long i=0; i<nMembCount; i++ ) - { - long nSorted = rGlobalOrder.empty() ? i : rGlobalOrder[i]; + bool bNewAllMembers =(!rParams.IsRow()) || nPos == 0 || bLateInitAllMembers ; - ScDPMember* pMember = pMembers->getByIndex(nSorted); - if ( aCompare.IsIncluded( *pMember ) ) + if (bNewAllMembers ) + { + // global order is used to initialize aMembers, so it doesn't have to be looked at later + if ( !bInitialized ) + { //init all members + const ScMemberSortOrder& rGlobalOrder = pThisLevel->GetGlobalOrder(); + + ScDPGroupCompare aCompare( pResultData, rInitState, nDimSource ); + ScDPMembers* pMembers = pThisLevel->GetMembersObject(); + long nMembCount = pMembers->getCount(); + for ( long i=0; i<nMembCount; i++ ) { - ScDPResultMember* pNew = new ScDPResultMember( pResultData, pThisDim, - pThisLevel, pMember, FALSE ); - maMemberArray.push_back( pNew ); + long nSorted = rGlobalOrder.empty() ? i : rGlobalOrder[i]; - ScDPItemData aMemberData; - pMember->FillItemData( aMemberData ); - - // honour order of maMemberArray and only insert if it does not - // already exist - if ( maMemberHash.end() == maMemberHash.find( aMemberData ) ) - maMemberHash.insert( std::pair< const ScDPItemData, ScDPResultMember *>( aMemberData, pNew ) ); + ScDPMember* pMember = pMembers->getByIndex(nSorted); + if ( aCompare.IsIncluded( *pMember ) ) + { // add all members + ScDPParentDimData aData( i, pThisDim, pThisLevel, pMember ); + AddMember( aData ); + } } + bInitialized = TRUE; // don't call again, even if no members were included } - bInitialized = TRUE; // don't call again, even if no members were included - } - // initialize only specific member (or all if "show empty" flag is set) - - BOOL bShowEmpty = pThisLevel->getShowEmpty(); - if ( bIsDataLayout || bShowEmpty ) - { - long nCount = maMemberArray.size(); - for (long i=0; i<nCount; i++) + if ( bLateInitAllMembers ) { - ScDPResultMember* pResultMember = maMemberArray[i]; - ScDPItemData aMemberData; - pResultMember->FillItemData( aMemberData ); - rInitState.AddMember( nDimSource, aMemberData ); - pResultMember->LateInitFrom( ppDim, ppLev, pItemData, nPos+1, rInitState ); - rInitState.RemoveMember(); + long nCount = maMemberArray.size(); + for (long i=0; i<nCount; i++) + { + ScDPResultMember* pResultMember = maMemberArray[i]; + + // check show empty + BOOL bAllChildren = FALSE; + if( bShowEmpty ) + { + if ( pResultMember->IsNamedItem( rThisData ) ) + bAllChildren = FALSE; + else + bAllChildren = TRUE; + } + rParams.SetInitAllChildren( bAllChildren ); + rInitState.AddMember( nDimSource, pResultMember->GetDataId() ); + pResultMember->LateInitFrom( rParams, pItemData, nPos+1, rInitState ); + rInitState.RemoveMember(); + } } - } - else - { - ScDPResultMember* pResultMember = FindMember( rThisData ); - if( NULL != pResultMember ) + else { - ScDPItemData aMemberData; - pResultMember->FillItemData( aMemberData ); - rInitState.AddMember( nDimSource, aMemberData ); - pResultMember->LateInitFrom( ppDim, ppLev, pItemData, nPos+1, rInitState ); - rInitState.RemoveMember(); + ScDPResultMember* pResultMember = FindMember( rThisData ); + if( NULL != pResultMember ) + { + //DBG_TRACE( "ScDPResultDimension::LateInitFrom"); + // DBG_TRACESTR( pResultMember->GetDPMember()->GetNameStr()); + + rInitState.AddMember( nDimSource, pResultMember->GetDataId() ); + pResultMember->LateInitFrom( rParams, pItemData, nPos+1, rInitState ); + rInitState.RemoveMember(); + } } } + else + InitWithMembers( rParams, pItemData, nPos, rInitState ); } long ScDPResultDimension::GetSize(long nMeasure) const @@ -2811,7 +2987,7 @@ long ScDPResultDimension::GetSize(long nMeasure) const return nTotal; } -bool ScDPResultDimension::IsValidEntry( const vector<ScDPItemData>& aMembers ) const +bool ScDPResultDimension::IsValidEntry( const vector< SCROW >& aMembers ) const { if (aMembers.empty()) return false; @@ -2819,14 +2995,18 @@ bool ScDPResultDimension::IsValidEntry( const vector<ScDPItemData>& aMembers ) c const ScDPResultMember* pMember = FindMember( aMembers[0] ); if ( NULL != pMember ) return pMember->IsValidEntry( aMembers ); - - DBG_ERROR("IsValidEntry: Member not found"); +#ifdef DBG_UTIL + ByteString strTemp ("IsValidEntry: Member not found, DimName = " ); + strTemp += ByteString( GetName(), RTL_TEXTENCODING_UTF8 ); + DBG_TRACE( strTemp.GetBuffer() ); + // DBG_ERROR("IsValidEntry: Member not found"); +#endif return false; } -void ScDPResultDimension::ProcessData( const vector<ScDPItemData>& aMembers, +void ScDPResultDimension::ProcessData( const vector< SCROW >& aMembers, const ScDPResultDimension* pDataDim, - const vector<ScDPItemData>& aDataMembers, + const vector< SCROW >& aDataMembers, const vector<ScDPValueData>& aValues ) const { if (aMembers.empty()) @@ -2835,11 +3015,11 @@ void ScDPResultDimension::ProcessData( const vector<ScDPItemData>& aMembers, ScDPResultMember* pMember = FindMember( aMembers[0] ); if ( NULL != pMember ) { - vector<ScDPItemData> aChildMembers; + vector</*ScDPItemData*/SCROW > aChildMembers; if (aMembers.size() > 1) { - vector<ScDPItemData>::const_iterator itr = aMembers.begin(); - aChildMembers.assign(++itr, aMembers.end()); + vector</*ScDPItemData*/SCROW >::const_iterator itr = aMembers.begin(); + aChildMembers.insert(aChildMembers.begin(), ++itr, aMembers.end()); } pMember->ProcessData( aChildMembers, pDataDim, aDataMembers, aValues ); return; @@ -3372,7 +3552,7 @@ void ScDPDataDimension::InitFrom( const ScDPResultDimension* pDim ) } } -void ScDPDataDimension::ProcessData( const vector<ScDPItemData>& aDataMembers, const vector<ScDPValueData>& aValues, +void ScDPDataDimension::ProcessData( const vector< SCROW >& aDataMembers, const vector<ScDPValueData>& aValues, const ScDPSubTotalState& rSubState ) { // the ScDPItemData array must contain enough entries for all dimensions - this isn't checked @@ -3385,11 +3565,11 @@ void ScDPDataDimension::ProcessData( const vector<ScDPItemData>& aDataMembers, c // always first member for data layout dim if ( bIsDataLayout || ( !aDataMembers.empty() && pMember->IsNamedItem(aDataMembers[0]) ) ) { - vector<ScDPItemData> aChildDataMembers; + vector</*ScDPItemData*/SCROW> aChildDataMembers; if (aDataMembers.size() > 1) { - vector<ScDPItemData>::const_iterator itr = aDataMembers.begin(); - aChildDataMembers.assign(++itr, aDataMembers.end()); + vector</*ScDPItemData*/SCROW >::const_iterator itr = aDataMembers.begin(); + aChildDataMembers.insert(aChildDataMembers.begin(), ++itr, aDataMembers.end()); } pMember->ProcessData( aChildDataMembers, aValues, rSubState ); return; @@ -3660,8 +3840,7 @@ ScDPDataMember* ScDPDataDimension::GetMember(long n) const // ---------------------------------------------------------------------------- ScDPResultVisibilityData::ScDPResultVisibilityData( - ScSimpleSharedString& rSharedString, ScDPSource* pSource) : - mrSharedString(rSharedString), + ScDPSource* pSource) : mpSource(pSource) { } @@ -3715,7 +3894,8 @@ void ScDPResultVisibilityData::fillFieldFilters(vector<ScDPCacheTable::Criterion long nDimIndex = itrField->second; aCri.mnFieldIndex = static_cast<sal_Int32>(nDimIndex); - aCri.mpFilter.reset(new ScDPCacheTable::GroupFilter(mrSharedString)); + aCri.mpFilter.reset(new ScDPCacheTable::GroupFilter(/*mrSharedString*/)); + ScDPCacheTable::GroupFilter* pGrpFilter = static_cast<ScDPCacheTable::GroupFilter*>(aCri.mpFilter.get()); @@ -3724,7 +3904,7 @@ void ScDPResultVisibilityData::fillFieldFilters(vector<ScDPCacheTable::Criterion itrMem != itrMemEnd; ++itrMem) { const ScDPItemData& rMemItem = *itrMem; - pGrpFilter->addMatchItem(rMemItem.aString, rMemItem.fValue, rMemItem.bHasValue); + pGrpFilter->addMatchItem(rMemItem.GetString(), rMemItem.GetValue(), rMemItem.IsValue()); } ScDPDimension* pDim = pDims->getByIndex(nDimIndex); @@ -3737,8 +3917,188 @@ void ScDPResultVisibilityData::fillFieldFilters(vector<ScDPCacheTable::Criterion size_t ScDPResultVisibilityData::MemberHash::operator() (const ScDPItemData& r) const { - if (r.bHasValue) - return static_cast<size_t>(::rtl::math::approxFloor(r.fValue)); + if (r.IsValue()) + return static_cast<size_t>(::rtl::math::approxFloor(r.GetValue())); else - return rtl_ustr_hashCode_WithLength(r.aString.GetBuffer(), r.aString.Len()); + return rtl_ustr_hashCode_WithLength(r.GetString().GetBuffer(), r.GetString().Len()); +} +// Wang Xu Ming -- 2009-6-10 +// DataPilot Migration +SCROW ScDPResultMember::GetDataId( ) const +{ + const ScDPMember* pMemberDesc = GetDPMember(); + if (pMemberDesc) + return pMemberDesc->GetItemDataId(); + return -1; +} + +ScDPResultMember* ScDPResultDimension::AddMember(const ScDPParentDimData &aData ) +{ + ScDPResultMember* pMember = new ScDPResultMember( pResultData, aData, FALSE ); + SCROW nDataIndex = pMember->GetDataId(); + maMemberArray.push_back( pMember ); + + if ( maMemberHash.end() == maMemberHash.find( nDataIndex ) ) + maMemberHash.insert( std::pair< SCROW, ScDPResultMember *>( nDataIndex, pMember ) ); + return pMember; +} + +ResultMembers* ScDPResultDimension::GetResultMember( ScDPDimension* pThisDim, ScDPLevel* pThisLevel ) +{ + ResultMembers* pResultMembers = new ResultMembers(); + // global order is used to initialize aMembers, so it doesn't have to be looked at later + const ScMemberSortOrder& rGlobalOrder = pThisLevel->GetGlobalOrder(); + + ScDPMembers* pMembers = pThisLevel->GetMembersObject(); + long nMembCount = pMembers->getCount(); + for ( long i=0; i<nMembCount; i++ ) + { + long nSorted = rGlobalOrder.empty() ? i : rGlobalOrder[i]; + ScDPMember* pMember = pMembers->getByIndex(nSorted); + if ( NULL == pResultMembers->FindMember( pMember->GetItemDataId() ) ) + { + ScDPParentDimData* pNew = new ScDPParentDimData( i, pThisDim, pThisLevel, pMember ); + pResultMembers->InsertMember( pNew ); + } + } + return pResultMembers; } + +ScDPResultMember* ScDPResultDimension::InsertMember(ScDPParentDimData *pMemberData) +{ + SCROW nInsert = 0; + if ( !lcl_SearchMember( maMemberArray, pMemberData->mnOrder , nInsert ) ) + { //Member not exist + ScDPResultMember* pNew = new ScDPResultMember( pResultData, *pMemberData, FALSE ); + maMemberArray.insert( maMemberArray.begin()+nInsert, pNew ); + + SCROW nDataIndex = pMemberData->mpMemberDesc->GetItemDataId(); + if ( maMemberHash.end() == maMemberHash.find( nDataIndex ) ) + maMemberHash.insert( std::pair< SCROW, ScDPResultMember *>( nDataIndex, pNew ) ); + return pNew; + } + return maMemberArray[ nInsert ]; +} + +void ScDPResultDimension:: InitWithMembers( LateInitParams& rParams, + const ::std::vector< SCROW >& pItemData, + size_t nPos, + ScDPInitState& rInitState ) +{ + if ( rParams.IsEnd( nPos ) ) + return; + ScDPDimension* pThisDim = rParams.GetDim( nPos ); + ScDPLevel* pThisLevel = rParams.GetLevel( nPos ); + SCROW nDataID = pItemData[nPos]; + + if (pThisDim && pThisLevel) + { + long nDimSource = pThisDim->GetDimension(); //! check GetSourceDim? + + // create all members at the first call (preserve order) + ResultMembers* pMembers = pResultData->GetDimResultMembers(nDimSource, pThisDim, pThisLevel); + ScDPGroupCompare aCompare( pResultData, rInitState, nDimSource ); + // initialize only specific member (or all if "show empty" flag is set) + ScDPResultMember* pResultMember = NULL; + if ( bInitialized ) + pResultMember = FindMember( nDataID ); + else + bInitialized = TRUE; + + if ( pResultMember == NULL ) + { //only insert found item + ScDPParentDimData* pMemberData = pMembers->FindMember( nDataID ); + if ( pMemberData && aCompare.IsIncluded( *( pMemberData->mpMemberDesc ) ) ) + pResultMember = InsertMember( pMemberData ); + } + if ( pResultMember ) + { + // DBG_TRACE( "ScDPResultDimension::InitWithMembers"); + // DBG_TRACESTR( pResultMember->GetDPMember()->GetNameStr()); + rInitState.AddMember( nDimSource, pResultMember->GetDataId() ); + pResultMember->LateInitFrom( rParams /*ppDim, ppLev*/, pItemData, nPos+1 , rInitState ); + rInitState.RemoveMember(); + } + } +} + +ScDPParentDimData* ResultMembers::FindMember( const SCROW& nIndex ) const +{ + DimMemberHash::const_iterator aRes = maMemberHash.find( nIndex ); + if( aRes != maMemberHash.end()) { + if ( aRes->second->mpMemberDesc && aRes->second->mpMemberDesc->GetItemDataId()==nIndex ) + return aRes->second; + } + return NULL; +} +void ResultMembers::InsertMember( ScDPParentDimData* pNew ) +{ + if ( !pNew->mpMemberDesc->getShowDetails() ) + mbHasHideDetailsMember = TRUE; + maMemberHash.insert( std::pair< const SCROW, ScDPParentDimData *>( pNew->mpMemberDesc->GetItemDataId(), pNew ) ); +} + +ResultMembers::ResultMembers(): + mbHasHideDetailsMember( FALSE ) +{ +} +ResultMembers::~ResultMembers() +{ + for ( DimMemberHash::const_iterator iter = maMemberHash.begin(); iter != maMemberHash.end(); iter++ ) + delete iter->second; +} +// ----------------------------------------------------------------------- +LateInitParams::LateInitParams( const vector<ScDPDimension*>& ppDim, const vector<ScDPLevel*>& ppLev, BOOL bRow, BOOL bInitChild, BOOL bAllChildren ): + mppDim( ppDim ), + mppLev( ppLev ), + mbRow( bRow ), + mbInitChild( bInitChild ), + mbAllChildren( bAllChildren ) +{ +} + +LateInitParams::~LateInitParams() +{ +} + +BOOL LateInitParams::IsEnd( size_t nPos ) const +{ + return nPos >= mppDim.size(); +} + +// End Comments +// Wang Xu Ming -- 2009-8-4 +// DataPilot Migration - old defects merge +void ScDPResultDimension::CheckShowEmpty( BOOL bShow ) +{ + long nCount = maMemberArray.size(); + + ScDPResultMember* pMember = NULL; + for (long i=0; i<nCount; i++) + { + pMember = maMemberArray.at(i); + pMember->CheckShowEmpty( bShow ); + } + +} + +void ScDPResultMember::CheckShowEmpty( BOOL bShow ) +{ + if ( bHasElements ) + { + ScDPResultDimension* pChildDim = GetChildDimension(); + if (pChildDim ) + pChildDim->CheckShowEmpty(); + } + else if ( IsValid() && bInitialized ) + { + bShow = bShow || ( GetParentLevel() && GetParentLevel()->getShowEmpty() ); + if ( bShow ) + { + SetHasElements(); + ScDPResultDimension* pChildDim = GetChildDimension(); + if (pChildDim ) + pChildDim->CheckShowEmpty( TRUE ); + } + } +}// End Comments diff --git a/sc/source/core/data/dptabresmember.cxx b/sc/source/core/data/dptabresmember.cxx new file mode 100644 index 000000000000..8c3b7b164bc3 --- /dev/null +++ b/sc/source/core/data/dptabresmember.cxx @@ -0,0 +1,831 @@ +/************************************************************************* + * + * 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 new file mode 100644 index 000000000000..72657167d07d --- /dev/null +++ b/sc/source/core/data/dptabresmember.hxx @@ -0,0 +1,161 @@ +/************************************************************************* + * + * 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/dptabsrc.cxx b/sc/source/core/data/dptabsrc.cxx index 205c14021444..da40e6e230c4 100644..100755 --- a/sc/source/core/data/dptabsrc.cxx +++ b/sc/source/core/data/dptabsrc.cxx @@ -300,10 +300,11 @@ void ScDPSource::SetOrientation(long nColumn, USHORT nNew) case sheet::DataPilotFieldOrientation_PAGE: nPageDims[nPageDimCount++] = nColumn; break; + // Wang Xu Ming -- 2009-9-1 + // DataPilot Migration - Cache&&Performance case sheet::DataPilotFieldOrientation_HIDDEN: - /* Do not assert HIDDEN as it occurs e.g. while using the - csss.XDataPilotTables.createDataPilotDescriptor() function. */ break; + // End Comments default: DBG_ERROR( "ScDPSource::SetOrientation: unexpected orientation" ); break; @@ -325,6 +326,11 @@ BOOL ScDPSource::IsDateDimension(long nDim) return pData->IsDateDimension(nDim); } +UINT32 ScDPSource::GetNumberFormat(long nDim) +{ + return pData->GetNumberFormat( nDim ); +} + ScDPDimensions* ScDPSource::GetDimensionsObject() { if (!pDimensions) @@ -442,7 +448,6 @@ Sequence< Sequence<Any> > SAL_CALL ScDPSource::getDrillDownData(const Sequence<s throw (uno::RuntimeException) { long nColumnCount = GetData()->GetColumnCount(); - ScSimpleSharedString& rSharedString = GetData()->GetSharedString(); typedef hash_map<String, long, ScStringHashCode> FieldNameMapType; FieldNameMapType aFieldNames; @@ -472,17 +477,16 @@ Sequence< Sequence<Any> > SAL_CALL ScDPSource::getDrillDownData(const Sequence<s ScDPItemData aItem; pMembers->getByIndex(nIndex)->FillItemData( aItem ); aFilterCriteria.push_back( ScDPCacheTable::Criterion() ); - sal_Int32 nMatchStrId = rSharedString.getStringId(aItem.aString); aFilterCriteria.back().mnFieldIndex = nCol; aFilterCriteria.back().mpFilter.reset( - new ScDPCacheTable::SingleFilter(rSharedString, nMatchStrId, aItem.fValue, aItem.bHasValue) ); + new ScDPCacheTable::SingleFilter(aItem.GetString()/*rSharedString, nMatchStrId*/, aItem.GetValue(), aItem.IsValue()) ); } } } } // Take into account the visibilities of field members. - ScDPResultVisibilityData aResVisData(rSharedString, this); + ScDPResultVisibilityData aResVisData(/*rSharedString, */this); pRowResRoot->FillVisibilityData(aResVisData); pColResRoot->FillVisibilityData(aResVisData); aResVisData.fillFieldFilters(aFilterCriteria); @@ -737,7 +741,6 @@ void ScDPSource::GetCategoryDimensionIndices(hash_set<sal_Int32>& rCatDims) void ScDPSource::FilterCacheTableByPageDimensions() { - ScSimpleSharedString& rSharedString = GetData()->GetSharedString(); // filter table by page dimensions. vector<ScDPCacheTable::Criterion> aCriteria; @@ -752,7 +755,7 @@ void ScDPSource::FilterCacheTableByPageDimensions() long nMemCount = pMems->getCount(); ScDPCacheTable::Criterion aFilter; aFilter.mnFieldIndex = static_cast<sal_Int32>(nField); - aFilter.mpFilter.reset(new ScDPCacheTable::GroupFilter(rSharedString)); + aFilter.mpFilter.reset(new ScDPCacheTable::GroupFilter(/*rSharedString*/)); ScDPCacheTable::GroupFilter* pGrpFilter = static_cast<ScDPCacheTable::GroupFilter*>(aFilter.mpFilter.get()); for (long j = 0; j < nMemCount; ++j) @@ -762,7 +765,7 @@ void ScDPSource::FilterCacheTableByPageDimensions() { ScDPItemData aData; pMem->FillItemData(aData); - pGrpFilter->addMatchItem(aData.aString, aData.fValue, aData.bHasValue); + pGrpFilter->addMatchItem(aData.GetString(), aData.GetValue(), aData.IsValue()); } } if (pGrpFilter->getMatchItemCount() < static_cast<size_t>(nMemCount)) @@ -776,9 +779,8 @@ void ScDPSource::FilterCacheTableByPageDimensions() aCriteria.push_back(ScDPCacheTable::Criterion()); ScDPCacheTable::Criterion& r = aCriteria.back(); r.mnFieldIndex = static_cast<sal_Int32>(nField); - sal_Int32 nStrId = rSharedString.getStringId(rData.aString); r.mpFilter.reset( - new ScDPCacheTable::SingleFilter(rSharedString, nStrId, rData.fValue, rData.bHasValue)); + new ScDPCacheTable::SingleFilter(rData.GetString()/*rSharedString, nStrId*/, rData.GetValue(), rData.IsValue())); } if (!aCriteria.empty()) { @@ -900,11 +902,11 @@ void ScDPSource::CreateRes_Impl() { ScDPDimension* pDim = GetDimensionsObject()->getByIndex( nPageDims[i] ); if ( pDim->HasSelectedPage() ) - aInitState.AddMember( nPageDims[i], pDim->GetSelectedData() ); + aInitState.AddMember( nPageDims[i], GetMemberId( nPageDims[i], pDim->GetSelectedData() ) ); } - pColResRoot = new ScDPResultMember( pResData, NULL, NULL, NULL, bColumnGrand ); - pRowResRoot = new ScDPResultMember( pResData, NULL, NULL, NULL, bRowGrand ); + pColResRoot = new ScDPResultMember( pResData, /*NULL, NULL, NULL, */bColumnGrand ); + pRowResRoot = new ScDPResultMember( pResData, /*NULL, NULL, NULL, */bRowGrand ); FillCalcInfo(false, aInfo, bHasAutoShow); long nColLevelCount = aInfo.aColLevels.size(); @@ -944,7 +946,7 @@ void ScDPSource::CreateRes_Impl() long nMinColMembers = lcl_CountMinMembers( aInfo.aColDims, aInfo.aColLevels, nColLevelCount ); long nMinRowMembers = lcl_CountMinMembers( aInfo.aRowDims, aInfo.aRowLevels, nRowLevelCount ); - if ( nMinColMembers > SC_MINCOUNT_LIMIT || nMinRowMembers > SC_MINCOUNT_LIMIT ) + if ( nMinColMembers > MAXCOLCOUNT/*SC_MINCOUNT_LIMIT*/ || nMinRowMembers > SC_MINCOUNT_LIMIT ) { // resulting table is too big -> abort before calculating // (this relies on late init, so no members are allocated in InitFrom above) @@ -964,6 +966,8 @@ void ScDPSource::CreateRes_Impl() aInfo.pRowRoot = pRowResRoot; pData->CalcResults(aInfo, false); + pColResRoot->CheckShowEmpty(); + pRowResRoot->CheckShowEmpty(); // ---------------------------------------------------------------- // With all data processed, calculate the final results: @@ -1549,6 +1553,19 @@ const ScDPItemData& ScDPDimension::GetSelectedData() //UNUSED2009-05 return TRUE; // no selection -> all data //UNUSED2009-05 } +BOOL ScDPDimension::IsVisible( const ScDPItemData& rData ) +{ + if( ScDPMembers* pMembers = this->GetHierarchiesObject()->getByIndex(0)-> + GetLevelsObject()->getByIndex(0)->GetMembersObject() ) + { + for( long i = pMembers->getCount()-1; i>=0; i-- ) + if( ScDPMember *pDPMbr = pMembers->getByIndex( i ) ) + if( rData.IsCaseInsEqual( pDPMbr->GetItemData() ) && !pDPMbr->getIsVisible() ) + return FALSE; + } + + return TRUE; +} // XPropertySet uno::Reference<beans::XPropertySetInfo> SAL_CALL ScDPDimension::getPropertySetInfo() @@ -1692,6 +1709,23 @@ uno::Any SAL_CALL ScDPDimension::getPropertyValue( const rtl::OUString& aPropert // #i63745# don't use source format for "count" if ( eFunc != sheet::GeneralFunction_COUNT && eFunc != sheet::GeneralFunction_COUNTNUMS ) nFormat = pSource->GetData()->GetNumberFormat( ( nSourceDim >= 0 ) ? nSourceDim : nDim ); + + switch ( aReferenceValue.ReferenceType ) + { + case sheet::DataPilotFieldReferenceType::ITEM_PERCENTAGE: + case sheet::DataPilotFieldReferenceType::ITEM_PERCENTAGE_DIFFERENCE: + case sheet::DataPilotFieldReferenceType::ROW_PERCENTAGE: + case sheet::DataPilotFieldReferenceType::COLUMN_PERCENTAGE: + case sheet::DataPilotFieldReferenceType::TOTAL_PERCENTAGE: + nFormat = pSource->GetData()->GetNumberFormatByIdx( (NfIndexTableOffset)NF_PERCENT_DEC2 ); + break; + case sheet::DataPilotFieldReferenceType::INDEX: + nFormat = pSource->GetData()->GetNumberFormatByIdx( (NfIndexTableOffset)NF_NUMBER_SYSTEM ); + break; + default: + break; + } + aRet <<= nFormat; } else if ( aNameStr.EqualsAscii( SC_UNO_ORIGINAL ) ) @@ -2355,15 +2389,6 @@ SC_IMPL_DUMMY_PROPERTY_LISTENER( ScDPLevel ) // ----------------------------------------------------------------------- -USHORT lcl_GetFirstStringPos( const TypedScStrCollection& rColl ) -{ - USHORT nPos = 0; - USHORT nCount = rColl.GetCount(); - while ( nPos < nCount && !rColl[nPos]->IsStrData() ) - ++nPos; - return nPos; -} - ScDPMembers::ScDPMembers( ScDPSource* pSrc, long nD, long nH, long nL ) : pSource( pSrc ), nDim( nD ), @@ -2385,12 +2410,23 @@ ScDPMembers::ScDPMembers( ScDPSource* pSrc, long nD, long nH, long nL ) : { case SC_DAPI_LEVEL_YEAR: { - const TypedScStrCollection& rStrings = pSource->GetData()->GetColumnEntries(nSrcDim); - USHORT nFirstString = lcl_GetFirstStringPos( rStrings ); - if ( nFirstString > 0 ) + // Wang Xu Ming - DataPilot migration + const ScDPItemData* pLastNumData = NULL; + for ( SCROW n = 0 ;n <GetSrcItemsCount() ; n-- ) { - double fFirstVal = rStrings[0]->GetValue(); - double fLastVal = rStrings[nFirstString-1]->GetValue(); + const ScDPItemData* pData = GetSrcItemDataByIndex( n ); + if ( pData && pData->HasStringData() ) + break; + else + pLastNumData = pData; + } + // End Comments + + if ( pLastNumData ) + { + const ScDPItemData* pFirstData = GetSrcItemDataByIndex( 0 ); + double fFirstVal = pFirstData->GetValue(); + double fLastVal = pLastNumData->GetValue(); long nFirstYear = pSource->GetData()->GetDatePart( (long)::rtl::math::approxFloor( fFirstVal ), @@ -2427,11 +2463,7 @@ ScDPMembers::ScDPMembers( ScDPSource* pSrc, long nD, long nH, long nL ) : } } else - { - // StringCollection is cached at TableData - const TypedScStrCollection& rStrings = pSource->GetData()->GetColumnEntries(nSrcDim); - nMbrCount = rStrings.GetCount(); - } + nMbrCount = pSource->GetData()->GetMembersCount( nSrcDim ); } ScDPMembers::~ScDPMembers() @@ -2567,8 +2599,7 @@ ScDPMember* ScDPMembers::getByIndex(long nIndex) const if ( pSource->IsDataLayoutDimension(nSrcDim) ) { // empty name (never shown, not used for lookup) - pNew = new ScDPMember( pSource, nDim, nHier, nLev, - String(), 0.0, FALSE ); + pNew = new ScDPMember( pSource, nDim, nHier, nLev, 0 ); } else if ( nHier != SC_DAPI_HIERARCHY_FLAT && pSource->IsDateDimension( nSrcDim ) ) { @@ -2579,12 +2610,13 @@ ScDPMember* ScDPMembers::getByIndex(long nIndex) const { //! cache year range here! - const TypedScStrCollection& rStrings = pSource->GetData()->GetColumnEntries(nSrcDim); - double fFirstVal = rStrings[0]->GetValue(); + // Wang Xu Ming - DataPilot migration + double fFirstVal = pSource->GetData()->GetMemberByIndex( nSrcDim, 0 )->GetValue(); long nFirstYear = pSource->GetData()->GetDatePart( (long)::rtl::math::approxFloor( fFirstVal ), nHier, nLev ); + // End Comments nVal = nFirstYear + nIndex; } else if ( nHier == SC_DAPI_HIERARCHY_WEEK && nLev == SC_DAPI_LEVEL_WEEKDAY ) @@ -2607,19 +2639,20 @@ ScDPMember* ScDPMembers::getByIndex(long nIndex) const if ( !aName.Len() ) aName = String::CreateFromInt32(nVal); - pNew = new ScDPMember( pSource, nDim, nHier, nLev, aName, nVal, TRUE ); + ScDPItemData rData( aName, nVal, TRUE, 0 ) ; + pNew = new ScDPMember( pSource, nDim, nHier, nLev, pSource->GetCache()->GetAdditionalItemID(rData)); } else { - const TypedScStrCollection& rStrings = pSource->GetData()->GetColumnEntries(nSrcDim); - const TypedStrData* pData = rStrings[(USHORT)nIndex]; - pNew = new ScDPMember( pSource, nDim, nHier, nLev, - pData->GetString(), pData->GetValue(), !pData->IsStrData() ); + const std::vector< SCROW >& memberIndexs = pSource->GetData()->GetColumnEntries( nSrcDim ); + pNew = new ScDPMember( pSource, nDim, nHier, nLev, memberIndexs[nIndex] ); } pNew->acquire(); // ref-counted ppMbrs[nIndex] = pNew; } + DBG_ASSERT( ppMbrs[nIndex] ," member is not initialized " ); + return ppMbrs[nIndex]; } @@ -2629,12 +2662,12 @@ ScDPMember* ScDPMembers::getByIndex(long nIndex) const // ----------------------------------------------------------------------- ScDPMember::ScDPMember( ScDPSource* pSrc, long nD, long nH, long nL, - const String& rN, double fV, BOOL bHV ) : + SCROW nIndex /*const String& rN, double fV, BOOL bHV*/ ) : pSource( pSrc ), nDim( nD ), nHier( nH ), nLev( nL ), - maData( rN, fV, bHV ), + mnDataId( nIndex ), mpLayoutName(NULL), nPosition( -1 ), bVisible( TRUE ), @@ -2651,17 +2684,36 @@ ScDPMember::~ScDPMember() BOOL ScDPMember::IsNamedItem( const ScDPItemData& r ) const { long nSrcDim = pSource->GetSourceDim( nDim ); - if ( nHier != SC_DAPI_HIERARCHY_FLAT && pSource->IsDateDimension( nSrcDim ) && r.bHasValue ) + if ( nHier != SC_DAPI_HIERARCHY_FLAT && pSource->IsDateDimension( nSrcDim ) && r.IsValue() ) { long nComp = pSource->GetData()->GetDatePart( - (long)::rtl::math::approxFloor( r.fValue ), + (long)::rtl::math::approxFloor( r.GetValue() ), nHier, nLev ); // fValue is converted from integer, so simple comparison works - return nComp == maData.fValue; + return nComp == GetItemData().GetValue(); } - return r.IsCaseInsEqual( maData ); + return r.IsCaseInsEqual( GetItemData() ); +} + +BOOL ScDPMember::IsNamedItem( SCROW nIndex ) const +{ + long nSrcDim = pSource->GetSourceDim( nDim ); + if ( nHier != SC_DAPI_HIERARCHY_FLAT && pSource->IsDateDimension( nSrcDim ) ) + { + const ScDPItemData* pData = pSource->GetCache()->GetItemDataById( (SCCOL) nSrcDim, nIndex ); + if ( pData->IsValue() ) + { + long nComp = pSource->GetData()->GetDatePart( + (long)::rtl::math::approxFloor( pData->GetValue() ), + nHier, nLev ); + // fValue is converted from integer, so simple comparison works + return nComp == GetItemData().GetValue(); + } + } + + return nIndex == mnDataId; } sal_Int32 ScDPMember::Compare( const ScDPMember& rOther ) const @@ -2686,14 +2738,14 @@ sal_Int32 ScDPMember::Compare( const ScDPMember& rOther ) const } // no positions set - compare names - return ScDPItemData::Compare( maData, rOther.maData ); + return pSource->GetData()->Compare( pSource->GetSourceDim(nDim),mnDataId,rOther.GetItemDataId()); } void ScDPMember::FillItemData( ScDPItemData& rData ) const { //! handle date hierarchy... - rData = maData; + rData = GetItemData() ; } const OUString* ScDPMember::GetLayoutName() const @@ -2703,12 +2755,12 @@ const OUString* ScDPMember::GetLayoutName() const String ScDPMember::GetNameStr() const { - return maData.aString; + return GetItemData().GetString(); } ::rtl::OUString SAL_CALL ScDPMember::getName() throw(uno::RuntimeException) { - return maData.aString; + return GetItemData().GetString(); } void SAL_CALL ScDPMember::setName( const ::rtl::OUString& /* rNewName */ ) throw(uno::RuntimeException) @@ -2822,4 +2874,48 @@ uno::Any SAL_CALL ScDPMember::getPropertyValue( const rtl::OUString& aPropertyNa SC_IMPL_DUMMY_PROPERTY_LISTENER( ScDPMember ) +ScDPTableDataCache* ScDPSource::GetCache() +{ + DBG_ASSERT( GetData() , "empty ScDPTableData pointer"); + return ( GetData()!=NULL) ? GetData()->GetCacheTable().GetCache() : NULL ; +} + +const ScDPItemData& ScDPMember::GetItemData() const +{ + return *pSource->GetItemDataById( (SCCOL)nDim, mnDataId );//ms-cache-core +} + +const ScDPItemData* ScDPSource::GetItemDataById(long nDim, long nId) +{ + long nSrcDim = GetSourceDim( nDim ); + const ScDPItemData* pItemData = GetData()->GetMemberById( nSrcDim, nId ); + if ( !pItemData ) + { //todo: + ScDPItemData item; + nId = GetCache()->GetAdditionalItemID( item ); + pItemData = GetData()->GetMemberById( nSrcDim, nId ); + } + return pItemData; +} + +SCROW ScDPSource::GetMemberId( long nDim, const ScDPItemData& rData ) +{ + long nSrcDim = GetSourceDim( nDim ); + return GetCache()->GetIdByItemData( nSrcDim, rData ); +} + +const ScDPItemData* ScDPMembers::GetSrcItemDataByIndex( SCROW nIndex) +{ + const std::vector< SCROW >& memberIds = pSource->GetData()->GetColumnEntries( nDim ); + if ( nIndex >= (long )(memberIds.size()) || nIndex < 0 ) + return NULL; + SCROW nId = memberIds[ nIndex ]; + return pSource->GetItemDataById( nDim, nId ); +} + + SCROW ScDPMembers::GetSrcItemsCount() + { + return pSource->GetData()->GetColumnEntries( nDim ).size(); + } +// End Comments diff --git a/sc/source/core/data/drwlayer.cxx b/sc/source/core/data/drwlayer.cxx index 4e9de6179809..69dee934ce66 100644..100755 --- a/sc/source/core/data/drwlayer.cxx +++ b/sc/source/core/data/drwlayer.cxx @@ -28,6 +28,7 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sc.hxx" #include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/chart/XChartDocument.hpp> #include <com/sun/star/embed/XEmbeddedObject.hpp> #include <com/sun/star/embed/XVisualObject.hpp> #include <com/sun/star/embed/XClassifiedObject.hpp> @@ -79,6 +80,7 @@ #include "chartarr.hxx" #include "postit.hxx" #include "attrib.hxx" +#include "charthelper.hxx" #define DET_ARROW_OFFSET 1000 @@ -1386,7 +1388,9 @@ void ScDrawLayer::CopyToClip( ScDocument* pClipDoc, SCTAB nTab, const Rectangle& pNewObject->SetModel(pDestModel); pNewObject->SetPage(pDestPage); - pNewObject->NbcMove(Size(0,0)); + uno::Reference< chart2::XChartDocument > xOldChart( ScChartHelper::GetChartFromSdrObject( pOldObject ) ); + if(!xOldChart.is())//#i110034# do not move charts as they loose all their data references otherwise + pNewObject->NbcMove(Size(0,0)); pDestPage->InsertObject( pNewObject ); // no undo needed in clipboard document @@ -1399,38 +1403,48 @@ void ScDrawLayer::CopyToClip( ScDocument* pClipDoc, SCTAB nTab, const Rectangle& } } -BOOL lcl_IsAllInRange( const ScRangeList& rRanges, const ScRange& rClipRange ) +BOOL lcl_IsAllInRange( const ::std::vector< ScRangeList >& rRangesVector, const ScRange& rClipRange ) { - // check if every range of rRanges is completely in rClipRange + // check if every range of rRangesVector is completely in rClipRange - ULONG nCount = rRanges.Count(); - for (ULONG i=0; i<nCount; i++) + ::std::vector< ScRangeList >::const_iterator aIt = rRangesVector.begin(); + for( ;aIt!=rRangesVector.end(); ++aIt ) { - ScRange aRange = *rRanges.GetObject(i); - if ( !rClipRange.In( aRange ) ) + const ScRangeList& rRanges = *aIt; + ULONG nCount = rRanges.Count(); + for (ULONG i=0; i<nCount; i++) { - return FALSE; // at least one range is not valid + ScRange aRange = *rRanges.GetObject(i); + if ( !rClipRange.In( aRange ) ) + { + return FALSE; // at least one range is not valid + } } } return TRUE; // everything is fine } -BOOL lcl_MoveRanges( ScRangeList& rRanges, const ScRange& rSourceRange, const ScAddress& rDestPos ) +BOOL lcl_MoveRanges( ::std::vector< ScRangeList >& rRangesVector, const ScRange& rSourceRange, const ScAddress& rDestPos ) { BOOL bChanged = FALSE; - ULONG nCount = rRanges.Count(); - for (ULONG i=0; i<nCount; i++) + ::std::vector< ScRangeList >::iterator aIt = rRangesVector.begin(); + for( ;aIt!=rRangesVector.end(); ++aIt ) { - ScRange* pRange = rRanges.GetObject(i); - if ( rSourceRange.In( *pRange ) ) + ScRangeList& rRanges = *aIt; + ULONG nCount = rRanges.Count(); + for (ULONG i=0; i<nCount; i++) { - SCsCOL nDiffX = rDestPos.Col() - (SCsCOL)rSourceRange.aStart.Col(); - SCsROW nDiffY = rDestPos.Row() - (SCsROW)rSourceRange.aStart.Row(); - SCsTAB nDiffZ = rDestPos.Tab() - (SCsTAB)rSourceRange.aStart.Tab(); - pRange->Move( nDiffX, nDiffY, nDiffZ ); - bChanged = TRUE; + ScRange* pRange = rRanges.GetObject(i); + if ( rSourceRange.In( *pRange ) ) + { + SCsCOL nDiffX = rDestPos.Col() - (SCsCOL)rSourceRange.aStart.Col(); + SCsROW nDiffY = rDestPos.Row() - (SCsROW)rSourceRange.aStart.Row(); + SCsTAB nDiffZ = rDestPos.Tab() - (SCsTAB)rSourceRange.aStart.Tab(); + pRange->Move( nDiffX, nDiffY, nDiffZ ); + bChanged = TRUE; + } } } @@ -1469,6 +1483,37 @@ void ScDrawLayer::CopyFromClip( ScDrawLayer* pClipModel, SCTAB nSourceTab, const if ( !pSrcPage || !pDestPage ) return; + SdrObjListIter aIter( *pSrcPage, IM_FLAT ); + SdrObject* pOldObject = aIter.Next(); + + ScDocument* pClipDoc = pClipModel->GetDocument(); + // a clipboard document and its source share the same document item pool, + // so the pointers can be compared to see if this is copy&paste within + // the same document + BOOL bSameDoc = pDoc && pClipDoc && pDoc->GetPool() == pClipDoc->GetPool(); + BOOL bDestClip = pDoc && pDoc->IsClipboard(); + + //#i110034# charts need correct sheet names for xml range conversion during load + //so the target sheet name is temporarily renamed (if we have any SdrObjects) + String aDestTabName; + BOOL bRestoreDestTabName = FALSE; + if( pOldObject && !bSameDoc && !bDestClip ) + { + if( pDoc && pClipDoc ) + { + String aSourceTabName; + if( pClipDoc->GetName( nSourceTab, aSourceTabName ) + && pDoc->GetName( nDestTab, aDestTabName ) ) + { + if( !(aSourceTabName==aDestTabName) && + pDoc->ValidNewTabName(aSourceTabName) ) + { + bRestoreDestTabName = pDoc->RenameTab( nDestTab, aSourceTabName ); //BOOL bUpdateRef = TRUE, BOOL bExternalDocument = FALSE + } + } + } + } + // first mirror, then move Size aMove( rDestRange.Left() - aMirroredSource.Left(), rDestRange.Top() - aMirroredSource.Top() ); @@ -1497,8 +1542,6 @@ void ScDrawLayer::CopyFromClip( ScDrawLayer* pClipModel, SCTAB nSourceTab, const } Point aRefPos = rDestRange.TopLeft(); // for resizing (after moving) - SdrObjListIter aIter( *pSrcPage, IM_FLAT ); - SdrObject* pOldObject = aIter.Next(); while (pOldObject) { Rectangle aObjRect = pOldObject->GetCurrentBoundRect(); @@ -1522,7 +1565,7 @@ void ScDrawLayer::CopyFromClip( ScDrawLayer* pClipModel, SCTAB nSourceTab, const if (bRecording) AddCalcUndo( new SdrUndoInsertObj( *pNewObject ) ); - // handle chart data references (after InsertObject) + //#i110034# handle chart data references (after InsertObject) if ( pNewObject->GetObjIdentifier() == OBJ_OLE2 ) { @@ -1541,73 +1584,63 @@ void ScDrawLayer::CopyFromClip( ScDrawLayer* pClipModel, SCTAB nSourceTab, const if ( xIPObj.is() && SotExchange::IsChart( aObjectClassName ) ) { - String aNewName = ((SdrOle2Obj*)pNewObject)->GetPersistName(); - - //! need to set new DataProvider, or does Chart handle this itself? - - ScRangeListRef xRanges( new ScRangeList ); - BOOL bColHeaders = FALSE; - BOOL bRowHeaders = FALSE; - pDoc->GetOldChartParameters( aNewName, *xRanges, bColHeaders, bRowHeaders ); - - if ( xRanges->Count() > 0 ) + uno::Reference< chart2::XChartDocument > xNewChart( ScChartHelper::GetChartFromSdrObject( pNewObject ) ); + if( xNewChart.is() && !xNewChart->hasInternalDataProvider() ) { - ScDocument* pClipDoc = pClipModel->GetDocument(); - - // a clipboard document and its source share the same document item pool, - // so the pointers can be compared to see if this is copy&paste within - // the same document - BOOL bSameDoc = pDoc && pClipDoc && pDoc->GetPool() == pClipDoc->GetPool(); - - BOOL bDestClip = pDoc && pDoc->IsClipboard(); - - BOOL bInSourceRange = FALSE; - ScRange aClipRange; - if ( pClipDoc ) + String aChartName = ((SdrOle2Obj*)pNewObject)->GetPersistName(); + ::std::vector< ScRangeList > aRangesVector; + pDoc->GetChartRanges( aChartName, aRangesVector, pDoc ); + if( !aRangesVector.empty() ) { - SCCOL nClipStartX; - SCROW nClipStartY; - SCCOL nClipEndX; - SCROW nClipEndY; - pClipDoc->GetClipStart( nClipStartX, nClipStartY ); - pClipDoc->GetClipArea( nClipEndX, nClipEndY, TRUE ); - nClipEndX = nClipEndX + nClipStartX; - nClipEndY += nClipStartY; // GetClipArea returns the difference - - aClipRange = ScRange( nClipStartX, nClipStartY, nSourceTab, - nClipEndX, nClipEndY, nSourceTab ); - - bInSourceRange = lcl_IsAllInRange( *xRanges, aClipRange ); - } + BOOL bInSourceRange = FALSE; + ScRange aClipRange; + if ( pClipDoc ) + { + SCCOL nClipStartX; + SCROW nClipStartY; + SCCOL nClipEndX; + SCROW nClipEndY; + pClipDoc->GetClipStart( nClipStartX, nClipStartY ); + pClipDoc->GetClipArea( nClipEndX, nClipEndY, TRUE ); + nClipEndX = nClipEndX + nClipStartX; + nClipEndY += nClipStartY; // GetClipArea returns the difference + + SCTAB nClipTab = bRestoreDestTabName ? nDestTab : nSourceTab; + aClipRange = ScRange( nClipStartX, nClipStartY, nClipTab, + nClipEndX, nClipEndY, nClipTab ); + + bInSourceRange = lcl_IsAllInRange( aRangesVector, aClipRange ); + } - // always lose references when pasting into a clipboard document (transpose) - if ( ( bInSourceRange || bSameDoc ) && !bDestClip ) - { - if ( bInSourceRange ) + // always lose references when pasting into a clipboard document (transpose) + if ( ( bInSourceRange || bSameDoc ) && !bDestClip ) { - if ( rDestPos != aClipRange.aStart ) + if ( bInSourceRange ) { - // update the data ranges to the new (copied) position - ScRangeListRef xNewRanges = new ScRangeList( *xRanges ); - if ( lcl_MoveRanges( *xNewRanges, aClipRange, rDestPos ) ) + if ( rDestPos != aClipRange.aStart ) { - pDoc->UpdateChartArea( aNewName, xNewRanges, bColHeaders, bRowHeaders, FALSE ); + // update the data ranges to the new (copied) position + if ( lcl_MoveRanges( aRangesVector, aClipRange, rDestPos ) ) + pDoc->SetChartRanges( aChartName, aRangesVector ); } } + else + { + // leave the ranges unchanged + } } else { - // leave the ranges unchanged - } - } - else - { - // pasting into a new document without the complete source data - // -> break connection to source data + // pasting into a new document without the complete source data + // -> break connection to source data and switch to own data - // (see ScDocument::UpdateChartListenerCollection, PastingDrawFromOtherDoc) + uno::Reference< chart::XChartDocument > xOldChartDoc( ScChartHelper::GetChartFromSdrObject( pOldObject ), uno::UNO_QUERY ); + uno::Reference< chart::XChartDocument > xNewChartDoc( xNewChart, uno::UNO_QUERY ); + if( xOldChartDoc.is() && xNewChartDoc.is() ) + xNewChartDoc->attachData( xOldChartDoc->getData() ); - //! need chart interface to switch to own data + // (see ScDocument::UpdateChartListenerCollection, PastingDrawFromOtherDoc) + } } } } @@ -1616,6 +1649,9 @@ void ScDrawLayer::CopyFromClip( ScDrawLayer* pClipModel, SCTAB nSourceTab, const pOldObject = aIter.Next(); } + + if( bRestoreDestTabName ) + pDoc->RenameTab( nDestTab, aDestTabName ); } void ScDrawLayer::MirrorRTL( SdrObject* pObj ) diff --git a/sc/source/core/data/global2.cxx b/sc/source/core/data/global2.cxx index 21c09688aeee..d32ebdafbf78 100644 --- a/sc/source/core/data/global2.cxx +++ b/sc/source/core/data/global2.cxx @@ -49,6 +49,10 @@ #include "rechead.hxx" #include "compiler.hxx" #include "paramisc.hxx" +// Wang Xu Ming -- 2009-5-18 +// DataPilot Migration +#include "dpglobal.hxx" +// End Comments #include "sc.hrc" #include "globstr.hrc" @@ -59,7 +63,6 @@ using ::std::vector; -#define MAX_LABELS 256 //!!! aus fieldwnd.hxx, muss noch nach global.hxx ??? //------------------------------------------------------------------------ // struct ScImportParam: @@ -905,90 +908,3 @@ String ScGlobal::GetDocTabName( const String& rFileName, return aDocTab; } -// ============================================================================ - -ScSimpleSharedString::StringTable::StringTable() : - mnStrCount(0) -{ - // empty string (ID = 0) - maSharedStrings.push_back(String()); - maSharedStringIds.insert( SharedStrMap::value_type(String(), mnStrCount++) ); -} - -ScSimpleSharedString::StringTable::StringTable(const ScSimpleSharedString::StringTable& r) : - maSharedStrings(r.maSharedStrings), - maSharedStringIds(r.maSharedStringIds), - mnStrCount(r.mnStrCount) -{ -} - -ScSimpleSharedString::StringTable::~StringTable() -{ -} - -sal_Int32 ScSimpleSharedString::StringTable::insertString(const String& aStr) -{ - SharedStrMap::const_iterator itr = maSharedStringIds.find(aStr), - itrEnd = maSharedStringIds.end(); - - if (itr == itrEnd) - { - // new string. - maSharedStrings.push_back(aStr); - maSharedStringIds.insert( SharedStrMap::value_type(aStr, mnStrCount) ); - return mnStrCount++; - } - - // existing string. - return itr->second; -} - -sal_Int32 ScSimpleSharedString::StringTable::getStringId(const String& aStr) -{ - SharedStrMap::const_iterator itr = maSharedStringIds.find(aStr), - itrEnd = maSharedStringIds.end(); - if (itr == itrEnd) - { - // string not found. - return insertString(aStr); - } - return itr->second; -} - -const String* ScSimpleSharedString::StringTable::getString(sal_Int32 nId) const -{ - if (nId >= mnStrCount) - return NULL; - - return &maSharedStrings[nId]; -} - -// ---------------------------------------------------------------------------- - -ScSimpleSharedString::ScSimpleSharedString() -{ -} - -ScSimpleSharedString::ScSimpleSharedString(const ScSimpleSharedString& r) : - maStringTable(r.maStringTable) -{ -} - -ScSimpleSharedString::~ScSimpleSharedString() -{ -} - -sal_Int32 ScSimpleSharedString::insertString(const String& aStr) -{ - return maStringTable.insertString(aStr); -} - -const String* ScSimpleSharedString::getString(sal_Int32 nId) -{ - return maStringTable.getString(nId); -} - -sal_Int32 ScSimpleSharedString::getStringId(const String& aStr) -{ - return maStringTable.getStringId(aStr); -} diff --git a/sc/source/core/data/makefile.mk b/sc/source/core/data/makefile.mk index 1dd60f75176e..ab2160a93219 100644..100755 --- a/sc/source/core/data/makefile.mk +++ b/sc/source/core/data/makefile.mk @@ -72,6 +72,7 @@ SLOFILES = \ $(SLO)$/document.obj \ $(SLO)$/dpcachetable.obj \ $(SLO)$/dpdimsave.obj \ + $(SLO)$/dpglobal.obj \ $(SLO)$/dpgroup.obj \ $(SLO)$/dpobject.obj \ $(SLO)$/dpoutput.obj \ @@ -82,6 +83,8 @@ SLOFILES = \ $(SLO)$/dptabdat.obj \ $(SLO)$/dptabres.obj \ $(SLO)$/dptabsrc.obj \ + $(SLO)$/dptablecache.obj\ + $(SLO)$/scdpoutputimpl.obj\ $(SLO)$/drawpage.obj \ $(SLO)$/drwlayer.obj \ $(SLO)$/fillinfo.obj \ @@ -121,6 +124,7 @@ EXCEPTIONSFILES= \ $(SLO)$/documen2.obj \ $(SLO)$/document.obj \ $(SLO)$/dpdimsave.obj \ + $(SLO)$/dpglobal.obj \ $(SLO)$/dpgroup.obj \ $(SLO)$/dpshttab.obj \ $(SLO)$/dptabres.obj \ @@ -135,7 +139,9 @@ EXCEPTIONSFILES= \ $(SLO)$/documen5.obj \ $(SLO)$/documen6.obj \ $(SLO)$/documen9.obj \ - $(SLO)$/dpcachetable.obj \ + $(SLO)$/dpcachetable.obj \ + $(SLO)$/dptablecache.obj \ + $(SLO)$/scdpoutputimpl.obj \ $(SLO)$/dpsdbtab.obj \ $(SLO)$/dpobject.obj \ $(SLO)$/dpoutput.obj \ diff --git a/sc/source/core/data/scdpoutputimpl.cxx b/sc/source/core/data/scdpoutputimpl.cxx new file mode 100644 index 000000000000..6a667806e097 --- /dev/null +++ b/sc/source/core/data/scdpoutputimpl.cxx @@ -0,0 +1,187 @@ +/************************************************************************* + * + * 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: scdpoutputimpl.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" + +// INCLUDE --------------------------------------------------------------- +#include "scdpoutputimpl.hxx" +#include "scitems.hxx" +#include <editeng/boxitem.hxx> +// ----------------------------------------------------------------------- + +namespace +{ + bool lcl_compareColfuc ( SCCOL i, SCCOL j) { return (i<j); } + bool lcl_compareRowfuc ( SCROW i, SCROW j) { return (i<j); } +} + + +void OutputImpl::OutputDataArea() +{ + AddRow( mnDataStartRow ); + AddCol( mnDataStartCol ); + + mnCols.push_back( mnTabEndCol+1); //set last row bottom + mnRows.push_back( mnTabEndRow+1); //set last col bottom + + BOOL bAllRows = ( ( mnTabEndRow - mnDataStartRow + 2 ) == (SCROW) mnRows.size() ); + + std::sort( mnCols.begin(), mnCols.end(), lcl_compareColfuc ); + std::sort( mnRows.begin(), mnRows.end(), lcl_compareRowfuc ); + + for( SCCOL nCol = 0; nCol < (SCCOL)mnCols.size()-1; nCol ++ ) + { + if ( !bAllRows ) + { + if ( nCol < (SCCOL)mnCols.size()-2) + { + for ( SCROW i = nCol%2; i < (SCROW)mnRows.size()-2; i +=2 ) + OutputBlockFrame( mnCols[nCol], mnRows[i], mnCols[nCol+1]-1, mnRows[i+1]-1 ); + if ( mnRows.size()>=2 ) + OutputBlockFrame( mnCols[nCol], mnRows[mnRows.size()-2], mnCols[nCol+1]-1, mnRows[mnRows.size()-1]-1 ); + } + else + { + for ( SCROW i = 0 ; i < (SCROW)mnRows.size()-1; i++ ) + OutputBlockFrame( mnCols[nCol], mnRows[i], mnCols[nCol+1]-1, mnRows[i+1]-1 ); + } + } + else + OutputBlockFrame( mnCols[nCol], mnRows.front(), mnCols[nCol+1]-1, mnRows.back()-1, bAllRows ); + } + //out put rows area outer framer + if ( mnTabStartCol != mnDataStartCol ) + { + if ( mnTabStartRow != mnDataStartRow ) + OutputBlockFrame( mnTabStartCol, mnTabStartRow, mnDataStartCol-1, mnDataStartRow-1 ); + OutputBlockFrame( mnTabStartCol, mnDataStartRow, mnDataStartCol-1, mnTabEndRow ); + } + //out put cols area outer framer + OutputBlockFrame( mnDataStartCol, mnTabStartRow, mnTabEndCol, mnDataStartRow-1 ); +} + +OutputImpl::OutputImpl( ScDocument* pDoc, USHORT nTab, + SCCOL nTabStartCol, + SCROW nTabStartRow, + SCCOL nMemberStartCol, + SCROW nMemberStartRow, + SCCOL nDataStartCol, + SCROW nDataStartRow, + SCCOL nTabEndCol, + SCROW nTabEndRow ): + mpDoc( pDoc ), + mnTab( nTab ), + mnTabStartCol( nTabStartCol ), + mnTabStartRow( nTabStartRow ), + mnMemberStartCol( nMemberStartCol), + mnMemberStartRow( nMemberStartRow), + mnDataStartCol ( nDataStartCol ), + mnDataStartRow ( nDataStartRow ), + mnTabEndCol( nTabEndCol ), + mnTabEndRow( nTabEndRow ) +{ + mbNeedLineCols.resize( nTabEndCol-nDataStartCol+1, false ); + mbNeedLineRows.resize( nTabEndRow-nDataStartRow+1, false ); + +} + +BOOL OutputImpl::AddRow( SCROW nRow ) +{ + if ( !mbNeedLineRows[ nRow - mnDataStartRow ] ) + { + mbNeedLineRows[ nRow - mnDataStartRow ] = true; + mnRows.push_back( nRow ); + return TRUE; + } + else + return FALSE; +} + +BOOL OutputImpl::AddCol( SCCOL nCol ) +{ + + if ( !mbNeedLineCols[ nCol - mnDataStartCol ] ) + { + mbNeedLineCols[ nCol - mnDataStartCol ] = true; + mnCols.push_back( nCol ); + return TRUE; + } + else + return FALSE; +} + +void OutputImpl::OutputBlockFrame ( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, BOOL bHori ) +{ + + SvxBorderLine aLine, aOutLine; + aLine.SetColor( SC_DP_FRAME_COLOR ); + aLine.SetOutWidth( SC_DP_FRAME_INNER_BOLD ); + aOutLine.SetColor( SC_DP_FRAME_COLOR ); + aOutLine.SetOutWidth( SC_DP_FRAME_OUTER_BOLD ); + + SvxBoxItem aBox( ATTR_BORDER ); + + if ( nStartCol == mnTabStartCol ) + aBox.SetLine(&aOutLine, BOX_LINE_LEFT); + else + aBox.SetLine(&aLine, BOX_LINE_LEFT); + + if ( nStartRow == mnTabStartRow ) + aBox.SetLine(&aOutLine, BOX_LINE_TOP); + else + aBox.SetLine(&aLine, BOX_LINE_TOP); + + if ( nEndCol == mnTabEndCol ) //bottom row + aBox.SetLine(&aOutLine, BOX_LINE_RIGHT); + else + aBox.SetLine(&aLine, BOX_LINE_RIGHT); + + if ( nEndRow == mnTabEndRow ) //bottom + aBox.SetLine(&aOutLine, BOX_LINE_BOTTOM); + else + aBox.SetLine(&aLine, BOX_LINE_BOTTOM); + + + SvxBoxInfoItem aBoxInfo( ATTR_BORDER_INNER ); + aBoxInfo.SetValid(VALID_VERT,FALSE ); + if ( bHori ) + { + aBoxInfo.SetValid(VALID_HORI,TRUE); + aBoxInfo.SetLine( &aLine, BOXINFO_LINE_HORI ); + } + else + aBoxInfo.SetValid(VALID_HORI,FALSE ); + + aBoxInfo.SetValid(VALID_DISTANCE,FALSE); + + mpDoc->ApplyFrameAreaTab( ScRange( nStartCol, nStartRow, mnTab, nEndCol, nEndRow , mnTab ), &aBox, &aBoxInfo ); + +} diff --git a/sc/source/core/data/scdpoutputimpl.hxx b/sc/source/core/data/scdpoutputimpl.hxx new file mode 100755 index 000000000000..9148fe91ba02 --- /dev/null +++ b/sc/source/core/data/scdpoutputimpl.hxx @@ -0,0 +1,79 @@ +/************************************************************************* + * + * 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: scdpoutputimpl.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 SCDPOUTPUTIMPL_HXX +#define SCDPOUTPUTIMPL_HXX + +#include "document.hxx" + +#define SC_DP_FRAME_INNER_BOLD 20 +#define SC_DP_FRAME_OUTER_BOLD 40 + +#define SC_DP_FRAME_COLOR Color(0,0,0) //( 0x20, 0x40, 0x68 ) + +class OutputImpl +{ + ScDocument* mpDoc; + USHORT mnTab; + ::std::vector< bool > mbNeedLineCols; + ::std::vector< SCCOL > mnCols; + + ::std::vector< bool > mbNeedLineRows; + ::std::vector< SCROW > mnRows; + + SCCOL mnTabStartCol; + SCROW mnTabStartRow; + SCCOL mnMemberStartCol; + SCROW mnMemberStartRow; + + SCCOL mnDataStartCol; + SCROW mnDataStartRow; + SCCOL mnTabEndCol; + SCROW mnTabEndRow; + +public: + OutputImpl( ScDocument* pDoc, USHORT nTab, + SCCOL nTabStartCol, + SCROW nTabStartRow, + SCCOL nMemberStartCol, + SCROW nMemberStartRow, + SCCOL nDataStartCol, + SCROW nDataStartRow, + SCCOL nTabEndCol, + SCROW nTabEndRow ); + BOOL AddRow( SCROW nRow ); + BOOL AddCol( SCCOL nCol ); + + void OutputDataArea(); + void OutputBlockFrame ( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, BOOL bHori = FALSE ); + +}; + +#endif diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx index 5b3f6078d489..2163c3154d6a 100644 --- a/sc/source/core/data/table2.cxx +++ b/sc/source/core/data/table2.cxx @@ -853,10 +853,12 @@ void ScTable::PutCell( const ScAddress& rPos, ScBaseCell* pCell ) //UNUSED2009-05 } -BOOL ScTable::SetString( SCCOL nCol, SCROW nRow, SCTAB nTabP, const String& rString ) +BOOL ScTable::SetString( SCCOL nCol, SCROW nRow, SCTAB nTabP, const String& rString, + SvNumberFormatter* pFormatter, bool bDetectNumberFormat ) { if (ValidColRow(nCol,nRow)) - return aCol[nCol].SetString( nRow, nTabP, rString ); + return aCol[nCol].SetString( + nRow, nTabP, rString, pDocument->GetAddressConvention(), pFormatter, bDetectNumberFormat ); else return FALSE; } @@ -1188,9 +1190,9 @@ const ScPatternAttr* ScTable::GetMostUsedPattern( SCCOL nCol, SCROW nStartRow, S } -BOOL ScTable::HasAttrib( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, USHORT nMask ) const +bool ScTable::HasAttrib( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, USHORT nMask ) const { - BOOL bFound=FALSE; + bool bFound = false; for (SCCOL i=nCol1; i<=nCol2 && !bFound; i++) bFound |= aCol[i].HasAttrib( nRow1, nRow2, nMask ); return bFound; diff --git a/sc/source/core/inc/core_pch.hxx b/sc/source/core/inc/core_pch.hxx index 3e637550cd64..899169154d8d 100644 --- a/sc/source/core/inc/core_pch.hxx +++ b/sc/source/core/inc/core_pch.hxx @@ -158,7 +158,6 @@ #include <svtools/compat.hxx> #include <svl/inetdef.hxx> #include <svl/inethist.hxx> -#include <svl/cancel.hxx> #include <vcl/accel.hxx> #include <sfx2/sfxdefs.hxx> #include <sfx2/module.hxx> diff --git a/sc/source/core/tool/address.cxx b/sc/source/core/tool/address.cxx index 509a9fe293fb..ccbecd52d9f2 100644 --- a/sc/source/core/tool/address.cxx +++ b/sc/source/core/tool/address.cxx @@ -634,7 +634,9 @@ lcl_ScRange_Parse_XL_R1C1( ScRange& r, { const sal_Unicode* pTmp = NULL; String aExternDocName, aStartTabName, aEndTabName; - USHORT nFlags = SCA_VALID | SCA_VALID_TAB, nFlags2 = SCA_VALID_TAB2; + USHORT nFlags = SCA_VALID | SCA_VALID_TAB; + // Keep in mind that nFlags2 gets left-shifted by 4 bits before being merged. + USHORT nFlags2 = SCA_VALID_TAB; #if 0 { diff --git a/sc/source/core/tool/charthelper.cxx b/sc/source/core/tool/charthelper.cxx index 756493cc86e9..1b2cde3d4a6d 100644 --- a/sc/source/core/tool/charthelper.cxx +++ b/sc/source/core/tool/charthelper.cxx @@ -31,17 +31,18 @@ #include "charthelper.hxx" #include "document.hxx" #include "drwlayer.hxx" +#include "rangelst.hxx" +#include "chartlis.hxx" //#include <vcl/svapp.hxx> #include <svx/svditer.hxx> #include <svx/svdoole2.hxx> #include <svx/svdpage.hxx> -/* +#include <com/sun/star/chart2/data/XDataReceiver.hpp> + using namespace com::sun::star; using ::com::sun::star::uno::Reference; -using ::com::sun::star::uno::WeakReference; -*/ // ==================================================================== @@ -92,6 +93,37 @@ USHORT lcl_DoUpdateCharts( const ScAddress& rPos, ScDocument* pDoc, BOOL bAllCha return nFound; } +BOOL lcl_AdjustRanges( ScRangeList& rRanges, SCTAB nSourceTab, SCTAB nDestTab, SCTAB nTabCount ) +{ + //! if multiple sheets are copied, update references into the other copied sheets? + + BOOL bChanged = FALSE; + + ULONG nCount = rRanges.Count(); + for (ULONG i=0; i<nCount; i++) + { + ScRange* pRange = rRanges.GetObject(i); + if ( pRange->aStart.Tab() == nSourceTab && pRange->aEnd.Tab() == nSourceTab ) + { + pRange->aStart.SetTab( nDestTab ); + pRange->aEnd.SetTab( nDestTab ); + bChanged = TRUE; + } + if ( pRange->aStart.Tab() >= nTabCount ) + { + pRange->aStart.SetTab( nTabCount > 0 ? ( nTabCount - 1 ) : 0 ); + bChanged = TRUE; + } + if ( pRange->aEnd.Tab() >= nTabCount ) + { + pRange->aEnd.SetTab( nTabCount > 0 ? ( nTabCount - 1 ) : 0 ); + bChanged = TRUE; + } + } + + return bChanged; +} + }//end anonymous namespace // === ScChartHelper ====================================== @@ -107,3 +139,160 @@ USHORT ScChartHelper::DoUpdateAllCharts( ScDocument* pDoc ) { return lcl_DoUpdateCharts( ScAddress(), pDoc, TRUE ); } + +//static +void ScChartHelper::AdjustRangesOfChartsOnDestinationPage( ScDocument* pSrcDoc, ScDocument* pDestDoc, const SCTAB nSrcTab, const SCTAB nDestTab ) +{ + if( !pSrcDoc || !pDestDoc ) + return; + ScDrawLayer* pDrawLayer = pDestDoc->GetDrawLayer(); + if( !pDrawLayer ) + return; + + SdrPage* pDestPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nDestTab)); + if( pDestPage ) + { + SdrObjListIter aIter( *pDestPage, IM_FLAT ); + SdrObject* pObject = aIter.Next(); + while( pObject ) + { + if( pObject->GetObjIdentifier() == OBJ_OLE2 && ((SdrOle2Obj*)pObject)->IsChart() ) + { + String aChartName = ((SdrOle2Obj*)pObject)->GetPersistName(); + + Reference< chart2::XChartDocument > xChartDoc( pDestDoc->GetChartByName( aChartName ) ); + Reference< chart2::data::XDataReceiver > xReceiver( xChartDoc, uno::UNO_QUERY ); + if( xChartDoc.is() && xReceiver.is() && !xChartDoc->hasInternalDataProvider() ) + { + ::std::vector< ScRangeList > aRangesVector; + pDestDoc->GetChartRanges( aChartName, aRangesVector, pSrcDoc ); + + ::std::vector< ScRangeList >::iterator aIt( aRangesVector.begin() ); + for( ; aIt!=aRangesVector.end(); aIt++ ) + { + ScRangeList& rScRangeList( *aIt ); + lcl_AdjustRanges( rScRangeList, nSrcTab, nDestTab, pDestDoc->GetTableCount() ); + } + pDestDoc->SetChartRanges( aChartName, aRangesVector ); + } + } + pObject = aIter.Next(); + } + } +} + +//static +uno::Reference< chart2::XChartDocument > ScChartHelper::GetChartFromSdrObject( SdrObject* pObject ) +{ + uno::Reference< chart2::XChartDocument > xReturn; + if( pObject ) + { + if( pObject->GetObjIdentifier() == OBJ_OLE2 && ((SdrOle2Obj*)pObject)->IsChart() ) + { + uno::Reference< embed::XEmbeddedObject > xIPObj = ((SdrOle2Obj*)pObject)->GetObjRef(); + if( xIPObj.is() ) + { + svt::EmbeddedObjectRef::TryRunningState( xIPObj ); + uno::Reference< util::XCloseable > xComponent = xIPObj->getComponent(); + xReturn.set( uno::Reference< chart2::XChartDocument >( xComponent, uno::UNO_QUERY ) ); + } + } + } + return xReturn; +} + +void ScChartHelper::GetChartRanges( const uno::Reference< chart2::XChartDocument >& xChartDoc, + uno::Sequence< rtl::OUString >& rRanges ) +{ + rRanges.realloc(0); + uno::Reference< chart2::data::XDataSource > xDataSource( xChartDoc, uno::UNO_QUERY ); + if( !xDataSource.is() ) + return; + //uno::Reference< chart2::data::XDataProvider > xProvider = xChartDoc->getDataProvider(); + + uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence > > aLabeledDataSequences( xDataSource->getDataSequences() ); + rRanges.realloc(2*aLabeledDataSequences.getLength()); + sal_Int32 nRealCount=0; + for( sal_Int32 nN=0;nN<aLabeledDataSequences.getLength();nN++) + { + uno::Reference< chart2::data::XLabeledDataSequence > xLabeledSequence( aLabeledDataSequences[nN] ); + if(!xLabeledSequence.is()) + continue; + uno::Reference< chart2::data::XDataSequence > xLabel( xLabeledSequence->getLabel()); + uno::Reference< chart2::data::XDataSequence > xValues( xLabeledSequence->getValues()); + + if( xLabel.is()) + rRanges[nRealCount++] = xLabel->getSourceRangeRepresentation(); + if( xValues.is()) + rRanges[nRealCount++] = xValues->getSourceRangeRepresentation(); + } + rRanges.realloc(nRealCount); +} + +void ScChartHelper::SetChartRanges( const uno::Reference< chart2::XChartDocument >& xChartDoc, + const uno::Sequence< rtl::OUString >& rRanges ) +{ + uno::Reference< chart2::data::XDataSource > xDataSource( xChartDoc, uno::UNO_QUERY ); + if( !xDataSource.is() ) + return; + uno::Reference< chart2::data::XDataProvider > xDataProvider = xChartDoc->getDataProvider(); + if( !xDataProvider.is() ) + return; + + uno::Reference< frame::XModel > xModel( xChartDoc, uno::UNO_QUERY ); + if( xModel.is() ) + xModel->lockControllers(); + + try + { + rtl::OUString aPropertyNameRole( ::rtl::OUString::createFromAscii("Role") ); + + uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence > > aLabeledDataSequences( xDataSource->getDataSequences() ); + sal_Int32 nRange=0; + for( sal_Int32 nN=0; (nN<aLabeledDataSequences.getLength()) && (nRange<rRanges.getLength()); nN++ ) + { + uno::Reference< chart2::data::XLabeledDataSequence > xLabeledSequence( aLabeledDataSequences[nN] ); + if(!xLabeledSequence.is()) + continue; + uno::Reference< beans::XPropertySet > xLabel( xLabeledSequence->getLabel(), uno::UNO_QUERY ); + uno::Reference< beans::XPropertySet > xValues( xLabeledSequence->getValues(), uno::UNO_QUERY ); + + if( xLabel.is()) + { + // the range string must be in Calc A1 format. + uno::Reference< chart2::data::XDataSequence > xNewSeq( + xDataProvider->createDataSequenceByRangeRepresentation( rRanges[nRange++] )); + + uno::Reference< beans::XPropertySet > xNewProps( xNewSeq, uno::UNO_QUERY ); + if( xNewProps.is() ) + xNewProps->setPropertyValue( aPropertyNameRole, xLabel->getPropertyValue( aPropertyNameRole ) ); + + xLabeledSequence->setLabel( xNewSeq ); + } + + if( !(nRange<rRanges.getLength()) ) + break; + + if( xValues.is()) + { + // the range string must be in Calc A1 format. + uno::Reference< chart2::data::XDataSequence > xNewSeq( + xDataProvider->createDataSequenceByRangeRepresentation( rRanges[nRange++] )); + + uno::Reference< beans::XPropertySet > xNewProps( xNewSeq, uno::UNO_QUERY ); + if( xNewProps.is() ) + xNewProps->setPropertyValue( aPropertyNameRole, xValues->getPropertyValue( aPropertyNameRole ) ); + + xLabeledSequence->setValues( xNewSeq ); + } + } + } + catch ( uno::Exception& ex ) + { + (void)ex; + DBG_ERROR("Exception in ScChartHelper::SetChartRanges - invalid range string?"); + } + + if( xModel.is() ) + xModel->unlockControllers(); +} diff --git a/sc/source/core/tool/collect.cxx b/sc/source/core/tool/collect.cxx index 13df9307bc11..c7aa72343fbb 100644 --- a/sc/source/core/tool/collect.cxx +++ b/sc/source/core/tool/collect.cxx @@ -352,10 +352,18 @@ ScDataObject* ScStrCollection::Clone() const //UNUSED2008-05 } //UNUSED2008-05 } + ScDataObject* TypedStrData::Clone() const { return new TypedStrData(*this); } + +TypedScStrCollection::TypedScStrCollection( USHORT nLim , USHORT nDel , BOOL bDup ) + : ScSortedCollection( nLim, nDel, bDup ) +{ + bCaseSensitive = FALSE; +} + TypedScStrCollection::~TypedScStrCollection() {} ScDataObject* TypedScStrCollection::Clone() const @@ -363,6 +371,16 @@ ScDataObject* TypedScStrCollection::Clone() const return new TypedScStrCollection(*this); } +TypedStrData* TypedScStrCollection::operator[]( const USHORT nIndex) const +{ + return (TypedStrData*)At(nIndex); +} + +void TypedScStrCollection::SetCaseSensitive( BOOL bSet ) +{ + bCaseSensitive = bSet; +} + short TypedScStrCollection::Compare( ScDataObject* pKey1, ScDataObject* pKey2 ) const { short nResult = 0; diff --git a/sc/source/core/tool/doubleref.cxx b/sc/source/core/tool/doubleref.cxx index 28fae20ddb62..5c2d3f575654 100644 --- a/sc/source/core/tool/doubleref.cxx +++ b/sc/source/core/tool/doubleref.cxx @@ -337,7 +337,9 @@ OUString ScDBInternalRange::getString(SCCOL nCol, SCROW nRow) const { String aStr; const ScAddress& s = maRange.aStart; - getDoc()->GetString(s.Col() + nCol, s.Row() + nRow, maRange.aStart.Tab(), aStr); + // #i109200# this is used in formula calculation, use GetInputString, not GetString + // (consistent with ScDBInternalRange::getCellString) + getDoc()->GetInputString(s.Col() + nCol, s.Row() + nRow, maRange.aStart.Tab(), aStr); return aStr; } diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx index 166261b98ffd..94cd5c1a02e9 100644 --- a/sc/source/core/tool/interpr1.cxx +++ b/sc/source/core/tool/interpr1.cxx @@ -6053,6 +6053,10 @@ void ScInterpreter::ScDBCount() // iterators. ScDBQueryParamInternal* p = static_cast<ScDBQueryParamInternal*>(pQueryParam.get()); SCTAB nTab = p->nTab; + // ScQueryCellIterator doesn't make use of ScDBQueryParamBase::mnField, + // so the source range has to be restricted, like before the introduction + // of ScDBQueryParamBase. + p->nCol1 = p->nCol2 = p->mnField; ScQueryCellIterator aCellIter( pDok, nTab, *p); if ( aCellIter.GetFirst() ) { diff --git a/sc/source/core/tool/makefile.mk b/sc/source/core/tool/makefile.mk index 0bc433a7b187..6c730f3a1743 100644 --- a/sc/source/core/tool/makefile.mk +++ b/sc/source/core/tool/makefile.mk @@ -105,6 +105,7 @@ SLOFILES = \ $(SLO)$/refupdat.obj \ $(SLO)$/scmatrix.obj \ $(SLO)$/sctictac.obj \ + $(SLO)$/stringutil.obj \ $(SLO)$/subtotal.obj \ $(SLO)$/token.obj \ $(SLO)$/unitconv.obj \ @@ -115,6 +116,7 @@ SLOFILES = \ EXCEPTIONSFILES= \ $(SLO)$/addincol.obj \ $(SLO)$/cellkeytranslator.obj \ + $(SLO)$/charthelper.obj \ $(SLO)$/chartarr.obj \ $(SLO)$/chartlis.obj \ $(SLO)$/chartlock.obj \ @@ -131,6 +133,7 @@ EXCEPTIONSFILES= \ $(SLO)$/prnsave.obj \ $(SLO)$/queryparam.obj \ $(SLO)$/reftokenhelper.obj \ + $(SLO)$/stringutil.obj \ $(SLO)$/token.obj # [kh] POWERPC compiler problem diff --git a/sc/source/core/tool/optutil.cxx b/sc/source/core/tool/optutil.cxx index 4de458f698da..dc63c7819eff 100644 --- a/sc/source/core/tool/optutil.cxx +++ b/sc/source/core/tool/optutil.cxx @@ -51,12 +51,12 @@ BOOL ScOptionsUtil::IsMetricSystem() //------------------------------------------------------------------ -ScLinkConfigItem::ScLinkConfigItem( const rtl::OUString rSubTree ) : +ScLinkConfigItem::ScLinkConfigItem( const rtl::OUString& rSubTree ) : ConfigItem( rSubTree ) { } -ScLinkConfigItem::ScLinkConfigItem( const rtl::OUString rSubTree, sal_Int16 nMode ) : +ScLinkConfigItem::ScLinkConfigItem( const rtl::OUString& rSubTree, sal_Int16 nMode ) : ConfigItem( rSubTree, nMode ) { } diff --git a/sc/source/core/tool/rangelst.cxx b/sc/source/core/tool/rangelst.cxx index d0dd8ec9c163..a631ff3c3fbb 100644 --- a/sc/source/core/tool/rangelst.cxx +++ b/sc/source/core/tool/rangelst.cxx @@ -41,7 +41,7 @@ #include "document.hxx" #include "refupdat.hxx" #include "rechead.hxx" - +#include "compiler.hxx" // === ScRangeList ==================================================== @@ -58,32 +58,14 @@ void ScRangeList::RemoveAll() Clear(); } -static void defaultDelimiter( char& cDelimiter, formula::FormulaGrammar::AddressConvention eConv) -{ - if( cDelimiter == 0) - { - switch( eConv ) - { - default : - case formula::FormulaGrammar::CONV_OOO : - cDelimiter = ';'; - break; - - case formula::FormulaGrammar::CONV_XL_A1 : - case formula::FormulaGrammar::CONV_XL_R1C1 : - cDelimiter = ','; - break; - } - } -} - USHORT ScRangeList::Parse( const String& rStr, ScDocument* pDoc, USHORT nMask, formula::FormulaGrammar::AddressConvention eConv, - char cDelimiter ) + sal_Unicode cDelimiter ) { if ( rStr.Len() ) { - defaultDelimiter( cDelimiter, eConv); + if (!cDelimiter) + cDelimiter = ScCompiler::GetNativeSymbol(ocSep).GetChar(0); nMask |= SCA_VALID; // falls das jemand vergessen sollte USHORT nResult = (USHORT)~0; // alle Bits setzen @@ -123,11 +105,12 @@ USHORT ScRangeList::Parse( const String& rStr, ScDocument* pDoc, USHORT nMask, void ScRangeList::Format( String& rStr, USHORT nFlags, ScDocument* pDoc, formula::FormulaGrammar::AddressConvention eConv, - char cDelimiter ) const + sal_Unicode cDelimiter ) const { rStr.Erase(); - defaultDelimiter( cDelimiter, eConv); + if (!cDelimiter) + cDelimiter = ScCompiler::GetNativeSymbol(ocSep).GetChar(0); ULONG nCnt = Count(); for ( ULONG nIdx = 0; nIdx < nCnt; nIdx++ ) diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx index 326fda49eb30..fbb859b64ebf 100644 --- a/sc/source/core/tool/scmatrix.cxx +++ b/sc/source/core/tool/scmatrix.cxx @@ -62,12 +62,17 @@ void ScMatrix::CreateMatrix(SCSIZE nC, SCSIZE nR) // nur fuer ctor mnNonValue = 0; } -ScMatrix::~ScMatrix() +void ScMatrix::Clear() { DeleteIsString(); delete [] pMat; } +ScMatrix::~ScMatrix() +{ + Clear(); +} + ScMatrix* ScMatrix::Clone() const { ScMatrix* pScMat = new ScMatrix( nColCount, nRowCount); @@ -76,6 +81,12 @@ ScMatrix* ScMatrix::Clone() const return pScMat; } +void ScMatrix::Resize( SCSIZE nC, SCSIZE nR) +{ + Clear(); + CreateMatrix(nC, nR); +} + ScMatrix* ScMatrix::CloneAndExtend( SCSIZE nNewCols, SCSIZE nNewRows ) const { ScMatrix* pScMat = new ScMatrix( nNewCols, nNewRows); diff --git a/sc/source/core/tool/stringutil.cxx b/sc/source/core/tool/stringutil.cxx new file mode 100644 index 000000000000..28a4bc6755c2 --- /dev/null +++ b/sc/source/core/tool/stringutil.cxx @@ -0,0 +1,131 @@ +/************************************************************************* + * + * 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: table.hxx,v $ + * $Revision: 1.35 $ + * + * 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" + +// System - Includes ----------------------------------------------------- + +#include "stringutil.hxx" +#include "rtl/ustrbuf.hxx" +#include "rtl/math.hxx" + +using ::rtl::OUString; +using ::rtl::OUStringBuffer; + +bool ScStringUtil::parseSimpleNumber( + const OUString& rStr, sal_Unicode dsep, sal_Unicode gsep, double& rVal) +{ + if (gsep == 0x00A0) + // unicode space to ascii space + gsep = 0x0020; + + OUStringBuffer aBuf; + sal_Int32 n = rStr.getLength(); + const sal_Unicode* p = rStr.getStr(); + sal_Int32 nPosDSep = -1, nPosGSep = -1; + sal_uInt32 nDigitCount = 0; + + for (sal_Int32 i = 0; i < n; ++i) + { + sal_Unicode c = p[i]; + if (c == 0x00A0) + // unicode space to ascii space + c = 0x0020; + + if (sal_Unicode('0') <= c && c <= sal_Unicode('9')) + { + // this is a digit. + aBuf.append(c); + ++nDigitCount; + } + else if (c == dsep) + { + // this is a decimal separator. + + if (nPosDSep >= 0) + // a second decimal separator -> not a valid number. + return false; + + if (nPosGSep >= 0 && i - nPosGSep != 4) + // the number has a group separator and the decimal sep is not + // positioned correctly. + return false; + + nPosDSep = i; + nPosGSep = -1; + aBuf.append(c); + nDigitCount = 0; + } + else if (c == gsep) + { + // this is a group (thousand) separator. + + if (i == 0) + // not allowed as the first character. + return false; + + if (nPosDSep >= 0) + // not allowed after the decimal separator. + return false; + + if (nPosGSep >= 0 && nDigitCount != 3) + // must be exactly 3 digits since the last group separator. + return false; + + nPosGSep = i; + nDigitCount = 0; + } + else if (c == sal_Unicode('-') || c == sal_Unicode('+')) + { + // A sign must be the first character if it's given. + if (i == 0) + aBuf.append(c); + else + return false; + } + else + return false; + } + + // finished parsing the number. + + if (nPosGSep >= 0 && nDigitCount != 3) + // must be exactly 3 digits since the last group separator. + return false; + + rtl_math_ConversionStatus eStatus = rtl_math_ConversionStatus_Ok; + sal_Int32 nParseEnd = 0; + rVal = ::rtl::math::stringToDouble(aBuf.makeStringAndClear(), dsep, gsep, &eStatus, &nParseEnd); + if (eStatus != rtl_math_ConversionStatus_Ok) + return false; + + return true; +} diff --git a/sc/source/filter/excel/excform.cxx b/sc/source/filter/excel/excform.cxx index 5642c098027e..0652363e8822 100644 --- a/sc/source/filter/excel/excform.cxx +++ b/sc/source/filter/excel/excform.cxx @@ -471,10 +471,7 @@ ConvErr ExcelToSc::Convert( const ScTokenArray*& pErgebnis, XclImpStream& aIn, s aIn.Ignore( (meBiff == EXC_BIFF2) ? 3 : 4 ); if( bAllowArrays ) { - SCSIZE nC = nByte ? nByte : 256; - SCSIZE nR = nUINT16; - - aStack << aPool.StoreMatrix( nC, nR ); + aStack << aPool.StoreMatrix(); aExtensions.push_back( EXTENSION_ARRAY ); } else @@ -1892,6 +1889,7 @@ void ExcelToSc::ReadExtensionArray( unsigned int n, XclImpStream& aIn ) if( NULL != pMatrix ) { + pMatrix->Resize(nCols, nRows); pMatrix->GetDimensions( nC, nR); if( nC != nCols || nR != nRows ) { diff --git a/sc/source/filter/excel/excform8.cxx b/sc/source/filter/excel/excform8.cxx index 608d65dfc801..148b1542913a 100644 --- a/sc/source/filter/excel/excform8.cxx +++ b/sc/source/filter/excel/excform8.cxx @@ -392,10 +392,7 @@ ConvErr ExcelToSc8::Convert( const ScTokenArray*& rpTokArray, XclImpStream& aIn, aIn.Ignore( 4 ); if( bAllowArrays ) { - SCSIZE nC = nByte + 1; - SCSIZE nR = nUINT16 + 1; - - aStack << aPool.StoreMatrix( nC, nR ); + aStack << aPool.StoreMatrix(); aExtensions.push_back( EXTENSION_ARRAY ); } else diff --git a/sc/source/filter/excel/makefile.mk b/sc/source/filter/excel/makefile.mk index 33a5babda815..04ba76d4a68a 100644 --- a/sc/source/filter/excel/makefile.mk +++ b/sc/source/filter/excel/makefile.mk @@ -151,6 +151,7 @@ EXCEPTIONSFILES = \ $(SLO)$/xlpivot.obj \ $(SLO)$/xlroot.obj \ $(SLO)$/xlstyle.obj \ + $(SLO)$/xltools.obj \ $(SLO)$/xlview.obj # --- Targets ------------------------------------------------------- diff --git a/sc/source/filter/excel/tokstack.cxx b/sc/source/filter/excel/tokstack.cxx index 8685f404543a..b61a844d02a5 100644 --- a/sc/source/filter/excel/tokstack.cxx +++ b/sc/source/filter/excel/tokstack.cxx @@ -737,7 +737,7 @@ const TokenId TokenPool::StoreNlf( const ScSingleRefData& rTr ) return ( const TokenId ) nElementAkt; } -const TokenId TokenPool::StoreMatrix( SCSIZE nC, SCSIZE nR ) +const TokenId TokenPool::StoreMatrix() { ScMatrix* pM; @@ -750,8 +750,7 @@ const TokenId TokenPool::StoreMatrix( SCSIZE nC, SCSIZE nR ) pElement[ nElementAkt ] = nP_MatrixAkt; pType[ nElementAkt ] = T_Matrix; - pM = new ScMatrix( nC, nR ); - pM->FillDouble( 0., 0,0, nC-1, nR-1 ); + pM = new ScMatrix( 0, 0 ); pM->IncRef( ); ppP_Matrix[ nP_MatrixAkt ] = pM; diff --git a/sc/source/filter/excel/xepivot.cxx b/sc/source/filter/excel/xepivot.cxx index cb248f0eaf76..ddcdb3243167 100644 --- a/sc/source/filter/excel/xepivot.cxx +++ b/sc/source/filter/excel/xepivot.cxx @@ -538,16 +538,21 @@ void XclExpPCField::InsertNumDateGroupItems( const ScDPObject& rDPObj, const ScD { // get the string collection with original source elements ScSheetDPData aDPData( GetDocPtr(), *pSrcDesc ); - const TypedScStrCollection& rOrigColl = aDPData.GetColumnEntries( static_cast< long >( GetBaseFieldIndex() ) ); - + // Wang Xu Ming - DataPilot migration + // 2009-05-08 + const std::vector< SCROW > aOrignial = aDPData.GetColumnEntries( static_cast< long >( GetBaseFieldIndex() ) ); // get the string collection with generated grouping elements ScDPNumGroupDimension aTmpDim( rNumInfo ); if( nDatePart != 0 ) aTmpDim.MakeDateHelper( rNumInfo, nDatePart ); - const TypedScStrCollection& rGroupColl = aTmpDim.GetNumEntries( rOrigColl, GetDocPtr() ); - for( USHORT nIdx = 0, nCount = rGroupColl.GetCount(); nIdx < nCount; ++nIdx ) - if( const TypedStrData* pStrData = rGroupColl[ nIdx ] ) - InsertGroupItem( new XclExpPCItem( pStrData->GetString() ) ); + const std::vector< SCROW > aMemberIds = aTmpDim.GetNumEntries( static_cast< SCCOL >( GetBaseFieldIndex() ), aDPData.GetCacheTable().GetCache(), aOrignial ); + for ( size_t nIdx = 0 ; nIdx < aMemberIds.size(); nIdx++ ) + { + const ScDPItemData* pData = aDPData.GetMemberById( static_cast< long >( GetBaseFieldIndex() ) , aMemberIds[ nIdx] ); + if ( pData ) + InsertGroupItem( new XclExpPCItem( pData->GetString() ) ); + } +// End Comments } } diff --git a/sc/source/filter/excel/xicontent.cxx b/sc/source/filter/excel/xicontent.cxx index e095ef987615..fb1eb9a3bf44 100644 --- a/sc/source/filter/excel/xicontent.cxx +++ b/sc/source/filter/excel/xicontent.cxx @@ -1213,7 +1213,29 @@ void XclImpSheetProtectBuffer::ReadProtect( XclImpStream& rStrm, SCTAB nTab ) void XclImpSheetProtectBuffer::ReadOptions( XclImpStream& rStrm, SCTAB nTab ) { - rStrm.Ignore(19); + rStrm.Ignore(12); + + // feature type can be either 2 or 4. If 2, this record stores flag for + // enhanced protection, whereas if 4 it stores flag for smart tag. + sal_uInt16 nFeatureType; + rStrm >> nFeatureType; + if (nFeatureType != 2) + // We currently only support import of enhanced protection data. + return; + + rStrm.Ignore(1); // always 1 + + // The flag size specifies the size of bytes that follows that stores + // feature data. If -1 it depends on the feature type imported earlier. + // For enhanced protection data, the size is always 4. For the most xls + // documents out there this value is almost always -1. + sal_Int32 nFlagSize; + rStrm >> nFlagSize; + if (nFlagSize != -1) + return; + + // There are actually 4 bytes to read, but the upper 2 bytes currently + // don't store any bits. sal_uInt16 nOptions; rStrm >> nOptions; diff --git a/sc/source/filter/html/htmlimp.cxx b/sc/source/filter/html/htmlimp.cxx index ad3a5e041151..1c0b9fc8ec33 100644 --- a/sc/source/filter/html/htmlimp.cxx +++ b/sc/source/filter/html/htmlimp.cxx @@ -60,13 +60,14 @@ //------------------------------------------------------------------------ FltError ScFormatFilterPluginImpl::ScImportHTML( SvStream &rStream, const String& rBaseURL, ScDocument *pDoc, - ScRange& rRange, double nOutputFactor, BOOL bCalcWidthHeight ) + ScRange& rRange, double nOutputFactor, BOOL bCalcWidthHeight, SvNumberFormatter* pFormatter, + bool bConvertDate ) { ScHTMLImport aImp( pDoc, rBaseURL, rRange, bCalcWidthHeight ); FltError nErr = (FltError) aImp.Read( rStream, rBaseURL ); ScRange aR = aImp.GetRange(); rRange.aEnd = aR.aEnd; - aImp.WriteToDocument( TRUE, nOutputFactor ); + aImp.WriteToDocument( TRUE, nOutputFactor, pFormatter, bConvertDate ); return nErr; } @@ -134,9 +135,10 @@ void ScHTMLImport::InsertRangeName( ScDocument* pDoc, const String& rName, const delete pRangeData; } -void ScHTMLImport::WriteToDocument( BOOL bSizeColsRows, double nOutputFactor ) +void ScHTMLImport::WriteToDocument( + BOOL bSizeColsRows, double nOutputFactor, SvNumberFormatter* pFormatter, bool bConvertDate ) { - ScEEImport::WriteToDocument( bSizeColsRows, nOutputFactor ); + ScEEImport::WriteToDocument( bSizeColsRows, nOutputFactor, pFormatter, bConvertDate ); const ScHTMLParser* pParser = GetParser(); const ScHTMLTable* pGlobTable = pParser->GetGlobalTable(); diff --git a/sc/source/filter/inc/eeimport.hxx b/sc/source/filter/inc/eeimport.hxx index 59225a5a7138..634dfd1b4a33 100644 --- a/sc/source/filter/inc/eeimport.hxx +++ b/sc/source/filter/inc/eeimport.hxx @@ -60,7 +60,9 @@ public: virtual ULONG Read( SvStream& rStream, const String& rBaseURL ); virtual ScRange GetRange() { return maRange; } virtual void WriteToDocument( BOOL bSizeColsRows = FALSE, - double nOutputFactor = 1.0 ); + double nOutputFactor = 1.0, + SvNumberFormatter* pFormatter = NULL, + bool bConvertDate = true ); }; #endif diff --git a/sc/source/filter/inc/ftools.hxx b/sc/source/filter/inc/ftools.hxx index bdb17178d75c..c17aaa70445c 100644 --- a/sc/source/filter/inc/ftools.hxx +++ b/sc/source/filter/inc/ftools.hxx @@ -517,7 +517,9 @@ class ScFormatFilterPluginImpl : public ScFormatFilterPlugin { virtual FltError ScImportDif( SvStream&, ScDocument*, const ScAddress& rInsPos, const CharSet eSrc = RTL_TEXTENCODING_DONTKNOW, UINT32 nDifOption = SC_DIFOPT_EXCEL ); virtual FltError ScImportRTF( SvStream&, const String& rBaseURL, ScDocument*, ScRange& rRange ); - virtual FltError ScImportHTML( SvStream&, const String& rBaseURL, ScDocument*, ScRange& rRange, double nOutputFactor = 1.0, BOOL bCalcWidthHeight = TRUE ); + virtual FltError ScImportHTML( SvStream&, const String& rBaseURL, ScDocument*, ScRange& rRange, + double nOutputFactor = 1.0, BOOL bCalcWidthHeight = TRUE, + SvNumberFormatter* pFormatter = NULL, bool bConvertDate = true ); virtual ScEEAbsImport *CreateRTFImport( ScDocument* pDoc, const ScRange& rRange ); virtual ScEEAbsImport *CreateHTMLImport( ScDocument* pDocP, const String& rBaseURL, const ScRange& rRange, BOOL bCalcWidthHeight ); diff --git a/sc/source/filter/inc/htmlimp.hxx b/sc/source/filter/inc/htmlimp.hxx index 8a1d1c41b4fd..0376b3cd72f5 100644 --- a/sc/source/filter/inc/htmlimp.hxx +++ b/sc/source/filter/inc/htmlimp.hxx @@ -42,7 +42,8 @@ public: virtual ~ScHTMLImport(); const ScHTMLParser* GetParser() const { return (ScHTMLParser*)mpParser; } - virtual void WriteToDocument( BOOL bSizeColsRows = FALSE, double nOutputFactor = 1.0 ); + virtual void WriteToDocument( BOOL bSizeColsRows = FALSE, double nOutputFactor = 1.0, + SvNumberFormatter* pFormatter = NULL, bool bConvertDate = true ); static String GetHTMLRangeNameList( ScDocument* pDoc, const String& rOrigName ); }; diff --git a/sc/source/filter/inc/tokstack.hxx b/sc/source/filter/inc/tokstack.hxx index 80c94c729270..06a37639be89 100644 --- a/sc/source/filter/inc/tokstack.hxx +++ b/sc/source/filter/inc/tokstack.hxx @@ -207,7 +207,7 @@ class TokenPool const TokenId Store( const DefTokenId eId, const String& rName ); // 4 externals (e.g. AddIns, Makros...) const TokenId StoreNlf( const ScSingleRefData& rTr ); - const TokenId StoreMatrix( SCSIZE nC, SCSIZE nR ); + const TokenId StoreMatrix(); const TokenId StoreExtName( sal_uInt16 nFileId, const String& rName ); const TokenId StoreExtRef( sal_uInt16 nFileId, const String& rTabName, const ScSingleRefData& rRef ); const TokenId StoreExtRef( sal_uInt16 nFileId, const String& rTabName, const ScComplexRefData& rRef ); diff --git a/sc/source/filter/rtf/eeimpars.cxx b/sc/source/filter/rtf/eeimpars.cxx index 756b384b7f11..86a347970ff6 100644 --- a/sc/source/filter/rtf/eeimpars.cxx +++ b/sc/source/filter/rtf/eeimpars.cxx @@ -126,7 +126,7 @@ ULONG ScEEImport::Read( SvStream& rStream, const String& rBaseURL ) } -void ScEEImport::WriteToDocument( BOOL bSizeColsRows, double nOutputFactor ) +void ScEEImport::WriteToDocument( BOOL bSizeColsRows, double nOutputFactor, SvNumberFormatter* pFormatter, bool bConvertDate ) { ScProgress* pProgress = new ScProgress( mpDoc->GetDocumentShell(), ScGlobal::GetRscString( STR_LOAD_DOC ), mpParser->Count() ); @@ -147,10 +147,12 @@ void ScEEImport::WriteToDocument( BOOL bSizeColsRows, double nOutputFactor ) nLastMergedRow = SCROW_MAX; BOOL bHasGraphics = FALSE; ScEEParseEntry* pE; - SvNumberFormatter* pFormatter = mpDoc->GetFormatTable(); - bool bNumbersEnglishUS = (pFormatter->GetLanguage() != LANGUAGE_ENGLISH_US); - if (bNumbersEnglishUS) + if (!pFormatter) + pFormatter = mpDoc->GetFormatTable(); + bool bNumbersEnglishUS = false; + if (pFormatter->GetLanguage() == LANGUAGE_SYSTEM) { + // Automatic language option selected. Check for the global 'use US English' option. SvxHtmlOptions aOpt; bNumbersEnglishUS = aOpt.IsNumbersEnglishUS(); } @@ -332,7 +334,7 @@ void ScEEImport::WriteToDocument( BOOL bSizeColsRows, double nOutputFactor ) else if ( !pE->aSel.HasRange() ) { // maybe ALT text of IMG or similar - mpDoc->SetString( nCol, nRow, nTab, pE->aAltText ); + mpDoc->SetString( nCol, nRow, nTab, pE->aAltText, pFormatter ); // wenn SelRange komplett leer kann nachfolgender Text im gleichen Absatz liegen! } else @@ -377,7 +379,7 @@ void ScEEImport::WriteToDocument( BOOL bSizeColsRows, double nOutputFactor ) if (bNumbersEnglishUS && !bEnUsRecognized) mpDoc->PutCell( nCol, nRow, nTab, new ScStringCell( aStr)); else - mpDoc->SetString( nCol, nRow, nTab, aStr ); + mpDoc->SetString( nCol, nRow, nTab, aStr, pFormatter, bConvertDate ); } } else diff --git a/sc/source/filter/xml/xmldpimp.cxx b/sc/source/filter/xml/xmldpimp.cxx index 01dae48f6d84..93e529c4ceca 100644 --- a/sc/source/filter/xml/xmldpimp.cxx +++ b/sc/source/filter/xml/xmldpimp.cxx @@ -1453,6 +1453,7 @@ ScXMLDataPilotSubTotalContext::ScXMLDataPilotSubTotalContext( ScXMLImport& rImpo pDataPilotSubTotals->AddFunction( sal::static_int_cast<sal_Int16>( ScXMLConverter::GetFunctionFromString( sValue ) ) ); } + break; case XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_DISPLAY_NAME: case XML_TOK_DATA_PILOT_SUBTOTAL_ATTR_DISPLAY_NAME_EXT: pDataPilotSubTotals->SetDisplayName(sValue); diff --git a/sc/source/ui/Accessibility/AccessibleDocument.cxx b/sc/source/ui/Accessibility/AccessibleDocument.cxx index 1c1126e07640..4c65632fb45e 100644 --- a/sc/source/ui/Accessibility/AccessibleDocument.cxx +++ b/sc/source/ui/Accessibility/AccessibleDocument.cxx @@ -963,18 +963,14 @@ void ScChildrenShapes::FillSelectionSupplier() const SfxViewFrame* pViewFrame = mpViewShell->GetViewFrame(); if (pViewFrame) { - SfxFrame* pFrame = pViewFrame->GetFrame(); - if (pFrame) + xSelectionSupplier = uno::Reference<view::XSelectionSupplier>(pViewFrame->GetFrame().GetController(), uno::UNO_QUERY); + if (xSelectionSupplier.is()) { - xSelectionSupplier = uno::Reference<view::XSelectionSupplier>(pFrame->GetController(), uno::UNO_QUERY); - if (xSelectionSupplier.is()) - { - if (mpAccessibleDocument) - xSelectionSupplier->addSelectionChangeListener(mpAccessibleDocument); - uno::Reference<drawing::XShapes> xShapes (xSelectionSupplier->getSelection(), uno::UNO_QUERY); - if (xShapes.is()) - mnShapesSelected = xShapes->getCount(); - } + if (mpAccessibleDocument) + xSelectionSupplier->addSelectionChangeListener(mpAccessibleDocument); + uno::Reference<drawing::XShapes> xShapes (xSelectionSupplier->getSelection(), uno::UNO_QUERY); + if (xShapes.is()) + mnShapesSelected = xShapes->getCount(); } } } diff --git a/sc/source/ui/attrdlg/scdlgfact.cxx b/sc/source/ui/attrdlg/scdlgfact.cxx index ff42e379be13..0af2c30d628f 100644 --- a/sc/source/ui/attrdlg/scdlgfact.cxx +++ b/sc/source/ui/attrdlg/scdlgfact.cxx @@ -71,6 +71,7 @@ #include "validate.hxx" //add for ScValidationDlg #include "validate.hrc" //add for ScValidationDlg #include "sortdlg.hxx" //add for ScSortDlg +#include "textimportoptions.hxx" #include "opredlin.hxx" //add for ScRedlineOptionsTabPage #include "tpcalc.hxx" //add for ScTpCalcOptions #include "tpprint.hxx" //add for ScTpPrintOptions @@ -112,6 +113,7 @@ 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(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 // AbstractTabDialog_Impl begin @@ -193,6 +195,11 @@ void AbstractScImportAsciiDlg_Impl::SetTextToColumnsMode() pDlg->SetTextToColumnsMode(); } +void AbstractScImportAsciiDlg_Impl::SaveParameters() +{ + pDlg->SaveParameters(); +} + // AbstractScImportAsciiDlg_Impl end //AbstractScAutoFormatDlg_Impl begin @@ -617,6 +624,20 @@ void AbstractScImportOptionsDlg_Impl::GetImportOptions( ScImportOptions& rOption pDlg->GetImportOptions(rOptions); } // add for AbstractScImportOptionsDlg_Impl end + +//add for AbstractScLangChooserDlg_Impl begin +LanguageType AbstractScTextImportOptionsDlg_Impl::GetLanguageType() const +{ + return pDlg->getLanguageType(); +} + +bool AbstractScTextImportOptionsDlg_Impl::IsDateConversionSet() const +{ + return pDlg->isDateConversionSet(); +} + +//add for AbstractScLangChooserDlg_Impl end + // =========================Factories for createdialog =================== //add for ScImportAsciiDlg begin @@ -639,6 +660,21 @@ AbstractScImportAsciiDlg * ScAbstractDialogFactory_Impl::CreateScImportAsciiDlg } // ScImportAsciiDlg end +AbstractScTextImportOptionsDlg * ScAbstractDialogFactory_Impl::CreateScTextImportOptionsDlg( Window* pParent, int nId ) +{ + ScTextImportOptionsDlg* pDlg = NULL; + switch (nId) + { + case RID_SCDLG_TEXT_IMPORT_OPTIONS: + pDlg = new ScTextImportOptionsDlg(pParent); + break; + default: + ; + } + + return pDlg ? new AbstractScTextImportOptionsDlg_Impl(pDlg) : NULL; +} + //add for ScAutoFormatDlg begin AbstractScAutoFormatDlg * ScAbstractDialogFactory_Impl::CreateScAutoFormatDlg( Window* pParent, //add for ScAutoFormatDlg diff --git a/sc/source/ui/attrdlg/scdlgfact.hxx b/sc/source/ui/attrdlg/scdlgfact.hxx index 7a9b03217655..d9752c83da9a 100644 --- a/sc/source/ui/attrdlg/scdlgfact.hxx +++ b/sc/source/ui/attrdlg/scdlgfact.hxx @@ -61,6 +61,7 @@ class ScStringInputDlg; class ScImportOptionsDlg; class SfxTabDialog; class ScSortWarningDlg; +class ScTextImportOptionsDlg; #define DECL_ABSTDLG_BASE(Class,DialogClass) \ DialogClass* pDlg; \ @@ -116,6 +117,7 @@ class AbstractScImportAsciiDlg_Impl : public AbstractScImportAsciiDlg //add for DECL_ABSTDLG_BASE(AbstractScImportAsciiDlg_Impl, ScImportAsciiDlg) virtual void GetOptions( ScAsciiOptions& rOpt ); virtual void SetTextToColumnsMode(); + virtual void SaveParameters(); }; class AbstractScAutoFormatDlg_Impl : public AbstractScAutoFormatDlg //add for ScAutoFormatDlg @@ -340,6 +342,13 @@ class AbstractScImportOptionsDlg_Impl : public AbstractScImportOptionsDlg //add virtual void GetImportOptions( ScImportOptions& rOptions ) const; }; +class AbstractScTextImportOptionsDlg_Impl : public AbstractScTextImportOptionsDlg +{ + DECL_ABSTDLG_BASE( AbstractScTextImportOptionsDlg_Impl, ScTextImportOptionsDlg) + virtual LanguageType GetLanguageType() const; + virtual bool IsDateConversionSet() const; +}; + //add for ScAttrDlg , ScHFEditDlg, ScStyleDlg, ScSubTotalDlg, ScCharDlg, ScParagraphDlg, ScValidationDlg, ScSortDlg class AbstractTabDialog_Impl : public SfxAbstractTabDialog { @@ -381,6 +390,8 @@ public: SvStream* pInStream, int nId, sal_Unicode cSep = '\t'); + virtual AbstractScTextImportOptionsDlg * CreateScTextImportOptionsDlg( Window* pParent, int nId ); + virtual AbstractScAutoFormatDlg * CreateScAutoFormatDlg( Window* pParent, //add for ScAutoFormatDlg ScAutoFormat* pAutoFormat, const ScAutoFormatData* pSelFormatData, diff --git a/sc/source/ui/dbgui/asciiopt.cxx b/sc/source/ui/dbgui/asciiopt.cxx index a40a5fb994ea..cd1f85fb99cc 100644 --- a/sc/source/ui/dbgui/asciiopt.cxx +++ b/sc/source/ui/dbgui/asciiopt.cxx @@ -53,8 +53,11 @@ ScAsciiOptions::ScAsciiOptions() : bFixedLen ( FALSE ), aFieldSeps ( ';' ), bMergeFieldSeps ( FALSE ), + bQuotedFieldAsText(false), + bDetectSpecialNumber(false), cTextSep ( cDefaultTextSep ), eCharSet ( gsl_getSystemTextEncoding() ), + eLang ( LANGUAGE_SYSTEM ), bCharSetSystem ( FALSE ), nStartRow ( 1 ), nInfoCount ( 0 ), @@ -68,8 +71,11 @@ ScAsciiOptions::ScAsciiOptions(const ScAsciiOptions& rOpt) : bFixedLen ( rOpt.bFixedLen ), aFieldSeps ( rOpt.aFieldSeps ), bMergeFieldSeps ( rOpt.bMergeFieldSeps ), + bQuotedFieldAsText(rOpt.bQuotedFieldAsText), + bDetectSpecialNumber(rOpt.bDetectSpecialNumber), cTextSep ( rOpt.cTextSep ), eCharSet ( rOpt.eCharSet ), + eLang ( rOpt.eLang ), bCharSetSystem ( rOpt.bCharSetSystem ), nStartRow ( rOpt.nStartRow ), nInfoCount ( rOpt.nInfoCount ) @@ -152,6 +158,7 @@ ScAsciiOptions& ScAsciiOptions::operator=( const ScAsciiOptions& rCpy ) bFixedLen = rCpy.bFixedLen; aFieldSeps = rCpy.aFieldSeps; bMergeFieldSeps = rCpy.bMergeFieldSeps; + bQuotedFieldAsText = rCpy.bQuotedFieldAsText; cTextSep = rCpy.cTextSep; eCharSet = rCpy.eCharSet; bCharSetSystem = rCpy.bCharSetSystem; @@ -166,6 +173,7 @@ BOOL ScAsciiOptions::operator==( const ScAsciiOptions& rCmp ) const if ( bFixedLen == rCmp.bFixedLen && aFieldSeps == rCmp.aFieldSeps && bMergeFieldSeps == rCmp.bMergeFieldSeps && + bQuotedFieldAsText == rCmp.bQuotedFieldAsText && cTextSep == rCmp.cTextSep && eCharSet == rCmp.eCharSet && bCharSetSystem == rCmp.bCharSetSystem && @@ -245,13 +253,20 @@ 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 >= 4 ) + if ( nCount >= 5 ) { - aToken = rString.GetToken(3,','); + aToken = rString.GetToken(4,','); nStartRow = aToken.ToInt32(); } @@ -259,12 +274,12 @@ void ScAsciiOptions::ReadFromString( const String& rString ) // Spalten-Infos // - if ( nCount >= 5 ) + if ( nCount >= 6 ) { delete[] pColStart; delete[] pColFormat; - aToken = rString.GetToken(4,','); + aToken = rString.GetToken(5,','); nSub = aToken.GetTokenCount('/'); nInfoCount = nSub / 2; if (nInfoCount) @@ -283,6 +298,20 @@ void ScAsciiOptions::ReadFromString( const String& rString ) pColFormat = NULL; } } + + // Import quoted field as text. + if (nCount >= 7) + { + aToken = rString.GetToken(6, ','); + bQuotedFieldAsText = aToken.EqualsAscii("true") ? true : false; + } + + // Detect special nubmers. + if (nCount >= 8) + { + aToken = rString.GetToken(7, ','); + bDetectSpecialNumber = aToken.EqualsAscii("true") ? true : false; + } } @@ -333,6 +362,10 @@ String ScAsciiOptions::WriteToString() const aOutStr += ScGlobal::GetCharsetString( eCharSet ); aOutStr += ','; // Token-Ende + // Language + aOutStr += String::CreateFromInt32(eLang); + aOutStr += ','; + // // Startzeile // @@ -354,6 +387,15 @@ String ScAsciiOptions::WriteToString() const aOutStr += String::CreateFromInt32(pColFormat[nInfo]); } + aOutStr += ','; + + // Import quoted field as text. + aOutStr += String::CreateFromAscii(bQuotedFieldAsText ? "true" : "false"); + aOutStr += ','; + + // Detect special nubmers. + aOutStr += String::CreateFromAscii(bDetectSpecialNumber ? "true" : "false"); + return aOutStr; } diff --git a/sc/source/ui/dbgui/asciiopt.hrc b/sc/source/ui/dbgui/asciiopt.hrc index 275de80f5972..7bf6d42d6e2f 100644 --- a/sc/source/ui/dbgui/asciiopt.hrc +++ b/sc/source/ui/dbgui/asciiopt.hrc @@ -26,31 +26,46 @@ ************************************************************************/ #include "sc.hrc" //#define RID_SCDLG_ASCII 256 -#define RB_SEPARATED 1 -#define RB_FIXED 2 -#define FT_CHARSET 3 -#define LB_CHARSET 4 -#define FL_SEPOPT 5 -#define FT_FIELDSEP 6 -#define CB_FIELDSEP 7 -#define FT_TEXTSEP 8 -#define CB_TEXTSEP 9 -#define FL_FIELDOPT 10 -#define FT_TYPE 12 -#define FT_PREVIEW 13 -#define LB_TYPE1 23 -#define FL_WIDTH 30 -#define BTN_OK 31 -#define BTN_CANCEL 32 -#define BTN_HELP 33 -#define CTR_TABLEBOX 41 -#define CKB_TAB 51 -#define CKB_SPACE 52 -#define CKB_SEMICOLON 53 -#define CKB_COMMA 54 -#define CKB_OTHER 55 -#define ED_OTHER 56 -#define FT_AT_ROW 59 -#define NF_AT_ROW 60 -#define CB_ASONCE 90 -#define STR_TEXTTOCOLUMNS 100 +#define BTN_OK 1 +#define BTN_CANCEL 2 +#define BTN_HELP 3 + +#define FL_FIELDOPT 4 +#define FT_CHARSET 5 +#define LB_CHARSET 6 +#define FT_CUSTOMLANG 7 +#define LB_CUSTOMLANG 8 +#define FT_AT_ROW 9 +#define NF_AT_ROW 10 + +#define FL_SEPOPT 11 +#define RB_FIXED 12 +#define RB_SEPARATED 13 +#define CKB_TAB 14 +#define CKB_COMMA 15 +#define CKB_OTHER 16 +#define ED_OTHER 17 +#define CKB_SEMICOLON 18 +#define CKB_SPACE 19 +#define CB_ASONCE 20 +#define CB_TEXTSEP 21 +#define FT_TEXTSEP 22 + +#define FL_OTHER_OPTIONS 23 +#define CB_QUOTED_AS_TEXT 24 +#define CB_DETECT_SPECIAL_NUMBER 25 + +#define FL_WIDTH 26 +#define FT_TYPE 27 +#define LB_TYPE1 28 +#define CTR_TABLEBOX 29 +#define STR_TEXTTOCOLUMNS 30 + + + + + + + + + diff --git a/sc/source/ui/dbgui/asciiopt.src b/sc/source/ui/dbgui/asciiopt.src index b527719cb6de..9efbfe0f557f 100644 --- a/sc/source/ui/dbgui/asciiopt.src +++ b/sc/source/ui/dbgui/asciiopt.src @@ -31,55 +31,44 @@ ModalDialog RID_SCDLG_ASCII { OutputSize = TRUE ; SVLook = TRUE ; - Size = MAP_APPFONT ( 320 , 247 ) ; + Size = MAP_APPFONT ( 320 , 305 ) ; Text [ en-US ] = "Text Import" ; Moveable = TRUE ; - FixedLine FL_WIDTH - { - Pos = MAP_APPFONT ( 6 , 132 ) ; - Size = MAP_APPFONT ( 252 , 8 ) ; - Text [ en-US ] = "Fields" ; - }; - FixedText FT_TYPE - { - Pos = MAP_APPFONT ( 12 , 145 ) ; - Size = MAP_APPFONT ( 60 , 8 ) ; - Text [ en-US ] = "Column t~ype"; - }; - ListBox LB_TYPE1 + + OKButton BTN_OK { - Pos = MAP_APPFONT ( 76 , 143 ) ; - Size = MAP_APPFONT ( 60 , 68 ) ; + Pos = MAP_APPFONT ( 264 , 6 ) ; + Size = MAP_APPFONT ( 50 , 14 ) ; TabStop = TRUE ; - DropDown = TRUE ; + DefButton = TRUE ; }; - FixedLine FL_SEPOPT + CancelButton BTN_CANCEL { - Pos = MAP_APPFONT ( 6 , 48 ) ; - Size = MAP_APPFONT ( 252 , 8 ) ; - Text [ en-US ] = "Separator options" ; + Pos = MAP_APPFONT ( 264 , 23 ) ; + Size = MAP_APPFONT ( 50 , 14 ) ; + TabStop = TRUE ; }; - RadioButton RB_FIXED + HelpButton BTN_HELP { - Pos = MAP_APPFONT ( 12 , 59 ) ; - Size = MAP_APPFONT ( 243 , 10 ) ; - Text [ en-US ] = "~Fixed width" ; + Pos = MAP_APPFONT ( 264 , 43 ) ; + Size = MAP_APPFONT ( 50 , 14 ) ; TabStop = TRUE ; }; - RadioButton RB_SEPARATED + + FixedLine FL_FIELDOPT { - Pos = MAP_APPFONT ( 12 , 73 ) ; - Size = MAP_APPFONT ( 243 , 10 ) ; - Text [ en-US ] = "~Separated by" ; - TabStop = TRUE ; - Check = TRUE ; + Pos = MAP_APPFONT ( 6 , 3 ) ; + Size = MAP_APPFONT ( 252 , 8 ) ; + Text [ en-US ] = "Import" ; }; + FixedText FT_CHARSET { Pos = MAP_APPFONT ( 12 , 16 ) ; Size = MAP_APPFONT ( 60 , 8 ) ; Text [ en-US ] = "Ch~aracter set" ; }; + ListBox LB_CHARSET { Pos = MAP_APPFONT ( 76 , 14 ) ; @@ -88,119 +77,182 @@ ModalDialog RID_SCDLG_ASCII DropDown = TRUE ; Sort = TRUE; }; - FixedLine FL_FIELDOPT - { - Pos = MAP_APPFONT ( 6 , 3 ) ; - Size = MAP_APPFONT ( 252 , 8 ) ; - Text [ en-US ] = "Import" ; - }; - FixedText FT_TEXTSEP + + FixedText FT_CUSTOMLANG { - Pos = MAP_APPFONT ( 156 , 114 ) ; + Pos = MAP_APPFONT ( 12 , 32 ) ; Size = MAP_APPFONT ( 60 , 8 ) ; - Text [ en-US ] = "Te~xt delimiter" ; + Text [ en-US ] = "Language" ; }; - ComboBox CB_TEXTSEP + + ListBox LB_CUSTOMLANG { - Pos = MAP_APPFONT ( 218 , 112 ) ; - Size = MAP_APPFONT ( 37 , 94 ) ; + Pos = MAP_APPFONT ( 76 , 30 ) ; + Size = MAP_APPFONT ( 130 , 61 ) ; TabStop = TRUE ; DropDown = TRUE ; + Sort = TRUE; }; - OKButton BTN_OK + + FixedText FT_AT_ROW { - Pos = MAP_APPFONT ( 264 , 6 ) ; - Size = MAP_APPFONT ( 50 , 14 ) ; + Pos = MAP_APPFONT ( 12 , 48 ) ; + Size = MAP_APPFONT ( 60 , 8 ) ; + Text [ en-US ] = "From ro~w" ; + }; + + NumericField NF_AT_ROW + { + Border = TRUE ; + SVLook = TRUE ; + Pos = MAP_APPFONT ( 76 , 46 ) ; + Size = MAP_APPFONT ( 30 , 12 ) ; TabStop = TRUE ; - DefButton = TRUE ; + Spin = TRUE ; + Repeat = TRUE ; + Minimum = 1 ; }; - CancelButton BTN_CANCEL + + FixedLine FL_SEPOPT { - Pos = MAP_APPFONT ( 264 , 23 ) ; - Size = MAP_APPFONT ( 50 , 14 ) ; + Pos = MAP_APPFONT ( 6 , 63 ) ; + Size = MAP_APPFONT ( 252 , 8 ) ; + Text [ en-US ] = "Separator options" ; + }; + RadioButton RB_FIXED + { + Pos = MAP_APPFONT ( 12 , 75 ) ; + Size = MAP_APPFONT ( 243 , 10 ) ; + Text [ en-US ] = "~Fixed width" ; TabStop = TRUE ; }; - HelpButton BTN_HELP + RadioButton RB_SEPARATED { - Pos = MAP_APPFONT ( 264 , 43 ) ; - Size = MAP_APPFONT ( 50 , 14 ) ; + Pos = MAP_APPFONT ( 12 , 89 ) ; + Size = MAP_APPFONT ( 243 , 10 ) ; + Text [ en-US ] = "~Separated by" ; TabStop = TRUE ; + Check = TRUE ; }; + CheckBox CKB_TAB { - Pos = MAP_APPFONT ( 20 , 86 ) ; + Pos = MAP_APPFONT ( 20 , 102 ) ; Size = MAP_APPFONT ( 68 , 10 ) ; TabStop = TRUE ; Text [ en-US ] = "~Tab" ; }; - CheckBox CKB_SEMICOLON + CheckBox CKB_COMMA { - Pos = MAP_APPFONT ( 20 , 99 ) ; + Pos = MAP_APPFONT ( 92 , 102 ) ; Size = MAP_APPFONT ( 68 , 10 ) ; TabStop = TRUE ; - Text [ en-US ] = "S~emicolon" ; + Text [ en-US ] = "~Comma" ; }; - CheckBox CKB_COMMA + CheckBox CKB_OTHER + { + Pos = MAP_APPFONT ( 164 , 102 ) ; + Size = MAP_APPFONT ( 50 , 10 ) ; + TabStop = TRUE ; + Text [ en-US ] = "~Other" ; + }; + Edit ED_OTHER + { + Border = TRUE ; + Pos = MAP_APPFONT ( 218 , 100 ) ; + Size = MAP_APPFONT ( 37 , 12 ) ; + TabStop = TRUE ; + MaxTextLength = 10 ; + }; + + CheckBox CKB_SEMICOLON { - Pos = MAP_APPFONT ( 92 , 86 ) ; + Pos = MAP_APPFONT ( 20 , 115 ) ; Size = MAP_APPFONT ( 68 , 10 ) ; TabStop = TRUE ; - Text [ en-US ] = "~Comma" ; + Text [ en-US ] = "S~emicolon" ; }; CheckBox CKB_SPACE { - Pos = MAP_APPFONT ( 92 , 99 ) ; + Pos = MAP_APPFONT ( 92 , 115 ) ; Size = MAP_APPFONT ( 68 , 10 ) ; TabStop = TRUE ; Text [ en-US ] = "S~pace" ; }; - CheckBox CKB_OTHER + + CheckBox CB_ASONCE { - Pos = MAP_APPFONT ( 164 , 86 ) ; - Size = MAP_APPFONT ( 50 , 10 ) ; + Pos = MAP_APPFONT ( 20 , 130 ) ; + Size = MAP_APPFONT ( 130 , 10 ) ; TabStop = TRUE ; - Text [ en-US ] = "~Other" ; + Text [ en-US ] = "Merge ~delimiters" ; }; - Edit ED_OTHER + + ComboBox CB_TEXTSEP { - Border = TRUE ; - Pos = MAP_APPFONT ( 218 , 84 ) ; - Size = MAP_APPFONT ( 37 , 12 ) ; + Pos = MAP_APPFONT ( 218 , 128 ) ; + Size = MAP_APPFONT ( 37 , 94 ) ; TabStop = TRUE ; - MaxTextLength = 10 ; + DropDown = TRUE ; }; - FixedText FT_AT_ROW + FixedText FT_TEXTSEP { - Pos = MAP_APPFONT ( 12 , 32 ) ; + Pos = MAP_APPFONT ( 156 , 130 ) ; Size = MAP_APPFONT ( 60 , 8 ) ; - Text [ en-US ] = "From ro~w" ; + Text [ en-US ] = "Te~xt delimiter" ; }; - NumericField NF_AT_ROW + + FixedLine FL_OTHER_OPTIONS { - Border = TRUE ; - SVLook = TRUE ; - Pos = MAP_APPFONT ( 76 , 30 ) ; - Size = MAP_APPFONT ( 30 , 12 ) ; + Pos = MAP_APPFONT ( 6 , 146 ) ; + Size = MAP_APPFONT ( 252 , 8 ) ; + Text [ en-US ] = "Other options" ; + }; + + CheckBox CB_QUOTED_AS_TEXT + { + Pos = MAP_APPFONT ( 12 , 158 ) ; + Size = MAP_APPFONT ( 130 , 10 ) ; TabStop = TRUE ; - Spin = TRUE ; - Repeat = TRUE ; - Minimum = 1 ; + Text [ en-US ] = "~Quoted field as text" ; + }; + + CheckBox CB_DETECT_SPECIAL_NUMBER + { + Pos = MAP_APPFONT ( 12 , 171 ) ; + Size = MAP_APPFONT ( 130 , 10 ) ; + TabStop = TRUE ; + Text [ en-US ] = "Detect special numbers" ; + }; + + FixedLine FL_WIDTH + { + Pos = MAP_APPFONT ( 6 , 187 ) ; + Size = MAP_APPFONT ( 252 , 8 ) ; + Text [ en-US ] = "Fields" ; + }; + FixedText FT_TYPE + { + Pos = MAP_APPFONT ( 12 , 200 ) ; + Size = MAP_APPFONT ( 60 , 8 ) ; + Text [ en-US ] = "Column t~ype"; + }; + ListBox LB_TYPE1 + { + Pos = MAP_APPFONT ( 76 , 198 ) ; + Size = MAP_APPFONT ( 60 , 68 ) ; + TabStop = TRUE ; + DropDown = TRUE ; }; Control CTR_TABLEBOX { HelpId = HID_SC_ASCII_TABCTR ; Border = TRUE ; DialogControl = TRUE ; - Pos = MAP_APPFONT ( 12 , 159 ) ; + Pos = MAP_APPFONT ( 12 , 216 ) ; Size = MAP_APPFONT ( 243 , 82 ) ; }; - CheckBox CB_ASONCE - { - Pos = MAP_APPFONT ( 20 , 114 ) ; - Size = MAP_APPFONT ( 130 , 10 ) ; - TabStop = TRUE ; - Text [ en-US ] = "Merge ~delimiters" ; - }; + String STR_TEXTTOCOLUMNS { Text [ en-US ] = "Text to Columns" ; diff --git a/sc/source/ui/dbgui/csvgrid.cxx b/sc/source/ui/dbgui/csvgrid.cxx index 2ec05af2f72e..d271022a987c 100644 --- a/sc/source/ui/dbgui/csvgrid.cxx +++ b/sc/source/ui/dbgui/csvgrid.cxx @@ -734,7 +734,8 @@ void ScCsvGrid::ImplSetTextLineSep( while( *pChar && (nColIx < sal::static_int_cast<sal_uInt32>(CSV_MAXCOLCOUNT)) ) { // scan for next cell text - pChar = ScImportExport::ScanNextFieldFromString( pChar, aCellText, cTextSep, pSepChars, bMergeSep ); + bool bIsQuoted = false; + pChar = ScImportExport::ScanNextFieldFromString( pChar, aCellText, cTextSep, pSepChars, bMergeSep, bIsQuoted ); // update column width sal_Int32 nWidth = Max( CSV_MINCOLWIDTH, aCellText.Len() + sal_Int32( 1 ) ); diff --git a/sc/source/ui/dbgui/csvruler.cxx b/sc/source/ui/dbgui/csvruler.cxx index d84c938bfd14..56aa2a50a835 100644 --- a/sc/source/ui/dbgui/csvruler.cxx +++ b/sc/source/ui/dbgui/csvruler.cxx @@ -34,8 +34,77 @@ #include "AccessibleCsvControl.hxx" +#include <optutil.hxx> +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/uno/Sequence.hxx> +#include "miscuno.hxx" + +using namespace rtl; +using namespace com::sun::star::uno; + + + +// ============================================================================ +#define SEP_PATH "Office.Calc/Dialogs/CSVImport" +#define FIXED_WIDTH_LIST "FixedWidthList" + + // ============================================================================ +static void load_FixedWidthList(ScCsvSplits &aSplits) +{ + String sSplits; + OUString sFixedWidthLists; + + Sequence<Any>aValues; + const Any *pProperties; + Sequence<OUString> aNames(1); + OUString* pNames = aNames.getArray(); + ScLinkConfigItem aItem( OUString::createFromAscii( SEP_PATH ) ); + + pNames[0] = OUString::createFromAscii( FIXED_WIDTH_LIST ); + aValues = aItem.GetProperties( aNames ); + pProperties = aValues.getConstArray(); + + if( pProperties[0].hasValue() ) + { + aSplits.Clear(); + pProperties[0] >>= sFixedWidthLists; + + sSplits = String( sFixedWidthLists ); + + // String ends with a semi-colon so there is no 'int' after the last one. + xub_StrLen n = sSplits.GetTokenCount() - 1; + for (xub_StrLen i = 0; i < n; ++i) + aSplits.Insert( sSplits.GetToken(i).ToInt32() ); + } +} +static void save_FixedWidthList(ScCsvSplits aSplits) +{ + String sSplits; + // Create a semi-colon separated string to save the splits + sal_uInt32 n = aSplits.Count(); + for (sal_uInt32 i = 0; i < n; ++i) + { + sSplits.Append( String::CreateFromInt32( aSplits[i] ) ); + sSplits.Append((char)';'); + } + + OUString sFixedWidthLists = OUString( sSplits ); + Sequence<Any> aValues; + Any *pProperties; + Sequence<OUString> aNames(1); + OUString* pNames = aNames.getArray(); + ScLinkConfigItem aItem( OUString::createFromAscii( SEP_PATH ) ); + + pNames[0] = OUString::createFromAscii( FIXED_WIDTH_LIST ); + aValues = aItem.GetProperties( aNames ); + pProperties = aValues.getArray(); + pProperties[0] <<= sFixedWidthLists; + + aItem.PutProperties(aNames, aValues); +} + ScCsvRuler::ScCsvRuler( ScCsvControl& rParent ) : ScCsvControl( rParent ), mnPosCursorLast( 1 ) @@ -45,6 +114,13 @@ ScCsvRuler::ScCsvRuler( ScCsvControl& rParent ) : InitSizeData(); maBackgrDev.SetFont( GetFont() ); maRulerDev.SetFont( GetFont() ); + + load_FixedWidthList( maSplits ); +} + +ScCsvRuler::~ScCsvRuler() +{ + save_FixedWidthList( maSplits ); } diff --git a/sc/source/ui/dbgui/dapidata.cxx b/sc/source/ui/dbgui/dapidata.cxx index 87de71767a17..976e0ae23039 100644 --- a/sc/source/ui/dbgui/dapidata.cxx +++ b/sc/source/ui/dbgui/dapidata.cxx @@ -56,7 +56,7 @@ using namespace com::sun::star; //------------------------------------------------------------------------- #define DP_SERVICE_DBCONTEXT "com.sun.star.sdb.DatabaseContext" -#define SC_SERVICE_INTHANDLER "com.sun.star.sdb.InteractionHandler" +#define SC_SERVICE_INTHANDLER "com.sun.star.task.InteractionHandler" // entries in the "type" ListBox #define DP_TYPELIST_TABLE 0 diff --git a/sc/source/ui/dbgui/makefile.mk b/sc/source/ui/dbgui/makefile.mk index ee855d22aef1..2d4fa71f690e 100644 --- a/sc/source/ui/dbgui/makefile.mk +++ b/sc/source/ui/dbgui/makefile.mk @@ -49,6 +49,7 @@ SLOFILES = \ $(SLO)$/pfiltdlg.obj \ $(SLO)$/dbnamdlg.obj \ $(SLO)$/expftext.obj \ + $(SLO)$/textimportoptions.obj \ $(SLO)$/subtdlg.obj \ $(SLO)$/tpsubt.obj \ $(SLO)$/fieldwnd.obj \ @@ -83,6 +84,7 @@ EXCEPTIONSFILES= \ SRS1NAME=$(TARGET) SRC1FILES = \ + textimportoptions.src \ pivot.src \ pvfundlg.src \ dpgroupdlg.src \ diff --git a/sc/source/ui/dbgui/pvfundlg.cxx b/sc/source/ui/dbgui/pvfundlg.cxx index 8609bfcbfb0a..03de0b8914a3 100644 --- a/sc/source/ui/dbgui/pvfundlg.cxx +++ b/sc/source/ui/dbgui/pvfundlg.cxx @@ -739,9 +739,12 @@ ScDPShowDetailDlg::ScDPShowDetailDlg( Window* pParent, ScDPObject& rDPObj, USHOR const ScDPSaveDimension* pDimension = pSaveData ? pSaveData->GetExistingDimensionByName(aName) : 0; if ( !pDimension || (pDimension->GetOrientation() != nOrient) ) { - const OUString* pLayoutName = pDimension->GetLayoutName(); - if (pLayoutName) - aName = *pLayoutName; + if (pDimension) + { + const OUString* pLayoutName = pDimension->GetLayoutName(); + if (pLayoutName) + aName = *pLayoutName; + } maLbDims.InsertEntry( aName ); maNameIndexMap.insert(DimNameIndexMap::value_type(aName, nDim)); } diff --git a/sc/source/ui/dbgui/scuiasciiopt.cxx b/sc/source/ui/dbgui/scuiasciiopt.cxx index e4e568e00882..171daa0ca882 100644 --- a/sc/source/ui/dbgui/scuiasciiopt.cxx +++ b/sc/source/ui/dbgui/scuiasciiopt.cxx @@ -41,6 +41,12 @@ // ause #include "editutil.hxx" +#include <optutil.hxx> +#include <com/sun/star/uno/Any.hxx> +#include <com/sun/star/uno/Sequence.hxx> +#include "miscuno.hxx" + + //! TODO make dynamic #ifdef WIN const SCSIZE ASCIIDLG_MAXROWS = 10000; @@ -48,6 +54,22 @@ const SCSIZE ASCIIDLG_MAXROWS = 10000; const SCSIZE ASCIIDLG_MAXROWS = MAXROWCOUNT; #endif + +using namespace rtl; +using namespace com::sun::star::uno; + +// Defines - CSV Import Preserve Options +#define FIXED_WIDTH "FixedWidth" +#define FROM_ROW "FromRow" +#define CHAR_SET "CharSet" +#define SEPARATORS "Separators" +#define TEXT_SEPARATORS "TextSeparators" +#define MERGE_DELIMITERS "MergeDelimiters" +#define QUOTED_AS_TEXT "QuotedFieldAsText" +#define DETECT_SPECIAL_NUM "DetectSpecialNumbers" +#define LANGUAGE "Language" +#define SEP_PATH "Office.Calc/Dialogs/CSVImport" + // ============================================================================ void lcl_FillCombo( ComboBox& rCombo, const String& rList, sal_Unicode cSelect ) @@ -95,11 +117,96 @@ sal_Unicode lcl_CharFromCombo( ComboBox& rCombo, const String& rList ) return c; } +static void load_Separators( OUString &sFieldSeparators, OUString &sTextSeparators, + bool &bMergeDelimiters, bool& bQuotedAsText, bool& bDetectSpecialNum, + bool &bFixedWidth, sal_Int32 &nFromRow, sal_Int32 &nCharSet, + sal_Int32& nLanguage ) +{ + Sequence<Any>aValues; + const Any *pProperties; + Sequence<OUString> aNames(9); + OUString* pNames = aNames.getArray(); + ScLinkConfigItem aItem( OUString::createFromAscii( SEP_PATH ) ); + + pNames[0] = OUString::createFromAscii( MERGE_DELIMITERS ); + pNames[1] = OUString::createFromAscii( SEPARATORS ); + pNames[2] = OUString::createFromAscii( TEXT_SEPARATORS ); + pNames[3] = OUString::createFromAscii( FIXED_WIDTH ); + pNames[4] = OUString::createFromAscii( FROM_ROW ); + pNames[5] = OUString::createFromAscii( CHAR_SET ); + pNames[6] = OUString::createFromAscii( QUOTED_AS_TEXT ); + pNames[7] = OUString::createFromAscii( DETECT_SPECIAL_NUM ); + pNames[8] = OUString::createFromAscii( LANGUAGE ); + aValues = aItem.GetProperties( aNames ); + pProperties = aValues.getConstArray(); + if( pProperties[1].hasValue() ) + pProperties[1] >>= sFieldSeparators; + + if( pProperties[2].hasValue() ) + pProperties[2] >>= sTextSeparators; + + if( pProperties[0].hasValue() ) + bMergeDelimiters = ScUnoHelpFunctions::GetBoolFromAny( pProperties[0] ); + + if( pProperties[3].hasValue() ) + bFixedWidth = ScUnoHelpFunctions::GetBoolFromAny( pProperties[3] ); + + if( pProperties[4].hasValue() ) + pProperties[4] >>= nFromRow; + + if( pProperties[5].hasValue() ) + pProperties[5] >>= nCharSet; + + if ( pProperties[6].hasValue() ) + pProperties[6] >>= bQuotedAsText; + + if ( pProperties[7].hasValue() ) + pProperties[7] >>= bDetectSpecialNum; + + if ( pProperties[8].hasValue() ) + pProperties[8] >>= nLanguage; +} + +static void save_Separators( + String maSeparators, String maTxtSep, bool bMergeDelimiters, bool bQuotedAsText, + bool bDetectSpecialNum, bool bFixedWidth, sal_Int32 nFromRow, sal_Int32 nCharSet, sal_Int32 nLanguage ) +{ + OUString sFieldSeparators = OUString( maSeparators ); + OUString sTextSeparators = OUString( maTxtSep ); + Sequence<Any> aValues; + Any *pProperties; + Sequence<OUString> aNames(9); + OUString* pNames = aNames.getArray(); + ScLinkConfigItem aItem( OUString::createFromAscii( SEP_PATH ) ); + + pNames[0] = OUString::createFromAscii( MERGE_DELIMITERS ); + pNames[1] = OUString::createFromAscii( SEPARATORS ); + pNames[2] = OUString::createFromAscii( TEXT_SEPARATORS ); + pNames[3] = OUString::createFromAscii( FIXED_WIDTH ); + pNames[4] = OUString::createFromAscii( FROM_ROW ); + pNames[5] = OUString::createFromAscii( CHAR_SET ); + pNames[6] = OUString::createFromAscii( QUOTED_AS_TEXT ); + pNames[7] = OUString::createFromAscii( DETECT_SPECIAL_NUM ); + pNames[8] = OUString::createFromAscii( LANGUAGE ); + aValues = aItem.GetProperties( aNames ); + pProperties = aValues.getArray(); + pProperties[1] <<= sFieldSeparators; + pProperties[2] <<= sTextSeparators; + ScUnoHelpFunctions::SetBoolInAny( pProperties[0], bMergeDelimiters ); + ScUnoHelpFunctions::SetBoolInAny( pProperties[3], bFixedWidth ); + pProperties[4] <<= nFromRow; + pProperties[5] <<= nCharSet; + pProperties[6] <<= static_cast<sal_Bool>(bQuotedAsText); + pProperties[7] <<= static_cast<sal_Bool>(bDetectSpecialNum); + pProperties[8] <<= nLanguage; + + aItem.PutProperties(aNames, aValues); +} // ---------------------------------------------------------------------------- ScImportAsciiDlg::ScImportAsciiDlg( Window* pParent,String aDatName, - SvStream* pInStream, sal_Unicode cSep ) : + SvStream* pInStream, sal_Unicode /*cSep*/ ) : ModalDialog ( pParent, ScResId( RID_SCDLG_ASCII ) ), mpDatStream ( pInStream ), mnStreamPos( pInStream ? pInStream->Tell() : 0 ), @@ -110,6 +217,8 @@ ScImportAsciiDlg::ScImportAsciiDlg( Window* pParent,String aDatName, aFlFieldOpt ( this, ScResId( FL_FIELDOPT ) ), aFtCharSet ( this, ScResId( FT_CHARSET ) ), aLbCharSet ( this, ScResId( LB_CHARSET ) ), + aFtCustomLang( this, ScResId( FT_CUSTOMLANG ) ), + aLbCustomLang( this, ScResId( LB_CUSTOMLANG ) ), aFtRow ( this, ScResId( FT_AT_ROW ) ), aNfRow ( this, ScResId( NF_AT_ROW ) ), @@ -125,9 +234,14 @@ ScImportAsciiDlg::ScImportAsciiDlg( Window* pParent,String aDatName, aCkbOther ( this, ScResId( CKB_OTHER ) ), aEdOther ( this, ScResId( ED_OTHER ) ), aCkbAsOnce ( this, ScResId( CB_ASONCE) ), + aFlOtherOpt ( this, ScResId( FL_OTHER_OPTIONS ) ), + aFtTextSep ( this, ScResId( FT_TEXTSEP ) ), aCbTextSep ( this, ScResId( CB_TEXTSEP ) ), + aCkbQuotedAsText( this, ScResId(CB_QUOTED_AS_TEXT) ), + aCkbDetectNumber( this, ScResId(CB_DETECT_SPECIAL_NUMBER) ), + aFlWidth ( this, ScResId( FL_WIDTH ) ), aFtType ( this, ScResId( FT_TYPE ) ), aLbType ( this, ScResId( LB_TYPE1 ) ), @@ -143,14 +257,15 @@ ScImportAsciiDlg::ScImportAsciiDlg( Window* pParent,String aDatName, aFldSepList ( ScResId( SCSTR_FIELDSEP ) ), aTextSepList( ScResId( SCSTR_TEXTSEP ) ), mcTextSep ( ScAsciiOptions::cDefaultTextSep ), - maStrTextToColumns( ScResId( STR_TEXTTOCOLUMNS ) ) + maStrTextToColumns( ScResId( STR_TEXTTOCOLUMNS ) ), + mbFileImport(true) { FreeResource(); + mbFileImport = aDatName.Len() > 0; String aName = GetText(); // aDatName is empty if invoked during paste from clipboard. - BOOL bClipboard = (aDatName.Len() == 0); - if (!bClipboard) + if (mbFileImport) { aName.AppendAscii(RTL_CONSTASCII_STRINGPARAM(" - [")); aName += aDatName; @@ -158,20 +273,55 @@ ScImportAsciiDlg::ScImportAsciiDlg( Window* pParent,String aDatName, } SetText( aName ); - switch(cSep) + + OUString sFieldSeparators; + OUString sTextSeparators; + bool bMergeDelimiters = false; + bool bFixedWidth = false; + bool bQuotedFieldAsText = true; + bool bDetectSpecialNum = false; + sal_Int32 nFromRow = 1; + sal_Int32 nCharSet = -1; + sal_Int32 nLanguage = 0; + if (mbFileImport) + // load separators only when importing csv files. + load_Separators (sFieldSeparators, sTextSeparators, bMergeDelimiters, + bQuotedFieldAsText, bDetectSpecialNum, bFixedWidth, nFromRow, nCharSet, nLanguage); + maFieldSeparators = String(sFieldSeparators); + + if( bMergeDelimiters ) + aCkbAsOnce.Check(); + if (bQuotedFieldAsText) + aCkbQuotedAsText.Check(); + if (bDetectSpecialNum) + aCkbDetectNumber.Check(); + if( bFixedWidth ) + aRbFixed.Check(); + if( nFromRow != 1 ) + aNfRow.SetValue( nFromRow ); + + ByteString bString(maFieldSeparators,RTL_TEXTENCODING_MS_1252); + const sal_Char *aSep = bString.GetBuffer(); + int len = maFieldSeparators.Len(); + for (int i = 0; i < len; ++i) { - case '\t': aCkbTab.Check(); break; - case ';': aCkbSemicolon.Check(); break; - case ',': aCkbComma.Check(); break; - case ' ': aCkbSpace.Check(); break; - default: - aCkbOther.Check(); - aEdOther.SetText( cSep ); + switch( aSep[i] ) + { + case '\t': aCkbTab.Check(); break; + case ';': aCkbSemicolon.Check(); break; + case ',': aCkbComma.Check(); break; + case ' ': aCkbSpace.Check(); break; + default: + aCkbOther.Check(); + aEdOther.SetText( aEdOther.GetText() + OUString( aSep[i] ) ); + } } + + // Get Separators from the dialog maFieldSeparators = GetSeparators(); // Clipboard is always Unicode, else detect. - BOOL bPreselectUnicode = bClipboard; + bool bPreselectUnicode = !mbFileImport; // Sniff for Unicode / not if( !bPreselectUnicode && mpDatStream ) { @@ -207,6 +357,7 @@ ScImportAsciiDlg::ScImportAsciiDlg( Window* pParent,String aDatName, // *** Separator characters *** lcl_FillCombo( aCbTextSep, aTextSepList, mcTextSep ); + aCbTextSep.SetText( sTextSeparators ); Link aSeparatorHdl =LINK( this, ScImportAsciiDlg, SeparatorHdl ); aCbTextSep.SetSelectHdl( aSeparatorHdl ); @@ -215,6 +366,8 @@ ScImportAsciiDlg::ScImportAsciiDlg( Window* pParent,String aDatName, aCkbSemicolon.SetClickHdl( aSeparatorHdl ); aCkbComma.SetClickHdl( aSeparatorHdl ); aCkbAsOnce.SetClickHdl( aSeparatorHdl ); + aCkbQuotedAsText.SetClickHdl( aSeparatorHdl ); + aCkbDetectNumber.SetClickHdl( aSeparatorHdl ); aCkbSpace.SetClickHdl( aSeparatorHdl ); aCkbOther.SetClickHdl( aSeparatorHdl ); aEdOther.SetModifyHdl( aSeparatorHdl ); @@ -227,9 +380,18 @@ ScImportAsciiDlg::ScImportAsciiDlg( Window* pParent,String aDatName, aLbCharSet.InsertTextEncoding( RTL_TEXTENCODING_DONTKNOW, aCharSetUser ); aLbCharSet.SelectTextEncoding( bPreselectUnicode ? RTL_TEXTENCODING_UNICODE : gsl_getSystemTextEncoding() ); + + if( nCharSet >= 0 ) + aLbCharSet.SelectEntryPos( static_cast<USHORT>(nCharSet) ); + SetSelectedCharSet(); aLbCharSet.SetSelectHdl( LINK( this, ScImportAsciiDlg, CharSetHdl ) ); + aLbCustomLang.SetLanguageList( + LANG_LIST_ALL | LANG_LIST_ONLY_KNOWN, false, false); + aLbCustomLang.InsertLanguage(LANGUAGE_SYSTEM); + aLbCustomLang.SelectLanguage(static_cast<LanguageType>(nLanguage), true); + // *** column type ListBox *** xub_StrLen nCount = aColumnUser.GetTokenCount(); for (xub_StrLen i=0; i<nCount; i++) @@ -336,6 +498,7 @@ void ScImportAsciiDlg::GetOptions( ScAsciiOptions& rOpt ) { rOpt.SetCharSet( meCharSet ); rOpt.SetCharSetSystem( mbCharSetSystem ); + rOpt.SetLanguage(aLbCustomLang.GetSelectLanguage()); rOpt.SetFixedLen( aRbFixed.IsChecked() ); rOpt.SetStartRow( (long)aNfRow.GetValue() ); maTableBox.FillColumnData( rOpt ); @@ -345,6 +508,9 @@ void ScImportAsciiDlg::GetOptions( ScAsciiOptions& rOpt ) rOpt.SetMergeSeps( aCkbAsOnce.IsChecked() ); rOpt.SetTextSep( lcl_CharFromCombo( aCbTextSep, aTextSepList ) ); } + + rOpt.SetQuotedAsText(aCkbQuotedAsText.IsChecked()); + rOpt.SetDetectSpecialNumber(aCkbDetectNumber.IsChecked()); } void ScImportAsciiDlg::SetTextToColumnsMode() @@ -352,8 +518,33 @@ void ScImportAsciiDlg::SetTextToColumnsMode() SetText( maStrTextToColumns ); aFtCharSet.Disable(); aLbCharSet.Disable(); + aFtCustomLang.Disable(); + aLbCustomLang.SelectLanguage(LANGUAGE_SYSTEM); + aLbCustomLang.Disable(); aFtRow.Disable(); aNfRow.Disable(); + + // Quoted field as text option is not used for text-to-columns mode. + aCkbQuotedAsText.Check(false); + aCkbQuotedAsText.Disable(); + + // Always detect special numbers for text-to-columns mode. + aCkbDetectNumber.Check(); + aCkbDetectNumber.Disable(); +} + +void ScImportAsciiDlg::SaveParameters() +{ + if (!mbFileImport) + // We save parameters only for file import. + return; + + save_Separators( maFieldSeparators, aCbTextSep.GetText(), aCkbAsOnce.IsChecked(), + aCkbQuotedAsText.IsChecked(), aCkbDetectNumber.IsChecked(), + aRbFixed.IsChecked(), + static_cast<sal_Int32>(aNfRow.GetValue()), + static_cast<sal_Int32>(aLbCharSet.GetSelectEntryPos()), + static_cast<sal_Int32>(aLbCustomLang.GetSelectLanguage()) ); } void ScImportAsciiDlg::SetSelectedCharSet() diff --git a/sc/source/ui/dbgui/textimportoptions.cxx b/sc/source/ui/dbgui/textimportoptions.cxx new file mode 100644 index 000000000000..be918d2a0fbd --- /dev/null +++ b/sc/source/ui/dbgui/textimportoptions.cxx @@ -0,0 +1,121 @@ +/************************************************************************* + * + * 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: langbox.hxx,v $ + * $Revision: 1.4.242.1 $ + * + * 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 "textimportoptions.hxx" +#include "textimportoptions.hrc" + +#include "scresid.hxx" +#include "vcl/window.hxx" +#include "vcl/msgbox.hxx" +#include "vcl/svapp.hxx" + +ScTextImportOptionsDlg::ScTextImportOptionsDlg(Window* pParent) : + ModalDialog(pParent, ScResId(RID_SCDLG_TEXT_IMPORT_OPTIONS)), + + maBtnOk(this, ScResId(BTN_OK)), + maBtnCancel(this, ScResId(BTN_CANCEL)), + maBtnHelp(this, ScResId(BTN_HELP)), + maFlChooseLang(this, ScResId(FL_CHOOSE_LANG)), + maRbAutomatic(this, ScResId(RB_AUTOMATIC)), + maRbCustom(this, ScResId(RB_CUSTOM)), + maLbCustomLang(this, ScResId(LB_CUSTOM_LANG)), + maFlOption(this, ScResId(FL_OPTION)), + maBtnConvertDate(this, ScResId(BTN_CONVERT_DATE)) +{ + FreeResource(); + init(); +} + +ScTextImportOptionsDlg::~ScTextImportOptionsDlg() +{ +} + +short ScTextImportOptionsDlg::Execute() +{ + return ModalDialog::Execute(); +} + +LanguageType ScTextImportOptionsDlg::getLanguageType() const +{ + if (maRbAutomatic.IsChecked()) + return LANGUAGE_SYSTEM; + + return maLbCustomLang.GetSelectLanguage(); +} + +bool ScTextImportOptionsDlg::isDateConversionSet() const +{ + return maBtnConvertDate.IsChecked(); +} + +void ScTextImportOptionsDlg::init() +{ + Link aLink = LINK( this, ScTextImportOptionsDlg, OKHdl ); + maBtnOk.SetClickHdl(aLink); + aLink = LINK( this, ScTextImportOptionsDlg, RadioHdl ); + maRbAutomatic.SetClickHdl(aLink); + maRbCustom.SetClickHdl(aLink); + + maRbAutomatic.Check(true); + + maLbCustomLang.SetLanguageList( + LANG_LIST_ALL | LANG_LIST_ONLY_KNOWN, false, false); + + LanguageType eLang = Application::GetSettings().GetLanguage(); + maLbCustomLang.SelectLanguage(eLang); + maLbCustomLang.Disable(); +} + +IMPL_LINK( ScTextImportOptionsDlg, OKHdl, OKButton*, EMPTYARG ) +{ + EndDialog(RET_OK); + return 0; +} + +IMPL_LINK( ScTextImportOptionsDlg, RadioHdl, RadioButton*, pBtn ) +{ + if (pBtn == &maRbAutomatic) + { + maLbCustomLang.Disable(); + } + else if (pBtn == &maRbCustom) + { + maLbCustomLang.Enable(); + } + return 0; +} + diff --git a/sc/source/ui/dbgui/textimportoptions.src b/sc/source/ui/dbgui/textimportoptions.src new file mode 100644 index 000000000000..fff3c4b40749 --- /dev/null +++ b/sc/source/ui/dbgui/textimportoptions.src @@ -0,0 +1,112 @@ +/************************************************************************* + * + * 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: retypepassdlg.src,v $ + * $Revision: 1.1.2.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. + * + ************************************************************************/ + +#include "textimportoptions.hrc" + +ModalDialog RID_SCDLG_TEXT_IMPORT_OPTIONS +{ + Text [ en-US ] = "Import Options" ; + Size = MAP_APPFONT ( 190 , 101 ) ; + Moveable = TRUE ; + Closeable = TRUE ; + OutputSize = TRUE ; + + OKButton BTN_OK + { + Pos = MAP_APPFONT ( 135, 6 ) ; + Size = MAP_APPFONT ( 50, 14 ) ; + DefButton = TRUE ; + }; + + CancelButton BTN_CANCEL + { + Pos = MAP_APPFONT ( 135, 23 ) ; + Size = MAP_APPFONT ( 50, 14 ) ; + }; + + HelpButton BTN_HELP + { + Pos = MAP_APPFONT ( 135, 43 ) ; + Size = MAP_APPFONT ( 50, 14 ) ; + }; + + FixedLine FL_CHOOSE_LANG + { + Pos = MAP_APPFONT( 6, 3 ) ; + Size = MAP_APPFONT( 125, 14 ) ; + + Text [ en-US ] = "Select the language to use for import" ; + }; + + RadioButton RB_AUTOMATIC + { + Pos = MAP_APPFONT( 12, 20 ) ; + Size = MAP_APPFONT( 50, 10 ) ; + TabStop = TRUE ; + + Text [ en-US ] = "Automatic" ; + }; + + RadioButton RB_CUSTOM + { + Pos = MAP_APPFONT( 12, 34 ) ; + Size = MAP_APPFONT( 50, 10 ) ; + TabStop = TRUE ; + + Text [ en-US ] = "Custom" ; + }; + + ListBox LB_CUSTOM_LANG + { + Pos = MAP_APPFONT( 20, 50 ) ; + Size = MAP_APPFONT( 100, 55 ) ; + TabStop = TRUE ; + DropDown = TRUE ; + Sort = TRUE ; + }; + + FixedLine FL_OPTION + { + Pos = MAP_APPFONT( 6, 70 ); + Size = MAP_APPFONT( 125, 14 ); + + Text [ en-US ] = "Options" ; + }; + + CheckBox BTN_CONVERT_DATE + { + Pos = MAP_APPFONT( 12, 86 ); + Size = MAP_APPFONT( 125, 10 ); + TabStop = TRUE ; + + Text [ en-US ] = "Detect special numbers (such as dates)." ; + }; +}; + diff --git a/sc/source/ui/docshell/dbdocimp.cxx b/sc/source/ui/docshell/dbdocimp.cxx index 17b07099a491..be856ec9240b 100644 --- a/sc/source/ui/docshell/dbdocimp.cxx +++ b/sc/source/ui/docshell/dbdocimp.cxx @@ -69,7 +69,7 @@ using namespace com::sun::star; #define SC_SERVICE_ROWSET "com.sun.star.sdb.RowSet" -#define SC_SERVICE_INTHANDLER "com.sun.star.sdb.InteractionHandler" +#define SC_SERVICE_INTHANDLER "com.sun.star.task.InteractionHandler" //! move to a header file? #define SC_DBPROP_DATASOURCENAME "DataSourceName" @@ -86,7 +86,7 @@ void ScDBDocFunc::ShowInBeamer( const ScImportParam& rParam, SfxViewFrame* pFram if ( !pFrame || !rParam.bImport ) return; - uno::Reference<frame::XFrame> xFrame = pFrame->GetFrame()->GetFrameInterface(); + uno::Reference<frame::XFrame> xFrame = pFrame->GetFrame().GetFrameInterface(); uno::Reference<frame::XDispatchProvider> xDP(xFrame, uno::UNO_QUERY); uno::Reference<frame::XFrame> xBeamerFrame = xFrame->findFrame( diff --git a/sc/source/ui/docshell/docsh.cxx b/sc/source/ui/docshell/docsh.cxx index 1b4f9b677f81..821b2a6ad880 100644 --- a/sc/source/ui/docshell/docsh.cxx +++ b/sc/source/ui/docshell/docsh.cxx @@ -57,7 +57,6 @@ #include <sfx2/fcontnr.hxx> #include <sfx2/evntconf.hxx> #include <sfx2/sfx.hrc> -#include <sfx2/topfrm.hxx> #include <sfx2/objface.hxx> #include <svl/srchitem.hxx> #include <unotools/fltrcfg.hxx> @@ -127,6 +126,8 @@ #include <basic/sbstar.hxx> #include <basic/basmgr.hxx> using namespace com::sun::star; +using ::rtl::OUString; +using ::rtl::OUStringBuffer; // STATIC DATA ----------------------------------------------------------- @@ -817,6 +818,34 @@ BOOL __EXPORT ScDocShell::LoadFrom( SfxMedium& rMedium ) return bRet; } +static void lcl_parseHtmlFilterOption(const OUString& rOption, LanguageType& rLang, bool& rDateConvert) +{ + OUStringBuffer aBuf; + OUString aTokens[2]; + sal_Int32 n = rOption.getLength(); + const sal_Unicode* p = rOption.getStr(); + sal_Int32 nTokenId = 0; + for (sal_Int32 i = 0; i < n; ++i) + { + const sal_Unicode c = p[i]; + if (c == sal_Unicode(' ')) + { + if (aBuf.getLength()) + aTokens[nTokenId++] = aBuf.makeStringAndClear(); + } + else + aBuf.append(c); + + if (nTokenId >= 2) + break; + } + + if (aBuf.getLength()) + aTokens[nTokenId] = aBuf.makeStringAndClear(); + + rLang = static_cast<LanguageType>(aTokens[0].toInt32()); + rDateConvert = static_cast<bool>(aTokens[1].toInt32()); +} BOOL __EXPORT ScDocShell::ConvertFrom( SfxMedium& rMedium ) { @@ -1190,12 +1219,24 @@ BOOL __EXPORT ScDocShell::ConvertFrom( SfxMedium& rMedium ) SvStream* pInStream = rMedium.GetInStream(); if (pInStream) { + LanguageType eLang = LANGUAGE_SYSTEM; + bool bDateConvert = false; + SfxItemSet* pSet = rMedium.GetItemSet(); + const SfxPoolItem* pItem; + if ( pSet && SFX_ITEM_SET == + pSet->GetItemState( SID_FILE_FILTEROPTIONS, TRUE, &pItem ) ) + { + String aFilterOption = (static_cast<const SfxStringItem*>(pItem))->GetValue(); + lcl_parseHtmlFilterOption(aFilterOption, eLang, bDateConvert); + } + pInStream->Seek( 0 ); ScRange aRange; // HTML macht eigenes ColWidth/RowHeight CalcOutputFactor(); + SvNumberFormatter aNumFormatter(aDocument.GetServiceManager(), eLang); eError = ScFormatFilter::Get().ScImportHTML( *pInStream, rMedium.GetBaseURL(), &aDocument, aRange, - GetOutputFactor(), !bWebQuery ); + GetOutputFactor(), !bWebQuery, &aNumFormatter, bDateConvert ); if (eError != eERR_OK) { if (!GetError()) @@ -2114,7 +2155,7 @@ USHORT __EXPORT ScDocShell::PrepareClose( BOOL bUI, BOOL bForBrowsing ) { if(SC_MOD()->GetCurRefDlgId()>0) { - SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this, TYPE(SfxTopViewFrame) ); + SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this ); if( pFrame ) { SfxViewShell* p = pFrame->GetViewShell(); @@ -2162,6 +2203,11 @@ String ScDocShell::GetOwnFilterName() // static return String::CreateFromAscii(pFilterSc50); } +String ScDocShell::GetHtmlFilterName() +{ + return String::CreateFromAscii(pFilterHtml); +} + String ScDocShell::GetWebQueryFilterName() // static { return String::CreateFromAscii(pFilterHtmlWebQ); @@ -2261,22 +2307,19 @@ ScDocShell::ScDocShell( const ScDocShell& rShell ) //------------------------------------------------------------------ -ScDocShell::ScDocShell( SfxObjectCreateMode eMode, const bool _bScriptSupport ) - : SfxObjectShell( eMode ), - __SCDOCSHELL_INIT +ScDocShell::ScDocShell( const sal_uInt64 i_nSfxCreationFlags ) + : SfxObjectShell( i_nSfxCreationFlags ) + , __SCDOCSHELL_INIT { RTL_LOGFILE_CONTEXT_AUTHOR ( aLog, "sc", "nn93723", "ScDocShell::ScDocShell" ); SetPool( &SC_MOD()->GetPool() ); - bIsInplace = (eMode == SFX_CREATE_MODE_EMBEDDED); + bIsInplace = (GetCreateMode() == SFX_CREATE_MODE_EMBEDDED); // wird zurueckgesetzt, wenn nicht inplace pDocFunc = new ScDocFunc(*this); - if ( !_bScriptSupport ) - SetHasNoBasic(); - // SetBaseModel needs exception handling ScModelObj::CreateAndSet( this ); diff --git a/sc/source/ui/docshell/docsh4.cxx b/sc/source/ui/docshell/docsh4.cxx index 97403008915d..26d61a82c6be 100644 --- a/sc/source/ui/docshell/docsh4.cxx +++ b/sc/source/ui/docshell/docsh4.cxx @@ -53,7 +53,6 @@ using namespace ::com::sun::star; #include <sfx2/printer.hxx> #include <sfx2/request.hxx> #include <svtools/sfxecode.hxx> -#include <sfx2/topfrm.hxx> #include <svx/ofaitem.hxx> #include <sot/formats.hxx> #include <svtools/printdlg.hxx> @@ -2561,7 +2560,7 @@ ScTabViewShell* ScDocShell::GetBestViewShell( BOOL bOnlyVisible ) if( !pViewSh ) { // 1. ViewShell suchen - SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this, TYPE(SfxTopViewFrame), bOnlyVisible ); + SfxViewFrame* pFrame = SfxViewFrame::GetFirst( this, bOnlyVisible ); if( pFrame ) { SfxViewShell* p = pFrame->GetViewShell(); diff --git a/sc/source/ui/docshell/impex.cxx b/sc/source/ui/docshell/impex.cxx index 8fc49696ba59..46b6b7af3a63 100644 --- a/sc/source/ui/docshell/impex.cxx +++ b/sc/source/ui/docshell/impex.cxx @@ -902,12 +902,11 @@ BOOL ScImportExport::Text2Doc( SvStream& rStrm ) // -bool lcl_PutString( ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab, - const String& rStr, BYTE nColFormat, - ::utl::TransliterationWrapper& rTransliteration, - CalendarWrapper& rCalendar, - ::utl::TransliterationWrapper* pSecondTransliteration, - CalendarWrapper* pSecondCalendar ) +static bool lcl_PutString( + ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab, const String& rStr, BYTE nColFormat, + SvNumberFormatter* pFormatter, bool bDetectNumFormat, + ::utl::TransliterationWrapper& rTransliteration, CalendarWrapper& rCalendar, + ::utl::TransliterationWrapper* pSecondTransliteration, CalendarWrapper* pSecondCalendar ) { bool bMultiLine = false; if ( nColFormat == SC_COL_SKIP || !rStr.Len() || !ValidCol(nCol) || !ValidRow(nRow) ) @@ -923,10 +922,10 @@ bool lcl_PutString( ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab, { //! SetString mit Extra-Flag ??? - SvNumberFormatter* pFormatter = pDoc->GetFormatTable(); - sal_uInt32 nEnglish = pFormatter->GetStandardIndex(LANGUAGE_ENGLISH_US); + SvNumberFormatter* pDocFormatter = pDoc->GetFormatTable(); + sal_uInt32 nEnglish = pDocFormatter->GetStandardIndex(LANGUAGE_ENGLISH_US); double fVal; - if ( pFormatter->IsNumberFormat( rStr, nEnglish, fVal ) ) + if ( pDocFormatter->IsNumberFormat( rStr, nEnglish, fVal ) ) { // Zahlformat wird nicht auf englisch gesetzt pDoc->SetValue( nCol, nRow, nTab, fVal ); @@ -1062,9 +1061,9 @@ bool lcl_PutString( ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab, } } - SvNumberFormatter* pFormatter = pDoc->GetFormatTable(); + SvNumberFormatter* pDocFormatter = pDoc->GetFormatTable(); if ( nYear < 100 ) - nYear = pFormatter->ExpandTwoDigitYear( nYear ); + nYear = pDocFormatter->ExpandTwoDigitYear( nYear ); CalendarWrapper* pCalendar = (bSecondCal ? pSecondCalendar : &rCalendar); sal_Int16 nNumMonths = pCalendar->getNumberOfMonthsInYear(); @@ -1100,7 +1099,7 @@ bool lcl_PutString( ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab, pCalendar->setValue( i18n::CalendarFieldIndex::MILLISECOND, nMilli ); if ( pCalendar->isValid() ) { - double fDiff = DateTime(*pFormatter->GetNullDate()) - + double fDiff = DateTime(*pDocFormatter->GetNullDate()) - pCalendar->getEpochStart(); // #i14974# must use getLocalDateTime to get the same // date values as set above @@ -1112,10 +1111,10 @@ bool lcl_PutString( ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab, LanguageType eDocLang = eLatin; //! which language for date formats? short nType = (nFound > 3 ? NUMBERFORMAT_DATETIME : NUMBERFORMAT_DATE); - ULONG nFormat = pFormatter->GetStandardFormat( nType, eDocLang ); + ULONG nFormat = pDocFormatter->GetStandardFormat( nType, eDocLang ); // maybe there is a special format including seconds or milliseconds if (nFound > 5) - nFormat = pFormatter->GetStandardFormat( fDays, nFormat, nType, eDocLang); + nFormat = pDocFormatter->GetStandardFormat( fDays, nFormat, nType, eDocLang); pDoc->PutCell( nCol, nRow, nTab, new ScValueCell(fDays), nFormat, FALSE ); @@ -1127,7 +1126,7 @@ bool lcl_PutString( ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab, // Standard or date not determined -> SetString / EditCell if( rStr.Search( _LF ) == STRING_NOTFOUND ) - pDoc->SetString( nCol, nRow, nTab, rStr ); + pDoc->SetString( nCol, nRow, nTab, rStr, pFormatter, bDetectNumFormat ); else { bMultiLine = true; @@ -1137,7 +1136,7 @@ bool lcl_PutString( ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab, } -String lcl_GetFixed( const String& rLine, xub_StrLen nStart, xub_StrLen nNext ) +String lcl_GetFixed( const String& rLine, xub_StrLen nStart, xub_StrLen nNext, bool& rbIsQuoted ) { xub_StrLen nLen = rLine.Len(); if (nNext > nLen) @@ -1151,7 +1150,11 @@ String lcl_GetFixed( const String& rLine, xub_StrLen nStart, xub_StrLen nNext ) while ( nSpace > nStart && pStr[nSpace-1] == ' ' ) --nSpace; - return rLine.Copy( nStart, nSpace-nStart ); + rbIsQuoted = (pStr[nStart] == sal_Unicode('"') && pStr[nSpace-1] == sal_Unicode('"')); + if (rbIsQuoted) + return rLine.Copy(nStart+1, nSpace-nStart-2); + else + return rLine.Copy(nStart, nSpace-nStart); } BOOL ScImportExport::ExtText2Doc( SvStream& rStrm ) @@ -1184,9 +1187,9 @@ BOOL ScImportExport::ExtText2Doc( SvStream& rStrm ) const BYTE* pColFormat = pExtOptions->GetColFormat(); long nSkipLines = pExtOptions->GetStartRow(); - LanguageType eLatin, eCjk, eCtl; - pDoc->GetLanguage( eLatin, eCjk, eCtl ); - LanguageType eDocLang = eLatin; //! which language for date formats? + LanguageType eDocLang = pExtOptions->GetLanguage(); + SvNumberFormatter aNumFormatter(pDoc->GetServiceManager(), eDocLang); + bool bDetectNumFormat = pExtOptions->IsDetectSpecialNumber(); // For date recognition ::utl::TransliterationWrapper aTransliteration( @@ -1228,6 +1231,8 @@ BOOL ScImportExport::ExtText2Doc( SvStream& rStrm ) // survives the toggle of bDetermineRange down at the end of the do{} loop. bool bRangeIsDetermined = bDetermineRange; + bool bQuotedAsText = pExtOptions && pExtOptions->IsQuotedAsText(); + ULONG nOriginalStreamPos = rStrm.Tell(); do @@ -1249,7 +1254,8 @@ BOOL ScImportExport::ExtText2Doc( SvStream& rStrm ) // SC_COL_SKIP. for ( i=0; i<nInfoCount && nCol <= MAXCOL+1; i++ ) { - if ( pColFormat[i] != SC_COL_SKIP ) // sonst auch nCol nicht hochzaehlen + BYTE nFmt = pColFormat[i]; + if (nFmt != SC_COL_SKIP) // sonst auch nCol nicht hochzaehlen { if (nCol > MAXCOL) bOverflow = TRUE; // display warning on import @@ -1257,11 +1263,15 @@ BOOL ScImportExport::ExtText2Doc( SvStream& rStrm ) { xub_StrLen nStart = pColStart[i]; xub_StrLen nNext = ( i+1 < nInfoCount ) ? pColStart[i+1] : nLineLen; - aCell = lcl_GetFixed( aLine, nStart, nNext ); - bMultiLine |= lcl_PutString( pDoc, nCol, nRow, - nTab, aCell, pColFormat[i], - aTransliteration, aCalendar, - pEnglishTransliteration, pEnglishCalendar); + bool bIsQuoted = false; + aCell = lcl_GetFixed( aLine, nStart, nNext, bIsQuoted ); + if (bIsQuoted && bQuotedAsText) + nFmt = SC_COL_TEXT; + + bMultiLine |= lcl_PutString( + pDoc, nCol, nRow, nTab, aCell, nFmt, + &aNumFormatter, bDetectNumFormat, aTransliteration, aCalendar, + pEnglishTransliteration, pEnglishCalendar); } ++nCol; } @@ -1278,7 +1288,8 @@ BOOL ScImportExport::ExtText2Doc( SvStream& rStrm ) // SC_COL_SKIP. while (*p && nCol <= MAXCOL+1) { - p = ScImportExport::ScanNextFieldFromString( p, aCell, cStr, pSeps, bMerge ); + bool bIsQuoted = false; + p = ScImportExport::ScanNextFieldFromString( p, aCell, cStr, pSeps, bMerge, bIsQuoted ); BYTE nFmt = SC_COL_STANDARD; for ( i=nInfoStart; i<nInfoCount; i++ ) @@ -1295,10 +1306,15 @@ BOOL ScImportExport::ExtText2Doc( SvStream& rStrm ) if (nCol > MAXCOL) bOverflow = TRUE; // display warning on import else if (!bDetermineRange) - bMultiLine |= lcl_PutString( pDoc, nCol, nRow, - nTab, aCell, nFmt, aTransliteration, - aCalendar, pEnglishTransliteration, - pEnglishCalendar); + { + if (bIsQuoted && bQuotedAsText) + nFmt = SC_COL_TEXT; + + bMultiLine |= lcl_PutString( + pDoc, nCol, nRow, nTab, aCell, nFmt, + &aNumFormatter, bDetectNumFormat, aTransliteration, + aCalendar, pEnglishTransliteration, pEnglishCalendar); + } ++nCol; } @@ -1372,11 +1388,13 @@ BOOL ScImportExport::ExtText2Doc( SvStream& rStrm ) // static const sal_Unicode* ScImportExport::ScanNextFieldFromString( const sal_Unicode* p, - String& rField, sal_Unicode cStr, const sal_Unicode* pSeps, BOOL bMergeSeps ) + String& rField, sal_Unicode cStr, const sal_Unicode* pSeps, bool bMergeSeps, bool& rbIsQuoted ) { + rbIsQuoted = false; rField.Erase(); if ( *p == cStr ) // String in Anfuehrungszeichen { + rbIsQuoted = true; const sal_Unicode* p1; p1 = p = lcl_ScanString( p, rField, cStr, DQM_ESCAPE ); while ( *p && !ScGlobal::UnicodeStrChr( pSeps, *p ) ) @@ -2035,7 +2053,7 @@ class ScFormatFilterMissing : public ScFormatFilterPlugin { virtual FltError ScImportDif( SvStream&, ScDocument*, const ScAddress&, const CharSet, UINT32 ) RETURN_ERROR virtual FltError ScImportRTF( SvStream&, const String&, ScDocument*, ScRange& ) RETURN_ERROR - virtual FltError ScImportHTML( SvStream&, const String&, ScDocument*, ScRange&, double, BOOL ) RETURN_ERROR + virtual FltError ScImportHTML( SvStream&, const String&, ScDocument*, ScRange&, double, BOOL, SvNumberFormatter*, bool ) RETURN_ERROR virtual ScEEAbsImport *CreateRTFImport( ScDocument*, const ScRange& ) { return NULL; } virtual ScEEAbsImport *CreateHTMLImport( ScDocument*, const String&, const ScRange&, BOOL ) { return NULL; } diff --git a/sc/source/ui/drawfunc/drawsh.cxx b/sc/source/ui/drawfunc/drawsh.cxx index b44c396f4e0c..e2f70432d679 100644 --- a/sc/source/ui/drawfunc/drawsh.cxx +++ b/sc/source/ui/drawfunc/drawsh.cxx @@ -335,7 +335,7 @@ void ScDrawShell::ExecuteMacroAssign( SdrObject* pObj, Window* pWin ) com::sun::star::uno::Reference < com::sun::star::frame::XFrame > xFrame; if (GetViewShell()) - xFrame = GetViewShell()->GetViewFrame()->GetFrame()->GetFrameInterface(); + xFrame = GetViewShell()->GetViewFrame()->GetFrame().GetFrameInterface(); SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create(); SfxAbstractDialog* pMacroDlg = pFact->CreateSfxDialog( pWin, *pItemSet, xFrame, SID_EVENTCONFIG ); diff --git a/sc/source/ui/drawfunc/fudraw.cxx b/sc/source/ui/drawfunc/fudraw.cxx index 3a3fc833a515..bad23bf26ed1 100644 --- a/sc/source/ui/drawfunc/fudraw.cxx +++ b/sc/source/ui/drawfunc/fudraw.cxx @@ -310,7 +310,7 @@ BOOL __EXPORT FuDraw::KeyInput(const KeyEvent& rKEvt) const SdrMarkList& rMarkList = pView->GetMarkedObjectList(); if( !pView->IsTextEdit() && 1 == rMarkList.GetMarkCount() ) { - BOOL bOle = pViewShell->GetViewFrame()->GetFrame()->IsInPlace(); + BOOL bOle = pViewShell->GetViewFrame()->GetFrame().IsInPlace(); SdrObject* pObj = rMarkList.GetMark( 0 )->GetMarkedSdrObj(); if( pObj && pObj->ISA( SdrOle2Obj ) && !bOle ) { diff --git a/sc/source/ui/drawfunc/fuins2.cxx b/sc/source/ui/drawfunc/fuins2.cxx index e0721fc47f50..f648a1484e8e 100644 --- a/sc/source/ui/drawfunc/fuins2.cxx +++ b/sc/source/ui/drawfunc/fuins2.cxx @@ -526,7 +526,8 @@ FuInsertChart::FuInsertChart(ScTabViewShell* pViewSh, Window* pWin, ScDrawView* ScRangeList aRanges; aMultiMark.FillRangeListWithMarks( &aRanges, FALSE ); String aStr; - aRanges.Format( aStr, SCR_ABS_3D, pViewSh->GetViewData()->GetDocument() ); + ScDocument* pDocument = pViewSh->GetViewData()->GetDocument(); + aRanges.Format( aStr, SCR_ABS_3D, pDocument, pDocument->GetAddressConvention() ); aRangeString = aStr; // get "total" range for positioning diff --git a/sc/source/ui/drawfunc/fusel.cxx b/sc/source/ui/drawfunc/fusel.cxx index 213169b8b9fd..4a456522003c 100644 --- a/sc/source/ui/drawfunc/fusel.cxx +++ b/sc/source/ui/drawfunc/fusel.cxx @@ -390,7 +390,7 @@ BOOL __EXPORT FuSelection::MouseButtonUp(const MouseEvent& rMEvt) BOOL bReturn = FuDraw::MouseButtonUp(rMEvt); // BOOL bOle = pViewShell->GetViewData()->IsOle(); - BOOL bOle = pViewShell->GetViewFrame()->GetFrame()->IsInPlace(); + BOOL bOle = pViewShell->GetViewFrame()->GetFrame().IsInPlace(); if (aDragTimer.IsActive() ) { diff --git a/sc/source/ui/formdlg/formula.cxx b/sc/source/ui/formdlg/formula.cxx index d9add14952a4..2d9cdef1b54e 100644 --- a/sc/source/ui/formdlg/formula.cxx +++ b/sc/source/ui/formdlg/formula.cxx @@ -40,7 +40,6 @@ #include <svl/stritem.hxx> #include <svtools/svtreebx.hxx> #include <sfx2/viewfrm.hxx> -#include <sfx2/topfrm.hxx> #include <vcl/svapp.hxx> #include <vcl/mnemonic.hxx> #include <unotools/charclass.hxx> @@ -308,7 +307,7 @@ ScInputHandler* ScFormulaDlg::GetNextInputHandler(ScDocShell* pDocShell,PtrTabVi { ScInputHandler* pHdl=NULL; - SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pDocShell, TYPE(SfxTopViewFrame) ); + SfxViewFrame* pFrame = SfxViewFrame::GetFirst( pDocShell ); while( pFrame && pHdl==NULL) { SfxViewShell* p = pFrame->GetViewShell(); @@ -318,7 +317,7 @@ ScInputHandler* ScFormulaDlg::GetNextInputHandler(ScDocShell* pDocShell,PtrTabVi pHdl=pViewSh->GetInputHandler(); if(ppViewSh!=NULL) *ppViewSh=pViewSh; } - pFrame = SfxViewFrame::GetNext(*pFrame,pDocShell, TYPE(SfxTopViewFrame) ); + pFrame = SfxViewFrame::GetNext( *pFrame, pDocShell ); } diff --git a/sc/source/ui/inc/asciiopt.hxx b/sc/source/ui/inc/asciiopt.hxx index aee63d682a26..a5c7a2b554b4 100644 --- a/sc/source/ui/inc/asciiopt.hxx +++ b/sc/source/ui/inc/asciiopt.hxx @@ -52,7 +52,7 @@ #include <tools/stream.hxx> #include <svx/txencbox.hxx> #include "csvtablebox.hxx" - +#include "i18npool/lang.h" // ============================================================================ @@ -62,8 +62,11 @@ private: BOOL bFixedLen; String aFieldSeps; BOOL bMergeFieldSeps; + bool bQuotedFieldAsText; + bool bDetectSpecialNumber; sal_Unicode cTextSep; CharSet eCharSet; + LanguageType eLang; BOOL bCharSetSystem; long nStartRow; USHORT nInfoCount; @@ -90,20 +93,26 @@ public: BOOL GetCharSetSystem() const { return bCharSetSystem; } const String& GetFieldSeps() const { return aFieldSeps; } BOOL IsMergeSeps() const { return bMergeFieldSeps; } + bool IsQuotedAsText() const { return bQuotedFieldAsText; } + bool IsDetectSpecialNumber() const { return bDetectSpecialNumber; } sal_Unicode GetTextSep() const { return cTextSep; } BOOL IsFixedLen() const { return bFixedLen; } USHORT GetInfoCount() const { return nInfoCount; } const xub_StrLen* GetColStart() const { return pColStart; } const BYTE* GetColFormat() const { return pColFormat; } long GetStartRow() const { return nStartRow; } + LanguageType GetLanguage() const { return eLang; } void SetCharSet( CharSet eNew ) { eCharSet = eNew; } void SetCharSetSystem( BOOL bSet ) { bCharSetSystem = bSet; } void SetFixedLen( BOOL bSet ) { bFixedLen = bSet; } void SetFieldSeps( const String& rStr ) { aFieldSeps = rStr; } void SetMergeSeps( BOOL bSet ) { bMergeFieldSeps = bSet; } + void SetQuotedAsText(bool bSet) { bQuotedFieldAsText = bSet; } + void SetDetectSpecialNumber(bool bSet) { bDetectSpecialNumber = bSet; } void SetTextSep( sal_Unicode c ) { cTextSep = c; } void SetStartRow( long nRow) { nStartRow= nRow; } + void SetLanguage(LanguageType e) { eLang = e; } void SetColInfo( USHORT nCount, const xub_StrLen* pStart, const BYTE* pFormat ); void SetColumnInfo( const ScCsvExpDataVec& rDataVec ); diff --git a/sc/source/ui/inc/csvruler.hxx b/sc/source/ui/inc/csvruler.hxx index 5ddeb1f1ceba..52be4b4ebd8c 100644 --- a/sc/source/ui/inc/csvruler.hxx +++ b/sc/source/ui/inc/csvruler.hxx @@ -68,6 +68,7 @@ private: // ------------------------------------------------------------------------ public: explicit ScCsvRuler( ScCsvControl& rParent ); + ~ScCsvRuler(); // common ruler handling -------------------------------------------------- public: diff --git a/sc/source/ui/inc/dbfunc.hxx b/sc/source/ui/inc/dbfunc.hxx index 87df03b8ecd9..be206b396733 100644 --- a/sc/source/ui/inc/dbfunc.hxx +++ b/sc/source/ui/inc/dbfunc.hxx @@ -53,7 +53,7 @@ private: public: ScDBFunc( Window* pParent, ScDocShell& rDocSh, ScTabViewShell* pViewShell ); //UNUSED2008-05 ScDBFunc( Window* pParent, const ScDBFunc& rDBFunc, ScTabViewShell* pViewShell ); - ~ScDBFunc(); + virtual ~ScDBFunc(); // nur UISort wiederholt bei Bedarf die Teilergebnisse @@ -86,8 +86,10 @@ public: bool MakePivotTable( const ScDPSaveData& rData, const ScRange& rDest, BOOL bNewTable, const ScDPObject& rSource, BOOL bApi = FALSE ); void DeletePivotTable(); - void RecalcPivotTable(); - + // Wang Xu Ming -- 2009-6-17 + // DataPilot Migration + ULONG RecalcPivotTable(); + // End Comments BOOL HasSelectionForDateGroup( ScDPNumGroupInfo& rOldInfo, sal_Int32& rParts ); BOOL HasSelectionForNumGroup( ScDPNumGroupInfo& rOldInfo ); void GroupDataPilot(); diff --git a/sc/source/ui/inc/docsh.hxx b/sc/source/ui/inc/docsh.hxx index da5e5e7ffbff..88bbeb699539 100644 --- a/sc/source/ui/inc/docsh.hxx +++ b/sc/source/ui/inc/docsh.hxx @@ -31,10 +31,8 @@ #include <sfx2/objsh.hxx> -//REMOVE #ifndef _SFX_INTERNO_HXX //autogen -//REMOVE #include <sfx2/interno.hxx> -//REMOVE #endif #include <sfx2/docfac.hxx> +#include <sfx2/sfxmodelfactory.hxx> #include <sfx2/viewsh.hxx> #include "scdllapi.h" @@ -179,7 +177,7 @@ public: SFX_DECL_OBJECTFACTORY(); ScDocShell( const ScDocShell& rDocShell ); - ScDocShell( SfxObjectCreateMode eMode = SFX_CREATE_MODE_EMBEDDED, const bool _bScriptSupport = true ); + ScDocShell( const sal_uInt64 i_nSfxCreationFlags = SFXMODEL_EMBEDDED_OBJECT ); ~ScDocShell(); using SotObject::GetInterface; @@ -399,6 +397,7 @@ public: static ScDocShell* GetShellByNum( USHORT nDocNo ); static String GetOwnFilterName(); + static String GetHtmlFilterName(); static String GetWebQueryFilterName(); static String GetAsciiFilterName(); static String GetLotusFilterName(); diff --git a/sc/source/ui/inc/fieldwnd.hxx b/sc/source/ui/inc/fieldwnd.hxx index 45a573e72157..539dbe54e275 100644..100755 --- a/sc/source/ui/inc/fieldwnd.hxx +++ b/sc/source/ui/inc/fieldwnd.hxx @@ -34,7 +34,6 @@ #include <vcl/fixed.hxx> #include <cppuhelper/weakref.hxx> -#define MAX_LABELS 256 #define PAGE_SIZE 16 // count of visible fields for scrollbar #define LINE_SIZE 8 // count of fields per column for scrollbar #define MAX_FIELDS 8 // maximum count of fields for row/col/data area diff --git a/sc/source/ui/inc/gridwin.hxx b/sc/source/ui/inc/gridwin.hxx index 0f8e479f6e54..149498a8314d 100644 --- a/sc/source/ui/inc/gridwin.hxx +++ b/sc/source/ui/inc/gridwin.hxx @@ -273,7 +273,7 @@ private: void PasteSelection( const Point& rPosPixel ); - void SelectForContextMenu( const Point& rPosPixel ); + void SelectForContextMenu( const Point& rPosPixel, SCsCOL nCellX, SCsROW nCellY ); void GetSelectionRects( ::std::vector< Rectangle >& rPixelRects ); diff --git a/sc/source/ui/inc/hdrcont.hxx b/sc/source/ui/inc/hdrcont.hxx index 02a4df09afd2..ec4dd49705d1 100644 --- a/sc/source/ui/inc/hdrcont.hxx +++ b/sc/source/ui/inc/hdrcont.hxx @@ -77,7 +77,7 @@ private: long GetScrPos( SCCOLROW nEntryNo ); SCCOLROW GetMousePos( const MouseEvent& rMEvt, BOOL& rBorder ); - + bool IsSelectionAllowed(SCCOLROW nPos) const; void ShowDragHelp(); void DoPaint( SCCOLROW nStart, SCCOLROW nEnd ); diff --git a/sc/source/ui/inc/impex.hxx b/sc/source/ui/inc/impex.hxx index fe4177df7cae..86a91216edcc 100644 --- a/sc/source/ui/inc/impex.hxx +++ b/sc/source/ui/inc/impex.hxx @@ -107,7 +107,7 @@ public: static BOOL IsFormatSupported( ULONG nFormat ); static const sal_Unicode* ScanNextFieldFromString( const sal_Unicode* p, - String& rField, sal_Unicode cStr, const sal_Unicode* pSeps, BOOL bMergeSeps ); + String& rField, sal_Unicode cStr, const sal_Unicode* pSeps, bool bMergeSeps, bool& rbIsQuoted ); static void WriteUnicodeOrByteString( SvStream& rStrm, const String& rString, BOOL bZero = FALSE ); static void WriteUnicodeOrByteEndl( SvStream& rStrm ); static inline BOOL IsEndianSwap( const SvStream& rStrm ); diff --git a/sc/source/ui/inc/scuiasciiopt.hxx b/sc/source/ui/inc/scuiasciiopt.hxx index a1f73458c3a0..3e1a7db38fb2 100644 --- a/sc/source/ui/inc/scuiasciiopt.hxx +++ b/sc/source/ui/inc/scuiasciiopt.hxx @@ -32,6 +32,8 @@ #include "asciiopt.hxx" +#include "svx/langbox.hxx" + // ============================================================================ class ScImportAsciiDlg : public ModalDialog @@ -46,6 +48,8 @@ class ScImportAsciiDlg : public ModalDialog FixedLine aFlFieldOpt; FixedText aFtCharSet; SvxTextEncodingBox aLbCharSet; + FixedText aFtCustomLang; + SvxLanguageBox aLbCustomLang; FixedText aFtRow; NumericField aNfRow; @@ -61,9 +65,15 @@ class ScImportAsciiDlg : public ModalDialog CheckBox aCkbOther; Edit aEdOther; CheckBox aCkbAsOnce; + + FixedLine aFlOtherOpt; + FixedText aFtTextSep; ComboBox aCbTextSep; + CheckBox aCkbQuotedAsText; + CheckBox aCkbDetectNumber; + FixedLine aFlWidth; FixedText aFtType; ListBox aLbType; @@ -84,6 +94,7 @@ class ScImportAsciiDlg : public ModalDialog CharSet meCharSet; /// Selected char set. bool mbCharSetSystem; /// Is System char set selected? + bool mbFileImport; /// Is this dialog involked for csv file import ? public: ScImportAsciiDlg( @@ -93,6 +104,7 @@ public: void GetOptions( ScAsciiOptions& rOpt ); void SetTextToColumnsMode(); + void SaveParameters(); private: /** Sets the selected char set data to meCharSet and mbCharSetSystem. */ diff --git a/sc/source/ui/inc/textimportoptions.hrc b/sc/source/ui/inc/textimportoptions.hrc new file mode 100644 index 000000000000..93c554ef5c45 --- /dev/null +++ b/sc/source/ui/inc/textimportoptions.hrc @@ -0,0 +1,42 @@ +/************************************************************************* + * + * 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: retypepassdlg.src,v $ + * $Revision: 1.1.2.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. + * + ************************************************************************/ + +#include <sc.hrc> + +#define BTN_OK 1 +#define BTN_CANCEL 2 +#define BTN_HELP 3 + +#define FL_CHOOSE_LANG 4 +#define RB_AUTOMATIC 5 +#define RB_CUSTOM 6 +#define LB_CUSTOM_LANG 7 +#define FL_OPTION 8 +#define BTN_CONVERT_DATE 9 diff --git a/sc/source/ui/inc/textimportoptions.hxx b/sc/source/ui/inc/textimportoptions.hxx new file mode 100644 index 000000000000..bbb2bf6ebf09 --- /dev/null +++ b/sc/source/ui/inc/textimportoptions.hxx @@ -0,0 +1,76 @@ +/************************************************************************* + * + * 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: langbox.hxx,v $ + * $Revision: 1.4.242.1 $ + * + * 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_UI_IMPORTOPTIONS_HXX +#define SC_UI_IMPORTOPTIONS_HXX + +#include "vcl/dialog.hxx" +#include "vcl/button.hxx" +#include "vcl/fixed.hxx" +#include "i18npool/lang.h" +#include "svx/langbox.hxx" + +class ScTextImportOptionsDlg : public ModalDialog +{ +public: + ScTextImportOptionsDlg(Window* pParent); + virtual ~ScTextImportOptionsDlg(); + + virtual short Execute(); + + LanguageType getLanguageType() const; + bool isDateConversionSet() const; + +private: + void init(); + +private: + OKButton maBtnOk; + CancelButton maBtnCancel; + HelpButton maBtnHelp; + + FixedLine maFlChooseLang; + + RadioButton maRbAutomatic; + RadioButton maRbCustom; + + SvxLanguageBox maLbCustomLang; + + FixedLine maFlOption; + + CheckBox maBtnConvertDate; + + DECL_LINK( OKHdl, OKButton* ); + + DECL_LINK( RadioHdl, RadioButton* ); +}; + + +#endif diff --git a/sc/source/ui/inc/ui_pch.hxx b/sc/source/ui/inc/ui_pch.hxx index ba0cd9dbd3ce..1ef2f02d405b 100644 --- a/sc/source/ui/inc/ui_pch.hxx +++ b/sc/source/ui/inc/ui_pch.hxx @@ -171,7 +171,6 @@ #include <svl/inethist.hxx> #include <svl/inetdef.hxx> #include <sfx2/sfxdefs.hxx> -#include <svl/cancel.hxx> #include <svtools/compat.hxx> #include <svl/inetmsg.hxx> #include <sfx2/app.hxx> diff --git a/sc/source/ui/miscdlgs/anyrefdg.cxx b/sc/source/ui/miscdlgs/anyrefdg.cxx index 30e34def4620..32b3376da9a7 100644 --- a/sc/source/ui/miscdlgs/anyrefdg.cxx +++ b/sc/source/ui/miscdlgs/anyrefdg.cxx @@ -39,7 +39,6 @@ #include <vcl/mnemonic.hxx> #include <tools/shl.hxx> #include <svtools/taskbar.hxx> -#include <sfx2/topfrm.hxx> #include <sfx2/bindings.hxx> #include <sfx2/dispatch.hxx> @@ -103,7 +102,7 @@ void ScFormulaReferenceHelper::enableInput( BOOL bEnable ) while( pFrame ) { // #71577# enable everything except InPlace, including bean frames - if ( !pFrame->GetFrame()->IsInPlace() ) + if ( !pFrame->GetFrame().IsInPlace() ) { SfxViewShell* p = pFrame->GetViewShell(); ScTabViewShell* pViewSh = PTR_CAST(ScTabViewShell,p); @@ -602,7 +601,7 @@ void ScFormulaReferenceHelper::EnableSpreadsheets(BOOL bFlag, BOOL bChilds) while( pFrame ) { // #71577# enable everything except InPlace, including bean frames - if ( !pFrame->GetFrame()->IsInPlace() ) + if ( !pFrame->GetFrame().IsInPlace() ) { SfxViewShell* p = pFrame->GetViewShell(); ScTabViewShell* pViewSh = PTR_CAST(ScTabViewShell,p); @@ -642,7 +641,7 @@ void lcl_InvalidateWindows() while( pFrame ) { // #71577# enable everything except InPlace, including bean frames - if ( !pFrame->GetFrame()->IsInPlace() ) + if ( !pFrame->GetFrame().IsInPlace() ) { SfxViewShell* p = pFrame->GetViewShell(); ScTabViewShell* pViewSh = PTR_CAST(ScTabViewShell,p); diff --git a/sc/source/ui/miscdlgs/autofmt.cxx b/sc/source/ui/miscdlgs/autofmt.cxx index 78e5ea066c7d..940856775c07 100644 --- a/sc/source/ui/miscdlgs/autofmt.cxx +++ b/sc/source/ui/miscdlgs/autofmt.cxx @@ -44,10 +44,10 @@ #include <editeng/shdditem.hxx> #include <editeng/udlnitem.hxx> #include <editeng/wghtitem.hxx> -#include <sfx2/topfrm.hxx> #include <vcl/svapp.hxx> #include <svl/zforlist.hxx> #include <vcl/msgbox.hxx> +#include <sfx2/viewfrm.hxx> #include <comphelper/processfactory.hxx> #include "sc.hrc" diff --git a/sc/source/ui/src/globstr.src b/sc/source/ui/src/globstr.src index edb2165daf32..b08676bbe3db 100644 --- a/sc/source/ui/src/globstr.src +++ b/sc/source/ui/src/globstr.src @@ -1722,5 +1722,17 @@ Resource RID_GLOBSTR { Text [ en-US ] = "Page Styles"; }; + String STR_ERR_DATAPILOTSOURCE + { + Text [ en-US ] = "DataPilot source data is invalid."; + }; + String STR_PIVOT_FIRSTROWEMPTYERR + { + Text [ en-US ] = "The field name cannot be empty. Check the first row of data source to make sure there are no empty cells." ; + }; + String STR_PIVOT_ONLYONEROWERR + { + Text [ en-US ] = "DataPilot table needs at least two rows of data to create or refresh." ; + }; }; diff --git a/sc/source/ui/undo/makefile.mk b/sc/source/ui/undo/makefile.mk index 168130c022ea..01edd92f8553 100644 --- a/sc/source/ui/undo/makefile.mk +++ b/sc/source/ui/undo/makefile.mk @@ -74,6 +74,8 @@ SLOFILES = \ $(SLO)$/undotab.obj EXCEPTIONSFILES= \ + $(SLO)$/undoblk3.obj \ + $(SLO)$/undocell.obj \ $(SLO)$/undostyl.obj # --- Tagets ------------------------------------------------------- diff --git a/sc/source/ui/unoobj/chartuno.cxx b/sc/source/ui/unoobj/chartuno.cxx index 5feabe72207d..201c411ea45c 100644 --- a/sc/source/ui/unoobj/chartuno.cxx +++ b/sc/source/ui/unoobj/chartuno.cxx @@ -480,20 +480,15 @@ void ScChartObj::GetData_Impl( ScRangeListRef& rRanges, bool& rColHeaders, bool& { bool bFound = false; ScDocument* pDoc = (pDocShell? pDocShell->GetDocument(): 0); - uno::Reference< embed::XEmbeddedObject > xIPObj; + if( pDoc ) - xIPObj.set( pDoc->FindOleObjectByName( aChartName ), uno::UNO_QUERY ); - if( xIPObj.is()) { - //make sure that the chart is loaded - svt::EmbeddedObjectRef::TryRunningState( xIPObj ); - - uno::Reference< chart2::XChartDocument > xChartDoc( xIPObj->getComponent(), uno::UNO_QUERY ); - uno::Reference< chart2::data::XDataReceiver > xReceiver( xChartDoc, uno::UNO_QUERY ); - if( xReceiver.is() ) + uno::Reference< chart2::XChartDocument > xChartDoc( pDoc->GetChartByName( aChartName ) ); + if( xChartDoc.is() ) { + uno::Reference< chart2::data::XDataReceiver > xReceiver( xChartDoc, uno::UNO_QUERY ); uno::Reference< chart2::data::XDataProvider > xProvider = xChartDoc->getDataProvider(); - if( xProvider.is() ) + if( xReceiver.is() && xProvider.is() ) { uno::Sequence< beans::PropertyValue > aArgs( xProvider->detectArguments( xReceiver->getUsedData() ) ); diff --git a/sc/source/ui/unoobj/dapiuno.cxx b/sc/source/ui/unoobj/dapiuno.cxx index ab94be3052e0..7e23d6b2f9f5 100644..100755 --- a/sc/source/ui/unoobj/dapiuno.cxx +++ b/sc/source/ui/unoobj/dapiuno.cxx @@ -1274,17 +1274,21 @@ CellRangeAddress SAL_CALL ScDataPilotTableObj::getOutputRange() throw(RuntimeExc return aRet; } +ULONG RefreshDPObject( ScDPObject *pDPObj, ScDocument *pDoc, ScDocShell *pDocSh, BOOL bRecord, BOOL bApi ); + void SAL_CALL ScDataPilotTableObj::refresh() throw(RuntimeException) { ScUnoGuard aGuard; - ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName); - if (pDPObj) - { - ScDPObject* pNew = new ScDPObject(*pDPObj); - ScDBDocFunc aFunc(*GetDocShell()); - aFunc.DataPilotUpdate( pDPObj, pNew, TRUE, TRUE ); - delete pNew; // DataPilotUpdate copies settings from "new" object - } + if( ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName) ) + RefreshDPObject( pDPObj, NULL, GetDocShell(), TRUE, TRUE ); + //if (pDPObj) + //{ + // ScDPObject* pNew = new ScDPObject(*pDPObj); + // ScDBDocFunc aFunc(*GetDocShell()); + // aFunc.DataPilotUpdate( pDPObj, pNew, TRUE, TRUE ); + // delete pNew; // DataPilotUpdate copies settings from "new" object + //} + } Sequence< Sequence<Any> > SAL_CALL ScDataPilotTableObj::getDrillDownData(const CellAddress& aAddr) diff --git a/sc/source/ui/unoobj/dispuno.cxx b/sc/source/ui/unoobj/dispuno.cxx index cff547ce2652..6c82871d02da 100644 --- a/sc/source/ui/unoobj/dispuno.cxx +++ b/sc/source/ui/unoobj/dispuno.cxx @@ -65,9 +65,7 @@ uno::Reference<view::XSelectionSupplier> lcl_GetSelectionSupplier( SfxViewShell* SfxViewFrame* pViewFrame = pViewShell->GetViewFrame(); if (pViewFrame) { - SfxFrame* pFrame = pViewFrame->GetFrame(); - if (pFrame) - return uno::Reference<view::XSelectionSupplier>( pFrame->GetController(), uno::UNO_QUERY ); + return uno::Reference<view::XSelectionSupplier>( pViewFrame->GetFrame().GetController(), uno::UNO_QUERY ); } } return uno::Reference<view::XSelectionSupplier>(); @@ -81,8 +79,7 @@ ScDispatchProviderInterceptor::ScDispatchProviderInterceptor(ScTabViewShell* pVi { if ( pViewShell ) { - SfxFrame* pFrame = pViewShell->GetViewFrame()->GetFrame(); - m_xIntercepted.set(uno::Reference<frame::XDispatchProviderInterception>(pFrame->GetFrameInterface(), uno::UNO_QUERY)); + m_xIntercepted.set(uno::Reference<frame::XDispatchProviderInterception>(pViewShell->GetViewFrame()->GetFrame().GetFrameInterface(), uno::UNO_QUERY)); if (m_xIntercepted.is()) { comphelper::increment( m_refCount ); diff --git a/sc/source/ui/unoobj/filtuno.cxx b/sc/source/ui/unoobj/filtuno.cxx index 837d34544b60..8591f2fc0801 100644 --- a/sc/source/ui/unoobj/filtuno.cxx +++ b/sc/source/ui/unoobj/filtuno.cxx @@ -48,7 +48,12 @@ #include "sc.hrc" //CHINA001 #include "scabstdlg.hxx" //CHINA001 +#include "i18npool/lang.h" + +#include <memory> + using namespace ::com::sun::star; +using ::rtl::OUStringBuffer; //------------------------------------------------------------------------ @@ -143,6 +148,10 @@ sal_Int16 SAL_CALL ScFilterOptionsObj::execute() throw(uno::RuntimeException) sal_Int16 nRet = ui::dialogs::ExecutableDialogResults::CANCEL; String aFilterString( aFilterName ); + + ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create(); + DBG_ASSERT(pFact, "ScAbstractFactory create fail!"); + if ( !bExport && aFilterString == ScDocShell::GetAsciiFilterName() ) { // ascii import is special... @@ -161,20 +170,40 @@ sal_Int16 SAL_CALL ScFilterOptionsObj::execute() throw(uno::RuntimeException) pInStream = utl::UcbStreamHelper::CreateStream( xInputStream ); //CHINA001 ScImportAsciiDlg* pDlg = new ScImportAsciiDlg( NULL, aPrivDatName, pInStream, cAsciiDel ); - ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create(); - DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001 AbstractScImportAsciiDlg* pDlg = pFact->CreateScImportAsciiDlg( NULL, aPrivDatName, pInStream, RID_SCDLG_ASCII, cAsciiDel); DBG_ASSERT(pDlg, "Dialog create fail!");//CHINA001 if ( pDlg->Execute() == RET_OK ) { ScAsciiOptions aOptions; pDlg->GetOptions( aOptions ); + pDlg->SaveParameters(); aFilterOptions = aOptions.WriteToString(); nRet = ui::dialogs::ExecutableDialogResults::OK; } delete pDlg; delete pInStream; } + else if ( aFilterString == ScDocShell::GetWebQueryFilterName() || aFilterString == ScDocShell::GetHtmlFilterName() ) + { + if (!bExport) + { + // HTML import. + ::std::auto_ptr<AbstractScTextImportOptionsDlg> pDlg( + pFact->CreateScTextImportOptionsDlg(NULL, RID_SCDLG_TEXT_IMPORT_OPTIONS)); + + if (pDlg->Execute() == RET_OK) + { + LanguageType eLang = pDlg->GetLanguageType(); + OUStringBuffer aBuf; + + aBuf.append(String::CreateFromInt32(static_cast<sal_Int32>(eLang))); + aBuf.append(sal_Unicode(' ')); + aBuf.append(pDlg->IsDateConversionSet() ? sal_Unicode('1') : sal_Unicode('0')); + aFilterOptions = aBuf.makeStringAndClear(); + nRet = ui::dialogs::ExecutableDialogResults::OK; + } + } + } else { sal_Bool bMultiByte = sal_True; @@ -246,8 +275,6 @@ sal_Int16 SAL_CALL ScFilterOptionsObj::execute() throw(uno::RuntimeException) //CHINA001 &aOptions, &aTitle, bMultiByte, bDBEnc, //CHINA001 !bExport ); //CHINA001 - ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create(); - DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001 AbstractScImportOptionsDlg* pDlg = pFact->CreateScImportOptionsDlg( NULL, RID_SCDLG_IMPORTOPT, bAscii, &aOptions, &aTitle, bMultiByte, bDBEnc, diff --git a/sc/source/ui/unoobj/unodoc.cxx b/sc/source/ui/unoobj/unodoc.cxx index 9673db411ea0..d3d755e8b495 100644 --- a/sc/source/ui/unoobj/unodoc.cxx +++ b/sc/source/ui/unoobj/unodoc.cxx @@ -60,9 +60,7 @@ uno::Reference< uno::XInterface > SAL_CALL ScDocument_createInstance( { ::vos::OGuard aGuard( Application::GetSolarMutex() ); ScDLL::Init(); - const SfxObjectCreateMode eCreateMode = ( _nCreationFlags & SFXMODEL_EMBEDDED_OBJECT ) ? SFX_CREATE_MODE_EMBEDDED : SFX_CREATE_MODE_STANDARD; - const bool bScriptSupport = ( _nCreationFlags & SFXMODEL_DISABLE_EMBEDDED_SCRIPTS ) == 0; - SfxObjectShell* pShell = new ScDocShell( eCreateMode, bScriptSupport ); + SfxObjectShell* pShell = new ScDocShell( _nCreationFlags ); return uno::Reference< uno::XInterface >( pShell->GetModel() ); } diff --git a/sc/source/ui/vba/vbahelper.cxx b/sc/source/ui/vba/vbahelper.cxx index ca3b7825b232..4bc57e150c8f 100644 --- a/sc/source/ui/vba/vbahelper.cxx +++ b/sc/source/ui/vba/vbahelper.cxx @@ -518,7 +518,7 @@ void PrintOutHelper( const uno::Any& From, const uno::Any& To, const uno::Any& C { if ( bPreview ) { - if ( !pViewFrame->GetFrame()->IsInPlace() ) + if ( !pViewFrame->GetFrame().IsInPlace() ) { SC_MOD()->InputEnterHandler(); pViewFrame->GetDispatcher()->Execute( SID_VIEWSHELL1, SFX_CALLMODE_SYNCHRON ); diff --git a/sc/source/ui/vba/vbawindow.cxx b/sc/source/ui/vba/vbawindow.cxx index 0416b99abcb3..f0aafe83908b 100644 --- a/sc/source/ui/vba/vbawindow.cxx +++ b/sc/source/ui/vba/vbawindow.cxx @@ -48,7 +48,7 @@ #include <sc.hrc> #include <hash_map> #include <sfx2/viewfrm.hxx> -#include <sfx2/topfrm.hxx> +#include <vcl/wrkwin.hxx> #include "unonames.hxx" using namespace ::com::sun::star; @@ -400,17 +400,13 @@ ScVbaWindow::getWindowState() throw (uno::RuntimeException) sal_Int32 nwindowState = xlNormal; ScTabViewShell* pViewShell = excel::getBestViewShell( m_xModel ); SfxViewFrame* pViewFrame = pViewShell -> GetViewFrame(); - SfxTopViewFrame *pTop= PTR_CAST( SfxTopViewFrame, pViewFrame -> GetTopViewFrame() ); - if ( pTop ) + WorkWindow* pWork = (WorkWindow*) pViewFrame->GetFrame().GetSystemWindow(); + if ( pWork ) { - WorkWindow* pWork = (WorkWindow*) pTop->GetTopFrame_Impl()->GetSystemWindow(); - if ( pWork ) - { - if ( pWork -> IsMaximized()) - nwindowState = xlMaximized; - else if (pWork -> IsMinimized()) - nwindowState = xlMinimized; - } + if ( pWork -> IsMaximized()) + nwindowState = xlMaximized; + else if (pWork -> IsMinimized()) + nwindowState = xlMinimized; } return uno::makeAny( nwindowState ); } @@ -422,21 +418,17 @@ ScVbaWindow::setWindowState( const uno::Any& _windowstate ) throw (uno::RuntimeE _windowstate >>= nwindowState; ScTabViewShell* pViewShell = excel::getBestViewShell( m_xModel ); SfxViewFrame* pViewFrame = pViewShell -> GetViewFrame(); - SfxTopViewFrame *pTop= PTR_CAST( SfxTopViewFrame, pViewFrame -> GetTopViewFrame() ); - if ( pTop ) + WorkWindow* pWork = (WorkWindow*) pViewFrame->GetFrame().GetSystemWindow(); + if ( pWork ) { - WorkWindow* pWork = (WorkWindow*) pTop->GetTopFrame_Impl()->GetSystemWindow(); - if ( pWork ) - { - if ( nwindowState == xlMaximized) - pWork -> Maximize(); - else if (nwindowState == xlMinimized) - pWork -> Minimize(); - else if (nwindowState == xlNormal) - pWork -> Restore(); - else - throw uno::RuntimeException( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Invalid Parameter" ) ), uno::Reference< uno::XInterface >() ); - } + if ( nwindowState == xlMaximized) + pWork -> Maximize(); + else if (nwindowState == xlMinimized) + pWork -> Minimize(); + else if (nwindowState == xlNormal) + pWork -> Restore(); + else + throw uno::RuntimeException( rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "Invalid Parameter" ) ), uno::Reference< uno::XInterface >() ); } } diff --git a/sc/source/ui/view/cellsh.cxx b/sc/source/ui/view/cellsh.cxx index 916e670ec5b1..6d3f10e2ec5e 100644 --- a/sc/source/ui/view/cellsh.cxx +++ b/sc/source/ui/view/cellsh.cxx @@ -518,7 +518,7 @@ void ScCellShell::GetState(SfxItemSet &rSet) // removed: SID_BORDER_OBJECT (old Basic) ScTabViewShell* pTabViewShell = GetViewData()->GetViewShell(); -// BOOL bOle = pTabViewShell->GetViewFrame()->GetFrame()->IsInPlace(); +// BOOL bOle = pTabViewShell->GetViewFrame()->GetFrame().IsInPlace(); // BOOL bTabProt = GetViewData()->GetDocument()->IsTabProtected(GetViewData()->GetTabNo()); ScDocShell* pDocSh = GetViewData()->GetDocShell(); ScViewData* pData = GetViewData(); diff --git a/sc/source/ui/view/cellsh1.cxx b/sc/source/ui/view/cellsh1.cxx index aec15fceef9e..95d86032ef56 100644 --- a/sc/source/ui/view/cellsh1.cxx +++ b/sc/source/ui/view/cellsh1.cxx @@ -1944,7 +1944,7 @@ void ScCellShell::ExecuteEdit( SfxRequest& rReq ) aSet.Put( SvxFontItem( aCurFont.GetFamily(), aCurFont.GetName(), aCurFont.GetStyleName(), aCurFont.GetPitch(), aCurFont.GetCharSet(), GetPool().GetWhich(SID_ATTR_CHAR_FONT) ) ); SfxAbstractDialog* pDlg = pFact->CreateSfxDialog( pTabViewShell->GetDialogParent(), aSet, - pTabViewShell->GetViewFrame()->GetFrame()->GetFrameInterface(), RID_SVXDLG_CHARMAP ); + pTabViewShell->GetViewFrame()->GetFrame().GetFrameInterface(), RID_SVXDLG_CHARMAP ); if ( pDlg->Execute() == RET_OK ) { diff --git a/sc/source/ui/view/cellsh2.cxx b/sc/source/ui/view/cellsh2.cxx index 95ceffc5dc59..c082c6da375d 100644 --- a/sc/source/ui/view/cellsh2.cxx +++ b/sc/source/ui/view/cellsh2.cxx @@ -242,7 +242,7 @@ void ScCellShell::ExecuteDB( SfxRequest& rReq ) SfxViewFrame* pViewFrame = pTabViewShell->GetViewFrame(); BOOL bWasOpen = FALSE; { - uno::Reference<frame::XFrame> xFrame = pViewFrame->GetFrame()->GetFrameInterface(); + uno::Reference<frame::XFrame> xFrame = pViewFrame->GetFrame().GetFrameInterface(); uno::Reference<frame::XFrame> xBeamerFrame = xFrame->findFrame( rtl::OUString::createFromAscii("_beamer"), frame::FrameSearchFlag::CHILDREN); diff --git a/sc/source/ui/view/cellsh3.cxx b/sc/source/ui/view/cellsh3.cxx index 2cc42635b9b0..6f6c7057bddf 100644 --- a/sc/source/ui/view/cellsh3.cxx +++ b/sc/source/ui/view/cellsh3.cxx @@ -88,7 +88,7 @@ void ScCellShell::Execute( SfxRequest& rReq ) case SID_OPENDLG_FUNCTION: // #53318# inplace macht die EditShell Aerger... //! kann nicht immer umgeschaltet werden ???? - if (!pTabViewShell->GetViewFrame()->GetFrame()->IsInPlace()) + if (!pTabViewShell->GetViewFrame()->GetFrame().IsInPlace()) pTabViewShell->SetDontSwitch(TRUE); // EditShell nicht abschalten // kein break diff --git a/sc/source/ui/view/dbfunc3.cxx b/sc/source/ui/view/dbfunc3.cxx index 2ef65f596c34..406fdab9c824 100644..100755 --- a/sc/source/ui/view/dbfunc3.cxx +++ b/sc/source/ui/view/dbfunc3.cxx @@ -689,8 +689,41 @@ void ScDBFunc::DeletePivotTable() else ErrorMessage(STR_PIVOT_NOTFOUND); } +ULONG RefreshDPObject( ScDPObject *pDPObj, ScDocument *pDoc, ScDocShell *pDocSh, BOOL bRecord, BOOL bApi ) +{ + if( !pDPObj ) + return STR_PIVOT_NOTFOUND; + + if( !pDoc ) + return static_cast<ULONG>(-1); + + if( !pDocSh && ( pDocSh = PTR_CAST( ScDocShell, pDoc->GetDocumentShell() ) ) == NULL ) + return static_cast<ULONG>(-1); + + if( ULONG nErrId = pDPObj->RefreshCache() ) + return nErrId; + else if ( nErrId == 0 ) + { + //Refresh all dpobjects + ScDPCollection* pDPCollection = pDoc->GetDPCollection(); + USHORT nCount = pDPCollection->GetCount(); + for (USHORT i=0; i<nCount; i++) + { + if ( (*pDPCollection)[i]->GetCacheId() == pDPObj->GetCacheId() ) + { + ScDBDocFunc aFunc( * pDocSh ); + if ( !aFunc.DataPilotUpdate( (*pDPCollection)[i], (*pDPCollection)[i], bRecord, bApi ) ) + break; + } + } -void ScDBFunc::RecalcPivotTable() + return nErrId; + } + + return 0U; +} + +ULONG ScDBFunc::RecalcPivotTable() { ScDocShell* pDocSh = GetViewData()->GetDocShell(); ScDocument* pDoc = GetViewData()->GetDocument(); @@ -702,12 +735,26 @@ void ScDBFunc::RecalcPivotTable() GetViewData()->GetTabNo() ); if ( pDPObj ) { - ScDBDocFunc aFunc( *pDocSh ); - aFunc.DataPilotUpdate( pDPObj, pDPObj, TRUE, FALSE ); - CursorPosChanged(); // shells may be switched + // Wang Xu Ming -- 2009-6-17 + // DataPilot Migration + //ScDBDocFunc aFunc( *pDocSh ); + //aFunc.DataPilotUpdate( pDPObj, pDPObj, TRUE, FALSE ); + //CursorPosChanged(); // shells may be switched + ULONG nErrId = RefreshDPObject( pDPObj, pDoc, pDocSh, TRUE, FALSE );//pDPObj->RefreshCache(); + if ( nErrId == 0 ) + { + // There is no undo for the refresh of the cache table, but the undo history for cell changes + // remains valid and should be preserved, so the history isn't cleared here. + //GetViewData()->GetDocShell()->GetUndoManager()->Clear(); + } + else if (nErrId <= USHRT_MAX) + ErrorMessage(static_cast<USHORT>(nErrId)); + return nErrId; + // End Comments } else ErrorMessage(STR_PIVOT_NOTFOUND); + return STR_PIVOT_NOTFOUND; } void ScDBFunc::GetSelectedMemberList( ScStrCollection& rEntries, long& rDimension ) diff --git a/sc/source/ui/view/drawview.cxx b/sc/source/ui/view/drawview.cxx index 837cee2698b3..311bcf8c24b2 100644 --- a/sc/source/ui/view/drawview.cxx +++ b/sc/source/ui/view/drawview.cxx @@ -529,7 +529,7 @@ void ScDrawView::MarkListHasChanged() // Verben anpassen SfxViewFrame* pViewFrame = pViewSh->GetViewFrame(); - BOOL bOle = pViewSh->GetViewFrame()->GetFrame()->IsInPlace(); + BOOL bOle = pViewSh->GetViewFrame()->GetFrame().IsInPlace(); if ( pOle2Obj && !bOle ) { uno::Reference < embed::XEmbeddedObject > xObj = pOle2Obj->GetObjRef(); @@ -570,16 +570,13 @@ void ScDrawView::MarkListHasChanged() if (pViewFrame) { - SfxFrame* pFrame = pViewFrame->GetFrame(); - if (pFrame) + SfxFrame& rFrame = pViewFrame->GetFrame(); + uno::Reference<frame::XController> xController = rFrame.GetController(); + if (xController.is()) { - uno::Reference<frame::XController> xController = pFrame->GetController(); - if (xController.is()) - { - ScTabViewObj* pImp = ScTabViewObj::getImplementation( xController ); - if (pImp) - pImp->SelectionChanged(); - } + ScTabViewObj* pImp = ScTabViewObj::getImplementation( xController ); + if (pImp) + pImp->SelectionChanged(); } } diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx index cd55e4f72c34..b8eeb868809e 100644 --- a/sc/source/ui/view/gridwin.cxx +++ b/sc/source/ui/view/gridwin.cxx @@ -2407,24 +2407,20 @@ long ScGridWindow::PreNotify( NotifyEvent& rNEvt ) SfxViewFrame* pViewFrame = pViewData->GetViewShell()->GetViewFrame(); if (pViewFrame) { - SfxFrame* pFrame = pViewFrame->GetFrame(); - if (pFrame) + com::sun::star::uno::Reference<com::sun::star::frame::XController> xController = pViewFrame->GetFrame().GetController(); + if (xController.is()) { - com::sun::star::uno::Reference<com::sun::star::frame::XController> xController = pFrame->GetController(); - if (xController.is()) + ScTabViewObj* pImp = ScTabViewObj::getImplementation( xController ); + if (pImp && pImp->IsMouseListening()) { - ScTabViewObj* pImp = ScTabViewObj::getImplementation( xController ); - if (pImp && pImp->IsMouseListening()) - { - ::com::sun::star::awt::MouseEvent aEvent; - lcl_InitMouseEvent( aEvent, *rNEvt.GetMouseEvent() ); - if ( rNEvt.GetWindow() ) - aEvent.Source = rNEvt.GetWindow()->GetComponentInterface(); - if ( nType == EVENT_MOUSEBUTTONDOWN) - pImp->MousePressed( aEvent ); - else - pImp->MouseReleased( aEvent ); - } + ::com::sun::star::awt::MouseEvent aEvent; + lcl_InitMouseEvent( aEvent, *rNEvt.GetMouseEvent() ); + if ( rNEvt.GetWindow() ) + aEvent.Source = rNEvt.GetWindow()->GetComponentInterface(); + if ( nType == EVENT_MOUSEBUTTONDOWN) + pImp->MousePressed( aEvent ); + else + pImp->MouseReleased( aEvent ); } } } @@ -2689,9 +2685,32 @@ void __EXPORT ScGridWindow::Command( const CommandEvent& rCEvt ) if ( bMouse ) { + SCsCOL nCellX = -1; + SCsROW nCellY = -1; + pViewData->GetPosFromPixel(aPosPixel.X(), aPosPixel.Y(), eWhich, nCellX, nCellY); + ScDocument* pDoc = pViewData->GetDocument(); + SCTAB nTab = pViewData->GetTabNo(); + const ScTableProtection* pProtect = pDoc->GetTabProtection(nTab); + bool bSelectAllowed = true; + if ( pProtect && pProtect->isProtected() ) + { + // This sheet is protected. Check if a context menu is allowed on this cell. + bool bCellProtected = pDoc->HasAttrib(nCellX, nCellY, nTab, nCellX, nCellY, nTab, HASATTR_PROTECTED); + bool bSelProtected = pProtect->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS); + bool bSelUnprotected = pProtect->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS); + + if (bCellProtected) + bSelectAllowed = bSelProtected; + else + bSelectAllowed = bSelUnprotected; + } + if (!bSelectAllowed) + // Selecting this cell is not allowed, neither is context menu. + return; + // #i18735# First select the item under the mouse pointer. // This can change the selection, and the view state (edit mode, etc). - SelectForContextMenu( aPosPixel ); + SelectForContextMenu( aPosPixel, nCellX, nCellY ); } BOOL bDone = FALSE; @@ -2786,15 +2805,12 @@ void __EXPORT ScGridWindow::Command( const CommandEvent& rCEvt ) } } -void ScGridWindow::SelectForContextMenu( const Point& rPosPixel ) +void ScGridWindow::SelectForContextMenu( const Point& rPosPixel, SCsCOL nCellX, SCsROW nCellY ) { // #i18735# if the click was outside of the current selection, // the cursor is moved or an object at the click position selected. // (see SwEditWin::SelectMenuPosition in Writer) - SCsCOL nCellX; - SCsROW nCellY; - pViewData->GetPosFromPixel( rPosPixel.X(), rPosPixel.Y(), eWhich, nCellX, nCellY ); ScTabView* pView = pViewData->GetView(); ScDrawView* pDrawView = pView->GetScDrawView(); diff --git a/sc/source/ui/view/hdrcont.cxx b/sc/source/ui/view/hdrcont.cxx index 511463db8a10..6c389d496b73 100644 --- a/sc/source/ui/view/hdrcont.cxx +++ b/sc/source/ui/view/hdrcont.cxx @@ -44,6 +44,7 @@ #include "scmod.hxx" // Optionen #include "inputopt.hxx" // Optionen #include "gridmerg.hxx" +#include "document.hxx" // ----------------------------------------------------------------------- @@ -120,7 +121,7 @@ void ScHeaderControl::SetWidth( long nNew ) } } -__EXPORT ScHeaderControl::~ScHeaderControl() +ScHeaderControl::~ScHeaderControl() { } @@ -262,7 +263,7 @@ void ScHeaderControl::DrawShadedRect( long nStart, long nEnd, const Color& rBase // Paint // -void __EXPORT ScHeaderControl::Paint( const Rectangle& rRect ) +void ScHeaderControl::Paint( const Rectangle& rRect ) { // fuer VCL ist es wichtig, wenig Aufrufe zu haben, darum werden die aeusseren // Linien zusammengefasst @@ -652,7 +653,46 @@ SCCOLROW ScHeaderControl::GetMousePos( const MouseEvent& rMEvt, BOOL& rBorder ) return nHitNo; } -void __EXPORT ScHeaderControl::MouseButtonDown( const MouseEvent& rMEvt ) +bool ScHeaderControl::IsSelectionAllowed(SCCOLROW nPos) const +{ + ScTabViewShell* pViewSh = dynamic_cast<ScTabViewShell*>(SfxViewShell::Current()); + if (!pViewSh) + return false; + + ScViewData* pViewData = pViewSh->GetViewData(); + USHORT nTab = pViewData->GetTabNo(); + ScDocument* pDoc = pViewData->GetDocument(); + const ScTableProtection* pProtect = pDoc->GetTabProtection(nTab); + bool bSelectAllowed = true; + if ( pProtect && pProtect->isProtected() ) + { + // This sheet is protected. Check if a context menu is allowed on this cell. + bool bCellsProtected = false; + if (bVertical) + { + // row header + SCROW nRPos = static_cast<SCROW>(nPos); + bCellsProtected = pDoc->HasAttrib(0, nRPos, nTab, MAXCOL, nRPos, nTab, HASATTR_PROTECTED); + } + else + { + // column header + SCCOL nCPos = static_cast<SCCOL>(nPos); + bCellsProtected = pDoc->HasAttrib(nCPos, 0, nTab, nCPos, MAXROW, nTab, HASATTR_PROTECTED); + } + + bool bSelProtected = pProtect->isOptionEnabled(ScTableProtection::SELECT_LOCKED_CELLS); + bool bSelUnprotected = pProtect->isOptionEnabled(ScTableProtection::SELECT_UNLOCKED_CELLS); + + if (bCellsProtected) + bSelectAllowed = bSelProtected; + else + bSelectAllowed = bSelUnprotected; + } + return bSelectAllowed; +} + +void ScHeaderControl::MouseButtonDown( const MouseEvent& rMEvt ) { if (IsDisabled()) return; @@ -662,6 +702,8 @@ void __EXPORT ScHeaderControl::MouseButtonDown( const MouseEvent& rMEvt ) BOOL bFound; SCCOLROW nHitNo = GetMousePos( rMEvt, bFound ); + if (!IsSelectionAllowed(nHitNo)) + return; if ( bFound && rMEvt.IsLeft() && ResizeAllowed() ) { @@ -717,7 +759,7 @@ void __EXPORT ScHeaderControl::MouseButtonDown( const MouseEvent& rMEvt ) } } -void __EXPORT ScHeaderControl::MouseButtonUp( const MouseEvent& rMEvt ) +void ScHeaderControl::MouseButtonUp( const MouseEvent& rMEvt ) { if ( IsDisabled() ) return; @@ -770,7 +812,7 @@ void __EXPORT ScHeaderControl::MouseButtonUp( const MouseEvent& rMEvt ) } } -void __EXPORT ScHeaderControl::MouseMove( const MouseEvent& rMEvt ) +void ScHeaderControl::MouseMove( const MouseEvent& rMEvt ) { if ( IsDisabled() ) { @@ -820,7 +862,7 @@ void ScHeaderControl::Tracking( const TrackingEvent& rTEvt ) MouseMove( rTEvt.GetMouseEvent() ); } -void __EXPORT ScHeaderControl::Command( const CommandEvent& rCEvt ) +void ScHeaderControl::Command( const CommandEvent& rCEvt ) { USHORT nCmd = rCEvt.GetCommand(); if ( nCmd == COMMAND_CONTEXTMENU ) @@ -845,8 +887,11 @@ void __EXPORT ScHeaderControl::Command( const CommandEvent& rCEvt ) MouseEvent aMEvt( rCEvt.GetMousePosPixel() ); BOOL bBorder; SCCOLROW nPos = GetMousePos( aMEvt, bBorder ); - USHORT nTab = pViewData->GetTabNo(); + if (!IsSelectionAllowed(nPos)) + // Selecting this cell is not allowed, neither is context menu. + return; + SCTAB nTab = pViewData->GetTabNo(); ScRange aNewRange; if ( bVertical ) aNewRange = ScRange( 0, sal::static_int_cast<SCROW>(nPos), nTab, @@ -935,7 +980,7 @@ void ScHeaderControl::ShowDragHelp() } } -void __EXPORT ScHeaderControl::RequestHelp( const HelpEvent& rHEvt ) +void ScHeaderControl::RequestHelp( const HelpEvent& rHEvt ) { // Wenn eigene QuickHelp angezeigt wird, nicht durch RequestHelp // wieder wegnehmen lassen diff --git a/sc/source/ui/view/makefile.mk b/sc/source/ui/view/makefile.mk index e40d6da5c09d..feeacc865fba 100644 --- a/sc/source/ui/view/makefile.mk +++ b/sc/source/ui/view/makefile.mk @@ -156,6 +156,9 @@ EXCEPTIONSFILES= \ $(SLO)$/scextopt.obj \ $(SLO)$/tabvwshb.obj \ $(SLO)$/viewdata.obj \ + $(SLO)$/viewfunc.obj \ + $(SLO)$/viewfun2.obj \ + $(SLO)$/viewfun3.obj \ $(SLO)$/viewfun5.obj \ $(SLO)$/viewfun7.obj \ $(SLO)$/reffact.obj diff --git a/sc/source/ui/view/prevwsh.cxx b/sc/source/ui/view/prevwsh.cxx index f4b976b00e4d..38d5144274c5 100644 --- a/sc/source/ui/view/prevwsh.cxx +++ b/sc/source/ui/view/prevwsh.cxx @@ -44,7 +44,6 @@ #include <sfx2/dispatch.hxx> #include <sfx2/objface.hxx> #include <sfx2/request.hxx> -#include <sfx2/topfrm.hxx> #include <svtools/printdlg.hxx> #include <svl/stritem.hxx> #include <svl/whiter.hxx> @@ -151,7 +150,7 @@ void ScPreviewShell::Construct( Window* pParent ) ScPreviewShell::ScPreviewShell( SfxViewFrame* pViewFrame, SfxViewShell* pOldSh ) : - SfxViewShell( pViewFrame, SFX_VIEW_MAXIMIZE_FIRST | SFX_VIEW_CAN_PRINT | SFX_VIEW_HAS_PRINTOPTIONS ), + SfxViewShell( pViewFrame, SFX_VIEW_CAN_PRINT | SFX_VIEW_HAS_PRINTOPTIONS ), pDocShell( (ScDocShell*)pViewFrame->GetObjectShell() ), nSourceDesignMode( SC_FORCEMODE_NONE ), pAccessibilityBroadcaster( NULL ) diff --git a/sc/source/ui/view/tabview.cxx b/sc/source/ui/view/tabview.cxx index b8656e1e25a0..4938defa437d 100644 --- a/sc/source/ui/view/tabview.cxx +++ b/sc/source/ui/view/tabview.cxx @@ -1169,7 +1169,7 @@ BOOL ScTabView::ScrollCommand( const CommandEvent& rCEvt, ScSplitPos ePos ) const CommandWheelData* pData = rCEvt.GetWheelData(); if ( pData && pData->GetMode() == COMMAND_WHEEL_ZOOM ) { - if ( !aViewData.GetViewShell()->GetViewFrame()->GetFrame()->IsInPlace() ) + if ( !aViewData.GetViewShell()->GetViewFrame()->GetFrame().IsInPlace() ) { // for ole inplace editing, the scale is defined by the visarea and client size // and can't be changed directly @@ -1626,7 +1626,7 @@ void ScTabView::UpdateHeaderWidth( const ScVSplitPos* pWhich, const SCROW* pPosY return; SCROW nEndPos = MAXROW; - if ( !aViewData.GetViewShell()->GetViewFrame()->GetFrame()->IsInPlace() ) + if ( !aViewData.GetViewShell()->GetViewFrame()->GetFrame().IsInPlace() ) { // fuer OLE Inplace immer MAXROW @@ -2455,16 +2455,13 @@ void ScTabView::SetNewVisArea() SfxViewFrame* pViewFrame = aViewData.GetViewShell()->GetViewFrame(); if (pViewFrame) { - SfxFrame* pFrame = pViewFrame->GetFrame(); - if (pFrame) + SfxFrame& rFrame = pViewFrame->GetFrame(); + com::sun::star::uno::Reference<com::sun::star::frame::XController> xController = rFrame.GetController(); + if (xController.is()) { - com::sun::star::uno::Reference<com::sun::star::frame::XController> xController = pFrame->GetController(); - if (xController.is()) - { - ScTabViewObj* pImp = ScTabViewObj::getImplementation( xController ); - if (pImp) - pImp->VisAreaChanged(); - } + ScTabViewObj* pImp = ScTabViewObj::getImplementation( xController ); + if (pImp) + pImp->VisAreaChanged(); } } if (aViewData.GetViewShell()->HasAccessibilityObjects()) diff --git a/sc/source/ui/view/tabview3.cxx b/sc/source/ui/view/tabview3.cxx index b61c3ade64f4..304a858fa21f 100644 --- a/sc/source/ui/view/tabview3.cxx +++ b/sc/source/ui/view/tabview3.cxx @@ -367,16 +367,12 @@ void ScTabView::SelectionChanged() SfxViewFrame* pViewFrame = aViewData.GetViewShell()->GetViewFrame(); if (pViewFrame) { - SfxFrame* pFrame = pViewFrame->GetFrame(); - if (pFrame) + uno::Reference<frame::XController> xController = pViewFrame->GetFrame().GetController(); + if (xController.is()) { - uno::Reference<frame::XController> xController = pFrame->GetController(); - if (xController.is()) - { - ScTabViewObj* pImp = ScTabViewObj::getImplementation( xController ); - if (pImp) - pImp->SelectionChanged(); - } + ScTabViewObj* pImp = ScTabViewObj::getImplementation( xController ); + if (pImp) + pImp->SelectionChanged(); } } diff --git a/sc/source/ui/view/tabview5.cxx b/sc/source/ui/view/tabview5.cxx index 460f31b07175..bc5c94c271e2 100644 --- a/sc/source/ui/view/tabview5.cxx +++ b/sc/source/ui/view/tabview5.cxx @@ -334,16 +334,12 @@ void ScTabView::TabChanged() SfxViewFrame* pViewFrame = aViewData.GetViewShell()->GetViewFrame(); if (pViewFrame) { - SfxFrame* pFrame = pViewFrame->GetFrame(); - if (pFrame) + uno::Reference<frame::XController> xController = pViewFrame->GetFrame().GetController(); + if (xController.is()) { - uno::Reference<frame::XController> xController = pFrame->GetController(); - if (xController.is()) - { - ScTabViewObj* pImp = ScTabViewObj::getImplementation( xController ); - if (pImp) - pImp->SheetChanged(); - } + ScTabViewObj* pImp = ScTabViewObj::getImplementation( xController ); + if (pImp) + pImp->SheetChanged(); } } } diff --git a/sc/source/ui/view/tabvwsh2.cxx b/sc/source/ui/view/tabvwsh2.cxx index ab0dae319105..ca47535ad2cf 100644 --- a/sc/source/ui/view/tabvwsh2.cxx +++ b/sc/source/ui/view/tabvwsh2.cxx @@ -451,7 +451,7 @@ void ScTabViewShell::GetDrawState(SfxItemSet &rSet) case SID_DRAW_CHART: { - BOOL bOle = GetViewFrame()->GetFrame()->IsInPlace(); + BOOL bOle = GetViewFrame()->GetFrame().IsInPlace(); if ( bOle || !SvtModuleOptions().IsChart() ) rSet.DisableItem( nWhich ); } diff --git a/sc/source/ui/view/tabvwsh3.cxx b/sc/source/ui/view/tabvwsh3.cxx index 493760d7a6ba..c291d01d71c2 100644 --- a/sc/source/ui/view/tabvwsh3.cxx +++ b/sc/source/ui/view/tabvwsh3.cxx @@ -41,7 +41,6 @@ #include <sfx2/dispatch.hxx> #include <sfx2/passwd.hxx> #include <sfx2/request.hxx> -#include <sfx2/topfrm.hxx> #include <svl/ptitem.hxx> #include <svl/stritem.hxx> #include <tools/urlobj.hxx> @@ -482,7 +481,7 @@ void ScTabViewShell::Execute( SfxRequest& rReq ) { if ( pDocSh->GetTitle() == aStrDocName ) { - pViewFrame = SfxViewFrame::GetFirst( pDocSh, TYPE(SfxTopViewFrame) ); + pViewFrame = SfxViewFrame::GetFirst( pDocSh ); bFound = ( NULL != pViewFrame ); } @@ -490,8 +489,7 @@ void ScTabViewShell::Execute( SfxRequest& rReq ) } if ( bFound ) - if ( pViewFrame->ISA(SfxTopViewFrame) ) - pViewFrame->GetFrame()->Appear(); + pViewFrame->GetFrame().Appear(); rReq.Ignore();//XXX wird von SFX erledigt } @@ -502,7 +500,7 @@ void ScTabViewShell::Execute( SfxRequest& rReq ) case SID_PRINTPREVIEW: { - if ( !pThisFrame->GetFrame()->IsInPlace() ) // nicht bei OLE + if ( !pThisFrame->GetFrame().IsInPlace() ) // nicht bei OLE { // print preview is now always in the same frame as the tab view // -> always switch this frame back to normal view diff --git a/sc/source/ui/view/tabvwsh4.cxx b/sc/source/ui/view/tabvwsh4.cxx index d7a0e2b080b0..ed09ec85ee8c 100644 --- a/sc/source/ui/view/tabvwsh4.cxx +++ b/sc/source/ui/view/tabvwsh4.cxx @@ -32,7 +32,6 @@ // INCLUDE --------------------------------------------------------------- -#include <sfx2/topfrm.hxx> #include "scitems.hxx" #include <editeng/eeitem.hxx> @@ -263,7 +262,7 @@ void __EXPORT ScTabViewShell::Deactivate(BOOL bMDI) DeActivateOlk( GetViewData() ); ActivateView( FALSE, FALSE ); - if ( GetViewFrame()->GetFrame()->IsInPlace() ) // inplace + if ( GetViewFrame()->GetFrame().IsInPlace() ) // inplace GetViewData()->GetDocShell()->UpdateOle(GetViewData(),TRUE); if ( pHdl ) @@ -291,8 +290,7 @@ void ScTabViewShell::SetActive() #if 0 SfxViewFrame* pFrame = GetViewFrame(); - if ( pFrame->ISA(SfxTopViewFrame) ) - pFrame->GetFrame()->Appear(); + pFrame->GetFrame().Appear(); SFX_APP()->SetViewFrame( pFrame ); // immer erst Appear, dann SetViewFrame (#29290#) #endif @@ -390,7 +388,7 @@ void __EXPORT ScTabViewShell::AdjustPosSizePixel( const Point &rPos, const Size void __EXPORT ScTabViewShell::InnerResizePixel( const Point &rOfs, const Size &rSize ) { Size aNewSize( rSize ); - if ( GetViewFrame()->GetFrame()->IsInPlace() ) + if ( GetViewFrame()->GetFrame().IsInPlace() ) { SvBorder aBorder; GetBorderSize( aBorder, rSize ); @@ -1335,13 +1333,10 @@ ScTabViewObj* lcl_GetViewObj( ScTabViewShell& rShell ) SfxViewFrame* pViewFrame = rShell.GetViewFrame(); if (pViewFrame) { - SfxFrame* pFrame = pViewFrame->GetFrame(); - if (pFrame) - { - uno::Reference<frame::XController> xController = pFrame->GetController(); - if (xController.is()) - pRet = ScTabViewObj::getImplementation( xController ); - } + SfxFrame& rFrame = pViewFrame->GetFrame(); + uno::Reference<frame::XController> xController = rFrame.GetController(); + if (xController.is()) + pRet = ScTabViewObj::getImplementation( xController ); } return pRet; } @@ -1382,8 +1377,7 @@ void ScTabViewShell::StartSimpleRefDialog( // Then the view has to be activated first, the same way as in Execute for SID_CURRENTDOC. // Can't use GrabFocus here, because it needs to take effect immediately. - if ( pViewFrm->ISA(SfxTopViewFrame) ) - pViewFrm->GetFrame()->Appear(); + pViewFrm->GetFrame().Appear(); } USHORT nId = ScSimpleRefDlgWrapper::GetChildWindowId(); @@ -1525,7 +1519,7 @@ BOOL ScTabViewShell::TabKeyInput(const KeyEvent& rKEvt) // container app and are executed during Window::KeyInput. // -> don't pass keys to input handler that would be used there // but should call slots instead. - BOOL bParent = ( GetViewFrame()->GetFrame()->IsInPlace() && eFunc != KEYFUNC_DONTKNOW ); + BOOL bParent = ( GetViewFrame()->GetFrame().IsInPlace() && eFunc != KEYFUNC_DONTKNOW ); if( !bUsed && !bDraw && nCode != KEY_RETURN && !bParent ) bUsed = pScMod->InputKeyEvent( rKEvt, TRUE ); // Eingabe @@ -1645,8 +1639,6 @@ FASTBOOL __EXPORT ScTabViewShell::KeyInput( const KeyEvent &rKeyEvent ) //------------------------------------------------------------------ -// SfxViewShell( pViewFrame, SFX_VIEW_MAXIMIZE_FIRST | SFX_VIEW_DISABLE_ACCELS ), - #define __INIT_ScTabViewShell \ eCurOST(OST_NONE), \ nDrawSfxId(0), \ @@ -1736,7 +1728,7 @@ void ScTabViewShell::Construct( BYTE nForceDesignMode ) // show the right cells GetViewData()->SetScreenPos( bNegativePage ? aVisArea.TopRight() : aVisArea.TopLeft() ); - if ( GetViewFrame()->GetFrame()->IsInPlace() ) // inplace + if ( GetViewFrame()->GetFrame().IsInPlace() ) // inplace { pDocSh->SetInplace( TRUE ); // schon so initialisiert if (pDoc->IsEmbedded()) @@ -1876,7 +1868,7 @@ void ScTabViewShell::Construct( BYTE nForceDesignMode ) // #105575#; update only in the first creation of the ViewShell pDocSh->SetUpdateEnabled(FALSE); - if ( GetViewFrame()->GetFrame()->IsInPlace() ) + if ( GetViewFrame()->GetFrame().IsInPlace() ) UpdateHeaderWidth(); // The implace activation requires headers to be calculated SvBorder aBorder; @@ -1898,7 +1890,7 @@ void ScTabViewShell::Construct( BYTE nForceDesignMode ) //UNUSED2008-05 //UNUSED2008-05 UpdatePageBreakData(); //UNUSED2008-05 -//UNUSED2008-05 /*uno::Reference<frame::XFrame> xFrame = pViewFrame->GetFrame()->GetFrameInterface(); +//UNUSED2008-05 /*uno::Reference<frame::XFrame> xFrame = pViewFrame->GetFrame().GetFrameInterface(); //UNUSED2008-05 if (xFrame.is()) //UNUSED2008-05 xFrame->setComponent( uno::Reference<awt::XWindow>(), new ScTabViewObj( this ) );*/ //UNUSED2008-05 // make Controller known to SFX @@ -1914,7 +1906,7 @@ void ScTabViewShell::Construct( BYTE nForceDesignMode ) ScTabViewShell::ScTabViewShell( SfxViewFrame* pViewFrame, SfxViewShell* pOldSh ) : - SfxViewShell( pViewFrame, SFX_VIEW_MAXIMIZE_FIRST | SFX_VIEW_CAN_PRINT | SFX_VIEW_HAS_PRINTOPTIONS ), + SfxViewShell( pViewFrame, SFX_VIEW_CAN_PRINT | SFX_VIEW_HAS_PRINTOPTIONS ), ScDBFunc( &pViewFrame->GetWindow(), (ScDocShell&)*pViewFrame->GetObjectShell(), this ), __INIT_ScTabViewShell { @@ -1950,7 +1942,7 @@ ScTabViewShell::ScTabViewShell( SfxViewFrame* pViewFrame, SetZoomType( rAppOpt.GetZoomType(), TRUE ); } - /*uno::Reference<frame::XFrame> xFrame = pViewFrame->GetFrame()->GetFrameInterface(); + /*uno::Reference<frame::XFrame> xFrame = pViewFrame->GetFrame().GetFrameInterface(); if (xFrame.is()) xFrame->setComponent( uno::Reference<awt::XWindow>(), new ScTabViewObj( this ) );*/ // make Controller known to SFX diff --git a/sc/source/ui/view/tabvwsha.cxx b/sc/source/ui/view/tabvwsha.cxx index 5940b2a3b950..7734f3e24ff8 100644 --- a/sc/source/ui/view/tabvwsha.cxx +++ b/sc/source/ui/view/tabvwsha.cxx @@ -174,7 +174,7 @@ void __EXPORT ScTabViewShell::GetState( SfxItemSet& rSet ) USHORT nMyId = 0; SfxViewFrame* pThisFrame = GetViewFrame(); - BOOL bOle = GetViewFrame()->GetFrame()->IsInPlace(); + BOOL bOle = GetViewFrame()->GetFrame().IsInPlace(); SCTAB nTabCount = pDoc->GetTableCount(); SCTAB nTabSelCount = rMark.GetSelectCount(); diff --git a/sc/source/ui/view/tabvwshb.cxx b/sc/source/ui/view/tabvwshb.cxx index 5e69e5c9bf99..8f4a203ea14d 100644 --- a/sc/source/ui/view/tabvwshb.cxx +++ b/sc/source/ui/view/tabvwshb.cxx @@ -432,7 +432,7 @@ void ScTabViewShell::ExecDrawIns(SfxRequest& rReq) void ScTabViewShell::GetDrawInsState(SfxItemSet &rSet) { - BOOL bOle = GetViewFrame()->GetFrame()->IsInPlace(); + BOOL bOle = GetViewFrame()->GetFrame().IsInPlace(); BOOL bTabProt = GetViewData()->GetDocument()->IsTabProtected(GetViewData()->GetTabNo()); ScDocShell* pDocShell = ( GetViewData() ? GetViewData()->GetDocShell() : NULL ); bool bShared = ( pDocShell ? pDocShell->IsDocShared() : false ); diff --git a/sc/source/ui/view/tabvwshd.cxx b/sc/source/ui/view/tabvwshd.cxx index 6074d03a67aa..4ef5186a25a0 100644 --- a/sc/source/ui/view/tabvwshd.cxx +++ b/sc/source/ui/view/tabvwshd.cxx @@ -40,7 +40,7 @@ #include <sfx2/childwin.hxx> #include <sfx2/request.hxx> -#include <sfx2/topfrm.hxx> +#include <sfx2/viewfrm.hxx> #include <vcl/svapp.hxx> #include <vcl/wrkwin.hxx> diff --git a/sc/source/ui/view/viewfun2.cxx b/sc/source/ui/view/viewfun2.cxx index 627f214c4ec6..5fcd094acffc 100644 --- a/sc/source/ui/view/viewfun2.cxx +++ b/sc/source/ui/view/viewfun2.cxx @@ -85,6 +85,7 @@ #include "inputwin.hxx" #include "funcdesc.hxx" #include "docuno.hxx" +#include "charthelper.hxx" // STATIC DATA --------------------------------------------------------------- @@ -2800,6 +2801,10 @@ void ScViewFunc::MoveTable( USHORT nDestDocNo, SCTAB nDestTab, BOOL bCopy ) nNewTab--; SetTabNo( nNewTab, TRUE ); + + //#i29848# adjust references to data on the copied sheet + if( bCopy ) + ScChartHelper::AdjustRangesOfChartsOnDestinationPage( pDoc, pDestDoc, nTab, nNewTab ); } } diff --git a/sc/source/ui/view/viewutil.cxx b/sc/source/ui/view/viewutil.cxx index c348b843cfdc..f73346398ea1 100644 --- a/sc/source/ui/view/viewutil.cxx +++ b/sc/source/ui/view/viewutil.cxx @@ -370,7 +370,7 @@ BOOL ScViewUtil::ExecuteCharMap( const SvxFontItem& rOldFont, SfxAllItemSet aSet( rFrame.GetObjectShell()->GetPool() ); aSet.Put( SfxBoolItem( FN_PARAM_1, FALSE ) ); aSet.Put( SvxFontItem( rOldFont.GetFamily(), rOldFont.GetFamilyName(), rOldFont.GetStyleName(), rOldFont.GetPitch(), rOldFont.GetCharSet(), aSet.GetPool()->GetWhich( SID_ATTR_CHAR_FONT ) ) ); - SfxAbstractDialog* pDlg = pFact->CreateSfxDialog( &rFrame.GetWindow(), aSet, rFrame.GetFrame()->GetFrameInterface(), RID_SVXDLG_CHARMAP ); + SfxAbstractDialog* pDlg = pFact->CreateSfxDialog( &rFrame.GetWindow(), aSet, rFrame.GetFrame().GetFrameInterface(), RID_SVXDLG_CHARMAP ); if ( pDlg->Execute() == RET_OK ) { SFX_ITEMSET_ARG( pDlg->GetOutputItemSet(), pItem, SfxStringItem, SID_CHARMAP, FALSE ); diff --git a/sc/util/makefile.mk b/sc/util/makefile.mk index 0635ca4732df..fa1361c9f794 100644 --- a/sc/util/makefile.mk +++ b/sc/util/makefile.mk @@ -277,6 +277,7 @@ LIB8OBJFILES = \ $(SLO)$/dapidata.obj \ $(SLO)$/crdlg.obj \ $(SLO)$/scuiasciiopt.obj \ + $(SLO)$/textimportoptions.obj \ $(SLO)$/scuiautofmt.obj \ $(SLO)$/dpgroupdlg.obj \ $(SLO)$/editfield.obj |