This is an automated email from the git hooks/post-receive script. New commit to branch feature/7930 in repository tutti. See http://git.codelutin.com/tutti.git commit ad17e2a9a3564e3b74b88aa12b2c0ebec3bff1f3 Author: Kevin Morin <morin@codelutin.com> Date: Wed Feb 10 18:28:44 2016 +0100 - ajout de la suppression d'une ligne - activation/descativation des menus - validation de ce que l'utilisateur entre comme taille minimale dans la popup refs #7930 --- .../fr/ifremer/tutti/service/DecoratorService.java | 14 ++- .../resources/i18n/tutti-service_en_GB.properties | 1 + .../resources/i18n/tutti-service_fr_FR.properties | 1 + .../content/protocol/EditProtocolUIModel.java | 16 +-- .../CalcifiedPiecesSamplingEditorUI.jaxx | 1 + .../CalcifiedPiecesSamplingEditorUI.jcss | 9 ++ .../CalcifiedPiecesSamplingEditorUIHandler.java | 108 ++++++++++++++------- .../calcifiedpiecessampling/MinSizePopupUI.jaxx | 80 +++++++++++++++ .../calcifiedpiecessampling/MinSizePopupUI.jcss | 59 +++++++++++ .../MinSizePopupUIHandler.java | 91 +++++++++++++++++ .../MinSizePopupUIModel.java | 52 ++++++++++ .../actions/AddSpeciesAction.java | 9 +- .../actions/DeleteRowAction.java | 75 ++++++++++++++ .../actions/DeleteSpeciesAction.java | 2 +- .../actions/SplitSpeciesAction.java | 52 +++++----- .../MinSizePopupUIModel-error-validation.xml | 23 +++++ .../rtp/RtpEditorUIModel-error-validation.xml | 2 - .../resources/i18n/tutti-ui-swing_en_GB.properties | 8 ++ .../resources/i18n/tutti-ui-swing_fr_FR.properties | 12 ++- 19 files changed, 542 insertions(+), 73 deletions(-) diff --git a/tutti-service/src/main/java/fr/ifremer/tutti/service/DecoratorService.java b/tutti-service/src/main/java/fr/ifremer/tutti/service/DecoratorService.java index 7108250..3fd86a2 100644 --- a/tutti-service/src/main/java/fr/ifremer/tutti/service/DecoratorService.java +++ b/tutti-service/src/main/java/fr/ifremer/tutti/service/DecoratorService.java @@ -78,10 +78,12 @@ public class DecoratorService extends AbstractTuttiService { public static final String SPACE_EVERY_3_DIGIT = "spaceEvery3Digit"; - public static final String SEPARATOR = "#"; - public static final String MATURITY = "maturity"; + public static final String NULL_INFINITE = "nullInfinite"; + + public static final String SEPARATOR = "#"; + public static final Comparator<FishingOperation> FISHING_OPERATION_COMPARATOR_BY_GEAR_SHOOTING_START_DATE = new Comparator<FishingOperation>() { @Override public int compare(FishingOperation o1, FishingOperation o2) { @@ -159,6 +161,14 @@ public class DecoratorService extends AbstractTuttiService { } }); registerDecorator(SPACE_EVERY_3_DIGIT, new SpaceEvery3DigitDecorator()); + registerDecorator(NULL_INFINITE, new Decorator<Integer>(Integer.class) { + private static final long serialVersionUID = 1L; + + @Override + public String toString(Object bean) { + return bean == null ? t("tutti.decorator.null.infinite") : String.valueOf(bean); + } + }); registerDecorator(MATURITY, new MaturityDecorator()); registerDecorator(new VesselDecorator()); registerDecorator(new ProgramDecorator()); diff --git a/tutti-service/src/main/resources/i18n/tutti-service_en_GB.properties b/tutti-service/src/main/resources/i18n/tutti-service_en_GB.properties index fa432d4..23c8a02 100644 --- a/tutti-service/src/main/resources/i18n/tutti-service_en_GB.properties +++ b/tutti-service/src/main/resources/i18n/tutti-service_en_GB.properties @@ -8,6 +8,7 @@ tutti.caracteristicType.lengthStep= tutti.caracteristicType.vesselUseFeature= tutti.csv.import.error.on.field= tutti.csv.import.error.on.row= +tutti.decorator.null.infinite= tutti.error.benthos.not.in.protocol= tutti.error.messages= tutti.error.species.not.in.protocol= diff --git a/tutti-service/src/main/resources/i18n/tutti-service_fr_FR.properties b/tutti-service/src/main/resources/i18n/tutti-service_fr_FR.properties index 2b2727f..812cfd6 100644 --- a/tutti-service/src/main/resources/i18n/tutti-service_fr_FR.properties +++ b/tutti-service/src/main/resources/i18n/tutti-service_fr_FR.properties @@ -5,6 +5,7 @@ tutti.caracteristicType.VESSEL_USE_FEATURE=Autres caractéristiques tutti.caracteristicType.lengthStep= tutti.csv.import.error.on.field=Colonne %s \: %s tutti.csv.import.error.on.row=Des erreurs ont été détectées à la ligne %s \:\n %s +tutti.decorator.null.infinite= tutti.error.messages=Erreurs \:\n %s tutti.fatal.messages=Erreurs critiques \:\n %s tutti.io.mkDir.error=Erreur à la création du dossier %s diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/EditProtocolUIModel.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/EditProtocolUIModel.java index ae52a8b..bf2be98 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/EditProtocolUIModel.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/EditProtocolUIModel.java @@ -93,7 +93,7 @@ public class EditProtocolUIModel extends AbstractTuttiBeanUIModel<TuttiProtocol, public static final String PROPERTY_AVAILABLE_STRATAS = "availableStratas"; - public static final String PROPERTY_CSP_ROWS = "cspRows"; + public static final String PROPERTY_CSP_ROWS = "cpsRows"; /** * Delegate edit object. @@ -172,7 +172,7 @@ public class EditProtocolUIModel extends AbstractTuttiBeanUIModel<TuttiProtocol, protected List<EditProtocolSpeciesRowModel> benthosRow; - protected List<CalcifiedPiecesSamplingEditorRowModel> cspRows; + protected List<CalcifiedPiecesSamplingEditorRowModel> cpsRows; protected final Collection<StrataUIModel> availableStratas = new HashSet<>(); @@ -301,14 +301,14 @@ public class EditProtocolUIModel extends AbstractTuttiBeanUIModel<TuttiProtocol, firePropertyChange(PROPERTY_BENTHOS_ROW, oldValue, benthosRow); } - public List<CalcifiedPiecesSamplingEditorRowModel> getCspRows() { - return cspRows; + public List<CalcifiedPiecesSamplingEditorRowModel> getCpsRows() { + return cpsRows; } - public void setCspRows(List<CalcifiedPiecesSamplingEditorRowModel> cspRows) { - Object oldValue = getCspRows(); - this.cspRows = cspRows; - firePropertyChange(PROPERTY_CSP_ROWS, oldValue, cspRows); + public void setCpsRows(List<CalcifiedPiecesSamplingEditorRowModel> cpsRows) { + Object oldValue = getCpsRows(); + this.cpsRows = cpsRows; + firePropertyChange(PROPERTY_CSP_ROWS, oldValue, cpsRows); } public boolean isRemoveSpeciesEnabled() { diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/calcifiedpiecessampling/CalcifiedPiecesSamplingEditorUI.jaxx b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/calcifiedpiecessampling/CalcifiedPiecesSamplingEditorUI.jaxx index 44b86cf..cbbbcfd 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/calcifiedpiecessampling/CalcifiedPiecesSamplingEditorUI.jaxx +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/calcifiedpiecessampling/CalcifiedPiecesSamplingEditorUI.jaxx @@ -28,6 +28,7 @@ <JPopupMenu id='cpsTablePopup'> <JMenuItem id='splitCpsRowMenu'/> + <JMenuItem id='deleteCpsRowMenu'/> <JMenuItem id='deleteSpeciesMenu'/> </JPopupMenu> diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/calcifiedpiecessampling/CalcifiedPiecesSamplingEditorUI.jcss b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/calcifiedpiecessampling/CalcifiedPiecesSamplingEditorUI.jcss index ff9a4b8..f3362f5 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/calcifiedpiecessampling/CalcifiedPiecesSamplingEditorUI.jcss +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/calcifiedpiecessampling/CalcifiedPiecesSamplingEditorUI.jcss @@ -25,7 +25,16 @@ BeanFilterableComboBox { _simpleAction: {fr.ifremer.tutti.ui.swing.content.protocol.calcifiedpiecessampling.actions.SplitSpeciesAction.class}; } +#deleteCpsRowMenu { + actionIcon: delete; + _simpleAction: {fr.ifremer.tutti.ui.swing.content.protocol.calcifiedpiecessampling.actions.DeleteRowAction.class}; +} + #deleteSpeciesMenu { actionIcon: delete; _simpleAction: {fr.ifremer.tutti.ui.swing.content.protocol.calcifiedpiecessampling.actions.DeleteSpeciesAction.class}; +} + +#cpsTable { + selectionMode: {javax.swing.ListSelectionModel.SINGLE_SELECTION}; } \ No newline at end of file diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/calcifiedpiecessampling/CalcifiedPiecesSamplingEditorUIHandler.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/calcifiedpiecessampling/CalcifiedPiecesSamplingEditorUIHandler.java index 4d64fe5..4e35b5d 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/calcifiedpiecessampling/CalcifiedPiecesSamplingEditorUIHandler.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/calcifiedpiecessampling/CalcifiedPiecesSamplingEditorUIHandler.java @@ -16,9 +16,15 @@ import org.jdesktop.swingx.table.DefaultTableColumnModelExt; import org.jdesktop.swingx.table.TableColumnExt; import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.JTable; +import javax.swing.SwingConstants; import javax.swing.event.TableModelEvent; -import javax.swing.event.TableModelListener; +import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.JTableHeader; +import javax.swing.table.TableCellRenderer; +import java.awt.Component; +import java.io.Serializable; import java.util.ArrayList; import java.util.List; @@ -47,7 +53,6 @@ public class CalcifiedPiecesSamplingEditorUIHandler extends AbstractTuttiUIHandl null, newTableCellRender(Species.class), CalcifiedPiecesSamplingEditorTableModel.SPECIES); - speciesColumn.setSortable(true); DecoratorService.SpeciesDecorator speciesDecorator = new DecoratorService.SpeciesDecorator(); speciesColumn.putClientProperty(SpeciesAbleBatchRowHelper.SPECIES_DECORATOR, speciesDecorator); speciesColumn.setCellRenderer(newTableCellRender(speciesDecorator)); @@ -56,8 +61,25 @@ public class CalcifiedPiecesSamplingEditorUIHandler extends AbstractTuttiUIHandl null, newTableCellRender(Boolean.class, DecoratorService.MATURITY), CalcifiedPiecesSamplingEditorTableModel.MATURITY); + addIntegerColumnToModel(columnModel, CalcifiedPiecesSamplingEditorTableModel.MIN_SIZE, TuttiUI.INT_6_DIGITS_PATTERN, cpsTable); - addIntegerColumnToModel(columnModel, CalcifiedPiecesSamplingEditorTableModel.MAX_SIZE, TuttiUI.INT_6_DIGITS_PATTERN, cpsTable); + + // renderer to display infinite instead of null + TableCellRenderer renderer = new TableCellRenderer() { + + private final TableCellRenderer tableCellRenderer = new DefaultTableCellRenderer(); + + @Override + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + Component result = tableCellRenderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + JLabel jLabel = (JLabel) result; + jLabel.setHorizontalTextPosition(SwingConstants.RIGHT); + jLabel.setText(decorate((Serializable) value, DecoratorService.NULL_INFINITE)); + return result; + } + }; + addColumnToModel(columnModel, null, renderer, CalcifiedPiecesSamplingEditorTableModel.MAX_SIZE); + final CalcifiedPiecesSamplingEditorTableModel tableModel = new CalcifiedPiecesSamplingEditorTableModel(columnModel); @@ -78,45 +100,42 @@ public class CalcifiedPiecesSamplingEditorUIHandler extends AbstractTuttiUIHandl // cpsTable.getSelectionModel().addListSelectionListener(selectionListener); // when model change, then rebuild the species comparator + set model as modified - tableModel.addTableModelListener(new TableModelListener() { + tableModel.addTableModelListener(e -> { - @Override - public void tableChanged(TableModelEvent e) { - getModel().setModify(true); + getModel().setModify(true); - int type = e.getType(); - if (type == TableModelEvent.DELETE || - type == TableModelEvent.INSERT || - e.getLastRow() == Integer.MAX_VALUE) { + int type = e.getType(); + if (type == TableModelEvent.DELETE || + type == TableModelEvent.INSERT || + e.getLastRow() == Integer.MAX_VALUE) { - // get species column - TableColumnExt tableColumn = - (TableColumnExt) cpsTable.getColumns().get(0); + // get species column + TableColumnExt tableColumn = + (TableColumnExt) cpsTable.getColumns().get(0); - // get column comparator - TuttiDecorator.TuttiDecoratorComparator<Species> comparator = - (TuttiDecorator.TuttiDecoratorComparator<Species>) - tableColumn.getComparator(); + // get column comparator + TuttiDecorator.TuttiDecoratorComparator<Species> comparator = + (TuttiDecorator.TuttiDecoratorComparator<Species>) + tableColumn.getComparator(); - // get column comparator - TuttiDecorator<Species> decorator = - SpeciesAbleBatchRowHelper.getSpeciesColumnDecorator(tableColumn); + // get column comparator + TuttiDecorator<Species> decorator = + SpeciesAbleBatchRowHelper.getSpeciesColumnDecorator(tableColumn); - boolean comparatorNull = comparator == null; - if (comparatorNull) { + boolean comparatorNull = comparator == null; + if (comparatorNull) { - // first time coming here, add the comparator - comparator = decorator.getCurrentComparator(); - } + // first time coming here, add the comparator + comparator = decorator.getCurrentComparator(); + } - // init comparator with model species list - comparator.init(decorator, tableModel.getSpeciesList()); + // init comparator with model species list + comparator.init(decorator, tableModel.getSpeciesList()); - if (comparatorNull) { + if (comparatorNull) { - // affect it to colum - tableColumn.setComparator(comparator); - } + // affect it to colum + tableColumn.setComparator(comparator); } } }); @@ -133,11 +152,34 @@ public class CalcifiedPiecesSamplingEditorUIHandler extends AbstractTuttiUIHandl // at the very end, set rows to model List<CalcifiedPiecesSamplingEditorRowModel> rows = new ArrayList<>(); - getModel().setCspRows(rows); + getModel().setCpsRows(rows); tableModel.setRows(rows); } @Override + protected void beforeOpenPopup(int modelRowIndex, int modelColumnIndex) { + super.beforeOpenPopup(modelRowIndex, modelColumnIndex); + + boolean rowSelected = modelRowIndex >= 0 && modelRowIndex < getModel().getCpsRows().size(); + boolean splitEnabled = rowSelected; + boolean rowDeletable = rowSelected; + + if (rowSelected) { + CalcifiedPiecesSamplingEditorRowModel selectedRow = getModel().getCpsRows().get(modelRowIndex); + splitEnabled = selectedRow.getMaxSize() == null + || selectedRow.getMaxSize() - selectedRow.getMinSize() > 1; + rowDeletable = selectedRow.getMinSize() > 0; + } + + getUI().getSplitCpsRowMenu().setEnabled(splitEnabled); + + getUI().getDeleteCpsRowMenu().setEnabled(rowDeletable); + + getUI().getDeleteSpeciesMenu().setEnabled(rowSelected); + + } + + @Override protected JComponent getComponentToFocus() { return null; } diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/calcifiedpiecessampling/MinSizePopupUI.jaxx b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/calcifiedpiecessampling/MinSizePopupUI.jaxx new file mode 100644 index 0000000..50de932 --- /dev/null +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/calcifiedpiecessampling/MinSizePopupUI.jaxx @@ -0,0 +1,80 @@ +<!-- + #%L + Tutti :: UI + %% + Copyright (C) 2012 - 2014 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% + --> +<JDialog id='minSizeDialog' layout='{new BorderLayout()}' + implements='fr.ifremer.tutti.ui.swing.util.TuttiUI<MinSizePopupUIModel, MinSizePopupUIHandler>'> + + <import> + fr.ifremer.tutti.ui.swing.TuttiUIContext + fr.ifremer.tutti.ui.swing.util.TuttiUI + fr.ifremer.tutti.ui.swing.util.TuttiUIUtil + + jaxx.runtime.swing.editor.NumberEditor + </import> + + <script><![CDATA[ + +public MinSizePopupUI(TuttiUI<?,?> parentUI) { + super(parentUI.getHandler().getContext().getMainUI()); + TuttiUIUtil.setParentUI(this, parentUI); +} + +public void open(int minMinSize, Integer maxMinSize) { + handler.open(minMinSize, maxMinSize); +} + ]]></script> + + <MinSizePopupUIModel id="model" javaBean="new MinSizePopupUIModel()"/> + + <BeanValidator id='validator' bean='model' + uiClass='jaxx.runtime.validator.swing.ui.ImageValidationUI'> + <field name='minSize' component='minSizeField'/> + </BeanValidator> + + <Table id='mainPanel' fill='both'> + + <row columns='2'> + <cell> + <JLabel id='message'/> + </cell> + </row> + + <row> + <cell> + <JLabel id='minSizeLabel'/> + </cell> + <cell weightx='1'> + <NumberEditor id='minSizeField'/> + </cell> + </row> + + <row> + <cell columns='2'> + <JPanel layout='{new GridLayout(1, 0)}'> + <JButton id='cancelButton' onActionPerformed="handler.cancel()"/> + <JButton id='validateButton' onActionPerformed="handler.validate()"/> + </JPanel> + </cell> + </row> + + </Table> + +</JDialog> diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/calcifiedpiecessampling/MinSizePopupUI.jcss b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/calcifiedpiecessampling/MinSizePopupUI.jcss new file mode 100644 index 0000000..0c45e85 --- /dev/null +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/calcifiedpiecessampling/MinSizePopupUI.jcss @@ -0,0 +1,59 @@ +/* + * #%L + * Tutti :: UI + * %% + * Copyright (C) 2012 - 2014 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% +*/ + +#minSizeDialog { + modal: true; + title: "tutti.cpsEditor.dialog.minSize.title"; +} + +#minSizeLabel { + text: "tutti.cpsEditor.dialog.minSize.field"; + labelFor: {minSizeField}; +} + +#minSizeField { + autoPopup: {handler.getConfig().isAutoPopupNumberEditor()}; + showPopupButton: {handler.getConfig().isShowNumberEditorButton()}; + showReset: false; + useFloat: false; + useSign: false; + numberPattern: {TuttiUI.INT_6_DIGITS_PATTERN}; + bean: {model}; + property: "minSize"; + model: {model.getMinSize()}; +} + +#cancelButton { + actionIcon: cancel; + text: "tutti.common.cancel"; + toolTipText: "tutti.common.cancel"; + i18nMnemonic: "tutti.common.cancel.mnemonic"; +} + +#validateButton { + actionIcon: add; + text: "tutti.common.validate"; + toolTipText: "tutti.common.validate"; + i18nMnemonic: "tutti.common.validate.mnemonic"; + enabled: {validator.isValid()}; +} + diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/calcifiedpiecessampling/MinSizePopupUIHandler.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/calcifiedpiecessampling/MinSizePopupUIHandler.java new file mode 100644 index 0000000..ce3ed12 --- /dev/null +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/calcifiedpiecessampling/MinSizePopupUIHandler.java @@ -0,0 +1,91 @@ +package fr.ifremer.tutti.ui.swing.content.protocol.calcifiedpiecessampling; + +/* + * #%L + * Tutti :: UI + * %% + * Copyright (C) 2012 - 2014 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 fr.ifremer.tutti.ui.swing.util.AbstractTuttiUIHandler; +import jaxx.runtime.SwingUtil; +import jaxx.runtime.validator.swing.SwingValidator; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import javax.swing.JComponent; + +import static org.nuiton.i18n.I18n.t; + +/** + * @author Kevin Morin - kmorin@codelutin.com + * @since 4.5 + */ +public class MinSizePopupUIHandler extends AbstractTuttiUIHandler<MinSizePopupUIModel, MinSizePopupUI> { + + /** Logger. */ + private static final Log log = LogFactory.getLog(MinSizePopupUIHandler.class); + + @Override + public void afterInit(MinSizePopupUI ui) { + initNumberEditor(ui.getMinSizeField()); + initComponentToFocus(ui); + } + + @Override + public void onCloseUI() { + getUI().dispose(); + } + + @Override + public SwingValidator<MinSizePopupUIModel> getValidator() { + return getUI().getValidator(); + } + + @Override + protected JComponent getComponentToFocus() { + return getUI().getMinSizeField(); + } + + public void open(int minMinSize, Integer maxMinSize) { + getModel().setMinMinSize(minMinSize); + getModel().setMaxMinSize(maxMinSize); + + String message; + if (maxMinSize != null) { + message = t("tutti.cpsEditor.dialog.minSize.message", minMinSize, maxMinSize); + + } else { + message = t("tutti.cpsEditor.dialog.minSize.message.infinite", minMinSize); + } + getUI().getMessage().setText(message); + + getUI().pack(); + SwingUtil.center(getContext().getMainUI(), ui); + getUI().setVisible(true); + } + + public void validate() { + onCloseUI(); + } + + public void cancel() { + getModel().setMinSize(null); + onCloseUI(); + } +} diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/calcifiedpiecessampling/MinSizePopupUIModel.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/calcifiedpiecessampling/MinSizePopupUIModel.java new file mode 100644 index 0000000..63d4f49 --- /dev/null +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/calcifiedpiecessampling/MinSizePopupUIModel.java @@ -0,0 +1,52 @@ +package fr.ifremer.tutti.ui.swing.content.protocol.calcifiedpiecessampling; + +import org.jdesktop.beans.AbstractSerializableBean; + +/** + * @author Kevin Morin (Code Lutin) + * @since 4.5 + */ +public class MinSizePopupUIModel extends AbstractSerializableBean { + + public static final String PROPERTY_MIN_SIZE = "minSize"; + + public static final String PROPERTY_MIN_MIN_SIZE = "minMinSize"; + + public static final String PROPERTY_MAX_MIN_SIZE = "maxMinSize"; + + protected Integer minSize; + + protected int minMinSize; + + protected Integer maxMinSize; + + public Integer getMaxMinSize() { + return maxMinSize; + } + + public void setMaxMinSize(Integer maxMinSize) { + Object oldValue = getMaxMinSize(); + this.maxMinSize = maxMinSize; + firePropertyChange(PROPERTY_MAX_MIN_SIZE, oldValue, maxMinSize); + } + + public int getMinMinSize() { + return minMinSize; + } + + public void setMinMinSize(int minMinSize) { + Object oldValue = getMinMinSize(); + this.minMinSize = minMinSize; + firePropertyChange(PROPERTY_MIN_MIN_SIZE, oldValue, minMinSize); + } + + public Integer getMinSize() { + return minSize; + } + + public void setMinSize(Integer minSize) { + Object oldValue = getMinSize(); + this.minSize = minSize; + firePropertyChange(PROPERTY_MIN_SIZE, oldValue, minSize); + } +} diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/calcifiedpiecessampling/actions/AddSpeciesAction.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/calcifiedpiecessampling/actions/AddSpeciesAction.java index aa807bd..a4cc115 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/calcifiedpiecessampling/actions/AddSpeciesAction.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/calcifiedpiecessampling/actions/AddSpeciesAction.java @@ -9,6 +9,7 @@ import jaxx.runtime.SwingUtil; import jaxx.runtime.swing.editor.bean.BeanFilterableComboBox; import java.util.ArrayList; +import java.util.Comparator; import java.util.List; /** @@ -42,12 +43,14 @@ public class AddSpeciesAction extends SimpleActionSupport<CalcifiedPiecesSamplin newRows.add(newRow); } - ui.getModel().getCspRows().addAll(newRows); + List<CalcifiedPiecesSamplingEditorRowModel> cpsRows = ui.getModel().getCpsRows(); + cpsRows.addAll(newRows); + cpsRows.sort(Comparator.comparing(row -> row.getSpecies().toString())); speciesComboBox.removeItem(species); - int firstRowIndex = tableModel.getRowIndex(newRows.get(0)); - int lastRowIndex = tableModel.getRowIndex(newRows.get(newRows.size() - 1)); + int firstRowIndex = cpsRows.indexOf(newRows.get(0)); + int lastRowIndex = cpsRows.indexOf(newRows.get(newRows.size() - 1)); tableModel.fireTableRowsInserted(firstRowIndex, lastRowIndex); diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/calcifiedpiecessampling/actions/DeleteRowAction.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/calcifiedpiecessampling/actions/DeleteRowAction.java new file mode 100644 index 0000000..2442005 --- /dev/null +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/calcifiedpiecessampling/actions/DeleteRowAction.java @@ -0,0 +1,75 @@ +package fr.ifremer.tutti.ui.swing.content.protocol.calcifiedpiecessampling.actions; + +import fr.ifremer.tutti.persistence.entities.referential.Species; +import fr.ifremer.tutti.service.DecoratorService; +import fr.ifremer.tutti.ui.swing.content.protocol.calcifiedpiecessampling.CalcifiedPiecesSamplingEditorRowModel; +import fr.ifremer.tutti.ui.swing.content.protocol.calcifiedpiecessampling.CalcifiedPiecesSamplingEditorTableModel; +import fr.ifremer.tutti.ui.swing.content.protocol.calcifiedpiecessampling.CalcifiedPiecesSamplingEditorUI; +import fr.ifremer.tutti.ui.swing.util.actions.SimpleActionSupport; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.jdesktop.swingx.JXTable; + +import javax.swing.JOptionPane; +import java.util.List; + +import static org.nuiton.i18n.I18n.t; + +/** + * @author Kevin Morin (Code Lutin) + * @since 4.5 + */ +public class DeleteRowAction extends SimpleActionSupport<CalcifiedPiecesSamplingEditorUI> { + + /** Logger. */ + private static final Log log = LogFactory.getLog(DeleteRowAction.class); + + public DeleteRowAction(CalcifiedPiecesSamplingEditorUI ui) { + super(ui); + } + + @Override + protected void onActionPerformed(CalcifiedPiecesSamplingEditorUI ui) { + + JXTable cpsTable = ui.getCpsTable(); + CalcifiedPiecesSamplingEditorTableModel tableModel = (CalcifiedPiecesSamplingEditorTableModel) cpsTable.getModel(); + + int selectedRow = cpsTable.getSelectedRow(); + if (log.isInfoEnabled()) { + log.info("selected row " + selectedRow); + } + + List<CalcifiedPiecesSamplingEditorRowModel> cspRows = ui.getModel().getCpsRows(); + + CalcifiedPiecesSamplingEditorRowModel row = cspRows.get(selectedRow); + + if (row.getMinSize() > 0) { + Species speciesToDelete = row.getSpecies(); + //TODO decorator quand on aura le modele persisté + String decoratedSpecies = ui.getHandler().getDecorator(Species.class, null).toString(speciesToDelete); + String decoratedRow = decoratedSpecies + " | "; + if (row.getMaturity() != null) { + decoratedRow += ui.getHandler().getDecorator(Boolean.class, DecoratorService.MATURITY).toString(row.getMaturity()) + " | "; + } + decoratedRow += row.getMinSize() + " | " + + ui.getHandler().getDecorator(Integer.class, DecoratorService.NULL_INFINITE).toString(row.getMaxSize()); + + int confirmDeletion = JOptionPane.showConfirmDialog(ui, + t("tutti.editCps.deleteRow.message", decoratedRow), + t("tutti.editCps.deleteRow.title"), + JOptionPane.YES_NO_OPTION, + JOptionPane.QUESTION_MESSAGE); + + if (confirmDeletion == JOptionPane.YES_OPTION) { + + // merge the row with the previous one + CalcifiedPiecesSamplingEditorRowModel previousRow = cspRows.get(selectedRow - 1); + previousRow.setMaxSize(row.getMaxSize()); + + cspRows.remove(row); + tableModel.fireTableRowsDeleted(selectedRow, selectedRow); + } + } + } + +} diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/calcifiedpiecessampling/actions/DeleteSpeciesAction.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/calcifiedpiecessampling/actions/DeleteSpeciesAction.java index e409703..697de30 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/calcifiedpiecessampling/actions/DeleteSpeciesAction.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/calcifiedpiecessampling/actions/DeleteSpeciesAction.java @@ -40,7 +40,7 @@ public class DeleteSpeciesAction extends SimpleActionSupport<CalcifiedPiecesSamp log.info("selected row " + selectedRow); } - List<CalcifiedPiecesSamplingEditorRowModel> cspRows = ui.getModel().getCspRows(); + List<CalcifiedPiecesSamplingEditorRowModel> cspRows = ui.getModel().getCpsRows(); CalcifiedPiecesSamplingEditorRowModel row = cspRows.get(selectedRow); diff --git a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/calcifiedpiecessampling/actions/SplitSpeciesAction.java b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/calcifiedpiecessampling/actions/SplitSpeciesAction.java index a99d51f..e8c0179 100644 --- a/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/calcifiedpiecessampling/actions/SplitSpeciesAction.java +++ b/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/protocol/calcifiedpiecessampling/actions/SplitSpeciesAction.java @@ -3,12 +3,12 @@ package fr.ifremer.tutti.ui.swing.content.protocol.calcifiedpiecessampling.actio import fr.ifremer.tutti.ui.swing.content.protocol.calcifiedpiecessampling.CalcifiedPiecesSamplingEditorRowModel; import fr.ifremer.tutti.ui.swing.content.protocol.calcifiedpiecessampling.CalcifiedPiecesSamplingEditorTableModel; import fr.ifremer.tutti.ui.swing.content.protocol.calcifiedpiecessampling.CalcifiedPiecesSamplingEditorUI; +import fr.ifremer.tutti.ui.swing.content.protocol.calcifiedpiecessampling.MinSizePopupUI; import fr.ifremer.tutti.ui.swing.util.actions.SimpleActionSupport; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.jdesktop.swingx.JXTable; -import javax.swing.JOptionPane; import java.util.List; /** @@ -27,9 +27,6 @@ public class SplitSpeciesAction extends SimpleActionSupport<CalcifiedPiecesSampl @Override protected void onActionPerformed(CalcifiedPiecesSamplingEditorUI ui) { - String value = JOptionPane.showInputDialog(ui, "min size"); - int minSize = Integer.parseInt(value); - JXTable cpsTable = ui.getCpsTable(); CalcifiedPiecesSamplingEditorTableModel tableModel = (CalcifiedPiecesSamplingEditorTableModel) cpsTable.getModel(); @@ -38,30 +35,41 @@ public class SplitSpeciesAction extends SimpleActionSupport<CalcifiedPiecesSampl log.info("selected row " + selectedRow); } - List<CalcifiedPiecesSamplingEditorRowModel> cspRows = ui.getModel().getCspRows(); + List<CalcifiedPiecesSamplingEditorRowModel> cpsRows = ui.getModel().getCpsRows(); + + CalcifiedPiecesSamplingEditorRowModel row = cpsRows.get(selectedRow); + + int minMinSize = row.getMinSize() + 1; + Integer maxMinSize = row.getMaxSize() != null ? row.getMaxSize() - 1 : null; - CalcifiedPiecesSamplingEditorRowModel row = cspRows.get(selectedRow); - Integer exMaxSize = row.getMaxSize(); - row.setMaxSize(minSize - 1); + MinSizePopupUI minSizePopupUI = new MinSizePopupUI(ui); + minSizePopupUI.open(minMinSize, maxMinSize); + Integer minSize = minSizePopupUI.getModel().getMinSize(); - CalcifiedPiecesSamplingEditorRowModel newRow = tableModel.createNewRow(row.getSpecies(), - row.getMaturity(), - minSize, - exMaxSize); + if (minSize != null) { -// newRow.addPropertyChangeListener(CalcifiedPiecesSamplingEditorRowModel.PROPERTY_MIN_SIZE, evt -> { -// row.setMaxSize(((int) evt.getNewValue()) - 1); -// tableModel.fireTableRowsInserted(row); -// }); + Integer exMaxSize = row.getMaxSize(); + row.setMaxSize(minSize - 1); - cspRows.add(selectedRow + 1, newRow); + CalcifiedPiecesSamplingEditorRowModel newRow = tableModel.createNewRow(row.getSpecies(), + row.getMaturity(), + minSize, + exMaxSize); - tableModel.fireTableRowsUpdated(selectedRow, selectedRow); - tableModel.fireTableRowsInserted(newRow); + // newRow.addPropertyChangeListener(CalcifiedPiecesSamplingEditorRowModel.PROPERTY_MIN_SIZE, evt -> { + // row.setMaxSize(((int) evt.getNewValue()) - 1); + // tableModel.fireTableRowsInserted(row); + // }); - // select this new row -// int rowIndex = tableModel.getRowIndex(newRow); -// SwingUtil.setSelectionInterval(cpsTable, rowIndex); + cpsRows.add(selectedRow + 1, newRow); + + tableModel.fireTableRowsUpdated(selectedRow, selectedRow); + tableModel.fireTableRowsInserted(newRow); + + // select this new row + // int rowIndex = tableModel.getRowIndex(newRow); + // SwingUtil.setSelectionInterval(cpsTable, rowIndex); + } } } diff --git a/tutti-ui-swing/src/main/resources/fr/ifremer/tutti/ui/swing/content/protocol/calcifiedpiecessampling/MinSizePopupUIModel-error-validation.xml b/tutti-ui-swing/src/main/resources/fr/ifremer/tutti/ui/swing/content/protocol/calcifiedpiecessampling/MinSizePopupUIModel-error-validation.xml new file mode 100644 index 0000000..6e3afb5 --- /dev/null +++ b/tutti-ui-swing/src/main/resources/fr/ifremer/tutti/ui/swing/content/protocol/calcifiedpiecessampling/MinSizePopupUIModel-error-validation.xml @@ -0,0 +1,23 @@ + +<!DOCTYPE validators PUBLIC + "-//Apache Struts//XWork Validator 1.0.3//EN" + "http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd"> +<validators> + + <field name="minSize"> + <field-validator type="required" short-circuit="true"> + <message> + tutti.validator.error.cpsEditor.dialog.minSize.required + </message> + </field-validator> + <field-validator type="fieldexpression" short-circuit="true"> + <param name="expression"> + <![CDATA[ minSize >= minMinSize && (maxMinSize == null || minSize <= maxMinSize) ]]> + </param> + <message> + tutti.validator.error.cpsEditor.dialog.minSize.between + </message> + </field-validator> + </field> + +</validators> \ No newline at end of file diff --git a/tutti-ui-swing/src/main/resources/fr/ifremer/tutti/ui/swing/content/protocol/rtp/RtpEditorUIModel-error-validation.xml b/tutti-ui-swing/src/main/resources/fr/ifremer/tutti/ui/swing/content/protocol/rtp/RtpEditorUIModel-error-validation.xml index d704589..82a5d67 100644 --- a/tutti-ui-swing/src/main/resources/fr/ifremer/tutti/ui/swing/content/protocol/rtp/RtpEditorUIModel-error-validation.xml +++ b/tutti-ui-swing/src/main/resources/fr/ifremer/tutti/ui/swing/content/protocol/rtp/RtpEditorUIModel-error-validation.xml @@ -69,6 +69,4 @@ </field-validator> </field> - - </validators> diff --git a/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_en_GB.properties b/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_en_GB.properties index f786128..2222078 100644 --- a/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_en_GB.properties +++ b/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_en_GB.properties @@ -207,6 +207,10 @@ tutti.context.helpPage.notFound= tutti.context.service.close.error= tutti.coordinate.action.reset.latitude.tip= tutti.coordinate.action.reset.longitude.tip= +tutti.cpsEditor.dialog.minSize.field= +tutti.cpsEditor.dialog.minSize.message= +tutti.cpsEditor.dialog.minSize.message.infinite= +tutti.cpsEditor.dialog.minSize.title= tutti.createAccidentalBatch.action.cancel= tutti.createAccidentalBatch.action.cancel.mnemonic= tutti.createAccidentalBatch.action.cancel.tip= @@ -721,6 +725,8 @@ tutti.editCatchBatch.legend.marineLitter= tutti.editCatchBatch.legend.species= tutti.editCatchBatch.legend.total= tutti.editCatchBatch.svgLoading.error= +tutti.editCps.deleteRow.message= +tutti.editCps.deleteRow.title= tutti.editCps.deleteSpecies.message= tutti.editCps.deleteSpecies.title= tutti.editCps.field.maturity= @@ -2299,6 +2305,8 @@ tutti.validator.error.benthosFrequency.incoherentTotalWeights= tutti.validator.error.benthosFrequency.lengthStepCaracteristic.required= tutti.validator.error.benthosFrequency.oneRowRequired= tutti.validator.error.benthosFrequency.step.positiveValue= +tutti.validator.error.cpsEditor.dialog.minSize.between= +tutti.validator.error.cpsEditor.dialog.minSize.required= tutti.validator.error.createAccidentalBatch.species.required= tutti.validator.error.createBenthosBatch.batchWeight.noBatchSampleWeight= tutti.validator.error.createIndividualObservationBatch.lengthStepCaracteristic.required= diff --git a/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_fr_FR.properties b/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_fr_FR.properties index 58657bb..a45267e 100644 --- a/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_fr_FR.properties +++ b/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_fr_FR.properties @@ -181,6 +181,10 @@ tutti.context.helpPage.notFound=La page d'aide %s n'a pas été trouvée tutti.context.service.close.error=Erreur lors de la fermeture du service %s tutti.coordinate.action.reset.latitude.tip=Réinitialiser la latitude tutti.coordinate.action.reset.longitude.tip=Réinitialiser la longitude +tutti.cpsEditor.dialog.minSize.field=Taille min. +tutti.cpsEditor.dialog.minSize.message=Saisissez la taille minimale (entre %s et %s) +tutti.cpsEditor.dialog.minSize.message.infinite=Saisissez la taille minimale (supérieure ou égale à %s) +tutti.cpsEditor.dialog.minSize.title=Taille minimale tutti.createAccidentalBatch.action.cancel=Annuler tutti.createAccidentalBatch.action.cancel.mnemonic=A tutti.createAccidentalBatch.action.cancel.tip=Annuler la création de la capture accidentelle @@ -683,8 +687,10 @@ tutti.editCatchBatch.legend.marineLitter=Macro déchets tutti.editCatchBatch.legend.species=Espèces tutti.editCatchBatch.legend.total=Capture tutti.editCatchBatch.svgLoading.error=Erreur lors du chargement du diagramme du résumé -tutti.editCps.deleteSpecies.message= -tutti.editCps.deleteSpecies.title= +tutti.editCps.deleteRow.message=Êtes-vous sûr de vouloir supprimer la ligne %s ? +tutti.editCps.deleteRow.title=Suppression de ligne +tutti.editCps.deleteSpecies.message=Êtes-vous sûr de vouloir supprimer toutes les lignes pour l'espèce %s ? +tutti.editCps.deleteSpecies.title=Suppression des lignes d'une espèce tutti.editCps.field.maturity=Maturité tutti.editCps.field.maturity.tip= tutti.editCps.field.species.tip=Espèce @@ -2128,6 +2134,8 @@ tutti.validator.error.benthosFrequency.incoherentTotalWeights=Le poids total est tutti.validator.error.benthosFrequency.lengthStepCaracteristic.required=La classe de taille est obligatoire tutti.validator.error.benthosFrequency.oneRowRequired=Au moins une classe de taille doit être observée tutti.validator.error.benthosFrequency.step.positiveValue=Le pas de la classe de taille doit être strictement positif +tutti.validator.error.cpsEditor.dialog.minSize.between= +tutti.validator.error.cpsEditor.dialog.minSize.required= tutti.validator.error.createAccidentalBatch.species.required=L'espèce est obligatoire tutti.validator.error.createIndividualObservationBatch.lengthStepCaracteristic.required=La classe de taille est obligatoire tutti.validator.error.createIndividualObservationBatch.size.required=La taille est obligatoire -- To stop receiving notification emails like this one, please contact codelutin.com SCM administrator <admin+scm@codelutin.com>.