Hi Marcus,
Here is an updated patch which I hope you have time to review. I'm
sure that there are things that can be done differently, but basically
the patch works.

I have found two problems myself that I need help resolving:

1.) Compile time waring about resources ids. There is probably a
simple fix for this, I think I understand the problem but not what to
do about it.
f4099: "/home/thuswa/work/libo2/sc/source/ui/src/sortdlg.src", line
60: Warning in the object (Type: ListBox, 15):
Global resources should have an identifier >= 256.

Pos = MAP_APPFONT ( 172 , 11 ) ;
^
f4099: "/home/thuswa/work/libo2/sc/source/ui/src/sortdlg.src", line
68: Warning in the object (Type: RadioButton, 16):
Global resources should have an identifier >= 256.

Pos = MAP_APPFONT ( 172 , 25 ) ;
^
f4099: "/home/thuswa/work/libo2/sc/source/ui/src/sortdlg.src", line
75: Warning in the object (Type: RadioButton, 17):
Global resources should have an identifier >= 256.

Pos = MAP_APPFONT ( 6 , 0 ) ;
^
f4099: "/home/thuswa/work/libo2/sc/source/ui/src/sortdlg.src", line
82: Warning in the object (Type: FixedLine, 14):
Global resources should have an identifier >= 256.
[ build DEP ] SRS:sc/res


2.) to return a pointer to the vector containing the ui widgets is of
course not ideal, see below:

ScSortKeyItems* ScSortKeyWindow::AddSortKey( sal_uInt16 nItem )
ScSortKeyItems* ScSortKeyCtrl::AddSortKey( sal_uInt16 nItem )

Instead I probably should create a reference when I initialize
ScSortKeyCtrl and ScSortKeyWindow, but I'm not exactly sure how to do
this.

Thanks for your help.
/Albert
From 19c965f654ec408b6a7ad4b44d390033ef5729d0 Mon Sep 17 00:00:00 2001
From: Albert Thuswaldner <albert.thuswald...@gmail.com>
Date: Thu, 26 Apr 2012 23:35:46 +0200
Subject: [PATCH] fdo#45747 - remove the limitation to 3 sort entries in calc, part 2

---
 sc/Library_scui.mk                |    1 +
 sc/inc/helpids.h                  |    1 +
 sc/inc/sc.hrc                     |    4 +-
 sc/source/ui/dbgui/sortkeydlg.cxx |  213 +++++++++++++++++++++++++++++++++++++
 sc/source/ui/dbgui/tpsort.cxx     |  186 ++++++++++++++------------------
 sc/source/ui/inc/sortdlg.hrc      |   23 ++--
 sc/source/ui/inc/sortkeydlg.hxx   |  110 +++++++++++++++++++
 sc/source/ui/inc/tpsort.hxx       |   24 +----
 sc/source/ui/src/sortdlg.src      |  141 +++++++++----------------
 9 files changed, 473 insertions(+), 230 deletions(-)
 create mode 100644 sc/source/ui/dbgui/sortkeydlg.cxx
 create mode 100644 sc/source/ui/inc/sortkeydlg.hxx

