1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_sc.hxx" 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir 32*cdf0e10cSrcweir 33*cdf0e10cSrcweir // INCLUDE --------------------------------------------------------------- 34*cdf0e10cSrcweir 35*cdf0e10cSrcweir #include "dbfunc.hxx" 36*cdf0e10cSrcweir #include "scitems.hxx" 37*cdf0e10cSrcweir #include <sfx2/bindings.hxx> 38*cdf0e10cSrcweir #include <vcl/svapp.hxx> 39*cdf0e10cSrcweir #include <vcl/msgbox.hxx> 40*cdf0e10cSrcweir #include <vcl/sound.hxx> 41*cdf0e10cSrcweir #include <vcl/waitobj.hxx> 42*cdf0e10cSrcweir #include <svl/zforlist.hxx> 43*cdf0e10cSrcweir #include <sfx2/app.hxx> 44*cdf0e10cSrcweir #include <com/sun/star/beans/XPropertySet.hpp> 45*cdf0e10cSrcweir #include <com/sun/star/container/XNameAccess.hpp> 46*cdf0e10cSrcweir #include <com/sun/star/sheet/DataPilotFieldFilter.hpp> 47*cdf0e10cSrcweir #include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp> 48*cdf0e10cSrcweir #include <com/sun/star/sheet/DataPilotFieldOrientation.hpp> 49*cdf0e10cSrcweir #include <com/sun/star/sheet/DataPilotFieldSortMode.hpp> 50*cdf0e10cSrcweir #include <com/sun/star/sheet/DataPilotTableHeaderData.hpp> 51*cdf0e10cSrcweir #include <com/sun/star/sheet/GeneralFunction.hpp> 52*cdf0e10cSrcweir #include <com/sun/star/sheet/MemberResultFlags.hpp> 53*cdf0e10cSrcweir #include <com/sun/star/sheet/XDimensionsSupplier.hpp> 54*cdf0e10cSrcweir #include <com/sun/star/sheet/XDrillDownDataSupplier.hpp> 55*cdf0e10cSrcweir 56*cdf0e10cSrcweir #include "global.hxx" 57*cdf0e10cSrcweir #include "globstr.hrc" 58*cdf0e10cSrcweir #include "sc.hrc" 59*cdf0e10cSrcweir #include "undotab.hxx" 60*cdf0e10cSrcweir #include "undodat.hxx" 61*cdf0e10cSrcweir #include "dbcolect.hxx" 62*cdf0e10cSrcweir #include "rangenam.hxx" 63*cdf0e10cSrcweir #include "rangeutl.hxx" 64*cdf0e10cSrcweir #include "docsh.hxx" 65*cdf0e10cSrcweir #include "olinetab.hxx" 66*cdf0e10cSrcweir #include "consoli.hxx" 67*cdf0e10cSrcweir #include "olinefun.hxx" 68*cdf0e10cSrcweir #include "dpobject.hxx" 69*cdf0e10cSrcweir #include "dpsave.hxx" 70*cdf0e10cSrcweir #include "dpdimsave.hxx" 71*cdf0e10cSrcweir #include "dbdocfun.hxx" 72*cdf0e10cSrcweir #include "dpoutput.hxx" 73*cdf0e10cSrcweir #include "dptabsrc.hxx" 74*cdf0e10cSrcweir #include "editable.hxx" 75*cdf0e10cSrcweir #include "docpool.hxx" 76*cdf0e10cSrcweir #include "patattr.hxx" 77*cdf0e10cSrcweir #include "unonames.hxx" 78*cdf0e10cSrcweir #include "cell.hxx" 79*cdf0e10cSrcweir #include "userlist.hxx" 80*cdf0e10cSrcweir 81*cdf0e10cSrcweir #include <hash_set> 82*cdf0e10cSrcweir #include <hash_map> 83*cdf0e10cSrcweir #include <memory> 84*cdf0e10cSrcweir #include <list> 85*cdf0e10cSrcweir #include <vector> 86*cdf0e10cSrcweir 87*cdf0e10cSrcweir using namespace com::sun::star; 88*cdf0e10cSrcweir using ::com::sun::star::uno::Any; 89*cdf0e10cSrcweir using ::com::sun::star::uno::Sequence; 90*cdf0e10cSrcweir using ::com::sun::star::uno::Reference; 91*cdf0e10cSrcweir using ::com::sun::star::uno::UNO_QUERY; 92*cdf0e10cSrcweir using ::com::sun::star::beans::XPropertySet; 93*cdf0e10cSrcweir using ::com::sun::star::container::XNameAccess; 94*cdf0e10cSrcweir using ::com::sun::star::sheet::XDimensionsSupplier; 95*cdf0e10cSrcweir using ::rtl::OUString; 96*cdf0e10cSrcweir using ::rtl::OUStringHash; 97*cdf0e10cSrcweir using ::rtl::OUStringBuffer; 98*cdf0e10cSrcweir using ::std::auto_ptr; 99*cdf0e10cSrcweir using ::std::list; 100*cdf0e10cSrcweir using ::std::vector; 101*cdf0e10cSrcweir using ::std::hash_map; 102*cdf0e10cSrcweir using ::std::hash_set; 103*cdf0e10cSrcweir 104*cdf0e10cSrcweir // STATIC DATA ----------------------------------------------------------- 105*cdf0e10cSrcweir 106*cdf0e10cSrcweir 107*cdf0e10cSrcweir //================================================================== 108*cdf0e10cSrcweir 109*cdf0e10cSrcweir // 110*cdf0e10cSrcweir // Outliner 111*cdf0e10cSrcweir // 112*cdf0e10cSrcweir 113*cdf0e10cSrcweir // Outline-Gruppierung erzeugen 114*cdf0e10cSrcweir 115*cdf0e10cSrcweir void ScDBFunc::MakeOutline( sal_Bool bColumns, sal_Bool bRecord ) 116*cdf0e10cSrcweir { 117*cdf0e10cSrcweir ScRange aRange; 118*cdf0e10cSrcweir if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE) 119*cdf0e10cSrcweir { 120*cdf0e10cSrcweir ScDocShell* pDocSh = GetViewData()->GetDocShell(); 121*cdf0e10cSrcweir ScOutlineDocFunc aFunc(*pDocSh); 122*cdf0e10cSrcweir aFunc.MakeOutline( aRange, bColumns, bRecord, sal_False ); 123*cdf0e10cSrcweir } 124*cdf0e10cSrcweir else 125*cdf0e10cSrcweir ErrorMessage(STR_NOMULTISELECT); 126*cdf0e10cSrcweir } 127*cdf0e10cSrcweir 128*cdf0e10cSrcweir // Outline-Gruppierung loeschen 129*cdf0e10cSrcweir 130*cdf0e10cSrcweir void ScDBFunc::RemoveOutline( sal_Bool bColumns, sal_Bool bRecord ) 131*cdf0e10cSrcweir { 132*cdf0e10cSrcweir ScRange aRange; 133*cdf0e10cSrcweir if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE) 134*cdf0e10cSrcweir { 135*cdf0e10cSrcweir ScDocShell* pDocSh = GetViewData()->GetDocShell(); 136*cdf0e10cSrcweir ScOutlineDocFunc aFunc(*pDocSh); 137*cdf0e10cSrcweir aFunc.RemoveOutline( aRange, bColumns, bRecord, sal_False ); 138*cdf0e10cSrcweir } 139*cdf0e10cSrcweir else 140*cdf0e10cSrcweir ErrorMessage(STR_NOMULTISELECT); 141*cdf0e10cSrcweir } 142*cdf0e10cSrcweir 143*cdf0e10cSrcweir // Menue-Status: Outlines loeschen 144*cdf0e10cSrcweir 145*cdf0e10cSrcweir void ScDBFunc::TestRemoveOutline( sal_Bool& rCol, sal_Bool& rRow ) 146*cdf0e10cSrcweir { 147*cdf0e10cSrcweir sal_Bool bColFound = sal_False; 148*cdf0e10cSrcweir sal_Bool bRowFound = sal_False; 149*cdf0e10cSrcweir 150*cdf0e10cSrcweir SCCOL nStartCol, nEndCol; 151*cdf0e10cSrcweir SCROW nStartRow, nEndRow; 152*cdf0e10cSrcweir SCTAB nStartTab, nEndTab; 153*cdf0e10cSrcweir if (GetViewData()->GetSimpleArea(nStartCol,nStartRow,nStartTab,nEndCol,nEndRow,nEndTab) == SC_MARK_SIMPLE) 154*cdf0e10cSrcweir { 155*cdf0e10cSrcweir SCTAB nTab = nStartTab; 156*cdf0e10cSrcweir ScDocument* pDoc = GetViewData()->GetDocument(); 157*cdf0e10cSrcweir ScOutlineTable* pTable = pDoc->GetOutlineTable( nTab ); 158*cdf0e10cSrcweir if (pTable) 159*cdf0e10cSrcweir { 160*cdf0e10cSrcweir ScOutlineArray* pArray; 161*cdf0e10cSrcweir ScOutlineEntry* pEntry; 162*cdf0e10cSrcweir SCCOLROW nStart; 163*cdf0e10cSrcweir SCCOLROW nEnd; 164*cdf0e10cSrcweir sal_Bool bColMarked = ( nStartRow == 0 && nEndRow == MAXROW ); 165*cdf0e10cSrcweir sal_Bool bRowMarked = ( nStartCol == 0 && nEndCol == MAXCOL ); 166*cdf0e10cSrcweir 167*cdf0e10cSrcweir // Spalten 168*cdf0e10cSrcweir 169*cdf0e10cSrcweir if ( !bRowMarked || bColMarked ) // nicht wenn ganze Zeilen markiert 170*cdf0e10cSrcweir { 171*cdf0e10cSrcweir pArray = pTable->GetColArray(); 172*cdf0e10cSrcweir ScSubOutlineIterator aColIter( pArray ); 173*cdf0e10cSrcweir while ((pEntry=aColIter.GetNext()) != NULL && !bColFound) 174*cdf0e10cSrcweir { 175*cdf0e10cSrcweir nStart = pEntry->GetStart(); 176*cdf0e10cSrcweir nEnd = pEntry->GetEnd(); 177*cdf0e10cSrcweir if ( nStartCol<=static_cast<SCCOL>(nEnd) && nEndCol>=static_cast<SCCOL>(nStart) ) 178*cdf0e10cSrcweir bColFound = sal_True; 179*cdf0e10cSrcweir } 180*cdf0e10cSrcweir } 181*cdf0e10cSrcweir 182*cdf0e10cSrcweir // Zeilen 183*cdf0e10cSrcweir 184*cdf0e10cSrcweir if ( !bColMarked || bRowMarked ) // nicht wenn ganze Spalten markiert 185*cdf0e10cSrcweir { 186*cdf0e10cSrcweir pArray = pTable->GetRowArray(); 187*cdf0e10cSrcweir ScSubOutlineIterator aRowIter( pArray ); 188*cdf0e10cSrcweir while ((pEntry=aRowIter.GetNext()) != NULL && !bRowFound) 189*cdf0e10cSrcweir { 190*cdf0e10cSrcweir nStart = pEntry->GetStart(); 191*cdf0e10cSrcweir nEnd = pEntry->GetEnd(); 192*cdf0e10cSrcweir if ( nStartRow<=nEnd && nEndRow>=nStart ) 193*cdf0e10cSrcweir bRowFound = sal_True; 194*cdf0e10cSrcweir } 195*cdf0e10cSrcweir } 196*cdf0e10cSrcweir } 197*cdf0e10cSrcweir } 198*cdf0e10cSrcweir 199*cdf0e10cSrcweir rCol = bColFound; 200*cdf0e10cSrcweir rRow = bRowFound; 201*cdf0e10cSrcweir } 202*cdf0e10cSrcweir 203*cdf0e10cSrcweir void ScDBFunc::RemoveAllOutlines( sal_Bool bRecord ) 204*cdf0e10cSrcweir { 205*cdf0e10cSrcweir SCTAB nTab = GetViewData()->GetTabNo(); 206*cdf0e10cSrcweir ScDocShell* pDocSh = GetViewData()->GetDocShell(); 207*cdf0e10cSrcweir ScOutlineDocFunc aFunc(*pDocSh); 208*cdf0e10cSrcweir 209*cdf0e10cSrcweir HideCursor(); 210*cdf0e10cSrcweir sal_Bool bOk = aFunc.RemoveAllOutlines( nTab, bRecord, sal_False ); 211*cdf0e10cSrcweir ShowCursor(); 212*cdf0e10cSrcweir 213*cdf0e10cSrcweir if (bOk) 214*cdf0e10cSrcweir UpdateScrollBars(); 215*cdf0e10cSrcweir } 216*cdf0e10cSrcweir 217*cdf0e10cSrcweir // Auto-Outlines 218*cdf0e10cSrcweir 219*cdf0e10cSrcweir void ScDBFunc::AutoOutline( sal_Bool bRecord ) 220*cdf0e10cSrcweir { 221*cdf0e10cSrcweir SCTAB nTab = GetViewData()->GetTabNo(); 222*cdf0e10cSrcweir ScRange aRange( 0,0,nTab, MAXCOL,MAXROW,nTab ); // ganze Tabelle, wenn nichts markiert 223*cdf0e10cSrcweir ScMarkData& rMark = GetViewData()->GetMarkData(); 224*cdf0e10cSrcweir if ( rMark.IsMarked() || rMark.IsMultiMarked() ) 225*cdf0e10cSrcweir { 226*cdf0e10cSrcweir rMark.MarkToMulti(); 227*cdf0e10cSrcweir rMark.GetMultiMarkArea( aRange ); 228*cdf0e10cSrcweir } 229*cdf0e10cSrcweir 230*cdf0e10cSrcweir ScDocShell* pDocSh = GetViewData()->GetDocShell(); 231*cdf0e10cSrcweir ScOutlineDocFunc aFunc(*pDocSh); 232*cdf0e10cSrcweir aFunc.AutoOutline( aRange, bRecord, sal_False ); 233*cdf0e10cSrcweir } 234*cdf0e10cSrcweir 235*cdf0e10cSrcweir // Outline-Ebene auswaehlen 236*cdf0e10cSrcweir 237*cdf0e10cSrcweir void ScDBFunc::SelectLevel( sal_Bool bColumns, sal_uInt16 nLevel, sal_Bool bRecord, sal_Bool bPaint ) 238*cdf0e10cSrcweir { 239*cdf0e10cSrcweir SCTAB nTab = GetViewData()->GetTabNo(); 240*cdf0e10cSrcweir ScDocShell* pDocSh = GetViewData()->GetDocShell(); 241*cdf0e10cSrcweir ScOutlineDocFunc aFunc(*pDocSh); 242*cdf0e10cSrcweir 243*cdf0e10cSrcweir HideCursor(); 244*cdf0e10cSrcweir sal_Bool bOk = aFunc.SelectLevel( nTab, bColumns, nLevel, bRecord, bPaint, sal_False ); 245*cdf0e10cSrcweir ShowCursor(); 246*cdf0e10cSrcweir 247*cdf0e10cSrcweir if (bOk) 248*cdf0e10cSrcweir UpdateScrollBars(); 249*cdf0e10cSrcweir } 250*cdf0e10cSrcweir 251*cdf0e10cSrcweir // einzelne Outline-Gruppe einblenden 252*cdf0e10cSrcweir 253*cdf0e10cSrcweir void ScDBFunc::ShowOutline( sal_Bool bColumns, sal_uInt16 nLevel, sal_uInt16 nEntry, sal_Bool bRecord, sal_Bool bPaint ) 254*cdf0e10cSrcweir { 255*cdf0e10cSrcweir SCTAB nTab = GetViewData()->GetTabNo(); 256*cdf0e10cSrcweir ScDocShell* pDocSh = GetViewData()->GetDocShell(); 257*cdf0e10cSrcweir ScOutlineDocFunc aFunc(*pDocSh); 258*cdf0e10cSrcweir 259*cdf0e10cSrcweir HideCursor(); 260*cdf0e10cSrcweir sal_Bool bOk = aFunc.ShowOutline( nTab, bColumns, nLevel, nEntry, bRecord, bPaint, sal_False ); 261*cdf0e10cSrcweir ShowCursor(); 262*cdf0e10cSrcweir 263*cdf0e10cSrcweir if ( bOk && bPaint ) 264*cdf0e10cSrcweir UpdateScrollBars(); 265*cdf0e10cSrcweir } 266*cdf0e10cSrcweir 267*cdf0e10cSrcweir // einzelne Outline-Gruppe ausblenden 268*cdf0e10cSrcweir 269*cdf0e10cSrcweir void ScDBFunc::HideOutline( sal_Bool bColumns, sal_uInt16 nLevel, sal_uInt16 nEntry, sal_Bool bRecord, sal_Bool bPaint ) 270*cdf0e10cSrcweir { 271*cdf0e10cSrcweir SCTAB nTab = GetViewData()->GetTabNo(); 272*cdf0e10cSrcweir ScDocShell* pDocSh = GetViewData()->GetDocShell(); 273*cdf0e10cSrcweir ScOutlineDocFunc aFunc(*pDocSh); 274*cdf0e10cSrcweir 275*cdf0e10cSrcweir HideCursor(); 276*cdf0e10cSrcweir sal_Bool bOk = aFunc.HideOutline( nTab, bColumns, nLevel, nEntry, bRecord, bPaint, sal_False ); 277*cdf0e10cSrcweir ShowCursor(); 278*cdf0e10cSrcweir 279*cdf0e10cSrcweir if ( bOk && bPaint ) 280*cdf0e10cSrcweir UpdateScrollBars(); 281*cdf0e10cSrcweir } 282*cdf0e10cSrcweir 283*cdf0e10cSrcweir // Menue-Status: markierten Bereich ein-/ausblenden 284*cdf0e10cSrcweir 285*cdf0e10cSrcweir sal_Bool ScDBFunc::OutlinePossible(sal_Bool bHide) 286*cdf0e10cSrcweir { 287*cdf0e10cSrcweir sal_Bool bEnable = sal_False; 288*cdf0e10cSrcweir 289*cdf0e10cSrcweir SCCOL nStartCol; 290*cdf0e10cSrcweir SCROW nStartRow; 291*cdf0e10cSrcweir SCTAB nStartTab; 292*cdf0e10cSrcweir SCCOL nEndCol; 293*cdf0e10cSrcweir SCROW nEndRow; 294*cdf0e10cSrcweir SCTAB nEndTab; 295*cdf0e10cSrcweir 296*cdf0e10cSrcweir if (GetViewData()->GetSimpleArea(nStartCol,nStartRow,nStartTab,nEndCol,nEndRow,nEndTab) == SC_MARK_SIMPLE) 297*cdf0e10cSrcweir { 298*cdf0e10cSrcweir ScDocument* pDoc = GetViewData()->GetDocument(); 299*cdf0e10cSrcweir SCTAB nTab = GetViewData()->GetTabNo(); 300*cdf0e10cSrcweir ScOutlineTable* pTable = pDoc->GetOutlineTable( nTab ); 301*cdf0e10cSrcweir if (pTable) 302*cdf0e10cSrcweir { 303*cdf0e10cSrcweir ScOutlineArray* pArray; 304*cdf0e10cSrcweir ScOutlineEntry* pEntry; 305*cdf0e10cSrcweir SCCOLROW nStart; 306*cdf0e10cSrcweir SCCOLROW nEnd; 307*cdf0e10cSrcweir 308*cdf0e10cSrcweir // Spalten 309*cdf0e10cSrcweir 310*cdf0e10cSrcweir pArray = pTable->GetColArray(); 311*cdf0e10cSrcweir ScSubOutlineIterator aColIter( pArray ); 312*cdf0e10cSrcweir while ((pEntry=aColIter.GetNext()) != NULL && !bEnable) 313*cdf0e10cSrcweir { 314*cdf0e10cSrcweir nStart = pEntry->GetStart(); 315*cdf0e10cSrcweir nEnd = pEntry->GetEnd(); 316*cdf0e10cSrcweir if ( bHide ) 317*cdf0e10cSrcweir { 318*cdf0e10cSrcweir if ( nStartCol<=static_cast<SCCOL>(nEnd) && nEndCol>=static_cast<SCCOL>(nStart) ) 319*cdf0e10cSrcweir if (!pEntry->IsHidden()) 320*cdf0e10cSrcweir bEnable = sal_True; 321*cdf0e10cSrcweir } 322*cdf0e10cSrcweir else 323*cdf0e10cSrcweir { 324*cdf0e10cSrcweir if ( nStart>=nStartCol && nEnd<=nEndCol ) 325*cdf0e10cSrcweir if (pEntry->IsHidden()) 326*cdf0e10cSrcweir bEnable = sal_True; 327*cdf0e10cSrcweir } 328*cdf0e10cSrcweir } 329*cdf0e10cSrcweir 330*cdf0e10cSrcweir // Zeilen 331*cdf0e10cSrcweir 332*cdf0e10cSrcweir pArray = pTable->GetRowArray(); 333*cdf0e10cSrcweir ScSubOutlineIterator aRowIter( pArray ); 334*cdf0e10cSrcweir while ((pEntry=aRowIter.GetNext()) != NULL) 335*cdf0e10cSrcweir { 336*cdf0e10cSrcweir nStart = pEntry->GetStart(); 337*cdf0e10cSrcweir nEnd = pEntry->GetEnd(); 338*cdf0e10cSrcweir if ( bHide ) 339*cdf0e10cSrcweir { 340*cdf0e10cSrcweir if ( nStartRow<=nEnd && nEndRow>=nStart ) 341*cdf0e10cSrcweir if (!pEntry->IsHidden()) 342*cdf0e10cSrcweir bEnable = sal_True; 343*cdf0e10cSrcweir } 344*cdf0e10cSrcweir else 345*cdf0e10cSrcweir { 346*cdf0e10cSrcweir if ( nStart>=nStartRow && nEnd<=nEndRow ) 347*cdf0e10cSrcweir if (pEntry->IsHidden()) 348*cdf0e10cSrcweir bEnable = sal_True; 349*cdf0e10cSrcweir } 350*cdf0e10cSrcweir } 351*cdf0e10cSrcweir } 352*cdf0e10cSrcweir } 353*cdf0e10cSrcweir 354*cdf0e10cSrcweir return bEnable; 355*cdf0e10cSrcweir } 356*cdf0e10cSrcweir 357*cdf0e10cSrcweir // markierten Bereich einblenden 358*cdf0e10cSrcweir 359*cdf0e10cSrcweir void ScDBFunc::ShowMarkedOutlines( sal_Bool bRecord ) 360*cdf0e10cSrcweir { 361*cdf0e10cSrcweir ScRange aRange; 362*cdf0e10cSrcweir if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE) 363*cdf0e10cSrcweir { 364*cdf0e10cSrcweir ScDocShell* pDocSh = GetViewData()->GetDocShell(); 365*cdf0e10cSrcweir ScOutlineDocFunc aFunc(*pDocSh); 366*cdf0e10cSrcweir HideCursor(); 367*cdf0e10cSrcweir sal_Bool bDone = aFunc.ShowMarkedOutlines( aRange, bRecord, sal_False ); 368*cdf0e10cSrcweir ShowCursor(); 369*cdf0e10cSrcweir if (bDone) 370*cdf0e10cSrcweir UpdateScrollBars(); 371*cdf0e10cSrcweir } 372*cdf0e10cSrcweir else 373*cdf0e10cSrcweir ErrorMessage(STR_NOMULTISELECT); 374*cdf0e10cSrcweir } 375*cdf0e10cSrcweir 376*cdf0e10cSrcweir // markierten Bereich ausblenden 377*cdf0e10cSrcweir 378*cdf0e10cSrcweir void ScDBFunc::HideMarkedOutlines( sal_Bool bRecord ) 379*cdf0e10cSrcweir { 380*cdf0e10cSrcweir ScRange aRange; 381*cdf0e10cSrcweir if (GetViewData()->GetSimpleArea(aRange) == SC_MARK_SIMPLE) 382*cdf0e10cSrcweir { 383*cdf0e10cSrcweir ScDocShell* pDocSh = GetViewData()->GetDocShell(); 384*cdf0e10cSrcweir ScOutlineDocFunc aFunc(*pDocSh); 385*cdf0e10cSrcweir HideCursor(); 386*cdf0e10cSrcweir sal_Bool bDone = aFunc.HideMarkedOutlines( aRange, bRecord, sal_False ); 387*cdf0e10cSrcweir ShowCursor(); 388*cdf0e10cSrcweir if (bDone) 389*cdf0e10cSrcweir UpdateScrollBars(); 390*cdf0e10cSrcweir } 391*cdf0e10cSrcweir else 392*cdf0e10cSrcweir ErrorMessage(STR_NOMULTISELECT); 393*cdf0e10cSrcweir } 394*cdf0e10cSrcweir 395*cdf0e10cSrcweir // -------------------------------------------------------------------------- 396*cdf0e10cSrcweir 397*cdf0e10cSrcweir // 398*cdf0e10cSrcweir // Teilergebnisse 399*cdf0e10cSrcweir // 400*cdf0e10cSrcweir 401*cdf0e10cSrcweir void ScDBFunc::DoSubTotals( const ScSubTotalParam& rParam, sal_Bool bRecord, 402*cdf0e10cSrcweir const ScSortParam* pForceNewSort ) 403*cdf0e10cSrcweir { 404*cdf0e10cSrcweir sal_Bool bDo = !rParam.bRemoveOnly; // sal_False = nur loeschen 405*cdf0e10cSrcweir 406*cdf0e10cSrcweir ScDocShell* pDocSh = GetViewData()->GetDocShell(); 407*cdf0e10cSrcweir ScDocument* pDoc = pDocSh->GetDocument(); 408*cdf0e10cSrcweir ScMarkData& rMark = GetViewData()->GetMarkData(); 409*cdf0e10cSrcweir SCTAB nTab = GetViewData()->GetTabNo(); 410*cdf0e10cSrcweir if (bRecord && !pDoc->IsUndoEnabled()) 411*cdf0e10cSrcweir bRecord = sal_False; 412*cdf0e10cSrcweir 413*cdf0e10cSrcweir ScDBData* pDBData = pDoc->GetDBAtArea( nTab, rParam.nCol1, rParam.nRow1, 414*cdf0e10cSrcweir rParam.nCol2, rParam.nRow2 ); 415*cdf0e10cSrcweir if (!pDBData) 416*cdf0e10cSrcweir { 417*cdf0e10cSrcweir DBG_ERROR( "SubTotals: keine DBData" ); 418*cdf0e10cSrcweir return; 419*cdf0e10cSrcweir } 420*cdf0e10cSrcweir 421*cdf0e10cSrcweir ScEditableTester aTester( pDoc, nTab, 0,rParam.nRow1+1, MAXCOL,MAXROW ); 422*cdf0e10cSrcweir if (!aTester.IsEditable()) 423*cdf0e10cSrcweir { 424*cdf0e10cSrcweir ErrorMessage(aTester.GetMessageId()); 425*cdf0e10cSrcweir return; 426*cdf0e10cSrcweir } 427*cdf0e10cSrcweir 428*cdf0e10cSrcweir if (pDoc->HasAttrib( rParam.nCol1, rParam.nRow1+1, nTab, 429*cdf0e10cSrcweir rParam.nCol2, rParam.nRow2, nTab, HASATTR_MERGED | HASATTR_OVERLAPPED )) 430*cdf0e10cSrcweir { 431*cdf0e10cSrcweir ErrorMessage(STR_MSSG_INSERTCELLS_0); // nicht in zusammengefasste einfuegen 432*cdf0e10cSrcweir return; 433*cdf0e10cSrcweir } 434*cdf0e10cSrcweir 435*cdf0e10cSrcweir WaitObject aWait( GetViewData()->GetDialogParent() ); 436*cdf0e10cSrcweir sal_Bool bOk = sal_True; 437*cdf0e10cSrcweir sal_Bool bDelete = sal_False; 438*cdf0e10cSrcweir if (rParam.bReplace) 439*cdf0e10cSrcweir if (pDoc->TestRemoveSubTotals( nTab, rParam )) 440*cdf0e10cSrcweir { 441*cdf0e10cSrcweir bDelete = sal_True; 442*cdf0e10cSrcweir bOk = ( MessBox( GetViewData()->GetDialogParent(), WinBits(WB_YES_NO | WB_DEF_YES), 443*cdf0e10cSrcweir // "StarCalc" "Daten loeschen?" 444*cdf0e10cSrcweir ScGlobal::GetRscString( STR_MSSG_DOSUBTOTALS_0 ), 445*cdf0e10cSrcweir ScGlobal::GetRscString( STR_MSSG_DOSUBTOTALS_1 ) ).Execute() 446*cdf0e10cSrcweir == RET_YES ); 447*cdf0e10cSrcweir } 448*cdf0e10cSrcweir 449*cdf0e10cSrcweir if (bOk) 450*cdf0e10cSrcweir { 451*cdf0e10cSrcweir ScDocShellModificator aModificator( *pDocSh ); 452*cdf0e10cSrcweir 453*cdf0e10cSrcweir ScSubTotalParam aNewParam( rParam ); // Bereichsende wird veraendert 454*cdf0e10cSrcweir ScDocument* pUndoDoc = NULL; 455*cdf0e10cSrcweir ScOutlineTable* pUndoTab = NULL; 456*cdf0e10cSrcweir ScRangeName* pUndoRange = NULL; 457*cdf0e10cSrcweir ScDBCollection* pUndoDB = NULL; 458*cdf0e10cSrcweir SCTAB nTabCount = 0; // fuer Referenz-Undo 459*cdf0e10cSrcweir 460*cdf0e10cSrcweir if (bRecord) // alte Daten sichern 461*cdf0e10cSrcweir { 462*cdf0e10cSrcweir sal_Bool bOldFilter = bDo && rParam.bDoSort; 463*cdf0e10cSrcweir 464*cdf0e10cSrcweir nTabCount = pDoc->GetTableCount(); 465*cdf0e10cSrcweir pUndoDoc = new ScDocument( SCDOCMODE_UNDO ); 466*cdf0e10cSrcweir ScOutlineTable* pTable = pDoc->GetOutlineTable( nTab ); 467*cdf0e10cSrcweir if (pTable) 468*cdf0e10cSrcweir { 469*cdf0e10cSrcweir pUndoTab = new ScOutlineTable( *pTable ); 470*cdf0e10cSrcweir 471*cdf0e10cSrcweir SCCOLROW nOutStartCol; // Zeilen/Spaltenstatus 472*cdf0e10cSrcweir SCCOLROW nOutStartRow; 473*cdf0e10cSrcweir SCCOLROW nOutEndCol; 474*cdf0e10cSrcweir SCCOLROW nOutEndRow; 475*cdf0e10cSrcweir pTable->GetColArray()->GetRange( nOutStartCol, nOutEndCol ); 476*cdf0e10cSrcweir pTable->GetRowArray()->GetRange( nOutStartRow, nOutEndRow ); 477*cdf0e10cSrcweir 478*cdf0e10cSrcweir pUndoDoc->InitUndo( pDoc, nTab, nTab, sal_True, sal_True ); 479*cdf0e10cSrcweir pDoc->CopyToDocument( static_cast<SCCOL>(nOutStartCol), 0, nTab, static_cast<SCCOL>(nOutEndCol), MAXROW, nTab, IDF_NONE, sal_False, pUndoDoc ); 480*cdf0e10cSrcweir pDoc->CopyToDocument( 0, nOutStartRow, nTab, MAXCOL, nOutEndRow, nTab, IDF_NONE, sal_False, pUndoDoc ); 481*cdf0e10cSrcweir } 482*cdf0e10cSrcweir else 483*cdf0e10cSrcweir pUndoDoc->InitUndo( pDoc, nTab, nTab, sal_False, bOldFilter ); 484*cdf0e10cSrcweir 485*cdf0e10cSrcweir // Datenbereich sichern - incl. Filter-Ergebnis 486*cdf0e10cSrcweir pDoc->CopyToDocument( 0,rParam.nRow1+1,nTab, MAXCOL,rParam.nRow2,nTab, 487*cdf0e10cSrcweir IDF_ALL, sal_False, pUndoDoc ); 488*cdf0e10cSrcweir 489*cdf0e10cSrcweir // alle Formeln wegen Referenzen 490*cdf0e10cSrcweir pDoc->CopyToDocument( 0,0,0, MAXCOL,MAXROW,nTabCount-1, 491*cdf0e10cSrcweir IDF_FORMULA, sal_False, pUndoDoc ); 492*cdf0e10cSrcweir 493*cdf0e10cSrcweir // DB- und andere Bereiche 494*cdf0e10cSrcweir ScRangeName* pDocRange = pDoc->GetRangeName(); 495*cdf0e10cSrcweir if (pDocRange->GetCount()) 496*cdf0e10cSrcweir pUndoRange = new ScRangeName( *pDocRange ); 497*cdf0e10cSrcweir ScDBCollection* pDocDB = pDoc->GetDBCollection(); 498*cdf0e10cSrcweir if (pDocDB->GetCount()) 499*cdf0e10cSrcweir pUndoDB = new ScDBCollection( *pDocDB ); 500*cdf0e10cSrcweir } 501*cdf0e10cSrcweir 502*cdf0e10cSrcweir // pDoc->SetOutlineTable( nTab, NULL ); 503*cdf0e10cSrcweir ScOutlineTable* pOut = pDoc->GetOutlineTable( nTab ); 504*cdf0e10cSrcweir if (pOut) 505*cdf0e10cSrcweir pOut->GetRowArray()->RemoveAll(); // nur Zeilen-Outlines loeschen 506*cdf0e10cSrcweir 507*cdf0e10cSrcweir if (rParam.bReplace) 508*cdf0e10cSrcweir pDoc->RemoveSubTotals( nTab, aNewParam ); 509*cdf0e10cSrcweir sal_Bool bSuccess = sal_True; 510*cdf0e10cSrcweir if (bDo) 511*cdf0e10cSrcweir { 512*cdf0e10cSrcweir // Sortieren 513*cdf0e10cSrcweir if ( rParam.bDoSort || pForceNewSort ) 514*cdf0e10cSrcweir { 515*cdf0e10cSrcweir pDBData->SetArea( nTab, aNewParam.nCol1,aNewParam.nRow1, aNewParam.nCol2,aNewParam.nRow2 ); 516*cdf0e10cSrcweir 517*cdf0e10cSrcweir // Teilergebnis-Felder vor die Sortierung setzen 518*cdf0e10cSrcweir // (doppelte werden weggelassen, kann darum auch wieder aufgerufen werden) 519*cdf0e10cSrcweir 520*cdf0e10cSrcweir ScSortParam aOldSort; 521*cdf0e10cSrcweir pDBData->GetSortParam( aOldSort ); 522*cdf0e10cSrcweir ScSortParam aSortParam( aNewParam, pForceNewSort ? *pForceNewSort : aOldSort ); 523*cdf0e10cSrcweir Sort( aSortParam, sal_False, sal_False ); 524*cdf0e10cSrcweir } 525*cdf0e10cSrcweir 526*cdf0e10cSrcweir bSuccess = pDoc->DoSubTotals( nTab, aNewParam ); 527*cdf0e10cSrcweir } 528*cdf0e10cSrcweir ScRange aDirtyRange( aNewParam.nCol1, aNewParam.nRow1, nTab, 529*cdf0e10cSrcweir aNewParam.nCol2, aNewParam.nRow2, nTab ); 530*cdf0e10cSrcweir pDoc->SetDirty( aDirtyRange ); 531*cdf0e10cSrcweir 532*cdf0e10cSrcweir if (bRecord) 533*cdf0e10cSrcweir { 534*cdf0e10cSrcweir // ScDBData* pUndoDBData = pDBData ? new ScDBData( *pDBData ) : NULL; 535*cdf0e10cSrcweir pDocSh->GetUndoManager()->AddUndoAction( 536*cdf0e10cSrcweir new ScUndoSubTotals( pDocSh, nTab, 537*cdf0e10cSrcweir rParam, aNewParam.nRow2, 538*cdf0e10cSrcweir pUndoDoc, pUndoTab, // pUndoDBData, 539*cdf0e10cSrcweir pUndoRange, pUndoDB ) ); 540*cdf0e10cSrcweir } 541*cdf0e10cSrcweir 542*cdf0e10cSrcweir if (!bSuccess) 543*cdf0e10cSrcweir { 544*cdf0e10cSrcweir // "Kann keine Zeilen einfuegen" 545*cdf0e10cSrcweir ErrorMessage(STR_MSSG_DOSUBTOTALS_2); 546*cdf0e10cSrcweir } 547*cdf0e10cSrcweir 548*cdf0e10cSrcweir // merken 549*cdf0e10cSrcweir pDBData->SetSubTotalParam( aNewParam ); 550*cdf0e10cSrcweir pDBData->SetArea( nTab, aNewParam.nCol1,aNewParam.nRow1, aNewParam.nCol2,aNewParam.nRow2 ); 551*cdf0e10cSrcweir pDoc->CompileDBFormula(); 552*cdf0e10cSrcweir 553*cdf0e10cSrcweir DoneBlockMode(); 554*cdf0e10cSrcweir InitOwnBlockMode(); 555*cdf0e10cSrcweir rMark.SetMarkArea( ScRange( aNewParam.nCol1,aNewParam.nRow1,nTab, 556*cdf0e10cSrcweir aNewParam.nCol2,aNewParam.nRow2,nTab ) ); 557*cdf0e10cSrcweir MarkDataChanged(); 558*cdf0e10cSrcweir 559*cdf0e10cSrcweir pDocSh->PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, 560*cdf0e10cSrcweir PAINT_GRID | PAINT_LEFT | PAINT_TOP | PAINT_SIZE ); 561*cdf0e10cSrcweir 562*cdf0e10cSrcweir aModificator.SetDocumentModified(); 563*cdf0e10cSrcweir 564*cdf0e10cSrcweir SelectionChanged(); 565*cdf0e10cSrcweir } 566*cdf0e10cSrcweir } 567*cdf0e10cSrcweir 568*cdf0e10cSrcweir // 569*cdf0e10cSrcweir // Consolidate 570*cdf0e10cSrcweir // 571*cdf0e10cSrcweir 572*cdf0e10cSrcweir void ScDBFunc::Consolidate( const ScConsolidateParam& rParam, sal_Bool bRecord ) 573*cdf0e10cSrcweir { 574*cdf0e10cSrcweir ScDocShell* pDocShell = GetViewData()->GetDocShell(); 575*cdf0e10cSrcweir pDocShell->DoConsolidate( rParam, bRecord ); 576*cdf0e10cSrcweir SetTabNo( rParam.nTab, sal_True ); 577*cdf0e10cSrcweir } 578*cdf0e10cSrcweir 579*cdf0e10cSrcweir // 580*cdf0e10cSrcweir // Pivot 581*cdf0e10cSrcweir // 582*cdf0e10cSrcweir 583*cdf0e10cSrcweir String lcl_MakePivotTabName( const String& rPrefix, SCTAB nNumber ) 584*cdf0e10cSrcweir { 585*cdf0e10cSrcweir String aName = rPrefix; 586*cdf0e10cSrcweir aName += String::CreateFromInt32( nNumber ); 587*cdf0e10cSrcweir return aName; 588*cdf0e10cSrcweir } 589*cdf0e10cSrcweir 590*cdf0e10cSrcweir bool ScDBFunc::MakePivotTable( const ScDPSaveData& rData, const ScRange& rDest, sal_Bool bNewTable, 591*cdf0e10cSrcweir const ScDPObject& rSource, sal_Bool bApi ) 592*cdf0e10cSrcweir { 593*cdf0e10cSrcweir // #70096# error message if no fields are set 594*cdf0e10cSrcweir // this must be removed when drag&drop of fields from a toolbox is available 595*cdf0e10cSrcweir 596*cdf0e10cSrcweir if ( rData.IsEmpty() && !bApi ) 597*cdf0e10cSrcweir { 598*cdf0e10cSrcweir ErrorMessage(STR_PIVOT_NODATA); 599*cdf0e10cSrcweir return false; 600*cdf0e10cSrcweir } 601*cdf0e10cSrcweir 602*cdf0e10cSrcweir ScDocShell* pDocSh = GetViewData()->GetDocShell(); 603*cdf0e10cSrcweir ScDocument* pDoc = GetViewData()->GetDocument(); 604*cdf0e10cSrcweir sal_Bool bUndo(pDoc->IsUndoEnabled()); 605*cdf0e10cSrcweir 606*cdf0e10cSrcweir ScRange aDestRange = rDest; 607*cdf0e10cSrcweir if ( bNewTable ) 608*cdf0e10cSrcweir { 609*cdf0e10cSrcweir SCTAB nSrcTab = GetViewData()->GetTabNo(); 610*cdf0e10cSrcweir 611*cdf0e10cSrcweir String aName( ScGlobal::GetRscString(STR_PIVOT_TABLE) ); 612*cdf0e10cSrcweir String aStr; 613*cdf0e10cSrcweir 614*cdf0e10cSrcweir pDoc->GetName( nSrcTab, aStr ); 615*cdf0e10cSrcweir aName += '_'; 616*cdf0e10cSrcweir aName += aStr; 617*cdf0e10cSrcweir aName += '_'; 618*cdf0e10cSrcweir 619*cdf0e10cSrcweir SCTAB nNewTab = nSrcTab+1; 620*cdf0e10cSrcweir 621*cdf0e10cSrcweir SCTAB i=1; 622*cdf0e10cSrcweir while ( !pDoc->InsertTab( nNewTab, lcl_MakePivotTabName( aName, i ) ) && i <= MAXTAB ) 623*cdf0e10cSrcweir i++; 624*cdf0e10cSrcweir 625*cdf0e10cSrcweir sal_Bool bAppend = ( nNewTab+1 == pDoc->GetTableCount() ); 626*cdf0e10cSrcweir if (bUndo) 627*cdf0e10cSrcweir { 628*cdf0e10cSrcweir pDocSh->GetUndoManager()->AddUndoAction( 629*cdf0e10cSrcweir new ScUndoInsertTab( pDocSh, nNewTab, bAppend, lcl_MakePivotTabName( aName, i ) )); 630*cdf0e10cSrcweir } 631*cdf0e10cSrcweir 632*cdf0e10cSrcweir GetViewData()->InsertTab( nNewTab ); 633*cdf0e10cSrcweir SetTabNo( nNewTab, sal_True ); 634*cdf0e10cSrcweir 635*cdf0e10cSrcweir aDestRange = ScRange( 0, 0, nNewTab ); 636*cdf0e10cSrcweir } 637*cdf0e10cSrcweir 638*cdf0e10cSrcweir ScDPObject* pDPObj = pDoc->GetDPAtCursor( 639*cdf0e10cSrcweir aDestRange.aStart.Col(), aDestRange.aStart.Row(), aDestRange.aStart.Tab() ); 640*cdf0e10cSrcweir 641*cdf0e10cSrcweir ScDPObject aObj( rSource ); 642*cdf0e10cSrcweir aObj.SetOutRange( aDestRange ); 643*cdf0e10cSrcweir if ( pDPObj && !rData.GetExistingDimensionData() ) 644*cdf0e10cSrcweir { 645*cdf0e10cSrcweir // copy dimension data from old object - lost in the dialog 646*cdf0e10cSrcweir //! change the dialog to keep the dimension data 647*cdf0e10cSrcweir 648*cdf0e10cSrcweir ScDPSaveData aNewData( rData ); 649*cdf0e10cSrcweir const ScDPSaveData* pOldData = pDPObj->GetSaveData(); 650*cdf0e10cSrcweir if ( pOldData ) 651*cdf0e10cSrcweir { 652*cdf0e10cSrcweir const ScDPDimensionSaveData* pDimSave = pOldData->GetExistingDimensionData(); 653*cdf0e10cSrcweir aNewData.SetDimensionData( pDimSave ); 654*cdf0e10cSrcweir } 655*cdf0e10cSrcweir aObj.SetSaveData( aNewData ); 656*cdf0e10cSrcweir } 657*cdf0e10cSrcweir else 658*cdf0e10cSrcweir aObj.SetSaveData( rData ); 659*cdf0e10cSrcweir 660*cdf0e10cSrcweir sal_Bool bAllowMove = ( pDPObj != NULL ); // allow re-positioning when editing existing table 661*cdf0e10cSrcweir 662*cdf0e10cSrcweir ScDBDocFunc aFunc( *pDocSh ); 663*cdf0e10cSrcweir bool bSuccess = aFunc.DataPilotUpdate( pDPObj, &aObj, sal_True, sal_False, bAllowMove ); 664*cdf0e10cSrcweir 665*cdf0e10cSrcweir CursorPosChanged(); // shells may be switched 666*cdf0e10cSrcweir 667*cdf0e10cSrcweir if ( bNewTable ) 668*cdf0e10cSrcweir { 669*cdf0e10cSrcweir pDocSh->PostPaintExtras(); 670*cdf0e10cSrcweir SFX_APP()->Broadcast( SfxSimpleHint( SC_HINT_TABLES_CHANGED ) ); 671*cdf0e10cSrcweir } 672*cdf0e10cSrcweir 673*cdf0e10cSrcweir return bSuccess; 674*cdf0e10cSrcweir } 675*cdf0e10cSrcweir 676*cdf0e10cSrcweir void ScDBFunc::DeletePivotTable() 677*cdf0e10cSrcweir { 678*cdf0e10cSrcweir ScDocShell* pDocSh = GetViewData()->GetDocShell(); 679*cdf0e10cSrcweir ScDocument* pDoc = pDocSh->GetDocument(); 680*cdf0e10cSrcweir ScDPObject* pDPObj = pDoc->GetDPAtCursor( GetViewData()->GetCurX(), 681*cdf0e10cSrcweir GetViewData()->GetCurY(), 682*cdf0e10cSrcweir GetViewData()->GetTabNo() ); 683*cdf0e10cSrcweir if ( pDPObj ) 684*cdf0e10cSrcweir { 685*cdf0e10cSrcweir ScDBDocFunc aFunc( *pDocSh ); 686*cdf0e10cSrcweir aFunc.DataPilotUpdate( pDPObj, NULL, sal_True, sal_False ); 687*cdf0e10cSrcweir CursorPosChanged(); // shells may be switched 688*cdf0e10cSrcweir } 689*cdf0e10cSrcweir else 690*cdf0e10cSrcweir ErrorMessage(STR_PIVOT_NOTFOUND); 691*cdf0e10cSrcweir } 692*cdf0e10cSrcweir sal_uLong RefreshDPObject( ScDPObject *pDPObj, ScDocument *pDoc, ScDocShell *pDocSh, sal_Bool bRecord, sal_Bool bApi ) 693*cdf0e10cSrcweir { 694*cdf0e10cSrcweir if( !pDPObj ) 695*cdf0e10cSrcweir return STR_PIVOT_NOTFOUND; 696*cdf0e10cSrcweir 697*cdf0e10cSrcweir if ( pDocSh && !pDoc ) 698*cdf0e10cSrcweir pDoc = pDocSh->GetDocument(); 699*cdf0e10cSrcweir 700*cdf0e10cSrcweir if( !pDoc ) 701*cdf0e10cSrcweir return static_cast<sal_uLong>(-1); 702*cdf0e10cSrcweir 703*cdf0e10cSrcweir if( !pDocSh && ( pDocSh = PTR_CAST( ScDocShell, pDoc->GetDocumentShell() ) ) == NULL ) 704*cdf0e10cSrcweir return static_cast<sal_uLong>(-1); 705*cdf0e10cSrcweir 706*cdf0e10cSrcweir if( sal_uLong nErrId = pDPObj->RefreshCache() ) 707*cdf0e10cSrcweir return nErrId; 708*cdf0e10cSrcweir else if ( nErrId == 0 ) 709*cdf0e10cSrcweir { 710*cdf0e10cSrcweir //Refresh all dpobjects 711*cdf0e10cSrcweir ScDPCollection* pDPCollection = pDoc->GetDPCollection(); 712*cdf0e10cSrcweir sal_uInt16 nCount = pDPCollection->GetCount(); 713*cdf0e10cSrcweir for (sal_uInt16 i=0; i<nCount; i++) 714*cdf0e10cSrcweir { 715*cdf0e10cSrcweir if ( (*pDPCollection)[i]->GetCacheId() == pDPObj->GetCacheId() ) 716*cdf0e10cSrcweir { 717*cdf0e10cSrcweir ScDBDocFunc aFunc( * pDocSh ); 718*cdf0e10cSrcweir if ( !aFunc.DataPilotUpdate( (*pDPCollection)[i], (*pDPCollection)[i], bRecord, bApi ) ) 719*cdf0e10cSrcweir break; 720*cdf0e10cSrcweir } 721*cdf0e10cSrcweir } 722*cdf0e10cSrcweir 723*cdf0e10cSrcweir return nErrId; 724*cdf0e10cSrcweir } 725*cdf0e10cSrcweir 726*cdf0e10cSrcweir return 0U; 727*cdf0e10cSrcweir } 728*cdf0e10cSrcweir 729*cdf0e10cSrcweir sal_uLong ScDBFunc::RecalcPivotTable() 730*cdf0e10cSrcweir { 731*cdf0e10cSrcweir ScDocShell* pDocSh = GetViewData()->GetDocShell(); 732*cdf0e10cSrcweir ScDocument* pDoc = GetViewData()->GetDocument(); 733*cdf0e10cSrcweir 734*cdf0e10cSrcweir // old pivot not used any more 735*cdf0e10cSrcweir 736*cdf0e10cSrcweir ScDPObject* pDPObj = pDoc->GetDPAtCursor( GetViewData()->GetCurX(), 737*cdf0e10cSrcweir GetViewData()->GetCurY(), 738*cdf0e10cSrcweir GetViewData()->GetTabNo() ); 739*cdf0e10cSrcweir if ( pDPObj ) 740*cdf0e10cSrcweir { 741*cdf0e10cSrcweir // Wang Xu Ming -- 2009-6-17 742*cdf0e10cSrcweir // DataPilot Migration 743*cdf0e10cSrcweir //ScDBDocFunc aFunc( *pDocSh ); 744*cdf0e10cSrcweir //aFunc.DataPilotUpdate( pDPObj, pDPObj, sal_True, sal_False ); 745*cdf0e10cSrcweir //CursorPosChanged(); // shells may be switched 746*cdf0e10cSrcweir sal_uLong nErrId = RefreshDPObject( pDPObj, pDoc, pDocSh, sal_True, sal_False );//pDPObj->RefreshCache(); 747*cdf0e10cSrcweir if ( nErrId == 0 ) 748*cdf0e10cSrcweir { 749*cdf0e10cSrcweir // There is no undo for the refresh of the cache table, but the undo history for cell changes 750*cdf0e10cSrcweir // remains valid and should be preserved, so the history isn't cleared here. 751*cdf0e10cSrcweir //GetViewData()->GetDocShell()->GetUndoManager()->Clear(); 752*cdf0e10cSrcweir } 753*cdf0e10cSrcweir else if (nErrId <= USHRT_MAX) 754*cdf0e10cSrcweir ErrorMessage(static_cast<sal_uInt16>(nErrId)); 755*cdf0e10cSrcweir return nErrId; 756*cdf0e10cSrcweir // End Comments 757*cdf0e10cSrcweir } 758*cdf0e10cSrcweir else 759*cdf0e10cSrcweir ErrorMessage(STR_PIVOT_NOTFOUND); 760*cdf0e10cSrcweir return STR_PIVOT_NOTFOUND; 761*cdf0e10cSrcweir } 762*cdf0e10cSrcweir 763*cdf0e10cSrcweir void ScDBFunc::GetSelectedMemberList( ScStrCollection& rEntries, long& rDimension ) 764*cdf0e10cSrcweir { 765*cdf0e10cSrcweir ScDPObject* pDPObj = GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(), 766*cdf0e10cSrcweir GetViewData()->GetCurY(), GetViewData()->GetTabNo() ); 767*cdf0e10cSrcweir if ( !pDPObj ) 768*cdf0e10cSrcweir return; 769*cdf0e10cSrcweir 770*cdf0e10cSrcweir long nStartDimension = -1; 771*cdf0e10cSrcweir long nStartHierarchy = -1; 772*cdf0e10cSrcweir long nStartLevel = -1; 773*cdf0e10cSrcweir 774*cdf0e10cSrcweir ScRangeListRef xRanges; 775*cdf0e10cSrcweir GetViewData()->GetMultiArea( xRanges ); // incl. cursor if nothing is selected 776*cdf0e10cSrcweir sal_uLong nRangeCount = xRanges->Count(); 777*cdf0e10cSrcweir sal_Bool bContinue = sal_True; 778*cdf0e10cSrcweir 779*cdf0e10cSrcweir for (sal_uLong nRangePos=0; nRangePos<nRangeCount && bContinue; nRangePos++) 780*cdf0e10cSrcweir { 781*cdf0e10cSrcweir ScRange aRange = *xRanges->GetObject(nRangePos); 782*cdf0e10cSrcweir SCCOL nStartCol = aRange.aStart.Col(); 783*cdf0e10cSrcweir SCROW nStartRow = aRange.aStart.Row(); 784*cdf0e10cSrcweir SCCOL nEndCol = aRange.aEnd.Col(); 785*cdf0e10cSrcweir SCROW nEndRow = aRange.aEnd.Row(); 786*cdf0e10cSrcweir SCTAB nTab = aRange.aStart.Tab(); 787*cdf0e10cSrcweir 788*cdf0e10cSrcweir for (SCROW nRow=nStartRow; nRow<=nEndRow && bContinue; nRow++) 789*cdf0e10cSrcweir for (SCCOL nCol=nStartCol; nCol<=nEndCol && bContinue; nCol++) 790*cdf0e10cSrcweir { 791*cdf0e10cSrcweir sheet::DataPilotTableHeaderData aData; 792*cdf0e10cSrcweir pDPObj->GetHeaderPositionData(ScAddress(nCol, nRow, nTab), aData); 793*cdf0e10cSrcweir if ( aData.Dimension < 0 ) 794*cdf0e10cSrcweir bContinue = sal_False; // not part of any dimension 795*cdf0e10cSrcweir else 796*cdf0e10cSrcweir { 797*cdf0e10cSrcweir if ( nStartDimension < 0 ) // first member? 798*cdf0e10cSrcweir { 799*cdf0e10cSrcweir nStartDimension = aData.Dimension; 800*cdf0e10cSrcweir nStartHierarchy = aData.Hierarchy; 801*cdf0e10cSrcweir nStartLevel = aData.Level; 802*cdf0e10cSrcweir } 803*cdf0e10cSrcweir if ( aData.Dimension != nStartDimension || 804*cdf0e10cSrcweir aData.Hierarchy != nStartHierarchy || 805*cdf0e10cSrcweir aData.Level != nStartLevel ) 806*cdf0e10cSrcweir { 807*cdf0e10cSrcweir bContinue = sal_False; // cannot mix dimensions 808*cdf0e10cSrcweir } 809*cdf0e10cSrcweir } 810*cdf0e10cSrcweir if ( bContinue ) 811*cdf0e10cSrcweir { 812*cdf0e10cSrcweir // accept any part of a member description, also subtotals, 813*cdf0e10cSrcweir // but don't stop if empty parts are contained 814*cdf0e10cSrcweir if ( aData.Flags & sheet::MemberResultFlags::HASMEMBER ) 815*cdf0e10cSrcweir { 816*cdf0e10cSrcweir StrData* pNew = new StrData( aData.MemberName ); 817*cdf0e10cSrcweir if ( !rEntries.Insert( pNew ) ) 818*cdf0e10cSrcweir delete pNew; 819*cdf0e10cSrcweir } 820*cdf0e10cSrcweir } 821*cdf0e10cSrcweir } 822*cdf0e10cSrcweir } 823*cdf0e10cSrcweir 824*cdf0e10cSrcweir rDimension = nStartDimension; // dimension from which the found members came 825*cdf0e10cSrcweir if (!bContinue) 826*cdf0e10cSrcweir rEntries.FreeAll(); // remove all if not valid 827*cdf0e10cSrcweir } 828*cdf0e10cSrcweir 829*cdf0e10cSrcweir sal_Bool ScDBFunc::HasSelectionForDateGroup( ScDPNumGroupInfo& rOldInfo, sal_Int32& rParts ) 830*cdf0e10cSrcweir { 831*cdf0e10cSrcweir // determine if the date group dialog has to be shown for the current selection 832*cdf0e10cSrcweir 833*cdf0e10cSrcweir sal_Bool bFound = sal_False; 834*cdf0e10cSrcweir 835*cdf0e10cSrcweir SCCOL nCurX = GetViewData()->GetCurX(); 836*cdf0e10cSrcweir SCROW nCurY = GetViewData()->GetCurY(); 837*cdf0e10cSrcweir SCTAB nTab = GetViewData()->GetTabNo(); 838*cdf0e10cSrcweir ScDocument* pDoc = GetViewData()->GetDocument(); 839*cdf0e10cSrcweir 840*cdf0e10cSrcweir ScDPObject* pDPObj = pDoc->GetDPAtCursor( nCurX, nCurY, nTab ); 841*cdf0e10cSrcweir if ( pDPObj ) 842*cdf0e10cSrcweir { 843*cdf0e10cSrcweir ScStrCollection aEntries; 844*cdf0e10cSrcweir long nSelectDimension = -1; 845*cdf0e10cSrcweir GetSelectedMemberList( aEntries, nSelectDimension ); 846*cdf0e10cSrcweir 847*cdf0e10cSrcweir if ( aEntries.GetCount() > 0 ) 848*cdf0e10cSrcweir { 849*cdf0e10cSrcweir sal_Bool bIsDataLayout; 850*cdf0e10cSrcweir String aDimName = pDPObj->GetDimName( nSelectDimension, bIsDataLayout ); 851*cdf0e10cSrcweir String aBaseDimName( aDimName ); 852*cdf0e10cSrcweir 853*cdf0e10cSrcweir sal_Bool bInGroupDim = sal_False; 854*cdf0e10cSrcweir sal_Bool bFoundParts = sal_False; 855*cdf0e10cSrcweir 856*cdf0e10cSrcweir ScDPDimensionSaveData* pDimData = 857*cdf0e10cSrcweir const_cast<ScDPDimensionSaveData*>( pDPObj->GetSaveData()->GetExistingDimensionData() ); 858*cdf0e10cSrcweir if ( pDimData ) 859*cdf0e10cSrcweir { 860*cdf0e10cSrcweir const ScDPSaveNumGroupDimension* pNumGroupDim = pDimData->GetNumGroupDim( aDimName ); 861*cdf0e10cSrcweir const ScDPSaveGroupDimension* pGroupDim = pDimData->GetNamedGroupDim( aDimName ); 862*cdf0e10cSrcweir if ( pNumGroupDim ) 863*cdf0e10cSrcweir { 864*cdf0e10cSrcweir // existing num group dimension 865*cdf0e10cSrcweir 866*cdf0e10cSrcweir if ( pNumGroupDim->GetDatePart() != 0 ) 867*cdf0e10cSrcweir { 868*cdf0e10cSrcweir // dimension has date info -> edit settings of this dimension 869*cdf0e10cSrcweir // (parts are collected below) 870*cdf0e10cSrcweir 871*cdf0e10cSrcweir rOldInfo = pNumGroupDim->GetDateInfo(); 872*cdf0e10cSrcweir bFound = sal_True; 873*cdf0e10cSrcweir } 874*cdf0e10cSrcweir else if ( pNumGroupDim->GetInfo().DateValues ) 875*cdf0e10cSrcweir { 876*cdf0e10cSrcweir // Numerical grouping with DateValues flag is used for grouping 877*cdf0e10cSrcweir // of days with a "Number of days" value. 878*cdf0e10cSrcweir 879*cdf0e10cSrcweir rOldInfo = pNumGroupDim->GetInfo(); 880*cdf0e10cSrcweir rParts = com::sun::star::sheet::DataPilotFieldGroupBy::DAYS; // not found in CollectDateParts 881*cdf0e10cSrcweir bFoundParts = sal_True; 882*cdf0e10cSrcweir bFound = sal_True; 883*cdf0e10cSrcweir } 884*cdf0e10cSrcweir bInGroupDim = sal_True; 885*cdf0e10cSrcweir } 886*cdf0e10cSrcweir else if ( pGroupDim ) 887*cdf0e10cSrcweir { 888*cdf0e10cSrcweir // existing additional group dimension 889*cdf0e10cSrcweir 890*cdf0e10cSrcweir if ( pGroupDim->GetDatePart() != 0 ) 891*cdf0e10cSrcweir { 892*cdf0e10cSrcweir // dimension has date info -> edit settings of this dimension 893*cdf0e10cSrcweir // (parts are collected below) 894*cdf0e10cSrcweir 895*cdf0e10cSrcweir rOldInfo = pGroupDim->GetDateInfo(); 896*cdf0e10cSrcweir aBaseDimName = pGroupDim->GetSourceDimName(); 897*cdf0e10cSrcweir bFound = sal_True; 898*cdf0e10cSrcweir } 899*cdf0e10cSrcweir bInGroupDim = sal_True; 900*cdf0e10cSrcweir } 901*cdf0e10cSrcweir } 902*cdf0e10cSrcweir if ( bFound && !bFoundParts ) 903*cdf0e10cSrcweir { 904*cdf0e10cSrcweir // collect date parts from all group dimensions 905*cdf0e10cSrcweir rParts = pDimData->CollectDateParts( aBaseDimName ); 906*cdf0e10cSrcweir } 907*cdf0e10cSrcweir if ( !bFound && !bInGroupDim ) 908*cdf0e10cSrcweir { 909*cdf0e10cSrcweir // create new date group dimensions if the selection is a single cell 910*cdf0e10cSrcweir // in a normal dimension with date content 911*cdf0e10cSrcweir 912*cdf0e10cSrcweir ScRange aSelRange; 913*cdf0e10cSrcweir if ( (GetViewData()->GetSimpleArea( aSelRange ) == SC_MARK_SIMPLE) && 914*cdf0e10cSrcweir aSelRange.aStart == aSelRange.aEnd ) 915*cdf0e10cSrcweir { 916*cdf0e10cSrcweir SCCOL nSelCol = aSelRange.aStart.Col(); 917*cdf0e10cSrcweir SCROW nSelRow = aSelRange.aStart.Row(); 918*cdf0e10cSrcweir SCTAB nSelTab = aSelRange.aStart.Tab(); 919*cdf0e10cSrcweir if ( pDoc->HasValueData( nSelCol, nSelRow, nSelTab ) ) 920*cdf0e10cSrcweir { 921*cdf0e10cSrcweir sal_uLong nIndex = static_cast<const SfxUInt32Item*>(pDoc->GetAttr( 922*cdf0e10cSrcweir nSelCol, nSelRow, nSelTab, ATTR_VALUE_FORMAT))->GetValue(); 923*cdf0e10cSrcweir short nType = pDoc->GetFormatTable()->GetType(nIndex); 924*cdf0e10cSrcweir if ( nType == NUMBERFORMAT_DATE || nType == NUMBERFORMAT_TIME || nType == NUMBERFORMAT_DATETIME ) 925*cdf0e10cSrcweir { 926*cdf0e10cSrcweir bFound = sal_True; 927*cdf0e10cSrcweir // use currently selected value for automatic limits 928*cdf0e10cSrcweir if( rOldInfo.AutoStart ) 929*cdf0e10cSrcweir rOldInfo.Start = pDoc->GetValue( aSelRange.aStart ); 930*cdf0e10cSrcweir if( rOldInfo.AutoEnd ) 931*cdf0e10cSrcweir rOldInfo.End = pDoc->GetValue( aSelRange.aStart ); 932*cdf0e10cSrcweir } 933*cdf0e10cSrcweir } 934*cdf0e10cSrcweir } 935*cdf0e10cSrcweir } 936*cdf0e10cSrcweir } 937*cdf0e10cSrcweir } 938*cdf0e10cSrcweir 939*cdf0e10cSrcweir return bFound; 940*cdf0e10cSrcweir } 941*cdf0e10cSrcweir 942*cdf0e10cSrcweir sal_Bool ScDBFunc::HasSelectionForNumGroup( ScDPNumGroupInfo& rOldInfo ) 943*cdf0e10cSrcweir { 944*cdf0e10cSrcweir // determine if the numeric group dialog has to be shown for the current selection 945*cdf0e10cSrcweir 946*cdf0e10cSrcweir sal_Bool bFound = sal_False; 947*cdf0e10cSrcweir 948*cdf0e10cSrcweir SCCOL nCurX = GetViewData()->GetCurX(); 949*cdf0e10cSrcweir SCROW nCurY = GetViewData()->GetCurY(); 950*cdf0e10cSrcweir SCTAB nTab = GetViewData()->GetTabNo(); 951*cdf0e10cSrcweir ScDocument* pDoc = GetViewData()->GetDocument(); 952*cdf0e10cSrcweir 953*cdf0e10cSrcweir ScDPObject* pDPObj = pDoc->GetDPAtCursor( nCurX, nCurY, nTab ); 954*cdf0e10cSrcweir if ( pDPObj ) 955*cdf0e10cSrcweir { 956*cdf0e10cSrcweir ScStrCollection aEntries; 957*cdf0e10cSrcweir long nSelectDimension = -1; 958*cdf0e10cSrcweir GetSelectedMemberList( aEntries, nSelectDimension ); 959*cdf0e10cSrcweir 960*cdf0e10cSrcweir if ( aEntries.GetCount() > 0 ) 961*cdf0e10cSrcweir { 962*cdf0e10cSrcweir sal_Bool bIsDataLayout; 963*cdf0e10cSrcweir String aDimName = pDPObj->GetDimName( nSelectDimension, bIsDataLayout ); 964*cdf0e10cSrcweir 965*cdf0e10cSrcweir sal_Bool bInGroupDim = sal_False; 966*cdf0e10cSrcweir 967*cdf0e10cSrcweir ScDPDimensionSaveData* pDimData = 968*cdf0e10cSrcweir const_cast<ScDPDimensionSaveData*>( pDPObj->GetSaveData()->GetExistingDimensionData() ); 969*cdf0e10cSrcweir if ( pDimData ) 970*cdf0e10cSrcweir { 971*cdf0e10cSrcweir const ScDPSaveNumGroupDimension* pNumGroupDim = pDimData->GetNumGroupDim( aDimName ); 972*cdf0e10cSrcweir if ( pNumGroupDim ) 973*cdf0e10cSrcweir { 974*cdf0e10cSrcweir // existing num group dimension 975*cdf0e10cSrcweir // -> edit settings of this dimension 976*cdf0e10cSrcweir 977*cdf0e10cSrcweir rOldInfo = pNumGroupDim->GetInfo(); 978*cdf0e10cSrcweir bFound = sal_True; 979*cdf0e10cSrcweir } 980*cdf0e10cSrcweir else if ( pDimData->GetNamedGroupDim( aDimName ) ) 981*cdf0e10cSrcweir bInGroupDim = sal_True; // in a group dimension 982*cdf0e10cSrcweir } 983*cdf0e10cSrcweir if ( !bFound && !bInGroupDim ) 984*cdf0e10cSrcweir { 985*cdf0e10cSrcweir // create a new num group dimension if the selection is a single cell 986*cdf0e10cSrcweir // in a normal dimension with numeric content 987*cdf0e10cSrcweir 988*cdf0e10cSrcweir ScRange aSelRange; 989*cdf0e10cSrcweir if ( (GetViewData()->GetSimpleArea( aSelRange ) == SC_MARK_SIMPLE) && 990*cdf0e10cSrcweir aSelRange.aStart == aSelRange.aEnd ) 991*cdf0e10cSrcweir { 992*cdf0e10cSrcweir if ( pDoc->HasValueData( aSelRange.aStart.Col(), aSelRange.aStart.Row(), 993*cdf0e10cSrcweir aSelRange.aStart.Tab() ) ) 994*cdf0e10cSrcweir { 995*cdf0e10cSrcweir bFound = sal_True; 996*cdf0e10cSrcweir // use currently selected value for automatic limits 997*cdf0e10cSrcweir if( rOldInfo.AutoStart ) 998*cdf0e10cSrcweir rOldInfo.Start = pDoc->GetValue( aSelRange.aStart ); 999*cdf0e10cSrcweir if( rOldInfo.AutoEnd ) 1000*cdf0e10cSrcweir rOldInfo.End = pDoc->GetValue( aSelRange.aStart ); 1001*cdf0e10cSrcweir } 1002*cdf0e10cSrcweir } 1003*cdf0e10cSrcweir } 1004*cdf0e10cSrcweir } 1005*cdf0e10cSrcweir } 1006*cdf0e10cSrcweir 1007*cdf0e10cSrcweir return bFound; 1008*cdf0e10cSrcweir } 1009*cdf0e10cSrcweir 1010*cdf0e10cSrcweir void ScDBFunc::DateGroupDataPilot( const ScDPNumGroupInfo& rInfo, sal_Int32 nParts ) 1011*cdf0e10cSrcweir { 1012*cdf0e10cSrcweir ScDPObject* pDPObj = GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(), 1013*cdf0e10cSrcweir GetViewData()->GetCurY(), GetViewData()->GetTabNo() ); 1014*cdf0e10cSrcweir if ( pDPObj ) 1015*cdf0e10cSrcweir { 1016*cdf0e10cSrcweir ScStrCollection aEntries; 1017*cdf0e10cSrcweir long nSelectDimension = -1; 1018*cdf0e10cSrcweir GetSelectedMemberList( aEntries, nSelectDimension ); 1019*cdf0e10cSrcweir 1020*cdf0e10cSrcweir if ( aEntries.GetCount() > 0 ) 1021*cdf0e10cSrcweir { 1022*cdf0e10cSrcweir sal_Bool bIsDataLayout; 1023*cdf0e10cSrcweir String aDimName = pDPObj->GetDimName( nSelectDimension, bIsDataLayout ); 1024*cdf0e10cSrcweir 1025*cdf0e10cSrcweir ScDPSaveData aData( *pDPObj->GetSaveData() ); 1026*cdf0e10cSrcweir ScDPDimensionSaveData* pDimData = aData.GetDimensionData(); // created if not there 1027*cdf0e10cSrcweir 1028*cdf0e10cSrcweir // find original base 1029*cdf0e10cSrcweir String aBaseDimName = aDimName; 1030*cdf0e10cSrcweir if( const ScDPSaveGroupDimension* pBaseGroupDim = pDimData->GetNamedGroupDim( aDimName ) ) 1031*cdf0e10cSrcweir aBaseDimName = pBaseGroupDim->GetSourceDimName(); 1032*cdf0e10cSrcweir 1033*cdf0e10cSrcweir // remove all existing parts (the grouping is built completely new) 1034*cdf0e10cSrcweir 1035*cdf0e10cSrcweir /* Remove numeric group dimension (exists once at most). No need 1036*cdf0e10cSrcweir to delete anything in save data (grouping was done inplace in 1037*cdf0e10cSrcweir an existing base dimension). */ 1038*cdf0e10cSrcweir pDimData->RemoveNumGroupDimension( aBaseDimName ); 1039*cdf0e10cSrcweir 1040*cdf0e10cSrcweir /* Remove named group dimension(s). Collect deleted dimension 1041*cdf0e10cSrcweir names which may be reused while recreating the groups. 1042*cdf0e10cSrcweir Dimensions have to be removed from dimension save data and from 1043*cdf0e10cSrcweir save data too. */ 1044*cdf0e10cSrcweir std::vector< String > aDeletedNames; 1045*cdf0e10cSrcweir const ScDPSaveGroupDimension* pExistingGroup = pDimData->GetGroupDimForBase( aBaseDimName ); 1046*cdf0e10cSrcweir while ( pExistingGroup ) 1047*cdf0e10cSrcweir { 1048*cdf0e10cSrcweir String aGroupDimName = pExistingGroup->GetGroupDimName(); 1049*cdf0e10cSrcweir pDimData->RemoveGroupDimension( aGroupDimName ); // pExistingGroup is deleted 1050*cdf0e10cSrcweir 1051*cdf0e10cSrcweir // also remove SaveData settings for the dimension that no longer exists 1052*cdf0e10cSrcweir aData.RemoveDimensionByName( aGroupDimName ); 1053*cdf0e10cSrcweir 1054*cdf0e10cSrcweir /* The name can be used for the new group dimensions, although 1055*cdf0e10cSrcweir it is still in use with the DataPilotSource. */ 1056*cdf0e10cSrcweir aDeletedNames.push_back( aGroupDimName ); 1057*cdf0e10cSrcweir 1058*cdf0e10cSrcweir // see if there are more group dimensions 1059*cdf0e10cSrcweir pExistingGroup = pDimData->GetGroupDimForBase( aBaseDimName ); 1060*cdf0e10cSrcweir 1061*cdf0e10cSrcweir if ( pExistingGroup && pExistingGroup->GetGroupDimName() == aGroupDimName ) 1062*cdf0e10cSrcweir { 1063*cdf0e10cSrcweir // still get the same group dimension? 1064*cdf0e10cSrcweir DBG_ERROR("couldn't remove group dimension"); 1065*cdf0e10cSrcweir pExistingGroup = NULL; // avoid endless loop 1066*cdf0e10cSrcweir } 1067*cdf0e10cSrcweir } 1068*cdf0e10cSrcweir 1069*cdf0e10cSrcweir if ( nParts ) 1070*cdf0e10cSrcweir { 1071*cdf0e10cSrcweir // create date group dimensions 1072*cdf0e10cSrcweir 1073*cdf0e10cSrcweir ScDPNumGroupInfo aEmpty; 1074*cdf0e10cSrcweir bool bFirst = true; 1075*cdf0e10cSrcweir sal_Int32 nMask = 1; 1076*cdf0e10cSrcweir for (sal_uInt16 nBit=0; nBit<32; nBit++) 1077*cdf0e10cSrcweir { 1078*cdf0e10cSrcweir if ( nParts & nMask ) 1079*cdf0e10cSrcweir { 1080*cdf0e10cSrcweir if ( bFirst ) 1081*cdf0e10cSrcweir { 1082*cdf0e10cSrcweir // innermost part: create NumGroupDimension (replacing original values) 1083*cdf0e10cSrcweir // Dimension name is left unchanged 1084*cdf0e10cSrcweir 1085*cdf0e10cSrcweir if ( (nParts == sheet::DataPilotFieldGroupBy::DAYS) && (rInfo.Step >= 1.0) ) 1086*cdf0e10cSrcweir { 1087*cdf0e10cSrcweir // only days, and a step value specified: use numerical grouping 1088*cdf0e10cSrcweir // with DateValues flag, not date grouping 1089*cdf0e10cSrcweir 1090*cdf0e10cSrcweir ScDPNumGroupInfo aNumInfo( rInfo ); 1091*cdf0e10cSrcweir aNumInfo.DateValues = sal_True; 1092*cdf0e10cSrcweir 1093*cdf0e10cSrcweir ScDPSaveNumGroupDimension aNumGroupDim( aBaseDimName, aNumInfo ); 1094*cdf0e10cSrcweir pDimData->AddNumGroupDimension( aNumGroupDim ); 1095*cdf0e10cSrcweir } 1096*cdf0e10cSrcweir else 1097*cdf0e10cSrcweir { 1098*cdf0e10cSrcweir ScDPSaveNumGroupDimension aNumGroupDim( aBaseDimName, rInfo, nMask ); 1099*cdf0e10cSrcweir pDimData->AddNumGroupDimension( aNumGroupDim ); 1100*cdf0e10cSrcweir } 1101*cdf0e10cSrcweir 1102*cdf0e10cSrcweir bFirst = false; 1103*cdf0e10cSrcweir } 1104*cdf0e10cSrcweir else 1105*cdf0e10cSrcweir { 1106*cdf0e10cSrcweir // additional parts: create GroupDimension (shown as additional dimensions) 1107*cdf0e10cSrcweir String aGroupDimName = pDimData->CreateDateGroupDimName( nMask, *pDPObj, true, &aDeletedNames ); 1108*cdf0e10cSrcweir ScDPSaveGroupDimension aGroupDim( aBaseDimName, aGroupDimName ); 1109*cdf0e10cSrcweir aGroupDim.SetDateInfo( rInfo, nMask ); 1110*cdf0e10cSrcweir pDimData->AddGroupDimension( aGroupDim ); 1111*cdf0e10cSrcweir 1112*cdf0e10cSrcweir // set orientation 1113*cdf0e10cSrcweir ScDPSaveDimension* pSaveDimension = aData.GetDimensionByName( aGroupDimName ); 1114*cdf0e10cSrcweir if ( pSaveDimension->GetOrientation() == sheet::DataPilotFieldOrientation_HIDDEN ) 1115*cdf0e10cSrcweir { 1116*cdf0e10cSrcweir ScDPSaveDimension* pOldDimension = aData.GetDimensionByName( aBaseDimName ); 1117*cdf0e10cSrcweir pSaveDimension->SetOrientation( pOldDimension->GetOrientation() ); 1118*cdf0e10cSrcweir long nPosition = 0; //! before (immediate) base 1119*cdf0e10cSrcweir aData.SetPosition( pSaveDimension, nPosition ); 1120*cdf0e10cSrcweir } 1121*cdf0e10cSrcweir } 1122*cdf0e10cSrcweir } 1123*cdf0e10cSrcweir nMask *= 2; 1124*cdf0e10cSrcweir } 1125*cdf0e10cSrcweir } 1126*cdf0e10cSrcweir 1127*cdf0e10cSrcweir // apply changes 1128*cdf0e10cSrcweir ScDBDocFunc aFunc( *GetViewData()->GetDocShell() ); 1129*cdf0e10cSrcweir ScDPObject* pNewObj = new ScDPObject( *pDPObj ); 1130*cdf0e10cSrcweir pNewObj->SetSaveData( aData ); 1131*cdf0e10cSrcweir aFunc.DataPilotUpdate( pDPObj, pNewObj, sal_True, sal_False ); 1132*cdf0e10cSrcweir delete pNewObj; 1133*cdf0e10cSrcweir 1134*cdf0e10cSrcweir // unmark cell selection 1135*cdf0e10cSrcweir Unmark(); 1136*cdf0e10cSrcweir } 1137*cdf0e10cSrcweir } 1138*cdf0e10cSrcweir } 1139*cdf0e10cSrcweir 1140*cdf0e10cSrcweir void ScDBFunc::NumGroupDataPilot( const ScDPNumGroupInfo& rInfo ) 1141*cdf0e10cSrcweir { 1142*cdf0e10cSrcweir ScDPObject* pDPObj = GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(), 1143*cdf0e10cSrcweir GetViewData()->GetCurY(), GetViewData()->GetTabNo() ); 1144*cdf0e10cSrcweir if ( pDPObj ) 1145*cdf0e10cSrcweir { 1146*cdf0e10cSrcweir ScStrCollection aEntries; 1147*cdf0e10cSrcweir long nSelectDimension = -1; 1148*cdf0e10cSrcweir GetSelectedMemberList( aEntries, nSelectDimension ); 1149*cdf0e10cSrcweir 1150*cdf0e10cSrcweir if ( aEntries.GetCount() > 0 ) 1151*cdf0e10cSrcweir { 1152*cdf0e10cSrcweir sal_Bool bIsDataLayout; 1153*cdf0e10cSrcweir String aDimName = pDPObj->GetDimName( nSelectDimension, bIsDataLayout ); 1154*cdf0e10cSrcweir 1155*cdf0e10cSrcweir ScDPSaveData aData( *pDPObj->GetSaveData() ); 1156*cdf0e10cSrcweir ScDPDimensionSaveData* pDimData = aData.GetDimensionData(); // created if not there 1157*cdf0e10cSrcweir 1158*cdf0e10cSrcweir ScDPSaveNumGroupDimension* pExisting = pDimData->GetNumGroupDimAcc( aDimName ); 1159*cdf0e10cSrcweir if ( pExisting ) 1160*cdf0e10cSrcweir { 1161*cdf0e10cSrcweir // modify existing group dimension 1162*cdf0e10cSrcweir pExisting->SetGroupInfo( rInfo ); 1163*cdf0e10cSrcweir } 1164*cdf0e10cSrcweir else 1165*cdf0e10cSrcweir { 1166*cdf0e10cSrcweir // create new group dimension 1167*cdf0e10cSrcweir ScDPSaveNumGroupDimension aNumGroupDim( aDimName, rInfo ); 1168*cdf0e10cSrcweir pDimData->AddNumGroupDimension( aNumGroupDim ); 1169*cdf0e10cSrcweir } 1170*cdf0e10cSrcweir 1171*cdf0e10cSrcweir // apply changes 1172*cdf0e10cSrcweir ScDBDocFunc aFunc( *GetViewData()->GetDocShell() ); 1173*cdf0e10cSrcweir ScDPObject* pNewObj = new ScDPObject( *pDPObj ); 1174*cdf0e10cSrcweir pNewObj->SetSaveData( aData ); 1175*cdf0e10cSrcweir aFunc.DataPilotUpdate( pDPObj, pNewObj, sal_True, sal_False ); 1176*cdf0e10cSrcweir delete pNewObj; 1177*cdf0e10cSrcweir 1178*cdf0e10cSrcweir // unmark cell selection 1179*cdf0e10cSrcweir Unmark(); 1180*cdf0e10cSrcweir } 1181*cdf0e10cSrcweir } 1182*cdf0e10cSrcweir } 1183*cdf0e10cSrcweir 1184*cdf0e10cSrcweir void ScDBFunc::GroupDataPilot() 1185*cdf0e10cSrcweir { 1186*cdf0e10cSrcweir ScDPObject* pDPObj = GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(), 1187*cdf0e10cSrcweir GetViewData()->GetCurY(), GetViewData()->GetTabNo() ); 1188*cdf0e10cSrcweir if ( pDPObj ) 1189*cdf0e10cSrcweir { 1190*cdf0e10cSrcweir ScStrCollection aEntries; 1191*cdf0e10cSrcweir long nSelectDimension = -1; 1192*cdf0e10cSrcweir GetSelectedMemberList( aEntries, nSelectDimension ); 1193*cdf0e10cSrcweir 1194*cdf0e10cSrcweir if ( aEntries.GetCount() > 0 ) 1195*cdf0e10cSrcweir { 1196*cdf0e10cSrcweir sal_Bool bIsDataLayout; 1197*cdf0e10cSrcweir String aDimName = pDPObj->GetDimName( nSelectDimension, bIsDataLayout ); 1198*cdf0e10cSrcweir 1199*cdf0e10cSrcweir ScDPSaveData aData( *pDPObj->GetSaveData() ); 1200*cdf0e10cSrcweir ScDPDimensionSaveData* pDimData = aData.GetDimensionData(); // created if not there 1201*cdf0e10cSrcweir 1202*cdf0e10cSrcweir // find original base 1203*cdf0e10cSrcweir String aBaseDimName( aDimName ); 1204*cdf0e10cSrcweir const ScDPSaveGroupDimension* pBaseGroupDim = pDimData->GetNamedGroupDim( aDimName ); 1205*cdf0e10cSrcweir if ( pBaseGroupDim ) 1206*cdf0e10cSrcweir { 1207*cdf0e10cSrcweir // any entry's SourceDimName is the original base 1208*cdf0e10cSrcweir aBaseDimName = pBaseGroupDim->GetSourceDimName(); 1209*cdf0e10cSrcweir } 1210*cdf0e10cSrcweir 1211*cdf0e10cSrcweir // find existing group dimension 1212*cdf0e10cSrcweir // (using the selected dim, can be intermediate group dim) 1213*cdf0e10cSrcweir ScDPSaveGroupDimension* pGroupDimension = pDimData->GetGroupDimAccForBase( aDimName ); 1214*cdf0e10cSrcweir 1215*cdf0e10cSrcweir // remove the selected items from their groups 1216*cdf0e10cSrcweir // (empty groups are removed, too) 1217*cdf0e10cSrcweir sal_uInt16 nEntryCount = aEntries.GetCount(); 1218*cdf0e10cSrcweir sal_uInt16 nEntry; 1219*cdf0e10cSrcweir if ( pGroupDimension ) 1220*cdf0e10cSrcweir { 1221*cdf0e10cSrcweir for (nEntry=0; nEntry<nEntryCount; nEntry++) 1222*cdf0e10cSrcweir { 1223*cdf0e10cSrcweir String aEntryName = aEntries[nEntry]->GetString(); 1224*cdf0e10cSrcweir if ( pBaseGroupDim ) 1225*cdf0e10cSrcweir { 1226*cdf0e10cSrcweir // for each selected (intermediate) group, remove all its items 1227*cdf0e10cSrcweir // (same logic as for adding, below) 1228*cdf0e10cSrcweir const ScDPSaveGroupItem* pBaseGroup = pBaseGroupDim->GetNamedGroup( aEntryName ); 1229*cdf0e10cSrcweir if ( pBaseGroup ) 1230*cdf0e10cSrcweir pBaseGroup->RemoveElementsFromGroups( *pGroupDimension ); // remove all elements 1231*cdf0e10cSrcweir else 1232*cdf0e10cSrcweir pGroupDimension->RemoveFromGroups( aEntryName ); 1233*cdf0e10cSrcweir } 1234*cdf0e10cSrcweir else 1235*cdf0e10cSrcweir pGroupDimension->RemoveFromGroups( aEntryName ); 1236*cdf0e10cSrcweir } 1237*cdf0e10cSrcweir } 1238*cdf0e10cSrcweir 1239*cdf0e10cSrcweir ScDPSaveGroupDimension* pNewGroupDim = NULL; 1240*cdf0e10cSrcweir if ( !pGroupDimension ) 1241*cdf0e10cSrcweir { 1242*cdf0e10cSrcweir // create a new group dimension 1243*cdf0e10cSrcweir String aGroupDimName = pDimData->CreateGroupDimName( aBaseDimName, *pDPObj, false, NULL ); 1244*cdf0e10cSrcweir pNewGroupDim = new ScDPSaveGroupDimension( aBaseDimName, aGroupDimName ); 1245*cdf0e10cSrcweir 1246*cdf0e10cSrcweir pGroupDimension = pNewGroupDim; // make changes to the new dim if none existed 1247*cdf0e10cSrcweir 1248*cdf0e10cSrcweir if ( pBaseGroupDim ) 1249*cdf0e10cSrcweir { 1250*cdf0e10cSrcweir // If it's a higher-order group dimension, pre-allocate groups for all 1251*cdf0e10cSrcweir // non-selected original groups, so the individual base members aren't 1252*cdf0e10cSrcweir // used for automatic groups (this would make the original groups hard 1253*cdf0e10cSrcweir // to find). 1254*cdf0e10cSrcweir //! Also do this when removing groups? 1255*cdf0e10cSrcweir //! Handle this case dynamically with automatic groups? 1256*cdf0e10cSrcweir 1257*cdf0e10cSrcweir long nGroupCount = pBaseGroupDim->GetGroupCount(); 1258*cdf0e10cSrcweir for ( long nGroup = 0; nGroup < nGroupCount; nGroup++ ) 1259*cdf0e10cSrcweir { 1260*cdf0e10cSrcweir const ScDPSaveGroupItem* pBaseGroup = pBaseGroupDim->GetGroupByIndex( nGroup ); 1261*cdf0e10cSrcweir 1262*cdf0e10cSrcweir StrData aStrData( pBaseGroup->GetGroupName() ); 1263*cdf0e10cSrcweir sal_uInt16 nCollIndex; 1264*cdf0e10cSrcweir if ( !aEntries.Search( &aStrData, nCollIndex ) ) //! ignore case? 1265*cdf0e10cSrcweir { 1266*cdf0e10cSrcweir // add an additional group for each item that is not in the selection 1267*cdf0e10cSrcweir ScDPSaveGroupItem aGroup( pBaseGroup->GetGroupName() ); 1268*cdf0e10cSrcweir aGroup.AddElementsFromGroup( *pBaseGroup ); 1269*cdf0e10cSrcweir pGroupDimension->AddGroupItem( aGroup ); 1270*cdf0e10cSrcweir } 1271*cdf0e10cSrcweir } 1272*cdf0e10cSrcweir } 1273*cdf0e10cSrcweir } 1274*cdf0e10cSrcweir String aGroupDimName = pGroupDimension->GetGroupDimName(); 1275*cdf0e10cSrcweir 1276*cdf0e10cSrcweir //! localized prefix string 1277*cdf0e10cSrcweir String aGroupName = pGroupDimension->CreateGroupName( String::CreateFromAscii("Group") ); 1278*cdf0e10cSrcweir ScDPSaveGroupItem aGroup( aGroupName ); 1279*cdf0e10cSrcweir for (nEntry=0; nEntry<nEntryCount; nEntry++) 1280*cdf0e10cSrcweir { 1281*cdf0e10cSrcweir String aEntryName = aEntries[nEntry]->GetString(); 1282*cdf0e10cSrcweir if ( pBaseGroupDim ) 1283*cdf0e10cSrcweir { 1284*cdf0e10cSrcweir // for each selected (intermediate) group, add all its items 1285*cdf0e10cSrcweir const ScDPSaveGroupItem* pBaseGroup = pBaseGroupDim->GetNamedGroup( aEntryName ); 1286*cdf0e10cSrcweir if ( pBaseGroup ) 1287*cdf0e10cSrcweir aGroup.AddElementsFromGroup( *pBaseGroup ); 1288*cdf0e10cSrcweir else 1289*cdf0e10cSrcweir aGroup.AddElement( aEntryName ); // no group found -> automatic group, add the item itself 1290*cdf0e10cSrcweir } 1291*cdf0e10cSrcweir else 1292*cdf0e10cSrcweir aGroup.AddElement( aEntryName ); // no group dimension, add all items directly 1293*cdf0e10cSrcweir } 1294*cdf0e10cSrcweir 1295*cdf0e10cSrcweir pGroupDimension->AddGroupItem( aGroup ); 1296*cdf0e10cSrcweir 1297*cdf0e10cSrcweir if ( pNewGroupDim ) 1298*cdf0e10cSrcweir { 1299*cdf0e10cSrcweir pDimData->AddGroupDimension( *pNewGroupDim ); 1300*cdf0e10cSrcweir delete pNewGroupDim; // AddGroupDimension copies the object 1301*cdf0e10cSrcweir // don't access pGroupDimension after here 1302*cdf0e10cSrcweir } 1303*cdf0e10cSrcweir pGroupDimension = pNewGroupDim = NULL; 1304*cdf0e10cSrcweir 1305*cdf0e10cSrcweir // set orientation 1306*cdf0e10cSrcweir ScDPSaveDimension* pSaveDimension = aData.GetDimensionByName( aGroupDimName ); 1307*cdf0e10cSrcweir if ( pSaveDimension->GetOrientation() == sheet::DataPilotFieldOrientation_HIDDEN ) 1308*cdf0e10cSrcweir { 1309*cdf0e10cSrcweir ScDPSaveDimension* pOldDimension = aData.GetDimensionByName( aDimName ); 1310*cdf0e10cSrcweir pSaveDimension->SetOrientation( pOldDimension->GetOrientation() ); 1311*cdf0e10cSrcweir long nPosition = 0; //! before (immediate) base 1312*cdf0e10cSrcweir aData.SetPosition( pSaveDimension, nPosition ); 1313*cdf0e10cSrcweir } 1314*cdf0e10cSrcweir 1315*cdf0e10cSrcweir // apply changes 1316*cdf0e10cSrcweir ScDBDocFunc aFunc( *GetViewData()->GetDocShell() ); 1317*cdf0e10cSrcweir ScDPObject* pNewObj = new ScDPObject( *pDPObj ); 1318*cdf0e10cSrcweir pNewObj->SetSaveData( aData ); 1319*cdf0e10cSrcweir aFunc.DataPilotUpdate( pDPObj, pNewObj, sal_True, sal_False ); 1320*cdf0e10cSrcweir delete pNewObj; 1321*cdf0e10cSrcweir 1322*cdf0e10cSrcweir // unmark cell selection 1323*cdf0e10cSrcweir Unmark(); 1324*cdf0e10cSrcweir } 1325*cdf0e10cSrcweir } 1326*cdf0e10cSrcweir } 1327*cdf0e10cSrcweir 1328*cdf0e10cSrcweir void ScDBFunc::UngroupDataPilot() 1329*cdf0e10cSrcweir { 1330*cdf0e10cSrcweir ScDPObject* pDPObj = GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(), 1331*cdf0e10cSrcweir GetViewData()->GetCurY(), GetViewData()->GetTabNo() ); 1332*cdf0e10cSrcweir if ( pDPObj ) 1333*cdf0e10cSrcweir { 1334*cdf0e10cSrcweir ScStrCollection aEntries; 1335*cdf0e10cSrcweir long nSelectDimension = -1; 1336*cdf0e10cSrcweir GetSelectedMemberList( aEntries, nSelectDimension ); 1337*cdf0e10cSrcweir 1338*cdf0e10cSrcweir if ( aEntries.GetCount() > 0 ) 1339*cdf0e10cSrcweir { 1340*cdf0e10cSrcweir sal_Bool bIsDataLayout; 1341*cdf0e10cSrcweir String aDimName = pDPObj->GetDimName( nSelectDimension, bIsDataLayout ); 1342*cdf0e10cSrcweir 1343*cdf0e10cSrcweir ScDPSaveData aData( *pDPObj->GetSaveData() ); 1344*cdf0e10cSrcweir ScDPDimensionSaveData* pDimData = aData.GetDimensionData(); // created if not there 1345*cdf0e10cSrcweir //! test first if DimensionData exists? 1346*cdf0e10cSrcweir 1347*cdf0e10cSrcweir sal_Bool bApply = sal_False; 1348*cdf0e10cSrcweir 1349*cdf0e10cSrcweir ScDPSaveGroupDimension* pGroupDim = pDimData->GetNamedGroupDimAcc( aDimName ); 1350*cdf0e10cSrcweir const ScDPSaveNumGroupDimension* pNumGroupDim = pDimData->GetNumGroupDim( aDimName ); 1351*cdf0e10cSrcweir if ( ( pGroupDim && pGroupDim->GetDatePart() != 0 ) || 1352*cdf0e10cSrcweir ( pNumGroupDim && pNumGroupDim->GetDatePart() != 0 ) ) 1353*cdf0e10cSrcweir { 1354*cdf0e10cSrcweir // Date grouping: need to remove all affected group dimensions. 1355*cdf0e10cSrcweir // This is done using DateGroupDataPilot with nParts=0. 1356*cdf0e10cSrcweir 1357*cdf0e10cSrcweir DateGroupDataPilot( ScDPNumGroupInfo(), 0 ); 1358*cdf0e10cSrcweir // bApply remains FALSE 1359*cdf0e10cSrcweir // dimension pointers become invalid 1360*cdf0e10cSrcweir } 1361*cdf0e10cSrcweir else if ( pGroupDim ) 1362*cdf0e10cSrcweir { 1363*cdf0e10cSrcweir sal_uInt16 nEntryCount = aEntries.GetCount(); 1364*cdf0e10cSrcweir for (sal_uInt16 nEntry=0; nEntry<nEntryCount; nEntry++) 1365*cdf0e10cSrcweir { 1366*cdf0e10cSrcweir String aEntryName = aEntries[nEntry]->GetString(); 1367*cdf0e10cSrcweir pGroupDim->RemoveGroup( aEntryName ); 1368*cdf0e10cSrcweir } 1369*cdf0e10cSrcweir // remove group dimension if empty 1370*cdf0e10cSrcweir bool bEmptyDim = pGroupDim->IsEmpty(); 1371*cdf0e10cSrcweir if ( !bEmptyDim ) 1372*cdf0e10cSrcweir { 1373*cdf0e10cSrcweir // If all remaining groups in the dimension aren't shown, remove 1374*cdf0e10cSrcweir // the dimension too, as if it was completely empty. 1375*cdf0e10cSrcweir ScStrCollection aVisibleEntries; 1376*cdf0e10cSrcweir pDPObj->GetMemberResultNames( aVisibleEntries, nSelectDimension ); 1377*cdf0e10cSrcweir bEmptyDim = pGroupDim->HasOnlyHidden( aVisibleEntries ); 1378*cdf0e10cSrcweir } 1379*cdf0e10cSrcweir if ( bEmptyDim ) 1380*cdf0e10cSrcweir { 1381*cdf0e10cSrcweir pDimData->RemoveGroupDimension( aDimName ); // pGroupDim is deleted 1382*cdf0e10cSrcweir 1383*cdf0e10cSrcweir // also remove SaveData settings for the dimension that no longer exists 1384*cdf0e10cSrcweir aData.RemoveDimensionByName( aDimName ); 1385*cdf0e10cSrcweir } 1386*cdf0e10cSrcweir bApply = sal_True; 1387*cdf0e10cSrcweir } 1388*cdf0e10cSrcweir else if ( pNumGroupDim ) 1389*cdf0e10cSrcweir { 1390*cdf0e10cSrcweir // remove the numerical grouping 1391*cdf0e10cSrcweir pDimData->RemoveNumGroupDimension( aDimName ); 1392*cdf0e10cSrcweir // SaveData settings can remain unchanged - the same dimension still exists 1393*cdf0e10cSrcweir bApply = sal_True; 1394*cdf0e10cSrcweir } 1395*cdf0e10cSrcweir 1396*cdf0e10cSrcweir if ( bApply ) 1397*cdf0e10cSrcweir { 1398*cdf0e10cSrcweir // apply changes 1399*cdf0e10cSrcweir ScDBDocFunc aFunc( *GetViewData()->GetDocShell() ); 1400*cdf0e10cSrcweir ScDPObject* pNewObj = new ScDPObject( *pDPObj ); 1401*cdf0e10cSrcweir pNewObj->SetSaveData( aData ); 1402*cdf0e10cSrcweir aFunc.DataPilotUpdate( pDPObj, pNewObj, sal_True, sal_False ); 1403*cdf0e10cSrcweir delete pNewObj; 1404*cdf0e10cSrcweir 1405*cdf0e10cSrcweir // unmark cell selection 1406*cdf0e10cSrcweir Unmark(); 1407*cdf0e10cSrcweir } 1408*cdf0e10cSrcweir } 1409*cdf0e10cSrcweir } 1410*cdf0e10cSrcweir } 1411*cdf0e10cSrcweir 1412*cdf0e10cSrcweir static OUString lcl_replaceMemberNameInSubtotal(const OUString& rSubtotal, const OUString& rMemberName) 1413*cdf0e10cSrcweir { 1414*cdf0e10cSrcweir sal_Int32 n = rSubtotal.getLength(); 1415*cdf0e10cSrcweir const sal_Unicode* p = rSubtotal.getStr(); 1416*cdf0e10cSrcweir OUStringBuffer aBuf, aWordBuf; 1417*cdf0e10cSrcweir for (sal_Int32 i = 0; i < n; ++i) 1418*cdf0e10cSrcweir { 1419*cdf0e10cSrcweir sal_Unicode c = p[i]; 1420*cdf0e10cSrcweir if (c == sal_Unicode(' ')) 1421*cdf0e10cSrcweir { 1422*cdf0e10cSrcweir OUString aWord = aWordBuf.makeStringAndClear(); 1423*cdf0e10cSrcweir if (aWord.equals(rMemberName)) 1424*cdf0e10cSrcweir aBuf.append(sal_Unicode('?')); 1425*cdf0e10cSrcweir else 1426*cdf0e10cSrcweir aBuf.append(aWord); 1427*cdf0e10cSrcweir aBuf.append(c); 1428*cdf0e10cSrcweir } 1429*cdf0e10cSrcweir else if (c == sal_Unicode('\\')) 1430*cdf0e10cSrcweir { 1431*cdf0e10cSrcweir // Escape a backslash character. 1432*cdf0e10cSrcweir aWordBuf.append(c); 1433*cdf0e10cSrcweir aWordBuf.append(c); 1434*cdf0e10cSrcweir } 1435*cdf0e10cSrcweir else if (c == sal_Unicode('?')) 1436*cdf0e10cSrcweir { 1437*cdf0e10cSrcweir // A literal '?' must be escaped with a backslash ('\'); 1438*cdf0e10cSrcweir aWordBuf.append(sal_Unicode('\\')); 1439*cdf0e10cSrcweir aWordBuf.append(c); 1440*cdf0e10cSrcweir } 1441*cdf0e10cSrcweir else 1442*cdf0e10cSrcweir aWordBuf.append(c); 1443*cdf0e10cSrcweir } 1444*cdf0e10cSrcweir 1445*cdf0e10cSrcweir if (aWordBuf.getLength() > 0) 1446*cdf0e10cSrcweir { 1447*cdf0e10cSrcweir OUString aWord = aWordBuf.makeStringAndClear(); 1448*cdf0e10cSrcweir if (aWord.equals(rMemberName)) 1449*cdf0e10cSrcweir aBuf.append(sal_Unicode('?')); 1450*cdf0e10cSrcweir else 1451*cdf0e10cSrcweir aBuf.append(aWord); 1452*cdf0e10cSrcweir } 1453*cdf0e10cSrcweir 1454*cdf0e10cSrcweir return aBuf.makeStringAndClear(); 1455*cdf0e10cSrcweir } 1456*cdf0e10cSrcweir 1457*cdf0e10cSrcweir void ScDBFunc::DataPilotInput( const ScAddress& rPos, const String& rString ) 1458*cdf0e10cSrcweir { 1459*cdf0e10cSrcweir using namespace ::com::sun::star::sheet; 1460*cdf0e10cSrcweir 1461*cdf0e10cSrcweir String aNewName( rString ); 1462*cdf0e10cSrcweir 1463*cdf0e10cSrcweir ScDocument* pDoc = GetViewData()->GetDocument(); 1464*cdf0e10cSrcweir ScDPObject* pDPObj = pDoc->GetDPAtCursor( rPos.Col(), rPos.Row(), rPos.Tab() ); 1465*cdf0e10cSrcweir if (!pDPObj) 1466*cdf0e10cSrcweir return; 1467*cdf0e10cSrcweir 1468*cdf0e10cSrcweir String aOldText; 1469*cdf0e10cSrcweir pDoc->GetString( rPos.Col(), rPos.Row(), rPos.Tab(), aOldText ); 1470*cdf0e10cSrcweir 1471*cdf0e10cSrcweir if ( aOldText == rString ) 1472*cdf0e10cSrcweir { 1473*cdf0e10cSrcweir // nothing to do: silently exit 1474*cdf0e10cSrcweir return; 1475*cdf0e10cSrcweir } 1476*cdf0e10cSrcweir 1477*cdf0e10cSrcweir sal_uInt16 nErrorId = 0; 1478*cdf0e10cSrcweir 1479*cdf0e10cSrcweir pDPObj->BuildAllDimensionMembers(); 1480*cdf0e10cSrcweir ScDPSaveData aData( *pDPObj->GetSaveData() ); 1481*cdf0e10cSrcweir sal_Bool bChange = sal_False; 1482*cdf0e10cSrcweir 1483*cdf0e10cSrcweir sal_uInt16 nOrient = DataPilotFieldOrientation_HIDDEN; 1484*cdf0e10cSrcweir long nField = pDPObj->GetHeaderDim( rPos, nOrient ); 1485*cdf0e10cSrcweir if ( nField >= 0 ) 1486*cdf0e10cSrcweir { 1487*cdf0e10cSrcweir // changing a field title 1488*cdf0e10cSrcweir if ( aData.GetExistingDimensionData() ) 1489*cdf0e10cSrcweir { 1490*cdf0e10cSrcweir // only group dimensions can be renamed 1491*cdf0e10cSrcweir 1492*cdf0e10cSrcweir ScDPDimensionSaveData* pDimData = aData.GetDimensionData(); 1493*cdf0e10cSrcweir ScDPSaveGroupDimension* pGroupDim = pDimData->GetNamedGroupDimAcc( aOldText ); 1494*cdf0e10cSrcweir if ( pGroupDim ) 1495*cdf0e10cSrcweir { 1496*cdf0e10cSrcweir // valid name: not empty, no existing dimension (group or other) 1497*cdf0e10cSrcweir if ( rString.Len() && !pDPObj->IsDimNameInUse(rString) ) 1498*cdf0e10cSrcweir { 1499*cdf0e10cSrcweir pGroupDim->Rename( aNewName ); 1500*cdf0e10cSrcweir 1501*cdf0e10cSrcweir // also rename in SaveData to preserve the field settings 1502*cdf0e10cSrcweir ScDPSaveDimension* pSaveDim = aData.GetDimensionByName( aOldText ); 1503*cdf0e10cSrcweir pSaveDim->SetName( aNewName ); 1504*cdf0e10cSrcweir 1505*cdf0e10cSrcweir bChange = sal_True; 1506*cdf0e10cSrcweir } 1507*cdf0e10cSrcweir else 1508*cdf0e10cSrcweir nErrorId = STR_INVALIDNAME; 1509*cdf0e10cSrcweir } 1510*cdf0e10cSrcweir } 1511*cdf0e10cSrcweir else if (nOrient == DataPilotFieldOrientation_COLUMN || nOrient == DataPilotFieldOrientation_ROW) 1512*cdf0e10cSrcweir { 1513*cdf0e10cSrcweir sal_Bool bDataLayout = false; 1514*cdf0e10cSrcweir String aDimName = pDPObj->GetDimName(nField, bDataLayout); 1515*cdf0e10cSrcweir ScDPSaveDimension* pDim = bDataLayout ? aData.GetDataLayoutDimension() : aData.GetDimensionByName(aDimName); 1516*cdf0e10cSrcweir if (pDim) 1517*cdf0e10cSrcweir { 1518*cdf0e10cSrcweir if (rString.Len()) 1519*cdf0e10cSrcweir { 1520*cdf0e10cSrcweir if (rString.EqualsIgnoreCaseAscii(aDimName)) 1521*cdf0e10cSrcweir { 1522*cdf0e10cSrcweir pDim->RemoveLayoutName(); 1523*cdf0e10cSrcweir bChange = true; 1524*cdf0e10cSrcweir } 1525*cdf0e10cSrcweir else if (!pDPObj->IsDimNameInUse(rString)) 1526*cdf0e10cSrcweir { 1527*cdf0e10cSrcweir pDim->SetLayoutName(rString); 1528*cdf0e10cSrcweir bChange = true; 1529*cdf0e10cSrcweir } 1530*cdf0e10cSrcweir else 1531*cdf0e10cSrcweir nErrorId = STR_INVALIDNAME; 1532*cdf0e10cSrcweir } 1533*cdf0e10cSrcweir else 1534*cdf0e10cSrcweir nErrorId = STR_INVALIDNAME; 1535*cdf0e10cSrcweir } 1536*cdf0e10cSrcweir } 1537*cdf0e10cSrcweir } 1538*cdf0e10cSrcweir else if (pDPObj->IsDataDescriptionCell(rPos)) 1539*cdf0e10cSrcweir { 1540*cdf0e10cSrcweir // There is only one data dimension. 1541*cdf0e10cSrcweir ScDPSaveDimension* pDim = aData.GetFirstDimension(sheet::DataPilotFieldOrientation_DATA); 1542*cdf0e10cSrcweir if (pDim) 1543*cdf0e10cSrcweir { 1544*cdf0e10cSrcweir if (rString.Len()) 1545*cdf0e10cSrcweir { 1546*cdf0e10cSrcweir if (rString.EqualsIgnoreCaseAscii(pDim->GetName())) 1547*cdf0e10cSrcweir { 1548*cdf0e10cSrcweir pDim->RemoveLayoutName(); 1549*cdf0e10cSrcweir bChange = true; 1550*cdf0e10cSrcweir } 1551*cdf0e10cSrcweir else if (!pDPObj->IsDimNameInUse(rString)) 1552*cdf0e10cSrcweir { 1553*cdf0e10cSrcweir pDim->SetLayoutName(rString); 1554*cdf0e10cSrcweir bChange = true; 1555*cdf0e10cSrcweir } 1556*cdf0e10cSrcweir else 1557*cdf0e10cSrcweir nErrorId = STR_INVALIDNAME; 1558*cdf0e10cSrcweir } 1559*cdf0e10cSrcweir else 1560*cdf0e10cSrcweir nErrorId = STR_INVALIDNAME; 1561*cdf0e10cSrcweir } 1562*cdf0e10cSrcweir } 1563*cdf0e10cSrcweir else 1564*cdf0e10cSrcweir { 1565*cdf0e10cSrcweir // This is not a field header. 1566*cdf0e10cSrcweir sheet::DataPilotTableHeaderData aPosData; 1567*cdf0e10cSrcweir pDPObj->GetHeaderPositionData(rPos, aPosData); 1568*cdf0e10cSrcweir 1569*cdf0e10cSrcweir if ( (aPosData.Flags & MemberResultFlags::HASMEMBER) && aOldText.Len() ) 1570*cdf0e10cSrcweir { 1571*cdf0e10cSrcweir if ( aData.GetExistingDimensionData() && !(aPosData.Flags & MemberResultFlags::SUBTOTAL)) 1572*cdf0e10cSrcweir { 1573*cdf0e10cSrcweir sal_Bool bIsDataLayout; 1574*cdf0e10cSrcweir String aDimName = pDPObj->GetDimName( aPosData.Dimension, bIsDataLayout ); 1575*cdf0e10cSrcweir 1576*cdf0e10cSrcweir ScDPDimensionSaveData* pDimData = aData.GetDimensionData(); 1577*cdf0e10cSrcweir ScDPSaveGroupDimension* pGroupDim = pDimData->GetNamedGroupDimAcc( aDimName ); 1578*cdf0e10cSrcweir if ( pGroupDim ) 1579*cdf0e10cSrcweir { 1580*cdf0e10cSrcweir // valid name: not empty, no existing group in this dimension 1581*cdf0e10cSrcweir //! ignore case? 1582*cdf0e10cSrcweir if ( aNewName.Len() && !pGroupDim->GetNamedGroup( aNewName ) ) 1583*cdf0e10cSrcweir { 1584*cdf0e10cSrcweir ScDPSaveGroupItem* pGroup = pGroupDim->GetNamedGroupAcc( aOldText ); 1585*cdf0e10cSrcweir if ( pGroup ) 1586*cdf0e10cSrcweir pGroup->Rename( aNewName ); // rename the existing group 1587*cdf0e10cSrcweir else 1588*cdf0e10cSrcweir { 1589*cdf0e10cSrcweir // create a new group to replace the automatic group 1590*cdf0e10cSrcweir ScDPSaveGroupItem aGroup( aNewName ); 1591*cdf0e10cSrcweir aGroup.AddElement( aOldText ); 1592*cdf0e10cSrcweir pGroupDim->AddGroupItem( aGroup ); 1593*cdf0e10cSrcweir } 1594*cdf0e10cSrcweir 1595*cdf0e10cSrcweir // in both cases also adjust savedata, to preserve member settings (show details) 1596*cdf0e10cSrcweir ScDPSaveDimension* pSaveDim = aData.GetDimensionByName( aDimName ); 1597*cdf0e10cSrcweir ScDPSaveMember* pSaveMember = pSaveDim->GetExistingMemberByName( aOldText ); 1598*cdf0e10cSrcweir if ( pSaveMember ) 1599*cdf0e10cSrcweir pSaveMember->SetName( aNewName ); 1600*cdf0e10cSrcweir 1601*cdf0e10cSrcweir bChange = sal_True; 1602*cdf0e10cSrcweir } 1603*cdf0e10cSrcweir else 1604*cdf0e10cSrcweir nErrorId = STR_INVALIDNAME; 1605*cdf0e10cSrcweir } 1606*cdf0e10cSrcweir } 1607*cdf0e10cSrcweir else if ((aPosData.Flags & MemberResultFlags::GRANDTOTAL)) 1608*cdf0e10cSrcweir { 1609*cdf0e10cSrcweir aData.SetGrandTotalName(rString); 1610*cdf0e10cSrcweir bChange = true; 1611*cdf0e10cSrcweir } 1612*cdf0e10cSrcweir else if (aPosData.Dimension >= 0 && aPosData.MemberName.getLength() > 0) 1613*cdf0e10cSrcweir { 1614*cdf0e10cSrcweir sal_Bool bDataLayout = false; 1615*cdf0e10cSrcweir String aDimName = pDPObj->GetDimName(static_cast<long>(aPosData.Dimension), bDataLayout); 1616*cdf0e10cSrcweir if (bDataLayout) 1617*cdf0e10cSrcweir { 1618*cdf0e10cSrcweir // data dimension 1619*cdf0e10cSrcweir do 1620*cdf0e10cSrcweir { 1621*cdf0e10cSrcweir if ((aPosData.Flags & MemberResultFlags::SUBTOTAL)) 1622*cdf0e10cSrcweir break; 1623*cdf0e10cSrcweir 1624*cdf0e10cSrcweir ScDPSaveDimension* pDim = aData.GetDimensionByName(aPosData.MemberName); 1625*cdf0e10cSrcweir if (!pDim) 1626*cdf0e10cSrcweir break; 1627*cdf0e10cSrcweir 1628*cdf0e10cSrcweir if (!rString.Len()) 1629*cdf0e10cSrcweir { 1630*cdf0e10cSrcweir nErrorId = STR_INVALIDNAME; 1631*cdf0e10cSrcweir break; 1632*cdf0e10cSrcweir } 1633*cdf0e10cSrcweir 1634*cdf0e10cSrcweir if (aPosData.MemberName.equalsIgnoreAsciiCase(rString)) 1635*cdf0e10cSrcweir { 1636*cdf0e10cSrcweir pDim->RemoveLayoutName(); 1637*cdf0e10cSrcweir bChange = true; 1638*cdf0e10cSrcweir } 1639*cdf0e10cSrcweir else if (!pDPObj->IsDimNameInUse(rString)) 1640*cdf0e10cSrcweir { 1641*cdf0e10cSrcweir pDim->SetLayoutName(rString); 1642*cdf0e10cSrcweir bChange = true; 1643*cdf0e10cSrcweir } 1644*cdf0e10cSrcweir else 1645*cdf0e10cSrcweir nErrorId = STR_INVALIDNAME; 1646*cdf0e10cSrcweir } 1647*cdf0e10cSrcweir while (false); 1648*cdf0e10cSrcweir } 1649*cdf0e10cSrcweir else 1650*cdf0e10cSrcweir { 1651*cdf0e10cSrcweir // field member 1652*cdf0e10cSrcweir do 1653*cdf0e10cSrcweir { 1654*cdf0e10cSrcweir ScDPSaveDimension* pDim = aData.GetDimensionByName(aDimName); 1655*cdf0e10cSrcweir if (!pDim) 1656*cdf0e10cSrcweir break; 1657*cdf0e10cSrcweir 1658*cdf0e10cSrcweir ScDPSaveMember* pMem = pDim->GetExistingMemberByName(aPosData.MemberName); 1659*cdf0e10cSrcweir if (!pMem) 1660*cdf0e10cSrcweir break; 1661*cdf0e10cSrcweir 1662*cdf0e10cSrcweir if ((aPosData.Flags & MemberResultFlags::SUBTOTAL)) 1663*cdf0e10cSrcweir { 1664*cdf0e10cSrcweir // Change subtotal only when the table has one data dimension. 1665*cdf0e10cSrcweir if (aData.GetDataDimensionCount() > 1) 1666*cdf0e10cSrcweir break; 1667*cdf0e10cSrcweir 1668*cdf0e10cSrcweir // display name for subtotal is allowed only if the subtotal type is 'Automatic'. 1669*cdf0e10cSrcweir if (pDim->GetSubTotalsCount() != 1) 1670*cdf0e10cSrcweir break; 1671*cdf0e10cSrcweir 1672*cdf0e10cSrcweir if (pDim->GetSubTotalFunc(0) != sheet::GeneralFunction_AUTO) 1673*cdf0e10cSrcweir break; 1674*cdf0e10cSrcweir 1675*cdf0e10cSrcweir const OUString* pLayoutName = pMem->GetLayoutName(); 1676*cdf0e10cSrcweir String aMemberName; 1677*cdf0e10cSrcweir if (pLayoutName) 1678*cdf0e10cSrcweir aMemberName = *pLayoutName; 1679*cdf0e10cSrcweir else 1680*cdf0e10cSrcweir aMemberName = aPosData.MemberName; 1681*cdf0e10cSrcweir 1682*cdf0e10cSrcweir String aNew = lcl_replaceMemberNameInSubtotal(rString, aMemberName); 1683*cdf0e10cSrcweir pDim->SetSubtotalName(aNew); 1684*cdf0e10cSrcweir bChange = true; 1685*cdf0e10cSrcweir } 1686*cdf0e10cSrcweir else 1687*cdf0e10cSrcweir { 1688*cdf0e10cSrcweir // Check to make sure the member name isn't 1689*cdf0e10cSrcweir // already used. 1690*cdf0e10cSrcweir if (rString.Len()) 1691*cdf0e10cSrcweir { 1692*cdf0e10cSrcweir if (rString.EqualsIgnoreCaseAscii(pMem->GetName())) 1693*cdf0e10cSrcweir { 1694*cdf0e10cSrcweir pMem->RemoveLayoutName(); 1695*cdf0e10cSrcweir bChange = true; 1696*cdf0e10cSrcweir } 1697*cdf0e10cSrcweir else if (!pDim->IsMemberNameInUse(rString)) 1698*cdf0e10cSrcweir { 1699*cdf0e10cSrcweir pMem->SetLayoutName(rString); 1700*cdf0e10cSrcweir bChange = true; 1701*cdf0e10cSrcweir } 1702*cdf0e10cSrcweir else 1703*cdf0e10cSrcweir nErrorId = STR_INVALIDNAME; 1704*cdf0e10cSrcweir } 1705*cdf0e10cSrcweir else 1706*cdf0e10cSrcweir nErrorId = STR_INVALIDNAME; 1707*cdf0e10cSrcweir } 1708*cdf0e10cSrcweir } 1709*cdf0e10cSrcweir while (false); 1710*cdf0e10cSrcweir } 1711*cdf0e10cSrcweir } 1712*cdf0e10cSrcweir } 1713*cdf0e10cSrcweir } 1714*cdf0e10cSrcweir 1715*cdf0e10cSrcweir if ( bChange ) 1716*cdf0e10cSrcweir { 1717*cdf0e10cSrcweir // apply changes 1718*cdf0e10cSrcweir ScDBDocFunc aFunc( *GetViewData()->GetDocShell() ); 1719*cdf0e10cSrcweir ScDPObject* pNewObj = new ScDPObject( *pDPObj ); 1720*cdf0e10cSrcweir pNewObj->SetSaveData( aData ); 1721*cdf0e10cSrcweir aFunc.DataPilotUpdate( pDPObj, pNewObj, sal_True, sal_False ); 1722*cdf0e10cSrcweir delete pNewObj; 1723*cdf0e10cSrcweir } 1724*cdf0e10cSrcweir else 1725*cdf0e10cSrcweir { 1726*cdf0e10cSrcweir if ( !nErrorId ) 1727*cdf0e10cSrcweir nErrorId = STR_ERR_DATAPILOT_INPUT; 1728*cdf0e10cSrcweir ErrorMessage( nErrorId ); 1729*cdf0e10cSrcweir } 1730*cdf0e10cSrcweir } 1731*cdf0e10cSrcweir 1732*cdf0e10cSrcweir void lcl_MoveToEnd( ScDPSaveDimension& rDim, const String& rItemName ) 1733*cdf0e10cSrcweir { 1734*cdf0e10cSrcweir ScDPSaveMember* pNewMember = NULL; 1735*cdf0e10cSrcweir const ScDPSaveMember* pOldMember = rDim.GetExistingMemberByName( rItemName ); 1736*cdf0e10cSrcweir if ( pOldMember ) 1737*cdf0e10cSrcweir pNewMember = new ScDPSaveMember( *pOldMember ); 1738*cdf0e10cSrcweir else 1739*cdf0e10cSrcweir pNewMember = new ScDPSaveMember( rItemName ); 1740*cdf0e10cSrcweir rDim.AddMember( pNewMember ); 1741*cdf0e10cSrcweir // AddMember takes ownership of the new pointer, 1742*cdf0e10cSrcweir // puts it to the end of the list even if it was in the list before. 1743*cdf0e10cSrcweir } 1744*cdf0e10cSrcweir 1745*cdf0e10cSrcweir struct ScOUStringCollate 1746*cdf0e10cSrcweir { 1747*cdf0e10cSrcweir CollatorWrapper* mpCollator; 1748*cdf0e10cSrcweir 1749*cdf0e10cSrcweir ScOUStringCollate(CollatorWrapper* pColl) : mpCollator(pColl) {} 1750*cdf0e10cSrcweir 1751*cdf0e10cSrcweir bool operator()(const rtl::OUString& rStr1, const rtl::OUString& rStr2) const 1752*cdf0e10cSrcweir { 1753*cdf0e10cSrcweir return ( mpCollator->compareString(rStr1, rStr2) < 0 ); 1754*cdf0e10cSrcweir } 1755*cdf0e10cSrcweir }; 1756*cdf0e10cSrcweir 1757*cdf0e10cSrcweir bool ScDBFunc::DataPilotSort( const ScAddress& rPos, bool bAscending, sal_uInt16* pUserListId ) 1758*cdf0e10cSrcweir { 1759*cdf0e10cSrcweir ScDocument* pDoc = GetViewData()->GetDocument(); 1760*cdf0e10cSrcweir ScDPObject* pDPObj = pDoc->GetDPAtCursor(rPos.Col(), rPos.Row(), rPos.Tab()); 1761*cdf0e10cSrcweir if (!pDPObj) 1762*cdf0e10cSrcweir return false; 1763*cdf0e10cSrcweir 1764*cdf0e10cSrcweir // We need to run this to get all members later. 1765*cdf0e10cSrcweir if ( pUserListId ) 1766*cdf0e10cSrcweir pDPObj->BuildAllDimensionMembers(); 1767*cdf0e10cSrcweir 1768*cdf0e10cSrcweir sal_uInt16 nOrientation; 1769*cdf0e10cSrcweir long nDimIndex = pDPObj->GetHeaderDim(rPos, nOrientation); 1770*cdf0e10cSrcweir if (nDimIndex < 0) 1771*cdf0e10cSrcweir // Invalid dimension index. Bail out. 1772*cdf0e10cSrcweir return false; 1773*cdf0e10cSrcweir 1774*cdf0e10cSrcweir sal_Bool bDataLayout; 1775*cdf0e10cSrcweir ScDPSaveData* pSaveData = pDPObj->GetSaveData(); 1776*cdf0e10cSrcweir if (!pSaveData) 1777*cdf0e10cSrcweir return false; 1778*cdf0e10cSrcweir 1779*cdf0e10cSrcweir ScDPSaveData aNewSaveData(*pSaveData); 1780*cdf0e10cSrcweir String aDimName = pDPObj->GetDimName(nDimIndex, bDataLayout); 1781*cdf0e10cSrcweir ScDPSaveDimension* pSaveDim = aNewSaveData.GetDimensionByName(aDimName); 1782*cdf0e10cSrcweir if (!pSaveDim) 1783*cdf0e10cSrcweir return false; 1784*cdf0e10cSrcweir 1785*cdf0e10cSrcweir // manual evaluation of sort order is only needed if a user list id is given 1786*cdf0e10cSrcweir if ( pUserListId ) 1787*cdf0e10cSrcweir { 1788*cdf0e10cSrcweir typedef ScDPSaveDimension::MemberList MemList; 1789*cdf0e10cSrcweir const MemList& rDimMembers = pSaveDim->GetMembers(); 1790*cdf0e10cSrcweir list<OUString> aMembers; 1791*cdf0e10cSrcweir hash_set<OUString, ::rtl::OUStringHash> aMemberSet; 1792*cdf0e10cSrcweir size_t nMemberCount = 0; 1793*cdf0e10cSrcweir for (MemList::const_iterator itr = rDimMembers.begin(), itrEnd = rDimMembers.end(); 1794*cdf0e10cSrcweir itr != itrEnd; ++itr) 1795*cdf0e10cSrcweir { 1796*cdf0e10cSrcweir ScDPSaveMember* pMem = *itr; 1797*cdf0e10cSrcweir aMembers.push_back(pMem->GetName()); 1798*cdf0e10cSrcweir aMemberSet.insert(pMem->GetName()); 1799*cdf0e10cSrcweir ++nMemberCount; 1800*cdf0e10cSrcweir } 1801*cdf0e10cSrcweir 1802*cdf0e10cSrcweir // Sort the member list in ascending order. 1803*cdf0e10cSrcweir ScOUStringCollate aCollate( ScGlobal::GetCollator() ); 1804*cdf0e10cSrcweir aMembers.sort(aCollate); 1805*cdf0e10cSrcweir 1806*cdf0e10cSrcweir // Collect and rank those custom sort strings that also exist in the member name list. 1807*cdf0e10cSrcweir 1808*cdf0e10cSrcweir typedef hash_map<OUString, sal_uInt16, OUStringHash> UserSortMap; 1809*cdf0e10cSrcweir UserSortMap aSubStrs; 1810*cdf0e10cSrcweir sal_uInt16 nSubCount = 0; 1811*cdf0e10cSrcweir if (pUserListId) 1812*cdf0e10cSrcweir { 1813*cdf0e10cSrcweir ScUserList* pUserList = ScGlobal::GetUserList(); 1814*cdf0e10cSrcweir if (!pUserList) 1815*cdf0e10cSrcweir return false; 1816*cdf0e10cSrcweir 1817*cdf0e10cSrcweir { 1818*cdf0e10cSrcweir sal_uInt16 n = pUserList->GetCount(); 1819*cdf0e10cSrcweir if (!n || *pUserListId >= n) 1820*cdf0e10cSrcweir return false; 1821*cdf0e10cSrcweir } 1822*cdf0e10cSrcweir 1823*cdf0e10cSrcweir ScUserListData* pData = static_cast<ScUserListData*>((*pUserList)[*pUserListId]); 1824*cdf0e10cSrcweir if (pData) 1825*cdf0e10cSrcweir { 1826*cdf0e10cSrcweir sal_uInt16 n = pData->GetSubCount(); 1827*cdf0e10cSrcweir for (sal_uInt16 i = 0; i < n; ++i) 1828*cdf0e10cSrcweir { 1829*cdf0e10cSrcweir OUString aSub = pData->GetSubStr(i); 1830*cdf0e10cSrcweir if (!aMemberSet.count(aSub)) 1831*cdf0e10cSrcweir // This string doesn't exist in the member name set. Don't add this. 1832*cdf0e10cSrcweir continue; 1833*cdf0e10cSrcweir 1834*cdf0e10cSrcweir aSubStrs.insert(UserSortMap::value_type(aSub, nSubCount++)); 1835*cdf0e10cSrcweir } 1836*cdf0e10cSrcweir } 1837*cdf0e10cSrcweir } 1838*cdf0e10cSrcweir 1839*cdf0e10cSrcweir // Rank all members. 1840*cdf0e10cSrcweir 1841*cdf0e10cSrcweir vector<OUString> aRankedNames(nMemberCount); 1842*cdf0e10cSrcweir sal_uInt16 nCurStrId = 0; 1843*cdf0e10cSrcweir for (list<OUString>::const_iterator itr = aMembers.begin(), itrEnd = aMembers.end(); 1844*cdf0e10cSrcweir itr != itrEnd; ++itr) 1845*cdf0e10cSrcweir { 1846*cdf0e10cSrcweir OUString aName = *itr; 1847*cdf0e10cSrcweir sal_uInt16 nRank = 0; 1848*cdf0e10cSrcweir UserSortMap::const_iterator itrSub = aSubStrs.find(aName); 1849*cdf0e10cSrcweir if (itrSub == aSubStrs.end()) 1850*cdf0e10cSrcweir nRank = nSubCount + nCurStrId++; 1851*cdf0e10cSrcweir else 1852*cdf0e10cSrcweir nRank = itrSub->second; 1853*cdf0e10cSrcweir 1854*cdf0e10cSrcweir if (!bAscending) 1855*cdf0e10cSrcweir nRank = static_cast< sal_uInt16 >( nMemberCount - nRank - 1 ); 1856*cdf0e10cSrcweir 1857*cdf0e10cSrcweir aRankedNames[nRank] = aName; 1858*cdf0e10cSrcweir } 1859*cdf0e10cSrcweir 1860*cdf0e10cSrcweir // Re-order ScDPSaveMember instances with the new ranks. 1861*cdf0e10cSrcweir 1862*cdf0e10cSrcweir for (vector<OUString>::const_iterator itr = aRankedNames.begin(), itrEnd = aRankedNames.end(); 1863*cdf0e10cSrcweir itr != itrEnd; ++itr) 1864*cdf0e10cSrcweir { 1865*cdf0e10cSrcweir const ScDPSaveMember* pOldMem = pSaveDim->GetExistingMemberByName(*itr); 1866*cdf0e10cSrcweir if (!pOldMem) 1867*cdf0e10cSrcweir // All members are supposed to be present. 1868*cdf0e10cSrcweir continue; 1869*cdf0e10cSrcweir 1870*cdf0e10cSrcweir ScDPSaveMember* pNewMem = new ScDPSaveMember(*pOldMem); 1871*cdf0e10cSrcweir pSaveDim->AddMember(pNewMem); 1872*cdf0e10cSrcweir } 1873*cdf0e10cSrcweir 1874*cdf0e10cSrcweir // Set the sorting mode to manual for now. We may introduce a new sorting 1875*cdf0e10cSrcweir // mode later on. 1876*cdf0e10cSrcweir 1877*cdf0e10cSrcweir sheet::DataPilotFieldSortInfo aSortInfo; 1878*cdf0e10cSrcweir aSortInfo.Mode = sheet::DataPilotFieldSortMode::MANUAL; 1879*cdf0e10cSrcweir pSaveDim->SetSortInfo(&aSortInfo); 1880*cdf0e10cSrcweir } 1881*cdf0e10cSrcweir else 1882*cdf0e10cSrcweir { 1883*cdf0e10cSrcweir // without user list id, just apply sorting mode 1884*cdf0e10cSrcweir 1885*cdf0e10cSrcweir sheet::DataPilotFieldSortInfo aSortInfo; 1886*cdf0e10cSrcweir aSortInfo.Mode = sheet::DataPilotFieldSortMode::NAME; 1887*cdf0e10cSrcweir aSortInfo.IsAscending = bAscending; 1888*cdf0e10cSrcweir pSaveDim->SetSortInfo(&aSortInfo); 1889*cdf0e10cSrcweir } 1890*cdf0e10cSrcweir 1891*cdf0e10cSrcweir // Update the datapilot with the newly sorted field members. 1892*cdf0e10cSrcweir 1893*cdf0e10cSrcweir auto_ptr<ScDPObject> pNewObj(new ScDPObject(*pDPObj)); 1894*cdf0e10cSrcweir pNewObj->SetSaveData(aNewSaveData); 1895*cdf0e10cSrcweir ScDBDocFunc aFunc(*GetViewData()->GetDocShell()); 1896*cdf0e10cSrcweir 1897*cdf0e10cSrcweir return aFunc.DataPilotUpdate(pDPObj, pNewObj.get(), true, false); 1898*cdf0e10cSrcweir } 1899*cdf0e10cSrcweir 1900*cdf0e10cSrcweir sal_Bool ScDBFunc::DataPilotMove( const ScRange& rSource, const ScAddress& rDest ) 1901*cdf0e10cSrcweir { 1902*cdf0e10cSrcweir sal_Bool bRet = sal_False; 1903*cdf0e10cSrcweir ScDocument* pDoc = GetViewData()->GetDocument(); 1904*cdf0e10cSrcweir ScDPObject* pDPObj = pDoc->GetDPAtCursor( rSource.aStart.Col(), rSource.aStart.Row(), rSource.aStart.Tab() ); 1905*cdf0e10cSrcweir if ( pDPObj && pDPObj == pDoc->GetDPAtCursor( rDest.Col(), rDest.Row(), rDest.Tab() ) ) 1906*cdf0e10cSrcweir { 1907*cdf0e10cSrcweir sheet::DataPilotTableHeaderData aDestData; 1908*cdf0e10cSrcweir pDPObj->GetHeaderPositionData( rDest, aDestData ); 1909*cdf0e10cSrcweir bool bValid = ( aDestData.Dimension >= 0 ); // dropping onto a field 1910*cdf0e10cSrcweir 1911*cdf0e10cSrcweir // look through the source range 1912*cdf0e10cSrcweir std::hash_set< rtl::OUString, rtl::OUStringHash, std::equal_to<rtl::OUString> > aMembersSet; // for lookup 1913*cdf0e10cSrcweir std::vector< rtl::OUString > aMembersVector; // members in original order, for inserting 1914*cdf0e10cSrcweir aMembersVector.reserve( std::max( static_cast<SCSIZE>( rSource.aEnd.Col() - rSource.aStart.Col() + 1 ), 1915*cdf0e10cSrcweir static_cast<SCSIZE>( rSource.aEnd.Row() - rSource.aStart.Row() + 1 ) ) ); 1916*cdf0e10cSrcweir for (SCROW nRow = rSource.aStart.Row(); bValid && nRow <= rSource.aEnd.Row(); ++nRow ) 1917*cdf0e10cSrcweir for (SCCOL nCol = rSource.aStart.Col(); bValid && nCol <= rSource.aEnd.Col(); ++nCol ) 1918*cdf0e10cSrcweir { 1919*cdf0e10cSrcweir sheet::DataPilotTableHeaderData aSourceData; 1920*cdf0e10cSrcweir pDPObj->GetHeaderPositionData( ScAddress( nCol, nRow, rSource.aStart.Tab() ), aSourceData ); 1921*cdf0e10cSrcweir if ( aSourceData.Dimension == aDestData.Dimension && aSourceData.MemberName.getLength() ) 1922*cdf0e10cSrcweir { 1923*cdf0e10cSrcweir if ( aMembersSet.find( aSourceData.MemberName ) == aMembersSet.end() ) 1924*cdf0e10cSrcweir { 1925*cdf0e10cSrcweir aMembersSet.insert( aSourceData.MemberName ); 1926*cdf0e10cSrcweir aMembersVector.push_back( aSourceData.MemberName ); 1927*cdf0e10cSrcweir } 1928*cdf0e10cSrcweir // duplicates are ignored 1929*cdf0e10cSrcweir } 1930*cdf0e10cSrcweir else 1931*cdf0e10cSrcweir bValid = false; // empty (subtotal) or different field 1932*cdf0e10cSrcweir } 1933*cdf0e10cSrcweir 1934*cdf0e10cSrcweir if ( bValid ) 1935*cdf0e10cSrcweir { 1936*cdf0e10cSrcweir sal_Bool bIsDataLayout; 1937*cdf0e10cSrcweir String aDimName = pDPObj->GetDimName( aDestData.Dimension, bIsDataLayout ); 1938*cdf0e10cSrcweir if ( !bIsDataLayout ) 1939*cdf0e10cSrcweir { 1940*cdf0e10cSrcweir ScDPSaveData aData( *pDPObj->GetSaveData() ); 1941*cdf0e10cSrcweir ScDPSaveDimension* pDim = aData.GetDimensionByName( aDimName ); 1942*cdf0e10cSrcweir 1943*cdf0e10cSrcweir // get all member names in source order 1944*cdf0e10cSrcweir uno::Sequence<rtl::OUString> aMemberNames; 1945*cdf0e10cSrcweir pDPObj->GetMemberNames( aDestData.Dimension, aMemberNames ); 1946*cdf0e10cSrcweir 1947*cdf0e10cSrcweir bool bInserted = false; 1948*cdf0e10cSrcweir 1949*cdf0e10cSrcweir sal_Int32 nMemberCount = aMemberNames.getLength(); 1950*cdf0e10cSrcweir for (sal_Int32 nMemberPos=0; nMemberPos<nMemberCount; ++nMemberPos) 1951*cdf0e10cSrcweir { 1952*cdf0e10cSrcweir String aMemberStr( aMemberNames[nMemberPos] ); 1953*cdf0e10cSrcweir 1954*cdf0e10cSrcweir if ( !bInserted && aMemberNames[nMemberPos] == aDestData.MemberName ) 1955*cdf0e10cSrcweir { 1956*cdf0e10cSrcweir // insert dragged items before this item 1957*cdf0e10cSrcweir for ( std::vector<rtl::OUString>::const_iterator aIter = aMembersVector.begin(); 1958*cdf0e10cSrcweir aIter != aMembersVector.end(); ++aIter ) 1959*cdf0e10cSrcweir lcl_MoveToEnd( *pDim, *aIter ); 1960*cdf0e10cSrcweir bInserted = true; 1961*cdf0e10cSrcweir } 1962*cdf0e10cSrcweir 1963*cdf0e10cSrcweir if ( aMembersSet.find( aMemberStr ) == aMembersSet.end() ) // skip dragged items 1964*cdf0e10cSrcweir lcl_MoveToEnd( *pDim, aMemberStr ); 1965*cdf0e10cSrcweir } 1966*cdf0e10cSrcweir // insert dragged item at end if dest wasn't found (for example, empty) 1967*cdf0e10cSrcweir if ( !bInserted ) 1968*cdf0e10cSrcweir for ( std::vector<rtl::OUString>::const_iterator aIter = aMembersVector.begin(); 1969*cdf0e10cSrcweir aIter != aMembersVector.end(); ++aIter ) 1970*cdf0e10cSrcweir lcl_MoveToEnd( *pDim, *aIter ); 1971*cdf0e10cSrcweir 1972*cdf0e10cSrcweir // Items that were in SaveData, but not in the source, end up at the start of the list. 1973*cdf0e10cSrcweir 1974*cdf0e10cSrcweir // set flag for manual sorting 1975*cdf0e10cSrcweir sheet::DataPilotFieldSortInfo aSortInfo; 1976*cdf0e10cSrcweir aSortInfo.Mode = sheet::DataPilotFieldSortMode::MANUAL; 1977*cdf0e10cSrcweir pDim->SetSortInfo( &aSortInfo ); 1978*cdf0e10cSrcweir 1979*cdf0e10cSrcweir // apply changes 1980*cdf0e10cSrcweir ScDBDocFunc aFunc( *GetViewData()->GetDocShell() ); 1981*cdf0e10cSrcweir ScDPObject* pNewObj = new ScDPObject( *pDPObj ); 1982*cdf0e10cSrcweir pNewObj->SetSaveData( aData ); 1983*cdf0e10cSrcweir aFunc.DataPilotUpdate( pDPObj, pNewObj, sal_True, sal_False ); //! bApi for drag&drop? 1984*cdf0e10cSrcweir delete pNewObj; 1985*cdf0e10cSrcweir 1986*cdf0e10cSrcweir Unmark(); // entry was moved - no use in leaving the old cell selected 1987*cdf0e10cSrcweir 1988*cdf0e10cSrcweir bRet = sal_True; 1989*cdf0e10cSrcweir } 1990*cdf0e10cSrcweir } 1991*cdf0e10cSrcweir } 1992*cdf0e10cSrcweir 1993*cdf0e10cSrcweir return bRet; 1994*cdf0e10cSrcweir } 1995*cdf0e10cSrcweir 1996*cdf0e10cSrcweir sal_Bool ScDBFunc::HasSelectionForDrillDown( sal_uInt16& rOrientation ) 1997*cdf0e10cSrcweir { 1998*cdf0e10cSrcweir sal_Bool bRet = sal_False; 1999*cdf0e10cSrcweir 2000*cdf0e10cSrcweir ScDPObject* pDPObj = GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(), 2001*cdf0e10cSrcweir GetViewData()->GetCurY(), GetViewData()->GetTabNo() ); 2002*cdf0e10cSrcweir if ( pDPObj ) 2003*cdf0e10cSrcweir { 2004*cdf0e10cSrcweir ScStrCollection aEntries; 2005*cdf0e10cSrcweir long nSelectDimension = -1; 2006*cdf0e10cSrcweir GetSelectedMemberList( aEntries, nSelectDimension ); 2007*cdf0e10cSrcweir 2008*cdf0e10cSrcweir if ( aEntries.GetCount() > 0 ) 2009*cdf0e10cSrcweir { 2010*cdf0e10cSrcweir sal_Bool bIsDataLayout; 2011*cdf0e10cSrcweir String aDimName = pDPObj->GetDimName( nSelectDimension, bIsDataLayout ); 2012*cdf0e10cSrcweir if ( !bIsDataLayout ) 2013*cdf0e10cSrcweir { 2014*cdf0e10cSrcweir ScDPSaveData* pSaveData = pDPObj->GetSaveData(); 2015*cdf0e10cSrcweir ScDPSaveDimension* pDim = pSaveData->GetExistingDimensionByName( aDimName ); 2016*cdf0e10cSrcweir if ( pDim ) 2017*cdf0e10cSrcweir { 2018*cdf0e10cSrcweir sal_uInt16 nDimOrient = pDim->GetOrientation(); 2019*cdf0e10cSrcweir ScDPSaveDimension* pInner = pSaveData->GetInnermostDimension( nDimOrient ); 2020*cdf0e10cSrcweir if ( pDim == pInner ) 2021*cdf0e10cSrcweir { 2022*cdf0e10cSrcweir rOrientation = nDimOrient; 2023*cdf0e10cSrcweir bRet = sal_True; 2024*cdf0e10cSrcweir } 2025*cdf0e10cSrcweir } 2026*cdf0e10cSrcweir } 2027*cdf0e10cSrcweir } 2028*cdf0e10cSrcweir } 2029*cdf0e10cSrcweir 2030*cdf0e10cSrcweir return bRet; 2031*cdf0e10cSrcweir } 2032*cdf0e10cSrcweir 2033*cdf0e10cSrcweir void ScDBFunc::SetDataPilotDetails( sal_Bool bShow, const String* pNewDimensionName ) 2034*cdf0e10cSrcweir { 2035*cdf0e10cSrcweir ScDPObject* pDPObj = GetViewData()->GetDocument()->GetDPAtCursor( GetViewData()->GetCurX(), 2036*cdf0e10cSrcweir GetViewData()->GetCurY(), GetViewData()->GetTabNo() ); 2037*cdf0e10cSrcweir if ( pDPObj ) 2038*cdf0e10cSrcweir { 2039*cdf0e10cSrcweir ScStrCollection aEntries; 2040*cdf0e10cSrcweir long nSelectDimension = -1; 2041*cdf0e10cSrcweir GetSelectedMemberList( aEntries, nSelectDimension ); 2042*cdf0e10cSrcweir 2043*cdf0e10cSrcweir if ( aEntries.GetCount() > 0 ) 2044*cdf0e10cSrcweir { 2045*cdf0e10cSrcweir sal_Bool bIsDataLayout; 2046*cdf0e10cSrcweir String aDimName = pDPObj->GetDimName( nSelectDimension, bIsDataLayout ); 2047*cdf0e10cSrcweir if ( !bIsDataLayout ) 2048*cdf0e10cSrcweir { 2049*cdf0e10cSrcweir ScDPSaveData aData( *pDPObj->GetSaveData() ); 2050*cdf0e10cSrcweir ScDPSaveDimension* pDim = aData.GetDimensionByName( aDimName ); 2051*cdf0e10cSrcweir 2052*cdf0e10cSrcweir if ( bShow && pNewDimensionName ) 2053*cdf0e10cSrcweir { 2054*cdf0e10cSrcweir // add the new dimension with the same orientation, at the end 2055*cdf0e10cSrcweir 2056*cdf0e10cSrcweir ScDPSaveDimension* pNewDim = aData.GetDimensionByName( *pNewDimensionName ); 2057*cdf0e10cSrcweir ScDPSaveDimension* pDuplicated = NULL; 2058*cdf0e10cSrcweir if ( pNewDim->GetOrientation() == sheet::DataPilotFieldOrientation_DATA ) 2059*cdf0e10cSrcweir { 2060*cdf0e10cSrcweir // Need to duplicate the dimension, create column/row in addition to data: 2061*cdf0e10cSrcweir // The duplicated dimension inherits the existing settings, pNewDim is modified below. 2062*cdf0e10cSrcweir pDuplicated = aData.DuplicateDimension( *pNewDimensionName ); 2063*cdf0e10cSrcweir } 2064*cdf0e10cSrcweir 2065*cdf0e10cSrcweir sal_uInt16 nOrientation = pDim->GetOrientation(); 2066*cdf0e10cSrcweir pNewDim->SetOrientation( nOrientation ); 2067*cdf0e10cSrcweir 2068*cdf0e10cSrcweir long nPosition = LONG_MAX; 2069*cdf0e10cSrcweir aData.SetPosition( pNewDim, nPosition ); 2070*cdf0e10cSrcweir 2071*cdf0e10cSrcweir ScDPSaveDimension* pDataLayout = aData.GetDataLayoutDimension(); 2072*cdf0e10cSrcweir if ( pDataLayout->GetOrientation() == nOrientation && 2073*cdf0e10cSrcweir aData.GetDataDimensionCount() <= 1 ) 2074*cdf0e10cSrcweir { 2075*cdf0e10cSrcweir // If there is only one data dimension, the data layout dimension 2076*cdf0e10cSrcweir // must still be the last one in its orientation. 2077*cdf0e10cSrcweir aData.SetPosition( pDataLayout, nPosition ); 2078*cdf0e10cSrcweir } 2079*cdf0e10cSrcweir 2080*cdf0e10cSrcweir if ( pDuplicated ) 2081*cdf0e10cSrcweir { 2082*cdf0e10cSrcweir // The duplicated (data) dimension needs to be behind the original dimension 2083*cdf0e10cSrcweir aData.SetPosition( pDuplicated, nPosition ); 2084*cdf0e10cSrcweir } 2085*cdf0e10cSrcweir 2086*cdf0e10cSrcweir // Hide details for all visible members (selected are changed below). 2087*cdf0e10cSrcweir //! Use all members from source level instead (including non-visible)? 2088*cdf0e10cSrcweir 2089*cdf0e10cSrcweir ScStrCollection aVisibleEntries; 2090*cdf0e10cSrcweir pDPObj->GetMemberResultNames( aVisibleEntries, nSelectDimension ); 2091*cdf0e10cSrcweir 2092*cdf0e10cSrcweir sal_uInt16 nVisCount = aVisibleEntries.GetCount(); 2093*cdf0e10cSrcweir for (sal_uInt16 nVisPos=0; nVisPos<nVisCount; nVisPos++) 2094*cdf0e10cSrcweir { 2095*cdf0e10cSrcweir String aVisName = aVisibleEntries[nVisPos]->GetString(); 2096*cdf0e10cSrcweir ScDPSaveMember* pMember = pDim->GetMemberByName( aVisName ); 2097*cdf0e10cSrcweir pMember->SetShowDetails( sal_False ); 2098*cdf0e10cSrcweir } 2099*cdf0e10cSrcweir } 2100*cdf0e10cSrcweir 2101*cdf0e10cSrcweir sal_uInt16 nEntryCount = aEntries.GetCount(); 2102*cdf0e10cSrcweir for (sal_uInt16 nEntry=0; nEntry<nEntryCount; nEntry++) 2103*cdf0e10cSrcweir { 2104*cdf0e10cSrcweir String aEntryName = aEntries[nEntry]->GetString(); 2105*cdf0e10cSrcweir ScDPSaveMember* pMember = pDim->GetMemberByName( aEntryName ); 2106*cdf0e10cSrcweir pMember->SetShowDetails( bShow ); 2107*cdf0e10cSrcweir } 2108*cdf0e10cSrcweir 2109*cdf0e10cSrcweir // apply changes 2110*cdf0e10cSrcweir ScDBDocFunc aFunc( *GetViewData()->GetDocShell() ); 2111*cdf0e10cSrcweir ScDPObject* pNewObj = new ScDPObject( *pDPObj ); 2112*cdf0e10cSrcweir pNewObj->SetSaveData( aData ); 2113*cdf0e10cSrcweir aFunc.DataPilotUpdate( pDPObj, pNewObj, sal_True, sal_False ); 2114*cdf0e10cSrcweir delete pNewObj; 2115*cdf0e10cSrcweir 2116*cdf0e10cSrcweir // unmark cell selection 2117*cdf0e10cSrcweir Unmark(); 2118*cdf0e10cSrcweir } 2119*cdf0e10cSrcweir } 2120*cdf0e10cSrcweir } 2121*cdf0e10cSrcweir } 2122*cdf0e10cSrcweir 2123*cdf0e10cSrcweir void ScDBFunc::ShowDataPilotSourceData( ScDPObject& rDPObj, const Sequence<sheet::DataPilotFieldFilter>& rFilters ) 2124*cdf0e10cSrcweir { 2125*cdf0e10cSrcweir ScDocument* pDoc = GetViewData()->GetDocument(); 2126*cdf0e10cSrcweir if (pDoc->GetDocumentShell()->IsReadOnly()) 2127*cdf0e10cSrcweir { 2128*cdf0e10cSrcweir ErrorMessage(STR_READONLYERR); 2129*cdf0e10cSrcweir return; 2130*cdf0e10cSrcweir } 2131*cdf0e10cSrcweir 2132*cdf0e10cSrcweir Reference<sheet::XDimensionsSupplier> xDimSupplier = rDPObj.GetSource(); 2133*cdf0e10cSrcweir Reference<container::XNameAccess> xDims = xDimSupplier->getDimensions(); 2134*cdf0e10cSrcweir Reference<sheet::XDrillDownDataSupplier> xDDSupplier(xDimSupplier, UNO_QUERY); 2135*cdf0e10cSrcweir if (!xDDSupplier.is()) 2136*cdf0e10cSrcweir return; 2137*cdf0e10cSrcweir 2138*cdf0e10cSrcweir Sequence< Sequence<Any> > aTabData = xDDSupplier->getDrillDownData(rFilters); 2139*cdf0e10cSrcweir sal_Int32 nRowSize = aTabData.getLength(); 2140*cdf0e10cSrcweir if (nRowSize <= 1) 2141*cdf0e10cSrcweir // There is no data to show. Bail out. 2142*cdf0e10cSrcweir return; 2143*cdf0e10cSrcweir 2144*cdf0e10cSrcweir sal_Int32 nColSize = aTabData[0].getLength(); 2145*cdf0e10cSrcweir 2146*cdf0e10cSrcweir SCTAB nNewTab = GetViewData()->GetTabNo(); 2147*cdf0e10cSrcweir 2148*cdf0e10cSrcweir auto_ptr<ScDocument> pInsDoc(new ScDocument(SCDOCMODE_CLIP)); 2149*cdf0e10cSrcweir pInsDoc->ResetClip( pDoc, nNewTab ); 2150*cdf0e10cSrcweir for (SCROW nRow = 0; nRow < nRowSize; ++nRow) 2151*cdf0e10cSrcweir { 2152*cdf0e10cSrcweir for (SCCOL nCol = 0; nCol < nColSize; ++nCol) 2153*cdf0e10cSrcweir { 2154*cdf0e10cSrcweir const Any& rAny = aTabData[nRow][nCol]; 2155*cdf0e10cSrcweir rtl::OUString aStr; 2156*cdf0e10cSrcweir double fVal; 2157*cdf0e10cSrcweir if (rAny >>= aStr) 2158*cdf0e10cSrcweir pInsDoc->PutCell( ScAddress(nCol, nRow, nNewTab), new ScStringCell(String(aStr)) ); 2159*cdf0e10cSrcweir else if (rAny >>= fVal) 2160*cdf0e10cSrcweir pInsDoc->SetValue(nCol, nRow, nNewTab, fVal); 2161*cdf0e10cSrcweir } 2162*cdf0e10cSrcweir } 2163*cdf0e10cSrcweir 2164*cdf0e10cSrcweir // set number format (important for dates) 2165*cdf0e10cSrcweir for (SCCOL nCol = 0; nCol < nColSize; ++nCol) 2166*cdf0e10cSrcweir { 2167*cdf0e10cSrcweir rtl::OUString aStr; 2168*cdf0e10cSrcweir if (!(aTabData[0][nCol] >>= aStr)) 2169*cdf0e10cSrcweir continue; 2170*cdf0e10cSrcweir 2171*cdf0e10cSrcweir Reference<XPropertySet> xPropSet(xDims->getByName(aStr), UNO_QUERY); 2172*cdf0e10cSrcweir if (!xPropSet.is()) 2173*cdf0e10cSrcweir continue; 2174*cdf0e10cSrcweir 2175*cdf0e10cSrcweir Any any = xPropSet->getPropertyValue( rtl::OUString::createFromAscii(SC_UNO_NUMBERFO) ); 2176*cdf0e10cSrcweir sal_Int32 nNumFmt = 0; 2177*cdf0e10cSrcweir if (!(any >>= nNumFmt)) 2178*cdf0e10cSrcweir continue; 2179*cdf0e10cSrcweir 2180*cdf0e10cSrcweir ScPatternAttr aPattern( pInsDoc->GetPool() ); 2181*cdf0e10cSrcweir aPattern.GetItemSet().Put( SfxUInt32Item(ATTR_VALUE_FORMAT, static_cast<sal_uInt32>(nNumFmt)) ); 2182*cdf0e10cSrcweir pInsDoc->ApplyPatternAreaTab(nCol, 1, nCol, nRowSize-1, nNewTab, aPattern); 2183*cdf0e10cSrcweir } 2184*cdf0e10cSrcweir 2185*cdf0e10cSrcweir SCCOL nEndCol = 0; 2186*cdf0e10cSrcweir SCROW nEndRow = 0; 2187*cdf0e10cSrcweir pInsDoc->GetCellArea( nNewTab, nEndCol, nEndRow ); 2188*cdf0e10cSrcweir pInsDoc->SetClipArea( ScRange( 0, 0, nNewTab, nEndCol, nEndRow, nNewTab ) ); 2189*cdf0e10cSrcweir 2190*cdf0e10cSrcweir ::svl::IUndoManager* pMgr = GetViewData()->GetDocShell()->GetUndoManager(); 2191*cdf0e10cSrcweir String aUndo = ScGlobal::GetRscString( STR_UNDO_DOOUTLINE ); 2192*cdf0e10cSrcweir pMgr->EnterListAction( aUndo, aUndo ); 2193*cdf0e10cSrcweir 2194*cdf0e10cSrcweir String aNewTabName; 2195*cdf0e10cSrcweir pDoc->CreateValidTabName(aNewTabName); 2196*cdf0e10cSrcweir if ( InsertTable(aNewTabName, nNewTab) ) 2197*cdf0e10cSrcweir PasteFromClip( IDF_ALL, pInsDoc.get() ); 2198*cdf0e10cSrcweir 2199*cdf0e10cSrcweir pMgr->LeaveListAction(); 2200*cdf0e10cSrcweir } 2201*cdf0e10cSrcweir 2202*cdf0e10cSrcweir // 2203*cdf0e10cSrcweir // DB-Operationen (Sortieren, Filtern, Teilergebnisse) wiederholen 2204*cdf0e10cSrcweir // 2205*cdf0e10cSrcweir 2206*cdf0e10cSrcweir void ScDBFunc::RepeatDB( sal_Bool bRecord ) 2207*cdf0e10cSrcweir { 2208*cdf0e10cSrcweir SCCOL nCurX = GetViewData()->GetCurX(); 2209*cdf0e10cSrcweir SCROW nCurY = GetViewData()->GetCurY(); 2210*cdf0e10cSrcweir SCTAB nTab = GetViewData()->GetTabNo(); 2211*cdf0e10cSrcweir ScDocument* pDoc = GetViewData()->GetDocument(); 2212*cdf0e10cSrcweir ScDBData* pDBData = GetDBData(); 2213*cdf0e10cSrcweir if (bRecord && !pDoc->IsUndoEnabled()) 2214*cdf0e10cSrcweir bRecord = sal_False; 2215*cdf0e10cSrcweir 2216*cdf0e10cSrcweir ScQueryParam aQueryParam; 2217*cdf0e10cSrcweir pDBData->GetQueryParam( aQueryParam ); 2218*cdf0e10cSrcweir sal_Bool bQuery = aQueryParam.GetEntry(0).bDoQuery; 2219*cdf0e10cSrcweir 2220*cdf0e10cSrcweir ScSortParam aSortParam; 2221*cdf0e10cSrcweir pDBData->GetSortParam( aSortParam ); 2222*cdf0e10cSrcweir sal_Bool bSort = aSortParam.bDoSort[0]; 2223*cdf0e10cSrcweir 2224*cdf0e10cSrcweir ScSubTotalParam aSubTotalParam; 2225*cdf0e10cSrcweir pDBData->GetSubTotalParam( aSubTotalParam ); 2226*cdf0e10cSrcweir sal_Bool bSubTotal = aSubTotalParam.bGroupActive[0] && !aSubTotalParam.bRemoveOnly; 2227*cdf0e10cSrcweir 2228*cdf0e10cSrcweir if ( bQuery || bSort || bSubTotal ) 2229*cdf0e10cSrcweir { 2230*cdf0e10cSrcweir sal_Bool bQuerySize = sal_False; 2231*cdf0e10cSrcweir ScRange aOldQuery; 2232*cdf0e10cSrcweir ScRange aNewQuery; 2233*cdf0e10cSrcweir if (bQuery && !aQueryParam.bInplace) 2234*cdf0e10cSrcweir { 2235*cdf0e10cSrcweir ScDBData* pDest = pDoc->GetDBAtCursor( aQueryParam.nDestCol, aQueryParam.nDestRow, 2236*cdf0e10cSrcweir aQueryParam.nDestTab, sal_True ); 2237*cdf0e10cSrcweir if (pDest && pDest->IsDoSize()) 2238*cdf0e10cSrcweir { 2239*cdf0e10cSrcweir pDest->GetArea( aOldQuery ); 2240*cdf0e10cSrcweir bQuerySize = sal_True; 2241*cdf0e10cSrcweir } 2242*cdf0e10cSrcweir } 2243*cdf0e10cSrcweir 2244*cdf0e10cSrcweir SCTAB nDummy; 2245*cdf0e10cSrcweir SCCOL nStartCol; 2246*cdf0e10cSrcweir SCROW nStartRow; 2247*cdf0e10cSrcweir SCCOL nEndCol; 2248*cdf0e10cSrcweir SCROW nEndRow; 2249*cdf0e10cSrcweir pDBData->GetArea( nDummy, nStartCol, nStartRow, nEndCol, nEndRow ); 2250*cdf0e10cSrcweir 2251*cdf0e10cSrcweir //! Undo nur benoetigte Daten ? 2252*cdf0e10cSrcweir 2253*cdf0e10cSrcweir ScDocument* pUndoDoc = NULL; 2254*cdf0e10cSrcweir ScOutlineTable* pUndoTab = NULL; 2255*cdf0e10cSrcweir ScRangeName* pUndoRange = NULL; 2256*cdf0e10cSrcweir ScDBCollection* pUndoDB = NULL; 2257*cdf0e10cSrcweir 2258*cdf0e10cSrcweir if (bRecord) 2259*cdf0e10cSrcweir { 2260*cdf0e10cSrcweir SCTAB nTabCount = pDoc->GetTableCount(); 2261*cdf0e10cSrcweir pUndoDoc = new ScDocument( SCDOCMODE_UNDO ); 2262*cdf0e10cSrcweir ScOutlineTable* pTable = pDoc->GetOutlineTable( nTab ); 2263*cdf0e10cSrcweir if (pTable) 2264*cdf0e10cSrcweir { 2265*cdf0e10cSrcweir pUndoTab = new ScOutlineTable( *pTable ); 2266*cdf0e10cSrcweir 2267*cdf0e10cSrcweir SCCOLROW nOutStartCol; // Zeilen/Spaltenstatus 2268*cdf0e10cSrcweir SCCOLROW nOutStartRow; 2269*cdf0e10cSrcweir SCCOLROW nOutEndCol; 2270*cdf0e10cSrcweir SCCOLROW nOutEndRow; 2271*cdf0e10cSrcweir pTable->GetColArray()->GetRange( nOutStartCol, nOutEndCol ); 2272*cdf0e10cSrcweir pTable->GetRowArray()->GetRange( nOutStartRow, nOutEndRow ); 2273*cdf0e10cSrcweir 2274*cdf0e10cSrcweir pUndoDoc->InitUndo( pDoc, nTab, nTab, sal_True, sal_True ); 2275*cdf0e10cSrcweir pDoc->CopyToDocument( static_cast<SCCOL>(nOutStartCol), 0, nTab, static_cast<SCCOL>(nOutEndCol), MAXROW, nTab, IDF_NONE, sal_False, pUndoDoc ); 2276*cdf0e10cSrcweir pDoc->CopyToDocument( 0, nOutStartRow, nTab, MAXCOL, nOutEndRow, nTab, IDF_NONE, sal_False, pUndoDoc ); 2277*cdf0e10cSrcweir } 2278*cdf0e10cSrcweir else 2279*cdf0e10cSrcweir pUndoDoc->InitUndo( pDoc, nTab, nTab, sal_False, sal_True ); 2280*cdf0e10cSrcweir 2281*cdf0e10cSrcweir // Datenbereich sichern - incl. Filter-Ergebnis 2282*cdf0e10cSrcweir pDoc->CopyToDocument( 0,nStartRow,nTab, MAXCOL,nEndRow,nTab, IDF_ALL, sal_False, pUndoDoc ); 2283*cdf0e10cSrcweir 2284*cdf0e10cSrcweir // alle Formeln wegen Referenzen 2285*cdf0e10cSrcweir pDoc->CopyToDocument( 0,0,0, MAXCOL,MAXROW,nTabCount-1, IDF_FORMULA, sal_False, pUndoDoc ); 2286*cdf0e10cSrcweir 2287*cdf0e10cSrcweir // DB- und andere Bereiche 2288*cdf0e10cSrcweir ScRangeName* pDocRange = pDoc->GetRangeName(); 2289*cdf0e10cSrcweir if (pDocRange->GetCount()) 2290*cdf0e10cSrcweir pUndoRange = new ScRangeName( *pDocRange ); 2291*cdf0e10cSrcweir ScDBCollection* pDocDB = pDoc->GetDBCollection(); 2292*cdf0e10cSrcweir if (pDocDB->GetCount()) 2293*cdf0e10cSrcweir pUndoDB = new ScDBCollection( *pDocDB ); 2294*cdf0e10cSrcweir } 2295*cdf0e10cSrcweir 2296*cdf0e10cSrcweir if (bSort && bSubTotal) 2297*cdf0e10cSrcweir { 2298*cdf0e10cSrcweir // Sortieren ohne SubTotals 2299*cdf0e10cSrcweir 2300*cdf0e10cSrcweir aSubTotalParam.bRemoveOnly = sal_True; // wird unten wieder zurueckgesetzt 2301*cdf0e10cSrcweir DoSubTotals( aSubTotalParam, sal_False ); 2302*cdf0e10cSrcweir } 2303*cdf0e10cSrcweir 2304*cdf0e10cSrcweir if (bSort) 2305*cdf0e10cSrcweir { 2306*cdf0e10cSrcweir pDBData->GetSortParam( aSortParam ); // Bereich kann sich geaendert haben 2307*cdf0e10cSrcweir Sort( aSortParam, sal_False, sal_False); 2308*cdf0e10cSrcweir } 2309*cdf0e10cSrcweir if (bQuery) 2310*cdf0e10cSrcweir { 2311*cdf0e10cSrcweir pDBData->GetQueryParam( aQueryParam ); // Bereich kann sich geaendert haben 2312*cdf0e10cSrcweir ScRange aAdvSource; 2313*cdf0e10cSrcweir if (pDBData->GetAdvancedQuerySource(aAdvSource)) 2314*cdf0e10cSrcweir { 2315*cdf0e10cSrcweir pDoc->CreateQueryParam( 2316*cdf0e10cSrcweir aAdvSource.aStart.Col(), aAdvSource.aStart.Row(), 2317*cdf0e10cSrcweir aAdvSource.aEnd.Col(), aAdvSource.aEnd.Row(), 2318*cdf0e10cSrcweir aAdvSource.aStart.Tab(), aQueryParam ); 2319*cdf0e10cSrcweir Query( aQueryParam, &aAdvSource, sal_False ); 2320*cdf0e10cSrcweir } 2321*cdf0e10cSrcweir else 2322*cdf0e10cSrcweir Query( aQueryParam, NULL, sal_False ); 2323*cdf0e10cSrcweir 2324*cdf0e10cSrcweir // bei nicht-inplace kann die Tabelle umgestellt worden sein 2325*cdf0e10cSrcweir if ( !aQueryParam.bInplace && aQueryParam.nDestTab != nTab ) 2326*cdf0e10cSrcweir SetTabNo( nTab ); 2327*cdf0e10cSrcweir } 2328*cdf0e10cSrcweir if (bSubTotal) 2329*cdf0e10cSrcweir { 2330*cdf0e10cSrcweir pDBData->GetSubTotalParam( aSubTotalParam ); // Bereich kann sich geaendert haben 2331*cdf0e10cSrcweir aSubTotalParam.bRemoveOnly = sal_False; 2332*cdf0e10cSrcweir DoSubTotals( aSubTotalParam, sal_False ); 2333*cdf0e10cSrcweir } 2334*cdf0e10cSrcweir 2335*cdf0e10cSrcweir if (bRecord) 2336*cdf0e10cSrcweir { 2337*cdf0e10cSrcweir SCTAB nDummyTab; 2338*cdf0e10cSrcweir SCCOL nDummyCol; 2339*cdf0e10cSrcweir SCROW nDummyRow, nNewEndRow; 2340*cdf0e10cSrcweir pDBData->GetArea( nDummyTab, nDummyCol,nDummyRow, nDummyCol,nNewEndRow ); 2341*cdf0e10cSrcweir 2342*cdf0e10cSrcweir const ScRange* pOld = NULL; 2343*cdf0e10cSrcweir const ScRange* pNew = NULL; 2344*cdf0e10cSrcweir if (bQuerySize) 2345*cdf0e10cSrcweir { 2346*cdf0e10cSrcweir ScDBData* pDest = pDoc->GetDBAtCursor( aQueryParam.nDestCol, aQueryParam.nDestRow, 2347*cdf0e10cSrcweir aQueryParam.nDestTab, sal_True ); 2348*cdf0e10cSrcweir if (pDest) 2349*cdf0e10cSrcweir { 2350*cdf0e10cSrcweir pDest->GetArea( aNewQuery ); 2351*cdf0e10cSrcweir pOld = &aOldQuery; 2352*cdf0e10cSrcweir pNew = &aNewQuery; 2353*cdf0e10cSrcweir } 2354*cdf0e10cSrcweir } 2355*cdf0e10cSrcweir 2356*cdf0e10cSrcweir GetViewData()->GetDocShell()->GetUndoManager()->AddUndoAction( 2357*cdf0e10cSrcweir new ScUndoRepeatDB( GetViewData()->GetDocShell(), nTab, 2358*cdf0e10cSrcweir nStartCol, nStartRow, nEndCol, nEndRow, 2359*cdf0e10cSrcweir nNewEndRow, 2360*cdf0e10cSrcweir nCurX, nCurY, 2361*cdf0e10cSrcweir pUndoDoc, pUndoTab, 2362*cdf0e10cSrcweir pUndoRange, pUndoDB, 2363*cdf0e10cSrcweir pOld, pNew ) ); 2364*cdf0e10cSrcweir } 2365*cdf0e10cSrcweir 2366*cdf0e10cSrcweir GetViewData()->GetDocShell()->PostPaint( 0,0,nTab, MAXCOL,MAXROW,nTab, 2367*cdf0e10cSrcweir PAINT_GRID | PAINT_LEFT | PAINT_TOP | PAINT_SIZE ); 2368*cdf0e10cSrcweir } 2369*cdf0e10cSrcweir else // "Keine Operationen auszufuehren" 2370*cdf0e10cSrcweir ErrorMessage(STR_MSSG_REPEATDB_0); 2371*cdf0e10cSrcweir } 2372*cdf0e10cSrcweir 2373*cdf0e10cSrcweir 2374*cdf0e10cSrcweir 2375*cdf0e10cSrcweir 2376