r3161 - in branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main: java/org/chorem/pollen/ui java/org/chorem/pollen/ui/actions/poll java/org/chorem/pollen/ui/interceptors resources resources/config resources/i18n webapp/WEB-INF webapp/WEB-INF/jsp webapp/WEB-INF/jsp/poll webapp/css
Author: tchemit Date: 2012-03-06 00:26:09 +0100 (Tue, 06 Mar 2012) New Revision: 3161 Url: http://chorem.org/repositories/revision/pollen/3161 Log: Ajout de la page de cr?\195?\169ation d'un sondage Added: branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/AbstractDisplayChoice.java branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/DisplayDateChoice.java branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/DisplayImageChoice.java branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/DisplayTextChoice.java branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/interceptors/PollenFileUploadInterceptor.java branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/choiceHelper.jsp branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/dateChoice.jsp branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/imageChoice.jsp branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/resume.jsp branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/textChoice.jsp Modified: branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/PollenSession.java branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/AbstractVoteAction.java branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/Create.java branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/resources/config/struts-poll.xml branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/resources/i18n/pollen-ui-struts2_en_GB.properties branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/resources/i18n/pollen-ui-struts2_fr_FR.properties branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/resources/struts.xml branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/decorators.xml branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/create.jsp branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/css/pollCreation.css Modified: branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/PollenSession.java =================================================================== --- branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/PollenSession.java 2012-03-05 23:25:37 UTC (rev 3160) +++ branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/PollenSession.java 2012-03-05 23:26:09 UTC (rev 3161) @@ -23,10 +23,13 @@ */ package org.chorem.pollen.ui; +import com.google.common.collect.Maps; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.chorem.pollen.business.persistence.UserAccount; +import java.util.Map; + /** * User session to put in servlet session. * @@ -41,6 +44,9 @@ /** User loggued account (if anonymous, then userAccount is null). */ private UserAccount userAccount; + /** To push dynamic data which should be consumed in a page scope. */ + private Map<String, Object> dynamicData; + public UserAccount getUserAccount() { return userAccount; } @@ -48,4 +54,24 @@ public void setUserAccount(UserAccount userAccount) { this.userAccount = userAccount; } + + public Map<String, Object> getDynamicData() { + if (dynamicData == null) { + dynamicData = Maps.newHashMap(); + } + return dynamicData; + } + + public void putDynamicData(String token, Object data) { + getDynamicData().put(token, data); + } + + public <T> T getDynamicData(String token) { + Object result = getDynamicData().get(token); + return (T) result; + } + + public void removeDynamicData(String token) { + getDynamicData().remove(token); + } } Added: branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/AbstractDisplayChoice.java =================================================================== --- branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/AbstractDisplayChoice.java (rev 0) +++ branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/AbstractDisplayChoice.java 2012-03-05 23:26:09 UTC (rev 3161) @@ -0,0 +1,105 @@ +/* + * #%L + * Pollen :: UI (strust2) + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2009 - 2012 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ +package org.chorem.pollen.ui.actions.poll; + +import org.apache.commons.collections.MapUtils; +import org.apache.commons.lang3.StringUtils; +import org.chorem.pollen.business.persistence.Choice; +import org.chorem.pollen.ui.actions.PollenActionSupport; + +import java.util.Map; + +/** + * To generate the display for a text choice. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.2.6 + */ +public abstract class AbstractDisplayChoice extends PollenActionSupport { + + private static final long serialVersionUID = 1L; + + /** Where to find dynamic data (says choices in this case). */ + protected String tokenId; + + /** Number of choice to display. */ + protected int choiceNumber; + + /** + * Choice to display in ui (come from dynamic data if exists, or fresh + * created one). + */ + protected Choice choice; + + public void setTokenId(String tokenId) { + this.tokenId = tokenId; + } + + public void setChoiceNumber(int choiceNumber) { + this.choiceNumber = choiceNumber; + } + + public Choice getChoice() { + return choice; + } + + public int getChoiceNumber() { + return choiceNumber; + } + + protected abstract Choice createEmptyChoice(); + + @Override + public String execute() throws Exception { + if (StringUtils.isNotEmpty(tokenId)) { + + Map<Integer, Choice> choices = + getPollenSession().getDynamicData(tokenId); + + if (choices != null) { + + // get choices from datas + choice = choices.get(choiceNumber); + + if (choice != null) { + + // remove this choice from session + choices.remove(choiceNumber); + } + } + + if (MapUtils.isEmpty(choices)) { + + // remove it from session + getPollenSession().removeDynamicData(tokenId); + } + } + + if (choice == null) { + choice = createEmptyChoice(); + } + return SUCCESS; + } + +} Property changes on: branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/AbstractDisplayChoice.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Modified: branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/AbstractVoteAction.java =================================================================== --- branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/AbstractVoteAction.java 2012-03-05 23:25:37 UTC (rev 3160) +++ branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/AbstractVoteAction.java 2012-03-05 23:26:09 UTC (rev 3161) @@ -437,7 +437,7 @@ if (poll == null) { addActionError(_("pollen.error.poll.notfound")); } else { - if (poll.getClosed()) { + if (poll.getClosed() != null && poll.getClosed()) { addActionMessage(_("pollen.information.pollClosed")); } else if (!isPollStarted()) { addActionMessage(_("pollen.information.pollNotStarted")); Modified: branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/Create.java =================================================================== --- branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/Create.java 2012-03-05 23:25:37 UTC (rev 3160) +++ branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/Create.java 2012-03-05 23:26:09 UTC (rev 3161) @@ -23,9 +23,17 @@ */ package org.chorem.pollen.ui.actions.poll; +import com.google.common.base.Preconditions; import com.google.common.collect.Lists; import com.google.common.collect.Maps; +import com.google.common.collect.Sets; import com.opensymphony.xwork2.Preparable; +import org.apache.commons.collections.MapUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.struts2.interceptor.ParameterAware; +import org.chorem.pollen.bean.PollImageChoice; import org.chorem.pollen.business.persistence.Choice; import org.chorem.pollen.business.persistence.ChoiceImpl; import org.chorem.pollen.business.persistence.Poll; @@ -37,8 +45,14 @@ import org.chorem.pollen.services.impl.PollService; import org.chorem.pollen.ui.actions.PollenActionSupport; +import java.io.File; +import java.net.URL; +import java.util.Collections; import java.util.List; import java.util.Map; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * Creates a new poll. @@ -46,17 +60,29 @@ * @author tchemit <chemit@codelutin.com> * @since 1.2.6 */ -public class Create extends PollenActionSupport implements Preparable { +public class Create extends PollenActionSupport implements Preparable, ParameterAware { private static final long serialVersionUID = 1L; + /** Logger. */ + private static final Log log = LogFactory.getLog(Create.class); + + public static final Pattern TEXT_CHOICE_NAME_PATTERN = + Pattern.compile("textChoice_(\\d+).name"); + + public static final Pattern DATE_CHOICE_NAME_PATTERN = + Pattern.compile("dateChoice_(\\d+).name"); + + public static final Pattern IMAGE_CHOICE_NAME_PATTERN = + Pattern.compile("imageChoice_(\\d+).name"); + protected Poll poll; - protected Map<Integer, String> pollTypes; + protected Map<String, String> pollTypes; - protected Map<Integer, String> voteCountingTypes; + protected Map<String, String> voteCountingTypes; - protected Map<Integer, String> choiceTypes; + protected Map<String, String> choiceTypes; protected boolean notification; @@ -68,15 +94,34 @@ protected int notificationNumber; - /** Nombre de choix affichés initialement. */ - private int nbChoices = 5; + private String textChoiceTokenId; - private List<Choice> textChoices; + private String dateChoiceTokenId; - private List<Choice> dateChoices; + private String imageChoiceTokenId; - private List<Choice> imageChoices; + private int nbTextChoices; + private int nbDateChoices; + + private int nbImageChoices; + + /** Uploaded images (for choice type poll). */ + private List<File> imageChoice; + + /** Uploaded images content type (for choice type poll). */ + private List<String> imageChoiceContentType; + + /** Uploaded images name (from use desktop) (for choice type poll). */ + private List<String> imageChoiceFileName; + + /** + * All the parameters send by request used to build back choices of the + * poll. + */ + private Map<String, String[]> parameters; + + @Override public String getPageLogo() { return "Creation"; } @@ -89,15 +134,39 @@ return poll; } - public Map<Integer, String> getPollTypes() { + public int getNbTextChoices() { + return nbTextChoices; + } + + public String getTextChoiceTokenId() { + return textChoiceTokenId; + } + + public int getNbDateChoices() { + return nbDateChoices; + } + + public String getDateChoiceTokenId() { + return dateChoiceTokenId; + } + + public int getNbImageChoices() { + return nbImageChoices; + } + + public String getImageChoiceTokenId() { + return imageChoiceTokenId; + } + + public Map<String, String> getPollTypes() { return pollTypes; } - public Map<Integer, String> getVoteCountingTypes() { + public Map<String, String> getVoteCountingTypes() { return voteCountingTypes; } - public Map<Integer, String> getChoiceTypes() { + public Map<String, String> getChoiceTypes() { return choiceTypes; } @@ -141,81 +210,411 @@ this.notificationNumber = notificationNumber; } - public int getNbChoices() { - return nbChoices; + public List<File> getImageChoice() { + if (imageChoice == null) { + imageChoice = Lists.newArrayList(); + } + return imageChoice; } - public List<Choice> getTextChoices() { - if (textChoices == null) { - textChoices = Lists.newLinkedList(); + public void setImageChoice(int index, File imageChoice) { + addtoList(getImageChoice(), index, imageChoice); + } + + public List<String> getImageChoiceContentType() { + if (imageChoiceContentType == null) { + imageChoiceContentType = Lists.newArrayList(); } - return textChoices; + return imageChoiceContentType; } - public Choice getTextChoices(int index) { - return getChoices(getTextChoices(), index); + public List<String> getImageChoiceFileName() { + if (imageChoiceFileName == null) { + imageChoiceFileName = Lists.newArrayList(); + } + return imageChoiceFileName; } - public Choice getDateChoices(int index) { - return getChoices(getDateChoices(), index); + public void setImageChoiceContentType(int index, String imageChoiceContentType) { + addtoList(getImageChoiceContentType(), index, imageChoiceContentType); } - public Choice getImageChoices(int index) { - return getChoices(getImageChoices(), index); + public void setImageChoiceFileName(int index, String imageChoiceFileName) { + addtoList(getImageChoiceFileName(), index, imageChoiceFileName); } - public List<Choice> getDateChoices() { - if (dateChoices == null) { - dateChoices = Lists.newLinkedList(); + @Override + public void prepare() throws Exception { + + pollTypes = decorateToName(PollType.values()); + choiceTypes = decorateToName(ChoiceType.values()); + voteCountingTypes = decorateToName(VoteCountingType.values()); + + //TODO tchemit-2012-03-05 use a default value from configuration + nbTextChoices = nbDateChoices = nbImageChoices = 5; + + String tokenSuffix = getServiceContext().createPollenUrlId(); + + textChoiceTokenId = DisplayTextChoice.CHOICE_TOKEN + "_" + + tokenSuffix; + + dateChoiceTokenId = DisplayDateChoice.CHOICE_TOKEN + "_" + + tokenSuffix; + + imageChoiceTokenId = DisplayImageChoice.CHOICE_TOKEN + "_" + + tokenSuffix; + + ChoiceType pollChoiceType = getPoll().getChoiceType(); + + if (log.isInfoEnabled()) { + log.info("choice type " + pollChoiceType); } - return dateChoices; + + Map<Integer, Choice> choices = null; + String tokenId = null; + + switch (pollChoiceType) { + case TEXT: + choices = buildTextChoices(5); + tokenId = textChoiceTokenId; + break; + case DATE: + choices = buildDateChoices(5); + tokenId = dateChoiceTokenId; + break; + case IMAGE: + choices = buildImageChoices(5); + tokenId = imageChoiceTokenId; + break; + } + getPollenSession().putDynamicData(tokenId, choices); } - public List<Choice> getImageChoices() { - if (imageChoices == null) { - imageChoices = Lists.newLinkedList(); + @Override + public void validate() { + + Preconditions.checkNotNull(poll); + + // poll must have a title + if (StringUtils.isEmpty(poll.getTitle())) { + addFieldError("poll.title", _("poll.error.poll.required.title")); } - return imageChoices; + + // validate choices + Map<Integer, Choice> orderedChoices = getOrderedChoices(); + + if (MapUtils.isEmpty(orderedChoices)) { + + // poll must have at least one choice + addFieldError("poll.choices", + _("poll.error.poll.required.one.choice")); + } else { + + // check there is no choice with same name + boolean duplicateNameDetected = false; + Set<String> names = Sets.newHashSet(); + for (Choice choice : orderedChoices.values()) { + String choiceName = choice.getName(); + if (!names.add(choiceName)) { + duplicateNameDetected = true; + break; + } + } + if (duplicateNameDetected) { + addFieldError("poll.choices", + _("poll.error.poll.detected.duplicate.choice.name")); + } + } + + // validate security stuff + } @Override public String execute() throws Exception { + Map<Integer, Choice> orderedChoices = getOrderedChoices(); + + List<Choice> choices = Lists.newLinkedList(); + + for (Integer index : orderedChoices.keySet()) { + Choice choice = orderedChoices.get(index); + poll.addChoice(choice); + } + PollService service = newService(PollService.class); -// try { -// Poll basicPoll = service.createBasicPoll(poll); -// -// return SUCCESS; -// } catch (TopiaException e) { -// -// } + poll = service.createPoll(poll); - // back to input + getTransaction().commitTransaction(); + + // remove all stuff from session + getPollenSession().removeDynamicData(textChoiceTokenId); + getPollenSession().removeDynamicData(dateChoiceTokenId); + getPollenSession().removeDynamicData(imageChoiceTokenId); + + addActionMessage(_("poll.info.poll.created")); return SUCCESS; } + public String getPollVoteUrl() { + URL applicationUrl = getApplicationUrl(); + StringBuilder url = new StringBuilder(applicationUrl.toString()); + + url.append("/poll/votefor/").append(poll.getPollId()); + + if (poll.getPollType() != PollType.FREE) { + url.append(':').append(poll.getCreator().getAccountId()); + } + return url.toString(); + } + + public String getPollEditUrl() { + URL applicationUrl = getApplicationUrl(); + StringBuilder url = new StringBuilder(applicationUrl.toString()); + + url.append("/poll/modification/").append(poll.getPollId()); + url.append(':').append(poll.getCreator().getAccountId()); + return url.toString(); + } + @Override - public void prepare() throws Exception { + public void setParameters(Map<String, String[]> parameters) { + this.parameters = parameters; + } - pollTypes = decorate(PollType.values()); - choiceTypes = decorate(ChoiceType.values()); - voteCountingTypes = decorate(VoteCountingType.values()); + private Map<Integer, Choice> getOrderedChoices() { + Map<Integer, Choice> orderedChoices = null; + switch (poll.getChoiceType()) { + + case TEXT: + orderedChoices = getPollenSession().getDynamicData( + textChoiceTokenId); + + break; + case DATE: + orderedChoices = getPollenSession().getDynamicData( + dateChoiceTokenId); + break; + case IMAGE: + orderedChoices = getPollenSession().getDynamicData( + imageChoiceTokenId); + break; + } + return orderedChoices; } - private <E extends Enum<E> & I18nAble> Map<Integer, String> decorate(E... values) { - Map<Integer, String> result = Maps.newLinkedHashMap(); - for (E value : values) { - result.put(value.ordinal(), getText(value.getI18nKey())); + private Map<Integer, Choice> buildTextChoices(int nbDefault) { + Map<Integer, Choice> result = Maps.newTreeMap(); + + int maxNumber = 0; + + for (String paramName : parameters.keySet()) { + + Matcher matcher = TEXT_CHOICE_NAME_PATTERN.matcher(paramName); + if (matcher.matches()) { + + // found a text choice name + + String paramValue = getNonEmptyParameterValue(paramName); + if (paramValue != null) { + + // can keep this none empty text choice name + + Integer choiceNumber = Integer.valueOf(matcher.group(1)); + if (choiceNumber > maxNumber) { + maxNumber = choiceNumber; + } + Choice choice = new ChoiceImpl(); + createChoice(choice, "textChoice_" + choiceNumber, + paramValue); + result.put(choiceNumber, choice); + } + } } + result = reindexChoices(result, maxNumber); + + int size = result.size(); + nbTextChoices = Math.max(nbDefault, size); + log.info("nbTextChoices (from request) = " + size); + logChoice(result); return result; } - private Choice getChoices(List<Choice> choices, int index) { - while (choices.size() < index) { - choices.add(new ChoiceImpl()); + private Map<Integer, Choice> buildDateChoices(int nbDefault) { + Map<Integer, Choice> result = Maps.newTreeMap(); + + int maxNumber = 0; + for (String paramName : parameters.keySet()) { + + Matcher matcher = DATE_CHOICE_NAME_PATTERN.matcher(paramName); + if (matcher.matches()) { + + // found a text choice name + + String paramValue = getNonEmptyParameterValue(paramName); + if (paramValue != null) { + + // can keep this none empty text choice name + + Integer choiceNumber = Integer.valueOf(matcher.group(1)); + if (choiceNumber > maxNumber) { + maxNumber = choiceNumber; + } + Choice choice = new ChoiceImpl(); + createChoice(choice, + "dateChoice_" + choiceNumber, + paramValue); + result.put(choiceNumber, choice); + } + } } - return choices.get(index); + result = reindexChoices(result, maxNumber); + + int size = result.size(); + nbDateChoices = Math.max(nbDefault, size); + log.info("nbDateChoices (from request) = " + size); + logChoice(result); + return result; } + + private Map<Integer, Choice> buildImageChoices(int nbDefault) { + Map<Integer, Choice> result = Maps.newTreeMap(); + + // push back in parameters stuff from uploaded files + int index = 0; + + for (String fileName : getImageChoiceFileName()) { + if (fileName != null) { + parameters.put("imageChoice_" + index + ".name", new String[]{fileName}); + parameters.put("imageChoice_" + index + ".location", new String[]{getImageChoice().get(index).getAbsolutePath()}); + } + index++; + } + + int maxNumber = 0; + for (String paramName : parameters.keySet()) { + + Matcher matcher = IMAGE_CHOICE_NAME_PATTERN.matcher(paramName); + if (matcher.matches()) { + + // found a text choice name + + String paramValue = getNonEmptyParameterValue(paramName); + if (paramValue != null) { + + // can keep this none empty text choice name + + Integer choiceNumber = Integer.valueOf(matcher.group(1)); + if (choiceNumber > maxNumber) { + maxNumber = choiceNumber; + } + PollImageChoice choice = new PollImageChoice(); + createImageChoice(choice, + "imageChoice_" + choiceNumber, + paramValue); + + result.put(choiceNumber, choice); + } + } + } + result = reindexChoices(result, maxNumber); + int size = result.size(); + nbImageChoices = Math.max(nbDefault, size); + log.info("nbImageChoices (from request) = " + size); + logChoice(result); + return result; + } + + private void logChoice(Map<Integer, Choice> result) { + for (Map.Entry<Integer, Choice> e : result.entrySet()) { + Integer choiceId = e.getKey(); + Choice choice = e.getValue(); + if (log.isInfoEnabled()) { + log.info("Choice [" + choiceId + "] = " + + choice.getName() + " -- " + + choice.getDescription()); + } + } + } + + private Choice createImageChoice(PollImageChoice choice, + String prefix, String name) { + createChoice(choice, prefix, name); + String locationName = prefix + ".location"; + String location = getNonEmptyParameterValue(locationName); + choice.setLocation(location); + if (log.isInfoEnabled()) { + log.info("image location [" + name + "] =" + location); + } + return choice; + } + + private Choice createChoice(Choice choice, String prefix, String name) { + String descriptionName = prefix + ".description"; + String topiaIdName = prefix + ".topiaId"; + String description = getNonEmptyParameterValue(descriptionName); + String topiaId = getNonEmptyParameterValue(topiaIdName); + choice.setName(name); + choice.setDescription(description); + choice.setTopiaId(topiaId); + return choice; + } + + + private Map<Integer, Choice> reindexChoices(Map<Integer, Choice> result, + int maxNumber) { + Map<Integer, Choice> result2; + + if (maxNumber != result.size() - 1) { + + // means there is a hole inside the result (a empty choice was + // submitted) + + // le'ts remove this + List<Integer> numbers = Lists.newArrayList(result.keySet()); + + Collections.sort(numbers); + + result2 = Maps.newTreeMap(); + int i = 0; + for (Integer number : numbers) { + Choice choice = result.get(number); + result2.put(i++, choice); + } + } else { + result2 = result; + } + return result2; + } + + private <O> void addtoList(List<O> list, int index, O object) { + + while (list.size() < index) { + list.add(null); + } + list.add(index, object); + } + + + private String getNonEmptyParameterValue(String paramName) { + String[] paramValues = parameters.get(paramName); + String result = null; + if (paramValues.length == 1) { + String paramValue = paramValues[0]; + if (StringUtils.isNotEmpty(paramValue)) { + result = paramValue; + } + } + return result; + } + + private <E extends Enum<E> & I18nAble> Map<String, String> decorateToName(E... values) { + Map<String, String> result = Maps.newLinkedHashMap(); + for (E value : values) { + result.put(value.name(), getText(value.getI18nKey())); + } + return result; + } } Added: branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/DisplayDateChoice.java =================================================================== --- branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/DisplayDateChoice.java (rev 0) +++ branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/DisplayDateChoice.java 2012-03-05 23:26:09 UTC (rev 3161) @@ -0,0 +1,48 @@ +/* + * #%L + * Pollen :: UI (strust2) + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2009 - 2012 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ +package org.chorem.pollen.ui.actions.poll; + +import org.chorem.pollen.business.persistence.Choice; +import org.chorem.pollen.business.persistence.ChoiceImpl; + +/** + * To generate the display for a date choice. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.2.6 + */ +public class DisplayDateChoice extends AbstractDisplayChoice { + + private static final long serialVersionUID = 1L; + + public static final String CHOICE_TOKEN = "dateChoice"; + + @Override + protected Choice createEmptyChoice() { + Choice result = new ChoiceImpl(); + result.setName(""); + result.setDescription(""); + return result; + } +} Property changes on: branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/DisplayDateChoice.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/DisplayImageChoice.java =================================================================== --- branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/DisplayImageChoice.java (rev 0) +++ branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/DisplayImageChoice.java 2012-03-05 23:26:09 UTC (rev 3161) @@ -0,0 +1,49 @@ +/* + * #%L + * Pollen :: UI (strust2) + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2009 - 2012 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ +package org.chorem.pollen.ui.actions.poll; + +import org.chorem.pollen.bean.PollImageChoice; +import org.chorem.pollen.business.persistence.Choice; + +/** + * To generate the display for a image choice. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.2.6 + */ +public class DisplayImageChoice extends AbstractDisplayChoice { + + private static final long serialVersionUID = 1L; + + public static final String CHOICE_TOKEN = "imageChoice"; + + @Override + protected Choice createEmptyChoice() { + PollImageChoice result = new PollImageChoice(); + result.setName(""); + result.setDescription(""); + result.setLocation(""); + return result; + } +} Property changes on: branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/DisplayImageChoice.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/DisplayTextChoice.java =================================================================== --- branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/DisplayTextChoice.java (rev 0) +++ branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/DisplayTextChoice.java 2012-03-05 23:26:09 UTC (rev 3161) @@ -0,0 +1,48 @@ +/* + * #%L + * Pollen :: UI (strust2) + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2009 - 2012 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ +package org.chorem.pollen.ui.actions.poll; + +import org.chorem.pollen.business.persistence.Choice; +import org.chorem.pollen.business.persistence.ChoiceImpl; + +/** + * To generate the display for a text choice. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.2.6 + */ +public class DisplayTextChoice extends AbstractDisplayChoice { + + private static final long serialVersionUID = 1L; + + public static final String CHOICE_TOKEN = "textChoice"; + + @Override + protected Choice createEmptyChoice() { + Choice result = new ChoiceImpl(); + result.setName(""); + result.setDescription(""); + return result; + } +} Property changes on: branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/actions/poll/DisplayTextChoice.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/interceptors/PollenFileUploadInterceptor.java =================================================================== --- branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/interceptors/PollenFileUploadInterceptor.java (rev 0) +++ branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/interceptors/PollenFileUploadInterceptor.java 2012-03-05 23:26:09 UTC (rev 3161) @@ -0,0 +1,205 @@ +/* + * #%L + * Pollen :: UI (strust2) + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2009 - 2012 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ +package org.chorem.pollen.ui.interceptors; + +import com.opensymphony.xwork2.ActionContext; +import com.opensymphony.xwork2.ActionInvocation; +import com.opensymphony.xwork2.ActionProxy; +import com.opensymphony.xwork2.ValidationAware; +import com.opensymphony.xwork2.util.LocalizedTextUtil; +import org.apache.struts2.ServletActionContext; +import org.apache.struts2.dispatcher.multipart.MultiPartRequestWrapper; +import org.apache.struts2.interceptor.FileUploadInterceptor; + +import javax.servlet.http.HttpServletRequest; +import java.io.File; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Overrides the default file upload interceptor to be able to match uploaded + * files in specific fields. + * + * We want to put upload files in a list (field is file for example) and then + * fileName in another list but the default interceptor does not accept this + * since it suffix the filename field with FileName... + * + * TODO tchemit 2012-03-05 submit a patch to struts guys to avoid this fork. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.2.6 + */ +public class PollenFileUploadInterceptor extends FileUploadInterceptor { + private static final long serialVersionUID = 1L; + + + protected final Pattern FILENAME_PATTERN = Pattern.compile("(.+)\\[(.+)\\]"); + + @Override + public String intercept(ActionInvocation invocation) throws Exception { + ActionContext ac = invocation.getInvocationContext(); + + HttpServletRequest request = (HttpServletRequest) ac.get(ServletActionContext.HTTP_REQUEST); + + if (!(request instanceof MultiPartRequestWrapper)) { + if (LOG.isDebugEnabled()) { + ActionProxy proxy = invocation.getProxy(); + LOG.debug(getTextMessage("struts.messages.bypass.request", new Object[]{proxy.getNamespace(), proxy.getActionName()}, ac.getLocale())); + } + + return invocation.invoke(); + } + + ValidationAware validation = null; + + Object action = invocation.getAction(); + + if (action instanceof ValidationAware) { + validation = (ValidationAware) action; + } + + MultiPartRequestWrapper multiWrapper = (MultiPartRequestWrapper) request; + + if (multiWrapper.hasErrors()) { + for (String error : multiWrapper.getErrors()) { + if (validation != null) { + validation.addActionError(error); + } + + if (LOG.isWarnEnabled()) { + LOG.warn(error); + } + } + } + + // bind allowed Files + Enumeration fileParameterNames = multiWrapper.getFileParameterNames(); + while (fileParameterNames != null && fileParameterNames.hasMoreElements()) { + // get the value of this input tag + String inputName = (String) fileParameterNames.nextElement(); + + // get the content type + String[] contentType = multiWrapper.getContentTypes(inputName); + + if (isNonEmpty(contentType)) { + // get the name of the file from the input tag + String[] fileName = multiWrapper.getFileNames(inputName); + + if (isNonEmpty(fileName)) { + // get a File object for the uploaded File + File[] files = multiWrapper.getFiles(inputName); + if (files != null && files.length > 0) { + List<File> acceptedFiles = new ArrayList<File>(files.length); + List<String> acceptedContentTypes = new ArrayList<String>(files.length); + List<String> acceptedFileNames = new ArrayList<String>(files.length); + + Matcher matcher1 = FILENAME_PATTERN.matcher(inputName); + + String contentTypeName; + String fileNameName; + if (matcher1.matches()) { + String prefix = matcher1.group(1); + String suffix = matcher1.group(2); + contentTypeName = prefix + "ContentType[" + suffix + "]"; + fileNameName = prefix + "FileName[" + suffix + "]"; + } else { + contentTypeName = inputName + "ContentType"; + fileNameName = inputName + "FileName"; + } + + + for (int index = 0; index < files.length; index++) { + if (acceptFile(action, files[index], fileName[index], contentType[index], inputName, validation, ac.getLocale())) { + acceptedFiles.add(files[index]); + acceptedContentTypes.add(contentType[index]); + acceptedFileNames.add(fileName[index]); + } + } + + if (!acceptedFiles.isEmpty()) { + Map<String, Object> params = ac.getParameters(); + + params.put(inputName, acceptedFiles.toArray(new File[acceptedFiles.size()])); + params.put(contentTypeName, acceptedContentTypes.toArray(new String[acceptedContentTypes.size()])); + params.put(fileNameName, acceptedFileNames.toArray(new String[acceptedFileNames.size()])); + } + } + } else { + if (LOG.isWarnEnabled()) { + LOG.warn(getTextMessage(action, "struts.messages.invalid.file", new Object[]{inputName}, ac.getLocale())); + } + } + } else { + if (LOG.isWarnEnabled()) { + LOG.warn(getTextMessage(action, "struts.messages.invalid.content.type", new Object[]{inputName}, ac.getLocale())); + } + } + } + + // invoke action + return invocation.invoke(); + } + + private static final String DEFAULT_MESSAGE = "no.message.found"; + +// private PatternMatcher matcher; +// +// @Inject +// public void setMatcher(PatternMatcher matcher) { +// this.matcher = matcher; +// } + + private boolean isNonEmpty(Object[] objArray) { + boolean result = false; + for (int index = 0; index < objArray.length && !result; index++) { + if (objArray[index] != null) { + result = true; + } + } + return result; + } + + private String getTextMessage(String messageKey, Object[] args, Locale locale) { + return getTextMessage(null, messageKey, args, locale); + } + + private String getTextMessage(Object action, String messageKey, Object[] args, Locale locale) { + if (args == null || args.length == 0) { + if (action != null && useActionMessageBundle) { + return LocalizedTextUtil.findText(action.getClass(), messageKey, locale); + } + return LocalizedTextUtil.findText(this.getClass(), messageKey, locale); + } else { + if (action != null && useActionMessageBundle) { + return LocalizedTextUtil.findText(action.getClass(), messageKey, locale, DEFAULT_MESSAGE, args); + } + return LocalizedTextUtil.findText(this.getClass(), messageKey, locale, DEFAULT_MESSAGE, args); + } + } +} Property changes on: branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/java/org/chorem/pollen/ui/interceptors/PollenFileUploadInterceptor.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Modified: branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/resources/config/struts-poll.xml =================================================================== --- branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/resources/config/struts-poll.xml 2012-03-05 23:25:37 UTC (rev 3160) +++ branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/resources/config/struts-poll.xml 2012-03-05 23:26:09 UTC (rev 3161) @@ -44,14 +44,32 @@ <action name="create" class="org.chorem.pollen.ui.actions.poll.Create"> <result name="input">/WEB-INF/jsp/poll/create.jsp</result> - <result>/WEB-INF/jsp/home.jsp</result> + <result>/WEB-INF/jsp/poll/resume.jsp</result> </action> + <!-- display text choice --> + <action name="displayTextChoice" + class="org.chorem.pollen.ui.actions.poll.DisplayTextChoice"> + <result>/WEB-INF/jsp/poll/textChoice.jsp</result> + </action> + + <!-- display date choice --> + <action name="displayDateChoice" + class="org.chorem.pollen.ui.actions.poll.DisplayDateChoice"> + <result>/WEB-INF/jsp/poll/dateChoice.jsp</result> + </action> + + <!-- display image choice --> + <action name="displayImageChoice" + class="org.chorem.pollen.ui.actions.poll.DisplayImageChoice"> + <result>/WEB-INF/jsp/poll/imageChoice.jsp</result> + </action> + <!-- edit poll --> <action name="edit" class="org.chorem.pollen.ui.actions.poll.Edit"> <result name="input">/WEB-INF/jsp/poll/edit.jsp</result> - <result>/WEB-INF/jsp/home.jsp</result> + <result>/WEB-INF/jsp/poll/resume.jsp</result> </action> <!-- vote poll --> Modified: branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/resources/i18n/pollen-ui-struts2_en_GB.properties =================================================================== --- branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/resources/i18n/pollen-ui-struts2_en_GB.properties 2012-03-05 23:25:37 UTC (rev 3160) +++ branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/resources/i18n/pollen-ui-struts2_en_GB.properties 2012-03-05 23:26:09 UTC (rev 3161) @@ -1,11 +1,17 @@ poll.common.aboutPoll=About the poll poll.common.comments=Comments about this poll +poll.common.myPolls=My polls poll.common.select.choiceType=Select the type of choice poll.common.select.userFavoriteList=List poll.common.vote.results=Results poll.common.vote.results-help=Display results poll.common.vote.return=Back to poll poll.common.vote.return-help=Back to poll +poll.error.poll.detected.duplicate.choice.name=Choices must be unique. +poll.error.poll.required.one.choice=You must provide at least one choice. +poll.error.poll.required.title=You must provide a title for the poll +poll.info.poll.created=Poll created +poll.info.poll.updated=Poll modified pollen.action.addChoice=Add choice pollen.action.addComment=Add a comment pollen.action.backToFavoriteLists=Back to favorite lists @@ -26,6 +32,9 @@ pollen.action.editVote=Modifier le vote pollen.action.login=Log me In pollen.action.modify=Modify +pollen.action.pollChoiceDelete=Delete this choice +pollen.action.pollChoiceDown=Descendre ce choix +pollen.action.pollChoiceUp=Monter ce choix pollen.action.pollClone=Copy the poll to create a new one pollen.action.pollClose=Close the poll pollen.action.pollCommentDelete=Supprimer le commentaire @@ -41,6 +50,7 @@ pollen.common.beginChoiceDate=Begin choice date pollen.common.beginDate=Begin date pollen.common.bugReport=Bug report +pollen.common.by=by pollen.common.chartType-pie=Pie pollen.common.chartType-pie3d=Pie 3D pollen.common.chartType-ring=Ring @@ -51,6 +61,7 @@ pollen.common.description=Description pollen.common.displayType-group=Results by groups pollen.common.displayType-normal=Results +pollen.common.editAction=Edit pollen.common.email=Em@il pollen.common.endChoiceDate=end choice date pollen.common.endDate=End date @@ -88,6 +99,7 @@ pollen.common.userSupport=User support pollen.common.victories=Winners\: pollen.common.victory=Winner\: +pollen.common.voteAction=Vote pollen.common.voteCounting-label=Vote Counting\: pollen.common.voteCountingType=Response type pollen.common.voteCountingTypeHelp.condorcet=Condorcet vote\: rank choices by preference order from 1 to N (1\=favorite). Only the rank is taken into account, not the values. Two choices can have the same value. @@ -157,6 +169,9 @@ pollen.information.user.updated=User %s updated. pollen.information.your.are.loggued=You are logged. pollen.label.contact.administrator=Send an email to an administrator +pollen.label.pollEditPage=The link below leads to the page to modify your poll. Save it to be able to modify your poll later if you need it or to close it \: +pollen.label.pollRegisterPage=If you are a logged user, you can find these links on the page +pollen.label.pollVotePage=The link below leads to the page to vote for your poll. Save it and send it to the people that you want to vote \: pollen.legend.login=Login pollen.menu.admin=Administration pollen.menu.createPoll=Create a poll Modified: branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/resources/i18n/pollen-ui-struts2_fr_FR.properties =================================================================== --- branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/resources/i18n/pollen-ui-struts2_fr_FR.properties 2012-03-05 23:25:37 UTC (rev 3160) +++ branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/resources/i18n/pollen-ui-struts2_fr_FR.properties 2012-03-05 23:26:09 UTC (rev 3161) @@ -1,11 +1,17 @@ poll.common.aboutPoll=A propos du sondage poll.common.comments=Commentaire à propos du sondage +poll.common.myPolls=Mes sondages poll.common.select.choiceType=Sélectionner le type de choix poll.common.select.userFavoriteList=Liste poll.common.vote.results=Résultats poll.common.vote.results-help=Voir les résultats poll.common.vote.return=Retour au sondage poll.common.vote.return-help=Retour au sondage +poll.error.poll.detected.duplicate.choice.name=Les choix doivent être uniques. +poll.error.poll.required.one.choice=Vous devez saisir au moins un choix. +poll.error.poll.required.title=Vous devez fournir un titre pour le sondage +poll.info.poll.created=Sondage créé +poll.info.poll.updated=Sondage mise à jour pollen.action.addChoice=Ajouter un choix pollen.action.addComment=Ajouter un commentaire pollen.action.backToFavoriteLists=Retour à la liste des favoris @@ -26,6 +32,9 @@ pollen.action.editVote=Modifier le vote pollen.action.login=M'identifier pollen.action.modify=Modifier +pollen.action.pollChoiceDelete=Supprimer ce choix +pollen.action.pollChoiceDown=Descendre ce choix +pollen.action.pollChoiceUp=Monter ce choix pollen.action.pollClone=Créer un nouveau sondage à partir de celui-ci pollen.action.pollClose=Fermer le sondage pollen.action.pollCommentDelete=Supprimer le commentaire @@ -41,6 +50,7 @@ pollen.common.beginChoiceDate=Date de début des choix pollen.common.beginDate=Date de début pollen.common.bugReport=Rapport de bug +pollen.common.by=par pollen.common.chartType-pie=Camembert pollen.common.chartType-pie3d=Camembert 3D pollen.common.chartType-ring=Anneau @@ -51,6 +61,7 @@ pollen.common.description=Description pollen.common.displayType-group=Résultats par groupes pollen.common.displayType-normal=Résultats +pollen.common.editAction=Editer pollen.common.email=Em@il pollen.common.endChoiceDate=Date de fin des choix pollen.common.endDate=Date de fin @@ -89,6 +100,7 @@ pollen.common.userSupport=Support utilisateur pollen.common.victories=Gagnants \: pollen.common.victory=Gagnant \: +pollen.common.voteAction=Vote pollen.common.voteCountingType=Type de Réponse pollen.common.voteCountingTypeHelp.condorcet=Vote Condorcet \: classer les choix par ordre de préférence de 1 à N (1\=préféré). Seul l'ordre des choix compte, peu importe les valeurs. Deux choix peuvent avoir la même valeur. pollen.common.voteCountingTypeHelp.normal=Vote normal \: voter pour le ou les choix préférés. @@ -158,6 +170,9 @@ pollen.information.user.updated=L'utilisateur %s a été mis à jour. pollen.information.your.are.loggued=Vous êtes connecté. pollen.label.contact.administrator=Contacter un administrateur +pollen.label.pollEditPage=Le lien ci-dessous mène à la page de modification du sondage. Enregistrez-le pour pouvoir modifier votre sondage au besoin ou le clore \: +pollen.label.pollRegisterPage=Si vous êtes un utilisateur identifié, vous pouvez retrouver ces liens dans la page +pollen.label.pollVotePage=Le lien ci-dessous mène à la page de vote. Enregistrez-le et envoyez-le à ceux que vous voulez voir voter \: pollen.legend.login=Login pollen.menu.admin=Administration pollen.menu.createPoll=Créer un sondage @@ -189,3 +204,4 @@ pollen.title.pollsParticipatedList.legend=Liste des sondages pour lesquels vous avez voté pollen.title.register=S'enregistrer pollen.title.usersList=Gestion des utilisateurs +title=Création d'un sondage Modified: branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/resources/struts.xml =================================================================== --- branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/resources/struts.xml 2012-03-05 23:25:37 UTC (rev 3160) +++ branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/resources/struts.xml 2012-03-05 23:26:09 UTC (rev 3161) @@ -64,6 +64,9 @@ <interceptor name="paramRemover" class="com.opensymphony.xwork2.interceptor.ParameterRemoverInterceptor"/> + <interceptor name="pollenFileUpload" + class="org.chorem.pollen.ui.interceptors.PollenFileUploadInterceptor"/> + <interceptor name="checkUserLoggued" class="org.chorem.pollen.ui.interceptors.CheckUserIsLogguedInterceptor"> <param name="loginAction">/notLoggued</param> @@ -104,20 +107,21 @@ <interceptor-ref name="i18n"/> <interceptor-ref name="checkbox"/> <interceptor-ref name="multiselect"/> + <interceptor-ref name="pollenFileUpload"/> <interceptor-ref name="params"> <param name="excludeParams">dojo\..*,^struts\..*</param> </interceptor-ref> <interceptor-ref name="servletConfig"/> <interceptor-ref name="staticParams"/> + <interceptor-ref name="prepare"/> <interceptor-ref name="chain"/> <interceptor-ref name="modelDriven"/> - <interceptor-ref name="fileUpload"/> <!--<interceptor-ref name="staticParams"/>--> <interceptor-ref name="actionMappingParams"/> - <interceptor-ref name="params"> - <param name="excludeParams">dojo\..*,^struts\..*</param> - </interceptor-ref> + <!--<interceptor-ref name="params">--> + <!--<param name="excludeParams">dojo\..*,^struts\..*</param>--> + <!--</interceptor-ref>--> <interceptor-ref name="conversionError"/> <interceptor-ref name="validation"> <param name="excludeMethods">input,back,cancel,browse</param> Modified: branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/decorators.xml =================================================================== --- branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/decorators.xml 2012-03-05 23:25:37 UTC (rev 3160) +++ branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/decorators.xml 2012-03-05 23:26:09 UTC (rev 3161) @@ -30,6 +30,7 @@ <pattern>/config-browser/*</pattern> <pattern>/json/*</pattern> <pattern>/poll/confirmDelete*</pattern> + <pattern>/poll/display*</pattern> <pattern>/io/*</pattern> </excludes> Added: branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/choiceHelper.jsp =================================================================== --- branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/choiceHelper.jsp (rev 0) +++ branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/choiceHelper.jsp 2012-03-05 23:26:09 UTC (rev 3161) @@ -0,0 +1,191 @@ +<%-- + #%L + Pollen :: UI (strust2) + + $Id$ + $HeadURL$ + %% + Copyright (C) 2009 - 2012 CodeLutin + %% + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + #L% + --%> +<%@ page language="java" contentType="text/html" pageEncoding="utf-8" %> +<%@ taglib prefix="s" uri="/struts-tags" %> +<%@ taglib prefix="sj" uri="/struts-jquery-tags" %> + +<script type="text/javascript"> + + var choiceText = '<s:text name="pollen.common.choice"/>'; + + function getFirstChoice(containerId) { + var result = 65535; + + getAllChoices(containerId).each(function () { + var currentChoiceNumber = $(this).data('choiceNumber'); + if (currentChoiceNumber < result) { + result = currentChoiceNumber; + } + }); + return result; + } + + function getLastChoice(containerId) { + var result = 0; + getAllChoices(containerId).each(function () { + var currentChoiceNumber = $(this).data('choiceNumber'); + if (currentChoiceNumber > result) { + result = currentChoiceNumber; + } + }); + return result; + } + + function getAllChoices(containerId) { + return $("div[id^='" + containerId + "_']"); + } + + function updateUpdownActions(containerId) { + + var firstChoice = getFirstChoice(containerId); + var lastChoice = getLastChoice(containerId); + + getAllChoices(containerId).each(function (index) { + + var currentChoiceNumber = $(this).data('choiceNumber'); + + var labelWidget = $('#' + containerId + "_label_" + currentChoiceNumber); + labelWidget.html(choiceText + ' ' + (index+1)); + + /*var upWidget = $('#' + containerId + "_up_" + currentChoiceNumber); + if (firstChoice == currentChoiceNumber) { + // hide up + upWidget.addClass('hidden'); + } else { + //show up + upWidget.removeClass('hidden'); + } + + var downWidget = $('#' + containerId + "_down_" + currentChoiceNumber); + if (lastChoice == currentChoiceNumber) { + // hide down + downWidget.addClass('hidden'); + } else { + //show down + downWidget.removeClass('hidden'); + }*/ + }); + + } + + function loadChoice(containerId, url, choiceNumber, nbChoices, tokenId) { + if (choiceNumber == -1) { + + // to add a new choice + // get new choiceNumber + + choiceNumber = 1 + getLastChoice(containerId); + } + $.ajax( + { + url:url, + data:{ tokenId:tokenId, choiceNumber:choiceNumber }, + async:false, + dataType:"html", + success:function (data, textStatus) { + var container = $("#" + containerId); + container.append(data); + // store choiceNumber and choiceType + var choice = $("#" + containerId + "_" + choiceNumber); + choice.data('choiceType', containerId); + choice.data('choiceNumber', choiceNumber); + if (choiceNumber == nbChoices) { + + updateUpdownActions(containerId); + // end it can show it + var classes = container.attr("class"); + if (classes.indexOf("thischoice") > -1) { + // show it + container.removeClass('hidden'); + } + } + if (!tokenId) { + updateUpdownActions(containerId); + } + } + }); + } + + function addTextChoice(choiceNumber, nbChoices, tokenId) { + loadChoice( + 'choicesTEXT', + '<s:url namespace="/poll" action="displayTextChoice"/>', + choiceNumber, nbChoices, tokenId + ); + } + + function addDateChoice(choiceNumber, nbChoices, tokenId) { + loadChoice( + 'choicesDATE', + '<s:url namespace="/poll" action="displayDateChoice"/>', + choiceNumber, nbChoices, tokenId + ); + } + + function addImageChoice(choiceNumber, nbChoices, tokenId) { + loadChoice( + 'choicesIMAGE', + '<s:url namespace="/poll" action="displayImageChoice"/>', + choiceNumber, nbChoices, tokenId + ); + } + + function addNewChoice() { + var type = $('[name="poll.choiceType"][checked="checked"]').val(); + if ("TEXT" == type) { + addTextChoice(-1, -1); + } else if ("DATE" == type) { + addDateChoice(-1, -1); + } else if ("IMAGE" == type) { + addImageChoice(-1, -1); + } + return false; + } + + function deleteChoice(choiceId) { + var choice = $('#' + choiceId); + var containerId = choice.data('choiceType'); + choice.remove(); + updateUpdownActions(containerId); + return false; + } + + function upChoice(choiceId) { + var choice = $('#' + choiceId); + var containerId = choice.data('choiceType'); + var choiceNumber = choice.data('choiceNumber'); + console.info("will up [" + containerId + "-" + choiceNumber + "]"); + updateUpdownActions(containerId); + return false; + } + + function downChoice(choiceId) { + var choice = $('#' + choiceId); + var containerId = choice.data('choiceType'); + var choiceNumber = choice.data('choiceNumber'); + console.info("will down [" + containerId + "-" + choiceNumber + "]"); + updateUpdownActions(containerId); + return false; + } +</script> \ No newline at end of file Property changes on: branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/choiceHelper.jsp ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Modified: branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/create.jsp =================================================================== --- branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/create.jsp 2012-03-05 23:25:37 UTC (rev 3160) +++ branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/create.jsp 2012-03-05 23:26:09 UTC (rev 3161) @@ -26,6 +26,9 @@ <%@ taglib prefix="sj" uri="/struts-jquery-tags" %> <link rel="stylesheet" type="text/css" href="<s:url value='/css/pollCreation.css'/>"/> + +<%@include file="/WEB-INF/jsp/choiceHelper.jsp" %> + <script type="text/javascript"> jQuery(document).ready(function () { @@ -74,27 +77,48 @@ $('[name="poll.publicResults"]').prop('checked', val); }); - function changeChoicetype(type) { + function changeChoiceType(type) { $('.choices').addClass('hidden'); + $('.choices').removeClass('thischoice'); $('#choices' + type).removeClass('hidden'); + $('#choices' + type).addClass('thischoice'); + $('[name="poll.choiceType"]').attr('checked', false); + $('[name="poll.choiceType"][value="' + type + '"]').attr('checked', 'checked'); } $('[name="poll.choiceType"]').change(function (event) { - changeChoicetype($(this).val()); + changeChoiceType($(this).val()); }); - $('[name="poll.pollType"][value="<s:property value="%{poll.pollType.ordinal()}"/>"]').prop('checked', true); - $('[name="poll.voteCountingType"][value="<s:property value="%{poll.voteCountingType.ordinal()}"/>"]').prop('checked', true); + $('[name="poll.pollType"][value="<s:property value="%{poll.pollType.name()}"/>"]').attr('checked', 'checked'); + $('[name="poll.voteCountingType"][value="<s:property value="%{poll.voteCountingType.name()}"/>"]').attr('checked', 'checked'); - var choiceType = '<s:property value="%{poll.choiceType.ordinal()}"/>'; - $('[name="poll.choiceType"][value="' + choiceType + '"]').prop('checked', true); - changeChoicetype(choiceType); + changeChoiceType('<s:property value="%{poll.choiceType.name()}"/>'); + + // before loading all choices let's hide everything, it will be shown later + $('.choices').addClass('hidden'); + + // text choices loading + <s:iterator begin="1" end="nbTextChoices" status="status"> + addTextChoice(<s:property value='%{#status.index}'/>, <s:property value="nbTextChoices - 1"/>, '<s:property value="textChoiceTokenId" />'); + </s:iterator> + + // date choices loading + <s:iterator begin="1" end="nbDateChoices" status="status"> + addDateChoice(<s:property value='%{#status.index}'/>, <s:property value="nbDateChoices - 1"/>, '<s:property value="dateChoiceTokenId" />'); + </s:iterator> + + // image choices loading + <s:iterator begin="1" end="nbImageChoices" status="status"> + addImageChoice(<s:property value='%{#status.index}'/>, <s:property value="nbImageChoices - 1"/>, '<s:property value="imageChoiceTokenId" />'); + </s:iterator> }); </script> <title><s:text name="pollen.title.createPoll"/></title> <h1 class="title${pageLogo}"><s:text name="pollen.title.createPoll"/></h1> -<s:form method="POST" id="registerForm" namespace="/poll"> +<s:form method="POST" id="registerForm" namespace="/poll" + enctype="multipart/form-data"> <sj:tabbedpanel id="formTabs"> @@ -110,6 +134,7 @@ required="true" size="80"/> <s:textarea key="poll.description" rows="3" cols="54" label="%{getText('pollen.common.description')}"/> + <s:hidden key="poll.pollId" label=''/> </fieldset> <br/> @@ -127,72 +152,14 @@ <s:radio key='poll.choiceType' list="choiceTypes" label='' theme="simple"/> <hr/> + <s:fielderror fieldName="poll.choices"/> - <div id="choices0" class="choices"> - <s:iterator begin="0" end="nbChoices" status="status"> - <s:set name="tprefix">textChoices[<s:property - value="#status.index"/>].</s:set> - <div class="fleft choiceName"> - <s:label for="%{#tprefix}name" key="pollen.common.choice" - theme="simple"/> - <s:textfield cssClass="nameField" id='%{#tprefix}name' - key="%{#tprefix}name" label='' theme="simple"/> - - - <s:label for="%{#tprefix}description" - key="pollen.common.description" theme="simple"/> - </div> - <div class="fleft"> - <s:textarea cols="30" id="%{#tprefix}description" - key="%{#tprefix}description" label='' theme="simple"/> - </div> - <div class="cleanBoth"></div> - </s:iterator> - </div> - - <div id="choices1" class="choices"> - <s:iterator begin="0" end="nbChoices" status="status"> - <s:set name="dprefix">dateChoices.<s:property - value="#status.index"/>.</s:set> - <div class="fleft choiceName"> - <s:label for="%{#dprefix}name" key="pollen.common.choice" - theme="simple"/> - <sj:datepicker id='%{#dprefix}name' key="%{#dprefix}name" - changeMonth="true" changeYear="true" - labelSeparator="" theme="simple" label="" - timepicker="true"/> - - - <s:label for="%{#dprefix}description" - key="pollen.common.description" theme="simple"/> - </div> - <div class="fleft"> - <s:textarea cols="30" id="%{#dprefix}description" - key="%{#dprefix}description" label='' theme="simple"/> - </div> - <div class="cleanBoth"></div> - </s:iterator> - </div> - <div id="choices2" class="choices"> - <s:iterator begin="0" end="nbChoices" status="status"> - <s:set name="iprefix">imageChoices[<s:property - value="#status.index"/>].</s:set> - <div class="fleft choiceName"> - <s:label for="%{#iprefix}name" key="pollen.common.choice" - theme="simple"/> - <s:file id='%{#iprefix}name' key="%{#iprefix}name" - label='' theme="simple" cssClass="nameField"/> - - - <s:label for="%{#iprefix}description" - key="pollen.common.description" theme="simple"/> - </div> - <div class="fleft"> - <s:textarea cols="30" id="%{#iprefix}description" - key="%{#iprefix}description" label='' theme="simple"/> - </div> - <div class="cleanBoth"></div> - </s:iterator> - </div> + <div id="choicesTEXT" class="choices"></div> + <div id="choicesDATE" class="choices"></div> + <div id="choicesIMAGE" class="choices"></div> <hr/> - <s:submit key="pollen.action.addChoice" align="center"/> + <s:submit key="pollen.action.addChoice" align="center" + onclick="return addNewChoice();"/> </fieldset> @@ -202,10 +169,11 @@ <fieldset> <legend><s:text name="pollen.fieldset.poll.you"/></legend> - <s:textfield key="poll.creator.name" + <s:textfield key="poll.creator.votingId" size="80" label="%{getText('pollen.common.login')}"/> - <s:textfield key="poll.creator.email" + <s:textfield key="poll.creator.email" size="80" label="%{getText('pollen.common.email')}"/> + <s:hidden key="poll.creator.accountId" label=''/> </fieldset> <br/> @@ -275,4 +243,4 @@ <br/> <s:submit action="create" key="pollen.action.createPoll" align="center"/> -</s:form> +</s:form> \ No newline at end of file Added: branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/dateChoice.jsp =================================================================== --- branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/dateChoice.jsp (rev 0) +++ branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/dateChoice.jsp 2012-03-05 23:26:09 UTC (rev 3161) @@ -0,0 +1,70 @@ +<%-- + #%L + Pollen :: UI (strust2) + + $Id$ + $HeadURL$ + %% + Copyright (C) 2009 - 2012 CodeLutin + %% + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + #L% + --%> +<%@ page language="java" contentType="text/html" pageEncoding="utf-8" %> +<%@ taglib prefix="s" uri="/struts-tags" %> +<%@ taglib prefix="sj" uri="/struts-jquery-tags" %> + +<s:set name="prefix">dateChoice_<s:property value="choiceNumber"/></s:set> +<s:set id='deleteTitle'><s:text name="pollen.action.pollChoiceDelete"/></s:set> +<s:set id='upTitle'><s:text name="pollen.action.pollChoiceUp"/></s:set> +<s:set id='downTitle'><s:text name="pollen.action.pollChoiceDown"/></s:set> +<div id='choicesDATE_<s:property value="choiceNumber"/>'> + <s:hidden key='%{#prefix}.topiaId' value='%{choice.topiaId}' label=''/> + <div class="fleft choiceName"> + <s:label for="%{#prefix}.name" id="choicesDATE_label_%{choiceNumber}" + theme="simple" value=''/> + <sj:datepicker id='%{#prefix}.name' key="%{#prefix}.name" changeMonth="true" + changeYear="true" labelSeparator="" theme="simple" label="" + timepicker="true" value="%{choice.name}"/> + - + <s:label for="%{#prefix}.description" key="pollen.common.description" + theme="simple"/> + </div> + <div class="fleft"> + <s:textarea cols="30" id="%{#prefix}.description" + key="%{#prefix}.description" label='' theme="simple" + value="%{choice.description}"/> + </div> + <span> + <s:a href='#' onclick="return deleteChoice('choicesDATE_%{choiceNumber}')"> + <image alt='<s:property value="deleteTitle"/>' + title='<s:property value="deleteTitle"/>' + src="<s:url value='/img/delete.png'/>"></image> + </s:a> + <%--s:a id='choicesDATE_down_%{choiceNumber}' + cssClass="hidden" href='#' + onclick="return downChoice('choicesDATE_%{choiceNumber}')"> + <image alt='<s:property value="downTitle"/>' + title='<s:property value="downTitle"/>' + src="<s:url value='/img/1downarrow.png'/>"></image> + </s:a> + <s:a id='choicesDATE_up_%{choiceNumber}' href='#' cssClass="hidden" + onclick="return upChoice('choicesDATE_%{choiceNumber}')"> + <image alt='<s:property value="upTitle"/>' + title='<s:property value="upTitle"/>' + src="<s:url value='/img/1uparrow.png'/>"></image> + </s:a--%> + </span> + <div class="cleanBoth"></div> +</div> \ No newline at end of file Property changes on: branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/dateChoice.jsp ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/imageChoice.jsp =================================================================== --- branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/imageChoice.jsp (rev 0) +++ branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/imageChoice.jsp 2012-03-05 23:26:09 UTC (rev 3161) @@ -0,0 +1,84 @@ +<%-- + #%L + Pollen :: UI (strust2) + + $Id$ + $HeadURL$ + %% + Copyright (C) 2009 - 2012 CodeLutin + %% + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + #L% + --%> +<%@ page language="java" contentType="text/html" pageEncoding="utf-8" %> +<%@ taglib prefix="s" uri="/struts-tags" %> + +<s:set name="prefix">imageChoice_<s:property value="choiceNumber"/></s:set> +<s:set name="prefix2">imageChoice[<s:property value="choiceNumber"/>]</s:set> +<s:set id='deleteTitle'><s:text name="pollen.action.pollChoiceDelete"/></s:set> +<s:set id='upTitle'><s:text name="pollen.action.pollChoiceUp"/></s:set> +<s:set id='downTitle'><s:text name="pollen.action.pollChoiceDown"/></s:set> +<div id='choicesIMAGE_<s:property value="choiceNumber"/>'> + <s:hidden key='%{#prefix}.topiaId' value='%{choice.topiaId}' label=''/> + <div class="fleft choiceName"> + <s:label for="%{#prefix}.name" id="choicesIMAGE_label_%{choiceNumber}" + theme="simple" value=''/> + <s:if test="choice.name != ''"> + + <%--Uploaded image--%> + <s:hidden id="%{#prefix}.name" name="%{#prefix}.name" + value="%{choice.name}" label='' theme="simple"/> + + <s:hidden id="%{#prefix}.location" name="%{#prefix}.location" + value="%{choice.location}" label='' theme="simple"/> + + <s:label label='' theme="simple" cssClass="nameField" + value="%{choice.name}" readonly="true"/> + </s:if> + <s:else> + <%--New image--%> + <s:file key='%{#prefix2}' label='' theme="simple" cssClass="nameField"/> + </s:else> + - + <s:label for="%{#prefix}.description" key="pollen.common.description" + theme="simple"/> + </div> + <div class="fleft"> + <s:textarea cols="30" id="%{#prefix}.description" + key="%{#prefix}.description" + label='' theme="simple" value="%{choice.description}"/> + </div> + <span> + <s:a href='#' onclick="return deleteChoice('choicesIMAGE_%{choiceNumber}')"> + <image alt='<s:property value="deleteTitle"/>' + title='<s:property value="deleteTitle"/>' + src="<s:url value='/img/delete.png'/>"></image> + </s:a> + <%--s:a id='choicesIMAGE_down_%{choiceNumber}' + cssClass="hidden" href='#' + onclick="return downChoice('choicesIMAGE_%{choiceNumber}')"> + <image alt='<s:property value="downTitle"/>' + title='<s:property value="downTitle"/>' + src="<s:url value='/img/1downarrow.png'/>"></image> + </s:a> + <s:a id='choicesIMAGE_up_%{choiceNumber}' href='#' cssClass="hidden" + onclick="return upChoice('choicesIMAGE_%{choiceNumber}')"> + <image alt='<s:property value="upTitle"/>' + title='<s:property value="upTitle"/>' + src="<s:url value='/img/1uparrow.png'/>"></image> + </s:a--%> + </span> + + <div class="cleanBoth"></div> +</div> \ No newline at end of file Property changes on: branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/imageChoice.jsp ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/resume.jsp =================================================================== --- branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/resume.jsp (rev 0) +++ branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/resume.jsp 2012-03-05 23:26:09 UTC (rev 3161) @@ -0,0 +1,58 @@ +<%-- + #%L + Pollen :: UI (strust2) + + $Id$ + $HeadURL$ + %% + Copyright (C) 2009 - 2012 CodeLutin + %% + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + #L% + --%> +<%@ page language="java" contentType="text/html" pageEncoding="utf-8" %> +<%@ taglib prefix="s" uri="/struts-tags" %> +<h1 class="titleCreation"><s:property value="poll.title"/></h1> + +<h3><s:property value="poll.title"/> <s:text name="pollen.common.by"/> + <s:property value="poll.creator.votingId"/></h3> + +<div style="margin-top: 10px;"> + <img src="<s:url value='/img/vote.png'/>" + alt="<s:text name='pollen.common.voteAction'/>" + style="margin-right: 18px;"/> + <s:text name='pollen.label.pollVotePage'/> + <br/> + <s:set name="voteUrl" value="%{pollVoteUrl}"/> + <s:a href="%{voteUrl}" cssStyle="margin-left:50px;"> + <s:property value="voteUrl"/> + </s:a> +</div> +<div style="margin-top: 10px;"> + <img src="<s:url value='/img/edit.png'/>" + alt="<s:text name='pollen.common.editAction'/>" + style="margin-right: 20px;"/> + <s:text name='pollen.label.pollEditPage'/> + <br/> + <s:set name="editUrl" value="%{pollEditUrl}"/> + <s:a href="%{editUrl}" cssStyle="margin-left:50px;"> + <s:property value="editUrl"/> + </s:a> +</div> +<div style="margin-top: 30px;"> + <s:text name="pollen.label.pollRegisterPage"/> + <s:a namespace="/user" action="myPolls"> + <s:text name="poll.common.myPolls"/> + </s:a>. +</div> \ No newline at end of file Property changes on: branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/resume.jsp ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Added: branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/textChoice.jsp =================================================================== --- branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/textChoice.jsp (rev 0) +++ branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/textChoice.jsp 2012-03-05 23:26:09 UTC (rev 3161) @@ -0,0 +1,68 @@ +<%-- + #%L + Pollen :: UI (strust2) + + $Id$ + $HeadURL$ + %% + Copyright (C) 2009 - 2012 CodeLutin + %% + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + #L% + --%> +<%@ page language="java" contentType="text/html" pageEncoding="utf-8" %> +<%@ taglib prefix="s" uri="/struts-tags" %> + +<s:set name="prefix">textChoice_<s:property value="choiceNumber"/></s:set> +<s:set id='deleteTitle'><s:text name="pollen.action.pollChoiceDelete"/></s:set> +<s:set id='upTitle'><s:text name="pollen.action.pollChoiceUp"/></s:set> +<s:set id='downTitle'><s:text name="pollen.action.pollChoiceDown"/></s:set> +<div id='choicesTEXT_<s:property value="choiceNumber"/>'> + <s:hidden key='%{#prefix}.topiaId' value='%{choice.topiaId}' label=''/> + <div class="fleft choiceName"> + <s:label for="%{#prefix}.name" id="choicesTEXT_label_%{choiceNumber}" + theme="simple" value=''/> + <s:textfield cssClass="nameField" id='%{#prefix}.name' key="%{#prefix}.name" + label='' theme="simple" value="%{choice.name}"/> + - + <s:label for="%{#prefix}.description" key="pollen.common.description" + theme="simple"/> + </div> + <div class="fleft"> + <s:textarea cols="30" id="%{#prefix}.description" + key="%{#prefix}.description" + label='' theme="simple" value="%{choice.description}"/> + </div> + <span> + <s:a href='#' onclick="return deleteChoice('choicesTEXT_%{choiceNumber}')"> + <image alt='<s:property value="deleteTitle"/>' + title='<s:property value="deleteTitle"/>' + src="<s:url value='/img/delete.png'/>"></image> + </s:a> + <%--s:a id='choicesTEXT_down_%{choiceNumber}' + cssClass="hidden" href='#' + onclick="return downChoice('choicesTEXT_%{choiceNumber}')"> + <image alt='<s:property value="downTitle"/>' + title='<s:property value="downTitle"/>' + src="<s:url value='/img/1downarrow.png'/>"></image> + </s:a> + <s:a id='choicesTEXT_up_%{choiceNumber}' href='#' cssClass="hidden" + onclick="return upChoice('choicesTEXT_%{choiceNumber}')"> + <image alt='<s:property value="upTitle"/>' + title='<s:property value="upTitle"/>' + src="<s:url value='/img/1uparrow.png'/>"></image> + </s:a--%> + </span> + <div class="cleanBoth"></div> +</div> \ No newline at end of file Property changes on: branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/WEB-INF/jsp/poll/textChoice.jsp ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Modified: branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/css/pollCreation.css =================================================================== --- branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/css/pollCreation.css 2012-03-05 23:25:37 UTC (rev 3160) +++ branches/pollen-1.2.6-struts2/pollen-ui-struts2/src/main/webapp/css/pollCreation.css 2012-03-05 23:26:09 UTC (rev 3161) @@ -1,3 +1,26 @@ +/* + * #%L + * Pollen :: UI (strust2) + * + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2009 - 2012 CodeLutin + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * #L% + */ #pollCreationZone { width: 550px; margin: auto;
participants (1)
-
tchemit@users.chorem.org