diff --git a/sc/Library_scui.mk b/sc/Library_scui.mk
index 9af5a63..37478a2 100644
--- a/sc/Library_scui.mk
+++ b/sc/Library_scui.mk
@@ -72,6 +72,7 @@ $(eval $(call gb_Library_add_exception_objects,scui,\
     sc/source/ui/dbgui/scuiasciiopt \
     sc/source/ui/dbgui/scuiimoptdlg \
     sc/source/ui/dbgui/sortdlg \
+    sc/source/ui/dbgui/sortkeydlg \
     sc/source/ui/dbgui/subtdlg \
     sc/source/ui/dbgui/textimportoptions \
     sc/source/ui/dbgui/tpsort \
diff --git a/sc/inc/helpids.h b/sc/inc/helpids.h
index 5eec0d1..03b9f40 100644
--- a/sc/inc/helpids.h
+++ b/sc/inc/helpids.h
@@ -88,6 +88,7 @@
 #define HID_SC_FORM_ARGS                                        "SC_HID_SC_FORM_ARGS"
 #define HID_SCPAGE_SORT_FIELDS                                  "SC_HID_SCPAGE_SORT_FIELDS"
 #define HID_SCPAGE_SORT_OPTIONS                                 "SC_HID_SCPAGE_SORT_OPTIONS"
+#define HID_SCPAGE_SORTKEY_FIELDS                               "SC_HID_SCPAGE_SORTKEY_FIELDS"
 #define HID_SCPAGE_SUBT_OPTIONS                                 "SC_HID_SCPAGE_SUBT_OPTIONS"
 #define HID_SCPAGE_SUBT_GROUP                                   "SC_HID_SCPAGE_SUBT_GROUP"
 #define HID_SCPAGE_PROTECTION                                   "SC_HID_SCPAGE_PROTECTION"
diff --git a/sc/inc/sc.hrc b/sc/inc/sc.hrc
index f8b1875..25b90fe 100644
--- a/sc/inc/sc.hrc
+++ b/sc/inc/sc.hrc
@@ -1221,7 +1221,9 @@
 #define RID_POPUP_FILTER                (SC_DIALOGS_START + 153)
 #define RID_SCDLG_TAB_BG_COLOR          (SC_DIALOGS_START + 154)
 
-#define SC_DIALOGS_END                  (SC_DIALOGS_START + 155)
+#define RID_SCPAGE_SORTKEY_FIELDS       (SC_DIALOGS_START + 155)
+#define RID_SCDLG_SORTKEY               (SC_DIALOGS_START + 156)
+#define SC_DIALOGS_END                  (SC_DIALOGS_START + 157)
 
 #ifndef STD_MASKCOLOR
 #define STD_MASKCOLOR Color { Red = 0xFF00; Green = 0x0000; Blue = 0xFF00; }
diff --git a/sc/source/ui/dbgui/sortkeydlg.cxx b/sc/source/ui/dbgui/sortkeydlg.cxx
new file mode 100644
index 0000000..747f886
--- /dev/null
+++ b/sc/source/ui/dbgui/sortkeydlg.cxx
@@ -0,0 +1,213 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Version: MPL 1.1 / GPLv3+ / LGPLv3+
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License or as specified alternatively below. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Major Contributor(s):
+ *  Copyright (C) 2012 Albert Thuswaldner <albert.thuswald...@gmail.com> (initial developer)
+ *
+ * All Rights Reserved.
+ *
+ * For minor contributions see the git repository.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+ * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+ * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+ * instead of those above.
+ */
+
+#include "sortkeydlg.hxx"
+#include "sortdlg.hxx"
+#include "sortdlg.hrc"
+
+// =======================================================================
+
+ScSortKeyItem::ScSortKeyItem( Window* pParent ) :
+    //
+    aFlSort        ( pParent, ScResId( FL_SORT  ) ),
+    aLbSort        ( pParent, ScResId( LB_SORT  ) ),
+    aBtnUp         ( pParent, ScResId( BTN_UP   ) ),
+    aBtnDown       ( pParent, ScResId( BTN_DOWN ) )
+{
+}
+
+// -----------------------------------------------------------------------
+
+void ScSortKeyItem::DisableField()
+{
+    aFlSort.Disable();
+    aLbSort.Disable();
+    aBtnUp.Disable();
+    aBtnDown.Disable();
+
+}
+
+ // -----------------------------------------------------------------------
+
+void ScSortKeyItem::EnableField()
+{
+    aFlSort.Enable();
+    aLbSort.Enable();
+    aBtnUp.Enable();
+    aBtnDown.Enable();
+}
+
+// =======================================================================
+
+    ScSortKeyWindow::ScSortKeyWindow( Window* pParent, const ResId& rResId ) :
+    Window( pParent, rResId ),
+    //
+    aFlSort        ( this, ScResId( FL_SORT  ) ),
+    aLbSort        ( this, ScResId( LB_SORT  ) ),
+    aBtnUp         ( this, ScResId( BTN_UP   ) ),
+    aBtnDown       ( this, ScResId( BTN_DOWN ) ),
+    //
+    nScrollPos     ( 0 ),
+    nItemNumber    ( 0 )
+{
+    aFlSort.Hide();
+    aLbSort.Hide();
+    aBtnUp.Hide();
+    aBtnDown.Hide();
+}
+
+// -----------------------------------------------------------------------
+
+ScSortKeyWindow::~ScSortKeyWindow()
+{
+    std::vector< ScSortKeyItem* >::iterator pIter;
+    for ( pIter = mpSortKeyItems.begin(); pIter != mpSortKeyItems.end(); ++pIter )
+    {
+        ScSortKeyItem* pItem = *pIter;
+        delete pItem;
+    }
+
+}
+
+// -----------------------------------------------------------------------
+
+ScSortKeyItems* ScSortKeyWindow::AddSortKey( sal_uInt16 nItem )
+{
+    ScSortKeyItem* pSortKeyItem = new ScSortKeyItem( this );
+    nItemNumber = nItem;
+
+    // Set Sort key number
+    String aLine = pSortKeyItem->aFlSort.GetText();
+    aLine += String::CreateFromInt32( nItemNumber );
+    pSortKeyItem->aFlSort.SetText( aLine );
+
+    mpSortKeyItems.push_back( pSortKeyItem );
+
+    Window* pWindows[] = {  &aFlSort, &aLbSort, &aBtnUp, &aBtnDown, NULL };
+
+    Window* pNewWindows[] = { &pSortKeyItem->aFlSort, &pSortKeyItem->aLbSort,
+                              &pSortKeyItem->aBtnUp,  &pSortKeyItem->aBtnDown, NULL };
+    Window** pCurrent = pWindows;
+    Window** pNewCurrent = pNewWindows;
+    while ( *pCurrent )
+    {
+        Size aSize = (*pCurrent)->GetSizePixel();
+        Point aPos = (*pCurrent)->GetPosPixel();
+        aPos.Y() += ( nItemNumber - 1 ) * SORTKEY_OFFSET;
+        aPos.Y() += nScrollPos;
+        (*pNewCurrent)->SetPosSizePixel( aPos, aSize );
+        (*pNewCurrent)->Show();
+        pCurrent++;
+        pNewCurrent++;
+    }
+
+    return  &mpSortKeyItems;
+}
+
+// -----------------------------------------------------------------------
+
+void ScSortKeyWindow::DoScroll( sal_Int32 nNewPos )
+{
+    nScrollPos += nNewPos;
+    std::vector< ScSortKeyItem* >::iterator pIter;
+    for ( pIter = mpSortKeyItems.begin(); pIter != mpSortKeyItems.end(); ++pIter )
+    {
+        ScSortKeyItem* pItem = *pIter;
+        //        if ( pLine->m_bIsRemoved )
+        //    continue;
+
+        Window* pNewWindows[] = { &pItem->aFlSort, &pItem->aLbSort,
+                                  &pItem->aBtnUp,  &pItem->aBtnDown, NULL };
+
+        Window** pCurrent = pNewWindows;
+        while ( *pCurrent )
+        {
+            Point aPos = (*pCurrent)->GetPosPixel();
+            aPos.Y() += nNewPos;
+            (*pCurrent)->SetPosPixel( aPos );
+            pCurrent++;
+        }
+    }
+}
+
+// =======================================================================
+
+ScSortKeyCtrl::ScSortKeyCtrl( Window* pParent, const ScResId& rResId ):
+    Control( pParent, rResId),
+    //
+    aSortWin    ( this, ResId( WIN_MANAGESORTKEY, *rResId.GetResMgr() ) ),
+    aVertScroll ( this, ResId( SB_SORT, *rResId.GetResMgr() ) ),
+    nThumbPos   ( 0 )
+{
+    aVertScroll.EnableDrag();
+    aVertScroll.Show();
+
+    FreeResource();
+
+    aVertScroll.SetRangeMin( 0 );
+    sal_Int32 nScrollOffset = SORTKEY_OFFSET;
+    sal_Int32 nVisibleItems = aSortWin.GetSizePixel().Height() / nScrollOffset;
+    aVertScroll.SetRangeMax( nVisibleItems );
+    aVertScroll.SetPageSize( nVisibleItems - 1 );
+    aVertScroll.SetVisibleSize( nVisibleItems );
+
+    //    aPos = aVertScroll.GetPosPixel();
+    //aSize = aVertScroll.GetSizePixel();
+
+    Link aScrollLink = LINK( this, ScSortKeyCtrl, ScrollHdl );
+    aVertScroll.SetScrollHdl( aScrollLink );
+}
+
+// -----------------------------------------------------------------------
+
+ScSortKeyCtrl::~ScSortKeyCtrl()
+{
+}
+
+// -----------------------------------------------------------------------
+
+IMPL_LINK( ScSortKeyCtrl, ScrollHdl, ScrollBar*, pScrollBar )
+{
+    sal_Int32 nOffset = SORTKEY_OFFSET;
+    nOffset *= ( nThumbPos - pScrollBar->GetThumbPos() );
+    nThumbPos = pScrollBar->GetThumbPos();
+    aSortWin.DoScroll( nOffset );
+    return 0;
+}
+
+// -----------------------------------------------------------------------
+
+ScSortKeyItems* ScSortKeyCtrl::AddSortKey( sal_uInt16 nItem )
+{
+    aVertScroll.SetRangeMax( nItem );
+    aVertScroll.DoScroll( nItem );
+    return aSortWin.AddSortKey( nItem );
+
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/dbgui/tpsort.cxx b/sc/source/ui/dbgui/tpsort.cxx
index f36c0a3..6d77a46 100644
--- a/sc/source/ui/dbgui/tpsort.cxx
+++ b/sc/source/ui/dbgui/tpsort.cxx
@@ -49,6 +49,8 @@
 #include "sc.hrc"       // -> Slot IDs
 #include "globstr.hrc"
 
+#include "sortkeydlg.hxx"
+
 #include "sortdlg.hxx"
 #include "sortdlg.hrc"
 
@@ -89,21 +91,6 @@ ScTabPageSortFields::ScTabPageSortFields( Window*           pParent,
                           ScResId( RID_SCPAGE_SORT_FIELDS ),
                           rArgSet ),
         //
-        aFlSort1        ( this, ScResId( FL_SORT1  ) ),
-        aLbSort1        ( this, ScResId( LB_SORT1  ) ),
-        aBtnUp1         ( this, ScResId( BTN_UP1   ) ),
-        aBtnDown1       ( this, ScResId( BTN_DOWN1 ) ),
-        //
-        aFlSort2        ( this, ScResId( FL_SORT2  ) ),
-        aLbSort2        ( this, ScResId( LB_SORT2  ) ),
-        aBtnUp2         ( this, ScResId( BTN_UP2   ) ),
-        aBtnDown2       ( this, ScResId( BTN_DOWN2 ) ),
-        //
-        aFlSort3        ( this, ScResId( FL_SORT3  ) ),
-        aLbSort3        ( this, ScResId( LB_SORT3  ) ),
-        aBtnUp3         ( this, ScResId( BTN_UP3   ) ),
-        aBtnDown3       ( this, ScResId( BTN_DOWN3 ) ),
-
         aStrUndefined   ( ScResId( SCSTR_UNDEFINED ) ),
         aStrColumn      ( ScResId( SCSTR_COLUMN ) ),
         aStrRow         ( ScResId( SCSTR_ROW ) ),
@@ -114,12 +101,14 @@ ScTabPageSortFields::ScTabPageSortFields( Window*           pParent,
         rSortData       ( ((const ScSortItem&)
                            rArgSet.Get( nWhichSort )).
                                 GetSortData() ),
+        //
         aNewSortData    ( rSortData ),
         nFieldCount     ( 0 ),
         nSortKeyCount   ( DEFSORT ),
         nCurrentOffset  ( 0 ),
         bHasHeader      ( false ),
-        bSortByRows     ( false )
+        bSortByRows     ( false ),
+        maSortKeyCtrl   ( this, ScResId( CTRL_MANAGESORTKEY ) )
 {
     Init();
     FreeResource();
@@ -131,6 +120,7 @@ ScTabPageSortFields::ScTabPageSortFields( Window*           pParent,
 ScTabPageSortFields::~ScTabPageSortFields()
 {
 }
+
 // -----------------------------------------------------------------------
 
 void ScTabPageSortFields::Init()
@@ -139,7 +129,6 @@ void ScTabPageSortFields::Init()
                                   GetItemSet().Get( nWhichSort );
 
     pViewData = rSortItem.GetViewData();
-
     OSL_ENSURE( pViewData, "ViewData not found!" );
 
     // Create local copy of ScParam
@@ -153,33 +142,16 @@ void ScTabPageSortFields::Init()
             aNewSortData = static_cast<const ScSortItem*>(pItem)->GetSortData();
     }
 
-    // Connect handlers and widgets
     nFieldArr.push_back( 0 );
     nFirstCol = 0;
     nFirstRow = 0;
 
-    aLbSort1.SetSelectHdl( LINK( this, ScTabPageSortFields, SelectHdl ) );
-    aLbSort2.SetSelectHdl( LINK( this, ScTabPageSortFields, SelectHdl ) );
-    aLbSort3.SetSelectHdl( LINK( this, ScTabPageSortFields, SelectHdl ) );
-    aLbSort1.Clear();
-    aLbSort2.Clear();
-    aLbSort3.Clear();
-
-    aLbSortArr.push_back( &aLbSort1 );
-    aLbSortArr.push_back( &aLbSort2 );
-    aLbSortArr.push_back( &aLbSort3 );
-
-    aBtnUp.push_back( &aBtnUp1 );
-    aBtnUp.push_back( &aBtnUp2 );
-    aBtnUp.push_back( &aBtnUp3 );
-
-    aBtnDown.push_back( &aBtnDown1 );
-    aBtnDown.push_back( &aBtnDown2 );
-    aBtnDown.push_back( &aBtnDown3 );
-
-    aFlArr.push_back( &aFlSort1 );
-    aFlArr.push_back( &aFlSort2 );
-    aFlArr.push_back( &aFlSort3 );
+    // Create three sort key dialogs by default
+    for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
+    {
+        mpSortKeyItems = maSortKeyCtrl.AddSortKey(i+1);
+        (*mpSortKeyItems)[i] -> aLbSort.SetSelectHdl( LINK( this, ScTabPageSortFields, SelectHdl ) );
+    }
 }
 
 // -----------------------------------------------------------------------
@@ -197,7 +169,7 @@ void ScTabPageSortFields::Reset( const SfxItemSet& /* rArgSet */ )
     bSortByRows = aNewSortData.bByRow;
     bHasHeader  = aNewSortData.bHasHeader;
 
-    if ( aLbSort1.GetEntryCount() == 0 )
+    if ( (*mpSortKeyItems)[0] -> aLbSort.GetEntryCount() == 0 )
         FillFieldLists(0);
 
     // ListBox selection:
@@ -207,27 +179,28 @@ void ScTabPageSortFields::Reset( const SfxItemSet& /* rArgSet */ )
         {
             if ( aNewSortData.maKeyState[i].bDoSort )
             {
-                aLbSortArr[i]->SelectEntryPos( GetFieldSelPos(
-                                    aNewSortData.maKeyState[i].nField ) );
+                (*mpSortKeyItems)[i] -> aLbSort.SelectEntryPos( GetFieldSelPos(
+                                       aNewSortData.maKeyState[i].nField ) );
 
                 (aNewSortData.maKeyState[i].bAscending)
-                    ? aBtnUp[i]->Check()
-                    : aBtnDown[i]->Check();
+                    ? (*mpSortKeyItems)[i] -> aBtnUp.Check()
+                    : (*mpSortKeyItems)[i] -> aBtnDown.Check();
             }
             else
             {
-                aLbSortArr[i]->SelectEntryPos( 0 ); // Select none
-                aBtnUp[i]->Check();
+                (*mpSortKeyItems)[i] -> aLbSort.SelectEntryPos( 0 ); // Select none
+                (*mpSortKeyItems)[i] -> aBtnUp.Check();
             }
         }
 
         // Enable or disable field depending on preceding Listbox selection
-        EnableField( 0 );
+        (*mpSortKeyItems)[0] -> EnableField();
         for ( sal_uInt16 i=1; i<nSortKeyCount; i++ )
-            if ( aLbSortArr[i - 1] -> GetSelectEntryPos() == 0 )
-                DisableField( i );
+            if ( (*mpSortKeyItems)[i - 1] -> aLbSort.GetSelectEntryPos() == 0 )
+                (*mpSortKeyItems)[i] -> DisableField();
             else
-                EnableField( i );
+                (*mpSortKeyItems)[i] -> EnableField();
+
     }
     else
     {
@@ -240,17 +213,18 @@ void ScTabPageSortFields::Reset( const SfxItemSet& /* rArgSet */ )
 
         sal_uInt16  nSort1Pos = nCol - aNewSortData.nCol1+1;
 
-        aLbSortArr[0] -> SelectEntryPos( nSort1Pos );
+        (*mpSortKeyItems)[0] -> aLbSort.SelectEntryPos( nSort1Pos );
         for ( sal_uInt16 i=1; i<nSortKeyCount; i++ )
-            aLbSortArr[i] -> SelectEntryPos( 0 );
+            (*mpSortKeyItems)[i] -> aLbSort.SelectEntryPos( 0 );
 
         for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
-            aBtnUp[i] -> Check();
+            (*mpSortKeyItems)[i] -> aBtnUp.Check();
+
 
-        EnableField ( 0 );
-        EnableField ( 1 );
+        (*mpSortKeyItems)[0] -> EnableField();
+        (*mpSortKeyItems)[1] -> EnableField();
         for ( sal_uInt16 i=2; i<nSortKeyCount; i++ )
-            DisableField( i );
+            (*mpSortKeyItems)[i] -> DisableField();
     }
 
     if ( pDlg )
@@ -268,7 +242,7 @@ sal_Bool ScTabPageSortFields::FillItemSet( SfxItemSet& rArgSet )
 
     for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
     {
-        nSortPos.push_back( aLbSortArr[i] -> GetSelectEntryPos() );
+        nSortPos.push_back( (*mpSortKeyItems)[i] -> aLbSort.GetSelectEntryPos() );
 
         if ( nSortPos[i] == LISTBOX_ENTRY_NOTFOUND ) nSortPos[i] = 0;
     }
@@ -295,7 +269,7 @@ sal_Bool ScTabPageSortFields::FillItemSet( SfxItemSet& rArgSet )
         }
 
         for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
-            aNewSortData.maKeyState[i].bAscending = aBtnUp[i] -> IsChecked();
+            aNewSortData.maKeyState[i].bAscending = (*mpSortKeyItems)[i] -> aBtnUp.IsChecked();
 
         // bHasHeader is in ScTabPageSortOptions::FillItemSet, where it belongs
     }
@@ -322,14 +296,14 @@ void ScTabPageSortFields::ActivatePage()
         {
             std::vector<sal_uInt16> nCurSel;
             for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
-                nCurSel.push_back( aLbSortArr[i] -> GetSelectEntryPos() );
+                nCurSel.push_back( (*mpSortKeyItems)[i] -> aLbSort.GetSelectEntryPos() );
 
             bHasHeader  = pDlg->GetHeaders();
             bSortByRows = pDlg->GetByRows();
             FillFieldLists(0);
 
             for ( sal_uInt16 i=0; i<nSortKeyCount; i++ )
-                aLbSortArr[i] -> SelectEntryPos( nCurSel[i] );
+                (*mpSortKeyItems)[i] -> aLbSort.SelectEntryPos( nCurSel[i] );
         }
     }
 }
