001/*
002 * This library is part of OpenCms -
003 * the Open Source Content Management System
004 *
005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com)
006 *
007 * This library is free software; you can redistribute it and/or
008 * modify it under the terms of the GNU Lesser General Public
009 * License as published by the Free Software Foundation; either
010 * version 2.1 of the License, or (at your option) any later version.
011 *
012 * This library is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015 * Lesser General Public License for more details.
016 *
017 * For further information about Alkacon Software, please see the
018 * company website: http://www.alkacon.com
019 *
020 * For further information about OpenCms, please see the
021 * project website: http://www.opencms.org
022 *
023 * You should have received a copy of the GNU Lesser General Public
024 * License along with this library; if not, write to the Free Software
025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
026 */
027
028package org.opencms.gwt.client.ui.contextmenu;
029
030import org.opencms.gwt.client.Messages;
031import org.opencms.gwt.client.ui.CmsLoadingAnimation;
032import org.opencms.gwt.client.ui.CmsMenuButton;
033import org.opencms.gwt.client.ui.I_CmsButton;
034import org.opencms.gwt.client.ui.I_CmsButton.ButtonStyle;
035import org.opencms.gwt.client.ui.css.I_CmsLayoutBundle;
036import org.opencms.gwt.client.ui.input.CmsLabel;
037import org.opencms.gwt.client.util.CmsClientCollectionUtil;
038import org.opencms.gwt.shared.CmsCoreData.AdeContext;
039import org.opencms.util.CmsUUID;
040
041import java.util.List;
042
043import com.google.gwt.event.dom.client.ClickEvent;
044import com.google.gwt.event.dom.client.ClickHandler;
045import com.google.gwt.event.logical.shared.CloseEvent;
046import com.google.gwt.event.logical.shared.CloseHandler;
047import com.google.gwt.event.shared.HandlerRegistration;
048import com.google.gwt.user.client.Window;
049import com.google.gwt.user.client.ui.FlexTable;
050import com.google.gwt.user.client.ui.PopupPanel;
051
052/**
053 * The result item context menu button.<p>
054 */
055public class CmsContextMenuButton extends CmsMenuButton {
056
057    /** The menu data. */
058    protected List<I_CmsContextMenuEntry> m_menuEntries;
059
060    /** The loading panel. */
061    private CmsLoadingAnimation m_loadingPanel;
062
063    /** The context menu. */
064    private CmsContextMenu m_menu;
065
066    /** The registration for the first close handler. */
067    private HandlerRegistration m_menuCloseHandler;
068
069    /** The main content widget. */
070    private FlexTable m_menuPanel;
071
072    /** The label which is displayed when no entries are found. */
073    private CmsLabel m_noEntriesLabel;
074
075    /** The registration for the second close handler. */
076    private HandlerRegistration m_popupCloseHandler;
077
078    /**
079     * Constructor.<p>
080     *
081     * @param structureId the resource structure id
082     * @param handler the context menu handler
083     * @param context the ADE context
084     */
085    public CmsContextMenuButton(
086        final CmsUUID structureId,
087        final CmsContextMenuHandler handler,
088        final AdeContext context) {
089
090        super(null, I_CmsButton.CONTEXT_MENU_SMALL);
091        m_button.setSize(I_CmsButton.Size.medium);
092        setTitle(Messages.get().key(Messages.GUI_TOOLBAR_CONTEXT_0));
093        m_noEntriesLabel = new CmsLabel(Messages.get().key(Messages.GUI_TOOLBAR_CONTEXT_EMPTY_0));
094        m_noEntriesLabel.addStyleName(I_CmsLayoutBundle.INSTANCE.contextmenuCss().menuInfoLabel());
095        m_noEntriesLabel.addStyleName(I_CmsLayoutBundle.INSTANCE.generalCss().buttonCornerAll());
096        m_loadingPanel = new CmsLoadingAnimation();
097        // create the menu panel (it's a table because of ie6)
098        m_menuPanel = new FlexTable();
099        // set a style name for the menu table
100        m_menuPanel.getElement().addClassName(I_CmsLayoutBundle.INSTANCE.contextmenuCss().menuPanel());
101        m_button.setButtonStyle(ButtonStyle.TRANSPARENT, null);
102        // set the widget
103        setMenuWidget(m_menuPanel);
104
105        // clear the width of the popup content
106        getPopup().setWidth(0);
107        getPopup().addStyleName(I_CmsLayoutBundle.INSTANCE.dialogCss().contextMenu());
108
109        setToolbarMode(false);
110        getPopup().addAutoHidePartner(getElement());
111        getPopup().addCloseHandler(new CloseHandler<PopupPanel>() {
112
113            public void onClose(CloseEvent<PopupPanel> event) {
114
115                getParent().removeStyleName(I_CmsLayoutBundle.INSTANCE.listItemWidgetCss().permaVisible());
116            }
117        });
118        addClickHandler(new ClickHandler() {
119
120            /**
121             * @see com.google.gwt.event.dom.client.ClickHandler#onClick(com.google.gwt.event.dom.client.ClickEvent)
122             */
123            public void onClick(ClickEvent event) {
124
125                if (!isOpen()) {
126                    openMenu();
127                    getParent().addStyleName(I_CmsLayoutBundle.INSTANCE.listItemWidgetCss().permaVisible());
128                    handler.loadContextMenu(structureId, context, CmsContextMenuButton.this);
129                } else {
130                    hideMenu();
131                }
132            }
133
134        });
135    }
136
137    /**
138     * @see org.opencms.gwt.client.ui.CmsMenuButton#openMenu()
139     */
140    @Override
141    public void openMenu() {
142
143        if (m_menu == null) {
144            m_menuPanel.setWidget(0, 0, m_loadingPanel);
145        }
146        super.openMenu();
147
148    }
149
150    /**
151     * Creates the menu and adds it to the panel.<p>
152     *
153     * @param menuEntries the menu entries
154     */
155    public void showMenu(List<I_CmsContextMenuEntry> menuEntries) {
156
157        if (!CmsClientCollectionUtil.isEmptyOrNull(menuEntries)) {
158            // if there were entries found for the menu, create the menu
159            m_menu = new CmsContextMenu(menuEntries, true, getPopup());
160            // add the resize handler for the menu
161            m_resizeRegistration = Window.addResizeHandler(m_menu);
162            // set the menu as widget for the panel
163            m_menuPanel.setWidget(0, 0, m_menu);
164            if (m_menuCloseHandler != null) {
165                m_menuCloseHandler.removeHandler();
166            }
167            if (m_popupCloseHandler != null) {
168                m_popupCloseHandler.removeHandler();
169            }
170            // add the close handler for the menu
171            m_menuCloseHandler = getPopup().addCloseHandler(new CmsContextMenuCloseHandler(m_menu));
172            m_popupCloseHandler = getPopup().addCloseHandler(new CloseHandler<PopupPanel>() {
173
174                public void onClose(CloseEvent<PopupPanel> event) {
175
176                    closeMenu();
177                }
178            });
179            // calling m_popup.position() directly causes weird layout bugs, wait until end of event cycle
180            m_popup.positionDeferred();
181        } else {
182            m_menuPanel.setWidget(0, 0, m_noEntriesLabel);
183            m_popup.positionDeferred();
184        }
185    }
186
187    /**
188     * @see org.opencms.gwt.client.ui.CmsMenuButton#hideMenu()
189     *
190     * Needed to increase visibility.<p>
191     */
192    @Override
193    protected void hideMenu() {
194
195        super.hideMenu();
196    }
197}