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

com.alkacon.acacia.client.EditorBase Maven / Gradle / Ivy

Go to download

A GWT based resource editor. This component is used as a part of OpenCms, 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.

The newest version!
/*
 * This library is part of the Acacia Editor -
 * an open source inline and form based content editor for GWT.
 *
 * Copyright (c) Alkacon Software GmbH (http://www.alkacon.com)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * For further information about Alkacon Software, please see the
 * company website: http://www.alkacon.com
 * 
 * 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 com.alkacon.acacia.client;

import com.alkacon.acacia.client.ui.InlineEditOverlay;
import com.alkacon.acacia.client.widgets.FormWidgetWrapper;
import com.alkacon.acacia.client.widgets.I_EditWidget;
import com.alkacon.acacia.client.widgets.I_FormEditWidget;
import com.alkacon.acacia.client.widgets.StringWidget;
import com.alkacon.acacia.client.widgets.TinyMCEWidget;
import com.alkacon.acacia.shared.ContentDefinition;
import com.alkacon.acacia.shared.EntityHtml;
import com.alkacon.acacia.shared.TabInfo;
import com.alkacon.acacia.shared.ValidationResult;
import com.alkacon.acacia.shared.rpc.I_ContentServiceAsync;
import com.alkacon.geranium.client.ui.TabbedPanel;
import com.alkacon.geranium.client.ui.css.I_ImageBundle;
import com.alkacon.geranium.client.ui.css.I_LayoutBundle;
import com.alkacon.vie.client.Entity;
import com.alkacon.vie.client.I_Vie;
import com.alkacon.vie.client.Vie;
import com.alkacon.vie.shared.I_Entity;
import com.alkacon.vie.shared.I_Type;

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 EditorBase implements I_InlineHtmlUpdateHandler { /** 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 VIE instance. */ protected I_Vie m_vie; /** The in-line edit overlay hiding other content. */ private InlineEditOverlay m_editOverlay; /** The edited entity. */ private Entity m_entity; /** The form panel. */ private FlowPanel m_formPanel; /** The tab panel if tabs are used. */ private TabbedPanel m_formTabs; /** The window resize handler registration. */ private HandlerRegistration m_resizeHandlerRegistration; /** The root attribute handler. */ private RootHandler m_rootHandler; /** The content service instance. */ private I_ContentServiceAsync m_service; /** The tab infos. */ private List m_tabInfos; /** The validation handler. */ private ValidationHandler m_validationHandler; /** The widget service. */ private I_WidgetService m_widgetService; /** * Constructor.

* * @param service the content service * @param widgetService the widget service to use */ public EditorBase(I_ContentServiceAsync service, I_WidgetService widgetService) { I_ImageBundle.INSTANCE.style().ensureInjected(); I_LayoutBundle.INSTANCE.generalCss().ensureInjected(); I_LayoutBundle.INSTANCE.buttonCss().ensureInjected(); I_LayoutBundle.INSTANCE.highlightCss().ensureInjected(); I_LayoutBundle.INSTANCE.tabbedPanelCss().ensureInjected(); I_LayoutBundle.INSTANCE.dialogCss().ensureInjected(); com.alkacon.acacia.client.css.I_LayoutBundle.INSTANCE.form().ensureInjected(); com.alkacon.acacia.client.css.I_LayoutBundle.INSTANCE.attributeChoice().ensureInjected(); m_service = service; m_vie = Vie.getInstance(); m_widgetService = widgetService; I_EntityRenderer renderer = new Renderer(m_vie, m_widgetService); m_widgetService.setDefaultRenderer(renderer); m_widgetService.addWidgetFactory("string", new I_WidgetFactory() { public I_FormEditWidget createFormWidget(String configuration) { return new FormWidgetWrapper(new StringWidget()); } public I_EditWidget createInlineWidget(String configuration, Element element) { return new StringWidget(element); } }); m_widgetService.addWidgetFactory("html", new I_WidgetFactory() { public I_FormEditWidget createFormWidget(String configuration) { return new FormWidgetWrapper(new TinyMCEWidget(null)); } public I_EditWidget createInlineWidget(String configuration, Element element) { return new TinyMCEWidget(element, null); } }); // we may want to explicitly use the default renderer for specific attributes. m_widgetService.addRenderer(new Renderer(Vie.getInstance(), getWidgetService())); m_widgetService.addRenderer(new NativeComplexWidgetRenderer()); m_validationHandler = new ValidationHandler(); 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) { I_Entity entity = m_vie.getEntity(entityId); if (entity != null) { ((Entity)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 VIE

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

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

* * @return the content service */ public I_ContentServiceAsync 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(ContentDefinition 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(ContentDefinition definition) { m_widgetService.addConfigurations(definition.getConfigurations()); I_Type baseType = definition.getTypes().get(definition.getEntityTypeName()); m_vie.registerTypes(baseType, definition.getTypes()); m_vie.registerTypes(baseType, definition.getTypes()); m_vie.registerEntity(definition.getEntity()); } /** * @see com.alkacon.acacia.client.I_InlineHtmlUpdateHandler#reinitWidgets(com.alkacon.acacia.client.I_InlineFormParent) */ public void reinitWidgets(I_InlineFormParent 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) { Entity entity = (Entity)m_vie.getEntity(entityId); if (entity != null) { boolean initUndo = (m_entity == null) || !entity.getId().equals(m_entity.getId()); m_entity = entity; I_Type type = m_vie.getType(m_entity.getTypeName()); m_formPanel = new FlowPanel(); context.add(m_formPanel); AttributeHandler.setScrollElement(scrollParent); ButtonBarHandler.INSTANCE.setWidgetService(m_widgetService); if (m_rootHandler == null) { m_rootHandler = new RootHandler(); } 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) { UndoRedoHandler.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) { Entity entity = (Entity)m_vie.getEntity(entityId); if (entity != null) { boolean initUndo = (m_entity == null) || !entity.getId().equals(m_entity.getId()); m_entity = entity; I_Type type = m_vie.getType(m_entity.getTypeName()); m_formPanel = new FlowPanel(); context.add(m_formPanel); AttributeHandler.setScrollElement(scrollParent); ButtonBarHandler.INSTANCE.setWidgetService(m_widgetService); if (m_rootHandler == null) { m_rootHandler = new RootHandler(); } 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) { UndoRedoHandler.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_InlineFormParent formParent) { m_entity = (Entity)m_vie.getEntity(entityId); if (m_entity != null) { m_rootHandler = new RootHandler(); m_validationHandler.setContentService(m_service); m_validationHandler.registerEntity(m_entity); m_validationHandler.setRootHandler(m_rootHandler); I_Type type = m_vie.getType(m_entity.getTypeName()); ButtonBarHandler.INSTANCE.setWidgetService(m_widgetService); m_widgetService.getRendererForType(type).renderInline(m_entity, formParent, this); UndoRedoHandler.getInstance().initialize(m_entity, this, m_rootHandler); } } /** * Re-renders the form with the given entity data.

* * @param newContent the entity data */ public void rerenderForm(I_Entity newContent) { m_validationHandler.setPaused(true, m_entity); m_vie.changeEntityContentValues(m_entity, newContent); I_Type type = m_vie.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 VIE 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(ValidationResult result) { callback.execute(); if ((result != null) && result.hasErrors()) { // ValidationHandler.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 VIE 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) { I_Entity entity = m_vie.getEntity(entityId); if (entity != null) { entities.add(com.alkacon.acacia.shared.Entity.serializeEntity(entity)); } } saveEntities(entities, clearOnSuccess, callback); } /** * Saves the given entity.

* * @param entity the entity * @param clearOnSuccess true to clear all entities from VIE on success * @param callback the callback executed on success */ public void saveEntity(I_Entity entity, final boolean clearOnSuccess, final Command callback) { AsyncCallback asyncCallback = new AsyncCallback() { public void onFailure(Throwable caught) { onRpcError(caught); } public void onSuccess(ValidationResult result) { callback.execute(); if (clearOnSuccess) { destroyForm(true); } } }; getService().saveEntity(com.alkacon.acacia.shared.Entity.serializeEntity(entity), asyncCallback); } /** * Saves the given entity.

* * @param entityId the entity id * @param clearOnSuccess true to clear all entities from VIE on success * @param callback the callback executed on success */ public void saveEntity(String entityId, boolean clearOnSuccess, Command callback) { I_Entity entity = m_vie.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) { I_Entity entity = m_vie.getEntity(entityId); saveEntity(entity, false, callback); } /** * @see com.alkacon.acacia.client.I_InlineHtmlUpdateHandler#updateHtml(com.alkacon.acacia.client.I_InlineFormParent, com.google.gwt.user.client.Command) */ public void updateHtml(final I_InlineFormParent formParent, final Command onSuccess) { AsyncCallback callback = new AsyncCallback() { public void onFailure(Throwable caught) { onRpcError(caught); } public void onSuccess(EntityHtml result) { formParent.replaceHtml(result.getHtmlContent()); onSuccess.execute(); } }; getService().updateEntityHtml( com.alkacon.acacia.shared.Entity.serializeEntity(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(); UndoRedoHandler.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 validation handler.

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

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

* * @param element the element */ protected void initEditOverlay(Element element) { InlineEditOverlay.removeAll(); m_editOverlay = InlineEditOverlay.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; InlineEditOverlay.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() { InlineEditOverlay.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