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