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