Author: chatellier Date: 2010-11-03 16:11:03 +0000 (Wed, 03 Nov 2010) New Revision: 159 Log: Ajout des menus contextuel sur l'arbre des erreurs et sur la table des donn?\195?\169es Modified: trunk/coser-business/src/main/java/fr/ifremer/coser/control/ValidationError.java trunk/coser-business/src/main/java/fr/ifremer/coser/services/ProjectService.java trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/control/ControlHandler.java trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/control/ControlView.jaxx trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/control/GlobalValidationGroup.java trunk/coser-ui/src/main/resources/i18n/coser-ui-en_GB.properties trunk/coser-ui/src/main/resources/i18n/coser-ui-fr_FR.properties Modified: trunk/coser-business/src/main/java/fr/ifremer/coser/control/ValidationError.java =================================================================== --- trunk/coser-business/src/main/java/fr/ifremer/coser/control/ValidationError.java 2010-11-03 16:10:01 UTC (rev 158) +++ trunk/coser-business/src/main/java/fr/ifremer/coser/control/ValidationError.java 2010-11-03 16:11:03 UTC (rev 159) @@ -27,7 +27,6 @@ import java.io.Serializable; -import fr.ifremer.coser.CoserConstants.Category; import fr.ifremer.coser.CoserConstants.ValidationLevel; /** Modified: trunk/coser-business/src/main/java/fr/ifremer/coser/services/ProjectService.java =================================================================== --- trunk/coser-business/src/main/java/fr/ifremer/coser/services/ProjectService.java 2010-11-03 16:10:01 UTC (rev 158) +++ trunk/coser-business/src/main/java/fr/ifremer/coser/services/ProjectService.java 2010-11-03 16:11:03 UTC (rev 159) @@ -605,8 +605,8 @@ * Set content into project depending on category type. * * @param project project + * @param container data container * @param category category - * @param content content to set * @param deletedContent if content means deleted objects for {@code category} */ protected DataStorage getProjectContent(Project project, AbstractDataContainer container, @@ -661,18 +661,35 @@ * @param control control * @param category category * @param index index to delete + * @param commandUUID command UUID * @throws CoserBusinessException */ - public void deleteData(Project project, Control control, Category category, String index) throws CoserBusinessException { + public void deleteData(Project project, Control control, Category category, String index, String commandUUID) throws CoserBusinessException { // create new delete action DeleteLineCommand command = new DeleteLineCommand(); command.setCategory(category); command.setLineNumber(index); + command.setCommandUUID(commandUUID); commandService.doAction(command, project, control); } /** + * Supprime une données via son index. + * + * Used in control ui. + * + * @param project project + * @param control control + * @param category category + * @param index index to delete + * @throws CoserBusinessException + */ + public void deleteData(Project project, Control control, Category category, String index) throws CoserBusinessException { + deleteData(project, control, category, index, null); + } + + /** * Replace une valeur d'un champs si nécéssaire. * * If {@code currentValue} is not equals to current data value for fieldName, Modified: trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/control/ControlHandler.java =================================================================== --- trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/control/ControlHandler.java 2010-11-03 16:10:01 UTC (rev 158) +++ trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/control/ControlHandler.java 2010-11-03 16:11:03 UTC (rev 159) @@ -49,12 +49,15 @@ import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.event.ListSelectionEvent; +import javax.swing.event.TreeSelectionEvent; +import javax.swing.tree.TreePath; import jaxx.runtime.JAXXUtil; import jaxx.runtime.SwingUtil; import jaxx.runtime.validator.swing.SwingValidator; import org.apache.commons.beanutils.PropertyUtils; +import org.apache.commons.lang.ArrayUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.jfree.chart.ChartPanel; @@ -112,12 +115,15 @@ int[] dataSelectedRows = controlView.getControlDataTable().getSelectedRows(); final int columnIndex = controlView.getControlDataTable().getColumnModel().getColumnIndexAtX(event.getX()); + JPopupMenu popupMenu = new JPopupMenu(_("coser.ui.control.dataMenuLabel")); + // plusieurs lignes selectionnées et pas la premiere colonne (Line index) if (dataSelectedRows.length > 0 && columnIndex > 0) { ControlDataTableModel controlDataModel = controlView.getControlDataTableModel(); final String columnName = controlView.getControlDataTable().getColumnName(columnIndex); final String firstValue = (String)controlDataModel.getValueAt(dataSelectedRows[0], columnIndex); - JPopupMenu popupMenu = new JPopupMenu(_("coser.ui.control.dataMenuLabel")); + + // replace in selection JMenuItem replaceMenu = new JMenuItem(_("coser.ui.control.dataMenuReplace", columnName)); replaceMenu.addActionListener(new ActionListener() { @Override @@ -132,12 +138,84 @@ } }); popupMenu.add(replaceMenu); - popupMenu.show(controlView.getControlDataTable(), event.getX(), event.getY()); } + + // replace in everywhere + if (columnIndex > 0) { + final String columnName = controlView.getControlDataTable().getColumnName(columnIndex); + JMenuItem replaceAllMenu = new JMenuItem(_("coser.ui.control.dataMenuReplaceAll", columnName)); + replaceAllMenu.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + ControlFindReplaceDialog viewDialog = new ControlFindReplaceDialog(controlView); + viewDialog.setHandler(ControlHandler.this); + viewDialog.setColumnIndex(columnIndex); + viewDialog.getReplaceFieldNameLabel().setText(columnName); + viewDialog.setLocationRelativeTo(controlView); + viewDialog.setVisible(true); + } + }); + popupMenu.add(replaceAllMenu); + } + + // delete selected + if (dataSelectedRows.length > 0) { + + JMenuItem deleteSelectedMenu = new JMenuItem(_("coser.ui.control.dataMenuDeleteSelected")); + deleteSelectedMenu.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + deletedSelectedDataLines(controlView); + } + }); + popupMenu.add(deleteSelectedMenu); + } + + popupMenu.show(controlView.getControlDataTable(), event.getX(), event.getY()); } } /** + * Delete selected line in data table (called from context menu). + * + * @param controlView view + */ + protected void deletedSelectedDataLines(ControlView controlView) { + + JTable controlDataTable = controlView.getControlDataTable(); + int[] selectedLines = controlDataTable.getSelectedRows(); + if (ArrayUtils.isNotEmpty(selectedLines)) { + + int response = JOptionPane.showConfirmDialog(controlView, _("coser.ui.control.confirmDeletionsMessage", selectedLines.length), + _("coser.ui.control.confirmDeletionTitle"), + JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE); + + if (response == JOptionPane.YES_OPTION) { + Project project = controlView.getContextValue(Project.class); + ProjectService projectService = controlView.getContextValue(ProjectService.class); + Category category = (Category)controlView.getCategoryComboBox().getSelectedItem(); + + ControlDataTableModel model = (ControlDataTableModel)controlDataTable.getModel(); + String commandUUID = UUID.randomUUID().toString(); + + // il faut le faire à l'envers, sinon, les index de + // selection change en cours de route + for (int indexSelected = selectedLines.length - 1 ; indexSelected >= 0 ; --indexSelected) { + int selectedLine = selectedLines[indexSelected]; + String[] data = model.getDataAt(selectedLine); + try { + projectService.deleteData(project, project.getControl(), category, data[AbstractDataEntity.INDEX_LINE], commandUUID); + model.fireTableRowsDeleted(selectedLine, selectedLine); + } + catch (CoserBusinessException ex) { + throw new CoserException("Can't delete data", ex); + } + } + } + } + } + + /** * Perform find and replace. * * @param replaceView view @@ -336,22 +414,91 @@ * @param view view * @param event selection event */ - public void showSelectedError(ControlView view, ListSelectionEvent event) { - int selectedError = view.getValidationGlobalErrorsTable().getSelectedRow(); - if (selectedError != -1) { - /*ValidationError error = view.getGlobalValidationModel().getErrorAt(selectedError); - String errorLineNumber = error.getLineNumber(); - - // peut être null, si l'erreur ne porte pas sur un bean en particulier - if (errorLineNumber != null) { - int errorLineIndex = view.getControlDataTableModel().getRealIndexOfLine(errorLineNumber); - view.getControlDataTableSelectionModel().setSelectionInterval(errorLineIndex, errorLineIndex); - scrollToVisible(view.getControlDataTable(), errorLineIndex, 0); - }*/ + public void showSelectedError(ControlView view, TreeSelectionEvent event) { + TreePath selectedError = view.getValidationGlobalErrorsTable().getTreeSelectionModel().getSelectionPath(); + if (selectedError != null) { + Object[] pathWay = selectedError.getPath(); + + // 2 = validation group (middle level) + // 3 = validation error (last level) + if (pathWay.length == 3) { + ValidationError error = (ValidationError)pathWay[2]; + String errorLineNumber = error.getLineNumber(); + // peut être null, si l'erreur ne porte pas sur un bean en particulier + if (errorLineNumber != null) { + int errorLineIndex = view.getControlDataTableModel().getRealIndexOfLine(errorLineNumber); + + // ca peut arriver si la ligne a été supprimée + if (errorLineIndex >= 0) { + view.getControlDataTableSelectionModel().setSelectionInterval(errorLineIndex, errorLineIndex); + scrollToVisible(view.getControlDataTable(), errorLineIndex, 0); + } + } + } } } + + /** + * Affiche le menu contextuel de l'arbre qui contient les erreurs de + * validation globales. + * + * @param controlView view + * @param event mouse event + */ + public void showGlobalErrorTableContextMenu(final ControlView controlView, MouseEvent event) { + // clic contextuel + if (event.getButton() == MouseEvent.BUTTON3) { + TreePath selectedError = controlView.getValidationGlobalErrorsTable().getTreeSelectionModel().getSelectionPath(); + + // plusieurs lignes selectionnées et pas la premiere colonne (Line index) + if (selectedError != null) { + Object[] pathWay = selectedError.getPath(); + + // 2 = validation group (middle level) + if (pathWay.length == 2) { + final GlobalValidationGroup validationGroup = (GlobalValidationGroup)pathWay[1]; + JPopupMenu popupMenu = new JPopupMenu(_("coser.ui.control.globalErrorMenuLabel")); + JMenuItem replaceMenu = new JMenuItem(_("coser.ui.control.globalErrorMenuSelectAll")); + replaceMenu.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + selectAllErrorGroupLines(controlView, validationGroup); + } + }); + popupMenu.add(replaceMenu); + popupMenu.show(controlView.getValidationGlobalErrorsTable(), event.getX(), event.getY()); + } + } + } + } + /** + * Selectionne toutes les lignes associés au erreur d'un group d'erreur. + * + * @param controlView controlView + * @param validationGroup validationGroup + */ + protected void selectAllErrorGroupLines(ControlView controlView, GlobalValidationGroup validationGroup) { + GlobalValidationModel model = controlView.getGlobalValidationModel(); + controlView.getControlDataTableSelectionModel().clearSelection(); + int childCount = model.getChildCount(validationGroup); + for (int indexChild = 0 ; indexChild < childCount ; ++indexChild) { + ValidationError validationError = (ValidationError)model.getChild(validationGroup, indexChild); + String errorLineNumber = validationError.getLineNumber(); + int errorLineIndex = controlView.getControlDataTableModel().getRealIndexOfLine(errorLineNumber); + + // ca peut arriver si la ligne a été supprimée + if (errorLineIndex >= 0) { + controlView.getControlDataTableSelectionModel().addSelectionInterval(errorLineIndex, errorLineIndex); + if (indexChild == 0) { + scrollToVisible(controlView.getControlDataTable(), errorLineIndex, 0); + } + } + } + } + + /** * Scroll le viewport de la table à la ligne demandée. * * @param table table Modified: trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/control/ControlView.jaxx =================================================================== --- trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/control/ControlView.jaxx 2010-11-03 16:10:01 UTC (rev 158) +++ trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/control/ControlView.jaxx 2010-11-03 16:11:03 UTC (rev 159) @@ -39,6 +39,10 @@ <row> <cell fill="horizontal" insets="0" anchor="west" columns="2"> <JToolBar floatable="false"> + <JButton id="saveButton" icon="bullet_disk.png" + text="coser.ui.control.save" enabled="false" + onActionPerformed="getHandler().saveControl(this)" /> + <JSeparator /> <fr.ifremer.coser.ui.control.ControlCategoryListModel id="categoryComboBoxModel" /> <JComboBox id="categoryComboBox" model="{categoryComboBoxModel}" renderer="{new fr.ifremer.coser.ui.control.ControlCategoryListRenderer()}" @@ -122,9 +126,11 @@ <GlobalValidationModel id="globalValidationModel" /> <JXTreeTable id='validationGlobalErrorsTable' treeTableModel="{globalValidationModel}" rootVisible="false" showsRootHandles="true" - treeCellRenderer="{new ControlValidationRenderer()}" /> - <ListSelectionModel id="globalValidationTableSelectionModel" - javaBean="validationGlobalErrorsTable.getSelectionModel()" + treeCellRenderer="{new ControlValidationRenderer()}" + onMouseClicked="getHandler().showGlobalErrorTableContextMenu(this, event)" + selectionMode="{ListSelectionModel.SINGLE_SELECTION}" /> + <javax.swing.tree.TreeSelectionModel id="globalValidationTableSelectionModel" + javaBean="validationGlobalErrorsTable.getTreeSelectionModel()" onValueChanged="getHandler().showSelectedError(this, event)" /> </JScrollPane> </cell> @@ -142,10 +148,4 @@ <JButton text="coser.ui.validation.checkData" onActionPerformed="getHandler().checkData(this)" /> </cell> </row> - <row> - <cell anchor="east" columns="2"> - <JButton id="saveButton" text="coser.ui.control.save" enabled="false" - onActionPerformed="getHandler().saveControl(this)" /> - </cell> - </row> </Table> Modified: trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/control/GlobalValidationGroup.java =================================================================== --- trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/control/GlobalValidationGroup.java 2010-11-03 16:10:01 UTC (rev 158) +++ trunk/coser-ui/src/main/java/fr/ifremer/coser/ui/control/GlobalValidationGroup.java 2010-11-03 16:11:03 UTC (rev 159) @@ -1,25 +1,23 @@ /* * #%L - * - * * $Id$ * $HeadURL$ * %% * Copyright (C) 2010 Ifremer, Codelutin, Chatellier Eric * %% * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as + * 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 Lesser Public License for more details. + * GNU General Public License for more details. * - * You should have received a copy of the GNU General Lesser Public + * You should have received a copy of the GNU General Public * License along with this program. If not, see - * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * <http://www.gnu.org/licenses/gpl-3.0.html>. * #L% */ Modified: trunk/coser-ui/src/main/resources/i18n/coser-ui-en_GB.properties =================================================================== --- trunk/coser-ui/src/main/resources/i18n/coser-ui-en_GB.properties 2010-11-03 16:10:01 UTC (rev 158) +++ trunk/coser-ui/src/main/resources/i18n/coser-ui-en_GB.properties 2010-11-03 16:11:03 UTC (rev 159) @@ -9,7 +9,6 @@ coser.config.support.email.description=Support email address coser.ui.common.cancel=Cancel coser.ui.common.comment=Comment -coser.ui.common.delete=Delete coser.ui.common.selectAll=All coser.ui.common.selectFile=Select\u2026 coser.ui.common.unselectAll=None @@ -17,12 +16,16 @@ coser.ui.config.title=Configuration coser.ui.control.confirmDeletionMessage=Are you sure you want to delete this data ? coser.ui.control.confirmDeletionTitle=Confirm delete +coser.ui.control.confirmDeletionsMessage=Are you sure you want to delete %d selected lines ? +coser.ui.control.dataMenuDeleteSelected=Deleted selected lines coser.ui.control.dataMenuLabel=Data menu -coser.ui.control.dataMenuReplace=Replace in %s +coser.ui.control.dataMenuReplace=Replace in %s for selection +coser.ui.control.dataMenuReplaceAll=Replace in %s in all data coser.ui.control.deleteLine=Delete line coser.ui.control.global.done=\u2026 -coser.ui.control.global.level=Type coser.ui.control.global.message=Message +coser.ui.control.globalErrorMenuLabel=Error menu +coser.ui.control.globalErrorMenuSelectAll=Select all lines coser.ui.control.graph.specy=Specy \: coser.ui.control.graphtitle=Graph coser.ui.control.replace.find=Find \: Modified: trunk/coser-ui/src/main/resources/i18n/coser-ui-fr_FR.properties =================================================================== --- trunk/coser-ui/src/main/resources/i18n/coser-ui-fr_FR.properties 2010-11-03 16:10:01 UTC (rev 158) +++ trunk/coser-ui/src/main/resources/i18n/coser-ui-fr_FR.properties 2010-11-03 16:11:03 UTC (rev 159) @@ -9,7 +9,6 @@ coser.config.support.email.description=Adresse de suport pour l'envoi des erreurs coser.ui.common.cancel=Annuler coser.ui.common.comment=Commentaire -coser.ui.common.delete=Supprimer coser.ui.common.selectAll=Tous coser.ui.common.selectFile=S\u00E9lectionner\u2026 coser.ui.common.unselectAll=Aucun @@ -17,12 +16,16 @@ coser.ui.config.title=Configuration coser.ui.control.confirmDeletionMessage=\u00CAtes vous s\u00FBr de vouloir supprimer cette donn\u00E9e ? coser.ui.control.confirmDeletionTitle=Confirmation de suppression +coser.ui.control.confirmDeletionsMessage=\u00CAtes vous s\u00FBr de vouloir supprimer les %d lignes s\u00E9lectionn\u00E9es ? +coser.ui.control.dataMenuDeleteSelected=Supprimer les lignes s\u00E9lectionn\u00E9es coser.ui.control.dataMenuLabel=Menu des donn\u00E9es -coser.ui.control.dataMenuReplace=Remplacer dans %s +coser.ui.control.dataMenuReplace=Remplacer dans %s pour la s\u00E9lection +coser.ui.control.dataMenuReplaceAll=Replacer dans %s pour toutes les lignes coser.ui.control.deleteLine=Supprimer la ligne coser.ui.control.global.done=\u2026 -coser.ui.control.global.level=Type coser.ui.control.global.message=Message +coser.ui.control.globalErrorMenuLabel=Menu des erreurs +coser.ui.control.globalErrorMenuSelectAll=S\u00E9lectionner toutes les lignes coser.ui.control.graph.specy=Esp\u00E8ces \: coser.ui.control.graphtitle=Graphique coser.ui.control.replace.find=Chercher \: