/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sc.hxx"

// INCLUDE ---------------------------------------------------------------

#include "dpcontrol.hxx"
#include "dpcontrol.hrc"

#include <vcl/outdev.hxx>
#include <vcl/settings.hxx>
#include <tools/wintypes.hxx>
#include <vcl/decoview.hxx>
#include "strload.hxx"
#include "global.hxx"
#include "scitems.hxx"
#include "document.hxx"
#include "docpool.hxx"
#include "patattr.hxx"

#include "AccessibleFilterMenu.hxx"
#include "AccessibleFilterTopWindow.hxx"

#include <com/sun/star/accessibility/XAccessible.hpp>
#include <com/sun/star/accessibility/XAccessibleContext.hpp>

using ::com::sun::star::uno::Reference;
using ::com::sun::star::accessibility::XAccessible;
using ::com::sun::star::accessibility::XAccessibleContext;
using ::rtl::OUString;
using ::rtl::OUStringHash;
using ::std::vector;
using ::std::hash_map;
using ::std::auto_ptr;

ScDPFieldButton::ScDPFieldButton(OutputDevice* pOutDev, const StyleSettings* pStyle, const Fraction* pZoomX, const Fraction* pZoomY, ScDocument* pDoc) :
    mpDoc(pDoc),
    mpOutDev(pOutDev),
    mpStyle(pStyle),
    mbBaseButton(true),
    mbPopupButton(false),
    mbHasHiddenMember(false),
    mbPopupPressed(false),
    mbPopupLeft(false)
{
    if (pZoomX)
        maZoomX = *pZoomX;
    else
        maZoomX = Fraction(1, 1);

    if (pZoomY)
        maZoomY = *pZoomY;
    else
        maZoomY = Fraction(1, 1);
}

ScDPFieldButton::~ScDPFieldButton()
{
}

void ScDPFieldButton::setText(const OUString& rText)
{
    maText = rText;
}

void ScDPFieldButton::setBoundingBox(const Point& rPos, const Size& rSize, bool bLayoutRTL)
{
    maPos = rPos;
    maSize = rSize;
    if (bLayoutRTL)
    {
        // rPos is the logical-left position, adjust maPos to visual-left (inside the cell border)
        maPos.X() -= maSize.Width() - 1;
    }
}

void ScDPFieldButton::setDrawBaseButton(bool b)
{
    mbBaseButton = b;
}

void ScDPFieldButton::setDrawPopupButton(bool b)
{
    mbPopupButton = b;
}

void ScDPFieldButton::setHasHiddenMember(bool b)
{
    mbHasHiddenMember = b;
}

void ScDPFieldButton::setPopupPressed(bool b)
{
    mbPopupPressed = b;
}

void ScDPFieldButton::setPopupLeft(bool b)
{
    mbPopupLeft = b;
}

void ScDPFieldButton::draw()
{
    const long nMargin = 2;
    bool bOldMapEnablaed = mpOutDev->IsMapModeEnabled();
    mpOutDev->EnableMapMode(false);
    
    if (mbBaseButton)
    {
        // Background
        Rectangle aRect(maPos, maSize);
        mpOutDev->SetLineColor(mpStyle->GetFaceColor());
        mpOutDev->SetFillColor(mpStyle->GetFaceColor());
        mpOutDev->DrawRect(aRect);
    
        // Border lines
        mpOutDev->SetLineColor(mpStyle->GetLightColor());
        mpOutDev->DrawLine(Point(maPos), Point(maPos.X(), maPos.Y()+maSize.Height()-1));
        mpOutDev->DrawLine(Point(maPos), Point(maPos.X()+maSize.Width()-1, maPos.Y()));
    
        mpOutDev->SetLineColor(mpStyle->GetShadowColor());
        mpOutDev->DrawLine(Point(maPos.X(), maPos.Y()+maSize.Height()-1),
                           Point(maPos.X()+maSize.Width()-1, maPos.Y()+maSize.Height()-1));
        mpOutDev->DrawLine(Point(maPos.X()+maSize.Width()-1, maPos.Y()),
                           Point(maPos.X()+maSize.Width()-1, maPos.Y()+maSize.Height()-1));
    
        // Field name.
        // Get the font and size the same way as in scenario selection (lcl_DrawOneFrame in gridwin4.cxx)
        Font aTextFont( mpStyle->GetAppFont() );
        if ( mpDoc )
        {
            //  use ScPatternAttr::GetFont only for font size
            Font aAttrFont;
            static_cast<const ScPatternAttr&>(mpDoc->GetPool()->GetDefaultItem(ATTR_PATTERN)).
                GetFont( aAttrFont, SC_AUTOCOL_BLACK, mpOutDev, &maZoomY );
            aTextFont.SetSize( aAttrFont.GetSize() );
        }
        mpOutDev->SetFont(aTextFont);
        mpOutDev->SetTextColor(mpStyle->GetButtonTextColor());
    
        Point aTextPos = maPos;
        long nTHeight = mpOutDev->GetTextHeight();
        aTextPos.setX(maPos.getX() + nMargin);
        aTextPos.setY(maPos.getY() + (maSize.Height()-nTHeight)/2);

        mpOutDev->Push(PUSH_CLIPREGION);
        mpOutDev->IntersectClipRegion(aRect);
        mpOutDev->DrawText(aTextPos, maText);
        mpOutDev->Pop();
    }

    if (mbPopupButton)
        drawPopupButton();

    mpOutDev->EnableMapMode(bOldMapEnablaed);
}

void ScDPFieldButton::getPopupBoundingBox(Point& rPos, Size& rSize) const
{
    long nW = maSize.getWidth() / 2;
    long nH = maSize.getHeight();
    if (nW > 18) 
        nW = 18;
    if (nH > 18)
        nH = 18;

    // #i114944# AutoFilter button is left-aligned in RTL.
    // DataPilot button is always right-aligned for now, so text output isn't affected.
    if (mbPopupLeft)
        rPos.setX(maPos.getX());
    else
        rPos.setX(maPos.getX() + maSize.getWidth() - nW);
    rPos.setY(maPos.getY() + maSize.getHeight() - nH);
    rSize.setWidth(nW);
    rSize.setHeight(nH);
}

void ScDPFieldButton::drawPopupButton()
{
    Point aPos;
    Size aSize;
    getPopupBoundingBox(aPos, aSize);

    // Background & outer black border
    mpOutDev->SetLineColor(COL_BLACK);
    mpOutDev->SetFillColor(mpStyle->GetFaceColor());
    mpOutDev->DrawRect(Rectangle(aPos, aSize));

    if (!mbPopupPressed)
    {    
        // border lines
        mpOutDev->SetLineColor(mpStyle->GetLightColor());
        mpOutDev->DrawLine(Point(aPos.X()+1, aPos.Y()+1), Point(aPos.X()+1, aPos.Y()+aSize.Height()-2));
        mpOutDev->DrawLine(Point(aPos.X()+1, aPos.Y()+1), Point(aPos.X()+aSize.Width()-2, aPos.Y()+1));
    
        mpOutDev->SetLineColor(mpStyle->GetShadowColor());
        mpOutDev->DrawLine(Point(aPos.X()+1, aPos.Y()+aSize.Height()-2),
                           Point(aPos.X()+aSize.Width()-2, aPos.Y()+aSize.Height()-2));
        mpOutDev->DrawLine(Point(aPos.X()+aSize.Width()-2, aPos.Y()+1),
                           Point(aPos.X()+aSize.Width()-2, aPos.Y()+aSize.Height()-2));
    }

    // the arrowhead
    Color aArrowColor = mbHasHiddenMember ? mpStyle->GetHighlightLinkColor() : mpStyle->GetButtonTextColor();
    mpOutDev->SetLineColor(aArrowColor);
    mpOutDev->SetFillColor(aArrowColor);
    Point aCenter(aPos.X() + (aSize.Width() >> 1), aPos.Y() + (aSize.Height() >> 1));
    Point aPos1, aPos2;
    aPos1.X() = aCenter.X() - 4;
    aPos2.X() = aCenter.X() + 4;
    aPos1.Y() = aCenter.Y() - 3;
    aPos2.Y() = aCenter.Y() - 3;

    if (mbPopupPressed)
    {
        aPos1.X() += 1;
        aPos2.X() += 1;
        aPos1.Y() += 1;
        aPos2.Y() += 1;
    }

    do
    {
        ++aPos1.X();
        --aPos2.X();
        ++aPos1.Y();
        ++aPos2.Y();
        mpOutDev->DrawLine(aPos1, aPos2);
    }
    while (aPos1 != aPos2);

    if (mbHasHiddenMember)
    {
        // tiny little box to display in presence of hidden member(s).
        Point aBoxPos(aPos.X() + aSize.Width() - 5, aPos.Y() + aSize.Height() - 5);
        if (mbPopupPressed)
        {
            aBoxPos.X() += 1;
            aBoxPos.Y() += 1;
        }
        Size aBoxSize(3, 3);
        mpOutDev->DrawRect(Rectangle(aBoxPos, aBoxSize));
    }
}

// ============================================================================

ScMenuFloatingWindow::MenuItemData::MenuItemData() :
    mbEnabled(true),
    mpAction(static_cast<ScDPFieldPopupWindow::Action*>(NULL)),
    mpSubMenuWin(static_cast<ScMenuFloatingWindow*>(NULL))
{
}

// ----------------------------------------------------------------------------

ScMenuFloatingWindow::SubMenuItemData::SubMenuItemData(ScMenuFloatingWindow* pParent) :
    mpSubMenu(NULL),
    mnMenuPos(MENU_NOT_SELECTED),
    mpParent(pParent)
{
    maTimer.SetTimeoutHdl( LINK(this, ScMenuFloatingWindow::SubMenuItemData, TimeoutHdl) );
    maTimer.SetTimeout(mpParent->GetSettings().GetMouseSettings().GetMenuDelay());
}

void ScMenuFloatingWindow::SubMenuItemData::reset()
{
    mpSubMenu = NULL;
    mnMenuPos = MENU_NOT_SELECTED;
    maTimer.Stop();
}

IMPL_LINK( ScMenuFloatingWindow::SubMenuItemData, TimeoutHdl, void*, EMPTYARG )
{
    mpParent->handleMenuTimeout(this);
    return 0;
}

// ----------------------------------------------------------------------------

size_t ScMenuFloatingWindow::MENU_NOT_SELECTED = 999;

ScMenuFloatingWindow::ScMenuFloatingWindow(Window* pParent, ScDocument* pDoc, sal_uInt16 nMenuStackLevel) :
    PopupMenuFloatingWindow(pParent),
    maOpenTimer(this),
    maCloseTimer(this),
    maName(OUString::createFromAscii("ScMenuFloatingWindow")),
    mnSelectedMenu(MENU_NOT_SELECTED),
    mnClickedMenu(MENU_NOT_SELECTED),
    mpDoc(pDoc),
    mpParentMenu(dynamic_cast<ScMenuFloatingWindow*>(pParent)),
    mpActiveSubMenu(NULL)
{
    SetMenuStackLevel(nMenuStackLevel);

    // TODO: How do we get the right font to use here ?
    const sal_uInt16 nPopupFontHeight = 12;
    const StyleSettings& rStyle = GetSettings().GetStyleSettings();
    maLabelFont = rStyle.GetLabelFont();
    maLabelFont.SetHeight(nPopupFontHeight);
    SetFont(maLabelFont);

    SetText(OUString::createFromAscii("ScMenuFloatingWindow"));
    SetPopupModeEndHdl( LINK(this, ScMenuFloatingWindow, PopupEndHdl) );
}

ScMenuFloatingWindow::~ScMenuFloatingWindow()
{
    EndPopupMode();
}

void ScMenuFloatingWindow::MouseMove(const MouseEvent& rMEvt)
{
    const Point& rPos = rMEvt.GetPosPixel();
    size_t nSelectedMenu = getEnclosingMenuItem(rPos);
    setSelectedMenuItem(nSelectedMenu, true, false);

    Window::MouseMove(rMEvt);
}

void ScMenuFloatingWindow::MouseButtonDown(const MouseEvent& rMEvt)
{
    const Point& rPos = rMEvt.GetPosPixel();
    mnClickedMenu = getEnclosingMenuItem(rPos);
    Window::MouseButtonDown(rMEvt);
}

void ScMenuFloatingWindow::MouseButtonUp(const MouseEvent& rMEvt)
{
    executeMenuItem(mnClickedMenu);
    mnClickedMenu = MENU_NOT_SELECTED;
    Window::MouseButtonUp(rMEvt);
}

void ScMenuFloatingWindow::KeyInput(const KeyEvent& rKEvt)
{
    const KeyCode& rKeyCode = rKEvt.GetKeyCode();
    bool bHandled = true;
    size_t nSelectedMenu = mnSelectedMenu;
    size_t nLastMenuPos = maMenuItems.size() - 1;
    switch (rKeyCode.GetCode())
    {
        case KEY_UP:
            if (nSelectedMenu == MENU_NOT_SELECTED || nSelectedMenu == 0)
                nSelectedMenu = nLastMenuPos;
            else
                --nSelectedMenu;
            setSelectedMenuItem(nSelectedMenu, false, false);
        break;
        case KEY_DOWN:
            if (nSelectedMenu == MENU_NOT_SELECTED || nSelectedMenu == nLastMenuPos)
                nSelectedMenu = 0;
            else
                ++nSelectedMenu;
            setSelectedMenuItem(nSelectedMenu, false, false);
        break;
        case KEY_LEFT:
            if (mpParentMenu)
                mpParentMenu->endSubMenu(this);
        break;
        case KEY_RIGHT:
        {
            if (mnSelectedMenu >= maMenuItems.size() || mnSelectedMenu == MENU_NOT_SELECTED)
                break;

            const MenuItemData& rMenu = maMenuItems[mnSelectedMenu];
            if (!rMenu.mbEnabled || !rMenu.mpSubMenuWin)
                break;

            maOpenTimer.mnMenuPos = mnSelectedMenu;
            maOpenTimer.mpSubMenu = rMenu.mpSubMenuWin.get();
            launchSubMenu(true);
        }
        break;
        case KEY_RETURN:
            if (nSelectedMenu != MENU_NOT_SELECTED)
                executeMenuItem(nSelectedMenu);
        break;
        default:
            bHandled = false;
    }

    if (!bHandled)
        Window::KeyInput(rKEvt);
}

void ScMenuFloatingWindow::Paint(const Rectangle& /*rRect*/)
{
    const StyleSettings& rStyle = GetSettings().GetStyleSettings();
    Color aBackColor = rStyle.GetMenuColor();
    Color aBorderColor = rStyle.GetShadowColor();

    Rectangle aCtrlRect(Point(0, 0), GetOutputSizePixel());

    // Window background
    bool bNativeDrawn = true;
    if (IsNativeControlSupported(CTRL_MENU_POPUP, PART_ENTIRE_CONTROL))
    {
        SetClipRegion();
        bNativeDrawn = DrawNativeControl(
            CTRL_MENU_POPUP, PART_ENTIRE_CONTROL, aCtrlRect, CTRL_STATE_ENABLED,
            ImplControlValue(), OUString());
    }
    else
        bNativeDrawn = false;

    if (!bNativeDrawn)
    {
        SetFillColor(aBackColor);
        SetLineColor(aBorderColor);
        DrawRect(aCtrlRect);
    }

    // Menu items
    SetTextColor(rStyle.GetMenuTextColor());
    drawAllMenuItems();
}

Reference<XAccessible> ScMenuFloatingWindow::CreateAccessible()
{
    if (!mxAccessible.is())
    {    
        Reference<XAccessible> xAccParent = mpParentMenu ? 
            mpParentMenu->GetAccessible() : GetAccessibleParentWindow()->GetAccessible();

        mxAccessible.set(new ScAccessibleFilterMenu(xAccParent, this, maName, 999, getDoc()));
        ScAccessibleFilterMenu* p = static_cast<ScAccessibleFilterMenu*>(
            mxAccessible.get());
        
        vector<MenuItemData>::const_iterator itr, itrBeg = maMenuItems.begin(), itrEnd = maMenuItems.end();
        for (itr = itrBeg; itr != itrEnd; ++itr)
        {
            size_t nPos = ::std::distance(itrBeg, itr);
            p->appendMenuItem(itr->maText, itr->mbEnabled, nPos);
        }
    }

    return mxAccessible;
}

void ScMenuFloatingWindow::addMenuItem(const OUString& rText, bool bEnabled, Action* pAction)
{
    MenuItemData aItem;
    aItem.maText = rText;
    aItem.mbEnabled = bEnabled;
    aItem.mpAction.reset(pAction);
    maMenuItems.push_back(aItem);
}

ScMenuFloatingWindow* ScMenuFloatingWindow::addSubMenuItem(const OUString& rText, bool bEnabled)
{
    MenuItemData aItem;
    aItem.maText = rText;
    aItem.mbEnabled = bEnabled;
    aItem.mpSubMenuWin.reset(new ScMenuFloatingWindow(this, mpDoc, GetMenuStackLevel()+1));
    aItem.mpSubMenuWin->setName(rText);
    maMenuItems.push_back(aItem);
    return aItem.mpSubMenuWin.get();
}

void ScMenuFloatingWindow::drawMenuItem(size_t nPos)
{
    if (nPos >= maMenuItems.size())
        return;

    Point aPos;
    Size aSize;
    getMenuItemPosSize(nPos, aPos, aSize);

    DecorationView aDecoView(this);
    long nXOffset = 5;
    long nYOffset = (aSize.Height() - maLabelFont.GetHeight())/2;
    DrawCtrlText(Point(aPos.X()+nXOffset, aPos.Y() + nYOffset), maMenuItems[nPos].maText, 0, STRING_LEN,
                 maMenuItems[nPos].mbEnabled ? TEXT_DRAW_MNEMONIC : TEXT_DRAW_DISABLE);

    if (maMenuItems[nPos].mpSubMenuWin)
    {
        long nFontHeight = maLabelFont.GetHeight();
        Point aMarkerPos = aPos;
        aMarkerPos.Y() += aSize.Height()/2 - nFontHeight/4 + 1;
        aMarkerPos.X() += aSize.Width() - nFontHeight + nFontHeight/4;
        Size aMarkerSize(nFontHeight/2, nFontHeight/2);
        aDecoView.DrawSymbol(Rectangle(aMarkerPos, aMarkerSize),
                             SYMBOL_SPIN_RIGHT, GetTextColor(), 0);
    }
}

void ScMenuFloatingWindow::drawAllMenuItems()
{
    size_t n = maMenuItems.size();
    for (size_t i = 0; i < n; ++i)
        highlightMenuItem(i, i == mnSelectedMenu);    
}

const Font& ScMenuFloatingWindow::getLabelFont() const
{
    return maLabelFont;
}

void ScMenuFloatingWindow::executeMenuItem(size_t nPos)
{
    if (nPos >= maMenuItems.size())
        return;

    if (!maMenuItems[nPos].mpAction)
        // no action is defined.
        return;

    maMenuItems[nPos].mpAction->execute();
    terminateAllPopupMenus();
}

void ScMenuFloatingWindow::setSelectedMenuItem(size_t nPos, bool bSubMenuTimer, bool bEnsureSubMenu)
{
    if (mnSelectedMenu == nPos)
        // nothing to do.
        return;

    if (bEnsureSubMenu)
    {
        // Dismiss any child popup menu windows.
        if (mnSelectedMenu < maMenuItems.size() && 
            maMenuItems[mnSelectedMenu].mpSubMenuWin && 
            maMenuItems[mnSelectedMenu].mpSubMenuWin->IsVisible())
        {    
            maMenuItems[mnSelectedMenu].mpSubMenuWin->ensureSubMenuNotVisible();
        }

        // The popup is not visible, yet a menu item is selected.  The request
        // most likely comes from the accessible object.  Make sure this
        // window, as well as all its parent windows are visible.
        if (!IsVisible() && mpParentMenu)
            mpParentMenu->ensureSubMenuVisible(this);
    }

    selectMenuItem(mnSelectedMenu, false, bSubMenuTimer);
    selectMenuItem(nPos, true, bSubMenuTimer);
    mnSelectedMenu = nPos;

    fireMenuHighlightedEvent();
}

size_t ScMenuFloatingWindow::getSelectedMenuItem() const
{
    return mnSelectedMenu;
}

void ScMenuFloatingWindow::handleMenuTimeout(SubMenuItemData* pTimer)
{
    if (pTimer == &maOpenTimer)
    {
        // Close any open submenu immediately.
        if (maCloseTimer.mpSubMenu)
        {
            maCloseTimer.mpSubMenu->EndPopupMode();
            maCloseTimer.mpSubMenu = NULL;
            maCloseTimer.maTimer.Stop();
        }

        launchSubMenu(false);
    }
    else if (pTimer == &maCloseTimer)
    {
        // end submenu.
        if (maCloseTimer.mpSubMenu)
        {
            maOpenTimer.mpSubMenu = NULL;

            maCloseTimer.mpSubMenu->EndPopupMode();
            maCloseTimer.mpSubMenu = NULL;

            highlightMenuItem(maOpenTimer.mnMenuPos, false);
            maOpenTimer.mnMenuPos = MENU_NOT_SELECTED;
        }
    }
}

void ScMenuFloatingWindow::queueLaunchSubMenu(size_t nPos, ScMenuFloatingWindow* pMenu)
{
    if (!pMenu)
        return;

    // Set the submenu on launch queue.
    if (maOpenTimer.mpSubMenu)
    {
        if (maOpenTimer.mpSubMenu == pMenu)
        {
            if (pMenu == maCloseTimer.mpSubMenu)
                maCloseTimer.reset();
            return;
        }

        // new submenu is being requested.
        queueCloseSubMenu();
    }

    maOpenTimer.mpSubMenu = pMenu;
    maOpenTimer.mnMenuPos = nPos;
    maOpenTimer.maTimer.Start();
}

void ScMenuFloatingWindow::queueCloseSubMenu()
{
    if (!maOpenTimer.mpSubMenu)
        // There is no submenu to close.
        return;

    // Stop any submenu on queue for opening.
    maOpenTimer.maTimer.Stop();

    maCloseTimer.mpSubMenu = maOpenTimer.mpSubMenu;
    maCloseTimer.mnMenuPos = maOpenTimer.mnMenuPos;
    maCloseTimer.maTimer.Start();
}

void ScMenuFloatingWindow::launchSubMenu(bool bSetMenuPos)
{
    Point aPos;
    Size aSize;
    getMenuItemPosSize(maOpenTimer.mnMenuPos, aPos, aSize);
    ScMenuFloatingWindow* pSubMenu = maOpenTimer.mpSubMenu;

    if (!pSubMenu)
        return;

    sal_uInt32 nOldFlags = GetPopupModeFlags();
    SetPopupModeFlags(nOldFlags | FLOATWIN_POPUPMODE_NOAPPFOCUSCLOSE);
    pSubMenu->resizeToFitMenuItems(); // set the size before launching the popup to get it positioned correctly.
    pSubMenu->StartPopupMode(
        Rectangle(aPos,aSize), (FLOATWIN_POPUPMODE_RIGHT | FLOATWIN_POPUPMODE_GRABFOCUS));
    pSubMenu->AddPopupModeWindow(this);
    if (bSetMenuPos)
        pSubMenu->setSelectedMenuItem(0, false, false); // select menu item after the popup becomes fully visible.
    SetPopupModeFlags(nOldFlags);
}

void ScMenuFloatingWindow::endSubMenu(ScMenuFloatingWindow* pSubMenu)
{
    if (!pSubMenu)
        return;

    pSubMenu->EndPopupMode();
    maOpenTimer.reset();

    size_t nMenuPos = getSubMenuPos(pSubMenu);
    if (nMenuPos != MENU_NOT_SELECTED)
    {    
        highlightMenuItem(nMenuPos, true);
        mnSelectedMenu = nMenuPos;
        fireMenuHighlightedEvent();
    }
}

void ScMenuFloatingWindow::fillMenuItemsToAccessible(ScAccessibleFilterMenu* pAccMenu) const
{
    vector<MenuItemData>::const_iterator itr, itrBeg = maMenuItems.begin(), itrEnd = maMenuItems.end();
    for (itr = itrBeg; itr != itrEnd; ++itr)
    {
        size_t nPos = ::std::distance(itrBeg, itr);
        pAccMenu->appendMenuItem(itr->maText, itr->mbEnabled, nPos);
    }
}

ScDocument* ScMenuFloatingWindow::getDoc()
{
    return mpDoc;
}

void ScMenuFloatingWindow::resizeToFitMenuItems()
{
    if (maMenuItems.empty())
        return;

    vector<MenuItemData>::const_iterator itr = maMenuItems.begin(), itrEnd = maMenuItems.end();
    long nTextWidth = 0;
    for (; itr != itrEnd; ++itr)
        nTextWidth = ::std::max(GetTextWidth(itr->maText), nTextWidth);

    size_t nLastPos = maMenuItems.size()-1;
    Point aPos;
    Size aSize;
    getMenuItemPosSize(nLastPos, aPos, aSize);
    aPos.X() += nTextWidth + 15;
    aPos.Y() += aSize.Height() + 5;
    SetOutputSizePixel(Size(aPos.X(), aPos.Y()));
}

void ScMenuFloatingWindow::selectMenuItem(size_t nPos, bool bSelected, bool bSubMenuTimer)
{
    if (nPos >= maMenuItems.size() || nPos == MENU_NOT_SELECTED)
    {
        queueCloseSubMenu();
        return;
    }

    if (!maMenuItems[nPos].mbEnabled)
    {    
        queueCloseSubMenu();
        return;
    }

    highlightMenuItem(nPos, bSelected);

    if (bSelected)
    {
        if (mpParentMenu)
            mpParentMenu->setSubMenuFocused(this);

        if (bSubMenuTimer)
        {
            if (maMenuItems[nPos].mpSubMenuWin)
            {
                ScMenuFloatingWindow* pSubMenu = maMenuItems[nPos].mpSubMenuWin.get();
                queueLaunchSubMenu(nPos, pSubMenu);
            }
            else
                queueCloseSubMenu();
        }
    }
}

void ScMenuFloatingWindow::clearSelectedMenuItem()
{
    selectMenuItem(mnSelectedMenu, false, false);
    mnSelectedMenu = MENU_NOT_SELECTED;
}

ScMenuFloatingWindow* ScMenuFloatingWindow::getSubMenuWindow(size_t nPos) const
{
    if (maMenuItems.size() <= nPos)
        return NULL;

    return maMenuItems[nPos].mpSubMenuWin.get();
}

bool ScMenuFloatingWindow::isMenuItemSelected(size_t nPos) const
{
    return nPos == mnSelectedMenu;
}

void ScMenuFloatingWindow::setName(const OUString& rName)
{
    maName = rName;
}

const OUString& ScMenuFloatingWindow::getName() const
{
    return maName;
}

void ScMenuFloatingWindow::highlightMenuItem(size_t nPos, bool bSelected)
{
    if (nPos == MENU_NOT_SELECTED)
        return;

    const StyleSettings& rStyle = GetSettings().GetStyleSettings();
    Color aBackColor = rStyle.GetMenuColor();
    SetFillColor(aBackColor);
    SetLineColor(aBackColor);

    Point aPos;
    Size aSize;
    getMenuItemPosSize(nPos, aPos, aSize);
    Rectangle aRegion(aPos,aSize);

    if (IsNativeControlSupported(CTRL_MENU_POPUP, PART_ENTIRE_CONTROL))
    {
        Push(PUSH_CLIPREGION);
        IntersectClipRegion(Rectangle(aPos, aSize));
        Rectangle aCtrlRect(Point(0,0), GetOutputSizePixel()); 
        DrawNativeControl(
            CTRL_MENU_POPUP, PART_ENTIRE_CONTROL, aCtrlRect, CTRL_STATE_ENABLED,
            ImplControlValue(), OUString());

        Pop();
    }

    bool bNativeDrawn = true;
    if (IsNativeControlSupported(CTRL_MENU_POPUP, PART_MENU_ITEM))
    {
        ControlState nState = bSelected ? CTRL_STATE_SELECTED : 0;
        if (maMenuItems[nPos].mbEnabled)
            nState |= CTRL_STATE_ENABLED;
        bNativeDrawn = DrawNativeControl(
            CTRL_MENU_POPUP, PART_MENU_ITEM, aRegion, nState, ImplControlValue(), OUString());
    }
    else
        bNativeDrawn = false;

    if (!bNativeDrawn)
    {
        if (bSelected)
        {
            aBackColor = rStyle.GetMenuHighlightColor();
            SetFillColor(aBackColor);
            SetLineColor(aBackColor);
        }
        DrawRect(Rectangle(aPos,aSize));
    }

    Color aTextColor = bSelected ? rStyle.GetMenuHighlightTextColor() : rStyle.GetMenuTextColor();
    SetTextColor(aTextColor);
    drawMenuItem(nPos);
}

void ScMenuFloatingWindow::getMenuItemPosSize(size_t nPos, Point& rPos, Size& rSize) const
{
    const sal_uInt16 nLeftMargin = 5;
    const sal_uInt16 nTopMargin = 5;
    const sal_uInt16 nMenuItemHeight = static_cast< sal_uInt16 >( maLabelFont.GetHeight()*1.8 );

    Size aWndSize = GetSizePixel();

    Point aPos1(nLeftMargin, nTopMargin);
    Size aSize1(aWndSize.Width() - nLeftMargin*2, nMenuItemHeight);

    rPos = aPos1;
    rPos.Y() += aSize1.Height()*nPos;
    rSize = aSize1;
}

ScMenuFloatingWindow* ScMenuFloatingWindow::getParentMenuWindow() const
{
    return mpParentMenu;
}

size_t ScMenuFloatingWindow::getEnclosingMenuItem(const Point& rPos) const
{
    size_t n = maMenuItems.size();
    for (size_t i = 0; i < n; ++i)
    {
        Point aPos;
        Size aSize;
        getMenuItemPosSize(i, aPos, aSize);
        Rectangle aRect(aPos, aSize);
        if (aRect.IsInside(rPos))
            return i;
    }
    return MENU_NOT_SELECTED;
}

size_t ScMenuFloatingWindow::getSubMenuPos(ScMenuFloatingWindow* pSubMenu)
{
    size_t n = maMenuItems.size();
    for (size_t i = 0; i < n; ++i)
    {
        if (maMenuItems[i].mpSubMenuWin.get() == pSubMenu)
            return i;
    }
    return MENU_NOT_SELECTED;
}

void ScMenuFloatingWindow::fireMenuHighlightedEvent()
{
    if (mnSelectedMenu == MENU_NOT_SELECTED)
        return;

    if (!mxAccessible.is())
        return;

    Reference<XAccessibleContext> xAccCxt = mxAccessible->getAccessibleContext();
    if (!xAccCxt.is())
        return;

    Reference<XAccessible> xAccMenu = xAccCxt->getAccessibleChild(mnSelectedMenu);
    if (!xAccMenu.is())
        return;

    VclAccessibleEvent aEvent(VCLEVENT_MENU_HIGHLIGHT, xAccMenu);
    FireVclEvent(&aEvent);
}

void ScMenuFloatingWindow::setSubMenuFocused(ScMenuFloatingWindow* pSubMenu)
{
    maCloseTimer.reset();
    size_t nMenuPos = getSubMenuPos(pSubMenu);
    if (mnSelectedMenu != nMenuPos)
    {
        highlightMenuItem(nMenuPos, true);
        mnSelectedMenu = nMenuPos;
    }
}

