summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@suse.com>2012-02-16 20:11:02 -0500
committerKohei Yoshida <kohei.yoshida@suse.com>2012-02-22 14:02:00 -0500
commitc5f0c11604bc64a0e6c4dbcdd7a4e077f834f407 (patch)
treeafa7bf11c6aad4d97bd2bf4566ebe6e1b4027e0a
parentdcd7dc43376c914027b76525959a9cea71d9279e (diff)
Alloow pivot table layout dialog to have duplicate data fields.
-rw-r--r--sc/inc/pivot.hxx17
-rw-r--r--sc/source/core/data/dpobject.cxx87
-rw-r--r--sc/source/core/data/pivot2.cxx44
-rw-r--r--sc/source/ui/Accessibility/AccessibleDataPilotControl.cxx8
-rw-r--r--sc/source/ui/dbgui/fieldwnd.cxx138
-rw-r--r--sc/source/ui/dbgui/pvlaydlg.cxx152
-rw-r--r--sc/source/ui/inc/AccessibleDataPilotControl.hxx1
-rw-r--r--sc/source/ui/inc/fieldwnd.hxx28
-rw-r--r--sc/source/ui/inc/pvlaydlg.hxx2
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 );