21 #include <globstr.hrc>
30 #include <rtl/math.hxx>
33 #include <LibreOfficeKit/LibreOfficeKitEnums.h>
38 #include <document.hxx>
41 using ::com::sun::star::uno::Reference;
94 if (!rMenu.mbEnabled || !rMenu.mxSubMenuWin)
134 mxMenu->append_text(rText);
136 mxMenu->set_image(
mxMenu->n_children() - 1, css::uno::Reference<css::graphic::XGraphic>(), 1);
150 std::vector<int> aWidths;
151 aWidths.push_back(rSize.Width() - (
mxMenu->get_text_height() * 3) / 4 - 6);
152 mxMenu->set_column_fixed_widths(aWidths);
157 int nWidth = (
mxMenu->get_text_height() * 3) / 4;
161 SymbolType::SPIN_RIGHT,
mxDropDown->GetTextColor(),
162 DrawSymbolFlags::NONE);
173 vcl::ILibreOfficeKitNotifier* pNotifier =
nullptr;
182 mxMenu->append_text(rText);
326 mxMenu->set_size_request(-1,
mxMenu->get_preferred_size().Height() + 2);
370 for (
size_t i = 0;
i < n; ++
i)
374 if (&
maMenuItems[
i].mxSubMenuWin->get_widget() == pSubMenu)
417 mbAllowEmptySet(true), mbRTL(false)
425 , meDatePartType(YEAR)
431 bool bHasDates,
int nWidth)
433 , mxBuilder(
Application::CreateInterimBuilder(pContainer,
"modules/scalc/ui/filterdropdown.ui", false))
434 ,
mxContainer(mxBuilder->weld_container(
"FilterDropDown"))
435 , mxMenu(mxBuilder->weld_tree_view(
"menu"))
436 , mxScratchIter(mxMenu->make_iterator())
437 , mxEdSearch(mxBuilder->weld_entry(
"search_edit"))
438 , mxBox(mxBuilder->weld_widget(
"box"))
439 , mxListChecks(mxBuilder->weld_tree_view(
"check_list_box"))
440 , mxTreeChecks(mxBuilder->weld_tree_view(
"check_tree_box"))
441 , mxChkToggleAll(mxBuilder->weld_check_button(
"toggle_all"))
442 , mxBtnSelectSingle(mxBuilder->weld_button(
"select_current"))
443 , mxBtnUnselectSingle(mxBuilder->weld_button(
"unselect_current"))
444 , mxButtonBox(mxBuilder->weld_box(
"buttonbox"))
445 , mxBtnOk(mxBuilder->weld_button(
"ok"))
446 , mxBtnCancel(mxBuilder->weld_button(
"cancel"))
447 , mxDropDown(mxMenu->create_virtual_device())
448 , mnCheckWidthReq(-1)
451 , mnSelectedMenu(MENU_NOT_SELECTED)
453 , mnAsyncPostPopdownId(nullptr)
454 , mbHasDates(bHasDates)
455 , mbCanHaveSubMenu(bCanHaveSubMenu)
481 if (!bIsSubMenu && nWidth != -1)
559 rMenuItem.mxSubMenuWin.disposeAndClear();
569 vcl::ILibreOfficeKitNotifier* pNotifier)
571 , mxParentMenu(pParentMenu)
578 set_id(
"check_list_menu");
583 if (rNEvt.
GetType() == MouseNotifyEvent::MOUSEMOVE)
614 mxMenu->set_size_request(-1,
mxMenu->get_preferred_size().Height() + 2);
647 if (&rBtn == mxBtnOk.get())
649 else if (&rBtn == mxBtnCancel.get())
651 else if (&rBtn == mxBtnSelectSingle.get() || &rBtn == mxBtnUnselectSingle.get())
653 selectCurrentMemberOnly(&rBtn == mxBtnSelectSingle.get());
654 std::unique_ptr<weld::TreeIter> xEntry = mpChecks->make_iterator();
655 if (!mpChecks->get_cursor(xEntry.get()))
663 switch (mePrevToggleAllState)
667 setAllMemberState(
true);
671 setAllMemberState(
false);
676 setAllMemberState(
true);
680 mePrevToggleAllState = mxChkToggleAll->get_state();
688 if (aLabel.isEmpty())
689 aLabel =
ScResId(STR_EMPTYDATA);
690 rView.
set_toggle(rIter, bChecked ? TRISTATE_TRUE : TRISTATE_FALSE);
697 OUString aSearchText = mxEdSearch->get_text();
699 bool bSearchTextEmpty = aSearchText.isEmpty();
700 size_t n = maMembers.size();
701 size_t nSelCount = 0;
709 bool bSomeDateDeletes =
false;
711 for (
size_t i = 0;
i < n; ++
i)
713 bool bIsDate = maMembers[
i].mbDate;
714 bool bPartialMatch =
false;
716 OUString aLabelDisp = maMembers[
i].maName;
717 if ( aLabelDisp.isEmpty() )
718 aLabelDisp =
ScResId( STR_EMPTYDATA );
720 if ( !bSearchTextEmpty )
726 maMembers[
i].maRealName + maMembers[
i].maDateParts[1] )).indexOf( aSearchText ) != -1);
733 if ( bSearchTextEmpty )
735 auto xLeaf = ShowCheckEntry(aLabelDisp, maMembers[
i],
true, maMembers[i].
mbVisible);
736 updateMemberParents(xLeaf.get(), i);
737 if ( maMembers[i].mbVisible )
744 auto xLeaf = ShowCheckEntry(aLabelDisp, maMembers[
i]);
745 updateMemberParents(xLeaf.get(), i);
750 ShowCheckEntry(aLabelDisp, maMembers[
i],
false,
false);
752 bSomeDateDeletes =
true;
756 if ( bSomeDateDeletes )
758 for (
size_t i = 0;
i < n; ++
i)
760 if (!maMembers[
i].mbDate)
764 updateMemberParents(
nullptr,
i);
774 if (bSearchTextEmpty)
775 nSelCount = initMembers();
778 std::vector<size_t> aShownIndexes;
780 for (
size_t i = 0;
i < n; ++
i)
784 OUString aLabelDisp = maMembers[
i].maName;
785 if ( aLabelDisp.isEmpty() )
786 aLabelDisp =
ScResId( STR_EMPTYDATA );
793 aShownIndexes.push_back(
i);
796 std::vector<int> aFixedWidths { mnCheckWidthReq };
798 mpChecks->bulk_insert_for_each(aShownIndexes.size(), [
this, &aShownIndexes, &nSelCount](
weld::TreeIter& rIter,
int i) {
799 size_t nIndex = aShownIndexes[
i];
800 insertMember(*mpChecks, rIter, maMembers[nIndex],
true);
809 if ( nSelCount == n )
811 else if ( nSelCount == 0 )
816 if ( !maConfig.mbAllowEmptySet )
818 const bool bEmptySet( nSelCount == 0 );
819 mpChecks->set_sensitive(!bEmptySet);
820 mxChkToggleAll->set_sensitive(!bEmptySet);
821 mxBtnSelectSingle->set_sensitive(!bEmptySet);
822 mxBtnUnselectSingle->set_sensitive(!bEmptySet);
823 mxBtnOk->set_sensitive(!bEmptySet);
829 if (mxBtnOk->get_sensitive())
836 Check(&rRowCol.first);
847 else if (nNumChecked == 0)
855 mxBtnOk->set_sensitive(nNumChecked != 0);
865 OUString aYearName =
maMembers[nIdx].maDateParts[0];
866 OUString aMonthName =
maMembers[nIdx].maDateParts[1];
871 std::unique_ptr<weld::TreeIter> xYearEntry;
882 maMembers[nIdx].mxParent = std::move(xMonthEntry);
885 size_t nMonthIdx = aItr->second;
886 maMembers[nMonthIdx].mxParent = std::move(xYearEntry);
891 std::unique_ptr<weld::TreeIter> xYearEntry =
FindEntry(
nullptr, aYearName);
894 size_t nMonthIdx = aItr->second;
898 else if (xYearEntry && !
FindEntry(xYearEntry.get(), aMonthName))
914 aDate.
AddDays(rtl::math::approxFloor(nVal));
916 sal_Int16 nYear = aDate.
GetYear();
917 sal_uInt16 nMonth = aDate.
GetMonth();
918 sal_uInt16 nDay = aDate.
GetDay();
922 uno::Sequence<i18n::CalendarItem2> aMonths = pCalendar->
getMonths();
923 if (aMonths.getLength() < nMonth)
926 OUString aYearName = OUString::number(nYear);
927 OUString aMonthName = aMonths[nMonth-1].FullName;
928 OUString aDayName = OUString::number(nDay);
930 if ( aDayName.getLength() == 1 )
931 aDayName =
"0" + aDayName;
935 std::unique_ptr<weld::TreeIter> xYearEntry =
FindEntry(
nullptr, aYearName);
939 mpChecks->
insert(
nullptr, -1,
nullptr,
nullptr,
nullptr,
nullptr,
false, xYearEntry.get());
943 aMemYear.
maName = aYearName;
950 maMembers.emplace_back(std::move(aMemYear));
953 std::unique_ptr<weld::TreeIter> xMonthEntry =
FindEntry(xYearEntry.get(), aMonthName);
957 mpChecks->
insert(xYearEntry.get(), -1,
nullptr,
nullptr,
nullptr,
nullptr,
false, xMonthEntry.get());
961 aMemMonth.
maName = aMonthName;
966 aMemMonth.
mxParent = std::move(xYearEntry);
968 maMembers.emplace_back(std::move(aMemMonth));
972 std::unique_ptr<weld::TreeIter> xDayEntry =
FindEntry(xMonthEntry.get(), aDayName);
976 mpChecks->
insert(xMonthEntry.get(), -1,
nullptr,
nullptr,
nullptr,
nullptr,
false, xDayEntry.get());
980 aMemDay.
maName = aDayName;
988 aMemDay.
mxParent = std::move(xMonthEntry);
990 maMembers.emplace_back(std::move(aMemDay));
1004 maMembers.emplace_back(std::move(aMember));
1029 if (rLabel.isEmpty())
1044 OUString aLabel = rLabel;
1046 if (!aLabel.isEmpty() && aLabel != rLabel)
1047 vOut.insert(aLabel);
1056 std::unordered_set<OUString> vResults(0);
1064 if (!aLabel.isEmpty())
1065 vResults.insert(aLabel);
1074 std::unique_ptr<weld::TreeIter> xEntry =
FindEntry(pParent, sName);
1080 std::unique_ptr<weld::TreeIter> xEntry =
FindEntry(pParent, sName);
1116 bool bChildChecked =
false;
1122 bChildChecked =
true;
1134 std::unique_ptr<weld::TreeIter> xEntry;
1151 mpChecks->
insert(
nullptr, -1,
nullptr,
nullptr,
nullptr,
nullptr,
false, xYearEntry.get());
1155 std::unique_ptr<weld::TreeIter> xMonthEntry =
FindEntry(xYearEntry.get(), rMember.
maDateParts[1]);
1159 mpChecks->
insert(xYearEntry.get(), -1,
nullptr,
nullptr,
nullptr,
nullptr,
false, xMonthEntry.get());
1163 std::unique_ptr<weld::TreeIter> xDayEntry =
FindEntry(xMonthEntry.get(), rMember.
maName);
1167 mpChecks->
insert(xMonthEntry.get(), -1,
nullptr,
nullptr,
nullptr,
nullptr,
false, xDayEntry.get());
1219 std::unique_ptr<weld::TreeIter> xEntry = mpChecks->make_iterator();
1220 bool bEntry = mpChecks->get_cursor(xEntry.get());
1223 bool bOldCheck = mpChecks->get_toggle(*xEntry) ==
TRISTATE_TRUE;
1224 CheckEntry(*xEntry, !bOldCheck);
1225 bool bNewCheck = mpChecks->get_toggle(*xEntry) ==
TRISTATE_TRUE;
1226 if (bOldCheck != bNewCheck)
1227 Check(xEntry.get());
1238 size_t nVisMemCount = 0;
1240 if (nMaxMemberWidth == -1)
1245 std::vector<int> aFixedWidths { nMaxMemberWidth };
1261 std::vector<std::unique_ptr<weld::TreeIter>> aExpandRows;
1263 for (
size_t i = 0;
i < n; ++
i)
1273 aExpandRows.emplace_back(std::move(xDateEntry));
1288 for (
auto& rRow : aExpandRows)
1292 if (nVisMemCount == n)
1298 else if (nVisMemCount == 0)
1313 return nVisMemCount;
1331 for (
size_t i = 0;
i < n; ++
i)
1336 if (aLabel.isEmpty())
1337 aLabel =
ScResId(STR_EMPTYDATA);
1352 bool bState = vCheckeds.find(aLabel.makeStringAndClear()) != vCheckeds.end();
1355 aResultEntry.
bValid = bState;
1361 aResult.insert(aResultEntry);
1364 rResult.swap(aResult);
1396 if (aNotifierWindow) {
1397 const vcl::ILibreOfficeKitNotifier* pNotifier = aNotifierWindow->
GetLOKNotifier();
1401 aJsonWriter.
put(
"jsontype",
"autofilter");
1402 aJsonWriter.
put(
"action",
"close");
1405 pNotifier->libreOfficeKitViewCallback(LOK_CALLBACK_JSDIALOG, message.c_str());
1442 clearSelectedMenuItem();
1443 if (mxPopupEndAction)
1444 mxPopupEndAction->execute();
1458 int nNewWidth = nMaxTextWidth - nBorder;
virtual void set_text(int row, const OUString &rText, int col=-1)=0
#define LINK(Instance, Class, Member)
void setDeferredProperties()
vcl::LOKWindowId GetLOKWindowId() const
virtual bool iter_parent(TreeIter &rIter) const =0
std::unique_ptr< weld::TreeIter > mxParent
virtual void insert(const TreeIter *pParent, int pos, const OUString *pStr, const OUString *pId, const OUString *pIconName, VirtualDevice *pImageSurface, bool bChildrenOnDemand, TreeIter *pRet)=0
WeakReference< XInterface > mxParent
static const AllSettings & GetSettings()
void SetPopupModeEndHdl(const vcl::Window *pWindow, const Link< FloatingWindow *, void > &rLink)
void SetLOKNotifier(const vcl::ILibreOfficeKitNotifier *pNotifier, bool bParent=false)
static ImplSVEvent * PostUserEvent(const Link< void *, void > &rLink, void *pCaller=nullptr, bool bReferenceLink=false)
sal_uInt16 GetCode() const
constexpr sal_uInt16 KEY_SPACE
VCL_DLLPUBLIC void SendFullUpdate(sal_uInt64 nWindowId, const OString &rWidget)
virtual TriState get_toggle(int row, int col=-1) const =0
virtual std::unique_ptr< TreeIter > make_iterator(const TreeIter *pOrig=nullptr) const =0
VclPtr< vcl::Window > GetParentWithLOKNotifier()
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
sal_uInt16 GetMonth() const
std::pair< const TreeIter &, int > iter_col
virtual int n_children() const =0
static SfxViewShell * Current()
virtual void bulk_insert_for_each(int nSourceCount, const std::function< void(TreeIter &, int nSourceIndex)> &func, const std::vector< int > *pFixedWidths=nullptr)=0
sal_Int16 GetYear() const
static void RemoveUserEvent(ImplSVEvent *nUserEvent)
SC_DLLPUBLIC SvNumberFormatter * GetFormatTable() const
std::vector< OUString > maDateParts
virtual void set_toggle(int row, TriState eState, int col=-1)=0
VclPtr< vcl::Window > m_xBox
virtual bool iter_has_child(const TreeIter &rIter) const =0
OUString ScResId(const char *pId)
virtual void Start() override
sal_uInt16 GetDay() const
MouseNotifyEvent GetType() const
void AddDays(sal_Int32 nAddDays)
virtual OUString get_text(int row, int col=-1) const =0
OUString lowercase(const OUString &rStr, sal_Int32 nPos, sal_Int32 nCount) const
virtual void expand_row(const TreeIter &rIter)=0
void SetTimeout(sal_uInt64 nTimeoutMs)
DatePartType meDatePartType
virtual bool get_cursor(TreeIter *pIter) const =0
constexpr sal_uInt16 KEY_RETURN
vcl::Window * GetWindow(GetWindowType nType) const
constexpr sal_uInt16 KEY_RIGHT
virtual bool iter_children(TreeIter &rIter) const =0
virtual void remove(int pos)=0
virtual bool EventNotify(NotifyEvent &rNEvt) override
void reset(reference_type *pBody)
tools::Long const nBorder
RegionData_Impl * mpParent
void set_id(const OUString &rID)
void EnableDocking(bool bEnable=true)
virtual void select(int pos)=0
virtual void all_foreach(const std::function< bool(TreeIter &)> &func)=0
static CalendarWrapper * GetCalendar()
virtual void dispose() override
css::uno::Sequence< css::i18n::CalendarItem2 > getMonths() const
virtual bool get_iter_first(TreeIter &rIter) const =0
virtual int get_height_rows(int nRows) const =0
static SC_DLLPUBLIC const CharClass * getCharClassPtr()
void SetInvokeHandler(const Link< Timer *, void > &rLink)
void EndPopupMode(const vcl::Window *pWin)
void append(TreeIter *pRet=nullptr)
VirtualDevice * get() const
void StartPopupMode(const vcl::Window *pWin, const tools::Rectangle &rRect, FloatWinPopupFlags nPopupModeFlags)
const vcl::ILibreOfficeKitNotifier * GetLOKNotifier() const
virtual bool iter_next_sibling(TreeIter &rIter) const =0
void DrawSymbol(const tools::Rectangle &rRect, SymbolType eType, const Color &rColor, DrawSymbolFlags nStyle=DrawSymbolFlags::NONE)
constexpr sal_uInt16 KEY_LEFT
sal_Int32 get_border_width() const
static DockingManager * GetDockingManager()
virtual int get_iter_depth(const TreeIter &rIter) const =0