All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.opencms.ui.components.CmsFileTable Maven / Gradle / Ivy

/*
 * This library is part of OpenCms -
 * the Open Source Content Management System
 *
 * Copyright (C) Alkacon Software (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 static org.opencms.ui.components.CmsResourceTableProperty.PROPERTY_DATE_CREATED;
import static org.opencms.ui.components.CmsResourceTableProperty.PROPERTY_DATE_EXPIRED;
import static org.opencms.ui.components.CmsResourceTableProperty.PROPERTY_DATE_MODIFIED;
import static org.opencms.ui.components.CmsResourceTableProperty.PROPERTY_DATE_RELEASED;
import static org.opencms.ui.components.CmsResourceTableProperty.PROPERTY_INSIDE_PROJECT;
import static org.opencms.ui.components.CmsResourceTableProperty.PROPERTY_IS_FOLDER;
import static org.opencms.ui.components.CmsResourceTableProperty.PROPERTY_NAVIGATION_TEXT;
import static org.opencms.ui.components.CmsResourceTableProperty.PROPERTY_PERMISSIONS;
import static org.opencms.ui.components.CmsResourceTableProperty.PROPERTY_PROJECT;
import static org.opencms.ui.components.CmsResourceTableProperty.PROPERTY_RELEASED_NOT_EXPIRED;
import static org.opencms.ui.components.CmsResourceTableProperty.PROPERTY_RESOURCE_NAME;
import static org.opencms.ui.components.CmsResourceTableProperty.PROPERTY_RESOURCE_TYPE;
import static org.opencms.ui.components.CmsResourceTableProperty.PROPERTY_SIZE;
import static org.opencms.ui.components.CmsResourceTableProperty.PROPERTY_STATE;
import static org.opencms.ui.components.CmsResourceTableProperty.PROPERTY_STATE_NAME;
import static org.opencms.ui.components.CmsResourceTableProperty.PROPERTY_TITLE;
import static org.opencms.ui.components.CmsResourceTableProperty.PROPERTY_TYPE_ICON;
import static org.opencms.ui.components.CmsResourceTableProperty.PROPERTY_USER_CREATED;
import static org.opencms.ui.components.CmsResourceTableProperty.PROPERTY_USER_LOCKED;
import static org.opencms.ui.components.CmsResourceTableProperty.PROPERTY_USER_MODIFIED;

import org.opencms.db.CmsResourceState;
import org.opencms.file.CmsObject;
import org.opencms.file.CmsResource;
import org.opencms.file.CmsResourceFilter;
import org.opencms.file.CmsVfsResourceNotFoundException;
import org.opencms.main.CmsException;
import org.opencms.main.CmsLog;
import org.opencms.main.OpenCms;
import org.opencms.ui.A_CmsUI;
import org.opencms.ui.I_CmsContextMenuBuilder;
import org.opencms.ui.apps.CmsFileExplorerSettings;
import org.opencms.ui.components.contextmenu.CmsContextMenu;
import org.opencms.util.CmsStringUtil;
import org.opencms.util.CmsUUID;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import org.apache.commons.logging.Log;

import com.google.common.collect.Lists;
import com.vaadin.data.Container;
import com.vaadin.data.Item;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.Property.ValueChangeListener;
import com.vaadin.data.util.DefaultItemSorter;
import com.vaadin.data.util.filter.Or;
import com.vaadin.data.util.filter.SimpleStringFilter;
import com.vaadin.event.FieldEvents.BlurEvent;
import com.vaadin.event.FieldEvents.BlurListener;
import com.vaadin.event.ItemClickEvent;
import com.vaadin.event.ItemClickEvent.ItemClickListener;
import com.vaadin.event.ShortcutAction.KeyCode;
import com.vaadin.event.ShortcutListener;
import com.vaadin.ui.AbstractTextField.TextChangeEventMode;
import com.vaadin.ui.Component;
import com.vaadin.ui.DefaultFieldFactory;
import com.vaadin.ui.Field;
import com.vaadin.ui.Table;
import com.vaadin.ui.TextField;
import com.vaadin.ui.themes.ValoTheme;

/**
 * Table for displaying resources.

*/ public class CmsFileTable extends CmsResourceTable { /** * File edit handler.

*/ public class FileEditHandler implements BlurListener { /** The serial version id. */ private static final long serialVersionUID = -2286815522247807054L; /** * @see com.vaadin.event.FieldEvents.BlurListener#blur(com.vaadin.event.FieldEvents.BlurEvent) */ public void blur(BlurEvent event) { stopEdit(); } } /** * Field factory to enable inline editing of individual file properties.

*/ public class FileFieldFactory extends DefaultFieldFactory { /** The serial version id. */ private static final long serialVersionUID = 3079590603587933576L; /** * @see com.vaadin.ui.DefaultFieldFactory#createField(com.vaadin.data.Container, java.lang.Object, java.lang.Object, com.vaadin.ui.Component) */ @Override public Field createField(Container container, Object itemId, Object propertyId, Component uiContext) { Field result = null; if (itemId.equals(getEditItemId()) && isEditProperty((CmsResourceTableProperty)propertyId)) { result = super.createField(container, itemId, propertyId, uiContext); result.addStyleName(OpenCmsTheme.INLINE_TEXTFIELD); result.addValidator(m_editHandler); if (result instanceof TextField) { ((TextField)result).setComponentError(null); ((TextField)result).addShortcutListener(new ShortcutListener("Cancel edit", KeyCode.ESCAPE, null) { private static final long serialVersionUID = 1L; @Override public void handleAction(Object sender, Object target) { cancelEdit(); } }); ((TextField)result).addShortcutListener(new ShortcutListener("Save", KeyCode.ENTER, null) { private static final long serialVersionUID = 1L; @Override public void handleAction(Object sender, Object target) { stopEdit(); } }); ((TextField)result).addBlurListener(m_fileEditHandler); ((TextField)result).setTextChangeEventMode(TextChangeEventMode.LAZY); ((TextField)result).addTextChangeListener(m_editHandler); } result.focus(); } return result; } } /** * Extends the default sorting to differentiate between files and folder when sorting by name.

*/ public static class FileSorter extends DefaultItemSorter { /** The serial version id. */ private static final long serialVersionUID = 1L; /** * @see com.vaadin.data.util.DefaultItemSorter#compareProperty(java.lang.Object, boolean, com.vaadin.data.Item, com.vaadin.data.Item) */ @Override protected int compareProperty(Object propertyId, boolean sortDirection, Item item1, Item item2) { if (CmsResourceTableProperty.PROPERTY_RESOURCE_NAME.equals(propertyId)) { Boolean isFolder1 = (Boolean)item1.getItemProperty( CmsResourceTableProperty.PROPERTY_IS_FOLDER).getValue(); Boolean isFolder2 = (Boolean)item2.getItemProperty( CmsResourceTableProperty.PROPERTY_IS_FOLDER).getValue(); if (!isFolder1.equals(isFolder2)) { int result = isFolder1.booleanValue() ? -1 : 1; if (!sortDirection) { result = result * (-1); } return result; } } return super.compareProperty(propertyId, sortDirection, item1, item2); } } /** The logger instance for this class. */ private static final Log LOG = CmsLog.getLog(CmsFileTable.class); /** The serial version id. */ private static final long serialVersionUID = 5460048685141699277L; /** The selected resources. */ protected List m_currentResources = new ArrayList(); /** The current file property edit handler. */ I_CmsFilePropertyEditHandler m_editHandler; /** File edit event handler. */ FileEditHandler m_fileEditHandler = new FileEditHandler(); /** The context menu. */ CmsContextMenu m_menu; /** The context menu builder. */ I_CmsContextMenuBuilder m_menuBuilder; /** The edited item id. */ private CmsUUID m_editItemId; /** The edited property id. */ private CmsResourceTableProperty m_editProperty; /** The original edit value. */ private String m_originalEditValue; /** * Default constructor.

*/ public CmsFileTable() { super(); m_container.setItemSorter(new FileSorter()); m_fileTable.addStyleName(ValoTheme.TABLE_BORDERLESS); m_fileTable.addStyleName(OpenCmsTheme.SIMPLE_DRAG); m_fileTable.setSizeFull(); m_fileTable.setColumnCollapsingAllowed(true); m_fileTable.setSelectable(true); m_fileTable.setMultiSelect(true); m_fileTable.setTableFieldFactory(new FileFieldFactory()); new ColumnBuilder() { { column(PROPERTY_TYPE_ICON); column(PROPERTY_PROJECT, COLLAPSED); column(PROPERTY_RESOURCE_NAME); column(PROPERTY_TITLE); column(PROPERTY_NAVIGATION_TEXT, COLLAPSED); column(PROPERTY_RESOURCE_TYPE); column(PROPERTY_SIZE); column(PROPERTY_PERMISSIONS, COLLAPSED); column(PROPERTY_DATE_MODIFIED); column(PROPERTY_USER_MODIFIED, COLLAPSED); column(PROPERTY_DATE_CREATED, COLLAPSED); column(PROPERTY_USER_CREATED, COLLAPSED); column(PROPERTY_DATE_RELEASED); column(PROPERTY_DATE_EXPIRED); column(PROPERTY_STATE_NAME); column(PROPERTY_USER_LOCKED); column(PROPERTY_IS_FOLDER, INVISIBLE); column(PROPERTY_STATE, INVISIBLE); column(PROPERTY_INSIDE_PROJECT, INVISIBLE); column(PROPERTY_RELEASED_NOT_EXPIRED, INVISIBLE); } }.buildColumns(); m_fileTable.setSortContainerPropertyId(CmsResourceTableProperty.PROPERTY_RESOURCE_NAME); m_menu = new CmsContextMenu(); m_fileTable.addValueChangeListener(new ValueChangeListener() { private static final long serialVersionUID = 1L; @SuppressWarnings("synthetic-access") public void valueChange(ValueChangeEvent event) { @SuppressWarnings("unchecked") Set selectedIds = (Set)event.getProperty().getValue(); List selectedResources = new ArrayList(); for (CmsUUID id : selectedIds) { try { CmsResource resource = A_CmsUI.getCmsObject().readResource(id, CmsResourceFilter.ALL); selectedResources.add(resource); } catch (CmsException e) { LOG.error(e.getLocalizedMessage(), e); } } m_currentResources = selectedResources; if (!selectedIds.isEmpty() && (m_menuBuilder != null)) { m_menu.removeAllItems(); m_menuBuilder.buildContextMenu(selectedResources, m_menu); } } }); m_fileTable.setCellStyleGenerator(new Table.CellStyleGenerator() { private static final long serialVersionUID = 1L; public String getStyle(Table source, Object itemId, Object propertyId) { return getStateStyle(m_container.getItem(itemId)) + (CmsResourceTableProperty.PROPERTY_RESOURCE_NAME == propertyId ? " " + OpenCmsTheme.HOVER_COLUMN : ""); } }); m_menu.setAsTableContextMenu(m_fileTable); } /** * Returns the resource state specific style name.

* * @param resourceItem the resource item * * @return the style name */ public static String getStateStyle(Item resourceItem) { String result = ""; if (resourceItem != null) { if ((resourceItem.getItemProperty(PROPERTY_INSIDE_PROJECT).getValue() == null) || ((Boolean)resourceItem.getItemProperty(PROPERTY_INSIDE_PROJECT).getValue()).booleanValue()) { CmsResourceState state = (CmsResourceState)resourceItem.getItemProperty( CmsResourceTableProperty.PROPERTY_STATE).getValue(); result = getStateStyle(state); } else { result = OpenCmsTheme.PROJECT_OTHER; } if ((resourceItem.getItemProperty(PROPERTY_RELEASED_NOT_EXPIRED).getValue() != null) && !((Boolean)resourceItem.getItemProperty(PROPERTY_RELEASED_NOT_EXPIRED).getValue()).booleanValue()) { result += " " + OpenCmsTheme.EXPIRED; } if ((resourceItem.getItemProperty(CmsResourceTableProperty.PROPERTY_DISABLED).getValue() != null) && ((Boolean)resourceItem.getItemProperty( CmsResourceTableProperty.PROPERTY_DISABLED).getValue()).booleanValue()) { result += " " + OpenCmsTheme.DISABLED; } } return result; } /** * Adds an item click listener to the table.

* * @param listener the listener */ public void addItemClickListener(ItemClickListener listener) { m_fileTable.addItemClickListener(listener); } /** * Filters the displayed resources.

* Only resources where either the resource name, the title or the nav-text contains the given substring are shown.

* * @param search the search term */ public void filterTable(String search) { m_container.removeAllContainerFilters(); if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(search)) { m_container.addContainerFilter( new Or( new SimpleStringFilter(CmsResourceTableProperty.PROPERTY_RESOURCE_NAME, search, true, false), new SimpleStringFilter(CmsResourceTableProperty.PROPERTY_NAVIGATION_TEXT, search, true, false), new SimpleStringFilter(CmsResourceTableProperty.PROPERTY_TITLE, search, true, false))); } } /** * Returns the index of the first visible item.

* * @return the first visible item */ public int getFirstVisibleItemIndex() { return m_fileTable.getCurrentPageFirstItemIndex(); } /** * Gets the selected structure ids.

* * @return the set of selected structure ids */ @SuppressWarnings("unchecked") public Set getSelectedIds() { return (Set)m_fileTable.getValue(); } /** * Gets the list of selected resources.

* * @return the list of selected resources */ public List getSelectedResources() { return m_currentResources; } /** * Returns the current table state.

* * @return the table state */ public CmsFileExplorerSettings getTableSettings() { CmsFileExplorerSettings fileTableState = new CmsFileExplorerSettings(); fileTableState.setSortAscending(m_fileTable.isSortAscending()); fileTableState.setSortColumnId((CmsResourceTableProperty)m_fileTable.getSortContainerPropertyId()); List collapsedCollumns = new ArrayList(); Object[] visibleCols = m_fileTable.getVisibleColumns(); for (int i = 0; i < visibleCols.length; i++) { if (m_fileTable.isColumnCollapsed(visibleCols[i])) { collapsedCollumns.add((CmsResourceTableProperty)visibleCols[i]); } } fileTableState.setCollapsedColumns(collapsedCollumns); return fileTableState; } /** * Handles the item selection.

* * @param itemId the selected item id */ public void handleSelection(CmsUUID itemId) { Set selection = getSelectedIds(); if (selection == null) { m_fileTable.select(itemId); } else if (!selection.contains(itemId)) { m_fileTable.setValue(null); m_fileTable.select(itemId); } } /** * Returns if a file property is being edited.

* @return true if a file property is being edited */ public boolean isEditing() { return m_editItemId != null; } /** * Returns if the given property is being edited.

* * @param propertyId the property id * * @return true if the given property is being edited */ public boolean isEditProperty(CmsResourceTableProperty propertyId) { return (m_editProperty != null) && m_editProperty.equals(propertyId); } /** * Opens the context menu.

* * @param event the click event */ public void openContextMenu(ItemClickEvent event) { m_menu.openForTable(event, m_fileTable); } /** * Sets the first visible item index.

* * @param i the item index */ public void setFirstVisibleItemIndex(int i) { m_fileTable.setCurrentPageFirstItemIndex(i); } /** * Sets the menu builder.

* * @param builder the menu builder */ public void setMenuBuilder(I_CmsContextMenuBuilder builder) { m_menuBuilder = builder; } /** * Sets the table state.

* * @param state the table state */ public void setTableState(CmsFileExplorerSettings state) { if (state != null) { m_fileTable.setSortContainerPropertyId(state.getSortColumnId()); m_fileTable.setSortAscending(state.isSortAscending()); Object[] visibleCols = m_fileTable.getVisibleColumns(); for (int i = 0; i < visibleCols.length; i++) { m_fileTable.setColumnCollapsed(visibleCols[i], state.getCollapsedColumns().contains(visibleCols[i])); } } } /** * Starts inline editing of the given file property.

* * @param itemId the item resource structure id * @param propertyId the property to edit * @param editHandler the edit handler */ public void startEdit( CmsUUID itemId, CmsResourceTableProperty propertyId, I_CmsFilePropertyEditHandler editHandler) { m_editItemId = itemId; m_editProperty = propertyId; m_originalEditValue = (String)m_container.getItem(m_editItemId).getItemProperty(m_editProperty).getValue(); m_editHandler = editHandler; m_fileTable.setEditable(true); } /** * Stops the current edit process to save the changed property value.

*/ public void stopEdit() { if (m_editHandler != null) { String value = (String)m_container.getItem(m_editItemId).getItemProperty(m_editProperty).getValue(); if (!value.equals(m_originalEditValue)) { m_editHandler.validate(value); m_editHandler.save(value); } else { // call cancel to ensure unlock m_editHandler.cancel(); } } clearEdit(); } /** * Updates all items with ids from the given list.

* * @param id the resource structure id to update * @param remove true if the item should be removed only */ public void update(CmsUUID id, boolean remove) { updateItem(id, remove); } /** * Updates the column widths.

* * The reason this is needed is that the Vaadin table does not support minimum widths for columns, * so expanding columns get squished when most of the horizontal space is used by other columns. * So we try to determine whether the expanded columns would have enough space, and if not, give them a * fixed width. * * @param estimatedSpace the estimated horizontal space available for the table. */ public void updateColumnWidths(int estimatedSpace) { Object[] cols = m_fileTable.getVisibleColumns(); List expandCols = Lists.newArrayList(); int nonExpandWidth = 0; int totalExpandMinWidth = 0; for (Object colObj : cols) { if (m_fileTable.isColumnCollapsed(colObj)) { continue; } CmsResourceTableProperty prop = (CmsResourceTableProperty)colObj; if (0 < m_fileTable.getColumnExpandRatio(prop)) { expandCols.add(prop); totalExpandMinWidth += getAlternativeWidthForExpandingColumns(prop); } else { nonExpandWidth += prop.getColumnWidth(); } } if (estimatedSpace < (totalExpandMinWidth + nonExpandWidth)) { for (CmsResourceTableProperty expandCol : expandCols) { m_fileTable.setColumnWidth(expandCol, getAlternativeWidthForExpandingColumns(expandCol)); } } } /** * Updates the file table sorting.

*/ public void updateSorting() { m_fileTable.sort(); } /** * Cancels the current edit process.

*/ void cancelEdit() { if (m_editHandler != null) { m_editHandler.cancel(); } clearEdit(); } /** * Returns the edit item id.

* * @return the edit item id */ CmsUUID getEditItemId() { return m_editItemId; } /** * Returns the edit property id.

* * @return the edit property id */ CmsResourceTableProperty getEditProperty() { return m_editProperty; } /** * Clears the current edit process.

*/ private void clearEdit() { m_fileTable.setEditable(false); if (m_editItemId != null) { updateItem(m_editItemId, false); } m_editItemId = null; m_editProperty = null; m_editHandler = null; updateSorting(); } /** * Gets alternative width for expanding table columns which is used when there is not enough space for * all visible columns.

* * @param prop the table property * @return the alternative column width */ private int getAlternativeWidthForExpandingColumns(CmsResourceTableProperty prop) { if (prop.getId().equals(CmsResourceTableProperty.PROPERTY_RESOURCE_NAME.getId())) { return 200; } if (prop.getId().equals(CmsResourceTableProperty.PROPERTY_TITLE.getId())) { return 300; } if (prop.getId().equals(CmsResourceTableProperty.PROPERTY_NAVIGATION_TEXT.getId())) { return 200; } return 200; } /** * Updates the given item in the file table.

* * @param itemId the item id * @param remove true if the item should be removed only */ private void updateItem(CmsUUID itemId, boolean remove) { if (remove) { m_container.removeItem(itemId); return; } CmsObject cms = A_CmsUI.getCmsObject(); try { CmsResource resource = cms.readResource(itemId, CmsResourceFilter.ALL); fillItem(cms, resource, OpenCms.getWorkplaceManager().getWorkplaceLocale(cms)); } catch (CmsVfsResourceNotFoundException e) { m_container.removeItem(itemId); LOG.debug("Failed to update file table item, removing it from view.", e); } catch (CmsException e) { LOG.error(e.getLocalizedMessage(), e); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy