ooo-build r12236 - in trunk: . patches/src680 scratch/sc-dptest



Author: kyoshida
Date: Mon Apr 21 04:25:54 2008
New Revision: 12236
URL: http://svn.gnome.org/viewvc/ooo-build?rev=12236&view=rev

Log:
2008-04-21  Kohei Yoshida  <kyoshida novell com>

	* patches/src680/offapi-calc-datapilot-drilldown.diff:
	* patches/src680/sc-calc-datapilot-drilldown.diff: latest code from
	koheidatapilot cws to fix a number of bugs and regressions
	(i#83250, i#88473).  This fixes regressions on drill-down sheet 
	insertion when used with the 'Ignore empty rows' and/or 'Identify
	categories' options, grouped fields, or numeric category names which 
	must be evaluated numerically intead of texturally.  It also fixes
	incorrect drill-down data when the field value is (empty) or 'Total'.
	
	* scratch/sc-dptest/Makefile: adopted to DEV300 tree.


Modified:
   trunk/ChangeLog
   trunk/patches/src680/offapi-calc-datapilot-drilldown.diff
   trunk/patches/src680/sc-calc-datapilot-drilldown.diff
   trunk/scratch/sc-dptest/Makefile

Modified: trunk/patches/src680/offapi-calc-datapilot-drilldown.diff
==============================================================================
--- trunk/patches/src680/offapi-calc-datapilot-drilldown.diff	(original)
+++ trunk/patches/src680/offapi-calc-datapilot-drilldown.diff	Mon Apr 21 04:25:54 2008
@@ -1,3 +1,4 @@
+? offapi/offapi.vpj
 Index: offapi/com/sun/star/sheet/DataPilotFieldFilter.idl
 ===================================================================
 RCS file: /cvs/api/offapi/com/sun/star/sheet/DataPilotFieldFilter.idl,v
@@ -372,17 +373,17 @@
 RCS file: offapi/com/sun/star/sheet/DataPilotTablePositionType.idl
 diff -N offapi/com/sun/star/sheet/DataPilotTablePositionType.idl
 --- /dev/null	1 Jan 1970 00:00:00 -0000
-+++ offapi/com/sun/star/sheet/DataPilotTablePositionType.idl	7 Dec 2007 05:29:36 -0000	1.1.2.6
-@@ -0,0 +1,82 @@
++++ offapi/com/sun/star/sheet/DataPilotTablePositionType.idl	18 Apr 2008 19:19:41 -0000	1.1.2.7
+@@ -0,0 +1,86 @@
 +/*************************************************************************
 + *
 + *  OpenOffice.org - a multi-platform office productivity suite
 + *
 + *  $RCSfile: DataPilotTablePositionType.idl,v $
 + *
-+ *  $Revision: 1.1.2.6 $
++ *  $Revision: 1.1.2.7 $
 + *
-+ *  last change: $Author: kohei $ $Date: 2007/12/07 05:29:36 $
++ *  last change: $Author: kohei $ $Date: 2008/04/18 19:19:41 $
 + *
 + *  The Contents of this file are made available subject to
 + *  the terms of GNU Lesser General Public License Version 2.1.
@@ -447,6 +448,10 @@
 +    const long COLUMN_HEADER = 3;
 +
 +    //------------------------------------------------------------------------
++
++    /** indicates that the specified cell is within the table but in areas 
++        other than the result or header areas. */
++    const long OTHER = 4;
 +};
 +
 +//============================================================================
@@ -562,17 +567,17 @@
 RCS file: offapi/com/sun/star/sheet/XDataPilotTable2.idl
 diff -N offapi/com/sun/star/sheet/XDataPilotTable2.idl
 --- /dev/null	1 Jan 1970 00:00:00 -0000
-+++ offapi/com/sun/star/sheet/XDataPilotTable2.idl	7 Dec 2007 05:29:36 -0000	1.1.2.6
-@@ -0,0 +1,137 @@
++++ offapi/com/sun/star/sheet/XDataPilotTable2.idl	18 Apr 2008 15:06:44 -0000	1.1.2.7
+@@ -0,0 +1,139 @@
 +/*************************************************************************
 + *
 + *  OpenOffice.org - a multi-platform office productivity suite
 + *
 + *  $RCSfile: XDataPilotTable2.idl,v $
 + *
-+ *  $Revision: 1.1.2.6 $
++ *  $Revision: 1.1.2.7 $
 + *
-+ *  last change: $Author: kohei $ $Date: 2007/12/07 05:29:36 $
++ *  last change: $Author: kohei $ $Date: 2008/04/18 15:06:44 $
 + *
 + *  The Contents of this file are made available subject to
 + *  the terms of GNU Lesser General Public License Version 2.1.
@@ -627,6 +632,7 @@
 +#endif
 +
 +#include <com/sun/star/sheet/DataPilotTablePositionData.idl>
++#include <com/sun/star/lang/IllegalArgumentException.idl>
 +
 +module com {  module sun {  module star {  module sheet {
 +
@@ -694,7 +700,8 @@
 +
 +        @see com::sun::star::sheet::DataPilotOutputRangeType
 +     */
-+    com::sun::star::table::CellRangeAddress getOutputRangeByType( [in] long nType );
++    com::sun::star::table::CellRangeAddress getOutputRangeByType( [in] long nType ) 
++        raises (com::sun::star::lang::IllegalArgumentException);
 +};
 +
 +}; }; }; };
@@ -803,21 +810,45 @@
 +
 +#endif
 +
---- offapi/com/sun/star/sheet/makefile.mk.orig	2008-01-15 11:37:11.000000000 -0500
-+++ offapi/com/sun/star/sheet/makefile.mk	2008-01-15 11:40:44.000000000 -0500
-@@ -315,7 +315,14 @@
- 	XViewPanesSupplier.idl\
- 	XViewSplitable.idl\
- 	XVolatileResult.idl\
--	_NamedRange.idl
-+	_NamedRange.idl\
-+	DataPilotTablePositionData.idl\
-+	DataPilotTablePositionType.idl\
+Index: offapi/com/sun/star/sheet/makefile.mk
+===================================================================
+RCS file: /cvs/api/offapi/com/sun/star/sheet/makefile.mk,v
+retrieving revision 1.27
+retrieving revision 1.24.138.5
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.27 -r1.24.138.5
+--- offapi/com/sun/star/sheet/makefile.mk	5 Feb 2008 15:53:10 -0000	1.27
++++ offapi/com/sun/star/sheet/makefile.mk	25 Feb 2008 14:45:39 -0000	1.24.138.5
+@@ -101,6 +101,7 @@
+ 	DataPilotItem.idl\
+ 	DataPilotItems.idl\
+ 	DataPilotItemsEnumeration.idl\
 +	DataPilotOutputRangeType.idl\
+ 	DataPilotSource.idl\
+ 	DataPilotSourceDimension.idl\
+ 	DataPilotSourceDimensions.idl\
+@@ -111,6 +112,10 @@
+ 	DataPilotSourceMember.idl\
+ 	DataPilotSourceMembers.idl\
+ 	DataPilotTable.idl\
 +	DataPilotTableHeaderData.idl\
++	DataPilotTablePositionData.idl\
++	DataPilotTablePositionType.idl\
 +	DataPilotTableResultData.idl\
+ 	DataPilotTables.idl\
+ 	DataPilotTablesEnumeration.idl\
+ 	DataResult.idl\
+@@ -244,12 +249,14 @@
+ 	XDataPilotMemberResults.idl\
+ 	XDataPilotResults.idl\
+ 	XDataPilotTable.idl\
 +	XDataPilotTable2.idl\
-+	XDrillDownDataSupplier.idl
- 
- # ------------------------------------------------------------------
- 
+ 	XDataPilotTables.idl\
+ 	XDataPilotTablesSupplier.idl\
+ 	XDatabaseRange.idl\
+ 	XDatabaseRanges.idl\
+ 	XDimensionsSupplier.idl\
+ 	XDocumentAuditing.idl\
++	XDrillDownDataSupplier.idl\
+ 	XEnhancedMouseClickBroadcaster.idl\
+ 	XExternalSheetName.idl\
+ 	XFillAcrossSheet.idl\

Modified: trunk/patches/src680/sc-calc-datapilot-drilldown.diff
==============================================================================
--- trunk/patches/src680/sc-calc-datapilot-drilldown.diff	(original)
+++ trunk/patches/src680/sc-calc-datapilot-drilldown.diff	Mon Apr 21 04:25:54 2008
@@ -1,13 +1,15 @@
+? sc/Debug
 ? sc/sc.diff
 ? sc/sc.vpj
+? sc/qa/unoapi/sc.sce.single
 Index: sc/inc/dapiuno.hxx
 ===================================================================
 RCS file: /cvs/sc/sc/inc/dapiuno.hxx,v
 retrieving revision 1.9
-retrieving revision 1.9.508.4
-diff -u -b -I $Revision.*$ -I $Author.*$ -r1.9 -r1.9.508.4
+retrieving revision 1.9.508.5
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.9 -r1.9.508.5
 --- sc/inc/dapiuno.hxx	13 Jan 2006 16:51:24 -0000	1.9
-+++ sc/inc/dapiuno.hxx	30 Nov 2007 00:13:25 -0000	1.9.508.4
++++ sc/inc/dapiuno.hxx	18 Apr 2008 15:07:06 -0000	1.9.508.5
 @@ -56,9 +56,7 @@
  #include <svtools/itemprop.hxx>
  #endif
@@ -40,7 +42,7 @@
  {
  private:
  	SCTAB					nTab;
-@@ -392,6 +395,21 @@
+@@ -392,6 +395,22 @@
  								throw(::com::sun::star::uno::RuntimeException);
  	virtual void SAL_CALL	refresh() throw(::com::sun::star::uno::RuntimeException);
  
@@ -57,7 +59,8 @@
 +                                throw(::com::sun::star::uno::RuntimeException);
 +
 +    virtual ::com::sun::star::table::CellRangeAddress SAL_CALL getOutputRangeByType( sal_Int32 nType )
-+                                throw(::com::sun::star::uno::RuntimeException);
++                                throw(::com::sun::star::lang::IllegalArgumentException,
++                                      ::com::sun::star::uno::RuntimeException);
 +
  							// XTypeProvider (overloaded)
  	virtual ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Type > SAL_CALL getTypes()
@@ -67,17 +70,17 @@
 RCS file: sc/inc/dpcachetable.hxx
 diff -N sc/inc/dpcachetable.hxx
 --- /dev/null	1 Jan 1970 00:00:00 -0000
-+++ sc/inc/dpcachetable.hxx	29 Oct 2007 17:44:39 -0000	1.1.2.1
-@@ -0,0 +1,189 @@
++++ sc/inc/dpcachetable.hxx	20 Apr 2008 02:46:57 -0000	1.1.2.7
+@@ -0,0 +1,197 @@
 +/*************************************************************************
 + *
 + *  OpenOffice.org - a multi-platform office productivity suite
 + *
 + *  $RCSfile: dpcachetable.hxx,v $
 + *
-+ *  $Revision: 1.1.2.1 $
++ *  $Revision: 1.1.2.7 $
 + *
-+ *  last change: $Author: kohei $ $Date: 2007/10/29 17:44:39 $
++ *  last change: $Author: kohei $ $Date: 2008/04/20 02:46:57 $
 + *
 + *  The Contents of this file are made available subject to
 + *  the terms of GNU Lesser General Public License Version 2.1.
@@ -133,6 +136,7 @@
 +class ScDocument;
 +class ScRange;
 +class ScDPDimension;
++struct ScDPItemData;
 +
 +class ScSharedStringTable
 +{
@@ -159,13 +163,16 @@
 +class ScDPCacheTable
 +{
 +public:
++    typedef ::std::hash_map<long, ::std::vector<ScDPItemData> > GroupFilterType;
++
 +    /** individual cell within table. */
 +    struct Cell
 +    {
++        SCROW       mnCategoryRef;
 +        sal_Int32   mnStrId;
++        sal_uInt8   mnType;
 +        double      mfValue;
 +        bool        mbNumeric;
-+        sal_uInt8   mnType;
 +
 +        Cell();
 +    };
@@ -175,6 +182,7 @@
 +    {
 +        sal_Int32   mnFieldIndex;
 +        sal_Int32   mnMatchStrId;
++        double      mfValue;
 +
 +        Filter();
 +    };
@@ -188,7 +196,8 @@
 +
 +    /** 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);
++    void fillTable(ScDocument* pDoc, const ScRange& rRange, const ScQueryParam& rQuery, BOOL* pSpecial, 
++                   bool bIgnoreEmptyRows);
 +
 +    /** Fill the internal table from database connection object.  This function
 +        assumes that the first row is the column header. */
@@ -207,7 +216,7 @@
 +    /** 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 ::ScDPCacheTable::Cell* getCell(SCCOL nCol, SCROW nRow) const;
++    const ::ScDPCacheTable::Cell* getCell(SCCOL nCol, SCROW nRow, bool bRepeatIfEmpty = false) const;
 +
 +    const String* getFieldName(sal_Int32 nIndex) const;
 +
@@ -221,8 +230,10 @@
 +        get an empty collection. */
 +    const TypedStrCollection& getFieldEntries(sal_Int32 nIndex) const;
 +
-+    void filterTable(const ::com::sun::star::uno::Sequence< ::com::sun::star::sheet::DataPilotFieldFilter >& rFilters,
-+                     ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > >& rTabData);
++    void filterTable(const ::std::hash_map<long, ScDPItemData>& rFilters,
++                     ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > >& rTabData,
++                     bool bRepeatIfEmpty = false,
++                     GroupFilterType* pGroupFilter = NULL);
 +
 +    void clear();
 +    void swap(ScDPCacheTable& rOther);
@@ -262,10 +273,10 @@
 ===================================================================
 RCS file: /cvs/sc/sc/inc/dpgroup.hxx,v
 retrieving revision 1.4
-retrieving revision 1.4.570.2
-diff -u -b -I $Revision.*$ -I $Author.*$ -r1.4 -r1.4.570.2
+retrieving revision 1.4.570.3
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.4 -r1.4.570.3
 --- sc/inc/dpgroup.hxx	8 Sep 2005 17:34:35 -0000	1.4
-+++ sc/inc/dpgroup.hxx	6 Dec 2007 07:06:14 -0000	1.4.570.2
++++ sc/inc/dpgroup.hxx	17 Apr 2008 13:10:39 -0000	1.4.570.3
 @@ -37,6 +37,7 @@
  #define SC_DPGROUP_HXX
  
@@ -274,7 +285,32 @@
  
  #ifndef SC_DPTABDAT_HXX
  #include "dptabdat.hxx"
-@@ -180,13 +181,17 @@
+@@ -102,6 +103,8 @@
+     const ScDPItemData& GetName() const     { return aGroupName; }
+     bool        HasElement( const ScDPItemData& rData ) const;
+     bool        HasCommonElement( const ScDPGroupItem& rOther ) const;
++
++    void        GetAllElements( ::std::vector<ScDPItemData>& rElements ) const;
+ };
+ 
+ typedef ::std::vector<ScDPGroupItem> ScDPGroupItemVec;
+@@ -132,12 +135,15 @@
+     const TypedStrCollection& GetColumnEntries( const TypedStrCollection& rOriginal, ScDocument* pDoc ) const;
+     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;
+ 
+     const ScDPDateGroupHelper* GetDateHelper() const    { return pDateHelper; }
+ 
+     void        MakeDateHelper( const ScDPNumGroupInfo& rInfo, sal_Int32 nPart );
+ 
+     void        DisposeData();
++
++    size_t      GetItemCount() const { return aItems.size(); }
+ };
+ 
+ typedef ::std::vector<ScDPGroupDimension> ScDPGroupDimensionVec;
+@@ -180,13 +186,17 @@
  
  class ScDPGroupTableData : public ScDPTableData
  {
@@ -292,7 +328,7 @@
      long*       CopyFields( const long* pSourceDims, long nCount );
  
      bool        IsNumGroupDimension( long nDimension ) const;
-@@ -213,8 +218,12 @@
+@@ -213,8 +223,13 @@
      virtual void                    DisposeData();
      virtual void                    SetEmptyFlags( BOOL bIgnoreEmptyRows, BOOL bRepeatIfEmpty );
  
@@ -300,8 +336,9 @@
 -    virtual BOOL                    GetNextRow( const ScDPTableIteratorParam& rParam );
 +    virtual void                    CreateCacheTable();
 +    virtual void                    FilterCacheTable(const ::std::vector<ScDPDimension*>& rPageDims);
-+    virtual void                    GetDrillDownData(const ::com::sun::star::uno::Sequence< ::com::sun::star::sheet::DataPilotFieldFilter >& rFilters,
-+                                                     ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > >& rTabData);
++    virtual void                    GetDrillDownData(const ::std::hash_map<long, ScDPItemData>& rFilters,
++                                                     ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > >& rTabData,
++                                                     GroupFilterType* pGroupFilter = NULL);
 +    virtual void                    CalcResults(CalcInfo& rInfo, bool bAutoShow);
 +    virtual const ScDPCacheTable&   GetCacheTable() const;
  
@@ -492,10 +529,10 @@
 ===================================================================
 RCS file: /cvs/sc/sc/inc/dpsdbtab.hxx,v
 retrieving revision 1.3
-retrieving revision 1.3.570.2
-diff -u -b -I $Revision.*$ -I $Author.*$ -r1.3 -r1.3.570.2
+retrieving revision 1.3.570.3
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.3 -r1.3.570.3
 --- sc/inc/dpsdbtab.hxx	8 Sep 2005 17:35:48 -0000	1.3
-+++ sc/inc/dpsdbtab.hxx	6 Dec 2007 07:06:15 -0000	1.3.570.2
++++ sc/inc/dpsdbtab.hxx	17 Apr 2008 13:10:39 -0000	1.3.570.3
 @@ -50,6 +50,11 @@
  #include "dptabdat.hxx"
  #endif
@@ -516,7 +553,7 @@
  
  public:
  					ScDatabaseDPData(
-@@ -94,8 +98,12 @@
+@@ -94,8 +98,13 @@
  	virtual void					DisposeData();
  	virtual void					SetEmptyFlags( BOOL bIgnoreEmptyRows, BOOL bRepeatIfEmpty );
  
@@ -524,8 +561,9 @@
 -	virtual BOOL					GetNextRow( const ScDPTableIteratorParam& rParam );
 +    virtual void                    CreateCacheTable();
 +    virtual void                    FilterCacheTable(const ::std::vector<ScDPDimension*>& rPageDims);
-+    virtual void                    GetDrillDownData(const ::com::sun::star::uno::Sequence< ::com::sun::star::sheet::DataPilotFieldFilter >& rFilters,
-+                                                     ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > >& rTabData);
++    virtual void                    GetDrillDownData(const ::std::hash_map<long, ScDPItemData>& rFilters,
++                                                     ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > >& rTabData,
++                                                     GroupFilterType* pGroupFilter = NULL);
 +    virtual void                    CalcResults(CalcInfo& rInfo, bool bAutoShow);
 +    virtual const ScDPCacheTable&   GetCacheTable() const;
  };
@@ -535,10 +573,10 @@
 ===================================================================
 RCS file: /cvs/sc/sc/inc/dpshttab.hxx,v
 retrieving revision 1.4
-retrieving revision 1.4.570.2
-diff -u -b -I $Revision.*$ -I $Author.*$ -r1.4 -r1.4.570.2
+retrieving revision 1.4.570.4
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.4 -r1.4.570.4
 --- sc/inc/dpshttab.hxx	8 Sep 2005 17:36:03 -0000	1.4
-+++ sc/inc/dpshttab.hxx	6 Dec 2007 07:06:15 -0000	1.4.570.2
++++ sc/inc/dpshttab.hxx	17 Apr 2008 13:10:39 -0000	1.4.570.4
 @@ -48,6 +48,14 @@
  #include "address.hxx"
  #endif
@@ -562,16 +600,19 @@
  
  public:
  					ScSheetDPData( ScDocument* pD, const ScSheetSourceDesc& rDesc );
-@@ -85,8 +92,12 @@
+@@ -85,8 +92,15 @@
  	virtual void					DisposeData();
  	virtual void					SetEmptyFlags( BOOL bIgnoreEmptyRows, BOOL bRepeatIfEmpty );
  
 -	virtual void					ResetIterator();
 -	virtual BOOL					GetNextRow( const ScDPTableIteratorParam& rParam );
++    virtual bool                    IsRepeatIfEmpty();
++
 +    virtual void                    CreateCacheTable();
 +    virtual void                    FilterCacheTable(const ::std::vector<ScDPDimension*>& rPageDims);
-+    virtual void                    GetDrillDownData(const ::com::sun::star::uno::Sequence< ::com::sun::star::sheet::DataPilotFieldFilter >& rFilters,
-+                                                     ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > >& rData);
++    virtual void                    GetDrillDownData(const ::std::hash_map<long, ScDPItemData>& rFilters,
++                                                     ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > >& rData,
++                                                     GroupFilterType* pGroupFilter = NULL);
 +    virtual void                    CalcResults(CalcInfo& rInfo, bool bAutoShow);
 +    virtual const ScDPCacheTable&   GetCacheTable() const;
  };
@@ -581,11 +622,11 @@
 ===================================================================
 RCS file: /cvs/sc/sc/inc/dptabdat.hxx,v
 retrieving revision 1.6
-retrieving revision 1.6.216.2
-diff -u -b -I $Revision.*$ -I $Author.*$ -r1.6 -r1.6.216.2
+retrieving revision 1.6.216.4
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.6 -r1.6.216.4
 --- sc/inc/dptabdat.hxx	25 Jan 2007 11:03:15 -0000	1.6
-+++ sc/inc/dptabdat.hxx	6 Dec 2007 07:06:15 -0000	1.6.216.2
-@@ -40,11 +40,21 @@
++++ sc/inc/dptabdat.hxx	17 Apr 2008 13:10:39 -0000	1.6.216.4
+@@ -40,11 +40,22 @@
  #include "address.hxx"
  #endif
  
@@ -597,6 +638,7 @@
  
 +#include <vector>
 +#include <set>
