/* * This library is part of OpenCms - * the Open Source Content Management System * * Copyright (c) Alkacon Software GmbH (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.ade.galleries.client.ui; import org.opencms.ade.galleries.client.Messages; import org.opencms.ade.galleries.client.ui.css.I_CmsLayoutBundle; import org.opencms.ade.galleries.client.ui.css.I_CmsLayoutBundle.I_CmsGalleryDialogCss; import org.opencms.ade.galleries.shared.I_CmsGalleryProviderConstants.GalleryTabId; import org.opencms.ade.upload.client.ui.CmsUploadButton; import org.opencms.gwt.client.ui.CmsList; import org.opencms.gwt.client.ui.I_CmsButton.ButtonStyle; import org.opencms.gwt.client.ui.I_CmsListItem; import org.opencms.gwt.client.ui.css.I_CmsImageBundle; import org.opencms.gwt.client.ui.input.CmsCheckBox; import org.opencms.gwt.client.ui.input.CmsSelectBox; import org.opencms.gwt.client.ui.input.CmsTextBox; import org.opencms.gwt.client.ui.tree.CmsTreeItem; import org.opencms.util.CmsPair; import org.opencms.util.CmsStringUtil; import java.util.List; import com.google.gwt.core.client.GWT; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.event.dom.client.DoubleClickEvent; import com.google.gwt.event.dom.client.DoubleClickHandler; import com.google.gwt.event.logical.shared.ValueChangeEvent; import com.google.gwt.event.logical.shared.ValueChangeHandler; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.Timer; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.HasText; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.ScrollPanel; import com.google.gwt.user.client.ui.Widget; /** * Provides a widget for the content of a tab.<p> * * @since 8.0. */ public abstract class A_CmsListTab extends A_CmsTab implements ValueChangeHandler<String> { /** Selection handler to handle check box click events and double clicks on the list items. */ protected abstract class A_SelectionHandler implements ClickHandler, DoubleClickHandler { /** The reference to the checkbox. */ private CmsCheckBox m_checkBox; /** * Constructor.<p> * * @param checkBox the item check box */ protected A_SelectionHandler(CmsCheckBox checkBox) { m_checkBox = checkBox; } /** * @see com.google.gwt.event.dom.client.ClickHandler#onClick(com.google.gwt.event.dom.client.ClickEvent) */ public void onClick(ClickEvent event) { onSelectionChange(); } /** * @see com.google.gwt.event.dom.client.DoubleClickHandler#onDoubleClick(com.google.gwt.event.dom.client.DoubleClickEvent) */ public void onDoubleClick(DoubleClickEvent event) { m_checkBox.setChecked(true); onSelectionChange(); getTabHandler().selectResultTab(); event.stopPropagation(); event.preventDefault(); } /** * Returns the check box.<p> * * @return the check box */ protected CmsCheckBox getCheckBox() { return m_checkBox; } /** * Executed on selection change. Either when the check box was clicked or on double click on a list item.<p> */ protected abstract void onSelectionChange(); } /** * @see com.google.gwt.uibinder.client.UiBinder */ interface I_CmsListTabUiBinder extends UiBinder<Widget, A_CmsListTab> { // GWT interface, nothing to do here } /** The css bundle used for this widget. */ protected static final I_CmsGalleryDialogCss DIALOG_CSS = I_CmsLayoutBundle.INSTANCE.galleryDialogCss(); /** The filtering delay. */ private static final int FILTER_DELAY = 200; /** Text metrics key. */ private static final String TM_GALLERY_SORT = "gallerySort"; /** The ui-binder instance for this class. */ private static I_CmsListTabUiBinder uiBinder = GWT.create(I_CmsListTabUiBinder.class); /** A label for displaying additional information about the tab. */ protected HasText m_infoLabel; /** The borded panel to hold the scrollable list. */ @UiField protected ScrollPanel m_list; /** The option panel. */ @UiField protected FlowPanel m_options; /** The Quick filter text box. */ protected CmsTextBox m_quickFilter; /** The scrollable list panel. */ protected CmsList<? extends I_CmsListItem> m_scrollList; /** The select box to change the sort order. */ protected CmsSelectBox m_sortSelectBox; /** The option panel. */ @UiField protected FlowPanel m_tab; /** The quick filter timer. */ private Timer m_filterTimer; /** * The default constructor with drag handler.<p> * * @param tabId the tab id */ public A_CmsListTab(GalleryTabId tabId) { this(tabId.name()); } /** * Sets up a list tab with a given tab id.<p> * * @param tabId the tab id */ public A_CmsListTab(String tabId) { super(tabId); uiBinder.createAndBindUi(this); initWidget(uiBinder.createAndBindUi(this)); List<CmsPair<String, String>> sortList = getSortList(); if (sortList != null) { m_sortSelectBox = new CmsSelectBox(sortList); m_sortSelectBox.addValueChangeHandler(this); m_sortSelectBox.addStyleName(DIALOG_CSS.selectboxWidth()); m_sortSelectBox.truncate(TM_GALLERY_SORT, 200); m_options.add(m_sortSelectBox); Label infoLabel = new Label(); infoLabel.setStyleName(DIALOG_CSS.infoLabel()); m_infoLabel = infoLabel; m_options.insert(infoLabel, 0); m_quickFilter = new CmsTextBox(); m_quickFilter.setVisible(hasQuickFilter()); m_quickFilter.addValueChangeHandler(this); m_quickFilter.addStyleName(DIALOG_CSS.quickFilterBox()); m_quickFilter.setTriggerChangeOnKeyPress(true); m_quickFilter.setGhostValue(Messages.get().key(Messages.GUI_QUICK_FINDER_SEARCH_0), true); m_quickFilter.setGhostModeClear(true); m_options.insert(m_quickFilter, 0); } m_filterTimer = new Timer() { @Override public void run() { getTabHandler().onSort(m_sortSelectBox.getFormValueAsString(), m_quickFilter.getFormValueAsString()); } }; m_scrollList = createScrollList(); m_list.add(m_scrollList); } /** * Returns the list.<p> * * @return the list */ public ScrollPanel getList() { return m_list; } /** * Will be triggered if the value in the select box changes.<p> * * @see com.google.gwt.event.logical.shared.ValueChangeHandler#onValueChange(com.google.gwt.event.logical.shared.ValueChangeEvent) */ public void onValueChange(ValueChangeEvent<String> event) { cancelQuickFilterTimer(); if (event.getSource() == m_sortSelectBox) { getTabHandler().onSort(event.getValue(), hasQuickFilter() ? m_quickFilter.getFormValueAsString() : null); } if ((event.getSource() == m_quickFilter) && (CmsStringUtil.isEmptyOrWhitespaceOnly(event.getValue()) || (event.getValue().length() >= 3))) { // only act if filter length is at least 3 characters or empty scheduleQuickFilterTimer(); } m_quickFilter.setVisible(hasQuickFilter()); } /** * Adds a widget to the front of the list.<p> * * @param listItem the list item to add */ protected void addWidgetToFrontOfList(Widget listItem) { m_scrollList.insert(listItem, 0); } /** * Add a list item widget to the list panel.<p> * * @param listItem the list item to add */ protected void addWidgetToList(Widget listItem) { m_scrollList.add(listItem); } /** * Add a widget to the option panel.<p> * * The option panel should contain drop down boxes or other list options. * * @param widget the widget to add */ protected void addWidgetToOptions(Widget widget) { m_options.add(widget); } /** * Cancels the quick filter timer.<p> */ protected void cancelQuickFilterTimer() { m_filterTimer.cancel(); } /** * Clears the list panel.<p> */ protected void clearList() { m_scrollList.clearList(); } /** * Creates the list which should contain the list items of the tab.<p> * * @return the newly created list widget */ protected CmsList<? extends I_CmsListItem> createScrollList() { return new CmsList<I_CmsListItem>(); } /** * Creates an upload button for the given target.<p> * * @param target the upload target folder * * @return the upload button */ protected CmsUploadButton createUploadButtonForTarget(String target) { CmsUploadButton uploadButton = new CmsUploadButton(); uploadButton.setTargetFolder(target); uploadButton.setText(null); uploadButton.setTitle(Messages.get().key(Messages.GUI_GALLERY_UPLOAD_TITLE_1, target)); uploadButton.setButtonStyle(ButtonStyle.TRANSPARENT, null); uploadButton.setImageClass(I_CmsImageBundle.INSTANCE.style().uploadIcon()); uploadButton.setDialogCloseHandler(getTabHandler()); return uploadButton; } /** * Returns a list with sort values for this tab.<p> * * @return list of sort order value/text pairs */ protected abstract List<CmsPair<String, String>> getSortList(); /** * Returns if this tab has quick filter enabled.<p> * * @return <code>true</code> if this tab has quick filter enabled */ protected abstract boolean hasQuickFilter(); /** * Schedules the quick filter action.<p> */ protected void scheduleQuickFilterTimer() { m_filterTimer.schedule(FILTER_DELAY); } /** * Searches in the categories tree or list the item and returns it.<p> * * @param list the list of items to start from * @param categoryPath the category id to search * @return the category item widget */ protected CmsTreeItem searchTreeItem(CmsList<? extends I_CmsListItem> list, String categoryPath) { CmsTreeItem resultItem = (CmsTreeItem)list.getItem(categoryPath); // item is not in this tree level if (resultItem == null) { // if list is not empty for (int i = 0; i < list.getWidgetCount(); i++) { CmsTreeItem listItem = (CmsTreeItem)list.getWidget(i); if (listItem.getChildCount() == 0) { continue; } // continue search in children resultItem = searchTreeItem(listItem.getChildren(), categoryPath); // break the search if result item is found if (resultItem != null) { break; } } } return resultItem; } }