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