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