@@ -355,32 +329,6 @@ int ScTabPageSortFields::DeactivatePage( SfxItemSet* pSetP )
 
 // -----------------------------------------------------------------------
 
-void ScTabPageSortFields::DisableField( sal_uInt16 nField )
-{
-    if ( nField<nSortKeyCount )
-    {
-        aLbSortArr[nField]   -> Disable();
-        aBtnUp[nField]       -> Disable();
-        aBtnDown[nField]     -> Disable();
-        aFlArr[nField]       -> Disable();
-    }
-}
-
-// -----------------------------------------------------------------------
-
-void ScTabPageSortFields::EnableField( sal_uInt16 nField )
-{
-    if ( nField<nSortKeyCount )
-    {
-        aLbSortArr[nField]   -> Enable();
-        aBtnUp[nField]       -> Enable();
-        aBtnDown[nField]     -> Enable();
-        aFlArr[nField]       -> Enable();
-    }
-}
-
-// -----------------------------------------------------------------------
-
 void ScTabPageSortFields::FillFieldLists( sal_uInt16 nStartField )
 {
     if ( pViewData )
@@ -391,8 +339,8 @@ void ScTabPageSortFields::FillFieldLists( sal_uInt16 nStartField )
         {
             for ( sal_uInt16 i=nStartField; i<nSortKeyCount; i++ )
             {
-                aLbSortArr[i] -> Clear();
-                aLbSortArr[i] -> InsertEntry( aStrUndefined, 0 );
+                (*mpSortKeyItems)[i] -> aLbSort.Clear();
+                (*mpSortKeyItems)[i] -> aLbSort.InsertEntry( aStrUndefined, 0 );
             }
 
             SCCOL   nFirstSortCol   = rSortData.nCol1;
@@ -418,7 +366,7 @@ void ScTabPageSortFields::FillFieldLists( sal_uInt16 nStartField )
                     nFieldArr.push_back( col );
 
                     for ( sal_uInt16 j=nStartField; j<nSortKeyCount; j++ )
-                        aLbSortArr[j] -> InsertEntry( aFieldName, i );
+                        (*mpSortKeyItems)[j] -> aLbSort.InsertEntry( aFieldName, i );
 
                     i++;
                 }
@@ -441,7 +389,7 @@ void ScTabPageSortFields::FillFieldLists( sal_uInt16 nStartField )
                     nFieldArr.push_back( row );
 
                     for ( sal_uInt16 j=nStartField; j<nSortKeyCount; j++ )
-                        aLbSortArr[j] -> InsertEntry( aFieldName, i );
+                        (*mpSortKeyItems)[j] -> aLbSort.InsertEntry( aFieldName, i );
 
                     i++;
                 }
