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

org.opencms.ade.containerpage.client.CmsContainerpageDNDController Maven / Gradle / Ivy

Go to download

OpenCms is an enterprise-ready, easy to use website content management system based on Java and XML technology. Offering a complete set of features, OpenCms helps content managers worldwide to create and maintain beautiful websites fast and efficiently.

There is a newer version: 18.0
Show newest version
/*
 * 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.ade.containerpage.client;

import org.opencms.ade.containerpage.client.ui.CmsContainerPageContainer;
import org.opencms.ade.containerpage.client.ui.CmsContainerPageElementPanel;
import org.opencms.ade.containerpage.client.ui.CmsDroppedElementModeSelectionDialog;
import org.opencms.ade.containerpage.client.ui.CmsElementOptionBar;
import org.opencms.ade.containerpage.client.ui.CmsGroupContainerElementPanel;
import org.opencms.ade.containerpage.client.ui.CmsToolbarAllGalleriesMenu;
import org.opencms.ade.containerpage.client.ui.I_CmsDropContainer;
import org.opencms.ade.containerpage.client.ui.css.I_CmsLayoutBundle;
import org.opencms.ade.containerpage.shared.CmsCntPageData.ElementReuseMode;
import org.opencms.ade.containerpage.shared.CmsContainer;
import org.opencms.ade.containerpage.shared.CmsContainerElement;
import org.opencms.ade.containerpage.shared.CmsContainerElementData;
import org.opencms.ade.contenteditor.shared.CmsEditorConstants;
import org.opencms.ade.galleries.client.ui.CmsResultListItem;
import org.opencms.gwt.client.dnd.CmsDNDHandler;
import org.opencms.gwt.client.dnd.CmsDNDHandler.Orientation;
import org.opencms.gwt.client.dnd.I_CmsDNDController;
import org.opencms.gwt.client.dnd.I_CmsDraggable;
import org.opencms.gwt.client.dnd.I_CmsDropTarget;
import org.opencms.gwt.client.ui.CmsErrorDialog;
import org.opencms.gwt.client.ui.CmsList;
import org.opencms.gwt.client.ui.CmsListItem;
import org.opencms.gwt.client.util.CmsDebugLog;
import org.opencms.gwt.client.util.CmsDomUtil;
import org.opencms.gwt.client.util.CmsPositionBean;
import org.opencms.gwt.client.util.I_CmsSimpleCallback;
import org.opencms.gwt.shared.CmsTemplateContextInfo;
import org.opencms.util.CmsStringUtil;
import org.opencms.util.CmsUUID;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import com.google.common.base.Objects;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.core.client.Scheduler.ScheduledCommand;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.Style;
import com.google.gwt.dom.client.Style.Display;
import com.google.gwt.dom.client.Style.Position;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Widget;

/**
 * The container-page editor drag and drop controller.

* * @since 8.0.0 */ public class CmsContainerpageDNDController implements I_CmsDNDController { /** The container highlighting offset. */ public static final int HIGHLIGHTING_OFFSET = 4; /** The minimum margin set to empty containers. */ private static final int MINIMUM_CONTAINER_MARGIN = 10; /** The container page controller. */ protected CmsContainerpageController m_controller; /** The id of the dragged element. */ protected String m_draggableId; /** The current place holder index. */ private int m_currentIndex = -1; /** The current drop target. */ private I_CmsDropTarget m_currentTarget; /** Map of current drag info beans. */ private Map m_dragInfos; /** The drag overlay. */ private Element m_dragOverlay; /** DND controller for images. We set this in onDragStart if we are dragging an image, and then delegate most of the other method calls to it if it is set.*/ private CmsImageDndController m_imageDndController; /** The ionitial drop target. */ private I_CmsDropTarget m_initialDropTarget; /** Creating new flag. */ private boolean m_isNew; /** The id of the container from which an element was dragged. */ String m_originalContainerId; /** The original position of the draggable. */ private int m_originalIndex; /** The copy group id. */ private String m_copyGroupId; /** * Constructor.

* * @param controller the container page controller */ public CmsContainerpageDNDController(CmsContainerpageController controller) { m_controller = controller; m_dragInfos = new HashMap(); } /** * @see org.opencms.gwt.client.dnd.I_CmsDNDController#onAnimationStart(org.opencms.gwt.client.dnd.I_CmsDraggable, org.opencms.gwt.client.dnd.I_CmsDropTarget, org.opencms.gwt.client.dnd.CmsDNDHandler) */ public void onAnimationStart(I_CmsDraggable draggable, I_CmsDropTarget target, CmsDNDHandler handler) { // remove highlighting for (I_CmsDropTarget dropTarget : m_dragInfos.keySet()) { if (dropTarget instanceof I_CmsDropContainer) { ((I_CmsDropContainer)dropTarget).removeHighlighting(); } } } /** * @see org.opencms.gwt.client.dnd.I_CmsDNDController#onBeforeDrop(org.opencms.gwt.client.dnd.I_CmsDraggable, org.opencms.gwt.client.dnd.I_CmsDropTarget, org.opencms.gwt.client.dnd.CmsDNDHandler) */ public boolean onBeforeDrop(I_CmsDraggable draggable, I_CmsDropTarget target, CmsDNDHandler handler) { return true; } /** * @see org.opencms.gwt.client.dnd.I_CmsDNDController#onDragCancel(org.opencms.gwt.client.dnd.I_CmsDraggable, org.opencms.gwt.client.dnd.I_CmsDropTarget, org.opencms.gwt.client.dnd.CmsDNDHandler) */ public void onDragCancel(I_CmsDraggable draggable, I_CmsDropTarget target, CmsDNDHandler handler) { if (m_imageDndController != null) { m_imageDndController.onDragCancel(draggable, target, handler); removeDragOverlay(); m_imageDndController = null; return; } stopDrag(handler); } /** * @see org.opencms.gwt.client.dnd.I_CmsDNDController#onDragStart(org.opencms.gwt.client.dnd.I_CmsDraggable, org.opencms.gwt.client.dnd.I_CmsDropTarget, org.opencms.gwt.client.dnd.CmsDNDHandler) */ public boolean onDragStart(final I_CmsDraggable draggable, I_CmsDropTarget target, final CmsDNDHandler handler) { installDragOverlay(); m_currentTarget = null; m_currentIndex = -1; m_draggableId = draggable.getId(); m_isNew = false; m_originalIndex = -1; m_initialDropTarget = target; handler.setOrientation(Orientation.ALL); m_controller.hideEditableListButtons(); if (isImage(draggable)) { if (m_controller.isGroupcontainerEditing()) { // don't allow image DND while editing group containers return false; } // We are going to delegate further method calls to this, and set it to null again if the image is dragged or the // DND operation is cancelled m_imageDndController = new CmsImageDndController(CmsContainerpageController.get()); return m_imageDndController.onDragStart(draggable, target, handler); } if (!m_controller.isGroupcontainerEditing()) { boolean locked = m_controller.lockContainerpage(); if (!locked) { return false; } } String containerId = null; if (target instanceof CmsContainerPageContainer) { containerId = ((CmsContainerPageContainer)target).getContainerId(); } else { // set marker id containerId = CmsContainerElement.MENU_CONTAINER_ID; } m_originalContainerId = containerId; if (target != null) { handler.addTarget(target); if (target instanceof I_CmsDropContainer) { prepareTargetContainer((I_CmsDropContainer)target, draggable, handler.getPlaceholder()); Element helper = handler.getDragHelper(); handler.setCursorOffsetX(helper.getOffsetWidth() - 15); handler.setCursorOffsetY(20); } } m_dragInfos.put(target, handler.getPlaceholder()); m_controller.getHandler().hideMenu(); String clientId = draggable.getId(); if (CmsStringUtil.isEmptyOrWhitespaceOnly(clientId)) { CmsDebugLog.getInstance().printLine("draggable has no id, canceling drop"); return false; } final I_CmsSimpleCallback callback = new I_CmsSimpleCallback() { /** * Execute on success.

* * @param arg the container element data */ public void execute(CmsContainerElementData arg) { prepareHelperElements(arg, handler, draggable); } }; if (isNewId(clientId)) { // for new content elements dragged from the gallery menu, the given id contains the resource type name m_isNew = true; m_controller.getNewElement(clientId, callback); } else { m_controller.getElementForDragAndDropFromContainer(clientId, m_originalContainerId, false, callback); } if (!(target instanceof CmsContainerPageContainer)) { handler.setStartPosition(-1, 0); } return true; } /** * @see org.opencms.gwt.client.dnd.I_CmsDNDController#onDrop(org.opencms.gwt.client.dnd.I_CmsDraggable, org.opencms.gwt.client.dnd.I_CmsDropTarget, org.opencms.gwt.client.dnd.CmsDNDHandler) */ public void onDrop(final I_CmsDraggable draggable, final I_CmsDropTarget target, CmsDNDHandler handler) { if (m_imageDndController != null) { m_imageDndController.onDrop(draggable, target, handler); removeDragOverlay(); m_imageDndController = null; return; } if (target != m_initialDropTarget) { if (target instanceof I_CmsDropContainer) { final I_CmsDropContainer container = (I_CmsDropContainer)target; final int index = container.getPlaceholderIndex(); final String modelReplaceId = container instanceof CmsContainerPageContainer ? ((CmsContainerPageContainer)container).getCopyModelReplaceId() : null; if (!m_isNew && (draggable instanceof CmsListItem)) { final String copyGroupId = m_copyGroupId; AsyncCallback modeCallback = new AsyncCallback() { public void onFailure(Throwable caught) { if (caught != null) { CmsErrorDialog.handleException(caught); } } public void onSuccess(String result) { if (Objects.equal(result, CmsEditorConstants.MODE_COPY)) { final CmsContainerpageController controller = CmsContainerpageController.get(); if (copyGroupId == null) { CmsContainerElementData data = controller.getCachedElement(m_draggableId); final Map settings = data.getSettings(); controller.copyElement( CmsContainerpageController.getServerId(m_draggableId), new I_CmsSimpleCallback() { public void execute(CmsUUID resultId) { controller.getElementWithSettings( "" + resultId, settings, new I_CmsSimpleCallback() { public void execute(CmsContainerElementData newData) { insertDropElement( newData, container, index, draggable instanceof CmsContainerPageElementPanel ? (CmsContainerPageElementPanel)draggable : null, modelReplaceId); container.removePlaceholder(); } }); } }); } else { controller.getElementForDragAndDropFromContainer( copyGroupId, m_originalContainerId, true, new I_CmsSimpleCallback() { public void execute(CmsContainerElementData arg) { insertDropElement( arg, container, index, draggable instanceof CmsContainerPageElementPanel ? (CmsContainerPageElementPanel)draggable : null, modelReplaceId); container.removePlaceholder(); } }); } } else if (Objects.equal(result, CmsEditorConstants.MODE_REUSE)) { insertDropElement( m_controller.getCachedElement(m_draggableId), container, index, draggable instanceof CmsContainerPageElementPanel ? (CmsContainerPageElementPanel)draggable : null, modelReplaceId); container.removePlaceholder(); } } }; CmsUUID structureId = new CmsUUID(CmsContainerpageController.getServerId(m_draggableId)); CmsContainerElementData cachedElementData = m_controller.getCachedElement(m_draggableId); CmsDebugLog.consoleLog("Cached element data available " + (cachedElementData != null)); if (cachedElementData != null) { CmsDebugLog.consoleLog("Is copy in models: " + cachedElementData.isCopyInModels()); } CmsDebugLog.consoleLog(copyGroupId); ElementReuseMode reuseMode = isCopyModel(draggable) ? ElementReuseMode.copy : (((cachedElementData != null) && !cachedElementData.isCopyInModels()) ? ElementReuseMode.reuse : CmsContainerpageController.get().getData().getElementReuseMode()); if (handler.hasModifierCTRL()) { reuseMode = ElementReuseMode.ask; } if (reuseMode != ElementReuseMode.reuse) { if ((cachedElementData != null) && (!cachedElementData.hasWritePermission() || cachedElementData.isModelGroup() || cachedElementData.isWasModelGroup())) { // User is not allowed to create this element in current view, so reuse the element instead reuseMode = ElementReuseMode.reuse; } } switch (reuseMode) { case ask: // when dropping elements from the into the page, we ask the user if the dropped element should // be used, or a copy of it. If the user wants a copy, we copy the corresponding resource and replace the element // in the page CmsDroppedElementModeSelectionDialog.showDialog(structureId, modeCallback); break; case copy: modeCallback.onSuccess(CmsEditorConstants.MODE_COPY); break; case reuse: default: modeCallback.onSuccess(CmsEditorConstants.MODE_REUSE); break; } } else { insertDropElement( m_controller.getCachedElement(m_draggableId), container, index, draggable instanceof CmsContainerPageElementPanel ? (CmsContainerPageElementPanel)draggable : null, null); } } else if (target instanceof CmsList) { m_controller.addToFavoriteList(m_draggableId); } } else if ((target instanceof I_CmsDropContainer) && (draggable instanceof CmsContainerPageElementPanel) && isChangedPosition(target)) { CmsDomUtil.showOverlay(draggable.getElement(), false); I_CmsDropContainer container = (I_CmsDropContainer)target; int count = container.getWidgetCount(); handler.getPlaceholder().getStyle().setDisplay(Display.NONE); if (container.getPlaceholderIndex() >= count) { container.add((CmsContainerPageElementPanel)draggable); } else { container.insert((CmsContainerPageElementPanel)draggable, container.getPlaceholderIndex()); } m_controller.addToRecentList(m_draggableId, null); // changes are only relevant to the container page if not group-container editing if (!m_controller.isGroupcontainerEditing()) { m_controller.setPageChanged(); } } else if (draggable instanceof CmsContainerPageElementPanel) { CmsDomUtil.showOverlay(draggable.getElement(), false); // to reset mouse over state remove and attach the option bar CmsContainerPageElementPanel containerElement = (CmsContainerPageElementPanel)draggable; CmsElementOptionBar optionBar = containerElement.getElementOptionBar(); optionBar.removeFromParent(); containerElement.setElementOptionBar(optionBar); } stopDrag(handler); } /** * @see org.opencms.gwt.client.dnd.I_CmsDNDController#onPositionedPlaceholder(org.opencms.gwt.client.dnd.I_CmsDraggable, org.opencms.gwt.client.dnd.I_CmsDropTarget, org.opencms.gwt.client.dnd.CmsDNDHandler) */ public void onPositionedPlaceholder(I_CmsDraggable draggable, I_CmsDropTarget target, CmsDNDHandler handler) { if (m_imageDndController != null) { m_imageDndController.onPositionedPlaceholder(draggable, target, handler); return; } if (hasChangedPosition(target)) { checkPlaceholderVisibility(target); updateHighlighting(false); } } /** * @see org.opencms.gwt.client.dnd.I_CmsDNDController#onTargetEnter(org.opencms.gwt.client.dnd.I_CmsDraggable, org.opencms.gwt.client.dnd.I_CmsDropTarget, org.opencms.gwt.client.dnd.CmsDNDHandler) */ public boolean onTargetEnter(I_CmsDraggable draggable, I_CmsDropTarget target, CmsDNDHandler handler) { if (m_imageDndController != null) { return m_imageDndController.onTargetEnter(draggable, target, handler); } Element placeholder = m_dragInfos.get(target); if (placeholder != null) { handler.getPlaceholder().getStyle().setDisplay(Display.NONE); handler.setPlaceholder(placeholder); placeholder.getStyle().clearDisplay(); if ((target != m_initialDropTarget) && (target instanceof I_CmsDropContainer)) { ((I_CmsDropContainer)target).checkMaxElementsOnEnter(); } } return true; } /** * @see org.opencms.gwt.client.dnd.I_CmsDNDController#onTargetLeave(org.opencms.gwt.client.dnd.I_CmsDraggable, org.opencms.gwt.client.dnd.I_CmsDropTarget, org.opencms.gwt.client.dnd.CmsDNDHandler) */ public void onTargetLeave(I_CmsDraggable draggable, I_CmsDropTarget target, CmsDNDHandler handler) { if (m_imageDndController != null) { m_imageDndController.onTargetLeave(draggable, target, handler); return; } m_currentTarget = null; m_currentIndex = -1; Element placeholder = m_dragInfos.get(m_initialDropTarget); if (placeholder != null) { handler.getPlaceholder().getStyle().setDisplay(Display.NONE); handler.setPlaceholder(placeholder); placeholder.getStyle().setDisplay(Display.NONE); if ((target != m_initialDropTarget) && (target instanceof I_CmsDropContainer)) { ((I_CmsDropContainer)target).checkMaxElementsOnLeave(); } } updateHighlighting(false); } /** * Prepares all helper elements for the different drop targets.

* * @param elementData the element data * @param handler the drag and drop handler * @param draggable the draggable */ protected void prepareHelperElements( CmsContainerElementData elementData, CmsDNDHandler handler, I_CmsDraggable draggable) { if (elementData == null) { CmsDebugLog.getInstance().printLine("elementData == null!"); handler.cancel(); return; } if (!handler.isDragging()) { return; } if (elementData.isGroup()) { m_copyGroupId = m_draggableId; } else { m_copyGroupId = null; } if ((elementData.getDndId() != null) && (m_controller.getCachedElement(elementData.getDndId()) != null)) { m_draggableId = elementData.getDndId(); elementData = m_controller.getCachedElement(m_draggableId); } else { m_draggableId = elementData.getClientId(); } if (m_controller.isGroupcontainerEditing()) { CmsGroupContainerElementPanel groupContainer = m_controller.getGroupcontainer(); if ((groupContainer != m_initialDropTarget) && !(elementData.isGroupContainer() || elementData.isInheritContainer()) && (elementData.getContents().get(groupContainer.getContainerId()) != null)) { Element placeholder = null; Set cssResources = elementData.getCssResources(groupContainer.getContainerId()); if ((cssResources != null) && !cssResources.isEmpty()) { // the element requires certain CSS resources, check if present and include if necessary for (String cssResourceLink : cssResources) { CmsDomUtil.ensureStyleSheetIncluded(cssResourceLink); } } try { String htmlContent = elementData.getContents().get(groupContainer.getContainerId()); placeholder = CmsDomUtil.createElement(htmlContent); // ensure any embedded flash players are set opaque so UI elements may be placed above them CmsDomUtil.fixFlashZindex(placeholder); placeholder.addClassName(I_CmsLayoutBundle.INSTANCE.dragdropCss().dragPlaceholder()); } catch (Exception e) { CmsDebugLog.getInstance().printLine(e.getMessage()); } if (placeholder != null) { prepareDragInfo(placeholder, groupContainer, handler); groupContainer.highlightContainer(); } } return; } if (!m_controller.isEditingDisabled()) { for (CmsContainerPageContainer container : m_controller.getContainerTargets().values()) { if (draggable.getElement().isOrHasChild(container.getElement())) { // skip containers that are children of the draggable element continue; } if ((container != m_initialDropTarget) && !container.isDetailView() && (m_controller.getData().isModelGroup() || !container.hasModelGroupParent()) && (elementData.getContents().get(container.getContainerId()) != null)) { Element placeholder = null; if (elementData.isGroupContainer() || elementData.isInheritContainer()) { placeholder = DOM.createDiv(); String content = ""; for (String groupId : elementData.getSubItems()) { CmsContainerElementData subData = m_controller.getCachedElement(groupId); if (subData != null) { if (subData.isShowInContext( CmsContainerpageController.get().getData().getTemplateContextInfo().getCurrentContext())) { if ((subData.getContents().get(container.getContainerId()) != null)) { content += subData.getContents().get(container.getContainerId()); } } else { content += "

"; } } } if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(content)) { placeholder.setInnerHTML(content); // ensure any embedded flash players are set opaque so UI elements may be placed above them CmsDomUtil.fixFlashZindex(placeholder); } else { placeholder.addClassName( I_CmsLayoutBundle.INSTANCE.containerpageCss().emptyGroupContainer()); } } else { Set cssResources = elementData.getCssResources(container.getContainerId()); if ((cssResources != null) && !cssResources.isEmpty()) { // the element requires certain CSS resources, check if present and include if necessary for (String cssResourceLink : cssResources) { CmsDomUtil.ensureStyleSheetIncluded(cssResourceLink); } } try { String htmlContent = elementData.getContents().get(container.getContainerId()); placeholder = CmsDomUtil.createElement(htmlContent); // ensure any embedded flash players are set opaque so UI elements may be placed above them CmsDomUtil.fixFlashZindex(placeholder); placeholder.addClassName(I_CmsLayoutBundle.INSTANCE.dragdropCss().dragPlaceholder()); } catch (Exception e) { CmsDebugLog.getInstance().printLine(e.getMessage()); } } if (placeholder != null) { prepareDragInfo(placeholder, container, handler); } } } initNestedContainers(); // add highlighting after all drag targets have been initialized updateHighlighting(true); } } /** * Inserts e new container element into the container once the drag and drop is finished.

* * @param elementData the element data to create the element from * @param container the target container * @param index the element index * @param draggable the original drag element * @param modelReplaceId the model replace id */ void insertDropElement( CmsContainerElementData elementData, I_CmsDropContainer container, int index, CmsContainerPageElementPanel draggable, String modelReplaceId) { try { CmsContainerPageElementPanel containerElement = m_controller.getContainerpageUtil().createElement( elementData, container, m_isNew); if (m_isNew) { CmsDebugLog.consoleLog("Setting new type: " + CmsContainerpageController.getServerId(m_draggableId)); containerElement.setNewType(CmsContainerpageController.getServerId(m_draggableId)); } else { m_controller.addToRecentList(elementData.getClientId(), null); } if (index >= container.getWidgetCount()) { container.add(containerElement); } else { container.insert(containerElement, index); } if (draggable != null) { draggable.removeFromParent(); } m_controller.initializeSubContainers(containerElement); if (modelReplaceId != null) { m_controller.executeCopyModelReplace( modelReplaceId, ((CmsContainerPageContainer)container).getFormerModelGroupParent(), m_controller.getCachedElement(m_draggableId)); } if (!m_controller.isGroupcontainerEditing()) { if (containerElement.hasReloadMarker()) { m_controller.setPageChanged(new Runnable() { public void run() { CmsContainerpageController.get().reloadPage(); } }); } else { m_controller.setPageChanged(); } } if (m_controller.isGroupcontainerEditing()) { container.getElement().removeClassName( I_CmsLayoutBundle.INSTANCE.containerpageCss().emptyGroupContainer()); } } catch (Exception e) { CmsErrorDialog.handleException(e.getMessage(), e); } } /** * Checks and sets if the place holder should be visible.

* * @param target the target container */ private void checkPlaceholderVisibility(I_CmsDropTarget target) { if (target instanceof I_CmsDropContainer) { I_CmsDropContainer container = (I_CmsDropContainer)target; container.setPlaceholderVisibility( (container != m_initialDropTarget) || ((m_currentIndex - m_originalIndex) > 1) || ((m_originalIndex - m_currentIndex) > 0)); } } /** * Checks if the placeholder position has changed.

* * @param target the current drop target * * @return true if the placeholder position has changed */ private boolean hasChangedPosition(I_CmsDropTarget target) { if ((m_currentTarget != target) || (m_currentIndex != target.getPlaceholderIndex())) { m_currentTarget = target; m_currentIndex = target.getPlaceholderIndex(); return true; } return false; } /** * Initializes the nested container infos.

*/ private void initNestedContainers() { for (CmsContainer container : m_controller.getContainers().values()) { if (container.isSubContainer()) { CmsContainerPageContainer containerWidget = m_controller.m_targetContainers.get(container.getName()); // check if the sub container is a valid drop targets if (m_dragInfos.keySet().contains(containerWidget)) { CmsContainer parentContainer = m_controller.getContainers().get(container.getParentContainerName()); // add the container to all it's ancestors as a dnd child while (parentContainer != null) { if (m_dragInfos.keySet().contains( m_controller.m_targetContainers.get(parentContainer.getName()))) { m_controller.m_targetContainers.get(parentContainer.getName()).addDndChild(containerWidget); } if (parentContainer.isSubContainer()) { parentContainer = m_controller.getContainers().get( parentContainer.getParentContainerName()); } else { parentContainer = null; } } } } } } /** * Installs the drag overlay to avoid any mouse over issues or similar.

*/ private void installDragOverlay() { if (m_dragOverlay != null) { m_dragOverlay.removeFromParent(); } m_dragOverlay = DOM.createDiv(); m_dragOverlay.addClassName(I_CmsLayoutBundle.INSTANCE.dragdropCss().dragOverlay()); Document.get().getBody().appendChild(m_dragOverlay); } /** * Checks whether the current placeholder position represents a change to the original draggable position within the tree.

* * @param target the current drop target * * @return true if the position changed */ private boolean isChangedPosition(I_CmsDropTarget target) { // if the new index is not next to the old one, the position has changed if ((target != m_initialDropTarget) || !((target.getPlaceholderIndex() == (m_originalIndex + 1)) || (target.getPlaceholderIndex() == m_originalIndex))) { return true; } return false; } /** * Checks if the draggable item is a copy model.

* * @param draggable the draggable item * * @return true if the item is a copy model */ private boolean isCopyModel(I_CmsDraggable draggable) { if (!(draggable instanceof CmsResultListItem)) { return false; } return ((CmsResultListItem)draggable).getResult().isCopyModel(); } /** * Checks if the given draggable item is an image.

* * @param draggable the item to check * * @return true if the given item is an image */ private boolean isImage(I_CmsDraggable draggable) { return (draggable instanceof CmsResultListItem) && CmsToolbarAllGalleriesMenu.DND_MARKER.equals(((CmsResultListItem)draggable).getData()); } /** * Checks if the given id is a new id.

* * @param id the id * * @return true if the id is a new id */ private boolean isNewId(String id) { if (id.contains("#")) { id = id.substring(0, id.indexOf("#")); } return !CmsUUID.isValidUUID(id); } /** * Sets styles of helper elements, appends the to the drop target and puts them into a drag info bean.

* * @param placeholder the placeholder element * @param target the drop target * @param handler the drag and drop handler */ private void prepareDragInfo(Element placeholder, I_CmsDropContainer target, CmsDNDHandler handler) { target.getElement().addClassName(I_CmsLayoutBundle.INSTANCE.dragdropCss().dragging()); String positioning = CmsDomUtil.getCurrentStyle( target.getElement(), org.opencms.gwt.client.util.CmsDomUtil.Style.position); // set target relative, if not absolute or fixed if (!Position.ABSOLUTE.getCssName().equals(positioning) && !Position.FIXED.getCssName().equals(positioning)) { target.getElement().getStyle().setPosition(Position.RELATIVE); // check for empty containers that don't have a minimum top and bottom margin to avoid containers overlapping if (target.getElement().getFirstChildElement() == null) { if (CmsDomUtil.getCurrentStyleInt( target.getElement(), CmsDomUtil.Style.marginTop) < MINIMUM_CONTAINER_MARGIN) { target.getElement().getStyle().setMarginTop(MINIMUM_CONTAINER_MARGIN, Unit.PX); } if (CmsDomUtil.getCurrentStyleInt( target.getElement(), CmsDomUtil.Style.marginBottom) < MINIMUM_CONTAINER_MARGIN) { target.getElement().getStyle().setMarginBottom(MINIMUM_CONTAINER_MARGIN, Unit.PX); } } } m_dragInfos.put(target, placeholder); handler.addTarget(target); } /** * Prepares the target container.

* * @param targetContainer the container * @param draggable the draggable * @param placeholder the placeholder */ private void prepareTargetContainer( I_CmsDropContainer targetContainer, I_CmsDraggable draggable, Element placeholder) { String positioning = CmsDomUtil.getCurrentStyle( targetContainer.getElement(), org.opencms.gwt.client.util.CmsDomUtil.Style.position); // set target relative, if not absolute or fixed if (!Position.ABSOLUTE.getCssName().equals(positioning) && !Position.FIXED.getCssName().equals(positioning)) { targetContainer.getElement().getStyle().setPosition(Position.RELATIVE); } m_originalIndex = targetContainer.getWidgetIndex((Widget)draggable); targetContainer.getElement().insertBefore(placeholder, draggable.getElement()); targetContainer.getElement().addClassName(I_CmsLayoutBundle.INSTANCE.dragdropCss().dragging()); CmsDomUtil.showOverlay(draggable.getElement(), true); targetContainer.highlightContainer(); } /** * Removes the drag overlay.

*/ private void removeDragOverlay() { if (m_dragOverlay != null) { m_dragOverlay.removeFromParent(); m_dragOverlay = null; } } /** * Function which is called when the drag process is stopped, either by cancelling or dropping.

* * @param handler the drag and drop handler */ private void stopDrag(final CmsDNDHandler handler) { removeDragOverlay(); for (I_CmsDropTarget target : m_dragInfos.keySet()) { target.getElement().removeClassName(I_CmsLayoutBundle.INSTANCE.dragdropCss().dragging()); target.getElement().removeClassName(I_CmsLayoutBundle.INSTANCE.dragdropCss().clearFix()); Style targetStyle = target.getElement().getStyle(); if (!(target instanceof CmsGroupContainerElementPanel)) { targetStyle.clearPosition(); } targetStyle.clearMarginTop(); targetStyle.clearMarginBottom(); if (target instanceof I_CmsDropContainer) { ((I_CmsDropContainer)target).removeHighlighting(); } } handler.getDragHelper().removeFromParent(); m_copyGroupId = null; m_currentTarget = null; m_currentIndex = -1; m_isNew = false; m_controller.getHandler().deactivateMenuButton(); final List dragTargets = new ArrayList(m_dragInfos.keySet()); m_dragInfos.clear(); Scheduler.get().scheduleDeferred(new ScheduledCommand() { /** * @see com.google.gwt.user.client.Command#execute() */ public void execute() { handler.clearTargets(); m_controller.resetEditButtons(); // in case of group editing, this will refresh the container position and size for (I_CmsDropTarget target : dragTargets) { if (target instanceof I_CmsDropContainer) { ((I_CmsDropContainer)target).refreshHighlighting(); // reset the nested container infos ((I_CmsDropContainer)target).clearDnDChildren(); } } } }); if (handler.getDraggable() instanceof CmsContainerPageElementPanel) { ((CmsContainerPageElementPanel)(handler.getDraggable())).removeHighlighting(); } } /** * Updates the drag target highlighting.

* * @param initial true when initially highlighting the drop containers */ private void updateHighlighting(boolean initial) { Map containers = new HashMap(); for (I_CmsDropTarget target : m_dragInfos.keySet()) { if ((target instanceof I_CmsDropContainer) && !Display.NONE.getCssName().equalsIgnoreCase( CmsDomUtil.getCurrentStyle(target.getElement(), CmsDomUtil.Style.display))) { if (initial && (target != m_initialDropTarget)) { ((I_CmsDropContainer)target).highlightContainer(); } else { ((I_CmsDropContainer)target).updatePositionInfo(); } containers.put((I_CmsDropContainer)target, ((I_CmsDropContainer)target).getPositionInfo()); } } List containersToMatch = new ArrayList(containers.keySet()); for (I_CmsDropContainer contA : containers.keySet()) { containersToMatch.remove(contA); for (I_CmsDropContainer contB : containersToMatch) { CmsPositionBean posA = containers.get(contA); CmsPositionBean posB = containers.get(contB); if (CmsPositionBean.checkCollision(posA, posB, HIGHLIGHTING_OFFSET * 3)) { if (contA.hasDnDChildren() && contA.getDnDChildren().contains(contB)) { if (!posA.isInside(posB, HIGHLIGHTING_OFFSET)) { // the nested container is not completely inside the other // increase the size of the outer container posA.ensureSurrounds(posB, HIGHLIGHTING_OFFSET); } } else if (contB.hasDnDChildren() && contB.getDnDChildren().contains(contA)) { if (!posB.isInside(posA, HIGHLIGHTING_OFFSET)) { // the nested container is not completely inside the other // increase the size of the outer container posB.ensureSurrounds(posA, HIGHLIGHTING_OFFSET); } } else { CmsPositionBean.avoidCollision(posA, posB, HIGHLIGHTING_OFFSET * 3); } } } } for (Entry containerEntry : containers.entrySet()) { containerEntry.getKey().refreshHighlighting(containerEntry.getValue()); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy