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