merge the formfield patch from ooo-build
[ooovba.git] / sc / source / ui / dbgui / pvlaydlg.cxx
blob78d5a2fecb65a96a13b211bf27851f7554305829
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: pvlaydlg.cxx,v $
10 * $Revision: 1.29 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
36 //----------------------------------------------------------------------------
38 #include "pvlaydlg.hxx"
39 #include "dbdocfun.hxx"
41 #include <sfx2/dispatch.hxx>
42 #include <vcl/msgbox.hxx>
44 #include <com/sun/star/sheet/DataPilotFieldOrientation.hpp>
45 #include <com/sun/star/sheet/DataPilotFieldSortMode.hpp>
47 #include "uiitems.hxx"
48 #include "rangeutl.hxx"
49 #include "document.hxx"
50 #include "viewdata.hxx"
51 #include "tabvwsh.hxx"
52 #include "reffact.hxx"
53 #include "scresid.hxx"
54 #include "pvglob.hxx"
55 //CHINA001 #include "pvfundlg.hxx"
56 #include "globstr.hrc"
57 #include "pivot.hrc"
58 #include "dpobject.hxx"
59 #include "dpsave.hxx"
60 #include "dpshttab.hxx"
61 #include "scmod.hxx"
63 #include "sc.hrc" //CHINA001
64 #include "scabstdlg.hxx" //CHINA001
65 using namespace com::sun::star;
66 using ::rtl::OUString;
67 using ::std::vector;
69 //----------------------------------------------------------------------------
71 #define FSTR(index) aFuncNameArr[index-1]
72 #define STD_FORMAT SCA_VALID | SCA_TAB_3D \
73 | SCA_COL_ABSOLUTE | SCA_ROW_ABSOLUTE | SCA_TAB_ABSOLUTE
75 long PivotGlobal::nObjHeight = 0; // initialized with resource data
76 long PivotGlobal::nObjWidth = 0;
77 long PivotGlobal::nSelSpace = 0;
80 //============================================================================
82 namespace {
84 void lcl_FillToPivotField( PivotField& rPivotField, const ScDPFuncData& rFuncData )
86 rPivotField.nCol = rFuncData.mnCol;
87 rPivotField.nFuncMask = rFuncData.mnFuncMask;
88 rPivotField.maFieldRef = rFuncData.maFieldRef;
91 PointerStyle lclGetPointerForField( ScDPFieldType eType )
93 switch( eType )
95 case TYPE_PAGE: return POINTER_PIVOT_FIELD;
96 case TYPE_COL: return POINTER_PIVOT_COL;
97 case TYPE_ROW: return POINTER_PIVOT_ROW;
98 case TYPE_DATA: return POINTER_PIVOT_FIELD;
99 case TYPE_SELECT: return POINTER_PIVOT_FIELD;
101 return POINTER_ARROW;
104 } // namespace
106 //============================================================================
108 //----------------------------------------------------------------------------
110 ScDPLayoutDlg::ScDPLayoutDlg( SfxBindings* pB, SfxChildWindow* pCW, Window* pParent,
111 const ScDPObject& rDPObject, bool bNewOutput )
112 : ScAnyRefDlg ( pB, pCW, pParent, RID_SCDLG_PIVOT_LAYOUT ),
113 aFlLayout ( this, ScResId( FL_LAYOUT ) ),
114 aFtPage ( this, ScResId( FT_PAGE ) ),
115 aWndPage ( this, ScResId( WND_PAGE ), TYPE_PAGE, &aFtPage ),
116 aFtCol ( this, ScResId( FT_COL ) ),
117 aWndCol ( this, ScResId( WND_COL ), TYPE_COL, &aFtCol ),
118 aFtRow ( this, ScResId( FT_ROW ) ),
119 aWndRow ( this, ScResId( WND_ROW ), TYPE_ROW, &aFtRow ),
120 aFtData ( this, ScResId( FT_DATA ) ),
121 aWndData ( this, ScResId( WND_DATA ), TYPE_DATA, &aFtData ),
122 aWndSelect ( this, ScResId( WND_SELECT ), TYPE_SELECT, String(ScResId(STR_SELECT)) ),
123 aSlider ( this, ScResId( WND_HSCROLL ) ),
124 aFtInfo ( this, ScResId( FT_INFO ) ),
126 aFlAreas ( this, ScResId( FL_OUTPUT ) ),
128 aFtInArea ( this, ScResId( FT_INAREA) ),
129 aEdInPos ( this, ScResId( ED_INAREA) ),
130 aRbInPos ( this, ScResId( RB_INAREA ), &aEdInPos, this ),
132 aLbOutPos ( this, ScResId( LB_OUTAREA ) ),
133 aFtOutArea ( this, ScResId( FT_OUTAREA ) ),
134 aEdOutPos ( this, this, ScResId( ED_OUTAREA ) ),
135 aRbOutPos ( this, ScResId( RB_OUTAREA ), &aEdOutPos, this ),
136 aBtnIgnEmptyRows( this, ScResId( BTN_IGNEMPTYROWS ) ),
137 aBtnDetectCat ( this, ScResId( BTN_DETECTCAT ) ),
138 aBtnTotalCol ( this, ScResId( BTN_TOTALCOL ) ),
139 aBtnTotalRow ( this, ScResId( BTN_TOTALROW ) ),
140 aBtnFilter ( this, ScResId( BTN_FILTER ) ),
141 aBtnDrillDown ( this, ScResId( BTN_DRILLDOWN ) ),
143 aBtnOk ( this, ScResId( BTN_OK ) ),
144 aBtnCancel ( this, ScResId( BTN_CANCEL ) ),
145 aBtnHelp ( this, ScResId( BTN_HELP ) ),
146 aBtnRemove ( this, ScResId( BTN_REMOVE ) ),
147 aBtnOptions ( this, ScResId( BTN_OPTIONS ) ),
148 aBtnMore ( this, ScResId( BTN_MORE ) ),
150 aStrUndefined ( ScResId( SCSTR_UNDEFINED ) ),
151 aStrNewTable ( ScResId( SCSTR_NEWTABLE ) ),
153 bIsDrag ( FALSE ),
155 pEditActive ( NULL ),
157 eLastActiveType ( TYPE_SELECT ),
158 nOffset ( 0 ),
160 xDlgDPObject ( new ScDPObject( rDPObject ) ),
161 pViewData ( ((ScTabViewShell*)SfxViewShell::Current())->
162 GetViewData() ),
163 pDoc ( ((ScTabViewShell*)SfxViewShell::Current())->
164 GetViewData()->GetDocument() ),
165 bRefInputMode ( FALSE )
167 xDlgDPObject->SetAlive( TRUE ); // needed to get structure information
168 xDlgDPObject->FillOldParam( thePivotData, FALSE );
169 xDlgDPObject->FillLabelData( thePivotData );
171 Init(bNewOutput);
172 FreeResource();
176 //----------------------------------------------------------------------------
178 ScDPLayoutDlg::~ScDPLayoutDlg()
180 USHORT nEntries = aLbOutPos.GetEntryCount();
181 USHORT i;
183 for ( i=2; i<nEntries; i++ )
184 delete (String*)aLbOutPos.GetEntryData( i );
188 //----------------------------------------------------------------------------
190 ScDPFieldWindow& ScDPLayoutDlg::GetFieldWindow( ScDPFieldType eType )
192 switch( eType )
194 case TYPE_PAGE: return aWndPage;
195 case TYPE_ROW: return aWndRow;
196 case TYPE_COL: return aWndCol;
197 case TYPE_DATA: return aWndData;
198 default:
200 // added to avoid warnings
203 return aWndSelect;
206 void __EXPORT ScDPLayoutDlg::Init(bool bNewOutput)
208 DBG_ASSERT( pViewData && pDoc,
209 "Ctor-Initialisierung fehlgeschlagen!" );
211 aBtnRemove.SetClickHdl( LINK( this, ScDPLayoutDlg, ClickHdl ) );
212 aBtnOptions.SetClickHdl( LINK( this, ScDPLayoutDlg, ClickHdl ) );
214 aFuncNameArr.reserve( FUNC_COUNT );
215 for ( USHORT i = 0; i < FUNC_COUNT; ++i )
216 aFuncNameArr.push_back( String( ScResId( i + 1 ) ) );
218 aBtnMore.AddWindow( &aFlAreas );
219 aBtnMore.AddWindow( &aFtInArea );
220 aBtnMore.AddWindow( &aEdInPos );
221 aBtnMore.AddWindow( &aRbInPos );
222 aBtnMore.AddWindow( &aFtOutArea );
223 aBtnMore.AddWindow( &aLbOutPos );
224 aBtnMore.AddWindow( &aEdOutPos );
225 aBtnMore.AddWindow( &aRbOutPos );
226 aBtnMore.AddWindow( &aBtnIgnEmptyRows );
227 aBtnMore.AddWindow( &aBtnDetectCat );
228 aBtnMore.AddWindow( &aBtnTotalCol );
229 aBtnMore.AddWindow( &aBtnTotalRow );
230 aBtnMore.AddWindow( &aBtnFilter );
231 aBtnMore.AddWindow( &aBtnDrillDown );
232 aBtnMore.SetClickHdl( LINK( this, ScDPLayoutDlg, MoreClickHdl ) );
235 Size aFieldSize( Window( this, ScResId( WND_FIELD ) ).GetSizePixel() );
236 OHEIGHT = aFieldSize.Height();
237 OWIDTH = aFieldSize.Width();
239 SSPACE = Window( this, ScResId( WND_FIELD_SPACE ) ).GetSizePixel().Width();
241 CalcWndSizes();
243 aSelectArr.resize( MAX_LABELS );
244 aPageArr.resize( MAX_PAGEFIELDS );
245 aColArr.resize( MAX_FIELDS );
246 aRowArr.resize( MAX_FIELDS );
247 aDataArr.resize( MAX_FIELDS );
249 ScRange inRange;
250 String inString;
251 if (xDlgDPObject->GetSheetDesc())
253 aEdInPos.Enable();
254 aRbInPos.Enable();
255 aOldRange = xDlgDPObject->GetSheetDesc()->aSourceRange;
256 aOldRange.Format( inString, SCR_ABS_3D, pDoc, pDoc->GetAddressConvention() );
257 aEdInPos.SetText(inString);
259 else
261 /* Data is not reachable, so could be a remote database */
262 aEdInPos.Disable();
263 aRbInPos.Disable();
266 InitFields();
268 aLbOutPos .SetSelectHdl( LINK( this, ScDPLayoutDlg, SelAreaHdl ) );
269 aEdOutPos .SetModifyHdl( LINK( this, ScDPLayoutDlg, EdModifyHdl ) );
270 aEdInPos .SetModifyHdl( LINK( this, ScDPLayoutDlg, EdInModifyHdl ) );
271 aBtnOk .SetClickHdl ( LINK( this, ScDPLayoutDlg, OkHdl ) );
272 aBtnCancel.SetClickHdl ( LINK( this, ScDPLayoutDlg, CancelHdl ) );
273 Link aLink = LINK( this, ScDPLayoutDlg, GetFocusHdl );
274 if ( aEdInPos.IsEnabled() )
275 // Once disabled it will never get enabled, so no need to handle focus.
276 aEdInPos.SetGetFocusHdl( aLink );
277 aEdOutPos.SetGetFocusHdl( aLink );
279 if ( pViewData && pDoc )
282 * Aus den RangeNames des Dokumentes werden nun die
283 * in einem Zeiger-Array gemerkt, bei denen es sich
284 * um sinnvolle Bereiche handelt
287 aLbOutPos.Clear();
288 aLbOutPos.InsertEntry( aStrUndefined, 0 );
289 aLbOutPos.InsertEntry( aStrNewTable, 1 );
291 ScAreaNameIterator aIter( pDoc );
292 String aName;
293 ScRange aRange;
294 String aRefStr;
295 while ( aIter.Next( aName, aRange ) )
297 if ( !aIter.WasDBName() ) // hier keine DB-Bereiche !
299 USHORT nInsert = aLbOutPos.InsertEntry( aName );
301 aRange.aStart.Format( aRefStr, SCA_ABS_3D, pDoc, pDoc->GetAddressConvention() );
302 aLbOutPos.SetEntryData( nInsert, new String( aRefStr ) );
307 if (bNewOutput)
309 // Output to a new sheet by default for a brand-new output.
310 aLbOutPos.SelectEntryPos(1);
311 aEdOutPos.Disable();
312 aRbOutPos.Disable();
314 else
316 // Modifying an existing dp output.
318 if ( thePivotData.nTab != MAXTAB+1 )
320 String aStr;
321 ScAddress( thePivotData.nCol,
322 thePivotData.nRow,
323 thePivotData.nTab ).Format( aStr, STD_FORMAT, pDoc, pDoc->GetAddressConvention() );
324 aEdOutPos.SetText( aStr );
325 EdModifyHdl(0);
327 else
329 aLbOutPos.SelectEntryPos( aLbOutPos.GetEntryCount()-1 );
330 SelAreaHdl(NULL);
334 aBtnIgnEmptyRows.Check( thePivotData.bIgnoreEmptyRows );
335 aBtnDetectCat .Check( thePivotData.bDetectCategories );
336 aBtnTotalCol .Check( thePivotData.bMakeTotalCol );
337 aBtnTotalRow .Check( thePivotData.bMakeTotalRow );
339 if( const ScDPSaveData* pSaveData = xDlgDPObject->GetSaveData() )
341 aBtnFilter.Check( pSaveData->GetFilterButton() );
342 aBtnDrillDown.Check( pSaveData->GetDrillDown() );
344 else
346 aBtnFilter.Check();
347 aBtnDrillDown.Check();
350 aWndPage.SetHelpId( HID_SC_DPLAY_PAGE );
351 aWndCol.SetHelpId( HID_SC_DPLAY_COLUMN );
352 aWndRow.SetHelpId( HID_SC_DPLAY_ROW );
353 aWndData.SetHelpId( HID_SC_DPLAY_DATA );
354 aWndSelect.SetHelpId( HID_SC_DPLAY_SELECT );
356 InitFocus();
358 // SetDispatcherLock( TRUE ); // Modal-Modus einschalten
360 //@BugID 54702 Enablen/Disablen nur noch in Basisklasse
361 //SFX_APPWINDOW->Disable(FALSE); //! allgemeine Methode im ScAnyRefDlg
365 //----------------------------------------------------------------------------
367 BOOL __EXPORT ScDPLayoutDlg::Close()
369 return DoClose( ScPivotLayoutWrapper::GetChildWindowId() );
372 //----------------------------------------------------------------------------
374 void ScDPLayoutDlg::StateChanged( StateChangedType nStateChange )
376 ScAnyRefDlg::StateChanged( nStateChange );
378 if ( nStateChange == STATE_CHANGE_INITSHOW )
380 // #124828# Hiding the FixedTexts and clearing the tab stop style bits
381 // has to be done after assigning the mnemonics, but Paint is too late,
382 // because the test tool may send key events to the dialog when it isn't visible.
383 // Mnemonics are assigned in the Dialog::StateChanged for STATE_CHANGE_INITSHOW,
384 // so this can be done immediately afterwards.
386 aWndPage.UseMnemonic();
387 aWndCol.UseMnemonic();
388 aWndRow.UseMnemonic();
389 aWndData.UseMnemonic();
393 //----------------------------------------------------------------------------
395 void ScDPLayoutDlg::InitWndSelect( const vector<ScDPLabelDataRef>& rLabels )
397 size_t nLabelCount = rLabels.size();
398 if (nLabelCount > MAX_LABELS)
399 nLabelCount = MAX_LABELS;
400 size_t nLast = (nLabelCount > PAGE_SIZE) ? (PAGE_SIZE - 1) : (nLabelCount - 1);
402 aLabelDataArr.clear();
403 aLabelDataArr.reserve( nLabelCount );
404 for ( size_t i=0; i < nLabelCount; i++ )
406 aLabelDataArr.push_back(*rLabels[i]);
408 if ( i <= nLast )
410 aWndSelect.AddField(aLabelDataArr[i].getDisplayName(), i);
411 aSelectArr[i].reset( new ScDPFuncData( aLabelDataArr[i].mnCol, aLabelDataArr[i].mnFuncMask ) );
417 //----------------------------------------------------------------------------
419 void ScDPLayoutDlg::InitWnd( PivotField* pArr, long nCount, ScDPFieldType eType )
421 if ( pArr && (eType != TYPE_SELECT) )
423 ScDPFuncDataVec* pInitArr = NULL;
424 ScDPFieldWindow* pInitWnd = NULL;
425 BOOL bDataArr = FALSE;
427 switch ( eType )
429 case TYPE_PAGE:
430 pInitArr = &aPageArr;
431 pInitWnd = &aWndPage;
432 break;
434 case TYPE_COL:
435 pInitArr = &aColArr;
436 pInitWnd = &aWndCol;
437 break;
439 case TYPE_ROW:
440 pInitArr = &aRowArr;
441 pInitWnd = &aWndRow;
442 break;
444 case TYPE_DATA:
445 pInitArr = &aDataArr;
446 pInitWnd = &aWndData;
447 bDataArr = TRUE;
448 break;
449 default:
450 break;
453 if ( pInitArr && pInitWnd )
455 long j=0;
456 for ( long i=0; (i<nCount); i++ )
458 SCCOL nCol = pArr[i].nCol;
459 USHORT nMask = pArr[i].nFuncMask;
461 if ( nCol != PIVOT_DATA_FIELD )
463 (*pInitArr)[j].reset( new ScDPFuncData( nCol, nMask, pArr[i].maFieldRef ) );
465 if ( !bDataArr )
467 pInitWnd->AddField( GetLabelString( nCol ), j );
469 else
471 ScDPLabelData* pData = GetLabelData( nCol );
472 DBG_ASSERT( pData, "ScDPLabelData not found" );
473 if (pData)
475 String aStr( GetFuncString( (*pInitArr)[j]->mnFuncMask,
476 pData->mbIsValue ) );
478 aStr += GetLabelString( nCol );
479 pInitWnd->AddField( aStr, j );
481 pData->mnFuncMask = nMask;
484 ++j;
487 // Do not redraw here -> first the FixedText has to get its mnemonic char
488 // pInitWnd->Redraw();
494 //----------------------------------------------------------------------------
496 void ScDPLayoutDlg::InitFocus()
498 if( aWndSelect.IsEmpty() )
500 aBtnOk.GrabFocus();
501 NotifyFieldFocus( TYPE_SELECT, FALSE );
503 else
504 aWndSelect.GrabFocus();
507 void ScDPLayoutDlg::InitFields()
509 InitWndSelect(thePivotData.maLabelArray);
510 InitWnd( thePivotData.aPageArr, static_cast<long>(thePivotData.nPageCount), TYPE_PAGE );
511 InitWnd( thePivotData.aColArr, static_cast<long>(thePivotData.nColCount), TYPE_COL );
512 InitWnd( thePivotData.aRowArr, static_cast<long>(thePivotData.nRowCount), TYPE_ROW );
513 InitWnd( thePivotData.aDataArr, static_cast<long>(thePivotData.nDataCount), TYPE_DATA );
515 size_t nLabels = thePivotData.maLabelArray.size();
516 aSlider.SetPageSize( PAGE_SIZE );
517 aSlider.SetVisibleSize( PAGE_SIZE );
518 aSlider.SetLineSize( LINE_SIZE );
519 aSlider.SetRange( Range( 0, static_cast<long>(((nLabels+LINE_SIZE-1)/LINE_SIZE)*LINE_SIZE) ) );
521 if ( nLabels > PAGE_SIZE )
523 aSlider.SetEndScrollHdl( LINK( this, ScDPLayoutDlg, ScrollHdl ) );
524 aSlider.Show();
526 else
527 aSlider.Hide();
530 //----------------------------------------------------------------------------
532 void ScDPLayoutDlg::AddField( size_t nFromIndex, ScDPFieldType eToType, const Point& rAtPos )
534 ScDPFuncData fData( *(aSelectArr[nFromIndex]) );
535 size_t nAt = 0;
536 ScDPFieldWindow* toWnd = NULL;
537 ScDPFieldWindow* rmWnd1 = NULL;
538 ScDPFieldWindow* rmWnd2 = NULL;
539 ScDPFuncDataVec* toArr = NULL;
540 ScDPFuncDataVec* rmArr1 = NULL;
541 ScDPFuncDataVec* rmArr2 = NULL;
542 BOOL bDataArr = FALSE;
544 switch ( eToType )
546 case TYPE_PAGE:
547 toWnd = &aWndPage;
548 rmWnd1 = &aWndRow;
549 rmWnd2 = &aWndCol;
550 toArr = &aPageArr;
551 rmArr1 = &aRowArr;
552 rmArr2 = &aColArr;
553 break;
555 case TYPE_COL:
556 toWnd = &aWndCol;
557 rmWnd1 = &aWndPage;
558 rmWnd2 = &aWndRow;
559 toArr = &aColArr;
560 rmArr1 = &aPageArr;
561 rmArr2 = &aRowArr;
562 break;
564 case TYPE_ROW:
565 toWnd = &aWndRow;
566 rmWnd1 = &aWndPage;
567 rmWnd2 = &aWndCol;
568 toArr = &aRowArr;
569 rmArr1 = &aPageArr;
570 rmArr2 = &aColArr;
571 break;
573 case TYPE_DATA:
574 toWnd = &aWndData;
575 toArr = &aDataArr;
576 bDataArr = TRUE;
577 break;
579 default:
581 // added to avoid warnings
585 if ( (toArr->back().get() == NULL)
586 && (!Contains( toArr, fData.mnCol, nAt )) )
588 // ggF. in anderem Fenster entfernen
589 if ( rmArr1 )
591 if ( Contains( rmArr1, fData.mnCol, nAt ) )
593 rmWnd1->DelField( nAt );
594 Remove( rmArr1, nAt );
597 if ( rmArr2 )
599 if ( Contains( rmArr2, fData.mnCol, nAt ) )
601 rmWnd2->DelField( nAt );
602 Remove( rmArr2, nAt );
606 ScDPLabelData& rData = aLabelDataArr[nFromIndex+nOffset];
607 size_t nAddedAt = 0;
609 if ( !bDataArr )
611 if ( toWnd->AddField( rData.getDisplayName(),
612 DlgPos2WndPos( rAtPos, *toWnd ),
613 nAddedAt ) )
615 Insert( toArr, fData, nAddedAt );
616 toWnd->GrabFocus();
619 else
621 USHORT nMask = fData.mnFuncMask;
622 OUString aStr = GetFuncString( nMask, rData.mbIsValue );
624 aStr += rData.getDisplayName();
626 if ( toWnd->AddField( aStr,
627 DlgPos2WndPos( rAtPos, *toWnd ),
628 nAddedAt ) )
630 fData.mnFuncMask = nMask;
631 Insert( toArr, fData, nAddedAt );
632 toWnd->GrabFocus();
640 //----------------------------------------------------------------------------
642 void ScDPLayoutDlg::MoveField( ScDPFieldType eFromType, size_t nFromIndex, ScDPFieldType eToType, const Point& rAtPos )
644 if ( eFromType == TYPE_SELECT )
645 AddField( nFromIndex, eToType, rAtPos );
646 else if ( eFromType != eToType )
648 ScDPFieldWindow* fromWnd = NULL;
649 ScDPFieldWindow* toWnd = NULL;
650 ScDPFieldWindow* rmWnd1 = NULL;
651 ScDPFieldWindow* rmWnd2 = NULL;
652 ScDPFuncDataVec* fromArr = NULL;
653 ScDPFuncDataVec* toArr = NULL;
654 ScDPFuncDataVec* rmArr1 = NULL;
655 ScDPFuncDataVec* rmArr2 = NULL;
656 size_t nAt = 0;
657 BOOL bDataArr = FALSE;
659 switch ( eFromType )
661 case TYPE_PAGE:
662 fromWnd = &aWndPage;
663 fromArr = &aPageArr;
664 break;
666 case TYPE_COL:
667 fromWnd = &aWndCol;
668 fromArr = &aColArr;
669 break;
671 case TYPE_ROW:
672 fromWnd = &aWndRow;
673 fromArr = &aRowArr;
674 break;
676 case TYPE_DATA:
677 fromWnd = &aWndData;
678 fromArr = &aDataArr;
679 break;
681 default:
683 // added to avoid warnings
687 switch ( eToType )
689 case TYPE_PAGE:
690 toWnd = &aWndPage;
691 toArr = &aPageArr;
692 rmWnd1 = &aWndCol;
693 rmWnd2 = &aWndRow;
694 rmArr1 = &aColArr;
695 rmArr2 = &aRowArr;
696 break;
698 case TYPE_COL:
699 toWnd = &aWndCol;
700 toArr = &aColArr;
701 rmWnd1 = &aWndPage;
702 rmWnd2 = &aWndRow;
703 rmArr1 = &aPageArr;
704 rmArr2 = &aRowArr;
705 break;
707 case TYPE_ROW:
708 toWnd = &aWndRow;
709 toArr = &aRowArr;
710 rmWnd1 = &aWndPage;
711 rmWnd2 = &aWndCol;
712 rmArr1 = &aPageArr;
713 rmArr2 = &aColArr;
714 break;
716 case TYPE_DATA:
717 toWnd = &aWndData;
718 toArr = &aDataArr;
719 bDataArr = TRUE;
720 break;
722 default:
724 // added to avoid warnings
728 if ( fromArr && toArr && fromWnd && toWnd )
730 ScDPFuncData fData( *((*fromArr)[nFromIndex]) );
732 if ( Contains( fromArr, fData.mnCol, nAt ) )
734 fromWnd->DelField( nAt );
735 Remove( fromArr, nAt );
737 if ( (toArr->back().get() == NULL)
738 && (!Contains( toArr, fData.mnCol, nAt )) )
740 size_t nAddedAt = 0;
741 if ( !bDataArr )
743 // ggF. in anderem Fenster entfernen
744 if ( rmArr1 )
746 if ( Contains( rmArr1, fData.mnCol, nAt ) )
748 rmWnd1->DelField( nAt );
749 Remove( rmArr1, nAt );
752 if ( rmArr2 )
754 if ( Contains( rmArr2, fData.mnCol, nAt ) )
756 rmWnd2->DelField( nAt );
757 Remove( rmArr2, nAt );
761 if ( toWnd->AddField( GetLabelString( fData.mnCol ),
762 DlgPos2WndPos( rAtPos, *toWnd ),
763 nAddedAt ) )
765 Insert( toArr, fData, nAddedAt );
766 toWnd->GrabFocus();
769 else
771 String aStr;
772 USHORT nMask = fData.mnFuncMask;
773 aStr = GetFuncString( nMask );
774 aStr += GetLabelString( fData.mnCol );
776 if ( toWnd->AddField( aStr,
777 DlgPos2WndPos( rAtPos, *toWnd ),
778 nAddedAt ) )
780 fData.mnFuncMask = nMask;
781 Insert( toArr, fData, nAddedAt );
782 toWnd->GrabFocus();
789 else // -> eFromType == eToType
791 ScDPFieldWindow* theWnd = NULL;
792 ScDPFuncDataVec* theArr = NULL;
793 size_t nAt = 0;
794 size_t nToIndex = 0;
795 Point aToPos;
796 BOOL bDataArr = FALSE;
798 switch ( eFromType )
800 case TYPE_PAGE:
801 theWnd = &aWndPage;
802 theArr = &aPageArr;
803 break;
805 case TYPE_COL:
806 theWnd = &aWndCol;
807 theArr = &aColArr;
808 break;
810 case TYPE_ROW:
811 theWnd = &aWndRow;
812 theArr = &aRowArr;
813 break;
815 case TYPE_DATA:
816 theWnd = &aWndData;
817 theArr = &aDataArr;
818 bDataArr = TRUE;
819 break;
821 default:
823 // added to avoid warnings
827 ScDPFuncData fData( *((*theArr)[nFromIndex]) );
829 if ( Contains( theArr, fData.mnCol, nAt ) )
831 aToPos = DlgPos2WndPos( rAtPos, *theWnd );
832 theWnd->GetExistingIndex( aToPos, nToIndex );
834 if ( nToIndex != nAt )
836 size_t nAddedAt = 0;
838 theWnd->DelField( nAt );
839 Remove( theArr, nAt );
841 if ( !bDataArr )
843 if ( theWnd->AddField( GetLabelString( fData.mnCol ),
844 aToPos,
845 nAddedAt ) )
847 Insert( theArr, fData, nAddedAt );
850 else
852 String aStr;
853 USHORT nMask = fData.mnFuncMask;
854 aStr = GetFuncString( nMask );
855 aStr += GetLabelString( fData.mnCol );
857 if ( theWnd->AddField( aStr,
858 DlgPos2WndPos( rAtPos, *theWnd ),
859 nAddedAt ) )
861 fData.mnFuncMask = nMask;
862 Insert( theArr, fData, nAddedAt );
870 //----------------------------------------------------------------------------
872 void ScDPLayoutDlg::RemoveField( ScDPFieldType eFromType, size_t nIndex )
874 ScDPFuncDataVec* pArr = NULL;
875 switch( eFromType )
877 case TYPE_PAGE: pArr = &aPageArr; break;
878 case TYPE_COL: pArr = &aColArr; break;
879 case TYPE_ROW: pArr = &aRowArr; break;
880 case TYPE_DATA: pArr = &aDataArr; break;
881 default:
883 // added to avoid warnings
887 if( pArr )
889 ScDPFieldWindow& rWnd = GetFieldWindow( eFromType );
890 rWnd.DelField( nIndex );
891 Remove( pArr, nIndex );
892 if( rWnd.IsEmpty() ) InitFocus();
896 //----------------------------------------------------------------------------
898 void ScDPLayoutDlg::NotifyMouseButtonUp( const Point& rAt )
900 if ( bIsDrag )
902 bIsDrag = FALSE;
904 ScDPFieldType eDnDToType = TYPE_SELECT;
905 Point aPos = ScreenToOutputPixel( rAt );
906 BOOL bDel = FALSE;
908 if ( aRectPage.IsInside( aPos ) )
910 eDnDToType = TYPE_PAGE;
911 bDel = FALSE;
913 else if ( aRectCol.IsInside( aPos ) )
915 eDnDToType = TYPE_COL;
916 bDel = FALSE;
918 else if ( aRectRow.IsInside( aPos ) )
920 eDnDToType = TYPE_ROW;
921 bDel = FALSE;
923 else if ( aRectData.IsInside( aPos ) )
925 eDnDToType = TYPE_DATA;
926 bDel = FALSE;
928 else if ( aRectSelect.IsInside( aPos ) )
930 eDnDToType = TYPE_SELECT;
931 bDel = TRUE;
933 else
934 bDel = TRUE;
936 if ( bDel )
937 RemoveField( eDnDFromType, nDnDFromIndex );
938 else
939 MoveField( eDnDFromType, nDnDFromIndex, eDnDToType, aPos );
944 //----------------------------------------------------------------------------
946 PointerStyle ScDPLayoutDlg::NotifyMouseMove( const Point& rAt )
948 PointerStyle ePtr = POINTER_ARROW;
950 if ( bIsDrag )
952 Point aPos = ScreenToOutputPixel( rAt );
954 if ( aRectPage.IsInside( aPos ) )
955 ePtr = lclGetPointerForField( TYPE_PAGE );
956 else if ( aRectCol.IsInside( aPos ) )
957 ePtr = lclGetPointerForField( TYPE_COL );
958 else if ( aRectRow.IsInside( aPos ) )
959 ePtr = lclGetPointerForField( TYPE_ROW );
960 else if ( aRectData.IsInside( aPos ) )
961 ePtr = lclGetPointerForField( TYPE_DATA );
962 else if ( eDnDFromType != TYPE_SELECT )
963 ePtr = POINTER_PIVOT_DELETE;
964 else if ( aRectSelect.IsInside( aPos ) )
965 ePtr = lclGetPointerForField( TYPE_SELECT );
966 else
967 ePtr = POINTER_NOTALLOWED;
970 return ePtr;
974 //----------------------------------------------------------------------------
976 PointerStyle ScDPLayoutDlg::NotifyMouseButtonDown( ScDPFieldType eType, size_t nFieldIndex )
978 bIsDrag = TRUE;
979 eDnDFromType = eType;
980 nDnDFromIndex = nFieldIndex;
981 return lclGetPointerForField( eType );
985 //----------------------------------------------------------------------------
987 void ScDPLayoutDlg::NotifyDoubleClick( ScDPFieldType eType, size_t nFieldIndex )
989 ScDPFuncDataVec* pArr = NULL;
990 switch ( eType )
992 case TYPE_PAGE: pArr = &aPageArr; break;
993 case TYPE_COL: pArr = &aColArr; break;
994 case TYPE_ROW: pArr = &aRowArr; break;
995 case TYPE_DATA: pArr = &aDataArr; break;
996 default:
998 // added to avoid warnings
1002 if ( pArr )
1004 if ( nFieldIndex >= pArr->size() )
1006 DBG_ERROR("invalid selection");
1007 return;
1010 size_t nArrPos = 0;
1011 if( ScDPLabelData* pData = GetLabelData( (*pArr)[nFieldIndex]->mnCol, &nArrPos ) )
1013 ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
1014 DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001
1016 switch ( eType )
1018 case TYPE_PAGE:
1019 case TYPE_COL:
1020 case TYPE_ROW:
1022 // list of names of all data fields
1023 std::vector< String > aDataFieldNames;
1024 for( ScDPFuncDataVec::const_iterator aIt = aDataArr.begin(), aEnd = aDataArr.end();
1025 (aIt != aEnd) && aIt->get(); ++aIt )
1027 String aName( GetLabelString( (*aIt)->mnCol ) );
1028 if( aName.Len() )
1029 aDataFieldNames.push_back( aName );
1032 bool bLayout = (eType == TYPE_ROW) &&
1033 ((aDataFieldNames.size() > 1) || ((nFieldIndex + 1 < pArr->size()) && (*pArr)[nFieldIndex+1].get()));
1035 AbstractScDPSubtotalDlg* pDlg = pFact->CreateScDPSubtotalDlg(
1036 this, RID_SCDLG_PIVOTSUBT,
1037 *xDlgDPObject, *pData, *(*pArr)[nFieldIndex], aDataFieldNames, bLayout );
1039 if ( pDlg->Execute() == RET_OK )
1041 pDlg->FillLabelData( *pData );
1042 (*pArr)[nFieldIndex]->mnFuncMask = pData->mnFuncMask;
1044 delete pDlg;
1046 break;
1048 case TYPE_DATA:
1050 AbstractScDPFunctionDlg* pDlg = pFact->CreateScDPFunctionDlg(
1051 this, RID_SCDLG_DPDATAFIELD,
1052 aLabelDataArr, *pData, *(*pArr)[nFieldIndex] );
1054 if ( pDlg->Execute() == RET_OK )
1056 (*pArr)[nFieldIndex]->mnFuncMask = pData->mnFuncMask = pDlg->GetFuncMask();
1057 (*pArr)[nFieldIndex]->maFieldRef = pDlg->GetFieldRef();
1059 String aStr( GetFuncString ( aDataArr[nFieldIndex]->mnFuncMask ) );
1060 aStr += GetLabelString( aDataArr[nFieldIndex]->mnCol );
1061 aWndData.SetFieldText( aStr, nFieldIndex );
1063 delete pDlg;
1065 break;
1067 default:
1069 // added to avoid warnings
1076 //----------------------------------------------------------------------------
1078 void ScDPLayoutDlg::NotifyFieldFocus( ScDPFieldType eType, BOOL bGotFocus )
1080 /* Enable Remove/Options buttons on GetFocus in field window.
1081 #107616# Enable them also, if dialog is deactivated (click into document).
1082 The !IsActive() condition handles the case that a LoseFocus event of a
1083 field window would follow the Deactivate event of this dialog. */
1084 BOOL bEnable = (bGotFocus || !IsActive()) && (eType != TYPE_SELECT);
1086 // #128113# The TestTool may set the focus into an empty field.
1087 // Then the Remove/Options buttons must be disabled.
1088 if ( bEnable && bGotFocus && GetFieldWindow( eType ).IsEmpty() )
1089 bEnable = FALSE;
1091 aBtnRemove.Enable( bEnable );
1092 aBtnOptions.Enable( bEnable );
1093 if( bGotFocus )
1094 eLastActiveType = eType;
1097 //----------------------------------------------------------------------------
1099 void ScDPLayoutDlg::NotifyMoveField( ScDPFieldType eToType )
1101 ScDPFieldWindow& rWnd = GetFieldWindow( eLastActiveType );
1102 if( (eToType != TYPE_SELECT) && !rWnd.IsEmpty() )
1104 MoveField( eLastActiveType, rWnd.GetSelectedField(), eToType, GetFieldWindow( eToType ).GetLastPosition() );
1105 if( rWnd.IsEmpty() )
1106 NotifyFieldFocus( eToType, TRUE );
1107 else
1108 rWnd.GrabFocus();
1109 if( eLastActiveType == TYPE_SELECT )
1110 aWndSelect.SelectNext();
1112 else
1113 InitFocus();
1116 //----------------------------------------------------------------------------
1118 void ScDPLayoutDlg::NotifyRemoveField( ScDPFieldType eType, size_t nFieldIndex )
1120 if( eType != TYPE_SELECT )
1121 RemoveField( eType, nFieldIndex );
1124 //----------------------------------------------------------------------------
1126 BOOL ScDPLayoutDlg::NotifyMoveSlider( USHORT nKeyCode )
1128 long nOldPos = aSlider.GetThumbPos();
1129 switch( nKeyCode )
1131 case KEY_HOME: aSlider.DoScroll( 0 ); break;
1132 case KEY_END: aSlider.DoScroll( aSlider.GetRangeMax() ); break;
1133 case KEY_UP:
1134 case KEY_LEFT: aSlider.DoScrollAction( SCROLL_LINEUP ); break;
1135 case KEY_DOWN:
1136 case KEY_RIGHT: aSlider.DoScrollAction( SCROLL_LINEDOWN ); break;
1138 return nOldPos != aSlider.GetThumbPos();
1141 //----------------------------------------------------------------------------
1143 void ScDPLayoutDlg::Deactivate()
1145 /* #107616# If the dialog has been deactivated (click into document), the LoseFocus
1146 event from field window disables Remove/Options buttons. Re-enable them here by
1147 simulating a GetFocus event. Event order of LoseFocus and Deactivate is not important.
1148 The last event will enable the buttons in both cases (see NotifyFieldFocus). */
1149 NotifyFieldFocus( eLastActiveType, TRUE );
1152 //----------------------------------------------------------------------------
1154 BOOL ScDPLayoutDlg::Contains( ScDPFuncDataVec* pArr, SCsCOL nCol, size_t& nAt )
1156 if ( !pArr )
1157 return FALSE;
1159 BOOL bFound = FALSE;
1160 size_t i = 0;
1162 while ( (i<pArr->size()) && ((*pArr)[i].get() != NULL) && !bFound )
1164 bFound = ((*pArr)[i]->mnCol == nCol);
1165 if ( bFound )
1166 nAt = i;
1167 i++;
1170 return bFound;
1174 //----------------------------------------------------------------------------
1176 void ScDPLayoutDlg::Remove( ScDPFuncDataVec* pArr, size_t nAt )
1178 if ( !pArr || (nAt>=pArr->size()) )
1179 return;
1181 pArr->erase( pArr->begin() + nAt );
1182 pArr->push_back( ScDPFuncDataRef() );
1186 //----------------------------------------------------------------------------
1188 void ScDPLayoutDlg::Insert( ScDPFuncDataVec* pArr, const ScDPFuncData& rFData, size_t nAt )
1190 if ( !pArr || (nAt>=pArr->size()) )
1191 return;
1193 if ( (*pArr)[nAt].get() == NULL )
1195 (*pArr)[nAt].reset( new ScDPFuncData( rFData ) );
1197 else
1199 if ( pArr->back().get() == NULL ) // mind. ein Slot frei?
1201 pArr->insert( pArr->begin() + nAt, ScDPFuncDataRef( new ScDPFuncData( rFData ) ) );
1202 pArr->erase( pArr->end() - 1 );
1208 //----------------------------------------------------------------------------
1210 ScDPLabelData* ScDPLayoutDlg::GetLabelData( SCsCOL nCol, size_t* pnPos )
1212 ScDPLabelData* pData = 0;
1213 for( ScDPLabelDataVec::iterator aIt = aLabelDataArr.begin(), aEnd = aLabelDataArr.end(); !pData && (aIt != aEnd); ++aIt )
1215 if( aIt->mnCol == nCol )
1217 pData = &*aIt;
1218 if( pnPos ) *pnPos = aIt - aLabelDataArr.begin();
1221 return pData;
1225 //----------------------------------------------------------------------------
1227 String ScDPLayoutDlg::GetLabelString( SCsCOL nCol )
1229 ScDPLabelData* pData = GetLabelData( nCol );
1230 DBG_ASSERT( pData, "LabelData not found" );
1231 if (pData)
1232 return pData->getDisplayName();
1233 return String();
1237 //----------------------------------------------------------------------------
1239 String ScDPLayoutDlg::GetFuncString( USHORT& rFuncMask, BOOL bIsValue )
1241 String aStr;
1243 if ( rFuncMask == PIVOT_FUNC_NONE
1244 || rFuncMask == PIVOT_FUNC_AUTO )
1246 if ( bIsValue )
1248 aStr = FSTR(PIVOTSTR_SUM);
1249 rFuncMask = PIVOT_FUNC_SUM;
1251 else
1253 aStr = FSTR(PIVOTSTR_COUNT);
1254 rFuncMask = PIVOT_FUNC_COUNT;
1257 else if ( rFuncMask == PIVOT_FUNC_SUM ) aStr = FSTR(PIVOTSTR_SUM);
1258 else if ( rFuncMask == PIVOT_FUNC_COUNT ) aStr = FSTR(PIVOTSTR_COUNT);
1259 else if ( rFuncMask == PIVOT_FUNC_AVERAGE ) aStr = FSTR(PIVOTSTR_AVG);
1260 else if ( rFuncMask == PIVOT_FUNC_MAX ) aStr = FSTR(PIVOTSTR_MAX);
1261 else if ( rFuncMask == PIVOT_FUNC_MIN ) aStr = FSTR(PIVOTSTR_MIN);
1262 else if ( rFuncMask == PIVOT_FUNC_PRODUCT ) aStr = FSTR(PIVOTSTR_PROD);
1263 else if ( rFuncMask == PIVOT_FUNC_COUNT_NUM ) aStr = FSTR(PIVOTSTR_COUNT2);
1264 else if ( rFuncMask == PIVOT_FUNC_STD_DEV ) aStr = FSTR(PIVOTSTR_DEV);
1265 else if ( rFuncMask == PIVOT_FUNC_STD_DEVP ) aStr = FSTR(PIVOTSTR_DEV2);
1266 else if ( rFuncMask == PIVOT_FUNC_STD_VAR ) aStr = FSTR(PIVOTSTR_VAR);
1267 else if ( rFuncMask == PIVOT_FUNC_STD_VARP ) aStr = FSTR(PIVOTSTR_VAR2);
1268 else
1270 aStr = ScGlobal::GetRscString( STR_TABLE_ERGEBNIS );
1271 aStr.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " - " ));
1274 return aStr;
1278 //----------------------------------------------------------------------------
1280 Point ScDPLayoutDlg::DlgPos2WndPos( const Point& rPt, Window& rWnd )
1282 Point aWndPt( rPt );
1283 aWndPt.X() = rPt.X()-rWnd.GetPosPixel().X();
1284 aWndPt.Y() = rPt.Y()-rWnd.GetPosPixel().Y();
1286 return aWndPt;
1290 //----------------------------------------------------------------------------
1292 void ScDPLayoutDlg::CalcWndSizes()
1294 // row/column/data area sizes
1295 aWndPage.SetSizePixel( Size( MAX_PAGEFIELDS * OWIDTH / 2, 2 * OHEIGHT ) );
1296 aWndRow.SetSizePixel( Size( OWIDTH, MAX_FIELDS * OHEIGHT ) );
1297 aWndCol.SetSizePixel( Size( MAX_FIELDS * OWIDTH / 2, 2 * OHEIGHT ) );
1298 aWndData.SetSizePixel( Size( MAX_FIELDS * OWIDTH / 2, MAX_FIELDS * OHEIGHT ) );
1300 // #i29203# align right border of page window with data window
1301 long nDataPosX = aWndData.GetPosPixel().X() + aWndData.GetSizePixel().Width();
1302 aWndPage.SetPosPixel( Point( nDataPosX - aWndPage.GetSizePixel().Width(), aWndPage.GetPosPixel().Y() ) );
1304 // selection area
1305 aWndSelect.SetSizePixel( Size(
1306 2 * OWIDTH + SSPACE, LINE_SIZE * OHEIGHT + (LINE_SIZE - 1) * SSPACE ) );
1308 // scroll bar
1309 Point aSliderPos( aWndSelect.GetPosPixel() );
1310 Size aSliderSize( aWndSelect.GetSizePixel() );
1311 aSliderPos.Y() += aSliderSize.Height() + SSPACE;
1312 aSliderSize.Height() = GetSettings().GetStyleSettings().GetScrollBarSize();
1313 aSlider.SetPosSizePixel( aSliderPos, aSliderSize );
1315 aRectPage = Rectangle( aWndPage.GetPosPixel(), aWndPage.GetSizePixel() );
1316 aRectRow = Rectangle( aWndRow.GetPosPixel(), aWndRow.GetSizePixel() );
1317 aRectCol = Rectangle( aWndCol.GetPosPixel(), aWndCol.GetSizePixel() );
1318 aRectData = Rectangle( aWndData.GetPosPixel(), aWndData.GetSizePixel() );
1319 aRectSelect = Rectangle( aWndSelect.GetPosPixel(), aWndSelect.GetSizePixel() );
1323 //----------------------------------------------------------------------------
1325 BOOL ScDPLayoutDlg::GetPivotArrays( PivotField* pPageArr,
1326 PivotField* pColArr,
1327 PivotField* pRowArr,
1328 PivotField* pDataArr,
1329 USHORT& rPageCount,
1330 USHORT& rColCount,
1331 USHORT& rRowCount,
1332 USHORT& rDataCount )
1334 BOOL bFit = TRUE;
1335 USHORT i=0;
1337 for ( i=0; (i<aDataArr.size()) && (aDataArr[i].get() != NULL ); i++ )
1338 lcl_FillToPivotField( pDataArr[i], *aDataArr[i] );
1339 rDataCount = i;
1341 for ( i=0; (i<aPageArr.size()) && (aPageArr[i].get() != NULL ); i++ )
1342 lcl_FillToPivotField( pPageArr[i], *aPageArr[i] );
1343 rPageCount = i;
1345 for ( i=0; (i<aColArr.size()) && (aColArr[i].get() != NULL ); i++ )
1346 lcl_FillToPivotField( pColArr[i], *aColArr[i] );
1347 rColCount = i;
1349 for ( i=0; (i<aRowArr.size()) && (aRowArr[i].get() != NULL ); i++ )
1350 lcl_FillToPivotField( pRowArr[i], *aRowArr[i] );
1351 rRowCount = i;
1353 if ( rRowCount < aRowArr.size() )
1354 pRowArr[rRowCount++].nCol = PIVOT_DATA_FIELD;
1355 else if ( rColCount < aColArr.size() )
1356 pColArr[rColCount++].nCol = PIVOT_DATA_FIELD;
1357 else
1358 bFit = FALSE; // kein Platz fuer Datenfeld
1360 return bFit;
1363 void ScDPLayoutDlg::UpdateSrcRange()
1365 String theCurPosStr = aEdInPos.GetText();
1366 USHORT nResult = ScRange().Parse(theCurPosStr, pDoc, pDoc->GetAddressConvention());
1368 if ( SCA_VALID != (nResult & SCA_VALID) )
1369 // invalid source range.
1370 return;
1372 ScRefAddress start, end;
1373 ConvertDoubleRef(pDoc, theCurPosStr, 1, start, end, pDoc->GetAddressConvention());
1374 ScRange aNewRange(start.GetAddress(), end.GetAddress());
1375 ScSheetSourceDesc inSheet = *xDlgDPObject->GetSheetDesc();
1377 if (inSheet.aSourceRange == aNewRange)
1378 // new range is identical to the current range. Nothing to do.
1379 return;
1381 ScTabViewShell * pTabViewShell = pViewData->GetViewShell();
1382 inSheet.aSourceRange = aNewRange;
1383 xDlgDPObject->SetSheetDesc(inSheet);
1384 xDlgDPObject->FillOldParam( thePivotData, FALSE );
1385 xDlgDPObject->FillLabelData(thePivotData);
1387 pTabViewShell->SetDialogDPObject(xDlgDPObject.get());
1388 aLabelDataArr.clear();
1389 aWndSelect.ClearFields();
1390 aWndData.ClearFields();
1391 aWndRow.ClearFields();
1392 aWndCol.ClearFields();
1393 aWndPage.ClearFields();
1395 for (size_t i = 0; i < MAX_LABELS; ++i)
1396 aSelectArr[i].reset();
1398 for (size_t i = 0; i < MAX_FIELDS; ++i)
1400 aRowArr[i].reset();
1401 aColArr[i].reset();
1402 aDataArr[i].reset();
1405 for (size_t i = 0; i < MAX_PAGEFIELDS; ++i)
1406 aPageArr[i].reset();
1408 InitFields();
1411 //----------------------------------------------------------------------------
1413 void ScDPLayoutDlg::SetReference( const ScRange& rRef, ScDocument* pDocP )
1415 if ( !bRefInputMode || !pEditActive )
1416 return;
1418 if ( rRef.aStart != rRef.aEnd )
1419 RefInputStart( pEditActive );
1421 if ( pEditActive == &aEdInPos )
1423 String aRefStr;
1424 rRef.Format( aRefStr, SCR_ABS_3D, pDocP, pDocP->GetAddressConvention() );
1425 pEditActive->SetRefString( aRefStr );
1427 else if ( pEditActive == &aEdOutPos )
1429 String aRefStr;
1430 rRef.aStart.Format( aRefStr, STD_FORMAT, pDocP, pDocP->GetAddressConvention() );
1431 pEditActive->SetRefString( aRefStr );
1436 //----------------------------------------------------------------------------
1438 void ScDPLayoutDlg::SetActive()
1440 if ( bRefInputMode )
1442 if ( pEditActive )
1443 pEditActive->GrabFocus();
1445 if ( pEditActive == &aEdInPos )
1446 EdInModifyHdl( NULL );
1447 else if ( pEditActive == &aEdOutPos )
1448 EdModifyHdl( NULL );
1450 else
1452 GrabFocus();
1455 RefInputDone();
1458 //----------------------------------------------------------------------------
1459 // Handler:
1460 //----------------------------------------------------------------------------
1462 IMPL_LINK( ScDPLayoutDlg, ClickHdl, PushButton *, pBtn )
1464 if( pBtn == &aBtnRemove )
1466 ScDPFieldWindow& rWnd = GetFieldWindow( eLastActiveType );
1467 RemoveField( eLastActiveType, rWnd.GetSelectedField() );
1468 if( !rWnd.IsEmpty() ) rWnd.GrabFocus();
1470 else if( pBtn == &aBtnOptions )
1472 ScDPFieldWindow& rWnd = GetFieldWindow( eLastActiveType );
1473 NotifyDoubleClick( eLastActiveType, rWnd.GetSelectedField() );
1474 rWnd.GrabFocus();
1476 return 0;
1479 //----------------------------------------------------------------------------
1481 IMPL_LINK( ScDPLayoutDlg, OkHdl, OKButton *, EMPTYARG )
1483 String aOutPosStr( aEdOutPos.GetText() );
1484 ScAddress aAdrDest;
1485 BOOL bToNewTable = (aLbOutPos.GetSelectEntryPos() == 1);
1486 USHORT nResult = !bToNewTable ? aAdrDest.Parse( aOutPosStr, pDoc, pDoc->GetAddressConvention() ) : 0;
1488 if ( bToNewTable
1489 || ( (aOutPosStr.Len() > 0) && (SCA_VALID == (nResult & SCA_VALID)) ) )
1491 //@BugID 54702 Enablen/Disablen nur noch in Basisklasse
1492 //SFX_APPWINDOW->Enable();
1494 ScPivotParam theOutParam;
1495 PivotPageFieldArr aPageFieldArr;
1496 PivotFieldArr aColFieldArr;
1497 PivotFieldArr aRowFieldArr;
1498 PivotFieldArr aDataFieldArr;
1499 USHORT nPageCount;
1500 USHORT nColCount;
1501 USHORT nRowCount;
1502 USHORT nDataCount;
1504 BOOL bFit = GetPivotArrays( aPageFieldArr, aColFieldArr, aRowFieldArr, aDataFieldArr,
1505 nPageCount, nColCount, nRowCount, nDataCount );
1506 if ( bFit )
1508 ScDPSaveData* pOldSaveData = xDlgDPObject->GetSaveData();
1510 ScRange aOutRange( aAdrDest ); // bToNewTable is passed separately
1512 ScDPSaveData aSaveData;
1513 aSaveData.SetIgnoreEmptyRows( aBtnIgnEmptyRows.IsChecked() );
1514 aSaveData.SetRepeatIfEmpty( aBtnDetectCat.IsChecked() );
1515 aSaveData.SetColumnGrand( aBtnTotalCol.IsChecked() );
1516 aSaveData.SetRowGrand( aBtnTotalRow.IsChecked() );
1517 aSaveData.SetFilterButton( aBtnFilter.IsChecked() );
1518 aSaveData.SetDrillDown( aBtnDrillDown.IsChecked() );
1520 uno::Reference<sheet::XDimensionsSupplier> xSource = xDlgDPObject->GetSource();
1522 ScDPObject::ConvertOrientation( aSaveData, aPageFieldArr, nPageCount,
1523 sheet::DataPilotFieldOrientation_PAGE, NULL, 0, 0, xSource, FALSE );
1524 ScDPObject::ConvertOrientation( aSaveData, aColFieldArr, nColCount,
1525 sheet::DataPilotFieldOrientation_COLUMN, NULL, 0, 0, xSource, FALSE );
1526 ScDPObject::ConvertOrientation( aSaveData, aRowFieldArr, nRowCount,
1527 sheet::DataPilotFieldOrientation_ROW, NULL, 0, 0, xSource, FALSE );
1528 ScDPObject::ConvertOrientation( aSaveData, aDataFieldArr, nDataCount,
1529 sheet::DataPilotFieldOrientation_DATA, NULL, 0, 0, xSource, FALSE,
1530 aColFieldArr, nColCount, aRowFieldArr, nRowCount, aPageFieldArr, nPageCount );
1532 for( ScDPLabelDataVec::const_iterator aIt = aLabelDataArr.begin(), aEnd = aLabelDataArr.end(); aIt != aEnd; ++aIt )
1534 if( ScDPSaveDimension* pDim = aSaveData.GetExistingDimensionByName( aIt->maName ) )
1536 pDim->SetUsedHierarchy( aIt->mnUsedHier );
1537 pDim->SetShowEmpty( aIt->mbShowAll );
1538 pDim->SetSortInfo( &aIt->maSortInfo );
1539 pDim->SetLayoutInfo( &aIt->maLayoutInfo );
1540 pDim->SetAutoShowInfo( &aIt->maShowInfo );
1541 ScDPSaveDimension* pOldDim = NULL;
1542 if (pOldSaveData)
1544 // Transfer the existing layout names to new dimension instance.
1545 pOldDim = pOldSaveData->GetExistingDimensionByName(aIt->maName);
1546 if (pOldDim)
1548 const OUString* pLayoutName = pOldDim->GetLayoutName();
1549 if (pLayoutName)
1550 pDim->SetLayoutName(*pLayoutName);
1552 const OUString* pSubtotalName = pOldDim->GetSubtotalName();
1553 if (pSubtotalName)
1554 pDim->SetSubtotalName(*pSubtotalName);
1558 bool bManualSort = ( aIt->maSortInfo.Mode == sheet::DataPilotFieldSortMode::MANUAL );
1560 // visibility of members
1561 for (vector<ScDPLabelData::Member>::const_iterator itr = aIt->maMembers.begin(), itrEnd = aIt->maMembers.end();
1562 itr != itrEnd; ++itr)
1564 ScDPSaveMember* pMember = pDim->GetMemberByName(itr->maName);
1566 // #i40054# create/access members only if flags are not default
1567 // (or in manual sorting mode - to keep the order)
1568 if (bManualSort || !itr->mbVisible || !itr->mbShowDetails)
1570 pMember->SetIsVisible(itr->mbVisible);
1571 pMember->SetShowDetails(itr->mbShowDetails);
1573 if (pOldDim)
1575 // Transfer the existing layout name.
1576 ScDPSaveMember* pOldMember = pOldDim->GetMemberByName(itr->maName);
1577 if (pOldMember)
1579 const OUString* pLayoutName = pOldMember->GetLayoutName();
1580 if (pLayoutName)
1581 pMember->SetLayoutName(*pLayoutName);
1587 ScDPSaveDimension* pDim = aSaveData.GetDataLayoutDimension();
1588 if (pDim && pOldSaveData)
1590 ScDPSaveDimension* pOldDim = pOldSaveData->GetDataLayoutDimension();
1591 if (pOldDim)
1593 const OUString* pLayoutName = pOldDim->GetLayoutName();
1594 if (pLayoutName)
1595 pDim->SetLayoutName(*pLayoutName);
1599 USHORT nWhichPivot = SC_MOD()->GetPool().GetWhich( SID_PIVOT_TABLE );
1600 ScPivotItem aOutItem( nWhichPivot, &aSaveData, &aOutRange, bToNewTable );
1602 bRefInputMode = FALSE; // to allow deselecting when switching sheets
1604 SetDispatcherLock( FALSE );
1605 SwitchToDocument();
1607 // #95513# don't hide the dialog before executing the slot, instead it is used as
1608 // parent for message boxes in ScTabViewShell::GetDialogParent
1610 const SfxPoolItem* pRet = GetBindings().GetDispatcher()->Execute(
1611 SID_PIVOT_TABLE, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD, &aOutItem, 0L, 0L );
1613 bool bSuccess = true;
1614 if (pRet)
1616 const SfxBoolItem* pItem = dynamic_cast<const SfxBoolItem*>(pRet);
1617 if (pItem)
1618 bSuccess = pItem->GetValue();
1620 if (bSuccess)
1621 // Table successfully inserted.
1622 Close();
1623 else
1625 // Table insertion failed. Keep the dialog open.
1626 bRefInputMode = true;
1627 SetDispatcherLock(true);
1630 else
1632 ErrorBox( this, WinBits( WB_OK | WB_DEF_OK ),
1633 ScGlobal::GetRscString( STR_PIVOT_ERROR )
1634 ).Execute();
1637 else
1639 if ( !aBtnMore.GetState() )
1640 aBtnMore.SetState( TRUE );
1642 ErrorBox( this, WinBits( WB_OK | WB_DEF_OK ),
1643 ScGlobal::GetRscString( STR_INVALID_TABREF )
1644 ).Execute();
1645 aEdOutPos.GrabFocus();
1647 return 0;
1651 //----------------------------------------------------------------------------
1653 IMPL_LINK( ScDPLayoutDlg, CancelHdl, CancelButton *, EMPTYARG )
1655 Close();
1656 return 0;
1660 //----------------------------------------------------------------------------
1662 IMPL_LINK( ScDPLayoutDlg, MoreClickHdl, MoreButton *, EMPTYARG )
1664 if ( aBtnMore.GetState() )
1666 bRefInputMode = TRUE;
1667 //@BugID 54702 Enablen/Disablen nur noch in Basisklasse
1668 //SFX_APPWINDOW->Enable();
1669 if ( aEdInPos.IsEnabled() )
1671 aEdInPos.Enable();
1672 aEdInPos.GrabFocus();
1673 aEdInPos.Enable();
1675 else
1677 aEdOutPos.Enable();
1678 aEdOutPos.GrabFocus();
1679 aEdOutPos.Enable();
1682 else
1684 bRefInputMode = FALSE;
1685 //@BugID 54702 Enablen/Disablen nur noch in Basisklasse
1686 //SFX_APPWINDOW->Disable(FALSE); //! allgemeine Methode im ScAnyRefDlg
1688 return 0;
1692 //----------------------------------------------------------------------------
1694 IMPL_LINK( ScDPLayoutDlg, EdModifyHdl, Edit *, EMPTYARG )
1696 String theCurPosStr = aEdOutPos.GetText();
1697 USHORT nResult = ScAddress().Parse( theCurPosStr, pDoc, pDoc->GetAddressConvention() );
1699 if ( SCA_VALID == (nResult & SCA_VALID) )
1701 String* pStr = NULL;
1702 BOOL bFound = FALSE;
1703 USHORT i = 0;
1704 USHORT nCount = aLbOutPos.GetEntryCount();
1706 for ( i=2; i<nCount && !bFound; i++ )
1708 pStr = (String*)aLbOutPos.GetEntryData( i );
1709 bFound = (theCurPosStr == *pStr);
1712 if ( bFound )
1713 aLbOutPos.SelectEntryPos( --i );
1714 else
1715 aLbOutPos.SelectEntryPos( 0 );
1717 return 0;
1721 IMPL_LINK( ScDPLayoutDlg, EdInModifyHdl, Edit *, EMPTYARG )
1723 UpdateSrcRange();
1724 return 0;
1728 //----------------------------------------------------------------------------
1730 IMPL_LINK( ScDPLayoutDlg, SelAreaHdl, ListBox *, EMPTYARG )
1732 String aString;
1733 USHORT nSelPos = aLbOutPos.GetSelectEntryPos();
1735 if ( nSelPos > 1 )
1737 aString = *(String*)aLbOutPos.GetEntryData( nSelPos );
1739 else if ( nSelPos == aLbOutPos.GetEntryCount()-1 ) // auf neue Tabelle?
1741 aEdOutPos.Disable();
1742 aRbOutPos.Disable();
1744 else
1746 aEdOutPos.Enable();
1747 aRbOutPos.Enable();
1750 aEdOutPos.SetText( aString );
1751 return 0;
1755 //----------------------------------------------------------------------------
1757 IMPL_LINK( ScDPLayoutDlg, ScrollHdl, ScrollBar *, EMPTYARG )
1759 long nNewOffset = aSlider.GetThumbPos();
1760 long nOffsetDiff = nNewOffset - nOffset;
1761 nOffset = nNewOffset;
1763 size_t nFields = std::min< size_t >( aLabelDataArr.size() - nOffset, PAGE_SIZE );
1765 aWndSelect.ClearFields();
1767 size_t i=0;
1768 for ( i=0; i<nFields; i++ )
1770 const ScDPLabelData& rData = aLabelDataArr[nOffset+i];
1771 aWndSelect.AddField(rData.getDisplayName(), i);
1772 aSelectArr[i].reset( new ScDPFuncData( rData.mnCol, rData.mnFuncMask ) );
1774 for ( ; i<aSelectArr.size(); i++ )
1775 aSelectArr[i].reset();
1777 aWndSelect.ModifySelectionOffset( nOffsetDiff ); // adjusts selection & redraws
1778 return 0;
1781 //----------------------------------------------------------------------------
1783 IMPL_LINK( ScDPLayoutDlg, GetFocusHdl, Control*, pCtrl )
1785 pEditActive = NULL;
1786 if ( pCtrl == &aEdInPos )
1787 pEditActive = &aEdInPos;
1788 else if ( pCtrl == &aEdOutPos )
1789 pEditActive = &aEdOutPos;
1791 return 0;