void ScMenuFloatingWindow::ensureSubMenuVisible(ScMenuFloatingWindow* pSubMenu)
{
    if (mpParentMenu)
        mpParentMenu->ensureSubMenuVisible(this);

    if (pSubMenu->IsVisible())
        return;

    // Find the menu position of the submenu.
    size_t nMenuPos = getSubMenuPos(pSubMenu);
    if (nMenuPos != MENU_NOT_SELECTED)
    {
        setSelectedMenuItem(nMenuPos, false, false);

        Point aPos;
        Size aSize;
        getMenuItemPosSize(nMenuPos, aPos, aSize);

        sal_uInt32 nOldFlags = GetPopupModeFlags();
        SetPopupModeFlags(nOldFlags | FLOATWIN_POPUPMODE_NOAPPFOCUSCLOSE);
        pSubMenu->resizeToFitMenuItems(); // set the size before launching the popup to get it positioned correctly.
        pSubMenu->StartPopupMode(
            Rectangle(aPos,aSize), (FLOATWIN_POPUPMODE_RIGHT | FLOATWIN_POPUPMODE_GRABFOCUS));
        pSubMenu->AddPopupModeWindow(this);
        SetPopupModeFlags(nOldFlags);
    }
}

void ScMenuFloatingWindow::ensureSubMenuNotVisible()
{
    if (mnSelectedMenu <= maMenuItems.size() && 
        maMenuItems[mnSelectedMenu].mpSubMenuWin && 
        maMenuItems[mnSelectedMenu].mpSubMenuWin->IsVisible())
    {    
        maMenuItems[mnSelectedMenu].mpSubMenuWin->ensureSubMenuNotVisible();
    }

    EndPopupMode();
}

void ScMenuFloatingWindow::terminateAllPopupMenus()
{
    EndPopupMode();
    if (mpParentMenu)
        mpParentMenu->terminateAllPopupMenus();
}

IMPL_LINK( ScMenuFloatingWindow, PopupEndHdl, void*, EMPTYARG )
{
    clearSelectedMenuItem();
    return 0;
}

// ============================================================================

ScDPFieldPopupWindow::Member::Member() :
    mbVisible(true)
{
}

// ----------------------------------------------------------------------------

ScDPFieldPopupWindow::CancelButton::CancelButton(ScDPFieldPopupWindow* pParent) :
    ::CancelButton(pParent), mpParent(pParent) {}

void ScDPFieldPopupWindow::CancelButton::Click()
{
    mpParent->EndPopupMode();
    ::CancelButton::Click();
}

// ----------------------------------------------------------------------------

ScDPFieldPopupWindow::ScDPFieldPopupWindow(Window* pParent, ScDocument* pDoc) :
    ScMenuFloatingWindow(pParent, pDoc),
    maChecks(this, 0),
    maChkToggleAll(this, 0),
    maBtnSelectSingle  (this, 0), 
    maBtnUnselectSingle(this, 0), 
    maBtnOk(this),
    maBtnCancel(this),
    mnCurTabStop(0),
    mpExtendedData(NULL),
    mpOKAction(NULL),
    maWndSize(240, 330),
    mePrevToggleAllState(STATE_DONTKNOW)
{
    maTabStopCtrls.reserve(7);
    maTabStopCtrls.push_back(this);
    maTabStopCtrls.push_back(&maChecks);
    maTabStopCtrls.push_back(&maChkToggleAll);
    maTabStopCtrls.push_back(&maBtnSelectSingle);
    maTabStopCtrls.push_back(&maBtnUnselectSingle);
    maTabStopCtrls.push_back(&maBtnOk);
    maTabStopCtrls.push_back(&maBtnCancel);

    const StyleSettings& rStyle = GetSettings().GetStyleSettings();

    Point aPos;
    Size aSize;
    getSectionPosSize(aPos, aSize, WHOLE);
    SetOutputSizePixel(aSize);
    Size aOutSize = GetOutputSizePixel();

    getSectionPosSize(aPos, aSize, BTN_OK);
    maBtnOk.SetPosSizePixel(aPos, aSize);
    maBtnOk.SetFont(getLabelFont());
    maBtnOk.SetClickHdl( LINK(this, ScDPFieldPopupWindow, ButtonHdl) );
    maBtnOk.Show();

    getSectionPosSize(aPos, aSize, BTN_CANCEL);
    maBtnCancel.SetPosSizePixel(aPos, aSize);
    maBtnCancel.SetFont(getLabelFont());
    maBtnCancel.Show();

    getSectionPosSize(aPos, aSize, LISTBOX_AREA_INNER);
    maChecks.SetPosSizePixel(aPos, aSize);
    maChecks.SetFont(getLabelFont());
    maChecks.SetCheckButtonHdl( LINK(this, ScDPFieldPopupWindow, CheckHdl) );
    maChecks.Show();

    getSectionPosSize(aPos, aSize, CHECK_TOGGLE_ALL);
    maChkToggleAll.SetPosSizePixel(aPos, aSize);
    maChkToggleAll.SetFont(getLabelFont());
    maChkToggleAll.SetText(ScRscStrLoader(RID_POPUP_FILTER, STR_BTN_TOGGLE_ALL).GetString());
    maChkToggleAll.SetControlBackground(rStyle.GetMenuColor());
    maChkToggleAll.SetClickHdl( LINK(this, ScDPFieldPopupWindow, TriStateHdl) );
    maChkToggleAll.Show();

    getSectionPosSize(aPos, aSize, BTN_SINGLE_SELECT);
    maBtnSelectSingle.SetPosSizePixel(aPos, aSize);
    maBtnSelectSingle.SetQuickHelpText(ScRscStrLoader(RID_POPUP_FILTER, STR_BTN_SELECT_CURRENT).GetString());
    maBtnSelectSingle.SetModeImage(Image(ScResId(RID_IMG_SELECT_CURRENT)), BMP_COLOR_NORMAL);
    maBtnSelectSingle.SetClickHdl( LINK(this, ScDPFieldPopupWindow, ButtonHdl) );
    maBtnSelectSingle.Show();

    getSectionPosSize(aPos, aSize, BTN_SINGLE_UNSELECT);
    maBtnUnselectSingle.SetPosSizePixel(aPos, aSize);
    maBtnUnselectSingle.SetQuickHelpText(ScRscStrLoader(RID_POPUP_FILTER, STR_BTN_UNSELECT_CURRENT).GetString());
    maBtnUnselectSingle.SetModeImage(Image(ScResId(RID_IMG_UNSELECT_CURRENT)), BMP_COLOR_NORMAL);
    maBtnUnselectSingle.SetClickHdl( LINK(this, ScDPFieldPopupWindow, ButtonHdl) );
    maBtnUnselectSingle.Show();
}

ScDPFieldPopupWindow::~ScDPFieldPopupWindow()
{
}

void ScDPFieldPopupWindow::getSectionPosSize(Point& rPos, Size& rSize, SectionType eType) const
{
    // constant parameters.
    const sal_uInt16 nListBoxMargin = 5;            // horizontal distance from the side of the dialog to the listbox border.
    const sal_uInt16 nListBoxInnerPadding = 5;
    const sal_uInt16 nTopMargin = 5;
    const sal_uInt16 nMenuHeight = 60;
    const sal_uInt16 nSingleItemBtnAreaHeight = 32; // height of the middle area below the list box where the single-action buttons are.
    const sal_uInt16 nBottomBtnAreaHeight = 50;     // height of the bottom area where the OK and Cancel buttons are.
    const sal_uInt16 nBtnWidth = 90;
    const sal_uInt16 nLabelHeight = static_cast< sal_uInt16 >( getLabelFont().GetHeight() );
    const sal_uInt16 nBtnHeight = nLabelHeight*2;
    const sal_uInt16 nBottomMargin = 10;
    const sal_uInt16 nMenuListMargin = 20;

    // parameters calculated from constants.
    const sal_uInt16 nListBoxWidth = static_cast< sal_uInt16 >( maWndSize.Width() - nListBoxMargin*2 );
    const sal_uInt16 nListBoxHeight = static_cast< sal_uInt16 >( maWndSize.Height() - nTopMargin - nMenuHeight - 
        nMenuListMargin - nSingleItemBtnAreaHeight - nBottomBtnAreaHeight );

    const sal_uInt16 nSingleBtnAreaY = nTopMargin + nMenuHeight + nListBoxHeight + nMenuListMargin - 1;

    switch (eType)
    {
        case WHOLE:
        {
            rPos  = Point(0, 0);
            rSize = maWndSize;
        }
        break;
        case LISTBOX_AREA_OUTER:
        {
            rPos = Point(nListBoxMargin, nTopMargin + nMenuHeight + nMenuListMargin);
            rSize = Size(nListBoxWidth, nListBoxHeight);
        }
        break;
        case LISTBOX_AREA_INNER:
        {
            rPos = Point(nListBoxMargin, nTopMargin + nMenuHeight + nMenuListMargin);
            rPos.X() += nListBoxInnerPadding;
            rPos.Y() += nListBoxInnerPadding;

            rSize = Size(nListBoxWidth, nListBoxHeight);
            rSize.Width()  -= nListBoxInnerPadding*2;
            rSize.Height() -= nListBoxInnerPadding*2;
        }
        break;
        case SINGLE_BTN_AREA:
        {
            rPos = Point(nListBoxMargin, nSingleBtnAreaY);
            rSize = Size(nListBoxWidth, nSingleItemBtnAreaHeight);
        }
        break;
        case CHECK_TOGGLE_ALL:
        {
            long h = nLabelHeight*3/2; // check box height is heuristically 150% of the text height.
            rPos = Point(nListBoxMargin, nSingleBtnAreaY);
            rPos.X() += 5;
            rPos.Y() += (nSingleItemBtnAreaHeight - h)/2;
            rSize = Size(70, h);
        }
        break;
        case BTN_SINGLE_SELECT:
        {
            long h = 26;
            rPos = Point(nListBoxMargin, nSingleBtnAreaY);
            rPos.X() += 150;
            rPos.Y() += (nSingleItemBtnAreaHeight - h)/2;
            rSize = Size(h, h);
        }
        break;
        case BTN_SINGLE_UNSELECT:
        {
            long h = 26;
            rPos = Point(nListBoxMargin, nSingleBtnAreaY);
            rPos.X() += 150 + h + 10;
            rPos.Y() += (nSingleItemBtnAreaHeight - h)/2;
            rSize = Size(h, h);
        }
        break;
        case BTN_OK:
        {
            long x = (maWndSize.Width() - nBtnWidth*2)/3;
            long y = maWndSize.Height() - nBottomMargin - nBtnHeight;
            rPos = Point(x, y);
            rSize = Size(nBtnWidth, nBtnHeight);
        }
        break;
        case BTN_CANCEL:
        {
            long x = (maWndSize.Width() - nBtnWidth*2)/3*2 + nBtnWidth;
            long y = maWndSize.Height() - nBottomMargin - nBtnHeight;
            rPos = Point(x, y);
            rSize = Size(nBtnWidth, nBtnHeight);
        }
        break;
        default:
            ;
    }
}

void ScDPFieldPopupWindow::setAllMemberState(bool bSet)
{
    size_t n = maMembers.size();
    for (size_t i = 0; i < n; ++i)
        maChecks.CheckEntryPos(static_cast< sal_uInt16 >( i ), bSet);
}

void ScDPFieldPopupWindow::selectCurrentMemberOnly(bool bSet)
{
    setAllMemberState(!bSet);
    sal_uInt16 nSelected = maChecks.GetSelectEntryPos();
    maChecks.CheckEntryPos(nSelected, bSet);
}

void ScDPFieldPopupWindow::cycleFocus(bool bReverse)
{
    maTabStopCtrls[mnCurTabStop]->SetFakeFocus(false);
    maTabStopCtrls[mnCurTabStop]->LoseFocus();
    if (mnCurTabStop == 0)
        clearSelectedMenuItem();

    if (bReverse)
    {
        if (mnCurTabStop > 0)
            --mnCurTabStop;
        else
            mnCurTabStop = maTabStopCtrls.size() - 1;
    }
    else
    {
        ++mnCurTabStop;
        if (mnCurTabStop >= maTabStopCtrls.size())
            mnCurTabStop = 0;
    }
    maTabStopCtrls[mnCurTabStop]->SetFakeFocus(true);
    maTabStopCtrls[mnCurTabStop]->GrabFocus();
}

IMPL_LINK( ScDPFieldPopupWindow, ButtonHdl, Button*, pBtn )
{
    if (pBtn == &maBtnOk)
        close(true);
    else if (pBtn == &maBtnSelectSingle)
    {    
        selectCurrentMemberOnly(true);
        CheckHdl(&maChecks);
    }
    else if (pBtn == &maBtnUnselectSingle)
    {    
        selectCurrentMemberOnly(false);
        CheckHdl(&maChecks);
    }
    return 0;
}

IMPL_LINK( ScDPFieldPopupWindow, TriStateHdl, TriStateBox*, EMPTYARG )
{
    switch (mePrevToggleAllState)
    {
        case STATE_NOCHECK:
            maChkToggleAll.SetState(STATE_CHECK);
            setAllMemberState(true);
        break;
        case STATE_CHECK:
            maChkToggleAll.SetState(STATE_NOCHECK);
            setAllMemberState(false);
        break;
        case STATE_DONTKNOW:
        default:
            maChkToggleAll.SetState(STATE_CHECK);
            setAllMemberState(true);
        break;
    }

    mePrevToggleAllState = maChkToggleAll.GetState();
    return 0;
}

