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.ade.galleries.client.preview.ui;
029
030import org.opencms.ade.galleries.client.Messages;
031import org.opencms.ade.galleries.client.preview.CmsImagePreviewHandler;
032import org.opencms.ade.galleries.client.ui.css.I_CmsLayoutBundle;
033import org.opencms.ade.galleries.shared.CmsImageInfoBean;
034import org.opencms.ade.galleries.shared.I_CmsGalleryProviderConstants.GalleryMode;
035import org.opencms.gwt.client.CmsCoreProvider;
036import org.opencms.gwt.client.util.CmsClientStringUtil;
037import org.opencms.gwt.client.util.I_CmsSimpleCallback;
038
039import java.util.Map;
040
041import com.google.gwt.core.client.Scheduler;
042import com.google.gwt.core.client.Scheduler.ScheduledCommand;
043import com.google.gwt.dom.client.Style.Unit;
044import com.google.gwt.event.logical.shared.SelectionEvent;
045import com.google.gwt.event.logical.shared.SelectionHandler;
046import com.google.gwt.user.client.Command;
047import com.google.gwt.user.client.Window;
048import com.google.gwt.user.client.ui.FlowPanel;
049import com.google.gwt.user.client.ui.Image;
050import com.google.gwt.user.client.ui.Widget;
051
052/**
053 * Provides a widget for the image preview dialog .<p>
054 *
055 * @since 8.0.
056 */
057public class CmsImagePreviewDialog extends A_CmsPreviewDialog<CmsImageInfoBean> {
058
059    /** The default min height of the image. */
060    public static final int IMAGE_HEIGHT_MAX = 361;
061
062    /** The default min width of the image. */
063    public static final int IMAGE_WIDTH_MAX = 640;
064
065    /** Style name for distinguishing whether the properties tab is currently active or not. */
066    public static final String STYLE_PROPERTIES_TAB_ACTIVE = "propertiesTabActive";
067
068    /** The preview handler. */
069    private CmsImagePreviewHandler m_handler;
070
071    /** The advanced image tab. */
072    private CmsImageAdvancedTab m_imageAdvancedTab;
073
074    /** The formats tab. */
075    private CmsImageEditorTab m_imageEditorFormatsTab;
076
077    /** The format tab. */
078    private CmsImageFormatsTab m_imageFormatTab;
079
080    /** The initial fill flag. */
081    private boolean m_initialFill = true;
082
083    /** The preview image. */
084    private Image m_previewImage;
085
086    /** The properties tab. */
087    private CmsPropertiesTab m_propertiesTab;
088
089    /**
090     * The constructor.<p>
091     *
092     * @param dialogMode the dialog mode
093     * @param dialogHeight the dialog height to set
094     * @param dialogWidth the dialog width to set
095     * @param disableSelection true if selection from the preview should be disabled
096     */
097    public CmsImagePreviewDialog(GalleryMode dialogMode, int dialogHeight, int dialogWidth, boolean disableSelection) {
098
099        super(dialogMode, dialogHeight, dialogWidth, disableSelection);
100        // set the line-height to the height of the preview panel to be able to center the image vertically
101        m_previewHolder.getElement().getStyle().setProperty("lineHeight", m_previewHeight - 2, Unit.PX);
102    }
103
104    /**
105     * Fills the content of the tabs panel.<p>
106     *
107     * @param infoBean the bean containing the parameter
108     */
109    @Override
110    public void fillContent(CmsImageInfoBean infoBean) {
111
112        // properties tab
113        m_propertiesTab.fillContent(infoBean);
114        if (m_initialFill) {
115            if (getGalleryMode() == GalleryMode.widget) {
116                m_imageFormatTab.fillContent(infoBean);
117            }
118            if (getGalleryMode() == GalleryMode.editor) {
119                m_imageFormatTab.fillContent(infoBean);
120                m_imageEditorFormatsTab.fillContent(infoBean);
121                m_imageAdvancedTab.fillContent(infoBean);
122            }
123            m_initialFill = false;
124        }
125        fillPreviewPanel(infoBean);
126    }
127
128    /**
129     * Fills the preview panel.<p>
130     *
131     * @param infoBean the image info
132     */
133    public void fillPreviewPanel(CmsImageInfoBean infoBean) {
134
135        FlowPanel panel = new FlowPanel();
136        panel.addStyleName(I_CmsLayoutBundle.INSTANCE.previewDialogCss().imagePanel());
137        m_previewImage = new Image();
138        if (CmsClientStringUtil.checkIsPathOrLinkToSvg(infoBean.getResourcePath())) {
139            m_previewImage.getElement().getStyle().setWidth(100, Unit.PCT);
140            m_previewImage.getElement().getStyle().setHeight(100, Unit.PCT);
141            m_previewImage.getElement().getStyle().setProperty("objectFit", "contain");
142        }
143        StringBuffer urlScaled = new StringBuffer(128);
144        String src = infoBean.getViewLink() != null
145        ? infoBean.getViewLink()
146        : CmsCoreProvider.get().link(infoBean.getResourcePath());
147        urlScaled.append(src);
148        m_previewPanel.setWidget(panel); // Need to already attach it here so we can measure the dimensions
149        m_handler.setImageContainerSize(panel.getOffsetWidth(), panel.getOffsetHeight());
150        String scalingParams = m_handler.getPreviewScaleParam(infoBean.getHeight(), infoBean.getWidth());
151        urlScaled.append("?").append(scalingParams);
152        // add time stamp to override image caching
153        urlScaled.append("&time=").append(System.currentTimeMillis());
154        m_previewImage.setUrl(urlScaled.toString());
155        getHandler().getFocalPointController().updateImage(panel, m_previewImage);
156        panel.add(m_previewImage);
157    }
158
159    /**
160     * Returns the dialog width.<p>
161     *
162     * @return the dialog width
163     */
164    public int getDialogWidth() {
165
166        return m_dialogWidth;
167    }
168
169    /**
170     * Adds necessary attributes to the map.<p>
171     *
172     * @param attributes the attribute map
173     * @param callback the callback to execute
174     */
175    public void getImageAttributes(Map<String, String> attributes, I_CmsSimpleCallback<Map<String, String>> callback) {
176
177        if (getGalleryMode() == GalleryMode.editor) {
178            m_imageEditorFormatsTab.getImageAttributes(attributes);
179            m_imageAdvancedTab.getImageAttributes(attributes, callback);
180        } else {
181            callback.execute(attributes);
182        }
183    }
184
185    /**
186     * Returns the preview height.<p>
187     *
188     * @return the preview height
189     */
190    public int getPreviewHeight() {
191
192        return m_previewHeight;
193    }
194
195    /**
196     * @see org.opencms.ade.galleries.client.preview.ui.A_CmsPreviewDialog#hasChanges()
197     */
198    @Override
199    public boolean hasChanges() {
200
201        return m_propertiesTab.isChanged();
202    }
203
204    /**
205     * Initializes the preview.<p>
206     *
207     * @param handler the preview handler
208     */
209    public void init(CmsImagePreviewHandler handler) {
210
211        m_handler = handler;
212        m_propertiesTab = new CmsPropertiesTab(m_galleryMode, m_dialogHeight, m_dialogWidth, m_handler);
213        m_tabbedPanel.add(m_propertiesTab, Messages.get().key(Messages.GUI_PREVIEW_TAB_PROPERTIES_0));
214        if ((m_galleryMode == GalleryMode.editor) || (m_galleryMode == GalleryMode.widget)) {
215            m_imageFormatTab = new CmsImageFormatsTab(m_galleryMode, m_dialogHeight, m_dialogWidth, handler, null);
216            m_tabbedPanel.add(m_imageFormatTab, Messages.get().key(Messages.GUI_PREVIEW_TAB_IMAGEFORMAT_0));
217        }
218        if (getGalleryMode() == GalleryMode.editor) {
219            m_imageEditorFormatsTab = new CmsImageEditorTab(m_galleryMode, m_dialogHeight, m_dialogWidth, handler);
220
221            String hideFormatsParam = Window.Location.getParameter("hideformats");
222            boolean hideFormats = "true".equals(hideFormatsParam);
223            if (!hideFormats) {
224                m_tabbedPanel.add(m_imageEditorFormatsTab, Messages.get().key(Messages.GUI_PREVIEW_TAB_IMAGEOPTIONS_0));
225            }
226
227            m_imageAdvancedTab = new CmsImageAdvancedTab(m_galleryMode, m_dialogHeight, m_dialogWidth, handler);
228            if (!hideFormats) {
229                m_tabbedPanel.add(m_imageAdvancedTab, Messages.get().key(Messages.GUI_PREVIEW_TAB_IMAGEADVANCED_0));
230            }
231        }
232        m_tabbedPanel.addSelectionHandler(new SelectionHandler<Integer>() {
233
234            public void onSelection(SelectionEvent<Integer> event) {
235
236                Scheduler.get().scheduleDeferred(new ScheduledCommand() {
237
238                    @SuppressWarnings("synthetic-access")
239                    public void execute() {
240
241                        updateClassForTab(event.getSelectedItem().intValue());
242                    }
243                });
244
245            }
246        });
247    }
248
249    /**
250     * Resets the image displayed in the preview.<p>
251     *
252     * @param path the image path including scale parameter
253     */
254    public void resetPreviewImage(String path) {
255
256        m_previewImage.setUrl(path);
257    }
258
259    /**
260     * @see org.opencms.ade.galleries.client.preview.ui.A_CmsPreviewDialog#saveChanges(com.google.gwt.user.client.Command)
261     */
262    @Override
263    public void saveChanges(Command afterSaveCommand) {
264
265        if (hasChanges()) {
266            m_propertiesTab.saveProperties(afterSaveCommand);
267        }
268    }
269
270    /**
271     * @see org.opencms.ade.galleries.client.preview.ui.A_CmsPreviewDialog#getHandler()
272     */
273    @Override
274    protected CmsImagePreviewHandler getHandler() {
275
276        return m_handler;
277    }
278
279    /**
280     * @see com.google.gwt.user.client.ui.Widget#onLoad()
281     */
282    @Override
283    protected void onLoad() {
284
285        updateClassForTab(m_tabbedPanel.getSelectedIndex());
286
287    }
288
289    /**
290     * Updates the CSS classes of the preview dialog depending on selected tab.<p>
291     *
292     * @param index the tab index
293     */
294    private void updateClassForTab(int index) {
295
296        Widget widget = m_tabbedPanel.getWidget(index);
297
298        String propertyTabStyle = STYLE_PROPERTIES_TAB_ACTIVE;
299        if (widget == m_propertiesTab) {
300            CmsImagePreviewDialog.this.addStyleName(propertyTabStyle);
301        } else {
302            CmsImagePreviewDialog.this.removeStyleName(propertyTabStyle);
303        }
304    }
305}