++#include <hash_map>
 +
 +namespace com { namespace sun { namespace star { namespace sheet {
 +    struct DataPilotFieldFilter;
@@ -607,7 +649,7 @@
  
  // -----------------------------------------------------------------------
  
-@@ -65,6 +75,7 @@
+@@ -65,6 +76,7 @@
  #define SC_DAPI_LEVEL_WEEK		1
  #define SC_DAPI_LEVEL_WEEKDAY	2
  
@@ -615,7 +657,7 @@
  // --------------------------------------------------------------------
  //
  //	base class ScDPTableData to allow implementation with tabular data
-@@ -105,29 +116,12 @@
+@@ -105,29 +117,12 @@
  	void	Set( double fV, BYTE nT ) { fValue = fV; nType = nT; }
  };
  
@@ -651,10 +693,12 @@
  
  class ScDPTableData
  {
-@@ -138,6 +132,25 @@
+@@ -138,6 +133,31 @@
  	long 	nLastRet;
  
  public:
++    typedef ::std::hash_map<long, ::std::vector<ScDPItemData> > GroupFilterType;
++
 +    /** This structure stores dimension information used when calculating
 +        results.  These data are read only during result calculation, so it
 +        should be passed as a const instance. */
@@ -672,27 +716,34 @@
 +        ScDPInitState*                  pInitState;
 +        ScDPResultMember*               pColRoot;
 +        ScDPResultMember*               pRowRoot;
++
++        bool                            bRepeatIfEmpty;
++
++        CalcInfo();
 +    };
 +
  				ScDPTableData();
  	virtual		~ScDPTableData();
  
-@@ -155,8 +168,12 @@
+@@ -155,8 +175,15 @@
  	virtual void					DisposeData() = 0;
  	virtual void					SetEmptyFlags( BOOL bIgnoreEmptyRows, BOOL bRepeatIfEmpty ) = 0;
  
 -	virtual void					ResetIterator() = 0;
 -	virtual BOOL					GetNextRow( const ScDPTableIteratorParam& rParam ) = 0;
++    virtual bool                    IsRepeatIfEmpty();
++
 +    virtual void                    CreateCacheTable();
 +    virtual void                    FilterCacheTable(const ::std::vector<ScDPDimension*>& rPageDims);
-+    virtual void                    GetDrillDownData(const ::com::sun::star::uno::Sequence< ::com::sun::star::sheet::DataPilotFieldFilter >& aFilters,
-+                                                     ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > >& rTabData);
++    virtual void                    GetDrillDownData(const ::std::hash_map<long, ScDPItemData>& rFilters,
++                                                     ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Any > >& rData,
++                                                     GroupFilterType* pGroupFilter = NULL);
 +    virtual void                    CalcResults(CalcInfo& rInfo, bool bAutoShow);
 +    virtual const ScDPCacheTable&   GetCacheTable() const = 0;
  
                                      // overloaded in ScDPGroupTableData:
      virtual BOOL                    IsBaseForGroup(long nDim) const;
-@@ -166,6 +183,25 @@
+@@ -166,6 +193,25 @@
                                                 const ScDPItemData& rBaseData, long nBaseIndex ) const;
      virtual BOOL                    HasCommonElement( const ScDPItemData& rFirstData, long nFirstIndex,
                                                        const ScDPItemData& rSecondData, long nSecondIndex ) const;
@@ -722,19 +773,11 @@
 ===================================================================
 RCS file: /cvs/sc/sc/inc/dptabres.hxx,v
 retrieving revision 1.7
-retrieving revision 1.7.202.6
-diff -u -b -I $Revision.*$ -I $Author.*$ -r1.7 -r1.7.202.6
+retrieving revision 1.7.202.7
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.7 -r1.7.202.7
 --- sc/inc/dptabres.hxx	27 Feb 2007 11:55:52 -0000	1.7
-+++ sc/inc/dptabres.hxx	6 Dec 2007 07:06:15 -0000	1.7.202.6
-@@ -302,15 +302,17 @@
-                                     const ScDPItemData& rBaseData, long nBaseIndex ) const;
-     BOOL                HasCommonElement( const ScDPItemData& rFirstData, long nFirstIndex,
-                                           const ScDPItemData& rSecondData, long nSecondIndex ) const;
-+
-+    void                Debug() const;
- };
- 
- 
++++ sc/inc/dptabres.hxx	21 Apr 2008 03:07:57 -0000	1.7.202.7
+@@ -308,9 +308,9 @@
  class ScDPResultMember
  {
  private:
@@ -747,7 +790,7 @@
  	const ScDPMember*		pMemberDesc;			//! Ref
  	ScDPResultDimension*	pChildDimension;
  	ScDPDataMember*			pDataRoot;
-@@ -322,15 +324,20 @@
+@@ -322,15 +322,20 @@
  	ScDPAggData				aColTotal;				// to store column totals
  
  public:
@@ -773,7 +816,7 @@
  	String				GetName() const;
      void                FillItemData( ScDPItemData& rData ) const;
  	BOOL				IsValid() const;
-@@ -343,15 +350,15 @@
+@@ -343,15 +348,15 @@
  	long				GetSubTotalCount( long* pUserSubStart = NULL ) const;
  
  	BOOL				IsNamedItem( const ScDPItemData& r ) const;
@@ -794,7 +837,7 @@
  
  	void				FillMemberResults( com::sun::star::uno::Sequence<
  												com::sun::star::sheet::MemberResult>* pSequences,
-@@ -391,15 +398,15 @@
+@@ -391,15 +396,15 @@
  class ScDPDataMember
  {
  private:
@@ -813,7 +856,7 @@
  						~ScDPDataMember();
  
  	void				InitFrom( const ScDPResultDimension* pDim );
-@@ -412,7 +419,7 @@
+@@ -412,7 +417,7 @@
  
  	BOOL				HasHiddenDetails() const;
  
@@ -822,7 +865,7 @@
  									const ScDPSubTotalState& rSubState );
  
  	BOOL				HasError( long nMeasure, const ScDPSubTotalState& rSubState ) const;
-@@ -462,7 +469,7 @@
+@@ -462,7 +467,7 @@
  	typedef	std::hash_map <ScDPItemData, ScDPResultMember *, MemberHashFunc>	MemberHash;
  
  private:
@@ -831,7 +874,7 @@
  	MemberArray				maMemberArray;
  	MemberHash				maMemberHash;
  	BOOL                    bInitialized;
-@@ -479,23 +486,28 @@
+@@ -479,23 +484,28 @@
  
  	ScDPResultMember* 		FindMember( const ScDPItemData& rData ) const;
  public:
@@ -869,7 +912,7 @@
  
  	void				FillMemberResults( com::sun::star::uno::Sequence<
  												com::sun::star::sheet::MemberResult>* pSequences,
-@@ -554,17 +566,17 @@
+@@ -554,17 +564,17 @@
  class ScDPDataDimension
  {
  private:
@@ -992,12 +1035,12 @@
 Index: sc/inc/unonames.hxx
 ===================================================================
 RCS file: /cvs/sc/sc/inc/unonames.hxx,v
-retrieving revision 1.74
-retrieving revision 1.74.106.1
-diff -u -b -I $Revision.*$ -I $Author.*$ -r1.74 -r1.74.106.1
---- sc/inc/unonames.hxx	6 Jul 2007 12:31:28 -0000	1.74
-+++ sc/inc/unonames.hxx	6 Dec 2007 16:40:33 -0000	1.74.106.1
-@@ -542,6 +542,10 @@
+retrieving revision 1.79
+retrieving revision 1.74.106.3
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.79 -r1.74.106.3
+--- sc/inc/unonames.hxx	7 Mar 2008 14:04:16 -0000	1.79
++++ sc/inc/unonames.hxx	12 Mar 2008 18:01:48 -0000	1.74.106.3
+@@ -555,6 +555,10 @@
  #define SC_UNO_REPEATIF				"RepeatIfEmpty"
  #define SC_UNO_DATADESC				"DataDescription"
  #define SC_UNO_NUMBERFO				"NumberFormat"
@@ -1013,17 +1056,17 @@
 RCS file: sc/source/core/data/dpcachetable.cxx
 diff -N sc/source/core/data/dpcachetable.cxx
 --- /dev/null	1 Jan 1970 00:00:00 -0000
-+++ sc/source/core/data/dpcachetable.cxx	31 Oct 2007 19:58:43 -0000	1.1.2.4
-@@ -0,0 +1,657 @@
++++ sc/source/core/data/dpcachetable.cxx	17 Apr 2008 13:11:10 -0000	1.1.2.10
+@@ -0,0 +1,803 @@
 +/*************************************************************************
 + *
 + *  OpenOffice.org - a multi-platform office productivity suite
 + *
 + *  $RCSfile: dpcachetable.cxx,v $
 + *
-+ *  $Revision: 1.1.2.4 $
++ *  $Revision: 1.1.2.10 $
 + *
-+ *  last change: $Author: kohei $ $Date: 2007/10/31 19:58:43 $
++ *  last change: $Author: kohei $ $Date: 2008/04/17 13:11:10 $
 + *
 + *  The Contents of this file are made available subject to
 + *  the terms of GNU Lesser General Public License Version 2.1.
@@ -1059,6 +1102,7 @@
 +
 +#include <stdio.h>
 +
++#include <com/sun/star/i18n/LocaleDataItem.hpp>
 +#include <com/sun/star/sdbc/DataType.hpp>
 +#include <com/sun/star/sdbc/XRow.hpp>
 +#include <com/sun/star/sdbc/XRowSet.hpp>
@@ -1067,11 +1111,16 @@
 +#include <com/sun/star/util/Date.hpp>
 +#include <com/sun/star/sheet/DataPilotFieldFilter.hpp>
 +
++#include <memory>
++
 +using namespace ::com::sun::star;
 +
 +using ::rtl::OUString;
 +using ::std::vector;
 +using ::std::set;
++using ::std::hash_map;
++using ::std::auto_ptr;
++using ::com::sun::star::i18n::LocaleDataItem;
 +using ::com::sun::star::uno::Exception;
 +using ::com::sun::star::uno::Reference;
 +using ::com::sun::star::uno::Sequence;
@@ -1138,13 +1187,18 @@
 +// ----------------------------------------------------------------------------
 +
 +ScDPCacheTable::Cell::Cell() :
++    mnCategoryRef(0),
++    mnStrId(ScSharedStringTable::EMPTY),
++    mnType(SC_VALTYPE_EMPTY),
 +    mfValue(0.0),
-+    mbNumeric(false),
-+    mnType(SC_VALTYPE_EMPTY)
++    mbNumeric(false)
 +{
 +}
 +
-+ScDPCacheTable::Filter::Filter()
++ScDPCacheTable::Filter::Filter() :
++    mnFieldIndex(-1),
++    mnMatchStrId(ScSharedStringTable::EMPTY),
++    mfValue(0.0)
 +{
 +}
 +
@@ -1174,7 +1228,8 @@
 +    return maTable.empty() ? 0 : maTable[0].size();
 +}
 +
-+void ScDPCacheTable::fillTable(ScDocument* pDoc, const ScRange& rRange, const ScQueryParam& rQuery, BOOL* pSpecial)
++void ScDPCacheTable::fillTable(ScDocument* pDoc, const ScRange& rRange, const ScQueryParam& rQuery, BOOL* pSpecial,
++                               bool bIgnoreEmptyRows)
 +{
 +    SCTAB nTab = rRange.aStart.Tab();
 +    SCCOL nStartCol = rRange.aStart.Col();
@@ -1210,6 +1265,8 @@
 +        maFieldEntries.push_back(p);
 +    }
 +
++    vector<SCROW> aLastNonEmptyRows(nColCount, 0);
++    
 +    // Data rows
 +    for (SCROW nRow = 1; nRow < nRowCount; ++nRow)
 +    {
@@ -1217,6 +1274,12 @@
 +            // 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>() );
@@ -1226,7 +1289,13 @@
 +        {
 +            maTable.back().push_back( ScDPCacheTable::Cell() );
 +            Cell& rCell = maTable.back().back();
-+                
++            rCell.mnCategoryRef = maTable.size()-1;
++
++            if (nRow == 0 || pDoc->HasData(nStartCol + nCol, nStartRow + nRow, nTab))
++                aLastNonEmptyRows[nCol] = maTable.size()-1;
++            else
++                rCell.mnCategoryRef = aLastNonEmptyRows[nCol];
++
 +            String aStr;
 +            pDoc->GetString(nStartCol + nCol, nStartRow + nRow, nTab, aStr);
 +            rCell.mnStrId = maStringTable.insertString(aStr);
@@ -1396,7 +1465,7 @@
 +
 +bool ScDPCacheTable::isRowActive(sal_Int32 nRow) const
 +{
-+    if (nRow < 0 || nRow >= maRowsVisible.size())
++    if (nRow < 0 || static_cast<size_t>(nRow) >= maRowsVisible.size())
 +        // row index out of bound
 +        return false;
 +
@@ -1437,7 +1506,7 @@
 +    }
 +}
 +
-+const ::ScDPCacheTable::Cell* ScDPCacheTable::getCell(SCCOL nCol, SCROW nRow) const
++const ::ScDPCacheTable::Cell* ScDPCacheTable::getCell(SCCOL nCol, SCROW nRow, bool bRepeatIfEmpty) const
 +{
 +    if ( nRow >= static_cast<SCROW>(maTable.size()) )
 +        return NULL;
@@ -1446,7 +1515,11 @@
 +    if ( nCol < 0 || static_cast<size_t>(nCol) >= rRow.size() )
 +        return NULL;
 +
-+    return &rRow.at(nCol);
++    const Cell* pCell = &rRow.at(nCol);
++    if (bRepeatIfEmpty && pCell && pCell->mnType == SC_VALTYPE_EMPTY)
++        pCell = getCell(nCol, pCell->mnCategoryRef, false);
++
++    return pCell;
 +}
 +
 +const String* ScDPCacheTable::getFieldName(sal_Int32 nIndex) const
@@ -1476,7 +1549,7 @@
 +
 +const TypedStrCollection& ScDPCacheTable::getFieldEntries(sal_Int32 nIndex) const
 +{
-+    if (nIndex < 0 || nIndex >= maFieldEntries.size())
++    if (nIndex < 0 || static_cast<size_t>(nIndex) >= maFieldEntries.size())
 +    {
 +        fprintf(stdout, "ScDPCacheTable::getFieldEntries: OUT OF BOUND\n");fflush(stdout);
 +        // index out of bound.  Hopefully this code will never be reached.
@@ -1487,9 +1560,33 @@
 +    return *maFieldEntries[nIndex].get();
 +}
 +
-+void ScDPCacheTable::filterTable(const Sequence<DataPilotFieldFilter>& rFilters, 
-+                                 Sequence< Sequence<Any> >& rTabData)
++void ScDPCacheTable::filterTable(const hash_map<long, ScDPItemData>& rFilters, 
++                                 Sequence< Sequence<Any> >& rTabData, bool bRepeatIfEmpty,
++                                 GroupFilterType* pGroupFilter)
 +{
++#if 0    
++    if (pGroupFilter)
++    {
++        GroupFilterType::const_iterator itrEnd = pGroupFilter->end();
++        for (GroupFilterType::const_iterator itr = pGroupFilter->begin(); itr != itrEnd; ++itr)
++        {
++            const String* fieldName = getFieldName(itr->first);
++            if (!fieldName)
++                continue;
++
++            fprintf(stdout, "ScDPCacheTable::filterTable:   group field name = '%s'\n",
++                    rtl::OUStringToOString(*fieldName, RTL_TEXTENCODING_UTF8).getStr());
++            const vector<ScDPItemData>& rGrpItems = itr->second;
++            vector<ScDPItemData>::const_iterator itrItemEnd = rGrpItems.end();
++            for (vector<ScDPItemData>::const_iterator itrItem = rGrpItems.begin(); itrItem != itrItemEnd; ++itrItem)
++            {
++                fprintf(stdout, "ScDPCacheTable::filterTable:     match name = '%s'\n",
++                        rtl::OUStringToOString(itrItem->aString, RTL_TEXTENCODING_UTF8).getStr());
++            }
++        }
++    }
++#endif    
++
 +    sal_Int32 nRowSize = getRowSize();
 +    sal_Int32 nColSize = getColSize();
 +
@@ -1497,19 +1594,6 @@
 +        // no data to filter.
 +        return;
 +
-+    // Convert filters first.
-+    vector<Filter> filters;
-+    sal_Int32 nFilterSize = rFilters.getLength();
-+    filters.reserve(nFilterSize);
-+    for (sal_Int32 i = 0; i < nFilterSize; ++i)
-+    {
-+        Filter fil;
-+        fil.mnFieldIndex = getFieldIndex(String(rFilters[i].FieldName));
-+        fil.mnMatchStrId = getStringId(String(rFilters[i].MatchValue));
-+        if (fil.mnFieldIndex >= 0)
-+            filters.push_back(fil);
-+    }
-+    
 +    // Row first, then column.
 +    vector< Sequence<Any> > tableData;
 +    tableData.reserve(nRowSize+1);
@@ -1529,6 +1613,47 @@
 +    }
 +    tableData.push_back(headerRow);
 +
++    // Convert filters.
++    vector<Filter> filters;
++    size_t nFilterSize = rFilters.size();
++    filters.reserve(nFilterSize);
++    {
++        hash_map<long, ScDPItemData>::const_iterator itrEnd = rFilters.end();
++        for (hash_map<long, ScDPItemData>::const_iterator itr = rFilters.begin(); itr != itrEnd; ++itr)
++        {
++            const ScDPItemData& rItem = itr->second;
++            Filter fil;
++            fil.mnFieldIndex = itr->first;
++            fil.mnMatchStrId = getStringId(itr->second.aString);
++            fil.mfValue = itr->second.fValue;
++            if (fil.mnFieldIndex >= 0)
++                filters.push_back(fil);
++        }
++    }
++
++    hash_map<long, vector<Filter> > groupFilters;
++    if (pGroupFilter)
++    {
++        GroupFilterType::const_iterator itrEnd = pGroupFilter->end();
++        for (GroupFilterType::const_iterator itr = pGroupFilter->begin(); itr != itrEnd; ++itr)
++        {
++            long nField = itr->first;
++            vector<Filter> aGrpItems;
++            const vector<ScDPItemData>& rGrpItems = itr->second;
++            vector<ScDPItemData>::const_iterator itrItemEnd = rGrpItems.end();
++            for (vector<ScDPItemData>::const_iterator itrItem = rGrpItems.begin(); itrItem != itrItemEnd; ++itrItem)
++            {
++                Filter fil;
++                fil.mnFieldIndex = itr->first;
++                fil.mnMatchStrId = getStringId(itrItem->aString);
++                fil.mfValue = itrItem->fValue;
++                aGrpItems.push_back(fil);
++            }
++
++            groupFilters.insert( hash_map<long, vector<Filter> >::value_type(nField, aGrpItems) );
++        }
++    }
++
 +    // Data rows.
 +    for (sal_Int32 nRow = 0; nRow < nRowSize; ++nRow)
 +    {
@@ -1537,45 +1662,109 @@
 +            continue;
 +
 +        bool bRetainRow = true;
-+        vector<Filter>::const_iterator itr, itrEnd = filters.end();
-+        for (itr = filters.begin(); itr != itrEnd; ++itr)
 +        {
-+            if (itr->mnFieldIndex >= nColSize)
++            vector<Filter>::const_iterator itr, itrEnd = filters.end();
++            for (itr = filters.begin(); itr != itrEnd; ++itr)
 +            {
-+                // specified field is outside the source data columns.
-+                bRetainRow = false;
-+                break;
++                if (itr->mnFieldIndex >= nColSize)
++                    // specified field is outside the source data columns.  Don't use
++                    // this criteria.
++                    continue;
++    
++                const Cell* pCell = getCell(itr->mnFieldIndex, nRow, bRepeatIfEmpty);
++                if (!pCell)
++                {
++                    // This should never happen, but just in case...
++                    bRetainRow = false;
++                    break;
++                }
++    
++                if (pCell->mnStrId != itr->mnMatchStrId &&
++                    (!pCell->mbNumeric || pCell->mfValue != itr->mfValue))
++                {
++                    bRetainRow = false;
++                    break;
++                }    
 +            }
++        }
 +
-+            if ( maTable[nRow][itr->mnFieldIndex].mnStrId != itr->mnMatchStrId )
++        if (!bRetainRow)
++            continue;
++
++        // filter for grouping.
++
++        if (!groupFilters.empty())
++        {
++            hash_map<long, vector<Filter> >::const_iterator itrEnd = groupFilters.end();
++            for (hash_map<long, vector<Filter> >::const_iterator itr = groupFilters.begin(); itr != itrEnd; ++itr)
 +            {
-+                // The string value does not match.
-+                bRetainRow = false;
-+                break;
++                if (itr->first >= nColSize)
++                    // specified field is outside the source data columns.  Don't use
++                    // this criteria.
++                    continue;
++
++                const Cell* pCell = getCell(itr->first, nRow, bRepeatIfEmpty);
++                if (!pCell)
++                {
++                    // This should never happen, but just in case...
++                    bRetainRow = false;
++                    break;
++                }
++
++                const vector<Filter>& rFilItems = itr->second;
++                vector<Filter>::const_iterator itr2End = rFilItems.end();
++                bool bGroupMatch = false;
++                for (vector<Filter>::const_iterator itr2 = rFilItems.begin(); itr2 != itr2End; ++itr2)
++                {
++                    if (pCell->mnStrId == itr2->mnMatchStrId ||
++                        (pCell->mbNumeric && pCell->mfValue == itr2->mfValue))
++                    {
++                        bGroupMatch = true;
++                        break;
++                    }
++                }
++
++                if (!bGroupMatch)
++                {
++                    bRetainRow = false;
++                    break;
++                }
 +            }
 +        }
 +
-+        if (bRetainRow)
++        if (!bRetainRow)
++            continue;
++
++        // Insert this row into table.
++
++        Sequence<Any> row(nColSize);
++        for (sal_Int32 nCol = 0; nCol < nColSize; ++nCol)
 +        {
-+            Sequence<Any> row(nColSize);
-+            for (sal_Int32 nCol = 0; nCol < nColSize; ++nCol)
++            Any any;
++            const Cell* pCell = getCell(nCol, nRow, bRepeatIfEmpty);
++            if (!pCell)
 +            {
-+                Any any;
-+                const Cell& rCell = maTable[nRow][nCol];
-+                if (rCell.mbNumeric)
-+                    any <<= rCell.mfValue;
-+                else
-+                {
-+                    OUString str;
-+                    const String* pStr = getString(rCell.mnStrId);
-+                    if (pStr)
-+                        str = *pStr;
-+                    any <<= str;
-+                }
++                    // 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;
++            else
++            {
++                OUString str;
++                const String* pStr = getString(pCell->mnStrId);
++                if (pStr)
++                    str = *pStr;
++                any <<= str;
 +            }
-+            tableData.push_back(row);
++            row[nCol] = any;
 +        }
++        tableData.push_back(row);
 +    }
 +
 +    // convert vector to Seqeunce
@@ -1676,20 +1865,11 @@
 ===================================================================
 RCS file: /cvs/sc/sc/source/core/data/dpgroup.cxx,v
 retrieving revision 1.7
-retrieving revision 1.7.202.2
-diff -u -b -I $Revision.*$ -I $Author.*$ -r1.7 -r1.7.202.2
+retrieving revision 1.7.202.4
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.7 -r1.7.202.4
 --- sc/source/core/data/dpgroup.cxx	27 Feb 2007 12:03:31 -0000	1.7
-+++ sc/source/core/data/dpgroup.cxx	6 Dec 2007 07:06:15 -0000	1.7.202.2
-@@ -36,7 +36,7 @@
- // MARKER(update_precomp.py): autogen include statement, do not remove
- #include "precompiled_sc.hxx"
- 
--
-+#include <stdio.h>
- 
- // INCLUDE ---------------------------------------------------------------
- 
-@@ -51,10 +51,24 @@
++++ sc/source/core/data/dpgroup.cxx	21 Apr 2008 03:07:58 -0000	1.7.202.4
+@@ -51,10 +51,29 @@
  #include "collect.hxx"
  #include "global.hxx"
  #include "document.hxx"
@@ -1703,6 +1883,8 @@
 +#include <com/sun/star/sheet/DataPilotFieldFilter.hpp>
 +
 +#include <vector>
++#include <hash_set>
++#include <hash_map>
 +
 +using namespace ::com::sun::star;
 +using ::com::sun::star::uno::Any;
@@ -1711,12 +1893,51 @@
 +using ::com::sun::star::uno::UNO_QUERY;
 +using ::com::sun::star::uno::UNO_QUERY_THROW;
 +using ::rtl::OUString;
++using ::rtl::OUStringHash;
 +
 +using ::std::vector;
++using ::std::hash_set;
++using ::std::hash_map;
  
  #define D_TIMEFACTOR              86400.0
  
-@@ -840,6 +854,7 @@
+@@ -396,6 +415,12 @@
+     return false;
+ }
+ 
++void ScDPGroupItem::GetAllElements( vector<ScDPItemData>& rElements ) const
++{
++    rElements.clear();
++    rElements.assign(aElements.begin(), aElements.end());
++}
++
+ // -----------------------------------------------------------------------
+ 
+ ScDPGroupDimension::ScDPGroupDimension( long nSource, const String& rNewName ) :
+@@ -514,6 +539,14 @@
+     return NULL;
+ }
+ 
++const ScDPGroupItem* ScDPGroupDimension::GetGroupByIndex( size_t nIndex ) const
++{
++    if (nIndex >= aItems.size())
++        return NULL;
++
++    return &aItems[nIndex];
++}
++
+ void ScDPGroupDimension::DisposeData()
+ {
+     delete pCollection;
+@@ -825,6 +858,7 @@
+ {
+     DBG_ASSERT( pSource, "ScDPGroupTableData: pSource can't be NULL" );
+ 
++    CreateCacheTable();
+     nSourceCount = pSource->GetColumnCount();               // real columns, excluding data layout
+     pNumGroups = new ScDPNumGroupDimension[nSourceCount];
+ }
+@@ -840,6 +874,7 @@
      ScDPGroupDimension aNewGroup( rGroup );
      aNewGroup.SetGroupDim( GetColumnCount() );      // new dimension will be at the end
      aGroups.push_back( aNewGroup );
@@ -1724,14 +1945,13 @@
  }
  
  void ScDPGroupTableData::SetNumGroupDimension( long nIndex, const ScDPNumGroupDimension& rGroup )
-@@ -972,9 +987,98 @@
+@@ -972,9 +1007,123 @@
      pSourceData->SetEmptyFlags( bIgnoreEmptyRows, bRepeatIfEmpty );
  }
  
 -void ScDPGroupTableData::ResetIterator()
 +void ScDPGroupTableData::CreateCacheTable()
- {
--    pSourceData->ResetIterator();
++{
 +    pSourceData->CreateCacheTable();
 +}
 +
@@ -1740,30 +1960,56 @@
 +    pSourceData->FilterCacheTable(rPageDims);
 +}
 +
-+void ScDPGroupTableData::GetDrillDownData(const Sequence<sheet::DataPilotFieldFilter>& aFilters, Sequence< Sequence<Any> >& rTabData)
++void ScDPGroupTableData::GetDrillDownData(const hash_map<long, ScDPItemData>& rFilters, Sequence< Sequence<Any> >& rTabData,
++                                          GroupFilterType* /*pGroupFilter*/)
 +{
-+    // Go through the field names and skip group name(s) if any.
-+    vector<sheet::DataPilotFieldFilter> filters;
-+    sal_Int32 nOrigSize = aFilters.getLength();
-+    filters.reserve(nOrigSize);
-+    StringHashSet::const_iterator itrEnd = aGroupNames.end();
-+    for (sal_Int32 i = 0; i < nOrigSize; ++i)
-+    {
-+        if (aGroupNames.find(aFilters[i].FieldName) == itrEnd)
-+            filters.push_back(aFilters[i]);
-+    }
-+
-+    // Convert vector to Sequence.
-+    size_t nSize = filters.size();
-+    Sequence<sheet::DataPilotFieldFilter> filters2(nSize);
-+    for (size_t i = 0; i < nSize; ++i)
-+        filters2[i] = filters[i];
++    typedef hash_map<long, const ScDPGroupDimension*> GroupFieldMapType;
++    GroupFieldMapType aGroupFieldIds;
++    {
++        ScDPGroupDimensionVec::const_iterator itrEnd = aGroups.end();
++        for (ScDPGroupDimensionVec::const_iterator itr = aGroups.begin(); itr != itrEnd; ++itr)
++            aGroupFieldIds.insert( hash_map<long, const ScDPGroupDimension*>::value_type(itr->GetGroupDim(), &(*itr)) );
++    }
 +
-+    pSourceData->GetDrillDownData(filters2, rTabData);
++    // Go through all the field names and skip group name(s) if any.
++    hash_map<long, ScDPItemData> filters;
++    GroupFilterType groupFilters;
++    {
++        hash_map<long, ScDPItemData>::const_iterator itrEnd = rFilters.end();
++        GroupFieldMapType::const_iterator itrGrpEnd = aGroupFieldIds.end();
++        for (hash_map<long, ScDPItemData>::const_iterator itr = rFilters.begin(); itr != itrEnd; ++itr)
++        {
++            const ScDPItemData& rGrpItem = itr->second;
++            GroupFieldMapType::const_iterator itrGrp = aGroupFieldIds.find(itr->first);
++            if (itrGrp == itrGrpEnd)
++                // This is a regular source field.
++                filters.insert( hash_map<long, ScDPItemData>::value_type(itr->first, itr->second) );
++            else
++            {
++                // This is a group field.
++                const ScDPGroupDimension* pGrpDim = itrGrp->second;
++                long nSrcDim = pGrpDim->GetSourceDim();
++                vector<ScDPItemData> aGrpItems;
++                size_t nGroupItemCount = pGrpDim->GetItemCount();
++                for (size_t i = 0; i < nGroupItemCount; ++i)
++                {
++                    const ScDPGroupItem* pGrpItem = pGrpDim->GetGroupByIndex(i);
++                    if (!pGrpItem || !pGrpItem->GetName().IsCaseInsEqual(rGrpItem))
++                        continue;
++
++                    pGrpItem->GetAllElements(aGrpItems);
++                }
++                groupFilters.insert( GroupFilterType::value_type(nSrcDim, aGrpItems) );
++            }
++        }
++    }
++    
++    pSourceData->GetDrillDownData(filters, rTabData, &groupFilters);
 +}
 +
 +void ScDPGroupTableData::CalcResults(CalcInfo& rInfo, bool bAutoShow)
-+{
+ {
+-    pSourceData->ResetIterator();
 +    // This CalcInfo instance is used only to retrive data from the original
 +    // data source.
 +    CalcInfo aInfoSrc = rInfo;
@@ -1805,7 +2051,7 @@
 +
 +    rNewFieldDims.clear();
 +    rNewFieldDims.reserve(nCount);
-+    for (long i = 0; i < nCount; ++i)
++    for (size_t i = 0; i < nCount; ++i)
 +    {
 +        if ( rFieldDims[i] >= nSourceCount )
 +        {
@@ -1825,7 +2071,7 @@
  }
  
  long* ScDPGroupTableData::CopyFields( const long* pSourceDims, long nCount )
-@@ -1055,42 +1159,6 @@
+@@ -1055,42 +1204,6 @@
      }
  }
  
@@ -1872,9 +2118,10 @@
 ===================================================================
 RCS file: /cvs/sc/sc/source/core/data/dpobject.cxx,v
 retrieving revision 1.22
-diff -u -b -I $Revision.*$ -I $Author.*$ -r1.22 dpobject.cxx
+retrieving revision 1.21.112.6
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.22 -r1.21.112.6
 --- sc/source/core/data/dpobject.cxx	26 Nov 2007 15:19:32 -0000	1.22
-+++ sc/source/core/data/dpobject.cxx	1 Feb 2008 05:52:05 -0000
++++ sc/source/core/data/dpobject.cxx	4 Dec 2007 06:06:26 -0000	1.21.112.6
 @@ -62,18 +62,32 @@
  #include "unonames.hxx"
  
@@ -2068,10 +2315,10 @@
 ===================================================================
 RCS file: /cvs/sc/sc/source/core/data/dpoutput.cxx,v
 retrieving revision 1.16
-retrieving revision 1.15.112.10
-diff -u -b -I $Revision.*$ -I $Author.*$ -r1.16 -r1.15.112.10
+retrieving revision 1.15.112.13
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.16 -r1.15.112.13
 --- sc/source/core/data/dpoutput.cxx	26 Nov 2007 15:19:49 -0000	1.16
-+++ sc/source/core/data/dpoutput.cxx	1 Feb 2008 05:28:12 -0000	1.15.112.10
++++ sc/source/core/data/dpoutput.cxx	21 Apr 2008 01:21:22 -0000	1.15.112.13
 @@ -48,6 +48,8 @@
  #include <unotools/transliterationwrapper.hxx>
  
@@ -2128,7 +2375,7 @@
  
  // -----------------------------------------------------------------------
  
-@@ -702,6 +721,42 @@
+@@ -702,6 +721,49 @@
  	}
  }
  
@@ -2152,26 +2399,33 @@
 +    if (nCol >= nDataStartCol && nCol <= nTabEndCol && nRow >= nDataStartRow && nRow <= nTabEndRow)
 +        return DataPilotTablePositionType::RESULT;
 +
-+    bool bInColHeader = (nRow >= nMemberStartRow && nRow < nMemberStartRow + nColFieldCount);
-+    bool bInRowHeader = (nCol >= nMemberStartCol && nCol < nMemberStartCol + nRowFieldCount);
++    bool bInColHeader = (nRow >= nTabStartRow && nRow < nDataStartRow);
++    bool bInRowHeader = (nCol >= nTabStartCol && nCol < nDataStartCol);
 +
 +    if (bInColHeader && bInRowHeader)
 +        // probably in that ugly little box at the upper-left corner of the table.
-+        return DataPilotTablePositionType::NOT_IN_TABLE;
++        return DataPilotTablePositionType::OTHER;
 +
 +    if (bInColHeader)
++    {
++        if (nRow == nTabStartRow)
++            // first row in the column header area is always used for column 
++            // field buttons.
++            return DataPilotTablePositionType::OTHER;
++
 +        return DataPilotTablePositionType::COLUMN_HEADER;
++    }
 +
 +    if (bInRowHeader)
 +        return DataPilotTablePositionType::ROW_HEADER;
 +
-+    return DataPilotTablePositionType::NOT_IN_TABLE;
++    return DataPilotTablePositionType::OTHER;
 +}
 +
  void ScDPOutput::Output()
  {
  	long nField;
-@@ -862,12 +917,30 @@
+@@ -862,12 +924,30 @@
  	lcl_SetFrame( pDoc,nTab, nTabStartCol,nTabStartRow, nTabEndCol,nTabEndRow, 40 );
  }
  
@@ -2204,7 +2458,7 @@
  }
  
  BOOL ScDPOutput::HasError()
