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

org.opencms.acacia.client.CmsEditorBase 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 (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.acacia.client;

import org.opencms.acacia.client.css.I_CmsWidgetsLayoutBundle;
import org.opencms.acacia.client.entity.CmsEntityBackend;
import org.opencms.acacia.client.entity.I_CmsEntityBackend;
import org.opencms.acacia.client.ui.CmsInlineEditOverlay;
import org.opencms.acacia.client.widgets.CmsFormWidgetWrapper;
import org.opencms.acacia.client.widgets.CmsStringWidget;
import org.opencms.acacia.client.widgets.CmsTinyMCEWidget;
import org.opencms.acacia.client.widgets.I_CmsEditWidget;
import org.opencms.acacia.client.widgets.I_CmsFormEditWidget;
import org.opencms.acacia.client.widgets.complex.CmsDataViewWidgetRenderer;
import org.opencms.acacia.shared.CmsContentDefinition;
import org.opencms.acacia.shared.CmsEntity;
import org.opencms.acacia.shared.CmsEntityHtml;
import org.opencms.acacia.shared.CmsTabInfo;
import org.opencms.acacia.shared.CmsType;
import org.opencms.acacia.shared.CmsValidationResult;
import org.opencms.acacia.shared.rpc.I_CmsContentServiceAsync;
import org.opencms.gwt.client.ui.CmsTabbedPanel;
import org.opencms.gwt.client.ui.css.I_CmsLayoutBundle;

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

import com.google.gwt.dom.client.Element;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.ResizeEvent;
import com.google.gwt.event.logical.shared.ResizeHandler;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.i18n.client.Dictionary;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Panel;

/**
 * The content editor base.

*/ public class CmsEditorBase implements I_CmsInlineHtmlUpdateHandler { /** Message constant for key in the resource bundle. */ public static final String GUI_CHOICE_ADD_CHOICE_1 = "GUI_CHOICE_ADD_CHOICE_1"; //Add choice {0} /** Message constant for key in the resource bundle. */ public static final String GUI_VIEW_ADD_1 = "GUI_VIEW_ADD_1"; //Add {0} /** Message constant for key in the resource bundle. */ public static final String GUI_VIEW_CLOSE_0 = "GUI_VIEW_CLOSE_0"; //Close /** Message constant for key in the resource bundle. */ public static final String GUI_VIEW_DELETE_1 = "GUI_VIEW_DELETE_1"; //Delete {0} /** Message constant for key in the resource bundle. */ public static final String GUI_VIEW_EDIT_1 = "GUI_VIEW_EDIT_1"; // Edit {0} /** Message constant for key in the resource bundle. */ public static final String GUI_VIEW_MOVE_1 = "GUI_VIEW_MOVE_1"; //Move {0} /** Message constant for key in the resource bundle. */ public static final String GUI_VIEW_MOVE_DOWN_0 = "GUI_VIEW_MOVE_DOWN_0"; //Move down /** Message constant for key in the resource bundle. */ public static final String GUI_VIEW_MOVE_UP_0 = "GUI_VIEW_MOVE_UP_0"; //Move up /** The inline edit focus marker. */ private static final String INLINE_EDIT_FOCUS_MARKER = "shouldFocusOnInlineEdit"; /** The localized dictionary. */ private static Dictionary m_dictionary; /** The id of the edited entity. */ protected String m_entityId; /** The entity back-end instance. */ protected I_CmsEntityBackend m_entityBackend; /** The in-line edit overlay hiding other content. */ private CmsInlineEditOverlay m_editOverlay; /** The edited entity. */ private CmsEntity m_entity; /** The form panel. */ private FlowPanel m_formPanel; /** The tab panel if tabs are used. */ private CmsTabbedPanel m_formTabs; /** The window resize handler registration. */ private HandlerRegistration m_resizeHandlerRegistration; /** The root attribute handler. */ private CmsRootHandler m_rootHandler; /** The content service instance. */ private I_CmsContentServiceAsync m_service; /** The tab infos. */ private List m_tabInfos; /** The validation handler. */ private CmsValidationHandler m_validationHandler; /** The widget service. */ private I_CmsWidgetService m_widgetService; /** * Constructor.

* * @param service the content service * @param widgetService the widget service to use */ public CmsEditorBase(I_CmsContentServiceAsync service, I_CmsWidgetService widgetService) { I_CmsLayoutBundle.INSTANCE.generalCss().ensureInjected(); I_CmsLayoutBundle.INSTANCE.buttonCss().ensureInjected(); I_CmsLayoutBundle.INSTANCE.highlightCss().ensureInjected(); I_CmsLayoutBundle.INSTANCE.tabbedPanelCss().ensureInjected(); I_CmsLayoutBundle.INSTANCE.dialogCss().ensureInjected(); org.opencms.acacia.client.css.I_CmsLayoutBundle.INSTANCE.form().ensureInjected(); org.opencms.acacia.client.css.I_CmsLayoutBundle.INSTANCE.attributeChoice().ensureInjected(); I_CmsWidgetsLayoutBundle.INSTANCE.widgetCss().ensureInjected(); I_CmsWidgetsLayoutBundle.INSTANCE.galleryWidgetsCss().ensureInjected(); m_service = service; m_entityBackend = CmsEntityBackend.getInstance(); m_widgetService = widgetService; I_CmsEntityRenderer renderer = new CmsRenderer(m_entityBackend, m_widgetService); m_widgetService.setDefaultRenderer(renderer); m_widgetService.addWidgetFactory("string", new I_CmsWidgetFactory() { public I_CmsFormEditWidget createFormWidget(String configuration) { return new CmsFormWidgetWrapper(new CmsStringWidget()); } public I_CmsEditWidget createInlineWidget(String configuration, Element element) { return new CmsStringWidget(element); } }); m_widgetService.addWidgetFactory("html", new I_CmsWidgetFactory() { public I_CmsFormEditWidget createFormWidget(String configuration) { return new CmsFormWidgetWrapper(new CmsTinyMCEWidget(null)); } public I_CmsEditWidget createInlineWidget(String configuration, Element element) { return new CmsTinyMCEWidget(element, null); } }); // we may want to explicitly use the default renderer for specific attributes. m_widgetService.addRenderer(new CmsRenderer(CmsEntityBackend.getInstance(), getWidgetService())); m_widgetService.addRenderer(new CmsNativeComplexWidgetRenderer()); m_widgetService.addRenderer(new CmsDataViewWidgetRenderer()); m_validationHandler = new CmsValidationHandler(); m_validationHandler.setContentService(m_service); } /** * Returns the formated message.

* * @param key the message key * @param args the parameters to insert into the placeholders * * @return the formated message */ public static String getMessageForKey(String key, Object... args) { String result = null; if (hasDictionary()) { result = m_dictionary.get(key); if ((result != null) && (args != null) && (args.length > 0)) { for (int i = 0; i < args.length; i++) { result = result.replace("{" + i + "}", String.valueOf(args[i])); } } } if (result == null) { result = ""; } return result; } /** * Returns if the messages dictionary is set.

* * @return true if the messages dictionary is set */ public static boolean hasDictionary() { return m_dictionary != null; } /** * Marks the given element to receive focus once the inline editing is initialized.

* * @param element the element to mark */ public static void markForInlineFocus(Element element) { element.setAttribute("rel", INLINE_EDIT_FOCUS_MARKER); } /** * Sets the m_dictionary.

* * @param dictionary the m_dictionary to set */ public static void setDictionary(Dictionary dictionary) { m_dictionary = dictionary; } /** * Checks whether the given element is marked to receive focus once the inline editing is initialized.

* * @param element the element to check * * @return true if the given element is marked to receive focus once the inline editing is initialized */ public static boolean shouldFocusOnInlineEdit(Element element) { return INLINE_EDIT_FOCUS_MARKER.equals(element.getAttribute("rel")); } /** * Adds the value change handler to the entity with the given id.

* * @param entityId the entity id * @param handler the change handler */ public void addEntityChangeHandler(String entityId, ValueChangeHandler handler) { CmsEntity entity = m_entityBackend.getEntity(entityId); if (entity != null) { entity.addValueChangeHandler(handler); } } /** * Adds a validation change handler.

* * @param handler the validation change handler * * @return the handler registration */ public HandlerRegistration addValidationChangeHandler(ValueChangeHandler handler) { return m_validationHandler.addValueChangeHandler(handler); } /** * Destroys the form and related resources. Also clears all entities from the entity back-end

* * @param clearEntities true to also clear all entities */ public void destroyForm(boolean clearEntities) { CmsValueFocusHandler.getInstance().destroy(); if (clearEntities) { m_entityBackend.clearEntities(); } } /** * Returns the currently edited entity.

* * @return the currently edited entity */ public CmsEntity getCurrentEntity() { return m_entityBackend.getEntity(m_entityId); } /** * Returns the content service instance.

* * @return the content service */ public I_CmsContentServiceAsync getService() { return m_service; } /** * Loads the content definition for the given entity and executes the callback on success.

* * @param entityId the entity id * @param callback the callback */ public void loadContentDefinition(final String entityId, final Command callback) { AsyncCallback asyncCallback = new AsyncCallback() { public void onFailure(Throwable caught) { onRpcError(caught); } public void onSuccess(CmsContentDefinition result) { registerContentDefinition(result); callback.execute(); } }; getService().loadContentDefinition(entityId, asyncCallback); } /** * Registers the types and entities of the given content definition.

* * @param definition the content definition */ public void registerContentDefinition(CmsContentDefinition definition) { m_widgetService.addConfigurations(definition.getConfigurations()); CmsType baseType = definition.getTypes().get(definition.getEntityTypeName()); m_entityBackend.registerTypes(baseType, definition.getTypes()); m_entityBackend.registerEntity(definition.getEntity()); } /** * @see org.opencms.acacia.client.I_CmsInlineHtmlUpdateHandler#reinitWidgets(org.opencms.acacia.client.I_CmsInlineFormParent) */ public void reinitWidgets(I_CmsInlineFormParent formParent) { renderInlineEntity(m_entityId, formParent); } /** * Renders the entity form within the given context.

* * @param entityId the entity id * @param tabInfos the tab informations * @param context the context element * @param scrollParent the scroll element to be used for automatic scrolling during drag and drop */ public void renderEntityForm(String entityId, List tabInfos, Panel context, Element scrollParent) { CmsEntity entity = m_entityBackend.getEntity(entityId); if (entity != null) { boolean initUndo = (m_entity == null) || !entity.getId().equals(m_entity.getId()); m_entity = entity; CmsType type = m_entityBackend.getType(m_entity.getTypeName()); m_formPanel = new FlowPanel(); context.add(m_formPanel); CmsAttributeHandler.setScrollElement(scrollParent); CmsButtonBarHandler.INSTANCE.setWidgetService(m_widgetService); if (m_rootHandler == null) { m_rootHandler = new CmsRootHandler(); } else { m_rootHandler.clearHandlers(); } m_tabInfos = tabInfos; m_formTabs = m_widgetService.getRendererForType(type).renderForm( m_entity, m_tabInfos, m_formPanel, m_rootHandler, 0); m_validationHandler.registerEntity(m_entity); m_validationHandler.setRootHandler(m_rootHandler); m_validationHandler.setFormTabPanel(m_formTabs); if (initUndo) { CmsUndoRedoHandler.getInstance().initialize(m_entity, this, m_rootHandler); } // trigger validation right away m_validationHandler.validate(m_entity); } } /** * Renders the entity form within the given context.

* * @param entityId the entity id * @param context the context element * @param scrollParent the scroll element to be used for automatic scrolling during drag and drop */ public void renderEntityForm(String entityId, Panel context, Element scrollParent) { CmsEntity entity = m_entityBackend.getEntity(entityId); if (entity != null) { boolean initUndo = (m_entity == null) || !entity.getId().equals(m_entity.getId()); m_entity = entity; CmsType type = m_entityBackend.getType(m_entity.getTypeName()); m_formPanel = new FlowPanel(); context.add(m_formPanel); CmsAttributeHandler.setScrollElement(scrollParent); CmsButtonBarHandler.INSTANCE.setWidgetService(m_widgetService); if (m_rootHandler == null) { m_rootHandler = new CmsRootHandler(); } else { m_rootHandler.clearHandlers(); } m_widgetService.getRendererForType(type).renderForm(m_entity, m_formPanel, m_rootHandler, 0); m_formTabs = null; m_tabInfos = null; m_validationHandler.setContentService(m_service); m_validationHandler.registerEntity(m_entity); m_validationHandler.setRootHandler(m_rootHandler); m_validationHandler.setFormTabPanel(null); if (initUndo) { CmsUndoRedoHandler.getInstance().initialize(m_entity, this, m_rootHandler); } } } /** * Renders the entity form within the given context.

* * @param entityId the entity id * @param formParent the form parent widget */ public void renderInlineEntity(String entityId, I_CmsInlineFormParent formParent) { m_entity = m_entityBackend.getEntity(entityId); if (m_entity != null) { if (m_rootHandler == null) { m_rootHandler = new CmsRootHandler(); } else { m_rootHandler.clearHandlers(); } m_validationHandler.setContentService(m_service); m_validationHandler.registerEntity(m_entity); m_validationHandler.setRootHandler(m_rootHandler); CmsType type = m_entityBackend.getType(m_entity.getTypeName()); CmsButtonBarHandler.INSTANCE.setWidgetService(m_widgetService); m_widgetService.getRendererForType(type).renderInline(m_entity, formParent, this, m_rootHandler, 0); CmsUndoRedoHandler.getInstance().initialize(m_entity, this, m_rootHandler); } } /** * Re-renders the form with the given entity data.

* * @param newContent the entity data */ public void rerenderForm(CmsEntity newContent) { m_validationHandler.setPaused(true, m_entity); m_entityBackend.changeEntityContentValues(m_entity, newContent); CmsType type = m_entityBackend.getType(m_entity.getTypeName()); if ((m_tabInfos != null) && !m_tabInfos.isEmpty()) { int currentTab = m_formTabs.getSelectedIndex(); m_formPanel.clear(); m_rootHandler.clearHandlers(); m_formTabs = m_widgetService.getRendererForType(type).renderForm( m_entity, m_tabInfos, m_formPanel, m_rootHandler, 0); m_formTabs.selectTab(currentTab); } else { m_formPanel.clear(); m_rootHandler.clearHandlers(); m_widgetService.getRendererForType(type).renderForm(m_entity, m_tabInfos, m_formPanel, m_rootHandler, 0); } m_validationHandler.setPaused(false, m_entity); } /** * Saves the given entities.

* * @param entities the entities to save * @param clearOnSuccess true to clear the entity back-end instance on success * @param callback the call back command */ public void saveEntities(List entities, final boolean clearOnSuccess, final Command callback) { AsyncCallback asyncCallback = new AsyncCallback() { public void onFailure(Throwable caught) { onRpcError(caught); } public void onSuccess(CmsValidationResult result) { callback.execute(); if ((result != null) && result.hasErrors()) { // CmsValidationHandler.getInstance().displayErrors(null, result) } if (clearOnSuccess) { destroyForm(true); } } }; getService().saveEntities(entities, asyncCallback); } /** * Saves the given entity.

* * @param entityIds the entity ids * @param clearOnSuccess true to clear all entities from entity back-end on success * @param callback the callback executed on success */ public void saveEntities(Set entityIds, boolean clearOnSuccess, Command callback) { List entities = new ArrayList(); for (String entityId : entityIds) { CmsEntity entity = m_entityBackend.getEntity(entityId); if (entity != null) { entities.add(entity); } } saveEntities(entities, clearOnSuccess, callback); } /** * Saves the given entity.

* * @param entity the entity * @param clearOnSuccess true to clear all entities from entity back-end on success * @param callback the callback executed on success */ public void saveEntity(CmsEntity entity, final boolean clearOnSuccess, final Command callback) { AsyncCallback asyncCallback = new AsyncCallback() { public void onFailure(Throwable caught) { onRpcError(caught); } public void onSuccess(CmsValidationResult result) { callback.execute(); if (clearOnSuccess) { destroyForm(true); } } }; getService().saveEntity(entity, asyncCallback); } /** * Saves the given entity.

* * @param entityId the entity id * @param clearOnSuccess true to clear all entities from entity back-end on success * @param callback the callback executed on success */ public void saveEntity(String entityId, boolean clearOnSuccess, Command callback) { CmsEntity entity = m_entityBackend.getEntity(entityId); saveEntity(entity, clearOnSuccess, callback); } /** * Saves the given entity.

* * @param entityId the entity id * @param callback the callback executed on success */ public void saveEntity(String entityId, Command callback) { CmsEntity entity = m_entityBackend.getEntity(entityId); saveEntity(entity, false, callback); } /** * @see org.opencms.acacia.client.I_CmsInlineHtmlUpdateHandler#updateHtml(org.opencms.acacia.client.I_CmsInlineFormParent, com.google.gwt.user.client.Command) */ public void updateHtml(final I_CmsInlineFormParent formParent, final Command onSuccess) { AsyncCallback callback = new AsyncCallback() { public void onFailure(Throwable caught) { onRpcError(caught); } public void onSuccess(CmsEntityHtml result) { if (result.getHtmlContent() != null) { formParent.replaceHtml(result.getHtmlContent()); onSuccess.execute(); } } }; getService().updateEntityHtml(getCurrentEntity(), getContextUri(), getHtmlContextInfo(), callback); } /** * Adds a click handler to the edit overlay.

* * @param handler the click handler * * @return the click handler registration */ protected HandlerRegistration addOverlayClickHandler(ClickHandler handler) { return m_editOverlay.addClickHandler(handler); } /** * Clears the editor.

*/ protected void clearEditor() { removeEditOverlays(); CmsUndoRedoHandler.getInstance().clear(); m_entity = null; m_entityId = null; m_tabInfos = null; m_rootHandler = null; m_formPanel = null; m_formTabs = null; } /** * Returns the context URI.

* Needed when updating the HTML due to content data changes.

* * Override to supply the required info.

* * @return the context URI */ protected String getContextUri() { return ""; } /** * Returns the in-line HTML context info.

* Needed when updating the HTML due to content data changes.

* * Override to supply the required info.

* * @return the HTML context info */ protected String getHtmlContextInfo() { return ""; } /** * Returns the root attribute handler.

* * @return the root attribute handler */ protected CmsRootHandler getRootAttributeHandler() { return m_rootHandler; } /** * Returns the validation handler.

* * @return the validation handler */ protected CmsValidationHandler getValidationHandler() { return m_validationHandler; } /** * Returns the widget service.

* * @return the widget service */ protected I_CmsWidgetService getWidgetService() { return m_widgetService; } /** * Initializes the edit overlay to be positioned around the given element.

* * @param element the element */ protected void initEditOverlay(Element element) { CmsInlineEditOverlay.removeAll(); m_editOverlay = CmsInlineEditOverlay.addOverlayForElement(element); if (m_resizeHandlerRegistration != null) { m_resizeHandlerRegistration.removeHandler(); } // add a handler to ensure the edit overlays get adjusted to changed window size m_resizeHandlerRegistration = Window.addResizeHandler(new ResizeHandler() { private Timer m_resizeTimer; public void onResize(ResizeEvent event) { if (m_resizeTimer == null) { m_resizeTimer = new Timer() { @Override public void run() { handleResize(); } }; m_resizeTimer.schedule(300); } } /** * Handles the window resize.

*/ void handleResize() { m_resizeTimer = null; CmsInlineEditOverlay.updateCurrentOverlayPosition(); } }); } /** * Handles RPC errors.

* * Override this for better error handling * * @param caught the error caught from the RPC */ protected void onRpcError(Throwable caught) { // doing nothing } /** * Removes the edit overlay from the DOM.

*/ protected void removeEditOverlays() { CmsInlineEditOverlay.removeAll(); m_editOverlay = null; if (m_resizeHandlerRegistration != null) { m_resizeHandlerRegistration.removeHandler(); m_resizeHandlerRegistration = null; } } /** * Updates the edit overlay position.

*/ protected void updateOverlayPosition() { if (m_editOverlay != null) { m_editOverlay.updatePosition(); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy