[Libreoffice-commits] .: sc/inc sc/source

Libreoffice Gerrit user logerrit at kemper.freedesktop.org
Wed Dec 19 20:38:06 PST 2012


 sc/inc/pivot.hxx                |    5 
 sc/source/core/data/pivot2.cxx  |   15 
 sc/source/ui/dbgui/fieldwnd.cxx |  246 ++++++++--
 sc/source/ui/dbgui/pvlaydlg.cxx |  941 +++++++++++++++-------------------------
 sc/source/ui/inc/fieldwnd.hxx   |   40 +
 sc/source/ui/inc/pvlaydlg.hxx   |   54 --
 6 files changed, 623 insertions(+), 678 deletions(-)

New commits:
commit 8c8402061bb3908d195e3d1b462409d8bcc8e279
Author: Kohei Yoshida <kohei.yoshida at gmail.com>
Date:   Tue Dec 18 12:57:35 2012 -0500

    Refactored pivot table dialog code for better modularity.
    
    Moved much of the field area specific storage from the parent dialog
    to its child field area control. It's much cleaner this way.
    
    Change-Id: I603fbebc2d9d62742a3808d6f72ca23357d84046

diff --git a/sc/inc/pivot.hxx b/sc/inc/pivot.hxx
index 1c4350b..ba87741 100644
--- a/sc/inc/pivot.hxx
+++ b/sc/inc/pivot.hxx
@@ -40,6 +40,7 @@
 #include "global.hxx"
 #include "address.hxx"
 #include "dpglobal.hxx"
+#include "dpmacros.hxx"
 
 #include <vector>
 #include <boost/ptr_container/ptr_vector.hpp>
@@ -164,6 +165,10 @@ struct ScPivotFuncData
         const ::com::sun::star::sheet::DataPilotFieldReference& rFieldRef );
 
     bool operator== (const ScPivotFuncData& r) const;
+
+#if DEBUG_PIVOT_TABLE
+    void Dump() const;
+#endif
 };
 
 typedef ::std::vector< ScPivotFuncData > ScPivotFuncDataVector;
diff --git a/sc/source/core/data/pivot2.cxx b/sc/source/core/data/pivot2.cxx
index 23739ea..a5e23d0 100644
--- a/sc/source/core/data/pivot2.cxx
+++ b/sc/source/core/data/pivot2.cxx
@@ -43,6 +43,12 @@
 #include "stlpool.hxx"
 #include "stlsheet.hxx"
 
+#if DEBUG_PIVOT_TABLE
+#include <iostream>
+using std::cout;
+using std::endl;
+#endif
+
 using ::com::sun::star::sheet::DataPilotFieldReference;
 using ::rtl::OUString;
 using ::std::vector;
@@ -229,6 +235,15 @@ bool ScPivotFuncData::operator== (const ScPivotFuncData& r) const
     return equals(maFieldRef, r.maFieldRef);
 }
 
+#if DEBUG_PIVOT_TABLE
+void ScPivotFuncData::Dump() const
+{
+    cout << "ScPivotFuncData: (col=" << mnCol << ", original dim=" << mnOriginalDim
+        << ", func mask=" << mnFuncMask << ", duplicate count=" << static_cast<int>(mnDupCount)
+        << ")" << endl;
+}
+#endif
+
 // ============================================================================
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/dbgui/fieldwnd.cxx b/sc/source/ui/dbgui/fieldwnd.cxx
index 9cd31f6..5bd76bd 100644
--- a/sc/source/ui/dbgui/fieldwnd.cxx
+++ b/sc/source/ui/dbgui/fieldwnd.cxx
@@ -46,6 +46,7 @@
 
 #include "pvlaydlg.hxx"
 #include "dpuiglobal.hxx"
+#include "dpmacros.hxx"
 #include "AccessibleDataPilotControl.hxx"
 #include "scresid.hxx"
 #include "pivot.hrc"
@@ -60,6 +61,26 @@ using ::com::sun::star::accessibility::XAccessible;
 const size_t PIVOTFIELD_INVALID = static_cast< size_t >(-1);
 const size_t INVALID_INDEX = static_cast<size_t>(-1);
 
+#if DEBUG_PIVOT_TABLE
+#include <iostream>
+using std::cout;
+using std::endl;
+#endif
+
+namespace {
+
+#if DEBUG_PIVOT_TABLE
+void DumpAllFuncData(const ScDPFieldControlBase::FuncDataType& rData)
+{
+    cout << "---" << endl;
+    ScDPFieldControlBase::FuncDataType::const_iterator it = rData.begin(), itEnd = rData.end();
+    for (; it != itEnd; ++it)
+        it->Dump();
+}
+#endif
+
+}
+
 ScDPFieldControlBase::FieldName::FieldName(const rtl::OUString& rText, bool bFits, sal_uInt8 nDupCount) :
     maText(rText), mbFits(bFits), mnDupCount(nDupCount) {}
 
@@ -130,44 +151,44 @@ bool ScDPFieldControlBase::IsExistingIndex( size_t nIndex ) const
     return nIndex < maFieldNames.size();
 }
 
-void ScDPFieldControlBase::AddField( const rtl::OUString& rText, size_t nNewIndex )
+void ScDPFieldControlBase::AppendField( const rtl::OUString& rText, const ScPivotFuncData& rFunc )
 {
-    OSL_ENSURE( nNewIndex == maFieldNames.size(), "ScDPFieldWindow::AddField - invalid index" );
-    if( IsValidIndex( nNewIndex ) )
-    {
-        sal_uInt8 nDupCount = GetNextDupCount(rText);
-        maFieldNames.push_back(FieldName(rText, true, nDupCount));
-        AccessRef xRef(mxAccessible);
-        if ( xRef.is() )
-            xRef->AddField(nNewIndex);
-    }
+    size_t nNewIndex = maFieldNames.size();
+
+    sal_uInt8 nDupCount = GetNextDupCount(rText);
+    maFieldNames.push_back(FieldName(rText, true, nDupCount));
+    maFuncData.push_back(new ScPivotFuncData(rFunc));
+
+    AccessRef xRef(mxAccessible);
+    if ( xRef.is() )
+        xRef->AddField(nNewIndex);
 }
 
-bool ScDPFieldControlBase::AddField(
-    const rtl::OUString& rText, const Point& rPos, size_t& rnIndex, sal_uInt8& rnDupCount)
+size_t ScDPFieldControlBase::AddField(
+    const rtl::OUString& rText, const Point& rPos, const ScPivotFuncData& rFunc)
 {
     size_t nNewIndex = GetFieldIndex(rPos);
-    if (nNewIndex != PIVOTFIELD_INVALID)
-    {
-        if( nNewIndex > maFieldNames.size() )
-            nNewIndex = maFieldNames.size();
+    if (nNewIndex == PIVOTFIELD_INVALID)
+        return PIVOTFIELD_INVALID;
 
-        sal_uInt8 nDupCount = GetNextDupCount(rText);
-        maFieldNames.insert(maFieldNames.begin() + nNewIndex, FieldName(rText, true, nDupCount));
-        mnFieldSelected = nNewIndex;
-        ResetScrollBar();
-        Invalidate();
-        rnIndex = nNewIndex;
-        rnDupCount = nDupCount;
+    if (nNewIndex > maFieldNames.size())
+        nNewIndex = maFieldNames.size();
 
-        AccessRef xRef( mxAccessible );
-        if ( xRef.is() )
-            xRef->AddField(nNewIndex);
+    sal_uInt8 nDupCount = GetNextDupCount(rText);
+    maFieldNames.insert(maFieldNames.begin() + nNewIndex, FieldName(rText, true, nDupCount));
 
-        return true;
-    }
+    maFuncData.insert(maFuncData.begin() + nNewIndex, new ScPivotFuncData(rFunc));
+    maFuncData.back().mnDupCount = nDupCount;
+
+    mnFieldSelected = nNewIndex;
+    ResetScrollBar();
+    Invalidate();
 
-    return false;
+    AccessRef xRef( mxAccessible );
+    if ( xRef.is() )
+        xRef->AddField(nNewIndex);
+
+    return nNewIndex;
 }
 
 bool ScDPFieldControlBase::MoveField(size_t nCurPos, const Point& rPos, size_t& rnIndex)
@@ -185,21 +206,26 @@ bool ScDPFieldControlBase::MoveField(size_t nCurPos, const Point& rPos, size_t&
         return true;
 
     FieldName aName = maFieldNames[nCurPos];
+    ScPivotFuncData aFunc = maFuncData[nCurPos];
     if (nNewIndex >= maFieldNames.size())
     {
         // Move to the back.
         maFieldNames.erase(maFieldNames.begin()+nCurPos);
         maFieldNames.push_back(aName);
+        maFuncData.erase(maFuncData.begin()+nCurPos);
+        maFuncData.push_back(new ScPivotFuncData(aFunc));
         rnIndex = maFieldNames.size()-1;
     }
     else
     {
         maFieldNames.erase(maFieldNames.begin()+nCurPos);
+        maFuncData.erase(maFuncData.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);
+        maFuncData.insert(maFuncData.begin()+nTmp, new ScPivotFuncData(aFunc));
         rnIndex = nTmp;
     }
 
@@ -213,38 +239,25 @@ bool ScDPFieldControlBase::MoveField(size_t nCurPos, const Point& rPos, size_t&
     return true;
 }
 
-bool ScDPFieldControlBase::AppendField(const rtl::OUString& rText, size_t& rnIndex)
+void ScDPFieldControlBase::DeleteFieldByIndex( size_t nIndex )
 {
-    if (!IsValidIndex(maFieldNames.size()))
-        return false;
+    if (!IsExistingIndex(nIndex))
+        // Nothing to delete.
+        return;
 
-    sal_uInt8 nDupCount = GetNextDupCount(rText);
-    maFieldNames.push_back(FieldName(rText, true, nDupCount));
-    mnFieldSelected = maFieldNames.size() - 1;
-    ResetScrollBar();
-    Invalidate();
+    AccessRef xRef(mxAccessible);
+    if (xRef.is())
+        xRef->RemoveField(nIndex);
 
-    rnIndex = mnFieldSelected;
-    return true;
-}
 
-void ScDPFieldControlBase::DelField( size_t nDelIndex )
-{
-    if ( IsExistingIndex(nDelIndex) )
-    {
-        {
-            AccessRef xRef( mxAccessible );
-            if ( xRef.is() )
-                xRef->RemoveField(nDelIndex);
-        }
+    maFieldNames.erase(maFieldNames.begin() + nIndex);
+    if (mnFieldSelected >= maFieldNames.size())
+        mnFieldSelected = maFieldNames.size() - 1;
 
-        maFieldNames.erase( maFieldNames.begin() + nDelIndex );
-        if (mnFieldSelected >= maFieldNames.size())
-            mnFieldSelected = maFieldNames.size() - 1;
+    maFuncData.erase(maFuncData.begin() + nIndex);
 
-        ResetScrollBar();
-        Invalidate();
-    }
+    ResetScrollBar();
+    Invalidate();
 }
 
 size_t ScDPFieldControlBase::GetFieldCount() const
@@ -265,6 +278,7 @@ void ScDPFieldControlBase::ClearFields()
             xRef->RemoveField( nIdx - 1 );
 
     maFieldNames.clear();
+    maFuncData.clear();
 }
 
 void ScDPFieldControlBase::SetFieldText(const rtl::OUString& rText, size_t nIndex, sal_uInt8 nDupCount)