@@ -474,35 +422,65 @@ sal_uInt16 ScTabPageSortFields::GetFieldSelPos( SCCOLROW nField )
 // Handler:
 //---------
 
+// -----------------------------------------------------------------------
+
 IMPL_LINK( ScTabPageSortFields, SelectHdl, ListBox *, pLb )
 {
     String aSelEntry = pLb->GetSelectEntry();
-    sal_uInt16  nPos   = 0;
+    ScSortKeyItems::iterator pIter;
+    ScSortKeyItem* pItem = (*mpSortKeyItems).back();
+    sal_uInt16 nSortKeyIndex = nSortKeyCount;
+
+    // If last listbox is enabled add one item
+    if ( &pItem->aLbSort == pLb )
+        if ( aSelEntry != aStrUndefined )
+        {
+            // Extend local SortParam copy
+            const ScSortKeyState atempKeyState = { false, 0, true };
+            aNewSortData.maKeyState.push_back( atempKeyState );
+
+            // Add Sort Key Item
+            ++nSortKeyCount;
+            mpSortKeyItems = maSortKeyCtrl.AddSortKey( nSortKeyCount );
+            (*mpSortKeyItems)[nSortKeyIndex] -> aLbSort.SetSelectHdl( LINK( this, ScTabPageSortFields, SelectHdl ) );
+
+            FillFieldLists( nSortKeyIndex );
+
+            // Set Status
+            (*mpSortKeyItems)[nSortKeyIndex] -> aBtnUp.Check();
+            (*mpSortKeyItems)[nSortKeyIndex] -> aLbSort.SelectEntryPos( 0 );
+            return 0;
+        }
 
     // Find selected listbox
-    while ( pLb != aLbSortArr[nPos] )
-        ++nPos;
+    for ( pIter = (*mpSortKeyItems).begin(); pIter != (*mpSortKeyItems).end(); ++pIter )
+    {
+        pItem = *pIter;
+        if ( &pItem->aLbSort == pLb ) break;
+    }
 
-    // If not selecting the last Listbox modify the succeeding ones
-    ++nPos;
-    if ( nPos < nSortKeyCount )
+    // If not selecting the last Listbox, modify the succeeding ones
+    ++pIter;
+    if ( std::distance((*mpSortKeyItems).begin(), pIter) < nSortKeyCount )
     {
         if ( aSelEntry == aStrUndefined )
         {
-            for ( sal_uInt16 i=nPos; i<nSortKeyCount; i++ )
+            for ( ; pIter != (*mpSortKeyItems).end(); ++pIter )
             {
-                aLbSortArr[i] -> SelectEntryPos( 0 );
+                pItem = *pIter;
+                (&pItem->aLbSort)->SelectEntryPos( 0 );
 
-                if ( aFlArr[i] -> IsEnabled() )
-                    DisableField( i );
+                if ( (&pItem->aFlSort)-> IsEnabled() )
+                    pItem -> DisableField();
             }
         }
         else
         {
-            if ( !aFlArr[nPos] -> IsEnabled() )
-                EnableField( nPos );
+            pItem = *pIter;
+            if ( !(&pItem->aFlSort)-> IsEnabled() )
+                    pItem -> EnableField();
         }
-    }
+     }
     return 0;
 }
 
