/* * Copyright (c) 2009-2011 Lockheed Martin Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.eurekastreams.web.client.ui.common.form.elements.avatar; import org.eurekastreams.commons.client.ActionProcessor; import org.eurekastreams.server.domain.AvatarUrlGenerator; import org.eurekastreams.server.domain.EntityType; import org.eurekastreams.web.client.events.ClearUploadedImageEvent; import org.eurekastreams.web.client.events.ClearUploadedImageEvent.ImageType; import org.eurekastreams.web.client.events.Observer; import org.eurekastreams.web.client.jsni.WidgetJSNIFacadeImpl; import org.eurekastreams.web.client.ui.Session; import org.eurekastreams.web.client.ui.common.dialog.Dialog; import org.eurekastreams.web.client.ui.common.dialog.imagecrop.ImageCropContent; import org.eurekastreams.web.client.ui.common.form.elements.avatar.strategies.ImageUploadStrategy; import org.eurekastreams.web.client.ui.pages.master.StaticResourceBundle; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.event.dom.client.LoadEvent; import com.google.gwt.event.dom.client.LoadHandler; import com.google.gwt.user.client.Command; import com.google.gwt.user.client.ui.Anchor; import com.google.gwt.user.client.ui.FileUpload; import com.google.gwt.user.client.ui.FlowPanel; import com.google.gwt.user.client.ui.FormPanel; import com.google.gwt.user.client.ui.FormPanel.SubmitCompleteEvent; import com.google.gwt.user.client.ui.FormPanel.SubmitCompleteHandler; import com.google.gwt.user.client.ui.Image; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.Widget; /** * The form element for the avatar upload. Its not a REAL form element because it doesnt save back with the form itself, * its Miss Independent. */ public class AvatarUploadFormElement extends FlowPanel { /** * The panel. */ private final FlowPanel panel = new FlowPanel(); /** * the processor. */ private ActionProcessor processor = null; /** * the upload form. */ FormPanel uploadForm = new FormPanel(); /** * the edit button. */ Anchor editButton; /** * the delete button. */ Anchor deleteButton; /** * the error box. */ FlowPanel errorBox; /** * the avatar container. */ FlowPanel avatarContainer = new FlowPanel(); /** * hidden image for full size avatar, only loaded on resize, never displayed. */ Image hiddenImage; /** * The avatar ID of the person. */ private String avatarId = ""; /** * The image crop content widget. */ private ImageCropContent imageCropDialog; /** * The image upload strategy. */ private final ImageUploadStrategy strategy; /** * Default description if none is provided. */ private static String description = // line break. "Select a JPG, PNG or GIF image from your computer. The maximum file size is 4MB."; /** * Create an avatar upload form element. * * @param label * the label of the element. * @param servletPath * the path to hit to upload the image * @param inProcessor * the processor. * @param inStrategy * the strategy. */ public AvatarUploadFormElement(final String label, final String servletPath, final ActionProcessor inProcessor, final ImageUploadStrategy inStrategy) { this(label, description, servletPath, inProcessor, inStrategy); } /** * Create an avatar upload form element. * * @param label * the label of the element. * @param desc * the description. * @param servletPath * the path to hit to upload the image * @param inProcessor * the processor. * @param inStrategy * the strategy. */ public AvatarUploadFormElement(final String label, final String desc, final String servletPath, final ActionProcessor inProcessor, final ImageUploadStrategy inStrategy) { description = desc; strategy = inStrategy; Boolean resizeable = strategy.isResizable(); errorBox = new FlowPanel(); errorBox.addStyleName(StaticResourceBundle.INSTANCE.coreCss().formErrorBox()); errorBox.add(new Label("There was an error uploading your image. Please be sure " + "that your photo is under 4MB and is a PNG, JPG, or GIF.")); errorBox.setVisible(false); this.addStyleName(StaticResourceBundle.INSTANCE.coreCss().formAvatarUpload()); this.addStyleName(StaticResourceBundle.INSTANCE.coreCss().formElement()); processor = inProcessor; // AvatarEntity Entity = inEntity; uploadForm.setAction(servletPath); uploadForm.setEncoding(FormPanel.ENCODING_MULTIPART); uploadForm.setMethod(FormPanel.METHOD_POST); Label photoLabel = new Label(label); photoLabel.addStyleName(StaticResourceBundle.INSTANCE.coreCss().formLabel()); panel.add(photoLabel); FlowPanel avatarModificationPanel = new FlowPanel(); avatarModificationPanel.addStyleName(StaticResourceBundle.INSTANCE.coreCss().avatarModificationPanel()); avatarContainer.addStyleName(StaticResourceBundle.INSTANCE.coreCss().avatarContainer()); avatarModificationPanel.add(avatarContainer); FlowPanel photoButtonPanel = new FlowPanel(); photoButtonPanel.addStyleName(StaticResourceBundle.INSTANCE.coreCss().formPhotoButtonPanel()); if (resizeable) { editButton = new Anchor("Resize"); editButton.addStyleName(StaticResourceBundle.INSTANCE.coreCss().formResizeButton()); editButton.addStyleName(StaticResourceBundle.INSTANCE.coreCss().formButton()); photoButtonPanel.add(editButton); } deleteButton = new Anchor("Delete"); deleteButton.addStyleName(StaticResourceBundle.INSTANCE.coreCss().formDeleteButton()); deleteButton.addStyleName(StaticResourceBundle.INSTANCE.coreCss().formButton()); photoButtonPanel.add(deleteButton); avatarModificationPanel.add(photoButtonPanel); panel.add(avatarModificationPanel); FlowPanel uploadPanel = new FlowPanel(); uploadPanel.addStyleName(StaticResourceBundle.INSTANCE.coreCss().formUploadPanel()); uploadPanel.add(errorBox); // Wrapping the FileUpload because otherwise IE7 shifts it way // to the right. I couldn't figure out why, // but for whatever reason, this works. FlowPanel fileUploadWrapper = new FlowPanel(); FileUpload upload = new FileUpload(); upload.setName("imageUploadFormElement"); upload.addStyleName(StaticResourceBundle.INSTANCE.coreCss().formAvatarUpload()); fileUploadWrapper.add(upload); uploadPanel.add(fileUploadWrapper); uploadPanel.add(new Label(description)); Anchor submitButton = new Anchor(""); submitButton.addStyleName(StaticResourceBundle.INSTANCE.coreCss().formUploadButton()); submitButton.addStyleName(StaticResourceBundle.INSTANCE.coreCss().formButton()); uploadPanel.add(submitButton); hiddenImage = new Image(); hiddenImage.addStyleName(StaticResourceBundle.INSTANCE.coreCss().avatarHiddenOriginal()); uploadPanel.add(hiddenImage); panel.add(uploadPanel); submitButton.addClickHandler(new ClickHandler() { public void onClick(final ClickEvent event) { uploadForm.submit(); } }); uploadForm.setWidget(panel); this.add(uploadForm); uploadForm.addSubmitCompleteHandler(new SubmitCompleteHandler() { public void onSubmitComplete(final SubmitCompleteEvent ev) { String result = ev.getResults().replaceAll("\\<.*?\\>", ""); final boolean fail = "fail".equals(result); errorBox.setVisible(fail); if (!fail) { String[] results = result.split(","); if (results.length >= 4) { strategy.setX(Integer.parseInt(results[1])); strategy.setY(Integer.parseInt(results[2])); strategy.setCropSize(Integer.parseInt(results[3])); } onAvatarIdChanged(results[0], strategy.getEntityType() == EntityType.PERSON); } } }); if (editButton != null) { editButton.addClickHandler(new ClickHandler() { public void onClick(final ClickEvent inArg0) { // Since the size of the image is required before we can correctly show the // resize dialog, this method determines the avatar url and sets image url. // The load event of that image being loaded will kick off the resize modal. AvatarUrlGenerator urlGenerator = new AvatarUrlGenerator(EntityType.PERSON); hiddenImage.setUrl(urlGenerator.getOriginalAvatarUrl(strategy.getId(), avatarId)); } }); hiddenImage.addLoadHandler(new LoadHandler() { public void onLoad(final LoadEvent inEvent) { imageCropDialog = new ImageCropContent(strategy, processor, avatarId, new Command() { public void execute() { onAvatarIdChanged(strategy.getImageId(), strategy.getEntityType() == EntityType.PERSON); } }, hiddenImage.getWidth() + "px", hiddenImage.getHeight() + "px"); Dialog dialog = new Dialog(imageCropDialog); dialog.showCentered(); } }); } if (strategy.getImageType().equals(ImageType.BANNER)) { onAvatarIdChanged(strategy.getImageId(), strategy.getId().equals(strategy.getImageEntityId()), true, strategy.getEntityType() == EntityType.PERSON); } else { onAvatarIdChanged(strategy.getImageId(), strategy.getEntityType() == EntityType.PERSON); } deleteButton.addClickHandler(new ClickHandler() { @SuppressWarnings("unchecked") public void onClick(final ClickEvent event) { if (new WidgetJSNIFacadeImpl().confirm("Are you sure you want to delete your current photo?")) { strategy.getDeleteAction().delete(strategy.getDeleteParam()); } } }); Session.getInstance().getEventBus().addObserver(ClearUploadedImageEvent.class, new Observer<ClearUploadedImageEvent>() { public void update(final ClearUploadedImageEvent event) { if (event.getImageType().equals(strategy.getImageType()) && event.getEntityType().equals(strategy.getEntityType())) { if (event.getImageType().equals(ImageType.BANNER)) { onAvatarIdChanged(event.getEntity().getBannerId(), strategy.getId().equals( event.getEntity().getBannerEntityId()), true, strategy.getEntityType() == EntityType.PERSON); } else { onAvatarIdChanged(null, strategy.getEntityType() == EntityType.PERSON); } } } }); } /** * Gets fired off when the avatar ID is changed. param inAvatarId the avatar ID. * * @param inAvatarId * the avatar id. * @param setPersonAvatar * if the person's avatar should be changed. */ public void onAvatarIdChanged(final String inAvatarId, final boolean setPersonAvatar) { onAvatarIdChanged(inAvatarId, (inAvatarId != null), (inAvatarId != null), setPersonAvatar); } /** * Gets fired off when the avatar id is changed. * * @param inAvatarId * - the avatar id. * @param inDisplayDelete * - flag telling to display or hide the delete button. * @param inDisplayEdit * - flag telling to display or hide the edit button * @param setPersonAvatar * if the person's avatar should be changed. */ public void onAvatarIdChanged(final String inAvatarId, final boolean inDisplayDelete, final boolean inDisplayEdit, final boolean setPersonAvatar) { if (setPersonAvatar) { Session.getInstance().getCurrentPerson().setAvatarId(inAvatarId); } avatarId = inAvatarId; Widget avatar = strategy.getImage(avatarId); avatarContainer.clear(); avatarContainer.add(avatar); if (editButton != null) { editButton.setVisible(inDisplayEdit); } if (deleteButton != null) { deleteButton.setVisible(inDisplayDelete); } } }