1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: document.hxx,v $
10 * $Revision: 1.115.36.9 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
34 // INCLUDE ---------------------------------------------------------------
36 #include "dpcontrol.hxx"
38 #include "vcl/outdev.hxx"
39 #include "vcl/settings.hxx"
40 #include "vcl/wintypes.hxx"
41 #include "vcl/decoview.hxx"
43 #define MENU_NOT_SELECTED 999
45 using ::rtl::OUString
;
46 using ::rtl::OUStringHash
;
48 using ::std::hash_map
;
50 ScDPFieldButton::ScDPFieldButton(OutputDevice
* pOutDev
, const StyleSettings
* pStyle
) :
54 mbHasHiddenMember(false)
58 ScDPFieldButton::~ScDPFieldButton()
62 void ScDPFieldButton::setText(const OUString
& rText
)
67 void ScDPFieldButton::setBoundingBox(const Point
& rPos
, const Size
& rSize
)
73 void ScDPFieldButton::setDrawPopupButton(bool b
)
78 void ScDPFieldButton::setHasHiddenMember(bool b
)
80 mbHasHiddenMember
= b
;
83 void ScDPFieldButton::draw()
85 const long nMargin
= 2;
88 Rectangle
aRect(maPos
, maSize
);
89 mpOutDev
->SetLineColor(mpStyle
->GetFaceColor());
90 mpOutDev
->SetFillColor(mpStyle
->GetFaceColor());
91 mpOutDev
->DrawRect(aRect
);
94 mpOutDev
->SetLineColor(mpStyle
->GetLightColor());
95 mpOutDev
->DrawLine(Point(maPos
), Point(maPos
.X(), maPos
.Y()+maSize
.Height()-1));
96 mpOutDev
->DrawLine(Point(maPos
), Point(maPos
.X()+maSize
.Width()-1, maPos
.Y()));
98 mpOutDev
->SetLineColor(mpStyle
->GetShadowColor());
99 mpOutDev
->DrawLine(Point(maPos
.X(), maPos
.Y()+maSize
.Height()-1),
100 Point(maPos
.X()+maSize
.Width()-1, maPos
.Y()+maSize
.Height()-1));
101 mpOutDev
->DrawLine(Point(maPos
.X()+maSize
.Width()-1, maPos
.Y()),
102 Point(maPos
.X()+maSize
.Width()-1, maPos
.Y()+maSize
.Height()-1));
105 Font
aTextFont( mpStyle
->GetLabelFont() );
106 aTextFont
.SetHeight(12);
107 mpOutDev
->SetFont(aTextFont
);
109 Point aTextPos
= maPos
;
110 long nTHeight
= mpOutDev
->GetTextHeight();
111 aTextPos
.setX(maPos
.getX() + nMargin
);
112 aTextPos
.setY(maPos
.getY() + (maSize
.Height()-nTHeight
)/2);
113 mpOutDev
->DrawText(aTextPos
, maText
);
119 void ScDPFieldButton::getPopupBoundingBox(Point
& rPos
, Size
& rSize
) const
121 long nW
= maSize
.getWidth()*0.5;
122 long nH
= maSize
.getHeight();
128 rPos
.setX(maPos
.getX() + maSize
.getWidth() - nW
);
129 rPos
.setY(maPos
.getY() + maSize
.getHeight() - nH
);
134 bool ScDPFieldButton::isPopupButton() const
136 return mbPopupButton
;
139 void ScDPFieldButton::drawPopupButton()
143 getPopupBoundingBox(aPos
, aSize
);
146 mpOutDev
->SetLineColor(mpStyle
->GetLightColor());
147 mpOutDev
->DrawLine(aPos
, Point(aPos
.X(), aPos
.Y()+aSize
.Height()-1));
148 mpOutDev
->DrawLine(aPos
, Point(aPos
.X()+aSize
.Width()-1, aPos
.Y()));
150 mpOutDev
->SetLineColor(mpStyle
->GetShadowColor());
151 mpOutDev
->DrawLine(Point(aPos
.X(), aPos
.Y()+aSize
.Height()-1),
152 Point(aPos
.X()+aSize
.Width()-1, aPos
.Y()+aSize
.Height()-1));
153 mpOutDev
->DrawLine(Point(aPos
.X()+aSize
.Width()-1, aPos
.Y()),
154 Point(aPos
.X()+aSize
.Width()-1, aPos
.Y()+aSize
.Height()-1));
157 Color aArrowColor
= mbHasHiddenMember
? mpStyle
->GetHighlightLinkColor() : mpStyle
->GetButtonTextColor();
158 mpOutDev
->SetLineColor(aArrowColor
);
159 mpOutDev
->SetFillColor(aArrowColor
);
160 Point
aCenter(aPos
.X() + (aSize
.Width() >> 1), aPos
.Y() + (aSize
.Height() >> 1));
162 aPos1
.X() = aCenter
.X() - 4;
163 aPos2
.X() = aCenter
.X() + 4;
164 aPos1
.Y() = aCenter
.Y() - 3;
165 aPos2
.Y() = aCenter
.Y() - 3;
173 mpOutDev
->DrawLine(aPos1
, aPos2
);
175 while (aPos1
!= aPos2
);
177 if (mbHasHiddenMember
)
179 // tiny little box to display in presence of hidden member(s).
180 Point
aBoxPos(aPos
.X() + aSize
.Width() - 5, aPos
.Y() + aSize
.Height() - 5);
182 mpOutDev
->DrawRect(Rectangle(aBoxPos
, aBoxSize
));
186 // ============================================================================
188 ScMenuFloatingWindow::MenuItem::MenuItem() :
190 mpAction(static_cast<ScDPFieldPopupWindow::Action
*>(NULL
)),
191 mpSubMenuWin(static_cast<ScMenuFloatingWindow
*>(NULL
))
195 // ----------------------------------------------------------------------------
197 ScMenuFloatingWindow::SubMenuItem::SubMenuItem(ScMenuFloatingWindow
* pParent
) :
199 mnMenuPos(MENU_NOT_SELECTED
),
202 maTimer
.SetTimeoutHdl( LINK(this, ScMenuFloatingWindow::SubMenuItem
, TimeoutHdl
) );
203 maTimer
.SetTimeout(mpParent
->GetSettings().GetMouseSettings().GetMenuDelay());
206 void ScMenuFloatingWindow::SubMenuItem::reset()
209 mnMenuPos
= MENU_NOT_SELECTED
;
213 IMPL_LINK( ScMenuFloatingWindow::SubMenuItem
, TimeoutHdl
, void*, EMPTYARG
)
215 mpParent
->handleMenuTimeout(this);
219 // ----------------------------------------------------------------------------
221 ScMenuFloatingWindow::ScMenuFloatingWindow(Window
* pParent
) :
222 FloatingWindow(pParent
, (WB_SYSTEMFLOATWIN
|WB_SYSTEMWINDOW
|WB_NOBORDER
)),
225 mnSelectedMenu(MENU_NOT_SELECTED
),
226 mnClickedMenu(MENU_NOT_SELECTED
),
227 mpParentMenu(dynamic_cast<ScMenuFloatingWindow
*>(pParent
)),
228 mpActiveSubMenu(NULL
),
231 // TODO: How do we get the right font to use here ?
232 const sal_uInt16 nPopupFontHeight
= 12;
233 const StyleSettings
& rStyle
= GetSettings().GetStyleSettings();
234 maLabelFont
= rStyle
.GetLabelFont();
235 maLabelFont
.SetHeight(nPopupFontHeight
);
236 SetFont(maLabelFont
);
238 SetPopupModeEndHdl( LINK(this, ScMenuFloatingWindow
, EndPopupHdl
) );
241 ScMenuFloatingWindow::~ScMenuFloatingWindow()
246 void ScMenuFloatingWindow::MouseMove(const MouseEvent
& rMEvt
)
248 const Point
& rPos
= rMEvt
.GetPosPixel();
249 size_t nSelectedMenu
= getEnclosingMenuItem(rPos
);
250 setSelectedMenuItem(nSelectedMenu
);
252 Window::MouseMove(rMEvt
);
255 void ScMenuFloatingWindow::MouseButtonDown(const MouseEvent
& rMEvt
)
257 const Point
& rPos
= rMEvt
.GetPosPixel();
258 mnClickedMenu
= getEnclosingMenuItem(rPos
);
259 Window::MouseButtonDown(rMEvt
);
262 void ScMenuFloatingWindow::MouseButtonUp(const MouseEvent
& rMEvt
)
264 executeMenu(mnClickedMenu
);
265 mnClickedMenu
= MENU_NOT_SELECTED
;
266 Window::MouseButtonUp(rMEvt
);
269 void ScMenuFloatingWindow::KeyInput(const KeyEvent
& rKEvt
)
271 const KeyCode
& rKeyCode
= rKEvt
.GetKeyCode();
272 bool bHandled
= true;
273 size_t nSelectedMenu
= mnSelectedMenu
;
274 size_t nLastMenuPos
= maMenuItems
.size() - 1;
275 switch (rKeyCode
.GetCode())
278 if (nSelectedMenu
== MENU_NOT_SELECTED
|| nSelectedMenu
== 0)
279 nSelectedMenu
= nLastMenuPos
;
282 setSelectedMenuItem(nSelectedMenu
, false);
285 if (nSelectedMenu
== MENU_NOT_SELECTED
|| nSelectedMenu
== nLastMenuPos
)
289 setSelectedMenuItem(nSelectedMenu
, false);
293 mpParentMenu
->endSubMenu();
297 if (mnSelectedMenu
>= maMenuItems
.size() || mnSelectedMenu
== MENU_NOT_SELECTED
)
300 const MenuItem
& rMenu
= maMenuItems
[mnSelectedMenu
];
301 if (!rMenu
.mbEnabled
|| !rMenu
.mpSubMenuWin
)
304 maOpenTimer
.mnMenuPos
= mnSelectedMenu
;
305 maOpenTimer
.mpSubMenu
= rMenu
.mpSubMenuWin
.get();
310 if (nSelectedMenu
!= MENU_NOT_SELECTED
)
311 executeMenu(nSelectedMenu
);
318 Window::KeyInput(rKEvt
);
321 void ScMenuFloatingWindow::Paint(const Rectangle
& /*rRect*/)
323 const StyleSettings
& rStyle
= GetSettings().GetStyleSettings();
324 Color aBackColor
= rStyle
.GetMenuColor();
325 Color aBorderColor
= rStyle
.GetShadowColor();
327 Rectangle
aCtrlRect(Point(0, 0), GetOutputSizePixel());
330 bool bNativeDrawn
= true;
331 if (IsNativeControlSupported(CTRL_MENU_POPUP
, PART_ENTIRE_CONTROL
))
334 bNativeDrawn
= DrawNativeControl(
335 CTRL_MENU_POPUP
, PART_ENTIRE_CONTROL
, Region(aCtrlRect
), CTRL_STATE_ENABLED
,
336 ImplControlValue(), OUString());
339 bNativeDrawn
= false;
343 SetFillColor(aBackColor
);
344 SetLineColor(aBorderColor
);
349 SetTextColor(rStyle
.GetMenuTextColor());
353 void ScMenuFloatingWindow::addMenuItem(const OUString
& rText
, bool bEnabled
, Action
* pAction
)
356 aItem
.maText
= rText
;
357 aItem
.mbEnabled
= bEnabled
;
358 aItem
.mpAction
.reset(pAction
);
359 maMenuItems
.push_back(aItem
);
362 ScMenuFloatingWindow
* ScMenuFloatingWindow::addSubMenuItem(const OUString
& rText
, bool bEnabled
)
365 aItem
.maText
= rText
;
366 aItem
.mbEnabled
= bEnabled
;
367 aItem
.mpSubMenuWin
.reset(new ScMenuFloatingWindow(this));
368 maMenuItems
.push_back(aItem
);
369 return aItem
.mpSubMenuWin
.get();
372 void ScMenuFloatingWindow::drawMenuItem(size_t nPos
)
374 if (nPos
>= maMenuItems
.size())
379 getMenuItemPosSize(aPos
, aSize
, nPos
);
381 DecorationView
aDecoView(this);
383 long nYOffset
= (aSize
.Height() - maLabelFont
.GetHeight())/2;
384 DrawCtrlText(Point(aPos
.X()+nXOffset
, aPos
.Y() + nYOffset
), maMenuItems
[nPos
].maText
, 0, STRING_LEN
,
385 maMenuItems
[nPos
].mbEnabled
? TEXT_DRAW_MNEMONIC
: TEXT_DRAW_DISABLE
);
387 if (maMenuItems
[nPos
].mpSubMenuWin
)
389 long nFontHeight
= maLabelFont
.GetHeight();
390 Point aMarkerPos
= aPos
;
391 aMarkerPos
.Y() += aSize
.Height()/2 - nFontHeight
/4 + 1;
392 aMarkerPos
.X() += aSize
.Width() - nFontHeight
+ nFontHeight
/4;
393 Size
aMarkerSize(nFontHeight
/2, nFontHeight
/2);
394 aDecoView
.DrawSymbol(Rectangle(aMarkerPos
, aMarkerSize
),
395 SYMBOL_SPIN_RIGHT
, GetTextColor(), 0);
399 void ScMenuFloatingWindow::drawAllMenuItems()
401 size_t n
= maMenuItems
.size();
402 for (size_t i
= 0; i
< n
; ++i
)
403 highlightMenuItem(i
, i
== mnSelectedMenu
);
406 const Font
& ScMenuFloatingWindow::getLabelFont() const
411 void ScMenuFloatingWindow::executeMenu(size_t nPos
)
413 if (nPos
>= maMenuItems
.size())
416 if (!maMenuItems
[nPos
].mpAction
)
417 // no action is defined.
420 maMenuItems
[nPos
].mpAction
->execute();
421 mbActionFired
= true;
425 void ScMenuFloatingWindow::setSelectedMenuItem(size_t nPos
, bool bSubMenuTimer
)
427 if (mnSelectedMenu
!= nPos
)
429 selectMenuItem(mnSelectedMenu
, false, bSubMenuTimer
);
430 selectMenuItem(nPos
, true, bSubMenuTimer
);
431 mnSelectedMenu
= nPos
;
435 size_t ScMenuFloatingWindow::getSelectedMenuItem() const
437 return mnSelectedMenu
;
440 void ScMenuFloatingWindow::handleMenuTimeout(SubMenuItem
* pTimer
)
442 if (pTimer
== &maOpenTimer
)
444 // Close any open submenu immediately.
445 if (maCloseTimer
.mpSubMenu
)
447 maCloseTimer
.mpSubMenu
->EndPopupMode();
448 maCloseTimer
.mpSubMenu
= NULL
;
449 maCloseTimer
.maTimer
.Stop();
452 launchSubMenu(false);
454 else if (pTimer
== &maCloseTimer
)
457 if (maCloseTimer
.mpSubMenu
)
459 maOpenTimer
.mpSubMenu
= NULL
;
461 maCloseTimer
.mpSubMenu
->EndPopupMode();
462 maCloseTimer
.mpSubMenu
= NULL
;
464 highlightMenuItem(maOpenTimer
.mnMenuPos
, false);
465 maOpenTimer
.mnMenuPos
= MENU_NOT_SELECTED
;
470 void ScMenuFloatingWindow::queueLaunchSubMenu(size_t nPos
, ScMenuFloatingWindow
* pMenu
)
475 // Set the submenu on launch queue.
476 if (maOpenTimer
.mpSubMenu
)
478 if (maOpenTimer
.mpSubMenu
== pMenu
)
480 if (pMenu
== maCloseTimer
.mpSubMenu
)
481 maCloseTimer
.reset();
485 // new submenu is being requested.
489 maOpenTimer
.mpSubMenu
= pMenu
;
490 maOpenTimer
.mnMenuPos
= nPos
;
491 maOpenTimer
.maTimer
.Start();
494 void ScMenuFloatingWindow::queueCloseSubMenu()
496 if (!maOpenTimer
.mpSubMenu
)
497 // There is no submenu to close.
500 // Stop any submenu on queue for opening.
501 maOpenTimer
.maTimer
.Stop();
503 maCloseTimer
.mpSubMenu
= maOpenTimer
.mpSubMenu
;
504 maCloseTimer
.mnMenuPos
= maOpenTimer
.mnMenuPos
;
505 maCloseTimer
.maTimer
.Start();
508 void ScMenuFloatingWindow::launchSubMenu(bool bSetMenuPos
)
512 getMenuItemPosSize(aPos
, aSize
, maOpenTimer
.mnMenuPos
);
513 ScMenuFloatingWindow
* pSubMenu
= maOpenTimer
.mpSubMenu
;
518 sal_uInt32 nOldFlags
= GetPopupModeFlags();
519 SetPopupModeFlags(nOldFlags
| FLOATWIN_POPUPMODE_NOAPPFOCUSCLOSE
);
520 pSubMenu
->resetMenu(bSetMenuPos
);
521 pSubMenu
->StartPopupMode(
522 Rectangle(aPos
,aSize
), (FLOATWIN_POPUPMODE_RIGHT
| FLOATWIN_POPUPMODE_GRABFOCUS
));
523 pSubMenu
->AddPopupModeWindow(this);
524 SetPopupModeFlags(nOldFlags
);
527 void ScMenuFloatingWindow::endSubMenu()
529 if (maOpenTimer
.mpSubMenu
)
531 maOpenTimer
.mpSubMenu
->EndPopupMode();
532 maOpenTimer
.mpSubMenu
= NULL
;
533 highlightMenuItem(maOpenTimer
.mnMenuPos
, true);
537 void ScMenuFloatingWindow::notify(NotificationType eType
)
541 case SUBMENU_FOCUSED
:
542 // Cancel any request for ending submenu.
543 maCloseTimer
.reset();
544 if (mnSelectedMenu
!= maOpenTimer
.mnMenuPos
)
546 highlightMenuItem(maOpenTimer
.mnMenuPos
, true);
547 mnSelectedMenu
= maOpenTimer
.mnMenuPos
;
555 void ScMenuFloatingWindow::resetMenu(bool bSetMenuPos
)
557 mnSelectedMenu
= bSetMenuPos
? 0 : MENU_NOT_SELECTED
;
558 resizeToFitMenuItems();
561 void ScMenuFloatingWindow::resizeToFitMenuItems()
563 if (maMenuItems
.empty())
566 vector
<MenuItem
>::const_iterator itr
= maMenuItems
.begin(), itrEnd
= maMenuItems
.end();
568 for (; itr
!= itrEnd
; ++itr
)
569 nTextWidth
= ::std::max(GetTextWidth(itr
->maText
), nTextWidth
);
571 size_t nLastPos
= maMenuItems
.size()-1;
574 getMenuItemPosSize(aPos
, aSize
, nLastPos
);
575 aPos
.X() += nTextWidth
+ 15;
576 aPos
.Y() += aSize
.Height() + 5;
577 SetOutputSizePixel(Size(aPos
.X(), aPos
.Y()));
580 void ScMenuFloatingWindow::selectMenuItem(size_t nPos
, bool bSelected
, bool bSubMenuTimer
)
582 if (nPos
>= maMenuItems
.size() || nPos
== MENU_NOT_SELECTED
)
588 if (!maMenuItems
[nPos
].mbEnabled
)
594 highlightMenuItem(nPos
, bSelected
);
599 mpParentMenu
->notify(SUBMENU_FOCUSED
);
603 if (maMenuItems
[nPos
].mpSubMenuWin
)
605 ScMenuFloatingWindow
* pSubMenu
= maMenuItems
[nPos
].mpSubMenuWin
.get();
606 queueLaunchSubMenu(nPos
, pSubMenu
);
614 void ScMenuFloatingWindow::highlightMenuItem(size_t nPos
, bool bSelected
)
616 const StyleSettings
& rStyle
= GetSettings().GetStyleSettings();
617 Color aBackColor
= rStyle
.GetMenuColor();
618 SetFillColor(aBackColor
);
619 SetLineColor(aBackColor
);
623 getMenuItemPosSize(aPos
, aSize
, nPos
);
624 Region
aRegion(Rectangle(aPos
,aSize
));
626 if (IsNativeControlSupported(CTRL_MENU_POPUP
, PART_ENTIRE_CONTROL
))
628 Push(PUSH_CLIPREGION
);
629 IntersectClipRegion(Rectangle(aPos
, aSize
));
630 Rectangle
aCtrlRect(Point(0,0), GetOutputSizePixel());
632 CTRL_MENU_POPUP
, PART_ENTIRE_CONTROL
, Region(aCtrlRect
), CTRL_STATE_ENABLED
,
633 ImplControlValue(), OUString());
638 bool bNativeDrawn
= true;
639 if (IsNativeControlSupported(CTRL_MENU_POPUP
, PART_MENU_ITEM
))
641 ControlState nState
= bSelected
? CTRL_STATE_SELECTED
: 0;
642 if (maMenuItems
[nPos
].mbEnabled
)
643 nState
|= CTRL_STATE_ENABLED
;
644 bNativeDrawn
= DrawNativeControl(
645 CTRL_MENU_POPUP
, PART_MENU_ITEM
, aRegion
, nState
, ImplControlValue(), OUString());
648 bNativeDrawn
= false;
654 aBackColor
= rStyle
.GetMenuHighlightColor();
655 SetFillColor(aBackColor
);
656 SetLineColor(aBackColor
);
658 DrawRect(Rectangle(aPos
,aSize
));
661 Color aTextColor
= bSelected
? rStyle
.GetMenuHighlightTextColor() : rStyle
.GetMenuTextColor();
662 SetTextColor(aTextColor
);
666 void ScMenuFloatingWindow::getMenuItemPosSize(Point
& rPos
, Size
& rSize
, size_t nPos
) const
668 const sal_uInt16 nLeftMargin
= 5;
669 const sal_uInt16 nTopMargin
= 5;
670 const sal_uInt16 nMenuItemHeight
= maLabelFont
.GetHeight()*1.8;
672 Size aWndSize
= GetSizePixel();
674 Point
aPos1(nLeftMargin
, nTopMargin
);
675 Size
aSize1(aWndSize
.Width() - nLeftMargin
*2, nMenuItemHeight
);
678 rPos
.Y() += aSize1
.Height()*nPos
;
682 size_t ScMenuFloatingWindow::getEnclosingMenuItem(const Point
& rPos
) const
684 size_t n
= maMenuItems
.size();
685 for (size_t i
= 0; i
< n
; ++i
)
689 getMenuItemPosSize(aPos
, aSize
, i
);
690 Rectangle
aRect(aPos
, aSize
);
691 if (aRect
.IsInside(rPos
))
694 return MENU_NOT_SELECTED
;
697 IMPL_LINK( ScMenuFloatingWindow
, EndPopupHdl
, void*, EMPTYARG
)
699 if (mbActionFired
&& mpParentMenu
)
700 mpParentMenu
->EndPopupMode();
705 // ============================================================================
707 ScDPFieldPopupWindow::Member::Member() :
712 // ----------------------------------------------------------------------------
714 ScDPFieldPopupWindow::CancelButton::CancelButton(ScDPFieldPopupWindow
* pParent
) :
715 ::CancelButton(pParent
), mpParent(pParent
) {}
717 void ScDPFieldPopupWindow::CancelButton::Click()
719 mpParent
->EndPopupMode();
720 ::CancelButton::Click();
723 // ----------------------------------------------------------------------------
725 ScDPFieldPopupWindow::ScDPFieldPopupWindow(Window
* pParent
) :
726 ScMenuFloatingWindow(pParent
),
737 maScrollBar(this, WB_VERT
),
740 mpExtendedData(NULL
),
746 getSectionPosSize(aPos
, aSize
, WHOLE
);
747 SetOutputSizePixel(aSize
);
748 Size aOutSize
= GetOutputSizePixel();
750 mpCheckPtr
.reserve(10);
751 mpCheckPtr
.push_back(&maCheck0
);
752 mpCheckPtr
.push_back(&maCheck1
);
753 mpCheckPtr
.push_back(&maCheck2
);
754 mpCheckPtr
.push_back(&maCheck3
);
755 mpCheckPtr
.push_back(&maCheck4
);
756 mpCheckPtr
.push_back(&maCheck5
);
757 mpCheckPtr
.push_back(&maCheck6
);
758 mpCheckPtr
.push_back(&maCheck7
);
759 mpCheckPtr
.push_back(&maCheck8
);
760 mpCheckPtr
.push_back(&maCheck9
);
762 getSectionPosSize(aPos
, aSize
, FIRST_LISTITEM
);
763 for (vector
<CheckBox
*>::iterator itr
= mpCheckPtr
.begin(), itrEnd
= mpCheckPtr
.end();
764 itr
!= itrEnd
; ++itr
)
767 p
->SetPosSizePixel(aPos
, aSize
);
768 p
->SetFont(getLabelFont());
769 p
->SetClickHdl( LINK(this, ScDPFieldPopupWindow
, CheckBoxHdl
) );
770 aPos
.Y() += aSize
.Height() + 1;
773 getSectionPosSize(aPos
, aSize
, BTN_OK
);
774 maBtnOk
.SetPosSizePixel(aPos
, aSize
);
775 maBtnOk
.SetFont(getLabelFont());
776 maBtnOk
.SetClickHdl( LINK(this, ScDPFieldPopupWindow
, OKButtonHdl
) );
779 getSectionPosSize(aPos
, aSize
, BTN_CANCEL
);
780 maBtnCancel
.SetPosSizePixel(aPos
, aSize
);
781 maBtnCancel
.SetFont(getLabelFont());
784 getSectionPosSize(aPos
, aSize
, SCROLL_BAR_V
);
785 maScrollBar
.SetPosSizePixel(aPos
, aSize
);
786 maScrollBar
.SetPageSize(mpCheckPtr
.size());
787 maScrollBar
.SetVisibleSize(mpCheckPtr
.size());
788 maScrollBar
.SetLineSize(1);
789 maScrollBar
.SetScrollHdl( LINK(this, ScDPFieldPopupWindow
, ScrollHdl
) );
790 maScrollBar
.EnableDrag(true);
793 ScDPFieldPopupWindow::~ScDPFieldPopupWindow()
797 vector
<ScDPFieldPopupWindow::Member
>& ScDPFieldPopupWindow::getMembers()
802 void ScDPFieldPopupWindow::getSectionPosSize(Point
& rPos
, Size
& rSize
, SectionType eType
) const
804 const sal_uInt16 nListBoxMargin
= 5;
805 const sal_uInt16 nTopMargin
= 5;
806 const sal_uInt16 nMenuHeight
= 60;
807 const sal_uInt16 nBottomBtnAreaHeight
= 50;
808 const sal_uInt16 nInnerItemMargin
= 5;
809 const sal_uInt16 nScrollBarWidth
= 17;
810 const sal_uInt16 nBtnWidth
= 60;
811 const sal_uInt16 nBtnHeight
= getLabelFont().GetHeight()*2;
812 const sal_uInt16 nBottomMargin
= 10;
813 const sal_uInt16 nMenuListMargin
= 20;
815 Size aWndSize
= Size(160, 330);
827 rPos
= Point(nListBoxMargin
, nTopMargin
+ nMenuHeight
+ nMenuListMargin
);
829 aWndSize
.Width() - nListBoxMargin
*2,
830 aWndSize
.Height() - nTopMargin
- nMenuHeight
- nMenuListMargin
- nBottomBtnAreaHeight
);
835 rPos
= Point(nListBoxMargin
+ nInnerItemMargin
,
836 nTopMargin
+ nMenuHeight
+ nMenuListMargin
+ nInnerItemMargin
);
838 aWndSize
.Width() - nListBoxMargin
*2 - nInnerItemMargin
- nScrollBarWidth
- 10,
844 long x
= (aWndSize
.Width() - nBtnWidth
*2)/3;
845 long y
= aWndSize
.Height() - nBottomMargin
- nBtnHeight
;
847 rSize
= Size(nBtnWidth
, nBtnHeight
);
852 long x
= (aWndSize
.Width() - nBtnWidth
*2)/3*2 + nBtnWidth
;
853 long y
= aWndSize
.Height() - nBottomMargin
- nBtnHeight
;
855 rSize
= Size(nBtnWidth
, nBtnHeight
);
860 long x
= aWndSize
.Width() - nListBoxMargin
- nInnerItemMargin
- nScrollBarWidth
;
861 long y
= nTopMargin
+ nMenuHeight
+ nMenuListMargin
+ nInnerItemMargin
;
863 long h
= aWndSize
.Height() - nTopMargin
- nMenuHeight
- nMenuListMargin
- nBottomBtnAreaHeight
- nInnerItemMargin
*2;
864 rSize
= Size(nScrollBarWidth
, h
);
872 void ScDPFieldPopupWindow::resetDisplayedItems()
874 long nScrollPos
= maScrollBar
.GetThumbPos();
878 mnScrollPos
= static_cast<size_t>(nScrollPos
);
879 size_t nCheckCount
= mpCheckPtr
.size();
880 for (size_t i
= 0; i
< nCheckCount
; ++i
)
882 CheckBox
* p
= mpCheckPtr
[i
];
883 p
->SetText(maMembers
[i
+mnScrollPos
].maName
);
884 TriState nNewState
= maMembers
[i
+mnScrollPos
].mbVisible
? STATE_CHECK
: STATE_NOCHECK
;
885 p
->SetState(nNewState
);
889 IMPL_LINK( ScDPFieldPopupWindow
, CheckBoxHdl
, CheckBox
*, pCheck
)
891 vector
<CheckBox
*>::const_iterator itr
, itrBeg
= mpCheckPtr
.begin(), itrEnd
= mpCheckPtr
.end();
892 for (itr
= itrBeg
; itr
!= itrEnd
; ++itr
)
896 size_t nIndex
= ::std::distance(itrBeg
, itr
);
897 maMembers
[nIndex
+mnScrollPos
].mbVisible
= !maMembers
[nIndex
+mnScrollPos
].mbVisible
;
903 IMPL_LINK( ScDPFieldPopupWindow
, OKButtonHdl
, OKButton
*, EMPTYARG
)
909 IMPL_LINK( ScDPFieldPopupWindow
, ScrollHdl
, ScrollBar
*, EMPTYARG
)
911 resetDisplayedItems();
915 void ScDPFieldPopupWindow::MouseMove(const MouseEvent
& rMEvt
)
917 ScMenuFloatingWindow::MouseMove(rMEvt
);
919 size_t nSelectedMenu
= getSelectedMenuItem();
920 if (nSelectedMenu
== MENU_NOT_SELECTED
)
924 void ScDPFieldPopupWindow::Paint(const Rectangle
& rRect
)
926 ScMenuFloatingWindow::Paint(rRect
);
928 const StyleSettings
& rStyle
= GetSettings().GetStyleSettings();
929 Color aMemberBackColor
= rStyle
.GetFieldColor();
931 // Member list box background
932 SetFillColor(aMemberBackColor
);
935 getSectionPosSize(aPos
, aSize
, LISTBOX_AREA
);
936 DrawRect(Rectangle(aPos
,aSize
));
939 void ScDPFieldPopupWindow::setMemberSize(size_t n
)
941 maMembers
.reserve(n
);
944 void ScDPFieldPopupWindow::addMember(const OUString
& rName
, bool bVisible
)
947 aMember
.maName
= rName
;
948 aMember
.mbVisible
= bVisible
;
949 maMembers
.push_back(aMember
);
952 void ScDPFieldPopupWindow::initMembers()
954 size_t nMemCount
= maMembers
.size();
955 size_t nCheckCount
= mpCheckPtr
.size();
956 bool bNeedsScroll
= false;
957 if (nMemCount
> nCheckCount
)
959 nMemCount
= nCheckCount
;
963 for (size_t i
= 0; i
< nMemCount
; ++i
)
965 CheckBox
* p
= mpCheckPtr
[i
];
966 p
->SetText(maMembers
[i
].maName
);
968 p
->SetState(maMembers
[i
].mbVisible
? STATE_CHECK
: STATE_NOCHECK
);
972 maScrollBar
.SetRange(Range(0, maMembers
.size()));
977 void ScDPFieldPopupWindow::getResult(hash_map
<OUString
, bool, OUStringHash
>& rResult
)
979 typedef hash_map
<OUString
, bool, OUStringHash
> ResultMap
;
981 vector
<Member
>::const_iterator itr
= maMembers
.begin(), itrEnd
= maMembers
.end();
982 for (; itr
!= itrEnd
; ++itr
)
983 aResult
.insert(ResultMap::value_type(itr
->maName
, itr
->mbVisible
));
984 rResult
.swap(aResult
);
987 void ScDPFieldPopupWindow::close(bool bOK
)
989 if (bOK
&& mpOKAction
.get())
990 mpOKAction
->execute();
995 void ScDPFieldPopupWindow::setExtendedData(ExtendedData
* p
)
997 mpExtendedData
.reset(p
);
1000 ScDPFieldPopupWindow::ExtendedData
* ScDPFieldPopupWindow::getExtendedData()
1002 return mpExtendedData
.get();
1005 void ScDPFieldPopupWindow::setOKAction(Action
* p
)
1007 mpOKAction
.reset(p
);