diff --git a/sc/source/ui/inc/sortdlg.hrc b/sc/source/ui/inc/sortdlg.hrc
index f583dd3d..d87d42a 100644
--- a/sc/source/ui/inc/sortdlg.hrc
+++ b/sc/source/ui/inc/sortdlg.hrc
@@ -38,18 +38,17 @@
 #define TP_OPTIONS          2
 
 // TP_SORT_FIELDS:
-#define FL_SORT1            1
-#define FL_SORT2            2
-#define FL_SORT3            3
-#define LB_SORT1            4
-#define LB_SORT2            5
-#define LB_SORT3            6
-#define BTN_UP1             7
-#define BTN_UP2             8
-#define BTN_UP3             9
-#define BTN_DOWN1           10
-#define BTN_DOWN2           11
-#define BTN_DOWN3           12
+#define CTRL_MANAGESORTKEY  1
+#define WIN_MANAGESORTKEY   2
+#define SB_SORT             3
+
+// SORT_KEY_FIELDS:
+#define FL_SORT             14
+#define LB_SORT             15
+#define BTN_UP              16
+#define BTN_DOWN            17
+
+
 
 // TP_SORT_OPTIONS:
 #define FL_DIRECTION        1
diff --git a/sc/source/ui/inc/sortkeydlg.hxx b/sc/source/ui/inc/sortkeydlg.hxx
new file mode 100644
index 0000000..cbacbb1
--- /dev/null
+++ b/sc/source/ui/inc/sortkeydlg.hxx
@@ -0,0 +1,110 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * Version: MPL 1.1 / GPLv3+ / LGPLv3+
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License or as specified alternatively below. You may obtain a copy of
+ * the License at http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * Major Contributor(s):
+ *  Copyright (C) 2012 Albert Thuswaldner <albert.thuswald...@gmail.com> (initial developer)
+ *
+ * All Rights Reserved.
+ *
+ * For minor contributions see the git repository.
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 3 or later (the "GPLv3+"), or
+ * the GNU Lesser General Public License Version 3 or later (the "LGPLv3+"),
+ * in which case the provisions of the GPLv3+ or the LGPLv3+ are applicable
+ * instead of those above.
+ */
+
+#ifndef SC_SORTKEYDLG_HXX
+#define SC_SORTKEYDLG_HXX
+
+//#include <vector>
+
+#include "anyrefdg.hxx"
+#include "sortdlg.hrc"
+
+#include <vcl/edit.hxx>
+#include <vcl/fixed.hxx>
+#include <vcl/lstbox.hxx>
+#include <vcl/scrbar.hxx>
+#include <vcl/ctrl.hxx>
+#include <svtools/stdctrl.hxx>
+#include <svx/langbox.hxx>
+
+#define SORTKEY_OFFSET 62L
+
+// =======================================================================
+
+struct ScSortKeyItem
+{
+    FixedLine       aFlSort;
+    ListBox         aLbSort;
+    RadioButton     aBtnUp;
+    RadioButton     aBtnDown;
+
+    ScSortKeyItem ( Window* pParent );
+
+    void DisableField();
+    void EnableField();
+};
+
+typedef std::vector<ScSortKeyItem*> ScSortKeyItems;
+
+// =======================================================================
+
+class ScSortKeyWindow : public Window
+{
+private:
+    FixedLine       aFlSort;
+    ListBox         aLbSort;
+    RadioButton     aBtnUp;
+    RadioButton     aBtnDown;
+
+    sal_Int32       nScrollPos;
+    sal_Int32       nItemNumber;
+    sal_Int32       nItemHeight;
+
+    ScSortKeyItems  mpSortKeyItems;
+
+public:
+
+    ScSortKeyWindow( Window* pParent, const ResId& rResId );
+    ~ScSortKeyWindow();
+
+    ScSortKeyItems* AddSortKey( sal_uInt16 nItem );
+    void DoScroll( sal_Int32 nNewPos );
+};
+
+// =======================================================================
+
+class ScSortKeyCtrl : public Control
+{
+private:
+    ScSortKeyWindow  aSortWin;
+    ScrollBar        aVertScroll;
+
+    sal_Int32        nThumbPos;
+
+    DECL_LINK( ScrollHdl, ScrollBar* );
+
+public:
+    ScSortKeyCtrl( Window* pParent, const ScResId& rResId );
+    ~ScSortKeyCtrl();
+
+    ScSortKeyItems* AddSortKey( sal_uInt16 nItem );
+};
+
+#endif // SC_SORTKEYDLG_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/ui/inc/tpsort.hxx b/sc/source/ui/inc/tpsort.hxx
index 2a447cb..2ba3ae1 100644
--- a/sc/source/ui/inc/tpsort.hxx
+++ b/sc/source/ui/inc/tpsort.hxx
@@ -38,6 +38,7 @@
 #include <svtools/stdctrl.hxx>
 #include <svx/langbox.hxx>
 
