LCOV - code coverage report
Current view: top level - sc/source/ui/cctrl - checklistmenu.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 0 934 0.0 %
Date: 2014-04-11 Functions: 0 99 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include "checklistmenu.hxx"
      21             : #include "checklistmenu.hrc"
      22             : #include "strload.hxx"
      23             : 
      24             : #include <vcl/decoview.hxx>
      25             : #include <vcl/settings.hxx>
      26             : #include <tools/wintypes.hxx>
      27             : 
      28             : #include "AccessibleFilterMenu.hxx"
      29             : #include "AccessibleFilterTopWindow.hxx"
      30             : 
      31             : #include <com/sun/star/accessibility/XAccessible.hpp>
      32             : #include <com/sun/star/accessibility/XAccessibleContext.hpp>
      33             : #include "svtools/fmtfield.hxx"
      34             : #include "document.hxx"
      35             : 
      36             : using namespace com::sun::star;
      37             : using ::com::sun::star::uno::Reference;
      38             : using ::com::sun::star::accessibility::XAccessible;
      39             : using ::com::sun::star::accessibility::XAccessibleContext;
      40             : using ::std::vector;
      41             : using ::boost::unordered_map;
      42             : 
      43           0 : ScMenuFloatingWindow::MenuItemData::MenuItemData() :
      44             :     mbEnabled(true), mbSeparator(false),
      45             :     mpAction(static_cast<ScCheckListMenuWindow::Action*>(NULL)),
      46           0 :     mpSubMenuWin(static_cast<ScMenuFloatingWindow*>(NULL))
      47             : {
      48           0 : }
      49             : 
      50           0 : ScMenuFloatingWindow::SubMenuItemData::SubMenuItemData(ScMenuFloatingWindow* pParent) :
      51             :     mpSubMenu(NULL),
      52             :     mnMenuPos(MENU_NOT_SELECTED),
      53           0 :     mpParent(pParent)
      54             : {
      55           0 :     maTimer.SetTimeoutHdl( LINK(this, ScMenuFloatingWindow::SubMenuItemData, TimeoutHdl) );
      56           0 :     maTimer.SetTimeout(mpParent->GetSettings().GetMouseSettings().GetMenuDelay());
      57           0 : }
      58             : 
      59           0 : void ScMenuFloatingWindow::SubMenuItemData::reset()
      60             : {
      61           0 :     mpSubMenu = NULL;
      62           0 :     mnMenuPos = MENU_NOT_SELECTED;
      63           0 :     maTimer.Stop();
      64           0 : }
      65             : 
      66           0 : IMPL_LINK_NOARG(ScMenuFloatingWindow::SubMenuItemData, TimeoutHdl)
      67             : {
      68           0 :     mpParent->handleMenuTimeout(this);
      69           0 :     return 0;
      70             : }
      71             : 
      72             : size_t ScMenuFloatingWindow::MENU_NOT_SELECTED = 999;
      73             : 
      74           0 : ScMenuFloatingWindow::ScMenuFloatingWindow(Window* pParent, ScDocument* pDoc, sal_uInt16 nMenuStackLevel) :
      75             :     PopupMenuFloatingWindow(pParent),
      76             :     maOpenTimer(this),
      77             :     maCloseTimer(this),
      78             :     maName("ScMenuFloatingWindow"),
      79             :     mnSelectedMenu(MENU_NOT_SELECTED),
      80             :     mnClickedMenu(MENU_NOT_SELECTED),
      81             :     mpDoc(pDoc),
      82           0 :     mpParentMenu(dynamic_cast<ScMenuFloatingWindow*>(pParent))
      83             : {
      84           0 :     SetMenuStackLevel(nMenuStackLevel);
      85             : 
      86             :     // TODO: How do we get the right font to use here ?
      87           0 :     const sal_uInt16 nPopupFontHeight = 12;
      88           0 :     const StyleSettings& rStyle = GetSettings().GetStyleSettings();
      89           0 :     maLabelFont = rStyle.GetLabelFont();
      90           0 :     maLabelFont.SetHeight(nPopupFontHeight);
      91           0 :     SetFont(maLabelFont);
      92             : 
      93           0 :     SetText( OUString("ScMenuFloatingWindow") );
      94           0 : }
      95             : 
      96           0 : ScMenuFloatingWindow::~ScMenuFloatingWindow()
      97             : {
      98           0 :     EndPopupMode();
      99           0 : }
     100             : 
     101           0 : void ScMenuFloatingWindow::PopupModeEnd()
     102             : {
     103           0 :     handlePopupEnd();
     104           0 : }
     105             : 
     106           0 : void ScMenuFloatingWindow::MouseMove(const MouseEvent& rMEvt)
     107             : {
     108           0 :     const Point& rPos = rMEvt.GetPosPixel();
     109           0 :     size_t nSelectedMenu = getEnclosingMenuItem(rPos);
     110           0 :     setSelectedMenuItem(nSelectedMenu, true, false);
     111             : 
     112           0 :     Window::MouseMove(rMEvt);
     113           0 : }
     114             : 
     115           0 : void ScMenuFloatingWindow::MouseButtonDown(const MouseEvent& rMEvt)
     116             : {
     117           0 :     const Point& rPos = rMEvt.GetPosPixel();
     118           0 :     mnClickedMenu = getEnclosingMenuItem(rPos);
     119           0 :     Window::MouseButtonDown(rMEvt);
     120           0 : }
     121             : 
     122           0 : void ScMenuFloatingWindow::MouseButtonUp(const MouseEvent& rMEvt)
     123             : {
     124           0 :     executeMenuItem(mnClickedMenu);
     125           0 :     mnClickedMenu = MENU_NOT_SELECTED;
     126           0 :     Window::MouseButtonUp(rMEvt);
     127           0 : }
     128             : 
     129           0 : void ScMenuFloatingWindow::KeyInput(const KeyEvent& rKEvt)
     130             : {
     131           0 :     if (maMenuItems.empty())
     132             :     {
     133           0 :         Window::KeyInput(rKEvt);
     134           0 :         return;
     135             :     }
     136             : 
     137           0 :     const KeyCode& rKeyCode = rKEvt.GetKeyCode();
     138           0 :     bool bHandled = true;
     139           0 :     size_t nSelectedMenu = mnSelectedMenu;
     140           0 :     size_t nLastMenuPos = maMenuItems.size() - 1;
     141           0 :     switch (rKeyCode.GetCode())
     142             :     {
     143             :         case KEY_UP:
     144             :         {
     145           0 :             if (nLastMenuPos == 0)
     146             :                 // There is only one menu item.  Do nothing.
     147           0 :                 break;
     148             : 
     149           0 :             size_t nOldPos = nSelectedMenu;
     150             : 
     151           0 :             if (nSelectedMenu == MENU_NOT_SELECTED || nSelectedMenu == 0)
     152           0 :                 nSelectedMenu = nLastMenuPos;
     153             :             else
     154           0 :                 --nSelectedMenu;
     155             : 
     156             :             // Loop until a non-separator menu item is found.
     157           0 :             while (nSelectedMenu != nOldPos)
     158             :             {
     159           0 :                 if (maMenuItems[nSelectedMenu].mbSeparator)
     160             :                 {
     161           0 :                     if (nSelectedMenu)
     162           0 :                         --nSelectedMenu;
     163             :                     else
     164           0 :                         nSelectedMenu = nLastMenuPos;
     165             :                 }
     166             :                 else
     167           0 :                     break;
     168             :             }
     169             : 
     170           0 :             setSelectedMenuItem(nSelectedMenu, false, false);
     171             :         }
     172           0 :         break;
     173             :         case KEY_DOWN:
     174             :         {
     175           0 :             if (nLastMenuPos == 0)
     176             :                 // There is only one menu item.  Do nothing.
     177           0 :                 break;
     178             : 
     179           0 :             size_t nOldPos = nSelectedMenu;
     180             : 
     181           0 :             if (nSelectedMenu == MENU_NOT_SELECTED || nSelectedMenu == nLastMenuPos)
     182           0 :                 nSelectedMenu = 0;
     183             :             else
     184           0 :                 ++nSelectedMenu;
     185             : 
     186             :             // Loop until a non-separator menu item is found.
     187           0 :             while (nSelectedMenu != nOldPos)
     188             :             {
     189           0 :                 if (maMenuItems[nSelectedMenu].mbSeparator)
     190             :                 {
     191           0 :                     if (nSelectedMenu == nLastMenuPos)
     192           0 :                         nSelectedMenu = 0;
     193             :                     else
     194           0 :                         ++nSelectedMenu;
     195             :                 }
     196             :                 else
     197           0 :                     break;
     198             :             }
     199             : 
     200           0 :             setSelectedMenuItem(nSelectedMenu, false, false);
     201             :         }
     202           0 :         break;
     203             :         case KEY_LEFT:
     204           0 :             if (mpParentMenu)
     205           0 :                 mpParentMenu->endSubMenu(this);
     206           0 :         break;
     207             :         case KEY_RIGHT:
     208             :         {
     209           0 :             if (mnSelectedMenu >= maMenuItems.size() || mnSelectedMenu == MENU_NOT_SELECTED)
     210           0 :                 break;
     211             : 
     212           0 :             const MenuItemData& rMenu = maMenuItems[mnSelectedMenu];
     213           0 :             if (!rMenu.mbEnabled || !rMenu.mpSubMenuWin)
     214           0 :                 break;
     215             : 
     216           0 :             maOpenTimer.mnMenuPos = mnSelectedMenu;
     217           0 :             maOpenTimer.mpSubMenu = rMenu.mpSubMenuWin.get();
     218           0 :             launchSubMenu(true);
     219             :         }
     220           0 :         break;
     221             :         case KEY_RETURN:
     222           0 :             if (nSelectedMenu != MENU_NOT_SELECTED)
     223           0 :                 executeMenuItem(nSelectedMenu);
     224           0 :         break;
     225             :         default:
     226           0 :             bHandled = false;
     227             :     }
     228             : 
     229           0 :     if (!bHandled)
     230           0 :         Window::KeyInput(rKEvt);
     231             : }
     232             : 
     233           0 : void ScMenuFloatingWindow::Paint(const Rectangle& /*rRect*/)
     234             : {
     235           0 :     const StyleSettings& rStyle = GetSettings().GetStyleSettings();
     236           0 :     Color aBackColor = rStyle.GetMenuColor();
     237           0 :     Color aBorderColor = rStyle.GetShadowColor();
     238             : 
     239           0 :     Rectangle aCtrlRect(Point(0, 0), GetOutputSizePixel());
     240             : 
     241             :     // Window background
     242           0 :     bool bNativeDrawn = true;
     243           0 :     if (IsNativeControlSupported(CTRL_MENU_POPUP, PART_ENTIRE_CONTROL))
     244             :     {
     245           0 :         SetClipRegion();
     246             :         bNativeDrawn = DrawNativeControl(
     247             :             CTRL_MENU_POPUP, PART_ENTIRE_CONTROL, aCtrlRect, CTRL_STATE_ENABLED,
     248           0 :             ImplControlValue(), OUString());
     249             :     }
     250             :     else
     251           0 :         bNativeDrawn = false;
     252             : 
     253           0 :     if (!bNativeDrawn)
     254             :     {
     255           0 :         SetFillColor(aBackColor);
     256           0 :         SetLineColor(aBorderColor);
     257           0 :         DrawRect(aCtrlRect);
     258             :     }
     259             : 
     260             :     // Menu items
     261           0 :     SetTextColor(rStyle.GetMenuTextColor());
     262           0 :     drawAllMenuItems();
     263           0 : }
     264             : 
     265           0 : Reference<XAccessible> ScMenuFloatingWindow::CreateAccessible()
     266             : {
     267           0 :     if (!mxAccessible.is())
     268             :     {
     269             :         Reference<XAccessible> xAccParent = mpParentMenu ?
     270           0 :             mpParentMenu->GetAccessible() : GetAccessibleParentWindow()->GetAccessible();
     271             : 
     272           0 :         mxAccessible.set(new ScAccessibleFilterMenu(xAccParent, this, maName, 999));
     273             :         ScAccessibleFilterMenu* p = static_cast<ScAccessibleFilterMenu*>(
     274           0 :             mxAccessible.get());
     275             : 
     276           0 :         vector<MenuItemData>::const_iterator itr, itrBeg = maMenuItems.begin(), itrEnd = maMenuItems.end();
     277           0 :         for (itr = itrBeg; itr != itrEnd; ++itr)
     278             :         {
     279           0 :             size_t nPos = ::std::distance(itrBeg, itr);
     280           0 :             p->appendMenuItem(itr->maText, itr->mbEnabled, nPos);
     281           0 :         }
     282             :     }
     283             : 
     284           0 :     return mxAccessible;
     285             : }
     286             : 
     287           0 : void ScMenuFloatingWindow::addMenuItem(const OUString& rText, bool bEnabled, Action* pAction)
     288             : {
     289           0 :     MenuItemData aItem;
     290           0 :     aItem.maText = rText;
     291           0 :     aItem.mbEnabled = bEnabled;
     292           0 :     aItem.mpAction.reset(pAction);
     293           0 :     maMenuItems.push_back(aItem);
     294           0 : }
     295             : 
     296           0 : void ScMenuFloatingWindow::addSeparator()
     297             : {
     298           0 :     MenuItemData aItem;
     299           0 :     aItem.mbSeparator = true;
     300           0 :     maMenuItems.push_back(aItem);
     301           0 : }
     302             : 
     303           0 : ScMenuFloatingWindow* ScMenuFloatingWindow::addSubMenuItem(const OUString& rText, bool bEnabled)
     304             : {
     305           0 :     MenuItemData aItem;
     306           0 :     aItem.maText = rText;
     307           0 :     aItem.mbEnabled = bEnabled;
     308           0 :     aItem.mpSubMenuWin.reset(new ScMenuFloatingWindow(this, mpDoc, GetMenuStackLevel()+1));
     309           0 :     aItem.mpSubMenuWin->setName(rText);
     310           0 :     maMenuItems.push_back(aItem);
     311           0 :     return aItem.mpSubMenuWin.get();
     312             : }
     313             : 
     314           0 : void ScMenuFloatingWindow::handlePopupEnd()
     315             : {
     316           0 :     clearSelectedMenuItem();
     317           0 : }
     318             : 
     319           0 : Size ScMenuFloatingWindow::getMenuSize() const
     320             : {
     321           0 :     if (maMenuItems.empty())
     322           0 :         return Size();
     323             : 
     324           0 :     vector<MenuItemData>::const_iterator itr = maMenuItems.begin(), itrEnd = maMenuItems.end();
     325           0 :     long nTextWidth = 0;
     326           0 :     for (; itr != itrEnd; ++itr)
     327             :     {
     328           0 :         if (itr->mbSeparator)
     329           0 :             continue;
     330             : 
     331           0 :         nTextWidth = ::std::max(GetTextWidth(itr->maText), nTextWidth);
     332             :     }
     333             : 
     334           0 :     size_t nLastPos = maMenuItems.size()-1;
     335           0 :     Point aPos;
     336           0 :     Size aSize;
     337           0 :     getMenuItemPosSize(nLastPos, aPos, aSize);
     338           0 :     aPos.X() += nTextWidth + 15;
     339           0 :     aPos.Y() += aSize.Height() + 5;
     340           0 :     return Size(aPos.X(), aPos.Y());
     341             : }
     342             : 
     343           0 : void ScMenuFloatingWindow::drawMenuItem(size_t nPos)
     344             : {
     345           0 :     if (nPos >= maMenuItems.size())
     346           0 :         return;
     347             : 
     348           0 :     Point aPos;
     349           0 :     Size aSize;
     350           0 :     getMenuItemPosSize(nPos, aPos, aSize);
     351             : 
     352           0 :     DecorationView aDecoView(this);
     353           0 :     long nXOffset = 5;
     354           0 :     long nYOffset = (aSize.Height() - maLabelFont.GetHeight())/2;
     355           0 :     DrawCtrlText(Point(aPos.X()+nXOffset, aPos.Y() + nYOffset), maMenuItems[nPos].maText, 0,
     356           0 :                  maMenuItems[nPos].maText.getLength(),
     357           0 :                  maMenuItems[nPos].mbEnabled ? TEXT_DRAW_MNEMONIC : TEXT_DRAW_DISABLE);
     358             : 
     359           0 :     if (maMenuItems[nPos].mpSubMenuWin)
     360             :     {
     361           0 :         long nFontHeight = maLabelFont.GetHeight();
     362           0 :         Point aMarkerPos = aPos;
     363           0 :         aMarkerPos.Y() += aSize.Height()/2 - nFontHeight/4 + 1;
     364           0 :         aMarkerPos.X() += aSize.Width() - nFontHeight + nFontHeight/4;
     365           0 :         Size aMarkerSize(nFontHeight/2, nFontHeight/2);
     366             :         aDecoView.DrawSymbol(Rectangle(aMarkerPos, aMarkerSize),
     367           0 :                              SYMBOL_SPIN_RIGHT, GetTextColor(), 0);
     368             :     }
     369             : }
     370             : 
     371           0 : void ScMenuFloatingWindow::drawSeparator(size_t nPos)
     372             : {
     373           0 :     Point aPos;
     374           0 :     Size aSize;
     375           0 :     getMenuItemPosSize(nPos, aPos, aSize);
     376           0 :     Rectangle aRegion(aPos,aSize);
     377             : 
     378           0 :     if (IsNativeControlSupported(CTRL_MENU_POPUP, PART_ENTIRE_CONTROL))
     379             :     {
     380           0 :         Push(PUSH_CLIPREGION);
     381           0 :         IntersectClipRegion(aRegion);
     382           0 :         Rectangle aCtrlRect(Point(0,0), GetOutputSizePixel());
     383             :         DrawNativeControl(
     384             :             CTRL_MENU_POPUP, PART_ENTIRE_CONTROL, aCtrlRect, CTRL_STATE_ENABLED,
     385           0 :             ImplControlValue(), OUString());
     386             : 
     387           0 :         Pop();
     388             :     }
     389             : 
     390           0 :     bool bNativeDrawn = false;
     391           0 :     if (IsNativeControlSupported(CTRL_MENU_POPUP, PART_MENU_SEPARATOR))
     392             :     {
     393           0 :         ControlState nState = 0;
     394           0 :         const MenuItemData& rData = maMenuItems[nPos];
     395           0 :         if (rData.mbEnabled)
     396           0 :             nState |= CTRL_STATE_ENABLED;
     397             : 
     398             :         bNativeDrawn = DrawNativeControl(
     399             :             CTRL_MENU_POPUP, PART_MENU_SEPARATOR,
     400           0 :             aRegion, nState, ImplControlValue(), OUString());
     401             :     }
     402             : 
     403           0 :     if (!bNativeDrawn)
     404             :     {
     405           0 :         const StyleSettings& rStyle = GetSettings().GetStyleSettings();
     406           0 :         Point aTmpPos = aPos;
     407           0 :         aTmpPos.Y() += aSize.Height()/2;
     408           0 :         SetLineColor(rStyle.GetShadowColor());
     409           0 :         DrawLine(aTmpPos, Point(aSize.Width()+aTmpPos.X(), aTmpPos.Y()));
     410           0 :         ++aTmpPos.Y();
     411           0 :         SetLineColor(rStyle.GetLightColor());
     412           0 :         DrawLine(aTmpPos, Point(aSize.Width()+aTmpPos.X(), aTmpPos.Y()));
     413           0 :         SetLineColor();
     414             :     }
     415           0 : }
     416             : 
     417           0 : void ScMenuFloatingWindow::drawAllMenuItems()
     418             : {
     419           0 :     size_t n = maMenuItems.size();
     420           0 :     for (size_t i = 0; i < n; ++i)
     421             :     {
     422           0 :         if (maMenuItems[i].mbSeparator)
     423             :             // Separator
     424           0 :             drawSeparator(i);
     425             :         else
     426             :             // Normal menu item
     427           0 :             highlightMenuItem(i, i == mnSelectedMenu);
     428             :     }
     429           0 : }
     430             : 
     431           0 : const Font& ScMenuFloatingWindow::getLabelFont() const
     432             : {
     433           0 :     return maLabelFont;
     434             : }
     435             : 
     436           0 : void ScMenuFloatingWindow::executeMenuItem(size_t nPos)
     437             : {
     438           0 :     if (nPos >= maMenuItems.size())
     439           0 :         return;
     440             : 
     441           0 :     if (!maMenuItems[nPos].mpAction)
     442             :         // no action is defined.
     443           0 :         return;
     444             : 
     445           0 :     maMenuItems[nPos].mpAction->execute();
     446           0 :     terminateAllPopupMenus();
     447             : }
     448             : 
     449           0 : void ScMenuFloatingWindow::setSelectedMenuItem(size_t nPos, bool bSubMenuTimer, bool bEnsureSubMenu)
     450             : {
     451           0 :     if (mnSelectedMenu == nPos)
     452             :         // nothing to do.
     453           0 :         return;
     454             : 
     455           0 :     if (bEnsureSubMenu)
     456             :     {
     457             :         // Dismiss any child popup menu windows.
     458           0 :         if (mnSelectedMenu < maMenuItems.size() &&
     459           0 :             maMenuItems[mnSelectedMenu].mpSubMenuWin &&
     460           0 :             maMenuItems[mnSelectedMenu].mpSubMenuWin->IsVisible())
     461             :         {
     462           0 :             maMenuItems[mnSelectedMenu].mpSubMenuWin->ensureSubMenuNotVisible();
     463             :         }
     464             : 
     465             :         // The popup is not visible, yet a menu item is selected.  The request
     466             :         // most likely comes from the accessible object.  Make sure this
     467             :         // window, as well as all its parent windows are visible.
     468           0 :         if (!IsVisible() && mpParentMenu)
     469           0 :             mpParentMenu->ensureSubMenuVisible(this);
     470             :     }
     471             : 
     472           0 :     selectMenuItem(mnSelectedMenu, false, bSubMenuTimer);
     473           0 :     selectMenuItem(nPos, true, bSubMenuTimer);
     474           0 :     mnSelectedMenu = nPos;
     475             : 
     476           0 :     fireMenuHighlightedEvent();
     477             : }
     478             : 
     479           0 : size_t ScMenuFloatingWindow::getSelectedMenuItem() const
     480             : {
     481           0 :     return mnSelectedMenu;
     482             : }
     483             : 
     484           0 : void ScMenuFloatingWindow::handleMenuTimeout(SubMenuItemData* pTimer)
     485             : {
     486           0 :     if (pTimer == &maOpenTimer)
     487             :     {
     488             :         // Close any open submenu immediately.
     489           0 :         if (maCloseTimer.mpSubMenu)
     490             :         {
     491           0 :             maCloseTimer.mpSubMenu->EndPopupMode();
     492           0 :             maCloseTimer.mpSubMenu = NULL;
     493           0 :             maCloseTimer.maTimer.Stop();
     494             :         }
     495             : 
     496           0 :         launchSubMenu(false);
     497             :     }
     498           0 :     else if (pTimer == &maCloseTimer)
     499             :     {
     500             :         // end submenu.
     501           0 :         if (maCloseTimer.mpSubMenu)
     502             :         {
     503           0 :             maOpenTimer.mpSubMenu = NULL;
     504             : 
     505           0 :             maCloseTimer.mpSubMenu->EndPopupMode();
     506           0 :             maCloseTimer.mpSubMenu = NULL;
     507             : 
     508           0 :             highlightMenuItem(maOpenTimer.mnMenuPos, false);
     509           0 :             maOpenTimer.mnMenuPos = MENU_NOT_SELECTED;
     510             :         }
     511             :     }
     512           0 : }
     513             : 
     514           0 : void ScMenuFloatingWindow::queueLaunchSubMenu(size_t nPos, ScMenuFloatingWindow* pMenu)
     515             : {
     516           0 :     if (!pMenu)
     517           0 :         return;
     518             : 
     519             :     // Set the submenu on launch queue.
     520           0 :     if (maOpenTimer.mpSubMenu)
     521             :     {
     522           0 :         if (maOpenTimer.mpSubMenu == pMenu)
     523             :         {
     524           0 :             if (pMenu == maCloseTimer.mpSubMenu)
     525           0 :                 maCloseTimer.reset();
     526           0 :             return;
     527             :         }
     528             : 
     529             :         // new submenu is being requested.
     530           0 :         queueCloseSubMenu();
     531             :     }
     532             : 
     533           0 :     maOpenTimer.mpSubMenu = pMenu;
     534           0 :     maOpenTimer.mnMenuPos = nPos;
     535           0 :     maOpenTimer.maTimer.Start();
     536             : }
     537             : 
     538           0 : void ScMenuFloatingWindow::queueCloseSubMenu()
     539             : {
     540           0 :     if (!maOpenTimer.mpSubMenu)
     541             :         // There is no submenu to close.
     542           0 :         return;
     543             : 
     544             :     // Stop any submenu on queue for opening.
     545           0 :     maOpenTimer.maTimer.Stop();
     546             : 
     547           0 :     maCloseTimer.mpSubMenu = maOpenTimer.mpSubMenu;
     548           0 :     maCloseTimer.mnMenuPos = maOpenTimer.mnMenuPos;
     549           0 :     maCloseTimer.maTimer.Start();
     550             : }
     551             : 
     552           0 : void ScMenuFloatingWindow::launchSubMenu(bool bSetMenuPos)
     553             : {
     554           0 :     Point aPos;
     555           0 :     Size aSize;
     556           0 :     getMenuItemPosSize(maOpenTimer.mnMenuPos, aPos, aSize);
     557           0 :     ScMenuFloatingWindow* pSubMenu = maOpenTimer.mpSubMenu;
     558             : 
     559           0 :     if (!pSubMenu)
     560           0 :         return;
     561             : 
     562           0 :     sal_uInt32 nOldFlags = GetPopupModeFlags();
     563           0 :     SetPopupModeFlags(nOldFlags | FLOATWIN_POPUPMODE_NOAPPFOCUSCLOSE);
     564           0 :     pSubMenu->resizeToFitMenuItems(); // set the size before launching the popup to get it positioned correctly.
     565             :     pSubMenu->StartPopupMode(
     566           0 :         Rectangle(aPos,aSize), (FLOATWIN_POPUPMODE_RIGHT | FLOATWIN_POPUPMODE_GRABFOCUS));
     567           0 :     pSubMenu->AddPopupModeWindow(this);
     568           0 :     if (bSetMenuPos)
     569           0 :         pSubMenu->setSelectedMenuItem(0, false, false); // select menu item after the popup becomes fully visible.
     570           0 :     SetPopupModeFlags(nOldFlags);
     571             : }
     572             : 
     573           0 : void ScMenuFloatingWindow::endSubMenu(ScMenuFloatingWindow* pSubMenu)
     574             : {
     575           0 :     if (!pSubMenu)
     576           0 :         return;
     577             : 
     578           0 :     pSubMenu->EndPopupMode();
     579           0 :     maOpenTimer.reset();
     580             : 
     581           0 :     size_t nMenuPos = getSubMenuPos(pSubMenu);
     582           0 :     if (nMenuPos != MENU_NOT_SELECTED)
     583             :     {
     584           0 :         highlightMenuItem(nMenuPos, true);
     585           0 :         mnSelectedMenu = nMenuPos;
     586           0 :         fireMenuHighlightedEvent();
     587             :     }
     588             : }
     589             : 
     590           0 : void ScMenuFloatingWindow::fillMenuItemsToAccessible(ScAccessibleFilterMenu* pAccMenu) const
     591             : {
     592           0 :     vector<MenuItemData>::const_iterator itr, itrBeg = maMenuItems.begin(), itrEnd = maMenuItems.end();
     593           0 :     for (itr = itrBeg; itr != itrEnd; ++itr)
     594             :     {
     595           0 :         size_t nPos = ::std::distance(itrBeg, itr);
     596           0 :         pAccMenu->appendMenuItem(itr->maText, itr->mbEnabled, nPos);
     597             :     }
     598           0 : }
     599             : 
     600           0 : void ScMenuFloatingWindow::resizeToFitMenuItems()
     601             : {
     602           0 :     SetOutputSizePixel(getMenuSize());
     603           0 : }
     604             : 
     605           0 : void ScMenuFloatingWindow::selectMenuItem(size_t nPos, bool bSelected, bool bSubMenuTimer)
     606             : {
     607           0 :     if (nPos >= maMenuItems.size() || nPos == MENU_NOT_SELECTED)
     608             :     {
     609           0 :         queueCloseSubMenu();
     610           0 :         return;
     611             :     }
     612             : 
     613           0 :     if (!maMenuItems[nPos].mbEnabled)
     614             :     {
     615           0 :         queueCloseSubMenu();
     616           0 :         return;
     617             :     }
     618             : 
     619           0 :     highlightMenuItem(nPos, bSelected);
     620             : 
     621           0 :     if (bSelected)
     622             :     {
     623           0 :         if (mpParentMenu)
     624           0 :             mpParentMenu->setSubMenuFocused(this);
     625             : 
     626           0 :         if (bSubMenuTimer)
     627             :         {
     628           0 :             if (maMenuItems[nPos].mpSubMenuWin)
     629             :             {
     630           0 :                 ScMenuFloatingWindow* pSubMenu = maMenuItems[nPos].mpSubMenuWin.get();
     631           0 :                 queueLaunchSubMenu(nPos, pSubMenu);
     632             :             }
     633             :             else
     634           0 :                 queueCloseSubMenu();
     635             :         }
     636             :     }
     637             : }
     638             : 
     639           0 : void ScMenuFloatingWindow::clearSelectedMenuItem()
     640             : {
     641           0 :     selectMenuItem(mnSelectedMenu, false, false);
     642           0 :     mnSelectedMenu = MENU_NOT_SELECTED;
     643           0 : }
     644             : 
     645           0 : ScMenuFloatingWindow* ScMenuFloatingWindow::getSubMenuWindow(size_t nPos) const
     646             : {
     647           0 :     if (maMenuItems.size() <= nPos)
     648           0 :         return NULL;
     649             : 
     650           0 :     return maMenuItems[nPos].mpSubMenuWin.get();
     651             : }
     652             : 
     653           0 : bool ScMenuFloatingWindow::isMenuItemSelected(size_t nPos) const
     654             : {
     655           0 :     return nPos == mnSelectedMenu;
     656             : }
     657             : 
     658           0 : void ScMenuFloatingWindow::setName(const OUString& rName)
     659             : {
     660           0 :     maName = rName;
     661           0 : }
     662             : 
     663           0 : const OUString& ScMenuFloatingWindow::getName() const
     664             : {
     665           0 :     return maName;
     666             : }
     667             : 
     668           0 : void ScMenuFloatingWindow::highlightMenuItem(size_t nPos, bool bSelected)
     669             : {
     670           0 :     if (nPos == MENU_NOT_SELECTED)
     671           0 :         return;
     672             : 
     673           0 :     const StyleSettings& rStyle = GetSettings().GetStyleSettings();
     674           0 :     Color aBackColor = rStyle.GetMenuColor();
     675           0 :     SetFillColor(aBackColor);
     676           0 :     SetLineColor(aBackColor);
     677             : 
     678           0 :     Point aPos;
     679           0 :     Size aSize;
     680           0 :     getMenuItemPosSize(nPos, aPos, aSize);
     681           0 :     Rectangle aRegion(aPos,aSize);
     682             : 
     683           0 :     if (IsNativeControlSupported(CTRL_MENU_POPUP, PART_ENTIRE_CONTROL))
     684             :     {
     685           0 :         Push(PUSH_CLIPREGION);
     686           0 :         IntersectClipRegion(Rectangle(aPos, aSize));
     687           0 :         Rectangle aCtrlRect(Point(0,0), GetOutputSizePixel());
     688             :         DrawNativeControl(
     689             :             CTRL_MENU_POPUP, PART_ENTIRE_CONTROL, aCtrlRect, CTRL_STATE_ENABLED,
     690           0 :             ImplControlValue(), OUString());
     691             : 
     692           0 :         Pop();
     693             :     }
     694             : 
     695           0 :     bool bNativeDrawn = true;
     696           0 :     if (IsNativeControlSupported(CTRL_MENU_POPUP, PART_MENU_ITEM))
     697             :     {
     698           0 :         ControlState nState = bSelected ? CTRL_STATE_SELECTED : 0;
     699           0 :         if (maMenuItems[nPos].mbEnabled)
     700           0 :             nState |= CTRL_STATE_ENABLED;
     701             :         bNativeDrawn = DrawNativeControl(
     702           0 :             CTRL_MENU_POPUP, PART_MENU_ITEM, aRegion, nState, ImplControlValue(), OUString());
     703             :     }
     704             :     else
     705           0 :         bNativeDrawn = false;
     706             : 
     707           0 :     if (!bNativeDrawn)
     708             :     {
     709           0 :         if (bSelected)
     710             :         {
     711           0 :             aBackColor = rStyle.GetMenuHighlightColor();
     712           0 :             SetFillColor(aBackColor);
     713           0 :             SetLineColor(aBackColor);
     714             :         }
     715           0 :         DrawRect(Rectangle(aPos,aSize));
     716             :     }
     717             : 
     718           0 :     Color aTextColor = bSelected ? rStyle.GetMenuHighlightTextColor() : rStyle.GetMenuTextColor();
     719           0 :     SetTextColor(aTextColor);
     720           0 :     drawMenuItem(nPos);
     721             : }
     722             : 
     723           0 : void ScMenuFloatingWindow::getMenuItemPosSize(size_t nPos, Point& rPos, Size& rSize) const
     724             : {
     725           0 :     size_t nCount = maMenuItems.size();
     726           0 :     if (nPos >= nCount)
     727           0 :         return;
     728             : 
     729           0 :     const sal_uInt16 nLeftMargin = 5;
     730           0 :     const sal_uInt16 nTopMargin = 5;
     731           0 :     const sal_uInt16 nMenuItemHeight = static_cast<sal_uInt16>(maLabelFont.GetHeight()*1.8);
     732           0 :     const sal_uInt16 nSepHeight = static_cast<sal_uInt16>(maLabelFont.GetHeight()*0.8);
     733             : 
     734           0 :     Point aPos1(nLeftMargin, nTopMargin);
     735           0 :     rPos = aPos1;
     736           0 :     for (size_t i = 0; i < nPos; ++i)
     737           0 :         rPos.Y() += maMenuItems[i].mbSeparator ? nSepHeight : nMenuItemHeight;
     738             : 
     739           0 :     Size aWndSize = GetSizePixel();
     740           0 :     sal_uInt16 nH = maMenuItems[nPos].mbSeparator ? nSepHeight : nMenuItemHeight;
     741           0 :     rSize = Size(aWndSize.Width() - nLeftMargin*2, nH);
     742             : }
     743             : 
     744           0 : ScMenuFloatingWindow* ScMenuFloatingWindow::getParentMenuWindow() const
     745             : {
     746           0 :     return mpParentMenu;
     747             : }
     748             : 
     749           0 : size_t ScMenuFloatingWindow::getEnclosingMenuItem(const Point& rPos) const
     750             : {
     751           0 :     size_t n = maMenuItems.size();
     752           0 :     for (size_t i = 0; i < n; ++i)
     753             :     {
     754           0 :         Point aPos;
     755           0 :         Size aSize;
     756           0 :         getMenuItemPosSize(i, aPos, aSize);
     757           0 :         Rectangle aRect(aPos, aSize);
     758           0 :         if (aRect.IsInside(rPos))
     759           0 :             return maMenuItems[i].mbSeparator ? MENU_NOT_SELECTED : i;
     760             :     }
     761           0 :     return MENU_NOT_SELECTED;
     762             : }
     763             : 
     764           0 : size_t ScMenuFloatingWindow::getSubMenuPos(ScMenuFloatingWindow* pSubMenu)
     765             : {
     766           0 :     size_t n = maMenuItems.size();
     767           0 :     for (size_t i = 0; i < n; ++i)
     768             :     {
     769           0 :         if (maMenuItems[i].mpSubMenuWin.get() == pSubMenu)
     770           0 :             return i;
     771             :     }
     772           0 :     return MENU_NOT_SELECTED;
     773             : }
     774             : 
     775           0 : void ScMenuFloatingWindow::fireMenuHighlightedEvent()
     776             : {
     777           0 :     if (mnSelectedMenu == MENU_NOT_SELECTED)
     778           0 :         return;
     779             : 
     780           0 :     if (!mxAccessible.is())
     781           0 :         return;
     782             : 
     783           0 :     Reference<XAccessibleContext> xAccCxt = mxAccessible->getAccessibleContext();
     784           0 :     if (!xAccCxt.is())
     785           0 :         return;
     786             : 
     787           0 :     Reference<XAccessible> xAccMenu = xAccCxt->getAccessibleChild(mnSelectedMenu);
     788           0 :     if (!xAccMenu.is())
     789           0 :         return;
     790             : 
     791           0 :     VclAccessibleEvent aEvent(VCLEVENT_MENU_HIGHLIGHT, xAccMenu);
     792           0 :     FireVclEvent(&aEvent);
     793             : }
     794             : 
     795           0 : void ScMenuFloatingWindow::setSubMenuFocused(ScMenuFloatingWindow* pSubMenu)
     796             : {
     797           0 :     maCloseTimer.reset();
     798           0 :     size_t nMenuPos = getSubMenuPos(pSubMenu);
     799           0 :     if (mnSelectedMenu != nMenuPos)
     800             :     {
     801           0 :         highlightMenuItem(nMenuPos, true);
     802           0 :         mnSelectedMenu = nMenuPos;
     803             :     }
     804           0 : }
     805             : 
     806           0 : void ScMenuFloatingWindow::ensureSubMenuVisible(ScMenuFloatingWindow* pSubMenu)
     807             : {
     808           0 :     if (mpParentMenu)
     809           0 :         mpParentMenu->ensureSubMenuVisible(this);
     810             : 
     811           0 :     if (pSubMenu->IsVisible())
     812           0 :         return;
     813             : 
     814             :     // Find the menu position of the submenu.
     815           0 :     size_t nMenuPos = getSubMenuPos(pSubMenu);
     816           0 :     if (nMenuPos != MENU_NOT_SELECTED)
     817             :     {
     818           0 :         setSelectedMenuItem(nMenuPos, false, false);
     819             : 
     820           0 :         Point aPos;
     821           0 :         Size aSize;
     822           0 :         getMenuItemPosSize(nMenuPos, aPos, aSize);
     823             : 
     824           0 :         sal_uInt32 nOldFlags = GetPopupModeFlags();
     825           0 :         SetPopupModeFlags(nOldFlags | FLOATWIN_POPUPMODE_NOAPPFOCUSCLOSE);
     826           0 :         pSubMenu->resizeToFitMenuItems(); // set the size before launching the popup to get it positioned correctly.
     827             :         pSubMenu->StartPopupMode(
     828           0 :             Rectangle(aPos,aSize), (FLOATWIN_POPUPMODE_RIGHT | FLOATWIN_POPUPMODE_GRABFOCUS));
     829           0 :         pSubMenu->AddPopupModeWindow(this);
     830           0 :         SetPopupModeFlags(nOldFlags);
     831             :     }
     832             : }
     833             : 
     834           0 : void ScMenuFloatingWindow::ensureSubMenuNotVisible()
     835             : {
     836           0 :     if (mnSelectedMenu <= maMenuItems.size() &&
     837           0 :         maMenuItems[mnSelectedMenu].mpSubMenuWin &&
     838           0 :         maMenuItems[mnSelectedMenu].mpSubMenuWin->IsVisible())
     839             :     {
     840           0 :         maMenuItems[mnSelectedMenu].mpSubMenuWin->ensureSubMenuNotVisible();
     841             :     }
     842             : 
     843           0 :     EndPopupMode();
     844           0 : }
     845             : 
     846           0 : void ScMenuFloatingWindow::terminateAllPopupMenus()
     847             : {
     848           0 :     EndPopupMode();
     849           0 :     if (mpParentMenu)
     850           0 :         mpParentMenu->terminateAllPopupMenus();
     851           0 : }
     852             : 
     853           0 : ScDocument* ScMenuFloatingWindow::getDoc()
     854             : {
     855           0 :     return mpDoc;
     856             : }
     857             : 
     858           0 : ScCheckListMenuWindow::Config::Config() :
     859           0 :     mbAllowEmptySet(true), mbRTL(false)
     860             : {
     861           0 : }
     862             : 
     863           0 : ScCheckListMenuWindow::Member::Member() :
     864           0 :     mbVisible(true), mbDate(false), mbLeaf(false)
     865             : {
     866           0 : }
     867             : 
     868           0 : ScCheckListMenuWindow::CancelButton::CancelButton(ScCheckListMenuWindow* pParent) :
     869           0 :     ::CancelButton(pParent), mpParent(pParent) {}
     870             : 
     871           0 : void ScCheckListMenuWindow::CancelButton::Click()
     872             : {
     873           0 :     mpParent->EndPopupMode();
     874           0 :     ::CancelButton::Click();
     875           0 : }
     876             : 
     877           0 : ScCheckListMenuWindow::ScCheckListMenuWindow(Window* pParent, ScDocument* pDoc) :
     878             :     ScMenuFloatingWindow(pParent, pDoc),
     879             :     maChecks(this,  WB_HASBUTTONS | WB_HASLINES | WB_HASLINESATROOT | WB_HASBUTTONSATROOT ),
     880             :     maChkToggleAll(this, 0),
     881             :     maBtnSelectSingle  (this, 0),
     882             :     maBtnUnselectSingle(this, 0),
     883             :     maBtnOk(this),
     884             :     maBtnCancel(this),
     885             :     mnCurTabStop(0),
     886             :     mpExtendedData(NULL),
     887             :     mpOKAction(NULL),
     888             :     mpPopupEndAction(NULL),
     889             :     maWndSize(200, 330),
     890           0 :     mePrevToggleAllState(TRISTATE_INDET)
     891             : {
     892           0 :     maTabStopCtrls.reserve(7);
     893           0 :     maTabStopCtrls.push_back(this);
     894           0 :     maTabStopCtrls.push_back(&maChecks);
     895           0 :     maTabStopCtrls.push_back(&maChkToggleAll);
     896           0 :     maTabStopCtrls.push_back(&maBtnSelectSingle);
     897           0 :     maTabStopCtrls.push_back(&maBtnUnselectSingle);
     898           0 :     maTabStopCtrls.push_back(&maBtnOk);
     899           0 :     maTabStopCtrls.push_back(&maBtnCancel);
     900             : 
     901             :     // Enable type-ahead search in the check list box.
     902           0 :     maChecks.SetStyle(maChecks.GetStyle() | WB_QUICK_SEARCH);
     903           0 : }
     904             : 
     905           0 : ScCheckListMenuWindow::~ScCheckListMenuWindow()
     906             : {
     907           0 : }
     908             : 
     909           0 : void ScCheckListMenuWindow::getSectionPosSize(
     910             :     Point& rPos, Size& rSize, SectionType eType) const
     911             : {
     912             :     // constant parameters.
     913           0 :     const long nListBoxMargin = 5;            // horizontal distance from the side of the dialog to the listbox border.
     914           0 :     const long nListBoxInnerPadding = 5;
     915           0 :     const long nTopMargin = 5;
     916           0 :     const long nMenuHeight = maMenuSize.getHeight();
     917           0 :     const long nSingleItemBtnAreaHeight = 32; // height of the middle area below the list box where the single-action buttons are.
     918           0 :     const long nBottomBtnAreaHeight = 50;     // height of the bottom area where the OK and Cancel buttons are.
     919           0 :     const long nBtnWidth = 90;
     920           0 :     const long nLabelHeight = getLabelFont().GetHeight();
     921           0 :     const long nBtnHeight = nLabelHeight*2;
     922           0 :     const long nBottomMargin = 10;
     923           0 :     const long nMenuListMargin = 5;
     924             : 
     925             :     // parameters calculated from constants.
     926           0 :     const long nListBoxWidth = maWndSize.Width() - nListBoxMargin*2;
     927           0 :     const long nListBoxHeight = maWndSize.Height() - nTopMargin - nMenuHeight -
     928           0 :         nMenuListMargin - nSingleItemBtnAreaHeight - nBottomBtnAreaHeight;
     929             : 
     930           0 :     const long nSingleBtnAreaY = nTopMargin + nMenuHeight + nListBoxHeight + nMenuListMargin - 1;
     931             : 
     932           0 :     switch (eType)
     933             :     {
     934             :         case WHOLE:
     935             :         {
     936           0 :             rPos  = Point(0, 0);
     937           0 :             rSize = maWndSize;
     938             :         }
     939           0 :         break;
     940             :         case LISTBOX_AREA_OUTER:
     941             :         {
     942           0 :             rPos = Point(nListBoxMargin, nTopMargin + nMenuHeight + nMenuListMargin);
     943           0 :             rSize = Size(nListBoxWidth, nListBoxHeight);
     944             :         }
     945           0 :         break;
     946             :         case LISTBOX_AREA_INNER:
     947             :         {
     948           0 :             rPos = Point(nListBoxMargin, nTopMargin + nMenuHeight + nMenuListMargin);
     949           0 :             rPos.X() += nListBoxInnerPadding;
     950           0 :             rPos.Y() += nListBoxInnerPadding;
     951             : 
     952           0 :             rSize = Size(nListBoxWidth, nListBoxHeight);
     953           0 :             rSize.Width()  -= nListBoxInnerPadding*2;
     954           0 :             rSize.Height() -= nListBoxInnerPadding*2;
     955             :         }
     956           0 :         break;
     957             :         case SINGLE_BTN_AREA:
     958             :         {
     959           0 :             rPos = Point(nListBoxMargin, nSingleBtnAreaY);
     960           0 :             rSize = Size(nListBoxWidth, nSingleItemBtnAreaHeight);
     961             :         }
     962           0 :         break;
     963             :         case CHECK_TOGGLE_ALL:
     964             :         {
     965           0 :             long h = std::min(maChkToggleAll.CalcMinimumSize().Height(), 26L);
     966           0 :             rPos = Point(nListBoxMargin, nSingleBtnAreaY);
     967           0 :             rPos.X() += 5;
     968           0 :             rPos.Y() += (nSingleItemBtnAreaHeight - h)/2;
     969           0 :             rSize = Size(70, h);
     970             :         }
     971           0 :         break;
     972             :         case BTN_SINGLE_SELECT:
     973             :         {
     974           0 :             long h = 26;
     975           0 :             rPos = Point(nListBoxMargin, nSingleBtnAreaY);
     976           0 :             rPos.X() += nListBoxWidth - h - 10 - h - 10;
     977           0 :             rPos.Y() += (nSingleItemBtnAreaHeight - h)/2;
     978           0 :             rSize = Size(h, h);
     979             :         }
     980           0 :         break;
     981             :         case BTN_SINGLE_UNSELECT:
     982             :         {
     983           0 :             long h = 26;
     984           0 :             rPos = Point(nListBoxMargin, nSingleBtnAreaY);
     985           0 :             rPos.X() += nListBoxWidth - h - 10;
     986           0 :             rPos.Y() += (nSingleItemBtnAreaHeight - h)/2;
     987           0 :             rSize = Size(h, h);
     988             :         }
     989           0 :         break;
     990             :         case BTN_OK:
     991             :         {
     992           0 :             long x = (maWndSize.Width() - nBtnWidth*2)/3;
     993           0 :             long y = maWndSize.Height() - nBottomMargin - nBtnHeight;
     994           0 :             rPos = Point(x, y);
     995           0 :             rSize = Size(nBtnWidth, nBtnHeight);
     996             :         }
     997           0 :         break;
     998             :         case BTN_CANCEL:
     999             :         {
    1000           0 :             long x = (maWndSize.Width() - nBtnWidth*2)/3*2 + nBtnWidth;
    1001           0 :             long y = maWndSize.Height() - nBottomMargin - nBtnHeight;
    1002           0 :             rPos = Point(x, y);
    1003           0 :             rSize = Size(nBtnWidth, nBtnHeight);
    1004             :         }
    1005           0 :         break;
    1006             :         default:
    1007             :             ;
    1008             :     }
    1009           0 : }
    1010             : 
    1011           0 : void ScCheckListMenuWindow::packWindow()
    1012             : {
    1013           0 :     maMenuSize = getMenuSize();
    1014             : 
    1015           0 :     if (maWndSize.Width() < maMenuSize.Width())
    1016             :         // Widen the window to fit the menu items.
    1017           0 :         maWndSize.Width() = maMenuSize.Width();
    1018             : 
    1019             :     // Set proper window height based on the number of menu items.
    1020           0 :     if (maWndSize.Height() < maMenuSize.Height()*2.8)
    1021           0 :         maWndSize.Height() = maMenuSize.Height()*2.8;
    1022             : 
    1023             :     // TODO: Make sure the window height never exceeds the height of the
    1024             :     // screen. Also do adjustment based on the number of check box items.
    1025             : 
    1026           0 :     SetOutputSizePixel(maWndSize);
    1027             : 
    1028           0 :     const StyleSettings& rStyle = GetSettings().GetStyleSettings();
    1029             : 
    1030           0 :     Point aPos;
    1031           0 :     Size aSize;
    1032           0 :     getSectionPosSize(aPos, aSize, WHOLE);
    1033           0 :     SetOutputSizePixel(aSize);
    1034             : 
    1035           0 :     getSectionPosSize(aPos, aSize, BTN_OK);
    1036           0 :     maBtnOk.SetPosSizePixel(aPos, aSize);
    1037           0 :     maBtnOk.SetFont(getLabelFont());
    1038           0 :     maBtnOk.SetClickHdl( LINK(this, ScCheckListMenuWindow, ButtonHdl) );
    1039           0 :     maBtnOk.Show();
    1040             : 
    1041           0 :     getSectionPosSize(aPos, aSize, BTN_CANCEL);
    1042           0 :     maBtnCancel.SetPosSizePixel(aPos, aSize);
    1043           0 :     maBtnCancel.SetFont(getLabelFont());
    1044           0 :     maBtnCancel.Show();
    1045             : 
    1046           0 :     getSectionPosSize(aPos, aSize, LISTBOX_AREA_INNER);
    1047           0 :     maChecks.SetPosSizePixel(aPos, aSize);
    1048           0 :     maChecks.SetFont(getLabelFont());
    1049           0 :     maChecks.SetCheckButtonHdl( LINK(this, ScCheckListMenuWindow, CheckHdl) );
    1050           0 :     maChecks.Show();
    1051             : 
    1052           0 :     getSectionPosSize(aPos, aSize, CHECK_TOGGLE_ALL);
    1053           0 :     maChkToggleAll.SetPosSizePixel(aPos, aSize);
    1054           0 :     maChkToggleAll.SetFont(getLabelFont());
    1055           0 :     maChkToggleAll.SetText(SC_STRLOAD(RID_POPUP_FILTER, STR_BTN_TOGGLE_ALL));
    1056           0 :     maChkToggleAll.SetTextColor(rStyle.GetMenuTextColor());
    1057           0 :     maChkToggleAll.SetControlBackground(rStyle.GetMenuColor());
    1058           0 :     maChkToggleAll.SetClickHdl( LINK(this, ScCheckListMenuWindow, TriStateHdl) );
    1059           0 :     maChkToggleAll.Show();
    1060             : 
    1061           0 :     getSectionPosSize(aPos, aSize, BTN_SINGLE_SELECT);
    1062           0 :     maBtnSelectSingle.SetPosSizePixel(aPos, aSize);
    1063           0 :     maBtnSelectSingle.SetQuickHelpText(SC_STRLOAD(RID_POPUP_FILTER, STR_BTN_SELECT_CURRENT));
    1064           0 :     maBtnSelectSingle.SetModeImage(Image(ScResId(RID_IMG_SELECT_CURRENT)));
    1065           0 :     maBtnSelectSingle.SetClickHdl( LINK(this, ScCheckListMenuWindow, ButtonHdl) );
    1066           0 :     maBtnSelectSingle.Show();
    1067             : 
    1068           0 :     getSectionPosSize(aPos, aSize, BTN_SINGLE_UNSELECT);
    1069           0 :     maBtnUnselectSingle.SetPosSizePixel(aPos, aSize);
    1070           0 :     maBtnUnselectSingle.SetQuickHelpText(SC_STRLOAD(RID_POPUP_FILTER, STR_BTN_UNSELECT_CURRENT));
    1071           0 :     maBtnUnselectSingle.SetModeImage(Image(ScResId(RID_IMG_UNSELECT_CURRENT)));
    1072           0 :     maBtnUnselectSingle.SetClickHdl( LINK(this, ScCheckListMenuWindow, ButtonHdl) );
    1073           0 :     maBtnUnselectSingle.Show();
    1074           0 : }
    1075             : 
    1076           0 : void ScCheckListMenuWindow::setAllMemberState(bool bSet)
    1077             : {
    1078           0 :     size_t n = maMembers.size();
    1079           0 :     for (size_t i = 0; i < n; ++i)
    1080           0 :         maChecks.CheckEntry( maMembers[i].maName, maMembers[i].mpParent, bSet);
    1081             : 
    1082           0 :     if (!maConfig.mbAllowEmptySet)
    1083             :         // We need to have at least one member selected.
    1084           0 :         maBtnOk.Enable(maChecks.GetCheckedEntryCount() != 0);
    1085           0 : }
    1086             : 
    1087           0 : void ScCheckListMenuWindow::selectCurrentMemberOnly(bool bSet)
    1088             : {
    1089           0 :     setAllMemberState(!bSet);
    1090           0 :     SvTreeListEntry* pEntry = maChecks.GetCurEntry();
    1091           0 :     maChecks.CheckEntry(pEntry, bSet );
    1092           0 : }
    1093             : 
    1094           0 : void ScCheckListMenuWindow::cycleFocus(bool bReverse)
    1095             : {
    1096           0 :     maTabStopCtrls[mnCurTabStop]->SetFakeFocus(false);
    1097           0 :     maTabStopCtrls[mnCurTabStop]->LoseFocus();
    1098           0 :     if (mnCurTabStop == 0)
    1099           0 :         clearSelectedMenuItem();
    1100             : 
    1101           0 :     if (bReverse)
    1102             :     {
    1103           0 :         if (mnCurTabStop > 0)
    1104           0 :             --mnCurTabStop;
    1105             :         else
    1106           0 :             mnCurTabStop = maTabStopCtrls.size() - 1;
    1107             :     }
    1108             :     else
    1109             :     {
    1110           0 :         ++mnCurTabStop;
    1111           0 :         if (mnCurTabStop >= maTabStopCtrls.size())
    1112           0 :             mnCurTabStop = 0;
    1113             :     }
    1114           0 :     maTabStopCtrls[mnCurTabStop]->SetFakeFocus(true);
    1115           0 :     maTabStopCtrls[mnCurTabStop]->GrabFocus();
    1116           0 : }
    1117             : 
    1118           0 : IMPL_LINK( ScCheckListMenuWindow, ButtonHdl, Button*, pBtn )
    1119             : {
    1120           0 :     if (pBtn == &maBtnOk)
    1121           0 :         close(true);
    1122           0 :     else if (pBtn == &maBtnSelectSingle)
    1123             :     {
    1124           0 :         selectCurrentMemberOnly(true);
    1125           0 :         CheckHdl(&maChecks);
    1126             :     }
    1127           0 :     else if (pBtn == &maBtnUnselectSingle)
    1128             :     {
    1129           0 :         selectCurrentMemberOnly(false);
    1130           0 :         CheckHdl(&maChecks);
    1131             :     }
    1132           0 :     return 0;
    1133             : }
    1134             : 
    1135           0 : IMPL_LINK_NOARG(ScCheckListMenuWindow, TriStateHdl)
    1136             : {
    1137           0 :     switch (mePrevToggleAllState)
    1138             :     {
    1139             :         case TRISTATE_FALSE:
    1140           0 :             maChkToggleAll.SetState(TRISTATE_TRUE);
    1141           0 :             setAllMemberState(true);
    1142           0 :         break;
    1143             :         case TRISTATE_TRUE:
    1144           0 :             maChkToggleAll.SetState(TRISTATE_FALSE);
    1145           0 :             setAllMemberState(false);
    1146           0 :         break;
    1147             :         case TRISTATE_INDET:
    1148             :         default:
    1149           0 :             maChkToggleAll.SetState(TRISTATE_TRUE);
    1150           0 :             setAllMemberState(true);
    1151           0 :         break;
    1152             :     }
    1153             : 
    1154           0 :     mePrevToggleAllState = maChkToggleAll.GetState();
    1155           0 :     return 0;
    1156             : }
    1157             : 
    1158           0 : IMPL_LINK( ScCheckListMenuWindow, CheckHdl, SvTreeListBox*, pChecks )
    1159             : {
    1160           0 :     if (pChecks != &maChecks)
    1161           0 :         return 0;
    1162           0 :     SvTreeListEntry* pEntry = pChecks->GetHdlEntry();
    1163           0 :     if ( pEntry )
    1164           0 :         maChecks.CheckEntry( pEntry,  ( pChecks->GetCheckButtonState( pEntry ) == SV_BUTTON_CHECKED ) );
    1165           0 :     size_t nNumChecked = maChecks.GetCheckedEntryCount();
    1166           0 :     if (nNumChecked == maMembers.size())
    1167             :         // all members visible
    1168           0 :         maChkToggleAll.SetState(TRISTATE_TRUE);
    1169           0 :     else if (nNumChecked == 0)
    1170             :         // no members visible
    1171           0 :         maChkToggleAll.SetState(TRISTATE_FALSE);
    1172             :     else
    1173           0 :         maChkToggleAll.SetState(TRISTATE_INDET);
    1174             : 
    1175           0 :     if (!maConfig.mbAllowEmptySet)
    1176             :         // We need to have at least one member selected.
    1177           0 :         maBtnOk.Enable(nNumChecked != 0);
    1178             : 
    1179           0 :     mePrevToggleAllState = maChkToggleAll.GetState();
    1180           0 :     return 0;
    1181             : }
    1182             : 
    1183           0 : void ScCheckListMenuWindow::MouseMove(const MouseEvent& rMEvt)
    1184             : {
    1185           0 :     ScMenuFloatingWindow::MouseMove(rMEvt);
    1186             : 
    1187           0 :     size_t nSelectedMenu = getSelectedMenuItem();
    1188           0 :     if (nSelectedMenu == MENU_NOT_SELECTED)
    1189           0 :         queueCloseSubMenu();
    1190           0 : }
    1191             : 
    1192           0 : bool ScCheckListMenuWindow::Notify(NotifyEvent& rNEvt)
    1193             : {
    1194           0 :     switch (rNEvt.GetType())
    1195             :     {
    1196             :         case EVENT_KEYUP:
    1197             :         {
    1198           0 :             const KeyEvent* pKeyEvent = rNEvt.GetKeyEvent();
    1199           0 :             const KeyCode& rCode = pKeyEvent->GetKeyCode();
    1200           0 :             bool bShift = rCode.IsShift();
    1201           0 :             if (rCode.GetCode() == KEY_TAB)
    1202             :             {
    1203           0 :                 cycleFocus(bShift);
    1204           0 :                 return true;
    1205             :             }
    1206             :         }
    1207           0 :         break;
    1208             :     }
    1209           0 :     return ScMenuFloatingWindow::Notify(rNEvt);
    1210             : }
    1211             : 
    1212           0 : void ScCheckListMenuWindow::Paint(const Rectangle& rRect)
    1213             : {
    1214           0 :     ScMenuFloatingWindow::Paint(rRect);
    1215             : 
    1216           0 :     const StyleSettings& rStyle = GetSettings().GetStyleSettings();
    1217           0 :     Color aMemberBackColor = rStyle.GetFieldColor();
    1218           0 :     Color aBorderColor = rStyle.GetShadowColor();
    1219             : 
    1220           0 :     Point aPos;
    1221           0 :     Size aSize;
    1222           0 :     getSectionPosSize(aPos, aSize, LISTBOX_AREA_OUTER);
    1223             : 
    1224             :     // Member list box background
    1225           0 :     SetFillColor(aMemberBackColor);
    1226           0 :     SetLineColor(aBorderColor);
    1227           0 :     DrawRect(Rectangle(aPos,aSize));
    1228             : 
    1229             :     // Single-action button box
    1230           0 :     getSectionPosSize(aPos, aSize, SINGLE_BTN_AREA);
    1231           0 :     SetFillColor(rStyle.GetMenuColor());
    1232           0 :     DrawRect(Rectangle(aPos,aSize));
    1233           0 : }
    1234             : 
    1235           0 : Window* ScCheckListMenuWindow::GetPreferredKeyInputWindow()
    1236             : {
    1237           0 :     return maTabStopCtrls[mnCurTabStop];
    1238             : }
    1239             : 
    1240           0 : Reference<XAccessible> ScCheckListMenuWindow::CreateAccessible()
    1241             : {
    1242           0 :     if (!mxAccessible.is())
    1243             :     {
    1244             :         mxAccessible.set(new ScAccessibleFilterTopWindow(
    1245           0 :             GetAccessibleParentWindow()->GetAccessible(), this, getName()));
    1246           0 :         ScAccessibleFilterTopWindow* pAccTop = static_cast<ScAccessibleFilterTopWindow*>(mxAccessible.get());
    1247           0 :         fillMenuItemsToAccessible(pAccTop);
    1248             : 
    1249             :         pAccTop->setAccessibleChild(
    1250           0 :             maChecks.CreateAccessible(), ScAccessibleFilterTopWindow::LISTBOX);
    1251             :         pAccTop->setAccessibleChild(
    1252           0 :             maChkToggleAll.CreateAccessible(), ScAccessibleFilterTopWindow::TOGGLE_ALL);
    1253             :         pAccTop->setAccessibleChild(
    1254           0 :             maBtnSelectSingle.CreateAccessible(), ScAccessibleFilterTopWindow::SINGLE_ON_BTN);
    1255             :         pAccTop->setAccessibleChild(
    1256           0 :             maBtnUnselectSingle.CreateAccessible(), ScAccessibleFilterTopWindow::SINGLE_OFF_BTN);
    1257             :         pAccTop->setAccessibleChild(
    1258           0 :             maBtnOk.CreateAccessible(), ScAccessibleFilterTopWindow::OK_BTN);
    1259             :         pAccTop->setAccessibleChild(
    1260           0 :             maBtnCancel.CreateAccessible(), ScAccessibleFilterTopWindow::CANCEL_BTN);
    1261             :     }
    1262             : 
    1263           0 :     return mxAccessible;
    1264             : }
    1265             : 
    1266           0 : void ScCheckListMenuWindow::setMemberSize(size_t n)
    1267             : {
    1268           0 :     maMembers.reserve(n);
    1269           0 : }
    1270             : 
    1271           0 : void ScCheckListMenuWindow::addDateMember(const OUString& rsName, double nVal, bool bVisible)
    1272             : {
    1273           0 :     ScDocument* pDoc = getDoc();
    1274           0 :     SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
    1275             : 
    1276             :     // Convert the numeric date value to a date object.
    1277           0 :     Date aDate = *(pFormatter->GetNullDate());
    1278           0 :     aDate += static_cast<long>(rtl::math::approxFloor(nVal));
    1279             : 
    1280           0 :     sal_uInt16 nYear = aDate.GetYear();
    1281           0 :     sal_uInt16 nMonth = aDate.GetMonth();
    1282           0 :     sal_uInt16 nDay = aDate.GetDay();
    1283             : 
    1284             :     // Get the localized month name list.
    1285           0 :     CalendarWrapper* pCalendar = ScGlobal::GetCalendar();
    1286           0 :     uno::Sequence<i18n::CalendarItem2> aMonths = pCalendar->getMonths();
    1287           0 :     if (aMonths.getLength() < nMonth)
    1288           0 :         return;
    1289             : 
    1290           0 :     OUString aYearName = OUString::number(nYear);
    1291           0 :     OUString aMonthName = aMonths[nMonth-1].FullName;
    1292           0 :     OUString aDayName = OUString::number(nDay);
    1293             : 
    1294           0 :     maChecks.SetUpdateMode(false);
    1295             : 
    1296           0 :     SvTreeListEntry* pYearEntry = maChecks.FindEntry(NULL, aYearName);
    1297           0 :     if (!pYearEntry)
    1298             :     {
    1299           0 :         pYearEntry = maChecks.InsertEntry(aYearName, NULL, true);
    1300           0 :         Member aMemYear;
    1301           0 :         aMemYear.maName = aYearName;
    1302           0 :         aMemYear.maRealName = rsName;
    1303           0 :         aMemYear.mbDate = true;
    1304           0 :         aMemYear.mbLeaf = false;
    1305           0 :         aMemYear.mbVisible = bVisible;
    1306           0 :         aMemYear.mpParent = NULL;
    1307           0 :         maMembers.push_back(aMemYear);
    1308             :     }
    1309             : 
    1310           0 :     SvTreeListEntry* pMonthEntry = maChecks.FindEntry(pYearEntry, aMonthName);
    1311           0 :     if (!pMonthEntry)
    1312             :     {
    1313           0 :         pMonthEntry = maChecks.InsertEntry(aMonthName, pYearEntry, true);
    1314           0 :         Member aMemMonth;
    1315           0 :         aMemMonth.maName = aMonthName;
    1316           0 :         aMemMonth.maRealName = rsName;
    1317           0 :         aMemMonth.mbDate = true;
    1318           0 :         aMemMonth.mbLeaf = false;
    1319           0 :         aMemMonth.mbVisible = bVisible;
    1320           0 :         aMemMonth.mpParent = pYearEntry;
    1321           0 :         maMembers.push_back(aMemMonth);
    1322             :     }
    1323             : 
    1324           0 :     SvTreeListEntry* pDayEntry = maChecks.FindEntry(pMonthEntry, aDayName);
    1325           0 :     if (!pDayEntry)
    1326             :     {
    1327           0 :         maChecks.InsertEntry(aDayName, pMonthEntry, false);
    1328           0 :         Member aMemDay;
    1329           0 :         aMemDay.maName = aDayName;
    1330           0 :         aMemDay.maRealName = rsName;
    1331           0 :         aMemDay.mbDate = true;
    1332           0 :         aMemDay.mbLeaf = true;
    1333           0 :         aMemDay.mbVisible = bVisible;
    1334           0 :         aMemDay.mpParent = pMonthEntry;
    1335           0 :         maMembers.push_back(aMemDay);
    1336             :     }
    1337             : 
    1338           0 :     maChecks.SetUpdateMode(true);
    1339             : }
    1340             : 
    1341           0 : void ScCheckListMenuWindow::addMember(const OUString& rName, bool bVisible)
    1342             : {
    1343           0 :     Member aMember;
    1344           0 :     aMember.maName = rName;
    1345           0 :     aMember.mbDate = false;
    1346           0 :     aMember.mbLeaf = true;
    1347           0 :     aMember.mbVisible = bVisible;
    1348           0 :     aMember.mpParent = NULL;
    1349           0 :     maMembers.push_back(aMember);
    1350           0 : }
    1351             : 
    1352           0 : ScCheckListBox::ScCheckListBox( Window* pParent, WinBits nWinStyle )
    1353           0 :    :  SvTreeListBox( pParent, nWinStyle ), mpCheckButton( NULL )
    1354             : {
    1355           0 :     Init();
    1356           0 : }
    1357             : 
    1358           0 : SvTreeListEntry* ScCheckListBox::FindEntry( SvTreeListEntry* pParent, const OUString& sNode )
    1359             : {
    1360           0 :     sal_uInt16 nRootPos = 0;
    1361           0 :     SvTreeListEntry* pEntry = pParent ? FirstChild( pParent ) : GetEntry( nRootPos );
    1362           0 :     while ( pEntry )
    1363             :     {
    1364           0 :         if (  sNode.equals(GetEntryText( pEntry )) )
    1365           0 :             return pEntry;
    1366             : 
    1367           0 :         pEntry = pParent ? NextSibling( pEntry ) : GetEntry( ++nRootPos );
    1368             :     }
    1369           0 :     return NULL;
    1370             : }
    1371             : 
    1372           0 : void ScCheckListBox::Init()
    1373             : {
    1374           0 :     mpCheckButton = new SvLBoxButtonData( this );
    1375           0 :     EnableCheckButton( mpCheckButton );
    1376           0 :     SetNodeDefaultImages();
    1377           0 : }
    1378             : 
    1379           0 : bool ScCheckListBox::IsChecked( OUString& sName, SvTreeListEntry* pParent )
    1380             : {
    1381           0 :     SvTreeListEntry* pEntry = FindEntry( pParent, sName );
    1382           0 :     if ( pEntry && GetCheckButtonState( pEntry ) == SV_BUTTON_CHECKED)
    1383           0 :         return true;
    1384           0 :     return false;
    1385             : }
    1386             : 
    1387           0 : void ScCheckListBox::CheckEntry( OUString& sName, SvTreeListEntry* pParent, bool bCheck )
    1388             : {
    1389           0 :     SvTreeListEntry* pEntry = FindEntry( pParent, sName );
    1390           0 :     if ( pEntry )
    1391           0 :         CheckEntry(  pEntry, bCheck );
    1392           0 : }
    1393             : 
    1394             : // Recursively check all children of pParent
    1395           0 : void ScCheckListBox::CheckAllChildren( SvTreeListEntry* pParent, bool bCheck )
    1396             : {
    1397           0 :     if ( pParent )
    1398             :     {
    1399             :         SetCheckButtonState(
    1400             :             pParent, bCheck ? SvButtonState( SV_BUTTON_CHECKED ) :
    1401           0 :                                            SvButtonState( SV_BUTTON_UNCHECKED ) );
    1402             :     }
    1403           0 :     SvTreeListEntry* pEntry = pParent ? FirstChild( pParent ) : First();
    1404           0 :     while ( pEntry )
    1405             :     {
    1406           0 :         CheckAllChildren( pEntry, bCheck );
    1407           0 :         pEntry = NextSibling( pEntry );
    1408             :     }
    1409           0 : }
    1410             : 
    1411           0 : void ScCheckListBox::CheckEntry( SvTreeListEntry* pParent, bool bCheck )
    1412             : {
    1413             :     // recursively check all items below pParent
    1414           0 :     CheckAllChildren( pParent, bCheck );
    1415             :     // checking pParent can affect ancestors, e.g. if ancestor is unchecked and pParent is
    1416             :     // now checked then the ancestor needs to be checked also
    1417           0 :     SvTreeListEntry* pAncestor = GetParent(pParent);
    1418           0 :     if ( pAncestor )
    1419             :     {
    1420           0 :         while ( pAncestor )
    1421             :         {
    1422             :             // if any first level children checked then ancestor
    1423             :             // needs to be checked, similarly if no first level children
    1424             :             // checked then ancestor needs to be unchecked
    1425           0 :             SvTreeListEntry* pChild = FirstChild( pAncestor );
    1426           0 :             bool bChildChecked = false;
    1427             : 
    1428           0 :             while ( pChild )
    1429             :             {
    1430           0 :                 if ( GetCheckButtonState( pChild ) == SV_BUTTON_CHECKED )
    1431             :                 {
    1432           0 :                     bChildChecked = true;
    1433           0 :                     break;
    1434             :                 }
    1435           0 :                 pChild = NextSibling( pChild );
    1436             :             }
    1437             :             SetCheckButtonState(
    1438             :                 pAncestor, bChildChecked ? SvButtonState( SV_BUTTON_CHECKED ) :
    1439           0 :                                            SvButtonState( SV_BUTTON_UNCHECKED ) );
    1440           0 :             pAncestor = GetParent(pAncestor);
    1441             :         }
    1442             :     }
    1443           0 : }
    1444             : 
    1445           0 : SvTreeListEntry* ScCheckListBox::CountCheckedEntries( SvTreeListEntry* pParent, sal_uLong& nCount ) const
    1446             : {
    1447           0 :     if ( pParent && GetCheckButtonState( pParent ) == SV_BUTTON_CHECKED  )
    1448           0 :         nCount++;
    1449             :     // Iterate over the children
    1450           0 :     SvTreeListEntry* pEntry = pParent ? FirstChild( pParent ) : First();
    1451           0 :     while ( pEntry )
    1452             :     {
    1453           0 :         CountCheckedEntries( pEntry, nCount );
    1454           0 :         pEntry = NextSibling( pEntry );
    1455             :     }
    1456           0 :     return NULL;
    1457             : }
    1458             : 
    1459           0 : sal_uInt16 ScCheckListBox::GetCheckedEntryCount() const
    1460             : {
    1461           0 :     sal_uLong nCount = 0;
    1462           0 :     CountCheckedEntries( NULL,  nCount );
    1463           0 :     return nCount;
    1464             : }
    1465             : 
    1466           0 : void ScCheckListBox::ExpandChildren( SvTreeListEntry* pParent )
    1467             : {
    1468           0 :     if ( pParent )
    1469           0 :         Expand( pParent );
    1470             :     // Iterate over the children
    1471           0 :     SvTreeListEntry* pEntry = pParent ? FirstChild( pParent ) : First();
    1472           0 :     while ( pEntry )
    1473             :     {
    1474           0 :         ExpandChildren( pEntry );
    1475           0 :         pEntry = NextSibling( pEntry );
    1476             :     }
    1477           0 : }
    1478             : 
    1479           0 : void ScCheckListBox::KeyInput( const KeyEvent& rKEvt )
    1480             : {
    1481           0 :     const KeyCode& rKey = rKEvt.GetKeyCode();
    1482             : 
    1483           0 :     if ( rKey.GetCode() == KEY_RETURN || rKey.GetCode() == KEY_SPACE )
    1484             :     {
    1485           0 :         SvTreeListEntry* pEntry = GetCurEntry();
    1486             : 
    1487           0 :         if ( pEntry )
    1488             :         {
    1489           0 :             bool bCheck = ( GetCheckButtonState( pEntry ) == SV_BUTTON_CHECKED );
    1490           0 :             CheckEntry( pEntry, !bCheck );
    1491           0 :             if ( bCheck != ( GetCheckButtonState( pEntry ) == SV_BUTTON_CHECKED ) )
    1492           0 :                 CheckButtonHdl();
    1493             :         }
    1494             :     }
    1495           0 :     else if ( GetEntryCount() )
    1496           0 :         SvTreeListBox::KeyInput( rKEvt );
    1497           0 : }
    1498             : 
    1499           0 : void ScCheckListMenuWindow::initMembers()
    1500             : {
    1501           0 :     size_t n = maMembers.size();
    1502           0 :     size_t nVisMemCount = 0;
    1503           0 :     maChecks.SetUpdateMode(false);
    1504           0 :     for (size_t i = 0; i < n; ++i)
    1505             :     {
    1506           0 :         if ( !maMembers[ i ].mbDate )
    1507             :         {
    1508           0 :             maChecks.InsertEntry(maMembers[i].maName, NULL, false, TREELIST_APPEND, NULL,
    1509           0 :                 SvLBoxButtonKind_enabledCheckbox );
    1510             :         }
    1511             : 
    1512           0 :         maChecks.CheckEntry( maMembers[i].maName, maMembers[i].mpParent, maMembers[i].mbVisible);
    1513             :         // Expand first node of checked dates
    1514           0 :         if ( maMembers[ i ].mpParent == NULL && maChecks.IsChecked( maMembers[i].maName,  maMembers[i].mpParent ) )
    1515             :         {
    1516           0 :             SvTreeListEntry* pEntry = maChecks.FindEntry( NULL, maMembers[ i ].maName );
    1517           0 :             if (pEntry)
    1518           0 :                 maChecks.Expand( pEntry );
    1519             :         }
    1520             : 
    1521           0 :         if (maMembers[i].mbVisible)
    1522           0 :             ++nVisMemCount;
    1523             :     }
    1524           0 :     if (nVisMemCount == n)
    1525             :     {
    1526             :         // all members visible
    1527           0 :         maChkToggleAll.SetState(TRISTATE_TRUE);
    1528           0 :         mePrevToggleAllState = TRISTATE_TRUE;
    1529             :     }
    1530           0 :     else if (nVisMemCount == 0)
    1531             :     {
    1532             :         // no members visible
    1533           0 :         maChkToggleAll.SetState(TRISTATE_FALSE);
    1534           0 :         mePrevToggleAllState = TRISTATE_FALSE;
    1535             :     }
    1536             :     else
    1537             :     {
    1538           0 :         maChkToggleAll.SetState(TRISTATE_INDET);
    1539           0 :         mePrevToggleAllState = TRISTATE_INDET;
    1540             :     }
    1541           0 :     maChecks.SetUpdateMode(true);
    1542           0 : }
    1543             : 
    1544           0 : void ScCheckListMenuWindow::setConfig(const Config& rConfig)
    1545             : {
    1546           0 :     maConfig = rConfig;
    1547           0 : }
    1548             : 
    1549           0 : bool ScCheckListMenuWindow::isAllSelected() const
    1550             : {
    1551           0 :     return maChkToggleAll.IsChecked();
    1552             : }
    1553             : 
    1554           0 : void ScCheckListMenuWindow::getResult(ResultType& rResult)
    1555             : {
    1556           0 :     ResultType aResult;
    1557           0 :     size_t n = maMembers.size();
    1558           0 :     for (size_t i = 0; i < n; ++i)
    1559             :     {
    1560           0 :         if ( maMembers[i].mbLeaf )
    1561             :         {
    1562           0 :             bool bState =  maChecks.IsChecked( maMembers[i].maName,  maMembers[i].mpParent );
    1563           0 :             OUString sName;
    1564           0 :             if ( maMembers[i].mbDate )
    1565           0 :                 sName = maMembers[i].maRealName;
    1566             :             else
    1567           0 :                 sName = maMembers[i].maName;
    1568           0 :             aResult.insert(ResultType::value_type(sName, bState));
    1569             :         }
    1570             :     }
    1571           0 :     rResult.swap(aResult);
    1572           0 : }
    1573             : 
    1574           0 : void ScCheckListMenuWindow::launch(const Rectangle& rRect)
    1575             : {
    1576           0 :     packWindow();
    1577           0 :     if (!maConfig.mbAllowEmptySet)
    1578             :         // We need to have at least one member selected.
    1579           0 :         maBtnOk.Enable(maChecks.GetCheckedEntryCount() != 0);
    1580             : 
    1581           0 :     Rectangle aRect(rRect);
    1582           0 :     if (maConfig.mbRTL)
    1583             :     {
    1584             :         // In RTL mode, the logical "left" is visual "right".
    1585           0 :         long nLeft = aRect.Left() - aRect.GetWidth();
    1586           0 :         aRect.Left() = nLeft;
    1587             :     }
    1588           0 :     else if (maWndSize.Width() < aRect.GetWidth())
    1589             :     {
    1590             :         // Target rectangle (i.e. cell width) is wider than the window.
    1591             :         // Simulate right-aligned launch by modifying the target rectangle
    1592             :         // size.
    1593           0 :         long nDiff = aRect.GetWidth() - maWndSize.Width();
    1594           0 :         aRect.Left() += nDiff;
    1595             :     }
    1596             : 
    1597           0 :     StartPopupMode(aRect, (FLOATWIN_POPUPMODE_DOWN | FLOATWIN_POPUPMODE_GRABFOCUS));
    1598           0 :     cycleFocus(); // Set initial focus to the check list box.
    1599           0 : }
    1600             : 
    1601           0 : void ScCheckListMenuWindow::close(bool bOK)
    1602             : {
    1603           0 :     if (bOK && mpOKAction.get())
    1604           0 :         mpOKAction->execute();
    1605             : 
    1606           0 :     EndPopupMode();
    1607           0 : }
    1608             : 
    1609           0 : void ScCheckListMenuWindow::setExtendedData(ExtendedData* p)
    1610             : {
    1611           0 :     mpExtendedData.reset(p);
    1612           0 : }
    1613             : 
    1614           0 : ScCheckListMenuWindow::ExtendedData* ScCheckListMenuWindow::getExtendedData()
    1615             : {
    1616           0 :     return mpExtendedData.get();
    1617             : }
    1618             : 
    1619           0 : void ScCheckListMenuWindow::setOKAction(Action* p)
    1620             : {
    1621           0 :     mpOKAction.reset(p);
    1622           0 : }
    1623             : 
    1624           0 : void ScCheckListMenuWindow::setPopupEndAction(Action* p)
    1625             : {
    1626           0 :     mpPopupEndAction.reset(p);
    1627           0 : }
    1628             : 
    1629           0 : void ScCheckListMenuWindow::handlePopupEnd()
    1630             : {
    1631           0 :     clearSelectedMenuItem();
    1632           0 :     if (mpPopupEndAction)
    1633           0 :         mpPopupEndAction->execute();
    1634           0 : }
    1635             : 
    1636             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10