@@ -678,6 +692,7 @@ void ScDPFieldControlBase::MoveField( size_t nDestIndex )
     if (nDestIndex != mnFieldSelected)
     {
         std::swap(maFieldNames[nDestIndex], maFieldNames[mnFieldSelected]);
+        std::swap(maFuncData[nDestIndex], maFuncData[mnFieldSelected]);
         mnFieldSelected = nDestIndex;
     }
 }
@@ -732,6 +747,29 @@ sal_uInt8 ScDPFieldControlBase::GetNextDupCount(const rtl::OUString& rFieldText)
     return nMax;
 }
 
+sal_uInt8 ScDPFieldControlBase::GetNextDupCount(const ScPivotFuncData& rData, size_t nSelfIndex) const
+{
+    sal_uInt8 nDupCount = 0;
+    bool bFound = false;
+    for (size_t i = 0, n = maFuncData.size(); i < n; ++i)
+    {
+        if (i == nSelfIndex)
+            // Skip itself.
+            continue;
+
+        const ScPivotFuncData& r = maFuncData[i];
+
+        if (r.mnCol != rData.mnCol || r.mnFuncMask != rData.mnFuncMask)
+            continue;
+
+        bFound = true;
+        if (r.mnDupCount > nDupCount)
+            nDupCount = r.mnDupCount;
+    }
+
+    return bFound ? nDupCount + 1 : 0;
+}
+
 void ScDPFieldControlBase::SelectNext()
 {
     MoveSelection(mnFieldSelected + 1);
@@ -744,6 +782,104 @@ void ScDPFieldControlBase::GrabFocusAndSelect( size_t nIndex )
         GrabFocus();
 }
 
+const ScPivotFuncData& ScDPFieldControlBase::GetFuncData(size_t nIndex) const
+{
+    return maFuncData.at(nIndex);
+}
+
+ScPivotFuncData& ScDPFieldControlBase::GetFuncData(size_t nIndex)
+{
+    return maFuncData.at(nIndex);
+}
+
+namespace {
+
+class PushFuncItem : std::unary_function<ScPivotFuncData, void>
+{
+    std::vector<ScDPFieldControlBase::FuncItem>& mrItems;
+public:
+    PushFuncItem(std::vector<ScDPFieldControlBase::FuncItem>& rItems) : mrItems(rItems) {}
+
+    void operator() (const ScPivotFuncData& r)
+    {
+        ScDPFieldControlBase::FuncItem aItem;
+        aItem.mnCol = r.mnCol;
+        aItem.mnFuncMask = r.mnFuncMask;
+        mrItems.push_back(aItem);
+    }
+};
+
+}
+
+void ScDPFieldControlBase::GetAllFuncItems(std::vector<FuncItem>& rItems) const
+{
+    std::for_each(maFuncData.begin(), maFuncData.end(), PushFuncItem(rItems));
+}
+
+namespace {
+
+class PivotFieldInserter : public ::std::unary_function<ScPivotFuncData, void>
+{
+    vector<ScPivotField>& mrFields;
+public:
+    explicit PivotFieldInserter(vector<ScPivotField>& r, size_t nSize) : mrFields(r)
+    {
+        mrFields.reserve(nSize);
+    }
+
+    PivotFieldInserter(const PivotFieldInserter& r) : mrFields(r.mrFields) {}
+
+    void operator() (const ScPivotFuncData& r)
+    {
+        ScPivotField aField;
+        aField.nCol = r.mnCol;
+        aField.mnOriginalDim = r.mnOriginalDim;
+        aField.mnDupCount = r.mnDupCount;
+        aField.nFuncMask = r.mnFuncMask;
+        aField.maFieldRef = r.maFieldRef;
+        mrFields.push_back(aField);
+    }
+};
+
+}
+
+void ScDPFieldControlBase::ConvertToPivotArray(std::vector<ScPivotField>& rArray) const
+{
+    for_each(maFuncData.begin(), maFuncData.end(), PivotFieldInserter(rArray, maFuncData.size()));
+}
+
+namespace {
+
+class EqualByDimOnly : std::unary_function<ScPivotFuncData, bool>
+{
+    const ScPivotFuncData& mrData;
+    long mnDim;
+
+public:
+    EqualByDimOnly(const ScPivotFuncData& rData) : mrData(rData)
+    {
+        mnDim = rData.mnCol;
+        if (rData.mnOriginalDim >= 0)
+            mnDim = rData.mnOriginalDim;
+    }
+    bool operator() (const ScPivotFuncData& rData) const
+    {
+        long nDim = rData.mnCol;
+        if (rData.mnOriginalDim >= 0)
+            nDim = rData.mnOriginalDim;
+
+        return nDim == mnDim;
+    }
+};
+
+}
+
+size_t ScDPFieldControlBase::GetFieldIndexByData( const ScPivotFuncData& rData ) const
+{
+    FuncDataType::const_iterator it = std::find_if(maFuncData.begin(), maFuncData.end(), EqualByDimOnly(rData));
+    return it == maFuncData.end() ? PIVOTFIELD_INVALID : std::distance(maFuncData.begin(), it);
+}
+
 //=============================================================================
 
 ScDPHorFieldControl::ScDPHorFieldControl(
diff --git a/sc/source/ui/dbgui/pvlaydlg.cxx b/sc/source/ui/dbgui/pvlaydlg.cxx
index 3ef8e0b..86a3069 100644
--- a/sc/source/ui/dbgui/pvlaydlg.cxx
+++ b/sc/source/ui/dbgui/pvlaydlg.cxx
@@ -62,18 +62,26 @@
 #include "sc.hrc"
 #include "scabstdlg.hxx"
 
+#include <boost/scoped_ptr.hpp>
+
 using namespace com::sun::star;
 using ::rtl::OUString;
 using ::std::vector;
 using ::std::for_each;
 
-ScPivotLayoutDlg::FieldRect::FieldRect(const Rectangle* pRect, ScPivotFieldType eType) :
-    mpRect(pRect), meType(eType) {}
-
 namespace {
 
 const sal_uInt16 STD_FORMAT = sal_uInt16( SCA_VALID | SCA_TAB_3D | SCA_COL_ABSOLUTE | SCA_ROW_ABSOLUTE | SCA_TAB_ABSOLUTE );
 
+Point DlgPos2WndPos( const Point& rPt, const Window& rWnd )
+{
+    Point aWndPt( rPt );
+    aWndPt.X() = rPt.X()-rWnd.GetPosPixel().X();
+    aWndPt.Y() = rPt.Y()-rWnd.GetPosPixel().Y();
+
+    return aWndPt;
+}
+
 } // namespace
 
 ScPivotLayoutDlg::ScPivotLayoutDlg( SfxBindings* pB, SfxChildWindow* pCW, Window* pParent, const ScDPObject& rDPObject, bool bNewOutput ) :
@@ -152,6 +160,13 @@ ScPivotLayoutDlg::ScPivotLayoutDlg( SfxBindings* pB, SfxChildWindow* pCW, Window
     maBtnMore.AddWindow( &maBtnDrillDown );
     maBtnMore.SetClickHdl( LINK( this, ScPivotLayoutDlg, MoreClickHdl ) );
 
+    maFieldCtrls.reserve(5);
+    maFieldCtrls.push_back(&maWndPage);
+    maFieldCtrls.push_back(&maWndCol);
+    maFieldCtrls.push_back(&maWndRow);
+    maFieldCtrls.push_back(&maWndData);
+    maFieldCtrls.push_back(&maWndSelect);
+
     InitControlAndDlgSizes();
 
     if (mxDlgDPObject->GetSheetDesc())
@@ -186,7 +201,7 @@ ScPivotLayoutDlg::ScPivotLayoutDlg( SfxBindings* pB, SfxChildWindow* pCW, Window
     maBtnCancel.SetClickHdl( LINK( this, ScPivotLayoutDlg, CancelHdl ) );
 
     // Set focus handler for the reference edit text boxes.
-    Link aGetFocusLink = LINK(this, ScPivotLayoutDlg, GetFocusHdl);
+    Link aGetFocusLink = LINK(this, ScPivotLayoutDlg, GetRefEditFocusHdl);
     if (maEdInPos.IsEnabled())
         maEdInPos.SetGetFocusHdl(aGetFocusLink);
     maEdOutPos.SetGetFocusHdl(aGetFocusLink);
@@ -214,7 +229,8 @@ ScPivotLayoutDlg::ScPivotLayoutDlg( SfxBindings* pB, SfxChildWindow* pCW, Window
                 sal_uInt16 nInsert = maLbOutPos.InsertEntry( aName );
 
                 aRange.aStart.Format( aRefStr, SCA_ABS_3D, mpDoc, mpDoc->GetAddressConvention() );
-                maLbOutPos.SetEntryData(nInsert, new rtl::OUString(aRefStr));
+                maRefStrs.push_back(new OUString(aRefStr));
+                maLbOutPos.SetEntryData(nInsert, &maRefStrs.back());
             }
         }
     }
@@ -237,6 +253,7 @@ ScPivotLayoutDlg::ScPivotLayoutDlg( SfxBindings* pB, SfxChildWindow* pCW, Window
                        maPivotData.nRow,
                        maPivotData.nTab ).Format( aStr, STD_FORMAT, mpDoc, mpDoc->GetAddressConvention() );
             maEdOutPos.SetText( aStr );
+            maOutputRefStr = aStr;
             EdOutModifyHdl(0);
         }
         else
@@ -262,8 +279,6 @@ ScPivotLayoutDlg::ScPivotLayoutDlg( SfxBindings* pB, SfxChildWindow* pCW, Window
 
 ScPivotLayoutDlg::~ScPivotLayoutDlg()
 {
-    for (sal_uInt16 i = 2, nEntries = maLbOutPos.GetEntryCount(); i < nEntries; ++i)
-        delete (OUString*)maLbOutPos.GetEntryData(i);
 }
 
 sal_Bool ScPivotLayoutDlg::Close()
@@ -289,8 +304,8 @@ void ScPivotLayoutDlg::InitWndSelect(const ScDPLabelDataVector& rLabels)
             // For dimension with duplicates, use the layout name of the
             // original dimension if available.  Be aware that duplicate
             // dimensions may have different layout names.
-            maWndSelect.AddField(maLabelData[i].getDisplayName(), i);
-            maSelectArr.push_back(new ScPivotFuncData(maLabelData[i].mnCol, maLabelData[i].mnFuncMask));
+            ScPivotFuncData aFunc(maLabelData[i].mnCol, maLabelData[i].mnFuncMask);
+            maWndSelect.AppendField(maLabelData[i].getDisplayName(), aFunc);
         }
     }
     maWndSelect.ResetScrollBar();
@@ -307,24 +322,20 @@ void ScPivotLayoutDlg::InitWndData(const vector<ScPivotField>& rFields)
         if (nCol == PIVOT_DATA_FIELD)
             continue;
 
-        size_t nFieldIndex = maDataArr.size();
-        maDataArr.push_back(
-            new ScPivotFuncData(nCol, it->mnOriginalDim, nMask, it->mnDupCount, it->maFieldRef));
-
         // data field - we need to concatenate function name with the field name.
         ScDPLabelData* pData = GetLabelData(nCol);
         OSL_ENSURE( pData, "ScDPLabelData not found" );
         if (pData)
         {
+            ScPivotFuncData aFunc(nCol, it->mnOriginalDim, nMask, it->mnDupCount, it->maFieldRef);
             OUString aStr = pData->maLayoutName;
             if (aStr.isEmpty())
             {
-                sal_uInt16 nInitMask = maDataArr.back().mnFuncMask;
-                aStr = GetFuncString(nInitMask, pData->mbIsValue);
+                aStr = GetFuncString(aFunc.mnFuncMask, pData->mbIsValue);
                 aStr += pData->maName;
             }
 
-            maWndData.AddField(aStr, nFieldIndex);
+            maWndData.AppendField(aStr, aFunc);
             pData->mnFuncMask = nMask;
         }
     }
@@ -334,10 +345,9 @@ void ScPivotLayoutDlg::InitWndData(const vector<ScPivotField>& rFields)
 void ScPivotLayoutDlg::InitFieldWindow( const vector<ScPivotField>& rFields, ScPivotFieldType eType )
 {
     OSL_ASSERT(eType != PIVOTFIELDTYPE_DATA);
-    ScDPFuncDataVec* pInitArr = GetFieldDataArray(eType);
     ScDPFieldControlBase* pInitWnd = GetFieldWindow(eType);
 
-    if (!pInitArr || !pInitWnd)
+    if (!pInitWnd)
         return;
 
     vector<ScPivotField>::const_iterator itr = rFields.begin(), itrEnd = rFields.end();
@@ -348,10 +358,8 @@ void ScPivotLayoutDlg::InitFieldWindow( const vector<ScPivotField>& rFields, ScP
         if (nCol == PIVOT_DATA_FIELD)
             continue;
 
-        size_t nFieldIndex = pInitArr->size();
-        pInitArr->push_back(
-            new ScPivotFuncData(nCol, itr->mnOriginalDim, nMask, itr->mnDupCount, itr->maFieldRef));
-        pInitWnd->AddField(GetLabelString(nCol), nFieldIndex);
+        ScPivotFuncData aFunc(nCol, itr->mnOriginalDim, nMask, itr->mnDupCount, itr->maFieldRef);
+        pInitWnd->AppendField(GetLabelString(nCol), aFunc);
     }
     pInitWnd->ResetScrollBar();
 }
@@ -380,9 +388,9 @@ void ScPivotLayoutDlg::GrabFieldFocus( ScDPFieldControlBase& rFieldWindow )
 
 void ScPivotLayoutDlg::AddField( size_t nFromIndex, ScPivotFieldType eToType, const Point& rAtPos )
 {
-    ScPivotFuncData fData = maSelectArr[nFromIndex];
+    ScPivotFuncData aFunc = maWndSelect.GetFuncData(nFromIndex); // local copy
 
-    bool bAllowed = IsOrientationAllowed( fData.mnCol, eToType );
+    bool bAllowed = IsOrientationAllowed(aFunc.mnCol, eToType);
     if (!bAllowed)
         return;
 
@@ -392,17 +400,12 @@ void ScPivotLayoutDlg::AddField( size_t nFromIndex, ScPivotFieldType eToType, co
     ScDPFieldControlBase* rmWnd2 = NULL;
     GetOtherFieldWindows(eToType, rmWnd1, rmWnd2);
 
-    ScDPFuncDataVec*    toArr = GetFieldDataArray(eToType);
-    ScDPFuncDataVec*    rmArr1 = NULL;
-    ScDPFuncDataVec*    rmArr2 = NULL;
-    GetOtherDataArrays(eToType, rmArr1, rmArr2);
-
     if (eToType == PIVOTFIELDTYPE_DATA)
     {
         // Data field allows duplicates.
-        ScDPLabelData* p = GetLabelData(fData.mnCol);
+        ScDPLabelData* p = GetLabelData(aFunc.mnCol);
         OUString aStr = p->maLayoutName;
-        sal_uInt16 nMask = fData.mnFuncMask;
+        sal_uInt16 nMask = aFunc.mnFuncMask;
         if (nMask == PIVOT_FUNC_NONE)
             nMask = PIVOT_FUNC_SUM; // Use SUM by default.
         if (aStr.isEmpty())
@@ -411,55 +414,40 @@ void ScPivotLayoutDlg::AddField( size_t nFromIndex, ScPivotFieldType eToType, co
             aStr += p->maName;
         }
 
-        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);
+        aFunc.mnFuncMask = nMask;
+        size_t nAddedAt = toWnd->AddField(aStr, DlgPos2WndPos(rAtPos, *toWnd), aFunc);
+        if (nAddedAt != PIVOTFIELD_INVALID)
             toWnd->GrabFocus();
-        }
 
         return;
     }
 
-    if (!Contains(toArr, fData, nAt))
+    nAt = toWnd->GetFieldIndexByData(aFunc);
+    if (nAt == PIVOTFIELD_INVALID)
     {
-        // ggF. in anderem Fenster entfernen
-        if ( rmArr1 )
+        if (rmWnd1)
         {
-            if ( Contains( rmArr1, fData, nAt ) )
-            {
-                rmWnd1->DelField( nAt );
-                Remove( rmArr1, nAt );
-            }
+            nAt = rmWnd1->GetFieldIndexByData(aFunc);
+            if (nAt != PIVOTFIELD_INVALID)
+                rmWnd1->DeleteFieldByIndex(nAt);
         }
-        if ( rmArr2 )
+        if (rmWnd2)
         {
-            if ( Contains( rmArr2, fData, nAt ) )
-            {
-                rmWnd2->DelField( nAt );
-                Remove( rmArr2, nAt );
-            }
+            nAt = rmWnd2->GetFieldIndexByData(aFunc);
+            if (nAt != PIVOTFIELD_INVALID)
+                rmWnd2->DeleteFieldByIndex(nAt);
         }
 
-        size_t nAddedAt = 0;
-        sal_uInt8 nDupCount = 0;
-        ScDPLabelData& rData = maLabelData[nFromIndex+mnOffset];
-        if (toWnd->AddField(
-            rData.getDisplayName(), DlgPos2WndPos(rAtPos, *toWnd), nAddedAt, nDupCount))
-        {
-            fData.mnDupCount = nDupCount;
-            Insert( toArr, fData, nAddedAt );
+        const ScDPLabelData& rData = maLabelData[nFromIndex+mnOffset];
+        size_t nAddedAt = toWnd->AddField(rData.getDisplayName(), DlgPos2WndPos(rAtPos, *toWnd), aFunc);
+        if (nAddedAt != PIVOTFIELD_INVALID)
             toWnd->GrabFocus();
-        }
     }
 }
 
 void ScPivotLayoutDlg::AppendField(size_t nFromIndex, ScPivotFieldType eToType)
 {
-    ScPivotFuncData aFuncData = maSelectArr[nFromIndex];
+    ScPivotFuncData aFunc = maWndSelect.GetFuncData(nFromIndex); // local copy
 
     size_t nAt = 0;
     ScDPFieldControlBase* toWnd = GetFieldWindow(eToType);
@@ -467,61 +455,45 @@ void ScPivotLayoutDlg::AppendField(size_t nFromIndex, ScPivotFieldType eToType)
     ScDPFieldControlBase* rmWnd2 = NULL;
     GetOtherFieldWindows(eToType, rmWnd1, rmWnd2);
 
-    ScDPFuncDataVec*    toArr = GetFieldDataArray(eToType);
-    ScDPFuncDataVec*    rmArr1 = NULL;
-    ScDPFuncDataVec*    rmArr2 = NULL;
-    GetOtherDataArrays(eToType, rmArr1, rmArr2);
-
     bool bDataArr = eToType == PIVOTFIELDTYPE_DATA;
 
-    if ( (!Contains( toArr, aFuncData, nAt )) )
+    nAt = toWnd->GetFieldIndexByData(aFunc);
+    if (nAt == PIVOTFIELD_INVALID)
     {
-        // ggF. in anderem Fenster entfernen
-        if ( rmArr1 )
+        if (rmWnd1)
         {
-            if ( Contains( rmArr1, aFuncData, nAt ) )
-            {
-                rmWnd1->DelField( nAt );
-                Remove( rmArr1, nAt );
-            }
+            nAt = rmWnd1->GetFieldIndexByData(aFunc);
+            if (nAt != PIVOTFIELD_INVALID)
+                rmWnd1->DeleteFieldByIndex(nAt);
         }
-        if ( rmArr2 )
+        if (rmWnd2)
         {
-            if ( Contains( rmArr2, aFuncData, nAt ) )
-            {
-                rmWnd2->DelField( nAt );
-                Remove( rmArr2, nAt );
-            }
+            nAt = rmWnd2->GetFieldIndexByData(aFunc);
+            if (nAt != PIVOTFIELD_INVALID)
+                rmWnd2->DeleteFieldByIndex(nAt);
         }
 
         ScDPLabelData&  rData = maLabelData[nFromIndex+mnOffset];
-        size_t      nAddedAt = 0;
 
         if ( !bDataArr )
         {
-            if ( toWnd->AppendField(rData.getDisplayName(), nAddedAt) )
-            {
-                Insert( toArr, aFuncData, nAddedAt );
-                toWnd->GrabFocus();
-            }
+            toWnd->AppendField(rData.getDisplayName(), aFunc);
+            toWnd->GrabFocus();
         }
         else
         {
-            ScDPLabelData* p = GetLabelData(aFuncData.mnCol);
+            ScDPLabelData* p = GetLabelData(aFunc.mnCol);
             OUString aStr = p->maLayoutName;
-            sal_uInt16 nMask = aFuncData.mnFuncMask;
+            sal_uInt16 nMask = aFunc.mnFuncMask;
             if (aStr.isEmpty())
             {
                 aStr = GetFuncString(nMask);
                 aStr += p->maName;
             }
 
-            if ( toWnd->AppendField(aStr, nAddedAt) )
-            {
-                aFuncData.mnFuncMask = nMask;
-                Insert( toArr, aFuncData, nAddedAt );
-                toWnd->GrabFocus();
-            }
+            aFunc.mnFuncMask = nMask;
+            toWnd->AppendField(aStr, aFunc);
+            toWnd->GrabFocus();
         }
     }
 }
@@ -541,79 +513,57 @@ void ScPivotLayoutDlg::MoveField( ScPivotFieldType eFromType, size_t nFromIndex,
         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);
-
         bool bDataArr = eToType == PIVOTFIELDTYPE_DATA;
 
-        if ( fromArr && toArr && fromWnd && toWnd )
+        if (fromWnd && toWnd)
         {
-            ScPivotFuncData fData = (*fromArr)[nFromIndex];
-            bool bAllowed = IsOrientationAllowed( fData.mnCol, eToType );
+            ScPivotFuncData aFunc = fromWnd->GetFuncData(nFromIndex); // local copy
+            bool bAllowed = IsOrientationAllowed(aFunc.mnCol, eToType);
 
-            size_t nAt = 0;
-            if ( bAllowed && Contains( fromArr, fData, nAt ) )
+            size_t nAt = fromWnd->GetFieldIndexByData(aFunc);
+            if (bAllowed && nAt != PIVOTFIELD_INVALID)
             {
-                fromWnd->DelField( nAt );
-                Remove( fromArr, nAt );
+                fromWnd->DeleteFieldByIndex(nAt);
 
-                if (!Contains( toArr, fData, nAt ))
+                nAt = toWnd->GetFieldIndexByData(aFunc);
+                if (nAt == PIVOTFIELD_INVALID)
                 {
                     size_t nAddedAt = 0;
-                    sal_uInt8 nDupCount = 0;
                     if ( !bDataArr )
                     {
-                        // ggF. in anderem Fenster entfernen
-                        if ( rmArr1 )
+                        if (rmWnd1)
                         {
-                            if ( Contains( rmArr1, fData, nAt ) )
-                            {
-                                rmWnd1->DelField( nAt );
-                                Remove( rmArr1, nAt );
-                            }
+                            nAt = rmWnd1->GetFieldIndexByData(aFunc);
+                            if (nAt != PIVOTFIELD_INVALID)
+                                rmWnd1->DeleteFieldByIndex(nAt);
                         }
-                        if ( rmArr2 )
+                        if (rmWnd2)
                         {
-                            if ( Contains( rmArr2, fData, nAt ) )
-                            {
-                                rmWnd2->DelField( nAt );
-                                Remove( rmArr2, nAt );
-                            }
+                            nAt = rmWnd2->GetFieldIndexByData(aFunc);
+                            if (nAt != PIVOTFIELD_INVALID)
+                                rmWnd2->DeleteFieldByIndex(nAt);
                         }
 
-                        if ( toWnd->AddField( GetLabelString( fData.mnCol ),
-                                              DlgPos2WndPos( rAtPos, *toWnd ),
-                                              nAddedAt, nDupCount) )
-                        {
-                            fData.mnDupCount = nDupCount;
-                            Insert( toArr, fData, nAddedAt );
+                        nAddedAt = toWnd->AddField(
+                            GetLabelString(aFunc.mnCol), DlgPos2WndPos(rAtPos, *toWnd), aFunc);
+                        if (nAddedAt != PIVOTFIELD_INVALID)
                             toWnd->GrabFocus();
-                        }
                     }
                     else
                     {
-                        ScDPLabelData* p = GetLabelData(fData.mnCol);
+                        ScDPLabelData* p = GetLabelData(aFunc.mnCol);
                         OUString aStr = p->maLayoutName;
-                        sal_uInt16 nMask = fData.mnFuncMask;
+                        sal_uInt16 nMask = aFunc.mnFuncMask;
                         if (aStr.isEmpty())
                         {
                             aStr = GetFuncString(nMask);
                             aStr += p->maName;
                         }
 
-                        if ( toWnd->AddField( aStr,
-                                              DlgPos2WndPos( rAtPos, *toWnd ),
-                                              nAddedAt, nDupCount) )
-                        {
-                            fData.mnFuncMask = nMask;
-                            fData.mnDupCount = nDupCount;
-                            Insert( toArr, fData, nAddedAt );
+                        aFunc.mnFuncMask = nMask;
+                        nAddedAt = toWnd->AddField(aStr, DlgPos2WndPos(rAtPos, *toWnd), aFunc);
+                        if (nAddedAt != PIVOTFIELD_INVALID)
                             toWnd->GrabFocus();
-                        }
                     }
                 }
             }
@@ -621,27 +571,23 @@ void ScPivotLayoutDlg::MoveField( ScPivotFieldType eFromType, size_t nFromIndex,
     }
     else // -> eFromType == eToType
     {
-        ScDPFieldControlBase* theWnd  = GetFieldWindow(eFromType);
-        ScDPFuncDataVec*    theArr   = GetFieldDataArray(eFromType);
-        size_t              nAt      = 0;
-        Point               aToPos;
+        ScDPFieldControlBase* pWnd  = GetFieldWindow(eFromType);
+        if (!pWnd)
+            return;
 
-        ScPivotFuncData fData = (*theArr)[nFromIndex];
+        const ScPivotFuncData& rFunc = pWnd->GetFuncData(nFromIndex);
 
-        if ( Contains( theArr, fData, nAt ) )
+        size_t nAt = pWnd->GetFieldIndexByData(rFunc);
+        if (nAt != PIVOTFIELD_INVALID)
         {
+            Point aToPos = DlgPos2WndPos( rAtPos, *pWnd );
             size_t nToIndex = 0;
-            aToPos = DlgPos2WndPos( rAtPos, *theWnd );
-            theWnd->GetExistingIndex( aToPos, nToIndex );
+            pWnd->GetExistingIndex(aToPos, nToIndex);
 
             if ( nToIndex != nAt )
             {
                 size_t nAddedAt = 0;
-                if (theWnd->MoveField(nAt, aToPos, nAddedAt))
-                {
-                    Remove(theArr, nAt);
-                    Insert(theArr, fData, nAddedAt);
-                }
+                pWnd->MoveField(nAt, aToPos, nAddedAt);
             }
         }
     }
@@ -660,121 +606,92 @@ void ScPivotLayoutDlg::MoveFieldToEnd( ScPivotFieldType eFromType, size_t nFromI
         ScDPFieldControlBase* rmWnd2   = NULL;
         GetOtherFieldWindows(eToType, rmWnd1, rmWnd2);
 
-        ScDPFuncDataVec*    fromArr  = GetFieldDataArray(eFromType);
-        ScDPFuncDataVec*    toArr    = GetFieldDataArray(eToType);
+        bool bDataArr = eToType == PIVOTFIELDTYPE_DATA;
 
-        ScDPFuncDataVec*    rmArr1   = NULL;
-        ScDPFuncDataVec*    rmArr2   = NULL;
-        GetOtherDataArrays(eToType, rmArr1, rmArr2);
+        if (!fromWnd || !toWnd)
+            return;
 
-        bool bDataArr = eToType == PIVOTFIELDTYPE_DATA;
+        ScPivotFuncData aFunc = fromWnd->GetFuncData(nFromIndex); // local copy
 
-        if ( fromArr && toArr && fromWnd && toWnd )
+        size_t nAt = fromWnd->GetFieldIndexByData(aFunc);
+        if (nAt != PIVOTFIELD_INVALID)
         {
-            ScPivotFuncData fData = (*fromArr)[nFromIndex];
+            fromWnd->DeleteFieldByIndex(nAt);
 
-            size_t nAt = 0;
-            if ( Contains( fromArr, fData, nAt ) )
+            nAt = toWnd->GetFieldIndexByData(aFunc);
+            if (nAt == PIVOTFIELD_INVALID)
             {
-                fromWnd->DelField( nAt );
-                Remove( fromArr, nAt );
-
-                if (!Contains( toArr, fData, nAt ))
+                if ( !bDataArr )
                 {
-                    size_t nAddedAt = 0;
-                    if ( !bDataArr )
+                    if (rmWnd1)
                     {
-                        // ggF. in anderem Fenster entfernen
-                        if ( rmArr1 )
-                        {
-                            if ( Contains( rmArr1, fData, nAt ) )
-                            {
-                                rmWnd1->DelField( nAt );
-                                Remove( rmArr1, nAt );
-                            }
-                        }
-                        if ( rmArr2 )
-                        {
-                            if ( Contains( rmArr2, fData, nAt ) )
-                            {
-                                rmWnd2->DelField( nAt );
-                                Remove( rmArr2, nAt );
-                            }
-                        }
-
-                        if ( toWnd->AppendField( GetLabelString( fData.mnCol ), nAddedAt ) )
-                        {
-                            Insert( toArr, fData, nAddedAt );
-                            toWnd->GrabFocus();
-                        }
+                        nAt = rmWnd1->GetFieldIndexByData(aFunc);
+                        if (nAt != PIVOTFIELD_INVALID)
+                            rmWnd1->DeleteFieldByIndex(nAt);
                     }
-                    else
+                    if (rmWnd2)
                     {
-                        ScDPLabelData* p = GetLabelData(fData.mnCol);
-                        OUString aStr = p->maLayoutName;
-                        sal_uInt16 nMask = fData.mnFuncMask;
-                        if (aStr.isEmpty())
-                        {
-                            aStr = GetFuncString(nMask);
-                            aStr += p->maName;
-                        }
+                        nAt = rmWnd2->GetFieldIndexByData(aFunc);
+                        if (nAt != PIVOTFIELD_INVALID)
+                            rmWnd2->DeleteFieldByIndex(nAt);
+                    }
 
-                        if ( toWnd->AppendField(aStr, nAddedAt) )
-                        {
-                            fData.mnFuncMask = nMask;
-                            Insert( toArr, fData, nAddedAt );
-                            toWnd->GrabFocus();
-                        }
+                    toWnd->AppendField(GetLabelString(aFunc.mnCol), aFunc);
+                    toWnd->GrabFocus();
+                }
+                else
+                {
+                    ScDPLabelData* p = GetLabelData(aFunc.mnCol);
+                    OUString aStr = p->maLayoutName;
+                    sal_uInt16 nMask = aFunc.mnFuncMask;
+                    if (aStr.isEmpty())
+                    {
+                        aStr = GetFuncString(nMask);
+                        aStr += p->maName;
                     }
+
+                    aFunc.mnFuncMask = nMask;
+                    toWnd->AppendField(aStr, aFunc);
+                    toWnd->GrabFocus();
                 }
             }
         }
     }
     else // -> eFromType == eToType
     {
-        ScDPFieldControlBase* theWnd  = GetFieldWindow(eFromType);
-        ScDPFuncDataVec*    theArr   = GetFieldDataArray(eFromType);
-        size_t              nAt      = 0;
-        Point               aToPos;
-        bool bDataArr = eFromType == PIVOTFIELDTYPE_DATA;
+        ScDPFieldControlBase* pWnd  = GetFieldWindow(eFromType);
+        if (!pWnd)
+            return;
 
-        ScPivotFuncData fData = (*theArr)[nFromIndex];
+        Point aToPos;
+        bool bDataArr = eFromType == PIVOTFIELDTYPE_DATA;
 
-        if ( Contains( theArr, fData, nAt ) )
+        ScPivotFuncData aFunc = pWnd->GetFuncData(nFromIndex); // local copy
+        size_t nAt = pWnd->GetFieldIndexByData(aFunc);
+        if (nAt != PIVOTFIELD_INVALID)
         {
             size_t nToIndex = 0;
-            theWnd->GetExistingIndex( aToPos, nToIndex );
+            pWnd->GetExistingIndex( aToPos, nToIndex );
 
             if ( nToIndex != nAt )
             {
-                size_t nAddedAt = 0;
-
-                theWnd->DelField( nAt );
-                Remove( theArr, nAt );
+                pWnd->DeleteFieldByIndex(nAt);
 
                 if ( !bDataArr )
-                {
-                    if ( theWnd->AppendField(GetLabelString( fData.mnCol ), nAddedAt) )
-                    {
-                        Insert( theArr, fData, nAddedAt );
-                    }
-                }
+                    pWnd->AppendField(GetLabelString(aFunc.mnCol), aFunc);
                 else
                 {
-                    ScDPLabelData* p = GetLabelData(fData.mnCol);
+                    ScDPLabelData* p = GetLabelData(aFunc.mnCol);
                     OUString aStr = p->maLayoutName;
-                    sal_uInt16 nMask = fData.mnFuncMask;
+                    sal_uInt16 nMask = aFunc.mnFuncMask;
                     if (aStr.isEmpty())
                     {
                         aStr = GetFuncString(nMask);
                         aStr += p->maName;
                     }
 
-                    if ( theWnd->AppendField(aStr, nAddedAt) )
-                    {
-                        fData.mnFuncMask = nMask;
-                        Insert( theArr, fData, nAddedAt );
-                    }
+                    aFunc.mnFuncMask = nMask;
+                    pWnd->AppendField(aStr, aFunc);
                 }
             }
         }
@@ -783,19 +700,17 @@ void ScPivotLayoutDlg::MoveFieldToEnd( ScPivotFieldType eFromType, size_t nFromI
 
 void ScPivotLayoutDlg::RemoveField( ScPivotFieldType eFromType, size_t nIndex )
 {
-    ScDPFuncDataVec* pArr = GetFieldDataArray(eFromType);
+    ScDPFieldControlBase* pWnd = GetFieldWindow(eFromType);
+    if (!pWnd)
+        return;
 
-    if( pArr )
-    {
-        ScDPFieldControlBase* pWnd = GetFieldWindow( eFromType );
-        if (pWnd)
-        {
-            pWnd->DelField( nIndex );
-            Remove( pArr, nIndex );
-            if( pWnd->IsEmpty() )
-                GrabFieldFocus( maWndSelect );
-        }
-    }
+    if (nIndex >= pWnd->GetFieldCount())
+        // out of bound
+        return;
+
+    pWnd->DeleteFieldByIndex(nIndex);
+    if (pWnd->IsEmpty())
+        GrabFieldFocus(maWndSelect);
 }
 
 PointerStyle ScPivotLayoutDlg::NotifyMouseButtonDown( ScPivotFieldType eType, size_t nFieldIndex )
@@ -824,104 +739,105 @@ PointerStyle ScPivotLayoutDlg::NotifyMouseButtonDown( ScPivotFieldType eType, si
 
 void ScPivotLayoutDlg::NotifyDoubleClick( ScPivotFieldType eType, size_t nFieldIndex )
 {
-    ScDPFuncDataVec* pArr = GetFieldDataArray(eType);
+    ScDPFieldControlBase* pWnd = GetFieldWindow(eType);
+    if (!pWnd)
+        return;
 
-    if ( pArr )
+    if (nFieldIndex >= pWnd->GetFieldCount())
     {
-        if ( nFieldIndex >= pArr->size() )
-        {
-            OSL_FAIL("invalid selection");
-            return;
-        }
+        OSL_FAIL("invalid selection");
+        return;
+    }
 
-        size_t nArrPos = 0;
-        if( ScDPLabelData* pData = GetLabelData( (*pArr)[nFieldIndex].mnCol, &nArrPos ) )
-        {
-            ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
-            OSL_ENSURE(pFact, "ScAbstractFactory create fail!");
+    ScPivotFuncData& rFunc = pWnd->GetFuncData(nFieldIndex);
+    ScDPLabelData* pData = GetLabelData(rFunc.mnCol);
+    if (!pData)
+        return;
 
-            switch ( eType )
-            {
-                case PIVOTFIELDTYPE_PAGE:
-                case PIVOTFIELDTYPE_COL:
-                case PIVOTFIELDTYPE_ROW:
-                {
-                    // list of names of all data fields
-                    vector<ScDPName> aDataFieldNames;
-                    for( ScDPFuncDataVec::const_iterator aIt = maDataArr.begin(), aEnd = maDataArr.end();
-                            (aIt != aEnd); ++aIt)
-                    {
-                        ScDPLabelData* pDFData = GetLabelData(aIt->mnCol);
-                        if (!pDFData)
-                            continue;
+    ScAbstractDialogFactory* pFact = ScAbstractDialogFactory::Create();
+    OSL_ENSURE(pFact, "ScAbstractFactory create fail!");
 
-                        if (pDFData->maName.isEmpty())
-                            continue;
+    switch ( eType )
+    {
+        case PIVOTFIELDTYPE_PAGE:
+        case PIVOTFIELDTYPE_COL:
+        case PIVOTFIELDTYPE_ROW:
+        {
+            // list of names of all data fields
+            vector<ScDPName> aDataFieldNames;
+            vector<ScDPFieldControlBase::FuncItem> aFuncItems;
+            maWndData.GetAllFuncItems(aFuncItems);
+            vector<ScDPFieldControlBase::FuncItem>::const_iterator it = aFuncItems.begin(), itEnd = aFuncItems.end();
+            for (; it != itEnd; ++it)
+            {
+                ScDPLabelData* pDFData = GetLabelData(it->mnCol);
+                if (!pDFData)
+                    continue;
 
-                        OUString aLayoutName = pDFData->maLayoutName;
-                        if (aLayoutName.isEmpty())
-                        {
-                            // No layout name exists.  Use the stock name.
-                            sal_uInt16 nMask = aIt->mnFuncMask;
-                            OUString aFuncStr = GetFuncString(nMask);
-                            aLayoutName = aFuncStr + pDFData->maName;
-                        }
-                        aDataFieldNames.push_back(ScDPName(pDFData->maName, aLayoutName));
-                    }
+                if (pDFData->maName.isEmpty())
+                    continue;
 
-                    bool bLayout = (eType == PIVOTFIELDTYPE_ROW) &&
-                        ((aDataFieldNames.size() > 1) || (nFieldIndex + 1 < pArr->size()));
+                OUString aLayoutName = pDFData->maLayoutName;
+                if (aLayoutName.isEmpty())
+                {
+                    // No layout name exists.  Use the stock name.
+                    sal_uInt16 nMask = it->mnFuncMask;
+                    OUString aFuncStr = GetFuncString(nMask);
+                    aLayoutName = aFuncStr + pDFData->maName;
+                }
+                aDataFieldNames.push_back(ScDPName(pDFData->maName, aLayoutName));
+            }
 
-                    AbstractScDPSubtotalDlg* pDlg = pFact->CreateScDPSubtotalDlg(
-                        this, RID_SCDLG_PIVOTSUBT,
-                        *mxDlgDPObject, *pData, (*pArr)[nFieldIndex], aDataFieldNames, bLayout );
+            bool bLayout = (eType == PIVOTFIELDTYPE_ROW) &&
+                ((aDataFieldNames.size() > 1) || (nFieldIndex + 1 < pWnd->GetFieldCount()));
 
-                    if ( pDlg->Execute() == RET_OK )
-                    {
-                        pDlg->FillLabelData( *pData );
-                        (*pArr)[nFieldIndex].mnFuncMask = pData->mnFuncMask;
-                    }
-                    delete pDlg;
-                }
-                break;
+            boost::scoped_ptr<AbstractScDPSubtotalDlg> pDlg(
+                pFact->CreateScDPSubtotalDlg(
+                    this, RID_SCDLG_PIVOTSUBT, *mxDlgDPObject, *pData, rFunc,
+                    aDataFieldNames, bLayout));
 
-                case PIVOTFIELDTYPE_DATA:
-                {
-                    ScPivotFuncData& rFuncData = maDataArr[nFieldIndex];
-                    AbstractScDPFunctionDlg* pDlg = pFact->CreateScDPFunctionDlg(
-                        this, RID_SCDLG_DPDATAFIELD,
-                        maLabelData, *pData, rFuncData);
+            if ( pDlg->Execute() == RET_OK )
+            {
+                pDlg->FillLabelData( *pData );
+                rFunc.mnFuncMask = pData->mnFuncMask;
+            }
+        }
+        break;
 
-                    if ( pDlg->Execute() == RET_OK )
-                    {
-                        bool bFuncChanged = rFuncData.mnFuncMask != pDlg->GetFuncMask();
-                        rFuncData.mnFuncMask = pData->mnFuncMask = pDlg->GetFuncMask();
-                        rFuncData.maFieldRef = pDlg->GetFieldRef();
+        case PIVOTFIELDTYPE_DATA:
+        {
+            ScPivotFuncData& rFuncData = maWndData.GetFuncData(nFieldIndex);
+            boost::scoped_ptr<AbstractScDPFunctionDlg> pDlg(
+                pFact->CreateScDPFunctionDlg(
+                    this, RID_SCDLG_DPDATAFIELD, maLabelData, *pData, rFuncData));
 
-                        if (bFuncChanged)
-                            // Get the new duplicate count since the function has changed.
-                            rFuncData.mnDupCount = GetNextDupCount(maDataArr, rFuncData, nFieldIndex);
+            if ( pDlg->Execute() == RET_OK )
+            {
+                bool bFuncChanged = rFuncData.mnFuncMask != pDlg->GetFuncMask();
+                rFuncData.mnFuncMask = pData->mnFuncMask = pDlg->GetFuncMask();
+                rFuncData.maFieldRef = pDlg->GetFieldRef();
 
-                        ScDPLabelData* p = GetLabelData(rFuncData.mnCol);
-                        OUString aStr = p->maLayoutName;
-                        if (aStr.isEmpty())
-                        {
-                            // Layout name is not available.  Use default name.
-                            aStr = GetFuncString (rFuncData.mnFuncMask);
-                            aStr += p->maName;
-                        }
-                        maWndData.SetFieldText(aStr, nFieldIndex, rFuncData.mnDupCount);
-                    }
-                    delete pDlg;
-                }
-                break;
+                if (bFuncChanged)
+                    // Get the new duplicate count since the function has changed.
+                    rFuncData.mnDupCount = maWndData.GetNextDupCount(rFuncData, nFieldIndex);
 
-                default:
+                ScDPLabelData* p = GetLabelData(rFuncData.mnCol);
+                OUString aStr = p->maLayoutName;
+                if (aStr.isEmpty())
                 {
-                    // added to avoid warnings
+                    // Layout name is not available.  Use default name.
+                    aStr = GetFuncString (rFuncData.mnFuncMask);
+                    aStr += p->maName;
                 }
+                maWndData.SetFieldText(aStr, nFieldIndex, rFuncData.mnDupCount);
             }
         }
+        break;
+
+        default:
+        {
+            // added to avoid warnings
+        }
     }
 }
 
@@ -1004,7 +920,6 @@ PointerStyle ScPivotLayoutDlg::GetPointerStyleAtPoint( const Point& /* rScrPos *
     if (!mbIsDrag)
         return POINTER_ARROW;
 
-//    Point aPos = ScreenToOutputPixel(rScrPos);
     if (eFieldType == PIVOTFIELDTYPE_UNKNOWN)
         // Outside any field areas.
         return meDnDFromType == PIVOTFIELDTYPE_SELECT ? POINTER_PIVOT_FIELD : POINTER_PIVOT_DELETE;
@@ -1013,8 +928,11 @@ PointerStyle ScPivotLayoutDlg::GetPointerStyleAtPoint( const Point& /* rScrPos *
         return POINTER_PIVOT_FIELD;
 
     // check if the target orientation is allowed for this field
-    ScDPFuncDataVec* fromArr = GetFieldDataArray(meDnDFromType);
-    const ScPivotFuncData& rData = (*fromArr)[mnDnDFromIndex];
+    ScDPFieldControlBase* pWnd = GetFieldWindow(meDnDFromType);
+    if (!pWnd)
+        return POINTER_ARROW;
+
+    const ScPivotFuncData& rData = pWnd->GetFuncData(mnDnDFromIndex);
     if (!IsOrientationAllowed(rData.mnCol, eFieldType))
         return POINTER_NOTALLOWED;
 
@@ -1034,17 +952,30 @@ PointerStyle ScPivotLayoutDlg::GetPointerStyleAtPoint( const Point& /* rScrPos *
     return POINTER_PIVOT_FIELD;
 }
 
-ScPivotFieldType ScPivotLayoutDlg::GetFieldTypeAtPoint( const Point& rScrPos ) const
+namespace {
+
+class InsideFieldControl : std::unary_function<ScDPFieldControlBase*, bool>
 {
-    Point aOutputPos = ScreenToOutputPixel(rScrPos);
-    std::vector<FieldRect>::const_iterator it = maFieldRects.begin(), itEnd = maFieldRects.end();
-    for (; it != itEnd; ++it)
+    Point maOutPos;
+public:
+    InsideFieldControl(const Point& rOutPos) : maOutPos(rOutPos) {}
+
+    bool operator() (const ScDPFieldControlBase* p) const
     {
-        if (it->mpRect->IsInside(aOutputPos))
-            return it->meType;
+        Rectangle aRect(p->GetPosPixel(), p->GetSizePixel());
+        return aRect.IsInside(maOutPos);
     }
+};
+
+}
+
+ScPivotFieldType ScPivotLayoutDlg::GetFieldTypeAtPoint( const Point& rScrPos ) const
+{
+    Point aOutputPos = ScreenToOutputPixel(rScrPos);
+    std::vector<ScDPFieldControlBase*>::const_iterator it =
+        std::find_if(maFieldCtrls.begin(), maFieldCtrls.end(), InsideFieldControl(aOutputPos));
 
-    return PIVOTFIELDTYPE_UNKNOWN;
+    return it == maFieldCtrls.end() ? PIVOTFIELDTYPE_UNKNOWN : (*it)->GetFieldType();
 }
 
 void ScPivotLayoutDlg::Deactivate()
@@ -1056,56 +987,27 @@ void ScPivotLayoutDlg::Deactivate()
     NotifyFieldFocus( meLastActiveType, true );
 }
 
-bool ScPivotLayoutDlg::Contains( ScDPFuncDataVec* pArr, const ScPivotFuncData& rData, size_t& nAt )
+namespace {
+
+class FindLabelDataByCol : std::unary_function<ScDPLabelData, bool>
 {
-    if (!pArr || pArr->empty())
-        return false;
+    SCCOL mnCol;
+public:
+    FindLabelDataByCol(SCCOL nCol) : mnCol(nCol) {}
 
-    ScDPFuncDataVec::const_iterator itr, itrBeg = pArr->begin(), itrEnd = pArr->end();
-    for (itr = itrBeg; itr != itrEnd; ++itr)
+    bool operator() (const ScDPLabelData& r) const
     {
-        if (*itr == rData)
-        {
-            // found!
-            nAt = ::std::distance(itrBeg, itr);
-            return true;
-        }
+        return r.mnCol == mnCol;
     }
-    return false;
-}
-
-void ScPivotLayoutDlg::Remove( ScDPFuncDataVec* pArr, size_t nAt )
-{
-    if ( !pArr || (nAt>=pArr->size()) )
-        return;
-
-    pArr->erase( pArr->begin() + nAt );
-}
-
-void ScPivotLayoutDlg::Insert( ScDPFuncDataVec* pArr, const ScPivotFuncData& rFData, size_t nAt )
-{
-    if (!pArr)
-        return;
+};
 
-    std::auto_ptr<ScPivotFuncData> p(new ScPivotFuncData(rFData));
-    if (nAt >= pArr->size())
-        pArr->push_back(p);
-    else
-        pArr->insert(pArr->begin() + nAt, p);
 }
 
-ScDPLabelData* ScPivotLayoutDlg::GetLabelData( SCsCOL nCol, size_t* pnPos )
+ScDPLabelData* ScPivotLayoutDlg::GetLabelData( SCCOL nCol )
 {
-    ScDPLabelData* pData = 0;
-    for( ScDPLabelDataVector::iterator aIt = maLabelData.begin(), aEnd = maLabelData.end(); !pData && (aIt != aEnd); ++aIt )
-    {
-        if( aIt->mnCol == nCol )
-        {
-            pData = &*aIt;
-            if( pnPos ) *pnPos = aIt - maLabelData.begin();
-        }
-    }
-    return pData;
+    ScDPLabelDataVector::iterator it =
+        std::find_if(maLabelData.begin(), maLabelData.end(), FindLabelDataByCol(nCol));
+    return it == maLabelData.end() ? NULL : &(*it);
 }
 
 rtl::OUString ScPivotLayoutDlg::GetLabelString( SCsCOL nCol )
@@ -1178,15 +1080,6 @@ rtl::OUString ScPivotLayoutDlg::GetFuncString( sal_uInt16& rFuncMask, bool bIsVa
     return aBuf.makeStringAndClear();
 }
 
-Point ScPivotLayoutDlg::DlgPos2WndPos( const Point& rPt, Window& rWnd )
-{
-    Point aWndPt( rPt );
-    aWndPt.X() = rPt.X()-rWnd.GetPosPixel().X();
-    aWndPt.Y() = rPt.Y()-rWnd.GetPosPixel().Y();
-
-    return aWndPt;
-}
-
 void ScPivotLayoutDlg::InitControlAndDlgSizes()
 {
     // The pivot.src file only specifies the positions of the controls. Here,
@@ -1225,18 +1118,6 @@ void ScPivotLayoutDlg::InitControlAndDlgSizes()
     maWndSelect.SetSizePixel(
         Size(2 * nFldW + ROW_FIELD_BTN_GAP + 10, nH));
 
-    maRectPage   = Rectangle( maWndPage.GetPosPixel(),    maWndPage.GetSizePixel() );
-    maRectRow    = Rectangle( maWndRow.GetPosPixel(),     maWndRow.GetSizePixel() );
-    maRectCol    = Rectangle( maWndCol.GetPosPixel(),     maWndCol.GetSizePixel() );
-    maRectData   = Rectangle( maWndData.GetPosPixel(),    maWndData.GetSizePixel() );
-    maRectSelect = Rectangle( maWndSelect.GetPosPixel(),  maWndSelect.GetSizePixel() );
-
-    maFieldRects.push_back(FieldRect(&maRectPage, PIVOTFIELDTYPE_PAGE));
-    maFieldRects.push_back(FieldRect(&maRectRow, PIVOTFIELDTYPE_ROW));
-    maFieldRects.push_back(FieldRect(&maRectCol, PIVOTFIELDTYPE_COL));
-    maFieldRects.push_back(FieldRect(&maRectData, PIVOTFIELDTYPE_DATA));
-    maFieldRects.push_back(FieldRect(&maRectSelect, PIVOTFIELDTYPE_SELECT));
-
     maWndPage.CalcSize();
     maWndRow.CalcSize();
     maWndCol.CalcSize();
@@ -1311,48 +1192,21 @@ void ScPivotLayoutDlg::AdjustDlgSize()
     std::for_each(aWndToMove.begin(), aWndToMove.end(), MoveWndDown(nDelta));
 }
 
-namespace {
-
-class PivotFieldInserter : public ::std::unary_function<ScPivotFuncData, void>
-{
-    vector<ScPivotField>& mrFields;
-public:
-    explicit PivotFieldInserter(vector<ScPivotField>& r, size_t nSize) : mrFields(r)
-    {
-        mrFields.reserve(nSize);
-    }
-
-    PivotFieldInserter(const PivotFieldInserter& r) : mrFields(r.mrFields) {}
-
-    void operator() (const ScPivotFuncData& r)
-    {
-        ScPivotField aField;
-        aField.nCol = r.mnCol;
-        aField.mnOriginalDim = r.mnOriginalDim;
-        aField.mnDupCount = r.mnDupCount;
-        aField.nFuncMask = r.mnFuncMask;
-        aField.maFieldRef = r.maFieldRef;
-        mrFields.push_back(aField);
-    }
-};
-
-}
-
 bool ScPivotLayoutDlg::GetPivotArrays(
     vector<ScPivotField>& rPageFields, vector<ScPivotField>& rColFields,
     vector<ScPivotField>& rRowFields, vector<ScPivotField>& rDataFields )
 {
     vector<ScPivotField> aPageFields;
-    for_each(maPageArr.begin(), maPageArr.end(), PivotFieldInserter(aPageFields, maPageArr.size()));
+    maWndPage.ConvertToPivotArray(aPageFields);
 
     vector<ScPivotField> aColFields;
-    for_each(maColArr.begin(), maColArr.end(), PivotFieldInserter(aColFields, maColArr.size()+1));
+    maWndCol.ConvertToPivotArray(aColFields);
 
     vector<ScPivotField> aRowFields;
-    for_each(maRowArr.begin(), maRowArr.end(), PivotFieldInserter(aRowFields, maRowArr.size()+1));
+    maWndRow.ConvertToPivotArray(aRowFields);
 
     vector<ScPivotField> aDataFields;
-    for_each(maDataArr.begin(), maDataArr.end(), PivotFieldInserter(aDataFields, maDataArr.size()));
+    maWndData.ConvertToPivotArray(aDataFields);
 
     sheet::DataPilotFieldOrientation eOrientDataLayout = sheet::DataPilotFieldOrientation_ROW;
     ScDPSaveData* pSaveData = mxDlgDPObject->GetSaveData();
@@ -1472,16 +1326,90 @@ void ScPivotLayoutDlg::UpdateSrcRange()
     maWndCol.ClearFields();
     maWndPage.ClearFields();
 
-    maSelectArr.clear();
-    maRowArr.clear();
-    maColArr.clear();
-    maDataArr.clear();
-    maPageArr.clear();
-
     InitFieldWindows();
     RepaintFieldWindows();
 }
 
+void ScPivotLayoutDlg::UpdateOutputPos()
+{
+    sal_uInt16 nSelPos = maLbOutPos.GetSelectEntryPos();
+    OUString aEntryStr = maLbOutPos.GetEntry(nSelPos);
+
+    if (aEntryStr == maStrNewTable)
+    {
+        // New sheet as output.
+        maEdOutPos.Disable();
+        maRbOutPos.Disable();
+        maEdOutPos.SetText(OUString()); // Clear the reference text.
+    }
+    else if (aEntryStr == maStrUndefined)
+    {
+        maEdOutPos.Enable();
+        maRbOutPos.Enable();
+        maEdOutPos.SetText(maOutputRefStr);
+        OutputPosUpdated();
+    }
+    else
+    {
+        // Named range as output. Get its corresponding reference string.
+        const OUString* p = (const OUString*)maLbOutPos.GetEntryData(nSelPos);
+        if (p)
+            maEdOutPos.SetText(*p);
+    }
+}
+
+void ScPivotLayoutDlg::OutputPosUpdated()
+{
+    OUString aOutPosStr = maEdOutPos.GetText();
+    sal_uInt16 nResult = ScAddress().Parse(aOutPosStr, mpDoc, mpDoc->GetAddressConvention());
+
+    if (!(nResult & SCA_VALID))
+    {
+        // Not a valid reference.
+        maEdOutPos.SetRefValid(false);
+        return;
+    }
+
+    maEdOutPos.SetRefValid(true);
+
+    boost::ptr_vector<OUString>::const_iterator it =
+        std::find(maRefStrs.begin(), maRefStrs.end(), aOutPosStr);
+
+    if (it == maRefStrs.end())
+    {
+        // This is NOT one of the named ranges.
+        maLbOutPos.SelectEntryPos(0);
+        return;
+    }
+
+    // Select the corresponding named range item in the list box.  Be sure to
+    // offset for the top two entries which are reserved for something else.
+    boost::ptr_vector<OUString>::const_iterator itBeg = maRefStrs.begin();
+    size_t nPos = std::distance(itBeg, it);
+    maLbOutPos.SelectEntryPos(nPos+2);
+}
+
+namespace {
+
+void EnableAndGrabFocus(formula::RefEdit& rEdit)
+{
+    rEdit.Enable();
+    rEdit.GrabFocus();
+    rEdit.Enable();
+}
+
+}
+
+void ScPivotLayoutDlg::MoreBtnClicked()
+{
+    mbRefInputMode = maBtnMore.GetState();
+    if (!maBtnMore.GetState())
+        return;
+
+    formula::RefEdit* p = maEdInPos.IsEnabled() ? &maEdInPos : &maEdOutPos;
+    EnableAndGrabFocus(*p);
+}
+
 void ScPivotLayoutDlg::RepaintFieldWindows()
 {
     Rectangle aRect; // currently has no effect whatsoever.
@@ -1534,73 +1462,6 @@ void ScPivotLayoutDlg::GetOtherFieldWindows(ScPivotFieldType eType, ScDPFieldCon
     }
 }
 
-ScPivotLayoutDlg::ScDPFuncDataVec* ScPivotLayoutDlg::GetFieldDataArray(ScPivotFieldType eType)
-{
-    switch (eType)
-    {
-        case PIVOTFIELDTYPE_PAGE:
-            return &maPageArr;
-        case PIVOTFIELDTYPE_COL:
-            return &maColArr;
-        case PIVOTFIELDTYPE_ROW:
-            return &maRowArr;
-        case PIVOTFIELDTYPE_DATA:
-            return &maDataArr;
-        case PIVOTFIELDTYPE_SELECT:
-            return &maSelectArr;
-        default:
-            ;
-    }
-    return NULL;
-}
-
-void ScPivotLayoutDlg::GetOtherDataArrays(
-    ScPivotFieldType eType, ScDPFuncDataVec*& rpArr1, ScDPFuncDataVec*& rpArr2)
-{
-    rpArr1 = NULL;
-    rpArr2 = NULL;
-    switch (eType)
-    {
-        case PIVOTFIELDTYPE_PAGE:
-            rpArr1 = &maRowArr;
-            rpArr2 = &maColArr;
-            break;
-        case PIVOTFIELDTYPE_COL:
-            rpArr1 = &maPageArr;
-            rpArr2 = &maRowArr;
-            break;
-        case PIVOTFIELDTYPE_ROW:
-            rpArr1 = &maPageArr;
-            rpArr2 = &maColArr;
-            break;
-        default:
-            ;
-    }
-}
-
-sal_uInt8 ScPivotLayoutDlg::GetNextDupCount(
-    const ScDPFuncDataVec& rArr, const ScPivotFuncData& rData, size_t nDataIndex) const
-{
-    sal_uInt8 nDupCount = 0;
-    bool bFound = false;
-    for (size_t i = 0, n = rArr.size(); i < n; ++i)
-    {
-        const ScPivotFuncData& r = rArr[i];
-        if (i == nDataIndex)
-            // Skip itself.
-            continue;
-
-        if (r.mnCol != rData.mnCol || r.mnFuncMask != rData.mnFuncMask)
-            continue;
-
-        bFound = true;
-        if (r.mnDupCount > nDupCount)
-            nDupCount = r.mnDupCount;
-    }
-
-    return bFound ? nDupCount + 1 : 0;
-}
-
 void ScPivotLayoutDlg::SetReference( const ScRange& rRef, ScDocument* pDoc )
 {
     if (!mbRefInputMode || !mpRefInputEdit)
@@ -1620,6 +1481,8 @@ void ScPivotLayoutDlg::SetReference( const ScRange& rRef, ScDocument* pDoc )
         rtl::OUString aRefStr;
         rRef.aStart.Format( aRefStr, STD_FORMAT, pDoc, pDoc->GetAddressConvention() );
         mpRefInputEdit->SetRefString(aRefStr);
+        maOutputRefStr = aRefStr;
+        OutputPosUpdated();
     }
 }
 
@@ -1833,52 +1696,13 @@ IMPL_LINK_NOARG(ScPivotLayoutDlg, CancelHdl)
 
 IMPL_LINK_NOARG(ScPivotLayoutDlg, MoreClickHdl)
 {
-    if ( maBtnMore.GetState() )
-    {
-        mbRefInputMode = true;
-        if ( maEdInPos.IsEnabled() )
-        {
-            maEdInPos.Enable();
-            maEdInPos.GrabFocus();
-            maEdInPos.Enable();
-        }
-        else
-        {
-        maEdOutPos.Enable();
-        maEdOutPos.GrabFocus();
-            maEdOutPos.Enable();
-        }
-    }
-    else
-    {
-        mbRefInputMode = false;
-    }
+    MoreBtnClicked();
     return 0;
 }
 
 IMPL_LINK_NOARG(ScPivotLayoutDlg, EdOutModifyHdl)
 {
-    rtl::OUString theCurPosStr = maEdOutPos.GetText();
-    sal_uInt16  nResult = ScAddress().Parse( theCurPosStr, mpDoc, mpDoc->GetAddressConvention() );
-
-    if ( SCA_VALID == (nResult & SCA_VALID) )
-    {
-        rtl::OUString* pStr = NULL;
-        bool bFound  = false;
-        sal_uInt16  i       = 0;
-        sal_uInt16  nCount  = maLbOutPos.GetEntryCount();
-
-        for ( i=2; i<nCount && !bFound; i++ )
-        {
-            pStr = static_cast<rtl::OUString*>(maLbOutPos.GetEntryData(i));
-            bFound = (theCurPosStr == *pStr);
-        }
-
-        if ( bFound )
-            maLbOutPos.SelectEntryPos( --i );
-        else
-            maLbOutPos.SelectEntryPos( 0 );
-    }
+    OutputPosUpdated();
     return 0;
 }
 
@@ -1890,36 +1714,13 @@ IMPL_LINK_NOARG(ScPivotLayoutDlg, EdInModifyHdl)
 
 IMPL_LINK_NOARG(ScPivotLayoutDlg, SelAreaHdl)
 {
-    rtl::OUString  aString;
-    sal_uInt16  nSelPos = maLbOutPos.GetSelectEntryPos();
-
-    if ( nSelPos > 1 )
-    {
-        aString = *(rtl::OUString*)maLbOutPos.GetEntryData(nSelPos);
-    }
-    else if ( nSelPos == maLbOutPos.GetEntryCount()-1 ) // auf neue Tabelle?
-    {
-        maEdOutPos.Disable();
-        maRbOutPos.Disable();
-    }
-    else
-    {
-        maEdOutPos.Enable();
-        maRbOutPos.Enable();
-    }
-
-    maEdOutPos.SetText( aString );
+    UpdateOutputPos();
     return 0;
 }
 
-IMPL_LINK( ScPivotLayoutDlg, GetFocusHdl, formula::RefEdit*, pEdit )
+IMPL_LINK( ScPivotLayoutDlg, GetRefEditFocusHdl, formula::RefEdit*, pEdit )
 {
-    if (pEdit == &maEdInPos)
-        mpRefInputEdit = &maEdInPos;
-    else if (pEdit == &maEdOutPos)
-        mpRefInputEdit = &maEdOutPos;
-    else mpRefInputEdit = NULL;
-
+    mpRefInputEdit = pEdit;
     return 0;
 }
 
diff --git a/sc/source/ui/inc/fieldwnd.hxx b/sc/source/ui/inc/fieldwnd.hxx
index 589650d..d613c84 100644
--- a/sc/source/ui/inc/fieldwnd.hxx
+++ b/sc/source/ui/inc/fieldwnd.hxx
@@ -29,6 +29,7 @@
 #include "address.hxx"
 #include "pivot.hxx"
 
+struct ScPivotField;
 class ScPivotLayoutDlg;
 class ScAccessibleDataPilotControl;
 
@@ -65,6 +66,13 @@ protected:
     typedef ::std::vector<FieldName> FieldNames;
 
 public:
+    typedef boost::ptr_vector<ScPivotFuncData> FuncDataType;
+
+    struct FuncItem
+    {
+        SCCOL mnCol;
+        sal_uInt16 mnFuncMask;
+    };
 
     /**
      * Custom scroll bar to pass the command event to its parent window.
@@ -111,21 +119,19 @@ public:
     /** @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 rtl::OUString& rText, size_t nNewIndex );
+    void AppendField( const rtl::OUString& rText, const ScPivotFuncData& rFunc );
 
-    /** 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 rtl::OUString& rText, const Point& rPos, size_t& rnIndex, sal_uInt8& rnDupCount);
+    /**
+     * Inserts a field using the specified pixel position.
+     *
+     * @param rPos  The coordinates to insert the field.
+     */
+    size_t AddField(const rtl::OUString& rText, const Point& rPos, const ScPivotFuncData& rFunc);
 
     bool MoveField(size_t nCurPos, const Point& rPos, size_t& rnIndex);
 
-    bool AppendField(const rtl::OUString& rText, size_t& rnIndex);
-
-    /** Removes a field from the specified index. */
-    void            DelField( size_t nDelIndex );
+    /** Remove a field by specified index. */
+    void DeleteFieldByIndex( size_t nIndex );
 
     /** Returns the number of existing fields. */
     size_t          GetFieldCount() const;
@@ -152,6 +158,17 @@ public:
     /** Grabs focus and sets new selection. */
     void            GrabFocusAndSelect( size_t nIndex );
 
+    const ScPivotFuncData& GetFuncData(size_t nIndex) const;
+    ScPivotFuncData& GetFuncData(size_t nIndex);
+
+    void GetAllFuncItems(std::vector<FuncItem>& rItems) const;
+
+    sal_uInt8 GetNextDupCount(const ScPivotFuncData& rData, size_t nSelfIndex) const;
+
+    void ConvertToPivotArray(std::vector<ScPivotField>& rFields) const;
+
+    size_t GetFieldIndexByData( const ScPivotFuncData& rData ) const;
+
     virtual void            Paint( const Rectangle& rRect );
 
 protected:
@@ -222,6 +239,7 @@ private:
     typedef ::std::vector<Window*> Paintables;
     Paintables maPaintables;
 
+    FuncDataType maFuncData;
     FieldNames maFieldNames;   /// String array of the field names and flags, if text fits into button.
     ScPivotLayoutDlg*  mpDlg;
     FixedText*      mpCaption;     /// FixedText containing the name of the control.
diff --git a/sc/source/ui/inc/pvlaydlg.hxx b/sc/source/ui/inc/pvlaydlg.hxx
index 678ccba..31bed6b 100644
--- a/sc/source/ui/inc/pvlaydlg.hxx
+++ b/sc/source/ui/inc/pvlaydlg.hxx
@@ -80,8 +80,6 @@ class ScDPObject;
 
 class ScPivotLayoutDlg : public ScAnyRefDlg
 {
-    typedef boost::ptr_vector<ScPivotFuncData> ScDPFuncDataVec;
-
     /** data source type */
     enum DataSrcType {
         SRC_REF,     /// range reference
@@ -146,14 +144,10 @@ private:
     void InitWndData(const std::vector<ScPivotField>& rFields);
     void                    InitFieldWindow ( const ::std::vector<ScPivotField>& rFields, ScPivotFieldType eType );
     void                    AdjustDlgSize();
-    Point                   DlgPos2WndPos   ( const Point& rPt, Window& rWnd );
-    ScDPLabelData*          GetLabelData    ( SCsCOL nCol, size_t* pPos = NULL );
+    ScDPLabelData* GetLabelData( SCCOL nCol );
     rtl::OUString GetLabelString(SCsCOL nCol);
     bool                    IsOrientationAllowed( SCsCOL nCol, ScPivotFieldType eType );
     rtl::OUString GetFuncString( sal_uInt16& rFuncMask, bool bIsValue = true );
-    bool Contains( ScDPFuncDataVec* pArr, const ScPivotFuncData& rData, size_t& nAt );
-    void                    Remove          ( ScDPFuncDataVec* pArr, size_t nAt );
-    void                    Insert          ( ScDPFuncDataVec* pArr, const ScPivotFuncData& rFData, size_t nAt );
 
     void                    AddField        ( size_t nFromIndex,
                                               ScPivotFieldType eToType, const Point& rAtPos );
@@ -168,7 +162,11 @@ private:
                                             ::std::vector<ScPivotField>& rRowFields,
                                             ::std::vector<ScPivotField>& rDataFields );
 
-    void                    UpdateSrcRange();
+    void UpdateSrcRange();
+    void UpdateOutputPos();
+    void OutputPosUpdated();
+    void MoreBtnClicked();
+
     void                    RepaintFieldWindows();
 
     /**
@@ -185,17 +183,6 @@ private:
     void GetOtherFieldWindows(
         ScPivotFieldType eType, ScDPFieldControlBase*& rpWnd1, ScDPFieldControlBase*& rpWnd2);
 
-    ScDPFuncDataVec* GetFieldDataArray(ScPivotFieldType eType);
-
-    /**
-     * Like GetOtherFieldWindows(), get pointers to data arrays of the fields
-     * that are <b>not</b> the specified field type.
-     */
-    void GetOtherDataArrays(
-        ScPivotFieldType eType, ScDPFuncDataVec*& rpArr1, ScDPFuncDataVec*& rpArr2);
-
-    sal_uInt8 GetNextDupCount(const ScDPFuncDataVec& rArr, const ScPivotFuncData& rData, size_t nDataIndex) const;
-
     // Handler
     DECL_LINK( ClickHdl, PushButton * );
     DECL_LINK( OkHdl, void * );
@@ -204,17 +191,9 @@ private:
     DECL_LINK( EdOutModifyHdl, void * );
     DECL_LINK( EdInModifyHdl, void * );
     DECL_LINK( SelAreaHdl, void * );
-    DECL_LINK( GetFocusHdl, formula::RefEdit* );
+    DECL_LINK( GetRefEditFocusHdl, formula::RefEdit* );
 
 private:
-    struct FieldRect
-    {
-        const Rectangle* mpRect;
-        ScPivotFieldType meType;
-
-        FieldRect(const Rectangle* pRect, ScPivotFieldType eType);
-    };
-
     typedef boost::scoped_ptr<ScDPObject> ScDPObjectPtr;
 
     FixedLine               maFlLayout;
@@ -229,6 +208,8 @@ private:
     ScDPSelectFieldControl  maWndSelect;
     FixedInfo               maFtInfo;
 
+    std::vector<ScDPFieldControlBase*> maFieldCtrls;
+
     FixedLine               maFlAreas;
     FixedText               maFtInArea;
     ::formula::RefEdit      maEdInPos;
@@ -251,6 +232,7 @@ private:
     PushButton              maBtnOptions;
     MoreButton              maBtnMore;
     std::vector<rtl::OUString> maFuncNames;     /// Localized function names from resource.
+    boost::ptr_vector<rtl::OUString> maRefStrs; /// Reference strings stored with the output list box.
     ScDPObjectPtr           mxDlgDPObject;      /// Clone of the pivot table object this dialog is based on.
     ScPivotParam            maPivotData;        /// The pivot table field configuration.
     ScDPLabelDataVector     maLabelData;        /// Information about all dimensions.
@@ -261,27 +243,15 @@ private:
 
     const rtl::OUString     maStrUndefined;
     const rtl::OUString     maStrNewTable;
+    rtl::OUString           maOutputRefStr; /// Used only for caching in UI.
 
     ScPivotFieldType           meDnDFromType;
     size_t                  mnDnDFromIndex;
     bool                    mbIsDrag;
 
-    Rectangle               maRectPage;
-    Rectangle               maRectRow;
-    Rectangle               maRectCol;
-    Rectangle               maRectData;
-    Rectangle               maRectSelect;
-    std::vector<FieldRect> maFieldRects;
-
-    ScPivotFieldType           meLastActiveType;        /// Type of last active area.
+    ScPivotFieldType        meLastActiveType;        /// Type of last active area.
     size_t                  mnOffset;                /// Offset of first field in TYPE_SELECT area.
 
-    ScDPFuncDataVec         maSelectArr;
-    ScDPFuncDataVec         maPageArr;
-    ScDPFuncDataVec         maColArr;
-    ScDPFuncDataVec         maRowArr;
-    ScDPFuncDataVec         maDataArr;
-
     ScRange                 maOldRange;
     bool                    mbRefInputMode;
 };


More information about the Libreoffice-commits mailing list