xref: /aoo41x/main/sc/source/ui/cctrl/dpcontrol.cxx (revision cdf0e10c)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_sc.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir // INCLUDE ---------------------------------------------------------------
32*cdf0e10cSrcweir 
33*cdf0e10cSrcweir #include "dpcontrol.hxx"
34*cdf0e10cSrcweir #include "dpcontrol.hrc"
35*cdf0e10cSrcweir 
36*cdf0e10cSrcweir #include <vcl/outdev.hxx>
37*cdf0e10cSrcweir #include <vcl/settings.hxx>
38*cdf0e10cSrcweir #include <tools/wintypes.hxx>
39*cdf0e10cSrcweir #include <vcl/decoview.hxx>
40*cdf0e10cSrcweir #include "strload.hxx"
41*cdf0e10cSrcweir #include "global.hxx"
42*cdf0e10cSrcweir #include "scitems.hxx"
43*cdf0e10cSrcweir #include "document.hxx"
44*cdf0e10cSrcweir #include "docpool.hxx"
45*cdf0e10cSrcweir #include "patattr.hxx"
46*cdf0e10cSrcweir 
47*cdf0e10cSrcweir #include "AccessibleFilterMenu.hxx"
48*cdf0e10cSrcweir #include "AccessibleFilterTopWindow.hxx"
49*cdf0e10cSrcweir 
50*cdf0e10cSrcweir #include <com/sun/star/accessibility/XAccessible.hpp>
51*cdf0e10cSrcweir #include <com/sun/star/accessibility/XAccessibleContext.hpp>
52*cdf0e10cSrcweir 
53*cdf0e10cSrcweir using ::com::sun::star::uno::Reference;
54*cdf0e10cSrcweir using ::com::sun::star::accessibility::XAccessible;
55*cdf0e10cSrcweir using ::com::sun::star::accessibility::XAccessibleContext;
56*cdf0e10cSrcweir using ::rtl::OUString;
57*cdf0e10cSrcweir using ::rtl::OUStringHash;
58*cdf0e10cSrcweir using ::std::vector;
59*cdf0e10cSrcweir using ::std::hash_map;
60*cdf0e10cSrcweir using ::std::auto_ptr;
61*cdf0e10cSrcweir 
62*cdf0e10cSrcweir ScDPFieldButton::ScDPFieldButton(OutputDevice* pOutDev, const StyleSettings* pStyle, const Fraction* pZoomX, const Fraction* pZoomY, ScDocument* pDoc) :
63*cdf0e10cSrcweir     mpDoc(pDoc),
64*cdf0e10cSrcweir     mpOutDev(pOutDev),
65*cdf0e10cSrcweir     mpStyle(pStyle),
66*cdf0e10cSrcweir     mbBaseButton(true),
67*cdf0e10cSrcweir     mbPopupButton(false),
68*cdf0e10cSrcweir     mbHasHiddenMember(false),
69*cdf0e10cSrcweir     mbPopupPressed(false),
70*cdf0e10cSrcweir     mbPopupLeft(false)
71*cdf0e10cSrcweir {
72*cdf0e10cSrcweir     if (pZoomX)
73*cdf0e10cSrcweir         maZoomX = *pZoomX;
74*cdf0e10cSrcweir     else
75*cdf0e10cSrcweir         maZoomX = Fraction(1, 1);
76*cdf0e10cSrcweir 
77*cdf0e10cSrcweir     if (pZoomY)
78*cdf0e10cSrcweir         maZoomY = *pZoomY;
79*cdf0e10cSrcweir     else
80*cdf0e10cSrcweir         maZoomY = Fraction(1, 1);
81*cdf0e10cSrcweir }
82*cdf0e10cSrcweir 
83*cdf0e10cSrcweir ScDPFieldButton::~ScDPFieldButton()
84*cdf0e10cSrcweir {
85*cdf0e10cSrcweir }
86*cdf0e10cSrcweir 
87*cdf0e10cSrcweir void ScDPFieldButton::setText(const OUString& rText)
88*cdf0e10cSrcweir {
89*cdf0e10cSrcweir     maText = rText;
90*cdf0e10cSrcweir }
91*cdf0e10cSrcweir 
92*cdf0e10cSrcweir void ScDPFieldButton::setBoundingBox(const Point& rPos, const Size& rSize, bool bLayoutRTL)
93*cdf0e10cSrcweir {
94*cdf0e10cSrcweir     maPos = rPos;
95*cdf0e10cSrcweir     maSize = rSize;
96*cdf0e10cSrcweir     if (bLayoutRTL)
97*cdf0e10cSrcweir     {
98*cdf0e10cSrcweir         // rPos is the logical-left position, adjust maPos to visual-left (inside the cell border)
99*cdf0e10cSrcweir         maPos.X() -= maSize.Width() - 1;
100*cdf0e10cSrcweir     }
101*cdf0e10cSrcweir }
102*cdf0e10cSrcweir 
103*cdf0e10cSrcweir void ScDPFieldButton::setDrawBaseButton(bool b)
104*cdf0e10cSrcweir {
105*cdf0e10cSrcweir     mbBaseButton = b;
106*cdf0e10cSrcweir }
107*cdf0e10cSrcweir 
108*cdf0e10cSrcweir void ScDPFieldButton::setDrawPopupButton(bool b)
109*cdf0e10cSrcweir {
110*cdf0e10cSrcweir     mbPopupButton = b;
111*cdf0e10cSrcweir }
112*cdf0e10cSrcweir 
113*cdf0e10cSrcweir void ScDPFieldButton::setHasHiddenMember(bool b)
114*cdf0e10cSrcweir {
115*cdf0e10cSrcweir     mbHasHiddenMember = b;
116*cdf0e10cSrcweir }
117*cdf0e10cSrcweir 
118*cdf0e10cSrcweir void ScDPFieldButton::setPopupPressed(bool b)
119*cdf0e10cSrcweir {
120*cdf0e10cSrcweir     mbPopupPressed = b;
121*cdf0e10cSrcweir }
122*cdf0e10cSrcweir 
123*cdf0e10cSrcweir void ScDPFieldButton::setPopupLeft(bool b)
124*cdf0e10cSrcweir {
125*cdf0e10cSrcweir     mbPopupLeft = b;
126*cdf0e10cSrcweir }
127*cdf0e10cSrcweir 
128*cdf0e10cSrcweir void ScDPFieldButton::draw()
129*cdf0e10cSrcweir {
130*cdf0e10cSrcweir     const long nMargin = 2;
131*cdf0e10cSrcweir     bool bOldMapEnablaed = mpOutDev->IsMapModeEnabled();
132*cdf0e10cSrcweir     mpOutDev->EnableMapMode(false);
133*cdf0e10cSrcweir 
134*cdf0e10cSrcweir     if (mbBaseButton)
135*cdf0e10cSrcweir     {
136*cdf0e10cSrcweir         // Background
137*cdf0e10cSrcweir         Rectangle aRect(maPos, maSize);
138*cdf0e10cSrcweir         mpOutDev->SetLineColor(mpStyle->GetFaceColor());
139*cdf0e10cSrcweir         mpOutDev->SetFillColor(mpStyle->GetFaceColor());
140*cdf0e10cSrcweir         mpOutDev->DrawRect(aRect);
141*cdf0e10cSrcweir 
142*cdf0e10cSrcweir         // Border lines
143*cdf0e10cSrcweir         mpOutDev->SetLineColor(mpStyle->GetLightColor());
144*cdf0e10cSrcweir         mpOutDev->DrawLine(Point(maPos), Point(maPos.X(), maPos.Y()+maSize.Height()-1));
145*cdf0e10cSrcweir         mpOutDev->DrawLine(Point(maPos), Point(maPos.X()+maSize.Width()-1, maPos.Y()));
146*cdf0e10cSrcweir 
147*cdf0e10cSrcweir         mpOutDev->SetLineColor(mpStyle->GetShadowColor());
148*cdf0e10cSrcweir         mpOutDev->DrawLine(Point(maPos.X(), maPos.Y()+maSize.Height()-1),
149*cdf0e10cSrcweir                            Point(maPos.X()+maSize.Width()-1, maPos.Y()+maSize.Height()-1));
150*cdf0e10cSrcweir         mpOutDev->DrawLine(Point(maPos.X()+maSize.Width()-1, maPos.Y()),
151*cdf0e10cSrcweir                            Point(maPos.X()+maSize.Width()-1, maPos.Y()+maSize.Height()-1));
152*cdf0e10cSrcweir 
153*cdf0e10cSrcweir         // Field name.
154*cdf0e10cSrcweir         // Get the font and size the same way as in scenario selection (lcl_DrawOneFrame in gridwin4.cxx)
155*cdf0e10cSrcweir         Font aTextFont( mpStyle->GetAppFont() );
156*cdf0e10cSrcweir         if ( mpDoc )
157*cdf0e10cSrcweir         {
158*cdf0e10cSrcweir             //  use ScPatternAttr::GetFont only for font size
159*cdf0e10cSrcweir             Font aAttrFont;
160*cdf0e10cSrcweir             static_cast<const ScPatternAttr&>(mpDoc->GetPool()->GetDefaultItem(ATTR_PATTERN)).
161*cdf0e10cSrcweir                 GetFont( aAttrFont, SC_AUTOCOL_BLACK, mpOutDev, &maZoomY );
162*cdf0e10cSrcweir             aTextFont.SetSize( aAttrFont.GetSize() );
163*cdf0e10cSrcweir         }
164*cdf0e10cSrcweir         mpOutDev->SetFont(aTextFont);
165*cdf0e10cSrcweir         mpOutDev->SetTextColor(mpStyle->GetButtonTextColor());
166*cdf0e10cSrcweir 
167*cdf0e10cSrcweir         Point aTextPos = maPos;
168*cdf0e10cSrcweir         long nTHeight = mpOutDev->GetTextHeight();
169*cdf0e10cSrcweir         aTextPos.setX(maPos.getX() + nMargin);
170*cdf0e10cSrcweir         aTextPos.setY(maPos.getY() + (maSize.Height()-nTHeight)/2);
171*cdf0e10cSrcweir 
172*cdf0e10cSrcweir         mpOutDev->Push(PUSH_CLIPREGION);
173*cdf0e10cSrcweir         mpOutDev->IntersectClipRegion(aRect);
174*cdf0e10cSrcweir         mpOutDev->DrawText(aTextPos, maText);
175*cdf0e10cSrcweir         mpOutDev->Pop();
176*cdf0e10cSrcweir     }
177*cdf0e10cSrcweir 
178*cdf0e10cSrcweir     if (mbPopupButton)
179*cdf0e10cSrcweir         drawPopupButton();
180*cdf0e10cSrcweir 
181*cdf0e10cSrcweir     mpOutDev->EnableMapMode(bOldMapEnablaed);
182*cdf0e10cSrcweir }
183*cdf0e10cSrcweir 
184*cdf0e10cSrcweir void ScDPFieldButton::getPopupBoundingBox(Point& rPos, Size& rSize) const
185*cdf0e10cSrcweir {
186*cdf0e10cSrcweir     long nW = maSize.getWidth() / 2;
187*cdf0e10cSrcweir     long nH = maSize.getHeight();
188*cdf0e10cSrcweir     if (nW > 18)
189*cdf0e10cSrcweir         nW = 18;
190*cdf0e10cSrcweir     if (nH > 18)
191*cdf0e10cSrcweir         nH = 18;
192*cdf0e10cSrcweir 
193*cdf0e10cSrcweir     // #i114944# AutoFilter button is left-aligned in RTL.
194*cdf0e10cSrcweir     // DataPilot button is always right-aligned for now, so text output isn't affected.
195*cdf0e10cSrcweir     if (mbPopupLeft)
196*cdf0e10cSrcweir         rPos.setX(maPos.getX());
197*cdf0e10cSrcweir     else
198*cdf0e10cSrcweir         rPos.setX(maPos.getX() + maSize.getWidth() - nW);
199*cdf0e10cSrcweir     rPos.setY(maPos.getY() + maSize.getHeight() - nH);
200*cdf0e10cSrcweir     rSize.setWidth(nW);
201*cdf0e10cSrcweir     rSize.setHeight(nH);
202*cdf0e10cSrcweir }
203*cdf0e10cSrcweir 
204*cdf0e10cSrcweir void ScDPFieldButton::drawPopupButton()
205*cdf0e10cSrcweir {
206*cdf0e10cSrcweir     Point aPos;
207*cdf0e10cSrcweir     Size aSize;
208*cdf0e10cSrcweir     getPopupBoundingBox(aPos, aSize);
209*cdf0e10cSrcweir 
210*cdf0e10cSrcweir     // Background & outer black border
211*cdf0e10cSrcweir     mpOutDev->SetLineColor(COL_BLACK);
212*cdf0e10cSrcweir     mpOutDev->SetFillColor(mpStyle->GetFaceColor());
213*cdf0e10cSrcweir     mpOutDev->DrawRect(Rectangle(aPos, aSize));
214*cdf0e10cSrcweir 
215*cdf0e10cSrcweir     if (!mbPopupPressed)
216*cdf0e10cSrcweir     {
217*cdf0e10cSrcweir         // border lines
218*cdf0e10cSrcweir         mpOutDev->SetLineColor(mpStyle->GetLightColor());
219*cdf0e10cSrcweir         mpOutDev->DrawLine(Point(aPos.X()+1, aPos.Y()+1), Point(aPos.X()+1, aPos.Y()+aSize.Height()-2));
220*cdf0e10cSrcweir         mpOutDev->DrawLine(Point(aPos.X()+1, aPos.Y()+1), Point(aPos.X()+aSize.Width()-2, aPos.Y()+1));
221*cdf0e10cSrcweir 
222*cdf0e10cSrcweir         mpOutDev->SetLineColor(mpStyle->GetShadowColor());
223*cdf0e10cSrcweir         mpOutDev->DrawLine(Point(aPos.X()+1, aPos.Y()+aSize.Height()-2),
224*cdf0e10cSrcweir                            Point(aPos.X()+aSize.Width()-2, aPos.Y()+aSize.Height()-2));
225*cdf0e10cSrcweir         mpOutDev->DrawLine(Point(aPos.X()+aSize.Width()-2, aPos.Y()+1),
226*cdf0e10cSrcweir                            Point(aPos.X()+aSize.Width()-2, aPos.Y()+aSize.Height()-2));
227*cdf0e10cSrcweir     }
228*cdf0e10cSrcweir 
229*cdf0e10cSrcweir     // the arrowhead
230*cdf0e10cSrcweir     Color aArrowColor = mbHasHiddenMember ? mpStyle->GetHighlightLinkColor() : mpStyle->GetButtonTextColor();
231*cdf0e10cSrcweir     mpOutDev->SetLineColor(aArrowColor);
232*cdf0e10cSrcweir     mpOutDev->SetFillColor(aArrowColor);
233*cdf0e10cSrcweir     Point aCenter(aPos.X() + (aSize.Width() >> 1), aPos.Y() + (aSize.Height() >> 1));
234*cdf0e10cSrcweir     Point aPos1, aPos2;
235*cdf0e10cSrcweir     aPos1.X() = aCenter.X() - 4;
236*cdf0e10cSrcweir     aPos2.X() = aCenter.X() + 4;
237*cdf0e10cSrcweir     aPos1.Y() = aCenter.Y() - 3;
238*cdf0e10cSrcweir     aPos2.Y() = aCenter.Y() - 3;
239*cdf0e10cSrcweir 
240*cdf0e10cSrcweir     if (mbPopupPressed)
241*cdf0e10cSrcweir     {
242*cdf0e10cSrcweir         aPos1.X() += 1;
243*cdf0e10cSrcweir         aPos2.X() += 1;
244*cdf0e10cSrcweir         aPos1.Y() += 1;
245*cdf0e10cSrcweir         aPos2.Y() += 1;
246*cdf0e10cSrcweir     }
247*cdf0e10cSrcweir 
248*cdf0e10cSrcweir     do
249*cdf0e10cSrcweir     {
250*cdf0e10cSrcweir         ++aPos1.X();
251*cdf0e10cSrcweir         --aPos2.X();
252*cdf0e10cSrcweir         ++aPos1.Y();
253*cdf0e10cSrcweir         ++aPos2.Y();
254*cdf0e10cSrcweir         mpOutDev->DrawLine(aPos1, aPos2);
255*cdf0e10cSrcweir     }
256*cdf0e10cSrcweir     while (aPos1 != aPos2);
257*cdf0e10cSrcweir 
258*cdf0e10cSrcweir     if (mbHasHiddenMember)
259*cdf0e10cSrcweir     {
260*cdf0e10cSrcweir         // tiny little box to display in presence of hidden member(s).
261*cdf0e10cSrcweir         Point aBoxPos(aPos.X() + aSize.Width() - 5, aPos.Y() + aSize.Height() - 5);
262*cdf0e10cSrcweir         if (mbPopupPressed)
263*cdf0e10cSrcweir         {
264*cdf0e10cSrcweir             aBoxPos.X() += 1;
265*cdf0e10cSrcweir             aBoxPos.Y() += 1;
266*cdf0e10cSrcweir         }
267*cdf0e10cSrcweir         Size aBoxSize(3, 3);
268*cdf0e10cSrcweir         mpOutDev->DrawRect(Rectangle(aBoxPos, aBoxSize));
269*cdf0e10cSrcweir     }
270*cdf0e10cSrcweir }
271*cdf0e10cSrcweir 
272*cdf0e10cSrcweir // ============================================================================
273*cdf0e10cSrcweir 
274*cdf0e10cSrcweir ScMenuFloatingWindow::MenuItemData::MenuItemData() :
275*cdf0e10cSrcweir     mbEnabled(true),
276*cdf0e10cSrcweir     mpAction(static_cast<ScDPFieldPopupWindow::Action*>(NULL)),
277*cdf0e10cSrcweir     mpSubMenuWin(static_cast<ScMenuFloatingWindow*>(NULL))
278*cdf0e10cSrcweir {
279*cdf0e10cSrcweir }
280*cdf0e10cSrcweir 
281*cdf0e10cSrcweir // ----------------------------------------------------------------------------
282*cdf0e10cSrcweir 
283*cdf0e10cSrcweir ScMenuFloatingWindow::SubMenuItemData::SubMenuItemData(ScMenuFloatingWindow* pParent) :
284*cdf0e10cSrcweir     mpSubMenu(NULL),
285*cdf0e10cSrcweir     mnMenuPos(MENU_NOT_SELECTED),
286*cdf0e10cSrcweir     mpParent(pParent)
287*cdf0e10cSrcweir {
288*cdf0e10cSrcweir     maTimer.SetTimeoutHdl( LINK(this, ScMenuFloatingWindow::SubMenuItemData, TimeoutHdl) );
289*cdf0e10cSrcweir     maTimer.SetTimeout(mpParent->GetSettings().GetMouseSettings().GetMenuDelay());
290*cdf0e10cSrcweir }
291*cdf0e10cSrcweir 
292*cdf0e10cSrcweir void ScMenuFloatingWindow::SubMenuItemData::reset()
293*cdf0e10cSrcweir {
294*cdf0e10cSrcweir     mpSubMenu = NULL;
295*cdf0e10cSrcweir     mnMenuPos = MENU_NOT_SELECTED;
296*cdf0e10cSrcweir     maTimer.Stop();
297*cdf0e10cSrcweir }
298*cdf0e10cSrcweir 
299*cdf0e10cSrcweir IMPL_LINK( ScMenuFloatingWindow::SubMenuItemData, TimeoutHdl, void*, EMPTYARG )
300*cdf0e10cSrcweir {
301*cdf0e10cSrcweir     mpParent->handleMenuTimeout(this);
302*cdf0e10cSrcweir     return 0;
303*cdf0e10cSrcweir }
304*cdf0e10cSrcweir 
305*cdf0e10cSrcweir // ----------------------------------------------------------------------------
306*cdf0e10cSrcweir 
307*cdf0e10cSrcweir size_t ScMenuFloatingWindow::MENU_NOT_SELECTED = 999;
308*cdf0e10cSrcweir 
309*cdf0e10cSrcweir ScMenuFloatingWindow::ScMenuFloatingWindow(Window* pParent, ScDocument* pDoc, sal_uInt16 nMenuStackLevel) :
310*cdf0e10cSrcweir     PopupMenuFloatingWindow(pParent),
311*cdf0e10cSrcweir     maOpenTimer(this),
312*cdf0e10cSrcweir     maCloseTimer(this),
313*cdf0e10cSrcweir     maName(OUString::createFromAscii("ScMenuFloatingWindow")),
314*cdf0e10cSrcweir     mnSelectedMenu(MENU_NOT_SELECTED),
315*cdf0e10cSrcweir     mnClickedMenu(MENU_NOT_SELECTED),
316*cdf0e10cSrcweir     mpDoc(pDoc),
317*cdf0e10cSrcweir     mpParentMenu(dynamic_cast<ScMenuFloatingWindow*>(pParent)),
318*cdf0e10cSrcweir     mpActiveSubMenu(NULL)
319*cdf0e10cSrcweir {
320*cdf0e10cSrcweir     SetMenuStackLevel(nMenuStackLevel);
321*cdf0e10cSrcweir 
322*cdf0e10cSrcweir     // TODO: How do we get the right font to use here ?
323*cdf0e10cSrcweir     const sal_uInt16 nPopupFontHeight = 12;
324*cdf0e10cSrcweir     const StyleSettings& rStyle = GetSettings().GetStyleSettings();
325*cdf0e10cSrcweir     maLabelFont = rStyle.GetLabelFont();
326*cdf0e10cSrcweir     maLabelFont.SetHeight(nPopupFontHeight);
327*cdf0e10cSrcweir     SetFont(maLabelFont);
328*cdf0e10cSrcweir 
329*cdf0e10cSrcweir     SetText(OUString::createFromAscii("ScMenuFloatingWindow"));
330*cdf0e10cSrcweir     SetPopupModeEndHdl( LINK(this, ScMenuFloatingWindow, PopupEndHdl) );
331*cdf0e10cSrcweir }
332*cdf0e10cSrcweir 
333*cdf0e10cSrcweir ScMenuFloatingWindow::~ScMenuFloatingWindow()
334*cdf0e10cSrcweir {
335*cdf0e10cSrcweir     EndPopupMode();
336*cdf0e10cSrcweir }
337*cdf0e10cSrcweir 
338*cdf0e10cSrcweir void ScMenuFloatingWindow::MouseMove(const MouseEvent& rMEvt)
339*cdf0e10cSrcweir {
340*cdf0e10cSrcweir     const Point& rPos = rMEvt.GetPosPixel();
341*cdf0e10cSrcweir     size_t nSelectedMenu = getEnclosingMenuItem(rPos);
342*cdf0e10cSrcweir     setSelectedMenuItem(nSelectedMenu, true, false);
343*cdf0e10cSrcweir 
344*cdf0e10cSrcweir     Window::MouseMove(rMEvt);
345*cdf0e10cSrcweir }
346*cdf0e10cSrcweir 
347*cdf0e10cSrcweir void ScMenuFloatingWindow::MouseButtonDown(const MouseEvent& rMEvt)
348*cdf0e10cSrcweir {
349*cdf0e10cSrcweir     const Point& rPos = rMEvt.GetPosPixel();
350*cdf0e10cSrcweir     mnClickedMenu = getEnclosingMenuItem(rPos);
351*cdf0e10cSrcweir     Window::MouseButtonDown(rMEvt);
352*cdf0e10cSrcweir }
353*cdf0e10cSrcweir 
354*cdf0e10cSrcweir void ScMenuFloatingWindow::MouseButtonUp(const MouseEvent& rMEvt)
355*cdf0e10cSrcweir {
356*cdf0e10cSrcweir     executeMenuItem(mnClickedMenu);
357*cdf0e10cSrcweir     mnClickedMenu = MENU_NOT_SELECTED;
358*cdf0e10cSrcweir     Window::MouseButtonUp(rMEvt);
359*cdf0e10cSrcweir }
360*cdf0e10cSrcweir 
361*cdf0e10cSrcweir void ScMenuFloatingWindow::KeyInput(const KeyEvent& rKEvt)
362*cdf0e10cSrcweir {
363*cdf0e10cSrcweir     const KeyCode& rKeyCode = rKEvt.GetKeyCode();
364*cdf0e10cSrcweir     bool bHandled = true;
365*cdf0e10cSrcweir     size_t nSelectedMenu = mnSelectedMenu;
366*cdf0e10cSrcweir     size_t nLastMenuPos = maMenuItems.size() - 1;
367*cdf0e10cSrcweir     switch (rKeyCode.GetCode())
368*cdf0e10cSrcweir     {
369*cdf0e10cSrcweir         case KEY_UP:
370*cdf0e10cSrcweir             if (nSelectedMenu == MENU_NOT_SELECTED || nSelectedMenu == 0)
371*cdf0e10cSrcweir                 nSelectedMenu = nLastMenuPos;
372*cdf0e10cSrcweir             else
373*cdf0e10cSrcweir                 --nSelectedMenu;
374*cdf0e10cSrcweir             setSelectedMenuItem(nSelectedMenu, false, false);
375*cdf0e10cSrcweir         break;
376*cdf0e10cSrcweir         case KEY_DOWN:
377*cdf0e10cSrcweir             if (nSelectedMenu == MENU_NOT_SELECTED || nSelectedMenu == nLastMenuPos)
378*cdf0e10cSrcweir                 nSelectedMenu = 0;
379*cdf0e10cSrcweir             else
380*cdf0e10cSrcweir                 ++nSelectedMenu;
381*cdf0e10cSrcweir             setSelectedMenuItem(nSelectedMenu, false, false);
382*cdf0e10cSrcweir         break;
383*cdf0e10cSrcweir         case KEY_LEFT:
384*cdf0e10cSrcweir             if (mpParentMenu)
385*cdf0e10cSrcweir                 mpParentMenu->endSubMenu(this);
386*cdf0e10cSrcweir         break;
387*cdf0e10cSrcweir         case KEY_RIGHT:
388*cdf0e10cSrcweir         {
389*cdf0e10cSrcweir             if (mnSelectedMenu >= maMenuItems.size() || mnSelectedMenu == MENU_NOT_SELECTED)
390*cdf0e10cSrcweir                 break;
391*cdf0e10cSrcweir 
392*cdf0e10cSrcweir             const MenuItemData& rMenu = maMenuItems[mnSelectedMenu];
393*cdf0e10cSrcweir             if (!rMenu.mbEnabled || !rMenu.mpSubMenuWin)
394*cdf0e10cSrcweir                 break;
395*cdf0e10cSrcweir 
396*cdf0e10cSrcweir             maOpenTimer.mnMenuPos = mnSelectedMenu;
397*cdf0e10cSrcweir             maOpenTimer.mpSubMenu = rMenu.mpSubMenuWin.get();
398*cdf0e10cSrcweir             launchSubMenu(true);
399*cdf0e10cSrcweir         }
400*cdf0e10cSrcweir         break;
401*cdf0e10cSrcweir         case KEY_RETURN:
402*cdf0e10cSrcweir             if (nSelectedMenu != MENU_NOT_SELECTED)
403*cdf0e10cSrcweir                 executeMenuItem(nSelectedMenu);
404*cdf0e10cSrcweir         break;
405*cdf0e10cSrcweir         default:
406*cdf0e10cSrcweir             bHandled = false;
407*cdf0e10cSrcweir     }
408*cdf0e10cSrcweir 
409*cdf0e10cSrcweir     if (!bHandled)
410*cdf0e10cSrcweir         Window::KeyInput(rKEvt);
411*cdf0e10cSrcweir }
412*cdf0e10cSrcweir 
413*cdf0e10cSrcweir void ScMenuFloatingWindow::Paint(const Rectangle& /*rRect*/)
414*cdf0e10cSrcweir {
415*cdf0e10cSrcweir     const StyleSettings& rStyle = GetSettings().GetStyleSettings();
416*cdf0e10cSrcweir     Color aBackColor = rStyle.GetMenuColor();
417*cdf0e10cSrcweir     Color aBorderColor = rStyle.GetShadowColor();
418*cdf0e10cSrcweir 
419*cdf0e10cSrcweir     Rectangle aCtrlRect(Point(0, 0), GetOutputSizePixel());
420*cdf0e10cSrcweir 
421*cdf0e10cSrcweir     // Window background
422*cdf0e10cSrcweir     bool bNativeDrawn = true;
423*cdf0e10cSrcweir     if (IsNativeControlSupported(CTRL_MENU_POPUP, PART_ENTIRE_CONTROL))
424*cdf0e10cSrcweir     {
425*cdf0e10cSrcweir         SetClipRegion();
426*cdf0e10cSrcweir         bNativeDrawn = DrawNativeControl(
427*cdf0e10cSrcweir             CTRL_MENU_POPUP, PART_ENTIRE_CONTROL, aCtrlRect, CTRL_STATE_ENABLED,
428*cdf0e10cSrcweir             ImplControlValue(), OUString());
429*cdf0e10cSrcweir     }
430*cdf0e10cSrcweir     else
431*cdf0e10cSrcweir         bNativeDrawn = false;
432*cdf0e10cSrcweir 
433*cdf0e10cSrcweir     if (!bNativeDrawn)
434*cdf0e10cSrcweir     {
435*cdf0e10cSrcweir         SetFillColor(aBackColor);
436*cdf0e10cSrcweir         SetLineColor(aBorderColor);
437*cdf0e10cSrcweir         DrawRect(aCtrlRect);
438*cdf0e10cSrcweir     }
439*cdf0e10cSrcweir 
440*cdf0e10cSrcweir     // Menu items
441*cdf0e10cSrcweir     SetTextColor(rStyle.GetMenuTextColor());
442*cdf0e10cSrcweir     drawAllMenuItems();
443*cdf0e10cSrcweir }
444*cdf0e10cSrcweir 
445*cdf0e10cSrcweir Reference<XAccessible> ScMenuFloatingWindow::CreateAccessible()
446*cdf0e10cSrcweir {
447*cdf0e10cSrcweir     if (!mxAccessible.is())
448*cdf0e10cSrcweir     {
449*cdf0e10cSrcweir         Reference<XAccessible> xAccParent = mpParentMenu ?
450*cdf0e10cSrcweir             mpParentMenu->GetAccessible() : GetAccessibleParentWindow()->GetAccessible();
451*cdf0e10cSrcweir 
452*cdf0e10cSrcweir         mxAccessible.set(new ScAccessibleFilterMenu(xAccParent, this, maName, 999, getDoc()));
453*cdf0e10cSrcweir         ScAccessibleFilterMenu* p = static_cast<ScAccessibleFilterMenu*>(
454*cdf0e10cSrcweir             mxAccessible.get());
455*cdf0e10cSrcweir 
456*cdf0e10cSrcweir         vector<MenuItemData>::const_iterator itr, itrBeg = maMenuItems.begin(), itrEnd = maMenuItems.end();
457*cdf0e10cSrcweir         for (itr = itrBeg; itr != itrEnd; ++itr)
458*cdf0e10cSrcweir         {
459*cdf0e10cSrcweir             size_t nPos = ::std::distance(itrBeg, itr);
460*cdf0e10cSrcweir             p->appendMenuItem(itr->maText, itr->mbEnabled, nPos);
461*cdf0e10cSrcweir         }
462*cdf0e10cSrcweir     }
463*cdf0e10cSrcweir 
464*cdf0e10cSrcweir     return mxAccessible;
465*cdf0e10cSrcweir }
466*cdf0e10cSrcweir 
467*cdf0e10cSrcweir void ScMenuFloatingWindow::addMenuItem(const OUString& rText, bool bEnabled, Action* pAction)
468*cdf0e10cSrcweir {
469*cdf0e10cSrcweir     MenuItemData aItem;
470*cdf0e10cSrcweir     aItem.maText = rText;
471*cdf0e10cSrcweir     aItem.mbEnabled = bEnabled;
472*cdf0e10cSrcweir     aItem.mpAction.reset(pAction);
473*cdf0e10cSrcweir     maMenuItems.push_back(aItem);
474*cdf0e10cSrcweir }
475*cdf0e10cSrcweir 
476*cdf0e10cSrcweir ScMenuFloatingWindow* ScMenuFloatingWindow::addSubMenuItem(const OUString& rText, bool bEnabled)
477*cdf0e10cSrcweir {
478*cdf0e10cSrcweir     MenuItemData aItem;
479*cdf0e10cSrcweir     aItem.maText = rText;
480*cdf0e10cSrcweir     aItem.mbEnabled = bEnabled;
481*cdf0e10cSrcweir     aItem.mpSubMenuWin.reset(new ScMenuFloatingWindow(this, mpDoc, GetMenuStackLevel()+1));
482*cdf0e10cSrcweir     aItem.mpSubMenuWin->setName(rText);
483*cdf0e10cSrcweir     maMenuItems.push_back(aItem);
484*cdf0e10cSrcweir     return aItem.mpSubMenuWin.get();
485*cdf0e10cSrcweir }
486*cdf0e10cSrcweir 
487*cdf0e10cSrcweir void ScMenuFloatingWindow::drawMenuItem(size_t nPos)
488*cdf0e10cSrcweir {
489*cdf0e10cSrcweir     if (nPos >= maMenuItems.size())
490*cdf0e10cSrcweir         return;
491*cdf0e10cSrcweir 
492*cdf0e10cSrcweir     Point aPos;
493*cdf0e10cSrcweir     Size aSize;
494*cdf0e10cSrcweir     getMenuItemPosSize(nPos, aPos, aSize);
495*cdf0e10cSrcweir 
496*cdf0e10cSrcweir     DecorationView aDecoView(this);
497*cdf0e10cSrcweir     long nXOffset = 5;
498*cdf0e10cSrcweir     long nYOffset = (aSize.Height() - maLabelFont.GetHeight())/2;
499*cdf0e10cSrcweir     DrawCtrlText(Point(aPos.X()+nXOffset, aPos.Y() + nYOffset), maMenuItems[nPos].maText, 0, STRING_LEN,
500*cdf0e10cSrcweir                  maMenuItems[nPos].mbEnabled ? TEXT_DRAW_MNEMONIC : TEXT_DRAW_DISABLE);
501*cdf0e10cSrcweir 
502*cdf0e10cSrcweir     if (maMenuItems[nPos].mpSubMenuWin)
503*cdf0e10cSrcweir     {
504*cdf0e10cSrcweir         long nFontHeight = maLabelFont.GetHeight();
505*cdf0e10cSrcweir         Point aMarkerPos = aPos;
506*cdf0e10cSrcweir         aMarkerPos.Y() += aSize.Height()/2 - nFontHeight/4 + 1;
507*cdf0e10cSrcweir         aMarkerPos.X() += aSize.Width() - nFontHeight + nFontHeight/4;
508*cdf0e10cSrcweir         Size aMarkerSize(nFontHeight/2, nFontHeight/2);
509*cdf0e10cSrcweir         aDecoView.DrawSymbol(Rectangle(aMarkerPos, aMarkerSize),
510*cdf0e10cSrcweir                              SYMBOL_SPIN_RIGHT, GetTextColor(), 0);
511*cdf0e10cSrcweir     }
512*cdf0e10cSrcweir }
513*cdf0e10cSrcweir 
514*cdf0e10cSrcweir void ScMenuFloatingWindow::drawAllMenuItems()
515*cdf0e10cSrcweir {
516*cdf0e10cSrcweir     size_t n = maMenuItems.size();
517*cdf0e10cSrcweir     for (size_t i = 0; i < n; ++i)
518*cdf0e10cSrcweir         highlightMenuItem(i, i == mnSelectedMenu);
519*cdf0e10cSrcweir }
520*cdf0e10cSrcweir 
521*cdf0e10cSrcweir const Font& ScMenuFloatingWindow::getLabelFont() const
522*cdf0e10cSrcweir {
523*cdf0e10cSrcweir     return maLabelFont;
524*cdf0e10cSrcweir }
525*cdf0e10cSrcweir 
526*cdf0e10cSrcweir void ScMenuFloatingWindow::executeMenuItem(size_t nPos)
527*cdf0e10cSrcweir {
528*cdf0e10cSrcweir     if (nPos >= maMenuItems.size())
529*cdf0e10cSrcweir         return;
530*cdf0e10cSrcweir 
531*cdf0e10cSrcweir     if (!maMenuItems[nPos].mpAction)
532*cdf0e10cSrcweir         // no action is defined.
533*cdf0e10cSrcweir         return;
534*cdf0e10cSrcweir 
535*cdf0e10cSrcweir     maMenuItems[nPos].mpAction->execute();
536*cdf0e10cSrcweir     terminateAllPopupMenus();
537*cdf0e10cSrcweir }
538*cdf0e10cSrcweir 
539*cdf0e10cSrcweir void ScMenuFloatingWindow::setSelectedMenuItem(size_t nPos, bool bSubMenuTimer, bool bEnsureSubMenu)
540*cdf0e10cSrcweir {
541*cdf0e10cSrcweir     if (mnSelectedMenu == nPos)
542*cdf0e10cSrcweir         // nothing to do.
543*cdf0e10cSrcweir         return;
544*cdf0e10cSrcweir 
545*cdf0e10cSrcweir     if (bEnsureSubMenu)
546*cdf0e10cSrcweir     {
547*cdf0e10cSrcweir         // Dismiss any child popup menu windows.
548*cdf0e10cSrcweir         if (mnSelectedMenu < maMenuItems.size() &&
549*cdf0e10cSrcweir             maMenuItems[mnSelectedMenu].mpSubMenuWin &&
550*cdf0e10cSrcweir             maMenuItems[mnSelectedMenu].mpSubMenuWin->IsVisible())
551*cdf0e10cSrcweir         {
552*cdf0e10cSrcweir             maMenuItems[mnSelectedMenu].mpSubMenuWin->ensureSubMenuNotVisible();
553*cdf0e10cSrcweir         }
554*cdf0e10cSrcweir 
555*cdf0e10cSrcweir         // The popup is not visible, yet a menu item is selected.  The request
556*cdf0e10cSrcweir         // most likely comes from the accessible object.  Make sure this
557*cdf0e10cSrcweir         // window, as well as all its parent windows are visible.
558*cdf0e10cSrcweir         if (!IsVisible() && mpParentMenu)
559*cdf0e10cSrcweir             mpParentMenu->ensureSubMenuVisible(this);
560*cdf0e10cSrcweir     }
561*cdf0e10cSrcweir 
562*cdf0e10cSrcweir     selectMenuItem(mnSelectedMenu, false, bSubMenuTimer);
563*cdf0e10cSrcweir     selectMenuItem(nPos, true, bSubMenuTimer);
564*cdf0e10cSrcweir     mnSelectedMenu = nPos;
565*cdf0e10cSrcweir 
566*cdf0e10cSrcweir     fireMenuHighlightedEvent();
567*cdf0e10cSrcweir }
568*cdf0e10cSrcweir 
569*cdf0e10cSrcweir size_t ScMenuFloatingWindow::getSelectedMenuItem() const
570*cdf0e10cSrcweir {
571*cdf0e10cSrcweir     return mnSelectedMenu;
572*cdf0e10cSrcweir }
573*cdf0e10cSrcweir 
574*cdf0e10cSrcweir void ScMenuFloatingWindow::handleMenuTimeout(SubMenuItemData* pTimer)
575*cdf0e10cSrcweir {
576*cdf0e10cSrcweir     if (pTimer == &maOpenTimer)
577*cdf0e10cSrcweir     {
578*cdf0e10cSrcweir         // Close any open submenu immediately.
579*cdf0e10cSrcweir         if (maCloseTimer.mpSubMenu)
580*cdf0e10cSrcweir         {
581*cdf0e10cSrcweir             maCloseTimer.mpSubMenu->EndPopupMode();
582*cdf0e10cSrcweir             maCloseTimer.mpSubMenu = NULL;
583*cdf0e10cSrcweir             maCloseTimer.maTimer.Stop();
584*cdf0e10cSrcweir         }
585*cdf0e10cSrcweir 
586*cdf0e10cSrcweir         launchSubMenu(false);
587*cdf0e10cSrcweir     }
588*cdf0e10cSrcweir     else if (pTimer == &maCloseTimer)
589*cdf0e10cSrcweir     {
590*cdf0e10cSrcweir         // end submenu.
591*cdf0e10cSrcweir         if (maCloseTimer.mpSubMenu)
592*cdf0e10cSrcweir         {
593*cdf0e10cSrcweir             maOpenTimer.mpSubMenu = NULL;
594*cdf0e10cSrcweir 
595*cdf0e10cSrcweir             maCloseTimer.mpSubMenu->EndPopupMode();
596*cdf0e10cSrcweir             maCloseTimer.mpSubMenu = NULL;
597*cdf0e10cSrcweir 
598*cdf0e10cSrcweir             highlightMenuItem(maOpenTimer.mnMenuPos, false);
599*cdf0e10cSrcweir             maOpenTimer.mnMenuPos = MENU_NOT_SELECTED;
600*cdf0e10cSrcweir         }
601*cdf0e10cSrcweir     }
602*cdf0e10cSrcweir }
603*cdf0e10cSrcweir 
604*cdf0e10cSrcweir void ScMenuFloatingWindow::queueLaunchSubMenu(size_t nPos, ScMenuFloatingWindow* pMenu)
605*cdf0e10cSrcweir {
606*cdf0e10cSrcweir     if (!pMenu)
607*cdf0e10cSrcweir         return;
608*cdf0e10cSrcweir 
609*cdf0e10cSrcweir     // Set the submenu on launch queue.
610*cdf0e10cSrcweir     if (maOpenTimer.mpSubMenu)
611*cdf0e10cSrcweir     {
612*cdf0e10cSrcweir         if (maOpenTimer.mpSubMenu == pMenu)
613*cdf0e10cSrcweir         {
614*cdf0e10cSrcweir             if (pMenu == maCloseTimer.mpSubMenu)
615*cdf0e10cSrcweir                 maCloseTimer.reset();
616*cdf0e10cSrcweir             return;
617*cdf0e10cSrcweir         }
618*cdf0e10cSrcweir 
619*cdf0e10cSrcweir         // new submenu is being requested.
620*cdf0e10cSrcweir         queueCloseSubMenu();
621*cdf0e10cSrcweir     }
622*cdf0e10cSrcweir 
623*cdf0e10cSrcweir     maOpenTimer.mpSubMenu = pMenu;
624*cdf0e10cSrcweir     maOpenTimer.mnMenuPos = nPos;
625*cdf0e10cSrcweir     maOpenTimer.maTimer.Start();
626*cdf0e10cSrcweir }
627*cdf0e10cSrcweir 
628*cdf0e10cSrcweir void ScMenuFloatingWindow::queueCloseSubMenu()
629*cdf0e10cSrcweir {
630*cdf0e10cSrcweir     if (!maOpenTimer.mpSubMenu)
631*cdf0e10cSrcweir         // There is no submenu to close.
632*cdf0e10cSrcweir         return;
633*cdf0e10cSrcweir 
634*cdf0e10cSrcweir     // Stop any submenu on queue for opening.
635*cdf0e10cSrcweir     maOpenTimer.maTimer.Stop();
636*cdf0e10cSrcweir 
637*cdf0e10cSrcweir     maCloseTimer.mpSubMenu = maOpenTimer.mpSubMenu;
638*cdf0e10cSrcweir     maCloseTimer.mnMenuPos = maOpenTimer.mnMenuPos;
639*cdf0e10cSrcweir     maCloseTimer.maTimer.Start();
640*cdf0e10cSrcweir }
641*cdf0e10cSrcweir 
642*cdf0e10cSrcweir void ScMenuFloatingWindow::launchSubMenu(bool bSetMenuPos)
643*cdf0e10cSrcweir {
644*cdf0e10cSrcweir     Point aPos;
645*cdf0e10cSrcweir     Size aSize;
646*cdf0e10cSrcweir     getMenuItemPosSize(maOpenTimer.mnMenuPos, aPos, aSize);
647*cdf0e10cSrcweir     ScMenuFloatingWindow* pSubMenu = maOpenTimer.mpSubMenu;
648*cdf0e10cSrcweir 
649*cdf0e10cSrcweir     if (!pSubMenu)
650*cdf0e10cSrcweir         return;
651*cdf0e10cSrcweir 
652*cdf0e10cSrcweir     sal_uInt32 nOldFlags = GetPopupModeFlags();
653*cdf0e10cSrcweir     SetPopupModeFlags(nOldFlags | FLOATWIN_POPUPMODE_NOAPPFOCUSCLOSE);
654*cdf0e10cSrcweir     pSubMenu->resizeToFitMenuItems(); // set the size before launching the popup to get it positioned correctly.
655*cdf0e10cSrcweir     pSubMenu->StartPopupMode(
656*cdf0e10cSrcweir         Rectangle(aPos,aSize), (FLOATWIN_POPUPMODE_RIGHT | FLOATWIN_POPUPMODE_GRABFOCUS));
657*cdf0e10cSrcweir     pSubMenu->AddPopupModeWindow(this);
658*cdf0e10cSrcweir     if (bSetMenuPos)
659*cdf0e10cSrcweir         pSubMenu->setSelectedMenuItem(0, false, false); // select menu item after the popup becomes fully visible.
660*cdf0e10cSrcweir     SetPopupModeFlags(nOldFlags);
661*cdf0e10cSrcweir }
662*cdf0e10cSrcweir 
663*cdf0e10cSrcweir void ScMenuFloatingWindow::endSubMenu(ScMenuFloatingWindow* pSubMenu)
664*cdf0e10cSrcweir {
665*cdf0e10cSrcweir     if (!pSubMenu)
666*cdf0e10cSrcweir         return;
667*cdf0e10cSrcweir 
668*cdf0e10cSrcweir     pSubMenu->EndPopupMode();
669*cdf0e10cSrcweir     maOpenTimer.reset();
670*cdf0e10cSrcweir 
671*cdf0e10cSrcweir     size_t nMenuPos = getSubMenuPos(pSubMenu);
672*cdf0e10cSrcweir     if (nMenuPos != MENU_NOT_SELECTED)
673*cdf0e10cSrcweir     {
674*cdf0e10cSrcweir         highlightMenuItem(nMenuPos, true);
675*cdf0e10cSrcweir         mnSelectedMenu = nMenuPos;
676*cdf0e10cSrcweir         fireMenuHighlightedEvent();
677*cdf0e10cSrcweir     }
678*cdf0e10cSrcweir }
679*cdf0e10cSrcweir 
680*cdf0e10cSrcweir void ScMenuFloatingWindow::fillMenuItemsToAccessible(ScAccessibleFilterMenu* pAccMenu) const
681*cdf0e10cSrcweir {
682*cdf0e10cSrcweir     vector<MenuItemData>::const_iterator itr, itrBeg = maMenuItems.begin(), itrEnd = maMenuItems.end();
683*cdf0e10cSrcweir     for (itr = itrBeg; itr != itrEnd; ++itr)
684*cdf0e10cSrcweir     {
685*cdf0e10cSrcweir         size_t nPos = ::std::distance(itrBeg, itr);
686*cdf0e10cSrcweir         pAccMenu->appendMenuItem(itr->maText, itr->mbEnabled, nPos);
687*cdf0e10cSrcweir     }
688*cdf0e10cSrcweir }
689*cdf0e10cSrcweir 
690*cdf0e10cSrcweir ScDocument* ScMenuFloatingWindow::getDoc()
691*cdf0e10cSrcweir {
692*cdf0e10cSrcweir     return mpDoc;
693*cdf0e10cSrcweir }
694*cdf0e10cSrcweir 
695*cdf0e10cSrcweir void ScMenuFloatingWindow::resizeToFitMenuItems()
696*cdf0e10cSrcweir {
697*cdf0e10cSrcweir     if (maMenuItems.empty())
698*cdf0e10cSrcweir         return;
699*cdf0e10cSrcweir 
700*cdf0e10cSrcweir     vector<MenuItemData>::const_iterator itr = maMenuItems.begin(), itrEnd = maMenuItems.end();
701*cdf0e10cSrcweir     long nTextWidth = 0;
702*cdf0e10cSrcweir     for (; itr != itrEnd; ++itr)
703*cdf0e10cSrcweir         nTextWidth = ::std::max(GetTextWidth(itr->maText), nTextWidth);
704*cdf0e10cSrcweir 
705*cdf0e10cSrcweir     size_t nLastPos = maMenuItems.size()-1;
706*cdf0e10cSrcweir     Point aPos;
707*cdf0e10cSrcweir     Size aSize;
708*cdf0e10cSrcweir     getMenuItemPosSize(nLastPos, aPos, aSize);
709*cdf0e10cSrcweir     aPos.X() += nTextWidth + 15;
710*cdf0e10cSrcweir     aPos.Y() += aSize.Height() + 5;
711*cdf0e10cSrcweir     SetOutputSizePixel(Size(aPos.X(), aPos.Y()));
712*cdf0e10cSrcweir }
713*cdf0e10cSrcweir 
714*cdf0e10cSrcweir void ScMenuFloatingWindow::selectMenuItem(size_t nPos, bool bSelected, bool bSubMenuTimer)
715*cdf0e10cSrcweir {
716*cdf0e10cSrcweir     if (nPos >= maMenuItems.size() || nPos == MENU_NOT_SELECTED)
717*cdf0e10cSrcweir     {
718*cdf0e10cSrcweir         queueCloseSubMenu();
719*cdf0e10cSrcweir         return;
720*cdf0e10cSrcweir     }
721*cdf0e10cSrcweir 
722*cdf0e10cSrcweir     if (!maMenuItems[nPos].mbEnabled)
723*cdf0e10cSrcweir     {
724*cdf0e10cSrcweir         queueCloseSubMenu();
725*cdf0e10cSrcweir         return;
726*cdf0e10cSrcweir     }
727*cdf0e10cSrcweir 
728*cdf0e10cSrcweir     highlightMenuItem(nPos, bSelected);
729*cdf0e10cSrcweir 
730*cdf0e10cSrcweir     if (bSelected)
731*cdf0e10cSrcweir     {
732*cdf0e10cSrcweir         if (mpParentMenu)
733*cdf0e10cSrcweir             mpParentMenu->setSubMenuFocused(this);
734*cdf0e10cSrcweir 
735*cdf0e10cSrcweir         if (bSubMenuTimer)
736*cdf0e10cSrcweir         {
737*cdf0e10cSrcweir             if (maMenuItems[nPos].mpSubMenuWin)
738*cdf0e10cSrcweir             {
739*cdf0e10cSrcweir                 ScMenuFloatingWindow* pSubMenu = maMenuItems[nPos].mpSubMenuWin.get();
740*cdf0e10cSrcweir                 queueLaunchSubMenu(nPos, pSubMenu);
741*cdf0e10cSrcweir             }
742*cdf0e10cSrcweir             else
743*cdf0e10cSrcweir                 queueCloseSubMenu();
744*cdf0e10cSrcweir         }
745*cdf0e10cSrcweir     }
746*cdf0e10cSrcweir }
747*cdf0e10cSrcweir 
748*cdf0e10cSrcweir void ScMenuFloatingWindow::clearSelectedMenuItem()
749*cdf0e10cSrcweir {
750*cdf0e10cSrcweir     selectMenuItem(mnSelectedMenu, false, false);
751*cdf0e10cSrcweir     mnSelectedMenu = MENU_NOT_SELECTED;
752*cdf0e10cSrcweir }
753*cdf0e10cSrcweir 
754*cdf0e10cSrcweir ScMenuFloatingWindow* ScMenuFloatingWindow::getSubMenuWindow(size_t nPos) const
755*cdf0e10cSrcweir {
756*cdf0e10cSrcweir     if (maMenuItems.size() <= nPos)
757*cdf0e10cSrcweir         return NULL;
758*cdf0e10cSrcweir 
759*cdf0e10cSrcweir     return maMenuItems[nPos].mpSubMenuWin.get();
760*cdf0e10cSrcweir }
761*cdf0e10cSrcweir 
762*cdf0e10cSrcweir bool ScMenuFloatingWindow::isMenuItemSelected(size_t nPos) const
763*cdf0e10cSrcweir {
764*cdf0e10cSrcweir     return nPos == mnSelectedMenu;
765*cdf0e10cSrcweir }
766*cdf0e10cSrcweir 
767*cdf0e10cSrcweir void ScMenuFloatingWindow::setName(const OUString& rName)
768*cdf0e10cSrcweir {
769*cdf0e10cSrcweir     maName = rName;
770*cdf0e10cSrcweir }
771*cdf0e10cSrcweir 
772*cdf0e10cSrcweir const OUString& ScMenuFloatingWindow::getName() const
773*cdf0e10cSrcweir {
774*cdf0e10cSrcweir     return maName;
775*cdf0e10cSrcweir }
776*cdf0e10cSrcweir 
777*cdf0e10cSrcweir void ScMenuFloatingWindow::highlightMenuItem(size_t nPos, bool bSelected)
778*cdf0e10cSrcweir {
779*cdf0e10cSrcweir     if (nPos == MENU_NOT_SELECTED)
780*cdf0e10cSrcweir         return;
781*cdf0e10cSrcweir 
782*cdf0e10cSrcweir     const StyleSettings& rStyle = GetSettings().GetStyleSettings();
783*cdf0e10cSrcweir     Color aBackColor = rStyle.GetMenuColor();
784*cdf0e10cSrcweir     SetFillColor(aBackColor);
785*cdf0e10cSrcweir     SetLineColor(aBackColor);
786*cdf0e10cSrcweir 
787*cdf0e10cSrcweir     Point aPos;
788*cdf0e10cSrcweir     Size aSize;
789*cdf0e10cSrcweir     getMenuItemPosSize(nPos, aPos, aSize);
790*cdf0e10cSrcweir     Rectangle aRegion(aPos,aSize);
791*cdf0e10cSrcweir 
792*cdf0e10cSrcweir     if (IsNativeControlSupported(CTRL_MENU_POPUP, PART_ENTIRE_CONTROL))
793*cdf0e10cSrcweir     {
794*cdf0e10cSrcweir         Push(PUSH_CLIPREGION);
795*cdf0e10cSrcweir         IntersectClipRegion(Rectangle(aPos, aSize));
796*cdf0e10cSrcweir         Rectangle aCtrlRect(Point(0,0), GetOutputSizePixel());
797*cdf0e10cSrcweir         DrawNativeControl(
798*cdf0e10cSrcweir             CTRL_MENU_POPUP, PART_ENTIRE_CONTROL, aCtrlRect, CTRL_STATE_ENABLED,
799*cdf0e10cSrcweir             ImplControlValue(), OUString());
800*cdf0e10cSrcweir 
801*cdf0e10cSrcweir         Pop();
802*cdf0e10cSrcweir     }
803*cdf0e10cSrcweir 
804*cdf0e10cSrcweir     bool bNativeDrawn = true;
805*cdf0e10cSrcweir     if (IsNativeControlSupported(CTRL_MENU_POPUP, PART_MENU_ITEM))
806*cdf0e10cSrcweir     {
807*cdf0e10cSrcweir         ControlState nState = bSelected ? CTRL_STATE_SELECTED : 0;
808*cdf0e10cSrcweir         if (maMenuItems[nPos].mbEnabled)
809*cdf0e10cSrcweir             nState |= CTRL_STATE_ENABLED;
810*cdf0e10cSrcweir         bNativeDrawn = DrawNativeControl(
811*cdf0e10cSrcweir             CTRL_MENU_POPUP, PART_MENU_ITEM, aRegion, nState, ImplControlValue(), OUString());
812*cdf0e10cSrcweir     }
813*cdf0e10cSrcweir     else
814*cdf0e10cSrcweir         bNativeDrawn = false;
815*cdf0e10cSrcweir 
816*cdf0e10cSrcweir     if (!bNativeDrawn)
817*cdf0e10cSrcweir     {
818*cdf0e10cSrcweir         if (bSelected)
819*cdf0e10cSrcweir         {
820*cdf0e10cSrcweir             aBackColor = rStyle.GetMenuHighlightColor();
821*cdf0e10cSrcweir             SetFillColor(aBackColor);
822*cdf0e10cSrcweir             SetLineColor(aBackColor);
823*cdf0e10cSrcweir         }
824*cdf0e10cSrcweir         DrawRect(Rectangle(aPos,aSize));
825*cdf0e10cSrcweir     }
826*cdf0e10cSrcweir 
827*cdf0e10cSrcweir     Color aTextColor = bSelected ? rStyle.GetMenuHighlightTextColor() : rStyle.GetMenuTextColor();
828*cdf0e10cSrcweir     SetTextColor(aTextColor);
829*cdf0e10cSrcweir     drawMenuItem(nPos);
830*cdf0e10cSrcweir }
831*cdf0e10cSrcweir 
832*cdf0e10cSrcweir void ScMenuFloatingWindow::getMenuItemPosSize(size_t nPos, Point& rPos, Size& rSize) const
833*cdf0e10cSrcweir {
834*cdf0e10cSrcweir     const sal_uInt16 nLeftMargin = 5;
835*cdf0e10cSrcweir     const sal_uInt16 nTopMargin = 5;
836*cdf0e10cSrcweir     const sal_uInt16 nMenuItemHeight = static_cast< sal_uInt16 >( maLabelFont.GetHeight()*1.8 );
837*cdf0e10cSrcweir 
838*cdf0e10cSrcweir     Size aWndSize = GetSizePixel();
839*cdf0e10cSrcweir 
840*cdf0e10cSrcweir     Point aPos1(nLeftMargin, nTopMargin);
841*cdf0e10cSrcweir     Size aSize1(aWndSize.Width() - nLeftMargin*2, nMenuItemHeight);
842*cdf0e10cSrcweir 
843*cdf0e10cSrcweir     rPos = aPos1;
844*cdf0e10cSrcweir     rPos.Y() += aSize1.Height()*nPos;
845*cdf0e10cSrcweir     rSize = aSize1;
846*cdf0e10cSrcweir }
847*cdf0e10cSrcweir 
848*cdf0e10cSrcweir ScMenuFloatingWindow* ScMenuFloatingWindow::getParentMenuWindow() const
849*cdf0e10cSrcweir {
850*cdf0e10cSrcweir     return mpParentMenu;
851*cdf0e10cSrcweir }
852*cdf0e10cSrcweir 
853*cdf0e10cSrcweir size_t ScMenuFloatingWindow::getEnclosingMenuItem(const Point& rPos) const
854*cdf0e10cSrcweir {
855*cdf0e10cSrcweir     size_t n = maMenuItems.size();
856*cdf0e10cSrcweir     for (size_t i = 0; i < n; ++i)
857*cdf0e10cSrcweir     {
858*cdf0e10cSrcweir         Point aPos;
859*cdf0e10cSrcweir         Size aSize;
860*cdf0e10cSrcweir         getMenuItemPosSize(i, aPos, aSize);
861*cdf0e10cSrcweir         Rectangle aRect(aPos, aSize);
862*cdf0e10cSrcweir         if (aRect.IsInside(rPos))
863*cdf0e10cSrcweir             return i;
864*cdf0e10cSrcweir     }
865*cdf0e10cSrcweir     return MENU_NOT_SELECTED;
866*cdf0e10cSrcweir }
867*cdf0e10cSrcweir 
868*cdf0e10cSrcweir size_t ScMenuFloatingWindow::getSubMenuPos(ScMenuFloatingWindow* pSubMenu)
869*cdf0e10cSrcweir {
870*cdf0e10cSrcweir     size_t n = maMenuItems.size();
871*cdf0e10cSrcweir     for (size_t i = 0; i < n; ++i)
872*cdf0e10cSrcweir     {
873*cdf0e10cSrcweir         if (maMenuItems[i].mpSubMenuWin.get() == pSubMenu)
874*cdf0e10cSrcweir             return i;
875*cdf0e10cSrcweir     }
876*cdf0e10cSrcweir     return MENU_NOT_SELECTED;
877*cdf0e10cSrcweir }
878*cdf0e10cSrcweir 
879*cdf0e10cSrcweir void ScMenuFloatingWindow::fireMenuHighlightedEvent()
880*cdf0e10cSrcweir {
881*cdf0e10cSrcweir     if (mnSelectedMenu == MENU_NOT_SELECTED)
882*cdf0e10cSrcweir         return;
883*cdf0e10cSrcweir 
884*cdf0e10cSrcweir     if (!mxAccessible.is())
885*cdf0e10cSrcweir         return;
886*cdf0e10cSrcweir 
887*cdf0e10cSrcweir     Reference<XAccessibleContext> xAccCxt = mxAccessible->getAccessibleContext();
888*cdf0e10cSrcweir     if (!xAccCxt.is())
889*cdf0e10cSrcweir         return;
890*cdf0e10cSrcweir 
891*cdf0e10cSrcweir     Reference<XAccessible> xAccMenu = xAccCxt->getAccessibleChild(mnSelectedMenu);
892*cdf0e10cSrcweir     if (!xAccMenu.is())
893*cdf0e10cSrcweir         return;
894*cdf0e10cSrcweir 
895*cdf0e10cSrcweir     VclAccessibleEvent aEvent(VCLEVENT_MENU_HIGHLIGHT, xAccMenu);
896*cdf0e10cSrcweir     FireVclEvent(&aEvent);
897*cdf0e10cSrcweir }
898*cdf0e10cSrcweir 
899*cdf0e10cSrcweir void ScMenuFloatingWindow::setSubMenuFocused(ScMenuFloatingWindow* pSubMenu)
900*cdf0e10cSrcweir {
901*cdf0e10cSrcweir     maCloseTimer.reset();
902*cdf0e10cSrcweir     size_t nMenuPos = getSubMenuPos(pSubMenu);
903*cdf0e10cSrcweir     if (mnSelectedMenu != nMenuPos)
904*cdf0e10cSrcweir     {
905*cdf0e10cSrcweir         highlightMenuItem(nMenuPos, true);
906*cdf0e10cSrcweir         mnSelectedMenu = nMenuPos;
907*cdf0e10cSrcweir     }
908*cdf0e10cSrcweir }
909*cdf0e10cSrcweir 
910*cdf0e10cSrcweir void ScMenuFloatingWindow::ensureSubMenuVisible(ScMenuFloatingWindow* pSubMenu)
911*cdf0e10cSrcweir {
912*cdf0e10cSrcweir     if (mpParentMenu)
913*cdf0e10cSrcweir         mpParentMenu->ensureSubMenuVisible(this);
914*cdf0e10cSrcweir 
915*cdf0e10cSrcweir     if (pSubMenu->IsVisible())
916*cdf0e10cSrcweir         return;
917*cdf0e10cSrcweir 
918*cdf0e10cSrcweir     // Find the menu position of the submenu.
919*cdf0e10cSrcweir     size_t nMenuPos = getSubMenuPos(pSubMenu);
920*cdf0e10cSrcweir     if (nMenuPos != MENU_NOT_SELECTED)
921*cdf0e10cSrcweir     {
922*cdf0e10cSrcweir         setSelectedMenuItem(nMenuPos, false, false);
923*cdf0e10cSrcweir 
924*cdf0e10cSrcweir         Point aPos;
925*cdf0e10cSrcweir         Size aSize;
926*cdf0e10cSrcweir         getMenuItemPosSize(nMenuPos, aPos, aSize);
927*cdf0e10cSrcweir 
928*cdf0e10cSrcweir         sal_uInt32 nOldFlags = GetPopupModeFlags();
929*cdf0e10cSrcweir         SetPopupModeFlags(nOldFlags | FLOATWIN_POPUPMODE_NOAPPFOCUSCLOSE);
930*cdf0e10cSrcweir         pSubMenu->resizeToFitMenuItems(); // set the size before launching the popup to get it positioned correctly.
931*cdf0e10cSrcweir         pSubMenu->StartPopupMode(
932*cdf0e10cSrcweir             Rectangle(aPos,aSize), (FLOATWIN_POPUPMODE_RIGHT | FLOATWIN_POPUPMODE_GRABFOCUS));
933*cdf0e10cSrcweir         pSubMenu->AddPopupModeWindow(this);
934*cdf0e10cSrcweir         SetPopupModeFlags(nOldFlags);
935*cdf0e10cSrcweir     }
936*cdf0e10cSrcweir }
937*cdf0e10cSrcweir 
938*cdf0e10cSrcweir void ScMenuFloatingWindow::ensureSubMenuNotVisible()
939*cdf0e10cSrcweir {
940*cdf0e10cSrcweir     if (mnSelectedMenu <= maMenuItems.size() &&
941*cdf0e10cSrcweir         maMenuItems[mnSelectedMenu].mpSubMenuWin &&
942*cdf0e10cSrcweir         maMenuItems[mnSelectedMenu].mpSubMenuWin->IsVisible())
943*cdf0e10cSrcweir     {
944*cdf0e10cSrcweir         maMenuItems[mnSelectedMenu].mpSubMenuWin->ensureSubMenuNotVisible();
945*cdf0e10cSrcweir     }
946*cdf0e10cSrcweir 
947*cdf0e10cSrcweir     EndPopupMode();
948*cdf0e10cSrcweir }
949*cdf0e10cSrcweir 
950*cdf0e10cSrcweir void ScMenuFloatingWindow::terminateAllPopupMenus()
951*cdf0e10cSrcweir {
952*cdf0e10cSrcweir     EndPopupMode();
953*cdf0e10cSrcweir     if (mpParentMenu)
954*cdf0e10cSrcweir         mpParentMenu->terminateAllPopupMenus();
955*cdf0e10cSrcweir }
956*cdf0e10cSrcweir 
957*cdf0e10cSrcweir IMPL_LINK( ScMenuFloatingWindow, PopupEndHdl, void*, EMPTYARG )
958*cdf0e10cSrcweir {
959*cdf0e10cSrcweir     clearSelectedMenuItem();
960*cdf0e10cSrcweir     return 0;
961*cdf0e10cSrcweir }
962*cdf0e10cSrcweir 
963*cdf0e10cSrcweir // ============================================================================
964*cdf0e10cSrcweir 
965*cdf0e10cSrcweir ScDPFieldPopupWindow::Member::Member() :
966*cdf0e10cSrcweir     mbVisible(true)
967*cdf0e10cSrcweir {
968*cdf0e10cSrcweir }
969*cdf0e10cSrcweir 
970*cdf0e10cSrcweir // ----------------------------------------------------------------------------
971*cdf0e10cSrcweir 
972*cdf0e10cSrcweir ScDPFieldPopupWindow::CancelButton::CancelButton(ScDPFieldPopupWindow* pParent) :
973*cdf0e10cSrcweir     ::CancelButton(pParent), mpParent(pParent) {}
974*cdf0e10cSrcweir 
975*cdf0e10cSrcweir void ScDPFieldPopupWindow::CancelButton::Click()
976*cdf0e10cSrcweir {
977*cdf0e10cSrcweir     mpParent->EndPopupMode();
978*cdf0e10cSrcweir     ::CancelButton::Click();
979*cdf0e10cSrcweir }
980*cdf0e10cSrcweir 
981*cdf0e10cSrcweir // ----------------------------------------------------------------------------
982*cdf0e10cSrcweir 
983*cdf0e10cSrcweir ScDPFieldPopupWindow::ScDPFieldPopupWindow(Window* pParent, ScDocument* pDoc) :
984*cdf0e10cSrcweir     ScMenuFloatingWindow(pParent, pDoc),
985*cdf0e10cSrcweir     maChecks(this, 0),
986*cdf0e10cSrcweir     maChkToggleAll(this, 0),
987*cdf0e10cSrcweir     maBtnSelectSingle  (this, 0),
988*cdf0e10cSrcweir     maBtnUnselectSingle(this, 0),
989*cdf0e10cSrcweir     maBtnOk(this),
990*cdf0e10cSrcweir     maBtnCancel(this),
991*cdf0e10cSrcweir     mnCurTabStop(0),
992*cdf0e10cSrcweir     mpExtendedData(NULL),
993*cdf0e10cSrcweir     mpOKAction(NULL),
994*cdf0e10cSrcweir     maWndSize(240, 330),
995*cdf0e10cSrcweir     mePrevToggleAllState(STATE_DONTKNOW)
996*cdf0e10cSrcweir {
997*cdf0e10cSrcweir     maTabStopCtrls.reserve(7);
998*cdf0e10cSrcweir     maTabStopCtrls.push_back(this);
999*cdf0e10cSrcweir     maTabStopCtrls.push_back(&maChecks);
1000*cdf0e10cSrcweir     maTabStopCtrls.push_back(&maChkToggleAll);
1001*cdf0e10cSrcweir     maTabStopCtrls.push_back(&maBtnSelectSingle);
1002*cdf0e10cSrcweir     maTabStopCtrls.push_back(&maBtnUnselectSingle);
1003*cdf0e10cSrcweir     maTabStopCtrls.push_back(&maBtnOk);
1004*cdf0e10cSrcweir     maTabStopCtrls.push_back(&maBtnCancel);
1005*cdf0e10cSrcweir 
1006*cdf0e10cSrcweir     const StyleSettings& rStyle = GetSettings().GetStyleSettings();
1007*cdf0e10cSrcweir 
1008*cdf0e10cSrcweir     Point aPos;
1009*cdf0e10cSrcweir     Size aSize;
1010*cdf0e10cSrcweir     getSectionPosSize(aPos, aSize, WHOLE);
1011*cdf0e10cSrcweir     SetOutputSizePixel(aSize);
1012*cdf0e10cSrcweir     Size aOutSize = GetOutputSizePixel();
1013*cdf0e10cSrcweir 
1014*cdf0e10cSrcweir     getSectionPosSize(aPos, aSize, BTN_OK);
1015*cdf0e10cSrcweir     maBtnOk.SetPosSizePixel(aPos, aSize);
1016*cdf0e10cSrcweir     maBtnOk.SetFont(getLabelFont());
1017*cdf0e10cSrcweir     maBtnOk.SetClickHdl( LINK(this, ScDPFieldPopupWindow, ButtonHdl) );
1018*cdf0e10cSrcweir     maBtnOk.Show();
1019*cdf0e10cSrcweir 
1020*cdf0e10cSrcweir     getSectionPosSize(aPos, aSize, BTN_CANCEL);
1021*cdf0e10cSrcweir     maBtnCancel.SetPosSizePixel(aPos, aSize);
1022*cdf0e10cSrcweir     maBtnCancel.SetFont(getLabelFont());
1023*cdf0e10cSrcweir     maBtnCancel.Show();
1024*cdf0e10cSrcweir 
1025*cdf0e10cSrcweir     getSectionPosSize(aPos, aSize, LISTBOX_AREA_INNER);
1026*cdf0e10cSrcweir     maChecks.SetPosSizePixel(aPos, aSize);
1027*cdf0e10cSrcweir     maChecks.SetFont(getLabelFont());
1028*cdf0e10cSrcweir     maChecks.SetCheckButtonHdl( LINK(this, ScDPFieldPopupWindow, CheckHdl) );
1029*cdf0e10cSrcweir     maChecks.Show();
1030*cdf0e10cSrcweir 
1031*cdf0e10cSrcweir     getSectionPosSize(aPos, aSize, CHECK_TOGGLE_ALL);
1032*cdf0e10cSrcweir     maChkToggleAll.SetPosSizePixel(aPos, aSize);
1033*cdf0e10cSrcweir     maChkToggleAll.SetFont(getLabelFont());
1034*cdf0e10cSrcweir     maChkToggleAll.SetText(ScRscStrLoader(RID_POPUP_FILTER, STR_BTN_TOGGLE_ALL).GetString());
1035*cdf0e10cSrcweir     maChkToggleAll.SetControlBackground(rStyle.GetMenuColor());
1036*cdf0e10cSrcweir     maChkToggleAll.SetClickHdl( LINK(this, ScDPFieldPopupWindow, TriStateHdl) );
1037*cdf0e10cSrcweir     maChkToggleAll.Show();
1038*cdf0e10cSrcweir 
1039*cdf0e10cSrcweir     getSectionPosSize(aPos, aSize, BTN_SINGLE_SELECT);
1040*cdf0e10cSrcweir     maBtnSelectSingle.SetPosSizePixel(aPos, aSize);
1041*cdf0e10cSrcweir     maBtnSelectSingle.SetQuickHelpText(ScRscStrLoader(RID_POPUP_FILTER, STR_BTN_SELECT_CURRENT).GetString());
1042*cdf0e10cSrcweir     maBtnSelectSingle.SetModeImage(Image(ScResId(RID_IMG_SELECT_CURRENT)), BMP_COLOR_NORMAL);
1043*cdf0e10cSrcweir     maBtnSelectSingle.SetClickHdl( LINK(this, ScDPFieldPopupWindow, ButtonHdl) );
1044*cdf0e10cSrcweir     maBtnSelectSingle.Show();
1045*cdf0e10cSrcweir 
1046*cdf0e10cSrcweir     getSectionPosSize(aPos, aSize, BTN_SINGLE_UNSELECT);
1047*cdf0e10cSrcweir     maBtnUnselectSingle.SetPosSizePixel(aPos, aSize);
1048*cdf0e10cSrcweir     maBtnUnselectSingle.SetQuickHelpText(ScRscStrLoader(RID_POPUP_FILTER, STR_BTN_UNSELECT_CURRENT).GetString());
1049*cdf0e10cSrcweir     maBtnUnselectSingle.SetModeImage(Image(ScResId(RID_IMG_UNSELECT_CURRENT)), BMP_COLOR_NORMAL);
1050*cdf0e10cSrcweir     maBtnUnselectSingle.SetClickHdl( LINK(this, ScDPFieldPopupWindow, ButtonHdl) );
1051*cdf0e10cSrcweir     maBtnUnselectSingle.Show();
1052*cdf0e10cSrcweir }
1053*cdf0e10cSrcweir 
1054*cdf0e10cSrcweir ScDPFieldPopupWindow::~ScDPFieldPopupWindow()
1055*cdf0e10cSrcweir {
1056*cdf0e10cSrcweir }
1057*cdf0e10cSrcweir 
1058*cdf0e10cSrcweir void ScDPFieldPopupWindow::getSectionPosSize(Point& rPos, Size& rSize, SectionType eType) const
1059*cdf0e10cSrcweir {
1060*cdf0e10cSrcweir     // constant parameters.
1061*cdf0e10cSrcweir     const sal_uInt16 nListBoxMargin = 5;            // horizontal distance from the side of the dialog to the listbox border.
1062*cdf0e10cSrcweir     const sal_uInt16 nListBoxInnerPadding = 5;
1063*cdf0e10cSrcweir     const sal_uInt16 nTopMargin = 5;
1064*cdf0e10cSrcweir     const sal_uInt16 nMenuHeight = 60;
1065*cdf0e10cSrcweir     const sal_uInt16 nSingleItemBtnAreaHeight = 32; // height of the middle area below the list box where the single-action buttons are.
1066*cdf0e10cSrcweir     const sal_uInt16 nBottomBtnAreaHeight = 50;     // height of the bottom area where the OK and Cancel buttons are.
1067*cdf0e10cSrcweir     const sal_uInt16 nBtnWidth = 90;
1068*cdf0e10cSrcweir     const sal_uInt16 nLabelHeight = static_cast< sal_uInt16 >( getLabelFont().GetHeight() );
1069*cdf0e10cSrcweir     const sal_uInt16 nBtnHeight = nLabelHeight*2;
1070*cdf0e10cSrcweir     const sal_uInt16 nBottomMargin = 10;
1071*cdf0e10cSrcweir     const sal_uInt16 nMenuListMargin = 20;
1072*cdf0e10cSrcweir 
1073*cdf0e10cSrcweir     // parameters calculated from constants.
1074*cdf0e10cSrcweir     const sal_uInt16 nListBoxWidth = static_cast< sal_uInt16 >( maWndSize.Width() - nListBoxMargin*2 );
1075*cdf0e10cSrcweir     const sal_uInt16 nListBoxHeight = static_cast< sal_uInt16 >( maWndSize.Height() - nTopMargin - nMenuHeight -
1076*cdf0e10cSrcweir         nMenuListMargin - nSingleItemBtnAreaHeight - nBottomBtnAreaHeight );
1077*cdf0e10cSrcweir 
1078*cdf0e10cSrcweir     const sal_uInt16 nSingleBtnAreaY = nTopMargin + nMenuHeight + nListBoxHeight + nMenuListMargin - 1;
1079*cdf0e10cSrcweir 
1080*cdf0e10cSrcweir     switch (eType)
1081*cdf0e10cSrcweir     {
1082*cdf0e10cSrcweir         case WHOLE:
1083*cdf0e10cSrcweir         {
1084*cdf0e10cSrcweir             rPos  = Point(0, 0);
1085*cdf0e10cSrcweir             rSize = maWndSize;
1086*cdf0e10cSrcweir         }
1087*cdf0e10cSrcweir         break;
1088*cdf0e10cSrcweir         case LISTBOX_AREA_OUTER:
1089*cdf0e10cSrcweir         {
1090*cdf0e10cSrcweir             rPos = Point(nListBoxMargin, nTopMargin + nMenuHeight + nMenuListMargin);
1091*cdf0e10cSrcweir             rSize = Size(nListBoxWidth, nListBoxHeight);
1092*cdf0e10cSrcweir         }
1093*cdf0e10cSrcweir         break;
1094*cdf0e10cSrcweir         case LISTBOX_AREA_INNER:
1095*cdf0e10cSrcweir         {
1096*cdf0e10cSrcweir             rPos = Point(nListBoxMargin, nTopMargin + nMenuHeight + nMenuListMargin);
1097*cdf0e10cSrcweir             rPos.X() += nListBoxInnerPadding;
1098*cdf0e10cSrcweir             rPos.Y() += nListBoxInnerPadding;
1099*cdf0e10cSrcweir 
1100*cdf0e10cSrcweir             rSize = Size(nListBoxWidth, nListBoxHeight);
1101*cdf0e10cSrcweir             rSize.Width()  -= nListBoxInnerPadding*2;
1102*cdf0e10cSrcweir             rSize.Height() -= nListBoxInnerPadding*2;
1103*cdf0e10cSrcweir         }
1104*cdf0e10cSrcweir         break;
1105*cdf0e10cSrcweir         case SINGLE_BTN_AREA:
1106*cdf0e10cSrcweir         {
1107*cdf0e10cSrcweir             rPos = Point(nListBoxMargin, nSingleBtnAreaY);
1108*cdf0e10cSrcweir             rSize = Size(nListBoxWidth, nSingleItemBtnAreaHeight);
1109*cdf0e10cSrcweir         }
1110*cdf0e10cSrcweir         break;
1111*cdf0e10cSrcweir         case CHECK_TOGGLE_ALL:
1112*cdf0e10cSrcweir         {
1113*cdf0e10cSrcweir             long h = nLabelHeight*3/2; // check box height is heuristically 150% of the text height.
1114*cdf0e10cSrcweir             rPos = Point(nListBoxMargin, nSingleBtnAreaY);
1115*cdf0e10cSrcweir             rPos.X() += 5;
1116*cdf0e10cSrcweir             rPos.Y() += (nSingleItemBtnAreaHeight - h)/2;
1117*cdf0e10cSrcweir             rSize = Size(70, h);
1118*cdf0e10cSrcweir         }
1119*cdf0e10cSrcweir         break;
1120*cdf0e10cSrcweir         case BTN_SINGLE_SELECT:
1121*cdf0e10cSrcweir         {
1122*cdf0e10cSrcweir             long h = 26;
1123*cdf0e10cSrcweir             rPos = Point(nListBoxMargin, nSingleBtnAreaY);
1124*cdf0e10cSrcweir             rPos.X() += 150;
1125*cdf0e10cSrcweir             rPos.Y() += (nSingleItemBtnAreaHeight - h)/2;
1126*cdf0e10cSrcweir             rSize = Size(h, h);
1127*cdf0e10cSrcweir         }
1128*cdf0e10cSrcweir         break;
1129*cdf0e10cSrcweir         case BTN_SINGLE_UNSELECT:
1130*cdf0e10cSrcweir         {
1131*cdf0e10cSrcweir             long h = 26;
1132*cdf0e10cSrcweir             rPos = Point(nListBoxMargin, nSingleBtnAreaY);
1133*cdf0e10cSrcweir             rPos.X() += 150 + h + 10;
1134*cdf0e10cSrcweir             rPos.Y() += (nSingleItemBtnAreaHeight - h)/2;
1135*cdf0e10cSrcweir             rSize = Size(h, h);
1136*cdf0e10cSrcweir         }
1137*cdf0e10cSrcweir         break;
1138*cdf0e10cSrcweir         case BTN_OK:
1139*cdf0e10cSrcweir         {
1140*cdf0e10cSrcweir             long x = (maWndSize.Width() - nBtnWidth*2)/3;
1141*cdf0e10cSrcweir             long y = maWndSize.Height() - nBottomMargin - nBtnHeight;
1142*cdf0e10cSrcweir             rPos = Point(x, y);
1143*cdf0e10cSrcweir             rSize = Size(nBtnWidth, nBtnHeight);
1144*cdf0e10cSrcweir         }
1145*cdf0e10cSrcweir         break;
1146*cdf0e10cSrcweir         case BTN_CANCEL:
1147*cdf0e10cSrcweir         {
1148*cdf0e10cSrcweir             long x = (maWndSize.Width() - nBtnWidth*2)/3*2 + nBtnWidth;
1149*cdf0e10cSrcweir             long y = maWndSize.Height() - nBottomMargin - nBtnHeight;
1150*cdf0e10cSrcweir             rPos = Point(x, y);
1151*cdf0e10cSrcweir             rSize = Size(nBtnWidth, nBtnHeight);
1152*cdf0e10cSrcweir         }
1153*cdf0e10cSrcweir         break;
1154*cdf0e10cSrcweir         default:
1155*cdf0e10cSrcweir             ;
1156*cdf0e10cSrcweir     }
1157*cdf0e10cSrcweir }
1158*cdf0e10cSrcweir 
1159*cdf0e10cSrcweir void ScDPFieldPopupWindow::setAllMemberState(bool bSet)
1160*cdf0e10cSrcweir {
1161*cdf0e10cSrcweir     size_t n = maMembers.size();
1162*cdf0e10cSrcweir     for (size_t i = 0; i < n; ++i)
1163*cdf0e10cSrcweir         maChecks.CheckEntryPos(static_cast< sal_uInt16 >( i ), bSet);
1164*cdf0e10cSrcweir }
1165*cdf0e10cSrcweir 
1166*cdf0e10cSrcweir void ScDPFieldPopupWindow::selectCurrentMemberOnly(bool bSet)
1167*cdf0e10cSrcweir {
1168*cdf0e10cSrcweir     setAllMemberState(!bSet);
1169*cdf0e10cSrcweir     sal_uInt16 nSelected = maChecks.GetSelectEntryPos();
1170*cdf0e10cSrcweir     maChecks.CheckEntryPos(nSelected, bSet);
1171*cdf0e10cSrcweir }
1172*cdf0e10cSrcweir 
1173*cdf0e10cSrcweir void ScDPFieldPopupWindow::cycleFocus(bool bReverse)
1174*cdf0e10cSrcweir {
1175*cdf0e10cSrcweir     maTabStopCtrls[mnCurTabStop]->SetFakeFocus(false);
1176*cdf0e10cSrcweir     maTabStopCtrls[mnCurTabStop]->LoseFocus();
1177*cdf0e10cSrcweir     if (mnCurTabStop == 0)
1178*cdf0e10cSrcweir         clearSelectedMenuItem();
1179*cdf0e10cSrcweir 
1180*cdf0e10cSrcweir     if (bReverse)
1181*cdf0e10cSrcweir     {
1182*cdf0e10cSrcweir         if (mnCurTabStop > 0)
1183*cdf0e10cSrcweir             --mnCurTabStop;
1184*cdf0e10cSrcweir         else
1185*cdf0e10cSrcweir             mnCurTabStop = maTabStopCtrls.size() - 1;
1186*cdf0e10cSrcweir     }
1187*cdf0e10cSrcweir     else
1188*cdf0e10cSrcweir     {
1189*cdf0e10cSrcweir         ++mnCurTabStop;
1190*cdf0e10cSrcweir         if (mnCurTabStop >= maTabStopCtrls.size())
1191*cdf0e10cSrcweir             mnCurTabStop = 0;
1192*cdf0e10cSrcweir     }
1193*cdf0e10cSrcweir     maTabStopCtrls[mnCurTabStop]->SetFakeFocus(true);
1194*cdf0e10cSrcweir     maTabStopCtrls[mnCurTabStop]->GrabFocus();
1195*cdf0e10cSrcweir }
1196*cdf0e10cSrcweir 
1197*cdf0e10cSrcweir IMPL_LINK( ScDPFieldPopupWindow, ButtonHdl, Button*, pBtn )
1198*cdf0e10cSrcweir {
1199*cdf0e10cSrcweir     if (pBtn == &maBtnOk)
1200*cdf0e10cSrcweir         close(true);
1201*cdf0e10cSrcweir     else if (pBtn == &maBtnSelectSingle)
1202*cdf0e10cSrcweir     {
1203*cdf0e10cSrcweir         selectCurrentMemberOnly(true);
1204*cdf0e10cSrcweir         CheckHdl(&maChecks);
1205*cdf0e10cSrcweir     }
1206*cdf0e10cSrcweir     else if (pBtn == &maBtnUnselectSingle)
1207*cdf0e10cSrcweir     {
1208*cdf0e10cSrcweir         selectCurrentMemberOnly(false);
1209*cdf0e10cSrcweir         CheckHdl(&maChecks);
1210*cdf0e10cSrcweir     }
1211*cdf0e10cSrcweir     return 0;
1212*cdf0e10cSrcweir }
1213*cdf0e10cSrcweir 
1214*cdf0e10cSrcweir IMPL_LINK( ScDPFieldPopupWindow, TriStateHdl, TriStateBox*, EMPTYARG )
1215*cdf0e10cSrcweir {
1216*cdf0e10cSrcweir     switch (mePrevToggleAllState)
1217*cdf0e10cSrcweir     {
1218*cdf0e10cSrcweir         case STATE_NOCHECK:
1219*cdf0e10cSrcweir             maChkToggleAll.SetState(STATE_CHECK);
1220*cdf0e10cSrcweir             setAllMemberState(true);
1221*cdf0e10cSrcweir         break;
1222*cdf0e10cSrcweir         case STATE_CHECK:
1223*cdf0e10cSrcweir             maChkToggleAll.SetState(STATE_NOCHECK);
1224*cdf0e10cSrcweir             setAllMemberState(false);
1225*cdf0e10cSrcweir         break;
1226*cdf0e10cSrcweir         case STATE_DONTKNOW:
1227*cdf0e10cSrcweir         default:
1228*cdf0e10cSrcweir             maChkToggleAll.SetState(STATE_CHECK);
1229*cdf0e10cSrcweir             setAllMemberState(true);
1230*cdf0e10cSrcweir         break;
1231*cdf0e10cSrcweir     }
1232*cdf0e10cSrcweir 
1233*cdf0e10cSrcweir     mePrevToggleAllState = maChkToggleAll.GetState();
1234*cdf0e10cSrcweir     return 0;
1235*cdf0e10cSrcweir }
1236*cdf0e10cSrcweir 
1237*cdf0e10cSrcweir IMPL_LINK( ScDPFieldPopupWindow, CheckHdl, SvTreeListBox*, pChecks )
1238*cdf0e10cSrcweir {
1239*cdf0e10cSrcweir     if (pChecks != &maChecks)
1240*cdf0e10cSrcweir         return 0;
1241*cdf0e10cSrcweir 
1242*cdf0e10cSrcweir     size_t nNumChecked = maChecks.GetCheckedEntryCount();
1243*cdf0e10cSrcweir     if (nNumChecked == maMembers.size())
1244*cdf0e10cSrcweir         // all members visible
1245*cdf0e10cSrcweir         maChkToggleAll.SetState(STATE_CHECK);
1246*cdf0e10cSrcweir     else if (nNumChecked == 0)
1247*cdf0e10cSrcweir         // no members visible
1248*cdf0e10cSrcweir         maChkToggleAll.SetState(STATE_NOCHECK);
1249*cdf0e10cSrcweir     else
1250*cdf0e10cSrcweir         maChkToggleAll.SetState(STATE_DONTKNOW);
1251*cdf0e10cSrcweir 
1252*cdf0e10cSrcweir     mePrevToggleAllState = maChkToggleAll.GetState();
1253*cdf0e10cSrcweir     return 0;
1254*cdf0e10cSrcweir }
1255*cdf0e10cSrcweir 
1256*cdf0e10cSrcweir void ScDPFieldPopupWindow::MouseMove(const MouseEvent& rMEvt)
1257*cdf0e10cSrcweir {
1258*cdf0e10cSrcweir     ScMenuFloatingWindow::MouseMove(rMEvt);
1259*cdf0e10cSrcweir 
1260*cdf0e10cSrcweir     size_t nSelectedMenu = getSelectedMenuItem();
1261*cdf0e10cSrcweir     if (nSelectedMenu == MENU_NOT_SELECTED)
1262*cdf0e10cSrcweir         queueCloseSubMenu();
1263*cdf0e10cSrcweir }
1264*cdf0e10cSrcweir 
1265*cdf0e10cSrcweir long ScDPFieldPopupWindow::Notify(NotifyEvent& rNEvt)
1266*cdf0e10cSrcweir {
1267*cdf0e10cSrcweir     switch (rNEvt.GetType())
1268*cdf0e10cSrcweir     {
1269*cdf0e10cSrcweir         case EVENT_KEYUP:
1270*cdf0e10cSrcweir         {
1271*cdf0e10cSrcweir             const KeyEvent* pKeyEvent = rNEvt.GetKeyEvent();
1272*cdf0e10cSrcweir             const KeyCode& rCode = pKeyEvent->GetKeyCode();
1273*cdf0e10cSrcweir             bool bShift = rCode.IsShift();
1274*cdf0e10cSrcweir             if (rCode.GetCode() == KEY_TAB)
1275*cdf0e10cSrcweir             {
1276*cdf0e10cSrcweir                 cycleFocus(bShift);
1277*cdf0e10cSrcweir                 return true;
1278*cdf0e10cSrcweir             }
1279*cdf0e10cSrcweir         }
1280*cdf0e10cSrcweir         break;
1281*cdf0e10cSrcweir     }
1282*cdf0e10cSrcweir     return ScMenuFloatingWindow::Notify(rNEvt);
1283*cdf0e10cSrcweir }
1284*cdf0e10cSrcweir 
1285*cdf0e10cSrcweir void ScDPFieldPopupWindow::Paint(const Rectangle& rRect)
1286*cdf0e10cSrcweir {
1287*cdf0e10cSrcweir     ScMenuFloatingWindow::Paint(rRect);
1288*cdf0e10cSrcweir 
1289*cdf0e10cSrcweir     const StyleSettings& rStyle = GetSettings().GetStyleSettings();
1290*cdf0e10cSrcweir     Color aMemberBackColor = rStyle.GetFieldColor();
1291*cdf0e10cSrcweir     Color aBorderColor = rStyle.GetShadowColor();
1292*cdf0e10cSrcweir 
1293*cdf0e10cSrcweir     Point aPos;
1294*cdf0e10cSrcweir     Size aSize;
1295*cdf0e10cSrcweir     getSectionPosSize(aPos, aSize, LISTBOX_AREA_OUTER);
1296*cdf0e10cSrcweir 
1297*cdf0e10cSrcweir     // Member list box background
1298*cdf0e10cSrcweir     SetFillColor(aMemberBackColor);
1299*cdf0e10cSrcweir     SetLineColor(aBorderColor);
1300*cdf0e10cSrcweir     DrawRect(Rectangle(aPos,aSize));
1301*cdf0e10cSrcweir 
1302*cdf0e10cSrcweir     // Single-action button box
1303*cdf0e10cSrcweir     getSectionPosSize(aPos, aSize, SINGLE_BTN_AREA);
1304*cdf0e10cSrcweir     SetFillColor(rStyle.GetMenuColor());
1305*cdf0e10cSrcweir     DrawRect(Rectangle(aPos,aSize));
1306*cdf0e10cSrcweir }
1307*cdf0e10cSrcweir 
1308*cdf0e10cSrcweir Window* ScDPFieldPopupWindow::GetPreferredKeyInputWindow()
1309*cdf0e10cSrcweir {
1310*cdf0e10cSrcweir     return maTabStopCtrls[mnCurTabStop];
1311*cdf0e10cSrcweir }
1312*cdf0e10cSrcweir 
1313*cdf0e10cSrcweir Reference<XAccessible> ScDPFieldPopupWindow::CreateAccessible()
1314*cdf0e10cSrcweir {
1315*cdf0e10cSrcweir     if (!mxAccessible.is())
1316*cdf0e10cSrcweir     {
1317*cdf0e10cSrcweir         mxAccessible.set(new ScAccessibleFilterTopWindow(
1318*cdf0e10cSrcweir             GetAccessibleParentWindow()->GetAccessible(), this, getName(), getDoc()));
1319*cdf0e10cSrcweir         ScAccessibleFilterTopWindow* pAccTop = static_cast<ScAccessibleFilterTopWindow*>(mxAccessible.get());
1320*cdf0e10cSrcweir         fillMenuItemsToAccessible(pAccTop);
1321*cdf0e10cSrcweir 
1322*cdf0e10cSrcweir         pAccTop->setAccessibleChild(
1323*cdf0e10cSrcweir             maChecks.CreateAccessible(), ScAccessibleFilterTopWindow::LISTBOX);
1324*cdf0e10cSrcweir         pAccTop->setAccessibleChild(
1325*cdf0e10cSrcweir             maChkToggleAll.CreateAccessible(), ScAccessibleFilterTopWindow::TOGGLE_ALL);
1326*cdf0e10cSrcweir         pAccTop->setAccessibleChild(
1327*cdf0e10cSrcweir             maBtnSelectSingle.CreateAccessible(), ScAccessibleFilterTopWindow::SINGLE_ON_BTN);
1328*cdf0e10cSrcweir         pAccTop->setAccessibleChild(
1329*cdf0e10cSrcweir             maBtnUnselectSingle.CreateAccessible(), ScAccessibleFilterTopWindow::SINGLE_OFF_BTN);
1330*cdf0e10cSrcweir         pAccTop->setAccessibleChild(
1331*cdf0e10cSrcweir             maBtnOk.CreateAccessible(), ScAccessibleFilterTopWindow::OK_BTN);
1332*cdf0e10cSrcweir         pAccTop->setAccessibleChild(
1333*cdf0e10cSrcweir             maBtnCancel.CreateAccessible(), ScAccessibleFilterTopWindow::CANCEL_BTN);
1334*cdf0e10cSrcweir     }
1335*cdf0e10cSrcweir 
1336*cdf0e10cSrcweir     return mxAccessible;
1337*cdf0e10cSrcweir }
1338*cdf0e10cSrcweir 
1339*cdf0e10cSrcweir void ScDPFieldPopupWindow::setMemberSize(size_t n)
1340*cdf0e10cSrcweir {
1341*cdf0e10cSrcweir     maMembers.reserve(n);
1342*cdf0e10cSrcweir }
1343*cdf0e10cSrcweir 
1344*cdf0e10cSrcweir void ScDPFieldPopupWindow::addMember(const OUString& rName, bool bVisible)
1345*cdf0e10cSrcweir {
1346*cdf0e10cSrcweir     Member aMember;
1347*cdf0e10cSrcweir     aMember.maName = rName;
1348*cdf0e10cSrcweir     aMember.mbVisible = bVisible;
1349*cdf0e10cSrcweir     maMembers.push_back(aMember);
1350*cdf0e10cSrcweir }
1351*cdf0e10cSrcweir 
1352*cdf0e10cSrcweir void ScDPFieldPopupWindow::initMembers()
1353*cdf0e10cSrcweir {
1354*cdf0e10cSrcweir     size_t n = maMembers.size();
1355*cdf0e10cSrcweir     size_t nVisMemCount = 0;
1356*cdf0e10cSrcweir     for (size_t i = 0; i < n; ++i)
1357*cdf0e10cSrcweir     {
1358*cdf0e10cSrcweir         maChecks.InsertEntry(maMembers[i].maName);
1359*cdf0e10cSrcweir         maChecks.CheckEntryPos(static_cast< sal_uInt16 >( i ), maMembers[i].mbVisible);
1360*cdf0e10cSrcweir         if (maMembers[i].mbVisible)
1361*cdf0e10cSrcweir             ++nVisMemCount;
1362*cdf0e10cSrcweir     }
1363*cdf0e10cSrcweir     if (nVisMemCount == n)
1364*cdf0e10cSrcweir     {
1365*cdf0e10cSrcweir         // all members visible
1366*cdf0e10cSrcweir         maChkToggleAll.SetState(STATE_CHECK);
1367*cdf0e10cSrcweir         mePrevToggleAllState = STATE_CHECK;
1368*cdf0e10cSrcweir     }
1369*cdf0e10cSrcweir     else if (nVisMemCount == 0)
1370*cdf0e10cSrcweir     {
1371*cdf0e10cSrcweir         // no members visible
1372*cdf0e10cSrcweir         maChkToggleAll.SetState(STATE_NOCHECK);
1373*cdf0e10cSrcweir         mePrevToggleAllState = STATE_NOCHECK;
1374*cdf0e10cSrcweir     }
1375*cdf0e10cSrcweir     else
1376*cdf0e10cSrcweir     {
1377*cdf0e10cSrcweir         maChkToggleAll.SetState(STATE_DONTKNOW);
1378*cdf0e10cSrcweir         mePrevToggleAllState = STATE_DONTKNOW;
1379*cdf0e10cSrcweir     }
1380*cdf0e10cSrcweir }
1381*cdf0e10cSrcweir 
1382*cdf0e10cSrcweir const Size& ScDPFieldPopupWindow::getWindowSize() const
1383*cdf0e10cSrcweir {
1384*cdf0e10cSrcweir     return maWndSize;
1385*cdf0e10cSrcweir }
1386*cdf0e10cSrcweir 
1387*cdf0e10cSrcweir void ScDPFieldPopupWindow::getResult(hash_map<OUString, bool, OUStringHash>& rResult)
1388*cdf0e10cSrcweir {
1389*cdf0e10cSrcweir     typedef hash_map<OUString, bool, OUStringHash> ResultMap;
1390*cdf0e10cSrcweir     ResultMap aResult;
1391*cdf0e10cSrcweir     size_t n = maMembers.size();
1392*cdf0e10cSrcweir     for (size_t i = 0; i < n; ++i)
1393*cdf0e10cSrcweir     {
1394*cdf0e10cSrcweir         bool bState = maChecks.IsChecked(static_cast< sal_uInt16 >( i ));
1395*cdf0e10cSrcweir         aResult.insert(ResultMap::value_type(maMembers[i].maName, bState));
1396*cdf0e10cSrcweir     }
1397*cdf0e10cSrcweir     rResult.swap(aResult);
1398*cdf0e10cSrcweir }
1399*cdf0e10cSrcweir 
1400*cdf0e10cSrcweir void ScDPFieldPopupWindow::close(bool bOK)
1401*cdf0e10cSrcweir {
1402*cdf0e10cSrcweir     if (bOK && mpOKAction.get())
1403*cdf0e10cSrcweir         mpOKAction->execute();
1404*cdf0e10cSrcweir 
1405*cdf0e10cSrcweir     EndPopupMode();
1406*cdf0e10cSrcweir }
1407*cdf0e10cSrcweir 
1408*cdf0e10cSrcweir void ScDPFieldPopupWindow::setExtendedData(ExtendedData* p)
1409*cdf0e10cSrcweir {
1410*cdf0e10cSrcweir     mpExtendedData.reset(p);
1411*cdf0e10cSrcweir }
1412*cdf0e10cSrcweir 
1413*cdf0e10cSrcweir ScDPFieldPopupWindow::ExtendedData* ScDPFieldPopupWindow::getExtendedData()
1414*cdf0e10cSrcweir {
1415*cdf0e10cSrcweir     return mpExtendedData.get();
1416*cdf0e10cSrcweir }
1417*cdf0e10cSrcweir 
1418*cdf0e10cSrcweir void ScDPFieldPopupWindow::setOKAction(Action* p)
1419*cdf0e10cSrcweir {
1420*cdf0e10cSrcweir     mpOKAction.reset(p);
1421*cdf0e10cSrcweir }
1422*cdf0e10cSrcweir 
1423