org.opencms.ui.components.CmsToolBar Maven / Gradle / Ivy
Show all versions of opencms-test Show documentation
/*
* This library is part of OpenCms -
* the Open Source Content Management System
*
* Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* For further information about Alkacon Software, please see the
* company website: http://www.alkacon.com
*
* For further information about OpenCms, please see the
* project website: http://www.opencms.org
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.opencms.ui.components;
import org.opencms.file.CmsObject;
import org.opencms.file.CmsResource;
import org.opencms.file.CmsResourceFilter;
import org.opencms.main.CmsException;
import org.opencms.main.CmsLog;
import org.opencms.main.OpenCms;
import org.opencms.site.CmsSite;
import org.opencms.ui.A_CmsDialogContext;
import org.opencms.ui.A_CmsUI;
import org.opencms.ui.CmsVaadinUtils;
import org.opencms.ui.FontOpenCms;
import org.opencms.ui.I_CmsDialogContext;
import org.opencms.ui.apps.CmsAppWorkplaceUi;
import org.opencms.ui.apps.CmsDefaultAppButtonProvider;
import org.opencms.ui.apps.I_CmsWorkplaceAppConfiguration;
import org.opencms.ui.apps.Messages;
import org.opencms.ui.components.CmsUploadButton.I_UploadListener;
import org.opencms.ui.contextmenu.CmsContextMenuTreeBuilder;
import org.opencms.ui.contextmenu.I_CmsContextMenuItem;
import org.opencms.util.CmsStringUtil;
import org.opencms.util.CmsTreeNode;
import org.opencms.util.CmsUUID;
import org.opencms.workplace.CmsWorkplace;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import org.apache.commons.logging.Log;
import com.google.common.collect.Lists;
import com.vaadin.server.ExternalResource;
import com.vaadin.server.FontIcon;
import com.vaadin.server.Page;
import com.vaadin.server.Page.BrowserWindowResizeEvent;
import com.vaadin.server.Page.BrowserWindowResizeListener;
import com.vaadin.server.Resource;
import com.vaadin.ui.AbstractOrderedLayout;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.Button;
import com.vaadin.ui.Component;
import com.vaadin.ui.CssLayout;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.MenuBar;
import com.vaadin.ui.MenuBar.Command;
import com.vaadin.ui.MenuBar.MenuItem;
import com.vaadin.ui.PopupView;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.declarative.Design;
import com.vaadin.ui.themes.ValoTheme;
/**
* The workplace toolbar.
*/
public class CmsToolBar extends CssLayout implements BrowserWindowResizeListener {
/** Toolbar dialog context. */
protected class ToolbarContext extends A_CmsDialogContext {
/**
* Constructor.
*
* @param appId the app id
*/
protected ToolbarContext(String appId) {
super(appId, ContextType.appToolbar, Collections. emptyList());
}
/**
* @see org.opencms.ui.I_CmsDialogContext#focus(org.opencms.util.CmsUUID)
*/
public void focus(CmsUUID structureId) {
// nothing to do
}
/**
* @see org.opencms.ui.I_CmsDialogContext#getAllStructureIdsInView()
*/
public List getAllStructureIdsInView() {
return Lists.newArrayList();
}
/**
* @see org.opencms.ui.I_CmsDialogContext#updateUserInfo()
*/
public void updateUserInfo() {
refreshUserInfoDropDown();
}
}
/** Logger instance for this class. */
private static final Log LOG = CmsLog.getLog(CmsToolBar.class);
/** The serial version id. */
private static final long serialVersionUID = -4551194983054069395L;
/** The app indicator. */
private Label m_appIndicator;
/** Flag indicating the toolbar buttons are folded into a sub menu. */
private boolean m_buttonsFolded;
/** The context menu component. */
private MenuBar m_contextMenu;
/** The dialog context. */
private I_CmsDialogContext m_dialogContext;
/** The sub menu displaying the folded buttons. */
private PopupView m_foldedButtonsMenu;
/** The browser window width that is required to display all toolbar buttons. */
private int m_foldingThreshhold;
/** Toolbar items left. */
private HorizontalLayout m_itemsLeft;
/** Toolbar items right. */
private HorizontalLayout m_itemsRight;
/** The contains the buttons from the left side, displayed in the folded buttons sub menu. */
private VerticalLayout m_leftButtons;
/** The quick launch drop down. */
private Component m_quickLaunchDropDown;
/** The contains the buttons from the right side, displayed in the folded buttons sub menu. */
private VerticalLayout m_rightButtons;
/** The user drop down. */
private Component m_userDropDown;
/**
* Constructor.
*/
public CmsToolBar() {
m_quickLaunchDropDown = createQuickLaunchDropDown();
m_userDropDown = createUserInfoDropDown();
m_leftButtons = new VerticalLayout();
m_rightButtons = new VerticalLayout();
VerticalLayout layout = new VerticalLayout();
layout.addComponent(m_leftButtons);
layout.addComponent(m_rightButtons);
m_foldedButtonsMenu = new PopupView(getDropDownButtonHtml(FontOpenCms.CONTEXT_MENU_DOTS), layout);
m_foldedButtonsMenu.addStyleName(OpenCmsTheme.NAVIGATOR_DROPDOWN);
m_foldedButtonsMenu.setHideOnMouseOut(false);
Design.read("CmsToolBar.html", this);
}
/**
* Creates a properly styled toolbar button.
*
* @param icon the button icon
* @param title the button title, will be used for the tooltip
*
* @return the button
*/
public static Button createButton(Resource icon, String title) {
return createButton(icon, title, false);
}
/**
* Creates a properly styled toolbar button.
*
* @param icon the button icon
* @param title the button title, will be used for the tooltip
* @param alwaysShow true
to prevent the button to be folded into a sub menu for small screens
*
* @return the button
*/
public static Button createButton(Resource icon, String title, boolean alwaysShow) {
Button button = new Button(icon);
button.setDescription(title);
button.addStyleName(ValoTheme.BUTTON_BORDERLESS);
button.addStyleName(OpenCmsTheme.TOOLBAR_BUTTON);
if (alwaysShow) {
button.addStyleName(OpenCmsTheme.REQUIRED_BUTTON);
}
return button;
}
/**
* Creates a drop down menu.
*
* @param icon the button icon
* @param content the drop down content
* @param title the button title
*
* @return the component
*/
public static Component createDropDown(ExternalResource icon, Component content, String title) {
return createDropDown(getDropDownButtonHtml(icon), content, title);
}
/**
* Creates a drop down menu.
*
* @param icon the button icon
* @param content the drop down content
* @param title the drop down title
*
* @return the component
*/
public static Component createDropDown(FontIcon icon, Component content, String title) {
return createDropDown(getDropDownButtonHtml(icon), content, title);
}
/**
* Creates a drop down menu.
*
* @param buttonHtml the button HTML
* @param content the drop down content
* @param title the button title
*
* @return the component
*/
public static Component createDropDown(String buttonHtml, Component content, String title) {
PopupView pv = new PopupView(buttonHtml, content);
pv.setDescription(title);
pv.addStyleName(OpenCmsTheme.NAVIGATOR_DROPDOWN);
pv.setHideOnMouseOut(false);
return pv;
}
/**
* Creates the button HTML for the given icon resource.
*
* @param icon the icon
*
* @return the HTML
*/
static String getDropDownButtonHtml(ExternalResource icon) {
return "
";
}
/**
* Creates the button HTML for the given icon resource.
*
* @param icon the icon
*
* @return the HTML
*/
static String getDropDownButtonHtml(FontIcon icon) {
return "
";
}
/**
* Adds a button to left toolbar side.
*
* @param button the button
*/
public void addButtonLeft(Component button) {
if (m_buttonsFolded && !isAlwaysShow(button)) {
m_leftButtons.addComponent(button);
} else {
m_itemsLeft.addComponent(button);
}
updateFoldingThreshhold();
}
/**
* Adds a button to right toolbar side.
*
* @param button the button
*/
public void addButtonRight(Component button) {
if (m_buttonsFolded && !isAlwaysShow(button)) {
m_rightButtons.addComponent(button);
} else {
int dropDownIndex = m_itemsRight.getComponentIndex(m_userDropDown);
if (dropDownIndex >= 0) {
m_itemsRight.addComponent(button, dropDownIndex);
} else {
m_itemsRight.addComponent(button);
}
}
updateFoldingThreshhold();
}
/**
* @see com.vaadin.server.Page.BrowserWindowResizeListener#browserWindowResized(com.vaadin.server.Page.BrowserWindowResizeEvent)
*/
public void browserWindowResized(BrowserWindowResizeEvent event) {
updateButtonVisibility(event.getWidth());
}
/**
* Clears the left toolbar buttons.
*/
public void clearButtonsLeft() {
m_itemsLeft.removeAllComponents();
m_leftButtons.removeAllComponents();
// in case the app title is set, make sure to keep the label in the button bar
if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(m_appIndicator.getValue())) {
m_itemsLeft.addComponent(m_appIndicator);
}
updateFoldingThreshhold();
}
/**
* Clears the right toolbar buttons.
*/
public void clearButtonsRight() {
m_itemsRight.removeAllComponents();
m_rightButtons.removeAllComponents();
updateFoldingThreshhold();
}
/**
* Closes all visible popup views.
*/
public void closePopupViews() {
closePopupViews(m_itemsLeft);
closePopupViews(m_itemsRight);
}
/**
* Enables or removes the default toolbar buttons.
* These are the context menu and the quick launch drop down.
* The default is enabled = true
.
*
* @param enabled true
to enable the buttons
*/
public void enableDefaultButtons(boolean enabled) {
if (enabled) {
m_itemsRight.addComponent(m_contextMenu, 0);
m_itemsRight.addComponent(m_quickLaunchDropDown, 1);
} else {
m_itemsRight.removeComponent(m_contextMenu);
m_itemsRight.removeComponent(m_quickLaunchDropDown);
}
updateFoldingThreshhold();
}
/**
* Refreshes the user drop down.
*/
public void refreshUserInfoDropDown() {
Component oldVersion = m_userDropDown;
m_userDropDown = createUserInfoDropDown();
m_itemsRight.replaceComponent(oldVersion, m_userDropDown);
}
/**
* Removes the given button from the toolbar.
*
* @param button the button to remove
*/
public void removeButton(Component button) {
m_itemsLeft.removeComponent(button);
m_itemsRight.removeComponent(button);
m_leftButtons.removeComponent(button);
m_rightButtons.removeComponent(button);
updateFoldingThreshhold();
}
/**
* Sets the app title.
*
* @param appTitle the app title
*/
public void setAppTitle(String appTitle) {
if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(appTitle)) {
m_appIndicator.setValue(appTitle);
updateAppIndicator();
m_appIndicator.setVisible(true);
} else {
m_appIndicator.setVisible(false);
}
}
/**
* Updates the app indicator site and project info.
*/
public void updateAppIndicator() {
if (CmsAppWorkplaceUi.isOnlineProject()) {
m_appIndicator.addStyleName(OpenCmsTheme.TOOLABER_APP_INDICATOR_ONLINE);
} else {
m_appIndicator.removeStyleName(OpenCmsTheme.TOOLABER_APP_INDICATOR_ONLINE);
}
CmsObject cms = A_CmsUI.getCmsObject();
String siteRoot = cms.getRequestContext().getSiteRoot();
CmsSite site = OpenCms.getSiteManager().getSiteForSiteRoot(siteRoot);
String siteName = null;
if (site != null) {
siteName = site.getTitle();
} else {
try {
CmsResource folder = cms.readResource("/", CmsResourceFilter.ONLY_VISIBLE_NO_DELETED);
siteName = OpenCms.getSiteManager().getSiteTitle(cms, folder);
} catch (CmsException e) {
LOG.warn("Error reading site title.", e);
}
}
if (CmsStringUtil.isEmptyOrWhitespaceOnly(siteName)) {
siteName = siteRoot;
} else {
siteName = CmsWorkplace.substituteSiteTitleStatic(siteName, UI.getCurrent().getLocale());
}
m_appIndicator.setDescription(
CmsVaadinUtils.getMessageText(
Messages.GUI_TOOLBAR_PROJECT_SITE_INFO_2,
A_CmsUI.getCmsObject().getRequestContext().getCurrentProject().getName(),
siteName));
}
/**
* Initializes the toolbar.
*
* @param appId the app id
*/
protected void init(String appId) {
m_dialogContext = new ToolbarContext(appId);
initContextMenu();
m_itemsRight.addComponent(m_quickLaunchDropDown);
m_itemsRight.addComponent(m_userDropDown);
}
/**
* Sets the dialog context.
*
* @param context the dialog context
*/
protected void setDialogContext(I_CmsDialogContext context) {
m_dialogContext = context;
// reinit context menu
initContextMenu();
}
/**
* Updates the button visibility according o the given widow width.
*
* @param width the window width
*/
protected void updateButtonVisibility(int width) {
if (!m_buttonsFolded && (m_foldingThreshhold > width)) {
foldButtons();
} else if (m_buttonsFolded && (width > m_foldingThreshhold)) {
unfoldButtons();
}
}
/**
* Recalculates the space required by the toolbar buttons
*/
protected void updateFoldingThreshhold() {
int left = estimateRequiredWidth(m_itemsLeft) + estimateRequiredWidth(m_leftButtons);
int right = estimateRequiredWidth(m_itemsRight) + estimateRequiredWidth(m_rightButtons);
int requiredWidth = left > right ? left : right;
if (requiredWidth < 350) {
// folding not required at any width
m_foldingThreshhold = 0;
} else if (requiredWidth < 400) {
m_foldingThreshhold = 984;
} else if (requiredWidth <= 520) {
m_foldingThreshhold = 1240;
} else {
// always fold
m_foldingThreshhold = 10000;
}
updateButtonVisibility(Page.getCurrent().getBrowserWindowWidth());
}
/**
* Returns the dialog context.
*
* @return the dialog context
*/
I_CmsDialogContext getDialogContext() {
return m_dialogContext;
}
/**
* Handles the user image file upload.
*
* @param uploadedFiles the uploaded file names
*/
void handleUpload(List uploadedFiles) {
CmsObject cms = A_CmsUI.getCmsObject();
boolean success = OpenCms.getWorkplaceAppManager().getUserIconHelper().handleImageUpload(cms, uploadedFiles);
if (success) {
refreshUserInfoDropDown();
}
}
/**
* Closes the visible popup view children of the given layout.
*
* @param layout the layout
*/
private void closePopupViews(AbstractOrderedLayout layout) {
for (Component item : layout) {
if (item instanceof PopupView) {
((PopupView)item).setPopupVisible(false);
}
}
}
/**
* Creates the context menu entry and it's children.
*
* @param parent the entry parent
* @param node the item tree node
* @param treeBuilder the tree builder
*/
private void createMenuEntry(
MenuItem parent,
final CmsTreeNode node,
CmsContextMenuTreeBuilder treeBuilder) {
Command entryCommand = null;
if (node.getChildren().size() == 0) {
entryCommand = new Command() {
private static final long serialVersionUID = 1L;
public void menuSelected(MenuItem selectedItem) {
node.getData().executeAction(getDialogContext());
}
};
}
MenuItem entry = parent.addItem((node.getData().getTitle(A_CmsUI.get().getLocale())), entryCommand);
for (CmsTreeNode child : node.getChildren()) {
createMenuEntry(entry, child, treeBuilder);
}
if (treeBuilder.getVisibility(node.getData()).isInActive()) {
entry.setEnabled(false);
}
}
/**
* Creates the app select drop down.
*
* @return the drop down component
*/
private Component createQuickLaunchDropDown() {
PopupView pv = new PopupView(new PopupView.Content() {
private static final long serialVersionUID = 1L;
public String getMinimizedValueAsHTML() {
return getDropDownButtonHtml(FontOpenCms.APPS);
}
public Component getPopupComponent() {
CmsObject cms = A_CmsUI.getCmsObject();
Locale locale = UI.getCurrent().getLocale();
HorizontalLayout layout = new HorizontalLayout();
layout.addStyleName(ValoTheme.LAYOUT_HORIZONTAL_WRAPPING);
layout.addStyleName(OpenCmsTheme.QUICK_LAUNCH);
// layout.setSpacing(true);
layout.setMargin(true);
for (I_CmsWorkplaceAppConfiguration config : OpenCms.getWorkplaceAppManager().getQuickLaunchConfigurations(
cms)) {
layout.addComponent(CmsDefaultAppButtonProvider.createAppButton(cms, config, locale));
}
return layout;
}
});
pv.setDescription(CmsVaadinUtils.getMessageText(Messages.GUI_QUICK_LAUNCH_TITLE_0));
pv.addStyleName(OpenCmsTheme.NAVIGATOR_DROPDOWN);
pv.setHideOnMouseOut(false);
return pv;
}
/**
* Creates the user info drop down.
*
* @return the drop down component
*/
private Component createUserInfoDropDown() {
PopupView pv = new PopupView(new PopupView.Content() {
private static final long serialVersionUID = 1L;
public String getMinimizedValueAsHTML() {
CmsObject cms = A_CmsUI.getCmsObject();
return getDropDownButtonHtml(
new ExternalResource(
OpenCms.getWorkplaceAppManager().getUserIconHelper().getSmallIconPath(
cms,
cms.getRequestContext().getCurrentUser())));
}
public Component getPopupComponent() {
return new CmsUserInfo(new I_UploadListener() {
public void onUploadFinished(List uploadedFiles) {
handleUpload(uploadedFiles);
}
}, getDialogContext());
}
});
pv.setDescription(CmsVaadinUtils.getMessageText(Messages.GUI_USER_INFO_TITLE_0));
pv.addStyleName(OpenCmsTheme.NAVIGATOR_DROPDOWN);
pv.setHideOnMouseOut(false);
pv.addStyleName(OpenCmsTheme.USER_INFO);
return pv;
}
/**
* Calculates the width required by the layout components
*
* @param items the layout
*
* @return the width
*/
private int estimateRequiredWidth(AbstractOrderedLayout items) {
int result = 0;
if (items != null) {
for (Component comp : items) {
if (comp == m_foldedButtonsMenu) {
continue;
} else if ((comp instanceof Button) || (comp instanceof PopupView) || (comp instanceof MenuBar)) {
// assume all buttons have a with of 50px
result += 50;
} else if (comp == m_appIndicator) {
// assume app indicator requires 150px
result += 50;
} else {
float compWidth = comp.getWidth();
if ((compWidth > 0) && (comp.getWidthUnits() == Unit.PIXELS)) {
// also add 10px margin
result += compWidth + 10;
} else {
result += 200;
}
}
}
}
return result;
}
/**
* Folds the toolbar buttons into a sub menu.
*/
private void foldButtons() {
VerticalLayout mainPV = (VerticalLayout)m_foldedButtonsMenu.getContent().getPopupComponent();
for (int i = m_itemsLeft.getComponentCount() - 1; i > -1; i--) {
Component comp = m_itemsLeft.getComponent(i);
if (!isAlwaysShow(comp)) {
m_itemsLeft.removeComponent(comp);
m_leftButtons.addComponent(comp, 0);
m_leftButtons.setComponentAlignment(comp, Alignment.MIDDLE_CENTER);
}
}
if (m_leftButtons.getComponentCount() == 0) {
mainPV.removeComponent(m_leftButtons);
} else {
mainPV.addComponent(m_leftButtons, 0);
}
for (int i = m_itemsRight.getComponentCount() - 1; i > -1; i--) {
Component comp = m_itemsRight.getComponent(i);
if (!isAlwaysShow(comp)) {
m_itemsRight.removeComponent(comp);
m_rightButtons.addComponent(comp, 0);
m_rightButtons.setComponentAlignment(comp, Alignment.MIDDLE_CENTER);
}
}
if (m_rightButtons.getComponentCount() == 0) {
mainPV.removeComponent(m_rightButtons);
} else {
mainPV.addComponent(m_rightButtons);
}
m_itemsRight.addComponent(m_foldedButtonsMenu, 0);
m_buttonsFolded = true;
markAsDirtyRecursive();
}
/**
* Initializes the context menu entries.
*/
private void initContextMenu() {
m_contextMenu.removeItems();
MenuItem main = m_contextMenu.addItem("", null);
main.setIcon(FontOpenCms.CONTEXT_MENU);
main.setDescription(CmsVaadinUtils.getMessageText(Messages.GUI_MENU_TITLE_0));
CmsContextMenuTreeBuilder treeBuilder = new CmsContextMenuTreeBuilder(getDialogContext());
CmsTreeNode tree = treeBuilder.buildAll(
OpenCms.getWorkplaceAppManager().getMenuItemProvider().getMenuItems());
for (CmsTreeNode node : tree.getChildren()) {
createMenuEntry(main, node, treeBuilder);
}
}
/**
* Checks whether the given component may be placed into the buttons sub menu.
*
* @param comp the component to check
*
* @return true
in case the component should always be displayed in the toolbar
*/
private boolean isAlwaysShow(Component comp) {
return ((comp == m_appIndicator)
|| (comp == m_contextMenu)
|| (comp == m_userDropDown)
|| (comp == m_quickLaunchDropDown)
|| comp.getStyleName().contains(OpenCmsTheme.REQUIRED_BUTTON));
}
/**
* Places the buttons formerly moved to the sub menu back into the toolbar.
*/
private void unfoldButtons() {
m_itemsRight.removeComponent(m_foldedButtonsMenu);
while (m_leftButtons.getComponentCount() > 0) {
Component comp = m_leftButtons.getComponent(0);
if (!isAlwaysShow(comp)) {
m_leftButtons.removeComponent(comp);
m_itemsLeft.addComponent(comp);
}
}
int index = 0;
while (m_rightButtons.getComponentCount() > 0) {
Component comp = m_rightButtons.getComponent(0);
m_rightButtons.removeComponent(comp);
m_itemsRight.addComponent(comp, index);
index++;
}
m_buttonsFolded = false;
markAsDirtyRecursive();
}
}