1b3f79822SAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
3b3f79822SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
4b3f79822SAndrew Rist * or more contributor license agreements. See the NOTICE file
5b3f79822SAndrew Rist * distributed with this work for additional information
6b3f79822SAndrew Rist * regarding copyright ownership. The ASF licenses this file
7b3f79822SAndrew Rist * to you under the Apache License, Version 2.0 (the
8b3f79822SAndrew Rist * "License"); you may not use this file except in compliance
9b3f79822SAndrew Rist * with the License. You may obtain a copy of the License at
10b3f79822SAndrew Rist *
11b3f79822SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12b3f79822SAndrew Rist *
13b3f79822SAndrew Rist * Unless required by applicable law or agreed to in writing,
14b3f79822SAndrew Rist * software distributed under the License is distributed on an
15b3f79822SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16b3f79822SAndrew Rist * KIND, either express or implied. See the License for the
17b3f79822SAndrew Rist * specific language governing permissions and limitations
18b3f79822SAndrew Rist * under the License.
19b3f79822SAndrew Rist *
20b3f79822SAndrew Rist *************************************************************/
21b3f79822SAndrew Rist
22b3f79822SAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sc.hxx"
26cdf0e10cSrcweir
27cdf0e10cSrcweir
28cdf0e10cSrcweir
29cdf0e10cSrcweir // INCLUDE ---------------------------------------------------------------
30cdf0e10cSrcweir
31cdf0e10cSrcweir #include "scitems.hxx"
32cdf0e10cSrcweir #include <svx/algitem.hxx>
33cdf0e10cSrcweir #include <editeng/boxitem.hxx>
34cdf0e10cSrcweir #include <editeng/brshitem.hxx>
35cdf0e10cSrcweir #include <editeng/wghtitem.hxx>
36cdf0e10cSrcweir #include <unotools/transliterationwrapper.hxx>
37cdf0e10cSrcweir
38cdf0e10cSrcweir #include "dpoutput.hxx"
39cdf0e10cSrcweir #include "dptabsrc.hxx"
40cdf0e10cSrcweir #include "dpcachetable.hxx"
41cdf0e10cSrcweir #include "document.hxx"
42cdf0e10cSrcweir #include "patattr.hxx"
43cdf0e10cSrcweir #include "docpool.hxx"
44cdf0e10cSrcweir #include "markdata.hxx"
45cdf0e10cSrcweir #include "attrib.hxx"
46cdf0e10cSrcweir #include "formula/errorcodes.hxx" // errNoValue
47cdf0e10cSrcweir #include "miscuno.hxx"
48cdf0e10cSrcweir #include "globstr.hrc"
49cdf0e10cSrcweir #include "stlpool.hxx"
50cdf0e10cSrcweir #include "stlsheet.hxx"
51cdf0e10cSrcweir #include "collect.hxx"
52cdf0e10cSrcweir #include "scresid.hxx"
53cdf0e10cSrcweir #include "unonames.hxx"
54cdf0e10cSrcweir #include "sc.hrc"
55cdf0e10cSrcweir // Wang Xu Ming -- 2009-8-17
56cdf0e10cSrcweir // DataPilot Migration - Cache&&Performance
57cdf0e10cSrcweir #include "scdpoutputimpl.hxx"
58cdf0e10cSrcweir #include "dpglobal.hxx"
59cdf0e10cSrcweir // End Comments
60cdf0e10cSrcweir #include <com/sun/star/beans/XPropertySet.hpp>
61cdf0e10cSrcweir
62cdf0e10cSrcweir #include <vector>
63cdf0e10cSrcweir
64cdf0e10cSrcweir using namespace com::sun::star;
65cdf0e10cSrcweir using ::std::vector;
66cdf0e10cSrcweir using ::com::sun::star::beans::XPropertySet;
67cdf0e10cSrcweir using ::com::sun::star::uno::Sequence;
68cdf0e10cSrcweir using ::com::sun::star::uno::UNO_QUERY;
69cdf0e10cSrcweir using ::com::sun::star::uno::Reference;
70cdf0e10cSrcweir using ::com::sun::star::sheet::DataPilotTablePositionData;
71cdf0e10cSrcweir using ::com::sun::star::sheet::DataPilotTableResultData;
72cdf0e10cSrcweir using ::com::sun::star::uno::makeAny;
73cdf0e10cSrcweir using ::com::sun::star::uno::Any;
74cdf0e10cSrcweir using ::rtl::OUString;
75cdf0e10cSrcweir
76cdf0e10cSrcweir // -----------------------------------------------------------------------
77cdf0e10cSrcweir
78cdf0e10cSrcweir //! move to a header file
79cdf0e10cSrcweir //! use names from unonames.hxx?
80cdf0e10cSrcweir #define DP_PROP_FUNCTION "Function"
81cdf0e10cSrcweir #define DP_PROP_ORIENTATION "Orientation"
82cdf0e10cSrcweir #define DP_PROP_POSITION "Position"
83cdf0e10cSrcweir #define DP_PROP_USEDHIERARCHY "UsedHierarchy"
84cdf0e10cSrcweir #define DP_PROP_ISDATALAYOUT "IsDataLayoutDimension"
85cdf0e10cSrcweir #define DP_PROP_NUMBERFORMAT "NumberFormat"
86cdf0e10cSrcweir #define DP_PROP_FILTER "Filter"
87cdf0e10cSrcweir #define DP_PROP_COLUMNGRAND "ColumnGrand"
88cdf0e10cSrcweir #define DP_PROP_ROWGRAND "RowGrand"
89cdf0e10cSrcweir #define DP_PROP_SUBTOTALS "SubTotals"
90cdf0e10cSrcweir
91cdf0e10cSrcweir // -----------------------------------------------------------------------
92cdf0e10cSrcweir
93cdf0e10cSrcweir //! dynamic!!!
94cdf0e10cSrcweir #define SC_DPOUT_MAXLEVELS 256
95cdf0e10cSrcweir
96cdf0e10cSrcweir
97cdf0e10cSrcweir struct ScDPOutLevelData
98cdf0e10cSrcweir {
99cdf0e10cSrcweir long nDim;
100cdf0e10cSrcweir long nHier;
101cdf0e10cSrcweir long nLevel;
102cdf0e10cSrcweir long nDimPos;
103cdf0e10cSrcweir uno::Sequence<sheet::MemberResult> aResult;
104cdf0e10cSrcweir String maName; /// Name is the internal field name.
105cdf0e10cSrcweir String aCaption; /// Caption is the name visible in the output table.
106cdf0e10cSrcweir bool mbHasHiddenMember;
107cdf0e10cSrcweir
ScDPOutLevelDataScDPOutLevelData108cdf0e10cSrcweir ScDPOutLevelData()
109cdf0e10cSrcweir {
110cdf0e10cSrcweir nDim = nHier = nLevel = nDimPos = -1;
111cdf0e10cSrcweir mbHasHiddenMember = false;
112cdf0e10cSrcweir }
113cdf0e10cSrcweir
operator <ScDPOutLevelData114cdf0e10cSrcweir sal_Bool operator<(const ScDPOutLevelData& r) const
115cdf0e10cSrcweir { return nDimPos<r.nDimPos || ( nDimPos==r.nDimPos && nHier<r.nHier ) ||
116cdf0e10cSrcweir ( nDimPos==r.nDimPos && nHier==r.nHier && nLevel<r.nLevel ); }
117cdf0e10cSrcweir
SwapScDPOutLevelData118cdf0e10cSrcweir void Swap(ScDPOutLevelData& r)
119cdf0e10cSrcweir //! { ScDPOutLevelData aTemp = r; r = *this; *this = aTemp; }
120cdf0e10cSrcweir { ScDPOutLevelData aTemp; aTemp = r; r = *this; *this = aTemp; }
121cdf0e10cSrcweir
122cdf0e10cSrcweir //! bug (73840) in uno::Sequence - copy and then assign doesn't work!
123cdf0e10cSrcweir };
124cdf0e10cSrcweir
125cdf0e10cSrcweir // -----------------------------------------------------------------------
126cdf0e10cSrcweir
lcl_SetStyleById(ScDocument * pDoc,SCTAB nTab,SCCOL nCol1,SCROW nRow1,SCCOL nCol2,SCROW nRow2,sal_uInt16 nStrId)127cdf0e10cSrcweir void lcl_SetStyleById( ScDocument* pDoc, SCTAB nTab,
128cdf0e10cSrcweir SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
129cdf0e10cSrcweir sal_uInt16 nStrId )
130cdf0e10cSrcweir {
131cdf0e10cSrcweir if ( nCol1 > nCol2 || nRow1 > nRow2 )
132cdf0e10cSrcweir {
133cdf0e10cSrcweir DBG_ERROR("SetStyleById: invalid range");
134cdf0e10cSrcweir return;
135cdf0e10cSrcweir }
136cdf0e10cSrcweir
137cdf0e10cSrcweir String aStyleName = ScGlobal::GetRscString( nStrId );
138cdf0e10cSrcweir ScStyleSheetPool* pStlPool = pDoc->GetStyleSheetPool();
139cdf0e10cSrcweir ScStyleSheet* pStyle = (ScStyleSheet*) pStlPool->Find( aStyleName, SFX_STYLE_FAMILY_PARA );
140cdf0e10cSrcweir if (!pStyle)
141cdf0e10cSrcweir {
142cdf0e10cSrcweir // create new style (was in ScPivot::SetStyle)
143cdf0e10cSrcweir
144cdf0e10cSrcweir pStyle = (ScStyleSheet*) &pStlPool->Make( aStyleName, SFX_STYLE_FAMILY_PARA,
145cdf0e10cSrcweir SFXSTYLEBIT_USERDEF );
146cdf0e10cSrcweir pStyle->SetParent( ScGlobal::GetRscString(STR_STYLENAME_STANDARD) );
147cdf0e10cSrcweir SfxItemSet& rSet = pStyle->GetItemSet();
148cdf0e10cSrcweir if ( nStrId==STR_PIVOT_STYLE_RESULT || nStrId==STR_PIVOT_STYLE_TITLE )
149cdf0e10cSrcweir rSet.Put( SvxWeightItem( WEIGHT_BOLD, ATTR_FONT_WEIGHT ) );
150cdf0e10cSrcweir if ( nStrId==STR_PIVOT_STYLE_CATEGORY || nStrId==STR_PIVOT_STYLE_TITLE )
151cdf0e10cSrcweir rSet.Put( SvxHorJustifyItem( SVX_HOR_JUSTIFY_LEFT, ATTR_HOR_JUSTIFY ) );
152cdf0e10cSrcweir }
153cdf0e10cSrcweir
154cdf0e10cSrcweir pDoc->ApplyStyleAreaTab( nCol1, nRow1, nCol2, nRow2, nTab, *pStyle );
155cdf0e10cSrcweir }
156cdf0e10cSrcweir
lcl_SetFrame(ScDocument * pDoc,SCTAB nTab,SCCOL nCol1,SCROW nRow1,SCCOL nCol2,SCROW nRow2,sal_uInt16 nWidth)157cdf0e10cSrcweir void lcl_SetFrame( ScDocument* pDoc, SCTAB nTab,
158cdf0e10cSrcweir SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
159cdf0e10cSrcweir sal_uInt16 nWidth )
160cdf0e10cSrcweir {
161cdf0e10cSrcweir SvxBorderLine aLine;
162cdf0e10cSrcweir aLine.SetOutWidth(nWidth);
163cdf0e10cSrcweir SvxBoxItem aBox( ATTR_BORDER );
164cdf0e10cSrcweir aBox.SetLine(&aLine, BOX_LINE_LEFT);
165cdf0e10cSrcweir aBox.SetLine(&aLine, BOX_LINE_TOP);
166cdf0e10cSrcweir aBox.SetLine(&aLine, BOX_LINE_RIGHT);
167cdf0e10cSrcweir aBox.SetLine(&aLine, BOX_LINE_BOTTOM);
168cdf0e10cSrcweir SvxBoxInfoItem aBoxInfo( ATTR_BORDER_INNER );
169cdf0e10cSrcweir aBoxInfo.SetValid(VALID_HORI,sal_False);
170cdf0e10cSrcweir aBoxInfo.SetValid(VALID_VERT,sal_False);
171cdf0e10cSrcweir aBoxInfo.SetValid(VALID_DISTANCE,sal_False);
172cdf0e10cSrcweir
173cdf0e10cSrcweir pDoc->ApplyFrameAreaTab( ScRange( nCol1, nRow1, nTab, nCol2, nRow2, nTab ), &aBox, &aBoxInfo );
174cdf0e10cSrcweir }
175cdf0e10cSrcweir
176cdf0e10cSrcweir // -----------------------------------------------------------------------
177cdf0e10cSrcweir
lcl_FillNumberFormats(sal_uInt32 * & rFormats,long & rCount,const uno::Reference<sheet::XDataPilotMemberResults> & xLevRes,const uno::Reference<container::XIndexAccess> & xDims)178cdf0e10cSrcweir void lcl_FillNumberFormats( sal_uInt32*& rFormats, long& rCount,
179cdf0e10cSrcweir const uno::Reference<sheet::XDataPilotMemberResults>& xLevRes,
180cdf0e10cSrcweir const uno::Reference<container::XIndexAccess>& xDims )
181cdf0e10cSrcweir {
182cdf0e10cSrcweir if ( rFormats )
183cdf0e10cSrcweir return; // already set
184cdf0e10cSrcweir
185cdf0e10cSrcweir // xLevRes is from the data layout dimension
186cdf0e10cSrcweir //! use result sequence from ScDPOutLevelData!
187cdf0e10cSrcweir
188cdf0e10cSrcweir uno::Sequence<sheet::MemberResult> aResult = xLevRes->getResults();
189cdf0e10cSrcweir
190cdf0e10cSrcweir long nSize = aResult.getLength();
191cdf0e10cSrcweir if (nSize)
192cdf0e10cSrcweir {
193cdf0e10cSrcweir // get names/formats for all data dimensions
194cdf0e10cSrcweir //! merge this with the loop to collect ScDPOutLevelData?
195cdf0e10cSrcweir
196cdf0e10cSrcweir String aDataNames[SC_DPOUT_MAXLEVELS];
197cdf0e10cSrcweir sal_uInt32 nDataFormats[SC_DPOUT_MAXLEVELS];
198cdf0e10cSrcweir long nDataCount = 0;
199cdf0e10cSrcweir sal_Bool bAnySet = sal_False;
200cdf0e10cSrcweir
201cdf0e10cSrcweir long nDimCount = xDims->getCount();
202cdf0e10cSrcweir for (long nDim=0; nDim<nDimCount; nDim++)
203cdf0e10cSrcweir {
204cdf0e10cSrcweir uno::Reference<uno::XInterface> xDim =
205cdf0e10cSrcweir ScUnoHelpFunctions::AnyToInterface( xDims->getByIndex(nDim) );
206cdf0e10cSrcweir uno::Reference<beans::XPropertySet> xDimProp( xDim, uno::UNO_QUERY );
207cdf0e10cSrcweir uno::Reference<container::XNamed> xDimName( xDim, uno::UNO_QUERY );
208cdf0e10cSrcweir if ( xDimProp.is() && xDimName.is() )
209cdf0e10cSrcweir {
210cdf0e10cSrcweir sheet::DataPilotFieldOrientation eDimOrient =
211cdf0e10cSrcweir (sheet::DataPilotFieldOrientation) ScUnoHelpFunctions::GetEnumProperty(
212cdf0e10cSrcweir xDimProp, rtl::OUString::createFromAscii(DP_PROP_ORIENTATION),
213cdf0e10cSrcweir sheet::DataPilotFieldOrientation_HIDDEN );
214cdf0e10cSrcweir if ( eDimOrient == sheet::DataPilotFieldOrientation_DATA )
215cdf0e10cSrcweir {
216cdf0e10cSrcweir aDataNames[nDataCount] = String( xDimName->getName() );
217cdf0e10cSrcweir long nFormat = ScUnoHelpFunctions::GetLongProperty(
218cdf0e10cSrcweir xDimProp,
219cdf0e10cSrcweir rtl::OUString::createFromAscii(DP_PROP_NUMBERFORMAT) );
220cdf0e10cSrcweir nDataFormats[nDataCount] = nFormat;
221cdf0e10cSrcweir if ( nFormat != 0 )
222cdf0e10cSrcweir bAnySet = sal_True;
223cdf0e10cSrcweir ++nDataCount;
224cdf0e10cSrcweir }
225cdf0e10cSrcweir }
226cdf0e10cSrcweir }
227cdf0e10cSrcweir
228cdf0e10cSrcweir if ( bAnySet ) // forget everything if all formats are 0 (or no data dimensions)
229cdf0e10cSrcweir {
230cdf0e10cSrcweir const sheet::MemberResult* pArray = aResult.getConstArray();
231cdf0e10cSrcweir
232cdf0e10cSrcweir String aName;
233cdf0e10cSrcweir sal_uInt32* pNumFmt = new sal_uInt32[nSize];
234cdf0e10cSrcweir if (nDataCount == 1)
235cdf0e10cSrcweir {
236cdf0e10cSrcweir // only one data dimension -> use its numberformat everywhere
237cdf0e10cSrcweir long nFormat = nDataFormats[0];
238cdf0e10cSrcweir for (long nPos=0; nPos<nSize; nPos++)
239cdf0e10cSrcweir pNumFmt[nPos] = nFormat;
240cdf0e10cSrcweir }
241cdf0e10cSrcweir else
242cdf0e10cSrcweir {
243cdf0e10cSrcweir for (long nPos=0; nPos<nSize; nPos++)
244cdf0e10cSrcweir {
245cdf0e10cSrcweir // if CONTINUE bit is set, keep previous name
246cdf0e10cSrcweir //! keep number format instead!
247cdf0e10cSrcweir if ( !(pArray[nPos].Flags & sheet::MemberResultFlags::CONTINUE) )
248cdf0e10cSrcweir aName = String( pArray[nPos].Name );
249cdf0e10cSrcweir
250cdf0e10cSrcweir sal_uInt32 nFormat = 0;
251cdf0e10cSrcweir for (long i=0; i<nDataCount; i++)
252cdf0e10cSrcweir if (aName == aDataNames[i]) //! search more efficiently?
253cdf0e10cSrcweir {
254cdf0e10cSrcweir nFormat = nDataFormats[i];
255cdf0e10cSrcweir break;
256cdf0e10cSrcweir }
257cdf0e10cSrcweir pNumFmt[nPos] = nFormat;
258cdf0e10cSrcweir }
259cdf0e10cSrcweir }
260cdf0e10cSrcweir
261cdf0e10cSrcweir rFormats = pNumFmt;
262cdf0e10cSrcweir rCount = nSize;
263cdf0e10cSrcweir }
264cdf0e10cSrcweir }
265cdf0e10cSrcweir }
266cdf0e10cSrcweir
lcl_GetFirstNumberFormat(const uno::Reference<container::XIndexAccess> & xDims)267cdf0e10cSrcweir sal_uInt32 lcl_GetFirstNumberFormat( const uno::Reference<container::XIndexAccess>& xDims )
268cdf0e10cSrcweir {
269cdf0e10cSrcweir long nDimCount = xDims->getCount();
270cdf0e10cSrcweir for (long nDim=0; nDim<nDimCount; nDim++)
271cdf0e10cSrcweir {
272cdf0e10cSrcweir uno::Reference<uno::XInterface> xDim =
273cdf0e10cSrcweir ScUnoHelpFunctions::AnyToInterface( xDims->getByIndex(nDim) );
274cdf0e10cSrcweir uno::Reference<beans::XPropertySet> xDimProp( xDim, uno::UNO_QUERY );
275cdf0e10cSrcweir if ( xDimProp.is() )
276cdf0e10cSrcweir {
277cdf0e10cSrcweir sheet::DataPilotFieldOrientation eDimOrient =
278cdf0e10cSrcweir (sheet::DataPilotFieldOrientation) ScUnoHelpFunctions::GetEnumProperty(
279cdf0e10cSrcweir xDimProp, rtl::OUString::createFromAscii(DP_PROP_ORIENTATION),
280cdf0e10cSrcweir sheet::DataPilotFieldOrientation_HIDDEN );
281cdf0e10cSrcweir if ( eDimOrient == sheet::DataPilotFieldOrientation_DATA )
282cdf0e10cSrcweir {
283cdf0e10cSrcweir long nFormat = ScUnoHelpFunctions::GetLongProperty(
284cdf0e10cSrcweir xDimProp,
285cdf0e10cSrcweir rtl::OUString::createFromAscii(DP_PROP_NUMBERFORMAT) );
286cdf0e10cSrcweir
287cdf0e10cSrcweir return nFormat; // use format from first found data dimension
288cdf0e10cSrcweir }
289cdf0e10cSrcweir }
290cdf0e10cSrcweir }
291cdf0e10cSrcweir
292cdf0e10cSrcweir return 0; // none found
293cdf0e10cSrcweir }
294cdf0e10cSrcweir
lcl_SortFields(ScDPOutLevelData * pFields,long nFieldCount)295cdf0e10cSrcweir void lcl_SortFields( ScDPOutLevelData* pFields, long nFieldCount )
296cdf0e10cSrcweir {
297cdf0e10cSrcweir for (long i=0; i+1<nFieldCount; i++)
298cdf0e10cSrcweir {
299cdf0e10cSrcweir for (long j=0; j+i+1<nFieldCount; j++)
300cdf0e10cSrcweir if ( pFields[j+1] < pFields[j] )
301cdf0e10cSrcweir pFields[j].Swap( pFields[j+1] );
302cdf0e10cSrcweir }
303cdf0e10cSrcweir }
304cdf0e10cSrcweir
lcl_MemberEmpty(const uno::Sequence<sheet::MemberResult> & rSeq)305cdf0e10cSrcweir sal_Bool lcl_MemberEmpty( const uno::Sequence<sheet::MemberResult>& rSeq )
306cdf0e10cSrcweir {
307cdf0e10cSrcweir // used to skip levels that have no members
308cdf0e10cSrcweir
309cdf0e10cSrcweir long nLen = rSeq.getLength();
310cdf0e10cSrcweir const sheet::MemberResult* pArray = rSeq.getConstArray();
311cdf0e10cSrcweir for (long i=0; i<nLen; i++)
312cdf0e10cSrcweir if (pArray[i].Flags & sheet::MemberResultFlags::HASMEMBER)
313cdf0e10cSrcweir return sal_False;
314cdf0e10cSrcweir
315cdf0e10cSrcweir return sal_True; // no member data -> empty
316cdf0e10cSrcweir }
317cdf0e10cSrcweir
lcl_GetSelectedPageAsResult(const uno::Reference<beans::XPropertySet> & xDimProp)318cdf0e10cSrcweir uno::Sequence<sheet::MemberResult> lcl_GetSelectedPageAsResult( const uno::Reference<beans::XPropertySet>& xDimProp )
319cdf0e10cSrcweir {
320cdf0e10cSrcweir uno::Sequence<sheet::MemberResult> aRet;
321cdf0e10cSrcweir if ( xDimProp.is() )
322cdf0e10cSrcweir {
323cdf0e10cSrcweir try
324cdf0e10cSrcweir {
325cdf0e10cSrcweir //! merge with ScDPDimension::setPropertyValue?
326cdf0e10cSrcweir
327cdf0e10cSrcweir uno::Any aValue = xDimProp->getPropertyValue( rtl::OUString::createFromAscii(DP_PROP_FILTER) );
328cdf0e10cSrcweir
329cdf0e10cSrcweir uno::Sequence<sheet::TableFilterField> aSeq;
330cdf0e10cSrcweir if (aValue >>= aSeq)
331cdf0e10cSrcweir {
332cdf0e10cSrcweir if ( aSeq.getLength() == 1 )
333cdf0e10cSrcweir {
334cdf0e10cSrcweir const sheet::TableFilterField& rField = aSeq[0];
335cdf0e10cSrcweir if ( rField.Field == 0 && rField.Operator == sheet::FilterOperator_EQUAL && !rField.IsNumeric )
336cdf0e10cSrcweir {
337cdf0e10cSrcweir rtl::OUString aSelectedPage( rField.StringValue );
338cdf0e10cSrcweir //! different name/caption string?
339cdf0e10cSrcweir sheet::MemberResult aResult( aSelectedPage, aSelectedPage, 0 );
340cdf0e10cSrcweir aRet = uno::Sequence<sheet::MemberResult>( &aResult, 1 );
341cdf0e10cSrcweir }
342cdf0e10cSrcweir }
343cdf0e10cSrcweir // else return empty sequence
344cdf0e10cSrcweir }
345cdf0e10cSrcweir }
346cdf0e10cSrcweir catch ( uno::Exception& )
347cdf0e10cSrcweir {
348cdf0e10cSrcweir // recent addition - allow source to not handle it (no error)
349cdf0e10cSrcweir }
350cdf0e10cSrcweir }
351cdf0e10cSrcweir return aRet;
352cdf0e10cSrcweir }
353cdf0e10cSrcweir
ScDPOutput(ScDocument * pD,const uno::Reference<sheet::XDimensionsSupplier> & xSrc,const ScAddress & rPos,sal_Bool bFilter)354cdf0e10cSrcweir ScDPOutput::ScDPOutput( ScDocument* pD, const uno::Reference<sheet::XDimensionsSupplier>& xSrc,
355cdf0e10cSrcweir const ScAddress& rPos, sal_Bool bFilter ) :
356cdf0e10cSrcweir pDoc( pD ),
357cdf0e10cSrcweir xSource( xSrc ),
358cdf0e10cSrcweir aStartPos( rPos ),
359cdf0e10cSrcweir bDoFilter( bFilter ),
360cdf0e10cSrcweir bResultsError( sal_False ),
361cdf0e10cSrcweir mbHasDataLayout(false),
362cdf0e10cSrcweir pColNumFmt( NULL ),
363cdf0e10cSrcweir pRowNumFmt( NULL ),
364cdf0e10cSrcweir nColFmtCount( 0 ),
365cdf0e10cSrcweir nRowFmtCount( 0 ),
366cdf0e10cSrcweir nSingleNumFmt( 0 ),
367cdf0e10cSrcweir bSizesValid( sal_False ),
368cdf0e10cSrcweir bSizeOverflow( sal_False ),
369cdf0e10cSrcweir mbHeaderLayout( false )
370cdf0e10cSrcweir {
371cdf0e10cSrcweir nTabStartCol = nMemberStartCol = nDataStartCol = nTabEndCol = 0;
372cdf0e10cSrcweir nTabStartRow = nMemberStartRow = nDataStartRow = nTabEndRow = 0;
373cdf0e10cSrcweir
374cdf0e10cSrcweir pColFields = new ScDPOutLevelData[SC_DPOUT_MAXLEVELS];
375cdf0e10cSrcweir pRowFields = new ScDPOutLevelData[SC_DPOUT_MAXLEVELS];
376cdf0e10cSrcweir pPageFields = new ScDPOutLevelData[SC_DPOUT_MAXLEVELS];
377cdf0e10cSrcweir nColFieldCount = 0;
378cdf0e10cSrcweir nRowFieldCount = 0;
379cdf0e10cSrcweir nPageFieldCount = 0;
380cdf0e10cSrcweir
381cdf0e10cSrcweir uno::Reference<sheet::XDataPilotResults> xResult( xSource, uno::UNO_QUERY );
382cdf0e10cSrcweir if ( xSource.is() && xResult.is() )
383cdf0e10cSrcweir {
384cdf0e10cSrcweir // get dimension results:
385cdf0e10cSrcweir
386cdf0e10cSrcweir uno::Reference<container::XIndexAccess> xDims =
387cdf0e10cSrcweir new ScNameToIndexAccess( xSource->getDimensions() );
388cdf0e10cSrcweir long nDimCount = xDims->getCount();
389cdf0e10cSrcweir for (long nDim=0; nDim<nDimCount; nDim++)
390cdf0e10cSrcweir {
391cdf0e10cSrcweir uno::Reference<uno::XInterface> xDim =
392cdf0e10cSrcweir ScUnoHelpFunctions::AnyToInterface( xDims->getByIndex(nDim) );
393cdf0e10cSrcweir uno::Reference<beans::XPropertySet> xDimProp( xDim, uno::UNO_QUERY );
394cdf0e10cSrcweir uno::Reference<sheet::XHierarchiesSupplier> xDimSupp( xDim, uno::UNO_QUERY );
395cdf0e10cSrcweir if ( xDimProp.is() && xDimSupp.is() )
396cdf0e10cSrcweir {
397cdf0e10cSrcweir sheet::DataPilotFieldOrientation eDimOrient =
398cdf0e10cSrcweir (sheet::DataPilotFieldOrientation) ScUnoHelpFunctions::GetEnumProperty(
399cdf0e10cSrcweir xDimProp, rtl::OUString::createFromAscii(DP_PROP_ORIENTATION),
400cdf0e10cSrcweir sheet::DataPilotFieldOrientation_HIDDEN );
401cdf0e10cSrcweir long nDimPos = ScUnoHelpFunctions::GetLongProperty( xDimProp,
402cdf0e10cSrcweir rtl::OUString::createFromAscii(DP_PROP_POSITION) );
403cdf0e10cSrcweir sal_Bool bIsDataLayout = ScUnoHelpFunctions::GetBoolProperty(
404cdf0e10cSrcweir xDimProp,
405cdf0e10cSrcweir rtl::OUString::createFromAscii(DP_PROP_ISDATALAYOUT) );
406cdf0e10cSrcweir bool bHasHiddenMember = ScUnoHelpFunctions::GetBoolProperty(
407cdf0e10cSrcweir xDimProp, OUString::createFromAscii(SC_UNO_HAS_HIDDEN_MEMBER));
408cdf0e10cSrcweir
409cdf0e10cSrcweir if ( eDimOrient != sheet::DataPilotFieldOrientation_HIDDEN )
410cdf0e10cSrcweir {
411cdf0e10cSrcweir uno::Reference<container::XIndexAccess> xHiers =
412cdf0e10cSrcweir new ScNameToIndexAccess( xDimSupp->getHierarchies() );
413cdf0e10cSrcweir long nHierarchy = ScUnoHelpFunctions::GetLongProperty(
414cdf0e10cSrcweir xDimProp,
415cdf0e10cSrcweir rtl::OUString::createFromAscii(DP_PROP_USEDHIERARCHY) );
416cdf0e10cSrcweir if ( nHierarchy >= xHiers->getCount() )
417cdf0e10cSrcweir nHierarchy = 0;
418cdf0e10cSrcweir
419cdf0e10cSrcweir uno::Reference<uno::XInterface> xHier =
420cdf0e10cSrcweir ScUnoHelpFunctions::AnyToInterface(
421cdf0e10cSrcweir xHiers->getByIndex(nHierarchy) );
422cdf0e10cSrcweir uno::Reference<sheet::XLevelsSupplier> xHierSupp( xHier, uno::UNO_QUERY );
423cdf0e10cSrcweir if ( xHierSupp.is() )
424cdf0e10cSrcweir {
425cdf0e10cSrcweir uno::Reference<container::XIndexAccess> xLevels =
426cdf0e10cSrcweir new ScNameToIndexAccess( xHierSupp->getLevels() );
427cdf0e10cSrcweir long nLevCount = xLevels->getCount();
428cdf0e10cSrcweir for (long nLev=0; nLev<nLevCount; nLev++)
429cdf0e10cSrcweir {
430cdf0e10cSrcweir uno::Reference<uno::XInterface> xLevel =
431cdf0e10cSrcweir ScUnoHelpFunctions::AnyToInterface(
432cdf0e10cSrcweir xLevels->getByIndex(nLev) );
433cdf0e10cSrcweir uno::Reference<container::XNamed> xLevNam( xLevel, uno::UNO_QUERY );
434cdf0e10cSrcweir uno::Reference<sheet::XDataPilotMemberResults> xLevRes(
435cdf0e10cSrcweir xLevel, uno::UNO_QUERY );
436cdf0e10cSrcweir if ( xLevNam.is() && xLevRes.is() )
437cdf0e10cSrcweir {
438cdf0e10cSrcweir String aName = xLevNam->getName();
439cdf0e10cSrcweir Reference<XPropertySet> xPropSet(xLevel, UNO_QUERY);
440cdf0e10cSrcweir // Caption equals the field name by default.
441cdf0e10cSrcweir // #i108948# use ScUnoHelpFunctions::GetStringProperty, because
442cdf0e10cSrcweir // LayoutName is new and may not be present in external implementation
443cdf0e10cSrcweir OUString aCaption = ScUnoHelpFunctions::GetStringProperty( xPropSet,
444cdf0e10cSrcweir OUString::createFromAscii(SC_UNO_LAYOUTNAME), aName );
445cdf0e10cSrcweir
446cdf0e10cSrcweir bool bRowFieldHasMember = false;
447cdf0e10cSrcweir switch ( eDimOrient )
448cdf0e10cSrcweir {
449cdf0e10cSrcweir case sheet::DataPilotFieldOrientation_COLUMN:
450cdf0e10cSrcweir pColFields[nColFieldCount].nDim = nDim;
451cdf0e10cSrcweir pColFields[nColFieldCount].nHier = nHierarchy;
452cdf0e10cSrcweir pColFields[nColFieldCount].nLevel = nLev;
453cdf0e10cSrcweir pColFields[nColFieldCount].nDimPos = nDimPos;
454cdf0e10cSrcweir pColFields[nColFieldCount].aResult = xLevRes->getResults();
455cdf0e10cSrcweir pColFields[nColFieldCount].maName = aName;
456cdf0e10cSrcweir pColFields[nColFieldCount].aCaption= aCaption;
457cdf0e10cSrcweir pColFields[nColFieldCount].mbHasHiddenMember = bHasHiddenMember;
458cdf0e10cSrcweir if (!lcl_MemberEmpty(pColFields[nColFieldCount].aResult))
459cdf0e10cSrcweir ++nColFieldCount;
460cdf0e10cSrcweir break;
461cdf0e10cSrcweir case sheet::DataPilotFieldOrientation_ROW:
462cdf0e10cSrcweir pRowFields[nRowFieldCount].nDim = nDim;
463cdf0e10cSrcweir pRowFields[nRowFieldCount].nHier = nHierarchy;
464cdf0e10cSrcweir pRowFields[nRowFieldCount].nLevel = nLev;
465cdf0e10cSrcweir pRowFields[nRowFieldCount].nDimPos = nDimPos;
466cdf0e10cSrcweir pRowFields[nRowFieldCount].aResult = xLevRes->getResults();
467cdf0e10cSrcweir pRowFields[nRowFieldCount].maName = aName;
468cdf0e10cSrcweir pRowFields[nRowFieldCount].aCaption= aCaption;
469cdf0e10cSrcweir pRowFields[nRowFieldCount].mbHasHiddenMember = bHasHiddenMember;
470cdf0e10cSrcweir if (!lcl_MemberEmpty(pRowFields[nRowFieldCount].aResult))
471cdf0e10cSrcweir {
472cdf0e10cSrcweir ++nRowFieldCount;
473cdf0e10cSrcweir bRowFieldHasMember = true;
474cdf0e10cSrcweir }
475cdf0e10cSrcweir break;
476cdf0e10cSrcweir case sheet::DataPilotFieldOrientation_PAGE:
477cdf0e10cSrcweir pPageFields[nPageFieldCount].nDim = nDim;
478cdf0e10cSrcweir pPageFields[nPageFieldCount].nHier = nHierarchy;
479cdf0e10cSrcweir pPageFields[nPageFieldCount].nLevel = nLev;
480cdf0e10cSrcweir pPageFields[nPageFieldCount].nDimPos = nDimPos;
481cdf0e10cSrcweir pPageFields[nPageFieldCount].aResult = lcl_GetSelectedPageAsResult(xDimProp);
482cdf0e10cSrcweir pPageFields[nPageFieldCount].maName = aName;
483cdf0e10cSrcweir pPageFields[nPageFieldCount].aCaption= aCaption;
484cdf0e10cSrcweir pPageFields[nPageFieldCount].mbHasHiddenMember = bHasHiddenMember;
485cdf0e10cSrcweir // no check on results for page fields
486cdf0e10cSrcweir ++nPageFieldCount;
487cdf0e10cSrcweir break;
488cdf0e10cSrcweir default:
489cdf0e10cSrcweir {
490cdf0e10cSrcweir // added to avoid warnings
491cdf0e10cSrcweir }
492cdf0e10cSrcweir }
493cdf0e10cSrcweir
494cdf0e10cSrcweir // get number formats from data dimensions
495cdf0e10cSrcweir if ( bIsDataLayout )
496cdf0e10cSrcweir {
497cdf0e10cSrcweir if (bRowFieldHasMember)
498cdf0e10cSrcweir mbHasDataLayout = true;
499cdf0e10cSrcweir
500cdf0e10cSrcweir DBG_ASSERT( nLevCount == 1, "data layout: multiple levels?" );
501cdf0e10cSrcweir if ( eDimOrient == sheet::DataPilotFieldOrientation_COLUMN )
502cdf0e10cSrcweir lcl_FillNumberFormats( pColNumFmt, nColFmtCount, xLevRes, xDims );
503cdf0e10cSrcweir else if ( eDimOrient == sheet::DataPilotFieldOrientation_ROW )
504cdf0e10cSrcweir lcl_FillNumberFormats( pRowNumFmt, nRowFmtCount, xLevRes, xDims );
505cdf0e10cSrcweir }
506cdf0e10cSrcweir }
507cdf0e10cSrcweir }
508cdf0e10cSrcweir }
509cdf0e10cSrcweir }
510cdf0e10cSrcweir else if ( bIsDataLayout )
511cdf0e10cSrcweir {
512cdf0e10cSrcweir // data layout dimension is hidden (allowed if there is only one data dimension)
513cdf0e10cSrcweir // -> use the number format from the first data dimension for all results
514cdf0e10cSrcweir
515cdf0e10cSrcweir nSingleNumFmt = lcl_GetFirstNumberFormat( xDims );
516cdf0e10cSrcweir }
517cdf0e10cSrcweir }
518cdf0e10cSrcweir }
519cdf0e10cSrcweir lcl_SortFields( pColFields, nColFieldCount );
520cdf0e10cSrcweir lcl_SortFields( pRowFields, nRowFieldCount );
521cdf0e10cSrcweir lcl_SortFields( pPageFields, nPageFieldCount );
522cdf0e10cSrcweir
523cdf0e10cSrcweir // get data results:
524cdf0e10cSrcweir
525cdf0e10cSrcweir try
526cdf0e10cSrcweir {
527cdf0e10cSrcweir aData = xResult->getResults();
528cdf0e10cSrcweir }
529cdf0e10cSrcweir catch (uno::RuntimeException&)
530cdf0e10cSrcweir {
531cdf0e10cSrcweir bResultsError = sal_True;
532cdf0e10cSrcweir }
533cdf0e10cSrcweir }
534cdf0e10cSrcweir
535cdf0e10cSrcweir // get "DataDescription" property (may be missing in external sources)
536cdf0e10cSrcweir
537cdf0e10cSrcweir uno::Reference<beans::XPropertySet> xSrcProp( xSource, uno::UNO_QUERY );
538cdf0e10cSrcweir if ( xSrcProp.is() )
539cdf0e10cSrcweir {
540cdf0e10cSrcweir try
541cdf0e10cSrcweir {
542cdf0e10cSrcweir uno::Any aAny = xSrcProp->getPropertyValue(
543cdf0e10cSrcweir rtl::OUString::createFromAscii(SC_UNO_DATADESC) );
544cdf0e10cSrcweir rtl::OUString aUStr;
545cdf0e10cSrcweir aAny >>= aUStr;
546cdf0e10cSrcweir aDataDescription = String( aUStr );
547cdf0e10cSrcweir }
548cdf0e10cSrcweir catch(uno::Exception&)
549cdf0e10cSrcweir {
550cdf0e10cSrcweir }
551cdf0e10cSrcweir }
552cdf0e10cSrcweir }
553cdf0e10cSrcweir
~ScDPOutput()554cdf0e10cSrcweir ScDPOutput::~ScDPOutput()
555cdf0e10cSrcweir {
556cdf0e10cSrcweir delete[] pColFields;
557cdf0e10cSrcweir delete[] pRowFields;
558cdf0e10cSrcweir delete[] pPageFields;
559cdf0e10cSrcweir
560cdf0e10cSrcweir delete[] pColNumFmt;
561cdf0e10cSrcweir delete[] pRowNumFmt;
562cdf0e10cSrcweir }
563cdf0e10cSrcweir
SetPosition(const ScAddress & rPos)564cdf0e10cSrcweir void ScDPOutput::SetPosition( const ScAddress& rPos )
565cdf0e10cSrcweir {
566cdf0e10cSrcweir aStartPos = rPos;
567cdf0e10cSrcweir bSizesValid = bSizeOverflow = sal_False;
568cdf0e10cSrcweir }
569cdf0e10cSrcweir
DataCell(SCCOL nCol,SCROW nRow,SCTAB nTab,const sheet::DataResult & rData)570cdf0e10cSrcweir void ScDPOutput::DataCell( SCCOL nCol, SCROW nRow, SCTAB nTab, const sheet::DataResult& rData )
571cdf0e10cSrcweir {
572cdf0e10cSrcweir long nFlags = rData.Flags;
573cdf0e10cSrcweir if ( nFlags & sheet::DataResultFlags::ERROR )
574cdf0e10cSrcweir {
575cdf0e10cSrcweir pDoc->SetError( nCol, nRow, nTab, errNoValue );
576cdf0e10cSrcweir }
577cdf0e10cSrcweir else if ( nFlags & sheet::DataResultFlags::HASDATA )
578cdf0e10cSrcweir {
579cdf0e10cSrcweir pDoc->SetValue( nCol, nRow, nTab, rData.Value );
580cdf0e10cSrcweir
581cdf0e10cSrcweir // use number formats from source
582cdf0e10cSrcweir
583cdf0e10cSrcweir DBG_ASSERT( bSizesValid, "DataCell: !bSizesValid" );
584cdf0e10cSrcweir sal_uInt32 nFormat = 0;
585cdf0e10cSrcweir if ( pColNumFmt )
586cdf0e10cSrcweir {
587cdf0e10cSrcweir if ( nCol >= nDataStartCol )
588cdf0e10cSrcweir {
589cdf0e10cSrcweir long nIndex = nCol - nDataStartCol;
590cdf0e10cSrcweir if ( nIndex < nColFmtCount )
591cdf0e10cSrcweir nFormat = pColNumFmt[nIndex];
592cdf0e10cSrcweir }
593cdf0e10cSrcweir }
594cdf0e10cSrcweir else if ( pRowNumFmt )
595cdf0e10cSrcweir {
596cdf0e10cSrcweir if ( nRow >= nDataStartRow )
597cdf0e10cSrcweir {
598cdf0e10cSrcweir long nIndex = nRow - nDataStartRow;
599cdf0e10cSrcweir if ( nIndex < nRowFmtCount )
600cdf0e10cSrcweir nFormat = pRowNumFmt[nIndex];
601cdf0e10cSrcweir }
602cdf0e10cSrcweir }
603cdf0e10cSrcweir else if ( nSingleNumFmt != 0 )
604cdf0e10cSrcweir nFormat = nSingleNumFmt; // single format is used everywhere
605cdf0e10cSrcweir if ( nFormat != 0 )
606cdf0e10cSrcweir pDoc->ApplyAttr( nCol, nRow, nTab, SfxUInt32Item( ATTR_VALUE_FORMAT, nFormat ) );
607cdf0e10cSrcweir }
608cdf0e10cSrcweir else
609cdf0e10cSrcweir {
610cdf0e10cSrcweir //pDoc->SetString( nCol, nRow, nTab, EMPTY_STRING );
611cdf0e10cSrcweir }
612cdf0e10cSrcweir
613cdf0e10cSrcweir // SubTotal formatting is controlled by headers
614cdf0e10cSrcweir }
615cdf0e10cSrcweir
HeaderCell(SCCOL nCol,SCROW nRow,SCTAB nTab,const sheet::MemberResult & rData,sal_Bool bColHeader,long nLevel)616cdf0e10cSrcweir void ScDPOutput::HeaderCell( SCCOL nCol, SCROW nRow, SCTAB nTab,
617cdf0e10cSrcweir const sheet::MemberResult& rData, sal_Bool bColHeader, long nLevel )
618cdf0e10cSrcweir {
619cdf0e10cSrcweir long nFlags = rData.Flags;
620cdf0e10cSrcweir
621cdf0e10cSrcweir rtl::OUStringBuffer aCaptionBuf;
622cdf0e10cSrcweir if (!(nFlags & sheet::MemberResultFlags::NUMERIC))
623cdf0e10cSrcweir // This caption is not a number. Make sure it won't get parsed as one.
624cdf0e10cSrcweir aCaptionBuf.append(sal_Unicode('\''));
625cdf0e10cSrcweir aCaptionBuf.append(rData.Caption);
626cdf0e10cSrcweir
627cdf0e10cSrcweir if ( nFlags & sheet::MemberResultFlags::HASMEMBER )
628cdf0e10cSrcweir {
629cdf0e10cSrcweir pDoc->SetString( nCol, nRow, nTab, aCaptionBuf.makeStringAndClear() );
630cdf0e10cSrcweir }
631cdf0e10cSrcweir else
632cdf0e10cSrcweir {
633cdf0e10cSrcweir //pDoc->SetString( nCol, nRow, nTab, EMPTY_STRING );
634cdf0e10cSrcweir }
635cdf0e10cSrcweir
636cdf0e10cSrcweir if ( nFlags & sheet::MemberResultFlags::SUBTOTAL )
637cdf0e10cSrcweir {
638cdf0e10cSrcweir // SvxWeightItem aItem( WEIGHT_BOLD ); // weight is in the style
639cdf0e10cSrcweir // Wang Xu Ming -- 2009-8-17
640cdf0e10cSrcweir // DataPilot Migration - Cache&&Performance
641cdf0e10cSrcweir OutputImpl outputimp( pDoc, nTab,
642cdf0e10cSrcweir nTabStartCol, nTabStartRow, nMemberStartCol, nMemberStartRow,
643cdf0e10cSrcweir nDataStartCol, nDataStartRow, nTabEndCol, nTabEndRow );
644cdf0e10cSrcweir // End Comments
645cdf0e10cSrcweir //! limit frames to horizontal or vertical?
646cdf0e10cSrcweir if (bColHeader)
647cdf0e10cSrcweir {
648cdf0e10cSrcweir // Wang Xu Ming -- 2009-8-17
649cdf0e10cSrcweir // DataPilot Migration - Cache&&Performance
650cdf0e10cSrcweir //lcl_SetFrame( pDoc,nTab, nCol,nMemberStartRow+(SCROW)nLevel, nCol,nTabEndRow, SC_DP_FRAME_INNER_BOLD );
651cdf0e10cSrcweir outputimp.OutputBlockFrame( nCol,nMemberStartRow+(SCROW)nLevel, nCol,nDataStartRow-1 );
652cdf0e10cSrcweir // End Comments
653cdf0e10cSrcweir
654cdf0e10cSrcweir lcl_SetStyleById( pDoc,nTab, nCol,nMemberStartRow+(SCROW)nLevel, nCol,nDataStartRow-1,
655cdf0e10cSrcweir STR_PIVOT_STYLE_TITLE );
656cdf0e10cSrcweir lcl_SetStyleById( pDoc,nTab, nCol,nDataStartRow, nCol,nTabEndRow,
657cdf0e10cSrcweir STR_PIVOT_STYLE_RESULT );
658cdf0e10cSrcweir }
659cdf0e10cSrcweir else
660cdf0e10cSrcweir {
661cdf0e10cSrcweir // Wang Xu Ming -- 2009-8-17
662cdf0e10cSrcweir // DataPilot Migration - Cache&&Performance
663cdf0e10cSrcweir //lcl_SetFrame( pDoc,nTab, nMemberStartCol+(sal_uInt16)nLevel,nRow, nTabEndCol,nRow, SC_DP_FRAME_INNER_BOLD );
664cdf0e10cSrcweir outputimp.OutputBlockFrame( nMemberStartCol+(SCCOL)nLevel,nRow, nDataStartCol-1,nRow );
665cdf0e10cSrcweir // End Comments
666cdf0e10cSrcweir lcl_SetStyleById( pDoc,nTab, nMemberStartCol+(SCCOL)nLevel,nRow, nDataStartCol-1,nRow,
667cdf0e10cSrcweir STR_PIVOT_STYLE_TITLE );
668cdf0e10cSrcweir lcl_SetStyleById( pDoc,nTab, nDataStartCol,nRow, nTabEndCol,nRow,
669cdf0e10cSrcweir STR_PIVOT_STYLE_RESULT );
670cdf0e10cSrcweir }
671cdf0e10cSrcweir }
672cdf0e10cSrcweir }
673cdf0e10cSrcweir
FieldCell(SCCOL nCol,SCROW nRow,SCTAB nTab,const String & rCaption,bool bInTable,bool bPopup,bool bHasHiddenMember)674cdf0e10cSrcweir void ScDPOutput::FieldCell( SCCOL nCol, SCROW nRow, SCTAB nTab, const String& rCaption,
675cdf0e10cSrcweir bool bInTable, bool bPopup, bool bHasHiddenMember )
676cdf0e10cSrcweir {
677cdf0e10cSrcweir pDoc->SetString( nCol, nRow, nTab, rCaption );
678cdf0e10cSrcweir if (bInTable)
679cdf0e10cSrcweir lcl_SetFrame( pDoc,nTab, nCol,nRow, nCol,nRow, 20 );
680cdf0e10cSrcweir
681cdf0e10cSrcweir // Button
682cdf0e10cSrcweir sal_uInt16 nMergeFlag = SC_MF_BUTTON;
683cdf0e10cSrcweir if (bPopup)
684cdf0e10cSrcweir nMergeFlag |= SC_MF_BUTTON_POPUP;
685cdf0e10cSrcweir if (bHasHiddenMember)
686cdf0e10cSrcweir nMergeFlag |= SC_MF_HIDDEN_MEMBER;
687cdf0e10cSrcweir pDoc->ApplyFlagsTab(nCol, nRow, nCol, nRow, nTab, nMergeFlag);
688cdf0e10cSrcweir
689cdf0e10cSrcweir lcl_SetStyleById( pDoc,nTab, nCol,nRow, nCol,nRow, STR_PIVOT_STYLE_FIELDNAME );
690cdf0e10cSrcweir }
691cdf0e10cSrcweir
lcl_DoFilterButton(ScDocument * pDoc,SCCOL nCol,SCROW nRow,SCTAB nTab)692cdf0e10cSrcweir void lcl_DoFilterButton( ScDocument* pDoc, SCCOL nCol, SCROW nRow, SCTAB nTab )
693cdf0e10cSrcweir {
694cdf0e10cSrcweir pDoc->SetString( nCol, nRow, nTab, ScGlobal::GetRscString(STR_CELL_FILTER) );
695cdf0e10cSrcweir pDoc->ApplyFlagsTab(nCol, nRow, nCol, nRow, nTab, SC_MF_BUTTON);
696cdf0e10cSrcweir }
697cdf0e10cSrcweir
CalcSizes()698cdf0e10cSrcweir void ScDPOutput::CalcSizes()
699cdf0e10cSrcweir {
700cdf0e10cSrcweir if (!bSizesValid)
701cdf0e10cSrcweir {
702cdf0e10cSrcweir // get column size of data from first row
703cdf0e10cSrcweir //! allow different sizes (and clear following areas) ???
704cdf0e10cSrcweir
705cdf0e10cSrcweir nRowCount = aData.getLength();
706cdf0e10cSrcweir const uno::Sequence<sheet::DataResult>* pRowAry = aData.getConstArray();
707cdf0e10cSrcweir nColCount = nRowCount ? ( pRowAry[0].getLength() ) : 0;
708cdf0e10cSrcweir
709cdf0e10cSrcweir nHeaderSize = 1;
710cdf0e10cSrcweir if (GetHeaderLayout() && nColFieldCount == 0)
711cdf0e10cSrcweir // Insert an extra header row only when there is no column field.
712cdf0e10cSrcweir nHeaderSize = 2;
713cdf0e10cSrcweir
714cdf0e10cSrcweir // calculate output positions and sizes
715cdf0e10cSrcweir
716cdf0e10cSrcweir long nPageSize = 0; //! use page fields!
717cdf0e10cSrcweir if ( bDoFilter || nPageFieldCount )
718cdf0e10cSrcweir {
719cdf0e10cSrcweir nPageSize += nPageFieldCount + 1; // plus one empty row
720cdf0e10cSrcweir if ( bDoFilter )
721cdf0e10cSrcweir ++nPageSize; // filter button above the page fields
722cdf0e10cSrcweir }
723cdf0e10cSrcweir
724cdf0e10cSrcweir if ( aStartPos.Col() + nRowFieldCount + nColCount - 1 > MAXCOL ||
725cdf0e10cSrcweir aStartPos.Row() + nPageSize + nHeaderSize + nColFieldCount + nRowCount > MAXROW )
726cdf0e10cSrcweir {
727cdf0e10cSrcweir bSizeOverflow = sal_True;
728cdf0e10cSrcweir }
729cdf0e10cSrcweir
730cdf0e10cSrcweir nTabStartCol = aStartPos.Col();
731cdf0e10cSrcweir nTabStartRow = aStartPos.Row() + (SCROW)nPageSize; // below page fields
732cdf0e10cSrcweir nMemberStartCol = nTabStartCol;
733cdf0e10cSrcweir nMemberStartRow = nTabStartRow + (SCROW) nHeaderSize;
734cdf0e10cSrcweir nDataStartCol = nMemberStartCol + (SCCOL)nRowFieldCount;
735cdf0e10cSrcweir nDataStartRow = nMemberStartRow + (SCROW)nColFieldCount;
736cdf0e10cSrcweir if ( nColCount > 0 )
737cdf0e10cSrcweir nTabEndCol = nDataStartCol + (SCCOL)nColCount - 1;
738cdf0e10cSrcweir else
739cdf0e10cSrcweir nTabEndCol = nDataStartCol; // single column will remain empty
740cdf0e10cSrcweir // if page fields are involved, include the page selection cells
741cdf0e10cSrcweir if ( nPageFieldCount > 0 && nTabEndCol < nTabStartCol + 1 )
742cdf0e10cSrcweir nTabEndCol = nTabStartCol + 1;
743cdf0e10cSrcweir if ( nRowCount > 0 )
744cdf0e10cSrcweir nTabEndRow = nDataStartRow + (SCROW)nRowCount - 1;
745cdf0e10cSrcweir else
746cdf0e10cSrcweir nTabEndRow = nDataStartRow; // single row will remain empty
747cdf0e10cSrcweir bSizesValid = sal_True;
748cdf0e10cSrcweir }
749cdf0e10cSrcweir }
750cdf0e10cSrcweir
GetPositionType(const ScAddress & rPos)751cdf0e10cSrcweir sal_Int32 ScDPOutput::GetPositionType(const ScAddress& rPos)
752cdf0e10cSrcweir {
753cdf0e10cSrcweir using namespace ::com::sun::star::sheet;
754cdf0e10cSrcweir
755cdf0e10cSrcweir SCCOL nCol = rPos.Col();
756cdf0e10cSrcweir SCROW nRow = rPos.Row();
757cdf0e10cSrcweir SCTAB nTab = rPos.Tab();
758cdf0e10cSrcweir if ( nTab != aStartPos.Tab() )
759cdf0e10cSrcweir return DataPilotTablePositionType::NOT_IN_TABLE;
760cdf0e10cSrcweir
761cdf0e10cSrcweir CalcSizes();
762cdf0e10cSrcweir
763cdf0e10cSrcweir // Make sure the cursor is within the table.
764cdf0e10cSrcweir if (nCol < nTabStartCol || nRow < nTabStartRow || nCol > nTabEndCol || nRow > nTabEndRow)
765cdf0e10cSrcweir return DataPilotTablePositionType::NOT_IN_TABLE;
766cdf0e10cSrcweir
767cdf0e10cSrcweir // test for result data area.
768cdf0e10cSrcweir if (nCol >= nDataStartCol && nCol <= nTabEndCol && nRow >= nDataStartRow && nRow <= nTabEndRow)
769cdf0e10cSrcweir return DataPilotTablePositionType::RESULT;
770cdf0e10cSrcweir
771cdf0e10cSrcweir bool bInColHeader = (nRow >= nTabStartRow && nRow < nDataStartRow);
772cdf0e10cSrcweir bool bInRowHeader = (nCol >= nTabStartCol && nCol < nDataStartCol);
773cdf0e10cSrcweir
774cdf0e10cSrcweir if (bInColHeader && bInRowHeader)
775cdf0e10cSrcweir // probably in that ugly little box at the upper-left corner of the table.
776cdf0e10cSrcweir return DataPilotTablePositionType::OTHER;
777cdf0e10cSrcweir
778cdf0e10cSrcweir if (bInColHeader)
779cdf0e10cSrcweir {
780cdf0e10cSrcweir if (nRow == nTabStartRow)
781cdf0e10cSrcweir // first row in the column header area is always used for column
782cdf0e10cSrcweir // field buttons.
783cdf0e10cSrcweir return DataPilotTablePositionType::OTHER;
784cdf0e10cSrcweir
785cdf0e10cSrcweir return DataPilotTablePositionType::COLUMN_HEADER;
786cdf0e10cSrcweir }
787cdf0e10cSrcweir
788cdf0e10cSrcweir if (bInRowHeader)
789cdf0e10cSrcweir return DataPilotTablePositionType::ROW_HEADER;
790cdf0e10cSrcweir
791cdf0e10cSrcweir return DataPilotTablePositionType::OTHER;
792cdf0e10cSrcweir }
793cdf0e10cSrcweir
Output()794cdf0e10cSrcweir void ScDPOutput::Output()
795cdf0e10cSrcweir {
796cdf0e10cSrcweir long nField;
797cdf0e10cSrcweir SCTAB nTab = aStartPos.Tab();
798cdf0e10cSrcweir const uno::Sequence<sheet::DataResult>* pRowAry = aData.getConstArray();
799cdf0e10cSrcweir
800cdf0e10cSrcweir // calculate output positions and sizes
801cdf0e10cSrcweir
802cdf0e10cSrcweir CalcSizes();
803cdf0e10cSrcweir if ( bSizeOverflow || bResultsError ) // does output area exceed sheet limits?
804cdf0e10cSrcweir return; // nothing
805cdf0e10cSrcweir
806cdf0e10cSrcweir // clear whole (new) output area
807cdf0e10cSrcweir //! when modifying table, clear old area
808cdf0e10cSrcweir //! include IDF_OBJECTS ???
809cdf0e10cSrcweir pDoc->DeleteAreaTab( aStartPos.Col(), aStartPos.Row(), nTabEndCol, nTabEndRow, nTab, IDF_ALL );
810cdf0e10cSrcweir
811cdf0e10cSrcweir if ( bDoFilter )
812cdf0e10cSrcweir lcl_DoFilterButton( pDoc, aStartPos.Col(), aStartPos.Row(), nTab );
813cdf0e10cSrcweir
814cdf0e10cSrcweir // output data results:
815cdf0e10cSrcweir
816cdf0e10cSrcweir for (long nRow=0; nRow<nRowCount; nRow++)
817cdf0e10cSrcweir {
818cdf0e10cSrcweir SCROW nRowPos = nDataStartRow + (SCROW)nRow; //! check for overflow
819cdf0e10cSrcweir const sheet::DataResult* pColAry = pRowAry[nRow].getConstArray();
820cdf0e10cSrcweir long nThisColCount = pRowAry[nRow].getLength();
821cdf0e10cSrcweir DBG_ASSERT( nThisColCount == nColCount, "count mismatch" ); //! ???
822cdf0e10cSrcweir for (long nCol=0; nCol<nThisColCount; nCol++)
823cdf0e10cSrcweir {
824cdf0e10cSrcweir SCCOL nColPos = nDataStartCol + (SCCOL)nCol; //! check for overflow
825cdf0e10cSrcweir DataCell( nColPos, nRowPos, nTab, pColAry[nCol] );
826cdf0e10cSrcweir }
827cdf0e10cSrcweir }
828cdf0e10cSrcweir // output page fields:
829cdf0e10cSrcweir
830cdf0e10cSrcweir for (nField=0; nField<nPageFieldCount; nField++)
831cdf0e10cSrcweir {
832cdf0e10cSrcweir SCCOL nHdrCol = aStartPos.Col();
833cdf0e10cSrcweir SCROW nHdrRow = aStartPos.Row() + nField + ( bDoFilter ? 1 : 0 );
834cdf0e10cSrcweir // draw without frame for consistency with filter button:
835cdf0e10cSrcweir FieldCell( nHdrCol, nHdrRow, nTab, pPageFields[nField].aCaption, false, false, pPageFields[nField].mbHasHiddenMember );
836cdf0e10cSrcweir SCCOL nFldCol = nHdrCol + 1;
837cdf0e10cSrcweir
838cdf0e10cSrcweir String aPageValue;
839cdf0e10cSrcweir if ( pPageFields[nField].aResult.getLength() == 1 )
840cdf0e10cSrcweir aPageValue = pPageFields[nField].aResult[0].Caption;
841cdf0e10cSrcweir else
842cdf0e10cSrcweir aPageValue = String( ScResId( SCSTR_ALL ) ); //! separate string?
843cdf0e10cSrcweir
844cdf0e10cSrcweir pDoc->SetString( nFldCol, nHdrRow, nTab, aPageValue );
845cdf0e10cSrcweir
846cdf0e10cSrcweir lcl_SetFrame( pDoc,nTab, nFldCol,nHdrRow, nFldCol,nHdrRow, 20 );
847cdf0e10cSrcweir pDoc->ApplyAttr( nFldCol, nHdrRow, nTab, ScMergeFlagAttr(SC_MF_AUTO) );
848cdf0e10cSrcweir //! which style?
849cdf0e10cSrcweir }
850cdf0e10cSrcweir
851cdf0e10cSrcweir // data description
852cdf0e10cSrcweir // (may get overwritten by first row field)
853cdf0e10cSrcweir
854cdf0e10cSrcweir String aDesc = aDataDescription;
855cdf0e10cSrcweir if ( !aDesc.Len() )
856cdf0e10cSrcweir {
857cdf0e10cSrcweir //! use default string ("result") ?
858cdf0e10cSrcweir }
859cdf0e10cSrcweir pDoc->SetString( nTabStartCol, nTabStartRow, nTab, aDesc );
860cdf0e10cSrcweir
861cdf0e10cSrcweir // set STR_PIVOT_STYLE_INNER for whole data area (subtotals are overwritten)
862cdf0e10cSrcweir
863cdf0e10cSrcweir if ( nDataStartRow > nTabStartRow )
864cdf0e10cSrcweir lcl_SetStyleById( pDoc, nTab, nTabStartCol, nTabStartRow, nTabEndCol, nDataStartRow-1,
865cdf0e10cSrcweir STR_PIVOT_STYLE_TOP );
866cdf0e10cSrcweir lcl_SetStyleById( pDoc, nTab, nDataStartCol, nDataStartRow, nTabEndCol, nTabEndRow,
867cdf0e10cSrcweir STR_PIVOT_STYLE_INNER );
868cdf0e10cSrcweir
869cdf0e10cSrcweir // output column headers:
870cdf0e10cSrcweir // Wang Xu Ming -- 2009-8-17
871cdf0e10cSrcweir // DataPilot Migration - Cache&&Performance
872cdf0e10cSrcweir OutputImpl outputimp( pDoc, nTab,
873cdf0e10cSrcweir nTabStartCol, nTabStartRow, nMemberStartCol, nMemberStartRow,
874cdf0e10cSrcweir nDataStartCol, nDataStartRow, nTabEndCol, nTabEndRow );
875cdf0e10cSrcweir // End Comments
876cdf0e10cSrcweir for (nField=0; nField<nColFieldCount; nField++)
877cdf0e10cSrcweir {
878cdf0e10cSrcweir SCCOL nHdrCol = nDataStartCol + (SCCOL)nField; //! check for overflow
879cdf0e10cSrcweir FieldCell( nHdrCol, nTabStartRow, nTab, pColFields[nField].aCaption, true, true, pColFields[nField].mbHasHiddenMember );
880cdf0e10cSrcweir
881cdf0e10cSrcweir SCROW nRowPos = nMemberStartRow + (SCROW)nField; //! check for overflow
882cdf0e10cSrcweir const uno::Sequence<sheet::MemberResult> rSequence = pColFields[nField].aResult;
883cdf0e10cSrcweir const sheet::MemberResult* pArray = rSequence.getConstArray();
884cdf0e10cSrcweir long nThisColCount = rSequence.getLength();
885cdf0e10cSrcweir DBG_ASSERT( nThisColCount == nColCount, "count mismatch" ); //! ???
886cdf0e10cSrcweir for (long nCol=0; nCol<nThisColCount; nCol++)
887cdf0e10cSrcweir {
888cdf0e10cSrcweir SCCOL nColPos = nDataStartCol + (SCCOL)nCol; //! check for overflow
889cdf0e10cSrcweir HeaderCell( nColPos, nRowPos, nTab, pArray[nCol], sal_True, nField );
890cdf0e10cSrcweir // Wang Xu Ming -- 2009-8-17
891cdf0e10cSrcweir // DataPilot Migration - Cache&&Performance
892cdf0e10cSrcweir if ( ( pArray[nCol].Flags & sheet::MemberResultFlags::HASMEMBER ) &&
893cdf0e10cSrcweir !( pArray[nCol].Flags & sheet::MemberResultFlags::SUBTOTAL ) )
894cdf0e10cSrcweir {
895cdf0e10cSrcweir long nEnd = nCol;
896cdf0e10cSrcweir while ( nEnd+1 < nThisColCount && ( pArray[nEnd+1].Flags & sheet::MemberResultFlags::CONTINUE ) )
897cdf0e10cSrcweir ++nEnd;
898cdf0e10cSrcweir SCCOL nEndColPos = nDataStartCol + (SCCOL)nEnd; //! check for overflow
899cdf0e10cSrcweir if ( nField+1 < nColFieldCount )
900cdf0e10cSrcweir {
901cdf0e10cSrcweir // lcl_SetFrame( pDoc,nTab, nColPos,nRowPos, nEndColPos,nRowPos, SC_DP_FRAME_INNER_BOLD );
902cdf0e10cSrcweir // lcl_SetFrame( pDoc,nTab, nColPos,nRowPos, nEndColPos,nTabEndRow, SC_DP_FRAME_INNER_BOLD );
903cdf0e10cSrcweir if ( nField == nColFieldCount - 2 )
904cdf0e10cSrcweir {
905cdf0e10cSrcweir outputimp.AddCol( nColPos );
906cdf0e10cSrcweir if ( nColPos + 1 == nEndColPos )
907cdf0e10cSrcweir outputimp.OutputBlockFrame( nColPos,nRowPos, nEndColPos,nRowPos+1, sal_True );
908cdf0e10cSrcweir }
909cdf0e10cSrcweir else
910cdf0e10cSrcweir outputimp.OutputBlockFrame( nColPos,nRowPos, nEndColPos,nRowPos );
911cdf0e10cSrcweir
912cdf0e10cSrcweir lcl_SetStyleById( pDoc, nTab, nColPos,nRowPos, nEndColPos,nDataStartRow-1, STR_PIVOT_STYLE_CATEGORY );
913cdf0e10cSrcweir }
914cdf0e10cSrcweir else
915cdf0e10cSrcweir lcl_SetStyleById( pDoc, nTab, nColPos,nRowPos, nColPos,nDataStartRow-1, STR_PIVOT_STYLE_CATEGORY );
916cdf0e10cSrcweir }
917cdf0e10cSrcweir else if ( pArray[nCol].Flags & sheet::MemberResultFlags::SUBTOTAL )
918cdf0e10cSrcweir outputimp.AddCol( nColPos );
919cdf0e10cSrcweir }
920cdf0e10cSrcweir if ( nField== 0 && nColFieldCount == 1 )
921cdf0e10cSrcweir outputimp.OutputBlockFrame( nDataStartCol,nTabStartRow, nTabEndCol,nRowPos-1 );
922cdf0e10cSrcweir // End Comments
923cdf0e10cSrcweir }
924cdf0e10cSrcweir
925cdf0e10cSrcweir // output row headers:
926cdf0e10cSrcweir std::vector<sal_Bool> vbSetBorder;
927cdf0e10cSrcweir vbSetBorder.resize( nTabEndRow - nDataStartRow + 1, sal_False );
928cdf0e10cSrcweir for (nField=0; nField<nRowFieldCount; nField++)
929cdf0e10cSrcweir {
930cdf0e10cSrcweir bool bDataLayout = mbHasDataLayout && (nField == nRowFieldCount-1);
931cdf0e10cSrcweir
932cdf0e10cSrcweir SCCOL nHdrCol = nTabStartCol + (SCCOL)nField; //! check for overflow
933cdf0e10cSrcweir SCROW nHdrRow = nDataStartRow - 1;
934cdf0e10cSrcweir FieldCell( nHdrCol, nHdrRow, nTab, pRowFields[nField].aCaption, true, !bDataLayout,
935cdf0e10cSrcweir pRowFields[nField].mbHasHiddenMember );
936cdf0e10cSrcweir
937cdf0e10cSrcweir SCCOL nColPos = nMemberStartCol + (SCCOL)nField; //! check for overflow
938cdf0e10cSrcweir const uno::Sequence<sheet::MemberResult> rSequence = pRowFields[nField].aResult;
939cdf0e10cSrcweir const sheet::MemberResult* pArray = rSequence.getConstArray();
940cdf0e10cSrcweir long nThisRowCount = rSequence.getLength();
941cdf0e10cSrcweir DBG_ASSERT( nThisRowCount == nRowCount, "count mismatch" ); //! ???
942cdf0e10cSrcweir for (long nRow=0; nRow<nThisRowCount; nRow++)
943cdf0e10cSrcweir {
944cdf0e10cSrcweir SCROW nRowPos = nDataStartRow + (SCROW)nRow; //! check for overflow
945cdf0e10cSrcweir HeaderCell( nColPos, nRowPos, nTab, pArray[nRow], sal_False, nField );
946cdf0e10cSrcweir if ( ( pArray[nRow].Flags & sheet::MemberResultFlags::HASMEMBER ) &&
947cdf0e10cSrcweir !( pArray[nRow].Flags & sheet::MemberResultFlags::SUBTOTAL ) )
948cdf0e10cSrcweir {
949cdf0e10cSrcweir if ( nField+1 < nRowFieldCount )
950cdf0e10cSrcweir {
951cdf0e10cSrcweir long nEnd = nRow;
952cdf0e10cSrcweir while ( nEnd+1 < nThisRowCount && ( pArray[nEnd+1].Flags & sheet::MemberResultFlags::CONTINUE ) )
953cdf0e10cSrcweir ++nEnd;
954cdf0e10cSrcweir SCROW nEndRowPos = nDataStartRow + (SCROW)nEnd; //! check for overflow
955cdf0e10cSrcweir // Wang Xu Ming -- 2009-8-17
956cdf0e10cSrcweir // DataPilot Migration - Cache&&Performance
957cdf0e10cSrcweir // lcl_SetFrame( pDoc,nTab, nColPos,nRowPos, nColPos,nEndRowPos, SC_DP_FRAME_INNER_BOLD );
958cdf0e10cSrcweir //lcl_SetFrame( pDoc,nTab, nColPos,nRowPos, nTabEndCol,nEndRowPos, SC_DP_FRAME_INNER_BOLD );
959cdf0e10cSrcweir outputimp.AddRow( nRowPos );
960cdf0e10cSrcweir if ( vbSetBorder[ nRow ] == sal_False )
961cdf0e10cSrcweir {
962cdf0e10cSrcweir outputimp.OutputBlockFrame( nColPos, nRowPos, nTabEndCol, nEndRowPos );
963cdf0e10cSrcweir vbSetBorder[ nRow ] = sal_True;
964cdf0e10cSrcweir }
965cdf0e10cSrcweir outputimp.OutputBlockFrame( nColPos, nRowPos, nColPos, nEndRowPos );
966cdf0e10cSrcweir
967cdf0e10cSrcweir if ( nField == nRowFieldCount - 2 )
968cdf0e10cSrcweir outputimp.OutputBlockFrame( nColPos+1, nRowPos, nColPos+1, nEndRowPos );
969cdf0e10cSrcweir // End Comments
970cdf0e10cSrcweir
971cdf0e10cSrcweir lcl_SetStyleById( pDoc, nTab, nColPos,nRowPos, nDataStartCol-1,nEndRowPos, STR_PIVOT_STYLE_CATEGORY );
972cdf0e10cSrcweir }
973cdf0e10cSrcweir else
974cdf0e10cSrcweir lcl_SetStyleById( pDoc, nTab, nColPos,nRowPos, nDataStartCol-1,nRowPos, STR_PIVOT_STYLE_CATEGORY );
975cdf0e10cSrcweir }
976cdf0e10cSrcweir // Wang Xu Ming -- 2009-8-17
977cdf0e10cSrcweir // DataPilot Migration - Cache&&Performance
978cdf0e10cSrcweir else if ( pArray[nRow].Flags & sheet::MemberResultFlags::SUBTOTAL )
979cdf0e10cSrcweir outputimp.AddRow( nRowPos );
980cdf0e10cSrcweir // End Comments
981cdf0e10cSrcweir }
982cdf0e10cSrcweir }
983cdf0e10cSrcweir
984cdf0e10cSrcweir // Wang Xu Ming -- 2009-8-17
985cdf0e10cSrcweir // DataPilot Migration - Cache&&Performance
986cdf0e10cSrcweir outputimp.OutputDataArea();
987cdf0e10cSrcweir // End Comments
988cdf0e10cSrcweir }
989cdf0e10cSrcweir
GetOutputRange(sal_Int32 nRegionType)990cdf0e10cSrcweir ScRange ScDPOutput::GetOutputRange( sal_Int32 nRegionType )
991cdf0e10cSrcweir {
992cdf0e10cSrcweir using namespace ::com::sun::star::sheet;
993cdf0e10cSrcweir
994cdf0e10cSrcweir CalcSizes();
995cdf0e10cSrcweir
996cdf0e10cSrcweir // fprintf(stdout, "ScDPOutput::GetOutputRange: aStartPos = (%ld, %d)\n", aStartPos.Row(), aStartPos.Col());fflush(stdout);
997cdf0e10cSrcweir // fprintf(stdout, "ScDPOutput::GetOutputRange: nTabStart (Row = %ld, Col = %ld)\n", nTabStartRow, nTabStartCol);fflush(stdout);
998cdf0e10cSrcweir // fprintf(stdout, "ScDPOutput::GetOutputRange: nMemberStart (Row = %ld, Col = %ld)\n", nMemberStartRow, nMemberStartCol);fflush(stdout);
999cdf0e10cSrcweir // fprintf(stdout, "ScDPOutput::GetOutputRange: nDataStart (Row = %ld, Col = %ld)\n", nDataStartRow, nDataStartCol);fflush(stdout);
1000cdf0e10cSrcweir // fprintf(stdout, "ScDPOutput::GetOutputRange: nTabEnd (Row = %ld, Col = %ld)\n", nTabEndRow, nTabStartCol);fflush(stdout);
1001cdf0e10cSrcweir
1002cdf0e10cSrcweir SCTAB nTab = aStartPos.Tab();
1003cdf0e10cSrcweir switch (nRegionType)
1004cdf0e10cSrcweir {
1005cdf0e10cSrcweir case DataPilotOutputRangeType::RESULT:
1006cdf0e10cSrcweir return ScRange(nDataStartCol, nDataStartRow, nTab, nTabEndCol, nTabEndRow, nTab);
1007cdf0e10cSrcweir case DataPilotOutputRangeType::TABLE:
1008cdf0e10cSrcweir return ScRange(aStartPos.Col(), nTabStartRow, nTab, nTabEndCol, nTabEndRow, nTab);
1009cdf0e10cSrcweir default:
1010cdf0e10cSrcweir DBG_ASSERT(nRegionType == DataPilotOutputRangeType::WHOLE, "ScDPOutput::GetOutputRange: unknown region type");
1011cdf0e10cSrcweir break;
1012cdf0e10cSrcweir }
1013cdf0e10cSrcweir return ScRange(aStartPos.Col(), aStartPos.Row(), nTab, nTabEndCol, nTabEndRow, nTab);
1014cdf0e10cSrcweir }
1015cdf0e10cSrcweir
HasError()1016cdf0e10cSrcweir sal_Bool ScDPOutput::HasError()
1017cdf0e10cSrcweir {
1018cdf0e10cSrcweir CalcSizes();
1019cdf0e10cSrcweir
1020cdf0e10cSrcweir return bSizeOverflow || bResultsError;
1021cdf0e10cSrcweir }
1022cdf0e10cSrcweir
GetHeaderRows()1023cdf0e10cSrcweir long ScDPOutput::GetHeaderRows()
1024cdf0e10cSrcweir {
1025cdf0e10cSrcweir return nPageFieldCount + ( bDoFilter ? 1 : 0 );
1026cdf0e10cSrcweir }
1027cdf0e10cSrcweir
GetMemberResultNames(ScStrCollection & rNames,long nDimension)1028cdf0e10cSrcweir void ScDPOutput::GetMemberResultNames( ScStrCollection& rNames, long nDimension )
1029cdf0e10cSrcweir {
1030cdf0e10cSrcweir // Return the list of all member names in a dimension's MemberResults.
1031cdf0e10cSrcweir // Only the dimension has to be compared because this is only used with table data,
1032cdf0e10cSrcweir // where each dimension occurs only once.
1033cdf0e10cSrcweir
1034cdf0e10cSrcweir uno::Sequence<sheet::MemberResult> aMemberResults;
1035cdf0e10cSrcweir bool bFound = false;
1036cdf0e10cSrcweir long nField;
1037cdf0e10cSrcweir
1038cdf0e10cSrcweir // look in column fields
1039cdf0e10cSrcweir
1040cdf0e10cSrcweir for (nField=0; nField<nColFieldCount && !bFound; nField++)
1041cdf0e10cSrcweir if ( pColFields[nField].nDim == nDimension )
1042cdf0e10cSrcweir {
1043cdf0e10cSrcweir aMemberResults = pColFields[nField].aResult;
1044cdf0e10cSrcweir bFound = true;
1045cdf0e10cSrcweir }
1046cdf0e10cSrcweir
1047cdf0e10cSrcweir // look in row fields
1048cdf0e10cSrcweir
1049cdf0e10cSrcweir for (nField=0; nField<nRowFieldCount && !bFound; nField++)
1050cdf0e10cSrcweir if ( pRowFields[nField].nDim == nDimension )
1051cdf0e10cSrcweir {
1052cdf0e10cSrcweir aMemberResults = pRowFields[nField].aResult;
1053cdf0e10cSrcweir bFound = true;
1054cdf0e10cSrcweir }
1055cdf0e10cSrcweir
1056cdf0e10cSrcweir // collect the member names
1057cdf0e10cSrcweir
1058cdf0e10cSrcweir if ( bFound )
1059cdf0e10cSrcweir {
1060cdf0e10cSrcweir const sheet::MemberResult* pArray = aMemberResults.getConstArray();
1061cdf0e10cSrcweir long nResultCount = aMemberResults.getLength();
1062cdf0e10cSrcweir
1063cdf0e10cSrcweir for (long nItem=0; nItem<nResultCount; nItem++)
1064cdf0e10cSrcweir {
1065cdf0e10cSrcweir if ( pArray[nItem].Flags & sheet::MemberResultFlags::HASMEMBER )
1066cdf0e10cSrcweir {
1067cdf0e10cSrcweir StrData* pNew = new StrData( pArray[nItem].Name );
1068cdf0e10cSrcweir if ( !rNames.Insert( pNew ) )
1069cdf0e10cSrcweir delete pNew;
1070cdf0e10cSrcweir }
1071cdf0e10cSrcweir }
1072cdf0e10cSrcweir }
1073cdf0e10cSrcweir }
1074cdf0e10cSrcweir
SetHeaderLayout(bool bUseGrid)1075cdf0e10cSrcweir void ScDPOutput::SetHeaderLayout(bool bUseGrid)
1076cdf0e10cSrcweir {
1077cdf0e10cSrcweir mbHeaderLayout = bUseGrid;
1078cdf0e10cSrcweir bSizesValid = false;
1079cdf0e10cSrcweir }
1080cdf0e10cSrcweir
GetHeaderLayout() const1081cdf0e10cSrcweir bool ScDPOutput::GetHeaderLayout() const
1082cdf0e10cSrcweir {
1083cdf0e10cSrcweir return mbHeaderLayout;
1084cdf0e10cSrcweir }
1085cdf0e10cSrcweir
lcl_GetTableVars(sal_Int32 & rGrandTotalCols,sal_Int32 & rGrandTotalRows,sal_Int32 & rDataLayoutIndex,std::vector<String> & rDataNames,std::vector<String> & rGivenNames,sheet::DataPilotFieldOrientation & rDataOrient,const uno::Reference<sheet::XDimensionsSupplier> & xSource)1086cdf0e10cSrcweir void lcl_GetTableVars( sal_Int32& rGrandTotalCols, sal_Int32& rGrandTotalRows, sal_Int32& rDataLayoutIndex,
1087cdf0e10cSrcweir std::vector<String>& rDataNames, std::vector<String>& rGivenNames,
1088cdf0e10cSrcweir sheet::DataPilotFieldOrientation& rDataOrient,
1089cdf0e10cSrcweir const uno::Reference<sheet::XDimensionsSupplier>& xSource )
1090cdf0e10cSrcweir {
1091cdf0e10cSrcweir rDataLayoutIndex = -1; // invalid
1092cdf0e10cSrcweir rGrandTotalCols = 0;
1093cdf0e10cSrcweir rGrandTotalRows = 0;
1094cdf0e10cSrcweir rDataOrient = sheet::DataPilotFieldOrientation_HIDDEN;
1095cdf0e10cSrcweir
1096cdf0e10cSrcweir uno::Reference<beans::XPropertySet> xSrcProp( xSource, uno::UNO_QUERY );
1097cdf0e10cSrcweir sal_Bool bColGrand = ScUnoHelpFunctions::GetBoolProperty( xSrcProp,
1098cdf0e10cSrcweir rtl::OUString::createFromAscii(DP_PROP_COLUMNGRAND) );
1099cdf0e10cSrcweir if ( bColGrand )
1100cdf0e10cSrcweir rGrandTotalCols = 1; // default if data layout not in columns
1101cdf0e10cSrcweir
1102cdf0e10cSrcweir sal_Bool bRowGrand = ScUnoHelpFunctions::GetBoolProperty( xSrcProp,
1103cdf0e10cSrcweir rtl::OUString::createFromAscii(DP_PROP_ROWGRAND) );
1104cdf0e10cSrcweir if ( bRowGrand )
1105cdf0e10cSrcweir rGrandTotalRows = 1; // default if data layout not in rows
1106cdf0e10cSrcweir
1107cdf0e10cSrcweir if ( xSource.is() )
1108cdf0e10cSrcweir {
1109cdf0e10cSrcweir // find index and orientation of "data layout" dimension, count data dimensions
1110cdf0e10cSrcweir
1111cdf0e10cSrcweir sal_Int32 nDataCount = 0;
1112cdf0e10cSrcweir
1113cdf0e10cSrcweir uno::Reference<container::XIndexAccess> xDims = new ScNameToIndexAccess( xSource->getDimensions() );
1114cdf0e10cSrcweir long nDimCount = xDims->getCount();
1115cdf0e10cSrcweir for (long nDim=0; nDim<nDimCount; nDim++)
1116cdf0e10cSrcweir {
1117cdf0e10cSrcweir uno::Reference<uno::XInterface> xDim =
1118cdf0e10cSrcweir ScUnoHelpFunctions::AnyToInterface( xDims->getByIndex(nDim) );
1119cdf0e10cSrcweir uno::Reference<beans::XPropertySet> xDimProp( xDim, uno::UNO_QUERY );
1120cdf0e10cSrcweir if ( xDimProp.is() )
1121cdf0e10cSrcweir {
1122cdf0e10cSrcweir sheet::DataPilotFieldOrientation eDimOrient =
1123cdf0e10cSrcweir (sheet::DataPilotFieldOrientation) ScUnoHelpFunctions::GetEnumProperty(
1124cdf0e10cSrcweir xDimProp, rtl::OUString::createFromAscii(DP_PROP_ORIENTATION),
1125cdf0e10cSrcweir sheet::DataPilotFieldOrientation_HIDDEN );
1126cdf0e10cSrcweir if ( ScUnoHelpFunctions::GetBoolProperty( xDimProp,
1127cdf0e10cSrcweir rtl::OUString::createFromAscii(DP_PROP_ISDATALAYOUT) ) )
1128cdf0e10cSrcweir {
1129cdf0e10cSrcweir rDataLayoutIndex = nDim;
1130cdf0e10cSrcweir rDataOrient = eDimOrient;
1131cdf0e10cSrcweir }
1132cdf0e10cSrcweir if ( eDimOrient == sheet::DataPilotFieldOrientation_DATA )
1133cdf0e10cSrcweir {
1134cdf0e10cSrcweir String aSourceName;
1135cdf0e10cSrcweir String aGivenName;
1136cdf0e10cSrcweir ScDPOutput::GetDataDimensionNames( aSourceName, aGivenName, xDim );
1137*3944543cSWang Lei try
1138*3944543cSWang Lei {
1139*3944543cSWang Lei uno::Any aValue = xDimProp->getPropertyValue( rtl::OUString::createFromAscii(SC_UNO_LAYOUTNAME) );
1140*3944543cSWang Lei
1141*3944543cSWang Lei if( aValue.hasValue() )
1142*3944543cSWang Lei {
1143*3944543cSWang Lei OUString strLayoutName;
1144*3944543cSWang Lei
1145*3944543cSWang Lei if( aValue >>= strLayoutName )
1146*3944543cSWang Lei if ( strLayoutName.getLength() > 0 )
1147*3944543cSWang Lei aGivenName = strLayoutName;
1148*3944543cSWang Lei }
1149*3944543cSWang Lei }
1150*3944543cSWang Lei catch(uno::Exception&)
1151*3944543cSWang Lei {
1152*3944543cSWang Lei }
1153cdf0e10cSrcweir rDataNames.push_back( aSourceName );
1154cdf0e10cSrcweir rGivenNames.push_back( aGivenName );
1155cdf0e10cSrcweir
1156cdf0e10cSrcweir ++nDataCount;
1157cdf0e10cSrcweir }
1158cdf0e10cSrcweir }
1159cdf0e10cSrcweir }
1160cdf0e10cSrcweir
1161cdf0e10cSrcweir if ( ( rDataOrient == sheet::DataPilotFieldOrientation_COLUMN ) && bColGrand )
1162cdf0e10cSrcweir rGrandTotalCols = nDataCount;
1163cdf0e10cSrcweir else if ( ( rDataOrient == sheet::DataPilotFieldOrientation_ROW ) && bRowGrand )
1164cdf0e10cSrcweir rGrandTotalRows = nDataCount;
1165cdf0e10cSrcweir }
1166cdf0e10cSrcweir }
1167cdf0e10cSrcweir
GetPositionData(const ScAddress & rPos,DataPilotTablePositionData & rPosData)1168cdf0e10cSrcweir void ScDPOutput::GetPositionData(const ScAddress& rPos, DataPilotTablePositionData& rPosData)
1169cdf0e10cSrcweir {
1170cdf0e10cSrcweir using namespace ::com::sun::star::sheet;
1171cdf0e10cSrcweir
1172cdf0e10cSrcweir SCCOL nCol = rPos.Col();
1173cdf0e10cSrcweir SCROW nRow = rPos.Row();
1174cdf0e10cSrcweir SCTAB nTab = rPos.Tab();
1175cdf0e10cSrcweir if ( nTab != aStartPos.Tab() )
1176cdf0e10cSrcweir return; // wrong sheet
1177cdf0e10cSrcweir
1178cdf0e10cSrcweir // calculate output positions and sizes
1179cdf0e10cSrcweir
1180cdf0e10cSrcweir CalcSizes();
1181cdf0e10cSrcweir
1182cdf0e10cSrcweir rPosData.PositionType = GetPositionType(rPos);
1183cdf0e10cSrcweir switch (rPosData.PositionType)
1184cdf0e10cSrcweir {
1185cdf0e10cSrcweir case DataPilotTablePositionType::RESULT:
1186cdf0e10cSrcweir {
1187cdf0e10cSrcweir vector<DataPilotFieldFilter> aFilters;
1188cdf0e10cSrcweir GetDataResultPositionData(aFilters, rPos);
1189cdf0e10cSrcweir sal_Int32 nSize = aFilters.size();
1190cdf0e10cSrcweir
1191cdf0e10cSrcweir DataPilotTableResultData aResData;
1192cdf0e10cSrcweir aResData.FieldFilters.realloc(nSize);
1193cdf0e10cSrcweir for (sal_Int32 i = 0; i < nSize; ++i)
1194cdf0e10cSrcweir aResData.FieldFilters[i] = aFilters[i];
1195cdf0e10cSrcweir
1196cdf0e10cSrcweir aResData.DataFieldIndex = 0;
1197cdf0e10cSrcweir Reference<beans::XPropertySet> xPropSet(xSource, UNO_QUERY);
1198cdf0e10cSrcweir if (xPropSet.is())
1199cdf0e10cSrcweir {
1200cdf0e10cSrcweir sal_Int32 nDataFieldCount = ScUnoHelpFunctions::GetLongProperty( xPropSet,
1201cdf0e10cSrcweir rtl::OUString::createFromAscii(SC_UNO_DATAFIELDCOUNT) );
1202cdf0e10cSrcweir if (nDataFieldCount > 0)
1203cdf0e10cSrcweir aResData.DataFieldIndex = (nRow - nDataStartRow) % nDataFieldCount;
1204cdf0e10cSrcweir }
1205cdf0e10cSrcweir
1206cdf0e10cSrcweir // Copy appropriate DataResult object from the cached sheet::DataResult table.
1207cdf0e10cSrcweir if (aData.getLength() > nRow - nDataStartRow &&
1208cdf0e10cSrcweir aData[nRow-nDataStartRow].getLength() > nCol-nDataStartCol)
1209cdf0e10cSrcweir aResData.Result = aData[nRow-nDataStartRow][nCol-nDataStartCol];
1210cdf0e10cSrcweir
1211cdf0e10cSrcweir rPosData.PositionData = makeAny(aResData);
1212cdf0e10cSrcweir return;
1213cdf0e10cSrcweir }
1214cdf0e10cSrcweir case DataPilotTablePositionType::COLUMN_HEADER:
1215cdf0e10cSrcweir {
1216cdf0e10cSrcweir long nField = nRow - nTabStartRow - 1; // 1st line is used for the buttons
1217cdf0e10cSrcweir if (nField < 0)
1218cdf0e10cSrcweir break;
1219cdf0e10cSrcweir
1220cdf0e10cSrcweir const uno::Sequence<sheet::MemberResult> rSequence = pColFields[nField].aResult;
1221cdf0e10cSrcweir if (rSequence.getLength() == 0)
1222cdf0e10cSrcweir break;
1223cdf0e10cSrcweir const sheet::MemberResult* pArray = rSequence.getConstArray();
1224cdf0e10cSrcweir
1225cdf0e10cSrcweir long nItem = nCol - nDataStartCol;
1226cdf0e10cSrcweir // get origin of "continue" fields
1227cdf0e10cSrcweir while (nItem > 0 && ( pArray[nItem].Flags & sheet::MemberResultFlags::CONTINUE) )
1228cdf0e10cSrcweir --nItem;
1229cdf0e10cSrcweir
1230cdf0e10cSrcweir if (nItem < 0)
1231cdf0e10cSrcweir break;
1232cdf0e10cSrcweir
1233cdf0e10cSrcweir DataPilotTableHeaderData aHeaderData;
1234cdf0e10cSrcweir aHeaderData.MemberName = OUString(pArray[nItem].Name);
1235cdf0e10cSrcweir aHeaderData.Flags = pArray[nItem].Flags;
1236cdf0e10cSrcweir aHeaderData.Dimension = static_cast<sal_Int32>(pColFields[nField].nDim);
1237cdf0e10cSrcweir aHeaderData.Hierarchy = static_cast<sal_Int32>(pColFields[nField].nHier);
1238cdf0e10cSrcweir aHeaderData.Level = static_cast<sal_Int32>(pColFields[nField].nLevel);
1239cdf0e10cSrcweir
1240cdf0e10cSrcweir rPosData.PositionData = makeAny(aHeaderData);
1241cdf0e10cSrcweir return;
1242cdf0e10cSrcweir }
1243cdf0e10cSrcweir case DataPilotTablePositionType::ROW_HEADER:
1244cdf0e10cSrcweir {
1245cdf0e10cSrcweir long nField = nCol - nTabStartCol;
1246cdf0e10cSrcweir if (nField < 0)
1247cdf0e10cSrcweir break;
1248cdf0e10cSrcweir
1249cdf0e10cSrcweir const uno::Sequence<sheet::MemberResult> rSequence = pRowFields[nField].aResult;
1250cdf0e10cSrcweir if (rSequence.getLength() == 0)
1251cdf0e10cSrcweir break;
1252cdf0e10cSrcweir const sheet::MemberResult* pArray = rSequence.getConstArray();
1253cdf0e10cSrcweir
1254cdf0e10cSrcweir long nItem = nRow - nDataStartRow;
1255cdf0e10cSrcweir // get origin of "continue" fields
1256cdf0e10cSrcweir while ( nItem > 0 && (pArray[nItem].Flags & sheet::MemberResultFlags::CONTINUE) )
1257cdf0e10cSrcweir --nItem;
1258cdf0e10cSrcweir
1259cdf0e10cSrcweir if (nItem < 0)
1260cdf0e10cSrcweir break;
1261cdf0e10cSrcweir
1262cdf0e10cSrcweir DataPilotTableHeaderData aHeaderData;
1263cdf0e10cSrcweir aHeaderData.MemberName = OUString(pArray[nItem].Name);
1264cdf0e10cSrcweir aHeaderData.Flags = pArray[nItem].Flags;
1265cdf0e10cSrcweir aHeaderData.Dimension = static_cast<sal_Int32>(pRowFields[nField].nDim);
1266cdf0e10cSrcweir aHeaderData.Hierarchy = static_cast<sal_Int32>(pRowFields[nField].nHier);
1267cdf0e10cSrcweir aHeaderData.Level = static_cast<sal_Int32>(pRowFields[nField].nLevel);
1268cdf0e10cSrcweir
1269cdf0e10cSrcweir rPosData.PositionData = makeAny(aHeaderData);
1270cdf0e10cSrcweir return;
1271cdf0e10cSrcweir }
1272cdf0e10cSrcweir }
1273cdf0e10cSrcweir }
1274cdf0e10cSrcweir
GetDataResultPositionData(vector<sheet::DataPilotFieldFilter> & rFilters,const ScAddress & rPos)1275cdf0e10cSrcweir bool ScDPOutput::GetDataResultPositionData(vector<sheet::DataPilotFieldFilter>& rFilters, const ScAddress& rPos)
1276cdf0e10cSrcweir {
1277cdf0e10cSrcweir // Check to make sure there is at least one data field.
1278cdf0e10cSrcweir Reference<beans::XPropertySet> xPropSet(xSource, UNO_QUERY);
1279cdf0e10cSrcweir if (!xPropSet.is())
1280cdf0e10cSrcweir return false;
1281cdf0e10cSrcweir
1282cdf0e10cSrcweir sal_Int32 nDataFieldCount = ScUnoHelpFunctions::GetLongProperty( xPropSet,
1283cdf0e10cSrcweir rtl::OUString::createFromAscii(SC_UNO_DATAFIELDCOUNT) );
1284cdf0e10cSrcweir if (nDataFieldCount == 0)
1285cdf0e10cSrcweir // No data field is present in this datapilot table.
1286cdf0e10cSrcweir return false;
1287cdf0e10cSrcweir
1288cdf0e10cSrcweir // #i111421# use lcl_GetTableVars for correct size of totals and data layout position
1289cdf0e10cSrcweir sal_Int32 nGrandTotalCols;
1290cdf0e10cSrcweir sal_Int32 nGrandTotalRows;
1291cdf0e10cSrcweir sal_Int32 nDataLayoutIndex;
1292cdf0e10cSrcweir std::vector<String> aDataNames;
1293cdf0e10cSrcweir std::vector<String> aGivenNames;
1294cdf0e10cSrcweir sheet::DataPilotFieldOrientation eDataOrient;
1295cdf0e10cSrcweir lcl_GetTableVars( nGrandTotalCols, nGrandTotalRows, nDataLayoutIndex, aDataNames, aGivenNames, eDataOrient, xSource );
1296cdf0e10cSrcweir
1297cdf0e10cSrcweir SCCOL nCol = rPos.Col();
1298cdf0e10cSrcweir SCROW nRow = rPos.Row();
1299cdf0e10cSrcweir SCTAB nTab = rPos.Tab();
1300cdf0e10cSrcweir if ( nTab != aStartPos.Tab() )
1301cdf0e10cSrcweir return false; // wrong sheet
1302cdf0e10cSrcweir
1303cdf0e10cSrcweir CalcSizes();
1304cdf0e10cSrcweir
1305cdf0e10cSrcweir // test for data area.
1306cdf0e10cSrcweir if (nCol < nDataStartCol || nCol > nTabEndCol || nRow < nDataStartRow || nRow > nTabEndRow)
1307cdf0e10cSrcweir {
1308cdf0e10cSrcweir // Cell is outside the data field area.
1309cdf0e10cSrcweir return false;
1310cdf0e10cSrcweir }
1311cdf0e10cSrcweir
1312cdf0e10cSrcweir bool bFilterByCol = (nCol <= static_cast<SCCOL>(nTabEndCol - nGrandTotalCols));
1313cdf0e10cSrcweir bool bFilterByRow = (nRow <= static_cast<SCROW>(nTabEndRow - nGrandTotalRows));
1314cdf0e10cSrcweir
1315cdf0e10cSrcweir // column fields
1316cdf0e10cSrcweir for (SCCOL nColField = 0; nColField < nColFieldCount && bFilterByCol; ++nColField)
1317cdf0e10cSrcweir {
1318cdf0e10cSrcweir if (pColFields[nColField].nDim == nDataLayoutIndex)
1319cdf0e10cSrcweir // There is no sense including the data layout field for filtering.
1320cdf0e10cSrcweir continue;
1321cdf0e10cSrcweir
1322cdf0e10cSrcweir sheet::DataPilotFieldFilter filter;
1323cdf0e10cSrcweir filter.FieldName = pColFields[nColField].maName;
1324cdf0e10cSrcweir
1325cdf0e10cSrcweir const uno::Sequence<sheet::MemberResult> rSequence = pColFields[nColField].aResult;
1326cdf0e10cSrcweir const sheet::MemberResult* pArray = rSequence.getConstArray();
1327cdf0e10cSrcweir
1328cdf0e10cSrcweir DBG_ASSERT(nDataStartCol + rSequence.getLength() - 1 == nTabEndCol, "ScDPOutput::GetDataFieldCellData: error in geometric assumption");
1329cdf0e10cSrcweir
1330cdf0e10cSrcweir long nItem = nCol - nDataStartCol;
1331cdf0e10cSrcweir // get origin of "continue" fields
1332cdf0e10cSrcweir while ( nItem > 0 && (pArray[nItem].Flags & sheet::MemberResultFlags::CONTINUE) )
1333cdf0e10cSrcweir --nItem;
1334cdf0e10cSrcweir
1335cdf0e10cSrcweir filter.MatchValue = pArray[nItem].Name;
1336cdf0e10cSrcweir rFilters.push_back(filter);
1337cdf0e10cSrcweir }
1338cdf0e10cSrcweir
1339cdf0e10cSrcweir // row fields
1340cdf0e10cSrcweir for (SCROW nRowField = 0; nRowField < nRowFieldCount && bFilterByRow; ++nRowField)
1341cdf0e10cSrcweir {
1342cdf0e10cSrcweir if (pRowFields[nRowField].nDim == nDataLayoutIndex)
1343cdf0e10cSrcweir // There is no sense including the data layout field for filtering.
1344cdf0e10cSrcweir continue;
1345cdf0e10cSrcweir
1346cdf0e10cSrcweir sheet::DataPilotFieldFilter filter;
1347cdf0e10cSrcweir filter.FieldName = pRowFields[nRowField].maName;
1348cdf0e10cSrcweir
1349cdf0e10cSrcweir const uno::Sequence<sheet::MemberResult> rSequence = pRowFields[nRowField].aResult;
1350cdf0e10cSrcweir const sheet::MemberResult* pArray = rSequence.getConstArray();
1351cdf0e10cSrcweir
1352cdf0e10cSrcweir DBG_ASSERT(nDataStartRow + rSequence.getLength() - 1 == nTabEndRow, "ScDPOutput::GetDataFieldCellData: error in geometric assumption");
1353cdf0e10cSrcweir
1354cdf0e10cSrcweir long nItem = nRow - nDataStartRow;
1355cdf0e10cSrcweir // get origin of "continue" fields
1356cdf0e10cSrcweir while ( nItem > 0 && (pArray[nItem].Flags & sheet::MemberResultFlags::CONTINUE) )
1357cdf0e10cSrcweir --nItem;
1358cdf0e10cSrcweir
1359cdf0e10cSrcweir filter.MatchValue = pArray[nItem].Name;
1360cdf0e10cSrcweir rFilters.push_back(filter);
1361cdf0e10cSrcweir }
1362cdf0e10cSrcweir
1363cdf0e10cSrcweir return true;
1364cdf0e10cSrcweir }
1365cdf0e10cSrcweir
1366cdf0e10cSrcweir //
1367cdf0e10cSrcweir // helper functions for ScDPOutput::GetPivotData
1368cdf0e10cSrcweir //
1369cdf0e10cSrcweir
lcl_IsNamedDataField(const ScDPGetPivotDataField & rTarget,const String & rSourceName,const String & rGivenName)1370cdf0e10cSrcweir bool lcl_IsNamedDataField( const ScDPGetPivotDataField& rTarget, const String& rSourceName, const String& rGivenName )
1371cdf0e10cSrcweir {
1372cdf0e10cSrcweir // match one of the names, ignoring case
1373cdf0e10cSrcweir return ScGlobal::GetpTransliteration()->isEqual( rTarget.maFieldName, rSourceName ) ||
1374cdf0e10cSrcweir ScGlobal::GetpTransliteration()->isEqual( rTarget.maFieldName, rGivenName );
1375cdf0e10cSrcweir }
1376cdf0e10cSrcweir
lcl_IsNamedCategoryField(const ScDPGetPivotDataField & rFilter,const ScDPOutLevelData & rField)1377cdf0e10cSrcweir bool lcl_IsNamedCategoryField( const ScDPGetPivotDataField& rFilter, const ScDPOutLevelData& rField )
1378cdf0e10cSrcweir {
1379cdf0e10cSrcweir return ScGlobal::GetpTransliteration()->isEqual( rFilter.maFieldName, rField.maName );
1380cdf0e10cSrcweir }
1381cdf0e10cSrcweir
lcl_IsCondition(const sheet::MemberResult & rResultEntry,const ScDPGetPivotDataField & rFilter)1382cdf0e10cSrcweir bool lcl_IsCondition( const sheet::MemberResult& rResultEntry, const ScDPGetPivotDataField& rFilter )
1383cdf0e10cSrcweir {
1384cdf0e10cSrcweir //! handle numeric conditions?
1385cdf0e10cSrcweir return ScGlobal::GetpTransliteration()->isEqual( rResultEntry.Name, rFilter.maValStr );
1386cdf0e10cSrcweir }
1387cdf0e10cSrcweir
lcl_CheckPageField(const ScDPOutLevelData & rField,const std::vector<ScDPGetPivotDataField> & rFilters,std::vector<sal_Bool> & rFilterUsed)1388cdf0e10cSrcweir bool lcl_CheckPageField( const ScDPOutLevelData& rField,
1389cdf0e10cSrcweir const std::vector< ScDPGetPivotDataField >& rFilters,
1390cdf0e10cSrcweir std::vector< sal_Bool >& rFilterUsed )
1391cdf0e10cSrcweir {
1392cdf0e10cSrcweir for (SCSIZE nFilterPos = 0; nFilterPos < rFilters.size(); ++nFilterPos)
1393cdf0e10cSrcweir {
1394cdf0e10cSrcweir if ( lcl_IsNamedCategoryField( rFilters[nFilterPos], rField ) )
1395cdf0e10cSrcweir {
1396cdf0e10cSrcweir rFilterUsed[nFilterPos] = sal_True;
1397cdf0e10cSrcweir
1398cdf0e10cSrcweir // page field result is empty or the selection as single entry (see lcl_GetSelectedPageAsResult)
1399cdf0e10cSrcweir if ( rField.aResult.getLength() == 1 &&
1400cdf0e10cSrcweir lcl_IsCondition( rField.aResult[0], rFilters[nFilterPos] ) )
1401cdf0e10cSrcweir {
1402cdf0e10cSrcweir return true; // condition matches page selection
1403cdf0e10cSrcweir }
1404cdf0e10cSrcweir else
1405cdf0e10cSrcweir {
1406cdf0e10cSrcweir return false; // no page selection or different entry
1407cdf0e10cSrcweir }
1408cdf0e10cSrcweir }
1409cdf0e10cSrcweir }
1410cdf0e10cSrcweir
1411cdf0e10cSrcweir return true; // valid if the page field doesn't have a filter
1412cdf0e10cSrcweir }
1413cdf0e10cSrcweir
lcl_GetSubTotals(const uno::Reference<sheet::XDimensionsSupplier> & xSource,const ScDPOutLevelData & rField)1414cdf0e10cSrcweir uno::Sequence<sheet::GeneralFunction> lcl_GetSubTotals(
1415cdf0e10cSrcweir const uno::Reference<sheet::XDimensionsSupplier>& xSource, const ScDPOutLevelData& rField )
1416cdf0e10cSrcweir {
1417cdf0e10cSrcweir uno::Sequence<sheet::GeneralFunction> aSubTotals;
1418cdf0e10cSrcweir
1419cdf0e10cSrcweir uno::Reference<sheet::XHierarchiesSupplier> xHierSupp;
1420cdf0e10cSrcweir uno::Reference<container::XNameAccess> xDimsName = xSource->getDimensions();
1421cdf0e10cSrcweir uno::Reference<container::XIndexAccess> xIntDims = new ScNameToIndexAccess( xDimsName );
1422cdf0e10cSrcweir sal_Int32 nIntCount = xIntDims->getCount();
1423cdf0e10cSrcweir if ( rField.nDim < nIntCount )
1424cdf0e10cSrcweir {
1425cdf0e10cSrcweir uno::Reference<uno::XInterface> xIntDim = ScUnoHelpFunctions::AnyToInterface(
1426cdf0e10cSrcweir xIntDims->getByIndex( rField.nDim ) );
1427cdf0e10cSrcweir xHierSupp = uno::Reference<sheet::XHierarchiesSupplier>( xIntDim, uno::UNO_QUERY );
1428cdf0e10cSrcweir }
1429cdf0e10cSrcweir DBG_ASSERT( xHierSupp.is(), "dimension not found" );
1430cdf0e10cSrcweir
1431cdf0e10cSrcweir sal_Int32 nHierCount = 0;
1432cdf0e10cSrcweir uno::Reference<container::XIndexAccess> xHiers;
1433cdf0e10cSrcweir if ( xHierSupp.is() )
1434cdf0e10cSrcweir {
1435cdf0e10cSrcweir uno::Reference<container::XNameAccess> xHiersName = xHierSupp->getHierarchies();
1436cdf0e10cSrcweir xHiers = new ScNameToIndexAccess( xHiersName );
1437cdf0e10cSrcweir nHierCount = xHiers->getCount();
1438cdf0e10cSrcweir }
1439cdf0e10cSrcweir uno::Reference<uno::XInterface> xHier;
1440cdf0e10cSrcweir if ( rField.nHier < nHierCount )
1441cdf0e10cSrcweir xHier = ScUnoHelpFunctions::AnyToInterface( xHiers->getByIndex( rField.nHier ) );
1442cdf0e10cSrcweir DBG_ASSERT( xHier.is(), "hierarchy not found" );
1443cdf0e10cSrcweir
1444cdf0e10cSrcweir sal_Int32 nLevCount = 0;
1445cdf0e10cSrcweir uno::Reference<container::XIndexAccess> xLevels;
1446cdf0e10cSrcweir uno::Reference<sheet::XLevelsSupplier> xLevSupp( xHier, uno::UNO_QUERY );
1447cdf0e10cSrcweir if ( xLevSupp.is() )
1448cdf0e10cSrcweir {
1449cdf0e10cSrcweir uno::Reference<container::XNameAccess> xLevsName = xLevSupp->getLevels();
1450cdf0e10cSrcweir xLevels = new ScNameToIndexAccess( xLevsName );
1451cdf0e10cSrcweir nLevCount = xLevels->getCount();
1452cdf0e10cSrcweir }
1453cdf0e10cSrcweir uno::Reference<uno::XInterface> xLevel;
1454cdf0e10cSrcweir if ( rField.nLevel < nLevCount )
1455cdf0e10cSrcweir xLevel = ScUnoHelpFunctions::AnyToInterface( xLevels->getByIndex( rField.nLevel ) );
1456cdf0e10cSrcweir DBG_ASSERT( xLevel.is(), "level not found" );
1457cdf0e10cSrcweir
1458cdf0e10cSrcweir uno::Reference<beans::XPropertySet> xLevelProp( xLevel, uno::UNO_QUERY );
1459cdf0e10cSrcweir if ( xLevelProp.is() )
1460cdf0e10cSrcweir {
1461cdf0e10cSrcweir try
1462cdf0e10cSrcweir {
1463cdf0e10cSrcweir uno::Any aValue = xLevelProp->getPropertyValue( rtl::OUString::createFromAscii(DP_PROP_SUBTOTALS) );
1464cdf0e10cSrcweir aValue >>= aSubTotals;
1465cdf0e10cSrcweir }
1466cdf0e10cSrcweir catch(uno::Exception&)
1467cdf0e10cSrcweir {
1468cdf0e10cSrcweir }
1469cdf0e10cSrcweir }
1470cdf0e10cSrcweir
1471cdf0e10cSrcweir return aSubTotals;
1472cdf0e10cSrcweir }
1473cdf0e10cSrcweir
lcl_FilterInclude(std::vector<sal_Bool> & rResult,std::vector<sal_Int32> & rSubtotal,const ScDPOutLevelData & rField,const std::vector<ScDPGetPivotDataField> & rFilters,std::vector<sal_Bool> & rFilterUsed,bool & rBeforeDataLayout,sal_Int32 nGrandTotals,sal_Int32 nDataLayoutIndex,const std::vector<String> & rDataNames,const std::vector<String> & rGivenNames,const ScDPGetPivotDataField & rTarget,const uno::Reference<sheet::XDimensionsSupplier> & xSource)1474cdf0e10cSrcweir void lcl_FilterInclude( std::vector< sal_Bool >& rResult, std::vector< sal_Int32 >& rSubtotal,
1475cdf0e10cSrcweir const ScDPOutLevelData& rField,
1476cdf0e10cSrcweir const std::vector< ScDPGetPivotDataField >& rFilters,
1477cdf0e10cSrcweir std::vector< sal_Bool >& rFilterUsed,
1478cdf0e10cSrcweir bool& rBeforeDataLayout,
1479cdf0e10cSrcweir sal_Int32 nGrandTotals, sal_Int32 nDataLayoutIndex,
1480cdf0e10cSrcweir const std::vector<String>& rDataNames, const std::vector<String>& rGivenNames,
1481cdf0e10cSrcweir const ScDPGetPivotDataField& rTarget, const uno::Reference<sheet::XDimensionsSupplier>& xSource )
1482cdf0e10cSrcweir {
1483cdf0e10cSrcweir // returns true if a filter was given for the field
1484cdf0e10cSrcweir
1485cdf0e10cSrcweir DBG_ASSERT( rFilters.size() == rFilterUsed.size(), "wrong size" );
1486cdf0e10cSrcweir
1487cdf0e10cSrcweir const bool bIsDataLayout = ( rField.nDim == nDataLayoutIndex );
1488cdf0e10cSrcweir if (bIsDataLayout)
1489cdf0e10cSrcweir rBeforeDataLayout = false;
1490cdf0e10cSrcweir
1491cdf0e10cSrcweir bool bHasFilter = false;
1492cdf0e10cSrcweir ScDPGetPivotDataField aFilter;
1493cdf0e10cSrcweir if ( !bIsDataLayout ) // selection of data field is handled separately
1494cdf0e10cSrcweir {
1495cdf0e10cSrcweir for (SCSIZE nFilterPos = 0; nFilterPos < rFilters.size() && !bHasFilter; ++nFilterPos)
1496cdf0e10cSrcweir {
1497cdf0e10cSrcweir if ( lcl_IsNamedCategoryField( rFilters[nFilterPos], rField ) )
1498cdf0e10cSrcweir {
1499cdf0e10cSrcweir aFilter = rFilters[nFilterPos];
1500cdf0e10cSrcweir rFilterUsed[nFilterPos] = sal_True;
1501cdf0e10cSrcweir bHasFilter = true;
1502cdf0e10cSrcweir }
1503cdf0e10cSrcweir }
1504cdf0e10cSrcweir }
1505cdf0e10cSrcweir
1506cdf0e10cSrcweir bool bHasFunc = bHasFilter && aFilter.meFunction != sheet::GeneralFunction_NONE;
1507cdf0e10cSrcweir
1508cdf0e10cSrcweir uno::Sequence<sheet::GeneralFunction> aSubTotals;
1509cdf0e10cSrcweir if ( !bIsDataLayout )
1510cdf0e10cSrcweir aSubTotals = lcl_GetSubTotals( xSource, rField );
1511cdf0e10cSrcweir bool bManualSub = ( aSubTotals.getLength() > 0 && aSubTotals[0] != sheet::GeneralFunction_AUTO );
1512cdf0e10cSrcweir
1513cdf0e10cSrcweir const uno::Sequence<sheet::MemberResult>& rSequence = rField.aResult;
1514cdf0e10cSrcweir const sheet::MemberResult* pArray = rSequence.getConstArray();
1515cdf0e10cSrcweir sal_Int32 nSize = rSequence.getLength();
1516cdf0e10cSrcweir
1517cdf0e10cSrcweir DBG_ASSERT( (sal_Int32)rResult.size() == nSize, "Number of fields do not match result count" );
1518cdf0e10cSrcweir
1519cdf0e10cSrcweir sal_Int32 nContCount = 0;
1520cdf0e10cSrcweir sal_Int32 nSubTotalCount = 0;
1521cdf0e10cSrcweir sheet::MemberResult aPrevious;
1522cdf0e10cSrcweir for( sal_Int32 j=0; j < nSize; j++ )
1523cdf0e10cSrcweir {
1524cdf0e10cSrcweir sheet::MemberResult aResultEntry = pArray[j];
1525cdf0e10cSrcweir if ( aResultEntry.Flags & sheet::MemberResultFlags::CONTINUE )
1526cdf0e10cSrcweir {
1527cdf0e10cSrcweir aResultEntry = aPrevious;
1528cdf0e10cSrcweir ++nContCount;
1529cdf0e10cSrcweir }
1530cdf0e10cSrcweir else if ( ( aResultEntry.Flags & sheet::MemberResultFlags::SUBTOTAL ) == 0 )
1531cdf0e10cSrcweir {
1532cdf0e10cSrcweir // count the CONTINUE entries before a SUBTOTAL
1533cdf0e10cSrcweir nContCount = 0;
1534cdf0e10cSrcweir }
1535cdf0e10cSrcweir
1536cdf0e10cSrcweir if ( j >= nSize - nGrandTotals )
1537cdf0e10cSrcweir {
1538cdf0e10cSrcweir // mark as subtotal for the preceding data
1539cdf0e10cSrcweir if ( ( aResultEntry.Flags & sheet::MemberResultFlags::SUBTOTAL ) != 0 )
1540cdf0e10cSrcweir {
1541cdf0e10cSrcweir rSubtotal[j] = nSize - nGrandTotals;
1542cdf0e10cSrcweir
1543cdf0e10cSrcweir if ( rResult[j] && nGrandTotals > 1 )
1544cdf0e10cSrcweir {
1545cdf0e10cSrcweir // grand total is always automatic
1546cdf0e10cSrcweir sal_Int32 nDataPos = j - ( nSize - nGrandTotals );
1547cdf0e10cSrcweir DBG_ASSERT( nDataPos < (sal_Int32)rDataNames.size(), "wrong data count" );
1548cdf0e10cSrcweir String aSourceName( rDataNames[nDataPos] ); // vector contains source names
1549cdf0e10cSrcweir String aGivenName( rGivenNames[nDataPos] );
1550cdf0e10cSrcweir
1551cdf0e10cSrcweir rResult[j] = lcl_IsNamedDataField( rTarget, aSourceName, aGivenName );
1552cdf0e10cSrcweir }
1553cdf0e10cSrcweir }
1554cdf0e10cSrcweir
1555cdf0e10cSrcweir // treat "grand total" columns/rows as empty description, as if they were marked
1556cdf0e10cSrcweir // in a previous field
1557cdf0e10cSrcweir
1558cdf0e10cSrcweir DBG_ASSERT( ( aResultEntry.Flags &
1559cdf0e10cSrcweir ( sheet::MemberResultFlags::HASMEMBER | sheet::MemberResultFlags::SUBTOTAL ) ) == 0 ||
1560cdf0e10cSrcweir ( aResultEntry.Flags &
1561cdf0e10cSrcweir ( sheet::MemberResultFlags::HASMEMBER | sheet::MemberResultFlags::SUBTOTAL ) ) ==
1562cdf0e10cSrcweir ( sheet::MemberResultFlags::HASMEMBER | sheet::MemberResultFlags::SUBTOTAL ),
1563cdf0e10cSrcweir "non-subtotal member found in grand total result" );
1564cdf0e10cSrcweir aResultEntry.Flags = 0;
1565cdf0e10cSrcweir }
1566cdf0e10cSrcweir
1567cdf0e10cSrcweir // mark subtotals (not grand total) for preceding data (assume CONTINUE is set)
1568cdf0e10cSrcweir if ( ( aResultEntry.Flags & sheet::MemberResultFlags::SUBTOTAL ) != 0 )
1569cdf0e10cSrcweir {
1570cdf0e10cSrcweir rSubtotal[j] = nContCount + 1 + nSubTotalCount;
1571cdf0e10cSrcweir
1572cdf0e10cSrcweir if ( rResult[j] )
1573cdf0e10cSrcweir {
1574cdf0e10cSrcweir if ( bManualSub )
1575cdf0e10cSrcweir {
1576cdf0e10cSrcweir if ( rBeforeDataLayout )
1577cdf0e10cSrcweir {
1578cdf0e10cSrcweir // manual subtotals and several data fields
1579cdf0e10cSrcweir
1580cdf0e10cSrcweir sal_Int32 nDataCount = rDataNames.size();
1581cdf0e10cSrcweir sal_Int32 nFuncPos = nSubTotalCount / nDataCount; // outer order: subtotal functions
1582cdf0e10cSrcweir sal_Int32 nDataPos = nSubTotalCount % nDataCount; // inner order: data fields
1583cdf0e10cSrcweir
1584cdf0e10cSrcweir String aSourceName( rDataNames[nDataPos] ); // vector contains source names
1585cdf0e10cSrcweir String aGivenName( rGivenNames[nDataPos] );
1586cdf0e10cSrcweir
1587cdf0e10cSrcweir DBG_ASSERT( nFuncPos < aSubTotals.getLength(), "wrong subtotal count" );
1588cdf0e10cSrcweir rResult[j] = lcl_IsNamedDataField( rTarget, aSourceName, aGivenName ) &&
1589cdf0e10cSrcweir aSubTotals[nFuncPos] == aFilter.meFunction;
1590cdf0e10cSrcweir }
1591cdf0e10cSrcweir else
1592cdf0e10cSrcweir {
1593cdf0e10cSrcweir // manual subtotals for a single data field
1594cdf0e10cSrcweir
1595cdf0e10cSrcweir DBG_ASSERT( nSubTotalCount < aSubTotals.getLength(), "wrong subtotal count" );
1596cdf0e10cSrcweir rResult[j] = ( aSubTotals[nSubTotalCount] == aFilter.meFunction );
1597cdf0e10cSrcweir }
1598cdf0e10cSrcweir }
1599cdf0e10cSrcweir else // automatic subtotals
1600cdf0e10cSrcweir {
1601cdf0e10cSrcweir if ( rBeforeDataLayout )
1602cdf0e10cSrcweir {
1603cdf0e10cSrcweir DBG_ASSERT( nSubTotalCount < (sal_Int32)rDataNames.size(), "wrong data count" );
1604cdf0e10cSrcweir String aSourceName( rDataNames[nSubTotalCount] ); // vector contains source names
1605cdf0e10cSrcweir String aGivenName( rGivenNames[nSubTotalCount] );
1606cdf0e10cSrcweir
1607cdf0e10cSrcweir rResult[j] = lcl_IsNamedDataField( rTarget, aSourceName, aGivenName );
1608cdf0e10cSrcweir }
1609cdf0e10cSrcweir
1610cdf0e10cSrcweir // if a function was specified, automatic subtotals never match
1611cdf0e10cSrcweir if ( bHasFunc )
1612cdf0e10cSrcweir rResult[j] = sal_False;
1613cdf0e10cSrcweir }
1614cdf0e10cSrcweir }
1615cdf0e10cSrcweir
1616cdf0e10cSrcweir ++nSubTotalCount;
1617cdf0e10cSrcweir }
1618cdf0e10cSrcweir else
1619cdf0e10cSrcweir nSubTotalCount = 0;
1620cdf0e10cSrcweir
1621cdf0e10cSrcweir if( rResult[j] )
1622cdf0e10cSrcweir {
1623cdf0e10cSrcweir if ( bIsDataLayout )
1624cdf0e10cSrcweir {
1625cdf0e10cSrcweir if ( ( aResultEntry.Flags & sheet::MemberResultFlags::HASMEMBER ) != 0 )
1626cdf0e10cSrcweir {
1627cdf0e10cSrcweir // Asterisks are added in ScDPSaveData::WriteToSource to create unique names.
1628cdf0e10cSrcweir //! preserve original name there?
1629cdf0e10cSrcweir String aSourceName( aResultEntry.Name );
1630cdf0e10cSrcweir aSourceName.EraseTrailingChars( '*' );
1631cdf0e10cSrcweir
1632cdf0e10cSrcweir String aGivenName( aResultEntry.Caption ); //! Should use a stored name when available
1633cdf0e10cSrcweir aGivenName.EraseLeadingChars( '\'' );
1634cdf0e10cSrcweir
1635cdf0e10cSrcweir rResult[j] = lcl_IsNamedDataField( rTarget, aSourceName, aGivenName );
1636cdf0e10cSrcweir }
1637cdf0e10cSrcweir }
1638cdf0e10cSrcweir else if ( bHasFilter )
1639cdf0e10cSrcweir {
1640cdf0e10cSrcweir // name must match (simple value or subtotal)
1641cdf0e10cSrcweir rResult[j] = ( ( aResultEntry.Flags & sheet::MemberResultFlags::HASMEMBER ) != 0 ) &&
1642cdf0e10cSrcweir lcl_IsCondition( aResultEntry, aFilter );
1643cdf0e10cSrcweir
1644cdf0e10cSrcweir // if a function was specified, simple (non-subtotal) values never match
1645cdf0e10cSrcweir if ( bHasFunc && nSubTotalCount == 0 )
1646cdf0e10cSrcweir rResult[j] = sal_False;
1647cdf0e10cSrcweir }
1648cdf0e10cSrcweir // if no condition is given, keep the columns/rows included
1649cdf0e10cSrcweir }
1650cdf0e10cSrcweir aPrevious = aResultEntry;
1651cdf0e10cSrcweir }
1652cdf0e10cSrcweir }
1653cdf0e10cSrcweir
lcl_StripSubTotals(std::vector<sal_Bool> & rResult,const std::vector<sal_Int32> & rSubtotal)1654cdf0e10cSrcweir void lcl_StripSubTotals( std::vector< sal_Bool >& rResult, const std::vector< sal_Int32 >& rSubtotal )
1655cdf0e10cSrcweir {
1656cdf0e10cSrcweir sal_Int32 nSize = rResult.size();
1657cdf0e10cSrcweir DBG_ASSERT( (sal_Int32)rSubtotal.size() == nSize, "sizes don't match" );
1658cdf0e10cSrcweir
1659cdf0e10cSrcweir for (sal_Int32 nPos=0; nPos<nSize; nPos++)
1660cdf0e10cSrcweir if ( rResult[nPos] && rSubtotal[nPos] )
1661cdf0e10cSrcweir {
1662cdf0e10cSrcweir // if a subtotal is included, clear the result flag for the columns/rows that the subtotal includes
1663cdf0e10cSrcweir sal_Int32 nStart = nPos - rSubtotal[nPos];
1664cdf0e10cSrcweir DBG_ASSERT( nStart >= 0, "invalid subtotal count" );
1665cdf0e10cSrcweir
1666cdf0e10cSrcweir for (sal_Int32 nPrev = nStart; nPrev < nPos; nPrev++)
1667cdf0e10cSrcweir rResult[nPrev] = sal_False;
1668cdf0e10cSrcweir }
1669cdf0e10cSrcweir }
1670cdf0e10cSrcweir
lcl_GetDataFieldName(const String & rSourceName,sheet::GeneralFunction eFunc)1671cdf0e10cSrcweir String lcl_GetDataFieldName( const String& rSourceName, sheet::GeneralFunction eFunc )
1672cdf0e10cSrcweir {
1673cdf0e10cSrcweir sal_uInt16 nStrId = 0;
1674cdf0e10cSrcweir switch ( eFunc )
1675cdf0e10cSrcweir {
1676cdf0e10cSrcweir case sheet::GeneralFunction_SUM: nStrId = STR_FUN_TEXT_SUM; break;
1677cdf0e10cSrcweir case sheet::GeneralFunction_COUNT:
1678cdf0e10cSrcweir case sheet::GeneralFunction_COUNTNUMS: nStrId = STR_FUN_TEXT_COUNT; break;
1679cdf0e10cSrcweir case sheet::GeneralFunction_AVERAGE: nStrId = STR_FUN_TEXT_AVG; break;
1680cdf0e10cSrcweir case sheet::GeneralFunction_MAX: nStrId = STR_FUN_TEXT_MAX; break;
1681cdf0e10cSrcweir case sheet::GeneralFunction_MIN: nStrId = STR_FUN_TEXT_MIN; break;
1682cdf0e10cSrcweir case sheet::GeneralFunction_PRODUCT: nStrId = STR_FUN_TEXT_PRODUCT; break;
1683cdf0e10cSrcweir case sheet::GeneralFunction_STDEV:
1684cdf0e10cSrcweir case sheet::GeneralFunction_STDEVP: nStrId = STR_FUN_TEXT_STDDEV; break;
1685cdf0e10cSrcweir case sheet::GeneralFunction_VAR:
1686cdf0e10cSrcweir case sheet::GeneralFunction_VARP: nStrId = STR_FUN_TEXT_VAR; break;
1687cdf0e10cSrcweir case sheet::GeneralFunction_NONE:
1688cdf0e10cSrcweir case sheet::GeneralFunction_AUTO:
1689cdf0e10cSrcweir default:
1690cdf0e10cSrcweir {
1691cdf0e10cSrcweir DBG_ERRORFILE("wrong function");
1692cdf0e10cSrcweir }
1693cdf0e10cSrcweir }
1694cdf0e10cSrcweir if ( !nStrId )
1695cdf0e10cSrcweir return String();
1696cdf0e10cSrcweir
1697cdf0e10cSrcweir String aRet( ScGlobal::GetRscString( nStrId ) );
1698cdf0e10cSrcweir aRet.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " - " ));
1699cdf0e10cSrcweir aRet.Append( rSourceName );
1700cdf0e10cSrcweir return aRet;
1701cdf0e10cSrcweir }
1702cdf0e10cSrcweir
1703cdf0e10cSrcweir // static
GetDataDimensionNames(String & rSourceName,String & rGivenName,const uno::Reference<uno::XInterface> & xDim)1704cdf0e10cSrcweir void ScDPOutput::GetDataDimensionNames( String& rSourceName, String& rGivenName,
1705cdf0e10cSrcweir const uno::Reference<uno::XInterface>& xDim )
1706cdf0e10cSrcweir {
1707cdf0e10cSrcweir uno::Reference<beans::XPropertySet> xDimProp( xDim, uno::UNO_QUERY );
1708cdf0e10cSrcweir uno::Reference<container::XNamed> xDimName( xDim, uno::UNO_QUERY );
1709cdf0e10cSrcweir if ( xDimProp.is() && xDimName.is() )
1710cdf0e10cSrcweir {
1711cdf0e10cSrcweir // Asterisks are added in ScDPSaveData::WriteToSource to create unique names.
1712cdf0e10cSrcweir //! preserve original name there?
1713cdf0e10cSrcweir rSourceName = xDimName->getName();
1714cdf0e10cSrcweir rSourceName.EraseTrailingChars( '*' );
1715cdf0e10cSrcweir
1716cdf0e10cSrcweir // Generate "given name" the same way as in dptabres.
1717cdf0e10cSrcweir //! Should use a stored name when available
1718cdf0e10cSrcweir
1719cdf0e10cSrcweir sheet::GeneralFunction eFunc = (sheet::GeneralFunction)ScUnoHelpFunctions::GetEnumProperty(
1720cdf0e10cSrcweir xDimProp, rtl::OUString::createFromAscii(DP_PROP_FUNCTION),
1721cdf0e10cSrcweir sheet::GeneralFunction_NONE );
1722cdf0e10cSrcweir rGivenName = lcl_GetDataFieldName( rSourceName, eFunc );
1723cdf0e10cSrcweir }
1724cdf0e10cSrcweir }
1725cdf0e10cSrcweir
1726cdf0e10cSrcweir // Returns sal_True on success and stores the result in rTarget
1727cdf0e10cSrcweir // Returns sal_False if rFilters or rTarget describes something that is not visible
GetPivotData(ScDPGetPivotDataField & rTarget,const std::vector<ScDPGetPivotDataField> & rFilters)1728cdf0e10cSrcweir sal_Bool ScDPOutput::GetPivotData( ScDPGetPivotDataField& rTarget,
1729cdf0e10cSrcweir const std::vector< ScDPGetPivotDataField >& rFilters )
1730cdf0e10cSrcweir {
1731cdf0e10cSrcweir CalcSizes();
1732cdf0e10cSrcweir
1733cdf0e10cSrcweir // need to know about grand total columns/rows:
1734cdf0e10cSrcweir sal_Int32 nGrandTotalCols;
1735cdf0e10cSrcweir sal_Int32 nGrandTotalRows;
1736cdf0e10cSrcweir sal_Int32 nDataLayoutIndex;
1737cdf0e10cSrcweir std::vector<String> aDataNames;
1738cdf0e10cSrcweir std::vector<String> aGivenNames;
1739cdf0e10cSrcweir sheet::DataPilotFieldOrientation eDataOrient;
1740cdf0e10cSrcweir lcl_GetTableVars( nGrandTotalCols, nGrandTotalRows, nDataLayoutIndex, aDataNames, aGivenNames, eDataOrient, xSource );
1741cdf0e10cSrcweir
1742cdf0e10cSrcweir if ( aDataNames.empty() )
1743cdf0e10cSrcweir return sal_False; // incomplete table without data fields -> no result
1744cdf0e10cSrcweir
1745cdf0e10cSrcweir if ( eDataOrient == sheet::DataPilotFieldOrientation_HIDDEN )
1746cdf0e10cSrcweir {
1747cdf0e10cSrcweir // no data layout field -> single data field -> must match the selected field in rTarget
1748cdf0e10cSrcweir
1749cdf0e10cSrcweir DBG_ASSERT( aDataNames.size() == 1, "several data fields but no data layout field" );
1750cdf0e10cSrcweir if ( !lcl_IsNamedDataField( rTarget, aDataNames[0], aGivenNames[0] ) )
1751cdf0e10cSrcweir return sal_False;
1752cdf0e10cSrcweir }
1753cdf0e10cSrcweir
1754cdf0e10cSrcweir std::vector< sal_Bool > aIncludeCol( nColCount, sal_True );
1755cdf0e10cSrcweir std::vector< sal_Int32 > aSubtotalCol( nColCount, 0 );
1756cdf0e10cSrcweir std::vector< sal_Bool > aIncludeRow( nRowCount, sal_True );
1757cdf0e10cSrcweir std::vector< sal_Int32 > aSubtotalRow( nRowCount, 0 );
1758cdf0e10cSrcweir
1759cdf0e10cSrcweir std::vector< sal_Bool > aFilterUsed( rFilters.size(), sal_False );
1760cdf0e10cSrcweir
1761cdf0e10cSrcweir long nField;
1762cdf0e10cSrcweir long nCol;
1763cdf0e10cSrcweir long nRow;
1764cdf0e10cSrcweir bool bBeforeDataLayout;
1765cdf0e10cSrcweir
1766cdf0e10cSrcweir // look in column fields
1767cdf0e10cSrcweir
1768cdf0e10cSrcweir bBeforeDataLayout = ( eDataOrient == sheet::DataPilotFieldOrientation_COLUMN );
1769cdf0e10cSrcweir for (nField=0; nField<nColFieldCount; nField++)
1770cdf0e10cSrcweir lcl_FilterInclude( aIncludeCol, aSubtotalCol, pColFields[nField], rFilters, aFilterUsed, bBeforeDataLayout,
1771cdf0e10cSrcweir nGrandTotalCols, nDataLayoutIndex, aDataNames, aGivenNames, rTarget, xSource );
1772cdf0e10cSrcweir
1773cdf0e10cSrcweir // look in row fields
1774cdf0e10cSrcweir
1775cdf0e10cSrcweir bBeforeDataLayout = ( eDataOrient == sheet::DataPilotFieldOrientation_ROW );
1776cdf0e10cSrcweir for (nField=0; nField<nRowFieldCount; nField++)
1777cdf0e10cSrcweir lcl_FilterInclude( aIncludeRow, aSubtotalRow, pRowFields[nField], rFilters, aFilterUsed, bBeforeDataLayout,
1778cdf0e10cSrcweir nGrandTotalRows, nDataLayoutIndex, aDataNames, aGivenNames, rTarget, xSource );
1779cdf0e10cSrcweir
1780cdf0e10cSrcweir // page fields
1781cdf0e10cSrcweir
1782cdf0e10cSrcweir for (nField=0; nField<nPageFieldCount; nField++)
1783cdf0e10cSrcweir if ( !lcl_CheckPageField( pPageFields[nField], rFilters, aFilterUsed ) )
1784cdf0e10cSrcweir return sal_False;
1785cdf0e10cSrcweir
1786cdf0e10cSrcweir // all filter fields must be used
1787cdf0e10cSrcweir for (SCSIZE nFilter=0; nFilter<aFilterUsed.size(); nFilter++)
1788cdf0e10cSrcweir if (!aFilterUsed[nFilter])
1789cdf0e10cSrcweir return sal_False;
1790cdf0e10cSrcweir
1791cdf0e10cSrcweir lcl_StripSubTotals( aIncludeCol, aSubtotalCol );
1792cdf0e10cSrcweir lcl_StripSubTotals( aIncludeRow, aSubtotalRow );
1793cdf0e10cSrcweir
1794cdf0e10cSrcweir long nColPos = 0;
1795cdf0e10cSrcweir long nColIncluded = 0;
1796cdf0e10cSrcweir for (nCol=0; nCol<nColCount; nCol++)
1797cdf0e10cSrcweir if (aIncludeCol[nCol])
1798cdf0e10cSrcweir {
1799cdf0e10cSrcweir nColPos = nCol;
1800cdf0e10cSrcweir ++nColIncluded;
1801cdf0e10cSrcweir }
1802cdf0e10cSrcweir
1803cdf0e10cSrcweir long nRowPos = 0;
1804cdf0e10cSrcweir long nRowIncluded = 0;
1805cdf0e10cSrcweir for (nRow=0; nRow<nRowCount; nRow++)
1806cdf0e10cSrcweir if (aIncludeRow[nRow])
1807cdf0e10cSrcweir {
1808cdf0e10cSrcweir nRowPos = nRow;
1809cdf0e10cSrcweir ++nRowIncluded;
1810cdf0e10cSrcweir }
1811cdf0e10cSrcweir
1812cdf0e10cSrcweir if ( nColIncluded != 1 || nRowIncluded != 1 )
1813cdf0e10cSrcweir return sal_False;
1814cdf0e10cSrcweir
1815cdf0e10cSrcweir const uno::Sequence<sheet::DataResult>& rDataRow = aData[nRowPos];
1816cdf0e10cSrcweir if ( nColPos >= rDataRow.getLength() )
1817cdf0e10cSrcweir return sal_False;
1818cdf0e10cSrcweir
1819cdf0e10cSrcweir const sheet::DataResult& rResult = rDataRow[nColPos];
1820cdf0e10cSrcweir if ( rResult.Flags & sheet::DataResultFlags::ERROR )
1821cdf0e10cSrcweir return sal_False; //! different error?
1822cdf0e10cSrcweir
1823cdf0e10cSrcweir rTarget.mbValIsStr = sal_False;
1824cdf0e10cSrcweir rTarget.mnValNum = rResult.Value;
1825cdf0e10cSrcweir
1826cdf0e10cSrcweir return sal_True;
1827cdf0e10cSrcweir }
1828cdf0e10cSrcweir
IsFilterButton(const ScAddress & rPos)1829cdf0e10cSrcweir sal_Bool ScDPOutput::IsFilterButton( const ScAddress& rPos )
1830cdf0e10cSrcweir {
1831cdf0e10cSrcweir SCCOL nCol = rPos.Col();
1832cdf0e10cSrcweir SCROW nRow = rPos.Row();
1833cdf0e10cSrcweir SCTAB nTab = rPos.Tab();
1834cdf0e10cSrcweir if ( nTab != aStartPos.Tab() || !bDoFilter )
1835cdf0e10cSrcweir return sal_False; // wrong sheet or no button at all
1836cdf0e10cSrcweir
1837cdf0e10cSrcweir // filter button is at top left
1838cdf0e10cSrcweir return ( nCol == aStartPos.Col() && nRow == aStartPos.Row() );
1839cdf0e10cSrcweir }
1840cdf0e10cSrcweir
GetHeaderDim(const ScAddress & rPos,sal_uInt16 & rOrient)1841cdf0e10cSrcweir long ScDPOutput::GetHeaderDim( const ScAddress& rPos, sal_uInt16& rOrient )
1842cdf0e10cSrcweir {
1843cdf0e10cSrcweir SCCOL nCol = rPos.Col();
1844cdf0e10cSrcweir SCROW nRow = rPos.Row();
1845cdf0e10cSrcweir SCTAB nTab = rPos.Tab();
1846cdf0e10cSrcweir if ( nTab != aStartPos.Tab() )
1847cdf0e10cSrcweir return -1; // wrong sheet
1848cdf0e10cSrcweir
1849cdf0e10cSrcweir // calculate output positions and sizes
1850cdf0e10cSrcweir
1851cdf0e10cSrcweir CalcSizes();
1852cdf0e10cSrcweir
1853cdf0e10cSrcweir // test for column header
1854cdf0e10cSrcweir
1855cdf0e10cSrcweir if ( nRow == nTabStartRow && nCol >= nDataStartCol && nCol < nDataStartCol + nColFieldCount )
1856cdf0e10cSrcweir {
1857cdf0e10cSrcweir rOrient = sheet::DataPilotFieldOrientation_COLUMN;
1858cdf0e10cSrcweir long nField = nCol - nDataStartCol;
1859cdf0e10cSrcweir return pColFields[nField].nDim;
1860cdf0e10cSrcweir }
1861cdf0e10cSrcweir
1862cdf0e10cSrcweir // test for row header
1863cdf0e10cSrcweir
1864cdf0e10cSrcweir if ( nRow+1 == nDataStartRow && nCol >= nTabStartCol && nCol < nTabStartCol + nRowFieldCount )
1865cdf0e10cSrcweir {
1866cdf0e10cSrcweir rOrient = sheet::DataPilotFieldOrientation_ROW;
1867cdf0e10cSrcweir long nField = nCol - nTabStartCol;
1868cdf0e10cSrcweir return pRowFields[nField].nDim;
1869cdf0e10cSrcweir }
1870cdf0e10cSrcweir
1871cdf0e10cSrcweir // test for page field
1872cdf0e10cSrcweir
1873cdf0e10cSrcweir SCROW nPageStartRow = aStartPos.Row() + ( bDoFilter ? 1 : 0 );
1874cdf0e10cSrcweir if ( nCol == aStartPos.Col() && nRow >= nPageStartRow && nRow < nPageStartRow + nPageFieldCount )
1875cdf0e10cSrcweir {
1876cdf0e10cSrcweir rOrient = sheet::DataPilotFieldOrientation_PAGE;
1877cdf0e10cSrcweir long nField = nRow - nPageStartRow;
1878cdf0e10cSrcweir return pPageFields[nField].nDim;
1879cdf0e10cSrcweir }
1880cdf0e10cSrcweir
1881cdf0e10cSrcweir //! single data field (?)
1882cdf0e10cSrcweir
1883cdf0e10cSrcweir rOrient = sheet::DataPilotFieldOrientation_HIDDEN;
1884cdf0e10cSrcweir return -1; // invalid
1885cdf0e10cSrcweir }
1886cdf0e10cSrcweir
GetHeaderDrag(const ScAddress & rPos,sal_Bool bMouseLeft,sal_Bool bMouseTop,long nDragDim,Rectangle & rPosRect,sal_uInt16 & rOrient,long & rDimPos)1887cdf0e10cSrcweir sal_Bool ScDPOutput::GetHeaderDrag( const ScAddress& rPos, sal_Bool bMouseLeft, sal_Bool bMouseTop,
1888cdf0e10cSrcweir long nDragDim,
1889cdf0e10cSrcweir Rectangle& rPosRect, sal_uInt16& rOrient, long& rDimPos )
1890cdf0e10cSrcweir {
1891cdf0e10cSrcweir // Rectangle instead of ScRange for rPosRect to allow for negative values
1892cdf0e10cSrcweir
1893cdf0e10cSrcweir SCCOL nCol = rPos.Col();
1894cdf0e10cSrcweir SCROW nRow = rPos.Row();
1895cdf0e10cSrcweir SCTAB nTab = rPos.Tab();
1896cdf0e10cSrcweir if ( nTab != aStartPos.Tab() )
1897cdf0e10cSrcweir return sal_False; // wrong sheet
1898cdf0e10cSrcweir
1899cdf0e10cSrcweir // calculate output positions and sizes
1900cdf0e10cSrcweir
1901cdf0e10cSrcweir CalcSizes();
1902cdf0e10cSrcweir
1903cdf0e10cSrcweir // test for column header
1904cdf0e10cSrcweir
1905cdf0e10cSrcweir if ( nCol >= nDataStartCol && nCol <= nTabEndCol &&
1906cdf0e10cSrcweir nRow + 1 >= nMemberStartRow && nRow < nMemberStartRow + nColFieldCount )
1907cdf0e10cSrcweir {
1908cdf0e10cSrcweir long nField = nRow - nMemberStartRow;
1909cdf0e10cSrcweir if (nField < 0)
1910cdf0e10cSrcweir {
1911cdf0e10cSrcweir nField = 0;
1912cdf0e10cSrcweir bMouseTop = sal_True;
1913cdf0e10cSrcweir }
1914cdf0e10cSrcweir //! find start of dimension
1915cdf0e10cSrcweir
1916cdf0e10cSrcweir rPosRect = Rectangle( nDataStartCol, nMemberStartRow + nField,
1917cdf0e10cSrcweir nTabEndCol, nMemberStartRow + nField -1 );
1918cdf0e10cSrcweir
1919cdf0e10cSrcweir sal_Bool bFound = sal_False; // is this within the same orientation?
1920cdf0e10cSrcweir sal_Bool bBeforeDrag = sal_False;
1921cdf0e10cSrcweir sal_Bool bAfterDrag = sal_False;
1922cdf0e10cSrcweir for (long nPos=0; nPos<nColFieldCount && !bFound; nPos++)
1923cdf0e10cSrcweir {
1924cdf0e10cSrcweir if (pColFields[nPos].nDim == nDragDim)
1925cdf0e10cSrcweir {
1926cdf0e10cSrcweir bFound = sal_True;
1927cdf0e10cSrcweir if ( nField < nPos )
1928cdf0e10cSrcweir bBeforeDrag = sal_True;
1929cdf0e10cSrcweir else if ( nField > nPos )
1930cdf0e10cSrcweir bAfterDrag = sal_True;
1931cdf0e10cSrcweir }
1932cdf0e10cSrcweir }
1933cdf0e10cSrcweir
1934cdf0e10cSrcweir if ( bFound )
1935cdf0e10cSrcweir {
1936cdf0e10cSrcweir if (!bBeforeDrag)
1937cdf0e10cSrcweir {
1938cdf0e10cSrcweir ++rPosRect.Bottom();
1939cdf0e10cSrcweir if (bAfterDrag)
1940cdf0e10cSrcweir ++rPosRect.Top();
1941cdf0e10cSrcweir }
1942cdf0e10cSrcweir }
1943cdf0e10cSrcweir else
1944cdf0e10cSrcweir {
1945cdf0e10cSrcweir if ( !bMouseTop )
1946cdf0e10cSrcweir {
1947cdf0e10cSrcweir ++rPosRect.Top();
1948cdf0e10cSrcweir ++rPosRect.Bottom();
1949cdf0e10cSrcweir ++nField;
1950cdf0e10cSrcweir }
1951cdf0e10cSrcweir }
1952cdf0e10cSrcweir
1953cdf0e10cSrcweir rOrient = sheet::DataPilotFieldOrientation_COLUMN;
1954cdf0e10cSrcweir rDimPos = nField; //!...
1955cdf0e10cSrcweir return sal_True;
1956cdf0e10cSrcweir }
1957cdf0e10cSrcweir
1958cdf0e10cSrcweir // test for row header
1959cdf0e10cSrcweir
1960cdf0e10cSrcweir // special case if no row fields
1961cdf0e10cSrcweir sal_Bool bSpecial = ( nRow+1 >= nDataStartRow && nRow <= nTabEndRow &&
1962cdf0e10cSrcweir nRowFieldCount == 0 && nCol == nTabStartCol && bMouseLeft );
1963cdf0e10cSrcweir
1964cdf0e10cSrcweir if ( bSpecial || ( nRow+1 >= nDataStartRow && nRow <= nTabEndRow &&
1965cdf0e10cSrcweir nCol + 1 >= nTabStartCol && nCol < nTabStartCol + nRowFieldCount ) )
1966cdf0e10cSrcweir {
1967cdf0e10cSrcweir long nField = nCol - nTabStartCol;
1968cdf0e10cSrcweir //! find start of dimension
1969cdf0e10cSrcweir
1970cdf0e10cSrcweir rPosRect = Rectangle( nTabStartCol + nField, nDataStartRow - 1,
1971cdf0e10cSrcweir nTabStartCol + nField - 1, nTabEndRow );
1972cdf0e10cSrcweir
1973cdf0e10cSrcweir sal_Bool bFound = sal_False; // is this within the same orientation?
1974cdf0e10cSrcweir sal_Bool bBeforeDrag = sal_False;
1975cdf0e10cSrcweir sal_Bool bAfterDrag = sal_False;
1976cdf0e10cSrcweir for (long nPos=0; nPos<nRowFieldCount && !bFound; nPos++)
1977cdf0e10cSrcweir {
1978cdf0e10cSrcweir if (pRowFields[nPos].nDim == nDragDim)
1979cdf0e10cSrcweir {
1980cdf0e10cSrcweir bFound = sal_True;
1981cdf0e10cSrcweir if ( nField < nPos )
1982cdf0e10cSrcweir bBeforeDrag = sal_True;
1983cdf0e10cSrcweir else if ( nField > nPos )
1984cdf0e10cSrcweir bAfterDrag = sal_True;
1985cdf0e10cSrcweir }
1986cdf0e10cSrcweir }
1987cdf0e10cSrcweir
1988cdf0e10cSrcweir if ( bFound )
1989cdf0e10cSrcweir {
1990cdf0e10cSrcweir if (!bBeforeDrag)
1991cdf0e10cSrcweir {
1992cdf0e10cSrcweir ++rPosRect.Right();
1993cdf0e10cSrcweir if (bAfterDrag)
1994cdf0e10cSrcweir ++rPosRect.Left();
1995cdf0e10cSrcweir }
1996cdf0e10cSrcweir }
1997cdf0e10cSrcweir else
1998cdf0e10cSrcweir {
1999cdf0e10cSrcweir if ( !bMouseLeft )
2000cdf0e10cSrcweir {
2001cdf0e10cSrcweir ++rPosRect.Left();
2002cdf0e10cSrcweir ++rPosRect.Right();
2003cdf0e10cSrcweir ++nField;
2004cdf0e10cSrcweir }
2005cdf0e10cSrcweir }
2006cdf0e10cSrcweir
2007cdf0e10cSrcweir rOrient = sheet::DataPilotFieldOrientation_ROW;
2008cdf0e10cSrcweir rDimPos = nField; //!...
2009cdf0e10cSrcweir return sal_True;
2010cdf0e10cSrcweir }
2011cdf0e10cSrcweir
2012cdf0e10cSrcweir // test for page fields
2013cdf0e10cSrcweir
2014cdf0e10cSrcweir SCROW nPageStartRow = aStartPos.Row() + ( bDoFilter ? 1 : 0 );
2015cdf0e10cSrcweir if ( nCol >= aStartPos.Col() && nCol <= nTabEndCol &&
2016cdf0e10cSrcweir nRow + 1 >= nPageStartRow && nRow < nPageStartRow + nPageFieldCount )
2017cdf0e10cSrcweir {
2018cdf0e10cSrcweir long nField = nRow - nPageStartRow;
2019cdf0e10cSrcweir if (nField < 0)
2020cdf0e10cSrcweir {
2021cdf0e10cSrcweir nField = 0;
2022cdf0e10cSrcweir bMouseTop = sal_True;
2023cdf0e10cSrcweir }
2024cdf0e10cSrcweir //! find start of dimension
2025cdf0e10cSrcweir
2026cdf0e10cSrcweir rPosRect = Rectangle( aStartPos.Col(), nPageStartRow + nField,
2027cdf0e10cSrcweir nTabEndCol, nPageStartRow + nField - 1 );
2028cdf0e10cSrcweir
2029cdf0e10cSrcweir sal_Bool bFound = sal_False; // is this within the same orientation?
2030cdf0e10cSrcweir sal_Bool bBeforeDrag = sal_False;
2031cdf0e10cSrcweir sal_Bool bAfterDrag = sal_False;
2032cdf0e10cSrcweir for (long nPos=0; nPos<nPageFieldCount && !bFound; nPos++)
2033cdf0e10cSrcweir {
2034cdf0e10cSrcweir if (pPageFields[nPos].nDim == nDragDim)
2035cdf0e10cSrcweir {
2036cdf0e10cSrcweir bFound = sal_True;
2037cdf0e10cSrcweir if ( nField < nPos )
2038cdf0e10cSrcweir bBeforeDrag = sal_True;
2039cdf0e10cSrcweir else if ( nField > nPos )
2040cdf0e10cSrcweir bAfterDrag = sal_True;
2041cdf0e10cSrcweir }
2042cdf0e10cSrcweir }
2043cdf0e10cSrcweir
2044cdf0e10cSrcweir if ( bFound )
2045cdf0e10cSrcweir {
2046cdf0e10cSrcweir if (!bBeforeDrag)
2047cdf0e10cSrcweir {
2048cdf0e10cSrcweir ++rPosRect.Bottom();
2049cdf0e10cSrcweir if (bAfterDrag)
2050cdf0e10cSrcweir ++rPosRect.Top();
2051cdf0e10cSrcweir }
2052cdf0e10cSrcweir }
2053cdf0e10cSrcweir else
2054cdf0e10cSrcweir {
2055cdf0e10cSrcweir if ( !bMouseTop )
2056cdf0e10cSrcweir {
2057cdf0e10cSrcweir ++rPosRect.Top();
2058cdf0e10cSrcweir ++rPosRect.Bottom();
2059cdf0e10cSrcweir ++nField;
2060cdf0e10cSrcweir }
2061cdf0e10cSrcweir }
2062cdf0e10cSrcweir
2063cdf0e10cSrcweir rOrient = sheet::DataPilotFieldOrientation_PAGE;
2064cdf0e10cSrcweir rDimPos = nField; //!...
2065cdf0e10cSrcweir return sal_True;
2066cdf0e10cSrcweir }
2067cdf0e10cSrcweir
2068cdf0e10cSrcweir return sal_False;
2069cdf0e10cSrcweir }
2070cdf0e10cSrcweir
2071cdf0e10cSrcweir
2072cdf0e10cSrcweir
2073