diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ImageUploadController.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ImageUploadController.java index 842a6201d..dcbe01f07 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ImageUploadController.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ImageUploadController.java @@ -36,6 +36,7 @@ import edu.cornell.mannlib.vitro.webapp.filestorage.backend.FileStorageSetup; import edu.cornell.mannlib.vitro.webapp.filestorage.model.FileInfo; import edu.cornell.mannlib.vitro.webapp.filestorage.model.ImageInfo; import edu.cornell.mannlib.vitro.webapp.filestorage.uploadrequest.FileUploadServletRequest; +import edu.cornell.mannlib.vitro.webapp.i18n.I18n; import edu.cornell.mannlib.vitro.webapp.web.images.PlaceholderUtil; /** @@ -48,6 +49,9 @@ public class ImageUploadController extends FreemarkerHttpServlet { private static final String ATTRIBUTE_REFERRING_PAGE = "ImageUploadController.referringPage"; + private static final String ERROR_CODE_UNRECOGNIZED_URI = "imageUpload.errorUnrecognizedURI"; + private static final String ERROR_CODE_NO_URI = "imageUpload.errorNoURI"; + /** Limit file size to 6 megabytes. */ public static final int MAXIMUM_FILE_SIZE = 6 * 1024 * 1024; @@ -97,6 +101,14 @@ public class ImageUploadController extends FreemarkerHttpServlet { private static final String URL_HERE = UrlBuilder.getUrl("/uploadImages"); + private static final String TEXT_BUNDLE = "imageUpload"; + private static final String TEXT_STRING_UPLOAD_TITLE = "upload_page_title"; + private static final String TEXT_STRING_UPLOAD_TITLE_WITH_NAME = "upload_page_title_with_name"; + private static final String TEXT_STRING_REPLACE_TITLE = "replace_page_title"; + private static final String TEXT_STRING_REPLACE_TITLE_WITH_NAME = "replace_page_title_with_name"; + private static final String TEXT_STRING_CROP_TITLE = "crop_page_title"; + private static final String TEXT_STRING_CROP_TITLE_WITH_NAME = "crop_page_title_with_name"; + private FileStorage fileStorage; /** @@ -218,7 +230,7 @@ public class ImageUploadController extends FreemarkerHttpServlet { } } catch (UserMistakeException e) { // Can't find the entity? Complain. - return showAddImagePageWithError(vreq, null, e.getMessage()); + return showAddImagePageWithError(vreq, null, e.formatMessage(vreq)); } catch (Exception e) { // We weren't expecting this - log it, and apologize to the user. return new ExceptionResponseValues(e); @@ -274,7 +286,7 @@ public class ImageUploadController extends FreemarkerHttpServlet { return showCropImagePage(vreq, entity, fileInfo.getBytestreamAliasUrl(), size); } catch (UserMistakeException e) { - return showErrorMessage(vreq, entity, e.getMessage()); + return showErrorMessage(vreq, entity, e.formatMessage(vreq)); } } @@ -284,6 +296,7 @@ public class ImageUploadController extends FreemarkerHttpServlet { */ private ResponseValues showErrorMessage(VitroRequest vreq, Individual entity, String message) { + ImageInfo imageInfo = ImageInfo.instanceFromEntityUri( vreq.getFullWebappDaoFactory(), entity); if (imageInfo == null) { @@ -313,7 +326,7 @@ public class ImageUploadController extends FreemarkerHttpServlet { return showExitPage(vreq, entity); } catch (UserMistakeException e) { - return showErrorMessage(vreq, entity, e.getMessage()); + return showErrorMessage(vreq, entity, e.formatMessage(vreq)); } } @@ -350,15 +363,14 @@ public class ImageUploadController extends FreemarkerHttpServlet { throws UserMistakeException { String entityUri = vreq.getParameter(PARAMETER_ENTITY_URI); if (entityUri == null) { - throw new UserMistakeException("No entity URI was provided"); + throw new UserMistakeException(ERROR_CODE_NO_URI); } Individual entity = vreq.getFullWebappDaoFactory().getIndividualDao() .getIndividualByURI(entityUri); if (entity == null) { - throw new UserMistakeException( - "This URI is not recognized as belonging to anyone: '" - + entityUri + "'"); + throw new UserMistakeException(ERROR_CODE_UNRECOGNIZED_URI, + entityUri); } return entity; } @@ -416,7 +428,7 @@ public class ImageUploadController extends FreemarkerHttpServlet { rv.put(BODY_THUMBNAIL_URL, placeholderUrl); rv.put(BODY_FORM_ACTION, formAction); rv.put(BODY_CANCEL_URL, cancelUrl); - rv.put(BODY_TITLE, "Upload image" + forName(entity)); + rv.put(BODY_TITLE, figureUploadPageTitle(vreq, entity)); rv.put(BODY_MAX_FILE_SIZE, MAXIMUM_FILE_SIZE / (1024 * 1024)); rv.put(BODY_THUMBNAIL_HEIGHT, THUMBNAIL_HEIGHT); rv.put(BODY_THUMBNAIL_WIDTH, THUMBNAIL_WIDTH); @@ -442,7 +454,7 @@ public class ImageUploadController extends FreemarkerHttpServlet { rv.put(BODY_DELETE_URL, formAction(entity.getURI(), ACTION_DELETE_EDIT)); rv.put(BODY_FORM_ACTION, formAction(entity.getURI(), ACTION_UPLOAD)); rv.put(BODY_CANCEL_URL, exitPageUrl(vreq, entity.getURI())); - rv.put(BODY_TITLE, "Replace image" + forName(entity)); + rv.put(BODY_TITLE, figureReplacePageTitle(vreq, entity)); rv.put(BODY_MAX_FILE_SIZE, MAXIMUM_FILE_SIZE / (1024 * 1024)); rv.put(BODY_THUMBNAIL_HEIGHT, THUMBNAIL_HEIGHT); rv.put(BODY_THUMBNAIL_WIDTH, THUMBNAIL_WIDTH); @@ -472,7 +484,7 @@ public class ImageUploadController extends FreemarkerHttpServlet { rv.put(BODY_MAIN_IMAGE_WIDTH, dimensions.width); rv.put(BODY_FORM_ACTION, formAction(entity.getURI(), ACTION_SAVE)); rv.put(BODY_CANCEL_URL, exitPageUrl(vreq, entity.getURI())); - rv.put(BODY_TITLE, "Crop Photo" + forName(entity)); + rv.put(BODY_TITLE, figureCropPageTitle(vreq, entity)); return rv; } @@ -522,24 +534,59 @@ public class ImageUploadController extends FreemarkerHttpServlet { } /** - * Format the entity's name for display as part of the page title. + * Format the title for the Upload page. */ - private String forName(Individual entity) { + private String figureUploadPageTitle(HttpServletRequest req, + Individual entity) { + return figurePageTitle(req, entity, TEXT_STRING_UPLOAD_TITLE, + TEXT_STRING_UPLOAD_TITLE_WITH_NAME); + } + + /** + * Format the title for the Replace page. + */ + private String figureReplacePageTitle(HttpServletRequest req, + Individual entity) { + return figurePageTitle(req, entity, TEXT_STRING_REPLACE_TITLE, + TEXT_STRING_REPLACE_TITLE_WITH_NAME); + } + + /** + * Format the title for the Crop page. + */ + private String figureCropPageTitle(HttpServletRequest req, Individual entity) { + return figurePageTitle(req, entity, TEXT_STRING_CROP_TITLE, + TEXT_STRING_CROP_TITLE_WITH_NAME); + } + + /** + * Format one of two page titles, depending on whether the entity has a + * name. + */ + private String figurePageTitle(HttpServletRequest req, Individual entity, + String noNameTitleKey, String nameTitleKey) { if (entity != null) { String name = entity.getName(); if (name != null) { - return " for " + name; + return I18n.text(req, TEXT_BUNDLE, nameTitleKey, name); } } - return ""; + return I18n.text(req, TEXT_BUNDLE, noNameTitleKey); } /** * Holds an error message to use as a complaint to the user. */ static class UserMistakeException extends Exception { - UserMistakeException(String message) { + private final Object[] parameters; + + UserMistakeException(String message, Object... parameters) { super(message); + this.parameters = parameters; + } + + public String formatMessage(HttpServletRequest req) { + return I18n.text(req, getMessage(), parameters); } } diff --git a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ImageUploadHelper.java b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ImageUploadHelper.java index 656a0f0a7..e0052b7bd 100644 --- a/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ImageUploadHelper.java +++ b/webapp/src/edu/cornell/mannlib/vitro/webapp/controller/freemarker/ImageUploadHelper.java @@ -49,6 +49,18 @@ import edu.cornell.mannlib.vitro.webapp.filestorage.uploadrequest.FileUploadServ public class ImageUploadHelper { private static final Log log = LogFactory.getLog(ImageUploadHelper.class); + /* + * Keys to text strings for error messages. + */ + private static final String ERROR_CODE_NO_IMAGE_TO_CROP = "imageUpload.errorNoImageForCropping"; + private static final String ERROR_CODE_IMAGE_TOO_SMALL = "imageUpload.errorImageTooSmall"; + private static final String ERROR_CODE_UNKNOWN = "imageUpload.errorUnknown"; + private static final String ERROR_CODE_FILE_TOO_BIG = "imageUpload.errorFileTooBig"; + private static final String ERROR_CODE_UNRECOGNIZED_FILE_TYPE = "imageUpload.errorUnrecognizedFileType"; + private static final String ERROR_CODE_NO_PHOTO_SELECTED = "imageUpload.errorNoPhotoSelected"; + private static final String ERROR_CODE_BAD_MULTIPART_REQUEST = "imageUpload.errorBadMultipartRequest"; + private static final String ERROR_CODE_FORM_FIELD_MISSING = "imageUpload.errorFormFieldMissing"; + /** * When they upload a new image, store it as this session attribute until * we're ready to attach it to the Individual. @@ -127,35 +139,31 @@ public class ImageUploadHelper { Object exception = request.getAttribute(FILE_UPLOAD_EXCEPTION); if (exception != null) { int limit = MAXIMUM_FILE_SIZE / (1024 * 1024); - throw new UserMistakeException( - "Please upload an image smaller than " + limit - + " megabytes"); + throw new UserMistakeException(ERROR_CODE_FILE_TOO_BIG, limit); } Map> map = (Map>) request .getAttribute(FILE_ITEM_MAP); if (map == null) { - throw new IllegalStateException("Failed to parse the " - + "multi-part request for uploading an image."); + throw new IllegalStateException(ERROR_CODE_BAD_MULTIPART_REQUEST); } List list = map.get(PARAMETER_UPLOADED_FILE); if ((list == null) || list.isEmpty()) { - throw new UserMistakeException("The form did not contain a '" - + PARAMETER_UPLOADED_FILE + "' field."); + throw new UserMistakeException(ERROR_CODE_FORM_FIELD_MISSING, + PARAMETER_UPLOADED_FILE); } FileItem file = list.get(0); if (file.getSize() == 0) { - throw new UserMistakeException("Please browse and select a photo."); + throw new UserMistakeException(ERROR_CODE_NO_PHOTO_SELECTED); } String filename = getSimpleFilename(file); String mimeType = getMimeType(file); if (!RECOGNIZED_FILE_TYPES.containsValue(mimeType)) { log.debug("Unrecognized MIME type: '" + mimeType + "'"); - throw new UserMistakeException("'" + filename - + "' is not a recognized image file type. " - + "Please upload JPEG, GIF, or PNG files only."); + throw new UserMistakeException(ERROR_CODE_UNRECOGNIZED_FILE_TYPE, + filename); } return file; @@ -221,10 +229,8 @@ public class ImageUploadHelper { if ((size.height < THUMBNAIL_HEIGHT) || (size.width < THUMBNAIL_WIDTH)) { - throw new UserMistakeException( - "The uploaded image should be at least " - + THUMBNAIL_HEIGHT + " pixels high and " - + THUMBNAIL_WIDTH + " pixels wide."); + throw new UserMistakeException(ERROR_CODE_IMAGE_TOO_SMALL, + THUMBNAIL_HEIGHT, THUMBNAIL_WIDTH); } return size; @@ -237,8 +243,7 @@ public class ImageUploadHelper { throw e; } catch (Exception e) { log.warn("Unexpected exception in image handling", e); - throw new UserMistakeException("Sorry, we were unable to process " - + "the photo you provided. Please try another photo."); + throw new UserMistakeException(ERROR_CODE_UNKNOWN); } finally { if (source != null) { try { @@ -261,8 +266,7 @@ public class ImageUploadHelper { ATTRIBUTE_TEMP_FILE); if (fileInfo == null) { - throw new UserMistakeException( - "There is no image file to be cropped."); + throw new UserMistakeException(ERROR_CODE_NO_IMAGE_TO_CROP); } return fileInfo; diff --git a/webapp/web/i18n/all.properties b/webapp/web/i18n/all.properties new file mode 100644 index 000000000..ce912c828 --- /dev/null +++ b/webapp/web/i18n/all.properties @@ -0,0 +1,73 @@ +# +# Text strings for the controllers and templates +# +# Default (English) +# +save_changes = Save changes +cancel_link = Cancel +cancel_title = cancel +required_fields = required fields +or = or +alt_error_alert = Error alert icon +alt_confirmation = Confirmation icon + +email_address = Email address +first_name = First name +last_name = Last name +roles = Roles +status = Status + +ascending_order = ascending order +descending_order = descending order +select_one = Select one + +type_more_characters = type more characters +no_match = no match + +request_failed = Request failed. Please contact your system administrator. + +# +# Image upload pages +# +upload_page_title = Upload image +upload_page_title_with_name = Upload image for {0} +upload_heading = Photo Upload + +replace_page_title = Replace image +replace_page_title_with_name = Replace image for {0} + +crop_page_title = Crop image +crop_page_title_with_name = Crop image for {0} + +current_photo = Current Photo +upload_photo = Upload a photo +replace_photo = Replace Photo +photo_types = (JPEG, GIF or PNG) +maximum_file_size = Maximum file size: {0} megabytes +minimum_image_dimensions = Minimum image dimensions: {0} x {1} pixels + +cropping_caption = Your profile photo will look like the image below. +cropping_note = To make adjustments, you can drag around and resize the photo to the right. \ + When you are happy with your photo click the "Save Photo" button. + +alt_thumbnail_photo = Individual photo +alt_image_to_crop = Image to be cropped +alt_preview_crop = Preview of photo cropped + +delete_link = Delete photo +submit_upload = Upload photo +submit_save = Save photo + +confirm_delete = Are you sure you want to delete this photo? + +imageUpload.errorNoURI = No entity URI was provided +imageUpload.errorUnrecognizedURI = This URI is not recognized as belonging to anyone: ''{0}'' +imageUpload.errorNoImageForCropping = There is no image file to be cropped. +imageUpload.errorImageTooSmall = The uploaded image should be at least {0} pixels high and {1} pixels wide. +imageUpload.errorUnknown = Sorry, we were unable to process the photo you provided. Please try another photo. +imageUpload.errorFileTooBig = Please upload an image smaller than {0} megabytes. +imageUpload.errorUnrecognizedFileType = ''{0}'' is not a recognized image file type. Please upload JPEG, GIF, or PNG files only. +imageUpload.errorNoPhotoSelected = Please browse and select a photo. +imageUpload.errorBadMultipartRequest = Failed to parse the multi-part request for uploading an image. +imageUpload.errorFormFieldMissing = The form did not contain a ''{0}'' field." + diff --git a/webapp/web/i18n/all_es.properties b/webapp/web/i18n/all_es.properties new file mode 100644 index 000000000..ecb295fec --- /dev/null +++ b/webapp/web/i18n/all_es.properties @@ -0,0 +1,43 @@ +# +# Text strings for the controllers and templates +# +# Spanish +# +cancel_link = Cancelar +or = o +alt_error_alert = Icono de alerta con error + +# +# Image upload pages +# +upload_page_title = Subir foto +upload_page_title_with_name = Subir imagen para {0} +upload_heading = Subir foto + +replace_page_title = Reemplazar imagen +replace_page_title_with_name = Cambie la imagen por {0} + +crop_page_title = Recortar imagen +crop_page_title_with_name = Recorte imagen para {0} + +current_photo = Foto actual +upload_photo = Suba foto +replace_photo = Reemplace foto +photo_types = (JPEG, GIF, o PNG) +maximum_file_size = Tamaño máximo de archivo: {0} megabytes +minimum_image_dimensions = Dimensiones mínimas de imagen: {0} x {1} pixels + +cropping_caption = La foto de tu perfil se verá como la imagen de abajo. +cropping_note = Para realizar ajustes, arrastre alrededor y cambie el tamaño de la foto de la derecha. \ + Cuando esté satisfecho con su foto, haga clic en el botón "Guardar foto". + +alt_thumbnail_photo = Foto de individuo +alt_image_to_crop = Imagen que desea recortar +alt_preview_crop = Vista previa de la foto recortada + +delete_link = Borrar foto +submit_upload = Subir foto +submit_save = Guardar foto + +confirm_delete = ¿Seguro que quiere borrar esta foto? + diff --git a/webapp/web/js/imageUpload/imageUploadUtils.js b/webapp/web/js/imageUpload/imageUploadUtils.js index 0364689a1..2a2775d1c 100644 --- a/webapp/web/js/imageUpload/imageUploadUtils.js +++ b/webapp/web/js/imageUpload/imageUploadUtils.js @@ -4,7 +4,7 @@ $(document).ready(function(){ // Confirmation alert for photo deletion in image upload and individual templates $('#photoUploadDefaultImage a.thumbnail, a.delete-mainImage').click(function(){ - var answer = confirm('Are you sure you want to delete this photo?'); + var answer = confirm(i18n_confirmDelete); return answer; }); }); \ No newline at end of file diff --git a/webapp/web/templates/freemarker/body/imageUpload/imageUpload-cropImage.ftl b/webapp/web/templates/freemarker/body/imageUpload/imageUpload-cropImage.ftl index 9f6f94ad0..bd8d7b5b0 100644 --- a/webapp/web/templates/freemarker/body/imageUpload/imageUpload-cropImage.ftl +++ b/webapp/web/templates/freemarker/body/imageUpload/imageUpload-cropImage.ftl @@ -21,20 +21,22 @@ ${stylesheets.add(' -

Photo Upload

+

${i18n.upload_heading}

-

Your profile photo will look like the image below.

+

${i18n.cropping_caption}

- Image to be cropped + ${i18n.alt_image_to_crop}
-

To make adjustments, you can drag around and resize the photo to the right. When you are happy with your photo click the "Save Photo" button.

+

${i18n.cropping_note}

@@ -43,15 +45,15 @@ ${stylesheets.add(' - + - or Cancel + ${i18n.or} ${i18n.cancel_link}
- Preview of photo cropped + ${i18n.alt_preview_crop}
diff --git a/webapp/web/templates/freemarker/body/imageUpload/imageUpload-newImage.ftl b/webapp/web/templates/freemarker/body/imageUpload/imageUpload-newImage.ftl index 675b63920..cf9a6b204 100644 --- a/webapp/web/templates/freemarker/body/imageUpload/imageUpload-newImage.ftl +++ b/webapp/web/templates/freemarker/body/imageUpload/imageUpload-newImage.ftl @@ -7,29 +7,35 @@ ${scripts.add(' diff --git a/webapp/web/templates/freemarker/body/imageUpload/imageUpload-replaceImage.ftl b/webapp/web/templates/freemarker/body/imageUpload/imageUpload-replaceImage.ftl index d8850d188..cc5a9b7bd 100644 --- a/webapp/web/templates/freemarker/body/imageUpload/imageUpload-replaceImage.ftl +++ b/webapp/web/templates/freemarker/body/imageUpload/imageUpload-replaceImage.ftl @@ -7,30 +7,36 @@ ${scripts.add(' diff --git a/webapp/web/templates/freemarker/body/individual/individual-vitro.ftl b/webapp/web/templates/freemarker/body/individual/individual-vitro.ftl index 8e13dd2d9..12bc8f92c 100644 --- a/webapp/web/templates/freemarker/body/individual/individual-vitro.ftl +++ b/webapp/web/templates/freemarker/body/individual/individual-vitro.ftl @@ -77,3 +77,7 @@ ${headScripts.add('', '')} + +