001/*
002 * the Open Source Content Management System
003 *
004 * Copyright (c) Alkacon Software GmbH & Co. KG (http://www.alkacon.com)
005 *
006 * This library is free software; you can redistribute it and/or
007 * modify it under the terms of the GNU Lesser General Public
008 * License as published by the Free Software Foundation; either
009 * version 2.1 of the License, or (at your option) any later version.
010 *
011 * This library is distributed in the hope that it will be useful,
012 * but WITHOUT ANY WARRANTY; without even the implied warranty of
013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014 * Lesser General Public License for more details.
015 *
016 * For further information about Alkacon Software, please see the
017 * company website: http://www.alkacon.com
018 *
019 * For further information about OpenCms, please see the
020 * project website: http://www.opencms.org
021 *
022 * You should have received a copy of the GNU Lesser General Public
023 * License along with this library; if not, write to the Free Software
024 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
025 */
026
027package org.opencms.ade.postupload.client.ui;
028
029import org.opencms.ade.postupload.client.Messages;
030import org.opencms.ade.postupload.shared.CmsPostUploadDialogBean;
031import org.opencms.ade.postupload.shared.CmsPostUploadDialogPanelBean;
032import org.opencms.ade.postupload.shared.rpc.I_CmsPostUploadDialogService;
033import org.opencms.ade.postupload.shared.rpc.I_CmsPostUploadDialogServiceAsync;
034import org.opencms.gwt.client.CmsCoreProvider;
035import org.opencms.gwt.client.rpc.CmsRpcAction;
036import org.opencms.gwt.client.rpc.CmsRpcPrefetcher;
037import org.opencms.gwt.client.ui.CmsErrorDialog;
038import org.opencms.gwt.client.ui.CmsFrameDialog;
039import org.opencms.gwt.client.ui.CmsPushButton;
040import org.opencms.gwt.client.ui.CmsScrollPanel;
041import org.opencms.gwt.client.ui.I_CmsButton.ButtonColor;
042import org.opencms.gwt.client.ui.I_CmsButton.ButtonStyle;
043import org.opencms.util.CmsUUID;
044
045import java.util.ArrayList;
046import java.util.List;
047
048import com.google.gwt.core.client.GWT;
049import com.google.gwt.event.dom.client.ClickEvent;
050import com.google.gwt.event.dom.client.ClickHandler;
051import com.google.gwt.user.client.Command;
052import com.google.gwt.user.client.Window;
053import com.google.gwt.user.client.rpc.ServiceDefTarget;
054
055/**
056 * Provides a dialog.<p>
057 *
058 * @since 8.0.0
059 */
060public class CmsUploadPropertyDialog {
061
062    /** The panel for the content. */
063    CmsScrollPanel m_dialogContent = GWT.create(CmsScrollPanel.class);
064
065    /** The pre fetched date. */
066    CmsPostUploadDialogBean m_dialogData;
067
068    /** The index of the currently displayed resource. */
069    int m_dialogIndex;
070
071    /** List of resource uuids. */
072    List<CmsUUID> m_resources;
073
074    /** The advanced button. */
075    private CmsPushButton m_buttonAdvanced = new CmsPushButton();
076
077    /** The back button. */
078    private CmsPushButton m_buttonBack = new CmsPushButton();
079
080    /** The cancel button. */
081    private CmsPushButton m_buttonClose = new CmsPushButton();
082
083    /** The save button. */
084    private CmsPushButton m_buttonNext = new CmsPushButton();
085
086    /** The command that is executed on close action. */
087    private Command m_closeCommand;
088
089    /** The dialog service. */
090    private I_CmsPostUploadDialogServiceAsync m_dialogService;
091
092    /** The frame dialog. */
093    private CmsFrameDialog m_frameDialog = new CmsFrameDialog();
094
095    /** The next action to execute after a Save operation. */
096    private Runnable m_nextAction;
097
098    /** The current dialog bean. */
099    private CmsPostUploadDialogPanelBean m_panelData;
100
101    /** The current property panel. */
102    private CmsUploadPropertyPanel m_uploadPropertyPanel;
103
104    /**
105     * Public constructor.<p>
106     */
107    public CmsUploadPropertyDialog() {
108
109        m_frameDialog.setContent(m_dialogContent);
110        m_dialogContent.addStyleName(
111            org.opencms.ade.postupload.client.ui.css.I_CmsLayoutBundle.INSTANCE.dialogCss().propertyDialog());
112        try {
113            m_dialogData = (CmsPostUploadDialogBean)CmsRpcPrefetcher.getSerializedObjectFromDictionary(
114                getDialogService(),
115                CmsPostUploadDialogBean.DICT_NAME);
116            m_resources = new ArrayList<CmsUUID>(m_dialogData.getResources().keySet());
117        } catch (Exception e) {
118            CmsErrorDialog.handleException(
119                new Exception(
120                    "Deserialization of upload hook data failed."
121                        + "This may be caused by expired java-script resources, "
122                        + " please clear your browser cache and try again.",
123                    e));
124
125        }
126        if (!m_dialogData.getResources().isEmpty()) {
127            createButtons();
128        }
129    }
130
131    /**
132     * Closes the dialog.<p>
133     */
134    public void closeDialog() {
135
136        if (m_closeCommand != null) {
137            m_closeCommand.execute();
138        }
139        m_frameDialog.hide();
140    }
141
142    /**
143     * Returns <code>true</code> if we are currently in the explorer mode.<p>
144     *
145     * @return <code>true</code> if we are currently in the explorer mode
146     */
147    public native boolean isExplorerMode() /*-{
148
149                if ($wnd.self.name == 'explorer_files') {
150                        return true;
151                }
152                return false;
153    }-*/;
154
155    /**
156     * Returns if the dialog is in iFrame mode.<p>
157     *
158     * @return <code>true</code> if the dialog is in iFrame mode
159     */
160    public boolean isIFrameMode() {
161
162        return CmsFrameDialog.hasParentFrame();
163    }
164
165    /**
166     * Loads and shows the content of the dialog inside a popup.<p>
167     */
168    public void loadAndShow() {
169
170        loadDialogBean(m_resources.get(m_dialogIndex));
171    }
172
173    /**
174     * Runs the next action after finishing a save operation.
175     */
176    public void runAction() {
177
178        if (m_nextAction != null) {
179            m_nextAction.run();
180            m_nextAction = null;
181        }
182    }
183
184    /**
185     * Adds a close "button" to the top of the popup.<p>
186     *
187     * @param cmd the command that should be executed when the close button is clicked
188     */
189    public void setCloseCmd(final Command cmd) {
190
191        m_closeCommand = cmd;
192    }
193
194    /**
195     * Delegation method.<p>
196     *
197     * @param height the height
198     *
199     * @see org.opencms.gwt.client.ui.CmsFrameDialog#setHeight(int)
200     */
201    public void setHeight(int height) {
202
203        m_frameDialog.setHeight(height);
204
205    }
206
207    /**
208     * Delegation method.<p>
209     *
210     * @param title the title
211     *
212     * @see org.opencms.gwt.client.ui.CmsFrameDialog#setTitle(java.lang.String)
213     */
214    public void setTitle(String title) {
215
216        m_frameDialog.setTitle(title);
217    }
218
219    /**
220     * Delegation method.<p>
221     *
222     * @param width the width
223     *
224     * @see org.opencms.gwt.client.ui.CmsFrameDialog#setWidth(int)
225     */
226    public void setWidth(int width) {
227
228        m_frameDialog.setWidth(width);
229    }
230
231    /**
232     * Updates the height of the dialog to fit the content.<p>
233     */
234    public void updateHeight() {
235
236        int height = m_dialogContent.getOffsetHeight() + 76;
237        setHeight(height);
238    }
239
240    /**
241     *
242     */
243    protected void actionAdvanced() {
244
245        String resPath = m_dialogData.getResources().get(m_resources.get(m_dialogIndex));
246        String url = CmsCoreProvider.get().link("/system/workplace/commons/property_advanced.jsp?resource=" + resPath);
247        Window.Location.assign(url);
248    }
249
250    /**
251     * Action to display the dialog content for the previous resource.<p>
252     */
253    protected void actionBack() {
254
255        if (m_dialogIndex <= 0) {
256            return;
257        }
258
259        m_uploadPropertyPanel.getPropertyEditor().getForm().validateAndSubmit();
260        m_nextAction = new Runnable() {
261
262            public void run() {
263
264                m_dialogIndex--;
265                loadDialogBean(m_resources.get(m_dialogIndex));
266            }
267        };
268    }
269
270    /**
271     * Action to close the dialog.<p>
272     */
273    protected void actionClose() {
274
275        m_uploadPropertyPanel.getPropertyEditor().getForm().validateAndSubmit();
276        m_nextAction = new Runnable() {
277
278            public void run() {
279
280                closeDialog();
281            }
282        };
283    }
284
285    /**
286     * Action to display the dialog content for the next resource.<p>
287     */
288    protected void actionNext() {
289
290        if (m_dialogIndex >= (m_resources.size() - 1)) {
291            return;
292        }
293
294        m_uploadPropertyPanel.getPropertyEditor().getForm().validateAndSubmit();
295        m_nextAction = new Runnable() {
296
297            public void run() {
298
299                m_dialogIndex++;
300                loadDialogBean(m_resources.get(m_dialogIndex));
301            }
302        };
303    }
304
305    /**
306     * Returns the dialog service instance.<p>
307     *
308     * @return the dialog service instance
309     */
310    protected I_CmsPostUploadDialogServiceAsync getDialogService() {
311
312        if (m_dialogService == null) {
313            m_dialogService = GWT.create(I_CmsPostUploadDialogService.class);
314            String serviceUrl = CmsCoreProvider.get().link("org.opencms.ade.postupload.CmsPostUploadDialogService.gwt");
315            ((ServiceDefTarget)m_dialogService).setServiceEntryPoint(serviceUrl);
316        }
317        return m_dialogService;
318    }
319
320    /**
321     * Retrieves the resource information from the server,
322     * creates a the dialogs content and puts the content into the mainpanel.<p>
323     *
324     * @param uuid the structure id to show the dialog for
325     */
326    protected void loadDialogBean(final CmsUUID uuid) {
327
328        CmsRpcAction<CmsPostUploadDialogPanelBean> callback = new CmsRpcAction<CmsPostUploadDialogPanelBean>() {
329
330            /**
331             * @see org.opencms.gwt.client.rpc.CmsRpcAction#execute()
332             */
333            @Override
334            public void execute() {
335
336                getDialogService().load(
337                    uuid,
338                    m_dialogData.isUsePropertyConfiguration(),
339                    m_dialogData.isAddBasicProperties(),
340                    this);
341            }
342
343            /**
344             * @see org.opencms.gwt.client.rpc.CmsRpcAction#onFailure(java.lang.Throwable)
345             */
346            @Override
347            public void onFailure(Throwable t) {
348
349                super.onFailure(t);
350            }
351
352            /**
353             * @see org.opencms.gwt.client.rpc.CmsRpcAction#onResponse(java.lang.Object)
354             */
355            @Override
356            protected void onResponse(CmsPostUploadDialogPanelBean result) {
357
358                updateDialog(result);
359            }
360        };
361        callback.execute();
362    }
363
364    /**
365     * Updates the dialog.<p>
366     *
367     * @param result the result
368     */
369    protected void updateDialog(CmsPostUploadDialogPanelBean result) {
370
371        m_panelData = result;
372
373        if (m_dialogData.getResources().size() > 1) {
374            if (m_dialogIndex == 0) {
375                m_buttonBack.disable(
376                    org.opencms.ade.postupload.client.Messages.get().key(
377                        org.opencms.ade.postupload.client.Messages.GUI_DIALOG_INFO_FIRST_RESOURCE_0));
378            } else {
379                m_buttonBack.enable();
380            }
381            if (m_dialogIndex == (m_dialogData.getResources().size() - 1)) {
382                m_buttonNext.disable(
383                    org.opencms.ade.postupload.client.Messages.get().key(
384                        org.opencms.ade.postupload.client.Messages.GUI_DIALOG_INFO_LAST_RESOURCE_0));
385            } else {
386                m_buttonNext.enable();
387            }
388        }
389
390        // Disable finish button if current resource has properties with required validation
391        // and is not the last resource in the list.
392        // Since the resources with required validation come first in the list from the server,
393        // this prevents users from quitting the dialog unless the validation for all resources
394        // for which it is necessary has succeeded.
395        // Since the finish button triggers a validation for the current resource, enabling it for
396        // the last resource is OK.
397        if (!m_dialogData.getIdsWithRequiredValidation().contains(result.getStructureId())
398            || (m_dialogIndex == (m_dialogData.getResources().size() - 1))) {
399            m_buttonClose.enable();
400        } else {
401            m_buttonClose.disable(null);
402        }
403
404        m_uploadPropertyPanel = new CmsUploadPropertyPanel(this, m_dialogData, m_panelData);
405        m_dialogContent.setWidget(m_uploadPropertyPanel);
406        m_frameDialog.setWidth(975);
407        if (!m_frameDialog.isShowing()) {
408            m_frameDialog.show();
409            m_dialogContent.onResizeDescendant();
410        }
411    }
412
413    /**
414     * Creates the buttons.<p>
415     */
416    private void createButtons() {
417
418        m_buttonClose.setButtonStyle(ButtonStyle.TEXT, ButtonColor.GREEN);
419        m_buttonClose.setTitle(Messages.get().key(Messages.GUI_DIALOG_BUTTON_CLOSE_0));
420        m_buttonClose.setText(Messages.get().key(Messages.GUI_DIALOG_BUTTON_CLOSE_0));
421        m_buttonClose.setUseMinWidth(true);
422        m_buttonClose.addClickHandler(new ClickHandler() {
423
424            /**
425             * @see com.google.gwt.event.dom.client.ClickHandler#onClick(com.google.gwt.event.dom.client.ClickEvent)
426             */
427            public void onClick(ClickEvent event) {
428
429                actionClose();
430            }
431        });
432        m_frameDialog.addButton(m_buttonClose);
433
434        if (m_dialogData.getResources().size() > 1) {
435            m_buttonNext.setTitle(Messages.get().key(Messages.GUI_DIALOG_BUTTON_NEXT_0));
436            m_buttonNext.setText(Messages.get().key(Messages.GUI_DIALOG_BUTTON_NEXT_0));
437            m_buttonNext.setUseMinWidth(true);
438            m_buttonNext.addClickHandler(new ClickHandler() {
439
440                /**
441                 * @see com.google.gwt.event.dom.client.ClickHandler#onClick(com.google.gwt.event.dom.client.ClickEvent)
442                 */
443                public void onClick(ClickEvent event) {
444
445                    actionNext();
446                }
447            });
448            m_frameDialog.addButton(m_buttonNext);
449
450            m_buttonBack.setTitle(Messages.get().key(Messages.GUI_DIALOG_BUTTON_BACK_0));
451            m_buttonBack.setText(Messages.get().key(Messages.GUI_DIALOG_BUTTON_BACK_0));
452            m_buttonBack.setUseMinWidth(true);
453            m_buttonBack.addClickHandler(new ClickHandler() {
454
455                /**
456                 * @see com.google.gwt.event.dom.client.ClickHandler#onClick(com.google.gwt.event.dom.client.ClickEvent)
457                 */
458                public void onClick(ClickEvent event) {
459
460                    actionBack();
461                }
462            });
463            m_frameDialog.addButton(m_buttonBack);
464        }
465
466        if (isExplorerMode() && (m_resources.size() == 1)) {
467            m_buttonAdvanced.setButtonStyle(ButtonStyle.TEXT, ButtonColor.RED);
468            m_buttonAdvanced.setTitle(Messages.get().key(Messages.GUI_DIALOG_BUTTON_ADVANCED_0));
469            m_buttonAdvanced.setText(Messages.get().key(Messages.GUI_DIALOG_BUTTON_ADVANCED_0));
470            m_buttonAdvanced.setUseMinWidth(true);
471            m_buttonAdvanced.addClickHandler(new ClickHandler() {
472
473                /**
474                 * @see com.google.gwt.event.dom.client.ClickHandler#onClick(com.google.gwt.event.dom.client.ClickEvent)
475                 */
476                public void onClick(ClickEvent event) {
477
478                    actionAdvanced();
479                }
480            });
481            m_frameDialog.addButton(m_buttonAdvanced);
482        }
483    }
484
485}