Update to m13
[ooovba.git] / sc / source / core / data / pivot2.cxx
blobab8a69953c84f5e987a030ccb41a8b21ae035ee9
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: pivot2.cxx,v $
10 * $Revision: 1.14.32.3 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
36 #ifdef _MSC_VER
37 #pragma optimize("",off)
38 #endif
40 // INCLUDE ---------------------------------------------------------------
42 #include "scitems.hxx"
43 #include <svx/boxitem.hxx>
44 #include <svx/wghtitem.hxx>
45 #include <svx/algitem.hxx>
46 #include <unotools/transliterationwrapper.hxx>
48 #include "globstr.hrc"
49 #include "subtotal.hxx"
50 #include "rangeutl.hxx"
51 #include "attrib.hxx"
52 #include "patattr.hxx"
53 #include "docpool.hxx"
54 #include "document.hxx"
55 #include "userlist.hxx"
56 #include "pivot.hxx"
57 #include "rechead.hxx"
58 #include "formula/errorcodes.hxx" // fuer errNoValue
59 #include "refupdat.hxx"
60 #include "stlpool.hxx"
61 #include "stlsheet.hxx"
63 using ::com::sun::star::sheet::DataPilotFieldReference;
65 // STATIC DATA -----------------------------------------------------------
67 #if OLD_PIVOT_IMPLEMENTATION
68 //--------------------------------------------------------------------------------------------------
69 // Hilfsmethoden von ScPivot
70 //--------------------------------------------------------------------------------------------------
72 void ScPivot::SetFrame(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, USHORT nWidth)
74 if (pDoc->pTab[nDestTab])
76 SvxBorderLine aLine;
77 aLine.SetOutWidth(nWidth);
78 SvxBoxItem aBox( ATTR_BORDER );
79 aBox.SetLine(&aLine, BOX_LINE_LEFT);
80 aBox.SetLine(&aLine, BOX_LINE_TOP);
81 aBox.SetLine(&aLine, BOX_LINE_RIGHT);
82 aBox.SetLine(&aLine, BOX_LINE_BOTTOM);
83 SvxBoxInfoItem aBoxInfo( ATTR_BORDER_INNER );
84 aBoxInfo.SetValid(VALID_HORI,FALSE);
85 aBoxInfo.SetValid(VALID_VERT,FALSE);
86 aBoxInfo.SetValid(VALID_DISTANCE,FALSE);
87 pDoc->pTab[nDestTab]->ApplyBlockFrame(&aBox, &aBoxInfo, nCol1, nRow1, nCol2, nRow2);
91 void ScPivot::SetFrameHor(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2)
93 if (pDoc->pTab[nDestTab])
95 SvxBorderLine aLine;
96 aLine.SetOutWidth(20);
97 SvxBoxItem aBox( ATTR_BORDER );
98 aBox.SetLine(&aLine, BOX_LINE_LEFT);
99 aBox.SetLine(&aLine, BOX_LINE_TOP);
100 aBox.SetLine(&aLine, BOX_LINE_RIGHT);
101 aBox.SetLine(&aLine, BOX_LINE_BOTTOM);
102 SvxBoxInfoItem aBoxInfo(ATTR_BORDER_INNER);
103 aBoxInfo.SetValid(VALID_VERT,FALSE);
104 aBoxInfo.SetValid(VALID_DISTANCE,FALSE);
105 aBoxInfo.SetLine(&aLine, BOXINFO_LINE_HORI);
106 pDoc->pTab[nDestTab]->ApplyBlockFrame(&aBox, &aBoxInfo, nCol1, nRow1, nCol2, nRow2);
110 void ScPivot::SetFrameVer(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2)
112 if (pDoc->pTab[nDestTab])
114 SvxBorderLine aLine;
115 aLine.SetOutWidth(20);
116 SvxBoxItem aBox( ATTR_BORDER );
117 aBox.SetLine(&aLine, BOX_LINE_LEFT);
118 aBox.SetLine(&aLine, BOX_LINE_TOP);
119 aBox.SetLine(&aLine, BOX_LINE_RIGHT);
120 aBox.SetLine(&aLine, BOX_LINE_BOTTOM);
121 SvxBoxInfoItem aBoxInfo( ATTR_BORDER_INNER );
122 aBoxInfo.SetValid(VALID_HORI,FALSE);
123 aBoxInfo.SetValid(VALID_DISTANCE,FALSE);
124 aBoxInfo.SetLine(&aLine, BOXINFO_LINE_VERT);
125 pDoc->pTab[nDestTab]->ApplyBlockFrame(&aBox, &aBoxInfo, nCol1, nRow1, nCol2, nRow2);
129 void ScPivot::SetFontBold(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2)
131 if (pDoc->pTab[nDestTab])
133 ScPatternAttr aPattern( pDoc->GetPool() );
134 aPattern.GetItemSet().Put( SvxWeightItem( WEIGHT_BOLD, ATTR_FONT_WEIGHT ) );
135 pDoc->pTab[nDestTab]->ApplyPatternArea(nCol1, nRow1, nCol2, nRow2, aPattern);
139 void ScPivot::SetJustifyLeft(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2)
141 if (pDoc->pTab[nDestTab])
143 ScPatternAttr aPattern( pDoc->GetPool() );
144 aPattern.GetItemSet().Put( SvxHorJustifyItem( SVX_HOR_JUSTIFY_LEFT, ATTR_HOR_JUSTIFY ) );
145 pDoc->pTab[nDestTab]->ApplyPatternArea(nCol1, nRow1, nCol2, nRow2, aPattern);
149 void ScPivot::SetJustifyRight(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2)
151 if (pDoc->pTab[nDestTab])
153 ScPatternAttr aPattern( pDoc->GetPool() );
154 aPattern.GetItemSet().Put( SvxHorJustifyItem( SVX_HOR_JUSTIFY_RIGHT, ATTR_HOR_JUSTIFY ) );
155 pDoc->pTab[nDestTab]->ApplyPatternArea(nCol1, nRow1, nCol2, nRow2, aPattern);
159 void ScPivot::SetButton(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2)
161 pDoc->ApplyFlagsTab(nCol1, nRow1, nCol2, nRow2, nDestTab, SC_MF_BUTTON);
164 void ScPivot::SetStyle(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, USHORT nId)
166 if ( nCol1 > nCol2 || nRow1 > nRow2 )
167 return; // Falls Bereiche leer sind
169 USHORT nStringId = 0;
170 switch (nId)
172 case PIVOT_STYLE_INNER: nStringId = STR_PIVOT_STYLE_INNER; break;
173 case PIVOT_STYLE_RESULT: nStringId = STR_PIVOT_STYLE_RESULT; break;
174 case PIVOT_STYLE_CATEGORY: nStringId = STR_PIVOT_STYLE_CATEGORY; break;
175 case PIVOT_STYLE_TITLE: nStringId = STR_PIVOT_STYLE_TITLE; break;
176 case PIVOT_STYLE_FIELDNAME: nStringId = STR_PIVOT_STYLE_FIELDNAME; break;
177 case PIVOT_STYLE_TOP: nStringId = STR_PIVOT_STYLE_TOP; break;
178 default:
179 DBG_ERROR("falsche ID bei ScPivot::SetStyle");
180 return;
182 String aStyleName = ScGlobal::GetRscString(nStringId);
184 ScStyleSheetPool* pStlPool = pDoc->GetStyleSheetPool();
185 ScStyleSheet* pStyle = (ScStyleSheet*) pStlPool->Find( aStyleName, SFX_STYLE_FAMILY_PARA );
186 if (!pStyle)
188 // neu anlegen
190 pStyle = (ScStyleSheet*) &pStlPool->Make( aStyleName, SFX_STYLE_FAMILY_PARA,
191 SFXSTYLEBIT_USERDEF );
192 pStyle->SetParent( ScGlobal::GetRscString(STR_STYLENAME_STANDARD) );
193 SfxItemSet& rSet = pStyle->GetItemSet();
194 if ( nId==PIVOT_STYLE_RESULT || nId==PIVOT_STYLE_TITLE )
195 rSet.Put( SvxWeightItem( WEIGHT_BOLD, ATTR_FONT_WEIGHT ) );
196 if ( nId==PIVOT_STYLE_CATEGORY || nId==PIVOT_STYLE_TITLE )
197 rSet.Put( SvxHorJustifyItem( SVX_HOR_JUSTIFY_LEFT, ATTR_HOR_JUSTIFY ) );
200 pDoc->pTab[nDestTab]->ApplyStyleArea( nCol1, nRow1, nCol2, nRow2, *pStyle );
203 void ScPivot::SetValue(SCCOL nCol, SCROW nRow, const SubTotal& rTotal, USHORT nFunc)
205 if ( rTotal.Valid( nFunc ) == 1)
206 pDoc->SetValue(nCol, nRow, nDestTab, rTotal.Result( nFunc ));
207 else if ( rTotal.Valid( nFunc ) == 0)
208 pDoc->SetError(nCol, nRow, nDestTab, errNoValue);
211 //--------------------------------------------------------------------------------------------------
213 void ScPivot::GetParam( ScPivotParam& rParam, ScQueryParam& rQuery, ScArea& rSrcArea ) const
215 SCSIZE nCount;
216 SCCOL nDummyCol;
217 SCROW nDummyRow;
218 GetDestArea( rParam.nCol,rParam.nRow, nDummyCol,nDummyRow, rParam.nTab );
220 // Row und Col in der Bedeutung vertauscht:
221 GetRowFields( rParam.aColArr, nCount );
222 rParam.nColCount = nCount;
223 GetColFields( rParam.aRowArr, nCount );
224 rParam.nRowCount = nCount;
225 GetDataFields( rParam.aDataArr, nCount );
226 rParam.nDataCount = nCount;
228 rParam.bIgnoreEmptyRows = GetIgnoreEmpty();
229 rParam.bDetectCategories = GetDetectCat();
230 rParam.bMakeTotalCol = GetMakeTotalCol();
231 rParam.bMakeTotalRow = GetMakeTotalRow();
233 GetQuery(rQuery);
234 GetSrcArea( rSrcArea.nColStart, rSrcArea.nRowStart,
235 rSrcArea.nColEnd, rSrcArea.nRowEnd, rSrcArea.nTab );
238 void ScPivot::SetParam( const ScPivotParam& rParam, const ScQueryParam& rQuery,
239 const ScArea& rSrcArea )
241 SetQuery( rQuery );
242 SetHeader( TRUE );
243 SetSrcArea( rSrcArea.nColStart, rSrcArea.nRowStart,
244 rSrcArea.nColEnd, rSrcArea.nRowEnd, rSrcArea.nTab );
245 SetDestPos( rParam.nCol, rParam.nRow, rParam.nTab );
246 SetIgnoreEmpty( rParam.bIgnoreEmptyRows );
247 SetDetectCat( rParam.bDetectCategories );
248 SetMakeTotalCol( rParam.bMakeTotalCol );
249 SetMakeTotalRow( rParam.bMakeTotalRow );
251 // Row und Col in der Bedeutung vertauscht:
252 SetRowFields( rParam.aColArr, rParam.nColCount );
253 SetColFields( rParam.aRowArr, rParam.nRowCount );
254 SetDataFields( rParam.aDataArr, rParam.nDataCount );
257 ScDataObject* ScPivot::Clone() const
259 return new ScPivot(*this);
262 //--------------------------------------------------------------------------------------------------
263 // PivotScStrCollection
264 //--------------------------------------------------------------------------------------------------
266 ScDataObject* PivotScStrCollection::Clone() const
268 return new PivotScStrCollection(*this);
271 short PivotScStrCollection::Compare(ScDataObject* pKey1, ScDataObject* pKey2) const
273 DBG_ASSERT(pKey1&&pKey2,"0-Zeiger bei PivotScStrCollection::Compare");
275 short nResult = 0;
277 TypedStrData& rData1 = (TypedStrData&)*pKey1;
278 TypedStrData& rData2 = (TypedStrData&)*pKey2;
280 if ( rData1.nStrType > rData2.nStrType )
281 nResult = 1;
282 else if ( rData1.nStrType < rData2.nStrType )
283 nResult = -1;
284 else if ( !rData1.nStrType /* && !rData2.nStrType */ )
286 // Zahlen vergleichen:
288 if ( rData1.nValue == rData2.nValue )
289 nResult = 0;
290 else if ( rData1.nValue < rData2.nValue )
291 nResult = -1;
292 else
293 nResult = 1;
295 else /* if ( rData1.nStrType && rData2.nStrType ) */
297 // Strings vergleichen:
299 if (pUserData)
300 nResult = sal::static_int_cast<short>(pUserData->ICompare(rData1.aStrValue, rData2.aStrValue));
301 else
303 nResult = (short) ScGlobal::pTransliteration->compareString(
304 rData1.aStrValue, rData2.aStrValue );
308 return nResult;
311 USHORT PivotScStrCollection::GetIndex(TypedStrData* pData) const
313 USHORT nIndex = 0;
314 if (!Search(pData, nIndex))
315 nIndex = 0;
316 return nIndex;
319 //--------------------------------------------------------------------------------------------------
320 // PivotCollection
321 //--------------------------------------------------------------------------------------------------
323 String ScPivotCollection::CreateNewName( USHORT nMin ) const
325 String aBase( RTL_CONSTASCII_USTRINGPARAM("DataPilot") );
326 //! from Resource?
328 for (USHORT nAdd=0; nAdd<=nCount; nAdd++) // nCount+1 Versuche
330 String aNewName = aBase;
331 aNewName += String::CreateFromInt32( nMin + nAdd );
332 BOOL bFound = FALSE;
333 for (USHORT i=0; i<nCount && !bFound; i++)
334 if (((ScPivot*)pItems[i])->GetName() == aNewName)
335 bFound = TRUE;
336 if (!bFound)
337 return aNewName; // freien Namen gefunden
339 return String(); // sollte nicht vorkommen
342 ScPivot* ScPivotCollection::GetPivotAtCursor(SCCOL nCol, SCROW nRow, SCTAB nTab) const
344 if (pItems)
346 for (USHORT i = 0; i < nCount; i++)
347 if (((ScPivot*)pItems[i])->IsPivotAtCursor(nCol, nRow, nTab))
349 return (ScPivot*)pItems[i];
352 return NULL;
355 BOOL ScPivotCollection::Load(SvStream& rStream)
357 BOOL bSuccess = TRUE;
358 USHORT nNewCount, i;
359 FreeAll();
361 ScMultipleReadHeader aHdr( rStream );
363 rStream >> nNewCount;
364 for (i=0; i<nNewCount && bSuccess; i++)
366 ScPivot* pPivot = new ScPivot( pDoc );
367 if (pPivot)
369 bSuccess = pPivot->Load(rStream, aHdr);
370 Insert( pPivot );
372 else
373 bSuccess = FALSE;
376 // fuer alte Dateien: eindeutige Namen vergeben
378 if (bSuccess)
379 for (i=0; i<nCount; i++)
380 if (!((const ScPivot*)At(i))->GetName().Len())
381 ((ScPivot*)At(i))->SetName( CreateNewName() );
383 return bSuccess;
386 BOOL ScPivotCollection::Store(SvStream& rStream) const
388 BOOL bSuccess = TRUE;
390 ScMultipleWriteHeader aHdr( rStream );
392 rStream << nCount;
394 for (USHORT i=0; i<nCount && bSuccess; i++)
395 bSuccess = ((const ScPivot*)At(i))->Store( rStream, aHdr );
397 return bSuccess;
400 void ScPivotCollection::UpdateReference(UpdateRefMode eUpdateRefMode,
401 SCCOL nCol1, SCROW nRow1, SCTAB nTab1,
402 SCCOL nCol2, SCROW nRow2, SCTAB nTab2,
403 SCsCOL nDx, SCsROW nDy, SCsTAB nDz )
405 for (USHORT i=0; i<nCount; i++)
407 SCCOL theCol1;
408 SCROW theRow1;
409 SCTAB theTab1;
410 SCCOL theCol2;
411 SCROW theRow2;
412 SCTAB theTab2;
413 ScRefUpdateRes eRes;
414 ScPivot* pPivot = (ScPivot*)pItems[i];
416 // Source
418 pPivot->GetSrcArea( theCol1, theRow1, theCol2, theRow2, theTab1 );
419 theTab2 = theTab1;
421 eRes = ScRefUpdate::Update( pDoc, eUpdateRefMode,
422 nCol1,nRow1,nTab1, nCol2,nRow2,nTab2, nDx,nDy,nDz,
423 theCol1,theRow1,theTab1, theCol2,theRow2,theTab2 );
425 if (eRes != UR_NOTHING)
426 pPivot->MoveSrcArea( theCol1, theRow1, theTab1 );
428 // Dest
430 pPivot->GetDestArea( theCol1, theRow1, theCol2, theRow2, theTab1 );
431 theTab2 = theTab1;
433 eRes = ScRefUpdate::Update( pDoc, eUpdateRefMode,
434 nCol1,nRow1,nTab1, nCol2,nRow2,nTab2, nDx,nDy,nDz,
435 theCol1,theRow1,theTab1, theCol2,theRow2,theTab2 );
437 if (eRes != UR_NOTHING)
438 pPivot->MoveDestArea( theCol1, theRow1, theTab1 );
442 void ScPivotCollection::UpdateGrow( const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY )
444 // nur Quell-Bereich
446 for (USHORT i=0; i<nCount; i++)
448 ScPivot* pPivot = (ScPivot*)pItems[i];
449 ScRange aSrc = pPivot->GetSrcArea();
450 ScRefUpdateRes eRes = ScRefUpdate::DoGrow( rArea, nGrowX, nGrowY, aSrc );
451 if (eRes != UR_NOTHING)
452 pPivot->ExtendSrcArea( aSrc.aEnd.Col(), aSrc.aEnd.Row() );
456 BOOL ScPivotCollection::operator==(const ScPivotCollection& rCmp) const
458 if (nCount != rCmp.nCount)
459 return FALSE;
461 if (!nCount)
462 return TRUE; // beide leer - nicht erst die Param's anlegen!
464 ScPivotParam aMyParam, aCmpParam;
465 ScQueryParam aMyQuery, aCmpQuery;
466 ScArea aMyArea, aCmpArea;
468 for (USHORT i=0; i<nCount; i++)
470 ScPivot* pMyPivot = (ScPivot*)pItems[i];
471 pMyPivot->GetParam( aMyParam, aMyQuery, aMyArea );
472 ScPivot* pCmpPivot = (ScPivot*)rCmp.pItems[i];
473 pCmpPivot->GetParam( aCmpParam, aCmpQuery, aCmpArea );
474 if (!( aMyArea==aCmpArea && aMyParam==aCmpParam && aMyQuery==aCmpQuery ))
475 return FALSE;
478 return TRUE;
481 ScDataObject* ScPivotCollection::Clone() const
483 return new ScPivotCollection(*this);
486 #endif
488 // ============================================================================
490 ScDPLabelData::ScDPLabelData( const String& rName, short nCol, bool bIsValue ) :
491 maName( rName ),
492 mnCol( nCol ),
493 mnFuncMask( PIVOT_FUNC_NONE ),
494 mnUsedHier( 0 ),
495 mbShowAll( false ),
496 mbIsValue( bIsValue )
500 // ============================================================================
502 ScDPFuncData::ScDPFuncData( short nCol, USHORT nFuncMask ) :
503 mnCol( nCol ),
504 mnFuncMask( nFuncMask )
508 ScDPFuncData::ScDPFuncData( short nCol, USHORT nFuncMask, const DataPilotFieldReference& rFieldRef ) :
509 mnCol( nCol ),
510 mnFuncMask( nFuncMask ),
511 maFieldRef( rFieldRef )
515 // ============================================================================