[Libreoffice-commits] core.git: 2 commits - sc/inc sc/source

Noel Power noel.power at suse.com
Mon Aug 26 06:43:34 PDT 2013


 sc/inc/typedstrdata.hxx              |    5 
 sc/source/core/data/column3.cxx      |    6 
 sc/source/core/tool/typedstrdata.cxx |   25 +++
 sc/source/ui/cctrl/checklistmenu.cxx |  250 +++++++++++++++++++++++++++++++++--
 sc/source/ui/inc/checklistmenu.hxx   |   32 ++++
 sc/source/ui/view/gridwin.cxx        |    5 
 6 files changed, 305 insertions(+), 18 deletions(-)

New commits:
commit c2920b6d82bc667771edbc183b47d8e6ea1222dd
Author: Noel Power <noel.power at suse.com>
Date:   Mon Aug 26 14:36:33 2013 +0100

    add magic incantation for expander buttons in treelist, tweak some methods
    
    improved changed check behaviour, now check/unchecking a node not only affects
    children but ancestor nodes, cleaned up some of the code, renamed various methods
    
    Change-Id: If9f552ffe4c3610c259513020ee1d298cf1197bc

diff --git a/sc/source/ui/cctrl/checklistmenu.cxx b/sc/source/ui/cctrl/checklistmenu.cxx
index 08aa1b4..455fc3f 100644
--- a/sc/source/ui/cctrl/checklistmenu.cxx
+++ b/sc/source/ui/cctrl/checklistmenu.cxx
@@ -884,7 +884,7 @@ void ScCheckListMenuWindow::CancelButton::Click()
 
 ScCheckListMenuWindow::ScCheckListMenuWindow(Window* pParent, ScDocument* pDoc) :
     ScMenuFloatingWindow(pParent, pDoc),
-    maChecks(this, 0),
+    maChecks(this,  WB_HASBUTTONS | WB_HASLINES | WB_HASLINESATROOT | WB_HASBUTTONSATROOT ),
     maChkToggleAll(this, 0),
     maBtnSelectSingle  (this, 0),
     maBtnUnselectSingle(this, 0),
@@ -1085,7 +1085,7 @@ void ScCheckListMenuWindow::setAllMemberState(bool bSet)
 {
     size_t n = maMembers.size();
     for (size_t i = 0; i < n; ++i)
-        maChecks.CheckEntryPos( maMembers[i].maName, maMembers[i].mpParent, bSet);
+        maChecks.CheckEntry( maMembers[i].maName, maMembers[i].mpParent, bSet);
 
     if (!maConfig.mbAllowEmptySet)
         // We need to have at least one member selected.
@@ -1095,9 +1095,8 @@ void ScCheckListMenuWindow::setAllMemberState(bool bSet)
 void ScCheckListMenuWindow::selectCurrentMemberOnly(bool bSet)
 {
     setAllMemberState(!bSet);
-//    sal_uInt16 nSelected = maChecks.GetSelectEntryPos();
     SvTreeListEntry* pEntry = maChecks.GetCurEntry();
-    maChecks.CheckEntryPos(pEntry, bSet );
+    maChecks.CheckEntry(pEntry, bSet );
 }
 
 void ScCheckListMenuWindow::cycleFocus(bool bReverse)
@@ -1170,7 +1169,7 @@ IMPL_LINK( ScCheckListMenuWindow, CheckHdl, SvTreeListBox*, pChecks )
         return 0;
     SvTreeListEntry* pEntry = pChecks->GetHdlEntry();
     if ( pEntry )
-        maChecks.CheckEntryPos( pEntry,  ( pChecks->GetCheckButtonState( pEntry ) == SV_BUTTON_CHECKED ) );
+        maChecks.CheckEntry( pEntry,  ( pChecks->GetCheckButtonState( pEntry ) == SV_BUTTON_CHECKED ) );
     size_t nNumChecked = maChecks.GetCheckedEntryCount();
     if (nNumChecked == maMembers.size())
         // all members visible
@@ -1338,6 +1337,18 @@ void ScCheckListMenuWindow::addMember(const OUString& rName, bool bVisible)
     maMembers.push_back(aMember);
 }
 
+ScCheckListBox::ScCheckListBox( Window* pParent, WinBits nWinStyle )
+   :  SvTreeListBox( pParent, nWinStyle ), mpCheckButton( NULL )
+{
+    Init();
+}
+
+ScCheckListBox::ScCheckListBox( Window* pParent, const ResId& rResId )
+   :  SvTreeListBox( pParent, rResId ), mpCheckButton( NULL )
+{
+    Init();
+}
+
 SvTreeListEntry* ScCheckListBox::FindEntry( SvTreeListEntry* pParent, const OUString& sNode )
 {
     sal_uInt16 nRootPos = 0;
@@ -1367,19 +1378,16 @@ sal_Bool ScCheckListBox::IsChecked( OUString& sName, SvTreeListEntry* pParent )
     return sal_False;
 }
 
-void ScCheckListBox::CheckEntryPos( OUString& sName, SvTreeListEntry* pParent, sal_Bool bCheck )
+void ScCheckListBox::CheckEntry( OUString& sName, SvTreeListEntry* pParent, sal_Bool bCheck )
 {
     SvTreeListEntry* pEntry = FindEntry( pParent, sName );
     if ( pEntry )
-        CheckEntryPos(  pEntry, bCheck );
+        CheckEntry(  pEntry, bCheck );
 }
 
-void ScCheckListBox::CheckEntryPos( SvTreeListEntry* pParent, sal_Bool bCheck )
+// Recursively check all children of pParent
+void ScCheckListBox::CheckAllChildren( SvTreeListEntry* pParent, sal_Bool bCheck )
 {
-    // currently pParent ( and *all* children ) are checked with state of bCheck
-    // *BUT* if this is not a Root node then bCheck here should also influence the
-    // ancestor hierarchy ( e.g. a child node checked or uncheck MAY need to check/uncheck
-    // the parent/grandparent node )
     if ( pParent )
     {
         SetCheckButtonState(
@@ -1389,11 +1397,45 @@ void ScCheckListBox::CheckEntryPos( SvTreeListEntry* pParent, sal_Bool bCheck )
     SvTreeListEntry* pEntry = pParent ? FirstChild( pParent ) : First();
     while ( pEntry )
     {
-        CheckEntryPos( pEntry, bCheck );
+        CheckAllChildren( pEntry, bCheck );
         pEntry = NextSibling( pEntry );
     }
 }
 
+void ScCheckListBox::CheckEntry( SvTreeListEntry* pParent, sal_Bool bCheck )
+{
+    // recursively check all items below pParent
+    CheckAllChildren( pParent, bCheck );
+    // checking pParent can affect ancestors, e.g. if ancestor is unchecked and pParent is
+    // now checked then the ancestor needs to be checked also
+    SvTreeListEntry* pAncestor = GetParent(pParent);
+    if ( pAncestor )
+    {
+        while ( pAncestor )
+        {
+            // if any first level children checked then ancestor
+            // needs to be checked, similarly if no first level children
+            // checked then ancestor needs to be unchecked
+            SvTreeListEntry* pChild = FirstChild( pAncestor );
+            bool bChildChecked = false;
+
+            while ( pChild )
+            {
+                if ( GetCheckButtonState( pChild ) == SV_BUTTON_CHECKED )
+                {
+                    bChildChecked = true;
+                    break;
+                }
+                pChild = NextSibling( pChild );
+            }
+            SetCheckButtonState(
+                pAncestor, bChildChecked ? SvButtonState( SV_BUTTON_CHECKED ) :
+                                           SvButtonState( SV_BUTTON_UNCHECKED ) );
+            pAncestor = GetParent(pAncestor);
+        }
+    }
+}
+
 SvTreeListEntry* ScCheckListBox::CountCheckedEntries( SvTreeListEntry* pParent, sal_uLong& nCount ) const
 {
     if ( pParent && GetCheckButtonState( pParent ) == SV_BUTTON_CHECKED  )
@@ -1439,7 +1481,7 @@ void ScCheckListBox::KeyInput( const KeyEvent& rKEvt )
         if ( pEntry )
         {
             sal_Bool bCheck = ( GetCheckButtonState( pEntry ) == SV_BUTTON_CHECKED );
-            CheckEntryPos( pEntry, !bCheck );
+            CheckEntry( pEntry, !bCheck );
             if ( bCheck != ( GetCheckButtonState( pEntry ) == SV_BUTTON_CHECKED ) )
                 CheckButtonHdl();
         }
@@ -1460,14 +1502,12 @@ void ScCheckListMenuWindow::initMembers()
             maChecks.InsertEntry(maMembers[i].maName, NULL, sal_False, LISTBOX_APPEND, NULL,
                 SvLBoxButtonKind_enabledCheckbox );
         }
-        // Expand all nodes of dates
-        // Needs better behaviour, what gets expanded how much etc. ( depending
-        // on the tree contents )
-        else if ( maMembers[ i ].mpParent == NULL )
-        {
-            maChecks.ExpandChildren( maChecks.FindEntry( NULL, maMembers[ i ].maName ) );
-        }
-        maChecks.CheckEntryPos( maMembers[i].maName, maMembers[i].mpParent, maMembers[i].mbVisible);
+
+        maChecks.CheckEntry( maMembers[i].maName, maMembers[i].mpParent, maMembers[i].mbVisible);
+        // Expand first node of checked dates
+        if ( maMembers[ i ].mpParent == NULL && maChecks.IsChecked( maMembers[i].maName,  maMembers[i].mpParent ) )
+            maChecks.Expand( maChecks.FindEntry( NULL, maMembers[ i ].maName ) );
+
         if (maMembers[i].mbVisible)
             ++nVisMemCount;
     }
diff --git a/sc/source/ui/inc/checklistmenu.hxx b/sc/source/ui/inc/checklistmenu.hxx
index ba8166b..694d693 100644
--- a/sc/source/ui/inc/checklistmenu.hxx
+++ b/sc/source/ui/inc/checklistmenu.hxx
@@ -191,13 +191,16 @@ class ScCheckListBox : public SvTreeListBox
 {
     SvLBoxButtonData*   mpCheckButton;
     SvTreeListEntry* CountCheckedEntries( SvTreeListEntry* pParent, sal_uLong& nCount ) const;
+    void            CheckAllChildren( SvTreeListEntry* pEntry, sal_Bool bCheck = sal_True );
+
     public:
-    ScCheckListBox( Window* pParent, WinBits nWinStyle = 0 ) : SvTreeListBox( pParent, nWinStyle ) { Init(); }
-    ScCheckListBox( Window* pParent, const ResId& rResId ) : SvTreeListBox( pParent, rResId ) { Init(); }
+
+    ScCheckListBox( Window* pParent, WinBits nWinStyle = 0 );
+    ScCheckListBox( Window* pParent, const ResId& rResId );
     ~ScCheckListBox() { delete mpCheckButton; }
     void Init();
-    void            CheckEntryPos       ( OUString& sName, SvTreeListEntry* pParent, sal_Bool bCheck = sal_True );
-    void            CheckEntryPos       ( SvTreeListEntry* pEntry, sal_Bool bCheck = sal_True );
+    void            CheckEntry( OUString& sName, SvTreeListEntry* pParent, sal_Bool bCheck = sal_True );
+    void            CheckEntry( SvTreeListEntry* pEntry, sal_Bool bCheck = sal_True );
     sal_Bool        IsChecked( OUString& sName, SvTreeListEntry* pParent );
     SvTreeListEntry* FindEntry( SvTreeListEntry* pParent, const OUString& sNode );
     sal_uInt16 GetCheckedEntryCount() const;
commit e5755f4022c1e99514a236a97a9a62552dd8e9fe
Author: Noel Power <noel.power at suse.com>
Date:   Fri Aug 23 15:56:46 2013 +0100

    treelist for autofilter ( nested nodes for dates ) ( using SvxTreeListBox )
    
    Attempt at trying to get more interopable behavior, imho the way dates are
    presented in the autofilter of the "other" well known spreadsheet application
    is very nice and intuitive. This attempt here is lacking in that
    
    a) for some reason I am not getting the node icons ( and subsequently can't sing
    le click anything to expand the nodes ) Only double clicking works to expand
    b) the 'check' behaviour is not quite right, e.g. as simple example is if all
    nodes of a particular date are unset then clicking the leaf node ( e.g. day )
    wont set the ancestor nodes.
    
    Change-Id: Iaa89cac21fb18074ff64a984f099a35851c2fe3c

diff --git a/sc/inc/typedstrdata.hxx b/sc/inc/typedstrdata.hxx
index 346978b..7d8cf44 100644
--- a/sc/inc/typedstrdata.hxx
+++ b/sc/inc/typedstrdata.hxx
@@ -27,13 +27,15 @@ public:
     };
 
     ScTypedStrData( const OUString& rStr, double nVal = 0.0,
-                    StringType eType = Standard );
+                    StringType eType = Standard, bool bDate = false );
 
     ScTypedStrData( const ScTypedStrData& rCpy );
 
     bool IsStrData() const;
+    bool IsDate() const;
     SC_DLLPUBLIC const OUString& GetString() const;
     StringType GetStringType() const;
+    double GetValue() const { return mfValue; }
 
     struct LessCaseSensitive : std::binary_function<ScTypedStrData, ScTypedStrData, bool>
     {
@@ -62,6 +64,7 @@ private:
     OUString maStrValue;
     double mfValue;
     StringType meStrType;
+    bool   mbIsDate;
 };
 
 class FindTypedStrData : std::unary_function<ScTypedStrData, bool>
diff --git a/sc/source/core/data/column3.cxx b/sc/source/core/data/column3.cxx
index b452b68..ce2d81f 100644
--- a/sc/source/core/data/column3.cxx
+++ b/sc/source/core/data/column3.cxx
@@ -1795,15 +1795,17 @@ class FilterEntriesHandler
         }
 
         short nType = pFormatter->GetType(nFormat);
+        bool bDate = false;
         if ((nType & NUMBERFORMAT_DATE) && !(nType & NUMBERFORMAT_TIME))
         {
             // special case for date values.  Disregard the time
             // element if the number format is of date type.
             fVal = rtl::math::approxFloor(fVal);
             mbHasDates = true;
+            bDate = true;
         }
-
-        mrStrings.push_back(ScTypedStrData(aStr, fVal, ScTypedStrData::Value));
+        // maybe extend ScTypedStrData enum is also an option here
+        mrStrings.push_back(ScTypedStrData(aStr, fVal, ScTypedStrData::Value,bDate));
     }
 
 public:
diff --git a/sc/source/core/tool/typedstrdata.cxx b/sc/source/core/tool/typedstrdata.cxx
index 57d7358..2ffd773 100644
--- a/sc/source/core/tool/typedstrdata.cxx
+++ b/sc/source/core/tool/typedstrdata.cxx
@@ -20,6 +20,9 @@ bool ScTypedStrData::LessCaseSensitive::operator() (const ScTypedStrData& left,
     if (left.meStrType == Value)
         return left.mfValue < right.mfValue;
 
+    if (left.mbIsDate != right.mbIsDate)
+        return left.mbIsDate < right.mbIsDate;
+
     return ScGlobal::GetCaseCollator()->compareString(
         left.maStrValue, right.maStrValue) < 0;
 }
@@ -32,6 +35,9 @@ bool ScTypedStrData::LessCaseInsensitive::operator() (const ScTypedStrData& left
     if (left.meStrType == Value)
         return left.mfValue < right.mfValue;
 
+    if (left.mbIsDate != right.mbIsDate)
+        return left.mbIsDate < right.mbIsDate;
+
     return ScGlobal::GetCollator()->compareString(
         left.maStrValue, right.maStrValue) < 0;
 }
@@ -44,6 +50,9 @@ bool ScTypedStrData::EqualCaseSensitive::operator() (const ScTypedStrData& left,
     if (left.meStrType == Value && left.mfValue != right.mfValue)
         return false;
 
+    if (left.mbIsDate != right.mbIsDate )
+        return false;
+
     return ScGlobal::GetCaseCollator()->compareString(
         left.maStrValue, right.maStrValue) == 0;
 }
@@ -56,6 +65,9 @@ bool ScTypedStrData::EqualCaseInsensitive::operator() (const ScTypedStrData& lef
     if (left.meStrType == Value && left.mfValue != right.mfValue)
         return false;
 
+    if (left.mbIsDate != right.mbIsDate )
+        return false;
+
     return ScGlobal::GetCollator()->compareString(
         left.maStrValue, right.maStrValue) == 0;
 }
@@ -75,21 +87,28 @@ bool ScTypedStrData::operator< (const ScTypedStrData& r) const
 }
 
 ScTypedStrData::ScTypedStrData(
-    const OUString& rStr, double nVal, StringType nType ) :
+    const OUString& rStr, double nVal, StringType nType, bool bDate ) :
     maStrValue(rStr),
     mfValue(nVal),
-    meStrType(nType) {}
+    meStrType(nType),
+    mbIsDate( bDate ) {}
 
 ScTypedStrData::ScTypedStrData( const ScTypedStrData& rCpy ) :
     maStrValue(rCpy.maStrValue),
     mfValue(rCpy.mfValue),
-    meStrType(rCpy.meStrType) {}
+    meStrType(rCpy.meStrType),
+    mbIsDate( rCpy.mbIsDate ) {}
 
 bool ScTypedStrData::IsStrData() const
 {
     return meStrType != Value;
 }
 
+bool ScTypedStrData::IsDate() const
+{
+    return mbIsDate;
+}
+
 const OUString& ScTypedStrData::GetString() const
 {
     return maStrValue;
diff --git a/sc/source/ui/cctrl/checklistmenu.cxx b/sc/source/ui/cctrl/checklistmenu.cxx
index e32c03d..08aa1b4 100644
--- a/sc/source/ui/cctrl/checklistmenu.cxx
+++ b/sc/source/ui/cctrl/checklistmenu.cxx
@@ -29,6 +29,8 @@
 
 #include <com/sun/star/accessibility/XAccessible.hpp>
 #include <com/sun/star/accessibility/XAccessibleContext.hpp>
+#include "svtools/fmtfield.hxx"
+#include "document.hxx"
 
 using ::com::sun::star::uno::Reference;
 using ::com::sun::star::accessibility::XAccessible;
@@ -850,6 +852,11 @@ void ScMenuFloatingWindow::terminateAllPopupMenus()
         mpParentMenu->terminateAllPopupMenus();
 }
 
+ScDocument* ScMenuFloatingWindow::getDoc()
+{
+    return mpDoc;
+}
+
 // ============================================================================
 
 ScCheckListMenuWindow::Config::Config() :
