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