-@@ -929,13 +1002,10 @@
+@@ -929,13 +1009,10 @@
      }
  }
  
@@ -2220,7 +2474,7 @@
  
  	SCCOL nCol = rPos.Col();
  	SCROW nRow = rPos.Row();
-@@ -947,57 +1017,96 @@
+@@ -947,57 +1024,122 @@
  
  	CalcSizes();
  
@@ -2238,11 +2492,13 @@
 +            aResData.FieldFilters.realloc(nSize);
 +            for (sal_Int32 i = 0; i < nSize; ++i)
 +                aResData.FieldFilters[i] = aFilters[i];
-+    
+ 
+-	if ( nRow >= nMemberStartRow && nRow < nMemberStartRow + nColFieldCount )
 +            aResData.DataFieldIndex = 0;
 +            Reference<beans::XPropertySet> xPropSet(xSource, UNO_QUERY);
 +            if (xPropSet.is())
-+            {
+ 	{
+-		long nField = nRow - nMemberStartRow;
 +                sal_Int32 nDataFieldCount;
 +                Any any = xPropSet->getPropertyValue(rtl::OUString::createFromAscii("DataFieldCount"));
 +                if ((any >>= nDataFieldCount) && nDataFieldCount > 0)
@@ -2253,15 +2509,19 @@
 +            if (aData.getLength() > nRow - nDataStartRow && 
 +                aData[nRow-nDataStartRow].getLength() > nCol-nDataStartCol)
 +                aResData.Result = aData[nRow-nDataStartRow][nCol-nDataStartCol];
- 
--	if ( nRow >= nMemberStartRow && nRow < nMemberStartRow + nColFieldCount )
++    
 +            rPosData.PositionData = makeAny(aResData);
 +            return;
 +        }
 +        case DataPilotTablePositionType::COLUMN_HEADER:
- 	{
- 		long nField = nRow - nMemberStartRow;
++        {
++            long nField = nRow - nTabStartRow - 1; // 1st line is used for the buttons
++            if (nField < 0)
++                break;
++
  		const uno::Sequence<sheet::MemberResult> rSequence = pColFields[nField].aResult;
++            if (rSequence.getLength() == 0)
++                break;
  		const sheet::MemberResult* pArray = rSequence.getConstArray();
 -		long nThisColCount = rSequence.getLength();
  
@@ -2282,6 +2542,9 @@
 -	}
  
 -	//	test for row field
++            if (nItem < 0)
++                break;
++
 +            DataPilotTableHeaderData aHeaderData;
 +            aHeaderData.MemberName = OUString(pArray[nItem].Name);
 +            aHeaderData.Flags = pArray[nItem].Flags;
@@ -2295,8 +2558,14 @@
 +        }
 +        case DataPilotTablePositionType::ROW_HEADER:
  	{
- 		long nField = nCol - nMemberStartCol;
+-		long nField = nCol - nMemberStartCol;
++            long nField = nCol - nTabStartCol;
++            if (nField < 0)
++                break;
++
  		const uno::Sequence<sheet::MemberResult> rSequence = pRowFields[nField].aResult;
++            if (rSequence.getLength() == 0)
++                break;
  		const sheet::MemberResult* pArray = rSequence.getConstArray();
 -		long nThisRowCount = rSequence.getLength();
  
@@ -2313,6 +2582,9 @@
 -			rData.nHierarchy  = pRowFields[nField].nHier;
 -			rData.nLevel      = pRowFields[nField].nLevel;
 +
++            if (nItem < 0)
++                break;
++
 +            DataPilotTableHeaderData aHeaderData;
 +            aHeaderData.MemberName = OUString(pArray[nItem].Name);
 +            aHeaderData.Flags = pArray[nItem].Flags;
@@ -2340,19 +2612,34 @@
 +        // No data field is present in this datapilot table.
 +        return false;
 +
++    bool bColGrand;
++    any = xPropSet->getPropertyValue(rtl::OUString::createFromAscii(SC_UNO_COLGRAND));
++    if (!(any >>= bColGrand))
++        return false;
++
++    bool bRowGrand;
++    any = xPropSet->getPropertyValue(rtl::OUString::createFromAscii(SC_UNO_ROWGRAND));
++    if (!(any >>= bRowGrand))
++        return false;
++
      SCCOL nCol = rPos.Col();
      SCROW nRow = rPos.Row();
      SCTAB nTab = rPos.Tab();
-@@ -1013,8 +1122,6 @@
+@@ -1013,10 +1155,11 @@
          return false;
      }
  
 -    rtl::OUString sTotal( ScGlobal::GetRscString(STR_PIVOT_TOTAL) );
--
++    bool bFilterByCol = !(bColGrand && (nCol == nTabEndCol));
++    bool bFilterByRow = !(bRowGrand && (nRow == nTabEndRow));
+ 
      // column fields
-     for (SCCOL nColField = 0; nColField < nColFieldCount; ++nColField)
+-    for (SCCOL nColField = 0; nColField < nColFieldCount; ++nColField)
++    for (SCCOL nColField = 0; nColField < nColFieldCount && bFilterByCol; ++nColField)
      {
-@@ -1024,8 +1131,7 @@
+         sheet::DataPilotFieldFilter filter;
+         filter.FieldName = pColFields[nColField].aCaption;
+@@ -1024,8 +1167,7 @@
          const uno::Sequence<sheet::MemberResult> rSequence = pColFields[nColField].aResult;
          const sheet::MemberResult* pArray = rSequence.getConstArray();
  
@@ -2362,16 +2649,21 @@
  
          long nItem = nCol - nDataStartCol;
                  //	get origin of "continue" fields
-@@ -1033,7 +1139,7 @@
+@@ -1033,12 +1175,11 @@
              --nItem;
  
          filter.MatchValue = pArray[nItem].Name;
 -        if (pArray[nItem].Name.getLength() > 0 && pArray[nItem].Name != sTotal)
-+        if (pArray[nItem].Name.getLength() > 0 && !pArray[nItem].Name.equalsAscii("Total"))
              rFilters.push_back(filter);
      }
  
-@@ -1046,8 +1152,7 @@
+     // row fields
+-    for (SCROW nRowField = 0; nRowField < nRowFieldCount; ++nRowField)
++    for (SCROW nRowField = 0; nRowField < nRowFieldCount && bFilterByRow; ++nRowField)
+     {
+         sheet::DataPilotFieldFilter filter;
+         filter.FieldName = pRowFields[nRowField].aCaption;
+@@ -1046,8 +1187,7 @@
          const uno::Sequence<sheet::MemberResult> rSequence = pRowFields[nRowField].aResult;
          const sheet::MemberResult* pArray = rSequence.getConstArray();
  
@@ -2381,12 +2673,11 @@
  
          long nItem = nRow - nDataStartRow;
  			//	get origin of "continue" fields
-@@ -1055,7 +1160,7 @@
+@@ -1055,7 +1195,6 @@
              --nItem;
  
          filter.MatchValue = pArray[nItem].Name;
 -        if (pArray[nItem].Name.getLength() > 0 && pArray[nItem].Name != sTotal)
-+        if (pArray[nItem].Name.getLength() > 0 && !pArray[nItem].Name.equalsAscii("Total"))
              rFilters.push_back(filter);
      }
  
@@ -2394,20 +2685,11 @@
 ===================================================================
 RCS file: /cvs/sc/sc/source/core/data/dpsdbtab.cxx,v
 retrieving revision 1.12
-retrieving revision 1.12.202.3
-diff -u -b -I $Revision.*$ -I $Author.*$ -r1.12 -r1.12.202.3
+retrieving revision 1.12.202.5
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.12 -r1.12.202.5
 --- sc/source/core/data/dpsdbtab.cxx	27 Feb 2007 12:04:37 -0000	1.12
-+++ sc/source/core/data/dpsdbtab.cxx	6 Dec 2007 07:06:15 -0000	1.12.202.3
-@@ -36,7 +36,7 @@
- // MARKER(update_precomp.py): autogen include statement, do not remove
- #include "precompiled_sc.hxx"
- 
--
-+#include <stdio.h>
- 
- // INCLUDE --------------------------------------------------------------
- 
-@@ -55,14 +55,24 @@
++++ sc/source/core/data/dpsdbtab.cxx	21 Apr 2008 03:07:58 -0000	1.12.202.5
+@@ -55,14 +55,25 @@
  #include <com/sun/star/sdbc/XRowSet.hpp>
  #include <com/sun/star/sdbc/XResultSetMetaDataSupplier.hpp>
  #include <com/sun/star/lang/XMultiServiceFactory.hpp>
@@ -2424,6 +2706,7 @@
  
 +using ::std::vector;
 +using ::std::set;
++using ::std::hash_map;
 +using ::com::sun::star::uno::Sequence;
 +using ::com::sun::star::uno::Reference;
 +using ::com::sun::star::uno::Any;
@@ -2432,7 +2715,7 @@
  #define SC_SERVICE_ROWSET			"com.sun.star.sdb.RowSet"
  #define SC_SERVICE_INTHANDLER		"com.sun.star.sdb.InteractionHandler"
  
-@@ -79,14 +89,12 @@
+@@ -79,14 +90,12 @@
  	::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xServiceManager;
  	ScImportSourceDesc	aDesc;
  	long				nColCount;
@@ -2449,7 +2732,7 @@
  	ScDatabaseDPData_Impl() {}
  };
  
-@@ -100,14 +108,11 @@
+@@ -100,14 +109,11 @@
  	pImpl->xServiceManager = xSMgr;
  	pImpl->aDesc = rImport;
  	pImpl->nColCount = 0;
@@ -2465,7 +2748,7 @@
  }
  
  ScDatabaseDPData::~ScDatabaseDPData()
-@@ -115,13 +120,6 @@
+@@ -115,13 +121,6 @@
  	::comphelper::disposeComponent( pImpl->xRowSet );
  
  	delete[] pImpl->pTypes;
@@ -2479,7 +2762,7 @@
  	delete pImpl->pFormatter;		// NumberFormatter is local for this object
  	delete pImpl;
  }
-@@ -129,21 +127,7 @@
+@@ -129,21 +128,7 @@
  void ScDatabaseDPData::DisposeData()
  {
  	//!	use OpenDatabase here?
@@ -2502,7 +2785,7 @@
  }
  
  BOOL ScDatabaseDPData::OpenDatabase()
-@@ -199,8 +183,6 @@
+@@ -199,8 +184,6 @@
  			else
  				pImpl->xRowSet->execute();
  
@@ -2511,7 +2794,7 @@
  			//
  			//	get column descriptions
  			//
-@@ -216,22 +198,9 @@
+@@ -216,22 +199,9 @@
  			uno::Reference<sdbc::XResultSet> xResSet( pImpl->xRowSet, uno::UNO_QUERY );
  			if ( pImpl->nColCount > 0 && xResSet.is() )
  			{
@@ -2534,7 +2817,7 @@
  
  				bSuccess = TRUE;
  			}
-@@ -252,7 +221,6 @@
+@@ -252,7 +222,6 @@
  	if (!bSuccess)
  		::comphelper::disposeComponent( pImpl->xRowSet );
  
@@ -2542,7 +2825,7 @@
  	return bSuccess;
  }
  
-@@ -261,103 +229,6 @@
+@@ -261,103 +230,6 @@
  	return pImpl->nColCount;
  }
  
@@ -2646,7 +2929,7 @@
  void lcl_Reset( const uno::Reference<sdbc::XRowSet>& xRowSet )
  					throw(sdbc::SQLException, uno::RuntimeException)
  {
-@@ -367,104 +238,10 @@
+@@ -367,104 +239,10 @@
  	xRowSet->execute();		// restart
  }
  
@@ -2753,7 +3036,7 @@
  }
  
  String ScDatabaseDPData::getDimensionName(long nColumn)
-@@ -475,10 +252,12 @@
+@@ -475,10 +253,12 @@
  		//return "Data";
  		return ScGlobal::GetRscString(STR_PIVOT_DATA);
  	}
@@ -2770,7 +3053,7 @@
  	DBG_ERROR("getDimensionName: invalid dimension");
  	return String();
  }
-@@ -500,106 +279,39 @@
+@@ -500,106 +280,40 @@
  	//!	disable flags
  }
  
@@ -2870,10 +3153,11 @@
 -				}
 -				rParam.pValues[i].Set( fVal, SC_VALTYPE_VALUE );
 -			}
-+void ScDatabaseDPData::GetDrillDownData(const Sequence<sheet::DataPilotFieldFilter>& rFilters, Sequence< Sequence<Any> >& rTabData)
++void ScDatabaseDPData::GetDrillDownData(const hash_map<long, ScDPItemData>& rFilters, Sequence< Sequence<Any> >& rTabData,
++                                        GroupFilterType* pGroupFilter)
 +{
 +    CreateCacheTable();
-+    pImpl->aCacheTable.filterTable(rFilters, rTabData);
++    pImpl->aCacheTable.filterTable(rFilters, rTabData, IsRepeatIfEmpty(), pGroupFilter);
 +}
  
 -			bSuccess = TRUE;
@@ -2906,11 +3190,11 @@
 ===================================================================
 RCS file: /cvs/sc/sc/source/core/data/dpshttab.cxx,v
 retrieving revision 1.9
-retrieving revision 1.9.202.4
-diff -u -b -I $Revision.*$ -I $Author.*$ -r1.9 -r1.9.202.4
+retrieving revision 1.9.202.8
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.9 -r1.9.202.8
 --- sc/source/core/data/dpshttab.cxx	27 Feb 2007 12:04:49 -0000	1.9
-+++ sc/source/core/data/dpshttab.cxx	6 Dec 2007 07:06:15 -0000	1.9.202.4
-@@ -44,11 +44,24 @@
++++ sc/source/core/data/dpshttab.cxx	17 Apr 2008 13:11:10 -0000	1.9.202.8
+@@ -44,11 +44,25 @@
  #include <svtools/zforlist.hxx>
  
  #include "dpshttab.hxx"
@@ -2931,11 +3215,12 @@
 +using ::com::sun::star::uno::Sequence;
 +using ::std::vector;
 +using ::std::set;
++using ::std::hash_map;
 +
  // -----------------------------------------------------------------------
  
  class ScSheetDPData_Impl
-@@ -57,49 +70,47 @@
+@@ -57,49 +71,47 @@
  	ScDocument*		pDoc;
  	ScRange			aRange;
  	ScQueryParam	aQuery;
@@ -2995,12 +3280,7 @@
              }
              else
              {
-@@ -110,30 +121,25 @@
-             }
-     	}
-     }
-+    CreateCacheTable();
- }
+@@ -114,26 +126,20 @@
  
  ScSheetDPData::~ScSheetDPData()
  {
@@ -3173,26 +3453,21 @@
  }
  
  void ScSheetDPData::SetEmptyFlags( BOOL bIgnoreEmptyRows, BOOL bRepeatIfEmpty )
-@@ -295,131 +255,41 @@
+@@ -295,131 +255,48 @@
  	pImpl->bRepeatIfEmpty   = bRepeatIfEmpty;
  }
  
 -void ScSheetDPData::ResetIterator()
-+void ScSheetDPData::CreateCacheTable()
++bool ScSheetDPData::IsRepeatIfEmpty()
  {
 -	pImpl->nNextRow = pImpl->aRange.aStart.Row() + 1;
-+    // Scan and store the data from the source range.
-+    if (!pImpl->aCacheTable.empty())
-+        // already cached.
-+        return;
-+
-+    pImpl->aCacheTable.fillTable(pImpl->pDoc, pImpl->aRange, pImpl->aQuery, pImpl->pSpecial);
++    return pImpl->bRepeatIfEmpty;
  }
  
 -void lcl_GetStringOrValue( ScDPItemData& rData, ScDocument* pDoc,
 -							SCCOL nCol, SCROW nRow, SCTAB nTab,
 -							BOOL bRepeatIfEmpty, SCROW nFirstDataRow )
-+void ScSheetDPData::FilterCacheTable(const vector<ScDPDimension*>& rPageDims)
++void ScSheetDPData::CreateCacheTable()
  {
 -	if ( bRepeatIfEmpty )
 -	{
@@ -3203,19 +3478,23 @@
 -		while ( !pDoc->HasData( nCol, nRow, nTab ) && nRow > nFirstDataRow )
 -			--nRow;
 -	}
--
++    // Scan and store the data from the source range.
++    if (!pImpl->aCacheTable.empty())
++        // already cached.
++        return;
+ 
 -	BOOL bVal = pDoc->HasValueData( nCol, nRow, nTab );
 -	rData.bHasValue = bVal;
 -	if (bVal)
 -		rData.fValue = pDoc->GetValue( ScAddress( nCol, nRow, nTab ) );
 -	else
 -		pDoc->GetString( nCol, nRow, nTab, rData.aString );
-+    CreateCacheTable();
-+    pImpl->aCacheTable.filterByPageDimension(rPageDims);
++    pImpl->aCacheTable.fillTable(pImpl->pDoc, pImpl->aRange, pImpl->aQuery, pImpl->pSpecial, 
++                                 pImpl->bIgnoreEmptyRows);
  }
  
 -BOOL ScSheetDPData::GetNextRow( const ScDPTableIteratorParam& rParam )
-+void ScSheetDPData::GetDrillDownData(const Sequence<sheet::DataPilotFieldFilter>& rFilters, Sequence< Sequence<Any> >& rData)
++void ScSheetDPData::FilterCacheTable(const vector<ScDPDimension*>& rPageDims)
  {
 -	if ( pImpl->nNextRow > pImpl->aRange.aEnd.Row() )
 -		return FALSE;
@@ -3252,7 +3531,10 @@
 -	while (bFilteredOut);
 -
 -	//!	use more efficient iterators
--
++    CreateCacheTable();
++    pImpl->aCacheTable.filterByPageDimension(rPageDims);
++}
+ 
 -	for (i=0; i<rParam.nColCount; i++)
 -	{
 -		long nDim = rParam.pCols[i];
@@ -3263,6 +3545,9 @@
 -									(SCCOL)(nStartCol+nDim), pImpl->nNextRow, nDocTab,
 -									pImpl->bRepeatIfEmpty, nFirstDataRow );
 -	}
++void ScSheetDPData::GetDrillDownData(const hash_map<long, ScDPItemData>& rFilters, Sequence< Sequence<Any> >& rData,
++                                     GroupFilterType* pGroupFilter)
++{
 +    CreateCacheTable();
 +    sal_Int32 nRowSize = pImpl->aCacheTable.getRowSize();
 +    if (!nRowSize)
@@ -3278,7 +3563,7 @@
 -									(SCCOL)(nStartCol+nDim), pImpl->nNextRow, nDocTab,
 -									pImpl->bRepeatIfEmpty, nFirstDataRow );
 -	}
-+    pImpl->aCacheTable.filterTable(rFilters, rData);
++    pImpl->aCacheTable.filterTable(rFilters, rData, IsRepeatIfEmpty(), pGroupFilter);
 +}
  
 -	for (i=0; i<rParam.nPageCount; i++)
@@ -3334,20 +3619,11 @@
 ===================================================================
 RCS file: /cvs/sc/sc/source/core/data/dptabdat.cxx,v
 retrieving revision 1.12
-retrieving revision 1.12.202.5
-diff -u -b -I $Revision.*$ -I $Author.*$ -r1.12 -r1.12.202.5
+retrieving revision 1.12.202.8
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.12 -r1.12.202.8
 --- sc/source/core/data/dptabdat.cxx	27 Feb 2007 12:05:02 -0000	1.12
-+++ sc/source/core/data/dptabdat.cxx	6 Dec 2007 07:06:15 -0000	1.12.202.5
-@@ -36,7 +36,7 @@
- // MARKER(update_precomp.py): autogen include statement, do not remove
- #include "precompiled_sc.hxx"
- 
--
-+#include <stdio.h>
- 
- // INCLUDE ---------------------------------------------------------------
- 
-@@ -50,8 +50,18 @@
++++ sc/source/core/data/dptabdat.cxx	21 Apr 2008 03:07:58 -0000	1.12.202.8
+@@ -50,8 +50,19 @@
  #include <unotools/collatorwrapper.hxx>
  #endif
  
@@ -3363,15 +3639,17 @@
 +using ::com::sun::star::uno::Any;
 +using ::std::vector;
 +using ::std::set;
++using ::std::hash_map;
  
  // -----------------------------------------------------------------------
  
-@@ -113,29 +123,7 @@
+@@ -113,29 +124,14 @@
          return ScGlobal::pCollator->compareString( rA.aString, rB.aString );
  }
  
 -// -----------------------------------------------------------------------
--
++// ---------------------------------------------------------------------------
+ 
 -ScDPTableIteratorParam::ScDPTableIteratorParam(
 -							long nCCount, const long* pC, ScDPItemData* pCDat,
 -							long nRCount, const long* pR, ScDPItemData* pRDat,
@@ -3389,18 +3667,25 @@
 -	nDatCount( (SCSIZE)nDCount ),
 -	pDats	 ( pD ),
 -	pValues	 ( pV )
--{
--}
--
++ScDPTableData::CalcInfo::CalcInfo() :
++    bRepeatIfEmpty(false)
+ {
+ }
+ 
 -// -----------------------------------------------------------------------
 +// ---------------------------------------------------------------------------
  
  ScDPTableData::ScDPTableData()
  {
-@@ -193,6 +181,26 @@
+@@ -193,6 +189,31 @@
  	return nRet;
  }
  
++bool ScDPTableData::IsRepeatIfEmpty()
++{
++    return false;
++}
++
 +void ScDPTableData::CreateCacheTable()
 +{
 +    fprintf(stdout, "ScDPTableData::CreateCacheTable: un-implemented...\n");fflush(stdout);
@@ -3411,7 +3696,7 @@
 +    fprintf(stdout, "ScDPTableData::FilterCacheTable: un-implemented...\n");fflush(stdout);
 +}
 +
-+void ScDPTableData::GetDrillDownData(const Sequence<sheet::DataPilotFieldFilter>& aFilters, Sequence< Sequence<Any> >& rTabData)
++void ScDPTableData::GetDrillDownData(const hash_map<long, ScDPItemData>&, Sequence< Sequence<Any> >&, GroupFilterType*)
 +{
 +    fprintf(stdout, "ScDPTableData::GetDrillDownData: un-implemented...\n");fflush(stdout);
 +}
@@ -3424,7 +3709,7 @@
  UINT32 ScDPTableData::GetNumberFormat(long)
  {
  	return 0;			// default format
-@@ -227,6 +235,105 @@
+@@ -227,6 +248,105 @@
      return FALSE;
  }
  
@@ -3509,8 +3794,8 @@
 +            continue;
 +        }
 +
-+        const ScDPCacheTable::Cell* pCell = rCacheTable.getCell(nDim, nRow);
-+        if (!pCell)
++        const ScDPCacheTable::Cell* pCell = rCacheTable.getCell(nDim, nRow, IsRepeatIfEmpty());
++        if (!pCell || pCell->mnType == SC_VALTYPE_EMPTY)
 +            continue;
 +
 +        const String* pString = ScDPCacheTable::getString(pCell->mnStrId);
@@ -3534,19 +3819,10 @@
 ===================================================================
 RCS file: /cvs/sc/sc/source/core/data/dptabres.cxx,v
 retrieving revision 1.11
-retrieving revision 1.11.200.9
-diff -u -b -I $Revision.*$ -I $Author.*$ -r1.11 -r1.11.200.9
+retrieving revision 1.11.200.10
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.11 -r1.11.200.10
 --- sc/source/core/data/dptabres.cxx	27 Feb 2007 12:05:33 -0000	1.11
-+++ sc/source/core/data/dptabres.cxx	6 Dec 2007 07:06:15 -0000	1.11.200.9
-@@ -36,7 +36,7 @@
- // MARKER(update_precomp.py): autogen include statement, do not remove
- #include "precompiled_sc.hxx"
- 
--
-+#include <stdio.h>
- 
- // INCLUDE ---------------------------------------------------------------
- 
++++ sc/source/core/data/dptabres.cxx	21 Apr 2008 03:07:58 -0000	1.11.200.10
 @@ -66,6 +66,7 @@
  #include <com/sun/star/sheet/DataPilotFieldSortMode.hpp>
  
@@ -3563,29 +3839,7 @@
  	fVal = fResult;			// used directly from now on
  	fAux = 0.0;				// used for running total or original result of reference value
  }
-@@ -894,11 +896,30 @@
-     return pSource->GetData()->HasCommonElement( rFirstData, nFirstIndex, rSecondData, nSecondIndex );
- }
- 
-+void ScDPResultData::Debug() const
-+{
-+    fprintf(stdout, "------------------------------ ScDPResultData::Debug ------------------------------\n");
-+    fprintf(stdout, "data at col (%d);  data at row (%d);  late init(%d)\n", bDataAtCol, bDataAtRow, bLateInit);
-+    for (long i = 0; i < nMeasCount; ++i)
-+    {
-+        fprintf(stdout, "  measure id = %ld --------------------\n", i);
-+        fprintf(stdout, "    measure function = %d\n", pMeasFuncs[i]);
-+        fprintf(stdout, "    measure name = '%s'\n", 
-+                OUStringToOString(rtl::OUString(pMeasNames[i]), RTL_TEXTENCODING_UTF8).getStr());
-+        fprintf(stdout, "    measure ref orientation = %d\n", pMeasRefOrient[i]);
-+        fprintf(stdout, "    measure ref type = %ld  field = '%s'  item type = %ld  item name = '%s'\n", 
-+                pMeasRefs[i].ReferenceType, 
-+                OUStringToOString(pMeasRefs[i].ReferenceField, RTL_TEXTENCODING_UTF8).getStr(),
-+                pMeasRefs[i].ReferenceItemType,
-+                OUStringToOString(pMeasRefs[i].ReferenceItemName, RTL_TEXTENCODING_UTF8).getStr());
-+    }
-+}
-+
+@@ -897,8 +899,8 @@
  // -----------------------------------------------------------------------
  
  
@@ -3596,7 +3850,7 @@
  									BOOL bForceSub ) :
  	pResultData( pData ),
  	pParentDim( pDim ),
-@@ -945,19 +966,28 @@
+@@ -945,19 +947,28 @@
  		return ((ScDPMember*)pMemberDesc)->IsNamedItem( r );
  	return FALSE;
  }
@@ -3630,7 +3884,7 @@
  {
  	//	with LateInit, initialize only those members that have data
  	if ( pResultData->IsLateInit() )
-@@ -965,22 +995,22 @@
+@@ -965,22 +976,22 @@
  
  	bInitialized = TRUE;
  
@@ -3659,7 +3913,7 @@
                                      ScDPInitState& rInitState )
  {
  	//	without LateInit, everything has already been initialized
-@@ -989,21 +1019,22 @@
+@@ -989,21 +1000,22 @@
  
  	bInitialized = TRUE;
  
@@ -3687,7 +3941,7 @@
  }
  
  BOOL ScDPResultMember::IsSubTotalInTitle(long nMeasure) const
-@@ -1123,16 +1154,14 @@
+@@ -1123,16 +1135,14 @@
  		return 0;
  }
  
@@ -3707,7 +3961,7 @@
  		if ( !pDataRoot )
  		{
  			pDataRoot = new ScDPDataMember( pResultData, NULL );
-@@ -1158,8 +1187,7 @@
+@@ -1158,8 +1168,7 @@
  				aSubState.eRowForce = lcl_GetForceFunc( pParentLevel, nUserPos );
  			}
  
@@ -3717,7 +3971,7 @@
  	}
  }
  
-@@ -1575,7 +1603,7 @@
+@@ -1575,7 +1584,7 @@
  
  // -----------------------------------------------------------------------
  
@@ -3726,7 +3980,7 @@
  	pResultData( pData ),
  	pResultMember( pRes ),
  	pChildDimension( NULL )
-@@ -1647,7 +1675,7 @@
+@@ -1647,7 +1656,7 @@
  	return nRet;
  }
  
@@ -3735,7 +3989,7 @@
  {
  	//!	find out how many and which subtotals are used
  
-@@ -1663,19 +1691,15 @@
+@@ -1663,19 +1672,15 @@
  			pAgg = pAgg->GetChild();		// created if not there
  	}
  
@@ -3760,7 +4014,7 @@
  									const ScDPSubTotalState& rSubState )
  {
  	if ( pResultData->IsLateInit() && !pChildDimension && pResultMember && pResultMember->GetChildDimension() )
-@@ -1704,11 +1728,11 @@
+@@ -1704,11 +1709,11 @@
  			aLocalSubState.eColForce = lcl_GetForceFunc( pForceLevel, nUserPos );
  		}
  
@@ -3774,7 +4028,7 @@
  }
  
  BOOL ScDPDataMember::HasData( long nMeasure, const ScDPSubTotalState& rSubState ) const
-@@ -2413,7 +2437,7 @@
+@@ -2413,7 +2418,7 @@
  class ScDPGroupCompare
  {
  private:
@@ -3783,7 +4037,7 @@
      const ScDPInitState& rInitState;
      long                 nDimSource;
      BOOL                 bIncludeAll;
-@@ -2422,14 +2446,14 @@
+@@ -2422,14 +2427,14 @@
      const ScDPItemData*  pBaseData;
  
  public:
@@ -3800,7 +4054,7 @@
      pResultData( pData ),
      rInitState( rState ),
      nDimSource( nDimension ),
-@@ -2494,7 +2518,7 @@
+@@ -2494,7 +2499,7 @@
  
  // -----------------------------------------------------------------------
  
@@ -3809,7 +4063,7 @@
  	pResultData( pData ),
  	bInitialized( FALSE ),
  	bIsDataLayout( FALSE ),
-@@ -2538,18 +2562,28 @@
+@@ -2538,18 +2543,28 @@
  	return NULL;
  }
  
@@ -3821,32 +4075,32 @@
 -	ScDPLevel* pThisLevel = *ppLev;
 -	if (pThisDim && pThisLevel)
 +    if (nPos >= ppDim.size() || nPos >= ppLev.size())
- 	{
--		ScDPDimension** ppChildDim = ppDim + 1;
--		ScDPLevel** ppChildLev = ppLev + 1;
++    {
 +        bInitialized = true;
 +        return;
 +    }
- 
--		bIsDataLayout = pThisDim->getIsDataLayoutDimension();
--		aDimensionName = pThisDim->getName();
++
 +	ScDPDimension* pThisDim = ppDim[nPos];
 +	ScDPLevel* pThisLevel = ppLev[nPos];
- 
++
 +    if (!pThisDim || !pThisLevel)
-+    {
+ 	{
+-		ScDPDimension** ppChildDim = ppDim + 1;
+-		ScDPLevel** ppChildLev = ppLev + 1;
 +        bInitialized = true;
 +        return;
 +    }
-+
+ 
+-		bIsDataLayout = pThisDim->getIsDataLayoutDimension();
+-		aDimensionName = pThisDim->getName();
 +    bIsDataLayout = pThisDim->getIsDataLayoutDimension();   // member
 +    aDimensionName = pThisDim->getName();                   // member 
-+
+ 
 +    // Check the autoshow setting.  If it's enabled, store the settings.
      	const sheet::DataPilotFieldAutoShowInfo& rAutoInfo = pThisLevel->GetAutoShow();
      	if ( rAutoInfo.IsEnabled )
      	{
-@@ -2559,6 +2593,7 @@
+@@ -2559,6 +2574,7 @@
      	    nAutoCount    = rAutoInfo.ItemCount;
      	}
  
@@ -3854,7 +4108,7 @@
          const sheet::DataPilotFieldSortInfo& rSortInfo = pThisLevel->GetSortInfo();
          if ( rSortInfo.Mode == sheet::DataPilotFieldSortMode::DATA )
          {
-@@ -2573,6 +2608,7 @@
+@@ -2573,6 +2589,7 @@
          long nDimSource = pThisDim->GetDimension();     //! check GetSourceDim?
          ScDPGroupCompare aCompare( pResultData, rInitState, nDimSource );
  
@@ -3862,7 +4116,7 @@
  		ScDPMembers* pMembers = pThisLevel->GetMembersObject();
  		long nMembCount = pMembers->getCount();
  		for ( long i=0; i<nMembCount; i++ )
-@@ -2595,25 +2631,26 @@
+@@ -2595,25 +2612,26 @@
                      maMemberHash.insert( std::pair< const ScDPItemData, ScDPResultMember *>( aMemberData, pNew ) );
  
                  rInitState.AddMember( nDimSource, aMemberData );
@@ -3900,7 +4154,7 @@
  
          long nDimSource = pThisDim->GetDimension();     //! check GetSourceDim?
  
-@@ -2683,7 +2720,7 @@
+@@ -2683,7 +2701,7 @@
  				ScDPItemData aMemberData;
  				pResultMember->FillItemData( aMemberData );
  				rInitState.AddMember( nDimSource, aMemberData );
@@ -3909,7 +4163,7 @@
  				rInitState.RemoveMember();
  			}
  		}
-@@ -2695,11 +2732,10 @@
+@@ -2695,11 +2713,10 @@
                  ScDPItemData aMemberData;
                  pResultMember->FillItemData( aMemberData );
                  rInitState.AddMember( nDimSource, aMemberData );
@@ -3922,7 +4176,7 @@
  }
  
  long ScDPResultDimension::GetSize(long nMeasure) const
