diff options
author | Kohei Yoshida <kohei.yoshida@suse.com> | 2012-02-16 20:11:02 -0500 |
---|---|---|
committer | Kohei Yoshida <kohei.yoshida@suse.com> | 2012-02-22 14:02:00 -0500 |
commit | c5f0c11604bc64a0e6c4dbcdd7a4e077f834f407 (patch) | |
tree | afa7bf11c6aad4d97bd2bf4566ebe6e1b4027e0a | |
parent | dcd7dc43376c914027b76525959a9cea71d9279e (diff) |
Alloow pivot table layout dialog to have duplicate data fields.
-rw-r--r-- | sc/inc/pivot.hxx | 17 | ||||
-rw-r--r-- | sc/source/core/data/dpobject.cxx | 87 | ||||
-rw-r--r-- | sc/source/core/data/pivot2.cxx | 44 | ||||
-rw-r--r-- | sc/source/ui/Accessibility/AccessibleDataPilotControl.cxx | 8 | ||||
-rw-r--r-- | sc/source/ui/dbgui/fieldwnd.cxx | 138 | ||||
-rw-r--r-- | sc/source/ui/dbgui/pvlaydlg.cxx | 152 | ||||
-rw-r--r-- | sc/source/ui/inc/AccessibleDataPilotControl.hxx | 1 | ||||
-rw-r--r-- | sc/source/ui/inc/fieldwnd.hxx | 28 | ||||
-rw-r--r-- | sc/source/ui/inc/pvlaydlg.hxx | 2 |
9 files changed, 305 insertions, 172 deletions
diff --git a/sc/inc/pivot.hxx b/sc/inc/pivot.hxx index 11717374dc96..747506f7eb0d 100644 --- a/sc/inc/pivot.hxx +++ b/sc/inc/pivot.hxx @@ -75,8 +75,9 @@ typedef ::boost::shared_ptr<ScDPLabelData> ScDPLabelDataRef; struct PivotField { SCsCOL nCol; - sal_uInt16 nFuncMask; - sal_uInt16 nFuncCount; + sal_uInt16 nFuncMask; + sal_uInt16 nFuncCount; + sal_uInt8 mnDupCount; ::com::sun::star::sheet::DataPilotFieldReference maFieldRef; explicit PivotField( SCsCOL nNewCol = 0, sal_uInt16 nNewFuncMask = PIVOT_FUNC_NONE ); @@ -188,13 +189,17 @@ typedef ::std::vector< ScPivotField > ScPivotFieldVector; struct ScDPFuncData { - short mnCol; + SCCOL mnCol; sal_uInt16 mnFuncMask; + sal_uInt8 mnDupCount; ::com::sun::star::sheet::DataPilotFieldReference maFieldRef; - explicit ScDPFuncData( short nNewCol, sal_uInt16 nNewFuncMask ); - explicit ScDPFuncData( short nNewCol, sal_uInt16 nNewFuncMask, - const ::com::sun::star::sheet::DataPilotFieldReference& rFieldRef ); + explicit ScDPFuncData( SCCOL nNewCol, sal_uInt16 nNewFuncMask ); + explicit ScDPFuncData( + SCCOL nNewCol, sal_uInt16 nNewFuncMask, sal_uInt8 nDupCount, + const ::com::sun::star::sheet::DataPilotFieldReference& rFieldRef ); + + bool operator== (const ScDPFuncData& r) const; }; // ============================================================================ diff --git a/sc/source/core/data/dpobject.cxx b/sc/source/core/data/dpobject.cxx index d675bc898d2a..5b1b9a991fb7 100644 --- a/sc/source/core/data/dpobject.cxx +++ b/sc/source/core/data/dpobject.cxx @@ -1717,6 +1717,22 @@ sal_uInt16 lcl_CountBits( sal_uInt16 nBits ) return nCount; } +namespace { + +class FindByColumn : public std::unary_function<PivotField, bool> +{ + SCsCOL mnCol; + sal_uInt16 mnMask; +public: + FindByColumn(SCsCOL nCol, sal_uInt16 nMask) : mnCol(nCol), mnMask(nMask) {} + bool operator() (const PivotField& r) const + { + return r.nCol == mnCol && r.nFuncMask == mnMask; + } +}; + +} + void lcl_FillOldFields( vector<PivotField>& rFields, const uno::Reference<sheet::XDimensionsSupplier>& xSource, @@ -1793,62 +1809,49 @@ void lcl_FillOldFields( nDupSource = lcl_FindName( xNameOrig->getName(), xDimsName ); } - bool bDupUsed = false; - if ( nDupSource >= 0 ) + sal_uInt8 nDupCount = 0; + if (nDupSource >= 0) { // this dimension is cloned. - // add function bit to previous entry - 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 - 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) - { - itr->nFuncMask |= nMask; - itr->nFuncCount = lcl_CountBits(itr->nFuncMask); - bDupUsed = true; - break; - } - } + vector<PivotField>::iterator it = std::find_if(aFields.begin(), aFields.end(), FindByColumn(nCompCol, nMask)); + if (it != aFields.end()) + nDupCount = it->mnDupCount + 1; } - if ( !bDupUsed ) // also for duplicated dim if original has different orientation + aFields.push_back(PivotField()); + PivotField& rField = aFields.back(); + if (bDataLayout) { - aFields.push_back(PivotField()); - PivotField& rField = aFields.back(); - if (bDataLayout) - { - rField.nCol = PIVOT_DATA_FIELD; - bDataFound = true; - } - else if (nDupSource >= 0) - rField.nCol = static_cast<SCsCOL>(nDupSource)+nColAdd; //! seek from name - else - rField.nCol = static_cast<SCsCOL>(nDim)+nColAdd; //! seek source column from name + rField.nCol = PIVOT_DATA_FIELD; + bDataFound = true; + } + else if (nDupSource >= 0) + rField.nCol = static_cast<SCsCOL>(nDupSource)+nColAdd; //! seek from name + else + rField.nCol = static_cast<SCsCOL>(nDim)+nColAdd; //! seek source column from name - rField.nFuncMask = nMask; - rField.nFuncCount = lcl_CountBits(nMask); - long nPos = ScUnoHelpFunctions::GetLongProperty( - xDimProp, OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DP_POSITION))); - aPos.push_back(nPos); + rField.nFuncMask = nMask; + rField.nFuncCount = lcl_CountBits(nMask); + rField.mnDupCount = nDupCount; + long nPos = ScUnoHelpFunctions::GetLongProperty( + xDimProp, OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DP_POSITION))); + aPos.push_back(nPos); - try - { - if (nOrient == sheet::DataPilotFieldOrientation_DATA) - xDimProp->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DP_REFVALUE))) - >>= rField.maFieldRef; - } - catch (uno::Exception&) - { - } + try + { + if (nOrient == sheet::DataPilotFieldOrientation_DATA) + xDimProp->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNO_DP_REFVALUE))) + >>= rField.maFieldRef; + } + catch (uno::Exception&) + { } } } diff --git a/sc/source/core/data/pivot2.cxx b/sc/source/core/data/pivot2.cxx index 80d35f3c1fa2..022ba4d32ebd 100644 --- a/sc/source/core/data/pivot2.cxx +++ b/sc/source/core/data/pivot2.cxx @@ -58,6 +58,18 @@ using ::com::sun::star::sheet::DataPilotFieldReference; using ::rtl::OUString; using ::std::vector; +namespace { + +bool equals(const DataPilotFieldReference& left, const DataPilotFieldReference& right) +{ + return (left.ReferenceType == right.ReferenceType) + && (left.ReferenceField == right.ReferenceField) + && (left.ReferenceItemType == right.ReferenceItemType) + && (left.ReferenceItemName == right.ReferenceItemName); +} + +} + // ============================================================================ ScDPName::ScDPName(const OUString& rName, const OUString& rLayoutName) : @@ -101,24 +113,25 @@ OUString ScDPLabelData::getDisplayName() const PivotField::PivotField( SCsCOL nNewCol, sal_uInt16 nNewFuncMask ) : nCol( nNewCol ), nFuncMask( nNewFuncMask ), - nFuncCount( 0 ) + nFuncCount( 0 ), + mnDupCount(0) { } PivotField::PivotField( const PivotField& r ) : - nCol(r.nCol), nFuncMask(r.nFuncMask), nFuncCount(r.nFuncCount), maFieldRef(r.maFieldRef) -{ -} + nCol(r.nCol), + nFuncMask(r.nFuncMask), + nFuncCount(r.nFuncCount), + mnDupCount(r.mnDupCount), + maFieldRef(r.maFieldRef) {} bool PivotField::operator==( const PivotField& r ) const { return (nCol == r.nCol) && (nFuncMask == r.nFuncMask) && (nFuncCount == r.nFuncCount) - && (maFieldRef.ReferenceType == r.maFieldRef.ReferenceType) - && (maFieldRef.ReferenceField == r.maFieldRef.ReferenceField) - && (maFieldRef.ReferenceItemType == r.maFieldRef.ReferenceItemType) - && (maFieldRef.ReferenceItemName == r.maFieldRef.ReferenceItemName); + && (mnDupCount == r.mnDupCount) + && equals(maFieldRef, r.maFieldRef); } ScPivotParam::ScPivotParam() @@ -199,17 +212,28 @@ bool ScPivotParam::operator==( const ScPivotParam& r ) const ScDPFuncData::ScDPFuncData( SCCOL nCol, sal_uInt16 nFuncMask ) : mnCol( nCol ), - mnFuncMask( nFuncMask ) + mnFuncMask( nFuncMask ), + mnDupCount(0) { } -ScDPFuncData::ScDPFuncData( SCCOL nCol, sal_uInt16 nFuncMask, const DataPilotFieldReference& rFieldRef ) : +ScDPFuncData::ScDPFuncData( + SCCOL nCol, sal_uInt16 nFuncMask, sal_uInt8 nDupCount, const DataPilotFieldReference& rFieldRef ) : mnCol( nCol ), mnFuncMask( nFuncMask ), + mnDupCount(nDupCount), maFieldRef( rFieldRef ) { } +bool ScDPFuncData::operator== (const ScDPFuncData& r) const +{ + if (mnCol != r.mnCol || mnFuncMask != r.mnFuncMask || mnDupCount != r.mnDupCount) + return false; + + return equals(maFieldRef, r.maFieldRef); +} + // ============================================================================ /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/ui/Accessibility/AccessibleDataPilotControl.cxx b/sc/source/ui/Accessibility/AccessibleDataPilotControl.cxx index f21c4551b146..0b826fa1f016 100644 --- a/sc/source/ui/Accessibility/AccessibleDataPilotControl.cxx +++ b/sc/source/ui/Accessibility/AccessibleDataPilotControl.cxx @@ -225,6 +225,14 @@ void ScAccessibleDataPilotControl::AddField(sal_Int32 nNewIndex) } } +void ScAccessibleDataPilotControl::MoveField(sal_Int32 nOldIndex, sal_Int32 nNewIndex) +{ + RemoveField(nOldIndex); + if (nNewIndex > nOldIndex) + --nNewIndex; + AddField(nNewIndex); +} + void ScAccessibleDataPilotControl::RemoveField(sal_Int32 nOldIndex) { sal_Bool bRemoved(sal_False); diff --git a/sc/source/ui/dbgui/fieldwnd.cxx b/sc/source/ui/dbgui/fieldwnd.cxx index 9139be419d59..4607b2c9f1e8 100644 --- a/sc/source/ui/dbgui/fieldwnd.cxx +++ b/sc/source/ui/dbgui/fieldwnd.cxx @@ -41,6 +41,7 @@ #include "scresid.hxx" #include "pivot.hrc" +using namespace com::sun::star; using ::rtl::OUString; using ::std::vector; using ::com::sun::star::uno::Reference; @@ -49,6 +50,20 @@ using ::com::sun::star::accessibility::XAccessible; const size_t INVALID_INDEX = static_cast<size_t>(-1); +ScDPFieldControlBase::FieldName::FieldName(const rtl::OUString& rText, bool bFits, sal_uInt8 nDupCount) : + maText(rText), mbFits(bFits), mnDupCount(nDupCount) {} + +ScDPFieldControlBase::FieldName::FieldName(const FieldName& r) : + maText(r.maText), mbFits(r.mbFits), mnDupCount(r.mnDupCount) {} + +rtl::OUString ScDPFieldControlBase::FieldName::getDisplayedText() const +{ + rtl::OUStringBuffer aBuf(maText); + if (mnDupCount > 0) + aBuf.append(static_cast<sal_Int32>(mnDupCount+1)); + return aBuf.makeStringAndClear(); +} + ScDPFieldControlBase::ScrollBar::ScrollBar(Window* pParent, WinBits nStyle) : ::ScrollBar(pParent, nStyle), mpParent(pParent) @@ -110,12 +125,13 @@ bool ScDPFieldControlBase::IsExistingIndex( size_t nIndex ) const return nIndex < maFieldNames.size(); } -void ScDPFieldControlBase::AddField( const String& rText, size_t nNewIndex ) +void ScDPFieldControlBase::AddField( const rtl::OUString& rText, size_t nNewIndex ) { OSL_ENSURE( nNewIndex == maFieldNames.size(), "ScDPFieldWindow::AddField - invalid index" ); if( IsValidIndex( nNewIndex ) ) { - maFieldNames.push_back( FieldName( rText, true ) ); + sal_uInt8 nDupCount = GetNextDupCount(rText); + maFieldNames.push_back(FieldName(rText, true, nDupCount)); if (pAccessible) { com::sun::star::uno::Reference < com::sun::star::accessibility::XAccessible > xTempAcc = xAccessible; @@ -127,7 +143,8 @@ void ScDPFieldControlBase::AddField( const String& rText, size_t nNewIndex ) } } -bool ScDPFieldControlBase::AddField( const String& rText, const Point& rPos, size_t& rnIndex ) +bool ScDPFieldControlBase::AddField( + const rtl::OUString& rText, const Point& rPos, size_t& rnIndex, sal_uInt8& rnDupCount) { size_t nNewIndex = 0; if( GetFieldIndex( rPos, nNewIndex ) ) @@ -135,11 +152,13 @@ bool ScDPFieldControlBase::AddField( const String& rText, const Point& rPos, siz if( nNewIndex > maFieldNames.size() ) nNewIndex = maFieldNames.size(); - maFieldNames.insert( maFieldNames.begin() + nNewIndex, FieldName( rText, true ) ); + sal_uInt8 nDupCount = GetNextDupCount(rText); + maFieldNames.insert(maFieldNames.begin() + nNewIndex, FieldName(rText, true, nDupCount)); mnFieldSelected = nNewIndex; ResetScrollBar(); Redraw(); rnIndex = nNewIndex; + rnDupCount = nDupCount; if (pAccessible) { @@ -156,12 +175,61 @@ bool ScDPFieldControlBase::AddField( const String& rText, const Point& rPos, siz return false; } -bool ScDPFieldControlBase::AppendField(const String& rText, size_t& rnIndex) +bool ScDPFieldControlBase::MoveField(size_t nCurPos, const Point& rPos, size_t& rnIndex) +{ + if (nCurPos >= maFieldNames.size()) + // out-of-bound + return false; + + size_t nNewIndex = 0; + if (!GetFieldIndex(rPos, nNewIndex)) + return false; + + if (nNewIndex == nCurPos) + // Nothing to do. + return true; + + FieldName aName = maFieldNames[nCurPos]; + if (nNewIndex >= maFieldNames.size()) + { + // Move to the back. + maFieldNames.erase(maFieldNames.begin()+nCurPos); + maFieldNames.push_back(aName); + rnIndex = maFieldNames.size()-1; + } + else + { + maFieldNames.erase(maFieldNames.begin()+nCurPos); + size_t nTmp = nNewIndex; // we need to keep the original index for accessible. + if (nNewIndex > nCurPos) + --nTmp; + + maFieldNames.insert(maFieldNames.begin()+nTmp, aName); + rnIndex = nTmp; + } + + ResetScrollBar(); + Redraw(); + + if (pAccessible) + { + uno::Reference<accessibility::XAccessible> xTempAcc = xAccessible; + if (xTempAcc.is()) + pAccessible->MoveField(nCurPos, nNewIndex); + else + pAccessible = NULL; + } + + return true; +} + +bool ScDPFieldControlBase::AppendField(const rtl::OUString& rText, size_t& rnIndex) { if (!IsValidIndex(maFieldNames.size())) return false; - maFieldNames.push_back(FieldName(rText, true)); + sal_uInt8 nDupCount = GetNextDupCount(rText); + maFieldNames.push_back(FieldName(rText, true, nDupCount)); mnFieldSelected = maFieldNames.size() - 1; ResetScrollBar(); Redraw(); @@ -170,6 +238,14 @@ bool ScDPFieldControlBase::AppendField(const String& rText, size_t& rnIndex) return true; } +sal_uInt8 ScDPFieldControlBase::GetDupCount(size_t nIndex) const +{ + if (maFieldNames.size() <= nIndex) + return 0; + + return maFieldNames[nIndex].mnDupCount; +} + void ScDPFieldControlBase::DelField( size_t nDelIndex ) { if ( IsExistingIndex(nDelIndex) ) @@ -213,11 +289,12 @@ void ScDPFieldControlBase::ClearFields() maFieldNames.clear(); } -void ScDPFieldControlBase::SetFieldText( const String& rText, size_t nIndex ) +void ScDPFieldControlBase::SetFieldText( const rtl::OUString& rText, size_t nIndex ) { if( IsExistingIndex( nIndex ) ) { - maFieldNames[ nIndex ] = FieldName( rText, true ); + sal_uInt8 nDupCount = GetNextDupCount(rText); + maFieldNames[nIndex] = FieldName(rText, true, nDupCount); Redraw(); if (pAccessible) @@ -231,11 +308,11 @@ void ScDPFieldControlBase::SetFieldText( const String& rText, size_t nIndex ) } } -const String& ScDPFieldControlBase::GetFieldText( size_t nIndex ) const +rtl::OUString ScDPFieldControlBase::GetFieldText( size_t nIndex ) const { if( IsExistingIndex( nIndex ) ) - return maFieldNames[ nIndex ].first; - return EMPTY_STRING; + return maFieldNames[nIndex].maText; + return rtl::OUString(); } void ScDPFieldControlBase::GetExistingIndex( const Point& rPos, size_t& rnIndex ) @@ -520,7 +597,8 @@ void ScDPFieldControlBase::DrawField( // #i97623# VirtualDevice is always LTR while other windows derive direction from parent aVirDev.EnableRTL( IsRTLEnabled() ); - String aText = rText.first; + rtl::OUString aText = rText.getDisplayedText(); + Size aDevSize( rRect.GetSize() ); long nWidth = aDevSize.Width(); long nHeight = aDevSize.Height(); @@ -528,16 +606,18 @@ void ScDPFieldControlBase::DrawField( long nLabelHeight = rDev.GetTextHeight(); // #i31600# if text is too long, cut and add ellipsis - rText.second = nLabelWidth + 6 <= nWidth; - if( !rText.second ) + rText.mbFits = nLabelWidth + 6 <= nWidth; + if (!rText.mbFits) { - xub_StrLen nMinLen = 0; - xub_StrLen nMaxLen = aText.Len(); + sal_Int32 nMinLen = 0; + sal_Int32 nMaxLen = aText.getLength(); bool bFits = false; do { - xub_StrLen nCurrLen = (nMinLen + nMaxLen) / 2; - aText = String( rText.first, 0, nCurrLen ).AppendAscii( "..." ); + sal_Int32 nCurrLen = (nMinLen + nMaxLen) / 2; + rtl::OUStringBuffer aBuf(aText.copy(0, nCurrLen)); + aBuf.appendAscii("..."); + aText = aBuf.makeStringAndClear(); nLabelWidth = rDev.GetTextWidth( aText ); bFits = nLabelWidth + 6 <= nWidth; (bFits ? nMinLen : nMaxLen) = nCurrLen; @@ -589,7 +669,7 @@ void ScDPFieldControlBase::DrawInvertSelection() Size aFldSize = GetFieldSize(); long nFldWidth = aFldSize.Width(); long nSelWidth = std::min<long>( - GetTextWidth(maFieldNames[mnFieldSelected].first) + 4, nFldWidth - 6); + GetTextWidth(maFieldNames[mnFieldSelected].getDisplayedText()) + 4, nFldWidth - 6); Point aPos = GetFieldPosition(nPos); aPos += Point((nFldWidth - nSelWidth) / 2, 3); @@ -607,14 +687,14 @@ Size ScDPFieldControlBase::GetStdFieldBtnSize() const bool ScDPFieldControlBase::IsShortenedText( size_t nIndex ) const { const FieldNames& rFields = GetFieldNames(); - return (nIndex < rFields.size()) && !rFields[nIndex].second; + return (nIndex < rFields.size()) && !rFields[nIndex].mbFits; } void ScDPFieldControlBase::MoveField( size_t nDestIndex ) { if (nDestIndex != mnFieldSelected) { - swap(maFieldNames[nDestIndex], maFieldNames[mnFieldSelected]); + std::swap(maFieldNames[nDestIndex], maFieldNames[mnFieldSelected]); mnFieldSelected = nDestIndex; } } @@ -671,6 +751,22 @@ void ScDPFieldControlBase::MoveSelection(SCsCOL nDX, SCsROW nDY) SetSelection( nNewIndex ); } +sal_uInt8 ScDPFieldControlBase::GetNextDupCount(const rtl::OUString& rFieldText) const +{ + sal_uInt8 nMax = 0; + FieldNames::const_iterator it = maFieldNames.begin(), itEnd = maFieldNames.end(); + for (; it != itEnd; ++it) + { + if (it->maText != rFieldText) + continue; + + sal_uInt8 nNextUp = it->mnDupCount + 1; + if (nMax < nNextUp) + nMax = nNextUp; + } + return nMax; +} + void ScDPFieldControlBase::SelectNext() { SetSelection(mnFieldSelected + 1); diff --git a/sc/source/ui/dbgui/pvlaydlg.cxx b/sc/source/ui/dbgui/pvlaydlg.cxx index 2c27c1a9e505..16cb5311f007 100644 --- a/sc/source/ui/dbgui/pvlaydlg.cxx +++ b/sc/source/ui/dbgui/pvlaydlg.cxx @@ -382,7 +382,7 @@ void ScDPLayoutDlg::InitFieldWindow( const vector<PivotField>& rFields, ScDPFiel continue; size_t nFieldIndex = pInitArr->size(); - ScDPFuncDataRef p(new ScDPFuncData(nCol, nMask, itr->maFieldRef)); + ScDPFuncDataRef p(new ScDPFuncData(nCol, nMask, itr->mnDupCount, itr->maFieldRef)); pInitArr->push_back(p); if (eType == TYPE_DATA) @@ -437,6 +437,11 @@ void ScDPLayoutDlg::InitFields() void ScDPLayoutDlg::AddField( size_t nFromIndex, ScDPFieldType eToType, const Point& rAtPos ) { ScDPFuncData fData( *(aSelectArr[nFromIndex]) ); + + bool bAllowed = IsOrientationAllowed( fData.mnCol, eToType ); + if (!bAllowed) + return; + size_t nAt = 0; ScDPFieldControlBase* toWnd = GetFieldWindow(eToType); ScDPFieldControlBase* rmWnd1 = NULL; @@ -448,15 +453,37 @@ void ScDPLayoutDlg::AddField( size_t nFromIndex, ScDPFieldType eToType, const Po ScDPFuncDataVec* rmArr2 = NULL; GetOtherDataArrays(eToType, rmArr1, rmArr2); - bool bDataArr = eToType == TYPE_DATA; + if (eToType == TYPE_DATA) + { + // Data field allows duplicates. + ScDPLabelData* p = GetLabelData(fData.mnCol); + OUString aStr = p->maLayoutName; + sal_uInt16 nMask = fData.mnFuncMask; + if (aStr.isEmpty()) + { + aStr = GetFuncString(nMask); + aStr += p->maName; + } - bool bAllowed = IsOrientationAllowed( fData.mnCol, eToType ); - if ( bAllowed && (!Contains( toArr, fData.mnCol, nAt )) ) + size_t nAddedAt = 0; + sal_uInt8 nDupCount = 0; + if (toWnd->AddField(aStr, DlgPos2WndPos(rAtPos, *toWnd), nAddedAt, nDupCount)) + { + fData.mnFuncMask = nMask; + fData.mnDupCount = nDupCount; + Insert(toArr, fData, nAddedAt); + toWnd->GrabFocus(); + } + + return; + } + + if (!Contains(toArr, fData, nAt)) { // ggF. in anderem Fenster entfernen if ( rmArr1 ) { - if ( Contains( rmArr1, fData.mnCol, nAt ) ) + if ( Contains( rmArr1, fData, nAt ) ) { rmWnd1->DelField( nAt ); Remove( rmArr1, nAt ); @@ -464,47 +491,23 @@ void ScDPLayoutDlg::AddField( size_t nFromIndex, ScDPFieldType eToType, const Po } if ( rmArr2 ) { - if ( Contains( rmArr2, fData.mnCol, nAt ) ) + if ( Contains( rmArr2, fData, nAt ) ) { rmWnd2->DelField( nAt ); Remove( rmArr2, nAt ); } } - ScDPLabelData& rData = aLabelDataArr[nFromIndex+nOffset]; - size_t nAddedAt = 0; - - if ( !bDataArr ) + size_t nAddedAt = 0; + sal_uInt8 nDupCount = 0; + ScDPLabelData& rData = aLabelDataArr[nFromIndex+nOffset]; + if (toWnd->AddField( + rData.getDisplayName(), DlgPos2WndPos(rAtPos, *toWnd), nAddedAt, nDupCount)) { - if ( toWnd->AddField( rData.getDisplayName(), - DlgPos2WndPos( rAtPos, *toWnd ), - nAddedAt ) ) - { - Insert( toArr, fData, nAddedAt ); - toWnd->GrabFocus(); - } + fData.mnDupCount = nDupCount; + Insert( toArr, fData, nAddedAt ); + toWnd->GrabFocus(); } - else - { - ScDPLabelData* p = GetLabelData(fData.mnCol); - OUString aStr = p->maLayoutName; - sal_uInt16 nMask = fData.mnFuncMask; - if (aStr.isEmpty()) - { - aStr = GetFuncString(nMask); - aStr += p->maName; - } - - if ( toWnd->AddField( aStr, - DlgPos2WndPos( rAtPos, *toWnd ), - nAddedAt ) ) - { - fData.mnFuncMask = nMask; - Insert( toArr, fData, nAddedAt ); - toWnd->GrabFocus(); - } - } - } } @@ -525,12 +528,12 @@ void ScDPLayoutDlg::AppendField(size_t nFromIndex, ScDPFieldType eToType) bool bDataArr = eToType == TYPE_DATA; - if ( (!Contains( toArr, aFuncData.mnCol, nAt )) ) + if ( (!Contains( toArr, aFuncData, nAt )) ) { // ggF. in anderem Fenster entfernen if ( rmArr1 ) { - if ( Contains( rmArr1, aFuncData.mnCol, nAt ) ) + if ( Contains( rmArr1, aFuncData, nAt ) ) { rmWnd1->DelField( nAt ); Remove( rmArr1, nAt ); @@ -538,7 +541,7 @@ void ScDPLayoutDlg::AppendField(size_t nFromIndex, ScDPFieldType eToType) } if ( rmArr2 ) { - if ( Contains( rmArr2, aFuncData.mnCol, nAt ) ) + if ( Contains( rmArr2, aFuncData, nAt ) ) { rmWnd2->DelField( nAt ); Remove( rmArr2, nAt ); @@ -583,6 +586,8 @@ void ScDPLayoutDlg::MoveField( ScDPFieldType eFromType, size_t nFromIndex, ScDPF { if ( eFromType == TYPE_SELECT ) AddField( nFromIndex, eToType, rAtPos ); + else if (eFromType != TYPE_SELECT && eToType == TYPE_SELECT) + RemoveField(eFromType, nFromIndex); else if ( eFromType != eToType ) { ScDPFieldControlBase* fromWnd = GetFieldWindow(eFromType); @@ -607,20 +612,21 @@ void ScDPLayoutDlg::MoveField( ScDPFieldType eFromType, size_t nFromIndex, ScDPF bool bAllowed = IsOrientationAllowed( fData.mnCol, eToType ); size_t nAt = 0; - if ( bAllowed && Contains( fromArr, fData.mnCol, nAt ) ) + if ( bAllowed && Contains( fromArr, fData, nAt ) ) { fromWnd->DelField( nAt ); Remove( fromArr, nAt ); - if (!Contains( toArr, fData.mnCol, nAt )) + if (!Contains( toArr, fData, nAt )) { size_t nAddedAt = 0; + sal_uInt8 nDupCount = 0; if ( !bDataArr ) { // ggF. in anderem Fenster entfernen if ( rmArr1 ) { - if ( Contains( rmArr1, fData.mnCol, nAt ) ) + if ( Contains( rmArr1, fData, nAt ) ) { rmWnd1->DelField( nAt ); Remove( rmArr1, nAt ); @@ -628,7 +634,7 @@ void ScDPLayoutDlg::MoveField( ScDPFieldType eFromType, size_t nFromIndex, ScDPF } if ( rmArr2 ) { - if ( Contains( rmArr2, fData.mnCol, nAt ) ) + if ( Contains( rmArr2, fData, nAt ) ) { rmWnd2->DelField( nAt ); Remove( rmArr2, nAt ); @@ -637,8 +643,9 @@ void ScDPLayoutDlg::MoveField( ScDPFieldType eFromType, size_t nFromIndex, ScDPF if ( toWnd->AddField( GetLabelString( fData.mnCol ), DlgPos2WndPos( rAtPos, *toWnd ), - nAddedAt ) ) + nAddedAt, nDupCount) ) { + fData.mnDupCount = nDupCount; Insert( toArr, fData, nAddedAt ); toWnd->GrabFocus(); } @@ -656,9 +663,10 @@ void ScDPLayoutDlg::MoveField( ScDPFieldType eFromType, size_t nFromIndex, ScDPF if ( toWnd->AddField( aStr, DlgPos2WndPos( rAtPos, *toWnd ), - nAddedAt ) ) + nAddedAt, nDupCount) ) { fData.mnFuncMask = nMask; + fData.mnDupCount = nDupCount; Insert( toArr, fData, nAddedAt ); toWnd->GrabFocus(); } @@ -673,11 +681,10 @@ void ScDPLayoutDlg::MoveField( ScDPFieldType eFromType, size_t nFromIndex, ScDPF ScDPFuncDataVec* theArr = GetFieldDataArray(eFromType); size_t nAt = 0; Point aToPos; - sal_Bool bDataArr = eFromType == TYPE_DATA; ScDPFuncData fData( *((*theArr)[nFromIndex]) ); - if ( Contains( theArr, fData.mnCol, nAt ) ) + if ( Contains( theArr, fData, nAt ) ) { size_t nToIndex = 0; aToPos = DlgPos2WndPos( rAtPos, *theWnd ); @@ -686,37 +693,10 @@ void ScDPLayoutDlg::MoveField( ScDPFieldType eFromType, size_t nFromIndex, ScDPF if ( nToIndex != nAt ) { size_t nAddedAt = 0; - - theWnd->DelField( nAt ); - Remove( theArr, nAt ); - - if ( !bDataArr ) - { - if ( theWnd->AddField( GetLabelString( fData.mnCol ), - aToPos, - nAddedAt ) ) - { - Insert( theArr, fData, nAddedAt ); - } - } - else + if (theWnd->MoveField(nAt, aToPos, nAddedAt)) { - ScDPLabelData* p = GetLabelData(fData.mnCol); - OUString aStr = p->maLayoutName; - sal_uInt16 nMask = fData.mnFuncMask; - if (aStr.isEmpty()) - { - aStr = GetFuncString(nMask); - aStr += p->maName; - } - - if ( theWnd->AddField( aStr, - DlgPos2WndPos( rAtPos, *theWnd ), - nAddedAt ) ) - { - fData.mnFuncMask = nMask; - Insert( theArr, fData, nAddedAt ); - } + Remove(theArr, nAt); + Insert(theArr, fData, nAddedAt); } } } @@ -750,12 +730,12 @@ void ScDPLayoutDlg::MoveFieldToEnd( ScDPFieldType eFromType, size_t nFromIndex, ScDPFuncData fData( *((*fromArr)[nFromIndex]) ); size_t nAt = 0; - if ( Contains( fromArr, fData.mnCol, nAt ) ) + if ( Contains( fromArr, fData, nAt ) ) { fromWnd->DelField( nAt ); Remove( fromArr, nAt ); - if (!Contains( toArr, fData.mnCol, nAt )) + if (!Contains( toArr, fData, nAt )) { size_t nAddedAt = 0; if ( !bDataArr ) @@ -763,7 +743,7 @@ void ScDPLayoutDlg::MoveFieldToEnd( ScDPFieldType eFromType, size_t nFromIndex, // ggF. in anderem Fenster entfernen if ( rmArr1 ) { - if ( Contains( rmArr1, fData.mnCol, nAt ) ) + if ( Contains( rmArr1, fData, nAt ) ) { rmWnd1->DelField( nAt ); Remove( rmArr1, nAt ); @@ -771,7 +751,7 @@ void ScDPLayoutDlg::MoveFieldToEnd( ScDPFieldType eFromType, size_t nFromIndex, } if ( rmArr2 ) { - if ( Contains( rmArr2, fData.mnCol, nAt ) ) + if ( Contains( rmArr2, fData, nAt ) ) { rmWnd2->DelField( nAt ); Remove( rmArr2, nAt ); @@ -816,7 +796,7 @@ void ScDPLayoutDlg::MoveFieldToEnd( ScDPFieldType eFromType, size_t nFromIndex, ScDPFuncData fData( *((*theArr)[nFromIndex]) ); - if ( Contains( theArr, fData.mnCol, nAt ) ) + if ( Contains( theArr, fData, nAt ) ) { size_t nToIndex = 0; theWnd->GetExistingIndex( aToPos, nToIndex ); @@ -1149,7 +1129,7 @@ void ScDPLayoutDlg::Deactivate() //---------------------------------------------------------------------------- -sal_Bool ScDPLayoutDlg::Contains( ScDPFuncDataVec* pArr, SCsCOL nCol, size_t& nAt ) +bool ScDPLayoutDlg::Contains( ScDPFuncDataVec* pArr, const ScDPFuncData& rData, size_t& nAt ) { if (!pArr || pArr->empty()) return false; @@ -1157,7 +1137,7 @@ sal_Bool ScDPLayoutDlg::Contains( ScDPFuncDataVec* pArr, SCsCOL nCol, size_t& nA ScDPFuncDataVec::const_iterator itr, itrBeg = pArr->begin(), itrEnd = pArr->end(); for (itr = itrBeg; itr != itrEnd; ++itr) { - if ((*itr)->mnCol == nCol) + if (**itr == rData) { // found! nAt = ::std::distance(itrBeg, itr); diff --git a/sc/source/ui/inc/AccessibleDataPilotControl.hxx b/sc/source/ui/inc/AccessibleDataPilotControl.hxx index fb0e0f40ecd6..eebccedec723 100644 --- a/sc/source/ui/inc/AccessibleDataPilotControl.hxx +++ b/sc/source/ui/inc/AccessibleDataPilotControl.hxx @@ -51,6 +51,7 @@ public: virtual void SAL_CALL disposing(); void AddField(sal_Int32 nNewIndex); + void MoveField(sal_Int32 nOldIndex, sal_Int32 nNewIndex); void RemoveField(sal_Int32 nOldIndex); void FieldFocusChange(sal_Int32 nOldIndex, sal_Int32 nNewIndex); void FieldNameChange(sal_Int32 nIndex); diff --git a/sc/source/ui/inc/fieldwnd.hxx b/sc/source/ui/inc/fieldwnd.hxx index e1bcfdb15918..d8d50a827b95 100644 --- a/sc/source/ui/inc/fieldwnd.hxx +++ b/sc/source/ui/inc/fieldwnd.hxx @@ -61,7 +61,16 @@ enum ScDPFieldType class ScDPFieldControlBase : public Control { protected: - typedef ::std::pair<String, bool> FieldName; // true = text fits into button + struct FieldName + { + rtl::OUString maText; + bool mbFits; + sal_uInt8 mnDupCount; + FieldName(const rtl::OUString& rText, bool bFits, sal_uInt8 nDupCount = 0); + FieldName(const FieldName& r); + + rtl::OUString getDisplayedText() const; + }; typedef ::std::vector<FieldName> FieldNames; public: @@ -117,15 +126,20 @@ public: bool IsExistingIndex( size_t nIndex ) const; /** Inserts a field to the specified index. */ - void AddField( const String& rText, size_t nNewIndex ); + void AddField( const rtl::OUString& 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 AddField(const rtl::OUString& rText, const Point& rPos, size_t& rnIndex, sal_uInt8& rnDupCount); + + bool MoveField(size_t nCurPos, const Point& rPos, size_t& rnIndex); - bool AppendField(const String& rText, size_t& rnIndex); + bool AppendField(const rtl::OUString& rText, size_t& rnIndex); + + + sal_uInt8 GetDupCount(size_t nIndex) const; /** Removes a field from the specified index. */ void DelField( size_t nDelIndex ); @@ -138,9 +152,9 @@ public: /** Removes all fields. */ void ClearFields(); /** Changes the text on an existing field. */ - void SetFieldText( const String& rText, size_t nIndex ); + void SetFieldText( const rtl::OUString& rText, size_t nIndex ); /** Returns the text of an existing field. */ - const String& GetFieldText( size_t nIndex ) const; + rtl::OUString GetFieldText( size_t nIndex ) const; /** Calculates a field index at a specific pixel position. Returns in every case the index of an existing field. @@ -225,6 +239,8 @@ private: /** Sets selection to new position relative to current. */ void MoveSelection( SCsCOL nDX, SCsROW nDY ); + sal_uInt8 GetNextDupCount(const rtl::OUString& rFieldText) const; + private: typedef ::std::vector<Window*> Paintables; Paintables maPaintables; diff --git a/sc/source/ui/inc/pvlaydlg.hxx b/sc/source/ui/inc/pvlaydlg.hxx index 3ffcd6444302..f79f6f140c93 100644 --- a/sc/source/ui/inc/pvlaydlg.hxx +++ b/sc/source/ui/inc/pvlaydlg.hxx @@ -202,7 +202,7 @@ private: String GetLabelString ( SCsCOL nCol ); bool IsOrientationAllowed( SCsCOL nCol, ScDPFieldType eType ); String GetFuncString ( sal_uInt16& rFuncMask, sal_Bool bIsValue = true ); - sal_Bool Contains ( ScDPFuncDataVec* pArr, SCsCOL nCol, size_t& nAt ); + bool Contains( ScDPFuncDataVec* pArr, const ScDPFuncData& rData, size_t& nAt ); void Remove ( ScDPFuncDataVec* pArr, size_t nAt ); void Insert ( ScDPFuncDataVec* pArr, const ScDPFuncData& rFData, size_t nAt ); |