+#include "sortkeydlg.hxx"
 
 #include "global.hxx"
 #include "address.hxx"
@@ -76,21 +77,6 @@ protected:
     virtual int         DeactivatePage  ( SfxItemSet* pSet = 0);
 
 private:
-    FixedLine       aFlSort1;
-    ListBox         aLbSort1;
-    RadioButton     aBtnUp1;
-    RadioButton     aBtnDown1;
-
-    FixedLine       aFlSort2;
-    ListBox         aLbSort2;
-    RadioButton     aBtnUp2;
-    RadioButton     aBtnDown2;
-
-    FixedLine       aFlSort3;
-    ListBox         aLbSort3;
-    RadioButton     aBtnUp3;
-    RadioButton     aBtnDown3;
-
     String          aStrUndefined;
     String          aStrColumn;
     String          aStrRow;
@@ -110,16 +96,12 @@ private:
     sal_Bool            bHasHeader;
     sal_Bool            bSortByRows;
 
-    std::vector<ListBox*>      aLbSortArr;
-    std::vector<RadioButton*>  aBtnUp;
-    std::vector<RadioButton*>  aBtnDown;
-    std::vector<FixedLine*>    aFlArr;
+    ScSortKeyCtrl       maSortKeyCtrl;
+    ScSortKeyItems*     mpSortKeyItems;
 
 #ifdef _TPSORT_CXX
 private:
     void    Init            ();
-    void    DisableField    ( sal_uInt16 nField );
-    void    EnableField     ( sal_uInt16 nField );
     void    FillFieldLists  ( sal_uInt16 nStartField );
     sal_uInt16  GetFieldSelPos  ( SCCOLROW nField );
 
diff --git a/sc/source/ui/src/sortdlg.src b/sc/source/ui/src/sortdlg.src
index 466ab7a..87c26f0 100644
--- a/sc/source/ui/src/sortdlg.src
+++ b/sc/source/ui/src/sortdlg.src
@@ -32,101 +32,58 @@ TabPage RID_SCPAGE_SORT_FIELDS
     SVLook = TRUE ;
     HelpId = HID_SCPAGE_SORT_FIELDS ;
     Size = MAP_APPFONT ( 260 , 185 ) ;
-    ListBox LB_SORT1
+    Control CTRL_MANAGESORTKEY
     {
-        HelpID = "sc:ListBox:RID_SCPAGE_SORT_FIELDS:LB_SORT1";
-        Border = TRUE ;
-        Pos = MAP_APPFONT ( 12 , 19 ) ;
-        Size = MAP_APPFONT ( 154 , 90 ) ;
-        TabStop = TRUE ;
-        DropDown = TRUE ;
-    };
-    RadioButton BTN_UP1
-    {
-        HelpID = "sc:RadioButton:RID_SCPAGE_SORT_FIELDS:BTN_UP1";
-        Pos = MAP_APPFONT ( 172 , 14 ) ;
-        Size = MAP_APPFONT ( 79 , 10 ) ;
-        Text [ en-US ] = "~Ascending" ;
-        TabStop = TRUE ;
-    };
-    RadioButton BTN_DOWN1
-    {
-        HelpID = "sc:RadioButton:RID_SCPAGE_SORT_FIELDS:BTN_DOWN1";
-        Pos = MAP_APPFONT ( 172 , 28 ) ;
-        Size = MAP_APPFONT ( 79 , 10 ) ;
-        Text [ en-US ] = "~Descending" ;
-        TabStop = TRUE ;
-    };
-    FixedLine FL_SORT1
-    {
-        Pos = MAP_APPFONT ( 6 , 3 ) ;
-        Size = MAP_APPFONT ( 248 , 8 ) ;
-        Text [ en-US ] = "Sort ~key 1" ;
-    };
-    ListBox LB_SORT2
-    {
-        HelpID = "sc:ListBox:RID_SCPAGE_SORT_FIELDS:LB_SORT2";
-        Border = TRUE ;
-        Pos = MAP_APPFONT ( 12 , 60 ) ;
-        Size = MAP_APPFONT ( 154 , 90 ) ;
-        TabStop = TRUE ;
-        DropDown = TRUE ;
-    };
-    RadioButton BTN_UP2
-    {
-        HelpID = "sc:RadioButton:RID_SCPAGE_SORT_FIELDS:BTN_UP2";
-        Pos = MAP_APPFONT ( 172 , 55 ) ;
-        Size = MAP_APPFONT ( 79 , 10 ) ;
-        Text [ en-US ] = "A~scending" ;
-        TabStop = TRUE ;
-    };
-    RadioButton BTN_DOWN2
-    {
-        HelpID = "sc:RadioButton:RID_SCPAGE_SORT_FIELDS:BTN_DOWN2";
-        Pos = MAP_APPFONT ( 172 , 69 ) ;
-        Size = MAP_APPFONT ( 79 , 10 ) ;
-        Text [ en-US ] = "D~escending" ;
-        TabStop = TRUE ;
-    };
-    FixedLine FL_SORT2
-    {
-        Pos = MAP_APPFONT ( 6 , 44 ) ;
-        Size = MAP_APPFONT ( 248 , 8 ) ;
-        Text [ en-US ] = "Sort ~key 2" ;
-    };
-    ListBox LB_SORT3
-    {
-        HelpID = "sc:ListBox:RID_SCPAGE_SORT_FIELDS:LB_SORT3";
-        Border = TRUE ;
-        Pos = MAP_APPFONT ( 12 , 101 ) ;
-        Size = MAP_APPFONT ( 154 , 90 ) ;
-        TabStop = TRUE ;
-        DropDown = TRUE ;
-    };
-    RadioButton BTN_UP3
-    {
-        HelpID = "sc:RadioButton:RID_SCPAGE_SORT_FIELDS:BTN_UP3";
-        Pos = MAP_APPFONT ( 172 , 96 ) ;
-        Size = MAP_APPFONT ( 79 , 10 ) ;
-        Text [ en-US ] = "As~cending" ;
-        TabStop = TRUE ;
-    };
-    RadioButton BTN_DOWN3
-    {
-        HelpID = "sc:RadioButton:RID_SCPAGE_SORT_FIELDS:BTN_DOWN3";
-        Pos = MAP_APPFONT ( 172 , 110 ) ;
-        Size = MAP_APPFONT ( 79 , 10 ) ;
-        Text [ en-US ] = "Desce~nding" ;
-        TabStop = TRUE ;
-    };
-    FixedLine FL_SORT3
-    {
-        Pos = MAP_APPFONT ( 6 , 85 ) ;
-        Size = MAP_APPFONT ( 248 , 8 ) ;
-        Text [ en-US ] = "Sort ~key 3" ;
+        Pos = MAP_APPFONT( 2, 2 );
+        Size = MAP_APPFONT( 256, 181 );
+        Border = FALSE;
+        DialogControl = TRUE;
+        Window WIN_MANAGESORTKEY
+        {
+            OutputSize = TRUE ;
+            Pos = MAP_APPFONT ( 2 , 2 ) ;
+            Size = MAP_APPFONT ( 240 , 181 ) ;
+            DialogControl = TRUE;
+        };
+        ScrollBar SB_SORT
+        {
+            Pos = MAP_APPFONT ( 246 , 2 ) ;
+            Size = MAP_APPFONT ( 8 , 181 ) ;
+            VScroll = TRUE;
+        };
+
     };
 };
 
