Date: prev next · Thread: first prev next last
2012 Archives by date, by thread · List index


Hi Markus,
Thanks for your review.

On Thu, Mar 22, 2012 at 01:14, Markus Mohrhard
<markus.mohrhard@googlemail.com> wrote:
Hey Albert,

I will check this patch tomorrow. A quick look through the patch did
not show any serious problems only some small nit-picks that I will
change while reviewing.


Ok. So as promised I reviewed the patch now. Sadly there are some more
problems than I thought after my first quick look:

- please use Sc instead of SC for type prefix names
- Can you recheck ScSortParam constructos that already fill
maKeyState? std::vector[] does not increase the vector size so you are
only allowed to access existing entries. I think we should use
push_back there.
- It seems that you have still some whitespace changes in
ScTabPageSortFields::Reset
- personally I'm not a huge fan of hungarian notation but since we are
using it it would be great if you could use aNewSortParam instead of
theNewSortParam
- personally I prefer static_cast in c++ over the old c-cast but I
have no strong opinion there
- ScSortDescriptor::FillSortParam looks like there might happen some
index out of bounds access

So I have updated the patch with respect to your comments above and
corrected all the issues except for the last one, which I honestly can
not find. There are several ScSortDescriptor::FillSortParam in
different files which are touch by my patch. So could help me pointing
out the line(s) which you are concern about?

Regarding the remaining UI bits I have started to look at this and
think I understand how to implement it. The scroll handler is still a
mystery, see if I can figure it out.
From 4a129b97e6dbd2713f722a90ac17ab6b6f215bd3 Mon Sep 17 00:00:00 2001
From: Albert Thuswaldner <albert.thuswaldner@gmail.com>
Date: Tue, 20 Mar 2012 19:38:29 +0100
Subject: [PATCH] fdo#45747 remove the limitation to 3 sort entries in calc part1

---
 sc/inc/sortparam.hxx                             |   23 +-
 sc/source/core/data/sortparam.cxx                |   98 +++----
 sc/source/core/data/table3.cxx                   |   24 +-
 sc/source/core/tool/dbdata.cxx                   |   14 +-
 sc/source/filter/xml/XMLExportDatabaseRanges.cxx |    8 +-
 sc/source/filter/xml/xmldrani.cxx                |    6 +-
 sc/source/ui/dbgui/tpsort.cxx                    |  343 ++++++++++-----------
 sc/source/ui/docshell/dbdocfun.cxx               |    6 +-
 sc/source/ui/inc/tpsort.hxx                      |   18 +-
 sc/source/ui/src/sortdlg.src                     |    6 +-
 sc/source/ui/unoobj/cellsuno.cxx                 |   16 +-
 sc/source/ui/unoobj/datauno.cxx                  |   48 ++--
 sc/source/ui/vba/vbarange.cxx                    |   18 +-
 sc/source/ui/view/cellsh2.cxx                    |   62 ++--
 sc/source/ui/view/dbfunc3.cxx                    |    2 +-
 15 files changed, 340 insertions(+), 352 deletions(-)

diff --git a/sc/inc/sortparam.hxx b/sc/inc/sortparam.hxx
index f1d4e21..5f1fee0 100644
--- a/sc/inc/sortparam.hxx
+++ b/sc/inc/sortparam.hxx
@@ -29,16 +29,27 @@
 #ifndef SC_SORTPARAM_HXX
 #define SC_SORTPARAM_HXX
 
+#define DEFSORT 3
+
+#include <vector>
+
 #include "address.hxx"
 #include <tools/solar.h>
 #include <com/sun/star/lang/Locale.hpp>
 #include "scdllapi.h"
 
-#define MAXSORT 3
-
 struct ScSubTotalParam;
 struct ScQueryParam;
 
+struct ScSortKeyState
+{
+    bool     bDoSort;
+    SCCOLROW nField;
+    bool     bAscending;
+};
+
+typedef ::std::vector<ScSortKeyState> ScSortKeyStateVec;
+
 struct SC_DLLPUBLIC ScSortParam
 {
     SCCOL       nCol1;
@@ -56,13 +67,12 @@ struct SC_DLLPUBLIC ScSortParam
     SCTAB       nDestTab;
     SCCOL       nDestCol;
     SCROW       nDestRow;
-    bool        bDoSort[MAXSORT];
-    SCCOLROW    nField[MAXSORT];
-    bool        bAscending[MAXSORT];
+    ScSortKeyStateVec maKeyState;
     ::com::sun::star::lang::Locale aCollatorLocale;
     ::rtl::OUString aCollatorAlgorithm;
     sal_uInt16  nCompatHeader;
 
+
     ScSortParam();
     ScSortParam( const ScSortParam& r );
     /// SubTotals sort
@@ -73,8 +83,9 @@ struct SC_DLLPUBLIC ScSortParam
     ScSortParam&    operator=  ( const ScSortParam& r );
     bool            operator== ( const ScSortParam& rOther ) const;
     void            Clear       ();
-
     void            MoveToDest();
+
+    inline sal_uInt16 GetSortKeyCount() const { return maKeyState.size(); }
 };
 
 
diff --git a/sc/source/core/data/sortparam.cxx b/sc/source/core/data/sortparam.cxx
index 26e1ac7..b7788e5 100644
--- a/sc/source/core/data/sortparam.cxx
+++ b/sc/source/core/data/sortparam.cxx
@@ -51,15 +51,10 @@ ScSortParam::ScSortParam( const ScSortParam& r ) :
         bNaturalSort(r.bNaturalSort),bUserDef(r.bUserDef),
         bIncludePattern(r.bIncludePattern),bInplace(r.bInplace),
         nDestTab(r.nDestTab),nDestCol(r.nDestCol),nDestRow(r.nDestRow),
+        maKeyState( r.maKeyState ),
         aCollatorLocale( r.aCollatorLocale ), aCollatorAlgorithm( r.aCollatorAlgorithm ),
         nCompatHeader( r.nCompatHeader )
 {
-    for (sal_uInt16 i=0; i<MAXSORT; i++)
-    {
-        bDoSort[i]    = r.bDoSort[i];
-        nField[i]     = r.nField[i];
-        bAscending[i] = r.bAscending[i];
-    }
 }
 
 //------------------------------------------------------------------------
@@ -76,12 +71,8 @@ void ScSortParam::Clear()
     aCollatorLocale = ::com::sun::star::lang::Locale();
     aCollatorAlgorithm = ::rtl::OUString();
 
-    for (sal_uInt16 i=0; i<MAXSORT; i++)
-    {
-        bDoSort[i]    = false;
-        nField[i]     = 0;
-        bAscending[i] = true;
-    }
+    // Initialize to default size
+    maKeyState.assign( DEFSORT, { false, 0, true } );
 }
 
 //------------------------------------------------------------------------
@@ -103,17 +94,11 @@ ScSortParam& ScSortParam::operator=( const ScSortParam& r )
     nDestTab        = r.nDestTab;
     nDestCol        = r.nDestCol;
     nDestRow        = r.nDestRow;
+    maKeyState      = r.maKeyState;
     aCollatorLocale         = r.aCollatorLocale;
     aCollatorAlgorithm      = r.aCollatorAlgorithm;
     nCompatHeader   = r.nCompatHeader;
 
-    for (sal_uInt16 i=0; i<MAXSORT; i++)
-    {
-        bDoSort[i]    = r.bDoSort[i];
-        nField[i]     = r.nField[i];
-        bAscending[i] = r.bAscending[i];
-    }
-
     return *this;
 }
 
@@ -125,10 +110,20 @@ bool ScSortParam::operator==( const ScSortParam& rOther ) const
     // Anzahl der Sorts gleich?
     sal_uInt16 nLast      = 0;
     sal_uInt16 nOtherLast = 0;
-    while ( bDoSort[nLast++] && nLast < MAXSORT ) ;
-    while ( rOther.bDoSort[nOtherLast++] && nOtherLast < MAXSORT ) ;
-    nLast--;
-    nOtherLast--;
+    sal_uInt16 nSortSize = GetSortKeyCount();
+
+    if ( !maKeyState.empty() )
+    {
+        while ( maKeyState[nLast++].bDoSort && nLast < nSortSize ) ;
+        nLast--;
+    }
+
+    if ( !rOther.maKeyState.empty() )
+    {
+        while ( rOther.maKeyState[nOtherLast++].bDoSort && nOtherLast < nSortSize ) ;
+        nOtherLast--;
+    }
+
     if (   (nLast           == nOtherLast)
         && (nCol1           == rOther.nCol1)
         && (nRow1           == rOther.nRow1)
@@ -149,14 +144,17 @@ bool ScSortParam::operator==( const ScSortParam& rOther ) const
         && (aCollatorLocale.Country     == rOther.aCollatorLocale.Country)
         && (aCollatorLocale.Variant     == rOther.aCollatorLocale.Variant)
         && (aCollatorAlgorithm          == rOther.aCollatorAlgorithm)
+        && ( !maKeyState.empty() || !rOther.maKeyState.empty() )
         )
     {
         bEqual = true;
         for ( sal_uInt16 i=0; i<=nLast && bEqual; i++ )
-        {
-            bEqual = (nField[i] == rOther.nField[i]) && (bAscending[i]  == rOther.bAscending[i]);
-        }
+            bEqual = ( maKeyState[i].nField == rOther.maKeyState[i].nField ) &&
+                ( maKeyState[i].bAscending  == rOther.maKeyState[i].bAscending );
     }
+    if ( maKeyState.empty() && rOther.maKeyState.empty() )
+        bEqual = true;
+
     return bEqual;
 }
 
