Kaydet (Commit) f30aa6e5 authored tarafından Dennis Francis's avatar Dennis Francis Kaydeden (comit) Caolán McNamara

tdf#97340 : Handle autofilter search for dates correctly

Change-Id: I5c8413d560789a626ea87eb28a89059960177f1f
Reviewed-on: https://gerrit.libreoffice.org/25850Tested-by: 's avatarJenkins <ci@libreoffice.org>
Reviewed-by: 's avatarCaolán McNamara <caolanm@redhat.com>
Tested-by: 's avatarCaolán McNamara <caolanm@redhat.com>
üst 28fca2e3
...@@ -114,6 +114,7 @@ public: ...@@ -114,6 +114,7 @@ public:
void SetBackColor( const Color& aColor ) { maBackColor = aColor; } void SetBackColor( const Color& aColor ) { maBackColor = aColor; }
const Color& GetBackColor() const { return maBackColor; } const Color& GetBackColor() const { return maBackColor; }
SvTreeListEntry* GetParent() const { return pParent; }
}; };
#endif #endif
......
...@@ -845,10 +845,11 @@ ScCheckListMenuWindow::Config::Config() : ...@@ -845,10 +845,11 @@ ScCheckListMenuWindow::Config::Config() :
{ {
} }
ScCheckListMenuWindow::Member::Member() ScCheckListMember::ScCheckListMember()
: mbVisible(true) : mbVisible(true)
, mbDate(false) , mbDate(false)
, mbLeaf(false) , mbLeaf(false)
, meDatePartType(YEAR)
, mpParent(nullptr) , mpParent(nullptr)
{ {
} }
...@@ -1223,29 +1224,61 @@ IMPL_LINK_NOARG_TYPED(ScCheckListMenuWindow, EdModifyHdl, Edit&, void) ...@@ -1223,29 +1224,61 @@ IMPL_LINK_NOARG_TYPED(ScCheckListMenuWindow, EdModifyHdl, Edit&, void)
size_t n = maMembers.size(); size_t n = maMembers.size();
size_t nSelCount = 0; size_t nSelCount = 0;
OUString aLabelDisp; OUString aLabelDisp;
bool bSomeDateDeletes = false;
for (size_t i = 0; i < n; ++i) 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() ) if ( aLabelDisp.isEmpty() )
aLabelDisp = ScGlobal::GetRscString( STR_EMPTYDATA ); 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 ) 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 ) if ( maMembers[i].mbVisible )
++nSelCount; ++nSelCount;
continue; 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; ++nSelCount;
} }
else 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 ) if ( nSelCount == n )
...@@ -1331,6 +1364,42 @@ void ScCheckListMenuWindow::Paint(vcl::RenderContext& rRenderContext, const Rect ...@@ -1331,6 +1364,42 @@ void ScCheckListMenuWindow::Paint(vcl::RenderContext& rRenderContext, const Rect
rRenderContext.DrawRect(Rectangle(aPos,aSize)); rRenderContext.DrawRect(Rectangle(aPos,aSize));
} }
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() Reference<XAccessible> ScCheckListMenuWindow::CreateAccessible()
{ {
if (!mxAccessible.is()) if (!mxAccessible.is())
...@@ -1387,19 +1456,23 @@ void ScCheckListMenuWindow::addDateMember(const OUString& rsName, double nVal, b ...@@ -1387,19 +1456,23 @@ void ScCheckListMenuWindow::addDateMember(const OUString& rsName, double nVal, b
OUString aMonthName = aMonths[nMonth-1].FullName; OUString aMonthName = aMonths[nMonth-1].FullName;
OUString aDayName = OUString::number(nDay); OUString aDayName = OUString::number(nDay);
if ( aDayName.getLength() == 1 )
aDayName = "0" + aDayName;
maChecks->SetUpdateMode(false); maChecks->SetUpdateMode(false);
SvTreeListEntry* pYearEntry = maChecks->FindEntry(nullptr, aYearName); SvTreeListEntry* pYearEntry = maChecks->FindEntry(nullptr, aYearName);
if (!pYearEntry) if (!pYearEntry)
{ {
pYearEntry = maChecks->InsertEntry(aYearName, nullptr, true); pYearEntry = maChecks->InsertEntry(aYearName, nullptr, true);
Member aMemYear; ScCheckListMember aMemYear;
aMemYear.maName = aYearName; aMemYear.maName = aYearName;
aMemYear.maRealName = rsName; aMemYear.maRealName = rsName;
aMemYear.mbDate = true; aMemYear.mbDate = true;
aMemYear.mbLeaf = false; aMemYear.mbLeaf = false;
aMemYear.mbVisible = bVisible; aMemYear.mbVisible = bVisible;
aMemYear.mpParent = nullptr; aMemYear.mpParent = nullptr;
aMemYear.meDatePartType = ScCheckListMember::YEAR;
maMembers.push_back(aMemYear); maMembers.push_back(aMemYear);
} }
...@@ -1407,27 +1480,33 @@ void ScCheckListMenuWindow::addDateMember(const OUString& rsName, double nVal, b ...@@ -1407,27 +1480,33 @@ void ScCheckListMenuWindow::addDateMember(const OUString& rsName, double nVal, b
if (!pMonthEntry) if (!pMonthEntry)
{ {
pMonthEntry = maChecks->InsertEntry(aMonthName, pYearEntry, true); pMonthEntry = maChecks->InsertEntry(aMonthName, pYearEntry, true);
Member aMemMonth; ScCheckListMember aMemMonth;
aMemMonth.maName = aMonthName; aMemMonth.maName = aMonthName;
aMemMonth.maRealName = rsName; aMemMonth.maRealName = rsName;
aMemMonth.mbDate = true; aMemMonth.mbDate = true;
aMemMonth.mbLeaf = false; aMemMonth.mbLeaf = false;
aMemMonth.mbVisible = bVisible; aMemMonth.mbVisible = bVisible;
aMemMonth.mpParent = pYearEntry; aMemMonth.mpParent = pYearEntry;
aMemMonth.meDatePartType = ScCheckListMember::MONTH;
maMembers.push_back(aMemMonth); maMembers.push_back(aMemMonth);
maYearMonthMap[aYearName + aMonthName] = maMembers.size() - 1;
} }
SvTreeListEntry* pDayEntry = maChecks->FindEntry(pMonthEntry, aDayName); SvTreeListEntry* pDayEntry = maChecks->FindEntry(pMonthEntry, aDayName);
if (!pDayEntry) if (!pDayEntry)
{ {
maChecks->InsertEntry(aDayName, pMonthEntry); maChecks->InsertEntry(aDayName, pMonthEntry);
Member aMemDay; ScCheckListMember aMemDay;
aMemDay.maName = aDayName; aMemDay.maName = aDayName;
aMemDay.maRealName = rsName; aMemDay.maRealName = rsName;
aMemDay.maDateParts.resize(2);
aMemDay.maDateParts[0] = aYearName;
aMemDay.maDateParts[1] = aMonthName;
aMemDay.mbDate = true; aMemDay.mbDate = true;
aMemDay.mbLeaf = true; aMemDay.mbLeaf = true;
aMemDay.mbVisible = bVisible; aMemDay.mbVisible = bVisible;
aMemDay.mpParent = pMonthEntry; aMemDay.mpParent = pMonthEntry;
aMemDay.meDatePartType = ScCheckListMember::DAY;
maMembers.push_back(aMemDay); maMembers.push_back(aMemDay);
} }
...@@ -1436,7 +1515,7 @@ void ScCheckListMenuWindow::addDateMember(const OUString& rsName, double nVal, b ...@@ -1436,7 +1515,7 @@ void ScCheckListMenuWindow::addDateMember(const OUString& rsName, double nVal, b
void ScCheckListMenuWindow::addMember(const OUString& rName, bool bVisible) void ScCheckListMenuWindow::addMember(const OUString& rName, bool bVisible)
{ {
Member aMember; ScCheckListMember aMember;
aMember.maName = rName; aMember.maName = rName;
aMember.mbDate = false; aMember.mbDate = false;
aMember.mbLeaf = true; aMember.mbLeaf = true;
...@@ -1625,13 +1704,31 @@ void ScCheckListBox::CheckEntry( SvTreeListEntry* pParent, bool bCheck ) ...@@ -1625,13 +1704,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 ( bShow )
{ {
if ( !pEntry ) 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( pEntry = InsertEntry(
sName); sName);
...@@ -1642,7 +1739,17 @@ void ScCheckListBox::ShowCheckEntry( const OUString& sName, SvTreeListEntry* pPa ...@@ -1642,7 +1739,17 @@ void ScCheckListBox::ShowCheckEntry( const OUString& sName, SvTreeListEntry* pPa
CheckEntry( pEntry, bCheck ); CheckEntry( pEntry, bCheck );
} }
else if ( pEntry ) 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;
} }
void ScCheckListBox::CountCheckedEntries( SvTreeListEntry* pParent, sal_uLong& nCount ) const void ScCheckListBox::CountCheckedEntries( SvTreeListEntry* pParent, sal_uLong& nCount ) const
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <memory> #include <memory>
#include <unordered_map> #include <unordered_map>
#include <map>
namespace com { namespace sun { namespace star { namespace com { namespace sun { namespace star {
...@@ -218,6 +219,8 @@ public: ...@@ -218,6 +219,8 @@ public:
void clear(); void clear();
}; };
struct ScCheckListMember;
class ScCheckListBox : public SvTreeListBox class ScCheckListBox : public SvTreeListBox
{ {
SvLBoxButtonData* mpCheckButton; SvLBoxButtonData* mpCheckButton;
...@@ -234,7 +237,7 @@ class ScCheckListBox : public SvTreeListBox ...@@ -234,7 +237,7 @@ class ScCheckListBox : public SvTreeListBox
void Init(); void Init();
void CheckEntry( const OUString& sName, SvTreeListEntry* pParent, bool bCheck = true ); void CheckEntry( const OUString& sName, SvTreeListEntry* pParent, bool bCheck = true );
void CheckEntry( SvTreeListEntry* pEntry, 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 ); bool IsChecked( const OUString& sName, SvTreeListEntry* pParent );
SvTreeListEntry* FindEntry( SvTreeListEntry* pParent, const OUString& sNode ); SvTreeListEntry* FindEntry( SvTreeListEntry* pParent, const OUString& sNode );
sal_uInt16 GetCheckedEntryCount() const; sal_uInt16 GetCheckedEntryCount() const;
...@@ -262,6 +265,27 @@ public: ...@@ -262,6 +265,27 @@ public:
void SetTabStopsContainer( ScTabStops* pTabStops ) { mpTabStops = pTabStops; } void SetTabStopsContainer( ScTabStops* pTabStops ) { mpTabStops = pTabStops; }
}; };
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 * This class implements a popup window for field button, for quick access
* of hide-item list, and possibly more stuff related to field options. * of hide-item list, and possibly more stuff related to field options.
...@@ -330,17 +354,6 @@ protected: ...@@ -330,17 +354,6 @@ protected:
virtual void handlePopupEnd() override; virtual void handlePopupEnd() override;
private: private:
struct Member
{
OUString maName; // node name
OUString maRealName;
bool mbVisible;
bool mbDate;
bool mbLeaf;
Member();
SvTreeListEntry* mpParent;
};
class CancelButton : public ::CancelButton class CancelButton : public ::CancelButton
{ {
...@@ -376,6 +389,7 @@ private: ...@@ -376,6 +389,7 @@ private:
void packWindow(); void packWindow();
void setAllMemberState(bool bSet); void setAllMemberState(bool bSet);
void selectCurrentMemberOnly(bool bSet); void selectCurrentMemberOnly(bool bSet);
void updateMemberParents( SvTreeListEntry* pLeaf, size_t nIdx );
DECL_LINK_TYPED( ButtonHdl, Button*, void ); DECL_LINK_TYPED( ButtonHdl, Button*, void );
DECL_LINK_TYPED( TriStateHdl, Button*, void ); DECL_LINK_TYPED( TriStateHdl, Button*, void );
...@@ -393,7 +407,10 @@ private: ...@@ -393,7 +407,10 @@ private:
VclPtr<OKButton> maBtnOk; VclPtr<OKButton> maBtnOk;
VclPtr<CancelButton> maBtnCancel; VclPtr<CancelButton> maBtnCancel;
std::vector<Member> maMembers; std::vector<ScCheckListMember> maMembers;
// For Dates
std::map<OUString, size_t> maYearMonthMap;
std::unique_ptr<ExtendedData> mpExtendedData; std::unique_ptr<ExtendedData> mpExtendedData;
std::unique_ptr<Action> mpOKAction; std::unique_ptr<Action> mpOKAction;
std::unique_ptr<Action> mpPopupEndAction; std::unique_ptr<Action> mpPopupEndAction;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment