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.ade.sitemap.client.hoverbar;
029
030import org.opencms.ade.sitemap.client.Messages;
031import org.opencms.ade.sitemap.shared.CmsClientSitemapEntry;
032import org.opencms.gwt.client.ui.CmsMenuButton;
033import org.opencms.gwt.client.ui.I_CmsButton;
034import org.opencms.gwt.client.ui.contextmenu.CmsContextMenu;
035import org.opencms.gwt.client.ui.contextmenu.CmsContextMenuCloseHandler;
036import org.opencms.gwt.client.ui.contextmenu.I_CmsContextMenuEntry;
037import org.opencms.gwt.client.ui.css.I_CmsLayoutBundle;
038
039import java.util.ArrayList;
040import java.util.Arrays;
041import java.util.List;
042
043import com.google.common.collect.Lists;
044import com.google.gwt.event.dom.client.ClickEvent;
045import com.google.gwt.event.dom.client.ClickHandler;
046import com.google.gwt.event.logical.shared.CloseEvent;
047import com.google.gwt.event.logical.shared.CloseHandler;
048import com.google.gwt.user.client.rpc.AsyncCallback;
049import com.google.gwt.user.client.ui.FlexTable;
050import com.google.gwt.user.client.ui.PopupPanel;
051
052/**
053 * Sitemap context menu button.<p>
054 *
055 * @since 8.0.0
056 */
057public class CmsHoverbarContextMenuButton extends CmsMenuButton implements I_CmsContextMenuItemProvider {
058
059    /** The context menu entries. */
060    private List<A_CmsSitemapMenuEntry> m_entries;
061
062    /** The main content widget. */
063    private FlexTable m_menuPanel;
064
065    /**
066     * Constructor.<p>
067     *
068     * @param hoverbar the hoverbar
069     * @param menuItemProvider the context menu item provider
070     */
071    public CmsHoverbarContextMenuButton(
072        final CmsSitemapHoverbar hoverbar,
073        I_CmsContextMenuItemProvider menuItemProvider) {
074
075        super(null, I_CmsButton.CONTEXT_MENU_SMALL);
076        // create the menu panel (it's a table because of ie6)
077        m_menuPanel = new FlexTable();
078        // set a style name for the menu table
079        m_menuPanel.getElement().addClassName(I_CmsLayoutBundle.INSTANCE.contextmenuCss().menuPanel());
080        m_button.setSize(I_CmsButton.Size.medium);
081        // set the widget
082        setMenuWidget(m_menuPanel);
083        //    getPopupContent().removeAutoHidePartner(getElement());
084        getPopup().addAutoHidePartner(getElement());
085        getPopup().setWidth(0);
086        getPopup().addStyleName(I_CmsLayoutBundle.INSTANCE.dialogCss().contextMenu());
087
088        m_entries = new ArrayList<A_CmsSitemapMenuEntry>();
089        if (menuItemProvider == null) {
090            menuItemProvider = this;
091        }
092        m_entries.addAll(menuItemProvider.createContextMenu(hoverbar));
093
094        setTitle(Messages.get().key(Messages.GUI_HOVERBAR_TITLE_0));
095        setVisible(true);
096        addClickHandler(new ClickHandler() {
097
098            /**
099             * @see com.google.gwt.event.dom.client.ClickHandler#onClick(com.google.gwt.event.dom.client.ClickEvent)
100             */
101            public void onClick(ClickEvent event) {
102
103                if (!isOpen()) {
104                    showMenu(hoverbar);
105                } else {
106                    closeMenu();
107                }
108            }
109        });
110    }
111
112    /**
113     * @see org.opencms.ade.sitemap.client.hoverbar.I_CmsContextMenuItemProvider#createContextMenu(org.opencms.ade.sitemap.client.hoverbar.CmsSitemapHoverbar)
114     */
115    public List<A_CmsSitemapMenuEntry> createContextMenu(CmsSitemapHoverbar hoverbar) {
116
117        List<A_CmsSitemapMenuEntry> result = Lists.newArrayList();
118
119        result.add(new CmsGotoMenuEntry(hoverbar));
120        result.add(new CmsGotoExplorerMenuEntry(hoverbar));
121        result.add(new CmsOpenGalleryMenuEntry(hoverbar));
122        result.add(new CmsEditRedirectMenuEntry(hoverbar));
123        result.add(new CmsEditModelPageMenuEntry(hoverbar));
124        result.add(new CmsDeleteModelPageMenuEntry(hoverbar));
125        result.add(new CmsDisableMenuEntry(hoverbar));
126        result.add(new CmsEditMenuEntry(hoverbar));
127        result.add(new CmsCopyPageMenuEntry(hoverbar));
128        result.add(new CmsCopyModelPageMenuEntry(hoverbar));
129        result.add(new CmsSetDefaultModelMenuEntry(hoverbar));
130        result.add(new CmsCopyAsModelGroupPageMenuEntry(hoverbar));
131        result.add(new CmsCreateGalleryMenuEntry(hoverbar));
132        result.add(new CmsResourceInfoMenuEntry(hoverbar));
133        result.add(new CmsParentSitemapMenuEntry(hoverbar));
134        result.add(new CmsGotoSubSitemapMenuEntry(hoverbar));
135        result.add(new CmsNewChoiceMenuEntry(hoverbar));
136        result.add(new CmsHideMenuEntry(hoverbar));
137        result.add(new CmsShowMenuEntry(hoverbar));
138        result.add(new CmsAddToNavMenuEntry(hoverbar));
139        result.add(new CmsBumpDetailPageMenuEntry(hoverbar));
140        result.add(new CmsRefreshMenuEntry(hoverbar));
141        result.add(
142            new CmsAdvancedSubmenu(
143                hoverbar,
144                Arrays.asList(
145                    new CmsAvailabilityMenuEntry(hoverbar),
146                    new CmsLockReportMenuEntry(hoverbar),
147                    new CmsSeoMenuEntry(hoverbar),
148                    new CmsSubSitemapMenuEntry(hoverbar),
149                    new CmsMergeMenuEntry(hoverbar),
150                    new CmsRemoveMenuEntry(hoverbar))));
151        result.add(new CmsModelPageLockReportMenuEntry(hoverbar));
152        result.add(new CmsDeleteMenuEntry(hoverbar));
153
154        return result;
155    }
156
157    /**
158     * Rests the button state and hides the hoverbar.<p>
159     *
160     * @param hoverbar the hoverbar
161     */
162    protected void onMenuClose(CmsSitemapHoverbar hoverbar) {
163
164        m_button.setDown(false);
165        if (!hoverbar.isHovered()) {
166            hoverbar.hide();
167        } else {
168            hoverbar.setLocked(false);
169        }
170    }
171
172    /**
173     * Sets the context menu visible.<p>
174     *
175     * @param hoverbar the hoverbar instance
176     */
177    protected void setMenuVisible(final CmsSitemapHoverbar hoverbar) {
178
179        updateVisibility();
180        CmsContextMenu menu = new CmsContextMenu(new ArrayList<I_CmsContextMenuEntry>(m_entries), false, getPopup());
181        m_menuPanel.setWidget(0, 0, menu);
182        // add the close handler for the menu
183        getPopup().addCloseHandler(new CmsContextMenuCloseHandler(menu));
184        getPopup().addCloseHandler(new CloseHandler<PopupPanel>() {
185
186            public void onClose(CloseEvent<PopupPanel> closeEvent) {
187
188                onMenuClose(hoverbar);
189                closeMenu();
190            }
191        });
192        openMenu();
193    }
194
195    /**
196     * Shows the context menu.<p>
197     *
198     * @param hoverbar the hoverbar instance
199     */
200    protected void showMenu(final CmsSitemapHoverbar hoverbar) {
201
202        // lock the hoverbar visibility to avoid hide on mouse out
203        hoverbar.setLocked(true);
204        hoverbar.loadEntry(new AsyncCallback<CmsClientSitemapEntry>() {
205
206            public void onFailure(Throwable caught) {
207
208                // TODO Auto-generated method stub
209
210            }
211
212            public void onSuccess(CmsClientSitemapEntry result) {
213
214                setMenuVisible(hoverbar);
215            }
216        });
217    }
218
219    /**
220     * Updates the entry visibility.<p>
221     */
222    private void updateVisibility() {
223
224        for (A_CmsSitemapMenuEntry entry : m_entries) {
225            updateVisibility(entry);
226        }
227    }
228
229    /**
230     * Updates the visibility for an entry and its sub-entries.<p>
231     *
232     * @param entry the entry to update
233     */
234    private void updateVisibility(A_CmsSitemapMenuEntry entry) {
235
236        if (entry.getSubMenu() != null) {
237            for (I_CmsContextMenuEntry subItem : entry.getSubMenu()) {
238                updateVisibility((A_CmsSitemapMenuEntry)subItem);
239            }
240        }
241        entry.onShow();
242    }
243}