Author: kmorin Date: 2013-04-16 17:41:25 +0200 (Tue, 16 Apr 2013) New Revision: 807 Url: http://forge.codelutin.com/projects/tutti/repository/revisions/807 Log: fixes #2308 [OBSERVATIONS INDIVIDUELLES] auto compl?\195?\169tion du champ classe de taille Added: trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/individualobservation/create/SelectSpeciesForIndividualObservationBatchAction.java Modified: trunk/tutti-ui-swing/src/main/filtered-resources/tutti-help-en.properties trunk/tutti-ui-swing/src/main/filtered-resources/tutti-help-fr.properties trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/individualobservation/IndividualObservationBatchUIHandler.java trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/individualobservation/IndividualObservationBatchUIModel.java trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/individualobservation/create/CreateIndividualObservationBatchUI.css trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/individualobservation/create/CreateIndividualObservationBatchUI.jaxx trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/individualobservation/create/CreateIndividualObservationBatchUIHandler.java trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/individualobservation/create/CreateIndividualObservationBatchUIModel.java trunk/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_en_GB.properties trunk/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_fr_FR.properties Modified: trunk/tutti-ui-swing/src/main/filtered-resources/tutti-help-en.properties =================================================================== --- trunk/tutti-ui-swing/src/main/filtered-resources/tutti-help-en.properties 2013-04-16 15:37:31 UTC (rev 806) +++ trunk/tutti-ui-swing/src/main/filtered-resources/tutti-help-en.properties 2013-04-16 15:41:25 UTC (rev 807) @@ -1,28 +1,5 @@ -### -# #%L -# Tutti :: UI -# $Id$ -# $HeadURL$ -# %% -# Copyright (C) 2012 - 2013 Ifremer -# %% -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU 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 General Public -# License along with this program. If not, see -# <http://www.gnu.org/licenses/gpl-3.0.html>. -# #L% -### #Generated by org.nuiton.jaxx.plugin.GenerateHelpIdsMojo -#Fri Apr 12 10:46:52 CEST 2013 +#Tue Apr 16 17:33:03 CEST 2013 tutti.createAccidentalBatch.action.cancel.help= tutti.createAccidentalBatch.action.save.help= tutti.createAccidentalBatch.field.accidentalDeadOrAlive.help= @@ -38,6 +15,7 @@ tutti.createBenthosBatch.field.sortedUnsortedCategory.help=createBenthosBatch.html\#fields tutti.createBenthosBatch.field.species.help=createBenthosBatch.html\#fields tutti.createBenthosBatch.help=createBenthosBatch.html +tutti.createIndividualObservationBatch.action.addSpecies.help= tutti.createIndividualObservationBatch.action.cancel.help= tutti.createIndividualObservationBatch.action.save.help= tutti.createIndividualObservationBatch.field.individualObservationLengthStepCaracteristic.help= Modified: trunk/tutti-ui-swing/src/main/filtered-resources/tutti-help-fr.properties =================================================================== --- trunk/tutti-ui-swing/src/main/filtered-resources/tutti-help-fr.properties 2013-04-16 15:37:31 UTC (rev 806) +++ trunk/tutti-ui-swing/src/main/filtered-resources/tutti-help-fr.properties 2013-04-16 15:41:25 UTC (rev 807) @@ -1,28 +1,5 @@ -### -# #%L -# Tutti :: UI -# $Id$ -# $HeadURL$ -# %% -# Copyright (C) 2012 - 2013 Ifremer -# %% -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU 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 General Public -# License along with this program. If not, see -# <http://www.gnu.org/licenses/gpl-3.0.html>. -# #L% -### #Generated by org.nuiton.jaxx.plugin.GenerateHelpIdsMojo -#Fri Apr 12 10:46:52 CEST 2013 +#Tue Apr 16 17:33:03 CEST 2013 tutti.createAccidentalBatch.action.cancel.help= tutti.createAccidentalBatch.action.save.help= tutti.createAccidentalBatch.field.accidentalDeadOrAlive.help= @@ -38,6 +15,7 @@ tutti.createBenthosBatch.field.sortedUnsortedCategory.help=createBenthosBatch.html\#fields tutti.createBenthosBatch.field.species.help=createBenthosBatch.html\#fields tutti.createBenthosBatch.help=createBenthosBatch.html +tutti.createIndividualObservationBatch.action.addSpecies.help= tutti.createIndividualObservationBatch.action.cancel.help= tutti.createIndividualObservationBatch.action.save.help= tutti.createIndividualObservationBatch.field.individualObservationLengthStepCaracteristic.help= Modified: trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/individualobservation/IndividualObservationBatchUIHandler.java =================================================================== --- trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/individualobservation/IndividualObservationBatchUIHandler.java 2013-04-16 15:37:31 UTC (rev 806) +++ trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/individualobservation/IndividualObservationBatchUIHandler.java 2013-04-16 15:41:25 UTC (rev 807) @@ -400,7 +400,7 @@ EditCatchesUI parent = SwingUtil.getParentContainer(ui, EditCatchesUI.class); CreateIndividualObservationBatchUI createBatchEditor = parent.getIndividualObservationTabCreateBatch(); - createBatchEditor.getHandler().openUI(); + createBatchEditor.getHandler().openUI(getModel()); parent.getHandler().setIndividualObservationSelectedCard(EditCatchesUIHandler.CREATE_BATCH_CARD); } Modified: trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/individualobservation/IndividualObservationBatchUIModel.java =================================================================== --- trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/individualobservation/IndividualObservationBatchUIModel.java 2013-04-16 15:37:31 UTC (rev 806) +++ trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/individualobservation/IndividualObservationBatchUIModel.java 2013-04-16 15:41:25 UTC (rev 807) @@ -25,6 +25,7 @@ import com.google.common.collect.Lists; import fr.ifremer.tutti.persistence.entities.data.AttachementObjectTypeEnum; import fr.ifremer.tutti.persistence.entities.data.Attachment; +import fr.ifremer.tutti.persistence.entities.referential.Species; import fr.ifremer.tutti.ui.swing.content.operation.AbstractTuttiBatchUIModel; import fr.ifremer.tutti.ui.swing.content.operation.catches.EditCatchesUIModel; import fr.ifremer.tutti.ui.swing.util.TabContentModel; @@ -76,6 +77,14 @@ return rootBatchId; } + public Species getLastSpeciesUsed() { + Species result = null; + if (!rows.isEmpty()) { + result = rows.get(rows.size() - 1).getSpecies(); + } + return result; + } + //------------------------------------------------------------------------// //-- AttachmentModelAware --// //------------------------------------------------------------------------// Modified: trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/individualobservation/create/CreateIndividualObservationBatchUI.css =================================================================== --- trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/individualobservation/create/CreateIndividualObservationBatchUI.css 2013-04-16 15:37:31 UTC (rev 806) +++ trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/individualobservation/create/CreateIndividualObservationBatchUI.css 2013-04-16 15:41:25 UTC (rev 807) @@ -89,6 +89,14 @@ selectedItem: {model.getLengthStepCaracteristic()}; } +#addSpeciesButton { + text: "tutti.createIndividualObservationBatch.action.addSpecies"; + toolTipText: "tutti.createIndividualObservationBatch.action.addSpecies.tip"; + i18nMnemonic: "tutti.createIndividualObservationBatch.action.addSpecies.mnemonic"; + _tuttiAction: {SelectSpeciesForIndividualObservationBatchAction.class}; + _help: {"tutti.createIndividualObservationBatch.action.addSpecies.help"}; +} + #saveButton { actionIcon: save; text: "tutti.createIndividualObservationBatch.action.save"; Modified: trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/individualobservation/create/CreateIndividualObservationBatchUI.jaxx =================================================================== --- trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/individualobservation/create/CreateIndividualObservationBatchUI.jaxx 2013-04-16 15:37:31 UTC (rev 806) +++ trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/individualobservation/create/CreateIndividualObservationBatchUI.jaxx 2013-04-16 15:41:25 UTC (rev 807) @@ -83,6 +83,9 @@ constructorParams='this' genericType='Species'/> </cell> + <cell> + <JButton id='addSpeciesButton'/> + </cell> </row> <!-- IndividualObservation weight --> Modified: trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/individualobservation/create/CreateIndividualObservationBatchUIHandler.java =================================================================== --- trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/individualobservation/create/CreateIndividualObservationBatchUIHandler.java 2013-04-16 15:37:31 UTC (rev 806) +++ trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/individualobservation/create/CreateIndividualObservationBatchUIHandler.java 2013-04-16 15:41:25 UTC (rev 807) @@ -22,9 +22,20 @@ * #L% */ +import com.google.common.base.Preconditions; +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Multimap; +import fr.ifremer.tutti.persistence.entities.TuttiEntities; +import fr.ifremer.tutti.persistence.entities.data.IndividualObservationBatch; +import fr.ifremer.tutti.persistence.entities.protocol.SpeciesProtocol; +import fr.ifremer.tutti.persistence.entities.protocol.TuttiProtocol; +import fr.ifremer.tutti.persistence.entities.referential.Caracteristic; +import fr.ifremer.tutti.persistence.entities.referential.CaracteristicQualitativeValue; import fr.ifremer.tutti.persistence.entities.referential.Species; import fr.ifremer.tutti.ui.swing.content.operation.catches.EditCatchesUI; import fr.ifremer.tutti.ui.swing.content.operation.catches.EditCatchesUIHandler; +import fr.ifremer.tutti.ui.swing.content.operation.catches.individualobservation.IndividualObservationBatchUIModel; import fr.ifremer.tutti.ui.swing.util.AbstractTuttiUIHandler; import fr.ifremer.tutti.ui.swing.util.Cancelable; import fr.ifremer.tutti.ui.swing.util.TuttiUI; @@ -37,7 +48,10 @@ import javax.swing.JComponent; import java.awt.Dimension; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; import java.util.List; +import java.util.Map; /** * @author kmorin <kmorin@codelutin.com> @@ -71,13 +85,45 @@ initUI(ui); initBeanFilterableComboBox(ui.getIndividualObservationSpeciesComboBox(), - getDataContext().getReferentSpecies(), + getDataContext().getReferentSpeciesWithSurveyCode(), null); + List<Caracteristic> lengthStepCaracteristics = getDataContext().getLengthStepCaracteristics(); initBeanFilterableComboBox(ui.getIndividualObservationLengthStepCaracteristicComboBox(), - getDataContext().getLengthStepCaracteristics(), + lengthStepCaracteristics, null); + if (context.isProtocolFilled()) { + + // get loaded protocol + TuttiProtocol protocol = getDataContext().getProtocol(); + Preconditions.checkNotNull(protocol, + "Could not find protocol in ui context"); + + final Map<Integer, SpeciesProtocol> speciesProtocolMap = Maps.newHashMap(); + for (SpeciesProtocol sp : protocol.getSpecies()) { + speciesProtocolMap.put(sp.getSpeciesReferenceTaxonId(), sp); + } + + final Map<String, Caracteristic> lengthStepCaracteristicMap = TuttiEntities.splitById(lengthStepCaracteristics); + + getModel().addPropertyChangeListener(IndividualObservationBatch.PROPERTY_SPECIES, + new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + Species species = (Species) evt.getNewValue(); + if (species != null) { + SpeciesProtocol speciesProtocol = speciesProtocolMap.get(species.getReferenceTaxonId()); + if (speciesProtocol != null) { + String lengthStepPmfmId = speciesProtocol.getLengthStepPmfmId(); + Caracteristic lengthStepCaracteristic = lengthStepCaracteristicMap.get(lengthStepPmfmId); + getModel().setLengthStepCaracteristic(lengthStepCaracteristic); + } + } + } + }); + } + listenValidatorValid(ui.getValidator(), getModel()); } @@ -124,7 +170,7 @@ //-- Public methods --// //------------------------------------------------------------------------// - public void openUI() { + public void openUI(IndividualObservationBatchUIModel batchModel) { CreateIndividualObservationBatchUIModel model = getModel(); @@ -133,6 +179,9 @@ model.reset(); + model.setSpecies(batchModel.getLastSpeciesUsed()); + + model.setAvailableSpecies(getDataContext().getReferentSpeciesWithSurveyCode()); } public void save() { Modified: trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/individualobservation/create/CreateIndividualObservationBatchUIModel.java =================================================================== --- trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/individualobservation/create/CreateIndividualObservationBatchUIModel.java 2013-04-16 15:37:31 UTC (rev 806) +++ trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/individualobservation/create/CreateIndividualObservationBatchUIModel.java 2013-04-16 15:41:25 UTC (rev 807) @@ -22,22 +22,38 @@ * #L% */ +import com.google.common.collect.Multimap; import fr.ifremer.tutti.persistence.entities.TuttiBeanFactory; import fr.ifremer.tutti.persistence.entities.data.IndividualObservationBatch; import fr.ifremer.tutti.persistence.entities.referential.Caracteristic; +import fr.ifremer.tutti.persistence.entities.referential.CaracteristicQualitativeValue; import fr.ifremer.tutti.persistence.entities.referential.Species; import fr.ifremer.tutti.ui.swing.util.AbstractTuttiBeanUIModel; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import java.util.List; + /** * @author kmorin <kmorin@codelutin.com> * @since 1.4 */ public class CreateIndividualObservationBatchUIModel extends AbstractTuttiBeanUIModel<CreateIndividualObservationBatchUIModel, CreateIndividualObservationBatchUIModel> { - private static final long serialVersionUID = 1L; + private static final Log log = LogFactory.getLog(CreateIndividualObservationBatchUIModel.class); + + public static final String PROPERTY_AVAILABLE_SPECIES = "availableSpecies"; + /** + * All available species (sets by protocol). + * + * @since 2.0 + */ + protected List<Species> availableSpecies; + + /** * Delegate edit object. * * @since 1.3 @@ -89,6 +105,23 @@ firePropertyChange(IndividualObservationBatch.PROPERTY_LENGTH_STEP_CARACTERISTIC, oldValue, individualObservationLengthStepCaracteristic); } + public List<Species> getAvailableSpecies() { + if (log.isDebugEnabled()) { + log.debug("getAvailableSpecies " + availableSpecies); + } + return availableSpecies; + } + + public void setAvailableSpecies(List<Species> availableSpecies) { + + if (log.isDebugEnabled()) { + log.debug("setAvailableSpecies " + availableSpecies); + } + Object oldValue = getAvailableSpecies(); + this.availableSpecies = availableSpecies; + firePropertyChange(PROPERTY_AVAILABLE_SPECIES, oldValue, availableSpecies); + } + @Override protected CreateIndividualObservationBatchUIModel newEntity() { return new CreateIndividualObservationBatchUIModel(); Copied: trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/individualobservation/create/SelectSpeciesForIndividualObservationBatchAction.java (from rev 804, trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/create/SelectSpeciesForSpeciesBatchAction.java) =================================================================== --- trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/individualobservation/create/SelectSpeciesForIndividualObservationBatchAction.java (rev 0) +++ trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/individualobservation/create/SelectSpeciesForIndividualObservationBatchAction.java 2013-04-16 15:41:25 UTC (rev 807) @@ -0,0 +1,103 @@ +package fr.ifremer.tutti.ui.swing.content.operation.catches.individualobservation.create; + +/* + * #%L + * Tutti :: UI + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2012 - 2013 Ifremer + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/gpl-3.0.html>. + * #L% + */ + +import com.google.common.collect.Lists; +import fr.ifremer.tutti.persistence.entities.TuttiEntities; +import fr.ifremer.tutti.persistence.entities.referential.Species; +import fr.ifremer.tutti.service.DecoratorService; +import fr.ifremer.tutti.ui.swing.util.action.AbstractTuttiAction; + +import java.util.List; +import java.util.Map; + +import static org.nuiton.i18n.I18n._; + +/** + * Enable to select a species to the species selected in the protocol. + * + * @author kmorin <kmorin@codelutin.com> + * @since 2.0 + */ +public class SelectSpeciesForIndividualObservationBatchAction extends AbstractTuttiAction<CreateIndividualObservationBatchUIModel, + CreateIndividualObservationBatchUI, + CreateIndividualObservationBatchUIHandler> { + + protected List<Species> allSpecies; + + protected List<Species> referentSpecies; + + protected Species selectedSpecies; + + public SelectSpeciesForIndividualObservationBatchAction(CreateIndividualObservationBatchUIHandler handler) { + super(handler, false); + + allSpecies = getDataContext().getSpecies(); + referentSpecies = getDataContext().getReferentSpecies(); + } + + @Override + protected boolean prepareAction() throws Exception { + boolean canContinue = super.prepareAction(); + if (canContinue) { + + CreateIndividualObservationBatchUIModel model = getModel(); + + List<Species> species = Lists.newArrayList(allSpecies); + species.removeAll(model.getAvailableSpecies()); + + selectedSpecies = getHandler().openAddSpeciesDialog( + _("tutti.selectSpecies.title"), species); + canContinue = selectedSpecies != null; + } + return canContinue; + } + + @Override + protected void doAction() throws Exception { + + CreateIndividualObservationBatchUIModel model = getModel(); + + List<Species> availableSpecies = Lists.newArrayList(model.getAvailableSpecies()); + + if (!selectedSpecies.isReferenceTaxon()) { + String decoratedSynonym = decorate(selectedSpecies, DecoratorService.FROM_PROTOCOL); + List<Species> referents = referentSpecies; + Map<String, Species> referentsById = TuttiEntities.splitByTaxonId(referents); + String taxonId = String.valueOf(selectedSpecies.getReferenceTaxonId()); + selectedSpecies = referentsById.get(taxonId); + String decoratedReferent = decorate(selectedSpecies, DecoratorService.FROM_PROTOCOL); + sendMessage(_("tutti.flash.info.species.replaced", decoratedSynonym, decoratedReferent)); + } + + if (!availableSpecies.contains(selectedSpecies)) { + availableSpecies.add(selectedSpecies); + } + model.setAvailableSpecies(availableSpecies); + model.setSpecies(selectedSpecies); + + } + +} Modified: trunk/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_en_GB.properties =================================================================== --- trunk/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_en_GB.properties 2013-04-16 15:37:31 UTC (rev 806) +++ trunk/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_en_GB.properties 2013-04-16 15:41:25 UTC (rev 807) @@ -140,6 +140,9 @@ tutti.createBenthosBatch.title= tutti.createBenthosMelag.error.message= tutti.createBenthosMelag.error.title= +tutti.createIndividualObservationBatch.action.addSpecies= +tutti.createIndividualObservationBatch.action.addSpecies.mnemonic= +tutti.createIndividualObservationBatch.action.addSpecies.tip= tutti.createIndividualObservationBatch.action.cancel= tutti.createIndividualObservationBatch.action.cancel.mnemonic= tutti.createIndividualObservationBatch.action.cancel.tip= Modified: trunk/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_fr_FR.properties =================================================================== --- trunk/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_fr_FR.properties 2013-04-16 15:37:31 UTC (rev 806) +++ trunk/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_fr_FR.properties 2013-04-16 15:41:25 UTC (rev 807) @@ -141,6 +141,9 @@ tutti.createBenthosMelag.error.title=Erreur tutti.createBenthosMelag.message=Combien pesait le MELAG (kg) ? tutti.createBenthosMelag.title=Poids du MELAG (kg) +tutti.createIndividualObservationBatch.action.addSpecies=... +tutti.createIndividualObservationBatch.action.addSpecies.mnemonic=. +tutti.createIndividualObservationBatch.action.addSpecies.tip=Sélectionner une autre espèce tutti.createIndividualObservationBatch.action.cancel=Annuler tutti.createIndividualObservationBatch.action.cancel.mnemonic=A tutti.createIndividualObservationBatch.action.cancel.tip=Annuler la création de l'observation individuelle