001/*
002 * This library is part of OpenCms -
003 * the Open Source Content Management System
004 *
005 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com)
006 *
007 * This library is free software; you can redistribute it and/or
008 * modify it under the terms of the GNU Lesser General Public
009 * License as published by the Free Software Foundation; either
010 * version 2.1 of the License, or (at your option) any later version.
011 *
012 * This library is distributed in the hope that it will be useful,
013 * but WITHOUT ANY WARRANTY; without even the implied warranty of
014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015 * Lesser General Public License for more details.
016 *
017 * For further information about Alkacon Software, please see the
018 * company website: http://www.alkacon.com
019 *
020 * For further information about OpenCms, please see the
021 * project website: http://www.opencms.org
022 *
023 * You should have received a copy of the GNU Lesser General Public
024 * License along with this library; if not, write to the Free Software
025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
026 */
027
028package org.opencms.gwt.client.ui.contextmenu;
029
030import org.opencms.gwt.client.CmsCoreProvider;
031import org.opencms.gwt.client.I_CmsEditableData;
032import org.opencms.gwt.client.rpc.CmsRpcAction;
033import org.opencms.gwt.client.ui.I_CmsToolbarHandler;
034import org.opencms.gwt.client.ui.contenteditor.CmsContentEditorDialog;
035import org.opencms.gwt.client.ui.contenteditor.CmsContentEditorDialog.DialogOptions;
036import org.opencms.gwt.client.ui.contenteditor.I_CmsContentEditorHandler;
037import org.opencms.gwt.client.util.CmsEditableDataUtil;
038import org.opencms.gwt.shared.CmsContextMenuEntryBean;
039import org.opencms.gwt.shared.CmsMenuCommandParameters;
040import org.opencms.gwt.shared.CmsPrepareEditResponse;
041import org.opencms.gwt.shared.I_CmsEditableDataExtensions;
042import org.opencms.util.CmsUUID;
043
044import java.util.Map;
045
046import com.google.gwt.dom.client.FormElement;
047import com.google.gwt.user.client.Timer;
048import com.google.gwt.user.client.ui.RootPanel;
049
050/**
051 * A context menu command for editing an XML content. <p>
052 */
053public final class CmsEditFile implements I_CmsHasContextMenuCommand, I_CmsValidatingContextMenuCommand {
054
055    /** The context menu handler for this command instance. */
056    protected I_CmsContextMenuHandler m_menuHandler;
057
058    /** A flag which indicates whether the window should be reloaded after editing. */
059    protected boolean m_reload;
060
061    /** Flag controlling whether window should be immediately reloaded after finishing. */
062    private boolean m_immediateReload;
063
064    /** A flag indicating if the editor should open in the same window, not using any overlays and iFrames. */
065    private boolean m_useSelf;
066
067    /**
068     * Hidden utility class constructor.<p>
069     */
070    private CmsEditFile() {
071
072        // nothing to do
073    }
074
075    /**
076     * Returns the context menu command according to
077     * {@link org.opencms.gwt.client.ui.contextmenu.I_CmsHasContextMenuCommand}.<p>
078     *
079     * @return the context menu command
080     */
081    public static I_CmsContextMenuCommand getContextMenuCommand() {
082
083        return new CmsEditFile();
084    }
085
086    /**
087     * Actually starts the XML content editor for a given file name.<p>
088     *
089     * @param filename the file name
090     * @param structureId the file structure id
091     */
092    public void doEdit(final String filename, final CmsUUID structureId) {
093
094        I_CmsEditableData editData = new I_CmsEditableData() {
095
096            public String getContextId() {
097
098                return "";
099            }
100
101            public String getEditId() {
102
103                return null;
104            }
105
106            public String getElementId() {
107
108                // TODO Auto-generated method stub
109                return null;
110            }
111
112            public String getElementLanguage() {
113
114                return null;
115            }
116
117            public String getElementName() {
118
119                return null;
120            }
121
122            public I_CmsEditableDataExtensions getExtensions() {
123
124                return CmsEditableDataUtil.parseExtensions("{}");
125            }
126
127            public String getNewLink() {
128
129                return null;
130            }
131
132            public String getNewTitle() {
133
134                return null;
135            }
136
137            public String getNoEditReason() {
138
139                return null;
140            }
141
142            public String getPostCreateHandler() {
143
144                return null;
145            }
146
147            public String getSitePath() {
148
149                return filename;
150            }
151
152            public CmsUUID getStructureId() {
153
154                return structureId;
155            }
156
157            public boolean hasEditHandler() {
158
159                return false;
160            }
161
162            public boolean hasResource() {
163
164                return true;
165            }
166
167            public boolean isUnreleasedOrExpired() {
168
169                return false;
170            }
171
172            public void setSitePath(String sitePath) {
173
174                // nothing to do
175            }
176        };
177        if (m_useSelf) {
178            FormElement form = CmsContentEditorDialog.generateForm(editData, false, "_self", null);
179            RootPanel.getBodyElement().appendChild(form);
180            form.submit();
181        } else {
182
183            I_CmsContentEditorHandler handler = new I_CmsContentEditorHandler() {
184
185                @SuppressWarnings("synthetic-access")
186                public void onClose(
187                    String sitePath,
188                    CmsUUID id,
189                    boolean isNew,
190                    boolean hasChangedSettings,
191                    boolean usedPublishDialog) {
192
193                    if (!m_reload) {
194                        return;
195                    }
196
197                    if (m_immediateReload) {
198                        reloadTop();
199                    }
200
201                    // defer the window.location.reload until after the editor window has closed
202                    // so we don't get another confirmation dialog
203                    Timer timer = new Timer() {
204
205                        @Override
206                        public void run() {
207
208                            reloadTop();
209
210                        }
211
212                    };
213                    timer.schedule(10);
214                }
215            };
216            CmsContentEditorDialog.get().openEditDialog(editData, false, null, new DialogOptions(), handler);
217        }
218    }
219
220    /**
221     * @see org.opencms.gwt.client.ui.contextmenu.I_CmsContextMenuCommand#execute(org.opencms.util.CmsUUID, org.opencms.gwt.client.ui.contextmenu.I_CmsContextMenuHandler, org.opencms.gwt.shared.CmsContextMenuEntryBean)
222     */
223    public void execute(
224        final CmsUUID structureId,
225        final I_CmsContextMenuHandler handler,
226        CmsContextMenuEntryBean bean) {
227
228        m_menuHandler = handler;
229        Map<String, String> params = bean.getParams();
230        final String fileName = params.get(CmsMenuCommandParameters.PARAM_FILENAME);
231        if (fileName == null) {
232            return;
233        }
234        String reloadStr = params.get(CmsMenuCommandParameters.PARAM_RELOAD);
235        m_reload = Boolean.parseBoolean(reloadStr);
236        String useSelfStr = params.get(CmsMenuCommandParameters.PARAM_USE_SELF);
237        m_useSelf = Boolean.parseBoolean(useSelfStr);
238
239        m_immediateReload = Boolean.parseBoolean(params.get("immediateReload"));
240
241        if (handler instanceof I_CmsToolbarHandler) {
242            ((I_CmsToolbarHandler)handler).deactivateCurrentButton();
243        }
244        CmsRpcAction<CmsPrepareEditResponse> prepareEdit = new CmsRpcAction<CmsPrepareEditResponse>() {
245
246            @Override
247            public void execute() {
248
249                start(0, true);
250                CmsCoreProvider.getVfsService().prepareEdit(structureId, fileName, this);
251            }
252
253            @Override
254            public void onResponse(CmsPrepareEditResponse response) {
255
256                stop(false);
257                doEdit(response.getSitePath(), response.getStructureId());
258            }
259        };
260        prepareEdit.execute();
261    }
262
263    /**
264     * @see org.opencms.gwt.client.ui.contextmenu.I_CmsContextMenuCommand#getItemWidget(org.opencms.util.CmsUUID, org.opencms.gwt.client.ui.contextmenu.I_CmsContextMenuHandler, org.opencms.gwt.shared.CmsContextMenuEntryBean)
265     */
266    public A_CmsContextMenuItem getItemWidget(
267        CmsUUID structureId,
268        I_CmsContextMenuHandler handler,
269        CmsContextMenuEntryBean bean) {
270
271        return null;
272    }
273
274    /**
275     * @see org.opencms.gwt.client.ui.contextmenu.I_CmsContextMenuCommand#hasItemWidget()
276     */
277    public boolean hasItemWidget() {
278
279        return false;
280    }
281
282    /**
283     * Checks if we currently have an editor open somewhere.<p>
284     *
285     * @return true if there is an open editor
286     */
287    public native boolean isEditorOpen() /*-{
288        var windowStack = [ $wnd.top ];
289        var allWindows = [];
290        while (windowStack.length > 0) {
291            var current = windowStack.pop();
292            allWindows.push(current);
293            try {
294                for (var i = 0; i < current.frames.length; i++) {
295                    try {
296                        var frameWindow = current.frames[i];
297                        windowStack.push(frameWindow);
298                    } catch (e) {
299                        // ignore
300                    }
301                }
302            } catch (e2) {
303                // ignore
304            }
305
306        }
307        for (var i = 0; i < allWindows.length; i++) {
308            try {
309                var currentWindow = allWindows[i];
310                if (currentWindow.location.href.indexOf("acacia/editor.jsp") >= 0) {
311                    return true;
312                }
313                if (currentWindow.document
314                        .querySelector(".org-opencms-ade-contenteditor-client-css-I_CmsLayoutBundle-I_CmsXmlEditorCss-basePanel") != null) {
315                    return true;
316                }
317            } catch (e) {
318                // ignore
319            }
320        }
321
322        return false;
323
324    }-*/;
325
326    /**
327     * @see org.opencms.gwt.client.ui.contextmenu.I_CmsValidatingContextMenuCommand#validate(org.opencms.gwt.shared.CmsContextMenuEntryBean)
328     */
329    public boolean validate(CmsContextMenuEntryBean entry) {
330
331        try {
332            if (isEditorOpen()) {
333                return false;
334            }
335        } catch (Exception e) {
336            return false;
337        }
338
339        return true;
340    }
341
342    /**
343     * Reloads top frame.<p>
344     */
345    private native void reloadTop() /*-{
346        $wnd.top.location.reload();
347    }-*/;
348}