-@@ -2722,26 +2758,37 @@
+@@ -2722,26 +2739,37 @@
  	return nTotal;
  }
  
@@ -3973,7 +4227,7 @@
  			return;
  		}
  
-@@ -3210,7 +3257,7 @@
+@@ -3210,7 +3238,7 @@
  
  // -----------------------------------------------------------------------
  
@@ -3982,7 +4236,7 @@
  	pResultData( pData ),
  	pResultDimension( NULL ),
  	bIsDataLayout( FALSE )
-@@ -3229,6 +3276,8 @@
+@@ -3229,6 +3257,8 @@
      pResultDimension = pDim;
  	bIsDataLayout = pDim->IsDataLayout();
  
@@ -3991,7 +4245,7 @@
  	long nCount = pDim->GetMemberCount();
  	for (long i=0; i<nCount; i++)
  	{
-@@ -3249,7 +3298,7 @@
+@@ -3249,7 +3279,7 @@
  	}
  }
  
@@ -4000,17 +4254,17 @@
  									const ScDPSubTotalState& rSubState )
  {
      // the ScDPItemData array must contain enough entries for all dimensions - this isn't checked
-@@ -3260,9 +3309,15 @@
+@@ -3260,9 +3290,15 @@
  		ScDPDataMember* pMember = aMembers[(USHORT)i];
  
  		// always first member for data layout dim
 -		if ( bIsDataLayout || pMember->IsNamedItem( *pDataMembers ) )
 +        if ( bIsDataLayout || ( !aDataMembers.empty() && pMember->IsNamedItem(aDataMembers[0]) ) )
-+        {
-+            vector<ScDPItemData> aChildDataMembers;
-+            if (aDataMembers.size() > 1)
  		{
 -			pMember->ProcessData( pDataMembers + 1, pValues, rSubState );
++            vector<ScDPItemData> aChildDataMembers;
++            if (aDataMembers.size() > 1)
++            {
 +                vector<ScDPItemData>::const_iterator itr = aDataMembers.begin();
 +                aChildDataMembers.assign(++itr, aDataMembers.end());
 +            }
@@ -4021,12 +4275,12 @@
 Index: sc/source/core/data/dptabsrc.cxx
 ===================================================================
 RCS file: /cvs/sc/sc/source/core/data/dptabsrc.cxx,v
-retrieving revision 1.22
-retrieving revision 1.20.42.11
-diff -u -b -I $Revision.*$ -I $Author.*$ -r1.22 -r1.20.42.11
---- sc/source/core/data/dptabsrc.cxx	26 Nov 2007 15:20:11 -0000	1.22
-+++ sc/source/core/data/dptabsrc.cxx	6 Dec 2007 16:40:33 -0000	1.20.42.11
-@@ -36,11 +36,14 @@
+retrieving revision 1.23
+retrieving revision 1.20.42.13
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.23 -r1.20.42.13
+--- sc/source/core/data/dptabsrc.cxx	29 Jan 2008 15:18:53 -0000	1.23
++++ sc/source/core/data/dptabsrc.cxx	17 Apr 2008 13:11:10 -0000	1.20.42.13
+@@ -36,11 +36,15 @@
  // MARKER(update_precomp.py): autogen include statement, do not remove
  #include "precompiled_sc.hxx"
  
@@ -4038,10 +4292,11 @@
  #include <algorithm>
 +#include <vector>
 +#include <set>
++#include <hash_map>
  
  #include <tools/debug.hxx>
  #include <rtl/math.hxx>
-@@ -65,8 +68,10 @@
+@@ -66,8 +70,10 @@
  #include <com/sun/star/beans/PropertyAttribute.hpp>
  #include <com/sun/star/sheet/DataPilotFieldFilter.hpp>
  #include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
@@ -4052,34 +4307,62 @@
  
  #ifndef _UNOTOOLS_COLLATORWRAPPER_HXX
  #include <unotools/collatorwrapper.hxx>
-@@ -79,6 +84,11 @@
+@@ -80,6 +86,12 @@
  #endif
  
  using namespace com::sun::star;
 +using ::std::vector;
 +using ::std::set;
++using ::std::hash_map;
 +using ::com::sun::star::uno::Reference;
 +using ::com::sun::star::uno::Sequence;
 +using ::com::sun::star::uno::Any;
  
  // -----------------------------------------------------------------------
  
-@@ -416,6 +426,14 @@
+@@ -417,6 +429,41 @@
  	DBG_ERROR("not implemented");	//! exception?
  }
  
 +Sequence< Sequence<Any> > SAL_CALL ScDPSource::getDrillDownData(const Sequence<sheet::DataPilotFieldFilter>& aFilters)
 +    throw (uno::RuntimeException)
 +{
++    long nColumnCount = GetData()->GetColumnCount();
++
++    // collect ScDPItemData for each filtered column
++    hash_map<long, ScDPItemData> aFilterMap;
++    sal_Int32 nFilterCount = aFilters.getLength();
++    for (sal_Int32 i = 0; i < nFilterCount; ++i)
++    {
++        const sheet::DataPilotFieldFilter& rFilter = aFilters[i];
++        String aFieldName( rFilter.FieldName );
++        for (long nCol = 0; nCol < nColumnCount; ++nCol)
++        {
++            if ( aFieldName == pData->getDimensionName(nCol) )
++            {
++                ScDPDimension* pDim = GetDimensionsObject()->getByIndex( nCol );
++                ScDPMembers* pMembers = pDim->GetHierarchiesObject()->getByIndex(0)->
++                                        GetLevelsObject()->getByIndex(0)->GetMembersObject();
++                sal_Int32 nIndex = pMembers->GetIndexFromName( rFilter.MatchValue );
++                if ( nIndex >= 0 )
++                {
++                    ScDPItemData aItem;
++                    pMembers->getByIndex(nIndex)->FillItemData( aItem );
++                    aFilterMap.insert( hash_map<long, ScDPItemData>::value_type(nCol, aItem) );
++                }
++            }
++        }
++    }
++
 +    Sequence< Sequence<Any> > aTabData;
-+    pData->GetDrillDownData(aFilters, aTabData);
++    pData->GetDrillDownData(aFilterMap, aTabData);
 +    return aTabData;
 +}
 +
  String ScDPSource::getDataDescription()
  {
  	CreateRes_Impl();		// create pResData
-@@ -507,7 +525,7 @@
+@@ -508,7 +555,7 @@
  	bResultOverflow = FALSE;
  }
  
@@ -4088,7 +4371,7 @@
  {
  	//	Calculate the product of the member count for those consecutive levels that
  	//	have the "show all" flag, one following level, and the data layout dimension.
-@@ -579,6 +597,54 @@
+@@ -580,6 +627,54 @@
      return -1;  // not found
  }
  
@@ -4143,7 +4426,7 @@
  void ScDPSource::CreateRes_Impl()
  {
  	if ( !pResData )
-@@ -592,24 +658,33 @@
+@@ -593,24 +688,33 @@
  			nDataOrient = sheet::DataPilotFieldOrientation_ROW;
  		}
  
@@ -4179,7 +4462,7 @@
  			long nDimIndex = nDataDims[i];
  			ScDPDimension* pDim = GetDimensionsObject()->getByIndex(nDimIndex);
  			sheet::GeneralFunction eUser = (sheet::GeneralFunction)pDim->getFunction();
-@@ -618,7 +693,11 @@
+@@ -619,7 +723,11 @@
  				//!	test for numeric data
  				eUser = sheet::GeneralFunction_SUM;
  			}
@@ -4191,7 +4474,7 @@
  			pDataRefValues[i] = pDim->GetReferenceValue();
  			nDataRefOrient[i] = sheet::DataPilotFieldOrientation_HIDDEN;	// default if not used
  			sal_Int32 eRefType = pDataRefValues[i].ReferenceType;
-@@ -652,10 +731,10 @@
+@@ -653,10 +761,10 @@
  			//!	the complete name (function and field) must be stored at the dimension
  
  			long nSource = ((ScDPDimension*)pDim)->GetSourceDim();
@@ -4205,7 +4488,7 @@
  		}
  
  		pResData = new ScDPResultData( this );
-@@ -666,7 +745,7 @@
+@@ -667,7 +775,7 @@
  		delete[] pDataNames;
  		delete[] pDataRefValues;
  
@@ -4214,7 +4497,7 @@
  
          ScDPInitState aInitState;
  
-@@ -684,86 +763,22 @@
+@@ -685,86 +793,22 @@
  		pColResRoot = new ScDPResultMember( pResData, NULL, NULL, NULL, bColumnGrand );
  		pRowResRoot = new ScDPResultMember( pResData, NULL, NULL, NULL, bRowGrand );
  
@@ -4230,14 +4513,14 @@
 -				nHierarchy = 0;
 -			ScDPLevels* pLevels = pDim->GetHierarchiesObject()->getByIndex(nHierarchy)->GetLevelsObject();
 -			long nCount = pLevels->getCount();
-+        FillCalcInfo(false, aInfo, bHasAutoShow);
-+        long nColLevelCount = aInfo.aColLevels.size();
- 
+-
 -			//!	Test
 -			if ( pDim->getIsDataLayoutDimension() && nDataDimCount < 2 )
 -				nCount = 0;
 -			//!	Test
--
++        FillCalcInfo(false, aInfo, bHasAutoShow);
++        long nColLevelCount = aInfo.aColLevels.size();
+ 
 -			for (long j=0; j<nCount; j++)
 -			{
 -			    ScDPLevel* pLevel = pLevels->getByIndex(j);
@@ -4308,7 +4591,7 @@
  		pRowResRoot->SetHasElements();
  
          // initialize members object also for all page dimensions (needed for numeric groups)
-@@ -773,6 +788,7 @@
+@@ -774,6 +818,7 @@
              long nHierarchy = pDim->getUsedHierarchy();
              if ( nHierarchy >= pDim->GetHierarchiesObject()->getCount() )
                  nHierarchy = 0;
@@ -4316,7 +4599,7 @@
              ScDPLevels* pLevels = pDim->GetHierarchiesObject()->getByIndex(nHierarchy)->GetLevelsObject();
              long nCount = pLevels->getCount();
              for (long j=0; j<nCount; j++)
-@@ -782,8 +798,9 @@
+@@ -783,8 +828,9 @@
  		//	pre-check: calculate minimum number of result columns / rows from
  		//	levels that have the "show all" flag set
  
@@ -4328,7 +4611,7 @@
  		if ( nMinColMembers > SC_MINCOUNT_LIMIT || nMinRowMembers > SC_MINCOUNT_LIMIT )
  		{
  			//	resulting table is too big -> abort before calculating
-@@ -793,49 +810,25 @@
+@@ -794,49 +840,25 @@
  		}
  		else
  		{
@@ -4393,7 +4676,7 @@
  
  			// ----------------------------------------------------------------
  			//  With all data processed, calculate the final results:
-@@ -853,21 +846,7 @@
+@@ -854,21 +876,7 @@
      			//  desired members only.
      			pColResRoot->ResetResults( TRUE );
      			pRowResRoot->ResetResults( TRUE );
@@ -4416,7 +4699,7 @@
  
      			//  Call UpdateDataResults again, with the new (limited) values.
      			pRowResRoot->UpdateDataResults( pColResRoot, pResData->GetRowStartMeasure() );
-@@ -893,105 +872,6 @@
+@@ -894,105 +902,6 @@
  	}
  }
  
@@ -4522,7 +4805,7 @@
  void ScDPSource::DumpState( ScDocument* pDoc, const ScAddress& rPos )
  {
      CreateRes_Impl();
-@@ -1185,6 +1065,12 @@
+@@ -1186,6 +1095,12 @@
  		lcl_SetBoolInAny( aRet, getRepeatIfEmpty() );
  	else if ( aNameStr.EqualsAscii( SC_UNO_DATADESC ) )				// read-only
  		aRet <<= rtl::OUString( getDataDescription() );
@@ -4538,11 +4821,11 @@
 Index: sc/source/core/data/makefile.mk
 ===================================================================
 RCS file: /cvs/sc/sc/source/core/data/makefile.mk,v
-retrieving revision 1.21
-retrieving revision 1.21.202.1
-diff -u -b -I $Revision.*$ -I $Author.*$ -r1.21 -r1.21.202.1
---- sc/source/core/data/makefile.mk	27 Feb 2007 12:06:42 -0000	1.21
-+++ sc/source/core/data/makefile.mk	29 Oct 2007 17:44:40 -0000	1.21.202.1
+retrieving revision 1.23
+retrieving revision 1.21.202.3
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.23 -r1.21.202.3
+--- sc/source/core/data/makefile.mk	7 Mar 2008 11:13:34 -0000	1.23
++++ sc/source/core/data/makefile.mk	12 Mar 2008 18:02:06 -0000	1.21.202.3
 @@ -77,6 +77,7 @@
  	$(SLO)$/documen8.obj \
  	$(SLO)$/documen9.obj \
@@ -4551,7 +4834,7 @@
          $(SLO)$/dpdimsave.obj \
          $(SLO)$/dpgroup.obj \
  	$(SLO)$/dpobject.obj \
-@@ -131,6 +132,7 @@
+@@ -132,6 +133,7 @@
  	$(SLO)$/documen5.obj \
  	$(SLO)$/documen6.obj \
  	$(SLO)$/documen9.obj \
@@ -4580,10 +4863,10 @@
 ===================================================================
 RCS file: /cvs/sc/sc/source/ui/unoobj/dapiuno.cxx,v
 retrieving revision 1.20
-retrieving revision 1.19.202.7
-diff -u -b -I $Revision.*$ -I $Author.*$ -r1.20 -r1.19.202.7
+retrieving revision 1.19.202.10
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.20 -r1.19.202.10
 --- sc/source/ui/unoobj/dapiuno.cxx	20 Nov 2007 17:42:20 -0000	1.20
-+++ sc/source/ui/unoobj/dapiuno.cxx	6 Dec 2007 01:51:27 -0000	1.19.202.7
++++ sc/source/ui/unoobj/dapiuno.cxx	19 Apr 2008 18:40:53 -0000	1.19.202.10
 @@ -45,6 +45,7 @@
  #include "datauno.hxx"
  #include "miscuno.hxx"
@@ -4592,7 +4875,7 @@
  #include "pivot.hxx"
  #include "rangeutl.hxx"
  #include "unoguard.hxx"
-@@ -76,12 +77,23 @@
+@@ -76,12 +77,24 @@
  #include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp>
  #endif
  
@@ -4606,6 +4889,7 @@
  
  using namespace com::sun::star;
  
++using ::com::sun::star::lang::IllegalArgumentException;
 +using ::com::sun::star::sheet::DataPilotFieldFilter;
 +using ::com::sun::star::sheet::DataPilotTablePositionData;
 +using ::com::sun::star::uno::Sequence;
@@ -4616,7 +4900,7 @@
  
  //------------------------------------------------------------------------
  
-@@ -532,7 +544,7 @@
+@@ -532,7 +545,7 @@
  									lang::WrappedTargetException, uno::RuntimeException)
  {
  	ScUnoGuard aGuard;
@@ -4625,7 +4909,7 @@
  	if (xTable.is())
          return uno::makeAny(xTable);
  	else
-@@ -543,7 +555,7 @@
+@@ -543,7 +556,7 @@
  uno::Type SAL_CALL ScDataPilotTablesObj::getElementType() throw(uno::RuntimeException)
  {
  	ScUnoGuard aGuard;
@@ -4634,7 +4918,7 @@
  }
  
  sal_Bool SAL_CALL ScDataPilotTablesObj::hasElements() throw(uno::RuntimeException)
-@@ -559,7 +571,7 @@
+@@ -559,7 +572,7 @@
  					lang::WrappedTargetException, uno::RuntimeException)
  {
  	ScUnoGuard aGuard;
@@ -4643,7 +4927,7 @@
  	if (xTable.is())
          return uno::makeAny(xTable);
  	else
-@@ -1014,7 +1026,7 @@
+@@ -1014,7 +1027,7 @@
  uno::Any SAL_CALL ScDataPilotTableObj::queryInterface( const uno::Type& rType )
  												throw(uno::RuntimeException)
  {
@@ -4652,7 +4936,7 @@
  
  	return ScDataPilotDescriptorBase::queryInterface( rType );
  }
-@@ -1041,7 +1053,7 @@
+@@ -1041,7 +1054,7 @@
  
  		aTypes.realloc( nParentLen + 1 );
  		uno::Type* pPtr = aTypes.getArray();
@@ -4661,7 +4945,7 @@
  
  		for (long i=0; i<nParentLen; i++)
  			pPtr[i] = pParentPtr[i];				// parent types first
-@@ -1164,6 +1176,59 @@
+@@ -1164,6 +1177,70 @@
  	}
  }
  
@@ -4671,7 +4955,11 @@
 +    ScUnoGuard aGuard;
 +    Sequence< Sequence<Any> > aTabData;
 +    ScAddress aAddr2(aAddr.Column, aAddr.Row, aAddr.Sheet);
-+    GetDPObject()->GetDrillDownData(aAddr2, aTabData);
++    ScDPObject* pObj = GetDPObject();
++    if (!pObj)
++        throw RuntimeException();
++
++    pObj->GetDrillDownData(aAddr2, aTabData);
 +    return aTabData;
 +}
 +
@@ -4681,7 +4969,11 @@
 +    ScUnoGuard aGuard;
 +    DataPilotTablePositionData aPosData;
 +    ScAddress aAddr2(aAddr.Column, aAddr.Row, aAddr.Sheet);
-+    GetDPObject()->GetPositionData(aAddr2, aPosData);
++    ScDPObject* pObj = GetDPObject();
++    if (!pObj)
++        throw RuntimeException();
++
++    pObj->GetPositionData(aAddr2, aPosData);
 +    return aPosData;
 +}
 +
@@ -4700,9 +4992,12 @@
 +}
 +
 +CellRangeAddress SAL_CALL ScDataPilotTableObj::getOutputRangeByType( sal_Int32 nType )
-+    throw (RuntimeException)
++    throw (IllegalArgumentException, RuntimeException)
 +{
 +    ScUnoGuard aGuard;
++    if (nType < 0 || nType > ::com::sun::star::sheet::DataPilotOutputRangeType::RESULT)
++        throw IllegalArgumentException();
++
 +    table::CellRangeAddress aRet;
 +    ScDPObject* pDPObj = lcl_GetDPObject(GetDocShell(), nTab, aName);
 +    if (!pDPObj)
@@ -4724,21 +5019,12 @@
 Index: sc/source/ui/view/cellsh1.cxx
 ===================================================================
 RCS file: /cvs/sc/sc/source/ui/view/cellsh1.cxx,v
-retrieving revision 1.48
-retrieving revision 1.46.172.3
-diff -u -b -I $Revision.*$ -I $Author.*$ -r1.48 -r1.46.172.3
---- sc/source/ui/view/cellsh1.cxx	26 Nov 2007 15:20:42 -0000	1.48
-+++ sc/source/ui/view/cellsh1.cxx	5 Dec 2007 00:25:15 -0000	1.46.172.3
-@@ -35,7 +35,7 @@
- 
- // MARKER(update_precomp.py): autogen include statement, do not remove
- #include "precompiled_sc.hxx"
--
-+#include <stdio.h>
- 
- //------------------------------------------------------------------
- 
-@@ -973,7 +973,7 @@
+retrieving revision 1.49
+retrieving revision 1.46.172.5
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.49 -r1.46.172.5
+--- sc/source/ui/view/cellsh1.cxx	29 Jan 2008 15:48:29 -0000	1.49
++++ sc/source/ui/view/cellsh1.cxx	21 Apr 2008 03:07:58 -0000	1.46.172.5
+@@ -975,7 +975,7 @@
                                      GetViewData()->GetCurY(), GetViewData()->GetTabNo() );
                  if ( pDPObj )
                  {
@@ -4747,7 +5033,7 @@
                      USHORT nOrientation;
                      if ( pTabViewShell->HasSelectionForDrillDown( nOrientation ) )
                      {
-@@ -990,9 +990,9 @@
+@@ -992,9 +992,9 @@
                          }
                      }
                      else if ( !pDPObj->IsServiceData() &&
@@ -4763,11 +5049,11 @@
 Index: sc/source/ui/view/dbfunc3.cxx
 ===================================================================
 RCS file: /cvs/sc/sc/source/ui/view/dbfunc3.cxx,v
-retrieving revision 1.15
-retrieving revision 1.13.202.6
-diff -u -b -I $Revision.*$ -I $Author.*$ -r1.15 -r1.13.202.6
---- sc/source/ui/view/dbfunc3.cxx	26 Nov 2007 15:21:00 -0000	1.15
-+++ sc/source/ui/view/dbfunc3.cxx	6 Dec 2007 06:40:28 -0000	1.13.202.6
+retrieving revision 1.16
+retrieving revision 1.13.202.7
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.16 -r1.13.202.7
+--- sc/source/ui/view/dbfunc3.cxx	19 Feb 2008 15:34:47 -0000	1.16
++++ sc/source/ui/view/dbfunc3.cxx	25 Feb 2008 14:47:44 -0000	1.13.202.7
 @@ -40,6 +40,7 @@
  
  // INCLUDE ---------------------------------------------------------------
@@ -4819,7 +5105,7 @@
  
  // STATIC DATA -----------------------------------------------------------
  
-@@ -718,22 +732,21 @@
+@@ -719,22 +733,21 @@
          for (SCROW nRow=nStartRow; nRow<=nEndRow && bContinue; nRow++)
              for (SCCOL nCol=nStartCol; nCol<=nEndCol && bContinue; nCol++)
              {
@@ -4852,7 +5138,7 @@
                      {
                          bContinue = FALSE;          // cannot mix dimensions
                      }
-@@ -742,9 +755,9 @@
+@@ -743,9 +756,9 @@
                  {
                      // accept any part of a member description, also subtotals,
                      // but don't stop if empty parts are contained
@@ -4864,7 +5150,7 @@
                          if ( !rEntries.Insert( pNew ) )
                              delete pNew;
                      }
-@@ -1421,16 +1434,16 @@
+@@ -1422,16 +1435,16 @@
              // renaming a group (item)?
              // allow only on the item name itself - not on empty cells, not on subtotals
  
@@ -4886,7 +5172,7 @@
  
                      ScDPDimensionSaveData* pDimData = aData.GetDimensionData();
                      ScDPSaveGroupDimension* pGroupDim = pDimData->GetNamedGroupDimAcc( aDimName );
-@@ -1504,26 +1517,26 @@
+@@ -1505,26 +1518,26 @@
      ScDPObject* pDPObj = pDoc->GetDPAtCursor( rSource.aStart.Col(), rSource.aStart.Row(), rSource.aStart.Tab() );
      if ( pDPObj && pDPObj == pDoc->GetDPAtCursor( rDest.Col(), rDest.Row(), rDest.Tab() ) )
      {
@@ -4924,7 +5210,7 @@
                      }
                      // duplicates are ignored
                  }
-@@ -1534,7 +1547,7 @@
+@@ -1535,7 +1548,7 @@
          if ( bValid )
          {
              BOOL bIsDataLayout;
@@ -4933,7 +5219,7 @@
              if ( !bIsDataLayout )
              {
                  ScDPSaveData aData( *pDPObj->GetSaveData() );
-@@ -1542,7 +1555,7 @@
+@@ -1543,7 +1556,7 @@
  
                  // get all member names in source order
                  uno::Sequence<rtl::OUString> aMemberNames;
@@ -4942,7 +5228,7 @@
  
                  bool bInserted = false;
  
-@@ -1551,10 +1564,10 @@
+@@ -1552,10 +1565,10 @@
                  {
                      String aMemberStr( aMemberNames[nMemberPos] );
  
@@ -4955,7 +5241,7 @@
                                aIter != aMembersVector.end(); ++aIter )
                              lcl_MoveToEnd( *pDim, *aIter );
                          bInserted = true;
-@@ -1565,7 +1578,7 @@
+@@ -1566,7 +1579,7 @@
                  }
                  // insert dragged item at end if dest wasn't found (for example, empty)
                  if ( !bInserted )
@@ -4964,7 +5250,7 @@
                            aIter != aMembersVector.end(); ++aIter )
                          lcl_MoveToEnd( *pDim, *aIter );
  
-@@ -1720,19 +1733,62 @@
+@@ -1721,19 +1734,62 @@
      }
  }
  
@@ -5036,7 +5322,7 @@
          SCCOL nEndCol = 0;
          SCROW nEndRow = 0;
          pInsDoc->GetCellArea( nNewTab, nEndCol, nEndRow );
-@@ -1742,15 +1798,12 @@
+@@ -1743,15 +1799,12 @@
          String aUndo = ScGlobal::GetRscString( STR_UNDO_DOOUTLINE );
          pMgr->EnterListAction( aUndo, aUndo );
  
@@ -5057,10 +5343,11 @@
 Index: sc/source/ui/view/gridwin.cxx
 ===================================================================
 RCS file: /cvs/sc/sc/source/ui/view/gridwin.cxx,v
-retrieving revision 1.88
-diff -u -b -I $Revision.*$ -I $Author.*$ -r1.88 gridwin.cxx
---- sc/source/ui/view/gridwin.cxx	12 Dec 2007 13:21:19 -0000	1.88
-+++ sc/source/ui/view/gridwin.cxx	1 Feb 2008 05:52:06 -0000
+retrieving revision 1.92
+retrieving revision 1.85.36.11
+diff -u -b -I $Revision.*$ -I $Author.*$ -r1.92 -r1.85.36.11
+--- sc/source/ui/view/gridwin.cxx	6 Mar 2008 16:20:33 -0000	1.92
++++ sc/source/ui/view/gridwin.cxx	21 Apr 2008 03:07:59 -0000	1.85.36.11
 @@ -93,6 +93,10 @@
  
  #include <com/sun/star/sheet/DataPilotFieldFilter.hpp>
@@ -5081,7 +5368,7 @@
  
  const BYTE SC_NESTEDBUTTON_NONE = 0;
  const BYTE SC_NESTEDBUTTON_DOWN = 1;
-@@ -2028,11 +2034,13 @@
+@@ -2030,11 +2036,13 @@
  		if ( pDPObj && pDPObj->GetSaveData()->GetDrillDown() )
  		{
  			ScAddress aCellPos( nPosX, nPosY, nTab );
@@ -5099,7 +5386,7 @@
  			{
                  USHORT nDummy;
                  if ( pView->HasSelectionForDrillDown( nDummy ) )
-@@ -2054,8 +2062,8 @@
+@@ -2056,8 +2064,8 @@
              {
                  // Check if the data area is double-clicked.
  
@@ -5110,7 +5397,7 @@
                      pViewData->GetView()->ShowDataPilotSourceData( *pDPObj, aFilters );
                  else
                      Sound::Beep();  // nothing to expand/collapse/show
-@@ -3238,24 +3246,24 @@
+@@ -3240,24 +3248,24 @@
              bool bDPSort = false;
              if ( pThisDoc->GetDPAtCursor( nSourceStartX, nSourceStartY, aSourceRange.aStart.Tab() ) == pDPObj )
              {

Modified: trunk/scratch/sc-dptest/Makefile
==============================================================================
--- trunk/scratch/sc-dptest/Makefile	(original)
+++ trunk/scratch/sc-dptest/Makefile	Mon Apr 21 04:25:54 2008
@@ -1,5 +1,5 @@
 CWS_WORK_STAMP=koheidatapilot01
-MILESTONE=m238
+MILESTONE=m2
 BASEDIR=$(HOME)/ooo/$(CWS_WORK_STAMP)-$(MILESTONE)
 INSTBASEDIR=$(HOME)/ooo/install/$(CWS_WORK_STAMP)-$(MILESTONE)
 OBJDIR=obj
@@ -8,8 +8,8 @@
 CPPFLAGS= \
 	$(DEFINES) \
 	-I$(BASEDIR)/cppuhelper/inc \
-	-I$(BASEDIR)/solver/680/unxlngi6.pro/inc \
-	-I$(BASEDIR)/solver/680/unxlngi6.pro/inc/offuh \
+	-I$(BASEDIR)/solver/300/unxlngi6.pro/inc \
+	-I$(BASEDIR)/solver/300/unxlngi6.pro/inc/offuh \
 	-I./inc
 
 LDFLAGS= \



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]