@@ -172,6 +170,7 @@ ScSortParam::ScSortParam( const ScSubTotalParam& rSub, const ScSortParam& rOld )
         nCompatHeader( rOld.nCompatHeader )
 {
     sal_uInt16 nNewCount = 0;
+    sal_uInt16 nSortSize = GetSortKeyCount();
     sal_uInt16 i;
 
     //  zuerst die Gruppen aus den Teilergebnissen
@@ -179,42 +178,34 @@ ScSortParam::ScSortParam( const ScSubTotalParam& rSub, const ScSortParam& 
rOld )
         for (i=0; i<MAXSUBTOTAL; i++)
             if (rSub.bGroupActive[i])
             {
-                if (nNewCount < MAXSORT)
+                if (nNewCount < nSortSize)
                 {
-                    bDoSort[nNewCount]    = true;
-                    nField[nNewCount]     = rSub.nField[i];
-                    bAscending[nNewCount] = rSub.bAscending;
+                    maKeyState[nNewCount] = { true, rSub.nField[i], rSub.bAscending };
                     ++nNewCount;
                 }
             }
 
     //  dann dahinter die alten Einstellungen
-    for (i=0; i<MAXSORT; i++)
-        if (rOld.bDoSort[i])
+    for (i=0; i<nSortSize; i++)
+        if (rOld.maKeyState[i].bDoSort)
         {
-            SCCOLROW nThisField = rOld.nField[i];
+            SCCOLROW nThisField = rOld.maKeyState[i].nField;
             bool bDouble = false;
             for (sal_uInt16 j=0; j<nNewCount; j++)
-                if ( nField[j] == nThisField )
+                if ( maKeyState[j].nField == nThisField )
                     bDouble = true;
             if (!bDouble)               // ein Feld nicht zweimal eintragen
             {
-                if (nNewCount < MAXSORT)
+                if (nNewCount < nSortSize)
                 {
-                    bDoSort[nNewCount]    = true;
-                    nField[nNewCount]     = nThisField;
-                    bAscending[nNewCount] = rOld.bAscending[i];
+                    maKeyState[nNewCount] = { true, nThisField, rOld.maKeyState[i].bAscending };
                     ++nNewCount;
                 }
             }
         }
 
-    for (i=nNewCount; i<MAXSORT; i++)       // Rest loeschen
-    {
-        bDoSort[i]    = false;
-        nField[i]     = 0;
-        bAscending[i] = true;
-    }
+    for (i=nNewCount; i<nSortSize; i++)       // Rest loeschen
+        maKeyState.push_back( ScSortKeyState({ false, 0, true }) );
 }
 
 //------------------------------------------------------------------------
@@ -228,15 +219,10 @@ ScSortParam::ScSortParam( const ScQueryParam& rParam, SCCOL nCol ) :
         bInplace(true),
         nDestTab(0),nDestCol(0),nDestRow(0), nCompatHeader(2)
 {
-    bDoSort[0] = true;
-    nField[0] = nCol;
-    bAscending[0] = true;
-    for (sal_uInt16 i=1; i<MAXSORT; i++)
-    {
-        bDoSort[i]    = false;
-        nField[i]     = 0;
-        bAscending[i] = true;
-    }
+    maKeyState.push_back( ScSortKeyState( { true, nCol, true } ) );
+
+    for (sal_uInt16 i=1; i<GetSortKeyCount(); i++)
+        maKeyState.push_back( ScSortKeyState( { false, 0, true } ) );
 }
 
 //------------------------------------------------------------------------
@@ -252,11 +238,11 @@ void ScSortParam::MoveToDest()
         nRow1 = sal::static_int_cast<SCROW>( nRow1 + nDifY );
         nCol2 = sal::static_int_cast<SCCOL>( nCol2 + nDifX );
         nRow2 = sal::static_int_cast<SCROW>( nRow2 + nDifY );
-        for (sal_uInt16 i=0; i<MAXSORT; i++)
+        for (sal_uInt16 i=0; i<GetSortKeyCount(); i++)
             if (bByRow)
-                nField[i] += nDifX;
+                maKeyState[i].nField += nDifX;
             else
-                nField[i] += nDifY;
+                maKeyState[i].nField += nDifY;
 
         bInplace = true;
     }
diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx
index d740a30..3310956 100644
--- a/sc/source/core/data/table3.cxx
+++ b/sc/source/core/data/table3.cxx
@@ -270,14 +270,14 @@ public:
 ScSortInfoArray* ScTable::CreateSortInfoArray( SCCOLROW nInd1, SCCOLROW nInd2 )
 {
     sal_uInt16 nUsedSorts = 1;
-    while ( nUsedSorts < nMaxSorts && aSortParam.bDoSort[nUsedSorts] )
+    while ( nUsedSorts < nMaxSorts && aSortParam.maKeyState[nUsedSorts].bDoSort )
         nUsedSorts++;
     ScSortInfoArray* pArray = new ScSortInfoArray( nUsedSorts, nInd1, nInd2 );
     if ( aSortParam.bByRow )
     {
         for ( sal_uInt16 nSort = 0; nSort < nUsedSorts; nSort++ )
         {
-            SCCOL nCol = static_cast<SCCOL>(aSortParam.nField[nSort]);
+            SCCOL nCol = static_cast<SCCOL>(aSortParam.maKeyState[nSort].nField);
             ScColumn* pCol = &aCol[nCol];
             for ( SCROW nRow = nInd1; nRow <= nInd2; nRow++ )
             {
@@ -292,7 +292,7 @@ ScSortInfoArray* ScTable::CreateSortInfoArray( SCCOLROW nInd1, SCCOLROW nInd2 )
     {
         for ( sal_uInt16 nSort = 0; nSort < nUsedSorts; nSort++ )
         {
-            SCROW nRow = aSortParam.nField[nSort];
+            SCROW nRow = aSortParam.maKeyState[nSort].nField;
             for ( SCCOL nCol = static_cast<SCCOL>(nInd1);
                     nCol <= static_cast<SCCOL>(nInd2); nCol++ )
             {
@@ -473,7 +473,7 @@ short ScTable::CompareCell( sal_uInt16 nSort,
                 else if (nVal1 > nVal2)
                     nRes = 1;
             }
-            if ( !aSortParam.bAscending[nSort] )
+            if ( !aSortParam.maKeyState[nSort].bAscending )
                 nRes = -nRes;
         }
         else
@@ -499,12 +499,12 @@ short ScTable::Compare( ScSortInfoArray* pArray, SCCOLROW nIndex1, SCCOLROW 
nInd
         ScSortInfo* pInfo2 = pArray->Get( nSort, nIndex2 );
         if ( aSortParam.bByRow )
             nRes = CompareCell( nSort,
-                pInfo1->pCell, static_cast<SCCOL>(aSortParam.nField[nSort]), pInfo1->nOrg,
-                pInfo2->pCell, static_cast<SCCOL>(aSortParam.nField[nSort]), pInfo2->nOrg );
+                pInfo1->pCell, static_cast<SCCOL>(aSortParam.maKeyState[nSort].nField), 
pInfo1->nOrg,
+                pInfo2->pCell, static_cast<SCCOL>(aSortParam.maKeyState[nSort].nField), 
pInfo2->nOrg );
         else
             nRes = CompareCell( nSort,
-                pInfo1->pCell, static_cast<SCCOL>(pInfo1->nOrg), aSortParam.nField[nSort],
-                pInfo2->pCell, static_cast<SCCOL>(pInfo2->nOrg), aSortParam.nField[nSort] );
+                pInfo1->pCell, static_cast<SCCOL>(pInfo1->nOrg), 
aSortParam.maKeyState[nSort].nField,
+                pInfo2->pCell, static_cast<SCCOL>(pInfo2->nOrg), 
aSortParam.maKeyState[nSort].nField );
     } while ( nRes == 0 && ++nSort < pArray->GetUsedSorts() );
     if( nRes == 0 )
     {
@@ -684,22 +684,22 @@ short ScTable::Compare(SCCOLROW nIndex1, SCCOLROW nIndex2)
     {
         do
         {
-            SCCOL nCol = static_cast<SCCOL>(aSortParam.nField[nSort]);
+            SCCOL nCol = static_cast<SCCOL>(aSortParam.maKeyState[nSort].nField);
             ScBaseCell* pCell1 = aCol[nCol].GetCell( nIndex1 );
             ScBaseCell* pCell2 = aCol[nCol].GetCell( nIndex2 );
             nRes = CompareCell( nSort, pCell1, nCol, nIndex1, pCell2, nCol, nIndex2 );
-        } while ( nRes == 0 && ++nSort < nMaxSorts && aSortParam.bDoSort[nSort] );
+        } while ( nRes == 0 && ++nSort < nMaxSorts && aSortParam.maKeyState[nSort].bDoSort );
     }
     else
     {
         do
         {
-            SCROW nRow = aSortParam.nField[nSort];
+            SCROW nRow = aSortParam.maKeyState[nSort].nField;
             ScBaseCell* pCell1 = aCol[nIndex1].GetCell( nRow );
             ScBaseCell* pCell2 = aCol[nIndex2].GetCell( nRow );
             nRes = CompareCell( nSort, pCell1, static_cast<SCCOL>(nIndex1),
                     nRow, pCell2, static_cast<SCCOL>(nIndex2), nRow );
-        } while ( nRes == 0 && ++nSort < nMaxSorts && aSortParam.bDoSort[nSort] );
+        } while ( nRes == 0 && ++nSort < nMaxSorts && aSortParam.maKeyState[nSort].bDoSort );
     }
     return nRes;
 }
diff --git a/sc/source/core/tool/dbdata.cxx b/sc/source/core/tool/dbdata.cxx
index c612d32..4c14735 100644
--- a/sc/source/core/tool/dbdata.cxx
+++ b/sc/source/core/tool/dbdata.cxx
@@ -246,7 +246,7 @@ ScDBData::~ScDBData()
             aBuf.append(ScGlobal::GetRscString(STR_OPERATION_FILTER));
     }
 
-    if (mpSortParam->bDoSort[0])
+    if (mpSortParam->maKeyState[0].bDoSort)
     {
         if (aBuf.getLength())
             aBuf.appendAscii(RTL_CONSTASCII_STRINGPARAM(", "));
@@ -299,13 +299,13 @@ void ScDBData::MoveTo(SCTAB nTab, SCCOL nCol1, SCROW nRow1, SCCOL nCol2, 
SCROW n
     long nSortDif = bByRow ? nDifX : nDifY;
     long nSortEnd = bByRow ? static_cast<long>(nCol2) : static_cast<long>(nRow2);
 
-    for (i=0; i<MAXSORT; i++)
+    for (i=0; i<mpSortParam->GetSortKeyCount(); i++)
     {
-        mpSortParam->nField[i] += nSortDif;
-        if (mpSortParam->nField[i] > nSortEnd)
+        mpSortParam->maKeyState[i].nField += nSortDif;
+        if (mpSortParam->maKeyState[i].nField > nSortEnd)
         {
-            mpSortParam->nField[i] = 0;
-            mpSortParam->bDoSort[i] = false;
+            mpSortParam->maKeyState[i].nField = 0;
+            mpSortParam->maKeyState[i].bDoSort = false;
         }
     }
 
@@ -460,7 +460,7 @@ bool ScDBData::HasQueryParam() const
 
 bool ScDBData::HasSortParam() const
 {
-    return mpSortParam && mpSortParam->bDoSort[0];
+    return mpSortParam && mpSortParam->maKeyState[0].bDoSort;
 }
 
 bool ScDBData::HasSubTotalParam() const
diff --git a/sc/source/filter/xml/XMLExportDatabaseRanges.cxx 
b/sc/source/filter/xml/XMLExportDatabaseRanges.cxx
index 8aab8b5..551c035 100644
--- a/sc/source/filter/xml/XMLExportDatabaseRanges.cxx
+++ b/sc/source/filter/xml/XMLExportDatabaseRanges.cxx
@@ -317,9 +317,9 @@ private:
 
         // Count sort items first.
         size_t nSortCount = 0;
-        for (; nSortCount < MAXSORT; ++nSortCount)
+        for (; nSortCount < aParam.GetSortKeyCount(); ++nSortCount)
         {
-            if (!aParam.bDoSort[nSortCount])
+            if (!aParam.maKeyState[nSortCount].bDoSort)
                 break;
         }
 
@@ -359,10 +359,10 @@ private:
         for (size_t i = 0; i < nSortCount; ++i)
         {
             // Convert field value from absolute to relative.
-            SCCOLROW nField = aParam.nField[i] - nFieldStart;
+            SCCOLROW nField = aParam.maKeyState[i].nField - nFieldStart;
             mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_FIELD_NUMBER, 
OUString::valueOf(nField));
 
-            if (!aParam.bAscending[i])
+            if (!aParam.maKeyState[i].bAscending)
                 mrExport.AddAttribute(XML_NAMESPACE_TABLE, XML_ORDER, XML_DESCENDING);
 
             if (aParam.bUserDef)
diff --git a/sc/source/filter/xml/xmldrani.cxx b/sc/source/filter/xml/xmldrani.cxx
index 37c4471..c622255 100644
--- a/sc/source/filter/xml/xmldrani.cxx
+++ b/sc/source/filter/xml/xmldrani.cxx
@@ -370,11 +370,11 @@ ScDBData* ScXMLDatabaseRangeContext::ConvertToDBData(const OUString& rName)
         ScSortDescriptor::FillSortParam(aParam, aSortSequence);
 
         SCCOLROW nStartPos = aParam.bByRow ? maRange.aStart.Col() : maRange.aStart.Row();
-        for (size_t i = 0; i < MAXSORT; ++i)
+        for (size_t i = 0; i < aParam.GetSortKeyCount(); ++i)
         {
-            if (!aParam.bDoSort[i])
+            if (!aParam.maKeyState[i].bDoSort)
                 break;
-            aParam.nField[i] += nStartPos;
+            aParam.maKeyState[i].nField += nStartPos;
         }
 
         pData->SetSortParam(aParam);
diff --git a/sc/source/ui/dbgui/tpsort.cxx b/sc/source/ui/dbgui/tpsort.cxx
index f2cc430..a964391 100644
--- a/sc/source/ui/dbgui/tpsort.cxx
+++ b/sc/source/ui/dbgui/tpsort.cxx
@@ -114,7 +114,10 @@ ScTabPageSortFields::ScTabPageSortFields( Window*           pParent,
         rSortData       ( ((const ScSortItem&)
                            rArgSet.Get( nWhichSort )).
                                 GetSortData() ),
+        aNewSortData    ( rSortData ),
         nFieldCount     ( 0 ),
+        nSortKeyCount   ( DEFSORT ),
+        nCurrentOffset  ( 0 ),
         bHasHeader      ( false ),
         bSortByRows     ( false )
 {
@@ -128,7 +131,6 @@ ScTabPageSortFields::ScTabPageSortFields( Window*           pParent,
 ScTabPageSortFields::~ScTabPageSortFields()
 {
 }
-
 // -----------------------------------------------------------------------
 
 void ScTabPageSortFields::Init()
@@ -140,7 +142,19 @@ void ScTabPageSortFields::Init()
 
     OSL_ENSURE( pViewData, "ViewData not found!" );
 
-    nFieldArr[0] = 0;
+    // Create local copy of ScParam
+    aNewSortData = rSortData;
+
+    if (pDlg)
+    {
+        const SfxItemSet* pExample = pDlg->GetExampleSet();
+        const SfxPoolItem* pItem;
+        if ( pExample && pExample->GetItemState( nWhichSort, sal_True, &pItem ) == SFX_ITEM_SET )
+            aNewSortData = static_cast<const ScSortItem*>(pItem)->GetSortData();
+    }
+
+    // Connect handlers and widgets
+    nFieldArr.push_back( 0 );
     nFirstCol = 0;
     nFirstRow = 0;
 
@@ -151,18 +165,10 @@ void ScTabPageSortFields::Init()
     aLbSort2.Clear();
     aLbSort3.Clear();
 
-    aSortLbArr[0]       = &aLbSort1;
-    aSortLbArr[1]       = &aLbSort2;
-    aSortLbArr[2]       = &aLbSort3;
-    aDirBtnArr[0][0]    = &aBtnUp1;
-    aDirBtnArr[0][1]    = &aBtnDown1;
-    aDirBtnArr[1][0]    = &aBtnUp2;
-    aDirBtnArr[1][1]    = &aBtnDown2;
-    aDirBtnArr[2][0]    = &aBtnUp3;
-    aDirBtnArr[2][1]    = &aBtnDown3;
-    aFlArr[0]           = &aFlSort1;
-    aFlArr[1]           = &aFlSort2;
-    aFlArr[2]           = &aFlSort3;
+    aLbSortArr = { &aLbSort1,  &aLbSort2,  &aLbSort3 };
+    aBtnUp     = { &aBtnUp1,   &aBtnUp2,   &aBtnUp3 };
+    aBtnDown   = { &aBtnDown1, &aBtnDown2, &aBtnDown3 };
+    aFlArr     = { &aFlSort1,  &aFlSort2,  &aFlSort3 };
 }
 
 // -----------------------------------------------------------------------
@@ -177,61 +183,63 @@ SfxTabPage* ScTabPageSortFields::Create( Window*    pParent,
 
 void ScTabPageSortFields::Reset( const SfxItemSet& /* rArgSet */ )
 {
-    bSortByRows = rSortData.bByRow;
-    bHasHeader  = rSortData.bHasHeader;
+    bSortByRows = aNewSortData.bByRow;
+    bHasHeader  = aNewSortData.bHasHeader;
 
     if ( aLbSort1.GetEntryCount() == 0 )
-        FillFieldLists();
+        FillFieldLists(0);
 
     // ListBox selection:
-
-    if ( rSortData.bDoSort[0] )
+    if ( aNewSortData.maKeyState[0].bDoSort )
     {
-        for ( sal_uInt16 i=0; i<3; i++ )
+        for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
         {
-            if ( rSortData.bDoSort[i] )
+            if ( aNewSortData.maKeyState[i].bDoSort )
             {
-                aSortLbArr[i]->SelectEntryPos(
-                     GetFieldSelPos( rSortData.nField[i] ) );
+                aLbSortArr[i]->SelectEntryPos( GetFieldSelPos(
+                                    aNewSortData.maKeyState[i].nField ) );
 
-                (rSortData.bAscending[i])
-                    ? aDirBtnArr[i][0]->Check()     // Up
-                    : aDirBtnArr[i][1]->Check();    // Down
+                (aNewSortData.maKeyState[i].bAscending)
+                    ? aBtnUp[i]->Check()
+                    : aBtnDown[i]->Check();
             }
             else
             {
-                aSortLbArr[i]->SelectEntryPos( 0 ); // Select none
-                aDirBtnArr[i][0]->Check();          // Up
+                aLbSortArr[i]->SelectEntryPos( 0 ); // Select none
+                aBtnUp[i]->Check();
             }
         }
 
-        EnableField( 1 );
-        EnableField( 2 );
-        EnableField( 3 );
-        if ( aLbSort1.GetSelectEntryPos() == 0 )
-            DisableField( 2 );
-        if ( aLbSort2.GetSelectEntryPos() == 0 )
-            DisableField( 3 );
+        // Enable or disable field depending on preceding Listbox selection
+        EnableField( 0 );
+        for ( sal_uInt16 i=1; i<nSortKeyCount; i++ )
+            if ( aLbSortArr[i - 1] -> GetSelectEntryPos() == 0 )
+                DisableField( i );
+            else
+                EnableField( i );
     }
     else
     {
         SCCOL  nCol = pViewData->GetCurX();
 
-        if( nCol < rSortData.nCol1 )
-            nCol = rSortData.nCol1;
-        else if( nCol > rSortData.nCol2 )
-            nCol = rSortData.nCol2;
-
-        sal_uInt16  nSort1Pos = nCol - rSortData.nCol1+1;
-        aLbSort1.SelectEntryPos( nSort1Pos );
-        aLbSort2.SelectEntryPos( 0 );
-        aLbSort3.SelectEntryPos( 0 );
-        aBtnUp1.Check();
-        aBtnUp2.Check();
-        aBtnUp3.Check();
+        if( nCol < aNewSortData.nCol1 )
+            nCol = aNewSortData.nCol1;
+        else if( nCol > aNewSortData.nCol2 )
+            nCol = aNewSortData.nCol2;
+
+        sal_uInt16  nSort1Pos = nCol - aNewSortData.nCol1+1;
+
+        aLbSortArr[0] -> SelectEntryPos( nSort1Pos );
+        for ( sal_uInt16 i=1; i<nSortKeyCount; i++ )
+            aLbSortArr[i] -> SelectEntryPos( 0 );
+
+        for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
+            aBtnUp[i] -> Check();
+
+        EnableField ( 0 );
         EnableField ( 1 );
-        EnableField ( 2 );
-        DisableField( 3 );
+        for ( sal_uInt16 i=2; i<nSortKeyCount; i++ )
+            DisableField( i );
     }
 
     if ( pDlg )
@@ -245,65 +253,48 @@ void ScTabPageSortFields::Reset( const SfxItemSet& /* rArgSet */ )
 
 sal_Bool ScTabPageSortFields::FillItemSet( SfxItemSet& rArgSet )
 {
-    ScSortParam theSortData = rSortData;
-    if (pDlg)
-    {
-        const SfxItemSet* pExample = pDlg->GetExampleSet();
-        const SfxPoolItem* pItem;
-        if ( pExample && pExample->GetItemState( nWhichSort, sal_True, &pItem ) == SFX_ITEM_SET )
-            theSortData = ((const ScSortItem*)pItem)->GetSortData();
-    }
-
-    sal_uInt16  nSort1Pos = aLbSort1.GetSelectEntryPos();
-    sal_uInt16  nSort2Pos = aLbSort2.GetSelectEntryPos();
-    sal_uInt16  nSort3Pos = aLbSort3.GetSelectEntryPos();
+    std::vector<sal_uInt16>  nSortPos;
 
-    OSL_ENSURE(    (nSort1Pos <= SC_MAXFIELDS)
-                && (nSort2Pos <= SC_MAXFIELDS)
-                && (nSort3Pos <= SC_MAXFIELDS),
-                "Array range error!" );
+    for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
+    {
+        nSortPos.push_back( aLbSortArr[i] -> GetSelectEntryPos() );
 
-    if ( nSort1Pos == LISTBOX_ENTRY_NOTFOUND ) nSort1Pos = 0;
-    if ( nSort2Pos == LISTBOX_ENTRY_NOTFOUND ) nSort2Pos = 0;
-    if ( nSort3Pos == LISTBOX_ENTRY_NOTFOUND ) nSort3Pos = 0;
+        if ( nSortPos[i] == LISTBOX_ENTRY_NOTFOUND ) nSortPos[i] = 0;
+    }
 
-    if ( nSort1Pos > 0 )
+    if ( nSortPos[0] > 0 )
     {
-        theSortData.bDoSort[0] = (nSort1Pos > 0);
-        theSortData.bDoSort[1] = (nSort2Pos > 0);
-        theSortData.bDoSort[2] = (nSort3Pos > 0);
+        for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
+            aNewSortData.maKeyState[i].bDoSort = (nSortPos[i] > 0);
 
         // If the "OK" was selected on the Options page while the sort
         // direction was changed, then the first field (i.e. nFieldArr[0])
         // of the respective direction is chosen as the sorting criterion:
         if ( bSortByRows != pDlg->GetByRows() )
         {
-            theSortData.nField[0] =
-            theSortData.nField[1] =
-            theSortData.nField[2] = ( bSortByRows ?
-                    static_cast<SCCOLROW>(nFirstRow) :
-                    static_cast<SCCOLROW>(nFirstCol) );
+            for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
+                aNewSortData.maKeyState[i].nField = ( bSortByRows ?
+                        static_cast<SCCOLROW>(nFirstRow) :
+                        static_cast<SCCOLROW>(nFirstCol) );
         }
         else
         {
-            theSortData.nField[0] = nFieldArr[nSort1Pos];
-            theSortData.nField[1] = nFieldArr[nSort2Pos];
-            theSortData.nField[2] = nFieldArr[nSort3Pos];
+           for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
+               aNewSortData.maKeyState[i].nField = nFieldArr[nSortPos[i]];
         }
 
-        theSortData.bAscending[0] = aBtnUp1.IsChecked();
-        theSortData.bAscending[1] = aBtnUp2.IsChecked();
-        theSortData.bAscending[2] = aBtnUp3.IsChecked();
+        for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
+            aNewSortData.maKeyState[i].bAscending = aBtnUp[i] -> IsChecked();
+
         // bHasHeader is in ScTabPageSortOptions::FillItemSet, where it belongs
     }
     else
     {
-        theSortData.bDoSort[0] =
-        theSortData.bDoSort[1] =
-        theSortData.bDoSort[2] = false;
+        for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
+            aNewSortData.maKeyState[i].bDoSort = false;
     }
 
-    rArgSet.Put( ScSortItem( SCITEM_SORTDATA, NULL, &theSortData ) );
+    rArgSet.Put( ScSortItem( SCITEM_SORTDATA, NULL, &aNewSortData ) );
 
     return sal_True;
 }
@@ -315,19 +306,19 @@ void ScTabPageSortFields::ActivatePage()
 {
     if ( pDlg )
     {
-        if (   bHasHeader  != pDlg->GetHeaders()
-            || bSortByRows != pDlg->GetByRows()   )
+        if ( bHasHeader  != pDlg->GetHeaders()
+             || bSortByRows != pDlg->GetByRows() )
         {
-            sal_uInt16  nCurSel1 = aLbSort1.GetSelectEntryPos();
-            sal_uInt16  nCurSel2 = aLbSort2.GetSelectEntryPos();
-            sal_uInt16  nCurSel3 = aLbSort3.GetSelectEntryPos();
+            std::vector<sal_uInt16> nCurSel;
+            for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
+                nCurSel.push_back( aLbSortArr[i] -> GetSelectEntryPos() );
 
             bHasHeader  = pDlg->GetHeaders();
             bSortByRows = pDlg->GetByRows();
-            FillFieldLists();
-            aLbSort1.SelectEntryPos( nCurSel1 );
-            aLbSort2.SelectEntryPos( nCurSel2 );
-            aLbSort3.SelectEntryPos( nCurSel3 );
+            FillFieldLists(0);
+
+            for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
+                aLbSortArr[i] -> SelectEntryPos( nCurSel[i] );
         }
     }
 }
@@ -355,14 +346,12 @@ int ScTabPageSortFields::DeactivatePage( SfxItemSet* pSetP )
 
 void ScTabPageSortFields::DisableField( sal_uInt16 nField )
 {
-    nField--;
-
-    if ( nField<=2 )
+    if ( nField<nSortKeyCount )
     {
-        aSortLbArr[nField]   ->Disable();
-        aDirBtnArr[nField][0]->Disable();
-        aDirBtnArr[nField][1]->Disable();
-        aFlArr[nField]       ->Disable();
+        aLbSortArr[nField]   -> Disable();
+        aBtnUp[nField]       -> Disable();
+        aBtnDown[nField]     -> Disable();
+        aFlArr[nField]       -> Disable();
     }
 }
 
@@ -370,20 +359,18 @@ void ScTabPageSortFields::DisableField( sal_uInt16 nField )
 
 void ScTabPageSortFields::EnableField( sal_uInt16 nField )
 {
-    nField--;
-
-    if ( nField<=2 )
+    if ( nField<nSortKeyCount )
     {
-        aSortLbArr[nField]   ->Enable();
-        aDirBtnArr[nField][0]->Enable();
-        aDirBtnArr[nField][1]->Enable();
-        aFlArr[nField]       ->Enable();
+        aLbSortArr[nField]   -> Enable();
+        aBtnUp[nField]       -> Enable();
+        aBtnDown[nField]     -> Enable();
+        aFlArr[nField]       -> Enable();
     }
 }
 
 // -----------------------------------------------------------------------
 
-void ScTabPageSortFields::FillFieldLists()
+void ScTabPageSortFields::FillFieldLists( sal_uInt16 nStartField )
 {
     if ( pViewData )
     {
@@ -391,12 +378,11 @@ void ScTabPageSortFields::FillFieldLists()
 
         if ( pDoc )
         {
-            aLbSort1.Clear();
-            aLbSort2.Clear();
-            aLbSort3.Clear();
-            aLbSort1.InsertEntry( aStrUndefined, 0 );
-            aLbSort2.InsertEntry( aStrUndefined, 0 );
-            aLbSort3.InsertEntry( aStrUndefined, 0 );
+            for ( sal_uInt16 i=nStartField; i<nSortKeyCount; i++ )
+            {
+                aLbSortArr[i] -> Clear();
+                aLbSortArr[i] -> InsertEntry( aStrUndefined, 0 );
+            }
 
             SCCOL   nFirstSortCol   = rSortData.nCol1;
             SCROW   nFirstSortRow   = rSortData.nRow1;
@@ -418,10 +404,11 @@ void ScTabPageSortFields::FillFieldLists()
                         aFieldName += ' ';
                         aFieldName += ScColToAlpha( col );
                     }
-                    nFieldArr[i] = col;
-                    aLbSort1.InsertEntry( aFieldName, i );
-                    aLbSort2.InsertEntry( aFieldName, i );
-                    aLbSort3.InsertEntry( aFieldName, i );
+                    nFieldArr.push_back( col );
+
+                    for ( sal_uInt16 j=nStartField; j<nSortKeyCount; j++ )
+                        aLbSortArr[j] -> InsertEntry( aFieldName, i );
+
                     i++;
                 }
             }
@@ -440,10 +427,11 @@ void ScTabPageSortFields::FillFieldLists()
                         aFieldName += ' ';
                         aFieldName += String::CreateFromInt32( row+1 );
                     }
-                    nFieldArr[i] = row;
-                    aLbSort1.InsertEntry( aFieldName, i );
-                    aLbSort2.InsertEntry( aFieldName, i );
-                    aLbSort3.InsertEntry( aFieldName, i );
+                    nFieldArr.push_back( row );
+
+                    for ( sal_uInt16 j=nStartField; j<nSortKeyCount; j++ )
+                        aLbSortArr[j] -> InsertEntry( aFieldName, i );
+
                     i++;
                 }
             }
@@ -478,38 +466,30 @@ sal_uInt16 ScTabPageSortFields::GetFieldSelPos( SCCOLROW nField )
 IMPL_LINK( ScTabPageSortFields, SelectHdl, ListBox *, pLb )
 {
     String aSelEntry = pLb->GetSelectEntry();
+    sal_uInt16  nPos   = 0;
 
-    if ( pLb == &aLbSort1 )
-    {
-        if ( aSelEntry == aStrUndefined )
-        {
-            aLbSort2.SelectEntryPos( 0 );
-            aLbSort3.SelectEntryPos( 0 );
-
-            if ( aFlSort2.IsEnabled() )
-                DisableField( 2 );
+    // Find selected listbox
+    while ( pLb != aLbSortArr[nPos] )
+        ++nPos;
 
-            if ( aFlSort3.IsEnabled() )
-                DisableField( 3 );
-        }
-        else
-        {
-            if ( !aFlSort2.IsEnabled() )
-                EnableField( 2 );
-        }
-    }
-    else if ( pLb == &aLbSort2 )
+    // If not selecting the last Listbox modify the succeeding ones
+    ++nPos;
+    if ( nPos < nSortKeyCount )
     {
         if ( aSelEntry == aStrUndefined )
         {
-            aLbSort3.SelectEntryPos( 0 );
-            if ( aFlSort3.IsEnabled() )
-                DisableField( 3 );
+            for ( sal_uInt16 i=nPos; i<nSortKeyCount; i++ )
+            {
+                aLbSortArr[i] -> SelectEntryPos( 0 );
+
+                if ( aFlArr[i] -> IsEnabled() )
+                    DisableField( i );
+            }
         }
         else
         {
-            if ( !aFlSort3.IsEnabled() )
-                EnableField( 3 );
+            if ( !aFlArr[nPos] -> IsEnabled() )
+                EnableField( nPos );
         }
     }
     return 0;
@@ -550,6 +530,7 @@ ScTabPageSortOptions::ScTabPageSortOptions( Window*             pParent,
         nWhichSort      ( rArgSet.GetPool()->GetWhich( SID_SORT ) ),
         rSortData       ( ((const ScSortItem&)
                           rArgSet.Get( nWhichSort )).GetSortData() ),
+        aNewSortData    ( rSortData ),
         pViewData       ( NULL ),
         pDoc            ( NULL ),
         pDlg            ( (ScSortDlg*)(GetParent() ? GetParent()->GetParent() : 0 ) ),
@@ -606,12 +587,23 @@ void ScTabPageSortOptions::Init()
 
     OSL_ENSURE( pViewData, "ViewData not found! :-/" );
 
+    // Create local copy of ScParam
+    aNewSortData = rSortData;
+
+    if (pDlg)
+    {
+        const SfxItemSet* pExample = pDlg->GetExampleSet();
+        const SfxPoolItem* pItem;
+        if ( pExample && pExample->GetItemState( nWhichSort, sal_True, &pItem ) == SFX_ITEM_SET )
+            aNewSortData = static_cast<const ScSortItem*>(pItem)->GetSortData();
+    }
+
     if ( pViewData && pDoc )
     {
         String          theArea;
         ScDBCollection* pDBColl     = pDoc->GetDBCollection();
         String          theDbArea;
-        const SCTAB nCurTab     = pViewData->GetTabNo();
+        const SCTAB     nCurTab     = pViewData->GetTabNo();
         String          theDbName   = 
rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(STR_DB_LOCAL_NONAME));
         const formula::FormulaGrammar::AddressConvention eConv = pDoc->GetAddressConvention();
 
@@ -636,17 +628,17 @@ void ScTabPageSortOptions::Init()
 
         // Check whether the field that is passed on is a database field:
 
-        ScAddress aScAddress( rSortData.nCol1, rSortData.nRow1, nCurTab );
+        ScAddress aScAddress( aNewSortData.nCol1, aNewSortData.nRow1, nCurTab );
         ScRange( aScAddress,
-                 ScAddress( rSortData.nCol2, rSortData.nRow2, nCurTab )
+                 ScAddress( aNewSortData.nCol2, aNewSortData.nRow2, nCurTab )
                ).Format( theArea, SCR_ABS, pDoc, eConv );
 
         if ( pDBColl )
         {
             ScDBData* pDBData
                     = pDBColl->GetDBAtArea( nCurTab,
-                                            rSortData.nCol1, rSortData.nRow1,
-                                            rSortData.nCol2, rSortData.nRow2 );
+                                            aNewSortData.nCol1, aNewSortData.nRow1,
+                                            aNewSortData.nCol2, aNewSortData.nRow2 );
             if ( pDBData )
             {
                 theDbName = pDBData->GetName();
@@ -752,46 +744,37 @@ void ScTabPageSortOptions::Reset( const SfxItemSet& /* rArgSet */ )
 
 sal_Bool ScTabPageSortOptions::FillItemSet( SfxItemSet& rArgSet )
 {
-    ScSortParam theSortData = rSortData;
-    if (pDlg)
-    {
-        const SfxItemSet* pExample = pDlg->GetExampleSet();
-        const SfxPoolItem* pItem;
-        if ( pExample && pExample->GetItemState( nWhichSort, sal_True, &pItem ) == SFX_ITEM_SET )
-            theSortData = ((const ScSortItem*)pItem)->GetSortData();
-    }
-
-    theSortData.bByRow          = aBtnTopDown.IsChecked();
-    theSortData.bHasHeader      = aBtnHeader.IsChecked();
-    theSortData.bCaseSens       = aBtnCase.IsChecked();
-    theSortData.bNaturalSort    = aBtnNaturalSort.IsChecked();
-    theSortData.bIncludePattern = aBtnFormats.IsChecked();
-    theSortData.bInplace        = !aBtnCopyResult.IsChecked();
-    theSortData.nDestCol        = theOutPos.Col();
-    theSortData.nDestRow        = theOutPos.Row();
-    theSortData.nDestTab        = theOutPos.Tab();
-    theSortData.bUserDef        = aBtnSortUser.IsChecked();
-    theSortData.nUserIndex      = (aBtnSortUser.IsChecked())
-                                    ? aLbSortUser.GetSelectEntryPos()
-                                    : 0;
+    aNewSortData.bByRow          = aBtnTopDown.IsChecked();
+    aNewSortData.bHasHeader      = aBtnHeader.IsChecked();
+    aNewSortData.bCaseSens       = aBtnCase.IsChecked();
+    aNewSortData.bNaturalSort    = aBtnNaturalSort.IsChecked();
+    aNewSortData.bIncludePattern = aBtnFormats.IsChecked();
+    aNewSortData.bInplace        = !aBtnCopyResult.IsChecked();
+    aNewSortData.nDestCol        = theOutPos.Col();
+    aNewSortData.nDestRow        = theOutPos.Row();
+    aNewSortData.nDestTab        = theOutPos.Tab();
+    aNewSortData.bUserDef        = aBtnSortUser.IsChecked();
+    aNewSortData.nUserIndex      = (aBtnSortUser.IsChecked())
+                                   ? aLbSortUser.GetSelectEntryPos()
+                                   : 0;
 
     // get locale
     LanguageType eLang = aLbLanguage.GetSelectLanguage();
-    theSortData.aCollatorLocale = MsLangId::convertLanguageToLocale( eLang, false );
+    aNewSortData.aCollatorLocale = MsLangId::convertLanguageToLocale( eLang, false );
 
     // get algorithm
     String sAlg;
     if ( eLang != LANGUAGE_SYSTEM )
     {
         uno::Sequence<rtl::OUString> aAlgos = pColWrap->listCollatorAlgorithms(
-                theSortData.aCollatorLocale );
+                aNewSortData.aCollatorLocale );
         sal_uInt16 nSel = aLbAlgorithm.GetSelectEntryPos();
         if ( nSel < aAlgos.getLength() )
             sAlg = aAlgos[nSel];
     }
-    theSortData.aCollatorAlgorithm = sAlg;
+    aNewSortData.aCollatorAlgorithm = sAlg;
 
-    rArgSet.Put( ScSortItem( SCITEM_SORTDATA, &theSortData ) );
+    rArgSet.Put( ScSortItem( SCITEM_SORTDATA, &aNewSortData ) );
 
     return sal_True;
 }
diff --git a/sc/source/ui/docshell/dbdocfun.cxx b/sc/source/ui/docshell/dbdocfun.cxx
index c1464b1..7f43ba7 100644
--- a/sc/source/ui/docshell/dbdocfun.cxx
+++ b/sc/source/ui/docshell/dbdocfun.cxx
@@ -282,7 +282,7 @@ bool ScDBDocFunc::RepeatDB( const ::rtl::OUString& rDBName, bool bRecord, bool b
 
         ScSortParam aSortParam;
         pDBData->GetSortParam( aSortParam );
-        sal_Bool bSort = aSortParam.bDoSort[0];
+        sal_Bool bSort = aSortParam.maKeyState[0].bDoSort;
 
         ScSubTotalParam aSubTotalParam;
         pDBData->GetSubTotalParam( aSubTotalParam );
@@ -585,7 +585,7 @@ sal_Bool ScDBDocFunc::Sort( SCTAB nTab, const ScSortParam& rSortParam,
     }
 
     // don't call ScDocument::Sort with an empty SortParam (may be empty here if bCopy is set)
-    if ( aLocalParam.bDoSort[0] )
+    if ( aLocalParam.maKeyState[0].bDoSort )
         pDoc->Sort( nTab, aLocalParam, bRepeatQuery );
 
     sal_Bool bSave = sal_True;
@@ -593,7 +593,7 @@ sal_Bool ScDBDocFunc::Sort( SCTAB nTab, const ScSortParam& rSortParam,
     {
         ScSortParam aOldSortParam;
         pDBData->GetSortParam( aOldSortParam );
-        if ( aOldSortParam.bDoSort[0] && aOldSortParam.bInplace )   // Inplace-Sortierung gemerkt?
+        if ( aOldSortParam.maKeyState[0].bDoSort && aOldSortParam.bInplace )   // 
Inplace-Sortierung gemerkt?
         {
             bSave = false;
             aOldSortParam.nDestCol = rSortParam.nDestCol;
diff --git a/sc/source/ui/inc/tpsort.hxx b/sc/source/ui/inc/tpsort.hxx
index 8b87726..2a447cb 100644
--- a/sc/source/ui/inc/tpsort.hxx
+++ b/sc/source/ui/inc/tpsort.hxx
@@ -29,6 +29,7 @@
 #ifndef SC_TPSORT_HXX
 #define SC_TPSORT_HXX
 
+#include <vector>
 
 #include <sfx2/tabdlg.hxx>
 #include <vcl/edit.hxx>
@@ -40,6 +41,7 @@
 
 #include "global.hxx"
 #include "address.hxx"
+#include "sortparam.hxx"
 
 //------------------------------------------------------------------------
 
@@ -97,23 +99,28 @@ private:
     ScSortDlg*          pDlg;
     ScViewData*         pViewData;
     const ScSortParam&  rSortData;
-    SCCOLROW            nFieldArr[SC_MAXFIELDS];
+    ScSortParam         aNewSortData;
+    std::vector<SCCOLROW>  nFieldArr;
     sal_uInt16          nFieldCount;
+    sal_uInt16          nSortKeyCount;
+    sal_uInt16          nCurrentOffset;
+
     SCCOL               nFirstCol;
     SCROW               nFirstRow;
     sal_Bool            bHasHeader;
     sal_Bool            bSortByRows;
 
-    ListBox*            aSortLbArr[3];
-    RadioButton*        aDirBtnArr[3][2];
-    FixedLine*          aFlArr[3];
+    std::vector<ListBox*>      aLbSortArr;
+    std::vector<RadioButton*>  aBtnUp;
+    std::vector<RadioButton*>  aBtnDown;
+    std::vector<FixedLine*>    aFlArr;
 
 #ifdef _TPSORT_CXX
 private:
     void    Init            ();
     void    DisableField    ( sal_uInt16 nField );
     void    EnableField     ( sal_uInt16 nField );
-    void    FillFieldLists  ();
+    void    FillFieldLists  ( sal_uInt16 nStartField );
     sal_uInt16  GetFieldSelPos  ( SCCOLROW nField );
 
     // Handler ------------------------
@@ -181,6 +188,7 @@ private:
 
     const sal_uInt16    nWhichSort;
     const ScSortParam&  rSortData;
+    ScSortParam         aNewSortData;
     ScViewData*         pViewData;
     ScDocument*         pDoc;
     ScSortDlg*          pDlg;
diff --git a/sc/source/ui/src/sortdlg.src b/sc/source/ui/src/sortdlg.src
index a4296f4..466ab7a 100644
--- a/sc/source/ui/src/sortdlg.src
+++ b/sc/source/ui/src/sortdlg.src
@@ -61,7 +61,7 @@ TabPage RID_SCPAGE_SORT_FIELDS
     {
         Pos = MAP_APPFONT ( 6 , 3 ) ;
         Size = MAP_APPFONT ( 248 , 8 ) ;
-        Text [ en-US ] = "Sort ~by" ;
+        Text [ en-US ] = "Sort ~key 1" ;
     };
     ListBox LB_SORT2
     {
@@ -92,7 +92,7 @@ TabPage RID_SCPAGE_SORT_FIELDS
     {
         Pos = MAP_APPFONT ( 6 , 44 ) ;
         Size = MAP_APPFONT ( 248 , 8 ) ;
-        Text [ en-US ] = "Then b~y" ;
+        Text [ en-US ] = "Sort ~key 2" ;
     };
     ListBox LB_SORT3
     {
@@ -123,7 +123,7 @@ TabPage RID_SCPAGE_SORT_FIELDS
     {
         Pos = MAP_APPFONT ( 6 , 85 ) ;
         Size = MAP_APPFONT ( 248 , 8 ) ;
-        Text [ en-US ] = "T~hen by" ;
+        Text [ en-US ] = "Sort ~key 3" ;
     };
 };
 
diff --git a/sc/source/ui/unoobj/cellsuno.cxx b/sc/source/ui/unoobj/cellsuno.cxx
index c82e56a..750822c 100644
--- a/sc/source/ui/unoobj/cellsuno.cxx
+++ b/sc/source/ui/unoobj/cellsuno.cxx
@@ -5625,9 +5625,9 @@ uno::Sequence<beans::PropertyValue> SAL_CALL 
ScCellRangeObj::createSortDescripto
             SCCOLROW nFieldStart = aParam.bByRow ?
                 static_cast<SCCOLROW>(aDBRange.aStart.Col()) :
                 static_cast<SCCOLROW>(aDBRange.aStart.Row());
-            for (sal_uInt16 i=0; i<MAXSORT; i++)
-                if ( aParam.bDoSort[i] && aParam.nField[i] >= nFieldStart )
-                    aParam.nField[i] -= nFieldStart;
+            for (sal_uInt16 i=0; i<aParam.GetSortKeyCount(); i++)
+                if ( aParam.maKeyState[i].bDoSort && aParam.maKeyState[i].nField >= nFieldStart )
+                    aParam.maKeyState[i].nField -= nFieldStart;
         }
     }
 
@@ -5653,9 +5653,9 @@ void SAL_CALL ScCellRangeObj::sort( const 
uno::Sequence<beans::PropertyValue>& a
             SCCOLROW nOldStart = aParam.bByRow ?
                 static_cast<SCCOLROW>(aRange.aStart.Col()) :
                 static_cast<SCCOLROW>(aRange.aStart.Row());
-            for (i=0; i<MAXSORT; i++)
-                if ( aParam.bDoSort[i] && aParam.nField[i] >= nOldStart )
-                    aParam.nField[i] -= nOldStart;
+            for (i=0; i<aParam.GetSortKeyCount(); i++)
+                if ( aParam.maKeyState[i].bDoSort && aParam.maKeyState[i].nField >= nOldStart )
+                    aParam.maKeyState[i].nField -= nOldStart;
         }
 
         ScSortDescriptor::FillSortParam( aParam, aDescriptor );
@@ -5665,8 +5665,8 @@ void SAL_CALL ScCellRangeObj::sort( const 
uno::Sequence<beans::PropertyValue>& a
         SCCOLROW nFieldStart = aParam.bByRow ?
             static_cast<SCCOLROW>(aRange.aStart.Col()) :
             static_cast<SCCOLROW>(aRange.aStart.Row());
-        for (i=0; i<MAXSORT; i++)
-            aParam.nField[i] += nFieldStart;
+        for (i=0; i<aParam.GetSortKeyCount(); i++)
+            aParam.maKeyState[i].nField += nFieldStart;
 
         SCTAB nTab = aRange.aStart.Tab();
         aParam.nCol1 = aRange.aStart.Col();
diff --git a/sc/source/ui/unoobj/datauno.cxx b/sc/source/ui/unoobj/datauno.cxx
index 125ac54..c2243ee 100644
--- a/sc/source/ui/unoobj/datauno.cxx
+++ b/sc/source/ui/unoobj/datauno.cxx
@@ -334,7 +334,7 @@ void ScSortDescriptor::FillProperties( uno::Sequence<beans::PropertyValue>& rSeq
     aOutPos.Row    = rParam.nDestRow;
 
     sal_uInt16 nSortCount = 0;
-    while ( nSortCount < MAXSORT && rParam.bDoSort[nSortCount] )
+    while ( nSortCount < rParam.GetSortKeyCount() && rParam.maKeyState[nSortCount].bDoSort )
         ++nSortCount;
 
     uno::Sequence<table::TableSortField> aFields(nSortCount);
@@ -343,8 +343,8 @@ void ScSortDescriptor::FillProperties( uno::Sequence<beans::PropertyValue>& rSeq
         table::TableSortField* pFieldArray = aFields.getArray();
         for (sal_uInt16 i=0; i<nSortCount; i++)
         {
-            pFieldArray[i].Field         = rParam.nField[i];
-            pFieldArray[i].IsAscending   = rParam.bAscending[i];
+            pFieldArray[i].Field         = rParam.maKeyState[i].nField;
+            pFieldArray[i].IsAscending   = rParam.maKeyState[i].bAscending;
             pFieldArray[i].FieldType     = table::TableSortFieldType_AUTOMATIC;     // immer 
Automatic
             pFieldArray[i].IsCaseSensitive = rParam.bCaseSens;
             pFieldArray[i].CollatorLocale = rParam.aCollatorLocale;
@@ -361,7 +361,7 @@ void ScSortDescriptor::FillProperties( uno::Sequence<beans::PropertyValue>& rSeq
     ScUnoHelpFunctions::SetBoolInAny( pArray[1].Value, rParam.bHasHeader );
 
     pArray[2].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_MAXFLD ));
-    pArray[2].Value <<= (sal_Int32) MAXSORT;
+    pArray[2].Value <<= static_cast<sal_Int32>( rParam.GetSortKeyCount() );
 
     pArray[3].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_SORTFLD ));
     pArray[3].Value <<= aFields;
@@ -379,13 +379,15 @@ void ScSortDescriptor::FillProperties( uno::Sequence<beans::PropertyValue>& 
rSeq
     ScUnoHelpFunctions::SetBoolInAny( pArray[7].Value, rParam.bUserDef );
 
     pArray[8].Name = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( SC_UNONAME_UINDEX ));
-    pArray[8].Value <<= (sal_Int32) rParam.nUserIndex;
+    pArray[8].Value <<= static_cast<sal_Int32>( rParam.nUserIndex );
 }
 
 void ScSortDescriptor::FillSortParam( ScSortParam& rParam, const 
uno::Sequence<beans::PropertyValue>& rSeq )
 {
     const beans::PropertyValue* pPropArray = rSeq.getConstArray();
     long nPropCount = rSeq.getLength();
+    sal_Int16 nSortSize = rParam.GetSortKeyCount();
+
     for (long nProp = 0; nProp < nPropCount; nProp++)
     {
         const beans::PropertyValue& rProp = pPropArray[nProp];
@@ -407,7 +409,7 @@ void ScSortDescriptor::FillSortParam( ScSortParam& rParam, const uno::Sequence<b
         else if (aPropName.EqualsAscii( SC_UNONAME_MAXFLD ))
         {
             sal_Int32 nVal;
-            if ( (rProp.Value >>= nVal) && nVal > MAXSORT )
+            if ( (rProp.Value >>= nVal) && nVal > nSortSize )
             {
                 //! specify exceptions
                 //! throw lang::IllegalArgumentException();
@@ -421,37 +423,37 @@ void ScSortDescriptor::FillSortParam( ScSortParam& rParam, const 
uno::Sequence<b
             {
                 sal_Int32 nCount = aSeq.getLength();
                 sal_Int32 i;
-                if ( nCount > MAXSORT )
+                if ( nCount > static_cast<sal_Int32>( rParam.GetSortKeyCount() ) )
                 {
                     OSL_FAIL("Zu viele Sortierfelder");
-                    nCount = MAXSORT;
+                    nCount = nSortSize;
                 }
                 const util::SortField* pFieldArray = aSeq.getConstArray();
                 for (i=0; i<nCount; i++)
                 {
-                    rParam.nField[i]     = (SCCOLROW)pFieldArray[i].Field;
-                    rParam.bAscending[i] = pFieldArray[i].SortAscending;
+                    rParam.maKeyState[i].nField     = static_cast<SCCOLROW>( pFieldArray[i].Field 
);
+                    rParam.maKeyState[i].bAscending = pFieldArray[i].SortAscending;
 
                     // FieldType wird ignoriert
-                    rParam.bDoSort[i] = sal_True;
+                    rParam.maKeyState[i].bDoSort = sal_True;
                 }
-                for (i=nCount; i<MAXSORT; i++)
-                    rParam.bDoSort[i] = false;
+                for (i=nCount; i<nSortSize; i++)
+                    rParam.maKeyState[i].bDoSort = false;
             }
             else if ( rProp.Value >>= aNewSeq )
             {
                 sal_Int32 nCount = aNewSeq.getLength();
                 sal_Int32 i;
-                if ( nCount > MAXSORT )
+                if ( nCount > nSortSize )
                 {
                     OSL_FAIL("Zu viele Sortierfelder");
-                    nCount = MAXSORT;
+                    nCount = nSortSize;
                 }
                 const table::TableSortField* pFieldArray = aNewSeq.getConstArray();
                 for (i=0; i<nCount; i++)
                 {
-                    rParam.nField[i]     = (SCCOLROW)pFieldArray[i].Field;
-                    rParam.bAscending[i] = pFieldArray[i].IsAscending;
+                    rParam.maKeyState[i].nField     = static_cast<SCCOLROW>( pFieldArray[i].Field 
);
+                    rParam.maKeyState[i].bAscending = pFieldArray[i].IsAscending;
 
                     // only one is possible, sometime we should make it possible to have different 
for every entry
                     rParam.bCaseSens = pFieldArray[i].IsCaseSensitive;
@@ -459,10 +461,10 @@ void ScSortDescriptor::FillSortParam( ScSortParam& rParam, const 
uno::Sequence<b
                     rParam.aCollatorAlgorithm = pFieldArray[i].CollatorAlgorithm;
 
                     // FieldType wird ignoriert
-                    rParam.bDoSort[i] = sal_True;
+                    rParam.maKeyState[i].bDoSort = sal_True;
                 }
-                for (i=nCount; i<MAXSORT; i++)
-                    rParam.bDoSort[i] = false;
+                for (i=nCount; i<nSortSize; i++)
+                    rParam.maKeyState[i].bDoSort = false;
             }
         }
         else if (aPropName.EqualsAscii( SC_UNONAME_ISCASE ))
@@ -1818,9 +1820,9 @@ uno::Sequence<beans::PropertyValue> SAL_CALL 
ScDatabaseRangeObj::getSortDescript
         ScRange aDBRange;
         pData->GetArea(aDBRange);
         SCCOLROW nFieldStart = aParam.bByRow ? static_cast<SCCOLROW>(aDBRange.aStart.Col()) : 
static_cast<SCCOLROW>(aDBRange.aStart.Row());
-        for (sal_uInt16 i=0; i<MAXSORT; i++)
-            if ( aParam.bDoSort[i] && aParam.nField[i] >= nFieldStart )
-                aParam.nField[i] -= nFieldStart;
+        for (sal_uInt16 i=0; i<aParam.GetSortKeyCount(); i++)
+            if ( aParam.maKeyState[i].bDoSort && aParam.maKeyState[i].nField >= nFieldStart )
+                aParam.maKeyState[i].nField -= nFieldStart;
     }
 
     uno::Sequence<beans::PropertyValue> aSeq( ScSortDescriptor::GetPropertyCount() );
diff --git a/sc/source/ui/vba/vbarange.cxx b/sc/source/ui/vba/vbarange.cxx
index 23a7492..0a9af87 100644
--- a/sc/source/ui/vba/vbarange.cxx
+++ b/sc/source/ui/vba/vbarange.cxx
@@ -3540,9 +3540,9 @@ ScVbaRange::Sort( const uno::Any& Key1, const uno::Any& Order1, const 
uno::Any&
 
     // set up defaults
 
-    sal_Int16 nOrder1 = aSortParam.bAscending[0] ? excel::XlSortOrder::xlAscending : 
excel::XlSortOrder::xlDescending;
-    sal_Int16 nOrder2 = aSortParam.bAscending[1] ? excel::XlSortOrder::xlAscending : 
excel::XlSortOrder::xlDescending;
-    sal_Int16 nOrder3 = aSortParam.bAscending[2] ? excel::XlSortOrder::xlAscending : 
excel::XlSortOrder::xlDescending;
+    sal_Int16 nOrder1 = aSortParam.maKeyState[1].bAscending ? excel::XlSortOrder::xlAscending : 
excel::XlSortOrder::xlDescending;
+    sal_Int16 nOrder2 = aSortParam.maKeyState[2].bAscending ? excel::XlSortOrder::xlAscending : 
excel::XlSortOrder::xlDescending;
+    sal_Int16 nOrder3 = aSortParam.maKeyState[3].bAscending ? excel::XlSortOrder::xlAscending : 
excel::XlSortOrder::xlDescending;
 
     sal_Int16 nCustom = aSortParam.nUserIndex;
     sal_Int16 nSortMethod = excel::XlSortMethod::xlPinYin;
@@ -3621,26 +3621,26 @@ ScVbaRange::Sort( const uno::Any& Key1, const uno::Any& Order1, const 
uno::Any&
     {
         nOrder1 = ::comphelper::getINT16(Order1);
         if (  nOrder1 == excel::XlSortOrder::xlAscending )
-            aSortParam.bAscending[0]  = true;
+            aSortParam.maKeyState[0].bAscending  = true;
         else
-            aSortParam.bAscending[0]  = false;
+            aSortParam.maKeyState[0].bAscending  = false;
 
     }
     if ( Order2.hasValue() )
     {
         nOrder2 = ::comphelper::getINT16(Order2);
         if ( nOrder2 == excel::XlSortOrder::xlAscending )
-            aSortParam.bAscending[1]  = true;
+            aSortParam.maKeyState[1].bAscending  = true;
         else
-            aSortParam.bAscending[1]  = false;
+            aSortParam.maKeyState[1].bAscending  = false;
     }
     if ( Order3.hasValue() )
     {
         nOrder3 = ::comphelper::getINT16(Order3);
         if ( nOrder3 == excel::XlSortOrder::xlAscending )
-            aSortParam.bAscending[2]  = true;
+            aSortParam.maKeyState[2].bAscending  = true;
         else
-            aSortParam.bAscending[2]  = false;
+            aSortParam.maKeyState[2].bAscending  = false;
     }
 
     uno::Reference< table::XCellRange > xKey1;
diff --git a/sc/source/ui/view/cellsh2.cxx b/sc/source/ui/view/cellsh2.cxx
index 77121b7..cc29587 100644
--- a/sc/source/ui/view/cellsh2.cxx
+++ b/sc/source/ui/view/cellsh2.cxx
@@ -376,12 +376,10 @@ void ScCellShell::ExecuteDB( SfxRequest& rReq )
                     aSortParam.bNaturalSort     = false;
                     aSortParam.bIncludePattern  = true;
                     aSortParam.bInplace         = true;
-                    aSortParam.bDoSort[0]       = true;
-                    aSortParam.nField[0]        = nCol;
-                    aSortParam.bAscending[0]    = (nSlotId == SID_SORT_ASCENDING);
+                    aSortParam.maKeyState[0]    = { true, nCol, nSlotId == SID_SORT_ASCENDING };
 
-                    for ( sal_uInt16 i=1; i<MAXSORT; i++ )
-                        aSortParam.bDoSort[i] = false;
+                    for ( sal_uInt16 i=1; i<aSortParam.GetSortKeyCount(); i++ )
+                        aSortParam.maKeyState[i].bDoSort = false;
 
                     aArgSet.Put( ScSortItem( SCITEM_SORTDATA, GetViewData(), &aSortParam ) );
 
@@ -420,18 +418,18 @@ void ScCellShell::ExecuteDB( SfxRequest& rReq )
 
                         const SfxPoolItem* pItem;
                         if ( pArgs->GetItemState( SID_SORT_BYROW, sal_True, &pItem ) == 
SFX_ITEM_SET )
-                            aSortParam.bByRow = ((const SfxBoolItem*)pItem)->GetValue();
+                            aSortParam.bByRow = static_cast<const SfxBoolItem*>(pItem)->GetValue();
                         if ( pArgs->GetItemState( SID_SORT_HASHEADER, sal_True, &pItem ) == 
SFX_ITEM_SET )
-                            aSortParam.bHasHeader = ((const SfxBoolItem*)pItem)->GetValue();
+                            aSortParam.bHasHeader = static_cast<const 
SfxBoolItem*>(pItem)->GetValue();
                         if ( pArgs->GetItemState( SID_SORT_CASESENS, sal_True, &pItem ) == 
SFX_ITEM_SET )
-                            aSortParam.bCaseSens = ((const SfxBoolItem*)pItem)->GetValue();
+                            aSortParam.bCaseSens = static_cast<const 
SfxBoolItem*>(pItem)->GetValue();
                     if ( pArgs->GetItemState( SID_SORT_NATURALSORT, true, &pItem ) == SFX_ITEM_SET 
)
-                        aSortParam.bNaturalSort = ((const SfxBoolItem*)pItem)->GetValue();
+                        aSortParam.bNaturalSort = static_cast<const 
SfxBoolItem*>(pItem)->GetValue();
                         if ( pArgs->GetItemState( SID_SORT_ATTRIBS, true, &pItem ) == SFX_ITEM_SET 
)
-                            aSortParam.bIncludePattern = ((const SfxBoolItem*)pItem)->GetValue();
+                            aSortParam.bIncludePattern = static_cast<const 
SfxBoolItem*>(pItem)->GetValue();
                         if ( pArgs->GetItemState( SID_SORT_USERDEF, sal_True, &pItem ) == 
SFX_ITEM_SET )
                         {
-                            sal_uInt16 nUserIndex = ((const SfxUInt16Item*)pItem)->GetValue();
+                            sal_uInt16 nUserIndex = static_cast<const 
SfxUInt16Item*>(pItem)->GetValue();
                             aSortParam.bUserDef = ( nUserIndex != 0 );
                             if ( nUserIndex )
                                 aSortParam.nUserIndex = nUserIndex - 1;     // Basic: 1-based
@@ -439,25 +437,25 @@ void ScCellShell::ExecuteDB( SfxRequest& rReq )
 
                         SCCOLROW nField0 = 0;
                         if ( pArgs->GetItemState( FN_PARAM_1, sal_True, &pItem ) == SFX_ITEM_SET )
-                            nField0 = ((const SfxInt32Item*)pItem)->GetValue();
-                        aSortParam.bDoSort[0] = ( nField0 != 0 );
-                        aSortParam.nField[0] = nField0 > 0 ? (nField0-1) : 0;
+                            nField0 = static_cast<const SfxInt32Item*>(pItem)->GetValue();
+                        aSortParam.maKeyState[0].bDoSort = ( nField0 != 0 );
+                        aSortParam.maKeyState[0].nField = nField0 > 0 ? (nField0-1) : 0;
                         if ( pArgs->GetItemState( FN_PARAM_2, sal_True, &pItem ) == SFX_ITEM_SET )
-                            aSortParam.bAscending[0] = ((const SfxBoolItem*)pItem)->GetValue();
+                            aSortParam.maKeyState[0].bAscending = static_cast<const 
SfxBoolItem*>(pItem)->GetValue();
                         SCCOLROW nField1 = 0;
                         if ( pArgs->GetItemState( FN_PARAM_3, sal_True, &pItem ) == SFX_ITEM_SET )
-                            nField1 = ((const SfxInt32Item*)pItem)->GetValue();
-                        aSortParam.bDoSort[1] = ( nField1 != 0 );
-                        aSortParam.nField[1] = nField1 > 0 ? (nField1-1) : 0;
+                            nField1 = static_cast<const SfxInt32Item*>(pItem)->GetValue();
+                        aSortParam.maKeyState[1].bDoSort = ( nField1 != 0 );
+                        aSortParam.maKeyState[1].nField = nField1 > 0 ? (nField1-1) : 0;
                         if ( pArgs->GetItemState( FN_PARAM_4, sal_True, &pItem ) == SFX_ITEM_SET )
-                            aSortParam.bAscending[1] = ((const SfxBoolItem*)pItem)->GetValue();
+                            aSortParam.maKeyState[1].bAscending = static_cast<const 
SfxBoolItem*>(pItem)->GetValue();
                         SCCOLROW nField2 = 0;
                         if ( pArgs->GetItemState( FN_PARAM_5, sal_True, &pItem ) == SFX_ITEM_SET )
-                            nField2 = ((const SfxInt32Item*)pItem)->GetValue();
-                        aSortParam.bDoSort[2] = ( nField2 != 0 );
-                        aSortParam.nField[2] = nField2 > 0 ? (nField2-1) : 0;
+                            nField2 = static_cast<const SfxInt32Item*>(pItem)->GetValue();
+                        aSortParam.maKeyState[2].bDoSort = ( nField2 != 0 );
+                        aSortParam.maKeyState[2].nField = nField2 > 0 ? (nField2-1) : 0;
                         if ( pArgs->GetItemState( FN_PARAM_6, sal_True, &pItem ) == SFX_ITEM_SET )
-                            aSortParam.bAscending[2] = ((const SfxBoolItem*)pItem)->GetValue();
+                            aSortParam.maKeyState[2].bAscending = static_cast<const 
SfxBoolItem*>(pItem)->GetValue();
 
                         // subtotal when needed new
                         pTabViewShell->UISort( aSortParam );
@@ -516,26 +514,26 @@ void ScCellShell::ExecuteDB( SfxRequest& rReq )
                                     rOutParam.bIncludePattern ) );
                                 sal_uInt16 nUser = rOutParam.bUserDef ? ( rOutParam.nUserIndex + 1 
) : 0;
                                 rReq.AppendItem( SfxUInt16Item( SID_SORT_USERDEF, nUser ) );
-                                if ( rOutParam.bDoSort[0] )
+                                if ( rOutParam.maKeyState[0].bDoSort )
                                 {
                                     rReq.AppendItem( SfxInt32Item( FN_PARAM_1,
-                                        rOutParam.nField[0] + 1 ) );
+                                        rOutParam.maKeyState[0].nField + 1 ) );
                                     rReq.AppendItem( SfxBoolItem( FN_PARAM_2,
-                                        rOutParam.bAscending[0] ) );
+                                        rOutParam.maKeyState[0].bAscending ) );
                                 }
-                                if ( rOutParam.bDoSort[1] )
+                                if ( rOutParam.maKeyState[1].bDoSort )
                                 {
                                     rReq.AppendItem( SfxInt32Item( FN_PARAM_3,
-                                        rOutParam.nField[1] + 1 ) );
+                                        rOutParam.maKeyState[1].nField + 1 ) );
                                     rReq.AppendItem( SfxBoolItem( FN_PARAM_4,
-                                        rOutParam.bAscending[1] ) );
+                                        rOutParam.maKeyState[1].bAscending ) );
                                 }
-                                if ( rOutParam.bDoSort[2] )
+                                if ( rOutParam.maKeyState[2].bDoSort )
                                 {
                                     rReq.AppendItem( SfxInt32Item( FN_PARAM_5,
-                                        rOutParam.nField[2] + 1 ) );
+                                        rOutParam.maKeyState[2].nField + 1 ) );
                                     rReq.AppendItem( SfxBoolItem( FN_PARAM_6,
-                                        rOutParam.bAscending[2] ) );
+                                        rOutParam.maKeyState[2].bAscending ) );
                                 }
                             }
 
diff --git a/sc/source/ui/view/dbfunc3.cxx b/sc/source/ui/view/dbfunc3.cxx
index f6eb887..aa15898 100644
--- a/sc/source/ui/view/dbfunc3.cxx
+++ b/sc/source/ui/view/dbfunc3.cxx
@@ -2158,7 +2158,7 @@ void ScDBFunc::RepeatDB( sal_Bool bRecord )
 
     ScSortParam aSortParam;
     pDBData->GetSortParam( aSortParam );
-    sal_Bool bSort = aSortParam.bDoSort[0];
+    sal_Bool bSort = aSortParam.maKeyState[0].bDoSort;
 
     ScSubTotalParam aSubTotalParam;
     pDBData->GetSubTotalParam( aSubTotalParam );
-- 
1.7.3.4


Context


Privacy Policy | Impressum (Legal Info) | Copyright information: Unless otherwise specified, all text and images on this website are licensed under the Creative Commons Attribution-Share Alike 3.0 License. This does not include the source code of LibreOffice, which is licensed under the Mozilla Public License (MPLv2). "LibreOffice" and "The Document Foundation" are registered trademarks of their corresponding registered owners or are in actual use as trademarks in one or more countries. Their respective logos and icons are also subject to international copyright laws. Use thereof is explained in our trademark policy.