+ListBox LB_SORT
+{
+    Border = TRUE ;
+    Pos = MAP_APPFONT ( 12 , 16 ) ;
+    Size = MAP_APPFONT ( 154 , 90 ) ;
+    TabStop = TRUE ;
+    DropDown = TRUE ;
+};
+RadioButton BTN_UP
+{
+    Pos = MAP_APPFONT ( 172 , 11 ) ;
+    Size = MAP_APPFONT ( 79 , 10 ) ;
+    Text [ en-US ] = "~Ascending" ;
+    TabStop = TRUE ;
+};
+RadioButton BTN_DOWN
+{
+    Pos = MAP_APPFONT ( 172 , 25 ) ;
+    Size = MAP_APPFONT ( 79 , 10 ) ;
+    Text [ en-US ] = "~Descending" ;
+    TabStop = TRUE ;
+};
+FixedLine FL_SORT
+{
+    Pos = MAP_APPFONT ( 6 , 0 ) ;
+    Size = MAP_APPFONT ( 240 , 8 ) ;
+    Text [ en-US ] = "Sort ~key " ;
+};
+
 TabPage RID_SCPAGE_SORT_OPTIONS
 {
     Hide = TRUE ;
-- 
1.7.3.4

_______________________________________________
LibreOffice mailing list
LibreOffice@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/libreoffice

Reply via email to