merge the formfield patch from ooo-build
[ooovba.git] / sc / source / ui / cctrl / dpcontrol.cxx
blob2f09c88194b5ab94fae0fbf9d666fd93af2e7362
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: document.hxx,v $
10 * $Revision: 1.115.36.9 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
34 // INCLUDE ---------------------------------------------------------------
36 #include "dpcontrol.hxx"
37 #include "dpcontrol.hrc"
39 #include "vcl/outdev.hxx"
40 #include "vcl/settings.hxx"
41 #include "vcl/wintypes.hxx"
42 #include "vcl/decoview.hxx"
43 #include "strload.hxx"
44 #include "global.hxx"
46 #include "AccessibleFilterMenu.hxx"
47 #include "AccessibleFilterTopWindow.hxx"
49 #include <com/sun/star/accessibility/XAccessible.hpp>
50 #include <com/sun/star/accessibility/XAccessibleContext.hpp>
52 using ::com::sun::star::uno::Reference;
53 using ::com::sun::star::accessibility::XAccessible;
54 using ::com::sun::star::accessibility::XAccessibleContext;
55 using ::rtl::OUString;
56 using ::rtl::OUStringHash;
57 using ::std::vector;
58 using ::std::hash_map;
59 using ::std::auto_ptr;
61 ScDPFieldButton::ScDPFieldButton(OutputDevice* pOutDev, const StyleSettings* pStyle, const Fraction* pZoomX, const Fraction* pZoomY) :
62 mpOutDev(pOutDev),
63 mpStyle(pStyle),
64 mbBaseButton(true),
65 mbPopupButton(false),
66 mbHasHiddenMember(false),
67 mbPopupPressed(false)
69 if (pZoomX)
70 maZoomX = *pZoomX;
71 else
72 maZoomX = Fraction(1, 1);
74 if (pZoomY)
75 maZoomY = *pZoomY;
76 else
77 maZoomY = Fraction(1, 1);
80 ScDPFieldButton::~ScDPFieldButton()
84 void ScDPFieldButton::setText(const OUString& rText)
86 maText = rText;
89 void ScDPFieldButton::setBoundingBox(const Point& rPos, const Size& rSize)
91 maPos = rPos;
92 maSize = rSize;
95 void ScDPFieldButton::setDrawBaseButton(bool b)
97 mbBaseButton = b;
100 void ScDPFieldButton::setDrawPopupButton(bool b)
102 mbPopupButton = b;
105 void ScDPFieldButton::setHasHiddenMember(bool b)
107 mbHasHiddenMember = b;
110 void ScDPFieldButton::setPopupPressed(bool b)
112 mbPopupPressed = b;
115 void ScDPFieldButton::draw()
117 const long nMargin = 2;
118 bool bOldMapEnablaed = mpOutDev->IsMapModeEnabled();
119 mpOutDev->EnableMapMode(false);
121 if (mbBaseButton)
123 // Background
124 Rectangle aRect(maPos, maSize);
125 mpOutDev->SetLineColor(mpStyle->GetFaceColor());
126 mpOutDev->SetFillColor(mpStyle->GetFaceColor());
127 mpOutDev->DrawRect(aRect);
129 // Border lines
130 mpOutDev->SetLineColor(mpStyle->GetLightColor());
131 mpOutDev->DrawLine(Point(maPos), Point(maPos.X(), maPos.Y()+maSize.Height()-1));
132 mpOutDev->DrawLine(Point(maPos), Point(maPos.X()+maSize.Width()-1, maPos.Y()));
134 mpOutDev->SetLineColor(mpStyle->GetShadowColor());
135 mpOutDev->DrawLine(Point(maPos.X(), maPos.Y()+maSize.Height()-1),
136 Point(maPos.X()+maSize.Width()-1, maPos.Y()+maSize.Height()-1));
137 mpOutDev->DrawLine(Point(maPos.X()+maSize.Width()-1, maPos.Y()),
138 Point(maPos.X()+maSize.Width()-1, maPos.Y()+maSize.Height()-1));
140 // Field name.
141 Font aTextFont( mpStyle->GetLabelFont() );
142 double fFontHeight = 12.0;
143 fFontHeight *= static_cast<double>(maZoomY.GetNumerator()) / static_cast<double>(maZoomY.GetDenominator());
144 aTextFont.SetHeight(fFontHeight);
145 mpOutDev->SetFont(aTextFont);
147 Point aTextPos = maPos;
148 long nTHeight = static_cast<long>(fFontHeight);
149 aTextPos.setX(maPos.getX() + nMargin);
150 aTextPos.setY(maPos.getY() + (maSize.Height()-nTHeight)/2);
151 mpOutDev->DrawText(aTextPos, maText);
154 if (mbPopupButton)
155 drawPopupButton();
157 mpOutDev->EnableMapMode(bOldMapEnablaed);
160 void ScDPFieldButton::getPopupBoundingBox(Point& rPos, Size& rSize) const
162 long nW = maSize.getWidth()*0.5;
163 long nH = maSize.getHeight();
164 if (nW > 18)
165 nW = 18;
166 if (nH > 18)
167 nH = 18;
169 rPos.setX(maPos.getX() + maSize.getWidth() - nW);
170 rPos.setY(maPos.getY() + maSize.getHeight() - nH);
171 rSize.setWidth(nW);
172 rSize.setHeight(nH);
175 bool ScDPFieldButton::isPopupButton() const
177 return mbPopupButton;
180 void ScDPFieldButton::drawPopupButton()
182 Point aPos;
183 Size aSize;
184 getPopupBoundingBox(aPos, aSize);
186 // Background & outer black border
187 mpOutDev->SetLineColor(COL_BLACK);
188 mpOutDev->SetFillColor(mpStyle->GetFaceColor());
189 mpOutDev->DrawRect(Rectangle(aPos, aSize));
191 if (!mbPopupPressed)
193 // border lines
194 mpOutDev->SetLineColor(mpStyle->GetLightColor());
195 mpOutDev->DrawLine(Point(aPos.X()+1, aPos.Y()+1), Point(aPos.X()+1, aPos.Y()+aSize.Height()-2));
196 mpOutDev->DrawLine(Point(aPos.X()+1, aPos.Y()+1), Point(aPos.X()+aSize.Width()-2, aPos.Y()+1));
198 mpOutDev->SetLineColor(mpStyle->GetShadowColor());
199 mpOutDev->DrawLine(Point(aPos.X()+1, aPos.Y()+aSize.Height()-2),
200 Point(aPos.X()+aSize.Width()-2, aPos.Y()+aSize.Height()-2));
201 mpOutDev->DrawLine(Point(aPos.X()+aSize.Width()-2, aPos.Y()+1),
202 Point(aPos.X()+aSize.Width()-2, aPos.Y()+aSize.Height()-2));
205 // the arrowhead
206 Color aArrowColor = mbHasHiddenMember ? mpStyle->GetHighlightLinkColor() : mpStyle->GetButtonTextColor();
207 mpOutDev->SetLineColor(aArrowColor);
208 mpOutDev->SetFillColor(aArrowColor);
209 Point aCenter(aPos.X() + (aSize.Width() >> 1), aPos.Y() + (aSize.Height() >> 1));
210 Point aPos1, aPos2;
211 aPos1.X() = aCenter.X() - 4;
212 aPos2.X() = aCenter.X() + 4;
213 aPos1.Y() = aCenter.Y() - 3;
214 aPos2.Y() = aCenter.Y() - 3;
216 if (mbPopupPressed)
218 aPos1.X() += 1;
219 aPos2.X() += 1;
220 aPos1.Y() += 1;
221 aPos2.Y() += 1;
226 ++aPos1.X();
227 --aPos2.X();
228 ++aPos1.Y();
229 ++aPos2.Y();
230 mpOutDev->DrawLine(aPos1, aPos2);
232 while (aPos1 != aPos2);
234 if (mbHasHiddenMember)
236 // tiny little box to display in presence of hidden member(s).
237 Point aBoxPos(aPos.X() + aSize.Width() - 5, aPos.Y() + aSize.Height() - 5);
238 if (mbPopupPressed)
240 aBoxPos.X() += 1;
241 aBoxPos.Y() += 1;
243 Size aBoxSize(3, 3);
244 mpOutDev->DrawRect(Rectangle(aBoxPos, aBoxSize));
248 // ============================================================================
250 ScMenuFloatingWindow::MenuItemData::MenuItemData() :
251 mbEnabled(true),
252 mpAction(static_cast<ScDPFieldPopupWindow::Action*>(NULL)),
253 mpSubMenuWin(static_cast<ScMenuFloatingWindow*>(NULL))
257 // ----------------------------------------------------------------------------
259 ScMenuFloatingWindow::SubMenuItemData::SubMenuItemData(ScMenuFloatingWindow* pParent) :
260 mpSubMenu(NULL),
261 mnMenuPos(MENU_NOT_SELECTED),
262 mpParent(pParent)
264 maTimer.SetTimeoutHdl( LINK(this, ScMenuFloatingWindow::SubMenuItemData, TimeoutHdl) );
265 maTimer.SetTimeout(mpParent->GetSettings().GetMouseSettings().GetMenuDelay());
268 void ScMenuFloatingWindow::SubMenuItemData::reset()
270 mpSubMenu = NULL;
271 mnMenuPos = MENU_NOT_SELECTED;
272 maTimer.Stop();
275 IMPL_LINK( ScMenuFloatingWindow::SubMenuItemData, TimeoutHdl, void*, EMPTYARG )
277 mpParent->handleMenuTimeout(this);
278 return 0;
281 // ----------------------------------------------------------------------------
283 size_t ScMenuFloatingWindow::MENU_NOT_SELECTED = 999;
285 ScMenuFloatingWindow::ScMenuFloatingWindow(Window* pParent, ScDocument* pDoc, USHORT nMenuStackLevel) :
286 PopupMenuFloatingWindow(pParent),
287 maOpenTimer(this),
288 maCloseTimer(this),
289 maName(OUString::createFromAscii("ScMenuFloatingWindow")),
290 mnSelectedMenu(MENU_NOT_SELECTED),
291 mnClickedMenu(MENU_NOT_SELECTED),
292 mpDoc(pDoc),
293 mpParentMenu(dynamic_cast<ScMenuFloatingWindow*>(pParent)),
294 mpActiveSubMenu(NULL)
296 SetMenuStackLevel(nMenuStackLevel);
298 // TODO: How do we get the right font to use here ?
299 const sal_uInt16 nPopupFontHeight = 12;
300 const StyleSettings& rStyle = GetSettings().GetStyleSettings();
301 maLabelFont = rStyle.GetLabelFont();
302 maLabelFont.SetHeight(nPopupFontHeight);
303 SetFont(maLabelFont);
305 SetText(OUString::createFromAscii("ScMenuFloatingWindow"));
306 SetPopupModeEndHdl( LINK(this, ScMenuFloatingWindow, PopupEndHdl) );
309 ScMenuFloatingWindow::~ScMenuFloatingWindow()
311 EndPopupMode();
314 void ScMenuFloatingWindow::MouseMove(const MouseEvent& rMEvt)
316 const Point& rPos = rMEvt.GetPosPixel();
317 size_t nSelectedMenu = getEnclosingMenuItem(rPos);
318 setSelectedMenuItem(nSelectedMenu, true, false);
320 Window::MouseMove(rMEvt);
323 void ScMenuFloatingWindow::MouseButtonDown(const MouseEvent& rMEvt)
325 const Point& rPos = rMEvt.GetPosPixel();
326 mnClickedMenu = getEnclosingMenuItem(rPos);
327 Window::MouseButtonDown(rMEvt);
330 void ScMenuFloatingWindow::MouseButtonUp(const MouseEvent& rMEvt)
332 executeMenuItem(mnClickedMenu);
333 mnClickedMenu = MENU_NOT_SELECTED;
334 Window::MouseButtonUp(rMEvt);
337 void ScMenuFloatingWindow::KeyInput(const KeyEvent& rKEvt)
339 const KeyCode& rKeyCode = rKEvt.GetKeyCode();
340 bool bHandled = true;
341 size_t nSelectedMenu = mnSelectedMenu;
342 size_t nLastMenuPos = maMenuItems.size() - 1;
343 switch (rKeyCode.GetCode())
345 case KEY_UP:
346 if (nSelectedMenu == MENU_NOT_SELECTED || nSelectedMenu == 0)
347 nSelectedMenu = nLastMenuPos;
348 else
349 --nSelectedMenu;
350 setSelectedMenuItem(nSelectedMenu, false, false);
351 break;
352 case KEY_DOWN:
353 if (nSelectedMenu == MENU_NOT_SELECTED || nSelectedMenu == nLastMenuPos)
354 nSelectedMenu = 0;
355 else
356 ++nSelectedMenu;
357 setSelectedMenuItem(nSelectedMenu, false, false);
358 break;
359 case KEY_LEFT:
360 if (mpParentMenu)
361 mpParentMenu->endSubMenu(this);
362 break;
363 case KEY_RIGHT:
365 if (mnSelectedMenu >= maMenuItems.size() || mnSelectedMenu == MENU_NOT_SELECTED)
366 break;
368 const MenuItemData& rMenu = maMenuItems[mnSelectedMenu];
369 if (!rMenu.mbEnabled || !rMenu.mpSubMenuWin)
370 break;
372 maOpenTimer.mnMenuPos = mnSelectedMenu;
373 maOpenTimer.mpSubMenu = rMenu.mpSubMenuWin.get();
374 launchSubMenu(true);
376 break;
377 case KEY_RETURN:
378 if (nSelectedMenu != MENU_NOT_SELECTED)
379 executeMenuItem(nSelectedMenu);
380 break;
381 default:
382 bHandled = false;
385 if (!bHandled)
386 Window::KeyInput(rKEvt);
389 void ScMenuFloatingWindow::Paint(const Rectangle& /*rRect*/)
391 const StyleSettings& rStyle = GetSettings().GetStyleSettings();
392 Color aBackColor = rStyle.GetMenuColor();
393 Color aBorderColor = rStyle.GetShadowColor();
395 Rectangle aCtrlRect(Point(0, 0), GetOutputSizePixel());
397 // Window background
398 bool bNativeDrawn = true;
399 if (IsNativeControlSupported(CTRL_MENU_POPUP, PART_ENTIRE_CONTROL))
401 SetClipRegion();
402 bNativeDrawn = DrawNativeControl(
403 CTRL_MENU_POPUP, PART_ENTIRE_CONTROL, Region(aCtrlRect), CTRL_STATE_ENABLED,
404 ImplControlValue(), OUString());
406 else
407 bNativeDrawn = false;
409 if (!bNativeDrawn)
411 SetFillColor(aBackColor);
412 SetLineColor(aBorderColor);
413 DrawRect(aCtrlRect);
416 // Menu items
417 SetTextColor(rStyle.GetMenuTextColor());
418 drawAllMenuItems();
421 Reference<XAccessible> ScMenuFloatingWindow::CreateAccessible()
423 if (!mxAccessible.is())
425 Reference<XAccessible> xAccParent = mpParentMenu ?
426 mpParentMenu->GetAccessible() : GetAccessibleParentWindow()->GetAccessible();
428 mxAccessible.set(new ScAccessibleFilterMenu(xAccParent, this, maName, 999, getDoc()));
429 ScAccessibleFilterMenu* p = static_cast<ScAccessibleFilterMenu*>(
430 mxAccessible.get());
432 vector<MenuItemData>::const_iterator itr, itrBeg = maMenuItems.begin(), itrEnd = maMenuItems.end();
433 for (itr = itrBeg; itr != itrEnd; ++itr)
435 size_t nPos = ::std::distance(itrBeg, itr);
436 p->appendMenuItem(itr->maText, itr->mbEnabled, nPos);
440 return mxAccessible;
443 void ScMenuFloatingWindow::addMenuItem(const OUString& rText, bool bEnabled, Action* pAction)
445 MenuItemData aItem;
446 aItem.maText = rText;
447 aItem.mbEnabled = bEnabled;
448 aItem.mpAction.reset(pAction);
449 maMenuItems.push_back(aItem);
452 ScMenuFloatingWindow* ScMenuFloatingWindow::addSubMenuItem(const OUString& rText, bool bEnabled)
454 MenuItemData aItem;
455 aItem.maText = rText;
456 aItem.mbEnabled = bEnabled;
457 aItem.mpSubMenuWin.reset(new ScMenuFloatingWindow(this, mpDoc, GetMenuStackLevel()+1));
458 aItem.mpSubMenuWin->setName(rText);
459 maMenuItems.push_back(aItem);
460 return aItem.mpSubMenuWin.get();
463 void ScMenuFloatingWindow::drawMenuItem(size_t nPos)
465 if (nPos >= maMenuItems.size())
466 return;
468 Point aPos;
469 Size aSize;
470 getMenuItemPosSize(nPos, aPos, aSize);
472 DecorationView aDecoView(this);
473 long nXOffset = 5;
474 long nYOffset = (aSize.Height() - maLabelFont.GetHeight())/2;
475 DrawCtrlText(Point(aPos.X()+nXOffset, aPos.Y() + nYOffset), maMenuItems[nPos].maText, 0, STRING_LEN,
476 maMenuItems[nPos].mbEnabled ? TEXT_DRAW_MNEMONIC : TEXT_DRAW_DISABLE);
478 if (maMenuItems[nPos].mpSubMenuWin)
480 long nFontHeight = maLabelFont.GetHeight();
481 Point aMarkerPos = aPos;
482 aMarkerPos.Y() += aSize.Height()/2 - nFontHeight/4 + 1;
483 aMarkerPos.X() += aSize.Width() - nFontHeight + nFontHeight/4;
484 Size aMarkerSize(nFontHeight/2, nFontHeight/2);
485 aDecoView.DrawSymbol(Rectangle(aMarkerPos, aMarkerSize),
486 SYMBOL_SPIN_RIGHT, GetTextColor(), 0);
490 void ScMenuFloatingWindow::drawAllMenuItems()
492 size_t n = maMenuItems.size();
493 for (size_t i = 0; i < n; ++i)
494 highlightMenuItem(i, i == mnSelectedMenu);
497 const Font& ScMenuFloatingWindow::getLabelFont() const
499 return maLabelFont;
502 void ScMenuFloatingWindow::executeMenuItem(size_t nPos)
504 if (nPos >= maMenuItems.size())
505 return;
507 if (!maMenuItems[nPos].mpAction)
508 // no action is defined.
509 return;
511 maMenuItems[nPos].mpAction->execute();
512 terminateAllPopupMenus();
515 void ScMenuFloatingWindow::setSelectedMenuItem(size_t nPos, bool bSubMenuTimer, bool bEnsureSubMenu)
517 if (mnSelectedMenu == nPos)
518 // nothing to do.
519 return;
521 if (bEnsureSubMenu)
523 // Dismiss any child popup menu windows.
524 if (mnSelectedMenu < maMenuItems.size() &&
525 maMenuItems[mnSelectedMenu].mpSubMenuWin &&
526 maMenuItems[mnSelectedMenu].mpSubMenuWin->IsVisible())
528 maMenuItems[mnSelectedMenu].mpSubMenuWin->ensureSubMenuNotVisible();
531 // The popup is not visible, yet a menu item is selected. The request
532 // most likely comes from the accessible object. Make sure this
533 // window, as well as all its parent windows are visible.
534 if (!IsVisible() && mpParentMenu)
535 mpParentMenu->ensureSubMenuVisible(this);
538 selectMenuItem(mnSelectedMenu, false, bSubMenuTimer);
539 selectMenuItem(nPos, true, bSubMenuTimer);
540 mnSelectedMenu = nPos;
542 fireMenuHighlightedEvent();
545 size_t ScMenuFloatingWindow::getSelectedMenuItem() const
547 return mnSelectedMenu;
550 void ScMenuFloatingWindow::handleMenuTimeout(SubMenuItemData* pTimer)
552 if (pTimer == &maOpenTimer)
554 // Close any open submenu immediately.
555 if (maCloseTimer.mpSubMenu)
557 maCloseTimer.mpSubMenu->EndPopupMode();
558 maCloseTimer.mpSubMenu = NULL;
559 maCloseTimer.maTimer.Stop();
562 launchSubMenu(false);
564 else if (pTimer == &maCloseTimer)
566 // end submenu.
567 if (maCloseTimer.mpSubMenu)
569 maOpenTimer.mpSubMenu = NULL;
571 maCloseTimer.mpSubMenu->EndPopupMode();
572 maCloseTimer.mpSubMenu = NULL;
574 highlightMenuItem(maOpenTimer.mnMenuPos, false);
575 maOpenTimer.mnMenuPos = MENU_NOT_SELECTED;
580 void ScMenuFloatingWindow::queueLaunchSubMenu(size_t nPos, ScMenuFloatingWindow* pMenu)
582 if (!pMenu)
583 return;
585 // Set the submenu on launch queue.
586 if (maOpenTimer.mpSubMenu)
588 if (maOpenTimer.mpSubMenu == pMenu)
590 if (pMenu == maCloseTimer.mpSubMenu)
591 maCloseTimer.reset();
592 return;
595 // new submenu is being requested.
596 queueCloseSubMenu();
599 maOpenTimer.mpSubMenu = pMenu;
600 maOpenTimer.mnMenuPos = nPos;
601 maOpenTimer.maTimer.Start();
604 void ScMenuFloatingWindow::queueCloseSubMenu()
606 if (!maOpenTimer.mpSubMenu)
607 // There is no submenu to close.
608 return;
610 // Stop any submenu on queue for opening.
611 maOpenTimer.maTimer.Stop();
613 maCloseTimer.mpSubMenu = maOpenTimer.mpSubMenu;
614 maCloseTimer.mnMenuPos = maOpenTimer.mnMenuPos;
615 maCloseTimer.maTimer.Start();
618 void ScMenuFloatingWindow::launchSubMenu(bool bSetMenuPos)
620 Point aPos;
621 Size aSize;
622 getMenuItemPosSize(maOpenTimer.mnMenuPos, aPos, aSize);
623 ScMenuFloatingWindow* pSubMenu = maOpenTimer.mpSubMenu;
625 if (!pSubMenu)
626 return;
628 sal_uInt32 nOldFlags = GetPopupModeFlags();
629 SetPopupModeFlags(nOldFlags | FLOATWIN_POPUPMODE_NOAPPFOCUSCLOSE);
630 pSubMenu->resizeToFitMenuItems(); // set the size before launching the popup to get it positioned correctly.
631 pSubMenu->StartPopupMode(
632 Rectangle(aPos,aSize), (FLOATWIN_POPUPMODE_RIGHT | FLOATWIN_POPUPMODE_GRABFOCUS));
633 pSubMenu->AddPopupModeWindow(this);
634 if (bSetMenuPos)
635 pSubMenu->setSelectedMenuItem(0, false, false); // select menu item after the popup becomes fully visible.
636 SetPopupModeFlags(nOldFlags);
639 void ScMenuFloatingWindow::endSubMenu(ScMenuFloatingWindow* pSubMenu)
641 if (!pSubMenu)
642 return;
644 pSubMenu->EndPopupMode();
645 maOpenTimer.reset();
647 size_t nMenuPos = getSubMenuPos(pSubMenu);
648 if (nMenuPos != MENU_NOT_SELECTED)
650 highlightMenuItem(nMenuPos, true);
651 mnSelectedMenu = nMenuPos;
652 fireMenuHighlightedEvent();
656 void ScMenuFloatingWindow::fillMenuItemsToAccessible(ScAccessibleFilterMenu* pAccMenu) const
658 vector<MenuItemData>::const_iterator itr, itrBeg = maMenuItems.begin(), itrEnd = maMenuItems.end();
659 for (itr = itrBeg; itr != itrEnd; ++itr)
661 size_t nPos = ::std::distance(itrBeg, itr);
662 pAccMenu->appendMenuItem(itr->maText, itr->mbEnabled, nPos);
666 ScDocument* ScMenuFloatingWindow::getDoc()
668 return mpDoc;
671 void ScMenuFloatingWindow::resizeToFitMenuItems()
673 if (maMenuItems.empty())
674 return;
676 vector<MenuItemData>::const_iterator itr = maMenuItems.begin(), itrEnd = maMenuItems.end();
677 long nTextWidth = 0;
678 for (; itr != itrEnd; ++itr)
679 nTextWidth = ::std::max(GetTextWidth(itr->maText), nTextWidth);
681 size_t nLastPos = maMenuItems.size()-1;
682 Point aPos;
683 Size aSize;
684 getMenuItemPosSize(nLastPos, aPos, aSize);
685 aPos.X() += nTextWidth + 15;
686 aPos.Y() += aSize.Height() + 5;
687 SetOutputSizePixel(Size(aPos.X(), aPos.Y()));
690 void ScMenuFloatingWindow::selectMenuItem(size_t nPos, bool bSelected, bool bSubMenuTimer)
692 if (nPos >= maMenuItems.size() || nPos == MENU_NOT_SELECTED)
694 queueCloseSubMenu();
695 return;
698 if (!maMenuItems[nPos].mbEnabled)
700 queueCloseSubMenu();
701 return;
704 highlightMenuItem(nPos, bSelected);
706 if (bSelected)
708 if (mpParentMenu)
709 mpParentMenu->setSubMenuFocused(this);
711 if (bSubMenuTimer)
713 if (maMenuItems[nPos].mpSubMenuWin)
715 ScMenuFloatingWindow* pSubMenu = maMenuItems[nPos].mpSubMenuWin.get();
716 queueLaunchSubMenu(nPos, pSubMenu);
718 else
719 queueCloseSubMenu();
724 void ScMenuFloatingWindow::clearSelectedMenuItem()
726 selectMenuItem(mnSelectedMenu, false, false);
727 mnSelectedMenu = MENU_NOT_SELECTED;
730 ScMenuFloatingWindow* ScMenuFloatingWindow::getSubMenuWindow(size_t nPos) const
732 if (maMenuItems.size() <= nPos)
733 return NULL;
735 return maMenuItems[nPos].mpSubMenuWin.get();
738 size_t ScMenuFloatingWindow::getMenuItemCount() const
740 return maMenuItems.size();
743 OUString ScMenuFloatingWindow::getMenuItemName(size_t nPos) const
745 if (maMenuItems.size() <= nPos)
746 return ScGlobal::GetEmptyString();
748 return maMenuItems[nPos].maText;
751 bool ScMenuFloatingWindow::isMenuItemEnabled(size_t nPos) const
753 if (maMenuItems.size() <= nPos)
754 return false;
756 return maMenuItems[nPos].mbEnabled;
759 bool ScMenuFloatingWindow::isMenuItemSelected(size_t nPos) const
761 return nPos == mnSelectedMenu;
764 void ScMenuFloatingWindow::setName(const OUString& rName)
766 maName = rName;
769 const OUString& ScMenuFloatingWindow::getName() const
771 return maName;
774 void ScMenuFloatingWindow::highlightMenuItem(size_t nPos, bool bSelected)
776 if (nPos == MENU_NOT_SELECTED)
777 return;
779 const StyleSettings& rStyle = GetSettings().GetStyleSettings();
780 Color aBackColor = rStyle.GetMenuColor();
781 SetFillColor(aBackColor);
782 SetLineColor(aBackColor);
784 Point aPos;
785 Size aSize;
786 getMenuItemPosSize(nPos, aPos, aSize);
787 Region aRegion(Rectangle(aPos,aSize));
789 if (IsNativeControlSupported(CTRL_MENU_POPUP, PART_ENTIRE_CONTROL))
791 Push(PUSH_CLIPREGION);
792 IntersectClipRegion(Rectangle(aPos, aSize));
793 Rectangle aCtrlRect(Point(0,0), GetOutputSizePixel());
794 DrawNativeControl(
795 CTRL_MENU_POPUP, PART_ENTIRE_CONTROL, Region(aCtrlRect), CTRL_STATE_ENABLED,
796 ImplControlValue(), OUString());
798 Pop();
801 bool bNativeDrawn = true;
802 if (IsNativeControlSupported(CTRL_MENU_POPUP, PART_MENU_ITEM))
804 ControlState nState = bSelected ? CTRL_STATE_SELECTED : 0;
805 if (maMenuItems[nPos].mbEnabled)
806 nState |= CTRL_STATE_ENABLED;
807 bNativeDrawn = DrawNativeControl(
808 CTRL_MENU_POPUP, PART_MENU_ITEM, aRegion, nState, ImplControlValue(), OUString());
810 else
811 bNativeDrawn = false;
813 if (!bNativeDrawn)
815 if (bSelected)
817 aBackColor = rStyle.GetMenuHighlightColor();
818 SetFillColor(aBackColor);
819 SetLineColor(aBackColor);
821 DrawRect(Rectangle(aPos,aSize));
824 Color aTextColor = bSelected ? rStyle.GetMenuHighlightTextColor() : rStyle.GetMenuTextColor();
825 SetTextColor(aTextColor);
826 drawMenuItem(nPos);
829 void ScMenuFloatingWindow::getMenuItemPosSize(size_t nPos, Point& rPos, Size& rSize) const
831 const sal_uInt16 nLeftMargin = 5;
832 const sal_uInt16 nTopMargin = 5;
833 const sal_uInt16 nMenuItemHeight = maLabelFont.GetHeight()*1.8;
835 Size aWndSize = GetSizePixel();
837 Point aPos1(nLeftMargin, nTopMargin);
838 Size aSize1(aWndSize.Width() - nLeftMargin*2, nMenuItemHeight);
840 rPos = aPos1;
841 rPos.Y() += aSize1.Height()*nPos;
842 rSize = aSize1;
845 ScMenuFloatingWindow* ScMenuFloatingWindow::getParentMenuWindow() const
847 return mpParentMenu;
850 size_t ScMenuFloatingWindow::getEnclosingMenuItem(const Point& rPos) const
852 size_t n = maMenuItems.size();
853 for (size_t i = 0; i < n; ++i)
855 Point aPos;
856 Size aSize;
857 getMenuItemPosSize(i, aPos, aSize);
858 Rectangle aRect(aPos, aSize);
859 if (aRect.IsInside(rPos))
860 return i;
862 return MENU_NOT_SELECTED;
865 size_t ScMenuFloatingWindow::getSubMenuPos(ScMenuFloatingWindow* pSubMenu)
867 size_t n = maMenuItems.size();
868 for (size_t i = 0; i < n; ++i)
870 if (maMenuItems[i].mpSubMenuWin.get() == pSubMenu)
871 return i;
873 return MENU_NOT_SELECTED;
876 void ScMenuFloatingWindow::fireMenuHighlightedEvent()
878 if (mnSelectedMenu == MENU_NOT_SELECTED)
879 return;
881 if (!mxAccessible.is())
882 return;
884 Reference<XAccessibleContext> xAccCxt = mxAccessible->getAccessibleContext();
885 if (!xAccCxt.is())
886 return;
888 Reference<XAccessible> xAccMenu = xAccCxt->getAccessibleChild(mnSelectedMenu);
889 if (!xAccMenu.is())
890 return;
892 VclAccessibleEvent aEvent(VCLEVENT_MENU_HIGHLIGHT, xAccMenu);
893 FireVclEvent(&aEvent);
896 void ScMenuFloatingWindow::setSubMenuFocused(ScMenuFloatingWindow* pSubMenu)
898 maCloseTimer.reset();
899 size_t nMenuPos = getSubMenuPos(pSubMenu);
900 if (mnSelectedMenu != nMenuPos)
902 highlightMenuItem(nMenuPos, true);
903 mnSelectedMenu = nMenuPos;
907 void ScMenuFloatingWindow::ensureSubMenuVisible(ScMenuFloatingWindow* pSubMenu)
909 if (mpParentMenu)
910 mpParentMenu->ensureSubMenuVisible(this);
912 if (pSubMenu->IsVisible())
913 return;
915 // Find the menu position of the submenu.
916 size_t nMenuPos = getSubMenuPos(pSubMenu);
917 if (nMenuPos != MENU_NOT_SELECTED)
919 setSelectedMenuItem(nMenuPos, false, false);
921 Point aPos;
922 Size aSize;
923 getMenuItemPosSize(nMenuPos, aPos, aSize);
925 sal_uInt32 nOldFlags = GetPopupModeFlags();
926 SetPopupModeFlags(nOldFlags | FLOATWIN_POPUPMODE_NOAPPFOCUSCLOSE);
927 pSubMenu->resizeToFitMenuItems(); // set the size before launching the popup to get it positioned correctly.
928 pSubMenu->StartPopupMode(
929 Rectangle(aPos,aSize), (FLOATWIN_POPUPMODE_RIGHT | FLOATWIN_POPUPMODE_GRABFOCUS));
930 pSubMenu->AddPopupModeWindow(this);
931 SetPopupModeFlags(nOldFlags);
935 void ScMenuFloatingWindow::ensureSubMenuNotVisible()
937 if (mnSelectedMenu <= maMenuItems.size() &&
938 maMenuItems[mnSelectedMenu].mpSubMenuWin &&
939 maMenuItems[mnSelectedMenu].mpSubMenuWin->IsVisible())
941 maMenuItems[mnSelectedMenu].mpSubMenuWin->ensureSubMenuNotVisible();
944 EndPopupMode();
947 void ScMenuFloatingWindow::terminateAllPopupMenus()
949 EndPopupMode();
950 if (mpParentMenu)
951 mpParentMenu->terminateAllPopupMenus();
954 IMPL_LINK( ScMenuFloatingWindow, PopupEndHdl, void*, EMPTYARG )
956 clearSelectedMenuItem();
957 return 0;
960 // ============================================================================
962 ScDPFieldPopupWindow::Member::Member() :
963 mbVisible(true)
967 // ----------------------------------------------------------------------------
969 ScDPFieldPopupWindow::CancelButton::CancelButton(ScDPFieldPopupWindow* pParent) :
970 ::CancelButton(pParent), mpParent(pParent) {}
972 void ScDPFieldPopupWindow::CancelButton::Click()
974 mpParent->EndPopupMode();
975 ::CancelButton::Click();
978 // ----------------------------------------------------------------------------
980 ScDPFieldPopupWindow::ScDPFieldPopupWindow(Window* pParent, ScDocument* pDoc) :
981 ScMenuFloatingWindow(pParent, pDoc),
982 maChecks(this, 0),
983 maChkToggleAll(this, 0),
984 maBtnSelectSingle (this, 0),
985 maBtnUnselectSingle(this, 0),
986 maBtnOk(this),
987 maBtnCancel(this),
988 mnCurTabStop(0),
989 mpExtendedData(NULL),
990 mpOKAction(NULL),
991 maWndSize(160, 330),
992 mePrevToggleAllState(STATE_DONTKNOW)
994 maTabStopCtrls.reserve(7);
995 maTabStopCtrls.push_back(this);
996 maTabStopCtrls.push_back(&maChecks);
997 maTabStopCtrls.push_back(&maChkToggleAll);
998 maTabStopCtrls.push_back(&maBtnSelectSingle);
999 maTabStopCtrls.push_back(&maBtnUnselectSingle);
1000 maTabStopCtrls.push_back(&maBtnOk);
1001 maTabStopCtrls.push_back(&maBtnCancel);
1003 const StyleSettings& rStyle = GetSettings().GetStyleSettings();
1005 Point aPos;
1006 Size aSize;
1007 getSectionPosSize(aPos, aSize, WHOLE);
1008 SetOutputSizePixel(aSize);
1009 Size aOutSize = GetOutputSizePixel();
1011 getSectionPosSize(aPos, aSize, BTN_OK);
1012 maBtnOk.SetPosSizePixel(aPos, aSize);
1013 maBtnOk.SetFont(getLabelFont());
1014 maBtnOk.SetClickHdl( LINK(this, ScDPFieldPopupWindow, ButtonHdl) );
1015 maBtnOk.Show();
1017 getSectionPosSize(aPos, aSize, BTN_CANCEL);
1018 maBtnCancel.SetPosSizePixel(aPos, aSize);
1019 maBtnCancel.SetFont(getLabelFont());
1020 maBtnCancel.Show();
1022 getSectionPosSize(aPos, aSize, LISTBOX_AREA_INNER);
1023 maChecks.SetPosSizePixel(aPos, aSize);
1024 maChecks.SetFont(getLabelFont());
1025 maChecks.SetCheckButtonHdl( LINK(this, ScDPFieldPopupWindow, CheckHdl) );
1026 maChecks.Show();
1028 getSectionPosSize(aPos, aSize, CHECK_TOGGLE_ALL);
1029 maChkToggleAll.SetPosSizePixel(aPos, aSize);
1030 maChkToggleAll.SetFont(getLabelFont());
1031 maChkToggleAll.SetText(ScRscStrLoader(RID_POPUP_FILTER, STR_BTN_TOGGLE_ALL).GetString());
1032 maChkToggleAll.SetControlBackground(rStyle.GetMenuColor());
1033 maChkToggleAll.SetClickHdl( LINK(this, ScDPFieldPopupWindow, TriStateHdl) );
1034 maChkToggleAll.Show();
1036 getSectionPosSize(aPos, aSize, BTN_SINGLE_SELECT);
1037 maBtnSelectSingle.SetPosSizePixel(aPos, aSize);
1038 maBtnSelectSingle.SetQuickHelpText(ScRscStrLoader(RID_POPUP_FILTER, STR_BTN_SELECT_CURRENT).GetString());
1039 maBtnSelectSingle.SetModeImage(Image(ScResId(RID_IMG_SELECT_CURRENT)), BMP_COLOR_NORMAL);
1040 maBtnSelectSingle.SetClickHdl( LINK(this, ScDPFieldPopupWindow, ButtonHdl) );
1041 maBtnSelectSingle.Show();
1043 getSectionPosSize(aPos, aSize, BTN_SINGLE_UNSELECT);
1044 maBtnUnselectSingle.SetPosSizePixel(aPos, aSize);
1045 maBtnUnselectSingle.SetQuickHelpText(ScRscStrLoader(RID_POPUP_FILTER, STR_BTN_UNSELECT_CURRENT).GetString());
1046 maBtnUnselectSingle.SetModeImage(Image(ScResId(RID_IMG_UNSELECT_CURRENT)), BMP_COLOR_NORMAL);
1047 maBtnUnselectSingle.SetClickHdl( LINK(this, ScDPFieldPopupWindow, ButtonHdl) );
1048 maBtnUnselectSingle.Show();
1051 ScDPFieldPopupWindow::~ScDPFieldPopupWindow()
1055 void ScDPFieldPopupWindow::getSectionPosSize(Point& rPos, Size& rSize, SectionType eType) const
1057 // constant parameters.
1058 const sal_uInt16 nListBoxMargin = 5; // horizontal distance from the side of the dialog to the listbox border.
1059 const sal_uInt16 nListBoxInnerPadding = 5;
1060 const sal_uInt16 nTopMargin = 5;
1061 const sal_uInt16 nMenuHeight = 60;
1062 const sal_uInt16 nSingleItemBtnAreaHeight = 32; // height of the middle area below the list box where the single-action buttons are.
1063 const sal_uInt16 nBottomBtnAreaHeight = 50; // height of the bottom area where the OK and Cancel buttons are.
1064 const sal_uInt16 nBtnWidth = 60;
1065 const sal_uInt16 nLabelHeight = getLabelFont().GetHeight();
1066 const sal_uInt16 nBtnHeight = nLabelHeight*2;
1067 const sal_uInt16 nBottomMargin = 10;
1068 const sal_uInt16 nMenuListMargin = 20;
1070 // parameters calculated from constants.
1071 const sal_uInt16 nListBoxWidth = maWndSize.Width() - nListBoxMargin*2;
1072 const sal_uInt16 nListBoxHeight = maWndSize.Height() - nTopMargin - nMenuHeight -
1073 nMenuListMargin - nSingleItemBtnAreaHeight - nBottomBtnAreaHeight;
1075 const sal_uInt16 nSingleBtnAreaY = nTopMargin + nMenuHeight + nListBoxHeight + nMenuListMargin - 1;
1077 switch (eType)
1079 case WHOLE:
1081 rPos = Point(0, 0);
1082 rSize = maWndSize;
1084 break;
1085 case LISTBOX_AREA_OUTER:
1087 rPos = Point(nListBoxMargin, nTopMargin + nMenuHeight + nMenuListMargin);
1088 rSize = Size(nListBoxWidth, nListBoxHeight);
1090 break;
1091 case LISTBOX_AREA_INNER:
1093 rPos = Point(nListBoxMargin, nTopMargin + nMenuHeight + nMenuListMargin);
1094 rPos.X() += nListBoxInnerPadding;
1095 rPos.Y() += nListBoxInnerPadding;
1097 rSize = Size(nListBoxWidth, nListBoxHeight);
1098 rSize.Width() -= nListBoxInnerPadding*2;
1099 rSize.Height() -= nListBoxInnerPadding*2;
1101 break;
1102 case SINGLE_BTN_AREA:
1104 rPos = Point(nListBoxMargin, nSingleBtnAreaY);
1105 rSize = Size(nListBoxWidth, nSingleItemBtnAreaHeight);
1107 break;
1108 case CHECK_TOGGLE_ALL:
1110 long h = nLabelHeight*3/2; // check box height is heuristically 150% of the text height.
1111 rPos = Point(nListBoxMargin, nSingleBtnAreaY);
1112 rPos.X() += 5;
1113 rPos.Y() += (nSingleItemBtnAreaHeight - h)/2;
1114 rSize = Size(70, h);
1116 break;
1117 case BTN_SINGLE_SELECT:
1119 long h = 26;
1120 rPos = Point(nListBoxMargin, nSingleBtnAreaY);
1121 rPos.X() += 75;
1122 rPos.Y() += (nSingleItemBtnAreaHeight - h)/2;
1123 rSize = Size(h, h);
1125 break;
1126 case BTN_SINGLE_UNSELECT:
1128 long h = 26;
1129 rPos = Point(nListBoxMargin, nSingleBtnAreaY);
1130 rPos.X() += 75 + h + 10;
1131 rPos.Y() += (nSingleItemBtnAreaHeight - h)/2;
1132 rSize = Size(h, h);
1134 break;
1135 case BTN_OK:
1137 long x = (maWndSize.Width() - nBtnWidth*2)/3;
1138 long y = maWndSize.Height() - nBottomMargin - nBtnHeight;
1139 rPos = Point(x, y);
1140 rSize = Size(nBtnWidth, nBtnHeight);
1142 break;
1143 case BTN_CANCEL:
1145 long x = (maWndSize.Width() - nBtnWidth*2)/3*2 + nBtnWidth;
1146 long y = maWndSize.Height() - nBottomMargin - nBtnHeight;
1147 rPos = Point(x, y);
1148 rSize = Size(nBtnWidth, nBtnHeight);
1150 break;
1151 default:
1156 void ScDPFieldPopupWindow::setAllMemberState(bool bSet)
1158 size_t n = maMembers.size();
1159 for (size_t i = 0; i < n; ++i)
1160 maChecks.CheckEntryPos(i, bSet);
1163 void ScDPFieldPopupWindow::selectCurrentMemberOnly(bool bSet)
1165 setAllMemberState(!bSet);
1166 sal_uInt16 nSelected = maChecks.GetSelectEntryPos();
1167 maChecks.CheckEntryPos(nSelected, bSet);
1170 void ScDPFieldPopupWindow::cycleFocus(bool bReverse)
1172 maTabStopCtrls[mnCurTabStop]->SetFakeFocus(false);
1173 maTabStopCtrls[mnCurTabStop]->LoseFocus();
1174 if (mnCurTabStop == 0)
1175 clearSelectedMenuItem();
1177 if (bReverse)
1179 if (mnCurTabStop > 0)
1180 --mnCurTabStop;
1181 else
1182 mnCurTabStop = maTabStopCtrls.size() - 1;
1184 else
1186 ++mnCurTabStop;
1187 if (mnCurTabStop >= maTabStopCtrls.size())
1188 mnCurTabStop = 0;
1190 maTabStopCtrls[mnCurTabStop]->SetFakeFocus(true);
1191 maTabStopCtrls[mnCurTabStop]->GrabFocus();
1194 IMPL_LINK( ScDPFieldPopupWindow, ButtonHdl, Button*, pBtn )
1196 if (pBtn == &maBtnOk)
1197 close(true);
1198 else if (pBtn == &maBtnSelectSingle)
1200 selectCurrentMemberOnly(true);
1201 CheckHdl(&maChecks);
1203 else if (pBtn == &maBtnUnselectSingle)
1205 selectCurrentMemberOnly(false);
1206 CheckHdl(&maChecks);
1208 return 0;
1211 IMPL_LINK( ScDPFieldPopupWindow, TriStateHdl, TriStateBox*, EMPTYARG )
1213 switch (mePrevToggleAllState)
1215 case STATE_NOCHECK:
1216 maChkToggleAll.SetState(STATE_CHECK);
1217 setAllMemberState(true);
1218 break;
1219 case STATE_CHECK:
1220 maChkToggleAll.SetState(STATE_NOCHECK);
1221 setAllMemberState(false);
1222 break;
1223 case STATE_DONTKNOW:
1224 default:
1225 maChkToggleAll.SetState(STATE_CHECK);
1226 setAllMemberState(true);
1227 break;
1230 mePrevToggleAllState = maChkToggleAll.GetState();
1231 return 0;
1234 IMPL_LINK( ScDPFieldPopupWindow, CheckHdl, SvTreeListBox*, pChecks )
1236 if (pChecks != &maChecks)
1237 return 0;
1239 size_t nNumChecked = maChecks.GetCheckedEntryCount();
1240 if (nNumChecked == maMembers.size())
1241 // all members visible
1242 maChkToggleAll.SetState(STATE_CHECK);
1243 else if (nNumChecked == 0)
1244 // no members visible
1245 maChkToggleAll.SetState(STATE_NOCHECK);
1246 else
1247 maChkToggleAll.SetState(STATE_DONTKNOW);
1249 mePrevToggleAllState = maChkToggleAll.GetState();
1250 return 0;
1253 void ScDPFieldPopupWindow::MouseMove(const MouseEvent& rMEvt)
1255 ScMenuFloatingWindow::MouseMove(rMEvt);
1257 size_t nSelectedMenu = getSelectedMenuItem();
1258 if (nSelectedMenu == MENU_NOT_SELECTED)
1259 queueCloseSubMenu();
1262 long ScDPFieldPopupWindow::Notify(NotifyEvent& rNEvt)
1264 switch (rNEvt.GetType())
1266 case EVENT_KEYUP:
1268 const KeyEvent* pKeyEvent = rNEvt.GetKeyEvent();
1269 const KeyCode& rCode = pKeyEvent->GetKeyCode();
1270 bool bShift = rCode.IsShift();
1271 if (rCode.GetCode() == KEY_TAB)
1273 cycleFocus(bShift);
1274 return true;
1277 break;
1279 return ScMenuFloatingWindow::Notify(rNEvt);
1282 void ScDPFieldPopupWindow::Paint(const Rectangle& rRect)
1284 ScMenuFloatingWindow::Paint(rRect);
1286 const StyleSettings& rStyle = GetSettings().GetStyleSettings();
1287 Color aMemberBackColor = rStyle.GetFieldColor();
1288 Color aBorderColor = rStyle.GetShadowColor();
1290 Point aPos;
1291 Size aSize;
1292 getSectionPosSize(aPos, aSize, LISTBOX_AREA_OUTER);
1294 // Member list box background
1295 SetFillColor(aMemberBackColor);
1296 SetLineColor(aBorderColor);
1297 DrawRect(Rectangle(aPos,aSize));
1299 // Single-action button box
1300 getSectionPosSize(aPos, aSize, SINGLE_BTN_AREA);
1301 SetFillColor(rStyle.GetMenuColor());
1302 DrawRect(Rectangle(aPos,aSize));
1305 Window* ScDPFieldPopupWindow::GetPreferredKeyInputWindow()
1307 return maTabStopCtrls[mnCurTabStop];
1310 Reference<XAccessible> ScDPFieldPopupWindow::CreateAccessible()
1312 if (!mxAccessible.is())
1314 mxAccessible.set(new ScAccessibleFilterTopWindow(
1315 GetAccessibleParentWindow()->GetAccessible(), this, getName(), getDoc()));
1316 ScAccessibleFilterTopWindow* pAccTop = static_cast<ScAccessibleFilterTopWindow*>(mxAccessible.get());
1317 fillMenuItemsToAccessible(pAccTop);
1319 pAccTop->setAccessibleChild(
1320 maChecks.CreateAccessible(), ScAccessibleFilterTopWindow::LISTBOX);
1321 pAccTop->setAccessibleChild(
1322 maChkToggleAll.CreateAccessible(), ScAccessibleFilterTopWindow::TOGGLE_ALL);
1323 pAccTop->setAccessibleChild(
1324 maBtnSelectSingle.CreateAccessible(), ScAccessibleFilterTopWindow::SINGLE_ON_BTN);
1325 pAccTop->setAccessibleChild(
1326 maBtnUnselectSingle.CreateAccessible(), ScAccessibleFilterTopWindow::SINGLE_OFF_BTN);
1327 pAccTop->setAccessibleChild(
1328 maBtnOk.CreateAccessible(), ScAccessibleFilterTopWindow::OK_BTN);
1329 pAccTop->setAccessibleChild(
1330 maBtnCancel.CreateAccessible(), ScAccessibleFilterTopWindow::CANCEL_BTN);
1333 return mxAccessible;
1336 void ScDPFieldPopupWindow::setMemberSize(size_t n)
1338 maMembers.reserve(n);
1341 void ScDPFieldPopupWindow::addMember(const OUString& rName, bool bVisible)
1343 Member aMember;
1344 aMember.maName = rName;
1345 aMember.mbVisible = bVisible;
1346 maMembers.push_back(aMember);
1349 void ScDPFieldPopupWindow::initMembers()
1351 size_t n = maMembers.size();
1352 size_t nVisMemCount = 0;
1353 for (size_t i = 0; i < n; ++i)
1355 maChecks.InsertEntry(maMembers[i].maName);
1356 maChecks.CheckEntryPos(i, maMembers[i].mbVisible);
1357 if (maMembers[i].mbVisible)
1358 ++nVisMemCount;
1360 if (nVisMemCount == n)
1362 // all members visible
1363 maChkToggleAll.SetState(STATE_CHECK);
1364 mePrevToggleAllState = STATE_CHECK;
1366 else if (nVisMemCount == 0)
1368 // no members visible
1369 maChkToggleAll.SetState(STATE_NOCHECK);
1370 mePrevToggleAllState = STATE_NOCHECK;
1372 else
1374 maChkToggleAll.SetState(STATE_DONTKNOW);
1375 mePrevToggleAllState = STATE_DONTKNOW;
1379 const Size& ScDPFieldPopupWindow::getWindowSize() const
1381 return maWndSize;
1384 void ScDPFieldPopupWindow::getResult(hash_map<OUString, bool, OUStringHash>& rResult)
1386 typedef hash_map<OUString, bool, OUStringHash> ResultMap;
1387 ResultMap aResult;
1388 size_t n = maMembers.size();
1389 for (size_t i = 0; i < n; ++i)
1391 bool bState = maChecks.IsChecked(i);
1392 aResult.insert(ResultMap::value_type(maMembers[i].maName, bState));
1394 rResult.swap(aResult);
1397 void ScDPFieldPopupWindow::close(bool bOK)
1399 if (bOK && mpOKAction.get())
1400 mpOKAction->execute();
1402 EndPopupMode();
1405 void ScDPFieldPopupWindow::setExtendedData(ExtendedData* p)
1407 mpExtendedData.reset(p);
1410 ScDPFieldPopupWindow::ExtendedData* ScDPFieldPopupWindow::getExtendedData()
1412 return mpExtendedData.get();
1415 void ScDPFieldPopupWindow::setOKAction(Action* p)
1417 mpOKAction.reset(p);