summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDennis Francis <dennisfrancis.in@gmail.com>2016-05-31 23:46:52 +0530
committerCaolán McNamara <caolanm@redhat.com>2016-06-10 13:29:16 +0000
commit760ca821442e3d8c0d36122bb8bc4a9c8078e97c (patch)
tree374e066083758ac2ca873f5d0dc6198722272806
parent49b2548231a4eaf3f1304d15b0bb3f050ac99b49 (diff)
tdf#97340 : Handle autofilter search for dates correctly
Reviewed-on: https://gerrit.libreoffice.org/26005 Reviewed-by: Caolán McNamara <caolanm@redhat.com> Tested-by: Caolán McNamara <caolanm@redhat.com> (cherry picked from commit 848737eb576555f7c01d2159a9cf64d020dc2598) Change-Id: I5c8413d560789a626ea87eb28a89059960177f1f Reviewed-on: https://gerrit.libreoffice.org/26008 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Dennis Francis <dennisfrancis.in@gmail.com> Tested-by: Dennis Francis <dennisfrancis.in@gmail.com> Reviewed-by: Caolán McNamara <caolanm@redhat.com> Tested-by: Caolán McNamara <caolanm@redhat.com>
-rw-r--r--include/svtools/treelistentry.hxx1
-rw-r--r--sc/source/ui/cctrl/checklistmenu.cxx135
-rw-r--r--sc/source/ui/inc/checklistmenu.hxx44
3 files changed, 153 insertions, 27 deletions
diff --git a/include/svtools/treelistentry.hxx b/include/svtools/treelistentry.hxx
index c5c523ce85b6..adbb469e64cd 100644
--- a/include/svtools/treelistentry.hxx
+++ b/include/svtools/treelistentry.hxx
@@ -114,6 +114,7 @@ public:
void SetBackColor( const Color& aColor ) { maBackColor = aColor; }
Color GetBackColor() const { return maBackColor; }
+ SvTreeListEntry* GetParent() const { return pParent; }
};
#endif
diff --git a/sc/source/ui/cctrl/checklistmenu.cxx b/sc/source/ui/cctrl/checklistmenu.cxx
index 8f7a3a9ec771..e5897ec628bc 100644
--- a/sc/source/ui/cctrl/checklistmenu.cxx
+++ b/sc/source/ui/cctrl/checklistmenu.cxx
@@ -845,10 +845,11 @@ ScCheckListMenuWindow::Config::Config() :
{
}
-ScCheckListMenuWindow::Member::Member()
+ScCheckListMember::ScCheckListMember()
: mbVisible(true)
, mbDate(false)
, mbLeaf(false)
+ , meDatePartType(YEAR)
, mpParent(nullptr)
{
}
@@ -1136,7 +1137,7 @@ void ScCheckListMenuWindow::setAllMemberState(bool bSet)
aLabel = maMembers[i].maName;
if (aLabel.isEmpty())
aLabel = ScGlobal::GetRscString(STR_EMPTYDATA);
- maChecks->ShowCheckEntry( aLabel, maMembers[i].mpParent, true, bSet);
+ maChecks->ShowCheckEntry( aLabel, maMembers[i], true, bSet);
}
if (!maConfig.mbAllowEmptySet)
@@ -1223,29 +1224,61 @@ IMPL_LINK_NOARG_TYPED(ScCheckListMenuWindow, EdModifyHdl, Edit&, void)
size_t n = maMembers.size();
size_t nSelCount = 0;
OUString aLabelDisp;
+ bool bSomeDateDeletes = false;
for (size_t i = 0; i < n; ++i)
{
- aLabelDisp = maMembers[i].maName;
+ bool bIsDate = maMembers[i].mbDate;
+ bool bPartialMatch = false;
+ aLabelDisp = maMembers[i].maName;
if ( aLabelDisp.isEmpty() )
aLabelDisp = ScGlobal::GetRscString( STR_EMPTYDATA );
+ if ( !bSearchTextEmpty )
+ {
+ if ( !bIsDate )
+ bPartialMatch = ( aLabelDisp.toAsciiLowerCase().indexOf( aSearchText ) != -1 );
+ else if ( maMembers[i].meDatePartType == ScCheckListMember::DAY ) // Match with both numerical and text version of month
+ bPartialMatch = bPartialMatch || ( OUString( maMembers[i].maRealName + maMembers[i].maDateParts[1] )
+ .toAsciiLowerCase().indexOf( aSearchText ) != -1 );
+ else
+ continue;
+ }
+ else if ( bIsDate && maMembers[i].meDatePartType != ScCheckListMember::DAY )
+ continue;
+
if ( bSearchTextEmpty )
{
- maChecks->ShowCheckEntry( aLabelDisp, maMembers[i].mpParent, true, maMembers[i].mbVisible );
+ SvTreeListEntry* pLeaf = maChecks->ShowCheckEntry( aLabelDisp, maMembers[i], true, maMembers[i].mbVisible );
+ updateMemberParents( pLeaf, i );
if ( maMembers[i].mbVisible )
++nSelCount;
continue;
}
- if ( aLabelDisp.toAsciiLowerCase().indexOf( aSearchText ) != -1 )
+ if ( bPartialMatch )
{
- maChecks->ShowCheckEntry( aLabelDisp, maMembers[i].mpParent );
+ SvTreeListEntry* pLeaf = maChecks->ShowCheckEntry( aLabelDisp, maMembers[i] );
+ updateMemberParents( pLeaf, i );
++nSelCount;
}
else
- maChecks->ShowCheckEntry( aLabelDisp, maMembers[i].mpParent, false, false );
+ {
+ maChecks->ShowCheckEntry( aLabelDisp, maMembers[i], false, false );
+ if( bIsDate )
+ bSomeDateDeletes = true;
+ }
+ }
+
+ if ( bSomeDateDeletes )
+ {
+ for (size_t i = 0; i < n; ++i)
+ {
+ if ( !maMembers[i].mbDate ) continue;
+ if ( maMembers[i].meDatePartType != ScCheckListMember::DAY ) continue;
+ updateMemberParents( nullptr, i );
+ }
}
if ( nSelCount == n )
@@ -1336,6 +1369,42 @@ vcl::Window* ScCheckListMenuWindow::GetPreferredKeyInputWindow()
return maTabStopCtrls[mnCurTabStop];
}
+void ScCheckListMenuWindow::updateMemberParents( SvTreeListEntry* pLeaf, size_t nIdx )
+{
+
+ if ( !maMembers[nIdx].mbDate || maMembers[nIdx].meDatePartType != ScCheckListMember::DAY )
+ return;
+
+ OUString aYearName = maMembers[nIdx].maDateParts[0];
+ OUString aMonthName = maMembers[nIdx].maDateParts[1];
+ auto aItr = maYearMonthMap.find(aYearName + aMonthName);
+
+ if ( pLeaf )
+ {
+ SvTreeListEntry* pMonthEntry = pLeaf->GetParent();
+ SvTreeListEntry* pYearEntry = ( pMonthEntry ) ? pMonthEntry->GetParent() : nullptr;
+
+ maMembers[nIdx].mpParent = pMonthEntry;
+ if ( aItr != maYearMonthMap.end() )
+ {
+ size_t nMonthIdx = aItr->second;
+ maMembers[nMonthIdx].mpParent = pYearEntry;
+ }
+ }
+ else
+ {
+ SvTreeListEntry* pYearEntry = maChecks->FindEntry( nullptr, aYearName );
+ if ( aItr != maYearMonthMap.end() && !pYearEntry )
+ {
+ size_t nMonthIdx = aItr->second;
+ maMembers[nMonthIdx].mpParent = nullptr;
+ maMembers[nIdx].mpParent = nullptr;
+ }
+ else if ( pYearEntry && !maChecks->FindEntry( pYearEntry, aMonthName ) )
+ maMembers[nIdx].mpParent = nullptr;
+ }
+}
+
Reference<XAccessible> ScCheckListMenuWindow::CreateAccessible()
{
if (!mxAccessible.is())
@@ -1392,19 +1461,23 @@ void ScCheckListMenuWindow::addDateMember(const OUString& rsName, double nVal, b
OUString aMonthName = aMonths[nMonth-1].FullName;
OUString aDayName = OUString::number(nDay);
+ if ( aDayName.getLength() == 1 )
+ aDayName = "0" + aDayName;
+
maChecks->SetUpdateMode(false);
SvTreeListEntry* pYearEntry = maChecks->FindEntry(nullptr, aYearName);
if (!pYearEntry)
{
pYearEntry = maChecks->InsertEntry(aYearName, nullptr, true);
- Member aMemYear;
+ ScCheckListMember aMemYear;
aMemYear.maName = aYearName;
aMemYear.maRealName = rsName;
aMemYear.mbDate = true;
aMemYear.mbLeaf = false;
aMemYear.mbVisible = bVisible;
aMemYear.mpParent = nullptr;
+ aMemYear.meDatePartType = ScCheckListMember::YEAR;
maMembers.push_back(aMemYear);
}
@@ -1412,27 +1485,33 @@ void ScCheckListMenuWindow::addDateMember(const OUString& rsName, double nVal, b
if (!pMonthEntry)
{
pMonthEntry = maChecks->InsertEntry(aMonthName, pYearEntry, true);
- Member aMemMonth;
+ ScCheckListMember aMemMonth;
aMemMonth.maName = aMonthName;
aMemMonth.maRealName = rsName;
aMemMonth.mbDate = true;
aMemMonth.mbLeaf = false;
aMemMonth.mbVisible = bVisible;
aMemMonth.mpParent = pYearEntry;
+ aMemMonth.meDatePartType = ScCheckListMember::MONTH;
maMembers.push_back(aMemMonth);
+ maYearMonthMap[aYearName + aMonthName] = maMembers.size() - 1;
}
SvTreeListEntry* pDayEntry = maChecks->FindEntry(pMonthEntry, aDayName);
if (!pDayEntry)
{
maChecks->InsertEntry(aDayName, pMonthEntry);
- Member aMemDay;
+ ScCheckListMember aMemDay;
aMemDay.maName = aDayName;
aMemDay.maRealName = rsName;
+ aMemDay.maDateParts.resize(2);
+ aMemDay.maDateParts[0] = aYearName;
+ aMemDay.maDateParts[1] = aMonthName;
aMemDay.mbDate = true;
aMemDay.mbLeaf = true;
aMemDay.mbVisible = bVisible;
aMemDay.mpParent = pMonthEntry;
+ aMemDay.meDatePartType = ScCheckListMember::DAY;
maMembers.push_back(aMemDay);
}
@@ -1441,7 +1520,7 @@ void ScCheckListMenuWindow::addDateMember(const OUString& rsName, double nVal, b
void ScCheckListMenuWindow::addMember(const OUString& rName, bool bVisible)
{
- Member aMember;
+ ScCheckListMember aMember;
aMember.maName = rName;
aMember.mbDate = false;
aMember.mbLeaf = true;
@@ -1543,13 +1622,31 @@ void ScCheckListBox::CheckEntry( SvTreeListEntry* pParent, bool bCheck )
}
}
-void ScCheckListBox::ShowCheckEntry( const OUString& sName, SvTreeListEntry* pParent, bool bShow, bool bCheck )
+SvTreeListEntry* ScCheckListBox::ShowCheckEntry( const OUString& sName, ScCheckListMember& rMember, bool bShow, bool bCheck )
{
- SvTreeListEntry* pEntry = FindEntry( pParent, sName );
+ SvTreeListEntry* pEntry = nullptr;
+ if ( !rMember.mbDate || ( rMember.mbDate && rMember.mpParent ) )
+ pEntry = FindEntry( rMember.mpParent, sName );
+
if ( bShow )
{
if ( !pEntry )
{
+ if ( rMember.mbDate )
+ {
+ SvTreeListEntry* pYearEntry = FindEntry( nullptr, rMember.maDateParts[0] );
+ if ( !pYearEntry )
+ pYearEntry = InsertEntry( rMember.maDateParts[0], nullptr, true );
+ SvTreeListEntry* pMonthEntry = FindEntry( pYearEntry, rMember.maDateParts[1] );
+ if ( !pMonthEntry )
+ pMonthEntry = InsertEntry( rMember.maDateParts[1], pYearEntry, true );
+ SvTreeListEntry* pDayEntry = FindEntry( pMonthEntry, rMember.maName );
+ if ( !pDayEntry )
+ pDayEntry = InsertEntry( rMember.maName, pMonthEntry );
+
+ return pDayEntry; // Return leaf node
+ }
+
pEntry = InsertEntry(
sName);
@@ -1560,7 +1657,17 @@ void ScCheckListBox::ShowCheckEntry( const OUString& sName, SvTreeListEntry* pPa
CheckEntry( pEntry, bCheck );
}
else if ( pEntry )
- RemoveParentKeepChildren( pEntry );
+ {
+ GetModel()->Remove( pEntry );
+ SvTreeListEntry* pParent = rMember.mpParent;
+ while ( pParent && !pParent->HasChildren() )
+ {
+ SvTreeListEntry* pTmp = pParent;
+ pParent = pTmp->GetParent();
+ GetModel()->Remove( pTmp );
+ }
+ }
+ return nullptr;
}
SvTreeListEntry* ScCheckListBox::CountCheckedEntries( SvTreeListEntry* pParent, sal_uLong& nCount ) const
diff --git a/sc/source/ui/inc/checklistmenu.hxx b/sc/source/ui/inc/checklistmenu.hxx
index c6717110e988..9f7587a1f416 100644
--- a/sc/source/ui/inc/checklistmenu.hxx
+++ b/sc/source/ui/inc/checklistmenu.hxx
@@ -19,6 +19,7 @@
#include <memory>
#include <unordered_map>
+#include <map>
namespace com { namespace sun { namespace star {
@@ -190,6 +191,8 @@ private:
VclPtr<ScMenuFloatingWindow> mpParentMenu;
};
+struct ScCheckListMember;
+
class ScCheckListBox : public SvTreeListBox
{
SvLBoxButtonData* mpCheckButton;
@@ -204,13 +207,35 @@ class ScCheckListBox : public SvTreeListBox
void Init();
void CheckEntry( const OUString& sName, SvTreeListEntry* pParent, bool bCheck = true );
void CheckEntry( SvTreeListEntry* pEntry, bool bCheck = true );
- void ShowCheckEntry( const OUString& sName, SvTreeListEntry* pParent, bool bShow = true, bool bCheck = true );
+ SvTreeListEntry* ShowCheckEntry( const OUString& sName, ScCheckListMember& rMember, bool bShow = true, bool bCheck = true );
bool IsChecked( const 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 ) override;
};
+
+struct ScCheckListMember
+{
+ enum DatePartType
+ {
+ YEAR,
+ MONTH,
+ DAY,
+ };
+
+ OUString maName; // node name
+ OUString maRealName;
+ bool mbVisible;
+ bool mbDate;
+ bool mbLeaf;
+ DatePartType meDatePartType;
+ // To store Year and Month if the member if DAY type
+ std::vector<OUString> maDateParts;
+ ScCheckListMember();
+ SvTreeListEntry* mpParent;
+};
+
/**
* This class implements a popup window for field button, for quick access
* of hide-item list, and possibly more stuff related to field options.
@@ -280,17 +305,6 @@ protected:
virtual void handlePopupEnd() override;
private:
- struct Member
- {
- OUString maName; // node name
- OUString maRealName;
- bool mbVisible;
- bool mbDate;
- bool mbLeaf;
-
- Member();
- SvTreeListEntry* mpParent;
- };
class CancelButton : public ::CancelButton
{
@@ -327,6 +341,7 @@ private:
void setAllMemberState(bool bSet);
void selectCurrentMemberOnly(bool bSet);
void cycleFocus(bool bReverse = false);
+ void updateMemberParents( SvTreeListEntry* pLeaf, size_t nIdx );
DECL_LINK_TYPED( ButtonHdl, Button*, void );
DECL_LINK_TYPED( TriStateHdl, Button*, void );
@@ -347,7 +362,10 @@ private:
std::vector<VclPtr<vcl::Window> > maTabStopCtrls;
size_t mnCurTabStop;
- std::vector<Member> maMembers;
+ std::vector<ScCheckListMember> maMembers;
+ // For Dates
+ std::map<OUString, size_t> maYearMonthMap;
+
std::unique_ptr<ExtendedData> mpExtendedData;
std::unique_ptr<Action> mpOKAction;
std::unique_ptr<Action> mpPopupEndAction;