/* * This library is part of OpenCms - * the Open Source Content Management System * * Copyright (c) Alkacon Software GmbH (http://www.alkacon.com) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * For further information about Alkacon Software, please see the * company website: http://www.alkacon.com * * For further information about OpenCms, please see the * project website: http://www.opencms.org * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package org.opencms.gwt.client.ui.contenteditor; import org.opencms.gwt.client.CmsCoreProvider; import org.opencms.gwt.client.I_CmsEditableData; import org.opencms.gwt.client.Messages; import org.opencms.gwt.client.rpc.CmsRpcAction; import org.opencms.gwt.client.ui.CmsAlertDialog; import org.opencms.gwt.client.ui.CmsCancelCloseException; import org.opencms.gwt.client.ui.CmsConfirmDialog; import org.opencms.gwt.client.ui.CmsIFrame; import org.opencms.gwt.client.ui.CmsPopup; import org.opencms.gwt.client.ui.I_CmsConfirmDialogHandler; import org.opencms.gwt.client.ui.css.I_CmsLayoutBundle; import org.opencms.gwt.client.util.CmsDebugLog; import org.opencms.gwt.client.util.CmsDomUtil; import org.opencms.gwt.client.util.CmsDomUtil.Method; import org.opencms.util.CmsStringUtil; import java.util.HashMap; import java.util.Map; import com.google.gwt.dom.client.FormElement; import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.user.client.Command; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.Window.ClosingEvent; import com.google.gwt.user.client.Window.ClosingHandler; import com.google.gwt.user.client.ui.RootPanel; /** * XML content editor dialog.<p> * * @since 8.0.0 */ public final class CmsContentEditorDialog { /** Name of exported dialog close function. */ private static final String CLOSING_METHOD_NAME = "cms_ade_closeEditorDialog"; /** Name attribute value for editor iFrame. */ private static final String EDITOR_IFRAME_NAME = "cmsAdvancedDirectEditor"; /** The dialog instance. */ private static CmsContentEditorDialog INSTANCE; /** The window closing handler registration. */ private HandlerRegistration m_closingHandlerRegistration; /** The popup instance. */ private CmsPopup m_dialog; /** The currently edit element data. */ private I_CmsEditableData m_editableData; /** The editor handler. */ private I_CmsContentEditorHandler m_editorHandler; /** The form element. */ private FormElement m_form; /** Flag indicating if a new resource needs to created. */ private boolean m_isNew; /** * Hiding constructor.<p> */ private CmsContentEditorDialog() { exportClosingMethod(); } /** * Returns the dialogs instance.<p> * * @return the dialog instance */ public static CmsContentEditorDialog get() { if (INSTANCE == null) { INSTANCE = new CmsContentEditorDialog(); } return INSTANCE; } /** * Closes the dialog.<p> */ static void closeEditDialog() { get().close(); } /** * Opens the content editor dialog for the given element.<p> * * @param editableData the editable data * @param isNew <code>true</code> when creating a new resource * @param editorHandler the editor handler */ public void openEditDialog( final I_CmsEditableData editableData, boolean isNew, I_CmsContentEditorHandler editorHandler) { if ((m_dialog != null) && m_dialog.isShowing()) { CmsDebugLog.getInstance().printLine("Dialog is already open, cannot open another one."); return; } m_isNew = isNew; m_editableData = editableData; m_editorHandler = editorHandler; if (m_isNew || (editableData.getStructureId() == null)) { openDialog(); } else { CmsRpcAction<String> action = new CmsRpcAction<String>() { @Override public void execute() { show(true); CmsCoreProvider.getVfsService().getSitePath(getEditableData().getStructureId(), this); } @Override protected void onResponse(String result) { if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(result)) { getEditableData().setSitePath(result); openDialog(); } else { CmsAlertDialog alert = new CmsAlertDialog( Messages.get().key(Messages.ERR_TITLE_ERROR_0), Messages.get().key(Messages.ERR_RESOURCE_UNAVAILABLE_1, getEditableData().getSitePath())); alert.center(); } stop(false); } }; action.execute(); } } /** * Closes the dialog.<p> */ protected void close() { if (m_dialog != null) { m_dialog.hide(); m_dialog = null; m_editorHandler.onClose(m_editableData.getSitePath(), m_isNew); m_editorHandler = null; } if (m_form != null) { m_form.removeFromParent(); m_form = null; } if (m_closingHandlerRegistration != null) { m_closingHandlerRegistration.removeHandler(); m_closingHandlerRegistration = null; } } /** * Returns the editable data.<p> * * @return the editable data */ protected I_CmsEditableData getEditableData() { return m_editableData; } /** * Execute on window close.<p> * Will ask the user if the edited content should be saved.<p> */ protected void onWindowClose() { boolean savePage = Window.confirm(Messages.get().key( Messages.GUI_EDITOR_SAVE_BEFORE_LEAVING_1, m_editableData.getSitePath())); if (savePage) { saveEditorContent(); } } /** * Opens the dialog for the given sitepath.<p> */ protected void openDialog() { m_dialog = new CmsPopup(Messages.get().key(Messages.GUI_DIALOG_CONTENTEDITOR_TITLE_0) + " - " + (m_isNew ? m_editableData.getNewTitle() : m_editableData.getSitePath())); m_dialog.addStyleName(I_CmsLayoutBundle.INSTANCE.contentEditorCss().contentEditor()); // calculate width int width = Window.getClientWidth(); width = (width < 1350) ? width - 50 : 1300; m_dialog.setWidth(width); // calculate height int height = Window.getClientHeight() - 50; height = (height < 645) ? 645 : height; m_dialog.setHeight(height); m_dialog.setGlassEnabled(true); m_dialog.setUseAnimation(false); CmsIFrame editorFrame = new CmsIFrame(EDITOR_IFRAME_NAME, ""); m_dialog.addDialogClose(new Command() { /** * @see com.google.gwt.user.client.Command#execute() */ public void execute() { CmsConfirmDialog confirmDlg = new CmsConfirmDialog(Messages.get().key( Messages.GUI_EDITOR_CLOSE_CAPTION_0), Messages.get().key(Messages.GUI_EDITOR_CLOSE_TEXT_0)); confirmDlg.setHandler(new I_CmsConfirmDialogHandler() { public void onClose() { // do nothing } public void onOk() { CmsContentEditorDialog.this.close(); } }); confirmDlg.center(); // Let the confirm dialog handle the closing throw new CmsCancelCloseException(); } }); m_dialog.add(editorFrame); m_dialog.center(); m_form = generateForm(); RootPanel.getBodyElement().appendChild(m_form); m_form.submit(); // adding on close handler m_closingHandlerRegistration = Window.addWindowClosingHandler(new ClosingHandler() { public void onWindowClosing(ClosingEvent event) { onWindowClose(); } }); } /** * Exports the close method to the window object, so it can be accessed from within the content editor iFrame.<p> */ private native void exportClosingMethod() /*-{ $wnd[@org.opencms.gwt.client.ui.contenteditor.CmsContentEditorDialog::CLOSING_METHOD_NAME] = function() { @org.opencms.gwt.client.ui.contenteditor.CmsContentEditorDialog::closeEditDialog()(); }; }-*/; /** * Generates the form to post to the editor frame.<p> * * @return the form element */ private FormElement generateForm() { // create a form to submit a post request to the editor JSP Map<String, String> formValues = new HashMap<String, String>(); if (m_editableData.getSitePath() != null) { formValues.put("resource", m_editableData.getSitePath()); } if (m_editableData.getElementLanguage() != null) { formValues.put("elementlanguage", m_editableData.getElementLanguage()); } if (m_editableData.getElementName() != null) { formValues.put("elementname", m_editableData.getElementName()); } formValues.put("backlink", CmsCoreProvider.get().getContentEditorBacklinkUrl()); formValues.put("redirect", "true"); formValues.put("directedit", "true"); if (m_isNew) { formValues.put("newlink", m_editableData.getNewLink()); formValues.put("editortitle", m_editableData.getNewTitle()); } FormElement formElement = CmsDomUtil.generateHiddenForm(CmsCoreProvider.get().link( CmsCoreProvider.get().getContentEditorUrl()), Method.post, EDITOR_IFRAME_NAME, formValues); return formElement; } /** * Saves the current editor content synchronously.<p> */ private native void saveEditorContent() /*-{ var iFrame = $wnd.frames[@org.opencms.gwt.client.ui.contenteditor.CmsContentEditorDialog::EDITOR_IFRAME_NAME]; if (iFrame != null) { var editFrame = iFrame["edit"]; if (editFrame != null) { var editorFrame = editFrame.frames["editform"]; if (editorFrame != null) { var editForm = editorFrame.$("#EDITOR"); editForm.find("input[name='action']").attr("value", "saveexit"); if (editForm != null) { var data = editForm.serializeArray(editForm); editorFrame.$.ajax({ type : 'POST', async : false, url : editForm.attr("action"), data : data, success : function(result) { // nothing to do }, dataType : "html" }); } } } } }-*/; }