IMPL_LINK( ScDPFieldPopupWindow, CheckHdl, SvTreeListBox*, pChecks )
{
    if (pChecks != &maChecks)
        return 0;

    size_t nNumChecked = maChecks.GetCheckedEntryCount();
    if (nNumChecked == maMembers.size())
        // all members visible
        maChkToggleAll.SetState(STATE_CHECK);
    else if (nNumChecked == 0)
        // no members visible
        maChkToggleAll.SetState(STATE_NOCHECK);
    else
        maChkToggleAll.SetState(STATE_DONTKNOW);

    mePrevToggleAllState = maChkToggleAll.GetState();
    return 0;
}

void ScDPFieldPopupWindow::MouseMove(const MouseEvent& rMEvt)
{
    ScMenuFloatingWindow::MouseMove(rMEvt);

    size_t nSelectedMenu = getSelectedMenuItem();
    if (nSelectedMenu == MENU_NOT_SELECTED)
        queueCloseSubMenu();
}

long ScDPFieldPopupWindow::Notify(NotifyEvent& rNEvt)
{
    switch (rNEvt.GetType())
    {
        case EVENT_KEYUP:
        {
            const KeyEvent* pKeyEvent = rNEvt.GetKeyEvent();
            const KeyCode& rCode = pKeyEvent->GetKeyCode();
            bool bShift = rCode.IsShift();
            if (rCode.GetCode() == KEY_TAB)
            {
                cycleFocus(bShift);
                return true;
            }
        }
        break;
    }
    return ScMenuFloatingWindow::Notify(rNEvt);
}

void ScDPFieldPopupWindow::Paint(const Rectangle& rRect)
{
    ScMenuFloatingWindow::Paint(rRect);

    const StyleSettings& rStyle = GetSettings().GetStyleSettings();
    Color aMemberBackColor = rStyle.GetFieldColor();
    Color aBorderColor = rStyle.GetShadowColor();

    Point aPos;
    Size aSize;
    getSectionPosSize(aPos, aSize, LISTBOX_AREA_OUTER);

    // Member list box background
    SetFillColor(aMemberBackColor);
    SetLineColor(aBorderColor);
    DrawRect(Rectangle(aPos,aSize));

    // Single-action button box
    getSectionPosSize(aPos, aSize, SINGLE_BTN_AREA);
    SetFillColor(rStyle.GetMenuColor());
    DrawRect(Rectangle(aPos,aSize));
}

Window* ScDPFieldPopupWindow::GetPreferredKeyInputWindow()
{
    return maTabStopCtrls[mnCurTabStop];
}

Reference<XAccessible> ScDPFieldPopupWindow::CreateAccessible()
{
    if (!mxAccessible.is())
    {    
        mxAccessible.set(new ScAccessibleFilterTopWindow(
            GetAccessibleParentWindow()->GetAccessible(), this, getName(), getDoc()));
        ScAccessibleFilterTopWindow* pAccTop = static_cast<ScAccessibleFilterTopWindow*>(mxAccessible.get());
        fillMenuItemsToAccessible(pAccTop);

        pAccTop->setAccessibleChild(
            maChecks.CreateAccessible(), ScAccessibleFilterTopWindow::LISTBOX);
        pAccTop->setAccessibleChild(
            maChkToggleAll.CreateAccessible(), ScAccessibleFilterTopWindow::TOGGLE_ALL);
        pAccTop->setAccessibleChild(
            maBtnSelectSingle.CreateAccessible(), ScAccessibleFilterTopWindow::SINGLE_ON_BTN);
        pAccTop->setAccessibleChild(
            maBtnUnselectSingle.CreateAccessible(), ScAccessibleFilterTopWindow::SINGLE_OFF_BTN);
        pAccTop->setAccessibleChild(
            maBtnOk.CreateAccessible(), ScAccessibleFilterTopWindow::OK_BTN);
        pAccTop->setAccessibleChild(
            maBtnCancel.CreateAccessible(), ScAccessibleFilterTopWindow::CANCEL_BTN);
    }

    return mxAccessible;
}

void ScDPFieldPopupWindow::setMemberSize(size_t n)
{
    maMembers.reserve(n);
}

void ScDPFieldPopupWindow::addMember(const OUString& rName, bool bVisible)
{
    Member aMember;
    aMember.maName = rName;
    aMember.mbVisible = bVisible;
    maMembers.push_back(aMember);
}

void ScDPFieldPopupWindow::initMembers()
{
    size_t n = maMembers.size();
    size_t nVisMemCount = 0;
    for (size_t i = 0; i < n; ++i)
    {
        maChecks.InsertEntry(maMembers[i].maName);
        maChecks.CheckEntryPos(static_cast< sal_uInt16 >( i ), maMembers[i].mbVisible);
        if (maMembers[i].mbVisible)
            ++nVisMemCount;
    }
    if (nVisMemCount == n)
    {    
        // all members visible
        maChkToggleAll.SetState(STATE_CHECK);
        mePrevToggleAllState = STATE_CHECK;
    }
    else if (nVisMemCount == 0)
    {    
        // no members visible
        maChkToggleAll.SetState(STATE_NOCHECK);
        mePrevToggleAllState = STATE_NOCHECK;
    }
    else
    {    
        maChkToggleAll.SetState(STATE_DONTKNOW);
        mePrevToggleAllState = STATE_DONTKNOW;
    }
}

const Size& ScDPFieldPopupWindow::getWindowSize() const
{
    return maWndSize;
}

void ScDPFieldPopupWindow::getResult(hash_map<OUString, bool, OUStringHash>& rResult)
{
    typedef hash_map<OUString, bool, OUStringHash> ResultMap;
    ResultMap aResult;
    size_t n = maMembers.size();
    for (size_t i = 0; i < n; ++i)
    {
        bool bState = maChecks.IsChecked(static_cast< sal_uInt16 >( i ));
        aResult.insert(ResultMap::value_type(maMembers[i].maName, bState));
    }
    rResult.swap(aResult);
}

void ScDPFieldPopupWindow::close(bool bOK)
{
    if (bOK && mpOKAction.get())
        mpOKAction->execute();

    EndPopupMode();
}

void ScDPFieldPopupWindow::setExtendedData(ExtendedData* p)
{
    mpExtendedData.reset(p);
}

ScDPFieldPopupWindow::ExtendedData* ScDPFieldPopupWindow::getExtendedData()
{
    return mpExtendedData.get();
}

void ScDPFieldPopupWindow::setOKAction(Action* p)
{
    mpOKAction.reset(p);
}

