diff options
Diffstat (limited to 'sc/source/ui/dbgui/pvlaydlg.cxx')
-rw-r--r-- | sc/source/ui/dbgui/pvlaydlg.cxx | 1823 |
1 files changed, 1823 insertions, 0 deletions
diff --git a/sc/source/ui/dbgui/pvlaydlg.cxx b/sc/source/ui/dbgui/pvlaydlg.cxx new file mode 100644 index 000000000000..56d7e3550cda --- /dev/null +++ b/sc/source/ui/dbgui/pvlaydlg.cxx @@ -0,0 +1,1823 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + + + +//---------------------------------------------------------------------------- + +#include "pvlaydlg.hxx" +#include "dbdocfun.hxx" + +#include <sfx2/dispatch.hxx> +#include <vcl/msgbox.hxx> + +#include <com/sun/star/sheet/DataPilotFieldOrientation.hpp> +#include <com/sun/star/sheet/DataPilotFieldSortMode.hpp> + +#include "uiitems.hxx" +#include "rangeutl.hxx" +#include "document.hxx" +#include "viewdata.hxx" +#include "tabvwsh.hxx" +#include "reffact.hxx" +#include "scresid.hxx" +#include "pvglob.hxx" +//CHINA001 #include "pvfundlg.hxx" +#include "globstr.hrc" +#include "pivot.hrc" +#include "dpobject.hxx" +#include "dpsave.hxx" +#include "dpshttab.hxx" +#include "scmod.hxx" + +#include "sc.hrc" //CHINA001 +#include "scabstdlg.hxx" //CHINA001 +using namespace com::sun::star; +using ::rtl::OUString; +using ::std::vector; + +//---------------------------------------------------------------------------- + +#define FSTR(index) aFuncNameArr[index-1] +#define STD_FORMAT SCA_VALID | SCA_TAB_3D \ + | SCA_COL_ABSOLUTE | SCA_ROW_ABSOLUTE | SCA_TAB_ABSOLUTE + +long PivotGlobal::nObjHeight = 0; // initialized with resource data +long PivotGlobal::nObjWidth = 0; +long PivotGlobal::nSelSpace = 0; + + +//============================================================================ + +namespace { + +void lcl_FillToPivotField( PivotField& rPivotField, const ScDPFuncData& rFuncData ) +{ + rPivotField.nCol = rFuncData.mnCol; + rPivotField.nFuncMask = rFuncData.mnFuncMask; + rPivotField.maFieldRef = rFuncData.maFieldRef; +} + +PointerStyle lclGetPointerForField( ScDPFieldType eType ) +{ + switch( eType ) + { + case TYPE_PAGE: return POINTER_PIVOT_FIELD; + case TYPE_COL: return POINTER_PIVOT_COL; + case TYPE_ROW: return POINTER_PIVOT_ROW; + case TYPE_DATA: return POINTER_PIVOT_FIELD; + case TYPE_SELECT: return POINTER_PIVOT_FIELD; + } + return POINTER_ARROW; +} + +} // namespace + +//============================================================================ + +//---------------------------------------------------------------------------- + +ScDPLayoutDlg::ScDPLayoutDlg( SfxBindings* pB, SfxChildWindow* pCW, Window* pParent, + const ScDPObject& rDPObject ) + : ScAnyRefDlg ( pB, pCW, pParent, RID_SCDLG_PIVOT_LAYOUT ), + aFlLayout ( this, ScResId( FL_LAYOUT ) ), + aFtPage ( this, ScResId( FT_PAGE ) ), + aWndPage ( this, ScResId( WND_PAGE ), TYPE_PAGE, &aFtPage ), + aFtCol ( this, ScResId( FT_COL ) ), + aWndCol ( this, ScResId( WND_COL ), TYPE_COL, &aFtCol ), + aFtRow ( this, ScResId( FT_ROW ) ), + aWndRow ( this, ScResId( WND_ROW ), TYPE_ROW, &aFtRow ), + aFtData ( this, ScResId( FT_DATA ) ), + aWndData ( this, ScResId( WND_DATA ), TYPE_DATA, &aFtData ), + aWndSelect ( this, ScResId( WND_SELECT ), TYPE_SELECT, String(ScResId(STR_SELECT)) ), + aSlider ( this, ScResId( WND_HSCROLL ) ), + aFtInfo ( this, ScResId( FT_INFO ) ), + + aFlAreas ( this, ScResId( FL_OUTPUT ) ), + + aFtInArea ( this, ScResId( FT_INAREA) ), + aEdInPos ( this, ScResId( ED_INAREA) ), + aRbInPos ( this, ScResId( RB_INAREA ), &aEdInPos, this ), + + aLbOutPos ( this, ScResId( LB_OUTAREA ) ), + aFtOutArea ( this, ScResId( FT_OUTAREA ) ), + aEdOutPos ( this, this, ScResId( ED_OUTAREA ) ), + aRbOutPos ( this, ScResId( RB_OUTAREA ), &aEdOutPos, this ), + aBtnIgnEmptyRows( this, ScResId( BTN_IGNEMPTYROWS ) ), + aBtnDetectCat ( this, ScResId( BTN_DETECTCAT ) ), + aBtnTotalCol ( this, ScResId( BTN_TOTALCOL ) ), + aBtnTotalRow ( this, ScResId( BTN_TOTALROW ) ), + aBtnFilter ( this, ScResId( BTN_FILTER ) ), + aBtnDrillDown ( this, ScResId( BTN_DRILLDOWN ) ), + + aBtnOk ( this, ScResId( BTN_OK ) ), + aBtnCancel ( this, ScResId( BTN_CANCEL ) ), + aBtnHelp ( this, ScResId( BTN_HELP ) ), + aBtnRemove ( this, ScResId( BTN_REMOVE ) ), + aBtnOptions ( this, ScResId( BTN_OPTIONS ) ), + aBtnMore ( this, ScResId( BTN_MORE ) ), + + aStrUndefined ( ScResId( SCSTR_UNDEFINED ) ), + aStrNewTable ( ScResId( SCSTR_NEWTABLE ) ), + + bIsDrag ( FALSE ), + + pEditActive ( NULL ), + + eLastActiveType ( TYPE_SELECT ), + nOffset ( 0 ), + // + xDlgDPObject ( new ScDPObject( rDPObject ) ), + pViewData ( ((ScTabViewShell*)SfxViewShell::Current())-> + GetViewData() ), + pDoc ( ((ScTabViewShell*)SfxViewShell::Current())-> + GetViewData()->GetDocument() ), + bRefInputMode ( FALSE ) +{ + xDlgDPObject->SetAlive( TRUE ); // needed to get structure information + xDlgDPObject->FillOldParam( thePivotData, FALSE ); + xDlgDPObject->FillLabelData( thePivotData ); + + Init(); + FreeResource(); +} + + +//---------------------------------------------------------------------------- + +ScDPLayoutDlg::~ScDPLayoutDlg() +{ + USHORT nEntries = aLbOutPos.GetEntryCount(); + USHORT i; + + for ( i=2; i<nEntries; i++ ) + delete (String*)aLbOutPos.GetEntryData( i ); +} + + +//---------------------------------------------------------------------------- + +ScDPFieldWindow& ScDPLayoutDlg::GetFieldWindow( ScDPFieldType eType ) +{ + switch( eType ) + { + case TYPE_PAGE: return aWndPage; + case TYPE_ROW: return aWndRow; + case TYPE_COL: return aWndCol; + case TYPE_DATA: return aWndData; + default: + { + // added to avoid warnings + } + } + return aWndSelect; +} + +void __EXPORT ScDPLayoutDlg::Init() +{ + DBG_ASSERT( pViewData && pDoc, + "Ctor-Initialisierung fehlgeschlagen!" ); + + aBtnRemove.SetClickHdl( LINK( this, ScDPLayoutDlg, ClickHdl ) ); + aBtnOptions.SetClickHdl( LINK( this, ScDPLayoutDlg, ClickHdl ) ); + + aFuncNameArr.reserve( FUNC_COUNT ); + for ( USHORT i = 0; i < FUNC_COUNT; ++i ) + aFuncNameArr.push_back( String( ScResId( i + 1 ) ) ); + + aBtnMore.AddWindow( &aFlAreas ); + aBtnMore.AddWindow( &aFtInArea ); + aBtnMore.AddWindow( &aEdInPos ); + aBtnMore.AddWindow( &aRbInPos ); + aBtnMore.AddWindow( &aFtOutArea ); + aBtnMore.AddWindow( &aLbOutPos ); + aBtnMore.AddWindow( &aEdOutPos ); + aBtnMore.AddWindow( &aRbOutPos ); + aBtnMore.AddWindow( &aBtnIgnEmptyRows ); + aBtnMore.AddWindow( &aBtnDetectCat ); + aBtnMore.AddWindow( &aBtnTotalCol ); + aBtnMore.AddWindow( &aBtnTotalRow ); + aBtnMore.AddWindow( &aBtnFilter ); + aBtnMore.AddWindow( &aBtnDrillDown ); + aBtnMore.SetClickHdl( LINK( this, ScDPLayoutDlg, MoreClickHdl ) ); + + { + Size aFieldSize( Window( this, ScResId( WND_FIELD ) ).GetSizePixel() ); + OHEIGHT = aFieldSize.Height(); + OWIDTH = aFieldSize.Width(); + } + SSPACE = Window( this, ScResId( WND_FIELD_SPACE ) ).GetSizePixel().Width(); + + CalcWndSizes(); + + aSelectArr.resize( MAX_LABELS ); + aPageArr.resize( MAX_PAGEFIELDS ); + aColArr.resize( MAX_FIELDS ); + aRowArr.resize( MAX_FIELDS ); + aDataArr.resize( MAX_FIELDS ); + + ScRange inRange; + String inString; + if (xDlgDPObject->GetSheetDesc()) + { + aEdInPos.Enable(); + aRbInPos.Enable(); + aOldRange = xDlgDPObject->GetSheetDesc()->aSourceRange; + aOldRange.Format( inString, SCR_ABS_3D, pDoc, pDoc->GetAddressConvention() ); + aEdInPos.SetText(inString); + } + else + { + /* Data is not reachable, so could be a remote database */ + aEdInPos.Disable(); + aRbInPos.Disable(); + } + + InitFields(); + + aLbOutPos .SetSelectHdl( LINK( this, ScDPLayoutDlg, SelAreaHdl ) ); + aEdOutPos .SetModifyHdl( LINK( this, ScDPLayoutDlg, EdModifyHdl ) ); + aEdInPos .SetModifyHdl( LINK( this, ScDPLayoutDlg, EdInModifyHdl ) ); + aBtnOk .SetClickHdl ( LINK( this, ScDPLayoutDlg, OkHdl ) ); + aBtnCancel.SetClickHdl ( LINK( this, ScDPLayoutDlg, CancelHdl ) ); + Link aLink = LINK( this, ScDPLayoutDlg, GetFocusHdl ); + if ( aEdInPos.IsEnabled() ) + // Once disabled it will never get enabled, so no need to handle focus. + aEdInPos.SetGetFocusHdl( aLink ); + aEdOutPos.SetGetFocusHdl( aLink ); + + if ( pViewData && pDoc ) + { + /* + * Aus den RangeNames des Dokumentes werden nun die + * in einem Zeiger-Array gemerkt, bei denen es sich + * um sinnvolle Bereiche handelt + */ + + aLbOutPos.Clear(); + aLbOutPos.InsertEntry( aStrUndefined, 0 ); + aLbOutPos.InsertEntry( aStrNewTable, 1 ); + + ScAreaNameIterator aIter( pDoc ); + String aName; + ScRange aRange; + String aRefStr; + while ( aIter.Next( aName, aRange ) ) + { + if ( !aIter.WasDBName() ) // hier keine DB-Bereiche ! + { + USHORT nInsert = aLbOutPos.InsertEntry( aName ); + + aRange.aStart.Format( aRefStr, SCA_ABS_3D, pDoc, pDoc->GetAddressConvention() ); + aLbOutPos.SetEntryData( nInsert, new String( aRefStr ) ); + } + } + } + + if ( thePivotData.nTab != MAXTAB+1 ) + { + String aStr; + ScAddress( thePivotData.nCol, + thePivotData.nRow, + thePivotData.nTab ).Format( aStr, STD_FORMAT, pDoc, pDoc->GetAddressConvention() ); + aEdOutPos.SetText( aStr ); + EdModifyHdl(0); + } + else + { + aLbOutPos.SelectEntryPos( aLbOutPos.GetEntryCount()-1 ); + SelAreaHdl(NULL); + } + + aBtnIgnEmptyRows.Check( thePivotData.bIgnoreEmptyRows ); + aBtnDetectCat .Check( thePivotData.bDetectCategories ); + aBtnTotalCol .Check( thePivotData.bMakeTotalCol ); + aBtnTotalRow .Check( thePivotData.bMakeTotalRow ); + + if( const ScDPSaveData* pSaveData = xDlgDPObject->GetSaveData() ) + { + aBtnFilter.Check( pSaveData->GetFilterButton() ); + aBtnDrillDown.Check( pSaveData->GetDrillDown() ); + } + else + { + aBtnFilter.Check(); + aBtnDrillDown.Check(); + } + + aWndPage.SetHelpId( HID_SC_DPLAY_PAGE ); + aWndCol.SetHelpId( HID_SC_DPLAY_COLUMN ); + aWndRow.SetHelpId( HID_SC_DPLAY_ROW ); + aWndData.SetHelpId( HID_SC_DPLAY_DATA ); + aWndSelect.SetHelpId( HID_SC_DPLAY_SELECT ); + + InitFocus(); + +// SetDispatcherLock( TRUE ); // Modal-Modus einschalten + + //@BugID 54702 Enablen/Disablen nur noch in Basisklasse + //SFX_APPWINDOW->Disable(FALSE); //! allgemeine Methode im ScAnyRefDlg +} + + +//---------------------------------------------------------------------------- + +BOOL __EXPORT ScDPLayoutDlg::Close() +{ + return DoClose( ScPivotLayoutWrapper::GetChildWindowId() ); +} + +//---------------------------------------------------------------------------- + +void ScDPLayoutDlg::StateChanged( StateChangedType nStateChange ) +{ + ScAnyRefDlg::StateChanged( nStateChange ); + + if ( nStateChange == STATE_CHANGE_INITSHOW ) + { + // #124828# Hiding the FixedTexts and clearing the tab stop style bits + // has to be done after assigning the mnemonics, but Paint is too late, + // because the test tool may send key events to the dialog when it isn't visible. + // Mnemonics are assigned in the Dialog::StateChanged for STATE_CHANGE_INITSHOW, + // so this can be done immediately afterwards. + + aWndPage.UseMnemonic(); + aWndCol.UseMnemonic(); + aWndRow.UseMnemonic(); + aWndData.UseMnemonic(); + } +} + +//---------------------------------------------------------------------------- + +void ScDPLayoutDlg::InitWndSelect( const vector<ScDPLabelDataRef>& rLabels ) +{ + size_t nLabelCount = rLabels.size(); + if (nLabelCount > MAX_LABELS) + nLabelCount = MAX_LABELS; + size_t nLast = (nLabelCount > PAGE_SIZE) ? (PAGE_SIZE - 1) : (nLabelCount - 1); + + aLabelDataArr.clear(); + aLabelDataArr.reserve( nLabelCount ); + for ( size_t i=0; i < nLabelCount; i++ ) + { + aLabelDataArr.push_back(*rLabels[i]); + + if ( i <= nLast ) + { + aWndSelect.AddField(aLabelDataArr[i].getDisplayName(), i); + aSelectArr[i].reset( new ScDPFuncData( aLabelDataArr[i].mnCol, aLabelDataArr[i].mnFuncMask ) ); + } + } +} + + +//---------------------------------------------------------------------------- + +void ScDPLayoutDlg::InitWnd( PivotField* pArr, long nCount, ScDPFieldType eType ) +{ + if ( pArr && (eType != TYPE_SELECT) ) + { + ScDPFuncDataVec* pInitArr = NULL; + ScDPFieldWindow* pInitWnd = NULL; + BOOL bDataArr = FALSE; + + switch ( eType ) + { + case TYPE_PAGE: + pInitArr = &aPageArr; + pInitWnd = &aWndPage; + break; + + case TYPE_COL: + pInitArr = &aColArr; + pInitWnd = &aWndCol; + break; + + case TYPE_ROW: + pInitArr = &aRowArr; + pInitWnd = &aWndRow; + break; + + case TYPE_DATA: + pInitArr = &aDataArr; + pInitWnd = &aWndData; + bDataArr = TRUE; + break; + default: + break; + } + + if ( pInitArr && pInitWnd ) + { + long j=0; + for ( long i=0; (i<nCount); i++ ) + { + SCCOL nCol = pArr[i].nCol; + USHORT nMask = pArr[i].nFuncMask; + + if ( nCol != PIVOT_DATA_FIELD ) + { + (*pInitArr)[j].reset( new ScDPFuncData( nCol, nMask, pArr[i].maFieldRef ) ); + + if ( !bDataArr ) + { + pInitWnd->AddField( GetLabelString( nCol ), j ); + } + else + { + ScDPLabelData* pData = GetLabelData( nCol ); + DBG_ASSERT( pData, "ScDPLabelData not found" ); + if (pData) + { + String aStr( GetFuncString( (*pInitArr)[j]->mnFuncMask, + pData->mbIsValue ) ); + + aStr += GetLabelString( nCol ); + pInitWnd->AddField( aStr, j ); + + pData->mnFuncMask = nMask; + } + } + ++j; + } + } +// Do not redraw here -> first the FixedText has to get its mnemonic char +// pInitWnd->Redraw(); + } + } +} + + +//---------------------------------------------------------------------------- + +void ScDPLayoutDlg::InitFocus() +{ + if( aWndSelect.IsEmpty() ) + { + aBtnOk.GrabFocus(); + NotifyFieldFocus( TYPE_SELECT, FALSE ); + } + else + aWndSelect.GrabFocus(); +} + +void ScDPLayoutDlg::InitFields() +{ + InitWndSelect(thePivotData.maLabelArray); + InitWnd( thePivotData.aPageArr, static_cast<long>(thePivotData.nPageCount), TYPE_PAGE ); + InitWnd( thePivotData.aColArr, static_cast<long>(thePivotData.nColCount), TYPE_COL ); + InitWnd( thePivotData.aRowArr, static_cast<long>(thePivotData.nRowCount), TYPE_ROW ); + InitWnd( thePivotData.aDataArr, static_cast<long>(thePivotData.nDataCount), TYPE_DATA ); + + size_t nLabels = thePivotData.maLabelArray.size(); + aSlider.SetPageSize( PAGE_SIZE ); + aSlider.SetVisibleSize( PAGE_SIZE ); + aSlider.SetLineSize( LINE_SIZE ); + aSlider.SetRange( Range( 0, static_cast<long>(((nLabels+LINE_SIZE-1)/LINE_SIZE)*LINE_SIZE) ) ); + + if ( nLabels > PAGE_SIZE ) + { + aSlider.SetEndScrollHdl( LINK( this, ScDPLayoutDlg, ScrollHdl ) ); + aSlider.Show(); + } + else + aSlider.Hide(); +} + +//---------------------------------------------------------------------------- + +void ScDPLayoutDlg::AddField( size_t nFromIndex, ScDPFieldType eToType, const Point& rAtPos ) +{ + ScDPFuncData fData( *(aSelectArr[nFromIndex]) ); + size_t nAt = 0; + ScDPFieldWindow* toWnd = NULL; + ScDPFieldWindow* rmWnd1 = NULL; + ScDPFieldWindow* rmWnd2 = NULL; + ScDPFuncDataVec* toArr = NULL; + ScDPFuncDataVec* rmArr1 = NULL; + ScDPFuncDataVec* rmArr2 = NULL; + BOOL bDataArr = FALSE; + + switch ( eToType ) + { + case TYPE_PAGE: + toWnd = &aWndPage; + rmWnd1 = &aWndRow; + rmWnd2 = &aWndCol; + toArr = &aPageArr; + rmArr1 = &aRowArr; + rmArr2 = &aColArr; + break; + + case TYPE_COL: + toWnd = &aWndCol; + rmWnd1 = &aWndPage; + rmWnd2 = &aWndRow; + toArr = &aColArr; + rmArr1 = &aPageArr; + rmArr2 = &aRowArr; + break; + + case TYPE_ROW: + toWnd = &aWndRow; + rmWnd1 = &aWndPage; + rmWnd2 = &aWndCol; + toArr = &aRowArr; + rmArr1 = &aPageArr; + rmArr2 = &aColArr; + break; + + case TYPE_DATA: + toWnd = &aWndData; + toArr = &aDataArr; + bDataArr = TRUE; + break; + + default: + { + // added to avoid warnings + } + } + + bool bAllowed = IsOrientationAllowed( fData.mnCol, eToType ); + if ( bAllowed + && (toArr->back().get() == NULL) + && (!Contains( toArr, fData.mnCol, nAt )) ) + { + // ggF. in anderem Fenster entfernen + if ( rmArr1 ) + { + if ( Contains( rmArr1, fData.mnCol, nAt ) ) + { + rmWnd1->DelField( nAt ); + Remove( rmArr1, nAt ); + } + } + if ( rmArr2 ) + { + if ( Contains( rmArr2, fData.mnCol, nAt ) ) + { + rmWnd2->DelField( nAt ); + Remove( rmArr2, nAt ); + } + } + + ScDPLabelData& rData = aLabelDataArr[nFromIndex+nOffset]; + size_t nAddedAt = 0; + + if ( !bDataArr ) + { + if ( toWnd->AddField( rData.getDisplayName(), + DlgPos2WndPos( rAtPos, *toWnd ), + nAddedAt ) ) + { + Insert( toArr, fData, nAddedAt ); + toWnd->GrabFocus(); + } + } + else + { + USHORT nMask = fData.mnFuncMask; + OUString aStr = GetFuncString( nMask, rData.mbIsValue ); + + aStr += rData.getDisplayName(); + + if ( toWnd->AddField( aStr, + DlgPos2WndPos( rAtPos, *toWnd ), + nAddedAt ) ) + { + fData.mnFuncMask = nMask; + Insert( toArr, fData, nAddedAt ); + toWnd->GrabFocus(); + } + } + + } +} + + +//---------------------------------------------------------------------------- + +void ScDPLayoutDlg::MoveField( ScDPFieldType eFromType, size_t nFromIndex, ScDPFieldType eToType, const Point& rAtPos ) +{ + if ( eFromType == TYPE_SELECT ) + AddField( nFromIndex, eToType, rAtPos ); + else if ( eFromType != eToType ) + { + ScDPFieldWindow* fromWnd = NULL; + ScDPFieldWindow* toWnd = NULL; + ScDPFieldWindow* rmWnd1 = NULL; + ScDPFieldWindow* rmWnd2 = NULL; + ScDPFuncDataVec* fromArr = NULL; + ScDPFuncDataVec* toArr = NULL; + ScDPFuncDataVec* rmArr1 = NULL; + ScDPFuncDataVec* rmArr2 = NULL; + size_t nAt = 0; + BOOL bDataArr = FALSE; + + switch ( eFromType ) + { + case TYPE_PAGE: + fromWnd = &aWndPage; + fromArr = &aPageArr; + break; + + case TYPE_COL: + fromWnd = &aWndCol; + fromArr = &aColArr; + break; + + case TYPE_ROW: + fromWnd = &aWndRow; + fromArr = &aRowArr; + break; + + case TYPE_DATA: + fromWnd = &aWndData; + fromArr = &aDataArr; + break; + + default: + { + // added to avoid warnings + } + } + + switch ( eToType ) + { + case TYPE_PAGE: + toWnd = &aWndPage; + toArr = &aPageArr; + rmWnd1 = &aWndCol; + rmWnd2 = &aWndRow; + rmArr1 = &aColArr; + rmArr2 = &aRowArr; + break; + + case TYPE_COL: + toWnd = &aWndCol; + toArr = &aColArr; + rmWnd1 = &aWndPage; + rmWnd2 = &aWndRow; + rmArr1 = &aPageArr; + rmArr2 = &aRowArr; + break; + + case TYPE_ROW: + toWnd = &aWndRow; + toArr = &aRowArr; + rmWnd1 = &aWndPage; + rmWnd2 = &aWndCol; + rmArr1 = &aPageArr; + rmArr2 = &aColArr; + break; + + case TYPE_DATA: + toWnd = &aWndData; + toArr = &aDataArr; + bDataArr = TRUE; + break; + + default: + { + // added to avoid warnings + } + } + + if ( fromArr && toArr && fromWnd && toWnd ) + { + ScDPFuncData fData( *((*fromArr)[nFromIndex]) ); + + bool bAllowed = IsOrientationAllowed( fData.mnCol, eToType ); + if ( bAllowed && Contains( fromArr, fData.mnCol, nAt ) ) + { + fromWnd->DelField( nAt ); + Remove( fromArr, nAt ); + + if ( (toArr->back().get() == NULL) + && (!Contains( toArr, fData.mnCol, nAt )) ) + { + size_t nAddedAt = 0; + if ( !bDataArr ) + { + // ggF. in anderem Fenster entfernen + if ( rmArr1 ) + { + if ( Contains( rmArr1, fData.mnCol, nAt ) ) + { + rmWnd1->DelField( nAt ); + Remove( rmArr1, nAt ); + } + } + if ( rmArr2 ) + { + if ( Contains( rmArr2, fData.mnCol, nAt ) ) + { + rmWnd2->DelField( nAt ); + Remove( rmArr2, nAt ); + } + } + + if ( toWnd->AddField( GetLabelString( fData.mnCol ), + DlgPos2WndPos( rAtPos, *toWnd ), + nAddedAt ) ) + { + Insert( toArr, fData, nAddedAt ); + toWnd->GrabFocus(); + } + } + else + { + String aStr; + USHORT nMask = fData.mnFuncMask; + aStr = GetFuncString( nMask ); + aStr += GetLabelString( fData.mnCol ); + + if ( toWnd->AddField( aStr, + DlgPos2WndPos( rAtPos, *toWnd ), + nAddedAt ) ) + { + fData.mnFuncMask = nMask; + Insert( toArr, fData, nAddedAt ); + toWnd->GrabFocus(); + } + } + } + } + } + } + else // -> eFromType == eToType + { + ScDPFieldWindow* theWnd = NULL; + ScDPFuncDataVec* theArr = NULL; + size_t nAt = 0; + size_t nToIndex = 0; + Point aToPos; + BOOL bDataArr = FALSE; + + switch ( eFromType ) + { + case TYPE_PAGE: + theWnd = &aWndPage; + theArr = &aPageArr; + break; + + case TYPE_COL: + theWnd = &aWndCol; + theArr = &aColArr; + break; + + case TYPE_ROW: + theWnd = &aWndRow; + theArr = &aRowArr; + break; + + case TYPE_DATA: + theWnd = &aWndData; + theArr = &aDataArr; + bDataArr = TRUE; + break; + + default: + { + // added to avoid warnings + } + } + + ScDPFuncData fData( *((*theArr)[nFromIndex]) ); + + if ( Contains( theArr, fData.mnCol, nAt ) ) + { + aToPos = DlgPos2WndPos( rAtPos, *theWnd ); + theWnd->GetExistingIndex( aToPos, nToIndex ); + + if ( nToIndex != nAt ) + { + size_t nAddedAt = 0; + + theWnd->DelField( nAt ); + Remove( theArr, nAt ); + + if ( !bDataArr ) + { + if ( theWnd->AddField( GetLabelString( fData.mnCol ), + aToPos, + nAddedAt ) ) + { + Insert( theArr, fData, nAddedAt ); + } + } + else + { + String aStr; + USHORT nMask = fData.mnFuncMask; + aStr = GetFuncString( nMask ); + aStr += GetLabelString( fData.mnCol ); + + if ( theWnd->AddField( aStr, + DlgPos2WndPos( rAtPos, *theWnd ), + nAddedAt ) ) + { + fData.mnFuncMask = nMask; + Insert( theArr, fData, nAddedAt ); + } + } + } + } + } +} + +//---------------------------------------------------------------------------- + +void ScDPLayoutDlg::RemoveField( ScDPFieldType eFromType, size_t nIndex ) +{ + ScDPFuncDataVec* pArr = NULL; + switch( eFromType ) + { + case TYPE_PAGE: pArr = &aPageArr; break; + case TYPE_COL: pArr = &aColArr; break; + case TYPE_ROW: pArr = &aRowArr; break; + case TYPE_DATA: pArr = &aDataArr; break; + default: + { + // added to avoid warnings + } + } + + if( pArr ) + { + ScDPFieldWindow& rWnd = GetFieldWindow( eFromType ); + rWnd.DelField( nIndex ); + Remove( pArr, nIndex ); + if( rWnd.IsEmpty() ) InitFocus(); + } +} + +//---------------------------------------------------------------------------- + +void ScDPLayoutDlg::NotifyMouseButtonUp( const Point& rAt ) +{ + if ( bIsDrag ) + { + bIsDrag = FALSE; + + ScDPFieldType eDnDToType = TYPE_SELECT; + Point aPos = ScreenToOutputPixel( rAt ); + BOOL bDel = FALSE; + + if ( aRectPage.IsInside( aPos ) ) + { + eDnDToType = TYPE_PAGE; + bDel = FALSE; + } + else if ( aRectCol.IsInside( aPos ) ) + { + eDnDToType = TYPE_COL; + bDel = FALSE; + } + else if ( aRectRow.IsInside( aPos ) ) + { + eDnDToType = TYPE_ROW; + bDel = FALSE; + } + else if ( aRectData.IsInside( aPos ) ) + { + eDnDToType = TYPE_DATA; + bDel = FALSE; + } + else if ( aRectSelect.IsInside( aPos ) ) + { + eDnDToType = TYPE_SELECT; + bDel = TRUE; + } + else + bDel = TRUE; + + if ( bDel ) + RemoveField( eDnDFromType, nDnDFromIndex ); + else + MoveField( eDnDFromType, nDnDFromIndex, eDnDToType, aPos ); + } +} + + +//---------------------------------------------------------------------------- + +PointerStyle ScDPLayoutDlg::NotifyMouseMove( const Point& rAt ) +{ + PointerStyle ePtr = POINTER_ARROW; + + if ( bIsDrag ) + { + Point aPos = ScreenToOutputPixel( rAt ); + ScDPFieldType eCheckTarget = TYPE_SELECT; + + if ( aRectPage.IsInside( aPos ) ) + eCheckTarget = TYPE_PAGE; + else if ( aRectCol.IsInside( aPos ) ) + eCheckTarget = TYPE_COL; + else if ( aRectRow.IsInside( aPos ) ) + eCheckTarget = TYPE_ROW; + else if ( aRectData.IsInside( aPos ) ) + eCheckTarget = TYPE_DATA; + else if ( eDnDFromType != TYPE_SELECT ) + ePtr = POINTER_PIVOT_DELETE; + else if ( aRectSelect.IsInside( aPos ) ) + ePtr = lclGetPointerForField( TYPE_SELECT ); + else + ePtr = POINTER_NOTALLOWED; + + if ( eCheckTarget != TYPE_SELECT ) + { + // check if the target orientation is allowed for this field + ScDPFuncDataVec* fromArr = NULL; + switch ( eDnDFromType ) + { + case TYPE_PAGE: fromArr = &aPageArr; break; + case TYPE_COL: fromArr = &aColArr; break; + case TYPE_ROW: fromArr = &aRowArr; break; + case TYPE_DATA: fromArr = &aDataArr; break; + case TYPE_SELECT: fromArr = &aSelectArr; break; + } + ScDPFuncData fData( *((*fromArr)[nDnDFromIndex]) ); + if (IsOrientationAllowed( fData.mnCol, eCheckTarget )) + ePtr = lclGetPointerForField( eCheckTarget ); + else + ePtr = POINTER_NOTALLOWED; + } + } + + return ePtr; +} + + +//---------------------------------------------------------------------------- + +PointerStyle ScDPLayoutDlg::NotifyMouseButtonDown( ScDPFieldType eType, size_t nFieldIndex ) +{ + bIsDrag = TRUE; + eDnDFromType = eType; + nDnDFromIndex = nFieldIndex; + return lclGetPointerForField( eType ); +} + + +//---------------------------------------------------------------------------- + +void ScDPLayoutDlg::NotifyDoubleClick( ScDPFieldType eType, size_t nFieldIndex ) +{ + ScDPFuncDataVec* pArr = NULL; + switch ( eType ) + { + case TYPE_PAGE: pArr = &aPageArr; break; + case TYPE_COL: pArr = &aColArr; break; + case TYPE_ROW: pArr = &aRowArr; break; + case TYPE_DATA: pArr = &aDataArr; break; + default: + { + // added to avoid warnings + } + } + + if ( pArr ) + { + if ( nFieldIndex >= pArr->size() ) + { + DBG_ERROR("invalid selection"); + return; + } + + size_t nArrPos = 0; + if( ScDPLabelData* pData = GetLabelData( (*pArr)[nFieldIndex]->mnCol, &nArrPos ) ) + { + ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create(); + DBG_ASSERT(pFact, "ScAbstractFactory create fail!");//CHINA001 + + switch ( eType ) + { + case TYPE_PAGE: + case TYPE_COL: + case TYPE_ROW: + { + // list of names of all data fields + std::vector< String > aDataFieldNames; + for( ScDPFuncDataVec::const_iterator aIt = aDataArr.begin(), aEnd = aDataArr.end(); + (aIt != aEnd) && aIt->get(); ++aIt ) + { + String aName( GetLabelString( (*aIt)->mnCol ) ); + if( aName.Len() ) + aDataFieldNames.push_back( aName ); + } + + bool bLayout = (eType == TYPE_ROW) && + ((aDataFieldNames.size() > 1) || ((nFieldIndex + 1 < pArr->size()) && (*pArr)[nFieldIndex+1].get())); + + AbstractScDPSubtotalDlg* pDlg = pFact->CreateScDPSubtotalDlg( + this, RID_SCDLG_PIVOTSUBT, + *xDlgDPObject, *pData, *(*pArr)[nFieldIndex], aDataFieldNames, bLayout ); + + if ( pDlg->Execute() == RET_OK ) + { + pDlg->FillLabelData( *pData ); + (*pArr)[nFieldIndex]->mnFuncMask = pData->mnFuncMask; + } + delete pDlg; + } + break; + + case TYPE_DATA: + { + AbstractScDPFunctionDlg* pDlg = pFact->CreateScDPFunctionDlg( + this, RID_SCDLG_DPDATAFIELD, + aLabelDataArr, *pData, *(*pArr)[nFieldIndex] ); + + if ( pDlg->Execute() == RET_OK ) + { + (*pArr)[nFieldIndex]->mnFuncMask = pData->mnFuncMask = pDlg->GetFuncMask(); + (*pArr)[nFieldIndex]->maFieldRef = pDlg->GetFieldRef(); + + String aStr( GetFuncString ( aDataArr[nFieldIndex]->mnFuncMask ) ); + aStr += GetLabelString( aDataArr[nFieldIndex]->mnCol ); + aWndData.SetFieldText( aStr, nFieldIndex ); + } + delete pDlg; + } + break; + + default: + { + // added to avoid warnings + } + } + } + } +} + +//---------------------------------------------------------------------------- + +void ScDPLayoutDlg::NotifyFieldFocus( ScDPFieldType eType, BOOL bGotFocus ) +{ + /* Enable Remove/Options buttons on GetFocus in field window. + #107616# Enable them also, if dialog is deactivated (click into document). + The !IsActive() condition handles the case that a LoseFocus event of a + field window would follow the Deactivate event of this dialog. */ + BOOL bEnable = (bGotFocus || !IsActive()) && (eType != TYPE_SELECT); + + // #128113# The TestTool may set the focus into an empty field. + // Then the Remove/Options buttons must be disabled. + if ( bEnable && bGotFocus && GetFieldWindow( eType ).IsEmpty() ) + bEnable = FALSE; + + aBtnRemove.Enable( bEnable ); + aBtnOptions.Enable( bEnable ); + if( bGotFocus ) + eLastActiveType = eType; +} + +//---------------------------------------------------------------------------- + +void ScDPLayoutDlg::NotifyMoveField( ScDPFieldType eToType ) +{ + ScDPFieldWindow& rWnd = GetFieldWindow( eLastActiveType ); + if( (eToType != TYPE_SELECT) && !rWnd.IsEmpty() ) + { + MoveField( eLastActiveType, rWnd.GetSelectedField(), eToType, GetFieldWindow( eToType ).GetLastPosition() ); + if( rWnd.IsEmpty() ) + NotifyFieldFocus( eToType, TRUE ); + else + rWnd.GrabFocus(); + if( eLastActiveType == TYPE_SELECT ) + aWndSelect.SelectNext(); + } + else + InitFocus(); +} + +//---------------------------------------------------------------------------- + +void ScDPLayoutDlg::NotifyRemoveField( ScDPFieldType eType, size_t nFieldIndex ) +{ + if( eType != TYPE_SELECT ) + RemoveField( eType, nFieldIndex ); +} + +//---------------------------------------------------------------------------- + +BOOL ScDPLayoutDlg::NotifyMoveSlider( USHORT nKeyCode ) +{ + long nOldPos = aSlider.GetThumbPos(); + switch( nKeyCode ) + { + case KEY_HOME: aSlider.DoScroll( 0 ); break; + case KEY_END: aSlider.DoScroll( aSlider.GetRangeMax() ); break; + case KEY_UP: + case KEY_LEFT: aSlider.DoScrollAction( SCROLL_LINEUP ); break; + case KEY_DOWN: + case KEY_RIGHT: aSlider.DoScrollAction( SCROLL_LINEDOWN ); break; + } + return nOldPos != aSlider.GetThumbPos(); +} + +//---------------------------------------------------------------------------- + +void ScDPLayoutDlg::Deactivate() +{ + /* #107616# If the dialog has been deactivated (click into document), the LoseFocus + event from field window disables Remove/Options buttons. Re-enable them here by + simulating a GetFocus event. Event order of LoseFocus and Deactivate is not important. + The last event will enable the buttons in both cases (see NotifyFieldFocus). */ + NotifyFieldFocus( eLastActiveType, TRUE ); +} + +//---------------------------------------------------------------------------- + +BOOL ScDPLayoutDlg::Contains( ScDPFuncDataVec* pArr, SCsCOL nCol, size_t& nAt ) +{ + if ( !pArr ) + return FALSE; + + BOOL bFound = FALSE; + size_t i = 0; + + while ( (i<pArr->size()) && ((*pArr)[i].get() != NULL) && !bFound ) + { + bFound = ((*pArr)[i]->mnCol == nCol); + if ( bFound ) + nAt = i; + i++; + } + + return bFound; +} + + +//---------------------------------------------------------------------------- + +void ScDPLayoutDlg::Remove( ScDPFuncDataVec* pArr, size_t nAt ) +{ + if ( !pArr || (nAt>=pArr->size()) ) + return; + + pArr->erase( pArr->begin() + nAt ); + pArr->push_back( ScDPFuncDataRef() ); +} + + +//---------------------------------------------------------------------------- + +void ScDPLayoutDlg::Insert( ScDPFuncDataVec* pArr, const ScDPFuncData& rFData, size_t nAt ) +{ + if ( !pArr || (nAt>=pArr->size()) ) + return; + + if ( (*pArr)[nAt].get() == NULL ) + { + (*pArr)[nAt].reset( new ScDPFuncData( rFData ) ); + } + else + { + if ( pArr->back().get() == NULL ) // mind. ein Slot frei? + { + pArr->insert( pArr->begin() + nAt, ScDPFuncDataRef( new ScDPFuncData( rFData ) ) ); + pArr->erase( pArr->end() - 1 ); + } + } +} + + +//---------------------------------------------------------------------------- + +ScDPLabelData* ScDPLayoutDlg::GetLabelData( SCsCOL nCol, size_t* pnPos ) +{ + ScDPLabelData* pData = 0; + for( ScDPLabelDataVec::iterator aIt = aLabelDataArr.begin(), aEnd = aLabelDataArr.end(); !pData && (aIt != aEnd); ++aIt ) + { + if( aIt->mnCol == nCol ) + { + pData = &*aIt; + if( pnPos ) *pnPos = aIt - aLabelDataArr.begin(); + } + } + return pData; +} + + +//---------------------------------------------------------------------------- + +String ScDPLayoutDlg::GetLabelString( SCsCOL nCol ) +{ + ScDPLabelData* pData = GetLabelData( nCol ); + DBG_ASSERT( pData, "LabelData not found" ); + if (pData) + return pData->getDisplayName(); + return String(); +} + +//---------------------------------------------------------------------------- + +bool ScDPLayoutDlg::IsOrientationAllowed( SCsCOL nCol, ScDPFieldType eType ) +{ + bool bAllowed = true; + ScDPLabelData* pData = GetLabelData( nCol ); + DBG_ASSERT( pData, "LabelData not found" ); + if (pData) + { + sheet::DataPilotFieldOrientation eOrient = sheet::DataPilotFieldOrientation_HIDDEN; + switch (eType) + { + case TYPE_PAGE: eOrient = sheet::DataPilotFieldOrientation_PAGE; break; + case TYPE_COL: eOrient = sheet::DataPilotFieldOrientation_COLUMN; break; + case TYPE_ROW: eOrient = sheet::DataPilotFieldOrientation_ROW; break; + case TYPE_DATA: eOrient = sheet::DataPilotFieldOrientation_DATA; break; + case TYPE_SELECT: eOrient = sheet::DataPilotFieldOrientation_HIDDEN; break; + } + bAllowed = ScDPObject::IsOrientationAllowed( (USHORT)eOrient, pData->mnFlags ); + } + return bAllowed; +} + +//---------------------------------------------------------------------------- + +String ScDPLayoutDlg::GetFuncString( USHORT& rFuncMask, BOOL bIsValue ) +{ + String aStr; + + if ( rFuncMask == PIVOT_FUNC_NONE + || rFuncMask == PIVOT_FUNC_AUTO ) + { + if ( bIsValue ) + { + aStr = FSTR(PIVOTSTR_SUM); + rFuncMask = PIVOT_FUNC_SUM; + } + else + { + aStr = FSTR(PIVOTSTR_COUNT); + rFuncMask = PIVOT_FUNC_COUNT; + } + } + else if ( rFuncMask == PIVOT_FUNC_SUM ) aStr = FSTR(PIVOTSTR_SUM); + else if ( rFuncMask == PIVOT_FUNC_COUNT ) aStr = FSTR(PIVOTSTR_COUNT); + else if ( rFuncMask == PIVOT_FUNC_AVERAGE ) aStr = FSTR(PIVOTSTR_AVG); + else if ( rFuncMask == PIVOT_FUNC_MAX ) aStr = FSTR(PIVOTSTR_MAX); + else if ( rFuncMask == PIVOT_FUNC_MIN ) aStr = FSTR(PIVOTSTR_MIN); + else if ( rFuncMask == PIVOT_FUNC_PRODUCT ) aStr = FSTR(PIVOTSTR_PROD); + else if ( rFuncMask == PIVOT_FUNC_COUNT_NUM ) aStr = FSTR(PIVOTSTR_COUNT2); + else if ( rFuncMask == PIVOT_FUNC_STD_DEV ) aStr = FSTR(PIVOTSTR_DEV); + else if ( rFuncMask == PIVOT_FUNC_STD_DEVP ) aStr = FSTR(PIVOTSTR_DEV2); + else if ( rFuncMask == PIVOT_FUNC_STD_VAR ) aStr = FSTR(PIVOTSTR_VAR); + else if ( rFuncMask == PIVOT_FUNC_STD_VARP ) aStr = FSTR(PIVOTSTR_VAR2); + else + { + aStr = ScGlobal::GetRscString( STR_TABLE_ERGEBNIS ); + aStr.AppendAscii(RTL_CONSTASCII_STRINGPARAM( " - " )); + } + + return aStr; +} + + +//---------------------------------------------------------------------------- + +Point ScDPLayoutDlg::DlgPos2WndPos( const Point& rPt, Window& rWnd ) +{ + Point aWndPt( rPt ); + aWndPt.X() = rPt.X()-rWnd.GetPosPixel().X(); + aWndPt.Y() = rPt.Y()-rWnd.GetPosPixel().Y(); + + return aWndPt; +} + + +//---------------------------------------------------------------------------- + +void ScDPLayoutDlg::CalcWndSizes() +{ + // row/column/data area sizes + aWndPage.SetSizePixel( Size( MAX_PAGEFIELDS * OWIDTH / 2, 2 * OHEIGHT ) ); + aWndRow.SetSizePixel( Size( OWIDTH, MAX_FIELDS * OHEIGHT ) ); + aWndCol.SetSizePixel( Size( MAX_FIELDS * OWIDTH / 2, 2 * OHEIGHT ) ); + aWndData.SetSizePixel( Size( MAX_FIELDS * OWIDTH / 2, MAX_FIELDS * OHEIGHT ) ); + + // #i29203# align right border of page window with data window + long nDataPosX = aWndData.GetPosPixel().X() + aWndData.GetSizePixel().Width(); + aWndPage.SetPosPixel( Point( nDataPosX - aWndPage.GetSizePixel().Width(), aWndPage.GetPosPixel().Y() ) ); + + // selection area + aWndSelect.SetSizePixel( Size( + 2 * OWIDTH + SSPACE, LINE_SIZE * OHEIGHT + (LINE_SIZE - 1) * SSPACE ) ); + + // scroll bar + Point aSliderPos( aWndSelect.GetPosPixel() ); + Size aSliderSize( aWndSelect.GetSizePixel() ); + aSliderPos.Y() += aSliderSize.Height() + SSPACE; + aSliderSize.Height() = GetSettings().GetStyleSettings().GetScrollBarSize(); + aSlider.SetPosSizePixel( aSliderPos, aSliderSize ); + + aRectPage = Rectangle( aWndPage.GetPosPixel(), aWndPage.GetSizePixel() ); + aRectRow = Rectangle( aWndRow.GetPosPixel(), aWndRow.GetSizePixel() ); + aRectCol = Rectangle( aWndCol.GetPosPixel(), aWndCol.GetSizePixel() ); + aRectData = Rectangle( aWndData.GetPosPixel(), aWndData.GetSizePixel() ); + aRectSelect = Rectangle( aWndSelect.GetPosPixel(), aWndSelect.GetSizePixel() ); +} + + +//---------------------------------------------------------------------------- + +BOOL ScDPLayoutDlg::GetPivotArrays( PivotField* pPageArr, + PivotField* pColArr, + PivotField* pRowArr, + PivotField* pDataArr, + USHORT& rPageCount, + USHORT& rColCount, + USHORT& rRowCount, + USHORT& rDataCount ) +{ + BOOL bFit = TRUE; + USHORT i=0; + + for ( i=0; (i<aDataArr.size()) && (aDataArr[i].get() != NULL ); i++ ) + lcl_FillToPivotField( pDataArr[i], *aDataArr[i] ); + rDataCount = i; + + for ( i=0; (i<aPageArr.size()) && (aPageArr[i].get() != NULL ); i++ ) + lcl_FillToPivotField( pPageArr[i], *aPageArr[i] ); + rPageCount = i; + + for ( i=0; (i<aColArr.size()) && (aColArr[i].get() != NULL ); i++ ) + lcl_FillToPivotField( pColArr[i], *aColArr[i] ); + rColCount = i; + + for ( i=0; (i<aRowArr.size()) && (aRowArr[i].get() != NULL ); i++ ) + lcl_FillToPivotField( pRowArr[i], *aRowArr[i] ); + rRowCount = i; + + if ( rRowCount < aRowArr.size() ) + pRowArr[rRowCount++].nCol = PIVOT_DATA_FIELD; + else if ( rColCount < aColArr.size() ) + pColArr[rColCount++].nCol = PIVOT_DATA_FIELD; + else + bFit = FALSE; // kein Platz fuer Datenfeld + + return bFit; +} + +void ScDPLayoutDlg::UpdateSrcRange() +{ + String theCurPosStr = aEdInPos.GetText(); + USHORT nResult = ScRange().Parse(theCurPosStr, pDoc, pDoc->GetAddressConvention()); + + if ( SCA_VALID != (nResult & SCA_VALID) ) + // invalid source range. + return; + + ScRefAddress start, end; + ConvertDoubleRef(pDoc, theCurPosStr, 1, start, end, pDoc->GetAddressConvention()); + ScRange aNewRange(start.GetAddress(), end.GetAddress()); + ScSheetSourceDesc inSheet = *xDlgDPObject->GetSheetDesc(); + + if (inSheet.aSourceRange == aNewRange) + // new range is identical to the current range. Nothing to do. + return; + + ScTabViewShell * pTabViewShell = pViewData->GetViewShell(); + inSheet.aSourceRange = aNewRange; + xDlgDPObject->SetSheetDesc(inSheet); + xDlgDPObject->FillOldParam( thePivotData, FALSE ); + xDlgDPObject->FillLabelData(thePivotData); + + pTabViewShell->SetDialogDPObject(xDlgDPObject.get()); + aLabelDataArr.clear(); + aWndSelect.ClearFields(); + aWndData.ClearFields(); + aWndRow.ClearFields(); + aWndCol.ClearFields(); + aWndPage.ClearFields(); + + for (size_t i = 0; i < MAX_LABELS; ++i) + aSelectArr[i].reset(); + + for (size_t i = 0; i < MAX_FIELDS; ++i) + { + aRowArr[i].reset(); + aColArr[i].reset(); + aDataArr[i].reset(); + } + + for (size_t i = 0; i < MAX_PAGEFIELDS; ++i) + aPageArr[i].reset(); + + InitFields(); +} + +//---------------------------------------------------------------------------- + +void ScDPLayoutDlg::SetReference( const ScRange& rRef, ScDocument* pDocP ) +{ + if ( !bRefInputMode || !pEditActive ) + return; + + if ( rRef.aStart != rRef.aEnd ) + RefInputStart( pEditActive ); + + if ( pEditActive == &aEdInPos ) + { + String aRefStr; + rRef.Format( aRefStr, SCR_ABS_3D, pDocP, pDocP->GetAddressConvention() ); + pEditActive->SetRefString( aRefStr ); + } + else if ( pEditActive == &aEdOutPos ) + { + String aRefStr; + rRef.aStart.Format( aRefStr, STD_FORMAT, pDocP, pDocP->GetAddressConvention() ); + pEditActive->SetRefString( aRefStr ); + } +} + + +//---------------------------------------------------------------------------- + +void ScDPLayoutDlg::SetActive() +{ + if ( bRefInputMode ) + { + if ( pEditActive ) + pEditActive->GrabFocus(); + + if ( pEditActive == &aEdInPos ) + EdInModifyHdl( NULL ); + else if ( pEditActive == &aEdOutPos ) + EdModifyHdl( NULL ); + } + else + { + GrabFocus(); + } + + RefInputDone(); +} + +//---------------------------------------------------------------------------- +// Handler: +//---------------------------------------------------------------------------- + +IMPL_LINK( ScDPLayoutDlg, ClickHdl, PushButton *, pBtn ) +{ + if( pBtn == &aBtnRemove ) + { + ScDPFieldWindow& rWnd = GetFieldWindow( eLastActiveType ); + RemoveField( eLastActiveType, rWnd.GetSelectedField() ); + if( !rWnd.IsEmpty() ) rWnd.GrabFocus(); + } + else if( pBtn == &aBtnOptions ) + { + ScDPFieldWindow& rWnd = GetFieldWindow( eLastActiveType ); + NotifyDoubleClick( eLastActiveType, rWnd.GetSelectedField() ); + rWnd.GrabFocus(); + } + return 0; +} + +//---------------------------------------------------------------------------- + +IMPL_LINK( ScDPLayoutDlg, OkHdl, OKButton *, EMPTYARG ) +{ + String aOutPosStr( aEdOutPos.GetText() ); + ScAddress aAdrDest; + BOOL bToNewTable = (aLbOutPos.GetSelectEntryPos() == 1); + USHORT nResult = !bToNewTable ? aAdrDest.Parse( aOutPosStr, pDoc, pDoc->GetAddressConvention() ) : 0; + + if ( bToNewTable + || ( (aOutPosStr.Len() > 0) && (SCA_VALID == (nResult & SCA_VALID)) ) ) + { + //@BugID 54702 Enablen/Disablen nur noch in Basisklasse + //SFX_APPWINDOW->Enable(); + + ScPivotParam theOutParam; + PivotPageFieldArr aPageFieldArr; + PivotFieldArr aColFieldArr; + PivotFieldArr aRowFieldArr; + PivotFieldArr aDataFieldArr; + USHORT nPageCount; + USHORT nColCount; + USHORT nRowCount; + USHORT nDataCount; + + BOOL bFit = GetPivotArrays( aPageFieldArr, aColFieldArr, aRowFieldArr, aDataFieldArr, + nPageCount, nColCount, nRowCount, nDataCount ); + if ( bFit ) + { + ScDPSaveData* pOldSaveData = xDlgDPObject->GetSaveData(); + + ScRange aOutRange( aAdrDest ); // bToNewTable is passed separately + + ScDPSaveData aSaveData; + aSaveData.SetIgnoreEmptyRows( aBtnIgnEmptyRows.IsChecked() ); + aSaveData.SetRepeatIfEmpty( aBtnDetectCat.IsChecked() ); + aSaveData.SetColumnGrand( aBtnTotalCol.IsChecked() ); + aSaveData.SetRowGrand( aBtnTotalRow.IsChecked() ); + aSaveData.SetFilterButton( aBtnFilter.IsChecked() ); + aSaveData.SetDrillDown( aBtnDrillDown.IsChecked() ); + + uno::Reference<sheet::XDimensionsSupplier> xSource = xDlgDPObject->GetSource(); + + ScDPObject::ConvertOrientation( aSaveData, aPageFieldArr, nPageCount, + sheet::DataPilotFieldOrientation_PAGE, NULL, 0, 0, xSource, FALSE ); + ScDPObject::ConvertOrientation( aSaveData, aColFieldArr, nColCount, + sheet::DataPilotFieldOrientation_COLUMN, NULL, 0, 0, xSource, FALSE ); + ScDPObject::ConvertOrientation( aSaveData, aRowFieldArr, nRowCount, + sheet::DataPilotFieldOrientation_ROW, NULL, 0, 0, xSource, FALSE ); + ScDPObject::ConvertOrientation( aSaveData, aDataFieldArr, nDataCount, + sheet::DataPilotFieldOrientation_DATA, NULL, 0, 0, xSource, FALSE, + aColFieldArr, nColCount, aRowFieldArr, nRowCount, aPageFieldArr, nPageCount ); + + for( ScDPLabelDataVec::const_iterator aIt = aLabelDataArr.begin(), aEnd = aLabelDataArr.end(); aIt != aEnd; ++aIt ) + { + if( ScDPSaveDimension* pDim = aSaveData.GetExistingDimensionByName( aIt->maName ) ) + { + pDim->SetUsedHierarchy( aIt->mnUsedHier ); + pDim->SetShowEmpty( aIt->mbShowAll ); + pDim->SetSortInfo( &aIt->maSortInfo ); + pDim->SetLayoutInfo( &aIt->maLayoutInfo ); + pDim->SetAutoShowInfo( &aIt->maShowInfo ); + ScDPSaveDimension* pOldDim = NULL; + if (pOldSaveData) + { + // Transfer the existing layout names to new dimension instance. + pOldDim = pOldSaveData->GetExistingDimensionByName(aIt->maName); + if (pOldDim) + { + const OUString* pLayoutName = pOldDim->GetLayoutName(); + if (pLayoutName) + pDim->SetLayoutName(*pLayoutName); + + const OUString* pSubtotalName = pOldDim->GetSubtotalName(); + if (pSubtotalName) + pDim->SetSubtotalName(*pSubtotalName); + } + } + + bool bManualSort = ( aIt->maSortInfo.Mode == sheet::DataPilotFieldSortMode::MANUAL ); + + // visibility of members + for (vector<ScDPLabelData::Member>::const_iterator itr = aIt->maMembers.begin(), itrEnd = aIt->maMembers.end(); + itr != itrEnd; ++itr) + { + ScDPSaveMember* pMember = pDim->GetMemberByName(itr->maName); + + // #i40054# create/access members only if flags are not default + // (or in manual sorting mode - to keep the order) + if (bManualSort || !itr->mbVisible || !itr->mbShowDetails) + { + pMember->SetIsVisible(itr->mbVisible); + pMember->SetShowDetails(itr->mbShowDetails); + } + if (pOldDim) + { + // Transfer the existing layout name. + ScDPSaveMember* pOldMember = pOldDim->GetMemberByName(itr->maName); + if (pOldMember) + { + const OUString* pLayoutName = pOldMember->GetLayoutName(); + if (pLayoutName) + pMember->SetLayoutName(*pLayoutName); + } + } + } + } + } + ScDPSaveDimension* pDim = aSaveData.GetDataLayoutDimension(); + if (pDim && pOldSaveData) + { + ScDPSaveDimension* pOldDim = pOldSaveData->GetDataLayoutDimension(); + if (pOldDim) + { + const OUString* pLayoutName = pOldDim->GetLayoutName(); + if (pLayoutName) + pDim->SetLayoutName(*pLayoutName); + } + } + + USHORT nWhichPivot = SC_MOD()->GetPool().GetWhich( SID_PIVOT_TABLE ); + ScPivotItem aOutItem( nWhichPivot, &aSaveData, &aOutRange, bToNewTable ); + + bRefInputMode = FALSE; // to allow deselecting when switching sheets + + SetDispatcherLock( FALSE ); + SwitchToDocument(); + + // #95513# don't hide the dialog before executing the slot, instead it is used as + // parent for message boxes in ScTabViewShell::GetDialogParent + + const SfxPoolItem* pRet = GetBindings().GetDispatcher()->Execute( + SID_PIVOT_TABLE, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD, &aOutItem, 0L, 0L ); + + bool bSuccess = true; + if (pRet) + { + const SfxBoolItem* pItem = dynamic_cast<const SfxBoolItem*>(pRet); + if (pItem) + bSuccess = pItem->GetValue(); + } + if (bSuccess) + // Table successfully inserted. + Close(); + else + { + // Table insertion failed. Keep the dialog open. + bRefInputMode = true; + SetDispatcherLock(true); + } + } + else + { + ErrorBox( this, WinBits( WB_OK | WB_DEF_OK ), + ScGlobal::GetRscString( STR_PIVOT_ERROR ) + ).Execute(); + } + } + else + { + if ( !aBtnMore.GetState() ) + aBtnMore.SetState( TRUE ); + + ErrorBox( this, WinBits( WB_OK | WB_DEF_OK ), + ScGlobal::GetRscString( STR_INVALID_TABREF ) + ).Execute(); + aEdOutPos.GrabFocus(); + } + return 0; +} + + +//---------------------------------------------------------------------------- + +IMPL_LINK( ScDPLayoutDlg, CancelHdl, CancelButton *, EMPTYARG ) +{ + Close(); + return 0; +} + + +//---------------------------------------------------------------------------- + +IMPL_LINK( ScDPLayoutDlg, MoreClickHdl, MoreButton *, EMPTYARG ) +{ + if ( aBtnMore.GetState() ) + { + bRefInputMode = TRUE; + //@BugID 54702 Enablen/Disablen nur noch in Basisklasse + //SFX_APPWINDOW->Enable(); + if ( aEdInPos.IsEnabled() ) + { + aEdInPos.Enable(); + aEdInPos.GrabFocus(); + aEdInPos.Enable(); + } + else + { + aEdOutPos.Enable(); + aEdOutPos.GrabFocus(); + aEdOutPos.Enable(); + } + } + else + { + bRefInputMode = FALSE; + //@BugID 54702 Enablen/Disablen nur noch in Basisklasse + //SFX_APPWINDOW->Disable(FALSE); //! allgemeine Methode im ScAnyRefDlg + } + return 0; +} + + +//---------------------------------------------------------------------------- + +IMPL_LINK( ScDPLayoutDlg, EdModifyHdl, Edit *, EMPTYARG ) +{ + String theCurPosStr = aEdOutPos.GetText(); + USHORT nResult = ScAddress().Parse( theCurPosStr, pDoc, pDoc->GetAddressConvention() ); + + if ( SCA_VALID == (nResult & SCA_VALID) ) + { + String* pStr = NULL; + BOOL bFound = FALSE; + USHORT i = 0; + USHORT nCount = aLbOutPos.GetEntryCount(); + + for ( i=2; i<nCount && !bFound; i++ ) + { + pStr = (String*)aLbOutPos.GetEntryData( i ); + bFound = (theCurPosStr == *pStr); + } + + if ( bFound ) + aLbOutPos.SelectEntryPos( --i ); + else + aLbOutPos.SelectEntryPos( 0 ); + } + return 0; +} + + +IMPL_LINK( ScDPLayoutDlg, EdInModifyHdl, Edit *, EMPTYARG ) +{ + UpdateSrcRange(); + return 0; +} + + +//---------------------------------------------------------------------------- + +IMPL_LINK( ScDPLayoutDlg, SelAreaHdl, ListBox *, EMPTYARG ) +{ + String aString; + USHORT nSelPos = aLbOutPos.GetSelectEntryPos(); + + if ( nSelPos > 1 ) + { + aString = *(String*)aLbOutPos.GetEntryData( nSelPos ); + } + else if ( nSelPos == aLbOutPos.GetEntryCount()-1 ) // auf neue Tabelle? + { + aEdOutPos.Disable(); + aRbOutPos.Disable(); + } + else + { + aEdOutPos.Enable(); + aRbOutPos.Enable(); + } + + aEdOutPos.SetText( aString ); + return 0; +} + + +//---------------------------------------------------------------------------- + +IMPL_LINK( ScDPLayoutDlg, ScrollHdl, ScrollBar *, EMPTYARG ) +{ + long nNewOffset = aSlider.GetThumbPos(); + long nOffsetDiff = nNewOffset - nOffset; + nOffset = nNewOffset; + + size_t nFields = std::min< size_t >( aLabelDataArr.size() - nOffset, PAGE_SIZE ); + + aWndSelect.ClearFields(); + + size_t i=0; + for ( i=0; i<nFields; i++ ) + { + const ScDPLabelData& rData = aLabelDataArr[nOffset+i]; + aWndSelect.AddField(rData.getDisplayName(), i); + aSelectArr[i].reset( new ScDPFuncData( rData.mnCol, rData.mnFuncMask ) ); + } + for ( ; i<aSelectArr.size(); i++ ) + aSelectArr[i].reset(); + + aWndSelect.ModifySelectionOffset( nOffsetDiff ); // adjusts selection & redraws + return 0; +} + +//---------------------------------------------------------------------------- + +IMPL_LINK( ScDPLayoutDlg, GetFocusHdl, Control*, pCtrl ) +{ + pEditActive = NULL; + if ( pCtrl == &aEdInPos ) + pEditActive = &aEdInPos; + else if ( pCtrl == &aEdOutPos ) + pEditActive = &aEdOutPos; + + return 0; +} + |