From 419d8288c74c66dafe659bad335ef2672bc83855 Mon Sep 17 00:00:00 2001 From: jensp Date: Thu, 30 Mar 2017 10:44:53 +0000 Subject: [PATCH] CCM NG/ccm-cms: Next part of AssetPane git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@4654 8810af33-2d31-482b-a856-94f89814c4df --- .../cms/ui/assets/AssetFolderBrowser.java | 338 ++++++++++++++++-- .../assets/AssetFolderBrowserController.java | 153 ++++++-- ...etFolderBrowserPaginationModelBuilder.java | 65 ++++ .../assets/AssetFolderBrowserTableModel.java | 15 +- .../arsdigita/cms/ui/assets/AssetPane.java | 116 +++--- .../FolderBrowserPaginationModelBuilder.java | 10 +- .../org/librecms/CmsResources.properties | 1 + .../org/librecms/CmsResources_de.properties | 1 + .../org/librecms/CmsResources_fr.properties | 1 + .../bebop/ParameterSingleSelectionModel.java | 13 +- 10 files changed, 592 insertions(+), 121 deletions(-) create mode 100644 ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/AssetFolderBrowserPaginationModelBuilder.java diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/AssetFolderBrowser.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/AssetFolderBrowser.java index 4290562f8..d5d1079f2 100644 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/AssetFolderBrowser.java +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/AssetFolderBrowser.java @@ -18,18 +18,38 @@ */ package com.arsdigita.cms.ui.assets; +import com.arsdigita.bebop.Component; +import com.arsdigita.bebop.ControlLink; +import com.arsdigita.bebop.Image; +import com.arsdigita.bebop.Label; +import com.arsdigita.bebop.Link; +import com.arsdigita.bebop.Page; import com.arsdigita.bebop.PageState; import com.arsdigita.bebop.Paginator; +import com.arsdigita.bebop.SimpleContainer; import com.arsdigita.bebop.Table; +import com.arsdigita.bebop.Text; +import com.arsdigita.bebop.event.TableActionAdapter; +import com.arsdigita.bebop.event.TableActionEvent; import com.arsdigita.bebop.event.TableActionListener; import com.arsdigita.bebop.parameters.StringParameter; +import com.arsdigita.bebop.table.DefaultTableCellRenderer; import com.arsdigita.bebop.table.DefaultTableColumnModel; +import com.arsdigita.bebop.table.TableCellRenderer; import com.arsdigita.bebop.table.TableColumn; +import com.arsdigita.cms.CMS; +import com.arsdigita.cms.ui.folder.FolderBrowser; import com.arsdigita.cms.ui.folder.FolderSelectionModel; import com.arsdigita.globalization.GlobalizedMessage; +import java.util.Date; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.libreccm.cdi.utils.CdiUtil; -import javafx.scene.control.Pagination; import org.librecms.CmsConstants; +import org.librecms.contentsection.ContentSection; +import org.librecms.contentsection.ContentSectionManager; +import org.librecms.dispatcher.ItemResolver; /** * Browse folder and assets. @@ -48,13 +68,13 @@ public class AssetFolderBrowser extends Table { private final FolderSelectionModel folderSelectionModel; private TableActionListener folderChanger; - private TableActionListener tableDeleter; + private TableActionListener folderDeleter; private TableColumn nameColumn; private TableColumn deleteColumn; private final StringParameter sortTypeParameter = new StringParameter( - "sortType"); + "sortType"); private final StringParameter sortDirectionParameter = new StringParameter( - "sortDir"); + "sortDir"); private Paginator paginator; private long folderSize; @@ -69,22 +89,6 @@ public class AssetFolderBrowser extends Table { initComponents(); } - protected FolderSelectionModel getFolderSelectionModel() { - return folderSelectionModel; - } - - protected Paginator getPaginator() { - return paginator; - } - - protected String getSortType(final PageState state) { - return (String) state.getValue(sortTypeParameter); - } - - protected String getSortDirection(final PageState state) { - return (String) state.getValue(sortDirectionParameter); - } - private void initComponents() { setModelBuilder(new AssetFolderBrowserTableModelBuilder()); @@ -96,6 +100,71 @@ public class AssetFolderBrowser extends Table { globalize("cms.ui.folder.creation_date"), globalize("cms.ui.folder.last_modified"), globalize("cms.ui.folder.action")}; + + setModelBuilder(new AssetFolderBrowserTableModelBuilder()); + setColumnModel(new DefaultTableColumnModel(headers)); + setClassAttr("dataTable"); + + getHeader().setDefaultRenderer(new DefaultTableCellRenderer()); + + nameColumn = getColumn(AssetFolderBrowserTableModel.COL_NAME); + nameColumn.setCellRenderer(new NameCellRenderer()); + nameColumn.setHeaderRenderer(new HeaderCellRenderer(SORT_KEY_NAME)); + + getColumn(AssetFolderBrowserTableModel.COL_CREATION_DATE) + .setHeaderRenderer( + new HeaderCellRenderer(SORT_KEY_CREATION_DATE)); + getColumn(AssetFolderBrowserTableModel.COL_CREATION_DATE) + .setCellRenderer(new DateCellRenderer()); + + getColumn(AssetFolderBrowserTableModel.COL_LAST_MODIFIED) + .setHeaderRenderer(new HeaderCellRenderer( + SORT_KEY_LAST_MODIFIED_DATE)); + getColumn(AssetFolderBrowserTableModel.COL_LAST_MODIFIED) + .setCellRenderer(new DateCellRenderer()); + + deleteColumn = getColumn(AssetFolderBrowserTableModel.COL_ACTION); + deleteColumn.setCellRenderer(new ActionCellRenderer()); + deleteColumn.setAlign("center"); + + folderChanger = new FolderChanger(); + addTableActionListener(folderChanger); + + folderDeleter = new ItemDeleter(); + addTableActionListener(folderDeleter); + + setEmptyView(new Label(globalize("cms.ui.folder.no_assets"))); + } + + @Override + public void register(final Page page) { + + super.register(page); + + page.addComponentStateParam(this, folderSelectionModel. + getStateParameter()); + page.addComponentStateParam(this, sortTypeParameter); + page.addComponentStateParam(this, sortDirectionParameter); + } + + protected FolderSelectionModel getFolderSelectionModel() { + return folderSelectionModel; + } + + protected Paginator getPaginator() { + return paginator; + } + + protected void setPaginator(final Paginator paginator) { + this.paginator = paginator; + } + + protected String getSortType(final PageState state) { + return (String) state.getValue(sortTypeParameter); + } + + protected String getSortDirection(final PageState state) { + return (String) state.getValue(sortDirectionParameter); } /** @@ -108,4 +177,233 @@ public class AssetFolderBrowser extends Table { } + private class HeaderCellRenderer extends DefaultTableCellRenderer { + + private final String headerKey; + + public HeaderCellRenderer(final String headerKey) { + super(true); + this.headerKey = headerKey; + } + + @Override + public Component getComponent(final Table table, + final PageState state, + final Object value, + final boolean isSelected, + final Object key, + final int row, + final int column) { + + final GlobalizedMessage headerName = (GlobalizedMessage) value; + final String sortKey = (String) state.getValue(sortTypeParameter); + final boolean isCurrentKey = sortKey.equals(key); + final String currentSortDirection = (String) state + .getValue(sortDirectionParameter); + final String imageUrlStub; + + if (SORT_ACTION_UP.equals(currentSortDirection)) { + imageUrlStub = "gray-triangle-up.gif"; + } else { + imageUrlStub = "gray-triangle-down.gif"; + } + + final ControlLink link = new ControlLink(new Label(headerName)) { + + @Override + public void setControlEvent(final PageState state) { + String sortDirectionAction; + // by default, everything sorts "up" unless it + // is the current key and it is already pointing up + if (SORT_ACTION_UP.equals(currentSortDirection) + && isCurrentKey) { + sortDirectionAction = SORT_ACTION_DOWN; + } else { + sortDirectionAction = SORT_ACTION_UP; + } + state.setControlEvent(table, + sortDirectionAction, + headerKey); + } + + }; + final Label label = new Label(); + label.setLabel(headerName); + label.setClassAttr("folderBrowserLink"); + label.setOutputEscaping(false); + label.setFontWeight(Label.BOLD); + + final SimpleContainer container = new SimpleContainer(); + container.add(label); + if (isCurrentKey) { + Image image = new Image("/assets/" + imageUrlStub); + image.setBorder("0"); + container.add(image); + } + link.setChild(container); + return link; + } + + } + + /** + * Produce links to view an item or control links for folders to change into + * the folder. + */ + private class NameCellRenderer extends DefaultTableCellRenderer { + + public NameCellRenderer() { + super(true); + } + + @Override + public Component getComponent(final Table table, + final PageState state, + final Object value, + final boolean isSelected, + final Object key, + final int row, + final int column) { + + final String name = (String) value; + final ContentSection section = CMS.getContext(). + getContentSection(); + final ContentSectionManager sectionManager = CdiUtil. + createCdiUtil() + .findBean(ContentSectionManager.class); + + final boolean isFolder = ((AssetFolderBrowserTableModel) table + .getTableModel(state)) + .isFolder(); + final long objectId = getObjectId(key); + + if (isFolder) { + //return new ControlLink(new Text(name)); + return super.getComponent(table, + state, + value, + isSelected, + objectId, + row, + column); + } else { +// return new Link(new Text(name), +// itemResolver.generateItemURL(state, +// objectId, +// name, +// section, +// "DRAFT")); + return new Text(name); + } + } + + } + + private class DateCellRenderer implements TableCellRenderer { + + @Override + public Component getComponent(final Table table, + final PageState state, + final Object value, + final boolean isSelected, + final Object key, + final int row, + final int column) { + if (value instanceof Date) { + final Date date = (Date) value; + return new Text(String.format("%1$TF %1$TT", date)); + } else if (value == null) { + return new Text(""); + } else { + return new Text(value.toString()); + } + } + + } + + /** + * Produce delete links for items and non-empty folders. + */ + private class ActionCellRenderer implements TableCellRenderer { + + @Override + public Component getComponent(final Table table, + final PageState state, + final Object value, + final boolean isSelected, + final Object key, + final int row, + final int column) { + if (((Boolean) value)) { + return new Label(" ", false); + } else { + final ControlLink link = new ControlLink( + new Label(new GlobalizedMessage("cms.ui.folder.delete", + CmsConstants.CMS_BUNDLE))); + link.setConfirmation( + new GlobalizedMessage( + "cms.ui.folder.delete_confirmation", + CmsConstants.CMS_BUNDLE)); + return link; + } + } + + } + + // Deletes an item + private class ItemDeleter extends TableActionAdapter { + + @Override + public void cellSelected(final TableActionEvent event) { + int col = event.getColumn(); + + if (deleteColumn != getColumn(col)) { + return; + } + + final PageState state = event.getPageState(); + + final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); + final AssetFolderBrowserController controller = cdiUtil.findBean( + AssetFolderBrowserController.class); + controller.deleteObject((String) event.getRowKey()); + + ((Table) event.getSource()).clearSelection(state); + } + + } + + private class FolderChanger extends TableActionAdapter { + + @Override + public void cellSelected(final TableActionEvent event) { + final PageState state = event.getPageState(); + final int col = event.getColumn(); + + if (nameColumn != getColumn(col)) { + return; + } + + clearSelection(state); + getFolderSelectionModel().setSelectedKey( + state, + getObjectId(event.getRowKey())); + } + + } + + private long getObjectId(final Object key) { + + final String keyStr = (String) key; + + if (keyStr.startsWith("folder-")) { + return Long.parseLong(keyStr.substring("folder-".length())); + } else if (keyStr.startsWith("asset-")) { + return Long.parseLong(keyStr.substring("asset-".length())); + } else { + return Long.parseLong(keyStr); + } + + } + } diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/AssetFolderBrowserController.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/AssetFolderBrowserController.java index bcf61dcf8..37e0bcb17 100644 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/AssetFolderBrowserController.java +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/AssetFolderBrowserController.java @@ -38,6 +38,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Locale; +import java.util.Objects; import java.util.stream.Collectors; import javax.annotation.PostConstruct; @@ -52,6 +53,9 @@ import javax.persistence.criteria.Order; import javax.persistence.criteria.Path; import javax.persistence.criteria.Root; import javax.transaction.Transactional; +import org.libreccm.core.CcmObject; +import org.librecms.contentsection.AssetRepository; +import org.librecms.contentsection.FolderRepository; /** * @@ -72,6 +76,12 @@ public class AssetFolderBrowserController { @Inject private AssetTypesManager typesManager; + @Inject + private FolderRepository folderRepo; + + @Inject + private AssetRepository assetRepo; + @Inject private GlobalizationHelper globalizationHelper; @@ -86,7 +96,7 @@ public class AssetFolderBrowserController { @PostConstruct private void init() { final KernelConfig kernelConfig = confManager.findConfiguration( - KernelConfig.class); + KernelConfig.class); defaultLocale = kernelConfig.getDefaultLocale(); } @@ -102,25 +112,25 @@ public class AssetFolderBrowserController { firstResult, maxResults); final List subFolderRows = subFolders - .stream() - .map(subFolder -> buildRow(subFolder)) - .collect(Collectors.toList()); + .stream() + .map(subFolder -> buildRow(subFolder)) + .collect(Collectors.toList()); if (subFolders.size() > maxResults) { return subFolderRows; } else { final int maxAssets = maxResults - subFolders.size(); - final int firstItem = firstResult - subFolders.size(); + final int firstAsset = firstResult - subFolders.size(); final List assets = findAssetsInFolder(folder, orderBy, orderDirection, - firstResult, - maxResults); + firstAsset, + maxAssets); final List assetRows = assets - .stream() - .map(asset -> buildRow(asset)) - .collect(Collectors.toList()); + .stream() + .map(asset -> buildRow(asset)) + .collect(Collectors.toList()); final List rows = new ArrayList<>(); rows.addAll(subFolderRows); @@ -130,6 +140,76 @@ public class AssetFolderBrowserController { } } + @Transactional(Transactional.TxType.REQUIRED) + protected long countObjects(final Folder folder) { + + Objects.requireNonNull(folder); + + final CriteriaBuilder builder = entityManager.getCriteriaBuilder(); + CriteriaQuery criteriaQuery = builder.createQuery(Long.class); + final Root from = criteriaQuery.from(CcmObject.class); + + criteriaQuery = criteriaQuery.select(builder.count(from)); + + final List subFolders = findSubFolders( + folder, + AssetFolderBrowser.SORT_KEY_NAME, + AssetFolderBrowser.SORT_ACTION_UP, + -1, + -1); + final List assets = findAssetsInFolder( + folder, + AssetFolderBrowser.SORT_KEY_NAME, + AssetFolderBrowser.SORT_ACTION_UP, + -1, + -1); + + if (subFolders.isEmpty() && assets.isEmpty()) { + return 0; + } else if(subFolders.isEmpty() && !assets.isEmpty()) { + criteriaQuery = criteriaQuery.where(from.in(assets)); + } else if (!subFolders.isEmpty() && assets.isEmpty()) { + criteriaQuery = criteriaQuery.where(from.in(subFolders)); + } else { + criteriaQuery = criteriaQuery.where(builder.or( + from.in(subFolders), + from.in(assets))); + } + + return entityManager.createQuery(criteriaQuery).getSingleResult(); + + } + + /** + * Called by the {@link AssetFolderBrowser} to delete an object. + * + * @param objectId + */ + @Transactional(Transactional.TxType.REQUIRED) + protected void deleteObject(final String objectId) { + + Objects.requireNonNull(objectId); + + if (objectId.startsWith("folder-")) { + final long folderId = Long.parseLong( + objectId.substring("folder-".length())); + + folderRepo + .findById(folderId) + .ifPresent(folderRepo::delete); + } else if (objectId.startsWith("asset-")) { + final long assetId = Long.parseLong( + objectId.substring("asset-".length())); + + assetRepo + .findById(assetId) + .ifPresent(assetRepo::delete); + } else { + throw new IllegalArgumentException( + "The objectId is expected to start with 'folder-' or 'item.'."); + } + } + private AssetFolderBrowserTableRow buildRow(final Folder folder) { final AssetFolderBrowserTableRow row = new AssetFolderBrowserTableRow(); @@ -138,15 +218,15 @@ public class AssetFolderBrowserController { row.setObjectUuid(folder.getUuid()); row.setName(folder.getName()); if (folder.getTitle().hasValue(globalizationHelper - .getNegotiatedLocale())) { + .getNegotiatedLocale())) { row.setTitle(folder.getTitle().getValue(globalizationHelper - .getNegotiatedLocale())); + .getNegotiatedLocale())); } else { row.setTitle(folder.getTitle().getValue(defaultLocale)); } row.setFolder(true); row.setDeletable(!categoryManager.hasSubCategories(folder) - && !categoryManager.hasObjects(folder)); + && !categoryManager.hasObjects(folder)); return row; } @@ -159,14 +239,14 @@ public class AssetFolderBrowserController { row.setObjectUuid(asset.getUuid()); row.setName(asset.getDisplayName()); if (asset.getTitle().hasValue(globalizationHelper - .getNegotiatedLocale())) { + .getNegotiatedLocale())) { row.setTitle(asset.getTitle().getValue(globalizationHelper - .getNegotiatedLocale())); + .getNegotiatedLocale())); } else { row.setTitle(asset.getTitle().getValue(defaultLocale)); } final AssetTypeInfo typeInfo = typesManager - .getAssetTypeInfo(asset.getClass()); + .getAssetTypeInfo(asset.getClass()); row.setTypeLabelBundle(typeInfo.getLabelBundle()); row.setTypeLabelKey(typeInfo.getLabelKey()); @@ -184,24 +264,26 @@ public class AssetFolderBrowserController { final CriteriaBuilder builder = entityManager.getCriteriaBuilder(); final CriteriaQuery criteria = builder - .createQuery(Folder.class); + .createQuery(Folder.class); final Root from = criteria.from(Folder.class); final Order order; if (AssetFolderBrowser.SORT_KEY_NAME.equals(orderBy) - && AssetFolderBrowser.SORT_ACTION_DOWN.equals(orderDirection)) { + && AssetFolderBrowser.SORT_ACTION_DOWN. + equals(orderDirection)) { order = builder.desc(from.get("name")); } else { order = builder.asc(from.get("name")); } final TypedQuery query = entityManager - .createQuery( - criteria.where( - builder.equal(from.get("parentCategory"), folder) - ) - .orderBy(order) - ); + .createQuery( + criteria.where( + builder. + equal(from.get("parentCategory"), folder) + ) + .orderBy(order) + ); if (firstResult >= 0) { query.setFirstResult(firstResult); @@ -250,17 +332,18 @@ public class AssetFolderBrowserController { } final TypedQuery query = entityManager - .createQuery( - criteria.select(fromAsset) - .where( - builder.and( - builder.equal(join.get("category"), folder), - builder.equal(join.get("type"), - CmsConstants.CATEGORIZATION_TYPE_FOLDER) - ) - ) - .orderBy(order) - ); + .createQuery( + criteria.select(fromAsset) + .where( + builder.and( + builder.equal(join.get( + "category"), folder), + builder.equal(join.get("type"), + CmsConstants.CATEGORIZATION_TYPE_FOLDER) + ) + ) + .orderBy(order) + ); if (firstResult >= 0) { query.setFirstResult(firstResult); diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/AssetFolderBrowserPaginationModelBuilder.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/AssetFolderBrowserPaginationModelBuilder.java new file mode 100644 index 000000000..85ea33141 --- /dev/null +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/AssetFolderBrowserPaginationModelBuilder.java @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2017 LibreCCM Foundation. + * + * 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. + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301 USA + */ +package com.arsdigita.cms.ui.assets; + +import com.arsdigita.bebop.PageState; +import com.arsdigita.bebop.PaginationModelBuilder; +import com.arsdigita.bebop.Paginator; +import com.arsdigita.cms.ui.folder.FolderSelectionModel; +import org.libreccm.cdi.utils.CdiUtil; +import org.librecms.contentsection.Folder; + +/** + * + * @author Jens Pelzetter + */ +class AssetFolderBrowserPaginationModelBuilder implements PaginationModelBuilder { + + private final AssetFolderBrowser folderBrowser; + + public AssetFolderBrowserPaginationModelBuilder( + final AssetFolderBrowser folderBrowser) { + + this.folderBrowser = folderBrowser; + } + + @Override + public int getTotalSize(final Paginator paginator, final PageState state) { + + final FolderSelectionModel folderSelectionModel = folderBrowser + .getFolderSelectionModel(); + final Folder folder = folderSelectionModel.getSelectedObject(state); + if (folder == null) { + return 0; + } else { + final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); + final AssetFolderBrowserController controller = cdiUtil.findBean( + AssetFolderBrowserController.class); + return (int) controller.countObjects(folder); + } + } + + @Override + public boolean isVisible(final PageState state) { + return folderBrowser != null && folderBrowser.isVisible(state); + } + + + +} diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/AssetFolderBrowserTableModel.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/AssetFolderBrowserTableModel.java index 9108a0f4b..8ecaeb308 100644 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/AssetFolderBrowserTableModel.java +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/AssetFolderBrowserTableModel.java @@ -30,14 +30,15 @@ import java.util.List; * * @author Jens Pelzetter */ -public class AssetFolderBrowserTableModel implements TableModel { +class AssetFolderBrowserTableModel implements TableModel { - private static final int COL_NAME = 0; - private static final int COL_TITLE = 1; - private static final int COL_TYPE = 2; - private static final int COL_CREATION_DATE = 3; - private static final int COL_LAST_MODIFIED = 4; - private static final int COL_DELETEABLE = 5; + protected static final int COL_NAME = 0; + protected static final int COL_TITLE = 1; + protected static final int COL_TYPE = 2; + protected static final int COL_CREATION_DATE = 3; + protected static final int COL_LAST_MODIFIED = 4; + protected static final int COL_DELETEABLE = 5; + protected static final int COL_ACTION = 6; private final Iterator iterator; private AssetFolderBrowserTableRow currentRow; diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/AssetPane.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/AssetPane.java index 204edb332..aea69bca9 100644 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/AssetPane.java +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/assets/AssetPane.java @@ -23,6 +23,7 @@ import com.arsdigita.bebop.FormProcessException; import com.arsdigita.bebop.Label; import com.arsdigita.bebop.Page; import com.arsdigita.bebop.PageState; +import com.arsdigita.bebop.Paginator; import com.arsdigita.bebop.Resettable; import com.arsdigita.bebop.SegmentedPanel; import com.arsdigita.bebop.SimpleContainer; @@ -37,7 +38,6 @@ import com.arsdigita.bebop.event.PrintEvent; import com.arsdigita.bebop.event.PrintListener; import com.arsdigita.cms.CMS; import com.arsdigita.cms.ui.BaseTree; -import com.arsdigita.cms.ui.folder.FolderBrowser; import com.arsdigita.cms.ui.folder.FolderCreateForm; import com.arsdigita.cms.ui.folder.FolderEditorForm; import com.arsdigita.cms.ui.folder.FolderRequestLocal; @@ -55,6 +55,7 @@ import org.librecms.contentsection.ContentSection; import org.librecms.contentsection.Folder; import java.util.List; +import org.arsdigita.cms.CMSConfig; /** * @@ -69,8 +70,11 @@ public class AssetPane extends LayoutPanel implements Resettable { private final FolderSelectionModel folderSelectionModel; private final FolderRequestLocal folderRequestLocal; - private SegmentedPanel.Segment currentFolderSegment; + private AssetFolderBrowser folderBrowser; + private SegmentedPanel.Segment browseSegment; + private SegmentedPanel.Segment currentFolderSegment; + private SegmentedPanel.Segment actionsSegment; private SegmentedPanel.Segment newFolderSegment; private SegmentedPanel.Segment editFolderSegment; @@ -81,8 +85,8 @@ public class AssetPane extends LayoutPanel implements Resettable { @Override protected Folder getRootFolder(final PageState state) { final ContentSection section = CMS - .getContext() - .getContentSection(); + .getContext() + .getContentSection(); return section.getRootAssetsFolder(); } @@ -93,8 +97,8 @@ public class AssetPane extends LayoutPanel implements Resettable { @Override protected Long getRootFolderID(final PageState state) { final ContentSection section = CMS - .getContext() - .getContentSection(); + .getContext() + .getContentSection(); return section.getRootAssetsFolder().getObjectId(); } @@ -105,8 +109,8 @@ public class AssetPane extends LayoutPanel implements Resettable { setLeft(left); final Label heading = new Label( - new GlobalizedMessage("cms.ui.folder_browser", - CmsConstants.CMS_BUNDLE)); + new GlobalizedMessage("cms.ui.folder_browser", + CmsConstants.CMS_BUNDLE)); left.addSegment(heading, tree); // final Text placeholder = new Text("Placeholder"); @@ -118,6 +122,15 @@ public class AssetPane extends LayoutPanel implements Resettable { final SegmentedPanel panel = new SegmentedPanel(); + browseSegment = panel.addSegment(); + folderBrowser = new AssetFolderBrowser(folderSelectionModel); + final Paginator paginator = new Paginator( + new AssetFolderBrowserPaginationModelBuilder(folderBrowser), + CMSConfig.getConfig().getFolderBrowseListSize()); + folderBrowser.setPaginator(paginator); + browseSegment.add(paginator); + browseSegment.add(folderBrowser); + currentFolderSegment = panel.addSegment(); currentFolderSegment.addHeader(new Text("Current folder")); final Label currentFolderLabel = new Label(); @@ -129,39 +142,38 @@ public class AssetPane extends LayoutPanel implements Resettable { final Label target = (Label) event.getTarget(); final long selectedId = Long.parseLong(selectionModel - .getSelectedKey(state).toString()); + .getSelectedKey(state).toString()); final long currentFolderId = folderSelectionModel - .getSelectedObject(state).getObjectId(); + .getSelectedObject(state).getObjectId(); target.setLabel(String.format( - "selectedId = %d; currentFolderId = %d", - selectedId, - currentFolderId)); + "selectedId = %d; currentFolderId = %d", + selectedId, + currentFolderId)); } }); currentFolderSegment.add(currentFolderLabel); - browseSegment = panel.addSegment(); - browseSegment.setIdAttr("folder-browse"); - + actionsSegment = panel.addSegment(); + actionsSegment.setIdAttr("folder-browse"); final ActionGroup actions = new ActionGroup(); - browseSegment.add(actions); + actionsSegment.add(actions); final FolderCreateForm folderCreateForm = new FolderCreateForm( - "fcreat", folderSelectionModel); + "fcreat", folderSelectionModel); folderCreateForm.addSubmissionListener(new FormSubmissionListener() { @Override public void submitted(final FormSectionEvent event) - throws FormProcessException { + throws FormProcessException { final PageState state = event.getPageState(); if (event.getSource() == folderCreateForm - && folderCreateForm.isCancelled(state)) { + && folderCreateForm.isCancelled(state)) { browseMode(state); throw new FormProcessException(new GlobalizedMessage( - "cms.ui.cancelled", CmsConstants.CMS_BUNDLE)); + "cms.ui.cancelled", CmsConstants.CMS_BUNDLE)); } } @@ -171,7 +183,7 @@ public class AssetPane extends LayoutPanel implements Resettable { @Override public void process(final FormSectionEvent event) - throws FormProcessException { + throws FormProcessException { final PageState state = event.getPageState(); final Object source = event.getSource(); @@ -182,24 +194,24 @@ public class AssetPane extends LayoutPanel implements Resettable { }); newFolderSegment = panel.addSegment( - new Label(new GlobalizedMessage("cms.ui.new_folder", - CmsConstants.CMS_BUNDLE)), - folderCreateForm); + new Label(new GlobalizedMessage("cms.ui.new_folder", + CmsConstants.CMS_BUNDLE)), + folderCreateForm); final FolderEditorForm folderEditorForm = new FolderEditorForm( - "fedit", folderSelectionModel); + "fedit", folderSelectionModel); folderEditorForm.addSubmissionListener(new FormSubmissionListener() { @Override public void submitted(final FormSectionEvent event) - throws FormProcessException { + throws FormProcessException { final PageState state = event.getPageState(); if (event.getSource() == folderEditorForm - && folderEditorForm.isCancelled(state)) { + && folderEditorForm.isCancelled(state)) { browseMode(state); throw new FormProcessException(new GlobalizedMessage( - "cms.ui.cancelled", CmsConstants.CMS_BUNDLE)); + "cms.ui.cancelled", CmsConstants.CMS_BUNDLE)); } } @@ -208,7 +220,7 @@ public class AssetPane extends LayoutPanel implements Resettable { @Override public void process(final FormSectionEvent event) - throws FormProcessException { + throws FormProcessException { final PageState state = event.getPageState(); final Object source = event.getSource(); @@ -219,13 +231,13 @@ public class AssetPane extends LayoutPanel implements Resettable { }); editFolderSegment = panel.addSegment( - new Label(new GlobalizedMessage("cms.ui.edit_folder", - CmsConstants.CMS_BUNDLE)), - folderEditorForm); + new Label(new GlobalizedMessage("cms.ui.edit_folder", + CmsConstants.CMS_BUNDLE)), + folderEditorForm); final ActionLink createFolderAction = new ActionLink( - new Label(new GlobalizedMessage("cms.ui.new_folder", - CmsConstants.CMS_BUNDLE))); + new Label(new GlobalizedMessage("cms.ui.new_folder", + CmsConstants.CMS_BUNDLE))); createFolderAction.addActionListener(new ActionListener() { @Override @@ -241,8 +253,8 @@ public class AssetPane extends LayoutPanel implements Resettable { actions.addAction(createFolderAction); final ActionLink editFolderAction = new ActionLink( - new Label(new GlobalizedMessage("cms.ui.edit_folder", - CmsConstants.CMS_BUNDLE))); + new Label(new GlobalizedMessage("cms.ui.edit_folder", + CmsConstants.CMS_BUNDLE))); editFolderAction.addActionListener(new ActionListener() { @Override @@ -262,19 +274,22 @@ public class AssetPane extends LayoutPanel implements Resettable { protected void browseMode(final PageState state) { browseSegment.setVisible(state, true); + actionsSegment.setVisible(state, true); newFolderSegment.setVisible(state, false); editFolderSegment.setVisible(state, false); - + } protected void newFolderMode(final PageState state) { browseSegment.setVisible(state, false); + actionsSegment.setVisible(state, false); newFolderSegment.setVisible(state, true); editFolderSegment.setVisible(state, false); } - + protected void editFolderMode(final PageState state) { browseSegment.setVisible(state, false); + actionsSegment.setVisible(state, false); newFolderSegment.setVisible(state, false); editFolderSegment.setVisible(state, true); } @@ -288,6 +303,7 @@ public class AssetPane extends LayoutPanel implements Resettable { page.addActionListener(new FolderListener()); page.setVisibleDefault(browseSegment, true); + page.setVisibleDefault(actionsSegment, true); page.setVisibleDefault(newFolderSegment, false); page.setVisibleDefault(editFolderSegment, false); } @@ -296,6 +312,8 @@ public class AssetPane extends LayoutPanel implements Resettable { public void reset(final PageState state) { super.reset(state); + + folderBrowser.getPaginator().reset(state); } @@ -309,14 +327,14 @@ public class AssetPane extends LayoutPanel implements Resettable { if (!selectionModel.isSelected(state)) { final String folder = state - .getRequest() - .getParameter(SET_FOLDER); + .getRequest() + .getParameter(SET_FOLDER); if (folder == null) { final Category root = CMS - .getContext() - .getContentSection() - .getRootAssetsFolder(); + .getContext() + .getContentSection() + .getRootAssetsFolder(); final Long folderId = root.getObjectId(); selectionModel.setSelectedKey(state, folderId); @@ -336,18 +354,18 @@ public class AssetPane extends LayoutPanel implements Resettable { final PageState state = event.getPageState(); final Category root = CMS - .getContext() - .getContentSection() - .getRootAssetsFolder(); + .getContext() + .getContentSection() + .getRootAssetsFolder(); if (!root.equals(folderRequestLocal.getFolder(state))) { // Expand the ancestor nodes of the currently // selected node. final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); final FolderTreeModelController controller = cdiUtil.findBean( - FolderTreeModelController.class); + FolderTreeModelController.class); final List ancestorIds = controller.findAncestorIds( - folderRequestLocal.getFolder(state)); + folderRequestLocal.getFolder(state)); ancestorIds.forEach(id -> tree.expand(id.toString(), state)); } diff --git a/ccm-cms/src/main/java/com/arsdigita/cms/ui/folder/FolderBrowserPaginationModelBuilder.java b/ccm-cms/src/main/java/com/arsdigita/cms/ui/folder/FolderBrowserPaginationModelBuilder.java index 31a779ece..9e91909f8 100644 --- a/ccm-cms/src/main/java/com/arsdigita/cms/ui/folder/FolderBrowserPaginationModelBuilder.java +++ b/ccm-cms/src/main/java/com/arsdigita/cms/ui/folder/FolderBrowserPaginationModelBuilder.java @@ -38,10 +38,10 @@ class FolderBrowserPaginationModelBuilder implements PaginationModelBuilder { } @Override - public int getTotalSize(final Paginator paginator, - final PageState state) { + public int getTotalSize(final Paginator paginator, final PageState state) { + final FolderSelectionModel folderSelectionModel = folderBrowser - .getFolderSelectionModel(); + .getFolderSelectionModel(); final Folder folder = folderSelectionModel.getSelectedObject(state); if (folder == null) { return 0; @@ -49,7 +49,7 @@ class FolderBrowserPaginationModelBuilder implements PaginationModelBuilder { folderBrowser.getRowSelectionModel().clearSelection(state); final CdiUtil cdiUtil = CdiUtil.createCdiUtil(); final FolderBrowserController controller = cdiUtil.findBean( - FolderBrowserController.class); + FolderBrowserController.class); final String filter = folderBrowser.getFilter(state); final String atozFilter = folderBrowser.getAtoZfilter(state); final int first = paginator.getFirst(state); @@ -67,7 +67,7 @@ class FolderBrowserPaginationModelBuilder implements PaginationModelBuilder { if (filterTerm == null) { return (int) controller.countObjects(folder); } else { - return (int) controller.countObjects(folder, + return (int) controller.countObjects(folder, filter); } } diff --git a/ccm-cms/src/main/resources/org/librecms/CmsResources.properties b/ccm-cms/src/main/resources/org/librecms/CmsResources.properties index 5379cde1a..fbedc422d 100644 --- a/ccm-cms/src/main/resources/org/librecms/CmsResources.properties +++ b/ccm-cms/src/main/resources/org/librecms/CmsResources.properties @@ -245,3 +245,4 @@ cms.ui.type.workflow.select=Select default workflow cms.ui.type.select=Select Content Type cms.ui.type.select.none=There are no available content types to select cms.ui.assets=Assets +cms.ui.folder.no_assets=No assets diff --git a/ccm-cms/src/main/resources/org/librecms/CmsResources_de.properties b/ccm-cms/src/main/resources/org/librecms/CmsResources_de.properties index 97099400c..da570f196 100644 --- a/ccm-cms/src/main/resources/org/librecms/CmsResources_de.properties +++ b/ccm-cms/src/main/resources/org/librecms/CmsResources_de.properties @@ -244,3 +244,4 @@ cms.ui.type.workflow.select=Voreingestellten Arbeitsablauf ausw\u00e4hlen cms.ui.type.select=Dolkumententype ausw\u00e4hlen cms.ui.type.select.none=Keine verf\u00fcgbaren Dokumententypen cms.ui.assets=Medien & Daten +cms.ui.folder.no_assets=Keine Medien oder Datens\u00e4tze vorhanden diff --git a/ccm-cms/src/main/resources/org/librecms/CmsResources_fr.properties b/ccm-cms/src/main/resources/org/librecms/CmsResources_fr.properties index 5d4a644b0..fe78c70d9 100644 --- a/ccm-cms/src/main/resources/org/librecms/CmsResources_fr.properties +++ b/ccm-cms/src/main/resources/org/librecms/CmsResources_fr.properties @@ -203,3 +203,4 @@ cms.ui.type.workflow.select=Select default workflow cms.ui.type.select=Select Content Type cms.ui.type.select.none=There are no available content types to select cms.ui.assets=Assets +cms.ui.folder.no_assets=No assets diff --git a/ccm-core/src/main/java/com/arsdigita/bebop/ParameterSingleSelectionModel.java b/ccm-core/src/main/java/com/arsdigita/bebop/ParameterSingleSelectionModel.java index 7128b63e6..997e7827b 100755 --- a/ccm-core/src/main/java/com/arsdigita/bebop/ParameterSingleSelectionModel.java +++ b/ccm-core/src/main/java/com/arsdigita/bebop/ParameterSingleSelectionModel.java @@ -51,8 +51,8 @@ import com.arsdigita.util.Assert; * @author Jens Pelzetter * */ -public class ParameterSingleSelectionModel - extends AbstractSingleSelectionModel { +public class ParameterSingleSelectionModel + extends AbstractSingleSelectionModel { private final ParameterModel m_parameter; @@ -60,7 +60,7 @@ public class ParameterSingleSelectionModel * Constructs a new ParameterSingleSelectionModel. * * @param m the parameter model that will be used to keep track of the - * currently selected key + * currently selected key */ public ParameterSingleSelectionModel(ParameterModel m) { super(); @@ -94,7 +94,7 @@ public class ParameterSingleSelectionModel /** * Set the selected key. * - * @param state represents the state of the current request + * @param state represents the state of the current request * @param newKey the new selected key */ @Override @@ -103,7 +103,10 @@ public class ParameterSingleSelectionModel if (Assert.isEnabled()) { final FormModel model = state.getPage().getStateModel(); - Assert.isTrue(model.containsFormParam(m_parameter)); + Assert.isTrue(model.containsFormParam(m_parameter), + String.format( + "Parameter %s is not part of the FormModel.", + m_parameter.getName())); } state.setValue(m_parameter, newKey);