@@ -1078,7 +1085,7 @@ void ScCheckListMenuWindow::setAllMemberState(bool bSet)
 {
     size_t n = maMembers.size();
     for (size_t i = 0; i < n; ++i)
-        maChecks.CheckEntryPos(static_cast<sal_uInt16>(i), bSet);
+        maChecks.CheckEntryPos( maMembers[i].maName, maMembers[i].mpParent, bSet);
 
     if (!maConfig.mbAllowEmptySet)
         // We need to have at least one member selected.
@@ -1088,8 +1095,9 @@ void ScCheckListMenuWindow::setAllMemberState(bool bSet)
 void ScCheckListMenuWindow::selectCurrentMemberOnly(bool bSet)
 {
     setAllMemberState(!bSet);
-    sal_uInt16 nSelected = maChecks.GetSelectEntryPos();
-    maChecks.CheckEntryPos(nSelected, bSet);
+//    sal_uInt16 nSelected = maChecks.GetSelectEntryPos();
+    SvTreeListEntry* pEntry = maChecks.GetCurEntry();
+    maChecks.CheckEntryPos(pEntry, bSet );
 }
 
 void ScCheckListMenuWindow::cycleFocus(bool bReverse)
@@ -1160,7 +1168,9 @@ IMPL_LINK( ScCheckListMenuWindow, CheckHdl, SvTreeListBox*, pChecks )
 {
     if (pChecks != &maChecks)
         return 0;
-
+    SvTreeListEntry* pEntry = pChecks->GetHdlEntry();
+    if ( pEntry )
+        maChecks.CheckEntryPos( pEntry,  ( pChecks->GetCheckButtonState( pEntry ) == SV_BUTTON_CHECKED ) );
     size_t nNumChecked = maChecks.GetCheckedEntryCount();
     if (nNumChecked == maMembers.size())
         // all members visible
@@ -1267,14 +1277,177 @@ void ScCheckListMenuWindow::setMemberSize(size_t n)
     maMembers.reserve(n);
 }
 
+void ScCheckListMenuWindow::addDateMember(const OUString& rsName, double nVal, bool bVisible)
+{
+    ScDocument* pDoc = getDoc();
+    if ( pDoc )
+    {
+        SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
+        OUString rsDate;
+        if ( pFormatter )
+        {
+            OUString sFormat("YYYY/MMMM/DD");
+            Color* pColor = NULL;
+            pFormatter->GetPreviewString(sFormat,
+                nVal,
+                rsDate,
+                &pColor,
+                ScGlobal::eLnge );
+        }
+        maChecks.SetUpdateMode(false);
+        sal_Int32 nIndex = 0;
+        std::vector< OUString > vParts;
+        OUString sParent;
+        SvTreeListEntry* pParent = NULL;
+        int count = 0;
+        do
+        {
+            OUString sPart = rsDate.getToken( 0, '/', nIndex );
+            bool bLeaf = ( ++count == 3 );
+            SvTreeListEntry* pChild = maChecks.FindEntry( pParent, sPart );
+            if ( !pChild )
+            {
+                if ( bLeaf )
+                    pChild = maChecks.SvTreeListBox::InsertEntry( sPart, pParent, sal_False, LISTBOX_APPEND, NULL, SvLBoxButtonKind_enabledCheckbox );
+                else
+                    pChild = maChecks.SvTreeListBox::InsertEntry( sPart, pParent, sal_True, LISTBOX_APPEND, NULL, SvLBoxButtonKind_enabledCheckbox );
+                Member aMember;
+                aMember.maName = sPart;
+                aMember.maRealName = rsName;
+                aMember.mbDate = true;
+                aMember.mbLeaf = bLeaf;
+                aMember.mbVisible = bVisible;
+                aMember.mpParent = pParent;
+                maMembers.push_back(aMember);
+            }
+            sParent = sPart;
+            pParent = pChild;
+        } while ( nIndex >= 0 );
+        maChecks.SetUpdateMode(true);
+    }
+}
+
 void ScCheckListMenuWindow::addMember(const OUString& rName, bool bVisible)
 {
     Member aMember;
     aMember.maName = rName;
+    aMember.mbDate = false;
+    aMember.mbLeaf = true;
     aMember.mbVisible = bVisible;
+    aMember.mpParent = NULL;
     maMembers.push_back(aMember);
 }
 
+SvTreeListEntry* ScCheckListBox::FindEntry( SvTreeListEntry* pParent, const OUString& sNode )
+{
+    sal_uInt16 nRootPos = 0;
+    SvTreeListEntry* pEntry = pParent ? FirstChild( pParent ) : GetEntry( nRootPos );
+    while ( pEntry )
+    {
+        if (  sNode.equals(GetEntryText( pEntry )) )
+            return pEntry;
+
+        pEntry = pParent ? NextSibling( pEntry ) : GetEntry( ++nRootPos );
+    }
+    return NULL;
+}
+
+void ScCheckListBox::Init()
+{
+    mpCheckButton = new SvLBoxButtonData( this );
+    EnableCheckButton( mpCheckButton );
+    SetNodeDefaultImages();
+}
+
+sal_Bool ScCheckListBox::IsChecked( OUString& sName, SvTreeListEntry* pParent )
+{
+    SvTreeListEntry* pEntry = FindEntry( pParent, sName );
+    if ( pEntry && GetCheckButtonState( pEntry ) == SV_BUTTON_CHECKED)
+        return sal_True;
+    return sal_False;
+}
+
+void ScCheckListBox::CheckEntryPos( OUString& sName, SvTreeListEntry* pParent, sal_Bool bCheck )
+{
+    SvTreeListEntry* pEntry = FindEntry( pParent, sName );
+    if ( pEntry )
+        CheckEntryPos(  pEntry, bCheck );
+}
+
+void ScCheckListBox::CheckEntryPos( SvTreeListEntry* pParent, sal_Bool bCheck )
+{
+    // currently pParent ( and *all* children ) are checked with state of bCheck
+    // *BUT* if this is not a Root node then bCheck here should also influence the
+    // ancestor hierarchy ( e.g. a child node checked or uncheck MAY need to check/uncheck
+    // the parent/grandparent node )
+    if ( pParent )
+    {
+        SetCheckButtonState(
+            pParent, bCheck ? SvButtonState( SV_BUTTON_CHECKED ) :
+                                           SvButtonState( SV_BUTTON_UNCHECKED ) );
+    }
+    SvTreeListEntry* pEntry = pParent ? FirstChild( pParent ) : First();
+    while ( pEntry )
+    {
+        CheckEntryPos( pEntry, bCheck );
+        pEntry = NextSibling( pEntry );
+    }
+}
+
+SvTreeListEntry* ScCheckListBox::CountCheckedEntries( SvTreeListEntry* pParent, sal_uLong& nCount ) const
+{
+    if ( pParent && GetCheckButtonState( pParent ) == SV_BUTTON_CHECKED  )
+        nCount++;
+    // Iterate over the children
+    SvTreeListEntry* pEntry = pParent ? FirstChild( pParent ) : First();
+    while ( pEntry )
+    {
+        CountCheckedEntries( pEntry, nCount );
+        pEntry = NextSibling( pEntry );
+    }
+    return NULL;
+}
+
+sal_uInt16 ScCheckListBox::GetCheckedEntryCount() const
+{
+    sal_uLong nCount = 0;
+    CountCheckedEntries( NULL,  nCount );
+    return nCount;
+}
+
+void ScCheckListBox::ExpandChildren( SvTreeListEntry* pParent )
+{
+    if ( pParent )
+        Expand( pParent );
+    // Iterate over the children
+    SvTreeListEntry* pEntry = pParent ? FirstChild( pParent ) : First();
+    while ( pEntry )
+    {
+        ExpandChildren( pEntry );
+        pEntry = NextSibling( pEntry );
+    }
+}
+
+void ScCheckListBox::KeyInput( const KeyEvent& rKEvt )
+{
+    const KeyCode& rKey = rKEvt.GetKeyCode();
+
+    if ( rKey.GetCode() == KEY_RETURN || rKey.GetCode() == KEY_SPACE )
+    {
+        SvTreeListEntry* pEntry = GetCurEntry();
+
+        if ( pEntry )
+        {
+            sal_Bool bCheck = ( GetCheckButtonState( pEntry ) == SV_BUTTON_CHECKED );
+            CheckEntryPos( pEntry, !bCheck );
+            if ( bCheck != ( GetCheckButtonState( pEntry ) == SV_BUTTON_CHECKED ) )
+                CheckButtonHdl();
+        }
+    }
+    else if ( GetEntryCount() )
+        SvTreeListBox::KeyInput( rKEvt );
+}
+
 void ScCheckListMenuWindow::initMembers()
 {
     size_t n = maMembers.size();
@@ -1282,8 +1455,19 @@ void ScCheckListMenuWindow::initMembers()
     maChecks.SetUpdateMode(false);
     for (size_t i = 0; i < n; ++i)
     {
-        maChecks.InsertEntry(maMembers[i].maName);
-        maChecks.CheckEntryPos(static_cast< sal_uInt16 >( i ), maMembers[i].mbVisible);
+        if ( !maMembers[ i ].mbDate )
+        {
+            maChecks.InsertEntry(maMembers[i].maName, NULL, sal_False, LISTBOX_APPEND, NULL,
+                SvLBoxButtonKind_enabledCheckbox );
+        }
+        // Expand all nodes of dates
+        // Needs better behaviour, what gets expanded how much etc. ( depending
+        // on the tree contents )
+        else if ( maMembers[ i ].mpParent == NULL )
+        {
+            maChecks.ExpandChildren( maChecks.FindEntry( NULL, maMembers[ i ].maName ) );
+        }
+        maChecks.CheckEntryPos( maMembers[i].maName, maMembers[i].mpParent, maMembers[i].mbVisible);
         if (maMembers[i].mbVisible)
             ++nVisMemCount;
     }
@@ -1323,8 +1507,16 @@ void ScCheckListMenuWindow::getResult(ResultType& rResult)
     size_t n = maMembers.size();
     for (size_t i = 0; i < n; ++i)
     {
-        bool bState = maChecks.IsChecked(static_cast< sal_uInt16 >( i ));
-        aResult.insert(ResultType::value_type(maMembers[i].maName, bState));
+        if ( maMembers[i].mbLeaf )
+        {
+            bool bState =  maChecks.IsChecked( maMembers[i].maName,  maMembers[i].mpParent );
+            OUString sName;
+            if ( maMembers[i].mbDate )
+                sName = maMembers[i].maRealName;
+            else
+                sName = maMembers[i].maName;
+            aResult.insert(ResultType::value_type(sName, bState));
+        }
     }
     rResult.swap(aResult);
 }
diff --git a/sc/source/ui/inc/checklistmenu.hxx b/sc/source/ui/inc/checklistmenu.hxx
index 305026d..ba8166b 100644
--- a/sc/source/ui/inc/checklistmenu.hxx
+++ b/sc/source/ui/inc/checklistmenu.hxx
@@ -186,6 +186,24 @@ private:
     ScMenuFloatingWindow* mpParentMenu;
 };
 
+
+class ScCheckListBox : public SvTreeListBox
+{
+    SvLBoxButtonData*   mpCheckButton;
+    SvTreeListEntry* CountCheckedEntries( SvTreeListEntry* pParent, sal_uLong& nCount ) const;
+    public:
+    ScCheckListBox( Window* pParent, WinBits nWinStyle = 0 ) : SvTreeListBox( pParent, nWinStyle ) { Init(); }
+    ScCheckListBox( Window* pParent, const ResId& rResId ) : SvTreeListBox( pParent, rResId ) { Init(); }
+    ~ScCheckListBox() { delete mpCheckButton; }
+    void Init();
+    void            CheckEntryPos       ( OUString& sName, SvTreeListEntry* pParent, sal_Bool bCheck = sal_True );
+    void            CheckEntryPos       ( SvTreeListEntry* pEntry, sal_Bool bCheck = sal_True );
+    sal_Bool        IsChecked( OUString& sName, SvTreeListEntry* pParent );
+    SvTreeListEntry* FindEntry( SvTreeListEntry* pParent, const OUString& sNode );
+    sal_uInt16 GetCheckedEntryCount() const;
+    void         ExpandChildren( SvTreeListEntry* pParent );
+    virtual void KeyInput( const KeyEvent& rKEvt );
+};
 /**
  * This class implements a popup window for field button, for quick access
  * of hide-item list, and possibly more stuff related to field options.
@@ -225,6 +243,7 @@ public:
     virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > CreateAccessible();
 
     void setMemberSize(size_t n);
+    void addDateMember(const OUString& rName, double nVal, bool bVisible);
     void addMember(const OUString& rName, bool bVisible);
     void initMembers();
     void setConfig(const Config& rConfig);
@@ -255,10 +274,14 @@ protected:
 private:
     struct Member
     {
-        OUString maName;
+        OUString maName; // node name
+        OUString maRealName;
         bool            mbVisible;
+        bool            mbDate;
+        bool            mbLeaf;
 
         Member();
+        SvTreeListEntry* mpParent;
     };
 
     class CancelButton : public ::CancelButton
@@ -299,7 +322,9 @@ private:
     DECL_LINK( CheckHdl, SvTreeListBox* );
 
 private:
-    SvxCheckListBox maChecks;
+    SvTreeListEntry* findEntry(  SvTreeListEntry* pParent, const OUString& rText );
+
+    ScCheckListBox maChecks;
 
     TriStateBox     maChkToggleAll;
     ImageButton     maBtnSelectSingle;
diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx
index 2b4e657..dc13e38 100644
--- a/sc/source/ui/view/gridwin.cxx
+++ b/sc/source/ui/view/gridwin.cxx
@@ -706,7 +706,10 @@ void ScGridWindow::LaunchAutoFilterMenu(SCCOL nCol, SCROW nRow)
         bool bSelected = true;
         if (!aSelected.empty())
             bSelected = aSelected.count(aVal) > 0;
-        mpAutoFilterPopup->addMember(aVal, bSelected);
+        if ( it->IsDate() )
+            mpAutoFilterPopup->addDateMember( aVal, it->GetValue(), bSelected );
+        else
+            mpAutoFilterPopup->addMember(aVal, bSelected);
     }
     mpAutoFilterPopup->initMembers();
 


More information about the Libreoffice-commits mailing list