/* * 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.CmsGalleriesTabHandler; import org.opencms.ade.galleries.client.Messages; import org.opencms.ade.galleries.shared.CmsGalleryFolderBean; import org.opencms.ade.galleries.shared.CmsGallerySearchBean; import org.opencms.ade.galleries.shared.CmsGalleryTreeEntry; import org.opencms.ade.galleries.shared.I_CmsGalleryProviderConstants.GalleryTabId; import org.opencms.ade.galleries.shared.I_CmsGalleryProviderConstants.SortParams; import org.opencms.gwt.client.ui.CmsListItem; import org.opencms.gwt.client.ui.CmsListItemWidget; import org.opencms.gwt.client.ui.CmsSimpleListItem; import org.opencms.gwt.client.ui.input.CmsCheckBox; import org.opencms.gwt.client.ui.tree.CmsTreeItem; import org.opencms.gwt.client.util.CmsScrollToBottomHandler; import org.opencms.gwt.shared.CmsIconUtil; import org.opencms.gwt.shared.CmsListInfoBean; import org.opencms.util.CmsPair; import org.opencms.util.CmsStringUtil; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import com.google.gwt.core.client.Scheduler; import com.google.gwt.core.client.Scheduler.RepeatingCommand; import com.google.gwt.user.client.ui.Label; /** * Provides the widget for the galleries(folder) tab.<p> * * It displays the available gallery folders in the given order. * * @since 8.0. */ public class CmsGalleriesTab extends A_CmsListTab { /** * A class which generates list items incrementally to fill the galleries tab.<p> */ protected class ListItemGenerator implements Iterator<CmsTreeItem> { /** The internal iterator over the gallery beans. */ protected Iterator<CmsGalleryFolderBean> m_beanIterator; /** * Creates a new instance.<p> * @param folders the list of folders for which to generate list items */ public ListItemGenerator(List<CmsGalleryFolderBean> folders) { if (folders == null) { folders = new ArrayList<CmsGalleryFolderBean>(); } m_beanIterator = folders.iterator(); } /** * @see java.util.Iterator#hasNext() */ public boolean hasNext() { return m_beanIterator.hasNext(); } /** * @see java.util.Iterator#next() */ public CmsTreeItem next() { CmsGalleryFolderBean gallery = m_beanIterator.next(); CmsTreeItem treeItem = createTreeItem(gallery, m_selectedGalleries, false); return treeItem; } /** * @see java.util.Iterator#remove() */ public void remove() { throw new UnsupportedOperationException(); } } /** * Command for adding more list items to the list of publish items.<p> */ protected class MoreItemsCommand implements RepeatingCommand { /** The number of items left to add. */ private int m_numItems; /** * Creates a new instance.<p> * * @param numItems the maximal number of items to add */ public MoreItemsCommand(int numItems) { m_numItems = numItems; } /** * @see com.google.gwt.core.client.Scheduler.RepeatingCommand#execute() */ public boolean execute() { if (m_numItems == 0) { setLoading(false); return false; } boolean hasMore = m_itemIterator.hasNext(); if (!hasMore) { setLoading(false); return false; } else { CmsTreeItem treeItem = m_itemIterator.next(); addWidgetToList(treeItem); } m_numItems -= 1; return true; } } /** * A class which generates tree items incrementally to fill the galleries tab.<p> */ protected class TreeItemGenerator implements Iterator<CmsTreeItem> { /** The internal iterator over the gallery beans. <p> */ protected Iterator<CmsGalleryTreeEntry> m_beanIterator; /** * Creates a new instance.<p> * * @param folders the folders from which to generate list items */ public TreeItemGenerator(List<CmsGalleryTreeEntry> folders) { if (folders == null) { folders = new ArrayList<CmsGalleryTreeEntry>(); } m_beanIterator = folders.iterator(); } /** * @see java.util.Iterator#hasNext() */ public boolean hasNext() { return m_beanIterator.hasNext(); } /** * @see java.util.Iterator#next() */ public CmsTreeItem next() { CmsGalleryTreeEntry gallery = m_beanIterator.next(); CmsTreeItem treeItem = createTreeItem(gallery, m_selectedGalleries, true); addChildren(treeItem, gallery.getChildren(), m_selectedGalleries); treeItem.setOpen(true); return treeItem; } /** * @see java.util.Iterator#remove() */ public void remove() { throw new UnsupportedOperationException(); } } /** * Handles the change of the item selection.<p> */ private class SelectionHandler extends A_SelectionHandler { /** The gallery path as id for the selected gallery. */ private String m_galleryPath; /** * Constructor.<p> * * @param gallerPath as id for the selected category * @param checkBox the reference to the checkbox */ public SelectionHandler(String gallerPath, CmsCheckBox checkBox) { super(checkBox); m_galleryPath = gallerPath; } /** * @see org.opencms.ade.galleries.client.ui.A_CmsListTab.A_SelectionHandler#onSelectionChange() */ @Override protected void onSelectionChange() { if (getCheckBox().isChecked()) { getTabHandler().onSelectGallery(m_galleryPath); } else { getTabHandler().onDeselectGallery(m_galleryPath); } } } /** The batch size for adding new elements to the tab.<p> */ protected static final int LOAD_BATCH_SIZE = 50; /** Text metrics key. */ private static final String TM_GALLERY_TAB = "GalleryTab"; /** An iterator which produces new list items which should be added to the tab.<p> */ protected Iterator<CmsTreeItem> m_itemIterator; /** List of selected galleries. */ protected List<String> m_selectedGalleries; /** Map of gallery folders by path. */ private Map<String, CmsGalleryFolderBean> m_galleries; /** Flag which indicates whether new elements are currently being inserted into the galleries tab.<p> */ private boolean m_loading; /** The search parameter panel for this tab. */ private CmsSearchParamPanel m_paramPanel; /** The tab handler. */ private CmsGalleriesTabHandler m_tabHandler; /** * Constructor.<p> * * @param tabHandler the tab handler */ public CmsGalleriesTab(CmsGalleriesTabHandler tabHandler) { super(GalleryTabId.cms_tab_galleries); m_scrollList.truncate(TM_GALLERY_TAB, CmsGalleryDialog.DIALOG_WIDTH); getList().addScrollHandler(new CmsScrollToBottomHandler(new Runnable() { public void run() { if (!isLoading()) { loadMoreItems(); } } })); m_tabHandler = tabHandler; m_galleries = new HashMap<String, CmsGalleryFolderBean>(); } /** * Fill the content of the galleries tab panel.<p> * * @param galleryInfos the gallery info beans * @param selectedGalleries the list of galleries to select */ public void fillContent(List<CmsGalleryFolderBean> galleryInfos, List<String> selectedGalleries) { m_selectedGalleries = selectedGalleries; if (!galleryInfos.isEmpty()) { for (CmsGalleryFolderBean galleryInfo : galleryInfos) { m_galleries.put(galleryInfo.getPath(), galleryInfo); } m_itemIterator = new ListItemGenerator(galleryInfos); loadMoreItems(); } else { showIsEmptyLabel(); } } /** * Returns the content of the galleries search parameter.<p> * * @param selectedGalleries the list of selected galleries by the user * * @return the selected galleries */ public String getGalleriesParams(List<String> selectedGalleries) { if ((selectedGalleries == null) || (selectedGalleries.size() == 0)) { return null; } StringBuffer result = new StringBuffer(128); for (String galleryPath : selectedGalleries) { CmsGalleryFolderBean galleryBean = m_galleries.get(galleryPath); if (galleryBean != null) { String title = galleryBean.getTitle(); if (CmsStringUtil.isEmptyOrWhitespaceOnly(title)) { title = galleryBean.getPath(); } result.append(title).append(", "); } } if (result.length() == 0) { return null; } result.delete(result.length() - 2, result.length()); return result.toString(); } /** * @see org.opencms.ade.galleries.client.ui.A_CmsTab#getParamPanel(org.opencms.ade.galleries.shared.CmsGallerySearchBean) */ @Override public CmsSearchParamPanel getParamPanel(CmsGallerySearchBean searchObj) { if (m_paramPanel == null) { m_paramPanel = new CmsSearchParamPanel(Messages.get().key(Messages.GUI_PARAMS_LABEL_GALLERIES_0), this); } String content = getGalleriesParams(searchObj.getGalleries()); if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(content)) { m_paramPanel.setContent(content); return m_paramPanel; } return null; } /** * Returns the value of the "loading" flag, which indicates whether new elements are currently being added into the galleries tab.<p> * * @return the "loading" flag */ public boolean isLoading() { return m_loading; } /** * Sets the "loading" flag.<p> * * @param loading the new value of the loading flag */ public void setLoading(boolean loading) { m_loading = loading; } /** * De-selects the galleries in the galleries list.<p> * * @param galleries the galleries to deselect */ public void uncheckGalleries(List<String> galleries) { for (String gallery : galleries) { CmsListItem item = searchTreeItem(m_scrollList, gallery); if (item != null) { item.getCheckBox().setChecked(false); } } } /** * Update the galleries list.<p> * * @param galleries the new gallery list * @param selectedGalleries the list of galleries to select */ public void updateListContent(List<CmsGalleryFolderBean> galleries, List<String> selectedGalleries) { clearList(); fillContent(galleries, selectedGalleries); } /** * Update the galleries tree.<p> * * @param galleryTreeEntries the new gallery tree list * @param selectedGalleries the list of galleries to select */ public void updateTreeContent(List<CmsGalleryTreeEntry> galleryTreeEntries, List<String> selectedGalleries) { clearList(); m_selectedGalleries = selectedGalleries; if (!galleryTreeEntries.isEmpty()) { m_itemIterator = new TreeItemGenerator(galleryTreeEntries); loadMoreItems(); } else { showIsEmptyLabel(); } } /** * Adds children to the gallery tree and select the galleries.<p> * * @param parent the parent item * @param children the list of children * @param selectedGalleries the list of galleries to select */ protected void addChildren(CmsTreeItem parent, List<CmsGalleryTreeEntry> children, List<String> selectedGalleries) { if (children != null) { for (CmsGalleryTreeEntry child : children) { // set the category tree item and add to parent tree item CmsTreeItem treeItem = createTreeItem(child, selectedGalleries, true); if ((selectedGalleries != null) && selectedGalleries.contains(child.getPath())) { parent.setOpen(true); openParents(parent); } parent.addChild(treeItem); addChildren(treeItem, child.getChildren(), selectedGalleries); } } } /** * Creates a tree item widget used in list and tree view of this tab.<p> * * @param galleryInfo the gallery folder bean * @param selectedGalleries the selected galleries * @param forTree <code>true</code> if the item is used within tree view * * @return the tree item */ protected CmsTreeItem createTreeItem( CmsGalleryFolderBean galleryInfo, List<String> selectedGalleries, boolean forTree) { CmsListItemWidget listItemWidget = new CmsListItemWidget(new CmsListInfoBean( galleryInfo.getTitle(), galleryInfo.getPath(), null)); listItemWidget.setIcon(CmsIconUtil.getResourceIconClasses(galleryInfo.getType(), false)); CmsCheckBox checkBox = new CmsCheckBox(); SelectionHandler selectionHandler = new SelectionHandler(galleryInfo.getPath(), checkBox); checkBox.addClickHandler(selectionHandler); listItemWidget.addDoubleClickHandler(selectionHandler); if ((selectedGalleries != null) && selectedGalleries.contains(galleryInfo.getPath())) { checkBox.setChecked(true); } if (galleryInfo.isEditable()) { listItemWidget.addButton(createUploadButtonForTarget(galleryInfo.getPath())); } CmsTreeItem treeItem = new CmsTreeItem(forTree, checkBox, listItemWidget); treeItem.setId(galleryInfo.getPath()); return treeItem; } /** * @see org.opencms.ade.galleries.client.ui.A_CmsListTab#getSortList() */ @Override protected List<CmsPair<String, String>> getSortList() { List<CmsPair<String, String>> list = new ArrayList<CmsPair<String, String>>(); list.add(new CmsPair<String, String>(SortParams.title_asc.name(), Messages.get().key( Messages.GUI_SORT_LABEL_TITLE_ASC_0))); list.add(new CmsPair<String, String>(SortParams.title_desc.name(), Messages.get().key( Messages.GUI_SORT_LABEL_TITLE_DECS_0))); list.add(new CmsPair<String, String>(SortParams.type_asc.name(), Messages.get().key( Messages.GUI_SORT_LABEL_TYPE_ASC_0))); list.add(new CmsPair<String, String>(SortParams.type_desc.name(), Messages.get().key( Messages.GUI_SORT_LABEL_TYPE_DESC_0))); list.add(new CmsPair<String, String>(SortParams.tree.name(), Messages.get().key( Messages.GUI_SORT_LABEL_HIERARCHIC_0))); return list; } /** * @see org.opencms.ade.galleries.client.ui.A_CmsListTab#getTabHandler() */ @Override protected CmsGalleriesTabHandler getTabHandler() { return m_tabHandler; } /** * @see org.opencms.ade.galleries.client.ui.A_CmsListTab#hasQuickFilter() */ @Override protected boolean hasQuickFilter() { // allow filter if not in tree mode return SortParams.tree != SortParams.valueOf(m_sortSelectBox.getFormValueAsString()); } /** * Adds more gallery list items to display in the tab, if available.<p> */ protected void loadMoreItems() { setLoading(true); MoreItemsCommand cmd = new MoreItemsCommand(30); Scheduler.get().scheduleFixedDelay(cmd, 1); } /** * Goes up the tree and opens the parents of the item.<p> * * @param item the child item to start from */ private void openParents(CmsTreeItem item) { if (item != null) { item.setOpen(true); openParents(item.getParentItem()); } } /** * Shows the tab list is empty label.<p> */ private void showIsEmptyLabel() { CmsSimpleListItem item = new CmsSimpleListItem(); Label isEmptyLabel = new Label(Messages.get().key(Messages.GUI_TAB_GALLERIES_IS_EMPTY_0)); item.add(isEmptyLabel); m_scrollList.add(item); } }