diff options
-rw-r--r-- | sc/inc/dpglobal.hxx | 2 | ||||
-rw-r--r-- | sc/inc/dpobject.hxx | 10 | ||||
-rw-r--r-- | sc/inc/pivot.hxx | 23 | ||||
-rw-r--r-- | sc/source/core/data/dpobject.cxx | 300 | ||||
-rw-r--r-- | sc/source/core/data/dpoutput.cxx | 64 | ||||
-rw-r--r-- | sc/source/core/data/global2.cxx | 118 | ||||
-rw-r--r-- | sc/source/ui/Accessibility/AccessibleDataPilotControl.cxx | 10 | ||||
-rw-r--r-- | sc/source/ui/dbgui/dpuiglobal.hxx | 42 | ||||
-rw-r--r-- | sc/source/ui/dbgui/fieldwnd.cxx | 1806 | ||||
-rw-r--r-- | sc/source/ui/dbgui/pivot.hrc | 4 | ||||
-rw-r--r-- | sc/source/ui/dbgui/pivot.src | 77 | ||||
-rw-r--r-- | sc/source/ui/dbgui/pvglob.hxx | 45 | ||||
-rw-r--r-- | sc/source/ui/dbgui/pvlaydlg.cxx | 1179 | ||||
-rw-r--r-- | sc/source/ui/inc/AccessibleDataPilotControl.hxx | 6 | ||||
-rw-r--r-- | sc/source/ui/inc/fieldwnd.hxx | 454 | ||||
-rw-r--r-- | sc/source/ui/inc/pvlaydlg.hxx | 55 |
16 files changed, 2708 insertions, 1487 deletions
diff --git a/sc/inc/dpglobal.hxx b/sc/inc/dpglobal.hxx index 253f478cbf2b..ea9884c93b14 100644 --- a/sc/inc/dpglobal.hxx +++ b/sc/inc/dpglobal.hxx @@ -61,8 +61,6 @@ // moved from fieldwnd.hxx, see also SC_DAPI_MAXFIELDS #define MAX_LABELS 256 -#define MAX_PAGEFIELDS 10 // maximum count of fields for page area - #define PIVOT_MAXFUNC 11 #define PIVOT_FUNC_NONE 0x0000 #define PIVOT_FUNC_SUM 0x0001 diff --git a/sc/inc/dpobject.hxx b/sc/inc/dpobject.hxx index 8fa972f1f01e..b1a44825a49c 100644 --- a/sc/inc/dpobject.hxx +++ b/sc/inc/dpobject.hxx @@ -252,14 +252,12 @@ public: CreateSource( const ScDPServiceDesc& rDesc ); static void ConvertOrientation( ScDPSaveData& rSaveData, - PivotField* pFields, SCSIZE nCount, USHORT nOrient, - ScDocument* pDoc, SCROW nRow, SCTAB nTab, + const ::std::vector<PivotField>& rFields, USHORT nOrient, const com::sun::star::uno::Reference< com::sun::star::sheet::XDimensionsSupplier>& xSource, - BOOL bOldDefaults, - PivotField* pRefColFields = NULL, SCSIZE nRefColCount = 0, - PivotField* pRefRowFields = NULL, SCSIZE nRefRowCount = 0, - PivotField* pRefPageFields = NULL, SCSIZE nRefPageCount = 0 ); + ::std::vector<PivotField>* pRefColFields = NULL, + ::std::vector<PivotField>* pRefRowFields = NULL, + ::std::vector<PivotField>* pRefPageFields = NULL ); static bool IsOrientationAllowed( USHORT nOrient, sal_Int32 nDimFlags ); }; diff --git a/sc/inc/pivot.hxx b/sc/inc/pivot.hxx index a844b3d3ecbe..feb913d6e07e 100644 --- a/sc/inc/pivot.hxx +++ b/sc/inc/pivot.hxx @@ -77,12 +77,13 @@ typedef ::boost::shared_ptr<ScDPLabelData> ScDPLabelDataRef; struct PivotField { - SCsCOL nCol; + SCsCOL nCol; USHORT nFuncMask; USHORT nFuncCount; ::com::sun::star::sheet::DataPilotFieldReference maFieldRef; explicit PivotField( SCsCOL nNewCol = 0, USHORT nNewFuncMask = PIVOT_FUNC_NONE ); + PivotField( const PivotField& r ); bool operator==( const PivotField& r ) const; }; @@ -96,14 +97,10 @@ struct ScPivotParam SCROW nRow; // bzw. Anfang des Zielbereiches SCTAB nTab; ::std::vector<ScDPLabelDataRef> maLabelArray; - PivotField aPageArr[PIVOT_MAXPAGEFIELD]; - PivotField aColArr[PIVOT_MAXFIELD]; - PivotField aRowArr[PIVOT_MAXFIELD]; - PivotField aDataArr[PIVOT_MAXFIELD]; - SCSIZE nPageCount; - SCSIZE nColCount; - SCSIZE nRowCount; - SCSIZE nDataCount; + ::std::vector<PivotField> maPageFields; + ::std::vector<PivotField> maColFields; + ::std::vector<PivotField> maRowFields; + ::std::vector<PivotField> maDataFields; BOOL bIgnoreEmptyRows; BOOL bDetectCategories; BOOL bMakeTotalCol; @@ -117,14 +114,6 @@ struct ScPivotParam BOOL operator== ( const ScPivotParam& r ) const; void ClearPivotArrays(); void SetLabelData (const ::std::vector<ScDPLabelDataRef>& r); - void SetPivotArrays ( const PivotField* pPageArr, - const PivotField* pColArr, - const PivotField* pRowArr, - const PivotField* pDataArr, - SCSIZE nPageCnt, - SCSIZE nColCnt, - SCSIZE nRowCnt, - SCSIZE nDataCnt ); }; // ----------------------------------------------------------------------- diff --git a/sc/source/core/data/dpobject.cxx b/sc/source/core/data/dpobject.cxx index 97c1e9e52c6b..9f4870494ec9 100644 --- a/sc/source/core/data/dpobject.cxx +++ b/sc/source/core/data/dpobject.cxx @@ -29,8 +29,6 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sc.hxx" - - // INCLUDE --------------------------------------------------------------- #include "dpobject.hxx" @@ -94,10 +92,10 @@ using ::com::sun::star::uno::Exception; using ::com::sun::star::lang::XComponent; using ::com::sun::star::sheet::DataPilotTableHeaderData; using ::com::sun::star::sheet::DataPilotTablePositionData; +using ::com::sun::star::sheet::XDimensionsSupplier; using ::com::sun::star::beans::XPropertySet; using ::rtl::OUString; - // ----------------------------------------------------------------------- #define SCDPSOURCE_SERVICE "com.sun.star.sheet.DataPilotSource" @@ -1713,33 +1711,42 @@ USHORT lcl_CountBits( USHORT nBits ) return nCount; } -SCSIZE lcl_FillOldFields( PivotField* pFields, - const uno::Reference<sheet::XDimensionsSupplier>& xSource, - USHORT nOrient, SCCOL nColAdd, BOOL bAddData ) +void lcl_FillOldFields( + vector<PivotField>& rFields, + const uno::Reference<sheet::XDimensionsSupplier>& xSource, + USHORT nOrient, SCCOL nColAdd, bool bAddData ) { - SCSIZE nOutCount = 0; - BOOL bDataFound = FALSE; + vector<PivotField> aFields; - SCSIZE nCount = (nOrient == sheet::DataPilotFieldOrientation_PAGE) ? PIVOT_MAXPAGEFIELD : PIVOT_MAXFIELD; + bool bDataFound = false; //! merge multiple occurences (data field with different functions) //! force data field in one dimension - std::vector< long > aPos( nCount, 0 ); + vector<long> aPos; uno::Reference<container::XNameAccess> xDimsName = xSource->getDimensions(); uno::Reference<container::XIndexAccess> xDims = new ScNameToIndexAccess( xDimsName ); long nDimCount = xDims->getCount(); - for (long nDim=0; nDim < nDimCount && nOutCount < nCount; nDim++) + for (long nDim = 0; nDim < nDimCount; ++nDim) { + // Get dimension object. uno::Reference<uno::XInterface> xIntDim = ScUnoHelpFunctions::AnyToInterface( xDims->getByIndex(nDim) ); + + // dimension properties uno::Reference<beans::XPropertySet> xDimProp( xIntDim, uno::UNO_QUERY ); + + // dimension orientation, hidden by default. long nDimOrient = ScUnoHelpFunctions::GetEnumProperty( xDimProp, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(DP_PROP_ORIENTATION)), sheet::DataPilotFieldOrientation_HIDDEN ); + if ( xDimProp.is() && nDimOrient == nOrient ) { + // Let's take this dimension. + + // function mask. USHORT nMask = 0; if ( nOrient == sheet::DataPilotFieldOrientation_DATA ) { @@ -1780,85 +1787,88 @@ SCSIZE lcl_FillOldFields( PivotField* pFields, nDupSource = lcl_FindName( xNameOrig->getName(), xDimsName ); } - BOOL bDupUsed = FALSE; + bool bDupUsed = false; if ( nDupSource >= 0 ) { + // this dimension is cloned. + // add function bit to previous entry - SCsCOL nCompCol; + SCsCOL nCompCol; // column ID of the original dimension. if ( bDataLayout ) nCompCol = PIVOT_DATA_FIELD; else nCompCol = static_cast<SCsCOL>(nDupSource)+nColAdd; //! seek source column from name - for (SCSIZE nOld=0; nOld<nOutCount && !bDupUsed; nOld++) - if ( pFields[nOld].nCol == nCompCol ) + vector<PivotField>::iterator itr = aFields.begin(), itrEnd = aFields.end(); + for (; itr != itrEnd; ++itr) + { + // add to previous column only if new bits aren't already set there + if (itr->nCol == nCompCol && (itr->nFuncMask & nMask) == 0) { - // add to previous column only if new bits aren't already set there - if ( ( pFields[nOld].nFuncMask & nMask ) == 0 ) - { - pFields[nOld].nFuncMask |= nMask; - pFields[nOld].nFuncCount = lcl_CountBits( pFields[nOld].nFuncMask ); - bDupUsed = TRUE; - } + itr->nFuncMask |= nMask; + itr->nFuncCount = lcl_CountBits(itr->nFuncMask); + bDupUsed = true; + break; } + } } if ( !bDupUsed ) // also for duplicated dim if original has different orientation { - if ( bDataLayout ) + aFields.push_back(PivotField()); + PivotField& rField = aFields.back(); + if (bDataLayout) { - pFields[nOutCount].nCol = PIVOT_DATA_FIELD; - bDataFound = TRUE; + rField.nCol = PIVOT_DATA_FIELD; + bDataFound = true; } - else if ( nDupSource >= 0 ) // if source was not found (different orientation) - pFields[nOutCount].nCol = static_cast<SCsCOL>(nDupSource)+nColAdd; //! seek from name + else if (nDupSource >= 0) + rField.nCol = static_cast<SCsCOL>(nDupSource)+nColAdd; //! seek from name else - pFields[nOutCount].nCol = static_cast<SCsCOL>(nDim)+nColAdd; //! seek source column from name + rField.nCol = static_cast<SCsCOL>(nDim)+nColAdd; //! seek source column from name - pFields[nOutCount].nFuncMask = nMask; - pFields[nOutCount].nFuncCount = lcl_CountBits( nMask ); - aPos[nOutCount] = ScUnoHelpFunctions::GetLongProperty( xDimProp, - rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(DP_PROP_POSITION)) ); + rField.nFuncMask = nMask; + rField.nFuncCount = lcl_CountBits(nMask); + long nPos = ScUnoHelpFunctions::GetLongProperty( + xDimProp, OUString(RTL_CONSTASCII_USTRINGPARAM(DP_PROP_POSITION))); + aPos.push_back(nPos); try { - if( nOrient == sheet::DataPilotFieldOrientation_DATA ) - xDimProp->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( SC_UNO_REFVALUE ) ) ) - >>= pFields[nOutCount].maFieldRef; + if (nOrient == sheet::DataPilotFieldOrientation_DATA) + xDimProp->getPropertyValue(OUString::createFromAscii(SC_UNO_REFVALUE)) + >>= rField.maFieldRef; } - catch( uno::Exception& ) + catch (uno::Exception&) { } - - ++nOutCount; } } } // sort by getPosition() value - for (SCSIZE i=0; i+1<nOutCount; i++) + size_t nOutCount = aFields.size(); + if (nOutCount >= 1) { - for (SCSIZE j=0; j+i+1<nOutCount; j++) - if ( aPos[j+1] < aPos[j] ) + for (size_t i = 0; i < nOutCount - 1; ++i) + { + for (size_t j = 0; j + i < nOutCount - 1; ++j) { - std::swap( aPos[j], aPos[j+1] ); - std::swap( pFields[j], pFields[j+1] ); + if ( aPos[j+1] < aPos[j] ) + { + std::swap( aPos[j], aPos[j+1] ); + std::swap( aFields[j], aFields[j+1] ); + } } + } } - if ( bAddData && !bDataFound ) - { - if ( nOutCount >= nCount ) // space for data field? - --nOutCount; //! error? - pFields[nOutCount].nCol = PIVOT_DATA_FIELD; - pFields[nOutCount].nFuncMask = 0; - pFields[nOutCount].nFuncCount = 0; - ++nOutCount; - } + if (bAddData && !bDataFound) + aFields.push_back(PivotField(PIVOT_DATA_FIELD, 0)); - return nOutCount; + rFields.swap(aFields); } BOOL ScDPObject::FillOldParam(ScPivotParam& rParam, BOOL bForFile) const @@ -1879,15 +1889,15 @@ BOOL ScDPObject::FillOldParam(ScPivotParam& rParam, BOOL bForFile) const nColAdd = pSheetDesc->aSourceRange.aStart.Col(); } - BOOL bAddData = ( lcl_GetDataGetOrientation( xSource ) == sheet::DataPilotFieldOrientation_HIDDEN ); - rParam.nPageCount = lcl_FillOldFields( rParam.aPageArr, - xSource, sheet::DataPilotFieldOrientation_PAGE, nColAdd, FALSE ); - rParam.nColCount = lcl_FillOldFields( rParam.aColArr, - xSource, sheet::DataPilotFieldOrientation_COLUMN, nColAdd, bAddData ); - rParam.nRowCount = lcl_FillOldFields( rParam.aRowArr, - xSource, sheet::DataPilotFieldOrientation_ROW, nColAdd, FALSE ); - rParam.nDataCount = lcl_FillOldFields( rParam.aDataArr, - xSource, sheet::DataPilotFieldOrientation_DATA, nColAdd, FALSE ); + bool bAddData = ( lcl_GetDataGetOrientation( xSource ) == sheet::DataPilotFieldOrientation_HIDDEN ); + lcl_FillOldFields( + rParam.maPageFields, xSource, sheet::DataPilotFieldOrientation_PAGE, nColAdd, false); + lcl_FillOldFields( + rParam.maColFields, xSource, sheet::DataPilotFieldOrientation_COLUMN, nColAdd, bAddData); + lcl_FillOldFields( + rParam.maRowFields, xSource, sheet::DataPilotFieldOrientation_ROW, nColAdd, false); + lcl_FillOldFields( + rParam.maDataFields, xSource, sheet::DataPilotFieldOrientation_DATA, nColAdd, false); uno::Reference<beans::XPropertySet> xProp( xSource, uno::UNO_QUERY ); if (xProp.is()) @@ -2106,6 +2116,8 @@ BOOL ScDPObject::GetMembersNA( sal_Int32 nDim, sal_Int32 nHier, uno::Reference< //------------------------------------------------------------------------ // convert old pivot tables into new datapilot tables +namespace { + String lcl_GetDimName( const uno::Reference<sheet::XDimensionsSupplier>& xSource, long nDim ) { rtl::OUString aName; @@ -2134,111 +2146,125 @@ String lcl_GetDimName( const uno::Reference<sheet::XDimensionsSupplier>& xSource return aName; } +bool hasFieldColumn(const vector<PivotField>* pRefFields, SCCOL nCol) +{ + if (!pRefFields) + return false; + + vector<PivotField>::const_iterator itr = pRefFields->begin(), itrEnd = pRefFields->end(); + for (; itr != itrEnd; ++itr) + { + if (itr->nCol == nCol) + // This array of fields contains the specified column. + return true; + } + return false; +} + +} + // static -void ScDPObject::ConvertOrientation( ScDPSaveData& rSaveData, - PivotField* pFields, SCSIZE nCount, USHORT nOrient, - ScDocument* pDoc, SCROW nRow, SCTAB nTab, - const uno::Reference<sheet::XDimensionsSupplier>& xSource, - BOOL bOldDefaults, - PivotField* pRefColFields, SCSIZE nRefColCount, - PivotField* pRefRowFields, SCSIZE nRefRowCount, - PivotField* pRefPageFields, SCSIZE nRefPageCount ) +void ScDPObject::ConvertOrientation( + ScDPSaveData& rSaveData, const vector<PivotField>& rFields, USHORT nOrient, + const Reference<XDimensionsSupplier>& xSource, + vector<PivotField>* pRefColFields, vector<PivotField>* pRefRowFields, vector<PivotField>* pRefPageFields ) { // pDoc or xSource must be set DBG_ASSERT( pDoc || xSource.is(), "missing string source" ); - String aDocStr; - ScDPSaveDimension* pDim; - - for (SCSIZE i=0; i<nCount; i++) + vector<PivotField>::const_iterator itr, itrBeg = rFields.begin(), itrEnd = rFields.end(); + for (itr = itrBeg; itr != itrEnd; ++itr) { - SCCOL nCol = pFields[i].nCol; - USHORT nFuncs = pFields[i].nFuncMask; - const sheet::DataPilotFieldReference& rFieldRef = pFields[i].maFieldRef; + const PivotField& rField = *itr; + SCCOL nCol = rField.nCol; + USHORT nFuncs = rField.nFuncMask; + const sheet::DataPilotFieldReference& rFieldRef = rField.maFieldRef; + + ScDPSaveDimension* pDim = NULL; if ( nCol == PIVOT_DATA_FIELD ) pDim = rSaveData.GetDataLayoutDimension(); else { - if ( pDoc ) - pDoc->GetString( nCol, nRow, nTab, aDocStr ); - else - aDocStr = lcl_GetDimName( xSource, nCol ); // cols must start at 0 - + String aDocStr = lcl_GetDimName( xSource, nCol ); // cols must start at 0 if ( aDocStr.Len() ) pDim = rSaveData.GetDimensionByName(aDocStr); else pDim = NULL; } - if ( pDim ) + if (!pDim) + continue; + + if ( nOrient == sheet::DataPilotFieldOrientation_DATA ) // set summary function { - if ( nOrient == sheet::DataPilotFieldOrientation_DATA ) // set summary function - { - // generate an individual entry for each function - BOOL bFirst = TRUE; - - // if a dimension is used for column/row/page and data, - // use duplicated dimensions for all data occurrences - if (pRefColFields) - for (SCSIZE nRefCol=0; nRefCol<nRefColCount; nRefCol++) - if (pRefColFields[nRefCol].nCol == nCol) - bFirst = FALSE; - if (pRefRowFields) - for (SCSIZE nRefRow=0; nRefRow<nRefRowCount; nRefRow++) - if (pRefRowFields[nRefRow].nCol == nCol) - bFirst = FALSE; - if (pRefPageFields) - for (USHORT nRefPage=0; nRefPage<nRefPageCount; ++nRefPage) - if (pRefPageFields[nRefPage].nCol == nCol) - bFirst = FALSE; + // generate an individual entry for each function + bool bFirst = true; + + // if a dimension is used for column/row/page and data, + // use duplicated dimensions for all data occurrences + if (hasFieldColumn(pRefColFields, nCol)) + bFirst = false; + + if (bFirst && hasFieldColumn(pRefRowFields, nCol)) + bFirst = false; + if (bFirst && hasFieldColumn(pRefPageFields, nCol)) + bFirst = false; + + if (bFirst) + { // if set via api, a data column may occur several times // (if the function hasn't been changed yet) -> also look for duplicate data column - for (SCSIZE nPrevData=0; nPrevData<i; nPrevData++) - if (pFields[nPrevData].nCol == nCol) - bFirst = FALSE; - - USHORT nMask = 1; - for (USHORT nBit=0; nBit<16; nBit++) + for (vector<PivotField>::const_iterator itr2 = itrBeg; itr2 != itr; ++itr2) { - if ( nFuncs & nMask ) + if (itr2->nCol == nCol) { - sheet::GeneralFunction eFunc = ScDataPilotConversion::FirstFunc( nMask ); - ScDPSaveDimension* pCurrDim = bFirst ? pDim : rSaveData.DuplicateDimension(pDim->GetName()); - pCurrDim->SetOrientation( nOrient ); - pCurrDim->SetFunction( sal::static_int_cast<USHORT>(eFunc) ); - - if( rFieldRef.ReferenceType == sheet::DataPilotFieldReferenceType::NONE ) - pCurrDim->SetReferenceValue( 0 ); - else - pCurrDim->SetReferenceValue( &rFieldRef ); - - bFirst = FALSE; + bFirst = false; + break; } - nMask *= 2; } } - else // set SubTotals - { - pDim->SetOrientation( nOrient ); - USHORT nFuncArray[16]; - USHORT nFuncCount = 0; - USHORT nMask = 1; - for (USHORT nBit=0; nBit<16; nBit++) + USHORT nMask = 1; + for (USHORT nBit=0; nBit<16; nBit++) + { + if ( nFuncs & nMask ) { - if ( nFuncs & nMask ) - nFuncArray[nFuncCount++] = sal::static_int_cast<USHORT>(ScDataPilotConversion::FirstFunc( nMask )); - nMask *= 2; + sheet::GeneralFunction eFunc = ScDataPilotConversion::FirstFunc( nMask ); + ScDPSaveDimension* pCurrDim = bFirst ? pDim : rSaveData.DuplicateDimension(pDim->GetName()); + pCurrDim->SetOrientation( nOrient ); + pCurrDim->SetFunction( sal::static_int_cast<USHORT>(eFunc) ); + + if( rFieldRef.ReferenceType == sheet::DataPilotFieldReferenceType::NONE ) + pCurrDim->SetReferenceValue( 0 ); + else + pCurrDim->SetReferenceValue( &rFieldRef ); + + bFirst = false; } - pDim->SetSubTotals( nFuncCount, nFuncArray ); + nMask *= 2; + } + } + else // set SubTotals + { + pDim->SetOrientation( nOrient ); - // ShowEmpty was implicit in old tables, - // must be set for data layout dimension (not accessible in dialog) - if ( bOldDefaults || nCol == PIVOT_DATA_FIELD ) - pDim->SetShowEmpty( TRUE ); + USHORT nFuncArray[16]; + USHORT nFuncCount = 0; + USHORT nMask = 1; + for (USHORT nBit=0; nBit<16; nBit++) + { + if ( nFuncs & nMask ) + nFuncArray[nFuncCount++] = sal::static_int_cast<USHORT>(ScDataPilotConversion::FirstFunc( nMask )); + nMask *= 2; } + pDim->SetSubTotals( nFuncCount, nFuncArray ); + + // ShowEmpty was implicit in old tables, + // must be set for data layout dimension (not accessible in dialog) + if ( nCol == PIVOT_DATA_FIELD ) + pDim->SetShowEmpty( TRUE ); } } } @@ -2533,8 +2559,6 @@ String ScDPCollection::CreateNewName( USHORT nMin ) const return String(); // should not happen } - - // Wang Xu Ming -- 2009-8-17 // DataPilot Migration - Cache&&Performance long ScDPObject::GetCacheId() const diff --git a/sc/source/core/data/dpoutput.cxx b/sc/source/core/data/dpoutput.cxx index fde458b8c6dc..1104b4b4cc15 100644 --- a/sc/source/core/data/dpoutput.cxx +++ b/sc/source/core/data/dpoutput.cxx @@ -29,8 +29,6 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sc.hxx" - - // INCLUDE --------------------------------------------------------------- #include "scitems.hxx" @@ -79,6 +77,48 @@ using ::com::sun::star::uno::makeAny; using ::com::sun::star::uno::Any; using ::rtl::OUString; +#include <stdio.h> +#include <string> +#include <sys/time.h> + +namespace { + +class StackPrinter +{ +public: + explicit StackPrinter(const char* msg) : + msMsg(msg) + { + fprintf(stdout, "%s: --begin\n", msMsg.c_str()); + mfStartTime = getTime(); + } + + ~StackPrinter() + { + double fEndTime = getTime(); + fprintf(stdout, "%s: --end (duration: %g sec)\n", msMsg.c_str(), (fEndTime-mfStartTime)); + } + + void printTime(int line) const + { + double fEndTime = getTime(); + fprintf(stdout, "%s: --(%d) (duration: %g sec)\n", msMsg.c_str(), line, (fEndTime-mfStartTime)); + } + +private: + double getTime() const + { + timeval tv; + gettimeofday(&tv, NULL); + return tv.tv_sec + tv.tv_usec / 1000000.0; + } + + ::std::string msMsg; + double mfStartTime; +}; + +} + // ----------------------------------------------------------------------- //! move to a header file @@ -99,7 +139,6 @@ using ::rtl::OUString; //! dynamic!!! #define SC_DPOUT_MAXLEVELS 256 - struct ScDPOutLevelData { long nDim; @@ -374,6 +413,7 @@ ScDPOutput::ScDPOutput( ScDocument* pD, const uno::Reference<sheet::XDimensionsS bSizeOverflow( FALSE ), mbHeaderLayout( false ) { + StackPrinter __stack_printer__("ScDPOutput::ScDPOutput"); nTabStartCol = nMemberStartCol = nDataStartCol = nTabEndCol = 0; nTabStartRow = nMemberStartRow = nDataStartRow = nTabEndRow = 0; @@ -394,6 +434,7 @@ ScDPOutput::ScDPOutput( ScDocument* pD, const uno::Reference<sheet::XDimensionsS long nDimCount = xDims->getCount(); for (long nDim=0; nDim<nDimCount; nDim++) { + fprintf(stdout, "ScDPOutput::ScDPOutput: dimension = %ld\n", nDim); uno::Reference<uno::XInterface> xDim = ScUnoHelpFunctions::AnyToInterface( xDims->getByIndex(nDim) ); uno::Reference<beans::XPropertySet> xDimProp( xDim, uno::UNO_QUERY ); @@ -414,6 +455,7 @@ ScDPOutput::ScDPOutput( ScDocument* pD, const uno::Reference<sheet::XDimensionsS if ( eDimOrient != sheet::DataPilotFieldOrientation_HIDDEN ) { + fprintf(stdout, "ScDPOutput::ScDPOutput: not hidden\n"); uno::Reference<container::XIndexAccess> xHiers = new ScNameToIndexAccess( xDimSupp->getHierarchies() ); long nHierarchy = ScUnoHelpFunctions::GetLongProperty( @@ -453,6 +495,7 @@ ScDPOutput::ScDPOutput( ScDocument* pD, const uno::Reference<sheet::XDimensionsS switch ( eDimOrient ) { case sheet::DataPilotFieldOrientation_COLUMN: + fprintf(stdout, "ScDPOutput::ScDPOutput: column\n"); pColFields[nColFieldCount].nDim = nDim; pColFields[nColFieldCount].nHier = nHierarchy; pColFields[nColFieldCount].nLevel = nLev; @@ -465,6 +508,7 @@ ScDPOutput::ScDPOutput( ScDocument* pD, const uno::Reference<sheet::XDimensionsS ++nColFieldCount; break; case sheet::DataPilotFieldOrientation_ROW: + fprintf(stdout, "ScDPOutput::ScDPOutput: row\n"); pRowFields[nRowFieldCount].nDim = nDim; pRowFields[nRowFieldCount].nHier = nHierarchy; pRowFields[nRowFieldCount].nLevel = nLev; @@ -480,6 +524,7 @@ ScDPOutput::ScDPOutput( ScDocument* pD, const uno::Reference<sheet::XDimensionsS } break; case sheet::DataPilotFieldOrientation_PAGE: + fprintf(stdout, "ScDPOutput::ScDPOutput: page\n"); pPageFields[nPageFieldCount].nDim = nDim; pPageFields[nPageFieldCount].nHier = nHierarchy; pPageFields[nPageFieldCount].nLevel = nLev; @@ -493,6 +538,7 @@ ScDPOutput::ScDPOutput( ScDocument* pD, const uno::Reference<sheet::XDimensionsS break; default: { + fprintf(stdout, "ScDPOutput::ScDPOutput: none of the above\n"); // added to avoid warnings } } @@ -500,6 +546,7 @@ ScDPOutput::ScDPOutput( ScDocument* pD, const uno::Reference<sheet::XDimensionsS // get number formats from data dimensions if ( bIsDataLayout ) { + fprintf(stdout, "ScDPOutput::ScDPOutput: data layout\n"); if (bRowFieldHasMember) mbHasDataLayout = true; @@ -515,11 +562,14 @@ ScDPOutput::ScDPOutput( ScDocument* pD, const uno::Reference<sheet::XDimensionsS } else if ( bIsDataLayout ) { + fprintf(stdout, "ScDPOutput::ScDPOutput: hidden data layout\n"); // data layout dimension is hidden (allowed if there is only one data dimension) // -> use the number format from the first data dimension for all results nSingleNumFmt = lcl_GetFirstNumberFormat( xDims ); } + else + fprintf(stdout, "ScDPOutput::ScDPOutput: just hidden ?\n"); } } lcl_SortFields( pColFields, nColFieldCount ); @@ -717,6 +767,11 @@ void ScDPOutput::CalcSizes() // Insert an extra header row only when there is no column field. nHeaderSize = 2; + fprintf(stdout, "ScDPOutput::CalcSizes: header size = %d\n", nHeaderSize); + + fprintf(stdout, "ScDPOutput::CalcSizes: col fields = %d row fields = %d\n", + nColFieldCount, nRowFieldCount); + // calculate output positions and sizes long nPageSize = 0; //! use page fields! @@ -751,6 +806,9 @@ void ScDPOutput::CalcSizes() else nTabEndRow = nDataStartRow; // single row will remain empty bSizesValid = TRUE; + + fprintf(stdout, "ScDPOutput::CalcSizes: table size (col=%ld,row=%ld) - (col=%ld,row=%ld)\n", + nTabStartCol,nTabStartRow,nTabEndCol,nTabEndRow); } } diff --git a/sc/source/core/data/global2.cxx b/sc/source/core/data/global2.cxx index c9aaff566b15..7e8fabea60ba 100644 --- a/sc/source/core/data/global2.cxx +++ b/sc/source/core/data/global2.cxx @@ -29,8 +29,6 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sc.hxx" - - // INCLUDE --------------------------------------------------------------- #include <sfx2/docfile.hxx> @@ -62,9 +60,6 @@ using ::std::vector; // ----------------------------------------------------------------------- - - - //------------------------------------------------------------------------ // struct ScImportParam: @@ -98,7 +93,6 @@ ScImportParam::~ScImportParam() { } - ScImportParam& ScImportParam::operator=( const ScImportParam& r ) { nCol1 = r.nCol1; @@ -131,7 +125,6 @@ BOOL ScImportParam::operator==( const ScImportParam& rOther ) const //! nQuerySh und pConnection sind gleich ? } - //------------------------------------------------------------------------ // struct ScQueryParam: @@ -469,14 +462,14 @@ ScConsolidateParam::ScConsolidateParam( const ScConsolidateParam& r ) : //------------------------------------------------------------------------ -__EXPORT ScConsolidateParam::~ScConsolidateParam() +ScConsolidateParam::~ScConsolidateParam() { ClearDataAreas(); } //------------------------------------------------------------------------ -void __EXPORT ScConsolidateParam::ClearDataAreas() +void ScConsolidateParam::ClearDataAreas() { if ( ppDataAreas ) { @@ -490,7 +483,7 @@ void __EXPORT ScConsolidateParam::ClearDataAreas() //------------------------------------------------------------------------ -void __EXPORT ScConsolidateParam::Clear() +void ScConsolidateParam::Clear() { ClearDataAreas(); @@ -503,7 +496,7 @@ void __EXPORT ScConsolidateParam::Clear() //------------------------------------------------------------------------ -ScConsolidateParam& __EXPORT ScConsolidateParam::operator=( const ScConsolidateParam& r ) +ScConsolidateParam& ScConsolidateParam::operator=( const ScConsolidateParam& r ) { nCol = r.nCol; nRow = r.nRow; @@ -519,7 +512,7 @@ ScConsolidateParam& __EXPORT ScConsolidateParam::operator=( const ScConsolidateP //------------------------------------------------------------------------ -BOOL __EXPORT ScConsolidateParam::operator==( const ScConsolidateParam& r ) const +BOOL ScConsolidateParam::operator==( const ScConsolidateParam& r ) const { BOOL bEqual = (nCol == r.nCol) && (nRow == r.nRow) @@ -544,7 +537,7 @@ BOOL __EXPORT ScConsolidateParam::operator==( const ScConsolidateParam& r ) cons //------------------------------------------------------------------------ -void __EXPORT ScConsolidateParam::SetAreas( ScArea* const* ppAreas, USHORT nCount ) +void ScConsolidateParam::SetAreas( ScArea* const* ppAreas, USHORT nCount ) { ClearDataAreas(); if ( ppAreas && nCount > 0 ) @@ -565,6 +558,11 @@ PivotField::PivotField( SCsCOL nNewCol, USHORT nNewFuncMask ) : { } +PivotField::PivotField( const PivotField& r ) : + nCol(r.nCol), nFuncMask(r.nFuncMask), nFuncCount(r.nFuncCount), maFieldRef(r.maFieldRef) +{ +} + bool PivotField::operator==( const PivotField& r ) const { return (nCol == r.nCol) @@ -581,7 +579,6 @@ bool PivotField::operator==( const PivotField& r ) const ScPivotParam::ScPivotParam() : nCol(0), nRow(0), nTab(0), - nPageCount(0), nColCount(0), nRowCount(0), nDataCount(0), bIgnoreEmptyRows(FALSE), bDetectCategories(FALSE), bMakeTotalCol(TRUE), bMakeTotalRow(TRUE) { @@ -591,37 +588,32 @@ ScPivotParam::ScPivotParam() ScPivotParam::ScPivotParam( const ScPivotParam& r ) : nCol( r.nCol ), nRow( r.nRow ), nTab( r.nTab ), - nPageCount(0), nColCount(0), nRowCount(0), nDataCount(0), + maPageFields(r.maPageFields), + maColFields(r.maColFields), + maRowFields(r.maRowFields), + maDataFields(r.maDataFields), bIgnoreEmptyRows(r.bIgnoreEmptyRows), bDetectCategories(r.bDetectCategories), bMakeTotalCol(r.bMakeTotalCol), bMakeTotalRow(r.bMakeTotalRow) { - SetPivotArrays ( r.aPageArr, r.aColArr, r.aRowArr, r.aDataArr, - r.nPageCount, r.nColCount, r.nRowCount, r.nDataCount ); - SetLabelData(r.maLabelArray); } //------------------------------------------------------------------------ -__EXPORT ScPivotParam::~ScPivotParam() +ScPivotParam::~ScPivotParam() { } //------------------------------------------------------------------------ - -void __EXPORT ScPivotParam::ClearPivotArrays() +void ScPivotParam::ClearPivotArrays() { - memset( aPageArr, 0, PIVOT_MAXPAGEFIELD * sizeof(PivotField) ); - memset( aColArr, 0, PIVOT_MAXFIELD * sizeof(PivotField) ); - memset( aRowArr, 0, PIVOT_MAXFIELD * sizeof(PivotField) ); - memset( aDataArr, 0, PIVOT_MAXFIELD * sizeof(PivotField) ); - nPageCount = 0; - nColCount = 0; - nRowCount = 0; - nDataCount = 0; + maPageFields.clear(); + maColFields.clear(); + maRowFields.clear(); + maDataFields.clear(); } void ScPivotParam::SetLabelData(const vector<ScDPLabelDataRef>& r) @@ -639,34 +631,7 @@ void ScPivotParam::SetLabelData(const vector<ScDPLabelDataRef>& r) //------------------------------------------------------------------------ -void __EXPORT ScPivotParam::SetPivotArrays ( const PivotField* pPageArr, - const PivotField* pColArr, - const PivotField* pRowArr, - const PivotField* pDataArr, - SCSIZE nPageCnt, - SCSIZE nColCnt, - SCSIZE nRowCnt, - SCSIZE nDataCnt ) -{ - ClearPivotArrays(); - - if ( pPageArr && pColArr && pRowArr && pDataArr ) - { - nPageCount = (nPageCnt>PIVOT_MAXPAGEFIELD) ? PIVOT_MAXPAGEFIELD : nPageCnt; - nColCount = (nColCnt>PIVOT_MAXFIELD) ? PIVOT_MAXFIELD : nColCnt; - nRowCount = (nRowCnt>PIVOT_MAXFIELD) ? PIVOT_MAXFIELD : nRowCnt; - nDataCount = (nDataCnt>PIVOT_MAXFIELD) ? PIVOT_MAXFIELD : nDataCnt; - - memcpy( aPageArr, pPageArr, nPageCount * sizeof(PivotField) ); - memcpy( aColArr, pColArr, nColCount * sizeof(PivotField) ); - memcpy( aRowArr, pRowArr, nRowCount * sizeof(PivotField) ); - memcpy( aDataArr, pDataArr, nDataCount * sizeof(PivotField) ); - } -} - -//------------------------------------------------------------------------ - -ScPivotParam& __EXPORT ScPivotParam::operator=( const ScPivotParam& r ) +ScPivotParam& ScPivotParam::operator=( const ScPivotParam& r ) { nCol = r.nCol; nRow = r.nRow; @@ -676,15 +641,17 @@ ScPivotParam& __EXPORT ScPivotParam::operator=( const ScPivotParam& r ) bMakeTotalCol = r.bMakeTotalCol; bMakeTotalRow = r.bMakeTotalRow; - SetPivotArrays ( r.aPageArr, r.aColArr, r.aRowArr, r.aDataArr, - r.nPageCount, r.nColCount, r.nRowCount, r.nDataCount ); + maPageFields = r.maPageFields; + maColFields = r.maColFields; + maRowFields = r.maRowFields; + maDataFields = r.maDataFields; SetLabelData(r.maLabelArray); return *this; } //------------------------------------------------------------------------ -BOOL __EXPORT ScPivotParam::operator==( const ScPivotParam& r ) const +BOOL ScPivotParam::operator==( const ScPivotParam& r ) const { BOOL bEqual = (nCol == r.nCol) && (nRow == r.nRow) @@ -694,27 +661,10 @@ BOOL __EXPORT ScPivotParam::operator==( const ScPivotParam& r ) const && (bMakeTotalCol == r.bMakeTotalCol) && (bMakeTotalRow == r.bMakeTotalRow) && (maLabelArray.size() == r.maLabelArray.size()) - && (nPageCount == r.nPageCount) - && (nColCount == r.nColCount) - && (nRowCount == r.nRowCount) - && (nDataCount == r.nDataCount); - - if ( bEqual ) - { - SCSIZE i; - - for ( i=0; i<nPageCount && bEqual; i++ ) - bEqual = ( aPageArr[i] == r.aPageArr[i] ); - - for ( i=0; i<nColCount && bEqual; i++ ) - bEqual = ( aColArr[i] == r.aColArr[i] ); - - for ( i=0; i<nRowCount && bEqual; i++ ) - bEqual = ( aRowArr[i] == r.aRowArr[i] ); - - for ( i=0; i<nDataCount && bEqual; i++ ) - bEqual = ( aDataArr[i] == r.aDataArr[i] ); - } + && maPageFields == r.maPageFields + && maColFields == r.maColFields + && maRowFields == r.maRowFields + && maDataFields == r.maDataFields; return bEqual; } @@ -758,7 +708,7 @@ ScSolveParam::~ScSolveParam() //------------------------------------------------------------------------ -ScSolveParam& __EXPORT ScSolveParam::operator=( const ScSolveParam& r ) +ScSolveParam& ScSolveParam::operator=( const ScSolveParam& r ) { delete pStrTargetVal; @@ -790,7 +740,6 @@ BOOL ScSolveParam::operator==( const ScSolveParam& r ) const return bEqual; } - //------------------------------------------------------------------------ // struct ScTabOpParam @@ -832,7 +781,7 @@ ScTabOpParam& ScTabOpParam::operator=( const ScTabOpParam& r ) //------------------------------------------------------------------------ -BOOL __EXPORT ScTabOpParam::operator==( const ScTabOpParam& r ) const +BOOL ScTabOpParam::operator==( const ScTabOpParam& r ) const { return ( (aRefFormulaCell == r.aRefFormulaCell) && (aRefFormulaEnd == r.aRefFormulaEnd) @@ -874,7 +823,6 @@ String ScGlobal::GetAbsDocName( const String& rFileName, return aAbsName; } - String ScGlobal::GetDocTabName( const String& rFileName, const String& rTabName ) { diff --git a/sc/source/ui/Accessibility/AccessibleDataPilotControl.cxx b/sc/source/ui/Accessibility/AccessibleDataPilotControl.cxx index ea4865c91724..f4915eee443d 100644 --- a/sc/source/ui/Accessibility/AccessibleDataPilotControl.cxx +++ b/sc/source/ui/Accessibility/AccessibleDataPilotControl.cxx @@ -53,7 +53,7 @@ public: ScAccessibleDataPilotButton( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible>& rxParent, - ScDPFieldWindow* pDPFieldWindow, + ScDPFieldControlBase* pDPFieldWindow, sal_Int32 nIndex); virtual void Init(); @@ -146,14 +146,14 @@ protected: throw (::com::sun::star::uno::RuntimeException); private: - ScDPFieldWindow* mpDPFieldWindow; + ScDPFieldControlBase* mpDPFieldWindow; sal_Int32 mnIndex; }; //===== internal ======================================================== ScAccessibleDataPilotControl::ScAccessibleDataPilotControl( const uno::Reference<XAccessible>& rxParent, - ScDPFieldWindow* pDPFieldWindow) + ScDPFieldControlBase* pDPFieldWindow) : ScAccessibleContextBase(rxParent, AccessibleRole::GROUP_BOX), mpDPFieldWindow(pDPFieldWindow) @@ -381,7 +381,7 @@ sal_Int32 SAL_CALL ScAccessibleDataPilotControl::getBackground( ) sal_Int32 nColor(0); if (mpDPFieldWindow) { - if (mpDPFieldWindow->GetType() == TYPE_SELECT) + if (mpDPFieldWindow->GetFieldType() == TYPE_SELECT) { nColor = mpDPFieldWindow->GetSettings().GetStyleSettings().GetFaceColor().GetColor(); } @@ -527,7 +527,7 @@ Rectangle ScAccessibleDataPilotControl::GetBoundingBox(void) const ScAccessibleDataPilotButton::ScAccessibleDataPilotButton( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible>& rxParent, - ScDPFieldWindow* pDPFieldWindow, + ScDPFieldControlBase* pDPFieldWindow, sal_Int32 nIndex) : ScAccessibleContextBase(rxParent, AccessibleRole::PUSH_BUTTON), mpDPFieldWindow(pDPFieldWindow), diff --git a/sc/source/ui/dbgui/dpuiglobal.hxx b/sc/source/ui/dbgui/dpuiglobal.hxx new file mode 100644 index 000000000000..9312e07ddb2c --- /dev/null +++ b/sc/source/ui/dbgui/dpuiglobal.hxx @@ -0,0 +1,42 @@ +/* + * Version: MPL 1.1 / GPLv3+ / LGPLv3+ + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Initial Developer of the Original Code is + * Kohei Yoshida <kyoshida@novell.com> + * Portions created by the Initial Developer are Copyright (C) 2010 the + * Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 3 or later (the "GPLv3+"), or + * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"), + * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable + * instead of those above. + */ + +#ifndef __SC_DPUIGLOBAL_HXX__ +#define __SC_DPUIGLOBAL_HXX__ + +#define MAX_PAGEFIELDS 10 // maximum count of fields for page area + +#define OUTER_MARGIN_HOR 4 +#define OUTER_MARGIN_VER 4 +#define DATA_FIELD_BTN_GAP 4 // must be an even number +#define ROW_FIELD_BTN_GAP 2 // must be an even number +#define FIELD_BTN_WIDTH 81 +#define FIELD_BTN_HEIGHT 23 +#define SELECT_FIELD_BTN_SPACE 5 +#define FIELD_AREA_GAP 3 // gap between row/column/data/page areas + +#endif diff --git a/sc/source/ui/dbgui/fieldwnd.cxx b/sc/source/ui/dbgui/fieldwnd.cxx index 8c181959f049..e1865e2b3e5e 100644 --- a/sc/source/ui/dbgui/fieldwnd.cxx +++ b/sc/source/ui/dbgui/fieldwnd.cxx @@ -38,65 +38,73 @@ #include "fieldwnd.hxx" #include "pvlaydlg.hxx" -#include "pvglob.hxx" +#include "dpuiglobal.hxx" #include "AccessibleDataPilotControl.hxx" #include "scresid.hxx" #include "sc.hrc" -const size_t INVALID_INDEX = static_cast< size_t >( -1 ); +using ::rtl::OUString; +using ::std::vector; +using ::com::sun::star::uno::Reference; +using ::com::sun::star::uno::WeakReference; +using ::com::sun::star::accessibility::XAccessible; -//=================================================================== +#include <stdio.h> +#include <string> +#include <sys/time.h> -ScDPFieldWindow::ScDPFieldWindow( - ScDPLayoutDlg* pDialog, - const ResId& rResId, - ScDPFieldType eFieldType, - FixedText* pFtFieldCaption ) : - Control( pDialog, rResId ), - pDlg( pDialog ), - pFtCaption( pFtFieldCaption ), - eType( eFieldType ), - nFieldSelected( 0 ), - pAccessible( NULL ) -{ - Init(); - if (eType != TYPE_SELECT && pFtCaption) - aName = MnemonicGenerator::EraseAllMnemonicChars( pFtCaption->GetText() ); -} +namespace { -ScDPFieldWindow::ScDPFieldWindow( - ScDPLayoutDlg* pDialog, - const ResId& rResId, - ScDPFieldType eFieldType, - const String& rName ) : - Control( pDialog, rResId ), - aName(rName), - pDlg( pDialog ), - pFtCaption( NULL ), - eType( eFieldType ), - nFieldSelected( 0 ), - pAccessible( NULL ) +class StackPrinter { - Init(); -} +public: + explicit StackPrinter(const char* msg) : + msMsg(msg) + { + fprintf(stdout, "%s: --begin\n", msMsg.c_str()); + mfStartTime = getTime(); + } -void ScDPFieldWindow::Init() -{ - aWndRect = Rectangle( GetPosPixel(), GetSizePixel() ); - nFieldSize = (eType == TYPE_SELECT) ? PAGE_SIZE : ((eType == TYPE_PAGE) ? MAX_PAGEFIELDS : MAX_FIELDS); + ~StackPrinter() + { + double fEndTime = getTime(); + fprintf(stdout, "%s: --end (duration: %g sec)\n", msMsg.c_str(), (fEndTime-mfStartTime)); + } + + void printTime(int line) const + { + double fEndTime = getTime(); + fprintf(stdout, "%s: --(%d) (duration: %g sec)\n", msMsg.c_str(), line, (fEndTime-mfStartTime)); + } - if( pFtCaption ) +private: + double getTime() const { - Size aWinSize( aWndRect.GetSize() ); - Size aTextSize( GetTextWidth( pFtCaption->GetText() ), GetTextHeight() ); - aTextPos.X() = (aWinSize.Width() - aTextSize.Width()) / 2; - aTextPos.Y() = (aWinSize.Height() - aTextSize.Height()) / 2; + timeval tv; + gettimeofday(&tv, NULL); + return tv.tv_sec + tv.tv_usec / 1000000.0; } - GetStyleSettings(); + ::std::string msMsg; + double mfStartTime; +}; + } -__EXPORT ScDPFieldWindow::~ScDPFieldWindow() +const size_t INVALID_INDEX = static_cast<size_t>(-1); + +ScDPFieldControlBase::ScDPFieldControlBase( ScDPLayoutDlg* pParent, const ResId& rResId, FixedText* pCaption ) : + Control(pParent, rResId), + mpDlg(pParent), + mpCaption(pCaption), + mnFieldSelected(0), + pAccessible(NULL) +{ + if (pCaption) + maName = MnemonicGenerator::EraseAllMnemonicChars( pCaption->GetText() ); +} + +ScDPFieldControlBase::~ScDPFieldControlBase() { if (pAccessible) { @@ -106,134 +114,423 @@ __EXPORT ScDPFieldWindow::~ScDPFieldWindow() } } -//------------------------------------------------------------------- +void ScDPFieldControlBase::UseMnemonic() +{ + // Now the FixedText has its mnemonic char. Grab the text and hide the + // FixedText to be able to handle tabstop and mnemonics separately. + if (mpCaption) + { + SetText(mpCaption->GetText()); + mpCaption->Hide(); + } + + // after reading the mnemonics, tab stop style bits can be updated + UpdateStyle(); +} -void ScDPFieldWindow::GetStyleSettings() +OUString ScDPFieldControlBase::GetName() const { - const StyleSettings& rStyleSet = GetSettings().GetStyleSettings(); - aFaceColor = rStyleSet.GetFaceColor(); - aWinColor = rStyleSet.GetWindowColor(); - aTextColor = rStyleSet.GetButtonTextColor(); - aWinTextColor = rStyleSet.GetWindowTextColor(); + return maName; } -//------------------------------------------------------------------- +void ScDPFieldControlBase::SetName(const OUString& rName) +{ + maName = rName; +} -Point ScDPFieldWindow::GetFieldPosition( size_t nIndex ) const +bool ScDPFieldControlBase::IsExistingIndex( size_t nIndex ) const { - Point aPos; - switch( eType ) - { - case TYPE_PAGE: - aPos.X() = OWIDTH * (nIndex % (MAX_PAGEFIELDS / 2)); - aPos.Y() = OHEIGHT * (nIndex / (MAX_PAGEFIELDS / 2)); - break; - case TYPE_COL: - aPos.X() = OWIDTH * (nIndex % (MAX_FIELDS / 2)); - aPos.Y() = OHEIGHT * (nIndex / (MAX_FIELDS / 2)); - break; - case TYPE_ROW: - case TYPE_DATA: - aPos.X() = 0; - aPos.Y() = OHEIGHT * nIndex; - break; - case TYPE_SELECT: - aPos.X() = (OWIDTH + SSPACE) * (nIndex / LINE_SIZE); - aPos.Y() = (OHEIGHT + SSPACE) * (nIndex % LINE_SIZE); - break; + return nIndex < maFieldNames.size(); +} + +void ScDPFieldControlBase::AddField( const String& rText, size_t nNewIndex ) +{ + DBG_ASSERT( nNewIndex == maFieldNames.size(), "ScDPFieldWindow::AddField - invalid index" ); + if( IsValidIndex( nNewIndex ) ) + { + maFieldNames.push_back( FieldName( rText, true ) ); + if (pAccessible) + { + com::sun::star::uno::Reference < com::sun::star::accessibility::XAccessible > xTempAcc = xAccessible; + if (xTempAcc.is()) + pAccessible->AddField(nNewIndex); + else + pAccessible = NULL; + } } - return aPos; } -Size ScDPFieldWindow::GetFieldSize() const +bool ScDPFieldControlBase::AddField( const String& rText, const Point& rPos, size_t& rnIndex ) { - return Size( (eType == TYPE_DATA) ? GetSizePixel().Width() : OWIDTH, OHEIGHT ); + size_t nNewIndex = 0; + if( GetFieldIndex( rPos, nNewIndex ) ) + { + if( nNewIndex > maFieldNames.size() ) + nNewIndex = maFieldNames.size(); + + maFieldNames.insert( maFieldNames.begin() + nNewIndex, FieldName( rText, true ) ); + mnFieldSelected = nNewIndex; + ResetScrollBar(); + Redraw(); + rnIndex = nNewIndex; + + if (pAccessible) + { + com::sun::star::uno::Reference < com::sun::star::accessibility::XAccessible > xTempAcc = xAccessible; + if (xTempAcc.is()) + pAccessible->AddField(nNewIndex); + else + pAccessible = NULL; + } + + return true; + } + + return false; } -Point ScDPFieldWindow::GetLastPosition() const +bool ScDPFieldControlBase::AppendField(const String& rText, size_t& rnIndex) { - return OutputToScreenPixel( GetFieldPosition( nFieldSize - 1 ) ); + if (!IsValidIndex(maFieldNames.size())) + return false; + + maFieldNames.push_back(FieldName(rText, true)); + mnFieldSelected = maFieldNames.size() - 1; + ResetScrollBar(); + Redraw(); + + rnIndex = mnFieldSelected; + return true; } -bool ScDPFieldWindow::GetFieldIndex( const Point& rPos, size_t& rnIndex ) const +void ScDPFieldControlBase::DelField( size_t nDelIndex ) { - rnIndex = INVALID_INDEX; - if( (rPos.X() >= 0) && (rPos.Y() >= 0) ) + if ( IsExistingIndex(nDelIndex) ) { - switch( eType ) + if (pAccessible) // before decrement fieldcount { - case TYPE_ROW: - case TYPE_DATA: - rnIndex = rPos.Y() / OHEIGHT; - break; - case TYPE_PAGE: - { - size_t nRow = rPos.Y() / OHEIGHT; - size_t nCol = rPos.X() / OWIDTH; - rnIndex = nRow * MAX_PAGEFIELDS / 2 + nCol; - } - break; - case TYPE_COL: - { - size_t nRow = rPos.Y() / OHEIGHT; - size_t nCol = rPos.X() / OWIDTH; - rnIndex = nRow * MAX_FIELDS / 2 + nCol; - } - break; - case TYPE_SELECT: - { - size_t nRow = rPos.Y() / (OHEIGHT + SSPACE); - size_t nCol = rPos.X() / (OWIDTH + SSPACE); - // is not between controls? - if( (rPos.Y() % (OHEIGHT + SSPACE) < OHEIGHT) && (rPos.X() % (OWIDTH + SSPACE) < OWIDTH) ) - rnIndex = nCol * LINE_SIZE + nRow; - } - break; + com::sun::star::uno::Reference < com::sun::star::accessibility::XAccessible > xTempAcc = xAccessible; + if (xTempAcc.is()) + pAccessible->RemoveField(nDelIndex); + else + pAccessible = NULL; } + maFieldNames.erase( maFieldNames.begin() + nDelIndex ); + if (mnFieldSelected >= maFieldNames.size()) + mnFieldSelected = maFieldNames.size() - 1; + + ResetScrollBar(); + Redraw(); } - return IsValidIndex( rnIndex ); } -//------------------------------------------------------------------- +size_t ScDPFieldControlBase::GetFieldCount() const +{ + return maFieldNames.size(); +} -void ScDPFieldWindow::DrawBackground( OutputDevice& rDev ) +bool ScDPFieldControlBase::IsEmpty() const { - Point aPos0; - Size aSize( GetSizePixel() ); + return maFieldNames.empty(); +} - if ( eType == TYPE_SELECT ) +void ScDPFieldControlBase::ClearFields() +{ + com::sun::star::uno::Reference < com::sun::star::accessibility::XAccessible > xTempAcc = xAccessible; + if (!xTempAcc.is() && pAccessible) + pAccessible = NULL; + if (pAccessible) + for( size_t nIdx = maFieldNames.size(); nIdx > 0; --nIdx ) + pAccessible->RemoveField( nIdx - 1 ); + + maFieldNames.clear(); +} + +void ScDPFieldControlBase::SetFieldText( const String& rText, size_t nIndex ) +{ + if( IsExistingIndex( nIndex ) ) + { + maFieldNames[ nIndex ] = FieldName( rText, true ); + Redraw(); + + if (pAccessible) + { + com::sun::star::uno::Reference < com::sun::star::accessibility::XAccessible > xTempAcc = xAccessible; + if (xTempAcc.is()) + pAccessible->FieldNameChange(nIndex); + else + pAccessible = NULL; + } + } +} + +const String& ScDPFieldControlBase::GetFieldText( size_t nIndex ) const +{ + if( IsExistingIndex( nIndex ) ) + return maFieldNames[ nIndex ].first; + return EMPTY_STRING; +} + +void ScDPFieldControlBase::GetExistingIndex( const Point& rPos, size_t& rnIndex ) +{ + if( !maFieldNames.empty() && (GetFieldType() != TYPE_SELECT) && GetFieldIndex( rPos, rnIndex ) ) { - rDev.SetLineColor(); - rDev.SetFillColor( aFaceColor ); - rDev.DrawRect( Rectangle( aPos0, aSize ) ); + if( rnIndex >= maFieldNames.size() ) + rnIndex = maFieldNames.size() - 1; } else + rnIndex = 0; +} + +size_t ScDPFieldControlBase::GetSelectedField() const +{ + return mnFieldSelected; +} + +void ScDPFieldControlBase::SetSelectedField(size_t nSelected) +{ + mnFieldSelected = nSelected; +} + +vector<ScDPFieldControlBase::FieldName>& ScDPFieldControlBase::GetFieldNames() +{ + return maFieldNames; +} + +const vector<ScDPFieldControlBase::FieldName>& ScDPFieldControlBase::GetFieldNames() const +{ + return maFieldNames; +} + +void ScDPFieldControlBase::Paint( const Rectangle& /* rRect */ ) +{ + // #124828# hiding the caption is now done from StateChanged + Redraw(); +} + +void ScDPFieldControlBase::DataChanged( const DataChangedEvent& rDCEvt ) +{ + if( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_STYLE) ) { - rDev.SetLineColor( aWinTextColor ); - rDev.SetFillColor( aWinColor ); - rDev.DrawRect( Rectangle( aPos0, aSize ) ); + Redraw(); + } + Control::DataChanged( rDCEvt ); +} - rDev.SetTextColor( aWinTextColor ); +void ScDPFieldControlBase::MouseButtonDown( const MouseEvent& rMEvt ) +{ + if( rMEvt.IsLeft() ) + { + size_t nIndex = 0; + if( GetFieldIndex( rMEvt.GetPosPixel(), nIndex ) && IsExistingIndex( nIndex ) ) + { + GrabFocusWithSel( nIndex ); - /* Draw the caption text. This needs some special handling, because we - support hard line breaks here. This part will draw each line of the - text for itself. */ + if( rMEvt.GetClicks() == 1 ) + { + PointerStyle ePtr = mpDlg->NotifyMouseButtonDown( GetFieldType(), nIndex ); + CaptureMouse(); + SetPointer( Pointer( ePtr ) ); + } + else + mpDlg->NotifyDoubleClick( GetFieldType(), nIndex ); + } + } +} - xub_StrLen nTokenCnt = GetText().GetTokenCount( '\n' ); - long nY = (aSize.Height() - nTokenCnt * rDev.GetTextHeight()) / 2; - for( xub_StrLen nToken = 0, nStringIx = 0; nToken < nTokenCnt; ++nToken ) +void ScDPFieldControlBase::MouseButtonUp( const MouseEvent& rMEvt ) +{ + if( rMEvt.IsLeft() ) + { + if( rMEvt.GetClicks() == 1 ) { - String aLine( GetText().GetToken( 0, '\n', nStringIx ) ); - Point aLinePos( (aSize.Width() - rDev.GetCtrlTextWidth( aLine )) / 2, nY ); - rDev.DrawCtrlText( aLinePos, aLine ); - nY += rDev.GetTextHeight(); + mpDlg->NotifyMouseButtonUp( OutputToScreenPixel( rMEvt.GetPosPixel() ) ); + SetPointer( Pointer( POINTER_ARROW ) ); } + + if( IsMouseCaptured() ) + ReleaseMouse(); } } -void ScDPFieldWindow::DrawField( - OutputDevice& rDev, const Rectangle& rRect, FieldString& rText, bool bFocus ) +void ScDPFieldControlBase::MouseMove( const MouseEvent& rMEvt ) { + if( IsMouseCaptured() ) + { + PointerStyle ePtr = mpDlg->NotifyMouseMove( OutputToScreenPixel( rMEvt.GetPosPixel() ) ); + SetPointer( Pointer( ePtr ) ); + } + size_t nIndex = 0; + if( GetFieldIndex( rMEvt.GetPosPixel(), nIndex ) && IsShortenedText( nIndex ) ) + { + Point aPos = OutputToScreenPixel( rMEvt.GetPosPixel() ); + Rectangle aRect( aPos, GetSizePixel() ); + String aHelpText = GetFieldText(nIndex); + Help::ShowQuickHelp( this, aRect, aHelpText ); + } +} + +void ScDPFieldControlBase::KeyInput( const KeyEvent& rKEvt ) +{ + const KeyCode& rKeyCode = rKEvt.GetKeyCode(); + USHORT nCode = rKeyCode.GetCode(); + bool bKeyEvaluated = false; + + const FieldNames& rFields = GetFieldNames(); + if( rKeyCode.IsMod1() && (GetFieldType() != TYPE_SELECT) ) + { + bKeyEvaluated = true; + switch( nCode ) + { + case KEY_UP: MoveFieldRel( 0, -1 ); break; + case KEY_DOWN: MoveFieldRel( 0, 1 ); break; + case KEY_LEFT: MoveFieldRel( -1, 0 ); break; + case KEY_RIGHT: MoveFieldRel( 1, 0 ); break; + case KEY_HOME: MoveField( 0 ); break; + case KEY_END: MoveField( rFields.size() - 1 ); break; + default: bKeyEvaluated = false; + } + } + else + { + bKeyEvaluated = true; + switch( nCode ) + { + case KEY_UP: MoveSelection( nCode, 0, -1 ); break; + case KEY_DOWN: MoveSelection( nCode, 0, 1 ); break; + case KEY_LEFT: MoveSelection( nCode, -1, 0 ); break; + case KEY_RIGHT: MoveSelection( nCode, 1, 0 ); break; + case KEY_HOME: SetSelectionHome(); break; + case KEY_END: SetSelectionEnd(); break; + case KEY_DELETE: + mpDlg->NotifyRemoveField( GetFieldType(), mnFieldSelected ); break; + default: bKeyEvaluated = false; + } + } + + if (bKeyEvaluated) + { + ScrollToShowSelection(); + Redraw(); + } + else + Control::KeyInput( rKEvt ); +} + +void ScDPFieldControlBase::GetFocus() +{ + Control::GetFocus(); + Redraw(); + if( GetGetFocusFlags() & GETFOCUS_MNEMONIC ) // move field on shortcut + { + size_t nOldCount = GetFieldCount(); + mpDlg->NotifyMoveFieldToEnd( GetFieldType() ); + if (GetFieldCount() > nOldCount) + // Scroll to the end only when a new field is inserted. + ScrollToEnd(); + } + else // else change focus + mpDlg->NotifyFieldFocus( GetFieldType(), TRUE ); + + AccessibleSetFocus(true); +} + +void ScDPFieldControlBase::LoseFocus() +{ + Control::LoseFocus(); + Redraw(); + mpDlg->NotifyFieldFocus( GetFieldType(), FALSE ); + + AccessibleSetFocus(false); +} + +Reference<XAccessible> ScDPFieldControlBase::CreateAccessible() +{ + pAccessible = + new ScAccessibleDataPilotControl(GetAccessibleParentWindow()->GetAccessible(), this); + + com::sun::star::uno::Reference < ::com::sun::star::accessibility::XAccessible > xReturn = pAccessible; + + pAccessible->Init(); + xAccessible = xReturn; + + return xReturn; +} + +void ScDPFieldControlBase::FieldFocusChanged(size_t nOldSelected, size_t nFieldSelected) +{ + if (!pAccessible) + return; + + com::sun::star::uno::Reference < com::sun::star::accessibility::XAccessible > xTempAcc = xAccessible; + if (xTempAcc.is()) + pAccessible->FieldFocusChange(nOldSelected, nFieldSelected); + else + pAccessible = NULL; +} + +void ScDPFieldControlBase::AccessibleSetFocus(bool bOn) +{ + if (!pAccessible) + return; + + com::sun::star::uno::Reference < com::sun::star::accessibility::XAccessible > xTempAcc = xAccessible; + if (!xTempAcc.is()) + { + pAccessible = NULL; + return; + } + + if (bOn) + pAccessible->GotFocus(); + else + pAccessible->LostFocus(); +} + +void ScDPFieldControlBase::UpdateStyle() +{ + WinBits nMask = ~(WB_TABSTOP | WB_NOTABSTOP); + SetStyle( (GetStyle() & nMask) | (IsEmpty() ? WB_NOTABSTOP : WB_TABSTOP) ); +} + +void ScDPFieldControlBase::DrawBackground( OutputDevice& rDev ) +{ + const StyleSettings& rStyleSet = GetSettings().GetStyleSettings(); + Color aFaceColor = rStyleSet.GetFaceColor(); + Color aWinColor = rStyleSet.GetWindowColor(); + Color aTextColor = rStyleSet.GetButtonTextColor(); + Color aWinTextColor = rStyleSet.GetWindowTextColor(); + + Point aPos0; + Size aSize( GetSizePixel() ); + + rDev.SetLineColor( aWinTextColor ); + rDev.SetFillColor( aWinColor ); + rDev.DrawRect( Rectangle( aPos0, aSize ) ); + + rDev.SetTextColor( aWinTextColor ); + + /* Draw the caption text. This needs some special handling, because we + support hard line breaks here. This part will draw each line of the + text for itself. */ + + xub_StrLen nTokenCnt = GetText().GetTokenCount('\n'); + long nY = (aSize.Height() - nTokenCnt * rDev.GetTextHeight()) / 2; + for( xub_StrLen nToken = 0, nStringIx = 0; nToken < nTokenCnt; ++nToken ) + { + String aLine( GetText().GetToken( 0, '\n', nStringIx ) ); + Point aLinePos( (aSize.Width() - rDev.GetCtrlTextWidth( aLine )) / 2, nY ); + rDev.DrawCtrlText( aLinePos, aLine ); + nY += rDev.GetTextHeight(); + } +} + +void ScDPFieldControlBase::DrawField( + OutputDevice& rDev, const Rectangle& rRect, FieldName& rText, bool bFocus ) +{ + const StyleSettings& rStyleSet = GetSettings().GetStyleSettings(); + Color aTextColor = rStyleSet.GetButtonTextColor(); + VirtualDevice aVirDev( rDev ); // #i97623# VirtualDevice is always LTR while other windows derive direction from parent aVirDev.EnableRTL( IsRTLEnabled() ); @@ -273,142 +570,122 @@ void ScDPFieldWindow::DrawField( rDev.DrawBitmap( rRect.TopLeft(), aVirDev.GetBitmap( Point( 0, 0 ), aDevSize ) ); } -void ScDPFieldWindow::Redraw() +ScDPLayoutDlg* ScDPFieldControlBase::GetParentDlg() const { - VirtualDevice aVirDev; - // #i97623# VirtualDevice is always LTR while other windows derive direction from parent - aVirDev.EnableRTL( IsRTLEnabled() ); - aVirDev.SetMapMode( MAP_PIXEL ); - - Point aPos0; - Size aSize( GetSizePixel() ); - Font aFont( GetFont() ); // Font vom Window - aFont.SetTransparent( TRUE ); - aVirDev.SetFont( aFont ); - aVirDev.SetOutputSizePixel( aSize ); + return mpDlg; +} - DrawBackground( aVirDev ); +void ScDPFieldControlBase::AppendPaintable(Window* p) +{ + maPaintables.push_back(p); +} - if( !aFieldArr.empty() && (nFieldSelected >= aFieldArr.size()) ) - nFieldSelected = aFieldArr.size() - 1; - Rectangle aFieldRect( aPos0, GetFieldSize() ); - for( size_t nIx = 0; nIx < aFieldArr.size(); ++nIx ) +void ScDPFieldControlBase::DrawPaintables() +{ + Rectangle aRect(GetPosPixel(), GetSizePixel()); + Paintables::iterator itr = maPaintables.begin(), itrEnd = maPaintables.end(); + for (; itr != itrEnd; ++itr) { - aFieldRect.SetPos( GetFieldPosition( nIx ) ); - bool bFocus = HasFocus() && (nIx == nFieldSelected); - DrawField( aVirDev, aFieldRect, aFieldArr[ nIx ], bFocus ); - } - DrawBitmap( aPos0, aVirDev.GetBitmap( aPos0, aSize ) ); + Window* p = *itr; + if (!p->IsVisible()) + continue; - if( HasFocus() && (nFieldSelected < aFieldArr.size()) ) - { - long nFieldWidth = aFieldRect.GetWidth(); - long nSelectionWidth = Min( GetTextWidth( aFieldArr[ nFieldSelected ].first ) + 4, nFieldWidth - 6 ); - Rectangle aSelection( - GetFieldPosition( nFieldSelected ) + Point( (nFieldWidth - nSelectionWidth) / 2, 3 ), - Size( nSelectionWidth, aFieldRect.GetHeight() - 6 ) ); - InvertTracking( aSelection, SHOWTRACK_SMALL | SHOWTRACK_WINDOW ); + p->Paint(aRect); } - - UpdateStyle(); } -void ScDPFieldWindow::UpdateStyle() +void ScDPFieldControlBase::DrawInvertSelection() { - WinBits nMask = ~(WB_TABSTOP | WB_NOTABSTOP); - SetStyle( (GetStyle() & nMask) | (IsEmpty() ? WB_NOTABSTOP : WB_TABSTOP) ); -} + if (!HasFocus()) + return; -//------------------------------------------------------------------- + if (mnFieldSelected >= maFieldNames.size()) + return; -bool ScDPFieldWindow::IsValidIndex( size_t nIndex ) const -{ - return nIndex < nFieldSize; -} + size_t nPos = GetDisplayPosition(mnFieldSelected); + if (nPos == INVALID_INDEX) + return; -bool ScDPFieldWindow::IsExistingIndex( size_t nIndex ) const -{ - return nIndex < aFieldArr.size(); + Size aFldSize = GetFieldSize(); + long nFldWidth = aFldSize.Width(); + long nSelWidth = std::min<long>( + GetTextWidth(maFieldNames[mnFieldSelected].first) + 4, nFldWidth - 6); + + Point aPos = GetFieldPosition(nPos); + aPos += Point((nFldWidth - nSelWidth) / 2, 3); + Size aSize(nSelWidth, aFldSize.Height() - 6); + + Rectangle aSel(aPos, aSize); + InvertTracking(aSel, SHOWTRACK_SMALL | SHOWTRACK_WINDOW); } -bool ScDPFieldWindow::IsShortenedText( size_t nIndex ) const +bool ScDPFieldControlBase::IsShortenedText( size_t nIndex ) const { - return (nIndex < aFieldArr.size()) && !aFieldArr[ nIndex ].second; + const FieldNames& rFields = GetFieldNames(); + return (nIndex < rFields.size()) && !rFields[nIndex].second; } -size_t ScDPFieldWindow::CalcNewFieldIndex( SCsCOL nDX, SCsROW nDY ) const +void ScDPFieldControlBase::MoveField( size_t nDestIndex ) { - size_t nNewField = nFieldSelected; - switch( eType ) + if (nDestIndex != mnFieldSelected) { - case TYPE_PAGE: - nNewField += static_cast<SCsCOLROW>(nDX) + nDY * MAX_PAGEFIELDS / 2; - break; - case TYPE_COL: - nNewField += static_cast<SCsCOLROW>(nDX) + nDY * MAX_FIELDS / 2; - break; - case TYPE_ROW: - case TYPE_DATA: - nNewField += nDY; - break; - case TYPE_SELECT: - nNewField += static_cast<SCsCOLROW>(nDX) * LINE_SIZE + nDY; - break; + swap(maFieldNames[nDestIndex], maFieldNames[mnFieldSelected]); + mnFieldSelected = nDestIndex; } +} - return IsExistingIndex( nNewField ) ? nNewField : nFieldSelected; +void ScDPFieldControlBase::MoveFieldRel( SCsCOL nDX, SCsROW nDY ) +{ + MoveField( CalcNewFieldIndex( nDX, nDY ) ); } -void ScDPFieldWindow::SetSelection( size_t nIndex ) +void ScDPFieldControlBase::SetSelection(size_t nIndex) { - if( !aFieldArr.empty() ) + FieldNames& rFields = GetFieldNames(); + if (rFields.empty()) + return; + + if( mnFieldSelected >= rFields.size() ) + mnFieldSelected = rFields.size() - 1; + if( mnFieldSelected != nIndex ) { - if( nFieldSelected >= aFieldArr.size() ) - nFieldSelected = aFieldArr.size() - 1; - if( nFieldSelected != nIndex ) - { - sal_Int32 nOldSelected(nFieldSelected); - nFieldSelected = nIndex; - Redraw(); + size_t nOldSelected = mnFieldSelected; + mnFieldSelected = nIndex; + Redraw(); - if (pAccessible && HasFocus()) - { - com::sun::star::uno::Reference < com::sun::star::accessibility::XAccessible > xTempAcc = xAccessible; - if (xTempAcc.is()) - pAccessible->FieldFocusChange(nOldSelected, nFieldSelected); - else - pAccessible = NULL; - } - } + if (HasFocus()) + FieldFocusChanged(nOldSelected, mnFieldSelected); } } -void ScDPFieldWindow::SetSelectionHome() +void ScDPFieldControlBase::SetSelectionHome() { - if( !aFieldArr.empty() ) + const FieldNames& rFields = GetFieldNames(); + if( !rFields.empty() ) { - if( eType == TYPE_SELECT ) - pDlg->NotifyMoveSlider( KEY_HOME ); + if( GetFieldType() == TYPE_SELECT ) + mpDlg->NotifyMoveSlider( KEY_HOME ); SetSelection( 0 ); } } -void ScDPFieldWindow::SetSelectionEnd() +void ScDPFieldControlBase::SetSelectionEnd() { - if( !aFieldArr.empty() ) + const FieldNames& rFields = GetFieldNames(); + if( !rFields.empty() ) { - if( eType == TYPE_SELECT ) - pDlg->NotifyMoveSlider( KEY_END ); - SetSelection( aFieldArr.size() - 1 ); + if( GetFieldType() == TYPE_SELECT ) + mpDlg->NotifyMoveSlider( KEY_END ); + SetSelection( rFields.size() - 1 ); } } -void ScDPFieldWindow::MoveSelection( USHORT nKeyCode, SCsCOL nDX, SCsROW nDY ) +void ScDPFieldControlBase::MoveSelection( USHORT nKeyCode, SCsCOL nDX, SCsROW nDY ) { size_t nNewIndex = CalcNewFieldIndex( nDX, nDY ); - if( (eType == TYPE_SELECT) && (nNewIndex == nFieldSelected) ) + if( (GetFieldType() == TYPE_SELECT) && (nNewIndex == GetSelectedField()) ) { - if( pDlg->NotifyMoveSlider( nKeyCode ) ) + if( mpDlg->NotifyMoveSlider( nKeyCode ) ) { switch( nKeyCode ) { @@ -420,359 +697,986 @@ void ScDPFieldWindow::MoveSelection( USHORT nKeyCode, SCsCOL nDX, SCsROW nDY ) SetSelection( nNewIndex ); } -void ScDPFieldWindow::ModifySelectionOffset( long nOffsetDiff ) +void ScDPFieldControlBase::ModifySelectionOffset( long nOffsetDiff ) { - nFieldSelected -= nOffsetDiff; + mnFieldSelected -= nOffsetDiff; Redraw(); } -void ScDPFieldWindow::SelectNext() +void ScDPFieldControlBase::SelectNext() { - if( eType == TYPE_SELECT ) + if( GetFieldType() == TYPE_SELECT ) MoveSelection( KEY_DOWN, 0, 1 ); } -void ScDPFieldWindow::GrabFocusWithSel( size_t nIndex ) +void ScDPFieldControlBase::GrabFocusWithSel( size_t nIndex ) { SetSelection( nIndex ); if( !HasFocus() ) GrabFocus(); } -void ScDPFieldWindow::MoveField( size_t nDestIndex ) +//============================================================================= + +ScDPHorFieldControl::ScDPHorFieldControl( + ScDPLayoutDlg* pDialog, const ResId& rResId, FixedText* pCaption) : + ScDPFieldControlBase(pDialog, rResId, pCaption), + maScroll(this, WB_HORZ | WB_DRAG), + mnFieldBtnRowCount(0), + mnFieldBtnColCount(0) { - if( nDestIndex != nFieldSelected ) - { - // "recycle" existing functionality - pDlg->NotifyMouseButtonDown( eType, nFieldSelected ); - pDlg->NotifyMouseButtonUp( OutputToScreenPixel( GetFieldPosition( nDestIndex ) ) ); - } + maScroll.SetScrollHdl( LINK(this, ScDPHorFieldControl, ScrollHdl) ); + maScroll.SetEndScrollHdl( LINK(this, ScDPHorFieldControl, EndScrollHdl) ); + maScroll.Show(); + + AppendPaintable(&maScroll); } -void ScDPFieldWindow::MoveFieldRel( SCsCOL nDX, SCsROW nDY ) +ScDPHorFieldControl::~ScDPHorFieldControl() { - MoveField( CalcNewFieldIndex( nDX, nDY ) ); } -//------------------------------------------------------------------- +Point ScDPHorFieldControl::GetFieldPosition( size_t nIndex ) +{ + Point aPos; + Size aSize; + GetFieldBtnPosSize(nIndex, aPos, aSize); + return aPos; +} -void __EXPORT ScDPFieldWindow::Paint( const Rectangle& /* rRect */ ) +Size ScDPHorFieldControl::GetFieldSize() const { - // #124828# hiding the caption is now done from StateChanged - Redraw(); + return Size(FIELD_BTN_WIDTH, FIELD_BTN_HEIGHT); } -void ScDPFieldWindow::UseMnemonic() +bool ScDPHorFieldControl::GetFieldIndex( const Point& rPos, size_t& rnIndex ) { - // Now the FixedText has its mnemonic char. Grab the text and hide the - // FixedText to be able to handle tabstop and mnemonics separately. - if( pFtCaption ) + rnIndex = INVALID_INDEX; + if (rPos.X() < 0 || rPos.Y() < 0) + return false; + + Size aWndSize = GetSizePixel(); + if (rPos.X() > aWndSize.Width() || rPos.Y() > aWndSize.Height()) + return false; + + size_t nX = rPos.X(); + size_t nY = rPos.Y(); + size_t nW = aWndSize.Width(); + size_t nH = aWndSize.Height(); + + size_t nCurX = OUTER_MARGIN_HOR + FIELD_BTN_WIDTH + ROW_FIELD_BTN_GAP/2; + size_t nCurY = OUTER_MARGIN_VER + FIELD_BTN_HEIGHT + ROW_FIELD_BTN_GAP/2; + size_t nCol = 0; + size_t nRow = 0; + while (nX > nCurX && nCurX <= nW) { - SetText( pFtCaption->GetText() ); - pFtCaption->Hide(); + nCurX += FIELD_BTN_WIDTH + ROW_FIELD_BTN_GAP; + ++nCol; + } + while (nY > nCurY && nCurY <= nH) + { + nCurY += FIELD_BTN_HEIGHT + ROW_FIELD_BTN_GAP; + ++nRow; } - // after reading the mnemonics, tab stop style bits can be updated - UpdateStyle(); + size_t nOffset = maScroll.GetThumbPos(); + nCol += nOffset; // convert to logical column ID. + rnIndex = nCol * mnFieldBtnRowCount + nRow; + size_t nFldCount = GetFieldCount(); + if (rnIndex > nFldCount) + rnIndex = nFldCount; + return IsValidIndex(rnIndex); } -void __EXPORT ScDPFieldWindow::DataChanged( const DataChangedEvent& rDCEvt ) +void ScDPHorFieldControl::Redraw() { - if( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_STYLE) ) + const StyleSettings& rStyleSet = GetSettings().GetStyleSettings(); + Color aFaceColor = rStyleSet.GetFaceColor(); + Color aWinColor = rStyleSet.GetWindowColor(); + Color aTextColor = rStyleSet.GetButtonTextColor(); + Color aWinTextColor = rStyleSet.GetWindowTextColor(); + + VirtualDevice aVirDev; + // #i97623# VirtualDevice is always LTR while other windows derive direction from parent + aVirDev.EnableRTL( IsRTLEnabled() ); + aVirDev.SetMapMode( MAP_PIXEL ); + + Point aPos0; + Size aSize( GetSizePixel() ); + Font aFont( GetFont() ); // Font vom Window + aFont.SetTransparent( TRUE ); + aVirDev.SetFont( aFont ); + aVirDev.SetOutputSizePixel( aSize ); + + DrawBackground( aVirDev ); + + FieldNames& rFields = GetFieldNames(); { - GetStyleSettings(); - Redraw(); + long nScrollOffset = maScroll.GetThumbPos(); + FieldNames::iterator itr = rFields.begin(), itrEnd = rFields.end(); + if (nScrollOffset) + ::std::advance(itr, nScrollOffset*mnFieldBtnRowCount); + + for (size_t i = 0; itr != itrEnd; ++itr, ++i) + { + Point aFldPt; + Size aFldSize; + if (!GetFieldBtnPosSize(i, aFldPt, aFldSize)) + break; + + size_t nField = i + nScrollOffset*mnFieldBtnRowCount; + bool bFocus = HasFocus() && (nField == GetSelectedField()); + DrawField(aVirDev, Rectangle(aFldPt, aFldSize), *itr, bFocus); + } } - Control::DataChanged( rDCEvt ); + + DrawBitmap( aPos0, aVirDev.GetBitmap( aPos0, aSize ) ); + DrawPaintables(); + DrawInvertSelection(); + UpdateStyle(); } -void __EXPORT ScDPFieldWindow::MouseButtonDown( const MouseEvent& rMEvt ) +void ScDPHorFieldControl::CalcSize() { - if( rMEvt.IsLeft() ) - { - size_t nIndex = 0; - if( GetFieldIndex( rMEvt.GetPosPixel(), nIndex ) && IsExistingIndex( nIndex ) ) - { - GrabFocusWithSel( nIndex ); + Size aWndSize = GetSizePixel(); - if( rMEvt.GetClicks() == 1 ) - { - PointerStyle ePtr = pDlg->NotifyMouseButtonDown( eType, nIndex ); - CaptureMouse(); - SetPointer( Pointer( ePtr ) ); - } - else - pDlg->NotifyDoubleClick( eType, nIndex ); - } - } + long nScrollSize = GetSettings().GetStyleSettings().GetScrollBarSize(); + maScroll.SetSizePixel(Size(aWndSize.Width() - OUTER_MARGIN_HOR*2, nScrollSize)); + maScroll.SetPosPixel(Point(OUTER_MARGIN_HOR, aWndSize.Height() - OUTER_MARGIN_VER - nScrollSize)); + + long nTotalH = aWndSize.Height() - nScrollSize - OUTER_MARGIN_VER*2; + long nTotalW = aWndSize.Width() - OUTER_MARGIN_HOR*2; + mnFieldBtnRowCount = nTotalH / (FIELD_BTN_HEIGHT + ROW_FIELD_BTN_GAP); + mnFieldBtnColCount = (nTotalW + ROW_FIELD_BTN_GAP) / (FIELD_BTN_WIDTH + ROW_FIELD_BTN_GAP); + + maScroll.SetLineSize(mnFieldBtnRowCount); + maScroll.SetVisibleSize(mnFieldBtnColCount); + maScroll.SetPageSize(mnFieldBtnColCount); + maScroll.SetRange(Range(0, mnFieldBtnColCount)); } -void __EXPORT ScDPFieldWindow::MouseButtonUp( const MouseEvent& rMEvt ) +bool ScDPHorFieldControl::IsValidIndex(size_t /*nIndex*/) const { - if( rMEvt.IsLeft() ) - { - if( rMEvt.GetClicks() == 1 ) - { - pDlg->NotifyMouseButtonUp( OutputToScreenPixel( rMEvt.GetPosPixel() ) ); - SetPointer( Pointer( POINTER_ARROW ) ); - } + return true; +} - if( IsMouseCaptured() ) - ReleaseMouse(); - } +size_t ScDPHorFieldControl::CalcNewFieldIndex(SCsCOL nDX, SCsROW nDY) const +{ + size_t nSel = GetSelectedField(); + size_t nFldCount = GetFieldCount(); + SCsROW nRow = nSel % mnFieldBtnRowCount; + SCsCOL nCol = nSel / mnFieldBtnRowCount; + SCsCOL nColUpper = ceil( + static_cast<double>(nFldCount) / static_cast<double>(mnFieldBtnRowCount)) - 1; + SCsROW nRowUpper = mnFieldBtnRowCount - 1; + + nCol += nDX; + if (nCol < 0) + nCol = 0; + else if (nColUpper < nCol) + nCol = nColUpper; + nRow += nDY; + if (nRow < 0) + nRow = 0; + else if (nRowUpper < nRow) + nRow = nRowUpper; + + nSel = nCol*mnFieldBtnRowCount + nRow; + if (nSel >= nFldCount) + nSel = nFldCount - 1; + + return nSel; } -void __EXPORT ScDPFieldWindow::MouseMove( const MouseEvent& rMEvt ) +size_t ScDPHorFieldControl::GetDisplayPosition(size_t nIndex) const { - if( IsMouseCaptured() ) + size_t nColFirst = maScroll.GetThumbPos(); + size_t nColLast = nColFirst + mnFieldBtnColCount - 1; + size_t nCol = nIndex / mnFieldBtnRowCount; + size_t nRow = nIndex % mnFieldBtnRowCount; + if (nCol < nColFirst || nColLast < nCol) + // index is outside the visible area. + return INVALID_INDEX; + + size_t nPos = (nCol - nColFirst)*mnFieldBtnRowCount + nRow; + return nPos; +} + +String ScDPHorFieldControl::GetDescription() const +{ + return ScResId(STR_ACC_DATAPILOT_COL_DESCR); +} + +void ScDPHorFieldControl::ScrollToEnd() +{ + maScroll.DoScroll(maScroll.GetRangeMax()); +} + +void ScDPHorFieldControl::ScrollToShowSelection() +{ + size_t nLower = maScroll.GetThumbPos(); + size_t nUpper = nLower + mnFieldBtnColCount - 1; + size_t nCol = GetSelectedField() / mnFieldBtnRowCount; + if (nCol < nLower) { - PointerStyle ePtr = pDlg->NotifyMouseMove( OutputToScreenPixel( rMEvt.GetPosPixel() ) ); - SetPointer( Pointer( ePtr ) ); + // scroll to left. + maScroll.DoScroll(nCol); } - size_t nIndex = 0; - if( GetFieldIndex( rMEvt.GetPosPixel(), nIndex ) && IsShortenedText( nIndex ) ) + else if (nUpper < nCol) { - Point aPos = OutputToScreenPixel( rMEvt.GetPosPixel() ); - Rectangle aRect( aPos, GetSizePixel() ); - String aHelpText = GetFieldText(nIndex); - Help::ShowQuickHelp( this, aRect, aHelpText ); + // scroll to right. + maScroll.DoScroll(nCol - mnFieldBtnColCount + 1); } } -void __EXPORT ScDPFieldWindow::KeyInput( const KeyEvent& rKEvt ) +void ScDPHorFieldControl::ResetScrollBar() { - const KeyCode& rKeyCode = rKEvt.GetKeyCode(); - USHORT nCode = rKeyCode.GetCode(); - BOOL bKeyEvaluated = FALSE; + long nOldMax = maScroll.GetRangeMax(); + long nNewMax = ceil( + static_cast<double>(GetFieldCount()) / static_cast<double>(mnFieldBtnRowCount)); + + if (nOldMax != nNewMax) + maScroll.SetRangeMax(nNewMax); +} + +bool ScDPHorFieldControl::GetFieldBtnPosSize(size_t nPos, Point& rPos, Size& rSize) +{ + if (nPos >= mnFieldBtnColCount*mnFieldBtnRowCount) + return false; + + Point aPos = Point(OUTER_MARGIN_HOR, OUTER_MARGIN_VER); + size_t nRow = nPos % mnFieldBtnRowCount; + size_t nCol = nPos / mnFieldBtnRowCount; + + aPos.X() += nCol*(FIELD_BTN_WIDTH + ROW_FIELD_BTN_GAP); + aPos.Y() += nRow*(FIELD_BTN_HEIGHT + ROW_FIELD_BTN_GAP); + + rPos = aPos; + rSize = Size(FIELD_BTN_WIDTH, FIELD_BTN_HEIGHT); + return true; +} + +void ScDPHorFieldControl::HandleScroll() +{ + Redraw(); +} + +IMPL_LINK(ScDPHorFieldControl, ScrollHdl, ScrollBar*, EMPTYARG) +{ + HandleScroll(); + return 0; +} + +IMPL_LINK(ScDPHorFieldControl, EndScrollHdl, ScrollBar*, EMPTYARG) +{ + HandleScroll(); + return 0; +} + +//============================================================================= + +ScDPPageFieldControl::ScDPPageFieldControl( + ScDPLayoutDlg* pDialog, const ResId& rResId, FixedText* pCaption) : + ScDPHorFieldControl(pDialog, rResId, pCaption) +{ +} + +ScDPPageFieldControl::~ScDPPageFieldControl() +{ +} + +ScDPFieldType ScDPPageFieldControl::GetFieldType() const +{ + return TYPE_PAGE; +} + +//============================================================================= + +ScDPColFieldControl::ScDPColFieldControl( + ScDPLayoutDlg* pDialog, const ResId& rResId, FixedText* pCaption) : + ScDPHorFieldControl(pDialog, rResId, pCaption) +{ +} + +ScDPColFieldControl::~ScDPColFieldControl() +{ +} + +ScDPFieldType ScDPColFieldControl::GetFieldType() const +{ + return TYPE_COL; +} - if( rKeyCode.IsMod1() && (eType != TYPE_SELECT) ) +//============================================================================= + +ScDPRowFieldControl::ScDPRowFieldControl( + ScDPLayoutDlg* pDialog, const ResId& rResId, FixedText* pCaption ) : + ScDPFieldControlBase( pDialog, rResId, pCaption ), + maScroll(this, WB_VERT | WB_DRAG), + mnColumnBtnCount(0) +{ + maScroll.SetScrollHdl( LINK(this, ScDPRowFieldControl, ScrollHdl) ); + maScroll.SetEndScrollHdl( LINK(this, ScDPRowFieldControl, EndScrollHdl) ); + maScroll.Show(); + + AppendPaintable(&maScroll); +} + +ScDPRowFieldControl::~ScDPRowFieldControl() +{ +} + +//------------------------------------------------------------------- + +Point ScDPRowFieldControl::GetFieldPosition(size_t nIndex) +{ + Point aPos; + Size aSize; + GetFieldBtnPosSize(nIndex, aPos, aSize); + return aPos; +} + +Size ScDPRowFieldControl::GetFieldSize() const +{ + return Size(FIELD_BTN_WIDTH, FIELD_BTN_HEIGHT); +} + +bool ScDPRowFieldControl::GetFieldIndex( const Point& rPos, size_t& rnIndex ) +{ + rnIndex = INVALID_INDEX; + if (rPos.X() < 0 || rPos.Y() < 0) + return false; + + rnIndex = rPos.Y() / FIELD_BTN_HEIGHT + maScroll.GetThumbPos(); + return IsValidIndex(rnIndex); +} + +void ScDPRowFieldControl::Redraw() +{ + VirtualDevice aVirDev; + // #i97623# VirtualDevice is always LTR while other windows derive direction from parent + aVirDev.EnableRTL( IsRTLEnabled() ); + aVirDev.SetMapMode( MAP_PIXEL ); + + Point aPos0; + Size aWndSize = GetSizePixel(); + Font aFont = GetFont(); + aFont.SetTransparent(true); + aVirDev.SetFont(aFont); + aVirDev.SetOutputSizePixel(aWndSize); + + DrawBackground(aVirDev); + + FieldNames& rFields = GetFieldNames(); { - bKeyEvaluated = TRUE; - switch( nCode ) + long nScrollOffset = maScroll.GetThumbPos(); + FieldNames::iterator itr = rFields.begin(), itrEnd = rFields.end(); + if (nScrollOffset) + ::std::advance(itr, nScrollOffset); + + for (size_t i = 0; itr != itrEnd; ++itr, ++i) { - case KEY_UP: MoveFieldRel( 0, -1 ); break; - case KEY_DOWN: MoveFieldRel( 0, 1 ); break; - case KEY_LEFT: MoveFieldRel( -1, 0 ); break; - case KEY_RIGHT: MoveFieldRel( 1, 0 ); break; - case KEY_HOME: MoveField( 0 ); break; - case KEY_END: MoveField( aFieldArr.size() - 1 ); break; - default: bKeyEvaluated = FALSE; + Point aFldPt; + Size aFldSize; + if (!GetFieldBtnPosSize(i, aFldPt, aFldSize)) + break; + + size_t nField = i + nScrollOffset; + bool bFocus = HasFocus() && (nField == GetSelectedField()); + DrawField(aVirDev, Rectangle(aFldPt, aFldSize), *itr, bFocus); } } - else + + // Create a bitmap from the virtual device, and place that bitmap onto + // this control. + DrawBitmap(aPos0, aVirDev.GetBitmap(aPos0, aWndSize)); + + DrawPaintables(); + DrawInvertSelection(); + UpdateStyle(); +} + +void ScDPRowFieldControl::CalcSize() +{ + Size aWndSize = GetSizePixel(); + + long nTotal = aWndSize.Height() - OUTER_MARGIN_VER; + mnColumnBtnCount = nTotal / (FIELD_BTN_HEIGHT + ROW_FIELD_BTN_GAP); + + long nScrollSize = GetSettings().GetStyleSettings().GetScrollBarSize(); + + maScroll.SetSizePixel(Size(nScrollSize, aWndSize.Height() - OUTER_MARGIN_VER*2)); + maScroll.SetPosPixel(Point(aWndSize.Width() - nScrollSize - OUTER_MARGIN_HOR, OUTER_MARGIN_VER)); + maScroll.SetLineSize(1); + maScroll.SetVisibleSize(mnColumnBtnCount); + maScroll.SetPageSize(mnColumnBtnCount); + maScroll.SetRange(Range(0, mnColumnBtnCount)); + maScroll.DoScroll(0); + +} + +bool ScDPRowFieldControl::IsValidIndex(size_t /*nIndex*/) const +{ + return true; +} + +size_t ScDPRowFieldControl::CalcNewFieldIndex(SCsCOL /*nDX*/, SCsROW nDY) const +{ + size_t nNewField = GetSelectedField(); + nNewField += nDY; + return IsExistingIndex(nNewField) ? nNewField : GetSelectedField(); +} + +size_t ScDPRowFieldControl::GetDisplayPosition(size_t nIndex) const +{ + size_t nLower = maScroll.GetThumbPos(); + size_t nUpper = nLower + mnColumnBtnCount; + if (nLower <= nIndex && nIndex <= nUpper) + return nIndex - nLower; + + return INVALID_INDEX; +} + +//------------------------------------------------------------------- + +String ScDPRowFieldControl::GetDescription() const +{ + return ScResId(STR_ACC_DATAPILOT_ROW_DESCR); +} + +ScDPFieldType ScDPRowFieldControl::GetFieldType() const +{ + return TYPE_ROW; +} + +void ScDPRowFieldControl::ScrollToEnd() +{ + maScroll.DoScroll(maScroll.GetRangeMax()); +} + +void ScDPRowFieldControl::ScrollToShowSelection() +{ + size_t nLower = maScroll.GetThumbPos(); + size_t nUpper = nLower + mnColumnBtnCount - 1; + size_t nSel = GetSelectedField(); + if (nSel < nLower) { - bKeyEvaluated = TRUE; - switch( nCode ) - { - case KEY_UP: MoveSelection( nCode, 0, -1 ); break; - case KEY_DOWN: MoveSelection( nCode, 0, 1 ); break; - case KEY_LEFT: MoveSelection( nCode, -1, 0 ); break; - case KEY_RIGHT: MoveSelection( nCode, 1, 0 ); break; - case KEY_HOME: SetSelectionHome(); break; - case KEY_END: SetSelectionEnd(); break; - case KEY_DELETE: - pDlg->NotifyRemoveField( eType, nFieldSelected ); break; - default: bKeyEvaluated = FALSE; - } + // scroll up + maScroll.DoScroll(nSel); } + else if (nUpper < nSel) + { + // scroll down + size_t nD = nSel - nUpper; + maScroll.DoScroll(nLower + nD); + } +} - if( !bKeyEvaluated ) - Control::KeyInput( rKEvt ); +void ScDPRowFieldControl::ResetScrollBar() +{ + long nOldMax = maScroll.GetRangeMax(); + long nNewMax = std::max<long>(mnColumnBtnCount, GetFieldCount()); + + if (nOldMax != nNewMax) + maScroll.SetRangeMax(nNewMax); } -void __EXPORT ScDPFieldWindow::GetFocus() +bool ScDPRowFieldControl::GetFieldBtnPosSize(size_t nPos, Point& rPos, Size& rSize) +{ + if (nPos >= mnColumnBtnCount) + return false; + + size_t nOffset = maScroll.GetThumbPos(); + if (nPos + nOffset >= GetFieldCount()) + return false; + + rSize = Size(FIELD_BTN_WIDTH, FIELD_BTN_HEIGHT); + rPos = Point(OUTER_MARGIN_HOR, OUTER_MARGIN_VER); + rPos.Y() += nPos * (FIELD_BTN_HEIGHT + ROW_FIELD_BTN_GAP); + return true; +} + +void ScDPRowFieldControl::HandleScroll() { - Control::GetFocus(); Redraw(); - if( GetGetFocusFlags() & GETFOCUS_MNEMONIC ) // move field on shortcut - pDlg->NotifyMoveField( eType ); - else // else change focus - pDlg->NotifyFieldFocus( eType, TRUE ); +} - if (pAccessible) +IMPL_LINK(ScDPRowFieldControl, ScrollHdl, ScrollBar*, EMPTYARG) +{ + HandleScroll(); + return 0; +} + +IMPL_LINK(ScDPRowFieldControl, EndScrollHdl, ScrollBar*, EMPTYARG) +{ + HandleScroll(); + return 0; +} + +//============================================================================= + +ScDPSelectFieldControl::ScDPSelectFieldControl( + ScDPLayoutDlg* pDialog, const ResId& rResId, const String& rName ) : + ScDPFieldControlBase( pDialog, rResId, NULL ) +{ + SetName(rName); +} + +ScDPSelectFieldControl::~ScDPSelectFieldControl() +{ +} + +Point ScDPSelectFieldControl::GetFieldPosition( size_t nIndex ) +{ + Point aPos; + long nFldW = FIELD_BTN_WIDTH; + long nFldH = FIELD_BTN_HEIGHT; + long nSpace = SELECT_FIELD_BTN_SPACE; + + aPos.X() = (nFldW + nSpace) * (nIndex / LINE_SIZE); + aPos.Y() = (nFldH + nSpace) * (nIndex % LINE_SIZE); + return aPos; +} + +Size ScDPSelectFieldControl::GetFieldSize() const +{ + return Size(FIELD_BTN_WIDTH, FIELD_BTN_HEIGHT); +} + +bool ScDPSelectFieldControl::GetFieldIndex( const Point& rPos, size_t& rnIndex ) +{ + rnIndex = INVALID_INDEX; + long nFldW = FIELD_BTN_WIDTH; + long nFldH = FIELD_BTN_HEIGHT; + long nSpace = SELECT_FIELD_BTN_SPACE; + if( (rPos.X() >= 0) && (rPos.Y() >= 0) ) { - com::sun::star::uno::Reference < com::sun::star::accessibility::XAccessible > xTempAcc = xAccessible; - if (xTempAcc.is()) - pAccessible->GotFocus(); - else - pAccessible = NULL; + size_t nRow = rPos.Y() / (nFldH + nSpace); + size_t nCol = rPos.X() / (nFldW + nSpace); + // is not between controls? + if( (rPos.Y() % (nFldH + nSpace) < nFldH) && (rPos.X() % (nFldW + nSpace) < nFldW) ) + rnIndex = nCol * LINE_SIZE + nRow; } + return IsValidIndex( rnIndex ); } -void __EXPORT ScDPFieldWindow::LoseFocus() +void ScDPSelectFieldControl::Redraw() { - Control::LoseFocus(); - Redraw(); - pDlg->NotifyFieldFocus( eType, FALSE ); + const StyleSettings& rStyleSet = GetSettings().GetStyleSettings(); + Color aFaceColor = rStyleSet.GetFaceColor(); + Color aWinColor = rStyleSet.GetWindowColor(); + Color aTextColor = rStyleSet.GetButtonTextColor(); + Color aWinTextColor = rStyleSet.GetWindowTextColor(); - if (pAccessible) + VirtualDevice aVirDev; + // #i97623# VirtualDevice is always LTR while other windows derive direction from parent + aVirDev.EnableRTL( IsRTLEnabled() ); + aVirDev.SetMapMode( MAP_PIXEL ); + + Point aPos0; + Size aSize( GetSizePixel() ); + Font aFont( GetFont() ); // Font vom Window + aFont.SetTransparent( TRUE ); + aVirDev.SetFont( aFont ); + aVirDev.SetOutputSizePixel( aSize ); + + aVirDev.SetLineColor(); + aVirDev.SetFillColor( aFaceColor ); + aVirDev.DrawRect( Rectangle(aPos0, aSize) ); + + size_t nFieldSelected = GetSelectedField(); + FieldNames& rFields = GetFieldNames(); + + Rectangle aFieldRect( aPos0, GetFieldSize() ); + for( size_t nIx = 0; nIx < rFields.size(); ++nIx ) { - com::sun::star::uno::Reference < com::sun::star::accessibility::XAccessible > xTempAcc = xAccessible; - if (xTempAcc.is()) - pAccessible->LostFocus(); - else - pAccessible = NULL; + aFieldRect.SetPos( GetFieldPosition( nIx ) ); + bool bFocus = HasFocus() && (nIx == nFieldSelected); + DrawField( aVirDev, aFieldRect, rFields[ nIx ], bFocus ); } + + DrawBitmap( aPos0, aVirDev.GetBitmap( aPos0, aSize ) ); + DrawInvertSelection(); + UpdateStyle(); } //------------------------------------------------------------------- -void ScDPFieldWindow::AddField( const String& rText, size_t nNewIndex ) +bool ScDPSelectFieldControl::IsValidIndex( size_t nIndex ) const { - DBG_ASSERT( nNewIndex == aFieldArr.size(), "ScDPFieldWindow::AddField - invalid index" ); - if( IsValidIndex( nNewIndex ) ) + return nIndex < PAGE_SIZE; +} + +size_t ScDPSelectFieldControl::CalcNewFieldIndex( SCsCOL nDX, SCsROW nDY ) const +{ + size_t nNewField = GetSelectedField(); + nNewField += static_cast<SCsCOLROW>(nDX) * LINE_SIZE + nDY; + return IsExistingIndex( nNewField ) ? nNewField : GetSelectedField(); +} + +//------------------------------------------------------------------- + +String ScDPSelectFieldControl::GetDescription() const +{ + return ScResId(STR_ACC_DATAPILOT_SEL_DESCR); +} + +ScDPFieldType ScDPSelectFieldControl::GetFieldType() const +{ + return TYPE_SELECT; +} + +//============================================================================= + +ScDPDataFieldControl::ScDPDataFieldControl( ScDPLayoutDlg* pParent, const ResId& rResId, FixedText* pCaption ) : + ScDPFieldControlBase(pParent, rResId, pCaption), + maScroll(this, WB_HORZ | WB_DRAG), + mpParent(pParent), + mnScrollMarginHeight(0), + mnColumnBtnCount(0), + mnTotalBtnCount(0) +{ + maScroll.SetLineSize(1); + maScroll.SetVisibleSize(2); + maScroll.SetPageSize(2); + maScroll.SetRange(Range(0, 2)); + maScroll.DoScroll(0); + maScroll.SetScrollHdl( LINK(this, ScDPDataFieldControl, ScrollHdl) ); + maScroll.SetEndScrollHdl( LINK(this, ScDPDataFieldControl, EndScrollHdl) ); + maScroll.Show(); + + AppendPaintable(&maScroll); +} + +ScDPDataFieldControl::~ScDPDataFieldControl() +{ +} + +void ScDPDataFieldControl::CalcSize() +{ + long nScrollSize = GetSettings().GetStyleSettings().GetScrollBarSize(); + Size aWndSize = GetSizePixel(); + mnScrollMarginHeight = nScrollSize + OUTER_MARGIN_VER; + + maScroll.SetSizePixel(Size(aWndSize.Width() - OUTER_MARGIN_HOR*2, nScrollSize)); + maScroll.SetPosPixel(Point(OUTER_MARGIN_HOR, aWndSize.Height() - mnScrollMarginHeight)); + + long nH = FIELD_BTN_HEIGHT + DATA_FIELD_BTN_GAP; + long nTotalH = aWndSize.Height() - mnScrollMarginHeight - OUTER_MARGIN_VER; + mnColumnBtnCount = nTotalH / nH; + mnTotalBtnCount = mnColumnBtnCount * 2; +} + +bool ScDPDataFieldControl::IsValidIndex(size_t /*nIndex*/) const +{ + // We support unlimited number of data fields. If we ever want to put a + // cap on the number of data fields, this is the right place. + return true; +} + +Point ScDPDataFieldControl::GetFieldPosition(size_t nIndex) +{ + Point aPos; + Size aSize; + GetFieldBtnPosSize(nIndex, aPos, aSize); + return aPos; +} + +bool ScDPDataFieldControl::GetFieldIndex(const Point& rPos, size_t& rnIndex) +{ + size_t nCol, nRow; + GetFieldBtnColRow(rPos, nCol, nRow); + nCol += static_cast<size_t>(maScroll.GetThumbPos()); + size_t nIndex = nCol * mnColumnBtnCount; + + nIndex += nRow; + size_t nFldCount = GetFieldCount(); + if (nIndex >= nFldCount) + nIndex = nFldCount; + + rnIndex = nIndex; + return true; +} + +Size ScDPDataFieldControl::GetFieldSize() const +{ + Size aWndSize = GetSizePixel(); + long nFieldObjWidth = aWndSize.Width() / 2.0 - OUTER_MARGIN_HOR - DATA_FIELD_BTN_GAP/2; + Size aFieldSize(nFieldObjWidth, FIELD_BTN_HEIGHT); + return aFieldSize; +} + +String ScDPDataFieldControl::GetDescription() const +{ + return ScResId(STR_ACC_DATAPILOT_DATA_DESCR); +} + +ScDPFieldType ScDPDataFieldControl::GetFieldType() const +{ + return TYPE_DATA; +} + +void ScDPDataFieldControl::ScrollToEnd() +{ + maScroll.DoScroll(maScroll.GetRangeMax()); +} + +void ScDPDataFieldControl::ScrollToShowSelection() +{ + long nNewOffset = CalcOffsetToShowSelection(); + if (nNewOffset != maScroll.GetThumbPos()) + maScroll.DoScroll(nNewOffset); +} + +void ScDPDataFieldControl::ResetScrollBar() +{ + long nOldMax = maScroll.GetRangeMax(); + long nNewMax = ceil( + static_cast<double>(GetFieldCount()) / static_cast<double>(mnColumnBtnCount)); + + if (nOldMax != nNewMax) { - aFieldArr.push_back( FieldString( rText, true ) ); - if (pAccessible) + maScroll.SetRangeMax(nNewMax); + if (nNewMax < nOldMax) { - com::sun::star::uno::Reference < com::sun::star::accessibility::XAccessible > xTempAcc = xAccessible; - if (xTempAcc.is()) - pAccessible->AddField(nNewIndex); - else - pAccessible = NULL; + // We lost a column. Scroll to the right frame. + long nNewOffset = CalcOffsetToShowSelection(); + nNewOffset -= 2; + if (nNewOffset < 0) + nNewOffset = 0; + maScroll.DoScroll(nNewOffset); } } } -void ScDPFieldWindow::DelField( size_t nDelIndex ) +void ScDPDataFieldControl::Paint(const Rectangle& /*rRect*/) { - if( IsExistingIndex( nDelIndex ) ) + Redraw(); +} + +void ScDPDataFieldControl::DataChanged( const DataChangedEvent& rDCEvt ) +{ + ScDPFieldControlBase::DataChanged(rDCEvt); +} + +void ScDPDataFieldControl::MouseButtonDown(const MouseEvent& rMEvt) +{ + if (maScroll.IsVisible()) { - if (pAccessible) // before decrement fieldcount + Rectangle aRect(maScroll.GetPosPixel(), maScroll.GetSizePixel()); + if (aRect.IsInside(rMEvt.GetPosPixel())) { - com::sun::star::uno::Reference < com::sun::star::accessibility::XAccessible > xTempAcc = xAccessible; - if (xTempAcc.is()) - pAccessible->RemoveField(nDelIndex); - else - pAccessible = NULL; + maScroll.MouseButtonDown(rMEvt); + return; } - aFieldArr.erase( aFieldArr.begin() + nDelIndex ); - Redraw(); } + ScDPFieldControlBase::MouseButtonDown(rMEvt); } -void ScDPFieldWindow::ClearFields() +void ScDPDataFieldControl::MouseButtonUp(const MouseEvent& rMEvt) { - if( eType == TYPE_SELECT || eType == TYPE_PAGE || eType == TYPE_COL || eType == TYPE_ROW || eType == TYPE_DATA) + if (maScroll.IsVisible()) { - com::sun::star::uno::Reference < com::sun::star::accessibility::XAccessible > xTempAcc = xAccessible; - if (!xTempAcc.is() && pAccessible) - pAccessible = NULL; - if (pAccessible) - for( size_t nIdx = aFieldArr.size(); nIdx > 0; --nIdx ) - pAccessible->RemoveField( nIdx - 1 ); - - aFieldArr.clear(); + Rectangle aRect(maScroll.GetPosPixel(), maScroll.GetSizePixel()); + if (aRect.IsInside(rMEvt.GetPosPixel())) + { + maScroll.MouseButtonUp(rMEvt); + return; + } } + ScDPFieldControlBase::MouseButtonUp(rMEvt); } -void ScDPFieldWindow::SetFieldText( const String& rText, size_t nIndex ) +void ScDPDataFieldControl::MouseMove(const MouseEvent& rMEvt) { - if( IsExistingIndex( nIndex ) ) + if (maScroll.IsVisible()) { - aFieldArr[ nIndex ] = FieldString( rText, true ); - Redraw(); - - if (pAccessible) + Rectangle aRect(maScroll.GetPosPixel(), maScroll.GetSizePixel()); + if (aRect.IsInside(rMEvt.GetPosPixel())) { - com::sun::star::uno::Reference < com::sun::star::accessibility::XAccessible > xTempAcc = xAccessible; - if (xTempAcc.is()) - pAccessible->FieldNameChange(nIndex); - else - pAccessible = NULL; + maScroll.MouseMove(rMEvt); + return; } } + ScDPFieldControlBase::MouseMove(rMEvt); } -const String& ScDPFieldWindow::GetFieldText( size_t nIndex ) const +bool ScDPDataFieldControl::GetFieldBtnPosSize(size_t nPos, Point& rPos, Size& rSize) { - if( IsExistingIndex( nIndex ) ) - return aFieldArr[ nIndex ].first; - return EMPTY_STRING; -} + if (nPos >= mnTotalBtnCount) + return false; -//------------------------------------------------------------------- + Size aFieldSize = GetFieldSize(); + + size_t nCol = nPos / mnColumnBtnCount; + size_t nRow = nPos % mnColumnBtnCount; + + long nX = OUTER_MARGIN_HOR + aFieldSize.Width() * nCol; + if (nCol > 0) + nX += DATA_FIELD_BTN_GAP * nCol; + + long nY = OUTER_MARGIN_VER + aFieldSize.Height() * nRow; + if (nRow > 0) + nY += DATA_FIELD_BTN_GAP * nRow; + + rPos = Point(nX, nY); + rSize = aFieldSize; + return true; +} -bool ScDPFieldWindow::AddField( const String& rText, const Point& rPos, size_t& rnIndex ) +void ScDPDataFieldControl::GetFieldBtnColRow(const Point& rPos, size_t& rCol, size_t& rRow) { - if ( aFieldArr.size() == nFieldSize ) - return FALSE; + Size aSize = GetSizePixel(); + long nBtnH = FIELD_BTN_HEIGHT; - size_t nNewIndex = 0; - if( GetFieldIndex( rPos, nNewIndex ) ) - { - if( nNewIndex > aFieldArr.size() ) - nNewIndex = aFieldArr.size(); + size_t nCol = (rPos.X() <= aSize.Width()/2.0) ? 0 : 1; + size_t nRow = 0; - aFieldArr.insert( aFieldArr.begin() + nNewIndex, FieldString( rText, true ) ); - nFieldSelected = nNewIndex; - Redraw(); - rnIndex = nNewIndex; + long nVBound = OUTER_MARGIN_VER + nBtnH + DATA_FIELD_BTN_GAP; + while (true) + { + if (rPos.Y() <= nVBound) + break; - if (pAccessible) - { - com::sun::star::uno::Reference < com::sun::star::accessibility::XAccessible > xTempAcc = xAccessible; - if (xTempAcc.is()) - pAccessible->AddField(nNewIndex); - else - pAccessible = NULL; - } + nVBound += nBtnH + DATA_FIELD_BTN_GAP; + if (nVBound > aSize.Height()) + break; - return true; + ++nRow; } - return false; + rCol = nCol; + rRow = nRow; } -void ScDPFieldWindow::GetExistingIndex( const Point& rPos, size_t& rnIndex ) +long ScDPDataFieldControl::CalcOffsetToShowSelection() { - if( !aFieldArr.empty() && (eType != TYPE_SELECT) && GetFieldIndex( rPos, rnIndex ) ) + long nOffset = maScroll.GetThumbPos(); + size_t nSel = GetSelectedField(); + size_t nLower = nOffset*mnColumnBtnCount; + size_t nUpper = nLower + mnColumnBtnCount * 2 - 1; + long nNewOffset = nOffset; + if (nSel < nLower) { - if( rnIndex >= aFieldArr.size() ) - rnIndex = aFieldArr.size() - 1; + // scroll to left. The selected field should be in the left column. + nNewOffset = floor( + static_cast<double>(nSel) / static_cast<double>(mnColumnBtnCount)); } - else - rnIndex = 0; + else if (nUpper < nSel) + { + // scroll to right. The selected field should be in the right column. + nNewOffset = floor( + static_cast<double>(nSel) / static_cast<double>(mnColumnBtnCount))-1; + } + return nNewOffset; +} + +void ScDPDataFieldControl::HandleScroll() +{ + Redraw(); } -String ScDPFieldWindow::GetDescription() const -{ - String sDescription; - switch( eType ) - { - case TYPE_COL: - sDescription = ScResId(STR_ACC_DATAPILOT_COL_DESCR); - break; - case TYPE_ROW: - sDescription = ScResId(STR_ACC_DATAPILOT_ROW_DESCR); - break; - case TYPE_DATA: - sDescription = ScResId(STR_ACC_DATAPILOT_DATA_DESCR); - break; - case TYPE_SELECT: - sDescription = ScResId(STR_ACC_DATAPILOT_SEL_DESCR); - break; - default: +void ScDPDataFieldControl::Redraw() +{ + VirtualDevice aVirDev; + // #i97623# VirtualDevice is always LTR while other windows derive direction from parent + aVirDev.EnableRTL( IsRTLEnabled() ); + aVirDev.SetMapMode( MAP_PIXEL ); + + Point aPos0; + Size aWndSize = GetSizePixel(); + Font aFont = GetFont(); + aFont.SetTransparent(true); + aVirDev.SetFont(aFont); + aVirDev.SetOutputSizePixel(aWndSize); + + DrawBackground(aVirDev); + + long nOffset = maScroll.GetThumbPos(); + FieldNames& rFields = GetFieldNames(); + { + FieldNames::iterator itr = rFields.begin(), itrEnd = rFields.end(); + if (nOffset) + ::std::advance(itr, nOffset*mnColumnBtnCount); + + for (size_t i = 0; itr != itrEnd; ++itr, ++i) { - // added to avoid warnings + Point aFldPt; + Size aFldSize; + if (!GetFieldBtnPosSize(i, aFldPt, aFldSize)) + break; + + size_t nField = i + nOffset*mnColumnBtnCount; + bool bFocus = HasFocus() && (nField == GetSelectedField()); + DrawField(aVirDev, Rectangle(aFldPt, aFldSize), *itr, bFocus); } } - return sDescription; + + // Create a bitmap from the virtual device, and place that bitmap onto + // this control. + DrawBitmap(aPos0, aVirDev.GetBitmap(aPos0, aWndSize)); + + DrawPaintables(); + DrawInvertSelection(); + UpdateStyle(); } -::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > ScDPFieldWindow::CreateAccessible() +size_t ScDPDataFieldControl::CalcNewFieldIndex(SCsCOL nDX, SCsROW nDY) const { - pAccessible = - new ScAccessibleDataPilotControl(GetAccessibleParentWindow()->GetAccessible(), this); + size_t nField = GetSelectedField(); + if (nField < mnColumnBtnCount) + { + // selected button in the first column. + if (nDX < 0) + // in the left most column. We can't move any more to the left. + return nField; + if (nField == 0 && nDY < 0) + // at the top left most position. We can't move up any more. + return nField; + } - com::sun::star::uno::Reference < ::com::sun::star::accessibility::XAccessible > xReturn = pAccessible; + size_t nFldCount = GetFieldCount(); + size_t nFirstInLastCol = nFldCount / mnColumnBtnCount * mnColumnBtnCount; + if (nFirstInLastCol <= nField) + { + // selected button in the last column. + if (nDX > 0) + // can't move to the right any more. + return nField; + if (nDY > 0 && nField >= nFldCount) + // at the last position. Can't move down any more. + return nField; + } - pAccessible->Init(); - xAccessible = xReturn; + nDY += nDX * mnColumnBtnCount; + nField += nDY; - return xReturn; + if (nField >= nFldCount) + // Don't exceed the upper bound. + nField = nFldCount - 1; + return nField; } -//=================================================================== +size_t ScDPDataFieldControl::GetDisplayPosition(size_t nIndex) const +{ + long nOffset = maScroll.GetThumbPos(); + size_t nLower = mnColumnBtnCount * nOffset; + size_t nUpper = nLower + mnColumnBtnCount*2 - 1; + if (nLower <= nIndex && nIndex <= nUpper) + return nIndex - nLower; + + return INVALID_INDEX; +} +IMPL_LINK(ScDPDataFieldControl, ScrollHdl, ScrollBar*, EMPTYARG) +{ + HandleScroll(); + return 0; +} + +IMPL_LINK(ScDPDataFieldControl, EndScrollHdl, ScrollBar*, EMPTYARG) +{ + HandleScroll(); + return 0; +} /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/ui/dbgui/pivot.hrc b/sc/source/ui/dbgui/pivot.hrc index 1a97d4c75b52..6077ea8f8182 100644 --- a/sc/source/ui/dbgui/pivot.hrc +++ b/sc/source/ui/dbgui/pivot.hrc @@ -38,8 +38,8 @@ #define WND_ROW 12 #define WND_DATA 13 #define WND_SELECT 14 -#define WND_FIELD 15 -#define WND_FIELD_SPACE 16 +//#define WND_FIELD 15 +//#define WND_FIELD_SPACE 16 #define WND_HSCROLL 17 #define WND_PAGE 18 #define FT_COL 31 diff --git a/sc/source/ui/dbgui/pivot.src b/sc/source/ui/dbgui/pivot.src index 359c8a92d8e5..1aaf93726b80 100644 --- a/sc/source/ui/dbgui/pivot.src +++ b/sc/source/ui/dbgui/pivot.src @@ -31,7 +31,7 @@ ModelessDialog RID_SCDLG_PIVOT_LAYOUT { OutputSize = TRUE ; HelpId = SID_OPENDLG_PIVOTTABLE ; - Size = MAP_APPFONT ( 336 , 190 ) ; + Size = MAP_APPFONT ( 350 , 216 ) ; Hide = TRUE ; SVLook = TRUE ; Moveable = TRUE ; @@ -46,8 +46,8 @@ ModelessDialog RID_SCDLG_PIVOT_LAYOUT }; Control WND_PAGE { - Pos = MAP_APPFONT ( 6 , 14 ) ; - Size = MAP_APPFONT ( 182 , 24 ) ; + Pos = MAP_APPFONT ( 20 , 14 ) ; + Size = MAP_APPFONT ( 202 , 34 ) ; TabStop = TRUE ; }; FixedText FT_COL @@ -58,8 +58,8 @@ ModelessDialog RID_SCDLG_PIVOT_LAYOUT }; Control WND_COL { - Pos = MAP_APPFONT ( 44 , 40 ) ; - Size = MAP_APPFONT ( 144 , 24 ) ; + Pos = MAP_APPFONT ( 56 , 56 ) ; + Size = MAP_APPFONT ( 144 , 34 ) ; TabStop = TRUE ; }; FixedText FT_ROW @@ -70,25 +70,25 @@ ModelessDialog RID_SCDLG_PIVOT_LAYOUT }; Control WND_ROW { - Pos = MAP_APPFONT ( 6 , 66 ) ; - Size = MAP_APPFONT ( 36 , 96 ) ; + Pos = MAP_APPFONT ( 6 , 98 ) ; + Size = MAP_APPFONT ( 50 , 96 ) ; TabStop = TRUE ; }; FixedText FT_DATA { - Pos = MAP_APPFONT ( 231, 176 ) ; + Pos = MAP_APPFONT ( 227, 176 ) ; Size = MAP_APPFONT ( 37 , 8 ) ; Text [ en-US ] = "Data Fields" ; }; Control WND_DATA { - Pos = MAP_APPFONT ( 44 , 66 ) ; + Pos = MAP_APPFONT ( 56 , 98 ) ; Size = MAP_APPFONT ( 144 , 96 ) ; TabStop = TRUE ; }; Control WND_SELECT { - Pos = MAP_APPFONT ( 194 , 14 ) ; + Pos = MAP_APPFONT ( 210 , 14 ) ; Size = MAP_APPFONT ( 70 , 126 ) ; TabStop = TRUE ; }; @@ -98,14 +98,14 @@ ModelessDialog RID_SCDLG_PIVOT_LAYOUT }; ScrollBar WND_HSCROLL { - Pos = MAP_APPFONT ( 194 , 144 ) ; + Pos = MAP_APPFONT ( 208 , 144 ) ; Size = MAP_APPFONT ( 70 , 8 ) ; HScroll = TRUE ; TabStop = FALSE ; }; FixedText FT_INFO { - Pos = MAP_APPFONT ( 6 , 168 ) ; + Pos = MAP_APPFONT ( 6 , 200 ) ; Size = MAP_APPFONT ( 182 , 16 ) ; WordBreak = TRUE ; Text [ en-US ] = "Drag the fields from the right into the desired position." ; @@ -113,64 +113,53 @@ ModelessDialog RID_SCDLG_PIVOT_LAYOUT FixedLine FL_LAYOUT { Pos = MAP_APPFONT ( 6 , 3 ) ; - Size = MAP_APPFONT ( 268 , 8 ) ; + Size = MAP_APPFONT ( 282 , 8 ) ; Text [ en-US ] = "Layout"; }; OKButton BTN_OK { - Pos = MAP_APPFONT ( 280 , 6 ) ; + Pos = MAP_APPFONT ( 294 , 6 ) ; Size = MAP_APPFONT ( 50 , 14 ) ; TabStop = TRUE ; DefButton = TRUE ; }; CancelButton BTN_CANCEL { - Pos = MAP_APPFONT ( 280 , 23 ) ; + Pos = MAP_APPFONT ( 294 , 23 ) ; Size = MAP_APPFONT ( 50 , 14 ) ; TabStop = TRUE ; }; HelpButton BTN_HELP { - Pos = MAP_APPFONT ( 280 , 43 ) ; + Pos = MAP_APPFONT ( 294 , 43 ) ; Size = MAP_APPFONT ( 50 , 14 ) ; TabStop = TRUE ; }; PushButton BTN_REMOVE { - Pos = MAP_APPFONT ( 280 , 63 ) ; + Pos = MAP_APPFONT ( 294 , 63 ) ; Size = MAP_APPFONT ( 50 , 14 ) ; TabStop = TRUE ; Text [ en-US ] = "Remove"; }; PushButton BTN_OPTIONS { - Pos = MAP_APPFONT ( 280 , 80 ) ; + Pos = MAP_APPFONT ( 294 , 80 ) ; Size = MAP_APPFONT ( 50 , 14 ) ; TabStop = TRUE ; Text [ en-US ] = "Options..."; }; MoreButton BTN_MORE { - Pos = MAP_APPFONT ( 280 , 170 ) ; + Pos = MAP_APPFONT ( 294 , 190 ) ; Size = MAP_APPFONT ( 50 , 14 ) ; TabStop = TRUE ; MapUnit = MAP_APPFONT ; Delta = 90 ; }; - Window WND_FIELD - { - Border = TRUE ; - Pos = MAP_APPFONT ( 0 , 0 ) ; - Size = MAP_APPFONT ( 36 , 12 ) ; - }; - Window WND_FIELD_SPACE - { - Pos = MAP_APPFONT ( 0 , 0 ) ; - Size = MAP_APPFONT ( 2 , 2 ) ; - }; FixedLine FL_OUTPUT { - Pos = MAP_APPFONT ( 6 , 190 ) ; + Pos = MAP_APPFONT ( 6 , 216 ) ; Size = MAP_APPFONT ( 268 , 8 ) ; Text [ en-US ] = "Result" ; Hide = TRUE ; @@ -178,7 +167,7 @@ ModelessDialog RID_SCDLG_PIVOT_LAYOUT FixedText FT_INAREA { - Pos = MAP_APPFONT ( 12 , 203 ) ; + Pos = MAP_APPFONT ( 12 , 229 ) ; Size = MAP_APPFONT ( 59 , 8 ) ; Hide = TRUE ; Text [ en-US ] = "Selection from" ; @@ -186,14 +175,14 @@ ModelessDialog RID_SCDLG_PIVOT_LAYOUT Edit ED_INAREA { Border = TRUE ; - Pos = MAP_APPFONT ( 73 , 201 ) ; + Pos = MAP_APPFONT ( 73 , 227 ) ; Size = MAP_APPFONT ( 100 , 12 ) ; TabStop = TRUE ; Hide = TRUE ; }; ImageButton RB_INAREA { - Pos = MAP_APPFONT ( 177 , 200 ) ; + Pos = MAP_APPFONT ( 177 , 226 ) ; Size = MAP_APPFONT ( 13 , 15 ) ; TabStop = TRUE ; Hide = TRUE ; @@ -202,7 +191,7 @@ ModelessDialog RID_SCDLG_PIVOT_LAYOUT FixedText FT_OUTAREA { - Pos = MAP_APPFONT ( 12 , 221 ) ; + Pos = MAP_APPFONT ( 12 , 247 ) ; Size = MAP_APPFONT ( 59 , 8 ) ; Hide = TRUE ; Text [ en-US ] = "Results to" ; @@ -210,7 +199,7 @@ ModelessDialog RID_SCDLG_PIVOT_LAYOUT ListBox LB_OUTAREA { Border = TRUE ; - Pos = MAP_APPFONT ( 73 , 219 ) ; + Pos = MAP_APPFONT ( 73 , 245 ) ; Size = MAP_APPFONT ( 75 , 90 ) ; TabStop = TRUE ; DropDown = TRUE ; @@ -219,14 +208,14 @@ ModelessDialog RID_SCDLG_PIVOT_LAYOUT Edit ED_OUTAREA { Border = TRUE ; - Pos = MAP_APPFONT ( 152 , 219 ) ; + Pos = MAP_APPFONT ( 152 , 245 ) ; Size = MAP_APPFONT ( 100 , 12 ) ; TabStop = TRUE ; Hide = TRUE ; }; ImageButton RB_OUTAREA { - Pos = MAP_APPFONT ( 256 , 218 ) ; + Pos = MAP_APPFONT ( 256 , 244 ) ; Size = MAP_APPFONT ( 13 , 15 ) ; TabStop = TRUE ; Hide = TRUE ; @@ -234,7 +223,7 @@ ModelessDialog RID_SCDLG_PIVOT_LAYOUT }; CheckBox BTN_IGNEMPTYROWS { - Pos = MAP_APPFONT ( 12 , 237 ) ; + Pos = MAP_APPFONT ( 12 , 263 ) ; Size = MAP_APPFONT ( 124 , 10 ) ; TabStop = TRUE ; Hide = TRUE ; @@ -242,7 +231,7 @@ ModelessDialog RID_SCDLG_PIVOT_LAYOUT }; CheckBox BTN_DETECTCAT { - Pos = MAP_APPFONT ( 142 , 237 ) ; + Pos = MAP_APPFONT ( 142 , 263 ) ; Size = MAP_APPFONT ( 124 , 10 ) ; TabStop = TRUE ; Hide = TRUE ; @@ -250,7 +239,7 @@ ModelessDialog RID_SCDLG_PIVOT_LAYOUT }; CheckBox BTN_TOTALCOL { - Pos = MAP_APPFONT ( 12 , 251 ) ; + Pos = MAP_APPFONT ( 12 , 277 ) ; Size = MAP_APPFONT ( 124 , 10 ) ; TabStop = TRUE ; Hide = TRUE ; @@ -258,7 +247,7 @@ ModelessDialog RID_SCDLG_PIVOT_LAYOUT }; CheckBox BTN_TOTALROW { - Pos = MAP_APPFONT ( 142 , 251 ) ; + Pos = MAP_APPFONT ( 142 , 277 ) ; Size = MAP_APPFONT ( 124 , 10 ) ; TabStop = TRUE ; Hide = TRUE ; @@ -266,7 +255,7 @@ ModelessDialog RID_SCDLG_PIVOT_LAYOUT }; CheckBox BTN_FILTER { - Pos = MAP_APPFONT ( 12 , 265 ) ; + Pos = MAP_APPFONT ( 12 , 291 ) ; Size = MAP_APPFONT ( 124 , 10 ) ; TabStop = TRUE ; Hide = TRUE ; @@ -274,7 +263,7 @@ ModelessDialog RID_SCDLG_PIVOT_LAYOUT }; CheckBox BTN_DRILLDOWN { - Pos = MAP_APPFONT ( 142 , 265 ) ; + Pos = MAP_APPFONT ( 142 , 291 ) ; Size = MAP_APPFONT ( 124 , 10 ) ; TabStop = TRUE ; Hide = TRUE ; diff --git a/sc/source/ui/dbgui/pvglob.hxx b/sc/source/ui/dbgui/pvglob.hxx deleted file mode 100644 index 2ad61405aae8..000000000000 --- a/sc/source/ui/dbgui/pvglob.hxx +++ /dev/null @@ -1,45 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/************************************************************************* - * - * 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. - * - ************************************************************************/ - -#ifndef SC_PVGLOB_HXX -#define SC_PVGLOB_HXX - -//------------------------------------------------------------------- - -class PivotGlobal -{ -public: - static long nObjHeight; - static long nObjWidth; - static long nSelSpace; -}; - - -#endif // SC_PVGLOB_HXX - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/ui/dbgui/pvlaydlg.cxx b/sc/source/ui/dbgui/pvlaydlg.cxx index 3b26d1c836f6..dd9d4bf3528c 100644 --- a/sc/source/ui/dbgui/pvlaydlg.cxx +++ b/sc/source/ui/dbgui/pvlaydlg.cxx @@ -29,12 +29,11 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sc.hxx" - - //---------------------------------------------------------------------------- #include "pvlaydlg.hxx" #include "dbdocfun.hxx" +#include "dpuiglobal.hxx" #include <sfx2/dispatch.hxx> #include <vcl/msgbox.hxx> @@ -49,7 +48,6 @@ #include "tabvwsh.hxx" #include "reffact.hxx" #include "scresid.hxx" -#include "pvglob.hxx" #include "globstr.hrc" #include "pivot.hrc" #include "dpobject.hxx" @@ -59,9 +57,53 @@ #include "sc.hrc" #include "scabstdlg.hxx" + +#include <stdio.h> +#include <string> +#include <sys/time.h> + +namespace { + +class StackPrinter +{ +public: + explicit StackPrinter(const char* msg) : + msMsg(msg) + { + fprintf(stdout, "%s: --begin\n", msMsg.c_str()); + mfStartTime = getTime(); + } + + ~StackPrinter() + { + double fEndTime = getTime(); + fprintf(stdout, "%s: --end (duration: %g sec)\n", msMsg.c_str(), (fEndTime-mfStartTime)); + } + + void printTime(int line) const + { + double fEndTime = getTime(); + fprintf(stdout, "%s: --(%d) (duration: %g sec)\n", msMsg.c_str(), line, (fEndTime-mfStartTime)); + } + +private: + double getTime() const + { + timeval tv; + gettimeofday(&tv, NULL); + return tv.tv_sec + tv.tv_usec / 1000000.0; + } + + ::std::string msMsg; + double mfStartTime; +}; + +} + using namespace com::sun::star; using ::rtl::OUString; using ::std::vector; +using ::std::for_each; //---------------------------------------------------------------------------- @@ -69,22 +111,10 @@ using ::std::vector; #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 ) @@ -109,14 +139,14 @@ ScDPLayoutDlg::ScDPLayoutDlg( SfxBindings* pB, SfxChildWindow* pCW, Window* pPar : 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 ), + aWndPage ( this, ScResId( WND_PAGE ), &aFtPage ), aFtCol ( this, ScResId( FT_COL ) ), - aWndCol ( this, ScResId( WND_COL ), TYPE_COL, &aFtCol ), + aWndCol ( this, ScResId( WND_COL ), &aFtCol ), aFtRow ( this, ScResId( FT_ROW ) ), - aWndRow ( this, ScResId( WND_ROW ), TYPE_ROW, &aFtRow ), + aWndRow ( this, ScResId( WND_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)) ), + aWndData ( this, ScResId( WND_DATA ), &aFtData ), + aWndSelect ( this, ScResId( WND_SELECT ), String(ScResId(STR_SELECT)) ), aSlider ( this, ScResId( WND_HSCROLL ) ), aFtInfo ( this, ScResId( FT_INFO ) ), @@ -169,7 +199,6 @@ ScDPLayoutDlg::ScDPLayoutDlg( SfxBindings* pB, SfxChildWindow* pCW, Window* pPar FreeResource(); } - //---------------------------------------------------------------------------- ScDPLayoutDlg::~ScDPLayoutDlg() @@ -181,26 +210,9 @@ ScDPLayoutDlg::~ScDPLayoutDlg() 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(bool bNewOutput) +void ScDPLayoutDlg::Init(bool bNewOutput) { DBG_ASSERT( pViewData && pDoc, "Ctor-Initialisierung fehlgeschlagen!" ); @@ -208,8 +220,8 @@ void __EXPORT ScDPLayoutDlg::Init(bool bNewOutput) 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.reserve( PIVOT_MAXFUNC ); + for ( USHORT i = 0; i < PIVOT_MAXFUNC; ++i ) aFuncNameArr.push_back( String( ScResId( i + 1 ) ) ); aBtnMore.AddWindow( &aFlAreas ); @@ -228,20 +240,9 @@ void __EXPORT ScDPLayoutDlg::Init(bool bNewOutput) 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 ); + aSelectArr.resize( PAGE_SIZE ); ScRange inRange; String inString; @@ -358,10 +359,9 @@ void __EXPORT ScDPLayoutDlg::Init(bool bNewOutput) //SFX_APPWINDOW->Disable(FALSE); //! allgemeine Methode im ScAnyRefDlg } - //---------------------------------------------------------------------------- -BOOL __EXPORT ScDPLayoutDlg::Close() +BOOL ScDPLayoutDlg::Close() { return DoClose( ScPivotLayoutWrapper::GetChildWindowId() ); } @@ -410,88 +410,53 @@ void ScDPLayoutDlg::InitWndSelect( const vector<ScDPLabelDataRef>& rLabels ) } } - //---------------------------------------------------------------------------- -void ScDPLayoutDlg::InitWnd( PivotField* pArr, long nCount, ScDPFieldType eType ) +void ScDPLayoutDlg::InitFieldWindow( const vector<PivotField>& rFields, ScDPFieldType eType ) { - if ( pArr && (eType != TYPE_SELECT) ) - { - ScDPFuncDataVec* pInitArr = NULL; - ScDPFieldWindow* pInitWnd = NULL; - BOOL bDataArr = FALSE; + ScDPFuncDataVec* pInitArr = GetFieldDataArray(eType); + ScDPFieldControlBase* pInitWnd = GetFieldWindow(eType); - switch ( eType ) - { - case TYPE_PAGE: - pInitArr = &aPageArr; - pInitWnd = &aWndPage; - break; - - case TYPE_COL: - pInitArr = &aColArr; - pInitWnd = &aWndCol; - break; + if (!pInitArr || !pInitWnd) + return; - case TYPE_ROW: - pInitArr = &aRowArr; - pInitWnd = &aWndRow; - break; + vector<PivotField>::const_iterator itr = rFields.begin(), itrEnd = rFields.end(); + for (; itr != itrEnd; ++itr) + { + SCCOL nCol = itr->nCol; + USHORT nMask = itr->nFuncMask; + if (nCol == PIVOT_DATA_FIELD) + continue; - case TYPE_DATA: - pInitArr = &aDataArr; - pInitWnd = &aWndData; - bDataArr = TRUE; - break; - default: - break; - } + size_t nFieldIndex = pInitArr->size(); + ScDPFuncDataRef p(new ScDPFuncData(nCol, nMask, itr->maFieldRef)); + pInitArr->push_back(p); - if ( pInitArr && pInitWnd ) + if (eType == TYPE_DATA) { - long j=0; - for ( long i=0; (i<nCount); i++ ) + // data field - we need to concatenate function name with the field name. + ScDPLabelData* pData = GetLabelData(nCol); + DBG_ASSERT( pData, "ScDPLabelData not found" ); + if (pData) { - SCCOL nCol = pArr[i].nCol; - USHORT nMask = pArr[i].nFuncMask; - - if ( nCol != PIVOT_DATA_FIELD ) + OUString aStr = pData->maLayoutName; + if (!aStr.getLength()) { - (*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) - { - OUString aStr = pData->maLayoutName; - if (!aStr.getLength()) - { - USHORT nInitMask = (*pInitArr)[j]->mnFuncMask; - aStr = GetFuncString(nInitMask, pData->mbIsValue); - aStr += pData->maName; - } - - pInitWnd->AddField( aStr, j ); - - pData->mnFuncMask = nMask; - } - } - ++j; + USHORT nInitMask = pInitArr->back()->mnFuncMask; + aStr = GetFuncString(nInitMask, pData->mbIsValue); + aStr += pData->maName; } + + pInitWnd->AddField(aStr, nFieldIndex); + pData->mnFuncMask = nMask; } -// Do not redraw here -> first the FixedText has to get its mnemonic char -// pInitWnd->Redraw(); } + else + pInitWnd->AddField(GetLabelString(nCol), nFieldIndex); } + pInitWnd->ResetScrollBar(); } - //---------------------------------------------------------------------------- void ScDPLayoutDlg::InitFocus() @@ -508,10 +473,10 @@ void ScDPLayoutDlg::InitFocus() 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 ); + InitFieldWindow(thePivotData.maPageFields, TYPE_PAGE); + InitFieldWindow(thePivotData.maColFields, TYPE_COL); + InitFieldWindow(thePivotData.maRowFields, TYPE_ROW); + InitFieldWindow(thePivotData.maDataFields, TYPE_DATA); size_t nLabels = thePivotData.maLabelArray.size(); aSlider.SetPageSize( PAGE_SIZE ); @@ -532,61 +497,23 @@ void ScDPLayoutDlg::InitFields() void ScDPLayoutDlg::AddField( size_t nFromIndex, ScDPFieldType eToType, const Point& rAtPos ) { + fprintf(stdout, "ScDPLayoutDlg::AddField: from index = %d pos = (%ld, %ld)\n", nFromIndex, rAtPos.X(), rAtPos.Y()); ScDPFuncData fData( *(aSelectArr[nFromIndex]) ); - size_t nAt = 0; - ScDPFieldWindow* toWnd = NULL; - ScDPFieldWindow* rmWnd1 = NULL; - ScDPFieldWindow* rmWnd2 = NULL; - ScDPFuncDataVec* toArr = NULL; + size_t nAt = 0; + ScDPFieldControlBase* toWnd = GetFieldWindow(eToType); + ScDPFieldControlBase* rmWnd1 = NULL; + ScDPFieldControlBase* rmWnd2 = NULL; + GetOtherFieldWindows(eToType, rmWnd1, rmWnd2); + + ScDPFuncDataVec* toArr = GetFieldDataArray(eToType); 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; + GetOtherDataArrays(eToType, rmArr1, rmArr2); - 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 bDataArr = eToType == TYPE_DATA; bool bAllowed = IsOrientationAllowed( fData.mnCol, eToType ); - if ( bAllowed - && (toArr->back().get() == NULL) - && (!Contains( toArr, fData.mnCol, nAt )) ) + if ( bAllowed && (!Contains( toArr, fData.mnCol, nAt )) ) { // ggF. in anderem Fenster entfernen if ( rmArr1 ) @@ -643,94 +570,99 @@ void ScDPLayoutDlg::AddField( size_t nFromIndex, ScDPFieldType eToType, const Po } } - -//---------------------------------------------------------------------------- - -void ScDPLayoutDlg::MoveField( ScDPFieldType eFromType, size_t nFromIndex, ScDPFieldType eToType, const Point& rAtPos ) +void ScDPLayoutDlg::AppendField(size_t nFromIndex, ScDPFieldType eToType) { - 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; + ScDPFuncData aFuncData = *aSelectArr[nFromIndex]; - switch ( eFromType ) - { - case TYPE_PAGE: - fromWnd = &aWndPage; - fromArr = &aPageArr; - break; + size_t nAt = 0; + ScDPFieldControlBase* toWnd = GetFieldWindow(eToType); + ScDPFieldControlBase* rmWnd1 = NULL; + ScDPFieldControlBase* rmWnd2 = NULL; + GetOtherFieldWindows(eToType, rmWnd1, rmWnd2); - case TYPE_COL: - fromWnd = &aWndCol; - fromArr = &aColArr; - break; - - case TYPE_ROW: - fromWnd = &aWndRow; - fromArr = &aRowArr; - break; + ScDPFuncDataVec* toArr = GetFieldDataArray(eToType); + ScDPFuncDataVec* rmArr1 = NULL; + ScDPFuncDataVec* rmArr2 = NULL; + GetOtherDataArrays(eToType, rmArr1, rmArr2); - case TYPE_DATA: - fromWnd = &aWndData; - fromArr = &aDataArr; - break; + bool bDataArr = eToType == TYPE_DATA; - default: + if ( (!Contains( toArr, aFuncData.mnCol, nAt )) ) + { + // ggF. in anderem Fenster entfernen + if ( rmArr1 ) + { + if ( Contains( rmArr1, aFuncData.mnCol, nAt ) ) { - // added to avoid warnings + rmWnd1->DelField( nAt ); + Remove( rmArr1, nAt ); } } - - switch ( eToType ) + if ( rmArr2 ) { - 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; + if ( Contains( rmArr2, aFuncData.mnCol, nAt ) ) + { + rmWnd2->DelField( nAt ); + Remove( rmArr2, nAt ); + } + } - case TYPE_ROW: - toWnd = &aWndRow; - toArr = &aRowArr; - rmWnd1 = &aWndPage; - rmWnd2 = &aWndCol; - rmArr1 = &aPageArr; - rmArr2 = &aColArr; - break; + ScDPLabelData& rData = aLabelDataArr[nFromIndex+nOffset]; + size_t nAddedAt = 0; - case TYPE_DATA: - toWnd = &aWndData; - toArr = &aDataArr; - bDataArr = TRUE; - break; + if ( !bDataArr ) + { + if ( toWnd->AppendField(rData.getDisplayName(), nAddedAt) ) + { + Insert( toArr, aFuncData, nAddedAt ); + toWnd->GrabFocus(); + } + } + else + { + ScDPLabelData* p = GetLabelData(aFuncData.mnCol); + OUString aStr = p->maLayoutName; + USHORT nMask = aFuncData.mnFuncMask; + if (!aStr.getLength()) + { + aStr = GetFuncString(nMask); + aStr += p->maName; + } - default: + if ( toWnd->AppendField(aStr, nAddedAt) ) { - // added to avoid warnings + aFuncData.mnFuncMask = nMask; + Insert( toArr, aFuncData, 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 ) + { + ScDPFieldControlBase* fromWnd = GetFieldWindow(eFromType); + ScDPFieldControlBase* toWnd = GetFieldWindow(eToType); + + ScDPFieldControlBase* rmWnd1 = NULL; + ScDPFieldControlBase* rmWnd2 = NULL; + GetOtherFieldWindows(eToType, rmWnd1, rmWnd2); + + ScDPFuncDataVec* fromArr = GetFieldDataArray(eFromType); + ScDPFuncDataVec* toArr = GetFieldDataArray(eToType); + + ScDPFuncDataVec* rmArr1 = NULL; + ScDPFuncDataVec* rmArr2 = NULL; + GetOtherDataArrays(eToType, rmArr1, rmArr2); + + size_t nAt = 0; + bool bDataArr = eToType == TYPE_DATA; if ( fromArr && toArr && fromWnd && toWnd ) { @@ -742,8 +674,7 @@ void ScDPLayoutDlg::MoveField( ScDPFieldType eFromType, size_t nFromIndex, ScDPF fromWnd->DelField( nAt ); Remove( fromArr, nAt ); - if ( (toArr->back().get() == NULL) - && (!Contains( toArr, fData.mnCol, nAt )) ) + if (!Contains( toArr, fData.mnCol, nAt )) { size_t nAddedAt = 0; if ( !bDataArr ) @@ -800,47 +731,156 @@ void ScDPLayoutDlg::MoveField( ScDPFieldType eFromType, size_t nFromIndex, ScDPF } else // -> eFromType == eToType { - ScDPFieldWindow* theWnd = NULL; - ScDPFuncDataVec* theArr = NULL; + ScDPFieldControlBase* theWnd = GetFieldWindow(eFromType); + ScDPFuncDataVec* theArr = GetFieldDataArray(eFromType); size_t nAt = 0; size_t nToIndex = 0; Point aToPos; - BOOL bDataArr = FALSE; + BOOL bDataArr = eFromType == TYPE_DATA; - switch ( eFromType ) + ScDPFuncData fData( *((*theArr)[nFromIndex]) ); + + if ( Contains( theArr, fData.mnCol, nAt ) ) { - case TYPE_PAGE: - theWnd = &aWndPage; - theArr = &aPageArr; - break; + aToPos = DlgPos2WndPos( rAtPos, *theWnd ); + theWnd->GetExistingIndex( aToPos, nToIndex ); - case TYPE_COL: - theWnd = &aWndCol; - theArr = &aColArr; - break; + if ( nToIndex != nAt ) + { + size_t nAddedAt = 0; - case TYPE_ROW: - theWnd = &aWndRow; - theArr = &aRowArr; - break; + theWnd->DelField( nAt ); + Remove( theArr, nAt ); - case TYPE_DATA: - theWnd = &aWndData; - theArr = &aDataArr; - bDataArr = TRUE; - break; + if ( !bDataArr ) + { + if ( theWnd->AddField( GetLabelString( fData.mnCol ), + aToPos, + nAddedAt ) ) + { + Insert( theArr, fData, nAddedAt ); + } + } + else + { + ScDPLabelData* p = GetLabelData(fData.mnCol); + OUString aStr = p->maLayoutName; + USHORT nMask = fData.mnFuncMask; + if (!aStr.getLength()) + { + aStr = GetFuncString(nMask); + aStr += p->maName; + } - default: + if ( theWnd->AddField( aStr, + DlgPos2WndPos( rAtPos, *theWnd ), + nAddedAt ) ) + { + fData.mnFuncMask = nMask; + Insert( theArr, fData, nAddedAt ); + } + } + } + } + } +} + +void ScDPLayoutDlg::MoveFieldToEnd( ScDPFieldType eFromType, size_t nFromIndex, ScDPFieldType eToType ) +{ + if ( eFromType == TYPE_SELECT ) + AppendField( nFromIndex, eToType ); + else if ( eFromType != eToType ) + { + ScDPFieldControlBase* fromWnd = GetFieldWindow(eFromType); + ScDPFieldControlBase* toWnd = GetFieldWindow(eToType); + + ScDPFieldControlBase* rmWnd1 = NULL; + ScDPFieldControlBase* rmWnd2 = NULL; + GetOtherFieldWindows(eToType, rmWnd1, rmWnd2); + + ScDPFuncDataVec* fromArr = GetFieldDataArray(eFromType); + ScDPFuncDataVec* toArr = GetFieldDataArray(eToType); + + ScDPFuncDataVec* rmArr1 = NULL; + ScDPFuncDataVec* rmArr2 = NULL; + GetOtherDataArrays(eToType, rmArr1, rmArr2); + + size_t nAt = 0; + bool bDataArr = eToType == TYPE_DATA; + + if ( fromArr && toArr && fromWnd && toWnd ) + { + ScDPFuncData fData( *((*fromArr)[nFromIndex]) ); + + if ( Contains( fromArr, fData.mnCol, nAt ) ) { - // added to avoid warnings + fromWnd->DelField( nAt ); + Remove( fromArr, nAt ); + + if (!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->AppendField( GetLabelString( fData.mnCol ), nAddedAt ) ) + { + Insert( toArr, fData, nAddedAt ); + toWnd->GrabFocus(); + } + } + else + { + ScDPLabelData* p = GetLabelData(fData.mnCol); + OUString aStr = p->maLayoutName; + USHORT nMask = fData.mnFuncMask; + if (!aStr.getLength()) + { + aStr = GetFuncString(nMask); + aStr += p->maName; + } + + if ( toWnd->AppendField(aStr, nAddedAt) ) + { + fData.mnFuncMask = nMask; + Insert( toArr, fData, nAddedAt ); + toWnd->GrabFocus(); + } + } + } } } + } + else // -> eFromType == eToType + { + ScDPFieldControlBase* theWnd = GetFieldWindow(eFromType); + ScDPFuncDataVec* theArr = GetFieldDataArray(eFromType); + size_t nAt = 0; + size_t nToIndex = 0; + Point aToPos; + BOOL bDataArr = eFromType == TYPE_DATA; ScDPFuncData fData( *((*theArr)[nFromIndex]) ); if ( Contains( theArr, fData.mnCol, nAt ) ) { - aToPos = DlgPos2WndPos( rAtPos, *theWnd ); theWnd->GetExistingIndex( aToPos, nToIndex ); if ( nToIndex != nAt ) @@ -852,9 +892,7 @@ void ScDPLayoutDlg::MoveField( ScDPFieldType eFromType, size_t nFromIndex, ScDPF if ( !bDataArr ) { - if ( theWnd->AddField( GetLabelString( fData.mnCol ), - aToPos, - nAddedAt ) ) + if ( theWnd->AppendField(GetLabelString( fData.mnCol ), nAddedAt) ) { Insert( theArr, fData, nAddedAt ); } @@ -870,9 +908,7 @@ void ScDPLayoutDlg::MoveField( ScDPFieldType eFromType, size_t nFromIndex, ScDPF aStr += p->maName; } - if ( theWnd->AddField( aStr, - DlgPos2WndPos( rAtPos, *theWnd ), - nAddedAt ) ) + if ( theWnd->AppendField(aStr, nAddedAt) ) { fData.mnFuncMask = nMask; Insert( theArr, fData, nAddedAt ); @@ -887,25 +923,17 @@ void ScDPLayoutDlg::MoveField( ScDPFieldType eFromType, size_t nFromIndex, ScDPF 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 - } - } + ScDPFuncDataVec* pArr = GetFieldDataArray(eFromType); if( pArr ) { - ScDPFieldWindow& rWnd = GetFieldWindow( eFromType ); - rWnd.DelField( nIndex ); - Remove( pArr, nIndex ); - if( rWnd.IsEmpty() ) InitFocus(); + ScDPFieldControlBase* pWnd = GetFieldWindow( eFromType ); + if (pWnd) + { + pWnd->DelField( nIndex ); + Remove( pArr, nIndex ); + if( pWnd->IsEmpty() ) InitFocus(); + } } } @@ -956,7 +984,6 @@ void ScDPLayoutDlg::NotifyMouseButtonUp( const Point& rAt ) } } - //---------------------------------------------------------------------------- PointerStyle ScDPLayoutDlg::NotifyMouseMove( const Point& rAt ) @@ -1006,7 +1033,6 @@ PointerStyle ScDPLayoutDlg::NotifyMouseMove( const Point& rAt ) return ePtr; } - //---------------------------------------------------------------------------- PointerStyle ScDPLayoutDlg::NotifyMouseButtonDown( ScDPFieldType eType, size_t nFieldIndex ) @@ -1017,23 +1043,11 @@ PointerStyle ScDPLayoutDlg::NotifyMouseButtonDown( ScDPFieldType eType, size_t n 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 - } - } + ScDPFuncDataVec* pArr = GetFieldDataArray(eType); if ( pArr ) { @@ -1140,7 +1154,8 @@ void ScDPLayoutDlg::NotifyFieldFocus( ScDPFieldType eType, BOOL bGotFocus ) // #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() ) + ScDPFieldControlBase* pWnd = GetFieldWindow(eType); + if ( bEnable && bGotFocus && pWnd && pWnd->IsEmpty() ) bEnable = FALSE; aBtnRemove.Enable( bEnable ); @@ -1151,16 +1166,18 @@ void ScDPLayoutDlg::NotifyFieldFocus( ScDPFieldType eType, BOOL bGotFocus ) //---------------------------------------------------------------------------- -void ScDPLayoutDlg::NotifyMoveField( ScDPFieldType eToType ) +void ScDPLayoutDlg::NotifyMoveFieldToEnd( ScDPFieldType eToType ) { - ScDPFieldWindow& rWnd = GetFieldWindow( eLastActiveType ); - if( (eToType != TYPE_SELECT) && !rWnd.IsEmpty() ) + ScDPFieldControlBase* pWnd = GetFieldWindow(eLastActiveType); + ScDPFieldControlBase* pToWnd = GetFieldWindow(eToType); + if (pWnd && pToWnd && (eToType != TYPE_SELECT) && !pWnd->IsEmpty()) { - MoveField( eLastActiveType, rWnd.GetSelectedField(), eToType, GetFieldWindow( eToType ).GetLastPosition() ); - if( rWnd.IsEmpty() ) + MoveFieldToEnd(eLastActiveType, pWnd->GetSelectedField(), eToType); + + if( pWnd->IsEmpty() ) NotifyFieldFocus( eToType, TRUE ); else - rWnd.GrabFocus(); + pWnd->GrabFocus(); if( eLastActiveType == TYPE_SELECT ) aWndSelect.SelectNext(); } @@ -1208,24 +1225,22 @@ void ScDPLayoutDlg::Deactivate() BOOL ScDPLayoutDlg::Contains( ScDPFuncDataVec* pArr, SCsCOL nCol, size_t& nAt ) { - if ( !pArr ) + if (!pArr || pArr->empty()) return FALSE; - BOOL bFound = FALSE; - size_t i = 0; - - while ( (i<pArr->size()) && ((*pArr)[i].get() != NULL) && !bFound ) + ScDPFuncDataVec::const_iterator itr, itrBeg = pArr->begin(), itrEnd = pArr->end(); + for (itr = itrBeg; itr != itrEnd; ++itr) { - bFound = ((*pArr)[i]->mnCol == nCol); - if ( bFound ) - nAt = i; - i++; + if ((*itr)->mnCol == nCol) + { + // found! + nAt = ::std::distance(itrBeg, itr); + return true; + } } - - return bFound; + return false; } - //---------------------------------------------------------------------------- void ScDPLayoutDlg::Remove( ScDPFuncDataVec* pArr, size_t nAt ) @@ -1234,32 +1249,22 @@ void ScDPLayoutDlg::Remove( ScDPFuncDataVec* pArr, size_t nAt ) 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()) ) + if (!pArr) return; - if ( (*pArr)[nAt].get() == NULL ) - { - (*pArr)[nAt].reset( new ScDPFuncData( rFData ) ); - } + ScDPFuncDataRef p (new ScDPFuncData(rFData)); + if (nAt >= pArr->size()) + pArr->push_back(p); else - { - if ( pArr->back().get() == NULL ) // mind. ein Slot frei? - { - pArr->insert( pArr->begin() + nAt, ScDPFuncDataRef( new ScDPFuncData( rFData ) ) ); - pArr->erase( pArr->end() - 1 ); - } - } + pArr->insert(pArr->begin() + nAt, p); } - //---------------------------------------------------------------------------- ScDPLabelData* ScDPLayoutDlg::GetLabelData( SCsCOL nCol, size_t* pnPos ) @@ -1276,7 +1281,6 @@ ScDPLabelData* ScDPLayoutDlg::GetLabelData( SCsCOL nCol, size_t* pnPos ) return pData; } - //---------------------------------------------------------------------------- String ScDPLayoutDlg::GetLabelString( SCsCOL nCol ) @@ -1351,7 +1355,6 @@ String ScDPLayoutDlg::GetFuncString( USHORT& rFuncMask, BOOL bIsValue ) return aStr; } - //---------------------------------------------------------------------------- Point ScDPLayoutDlg::DlgPos2WndPos( const Point& rPt, Window& rWnd ) @@ -1363,29 +1366,39 @@ Point ScDPLayoutDlg::DlgPos2WndPos( const Point& rPt, Window& rWnd ) 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 ) ); + long nFldW = FIELD_BTN_WIDTH; + long nFldH = FIELD_BTN_HEIGHT; + aWndData.SetSizePixel(Size(338, 185)); + aWndPage.SetSizePixel( + Size(aWndData.GetSizePixel().Width() + 85, + aWndCol.GetPosPixel().Y() - aWndPage.GetPosPixel().Y() - FIELD_AREA_GAP)); + aWndRow.SetSizePixel( + Size(aWndData.GetPosPixel().X()-aWndRow.GetPosPixel().X() - FIELD_AREA_GAP, + aWndData.GetSizePixel().Height())); + aWndCol.SetSizePixel( + Size(aWndData.GetPosPixel().X() - aWndCol.GetPosPixel().X() + aWndData.GetSizePixel().Width(), + aWndData.GetPosPixel().Y() - aWndCol.GetPosPixel().Y() - FIELD_AREA_GAP)); // #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() ) ); + 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 ) ); + aWndSelect.SetSizePixel( + Size(2 * nFldW + SELECT_FIELD_BTN_SPACE, + LINE_SIZE * nFldH + (LINE_SIZE - 1) * SELECT_FIELD_BTN_SPACE)); // scroll bar Point aSliderPos( aWndSelect.GetPosPixel() ); Size aSliderSize( aWndSelect.GetSizePixel() ); - aSliderPos.Y() += aSliderSize.Height() + SSPACE; + aSliderPos.Y() += aSliderSize.Height() + SELECT_FIELD_BTN_SPACE; aSliderSize.Height() = GetSettings().GetStyleSettings().GetScrollBarSize(); aSlider.SetPosSizePixel( aSliderPos, aSliderSize ); @@ -1394,47 +1407,62 @@ void ScDPLayoutDlg::CalcWndSizes() aRectCol = Rectangle( aWndCol.GetPosPixel(), aWndCol.GetSizePixel() ); aRectData = Rectangle( aWndData.GetPosPixel(), aWndData.GetSizePixel() ); aRectSelect = Rectangle( aWndSelect.GetPosPixel(), aWndSelect.GetSizePixel() ); -} + aWndPage.CalcSize(); + aWndRow.CalcSize(); + aWndCol.CalcSize(); + aWndData.CalcSize(); +} -//---------------------------------------------------------------------------- +namespace { -BOOL ScDPLayoutDlg::GetPivotArrays( PivotField* pPageArr, - PivotField* pColArr, - PivotField* pRowArr, - PivotField* pDataArr, - USHORT& rPageCount, - USHORT& rColCount, - USHORT& rRowCount, - USHORT& rDataCount ) +class PivotFieldInserter : public ::std::unary_function<void, boost::shared_ptr<ScDPFuncData> > { - BOOL bFit = TRUE; - USHORT i=0; + vector<PivotField>& mrFields; +public: + explicit PivotFieldInserter(vector<PivotField>& r, size_t nSize) : mrFields(r) + { + mrFields.reserve(nSize); + } - for ( i=0; (i<aDataArr.size()) && (aDataArr[i].get() != NULL ); i++ ) - lcl_FillToPivotField( pDataArr[i], *aDataArr[i] ); - rDataCount = i; + PivotFieldInserter(const PivotFieldInserter& r) : mrFields(r.mrFields) {} - for ( i=0; (i<aPageArr.size()) && (aPageArr[i].get() != NULL ); i++ ) - lcl_FillToPivotField( pPageArr[i], *aPageArr[i] ); - rPageCount = i; + void operator() (const ::boost::shared_ptr<ScDPFuncData>& p) + { + PivotField aField; + aField.nCol = p->mnCol; + aField.nFuncMask = p->mnFuncMask; + aField.maFieldRef = p->maFieldRef; + mrFields.push_back(aField); + } +}; - 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; +bool ScDPLayoutDlg::GetPivotArrays( + vector<PivotField>& rPageFields, vector<PivotField>& rColFields, + vector<PivotField>& rRowFields, vector<PivotField>& rDataFields ) +{ + vector<PivotField> aPageFields; + for_each(aPageArr.begin(), aPageArr.end(), PivotFieldInserter(aPageFields, aPageArr.size())); - 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 + vector<PivotField> aColFields; + for_each(aColArr.begin(), aColArr.end(), PivotFieldInserter(aColFields, aColArr.size())); - return bFit; + // default data pilot table always has an extra row field as a data layout field. + vector<PivotField> aRowFields; + for_each(aRowArr.begin(), aRowArr.end(), PivotFieldInserter(aRowFields, aRowArr.size()+1)); + aRowFields.push_back(PivotField(PIVOT_DATA_FIELD, 0)); + + vector<PivotField> aDataFields; + for_each(aDataArr.begin(), aDataArr.end(), PivotFieldInserter(aDataFields, aDataArr.size())); + + rPageFields.swap(aPageFields); + rColFields.swap(aColFields); + rRowFields.swap(aRowFields); + rDataFields.swap(aDataFields); + + return true; } void ScDPLayoutDlg::UpdateSrcRange() @@ -1469,20 +1497,102 @@ void ScDPLayoutDlg::UpdateSrcRange() aWndCol.ClearFields(); aWndPage.ClearFields(); - for (size_t i = 0; i < MAX_LABELS; ++i) - aSelectArr[i].reset(); + aSelectArr.clear(); + aSelectArr.resize(PAGE_SIZE); + + aRowArr.clear(); + aColArr.clear(); + aDataArr.clear(); + aPageArr.clear(); + + InitFields(); +} - for (size_t i = 0; i < MAX_FIELDS; ++i) +ScDPFieldControlBase* ScDPLayoutDlg::GetFieldWindow(ScDPFieldType eType) +{ + switch (eType) { - aRowArr[i].reset(); - aColArr[i].reset(); - aDataArr[i].reset(); + case TYPE_PAGE: + return &aWndPage; + case TYPE_COL: + return &aWndCol; + case TYPE_ROW: + return &aWndRow; + case TYPE_DATA: + return &aWndData; + case TYPE_SELECT: + return &aWndSelect; + default: + ; } + return NULL; +} - for (size_t i = 0; i < MAX_PAGEFIELDS; ++i) - aPageArr[i].reset(); +void ScDPLayoutDlg::GetOtherFieldWindows(ScDPFieldType eType, ScDPFieldControlBase*& rpWnd1, ScDPFieldControlBase*& rpWnd2) +{ + rpWnd1 = NULL; + rpWnd2 = NULL; + switch (eType) + { + case TYPE_PAGE: + rpWnd1 = &aWndRow; + rpWnd2 = &aWndCol; + break; + case TYPE_COL: + rpWnd1 = &aWndPage; + rpWnd2 = &aWndRow; + break; + case TYPE_ROW: + rpWnd1 = &aWndPage; + rpWnd2 = &aWndCol; + break; + default: + ; + } +} - InitFields(); +ScDPLayoutDlg::ScDPFuncDataVec* ScDPLayoutDlg::GetFieldDataArray(ScDPFieldType eType) +{ + switch (eType) + { + case TYPE_PAGE: + return &aPageArr; + case TYPE_COL: + return &aColArr; + case TYPE_ROW: + return &aRowArr; + case TYPE_DATA: + return &aDataArr; + case TYPE_SELECT: + return &aSelectArr; + default: + ; + } + return NULL; +} + +void ScDPLayoutDlg::GetOtherDataArrays( + ScDPFieldType eType, ScDPFuncDataVec*& rpArr1, ScDPFuncDataVec*& rpArr2) +{ + rpArr1 = NULL; + rpArr2 = NULL; + switch (eType) + { + case TYPE_PAGE: + rpArr1 = &aRowArr; + rpArr2 = &aColArr; + break; + case TYPE_COL: + rpArr1 = &aPageArr; + rpArr2 = &aRowArr; + break; + case TYPE_ROW: + rpArr1 = &aPageArr; + rpArr2 = &aColArr; + break; + default: + ; + } } //---------------------------------------------------------------------------- @@ -1509,7 +1619,6 @@ void ScDPLayoutDlg::SetReference( const ScRange& rRef, ScDocument* pDocP ) } } - //---------------------------------------------------------------------------- void ScDPLayoutDlg::SetActive() @@ -1538,17 +1647,19 @@ void ScDPLayoutDlg::SetActive() IMPL_LINK( ScDPLayoutDlg, ClickHdl, PushButton *, pBtn ) { + ScDPFieldControlBase* pWnd = GetFieldWindow( eLastActiveType ); + if (!pWnd) + return 0; + if( pBtn == &aBtnRemove ) { - ScDPFieldWindow& rWnd = GetFieldWindow( eLastActiveType ); - RemoveField( eLastActiveType, rWnd.GetSelectedField() ); - if( !rWnd.IsEmpty() ) rWnd.GrabFocus(); + RemoveField( eLastActiveType, pWnd->GetSelectedField() ); + if( !pWnd->IsEmpty() ) pWnd->GrabFocus(); } else if( pBtn == &aBtnOptions ) { - ScDPFieldWindow& rWnd = GetFieldWindow( eLastActiveType ); - NotifyDoubleClick( eLastActiveType, rWnd.GetSelectedField() ); - rWnd.GrabFocus(); + NotifyDoubleClick( eLastActiveType, pWnd->GetSelectedField() ); + pWnd->GrabFocus(); } return 0; } @@ -1562,169 +1673,158 @@ IMPL_LINK( ScDPLayoutDlg, OkHdl, OKButton *, EMPTYARG ) 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)) ) ) + if (!bToNewTable && (aOutPosStr.Len() == 0 || (nResult & SCA_VALID) != SCA_VALID)) { - //@BugID 54702 Enablen/Disablen nur noch in Basisklasse - //SFX_APPWINDOW->Enable(); + // Invalid reference. Bail out. + if ( !aBtnMore.GetState() ) + aBtnMore.SetState(true); - 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); + ErrorBox(this, WinBits(WB_OK | WB_DEF_OK), ScGlobal::GetRscString(STR_INVALID_TABREF)).Execute(); + aEdOutPos.GrabFocus(); + return 0; + } - const OUString* pSubtotalName = pOldDim->GetSubtotalName(); - if (pSubtotalName) - pDim->SetSubtotalName(*pSubtotalName); - } - } + ScPivotParam theOutParam; + vector<PivotField> aPageFields; + vector<PivotField> aColFields; + vector<PivotField> aRowFields; + vector<PivotField> aDataFields; - bool bManualSort = ( aIt->maSortInfo.Mode == sheet::DataPilotFieldSortMode::MANUAL ); + // Convert an array of function data into an array of pivot field data. + bool bFit = GetPivotArrays(aPageFields, aColFields, aRowFields, aDataFields); - // 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); + if (!bFit) + { + // General data pilot table error. Bail out. + ErrorBox(this, WinBits(WB_OK | WB_DEF_OK), ScGlobal::GetRscString(STR_PIVOT_ERROR)).Execute(); + return 0; + } - // #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) + 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, aPageFields, sheet::DataPilotFieldOrientation_PAGE, xSource ); + ScDPObject::ConvertOrientation( + aSaveData, aColFields, sheet::DataPilotFieldOrientation_COLUMN, xSource ); + ScDPObject::ConvertOrientation( + aSaveData, aRowFields, sheet::DataPilotFieldOrientation_ROW, xSource ); + ScDPObject::ConvertOrientation( + aSaveData, aDataFields, sheet::DataPilotFieldOrientation_DATA, xSource, + &aColFields, &aRowFields, &aPageFields ); + + 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) { - ScDPSaveDimension* pOldDim = pOldSaveData->GetDataLayoutDimension(); + // 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); } } - 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(); + bool bManualSort = ( aIt->maSortInfo.Mode == sheet::DataPilotFieldSortMode::MANUAL ); - // #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) + // visibility of members + for (vector<ScDPLabelData::Member>::const_iterator itr = aIt->maMembers.begin(), itrEnd = aIt->maMembers.end(); + itr != itrEnd; ++itr) { - 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); + 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); + } + } } } - else + } + ScDPSaveDimension* pDim = aSaveData.GetDataLayoutDimension(); + if (pDim && pOldSaveData) + { + ScDPSaveDimension* pOldDim = pOldSaveData->GetDataLayoutDimension(); + if (pOldDim) { - ErrorBox( this, WinBits( WB_OK | WB_DEF_OK ), - ScGlobal::GetRscString( STR_PIVOT_ERROR ) - ).Execute(); + 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 { - if ( !aBtnMore.GetState() ) - aBtnMore.SetState( TRUE ); - - ErrorBox( this, WinBits( WB_OK | WB_DEF_OK ), - ScGlobal::GetRscString( STR_INVALID_TABREF ) - ).Execute(); - aEdOutPos.GrabFocus(); + // Table insertion failed. Keep the dialog open. + bRefInputMode = true; + SetDispatcherLock(true); } + return 0; } - //---------------------------------------------------------------------------- IMPL_LINK( ScDPLayoutDlg, CancelHdl, CancelButton *, EMPTYARG ) @@ -1733,7 +1833,6 @@ IMPL_LINK( ScDPLayoutDlg, CancelHdl, CancelButton *, EMPTYARG ) return 0; } - //---------------------------------------------------------------------------- IMPL_LINK( ScDPLayoutDlg, MoreClickHdl, MoreButton *, EMPTYARG ) @@ -1765,7 +1864,6 @@ IMPL_LINK( ScDPLayoutDlg, MoreClickHdl, MoreButton *, EMPTYARG ) return 0; } - //---------------------------------------------------------------------------- IMPL_LINK( ScDPLayoutDlg, EdModifyHdl, Edit *, EMPTYARG ) @@ -1794,14 +1892,12 @@ IMPL_LINK( ScDPLayoutDlg, EdModifyHdl, Edit *, EMPTYARG ) return 0; } - IMPL_LINK( ScDPLayoutDlg, EdInModifyHdl, Edit *, EMPTYARG ) { UpdateSrcRange(); return 0; } - //---------------------------------------------------------------------------- IMPL_LINK( ScDPLayoutDlg, SelAreaHdl, ListBox *, EMPTYARG ) @@ -1828,7 +1924,6 @@ IMPL_LINK( ScDPLayoutDlg, SelAreaHdl, ListBox *, EMPTYARG ) return 0; } - //---------------------------------------------------------------------------- IMPL_LINK( ScDPLayoutDlg, ScrollHdl, ScrollBar *, EMPTYARG ) diff --git a/sc/source/ui/inc/AccessibleDataPilotControl.hxx b/sc/source/ui/inc/AccessibleDataPilotControl.hxx index 7d9c3f470bb8..fb0e0f40ecd6 100644 --- a/sc/source/ui/inc/AccessibleDataPilotControl.hxx +++ b/sc/source/ui/inc/AccessibleDataPilotControl.hxx @@ -32,7 +32,7 @@ #include "AccessibleContextBase.hxx" -class ScDPFieldWindow; +class ScDPFieldControlBase; class ScAccessibleDataPilotButton; class ScAccessibleDataPilotControl @@ -43,7 +43,7 @@ public: ScAccessibleDataPilotControl( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible>& rxParent, - ScDPFieldWindow* pDPFieldWindow); + ScDPFieldControlBase* pDPFieldWindow); virtual void Init(); @@ -132,7 +132,7 @@ protected: throw (::com::sun::star::uno::RuntimeException); private: - ScDPFieldWindow* mpDPFieldWindow; + ScDPFieldControlBase* mpDPFieldWindow; struct AccessibleWeak { ::com::sun::star::uno::WeakReference< ::com::sun::star::accessibility::XAccessible > xWeakAcc; diff --git a/sc/source/ui/inc/fieldwnd.hxx b/sc/source/ui/inc/fieldwnd.hxx index bc7ccfe135cc..77c6b6644be8 100644 --- a/sc/source/ui/inc/fieldwnd.hxx +++ b/sc/source/ui/inc/fieldwnd.hxx @@ -31,18 +31,15 @@ #include <vector> #include "address.hxx" +#include "dpglobal.hxx" #include <vcl/ctrl.hxx> #include <vcl/fixed.hxx> +#include <vcl/scrbar.hxx> #include <cppuhelper/weakref.hxx> #define PAGE_SIZE 16 // count of visible fields for scrollbar #define LINE_SIZE 8 // count of fields per column for scrollbar #define MAX_FIELDS 8 // maximum count of fields for row/col/data area -#define MAX_PAGEFIELDS 10 // maximum count of fields for page area - -#define OWIDTH PivotGlobal::nObjWidth -#define OHEIGHT PivotGlobal::nObjHeight -#define SSPACE PivotGlobal::nSelSpace class ScDPLayoutDlg; class ScAccessibleDataPilotControl; @@ -61,53 +58,155 @@ enum ScDPFieldType //------------------------------------------------------------------- -/** Represents a field area in the DataPilot layout dialog. */ -class ScDPFieldWindow : public Control +/** + * Represents a field area in the DataPilot layout dialog. This base class + * handles storage of field names and the accessibility object. + */ +class ScDPFieldControlBase : public Control { -private: - typedef ::std::pair< String, bool > FieldString; // true = text fits into button - - String aName; /// name of the control, used in Accessibility - ScDPLayoutDlg* pDlg; /// Parent dialog. - Rectangle aWndRect; /// Area rectangle in pixels. - FixedText* pFtCaption; /// FixedText containing the name of the control. - Point aTextPos; /// Position of the caption text. - std::vector< FieldString > aFieldArr; /// String array of the field names and flags, if text fits into button. - ScDPFieldType eType; /// Type of this area. - Color aFaceColor; /// Color for dialog background. - Color aWinColor; /// Color for window background. - Color aTextColor; /// Color for text in buttons. - Color aWinTextColor; /// Color for text in field windows. - size_t nFieldSize; /// Maximum count of fields. - size_t nFieldSelected; /// Currently selected field. +protected: + typedef ::std::pair<String, bool> FieldName; // true = text fits into button + typedef ::std::vector<FieldName> FieldNames; - com::sun::star::uno::WeakReference< ::com::sun::star::accessibility::XAccessible > xAccessible; - ScAccessibleDataPilotControl* pAccessible; +public: + ScDPFieldControlBase( + ScDPLayoutDlg* pParent, const ResId& rResId, FixedText* pCaption ); + virtual ~ScDPFieldControlBase(); + + virtual void CalcSize() = 0; + + virtual bool IsValidIndex( size_t nIndex ) const = 0; + /** @return The pixel position of a field (without bound check). */ + virtual Point GetFieldPosition( size_t nIndex ) = 0; + /** Calculates the field index at a specific pixel position. + @param rnIndex The index of the field is returned here. + @return TRUE, if the index value is valid. */ + virtual bool GetFieldIndex( const Point& rPos, size_t& rnIndex ) = 0; + /** @return The pixel size of a field. */ + virtual Size GetFieldSize() const = 0; + + /** @return The description of the control which is used for the accessibility objects. */ + virtual String GetDescription() const = 0; + /** @return The type of the FieldWindow. */ + virtual ScDPFieldType GetFieldType() const = 0; + virtual void ScrollToShowSelection() = 0; + virtual void ScrollToEnd() = 0; + virtual void ResetScrollBar() = 0; + + /** Reads the FixedText's text with mnemonic and hides the FixedText. */ + void UseMnemonic(); + + /** @return The name of the control without shortcut. */ + ::rtl::OUString GetName() const; + void SetName(const ::rtl::OUString& rName); + + /** @return TRUE, if the field with the given index exists. */ + bool IsExistingIndex( size_t nIndex ) const; + + /** Inserts a field to the specified index. */ + void AddField( const String& rText, size_t nNewIndex ); + + /** Inserts a field using the specified pixel position. + @param rPos The coordinates to insert the field. + @param rnIndex The new index of the field is returned here. + @return true, if the field has been created. */ + bool AddField( const String& rText, const Point& rPos, size_t& rnIndex ); + + bool AppendField(const String& rText, size_t& rnIndex); + + /** Removes a field from the specified index. */ + void DelField( size_t nDelIndex ); + + /** @return The count of existing fields. */ + size_t GetFieldCount() const; + + bool IsEmpty() const; + + /** Removes all fields. */ + void ClearFields(); + /** Changes the text on an existing field. */ + void SetFieldText( const String& rText, size_t nIndex ); + /** Returns the text of an existing field. */ + const String& GetFieldText( size_t nIndex ) const; + + /** Calculates a field index at a specific pixel position. Returns in every + case the index of an existing field. + @param rnIndex The index of the field is returned here. + @return TRUE, if the index value is valid. */ + void GetExistingIndex( const Point& rPos, size_t& rnIndex ); + + size_t GetSelectedField() const; + void SetSelectedField(size_t nSelected); + + /** Notifies this control that the offset of the first field has been changed. + The control has to adjust the selection to keep the same field selected + on scrolling with scrollbar. */ + void ModifySelectionOffset( long nOffsetDiff ); + /** Selects the next field. Called i.e. after moving a field from SELECT area. */ + void SelectNext(); + /** Grabs focus and sets new selection. */ + void GrabFocusWithSel( size_t nIndex ); - /** Initilize the object. */ - void Init(); + virtual void Paint( const Rectangle& rRect ); + virtual void DataChanged( const DataChangedEvent& rDCEvt ); + virtual void MouseButtonDown( const MouseEvent& rMEvt ); + virtual void MouseButtonUp( const MouseEvent& rMEvt ); + virtual void MouseMove( const MouseEvent& rMEvt ); + virtual void KeyInput( const KeyEvent& rKEvt ); + virtual void GetFocus(); + virtual void LoseFocus(); + +protected: + FieldNames& GetFieldNames(); + const FieldNames& GetFieldNames() const; - /** Reads all needed style settings. */ - void GetStyleSettings(); + virtual ::com::sun::star::uno::Reference< + ::com::sun::star::accessibility::XAccessible > CreateAccessible(); + + void FieldFocusChanged(size_t nOldSelected, size_t nFieldSelected); + void AccessibleSetFocus(bool bOn); + + /** Updates the tab stop style bits. */ + void UpdateStyle(); /** Draws the background. */ - void DrawBackground( OutputDevice& rDev ); + void DrawBackground( OutputDevice& rDev ); + /** Draws a field into the specified rectangle. */ - void DrawField( - OutputDevice& rDev, - const Rectangle& rRect, - FieldString& rText, - bool bFocus ); - - /** @return TRUE, if the field index is inside of the control area. */ - bool IsValidIndex( size_t nIndex ) const; - /** @return TRUE, if the field with the given index exists. */ - bool IsExistingIndex( size_t nIndex ) const; + void DrawField( + OutputDevice& rDev, const Rectangle& rRect, FieldName& rText, bool bFocus ); + + ScDPLayoutDlg* GetParentDlg() const; + + void AppendPaintable(Window* p); + void DrawPaintables(); + void DrawInvertSelection(); + + /** @return The new selection index after moving to the given direction. */ + virtual size_t CalcNewFieldIndex( SCsCOL nDX, SCsROW nDY ) const = 0; + + /** + * @param nIndex logical index of a field name, independent of scroll + * offsets. + * @return Display position of the button. The first displayed button is + * always 0 no matter what the current scroll offset is. In case + * the field specified by the index is outside the visible range, + * <code>INVALID_INDEX</code> is returned. + */ + virtual size_t GetDisplayPosition(size_t nIndex) const = 0; + + /** Draws the complete control. */ + virtual void Redraw() = 0; + +private: /** @return TRUE, if the field with the given index exists and the text is too long for the button control. */ bool IsShortenedText( size_t nIndex ) const; - /** @return The new selection index after moving to the given direction. */ - size_t CalcNewFieldIndex( SCsCOL nDX, SCsROW nDY ) const; + + /** Moves the selected field to nDestIndex. */ + void MoveField( size_t nDestIndex ); + /** Moves the selected field to the given direction. */ + void MoveFieldRel( SCsCOL nDX, SCsROW nDY ); /** Sets selection to the field with index nIndex. */ void SetSelection( size_t nIndex ); @@ -118,105 +217,214 @@ private: /** Sets selection to new position relative to current. */ void MoveSelection( USHORT nKeyCode, SCsCOL nDX, SCsROW nDY ); - /** Moves the selected field to nDestIndex. */ - void MoveField( size_t nDestIndex ); - /** Moves the selected field to the given direction. */ - void MoveFieldRel( SCsCOL nDX, SCsROW nDY ); +private: + typedef ::std::vector<Window*> Paintables; + Paintables maPaintables; - /** Updates the tab stop style bits. */ - void UpdateStyle(); + FieldNames maFieldNames; /// String array of the field names and flags, if text fits into button. + ScDPLayoutDlg* mpDlg; + FixedText* mpCaption; /// FixedText containing the name of the control. + ::rtl::OUString maName; + + size_t mnFieldSelected; /// Currently selected field. + + com::sun::star::uno::WeakReference< ::com::sun::star::accessibility::XAccessible > xAccessible; + ScAccessibleDataPilotControl* pAccessible; +}; +// ============================================================================ + +class ScDPHorFieldControl : public ScDPFieldControlBase +{ protected: - virtual void Paint( const Rectangle& rRect ); - virtual void DataChanged( const DataChangedEvent& rDCEvt ); - virtual void MouseButtonDown( const MouseEvent& rMEvt ); - virtual void MouseButtonUp( const MouseEvent& rMEvt ); - virtual void MouseMove( const MouseEvent& rMEvt ); - virtual void KeyInput( const KeyEvent& rKEvt ); - virtual void GetFocus(); - virtual void LoseFocus(); - virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > CreateAccessible(); + virtual size_t CalcNewFieldIndex(SCsCOL nDX, SCsROW nDY) const; + virtual size_t GetDisplayPosition(size_t nIndex) const; + virtual void Redraw(); public: - ScDPFieldWindow( - ScDPLayoutDlg* pDialog, - const ResId& rResId, - ScDPFieldType eFieldType, - FixedText* pFtFieldCaption ); - ScDPFieldWindow( - ScDPLayoutDlg* pDialog, - const ResId& rResId, - ScDPFieldType eFieldType, - const String& aName ); - virtual ~ScDPFieldWindow(); + ScDPHorFieldControl( + ScDPLayoutDlg* pDialog, const ResId& rResId, FixedText* pCaption ); - /** Reads the FixedText's text with mnemonic and hides the FixedText. */ - void UseMnemonic(); + virtual ~ScDPHorFieldControl(); - /** Draws the complete control. */ - void Redraw(); + virtual void CalcSize(); + virtual bool IsValidIndex( size_t nIndex ) const; + virtual Point GetFieldPosition(size_t nIndex); + virtual Size GetFieldSize() const; + virtual bool GetFieldIndex( const Point& rPos, size_t& rnIndex ); + virtual String GetDescription() const; - /** @return The pixel position of a field (without bound check). */ - Point GetFieldPosition( size_t nIndex ) const; - /** @return The pixel size of a field. */ - Size GetFieldSize() const; + virtual void ScrollToEnd(); + virtual void ScrollToShowSelection(); + virtual void ResetScrollBar(); - /** @return The index of the selected field. */ - inline bool IsEmpty() const { return aFieldArr.empty(); } - /** @return The index of the selected field. */ - inline size_t GetSelectedField() const { return nFieldSelected; } - /** @return The pixel position of the last possible field. */ - Point GetLastPosition() const; +private: + bool GetFieldBtnPosSize(size_t nPos, Point& rPos, Size& rSize); + void HandleScroll(); - /** @return The count of existing fields. */ - inline size_t GetFieldCount() const { return aFieldArr.size(); } - /** Inserts a field to the specified index. */ - void AddField( const String& rText, size_t nNewIndex ); - /** Removes a field from the specified index. */ - void DelField( size_t nDelIndex ); - /** Removes all fields. */ - void ClearFields(); - /** Changes the text on an existing field. */ - void SetFieldText( const String& rText, size_t nIndex ); - /** Returns the text of an existing field. */ - const String& GetFieldText( size_t nIndex ) const; + DECL_LINK(ScrollHdl, ScrollBar*); + DECL_LINK(EndScrollHdl, ScrollBar*); - /** Inserts a field using the specified pixel position. - @param rPos The coordinates to insert the field. - @param rnIndex The new index of the field is returned here. - @return TRUE, if the field has been created. */ - bool AddField( const String& rText, const Point& rPos, size_t& rnIndex ); - /** Calculates the field index at a specific pixel position. - @param rnIndex The index of the field is returned here. - @return TRUE, if the index value is valid. */ - bool GetFieldIndex( const Point& rPos, size_t& rnIndex ) const; - /** Calculates a field index at a specific pixel position. Returns in every - case the index of an existing field. - @param rnIndex The index of the field is returned here. - @return TRUE, if the index value is valid. */ - void GetExistingIndex( const Point& rPos, size_t& rnIndex ); +private: - /** Notifies this control that the offset of the first field has been changed. - The control has to adjust the selection to keep the same field selected - on scrolling with scrollbar. */ - void ModifySelectionOffset( long nOffsetDiff ); - /** Selects the next field. Called i.e. after moving a field from SELECT area. */ - void SelectNext(); + ScrollBar maScroll; - /** @return The name of the control without shortcut. */ - inline String GetName() const { return aName; } + size_t mnFieldBtnRowCount; + size_t mnFieldBtnColCount; +}; - /** @return The description of the control which is used for the accessibility objects. */ - String GetDescription() const; +// ============================================================================ - /** Grabs focus and sets new selection. */ - void GrabFocusWithSel( size_t nIndex ); +class ScDPPageFieldControl : public ScDPHorFieldControl +{ +public: + ScDPPageFieldControl( + ScDPLayoutDlg* pDialog, const ResId& rResId, FixedText* pCaption); + virtual ~ScDPPageFieldControl(); - /** @return The type of the FieldWindow. */ - inline ScDPFieldType GetType() const { return eType; } + virtual ScDPFieldType GetFieldType() const; }; -//=================================================================== +// ============================================================================ + +class ScDPColFieldControl : public ScDPHorFieldControl +{ +public: + ScDPColFieldControl( + ScDPLayoutDlg* pDialog, const ResId& rResId, FixedText* pCaption); + virtual ~ScDPColFieldControl(); + + virtual ScDPFieldType GetFieldType() const; +}; + +// ============================================================================ + +class ScDPRowFieldControl : public ScDPFieldControlBase +{ +public: + ScDPRowFieldControl( + ScDPLayoutDlg* pDialog, const ResId& rResId, FixedText* pCaption ); + + virtual ~ScDPRowFieldControl(); + + virtual void CalcSize(); + virtual bool IsValidIndex( size_t nIndex ) const; + virtual Point GetFieldPosition( size_t nIndex ); + virtual Size GetFieldSize() const; + virtual bool GetFieldIndex( const Point& rPos, size_t& rnIndex ); + virtual String GetDescription() const; + virtual ScDPFieldType GetFieldType() const; + + virtual void ScrollToEnd(); + virtual void ScrollToShowSelection(); + virtual void ResetScrollBar(); + +protected: + virtual size_t CalcNewFieldIndex( SCsCOL nDX, SCsROW nDY ) const; + virtual size_t GetDisplayPosition(size_t nIndex) const; + virtual void Redraw(); + +private: + bool GetFieldBtnPosSize(size_t nPos, Point& rPos, Size& rSize); + void HandleScroll(); + + DECL_LINK(ScrollHdl, ScrollBar*); + DECL_LINK(EndScrollHdl, ScrollBar*); + +private: + + ScrollBar maScroll; + size_t mnColumnBtnCount; +}; + +// ============================================================================ + +class ScDPSelectFieldControl : public ScDPFieldControlBase +{ +public: + ScDPSelectFieldControl( + ScDPLayoutDlg* pDialog, const ResId& rResId, const String& aName ); + + virtual ~ScDPSelectFieldControl(); + + virtual void CalcSize() {} + virtual bool IsValidIndex( size_t nIndex ) const; + virtual Point GetFieldPosition( size_t nIndex ); + virtual Size GetFieldSize() const; + virtual bool GetFieldIndex( const Point& rPos, size_t& rnIndex ); + virtual String GetDescription() const; + virtual ScDPFieldType GetFieldType() const; + + virtual void ScrollToEnd() {} + virtual void ScrollToShowSelection() {} + virtual void ResetScrollBar() {} + +protected: + virtual size_t CalcNewFieldIndex( SCsCOL nDX, SCsROW nDY ) const; + virtual size_t GetDisplayPosition(size_t nIndex) const { return 0; } + virtual void Redraw(); +}; + +// ============================================================================ + +class ScDPDataFieldControl : public ScDPFieldControlBase +{ +public: + ScDPDataFieldControl( ScDPLayoutDlg* pParent, const ResId& rResId, FixedText* pCaption ); + virtual ~ScDPDataFieldControl(); + + virtual void CalcSize(); + virtual bool IsValidIndex( size_t nIndex ) const; + virtual Point GetFieldPosition( size_t nIndex ); + virtual bool GetFieldIndex(const Point& rPos, size_t& rnIndex); + virtual Size GetFieldSize() const; + virtual String GetDescription() const; + virtual ScDPFieldType GetFieldType() const; + virtual void ScrollToEnd(); + virtual void ScrollToShowSelection(); + virtual void ResetScrollBar(); + +public: + virtual void Paint( const Rectangle& rRect ); + virtual void DataChanged( const DataChangedEvent& rDCEvt ); + virtual void MouseButtonDown( const MouseEvent& rMEvt ); + virtual void MouseButtonUp( const MouseEvent& rMEvt ); + virtual void MouseMove( const MouseEvent& rMEvt ); + +protected: + virtual void Redraw(); + virtual size_t CalcNewFieldIndex( SCsCOL nDX, SCsROW nDY ) const; + virtual size_t GetDisplayPosition(size_t nIndex) const; + +private: + /** + * Get the size and position of specified field button. + * + * @param nPos position index of the field button. Note that this index + * differs from field name index in that, the top left button + * always has an index of 0 regardless off scroll offset. + * @param rPos + * @param rSize + * + * @return false if the position index is out-of-bound, or otherwise + * invalid. + */ + bool GetFieldBtnPosSize(size_t nPos, Point& rPos, Size& rSize); + void GetFieldBtnColRow(const Point& rPos, size_t& rCol, size_t& rRow); + long CalcOffsetToShowSelection(); + void HandleScroll(); + + DECL_LINK(ScrollHdl, ScrollBar*); + DECL_LINK(EndScrollHdl, ScrollBar*); + +private: + ScrollBar maScroll; + ScDPLayoutDlg* mpParent; + + long mnScrollMarginHeight; /// bottom scroll bar margin height. + size_t mnColumnBtnCount; /// number of buttons per single column. + size_t mnTotalBtnCount; /// number of total visible buttons +}; #endif // SC_FIELDWND_HXX diff --git a/sc/source/ui/inc/pvlaydlg.hxx b/sc/source/ui/inc/pvlaydlg.hxx index d9ae44cca438..f732e6c3a6f5 100644 --- a/sc/source/ui/inc/pvlaydlg.hxx +++ b/sc/source/ui/inc/pvlaydlg.hxx @@ -73,8 +73,6 @@ class ScDPObject; //============================================================================ -#define FUNC_COUNT 11 - class ScDPLayoutDlg : public ScAnyRefDlg { public: @@ -97,7 +95,7 @@ public: void NotifyMouseButtonUp ( const Point& rAt ); PointerStyle NotifyMouseMove ( const Point& rAt ); void NotifyFieldFocus ( ScDPFieldType eType, BOOL bGotFocus ); - void NotifyMoveField ( ScDPFieldType eToType ); + void NotifyMoveFieldToEnd ( ScDPFieldType eToType ); void NotifyRemoveField ( ScDPFieldType eType, size_t nFieldIndex ); BOOL NotifyMoveSlider ( USHORT nKeyCode ); // return TRUE, if position changed @@ -111,14 +109,14 @@ private: FixedLine aFlLayout; FixedText aFtPage; - ScDPFieldWindow aWndPage; + ScDPPageFieldControl aWndPage; FixedText aFtCol; - ScDPFieldWindow aWndCol; + ScDPColFieldControl aWndCol; FixedText aFtRow; - ScDPFieldWindow aWndRow; + ScDPRowFieldControl aWndRow; FixedText aFtData; - ScDPFieldWindow aWndData; - ScDPFieldWindow aWndSelect; + ScDPDataFieldControl aWndData; + ScDPSelectFieldControl aWndSelect; ScrollBar aSlider; FixedInfo aFtInfo; @@ -170,12 +168,14 @@ private: ScDPFieldType eLastActiveType; /// Type of last active area. size_t nOffset; /// Offset of first field in TYPE_SELECT area. - ScDPFuncDataVec aSelectArr; + ScDPFuncDataVec aSelectArr; // holds instances for visible buttons only ScDPFuncDataVec aPageArr; ScDPFuncDataVec aColArr; ScDPFuncDataVec aRowArr; ScDPFuncDataVec aDataArr; + long mnFieldObjSpace; + ScDPObjectPtr xDlgDPObject; ScRange aOldRange; ScPivotParam thePivotData; @@ -184,10 +184,9 @@ private: BOOL bRefInputMode; private: - ScDPFieldWindow& GetFieldWindow ( ScDPFieldType eType ); void Init (bool bNewOutput); void InitWndSelect ( const ::std::vector<ScDPLabelDataRef>& rLabels ); - void InitWnd ( PivotField* pArr, long nCount, ScDPFieldType eType ); + void InitFieldWindow ( const ::std::vector<PivotField>& rFields, ScDPFieldType eType ); void InitFocus (); void InitFields (); void CalcWndSizes (); @@ -202,21 +201,37 @@ private: void AddField ( size_t nFromIndex, ScDPFieldType eToType, const Point& rAtPos ); + void AppendField(size_t nFromIndex, ScDPFieldType eToType); void MoveField ( ScDPFieldType eFromType, size_t nFromIndex, ScDPFieldType eToType, const Point& rAtPos ); + void MoveFieldToEnd(ScDPFieldType eFromType, size_t nFromIndex, ScDPFieldType eToType); void RemoveField ( ScDPFieldType eRemType, size_t nRemIndex ); - BOOL GetPivotArrays ( PivotField* pPageArr, - PivotField* pColArr, - PivotField* pRowArr, - PivotField* pDataArr, - USHORT& rPageCount, - USHORT& rColCount, - USHORT& rRowCount, - USHORT& rDataCount ); + bool GetPivotArrays( ::std::vector<PivotField>& rPageFields, + ::std::vector<PivotField>& rColFields, + ::std::vector<PivotField>& rRowFields, + ::std::vector<PivotField>& rDataFields ); void UpdateSrcRange(); + ScDPFieldControlBase* GetFieldWindow(ScDPFieldType eType); + + /** + * Get pointers to field windows that are <b>not</b> the window of + * specified type. The select window type is not included. + */ + void GetOtherFieldWindows( + ScDPFieldType eType, ScDPFieldControlBase*& rpWnd1, ScDPFieldControlBase*& rpWnd2); + + ScDPFuncDataVec* GetFieldDataArray(ScDPFieldType eType); + + /** + * Like GetOtherFieldWindows(), get pointers to data arrays of the fields + * that are <b>not</b> the specified field type. + */ + void GetOtherDataArrays( + ScDPFieldType eType, ScDPFuncDataVec*& rpArr1, ScDPFuncDataVec*& rpArr2); + // Handler DECL_LINK( ClickHdl, PushButton * ); DECL_LINK( ScrollHdl, ScrollBar * ); @@ -229,8 +244,6 @@ private: DECL_LINK( GetFocusHdl, Control* ); }; - - #endif // SC_PVLAYDLG_HXX /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |