Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*************************************************************************
3 : *
4 : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : *
6 : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : *
8 : * OpenOffice.org - a multi-platform office productivity suite
9 : *
10 : * This file is part of OpenOffice.org.
11 : *
12 : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : * it under the terms of the GNU Lesser General Public License version 3
14 : * only, as published by the Free Software Foundation.
15 : *
16 : * OpenOffice.org is distributed in the hope that it will be useful,
17 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : * GNU Lesser General Public License version 3 for more details
20 : * (a copy is included in the LICENSE file that accompanied this code).
21 : *
22 : * You should have received a copy of the GNU Lesser General Public License
23 : * version 3 along with OpenOffice.org. If not, see
24 : * <http://www.openoffice.org/license.html>
25 : * for a copy of the LGPLv3 License.
26 : *
27 : * This file incorporates work covered by the following license notice:
28 : *
29 : * Licensed to the Apache Software Foundation (ASF) under one or more
30 : * contributor license agreements. See the NOTICE file distributed
31 : * with this work for additional information regarding copyright
32 : * ownership. The ASF licenses this file to you under the Apache
33 : * License, Version 2.0 (the "License"); you may not use this file
34 : * except in compliance with the License. You may obtain a copy of
35 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
36 : ************************************************************************/
37 :
38 : #include "pvlaydlg.hxx"
39 : #include "dpuiglobal.hxx"
40 :
41 : #include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
42 : #include <com/sun/star/sheet/DataPilotFieldSortMode.hpp>
43 :
44 : #include <sfx2/dispatch.hxx>
45 : #include <vcl/msgbox.hxx>
46 :
47 : #include "dbdocfun.hxx"
48 : #include "uiitems.hxx"
49 : #include "rangeutl.hxx"
50 : #include "document.hxx"
51 : #include "viewdata.hxx"
52 : #include "tabvwsh.hxx"
53 : #include "reffact.hxx"
54 : #include "scresid.hxx"
55 : #include "globstr.hrc"
56 : #include "pivot.hrc"
57 : #include "dpobject.hxx"
58 : #include "dpsave.hxx"
59 : #include "dpshttab.hxx"
60 : #include "scmod.hxx"
61 :
62 : #include "sc.hrc"
63 : #include "scabstdlg.hxx"
64 :
65 : #include <boost/scoped_ptr.hpp>
66 :
67 : using namespace com::sun::star;
68 : using ::rtl::OUString;
69 : using ::std::vector;
70 : using ::std::for_each;
71 :
72 : namespace {
73 :
74 : const sal_uInt16 STD_FORMAT = sal_uInt16( SCA_VALID | SCA_TAB_3D | SCA_COL_ABSOLUTE | SCA_ROW_ABSOLUTE | SCA_TAB_ABSOLUTE );
75 :
76 0 : Point DlgPos2WndPos( const Point& rPt, const Window& rWnd )
77 : {
78 0 : Point aWndPt( rPt );
79 0 : aWndPt.X() = rPt.X()-rWnd.GetPosPixel().X();
80 0 : aWndPt.Y() = rPt.Y()-rWnd.GetPosPixel().Y();
81 :
82 0 : return aWndPt;
83 : }
84 :
85 : } // namespace
86 :
87 0 : ScPivotLayoutDlg::ScPivotLayoutDlg( SfxBindings* pB, SfxChildWindow* pCW, Window* pParent, const ScDPObject& rDPObject, bool bNewOutput ) :
88 : ScAnyRefDlg( pB, pCW, pParent, RID_SCDLG_PIVOT_LAYOUT ),
89 :
90 : maFlLayout( this, ScResId( FL_LAYOUT ) ),
91 : maFtPage( this, ScResId( FT_PAGE ) ),
92 : maWndPage( this, ScResId( WND_PAGE ), &maFtPage, HID_SC_DPLAY_PAGE ),
93 : maFtCol( this, ScResId( FT_COL ) ),
94 : maWndCol( this, ScResId( WND_COL ), &maFtCol, HID_SC_DPLAY_COLUMN ),
95 : maFtRow( this, ScResId( FT_ROW ) ),
96 : maWndRow( this, ScResId( WND_ROW ), &maFtRow, HID_SC_DPLAY_ROW ),
97 : maFtData( this, ScResId( FT_DATA ) ),
98 : maWndData( this, ScResId( WND_DATA ), &maFtData, HID_SC_DPLAY_DATA ),
99 : maWndSelect( this, ScResId( WND_SELECT ), NULL, HID_SC_DPLAY_SELECT ),
100 : maFtInfo( this, ScResId( FT_INFO ) ),
101 :
102 : maFlAreas( this, ScResId( FL_OUTPUT ) ),
103 : maFtInArea( this, ScResId( FT_INAREA) ),
104 : maEdInPos( this, this, ScResId( ED_INAREA) ),
105 : maRbInPos( this, ScResId( RB_INAREA ), &maEdInPos, this ),
106 : maLbOutPos( this, ScResId( LB_OUTAREA ) ),
107 : maFtOutArea( this, ScResId( FT_OUTAREA ) ),
108 : maEdOutPos( this, this, ScResId( ED_OUTAREA ) ),
109 : maRbOutPos( this, ScResId( RB_OUTAREA ), &maEdOutPos, this ),
110 : maBtnIgnEmptyRows( this, ScResId( BTN_IGNEMPTYROWS ) ),
111 : maBtnDetectCat( this, ScResId( BTN_DETECTCAT ) ),
112 : maBtnTotalCol( this, ScResId( BTN_TOTALCOL ) ),
113 : maBtnTotalRow( this, ScResId( BTN_TOTALROW ) ),
114 : maBtnFilter( this, ScResId( BTN_FILTER ) ),
115 : maBtnDrillDown( this, ScResId( BTN_DRILLDOWN ) ),
116 :
117 : maBtnOk( this, ScResId( BTN_OK ) ),
118 : maBtnCancel( this, ScResId( BTN_CANCEL ) ),
119 : maBtnHelp( this, ScResId( BTN_HELP ) ),
120 : maBtnRemove( this, ScResId( BTN_REMOVE ) ),
121 : maBtnOptions( this, ScResId( BTN_OPTIONS ) ),
122 : maBtnMore( this, ScResId( BTN_MORE ) ),
123 :
124 0 : mxDlgDPObject( new ScDPObject( rDPObject ) ),
125 0 : mpViewData( ((ScTabViewShell*)SfxViewShell::Current())->GetViewData() ),
126 0 : mpDoc( ((ScTabViewShell*)SfxViewShell::Current())->GetViewData()->GetDocument() ),
127 : mpRefInputEdit(NULL),
128 :
129 : maStrUndefined(SC_RESSTR(SCSTR_UNDEFINED)),
130 : maStrNewTable(SC_RESSTR(SCSTR_NEWTABLE)),
131 : mbIsDrag(false),
132 : meLastActiveType(PIVOTFIELDTYPE_SELECT),
133 : mnOffset(0),
134 0 : mbRefInputMode( false )
135 : {
136 0 : mxDlgDPObject->SetAlive( true ); // needed to get structure information
137 0 : mxDlgDPObject->FillOldParam( maPivotData );
138 0 : mxDlgDPObject->FillLabelData( maPivotData );
139 :
140 0 : maBtnRemove.SetClickHdl( LINK( this, ScPivotLayoutDlg, ClickHdl ) );
141 0 : maBtnOptions.SetClickHdl( LINK( this, ScPivotLayoutDlg, ClickHdl ) );
142 :
143 0 : maFuncNames.reserve( PIVOT_MAXFUNC );
144 0 : for ( sal_uInt16 i = 1; i <= PIVOT_MAXFUNC; ++i )
145 0 : maFuncNames.push_back(ScResId(i).toString());
146 :
147 0 : maBtnMore.AddWindow( &maFlAreas );
148 0 : maBtnMore.AddWindow( &maFtInArea );
149 0 : maBtnMore.AddWindow( &maEdInPos );
150 0 : maBtnMore.AddWindow( &maRbInPos );
151 0 : maBtnMore.AddWindow( &maFtOutArea );
152 0 : maBtnMore.AddWindow( &maLbOutPos );
153 0 : maBtnMore.AddWindow( &maEdOutPos );
154 0 : maBtnMore.AddWindow( &maRbOutPos );
155 0 : maBtnMore.AddWindow( &maBtnIgnEmptyRows );
156 0 : maBtnMore.AddWindow( &maBtnDetectCat );
157 0 : maBtnMore.AddWindow( &maBtnTotalCol );
158 0 : maBtnMore.AddWindow( &maBtnTotalRow );
159 0 : maBtnMore.AddWindow( &maBtnFilter );
160 0 : maBtnMore.AddWindow( &maBtnDrillDown );
161 0 : maBtnMore.SetClickHdl( LINK( this, ScPivotLayoutDlg, MoreClickHdl ) );
162 :
163 0 : maFieldCtrls.reserve(5);
164 0 : maFieldCtrls.push_back(&maWndPage);
165 0 : maFieldCtrls.push_back(&maWndCol);
166 0 : maFieldCtrls.push_back(&maWndRow);
167 0 : maFieldCtrls.push_back(&maWndData);
168 0 : maFieldCtrls.push_back(&maWndSelect);
169 :
170 0 : InitControlAndDlgSizes();
171 :
172 0 : if (mxDlgDPObject->GetSheetDesc())
173 : {
174 0 : maEdInPos.Enable();
175 0 : maRbInPos.Enable();
176 0 : const ScSheetSourceDesc* p = mxDlgDPObject->GetSheetDesc();
177 0 : OUString aRangeName = p->GetRangeName();
178 0 : if (!aRangeName.isEmpty())
179 0 : maEdInPos.SetText(aRangeName);
180 : else
181 : {
182 0 : rtl::OUString aStr;
183 0 : maOldRange = p->GetSourceRange();
184 0 : maOldRange.Format(aStr, SCR_ABS_3D, mpDoc, mpDoc->GetAddressConvention());
185 0 : maEdInPos.SetText(aStr);
186 0 : }
187 : }
188 : else
189 : {
190 : // data is not reachable, so could be a remote database
191 0 : maEdInPos.Disable();
192 0 : maRbInPos.Disable();
193 : }
194 :
195 0 : InitFieldWindows();
196 :
197 0 : maLbOutPos.SetSelectHdl( LINK( this, ScPivotLayoutDlg, SelAreaHdl ) );
198 0 : maEdOutPos.SetModifyHdl( LINK( this, ScPivotLayoutDlg, EdOutModifyHdl ) );
199 0 : maEdInPos.SetModifyHdl( LINK( this, ScPivotLayoutDlg, EdInModifyHdl ) );
200 0 : maBtnOk.SetClickHdl( LINK( this, ScPivotLayoutDlg, OkHdl ) );
201 0 : maBtnCancel.SetClickHdl( LINK( this, ScPivotLayoutDlg, CancelHdl ) );
202 :
203 : // Set focus handler for the reference edit text boxes.
204 0 : Link aGetFocusLink = LINK(this, ScPivotLayoutDlg, GetRefEditFocusHdl);
205 0 : if (maEdInPos.IsEnabled())
206 0 : maEdInPos.SetGetFocusHdl(aGetFocusLink);
207 0 : maEdOutPos.SetGetFocusHdl(aGetFocusLink);
208 :
209 0 : if ( mpViewData && mpDoc )
210 : {
211 : /*
212 : * Aus den RangeNames des Dokumentes werden nun die
213 : * in einem Zeiger-Array gemerkt, bei denen es sich
214 : * um sinnvolle Bereiche handelt
215 : */
216 :
217 0 : maLbOutPos.Clear();
218 0 : maLbOutPos.InsertEntry( maStrUndefined, 0 );
219 0 : maLbOutPos.InsertEntry( maStrNewTable, 1 );
220 :
221 0 : ScAreaNameIterator aIter( mpDoc );
222 0 : rtl::OUString aName;
223 0 : ScRange aRange;
224 0 : rtl::OUString aRefStr;
225 0 : while ( aIter.Next( aName, aRange ) )
226 : {
227 0 : if ( !aIter.WasDBName() ) // hier keine DB-Bereiche !
228 : {
229 0 : sal_uInt16 nInsert = maLbOutPos.InsertEntry( aName );
230 :
231 0 : aRange.aStart.Format( aRefStr, SCA_ABS_3D, mpDoc, mpDoc->GetAddressConvention() );
232 0 : maRefStrs.push_back(new OUString(aRefStr));
233 0 : maLbOutPos.SetEntryData(nInsert, &maRefStrs.back());
234 : }
235 0 : }
236 : }
237 :
238 0 : if (bNewOutput)
239 : {
240 : // Output to a new sheet by default for a brand-new output.
241 0 : maLbOutPos.SelectEntryPos(1);
242 0 : maEdOutPos.Disable();
243 0 : maRbOutPos.Disable();
244 : }
245 : else
246 : {
247 : // Modifying an existing dp output.
248 :
249 0 : if ( maPivotData.nTab != MAXTAB+1 )
250 : {
251 0 : rtl::OUString aStr;
252 : ScAddress( maPivotData.nCol,
253 : maPivotData.nRow,
254 0 : maPivotData.nTab ).Format( aStr, STD_FORMAT, mpDoc, mpDoc->GetAddressConvention() );
255 0 : maEdOutPos.SetText( aStr );
256 0 : maOutputRefStr = aStr;
257 0 : EdOutModifyHdl(0);
258 : }
259 : else
260 : {
261 0 : maLbOutPos.SelectEntryPos( maLbOutPos.GetEntryCount()-1 );
262 0 : SelAreaHdl(NULL);
263 : }
264 : }
265 :
266 0 : maBtnIgnEmptyRows.Check( maPivotData.bIgnoreEmptyRows );
267 0 : maBtnDetectCat .Check( maPivotData.bDetectCategories );
268 0 : maBtnTotalCol .Check( maPivotData.bMakeTotalCol );
269 0 : maBtnTotalRow .Check( maPivotData.bMakeTotalRow );
270 :
271 0 : const ScDPSaveData* pSaveData = mxDlgDPObject->GetSaveData();
272 0 : maBtnFilter.Check( !pSaveData || pSaveData->GetFilterButton() );
273 0 : maBtnDrillDown.Check( !pSaveData || pSaveData->GetDrillDown() );
274 :
275 0 : GrabFieldFocus( maWndSelect );
276 :
277 0 : FreeResource();
278 0 : }
279 :
280 0 : ScPivotLayoutDlg::~ScPivotLayoutDlg()
281 : {
282 0 : }
283 :
284 0 : sal_Bool ScPivotLayoutDlg::Close()
285 : {
286 0 : return DoClose( ScPivotLayoutWrapper::GetChildWindowId() );
287 : }
288 :
289 0 : void ScPivotLayoutDlg::InitWndSelect(const ScDPLabelDataVector& rLabels)
290 : {
291 0 : size_t nLabelCount = rLabels.size();
292 0 : if (nLabelCount > SC_DP_MAX_FIELDS)
293 0 : nLabelCount = SC_DP_MAX_FIELDS;
294 :
295 0 : maLabelData.clear();
296 0 : maLabelData.reserve( nLabelCount );
297 0 : for ( size_t i=0; i < nLabelCount; i++ )
298 : {
299 0 : const ScDPLabelData& r = rLabels[i];
300 :
301 0 : maLabelData.push_back(new ScDPLabelData(r));
302 0 : if (r.mnOriginalDim < 0 && !r.mbDataLayout)
303 : {
304 : // For dimension with duplicates, use the layout name of the
305 : // original dimension if available. Be aware that duplicate
306 : // dimensions may have different layout names.
307 0 : ScPivotFuncData aFunc(maLabelData[i].mnCol, maLabelData[i].mnFuncMask);
308 0 : maWndSelect.AppendField(maLabelData[i].getDisplayName(), aFunc);
309 : }
310 : }
311 0 : maWndSelect.ResetScrollBar();
312 0 : maWndSelect.Paint(Rectangle());
313 0 : }
314 :
315 0 : void ScPivotLayoutDlg::InitWndData(const vector<ScPivotField>& rFields)
316 : {
317 0 : vector<ScPivotField>::const_iterator it = rFields.begin(), itEnd = rFields.end();
318 0 : for (; it != itEnd; ++it)
319 : {
320 0 : SCCOL nCol = it->nCol;
321 0 : sal_uInt16 nMask = it->nFuncMask;
322 0 : if (nCol == PIVOT_DATA_FIELD)
323 0 : continue;
324 :
325 : // data field - we need to concatenate function name with the field name.
326 0 : ScDPLabelData* pData = GetLabelData(nCol);
327 : OSL_ENSURE( pData, "ScDPLabelData not found" );
328 0 : if (pData)
329 : {
330 0 : ScPivotFuncData aFunc(nCol, it->mnOriginalDim, nMask, it->mnDupCount, it->maFieldRef);
331 0 : OUString aStr = pData->maLayoutName;
332 0 : if (aStr.isEmpty())
333 : {
334 0 : aStr = GetFuncString(aFunc.mnFuncMask, pData->mbIsValue);
335 0 : aStr += pData->maName;
336 : }
337 :
338 0 : maWndData.AppendField(aStr, aFunc);
339 0 : pData->mnFuncMask = nMask;
340 : }
341 : }
342 0 : maWndData.ResetScrollBar();
343 0 : }
344 :
345 0 : void ScPivotLayoutDlg::InitFieldWindow( const vector<ScPivotField>& rFields, ScPivotFieldType eType )
346 : {
347 : OSL_ASSERT(eType != PIVOTFIELDTYPE_DATA);
348 0 : ScDPFieldControlBase* pInitWnd = GetFieldWindow(eType);
349 :
350 0 : if (!pInitWnd)
351 0 : return;
352 :
353 0 : vector<ScPivotField>::const_iterator itr = rFields.begin(), itrEnd = rFields.end();
354 0 : for (; itr != itrEnd; ++itr)
355 : {
356 0 : SCCOL nCol = itr->nCol;
357 0 : sal_uInt16 nMask = itr->nFuncMask;
358 0 : if (nCol == PIVOT_DATA_FIELD)
359 0 : continue;
360 :
361 0 : ScPivotFuncData aFunc(nCol, itr->mnOriginalDim, nMask, itr->mnDupCount, itr->maFieldRef);
362 0 : pInitWnd->AppendField(GetLabelString(nCol), aFunc);
363 0 : }
364 0 : pInitWnd->ResetScrollBar();
365 : }
366 :
367 0 : void ScPivotLayoutDlg::InitFieldWindows()
368 : {
369 0 : InitWndSelect(maPivotData.maLabelArray);
370 0 : InitFieldWindow(maPivotData.maPageFields, PIVOTFIELDTYPE_PAGE);
371 0 : InitFieldWindow(maPivotData.maColFields, PIVOTFIELDTYPE_COL);
372 0 : InitFieldWindow(maPivotData.maRowFields, PIVOTFIELDTYPE_ROW);
373 0 : InitWndData(maPivotData.maDataFields);
374 0 : }
375 :
376 0 : void ScPivotLayoutDlg::GrabFieldFocus( ScDPFieldControlBase& rFieldWindow )
377 : {
378 0 : if( rFieldWindow.IsEmpty() )
379 : {
380 0 : if( maWndSelect.IsEmpty() )
381 0 : maBtnOk.GrabFocus();
382 : else
383 0 : maWndSelect.GrabFocus();
384 : }
385 : else
386 0 : rFieldWindow.GrabFocus();
387 0 : }
388 :
389 0 : void ScPivotLayoutDlg::AddField( size_t nFromIndex, ScPivotFieldType eToType, const Point& rAtPos )
390 : {
391 0 : ScPivotFuncData aFunc = maWndSelect.GetFuncData(nFromIndex); // local copy
392 :
393 0 : bool bAllowed = IsOrientationAllowed(aFunc.mnCol, eToType);
394 0 : if (!bAllowed)
395 : return;
396 :
397 0 : size_t nAt = 0;
398 0 : ScDPFieldControlBase* toWnd = GetFieldWindow(eToType);
399 0 : ScDPFieldControlBase* rmWnd1 = NULL;
400 0 : ScDPFieldControlBase* rmWnd2 = NULL;
401 0 : GetOtherFieldWindows(eToType, rmWnd1, rmWnd2);
402 :
403 0 : if (eToType == PIVOTFIELDTYPE_DATA)
404 : {
405 : // Data field allows duplicates.
406 0 : ScDPLabelData* p = GetLabelData(aFunc.mnCol);
407 0 : OUString aStr = p->maLayoutName;
408 0 : sal_uInt16 nMask = aFunc.mnFuncMask;
409 0 : if (nMask == PIVOT_FUNC_NONE)
410 0 : nMask = PIVOT_FUNC_SUM; // Use SUM by default.
411 0 : if (aStr.isEmpty())
412 : {
413 0 : aStr = GetFuncString(nMask);
414 0 : aStr += p->maName;
415 : }
416 :
417 0 : aFunc.mnFuncMask = nMask;
418 0 : size_t nAddedAt = toWnd->AddField(aStr, DlgPos2WndPos(rAtPos, *toWnd), aFunc);
419 0 : if (nAddedAt != PIVOTFIELD_INVALID)
420 0 : toWnd->GrabFocus();
421 :
422 0 : return;
423 : }
424 :
425 0 : nAt = toWnd->GetFieldIndexByData(aFunc);
426 0 : if (nAt == PIVOTFIELD_INVALID)
427 : {
428 0 : if (rmWnd1)
429 : {
430 0 : nAt = rmWnd1->GetFieldIndexByData(aFunc);
431 0 : if (nAt != PIVOTFIELD_INVALID)
432 0 : rmWnd1->DeleteFieldByIndex(nAt);
433 : }
434 0 : if (rmWnd2)
435 : {
436 0 : nAt = rmWnd2->GetFieldIndexByData(aFunc);
437 0 : if (nAt != PIVOTFIELD_INVALID)
438 0 : rmWnd2->DeleteFieldByIndex(nAt);
439 : }
440 :
441 0 : const ScDPLabelData& rData = maLabelData[nFromIndex+mnOffset];
442 0 : size_t nAddedAt = toWnd->AddField(rData.getDisplayName(), DlgPos2WndPos(rAtPos, *toWnd), aFunc);
443 0 : if (nAddedAt != PIVOTFIELD_INVALID)
444 0 : toWnd->GrabFocus();
445 0 : }
446 : }
447 :
448 0 : void ScPivotLayoutDlg::AppendField(size_t nFromIndex, ScPivotFieldType eToType)
449 : {
450 0 : ScPivotFuncData aFunc = maWndSelect.GetFuncData(nFromIndex); // local copy
451 :
452 0 : size_t nAt = 0;
453 0 : ScDPFieldControlBase* toWnd = GetFieldWindow(eToType);
454 0 : ScDPFieldControlBase* rmWnd1 = NULL;
455 0 : ScDPFieldControlBase* rmWnd2 = NULL;
456 0 : GetOtherFieldWindows(eToType, rmWnd1, rmWnd2);
457 :
458 0 : bool bDataArr = eToType == PIVOTFIELDTYPE_DATA;
459 :
460 0 : nAt = toWnd->GetFieldIndexByData(aFunc);
461 0 : if (nAt == PIVOTFIELD_INVALID)
462 : {
463 0 : if (rmWnd1)
464 : {
465 0 : nAt = rmWnd1->GetFieldIndexByData(aFunc);
466 0 : if (nAt != PIVOTFIELD_INVALID)
467 0 : rmWnd1->DeleteFieldByIndex(nAt);
468 : }
469 0 : if (rmWnd2)
470 : {
471 0 : nAt = rmWnd2->GetFieldIndexByData(aFunc);
472 0 : if (nAt != PIVOTFIELD_INVALID)
473 0 : rmWnd2->DeleteFieldByIndex(nAt);
474 : }
475 :
476 0 : ScDPLabelData& rData = maLabelData[nFromIndex+mnOffset];
477 :
478 0 : if ( !bDataArr )
479 : {
480 0 : toWnd->AppendField(rData.getDisplayName(), aFunc);
481 0 : toWnd->GrabFocus();
482 : }
483 : else
484 : {
485 0 : ScDPLabelData* p = GetLabelData(aFunc.mnCol);
486 0 : OUString aStr = p->maLayoutName;
487 0 : sal_uInt16 nMask = aFunc.mnFuncMask;
488 0 : if (aStr.isEmpty())
489 : {
490 0 : aStr = GetFuncString(nMask);
491 0 : aStr += p->maName;
492 : }
493 :
494 0 : aFunc.mnFuncMask = nMask;
495 0 : toWnd->AppendField(aStr, aFunc);
496 0 : toWnd->GrabFocus();
497 : }
498 0 : }
499 0 : }
500 :
501 0 : void ScPivotLayoutDlg::MoveField( ScPivotFieldType eFromType, size_t nFromIndex, ScPivotFieldType eToType, const Point& rAtPos )
502 : {
503 0 : if ( eFromType == PIVOTFIELDTYPE_SELECT )
504 0 : AddField( nFromIndex, eToType, rAtPos );
505 0 : else if (eFromType != PIVOTFIELDTYPE_SELECT && eToType == PIVOTFIELDTYPE_SELECT)
506 0 : RemoveField(eFromType, nFromIndex);
507 0 : else if ( eFromType != eToType )
508 : {
509 0 : ScDPFieldControlBase* fromWnd = GetFieldWindow(eFromType);
510 0 : ScDPFieldControlBase* toWnd = GetFieldWindow(eToType);
511 :
512 0 : ScDPFieldControlBase* rmWnd1 = NULL;
513 0 : ScDPFieldControlBase* rmWnd2 = NULL;
514 0 : GetOtherFieldWindows(eToType, rmWnd1, rmWnd2);
515 :
516 0 : bool bDataArr = eToType == PIVOTFIELDTYPE_DATA;
517 :
518 0 : if (fromWnd && toWnd)
519 : {
520 0 : ScPivotFuncData aFunc = fromWnd->GetFuncData(nFromIndex); // local copy
521 0 : bool bAllowed = IsOrientationAllowed(aFunc.mnCol, eToType);
522 :
523 0 : size_t nAt = fromWnd->GetFieldIndexByData(aFunc);
524 0 : if (bAllowed && nAt != PIVOTFIELD_INVALID)
525 : {
526 0 : fromWnd->DeleteFieldByIndex(nAt);
527 :
528 0 : nAt = toWnd->GetFieldIndexByData(aFunc);
529 0 : if (nAt == PIVOTFIELD_INVALID)
530 : {
531 0 : size_t nAddedAt = 0;
532 0 : if ( !bDataArr )
533 : {
534 0 : if (rmWnd1)
535 : {
536 0 : nAt = rmWnd1->GetFieldIndexByData(aFunc);
537 0 : if (nAt != PIVOTFIELD_INVALID)
538 0 : rmWnd1->DeleteFieldByIndex(nAt);
539 : }
540 0 : if (rmWnd2)
541 : {
542 0 : nAt = rmWnd2->GetFieldIndexByData(aFunc);
543 0 : if (nAt != PIVOTFIELD_INVALID)
544 0 : rmWnd2->DeleteFieldByIndex(nAt);
545 : }
546 :
547 : nAddedAt = toWnd->AddField(
548 0 : GetLabelString(aFunc.mnCol), DlgPos2WndPos(rAtPos, *toWnd), aFunc);
549 0 : if (nAddedAt != PIVOTFIELD_INVALID)
550 0 : toWnd->GrabFocus();
551 : }
552 : else
553 : {
554 0 : ScDPLabelData* p = GetLabelData(aFunc.mnCol);
555 0 : OUString aStr = p->maLayoutName;
556 0 : sal_uInt16 nMask = aFunc.mnFuncMask;
557 0 : if (aStr.isEmpty())
558 : {
559 0 : aStr = GetFuncString(nMask);
560 0 : aStr += p->maName;
561 : }
562 :
563 0 : aFunc.mnFuncMask = nMask;
564 0 : nAddedAt = toWnd->AddField(aStr, DlgPos2WndPos(rAtPos, *toWnd), aFunc);
565 0 : if (nAddedAt != PIVOTFIELD_INVALID)
566 0 : toWnd->GrabFocus();
567 : }
568 : }
569 0 : }
570 : }
571 : }
572 : else // -> eFromType == eToType
573 : {
574 0 : ScDPFieldControlBase* pWnd = GetFieldWindow(eFromType);
575 0 : if (!pWnd)
576 0 : return;
577 :
578 0 : const ScPivotFuncData& rFunc = pWnd->GetFuncData(nFromIndex);
579 :
580 0 : size_t nAt = pWnd->GetFieldIndexByData(rFunc);
581 0 : if (nAt != PIVOTFIELD_INVALID)
582 : {
583 0 : Point aToPos = DlgPos2WndPos( rAtPos, *pWnd );
584 0 : size_t nToIndex = 0;
585 0 : pWnd->GetExistingIndex(aToPos, nToIndex);
586 :
587 0 : if ( nToIndex != nAt )
588 : {
589 0 : size_t nAddedAt = 0;
590 0 : pWnd->MoveField(nAt, aToPos, nAddedAt);
591 : }
592 : }
593 : }
594 : }
595 :
596 0 : void ScPivotLayoutDlg::MoveFieldToEnd( ScPivotFieldType eFromType, size_t nFromIndex, ScPivotFieldType eToType )
597 : {
598 0 : if ( eFromType == PIVOTFIELDTYPE_SELECT )
599 0 : AppendField( nFromIndex, eToType );
600 0 : else if ( eFromType != eToType )
601 : {
602 0 : ScDPFieldControlBase* fromWnd = GetFieldWindow(eFromType);
603 0 : ScDPFieldControlBase* toWnd = GetFieldWindow(eToType);
604 :
605 0 : ScDPFieldControlBase* rmWnd1 = NULL;
606 0 : ScDPFieldControlBase* rmWnd2 = NULL;
607 0 : GetOtherFieldWindows(eToType, rmWnd1, rmWnd2);
608 :
609 0 : bool bDataArr = eToType == PIVOTFIELDTYPE_DATA;
610 :
611 0 : if (!fromWnd || !toWnd)
612 : return;
613 :
614 0 : ScPivotFuncData aFunc = fromWnd->GetFuncData(nFromIndex); // local copy
615 :
616 0 : size_t nAt = fromWnd->GetFieldIndexByData(aFunc);
617 0 : if (nAt != PIVOTFIELD_INVALID)
618 : {
619 0 : fromWnd->DeleteFieldByIndex(nAt);
620 :
621 0 : nAt = toWnd->GetFieldIndexByData(aFunc);
622 0 : if (nAt == PIVOTFIELD_INVALID)
623 : {
624 0 : if ( !bDataArr )
625 : {
626 0 : if (rmWnd1)
627 : {
628 0 : nAt = rmWnd1->GetFieldIndexByData(aFunc);
629 0 : if (nAt != PIVOTFIELD_INVALID)
630 0 : rmWnd1->DeleteFieldByIndex(nAt);
631 : }
632 0 : if (rmWnd2)
633 : {
634 0 : nAt = rmWnd2->GetFieldIndexByData(aFunc);
635 0 : if (nAt != PIVOTFIELD_INVALID)
636 0 : rmWnd2->DeleteFieldByIndex(nAt);
637 : }
638 :
639 0 : toWnd->AppendField(GetLabelString(aFunc.mnCol), aFunc);
640 0 : toWnd->GrabFocus();
641 : }
642 : else
643 : {
644 0 : ScDPLabelData* p = GetLabelData(aFunc.mnCol);
645 0 : OUString aStr = p->maLayoutName;
646 0 : sal_uInt16 nMask = aFunc.mnFuncMask;
647 0 : if (aStr.isEmpty())
648 : {
649 0 : aStr = GetFuncString(nMask);
650 0 : aStr += p->maName;
651 : }
652 :
653 0 : aFunc.mnFuncMask = nMask;
654 0 : toWnd->AppendField(aStr, aFunc);
655 0 : toWnd->GrabFocus();
656 : }
657 : }
658 0 : }
659 : }
660 : else // -> eFromType == eToType
661 : {
662 0 : ScDPFieldControlBase* pWnd = GetFieldWindow(eFromType);
663 0 : if (!pWnd)
664 : return;
665 :
666 0 : Point aToPos;
667 0 : bool bDataArr = eFromType == PIVOTFIELDTYPE_DATA;
668 :
669 0 : ScPivotFuncData aFunc = pWnd->GetFuncData(nFromIndex); // local copy
670 0 : size_t nAt = pWnd->GetFieldIndexByData(aFunc);
671 0 : if (nAt != PIVOTFIELD_INVALID)
672 : {
673 0 : size_t nToIndex = 0;
674 0 : pWnd->GetExistingIndex( aToPos, nToIndex );
675 :
676 0 : if ( nToIndex != nAt )
677 : {
678 0 : pWnd->DeleteFieldByIndex(nAt);
679 :
680 0 : if ( !bDataArr )
681 0 : pWnd->AppendField(GetLabelString(aFunc.mnCol), aFunc);
682 : else
683 : {
684 0 : ScDPLabelData* p = GetLabelData(aFunc.mnCol);
685 0 : OUString aStr = p->maLayoutName;
686 0 : sal_uInt16 nMask = aFunc.mnFuncMask;
687 0 : if (aStr.isEmpty())
688 : {
689 0 : aStr = GetFuncString(nMask);
690 0 : aStr += p->maName;
691 : }
692 :
693 0 : aFunc.mnFuncMask = nMask;
694 0 : pWnd->AppendField(aStr, aFunc);
695 : }
696 : }
697 0 : }
698 : }
699 : }
700 :
701 0 : void ScPivotLayoutDlg::RemoveField( ScPivotFieldType eFromType, size_t nIndex )
702 : {
703 0 : ScDPFieldControlBase* pWnd = GetFieldWindow(eFromType);
704 0 : if (!pWnd)
705 0 : return;
706 :
707 0 : if (nIndex >= pWnd->GetFieldCount())
708 : // out of bound
709 0 : return;
710 :
711 0 : pWnd->DeleteFieldByIndex(nIndex);
712 0 : if (pWnd->IsEmpty())
713 0 : GrabFieldFocus(maWndSelect);
714 : }
715 :
716 0 : PointerStyle ScPivotLayoutDlg::NotifyMouseButtonDown( ScPivotFieldType eType, size_t nFieldIndex )
717 : {
718 0 : mbIsDrag = true;
719 0 : meDnDFromType = eType;
720 0 : mnDnDFromIndex = nFieldIndex;
721 :
722 0 : switch (eType)
723 : {
724 : case PIVOTFIELDTYPE_PAGE:
725 0 : return POINTER_PIVOT_FIELD;
726 : case PIVOTFIELDTYPE_COL:
727 0 : return POINTER_PIVOT_COL;
728 : case PIVOTFIELDTYPE_ROW:
729 0 : return POINTER_PIVOT_ROW;
730 : case PIVOTFIELDTYPE_DATA:
731 0 : return POINTER_PIVOT_FIELD;
732 : case PIVOTFIELDTYPE_SELECT:
733 0 : return POINTER_PIVOT_FIELD;
734 : default:
735 : ;
736 : }
737 0 : return POINTER_ARROW;
738 : }
739 :
740 0 : void ScPivotLayoutDlg::NotifyDoubleClick( ScPivotFieldType eType, size_t nFieldIndex )
741 : {
742 0 : ScDPFieldControlBase* pWnd = GetFieldWindow(eType);
743 0 : if (!pWnd)
744 0 : return;
745 :
746 0 : if (nFieldIndex >= pWnd->GetFieldCount())
747 : {
748 : OSL_FAIL("invalid selection");
749 0 : return;
750 : }
751 :
752 0 : ScPivotFuncData& rFunc = pWnd->GetFuncData(nFieldIndex);
753 0 : ScDPLabelData* pData = GetLabelData(rFunc.mnCol);
754 0 : if (!pData)
755 0 : return;
756 :
757 0 : ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
758 : OSL_ENSURE(pFact, "ScAbstractFactory create fail!");
759 :
760 0 : switch ( eType )
761 : {
762 : case PIVOTFIELDTYPE_PAGE:
763 : case PIVOTFIELDTYPE_COL:
764 : case PIVOTFIELDTYPE_ROW:
765 : {
766 : // list of names of all data fields
767 0 : vector<ScDPName> aDataFieldNames;
768 0 : vector<ScDPFieldControlBase::FuncItem> aFuncItems;
769 0 : maWndData.GetAllFuncItems(aFuncItems);
770 0 : vector<ScDPFieldControlBase::FuncItem>::const_iterator it = aFuncItems.begin(), itEnd = aFuncItems.end();
771 0 : for (; it != itEnd; ++it)
772 : {
773 0 : ScDPLabelData* pDFData = GetLabelData(it->mnCol);
774 0 : if (!pDFData)
775 0 : continue;
776 :
777 0 : if (pDFData->maName.isEmpty())
778 0 : continue;
779 :
780 0 : OUString aLayoutName = pDFData->maLayoutName;
781 0 : if (aLayoutName.isEmpty())
782 : {
783 : // No layout name exists. Use the stock name.
784 0 : sal_uInt16 nMask = it->mnFuncMask;
785 0 : OUString aFuncStr = GetFuncString(nMask);
786 0 : aLayoutName = aFuncStr + pDFData->maName;
787 : }
788 0 : aDataFieldNames.push_back(ScDPName(pDFData->maName, aLayoutName));
789 0 : }
790 :
791 : bool bLayout = (eType == PIVOTFIELDTYPE_ROW) &&
792 0 : ((aDataFieldNames.size() > 1) || (nFieldIndex + 1 < pWnd->GetFieldCount()));
793 :
794 : boost::scoped_ptr<AbstractScDPSubtotalDlg> pDlg(
795 : pFact->CreateScDPSubtotalDlg(
796 0 : this, RID_SCDLG_PIVOTSUBT, *mxDlgDPObject, *pData, rFunc,
797 0 : aDataFieldNames, bLayout));
798 :
799 0 : if ( pDlg->Execute() == RET_OK )
800 : {
801 0 : pDlg->FillLabelData( *pData );
802 0 : rFunc.mnFuncMask = pData->mnFuncMask;
803 0 : }
804 : }
805 0 : break;
806 :
807 : case PIVOTFIELDTYPE_DATA:
808 : {
809 0 : ScPivotFuncData& rFuncData = maWndData.GetFuncData(nFieldIndex);
810 : boost::scoped_ptr<AbstractScDPFunctionDlg> pDlg(
811 : pFact->CreateScDPFunctionDlg(
812 0 : this, RID_SCDLG_DPDATAFIELD, maLabelData, *pData, rFuncData));
813 :
814 0 : if ( pDlg->Execute() == RET_OK )
815 : {
816 0 : bool bFuncChanged = rFuncData.mnFuncMask != pDlg->GetFuncMask();
817 0 : rFuncData.mnFuncMask = pData->mnFuncMask = pDlg->GetFuncMask();
818 0 : rFuncData.maFieldRef = pDlg->GetFieldRef();
819 :
820 0 : if (bFuncChanged)
821 : // Get the new duplicate count since the function has changed.
822 0 : rFuncData.mnDupCount = maWndData.GetNextDupCount(rFuncData, nFieldIndex);
823 :
824 0 : ScDPLabelData* p = GetLabelData(rFuncData.mnCol);
825 0 : OUString aStr = p->maLayoutName;
826 0 : if (aStr.isEmpty())
827 : {
828 : // Layout name is not available. Use default name.
829 0 : aStr = GetFuncString (rFuncData.mnFuncMask);
830 0 : aStr += p->maName;
831 : }
832 0 : maWndData.SetFieldText(aStr, nFieldIndex, rFuncData.mnDupCount);
833 0 : }
834 : }
835 0 : break;
836 :
837 : default:
838 : {
839 : // added to avoid warnings
840 : }
841 : }
842 : }
843 :
844 0 : void ScPivotLayoutDlg::NotifyFieldFocus( ScPivotFieldType eType, bool bGotFocus )
845 : {
846 : /* Enable Remove/Options buttons on GetFocus in field window.
847 : Enable them also, if dialog is deactivated (click into document).
848 : The !IsActive() condition handles the case that a LoseFocus event of a
849 : field window would follow the Deactivate event of this dialog. */
850 0 : bool bEnable = (bGotFocus || !IsActive()) && (eType != PIVOTFIELDTYPE_SELECT);
851 :
852 : // The TestTool may set the focus into an empty field.
853 : // Then the Remove/Options buttons must be disabled.
854 0 : ScDPFieldControlBase* pWnd = GetFieldWindow(eType);
855 0 : if ( bEnable && bGotFocus && pWnd && pWnd->IsEmpty() )
856 0 : bEnable = false;
857 :
858 0 : maBtnRemove.Enable( bEnable );
859 0 : maBtnOptions.Enable( bEnable );
860 0 : if( bGotFocus )
861 0 : meLastActiveType = eType;
862 0 : }
863 :
864 0 : void ScPivotLayoutDlg::NotifyMoveFieldToEnd( ScPivotFieldType eToType )
865 : {
866 0 : ScDPFieldControlBase* pWnd = GetFieldWindow(meLastActiveType);
867 0 : ScDPFieldControlBase* pToWnd = GetFieldWindow(eToType);
868 0 : if (pWnd && pToWnd && (eToType != PIVOTFIELDTYPE_SELECT) && !pWnd->IsEmpty())
869 : {
870 0 : MoveFieldToEnd(meLastActiveType, pWnd->GetSelectedField(), eToType);
871 :
872 0 : if( pWnd->IsEmpty() )
873 0 : NotifyFieldFocus( eToType, true );
874 : else
875 0 : pWnd->GrabFocus();
876 0 : if( meLastActiveType == PIVOTFIELDTYPE_SELECT )
877 0 : maWndSelect.SelectNext();
878 : }
879 : else
880 0 : GrabFieldFocus( maWndSelect );
881 0 : }
882 :
883 0 : void ScPivotLayoutDlg::NotifyRemoveField( ScPivotFieldType eType, size_t nFieldIndex )
884 : {
885 0 : if( eType != PIVOTFIELDTYPE_SELECT )
886 0 : RemoveField( eType, nFieldIndex );
887 0 : }
888 :
889 0 : Size ScPivotLayoutDlg::GetStdFieldBtnSize() const
890 : {
891 : // This size is static but is platform dependent. The field button size
892 : // is calculated relative to the size of the OK button.
893 0 : double w = static_cast<double>(maBtnOk.GetSizePixel().Width()) * 0.70;
894 0 : return Size(static_cast<long>(w), FIELD_BTN_HEIGHT);
895 : }
896 :
897 0 : void ScPivotLayoutDlg::DropFieldItem( const Point& rScrPos, ScPivotFieldType eToType )
898 : {
899 0 : if (!mbIsDrag)
900 : // Not in drag mode. Do nothing.
901 0 : return;
902 :
903 0 : mbIsDrag = false;
904 :
905 0 : if (eToType == PIVOTFIELDTYPE_UNKNOWN)
906 : {
907 : // We don't remove any buttons from the select field.
908 0 : if (meDnDFromType != PIVOTFIELDTYPE_SELECT)
909 0 : RemoveField(meDnDFromType, mnDnDFromIndex);
910 : }
911 : else
912 : {
913 0 : Point aOutPos = ScreenToOutputPixel(rScrPos);
914 0 : MoveField(meDnDFromType, mnDnDFromIndex, eToType, aOutPos);
915 : }
916 : }
917 :
918 0 : PointerStyle ScPivotLayoutDlg::GetPointerStyleAtPoint( const Point& /* rScrPos */, ScPivotFieldType eFieldType )
919 : {
920 0 : if (!mbIsDrag)
921 0 : return POINTER_ARROW;
922 :
923 0 : if (eFieldType == PIVOTFIELDTYPE_UNKNOWN)
924 : // Outside any field areas.
925 0 : return meDnDFromType == PIVOTFIELDTYPE_SELECT ? POINTER_PIVOT_FIELD : POINTER_PIVOT_DELETE;
926 :
927 0 : if (eFieldType == PIVOTFIELDTYPE_SELECT)
928 0 : return POINTER_PIVOT_FIELD;
929 :
930 : // check if the target orientation is allowed for this field
931 0 : ScDPFieldControlBase* pWnd = GetFieldWindow(meDnDFromType);
932 0 : if (!pWnd)
933 0 : return POINTER_ARROW;
934 :
935 0 : const ScPivotFuncData& rData = pWnd->GetFuncData(mnDnDFromIndex);
936 0 : if (!IsOrientationAllowed(rData.mnCol, eFieldType))
937 0 : return POINTER_NOTALLOWED;
938 :
939 0 : switch (eFieldType)
940 : {
941 : case PIVOTFIELDTYPE_COL:
942 0 : return POINTER_PIVOT_COL;
943 : case PIVOTFIELDTYPE_ROW:
944 0 : return POINTER_PIVOT_ROW;
945 : case PIVOTFIELDTYPE_DATA:
946 : case PIVOTFIELDTYPE_SELECT:
947 : case PIVOTFIELDTYPE_PAGE:
948 : default:
949 : ;
950 : }
951 :
952 0 : return POINTER_PIVOT_FIELD;
953 : }
954 :
955 : namespace {
956 :
957 : class InsideFieldControl : std::unary_function<ScDPFieldControlBase*, bool>
958 : {
959 : Point maOutPos;
960 : public:
961 0 : InsideFieldControl(const Point& rOutPos) : maOutPos(rOutPos) {}
962 :
963 0 : bool operator() (const ScDPFieldControlBase* p) const
964 : {
965 0 : Rectangle aRect(p->GetPosPixel(), p->GetSizePixel());
966 0 : return aRect.IsInside(maOutPos);
967 : }
968 : };
969 :
970 : }
971 :
972 0 : ScPivotFieldType ScPivotLayoutDlg::GetFieldTypeAtPoint( const Point& rScrPos ) const
973 : {
974 0 : Point aOutputPos = ScreenToOutputPixel(rScrPos);
975 : std::vector<ScDPFieldControlBase*>::const_iterator it =
976 0 : std::find_if(maFieldCtrls.begin(), maFieldCtrls.end(), InsideFieldControl(aOutputPos));
977 :
978 0 : return it == maFieldCtrls.end() ? PIVOTFIELDTYPE_UNKNOWN : (*it)->GetFieldType();
979 : }
980 :
981 0 : void ScPivotLayoutDlg::Deactivate()
982 : {
983 : /* If the dialog has been deactivated (click into document), the LoseFocus
984 : event from field window disables Remove/Options buttons. Re-enable them here by
985 : simulating a GetFocus event. Event order of LoseFocus and Deactivate is not important.
986 : The last event will enable the buttons in both cases (see NotifyFieldFocus). */
987 0 : NotifyFieldFocus( meLastActiveType, true );
988 0 : }
989 :
990 : namespace {
991 :
992 : class FindLabelDataByCol : std::unary_function<ScDPLabelData, bool>
993 : {
994 : SCCOL mnCol;
995 : public:
996 0 : FindLabelDataByCol(SCCOL nCol) : mnCol(nCol) {}
997 :
998 0 : bool operator() (const ScDPLabelData& r) const
999 : {
1000 0 : return r.mnCol == mnCol;
1001 : }
1002 : };
1003 :
1004 : }
1005 :
1006 0 : ScDPLabelData* ScPivotLayoutDlg::GetLabelData( SCCOL nCol )
1007 : {
1008 : ScDPLabelDataVector::iterator it =
1009 0 : std::find_if(maLabelData.begin(), maLabelData.end(), FindLabelDataByCol(nCol));
1010 0 : return it == maLabelData.end() ? NULL : &(*it);
1011 : }
1012 :
1013 0 : rtl::OUString ScPivotLayoutDlg::GetLabelString( SCsCOL nCol )
1014 : {
1015 0 : ScDPLabelData* pData = GetLabelData( nCol );
1016 : OSL_ENSURE( pData, "LabelData not found" );
1017 0 : if (pData)
1018 0 : return pData->getDisplayName();
1019 0 : return rtl::OUString();
1020 : }
1021 :
1022 0 : bool ScPivotLayoutDlg::IsOrientationAllowed( SCsCOL nCol, ScPivotFieldType eType )
1023 : {
1024 0 : bool bAllowed = true;
1025 0 : ScDPLabelData* pData = GetLabelData( nCol );
1026 : OSL_ENSURE( pData, "LabelData not found" );
1027 0 : if (pData)
1028 : {
1029 0 : sheet::DataPilotFieldOrientation eOrient = sheet::DataPilotFieldOrientation_HIDDEN;
1030 0 : switch (eType)
1031 : {
1032 0 : case PIVOTFIELDTYPE_PAGE: eOrient = sheet::DataPilotFieldOrientation_PAGE; break;
1033 0 : case PIVOTFIELDTYPE_COL: eOrient = sheet::DataPilotFieldOrientation_COLUMN; break;
1034 0 : case PIVOTFIELDTYPE_ROW: eOrient = sheet::DataPilotFieldOrientation_ROW; break;
1035 0 : case PIVOTFIELDTYPE_DATA: eOrient = sheet::DataPilotFieldOrientation_DATA; break;
1036 0 : case PIVOTFIELDTYPE_SELECT: eOrient = sheet::DataPilotFieldOrientation_HIDDEN; break;
1037 : default:
1038 : ;
1039 : }
1040 0 : bAllowed = ScDPObject::IsOrientationAllowed( (sal_uInt16)eOrient, pData->mnFlags );
1041 : }
1042 0 : return bAllowed;
1043 : }
1044 :
1045 0 : rtl::OUString ScPivotLayoutDlg::GetFuncString( sal_uInt16& rFuncMask, bool bIsValue )
1046 : {
1047 0 : rtl::OUStringBuffer aBuf;
1048 :
1049 0 : if ( rFuncMask == PIVOT_FUNC_NONE
1050 : || rFuncMask == PIVOT_FUNC_AUTO )
1051 : {
1052 0 : if ( bIsValue )
1053 : {
1054 0 : aBuf.append(GetFuncName(PIVOTSTR_SUM));
1055 0 : rFuncMask = PIVOT_FUNC_SUM;
1056 : }
1057 : else
1058 : {
1059 0 : aBuf.append(GetFuncName(PIVOTSTR_COUNT));
1060 0 : rFuncMask = PIVOT_FUNC_COUNT;
1061 : }
1062 : }
1063 0 : else if ( rFuncMask == PIVOT_FUNC_SUM ) aBuf = GetFuncName(PIVOTSTR_SUM);
1064 0 : else if ( rFuncMask == PIVOT_FUNC_COUNT ) aBuf = GetFuncName(PIVOTSTR_COUNT);
1065 0 : else if ( rFuncMask == PIVOT_FUNC_AVERAGE ) aBuf = GetFuncName(PIVOTSTR_AVG);
1066 0 : else if ( rFuncMask == PIVOT_FUNC_MAX ) aBuf = GetFuncName(PIVOTSTR_MAX);
1067 0 : else if ( rFuncMask == PIVOT_FUNC_MIN ) aBuf = GetFuncName(PIVOTSTR_MIN);
1068 0 : else if ( rFuncMask == PIVOT_FUNC_PRODUCT ) aBuf = GetFuncName(PIVOTSTR_PROD);
1069 0 : else if ( rFuncMask == PIVOT_FUNC_COUNT_NUM ) aBuf = GetFuncName(PIVOTSTR_COUNT2);
1070 0 : else if ( rFuncMask == PIVOT_FUNC_STD_DEV ) aBuf = GetFuncName(PIVOTSTR_DEV);
1071 0 : else if ( rFuncMask == PIVOT_FUNC_STD_DEVP ) aBuf = GetFuncName(PIVOTSTR_DEV2);
1072 0 : else if ( rFuncMask == PIVOT_FUNC_STD_VAR ) aBuf = GetFuncName(PIVOTSTR_VAR);
1073 0 : else if ( rFuncMask == PIVOT_FUNC_STD_VARP ) aBuf = GetFuncName(PIVOTSTR_VAR2);
1074 : else
1075 : {
1076 0 : aBuf.append(ScGlobal::GetRscString(STR_TABLE_ERGEBNIS));
1077 0 : aBuf.appendAscii(" - ");
1078 : }
1079 :
1080 0 : return aBuf.makeStringAndClear();
1081 : }
1082 :
1083 0 : void ScPivotLayoutDlg::InitControlAndDlgSizes()
1084 : {
1085 : // The pivot.src file only specifies the positions of the controls. Here,
1086 : // we calculate appropriate size of each control based on how they are
1087 : // positioned relative to each other.
1088 :
1089 : // row/column/data area sizes
1090 0 : long nFldW = GetStdFieldBtnSize().Width();
1091 0 : long nFldH = GetStdFieldBtnSize().Height();
1092 :
1093 : maWndData.SetSizePixel(
1094 0 : Size(maWndSelect.GetPosPixel().X() - maWndData.GetPosPixel().X() - FIELD_AREA_GAP*4,
1095 0 : 185));
1096 :
1097 : maWndPage.SetSizePixel(
1098 0 : Size(maWndData.GetSizePixel().Width() + 85,
1099 0 : maWndCol.GetPosPixel().Y() - maWndPage.GetPosPixel().Y() - FIELD_AREA_GAP));
1100 : maWndRow.SetSizePixel(
1101 0 : Size(maWndData.GetPosPixel().X()-maWndRow.GetPosPixel().X() - FIELD_AREA_GAP,
1102 0 : maWndData.GetSizePixel().Height()));
1103 : maWndCol.SetSizePixel(
1104 0 : Size(maWndData.GetPosPixel().X() - maWndCol.GetPosPixel().X() + maWndData.GetSizePixel().Width(),
1105 0 : maWndData.GetPosPixel().Y() - maWndCol.GetPosPixel().Y() - FIELD_AREA_GAP));
1106 :
1107 : // #i29203# align right border of page window with data window
1108 0 : long nDataPosX = maWndData.GetPosPixel().X() + maWndData.GetSizePixel().Width();
1109 : maWndPage.SetPosPixel(
1110 0 : Point(nDataPosX - maWndPage.GetSizePixel().Width(),
1111 0 : maWndPage.GetPosPixel().Y()));
1112 :
1113 : // selection area
1114 0 : long nLineSize = 10; // number of fields per column.
1115 0 : long nH = OUTER_MARGIN_VER + nLineSize* nFldH + nLineSize * ROW_FIELD_BTN_GAP;
1116 0 : nH += ROW_FIELD_BTN_GAP;
1117 0 : nH += GetSettings().GetStyleSettings().GetScrollBarSize() + OUTER_MARGIN_VER;
1118 : maWndSelect.SetSizePixel(
1119 0 : Size(2 * nFldW + ROW_FIELD_BTN_GAP + 10, nH));
1120 :
1121 0 : maWndPage.CalcSize();
1122 0 : maWndRow.CalcSize();
1123 0 : maWndCol.CalcSize();
1124 0 : maWndData.CalcSize();
1125 0 : maWndSelect.CalcSize();
1126 :
1127 0 : AdjustDlgSize();
1128 0 : }
1129 :
1130 : namespace {
1131 :
1132 : class MoveWndDown : public std::unary_function<Window*, void>
1133 : {
1134 : long mnDelta;
1135 : public:
1136 0 : MoveWndDown(long nDelta) : mnDelta(nDelta) {}
1137 0 : void operator() (Window* p) const
1138 : {
1139 0 : Point aPos = p->GetPosPixel();
1140 0 : aPos.Y() += mnDelta;
1141 0 : p->SetPosPixel(aPos);
1142 0 : }
1143 : };
1144 :
1145 : }
1146 :
1147 0 : void ScPivotLayoutDlg::AdjustDlgSize()
1148 : {
1149 : // On some platforms such as Windows XP, the dialog is not large enough to
1150 : // show the 'Drag the fields from the right...' text at the bottom. Check
1151 : // if it overlaps, and if it does, make the dialog size larger.
1152 0 : Size aWndSize = GetSizePixel();
1153 :
1154 0 : Point aPosText = maFtInfo.GetPosPixel();
1155 0 : Size aSizeText = maFtInfo.GetSizePixel();
1156 0 : long nYRef = maWndData.GetPosPixel().Y() + maWndData.GetSizePixel().Height();
1157 0 : if (aPosText.Y() > nYRef)
1158 : // This text is visible. No need to adjust.
1159 : return;
1160 :
1161 : // Calculate the extra height necessary.
1162 0 : long nBottomMargin = aWndSize.Height() - (aPosText.Y() + aSizeText.Height());
1163 0 : long nHeightNeeded = nYRef + TEXT_INFO_GAP + aSizeText.Height() + nBottomMargin;
1164 0 : long nDelta = nHeightNeeded - aWndSize.Height();
1165 0 : if (nDelta <= 0)
1166 : // This should never happen but just in case....
1167 : return;
1168 :
1169 : // Make the main dialog taller.
1170 0 : aWndSize.Height() += nDelta;
1171 0 : SetSizePixel(aWndSize);
1172 :
1173 : // Move the relevant controls downward.
1174 0 : std::vector<Window*> aWndToMove;
1175 0 : aWndToMove.reserve(16);
1176 0 : aWndToMove.push_back(&maFtInfo);
1177 0 : aWndToMove.push_back(&maBtnMore);
1178 0 : aWndToMove.push_back(&maFlAreas);
1179 0 : aWndToMove.push_back(&maFtInArea);
1180 0 : aWndToMove.push_back(&maEdInPos);
1181 0 : aWndToMove.push_back(&maRbInPos);
1182 0 : aWndToMove.push_back(&maFtOutArea);
1183 0 : aWndToMove.push_back(&maLbOutPos);
1184 0 : aWndToMove.push_back(&maEdOutPos);
1185 0 : aWndToMove.push_back(&maRbOutPos);
1186 0 : aWndToMove.push_back(&maBtnIgnEmptyRows);
1187 0 : aWndToMove.push_back(&maBtnDetectCat);
1188 0 : aWndToMove.push_back(&maBtnTotalCol);
1189 0 : aWndToMove.push_back(&maBtnTotalRow);
1190 0 : aWndToMove.push_back(&maBtnFilter);
1191 0 : aWndToMove.push_back(&maBtnDrillDown);
1192 0 : std::for_each(aWndToMove.begin(), aWndToMove.end(), MoveWndDown(nDelta));
1193 : }
1194 :
1195 0 : bool ScPivotLayoutDlg::GetPivotArrays(
1196 : vector<ScPivotField>& rPageFields, vector<ScPivotField>& rColFields,
1197 : vector<ScPivotField>& rRowFields, vector<ScPivotField>& rDataFields )
1198 : {
1199 0 : vector<ScPivotField> aPageFields;
1200 0 : maWndPage.ConvertToPivotArray(aPageFields);
1201 :
1202 0 : vector<ScPivotField> aColFields;
1203 0 : maWndCol.ConvertToPivotArray(aColFields);
1204 :
1205 0 : vector<ScPivotField> aRowFields;
1206 0 : maWndRow.ConvertToPivotArray(aRowFields);
1207 :
1208 0 : vector<ScPivotField> aDataFields;
1209 0 : maWndData.ConvertToPivotArray(aDataFields);
1210 :
1211 0 : sheet::DataPilotFieldOrientation eOrientDataLayout = sheet::DataPilotFieldOrientation_ROW;
1212 0 : ScDPSaveData* pSaveData = mxDlgDPObject->GetSaveData();
1213 0 : if (pSaveData)
1214 : {
1215 0 : const ScDPSaveDimension* p = pSaveData->GetExistingDataLayoutDimension();
1216 0 : if (p)
1217 : // Try to preserve the orientation of existing data layout dimension.
1218 0 : eOrientDataLayout = static_cast<sheet::DataPilotFieldOrientation>(p->GetOrientation());
1219 : }
1220 0 : switch (eOrientDataLayout)
1221 : {
1222 : case sheet::DataPilotFieldOrientation_COLUMN:
1223 0 : aColFields.push_back(ScPivotField(PIVOT_DATA_FIELD, 0));
1224 0 : break;
1225 : default:
1226 : // data layout dimension can only be row or column.
1227 0 : aRowFields.push_back(ScPivotField(PIVOT_DATA_FIELD, 0));
1228 : }
1229 :
1230 0 : rPageFields.swap(aPageFields);
1231 0 : rColFields.swap(aColFields);
1232 0 : rRowFields.swap(aRowFields);
1233 0 : rDataFields.swap(aDataFields);
1234 :
1235 0 : return true;
1236 : }
1237 :
1238 0 : void ScPivotLayoutDlg::UpdateSrcRange()
1239 : {
1240 0 : rtl::OUString aSrcStr = maEdInPos.GetText();
1241 0 : sal_uInt16 nResult = ScRange().Parse(aSrcStr, mpDoc, mpDoc->GetAddressConvention());
1242 0 : DataSrcType eSrcType = SRC_INVALID;
1243 0 : ScRange aNewRange;
1244 :
1245 0 : if (SCA_VALID == (nResult & SCA_VALID))
1246 : {
1247 : // Valid source range. Take it.
1248 0 : ScRefAddress start, end;
1249 0 : ConvertDoubleRef(mpDoc, aSrcStr, 1, start, end, mpDoc->GetAddressConvention());
1250 0 : aNewRange.aStart = start.GetAddress();
1251 0 : aNewRange.aEnd = end.GetAddress();
1252 0 : maEdInPos.SetRefValid(true);
1253 0 : eSrcType = SRC_REF;
1254 : }
1255 : else
1256 : {
1257 : // invalid source range. Check if this is a valid range name.
1258 0 : bool bValid = false;
1259 0 : ScRangeName* pRangeName = mpDoc->GetRangeName();
1260 0 : if (pRangeName)
1261 : {
1262 0 : OUString aUpper = ScGlobal::pCharClass->uppercase(aSrcStr);
1263 0 : const ScRangeData* pData = pRangeName->findByUpperName(aUpper);
1264 0 : if (pData)
1265 : {
1266 : // range name found. Check if this is a valid reference.
1267 0 : bValid = pData->IsReference(aNewRange);
1268 0 : }
1269 : }
1270 :
1271 0 : maEdInPos.SetRefValid(bValid);
1272 0 : if (!bValid)
1273 : {
1274 : // All attempts have failed. Give up.
1275 0 : maBtnOk.Disable();
1276 : return;
1277 : }
1278 :
1279 0 : eSrcType = SRC_NAME;
1280 : }
1281 :
1282 0 : maBtnOk.Enable();
1283 :
1284 : // Now update the data src range or range name with the dp object.
1285 0 : ScSheetSourceDesc inSheet = *mxDlgDPObject->GetSheetDesc();
1286 :
1287 0 : switch (eSrcType)
1288 : {
1289 : case SRC_REF:
1290 : {
1291 : // data source is a range reference.
1292 0 : if (inSheet.GetSourceRange() == aNewRange)
1293 : // new range is identical to the current range. Nothing to do.
1294 : return;
1295 0 : inSheet.SetSourceRange(aNewRange);
1296 0 : sal_uLong nError = inSheet.CheckSourceRange();
1297 0 : if (nError)
1298 : {
1299 : // The error number corresponds with string ID for the error
1300 : // message. In the future we should display the error message
1301 : // somewhere in the dialog to let the user know of the reason
1302 : // for error.
1303 0 : maEdInPos.SetRefValid(false);
1304 0 : maBtnOk.Disable();
1305 : return;
1306 : }
1307 : }
1308 0 : break;
1309 : case SRC_NAME:
1310 : // data source is a range name.
1311 0 : inSheet.SetRangeName(aSrcStr);
1312 0 : break;
1313 : default:
1314 : OSL_FAIL( "Unknown source type.");
1315 : return;
1316 : }
1317 :
1318 0 : mxDlgDPObject->SetSheetDesc(inSheet);
1319 0 : mxDlgDPObject->FillOldParam( maPivotData );
1320 0 : mxDlgDPObject->FillLabelData(maPivotData);
1321 :
1322 0 : maLabelData.clear();
1323 0 : maWndSelect.ClearFields();
1324 0 : maWndData.ClearFields();
1325 0 : maWndRow.ClearFields();
1326 0 : maWndCol.ClearFields();
1327 0 : maWndPage.ClearFields();
1328 :
1329 0 : InitFieldWindows();
1330 0 : RepaintFieldWindows();
1331 : }
1332 :
1333 0 : void ScPivotLayoutDlg::UpdateOutputPos()
1334 : {
1335 0 : sal_uInt16 nSelPos = maLbOutPos.GetSelectEntryPos();
1336 0 : OUString aEntryStr = maLbOutPos.GetEntry(nSelPos);
1337 :
1338 0 : if (aEntryStr == maStrNewTable)
1339 : {
1340 : // New sheet as output.
1341 0 : maEdOutPos.Disable();
1342 0 : maRbOutPos.Disable();
1343 0 : maEdOutPos.SetText(OUString()); // Clear the reference text.
1344 : }
1345 0 : else if (aEntryStr == maStrUndefined)
1346 : {
1347 0 : maEdOutPos.Enable();
1348 0 : maRbOutPos.Enable();
1349 0 : maEdOutPos.SetText(maOutputRefStr);
1350 0 : OutputPosUpdated();
1351 : }
1352 : else
1353 : {
1354 : // Named range as output. Get its corresponding reference string.
1355 0 : const OUString* p = (const OUString*)maLbOutPos.GetEntryData(nSelPos);
1356 0 : if (p)
1357 0 : maEdOutPos.SetText(*p);
1358 0 : }
1359 0 : }
1360 :
1361 0 : void ScPivotLayoutDlg::OutputPosUpdated()
1362 : {
1363 0 : OUString aOutPosStr = maEdOutPos.GetText();
1364 0 : sal_uInt16 nResult = ScAddress().Parse(aOutPosStr, mpDoc, mpDoc->GetAddressConvention());
1365 :
1366 0 : if (!(nResult & SCA_VALID))
1367 : {
1368 : // Not a valid reference.
1369 0 : maEdOutPos.SetRefValid(false);
1370 : return;
1371 : }
1372 :
1373 0 : maEdOutPos.SetRefValid(true);
1374 :
1375 : boost::ptr_vector<OUString>::const_iterator it =
1376 0 : std::find(maRefStrs.begin(), maRefStrs.end(), aOutPosStr);
1377 :
1378 0 : if (it == maRefStrs.end())
1379 : {
1380 : // This is NOT one of the named ranges.
1381 0 : maLbOutPos.SelectEntryPos(0);
1382 : return;
1383 : }
1384 :
1385 : // Select the corresponding named range item in the list box. Be sure to
1386 : // offset for the top two entries which are reserved for something else.
1387 0 : boost::ptr_vector<OUString>::const_iterator itBeg = maRefStrs.begin();
1388 0 : size_t nPos = std::distance(itBeg, it);
1389 0 : maLbOutPos.SelectEntryPos(nPos+2);
1390 : }
1391 :
1392 : namespace {
1393 :
1394 0 : void EnableAndGrabFocus(formula::RefEdit& rEdit)
1395 : {
1396 0 : rEdit.Enable();
1397 0 : rEdit.GrabFocus();
1398 0 : rEdit.Enable();
1399 0 : }
1400 :
1401 : }
1402 :
1403 0 : void ScPivotLayoutDlg::MoreBtnClicked()
1404 : {
1405 0 : mbRefInputMode = maBtnMore.GetState();
1406 0 : if (!maBtnMore.GetState())
1407 0 : return;
1408 :
1409 0 : formula::RefEdit* p = maEdInPos.IsEnabled() ? &maEdInPos : &maEdOutPos;
1410 0 : EnableAndGrabFocus(*p);
1411 : }
1412 :
1413 0 : void ScPivotLayoutDlg::RepaintFieldWindows()
1414 : {
1415 0 : Rectangle aRect; // currently has no effect whatsoever.
1416 0 : maWndPage.Paint(aRect);
1417 0 : maWndCol.Paint(aRect);
1418 0 : maWndRow.Paint(aRect);
1419 0 : maWndData.Paint(aRect);
1420 0 : }
1421 :
1422 0 : ScDPFieldControlBase* ScPivotLayoutDlg::GetFieldWindow(ScPivotFieldType eType)
1423 : {
1424 0 : switch (eType)
1425 : {
1426 : case PIVOTFIELDTYPE_PAGE:
1427 0 : return &maWndPage;
1428 : case PIVOTFIELDTYPE_COL:
1429 0 : return &maWndCol;
1430 : case PIVOTFIELDTYPE_ROW:
1431 0 : return &maWndRow;
1432 : case PIVOTFIELDTYPE_DATA:
1433 0 : return &maWndData;
1434 : case PIVOTFIELDTYPE_SELECT:
1435 0 : return &maWndSelect;
1436 : default:
1437 : ;
1438 : }
1439 0 : return NULL;
1440 : }
1441 :
1442 0 : void ScPivotLayoutDlg::GetOtherFieldWindows(ScPivotFieldType eType, ScDPFieldControlBase*& rpWnd1, ScDPFieldControlBase*& rpWnd2)
1443 : {
1444 0 : rpWnd1 = NULL;
1445 0 : rpWnd2 = NULL;
1446 0 : switch (eType)
1447 : {
1448 : case PIVOTFIELDTYPE_PAGE:
1449 0 : rpWnd1 = &maWndRow;
1450 0 : rpWnd2 = &maWndCol;
1451 0 : break;
1452 : case PIVOTFIELDTYPE_COL:
1453 0 : rpWnd1 = &maWndPage;
1454 0 : rpWnd2 = &maWndRow;
1455 0 : break;
1456 : case PIVOTFIELDTYPE_ROW:
1457 0 : rpWnd1 = &maWndPage;
1458 0 : rpWnd2 = &maWndCol;
1459 0 : break;
1460 : default:
1461 : ;
1462 : }
1463 0 : }
1464 :
1465 0 : void ScPivotLayoutDlg::SetReference( const ScRange& rRef, ScDocument* pDoc )
1466 : {
1467 0 : if (!mbRefInputMode || !mpRefInputEdit)
1468 0 : return;
1469 :
1470 0 : if ( rRef.aStart != rRef.aEnd )
1471 0 : RefInputStart(mpRefInputEdit);
1472 :
1473 0 : if (mpRefInputEdit == &maEdInPos)
1474 : {
1475 0 : rtl::OUString aRefStr;
1476 0 : rRef.Format( aRefStr, SCR_ABS_3D, pDoc, pDoc->GetAddressConvention() );
1477 0 : mpRefInputEdit->SetRefString(aRefStr);
1478 : }
1479 0 : else if (mpRefInputEdit == &maEdOutPos)
1480 : {
1481 0 : rtl::OUString aRefStr;
1482 0 : rRef.aStart.Format( aRefStr, STD_FORMAT, pDoc, pDoc->GetAddressConvention() );
1483 0 : mpRefInputEdit->SetRefString(aRefStr);
1484 0 : maOutputRefStr = aRefStr;
1485 0 : OutputPosUpdated();
1486 : }
1487 : }
1488 :
1489 0 : sal_Bool ScPivotLayoutDlg::IsRefInputMode() const
1490 : {
1491 0 : return mbRefInputMode;
1492 : }
1493 :
1494 0 : void ScPivotLayoutDlg::SetActive()
1495 : {
1496 0 : if ( mbRefInputMode )
1497 : {
1498 0 : if (mpRefInputEdit)
1499 0 : mpRefInputEdit->GrabFocus();
1500 :
1501 0 : if (mpRefInputEdit == &maEdInPos)
1502 0 : EdInModifyHdl( NULL );
1503 0 : else if (mpRefInputEdit == &maEdOutPos)
1504 0 : EdOutModifyHdl( NULL );
1505 : }
1506 : else
1507 : {
1508 0 : GrabFocus();
1509 : }
1510 :
1511 0 : RefInputDone();
1512 0 : }
1513 :
1514 0 : IMPL_LINK( ScPivotLayoutDlg, ClickHdl, PushButton *, pBtn )
1515 : {
1516 0 : ScDPFieldControlBase* pWnd = GetFieldWindow( meLastActiveType );
1517 0 : if (!pWnd)
1518 0 : return 0;
1519 :
1520 0 : if( pBtn == &maBtnRemove )
1521 : {
1522 0 : RemoveField( meLastActiveType, pWnd->GetSelectedField() );
1523 0 : if( !pWnd->IsEmpty() ) pWnd->GrabFocus();
1524 : }
1525 0 : else if( pBtn == &maBtnOptions )
1526 : {
1527 0 : NotifyDoubleClick( meLastActiveType, pWnd->GetSelectedField() );
1528 0 : pWnd->GrabFocus();
1529 : }
1530 0 : return 0;
1531 : }
1532 :
1533 0 : IMPL_LINK_NOARG(ScPivotLayoutDlg, OkHdl)
1534 : {
1535 0 : rtl::OUString aOutPosStr = maEdOutPos.GetText();
1536 0 : ScAddress aAdrDest;
1537 0 : bool bToNewTable = (maLbOutPos.GetSelectEntryPos() == 1);
1538 0 : sal_uInt16 nResult = !bToNewTable ? aAdrDest.Parse( aOutPosStr, mpDoc, mpDoc->GetAddressConvention() ) : 0;
1539 :
1540 0 : if (!bToNewTable && (aOutPosStr.isEmpty() || (nResult & SCA_VALID) != SCA_VALID))
1541 : {
1542 : // Invalid reference. Bail out.
1543 0 : if ( !maBtnMore.GetState() )
1544 0 : maBtnMore.SetState(true);
1545 :
1546 0 : ErrorBox(this, WinBits(WB_OK | WB_DEF_OK), ScGlobal::GetRscString(STR_INVALID_TABREF)).Execute();
1547 0 : maEdOutPos.GrabFocus();
1548 0 : return 0;
1549 : }
1550 :
1551 0 : ScPivotParam theOutParam;
1552 0 : vector<ScPivotField> aPageFields;
1553 0 : vector<ScPivotField> aColFields;
1554 0 : vector<ScPivotField> aRowFields;
1555 0 : vector<ScPivotField> aDataFields;
1556 :
1557 : // Convert an array of function data into an array of pivot field data.
1558 0 : bool bFit = GetPivotArrays(aPageFields, aColFields, aRowFields, aDataFields);
1559 :
1560 0 : if (!bFit)
1561 : {
1562 : // General data pilot table error. Bail out.
1563 0 : ErrorBox(this, WinBits(WB_OK | WB_DEF_OK), ScGlobal::GetRscString(STR_PIVOT_ERROR)).Execute();
1564 0 : return 0;
1565 : }
1566 :
1567 0 : ScDPSaveData* pOldSaveData = mxDlgDPObject->GetSaveData();
1568 :
1569 0 : ScRange aOutRange( aAdrDest ); // bToNewTable is passed separately
1570 :
1571 0 : ScDPSaveData aSaveData;
1572 0 : aSaveData.SetIgnoreEmptyRows( maBtnIgnEmptyRows.IsChecked() );
1573 0 : aSaveData.SetRepeatIfEmpty( maBtnDetectCat.IsChecked() );
1574 0 : aSaveData.SetColumnGrand( maBtnTotalCol.IsChecked() );
1575 0 : aSaveData.SetRowGrand( maBtnTotalRow.IsChecked() );
1576 0 : aSaveData.SetFilterButton( maBtnFilter.IsChecked() );
1577 0 : aSaveData.SetDrillDown( maBtnDrillDown.IsChecked() );
1578 :
1579 0 : uno::Reference<sheet::XDimensionsSupplier> xSource = mxDlgDPObject->GetSource();
1580 :
1581 : ScDPObject::ConvertOrientation(
1582 0 : aSaveData, aPageFields, sheet::DataPilotFieldOrientation_PAGE, xSource, maLabelData);
1583 : ScDPObject::ConvertOrientation(
1584 0 : aSaveData, aColFields, sheet::DataPilotFieldOrientation_COLUMN, xSource, maLabelData);
1585 : ScDPObject::ConvertOrientation(
1586 0 : aSaveData, aRowFields, sheet::DataPilotFieldOrientation_ROW, xSource, maLabelData);
1587 : ScDPObject::ConvertOrientation(
1588 : aSaveData, aDataFields, sheet::DataPilotFieldOrientation_DATA, xSource, maLabelData,
1589 0 : &aColFields, &aRowFields, &aPageFields );
1590 :
1591 0 : for( ScDPLabelDataVector::const_iterator aIt = maLabelData.begin(), aEnd = maLabelData.end(); aIt != aEnd; ++aIt )
1592 : {
1593 0 : ScDPSaveDimension* pDim = aSaveData.GetExistingDimensionByName(aIt->maName);
1594 :
1595 0 : if (!pDim)
1596 0 : continue;
1597 :
1598 0 : pDim->SetUsedHierarchy( aIt->mnUsedHier );
1599 0 : pDim->SetShowEmpty( aIt->mbShowAll );
1600 0 : pDim->SetSortInfo( &aIt->maSortInfo );
1601 0 : pDim->SetLayoutInfo( &aIt->maLayoutInfo );
1602 0 : pDim->SetAutoShowInfo( &aIt->maShowInfo );
1603 0 : ScDPSaveDimension* pOldDim = NULL;
1604 :
1605 0 : bool bManualSort = ( aIt->maSortInfo.Mode == sheet::DataPilotFieldSortMode::MANUAL );
1606 :
1607 : // visibility of members
1608 0 : for (vector<ScDPLabelData::Member>::const_iterator itr = aIt->maMembers.begin(), itrEnd = aIt->maMembers.end();
1609 : itr != itrEnd; ++itr)
1610 : {
1611 0 : ScDPSaveMember* pMember = pDim->GetMemberByName(itr->maName);
1612 :
1613 : // #i40054# create/access members only if flags are not default
1614 : // (or in manual sorting mode - to keep the order)
1615 0 : if (bManualSort || !itr->mbVisible || !itr->mbShowDetails)
1616 : {
1617 0 : pMember->SetIsVisible(itr->mbVisible);
1618 0 : pMember->SetShowDetails(itr->mbShowDetails);
1619 : }
1620 :
1621 0 : if (!pOldDim)
1622 0 : continue;
1623 :
1624 : // Transfer the existing layout name.
1625 0 : ScDPSaveMember* pOldMember = pOldDim->GetMemberByName(itr->maName);
1626 0 : if (pOldMember)
1627 : {
1628 0 : const OUString* pLayoutName = pOldMember->GetLayoutName();
1629 0 : if (pLayoutName)
1630 0 : pMember->SetLayoutName(*pLayoutName);
1631 : }
1632 : }
1633 : }
1634 0 : ScDPSaveDimension* pDim = aSaveData.GetDataLayoutDimension();
1635 0 : if (pDim && pOldSaveData)
1636 : {
1637 0 : ScDPSaveDimension* pOldDim = pOldSaveData->GetDataLayoutDimension();
1638 0 : if (pOldDim)
1639 : {
1640 0 : const OUString* pLayoutName = pOldDim->GetLayoutName();
1641 0 : if (pLayoutName)
1642 0 : pDim->SetLayoutName(*pLayoutName);
1643 : }
1644 : }
1645 :
1646 : // also transfer grand total name
1647 0 : if (pOldSaveData)
1648 : {
1649 0 : const OUString* pGrandTotalName = pOldSaveData->GetGrandTotalName();
1650 0 : if (pGrandTotalName)
1651 0 : aSaveData.SetGrandTotalName(*pGrandTotalName);
1652 : }
1653 :
1654 0 : sal_uInt16 nWhichPivot = SC_MOD()->GetPool().GetWhich( SID_PIVOT_TABLE );
1655 0 : ScPivotItem aOutItem( nWhichPivot, &aSaveData, &aOutRange, bToNewTable );
1656 :
1657 0 : mbRefInputMode = false; // to allow deselecting when switching sheets
1658 :
1659 0 : SetDispatcherLock( false );
1660 0 : SwitchToDocument();
1661 :
1662 0 : ScTabViewShell* pTabViewShell = mpViewData->GetViewShell();
1663 0 : pTabViewShell->SetDialogDPObject(mxDlgDPObject.get());
1664 :
1665 : // don't hide the dialog before executing the slot, instead it is used as
1666 : // parent for message boxes in ScTabViewShell::GetDialogParent
1667 :
1668 0 : const SfxPoolItem* pRet = GetBindings().GetDispatcher()->Execute(
1669 0 : SID_PIVOT_TABLE, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD, &aOutItem, 0L, 0L );
1670 :
1671 0 : bool bSuccess = true;
1672 0 : if (pRet)
1673 : {
1674 0 : const SfxBoolItem* pItem = dynamic_cast<const SfxBoolItem*>(pRet);
1675 0 : if (pItem)
1676 0 : bSuccess = pItem->GetValue();
1677 : }
1678 0 : if (bSuccess)
1679 : // Table successfully inserted.
1680 0 : Close();
1681 : else
1682 : {
1683 : // Table insertion failed. Keep the dialog open.
1684 0 : mbRefInputMode = true;
1685 0 : SetDispatcherLock(true);
1686 : }
1687 :
1688 0 : return 0;
1689 : }
1690 :
1691 0 : IMPL_LINK_NOARG(ScPivotLayoutDlg, CancelHdl)
1692 : {
1693 0 : Close();
1694 0 : return 0;
1695 : }
1696 :
1697 0 : IMPL_LINK_NOARG(ScPivotLayoutDlg, MoreClickHdl)
1698 : {
1699 0 : MoreBtnClicked();
1700 0 : return 0;
1701 : }
1702 :
1703 0 : IMPL_LINK_NOARG(ScPivotLayoutDlg, EdOutModifyHdl)
1704 : {
1705 0 : OutputPosUpdated();
1706 0 : return 0;
1707 : }
1708 :
1709 0 : IMPL_LINK_NOARG(ScPivotLayoutDlg, EdInModifyHdl)
1710 : {
1711 0 : UpdateSrcRange();
1712 0 : return 0;
1713 : }
1714 :
1715 0 : IMPL_LINK_NOARG(ScPivotLayoutDlg, SelAreaHdl)
1716 : {
1717 0 : UpdateOutputPos();
1718 0 : return 0;
1719 : }
1720 :
1721 0 : IMPL_LINK( ScPivotLayoutDlg, GetRefEditFocusHdl, formula::RefEdit*, pEdit )
1722 : {
1723 0 : mpRefInputEdit = pEdit;
1724 0 : return 0;
1725 15 : }
1726 :
1727 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|