Author: tchemit Date: 2014-01-29 18:47:27 +0100 (Wed, 29 Jan 2014) New Revision: 1538 Url: http://forge.codelutin.com/projects/tutti/repository/revisions/1538 Log: refs #3875: Import des mensurations en continue depuis un ictyom?\195?\168tre Added: trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/action/ConnectIchtyometerAction.java trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/action/DisconnectIchtyometerAction.java Modified: trunk/tutti-ui-swing/pom.xml trunk/tutti-ui-swing/src/main/filtered-resources/tutti-help-fr.properties trunk/tutti-ui-swing/src/main/help/fr/menu.html trunk/tutti-ui-swing/src/main/help/fr/navbar.js trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/TuttiUIContext.java trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/MainUI.css trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/MainUI.jaxx trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/MainUIHandler.java trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SpeciesFrequencyUIHandler.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/pom.xml =================================================================== --- trunk/tutti-ui-swing/pom.xml 2014-01-29 17:41:11 UTC (rev 1537) +++ trunk/tutti-ui-swing/pom.xml 2014-01-29 17:47:27 UTC (rev 1538) @@ -105,6 +105,11 @@ <artifactId>tutti-service</artifactId> <version>${project.version}</version> </dependency> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>tutti-ichtyometer</artifactId> + <version>${project.version}</version> + </dependency> <!-- Ifremer shared --> <dependency> 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 2014-01-29 17:41:11 UTC (rev 1537) +++ trunk/tutti-ui-swing/src/main/filtered-resources/tutti-help-fr.properties 2014-01-29 17:47:27 UTC (rev 1538) @@ -1,5 +1,5 @@ #Generated by org.nuiton.jaxx.plugin.GenerateHelpIdsMojo -#Tue Jan 21 11:51:19 CET 2014 +#Wed Jan 29 07:36:56 CET 2014 tutti.config.help=config.html tutti.createAccidentalBatch.action.cancel.help=editFishingOperation.html\#captureCapturesAccidentellesActions tutti.createAccidentalBatch.action.saveAndClose.help=editFishingOperation.html\#captureCapturesAccidentellesActions @@ -320,8 +320,12 @@ tutti.main.menu.action.showHelp.help=menu.html\#menu_aide tutti.main.menu.action.site.help=menu.html\#menu_aide tutti.main.menu.action.updateApplication.help=menu.html\#menu_fichier +tutti.main.menu.action.connectIchtyometer.help=menu.html\#menu_fichier +tutti.main.menu.action.disconnectIchtyometer.help=menu.html\#menu_fichier tutti.main.menu.action.updateReport.help=menu.html\#menu_fichier tutti.main.menu.action.validateCatches.help=menu.html\#menu_action +tutti.main.status.ichtyometer.help=menu.html\#status +tutti.main.status.validation.help=menu.html\#status tutti.manageTemporaryReferential.action.exportTemporaryGearExample.help=menu.html\#menu_administration_referentiel tutti.manageTemporaryReferential.action.exportTemporaryPersonExample.help=menu.html\#menu_administration_referentiel tutti.manageTemporaryReferential.action.exportTemporarySpeciesExample.help=menu.html\#menu_administration_referentiel Modified: trunk/tutti-ui-swing/src/main/help/fr/menu.html =================================================================== --- trunk/tutti-ui-swing/src/main/help/fr/menu.html 2014-01-29 17:41:11 UTC (rev 1537) +++ trunk/tutti-ui-swing/src/main/help/fr/menu.html 2014-01-29 17:47:27 UTC (rev 1538) @@ -72,6 +72,14 @@ <a name="menu_fichier_mise_a_jour_rapport"></a> Permet de vérifier les mises à jour des rapports utilisés dans l'aplication.<br> +<h3>Se connecter à un ichtyomètre</h3> +<a name="menu_fichier_connection_ichtyometre"></a> +Permet de se connecter à un ichtyomètre de type BigFin pour ensuite pouvoir récupérer en temps réel les mesures effectués dans l'écran des mensurations.<br> + +<h3>Se déconnecter d'un ichtyomètre</h3> +<a name="menu_fichier_decconnection_ichtyometre"></a> +Permet de ne plus écouter un ichtyomètre.<br> + <h3>Gestionnaire de base</h3> <a name="menu_fichier_gestionnaire_base"></a> Modified: trunk/tutti-ui-swing/src/main/help/fr/navbar.js =================================================================== --- trunk/tutti-ui-swing/src/main/help/fr/navbar.js 2014-01-29 17:41:11 UTC (rev 1537) +++ trunk/tutti-ui-swing/src/main/help/fr/navbar.js 2014-01-29 17:47:27 UTC (rev 1538) @@ -39,6 +39,8 @@ document.write(' <li><a href="menu.html#menu_fichier_configuration">Configuration</a></li>'); document.write(' <li><a href="menu.html#menu_fichier_mise_a_jour_logicelle">Vérifier les mises à jour logicielles</a></li>'); document.write(' <li><a href="menu.html#menu_fichier_mise_a_jour_rapport">Vérifier les mises à jour des rapports</a></li>'); +document.write(' <li><a href="menu.html#menu_fichier_connection_ichtyometre">Se connecter à un ichtyomètre</a></li>'); +document.write(' <li><a href="menu.html#menu_fichier_deconnection_ichtyometre">Se déconnecter d'un ichtyomètre</a></li>'); document.write(' <li><a href="menu.html#menu_fichier_gestionnaire_base">Gestionnaire de bases</a></li>'); document.write(' <li><a href="menu.html#menu_fichier_quitter">Quitter</a></li>'); document.write(' </ul>'); Modified: trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/TuttiUIContext.java =================================================================== --- trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/TuttiUIContext.java 2014-01-29 17:41:11 UTC (rev 1537) +++ trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/TuttiUIContext.java 2014-01-29 17:47:27 UTC (rev 1538) @@ -38,6 +38,7 @@ import fr.ifremer.shared.application.swing.action.ApplicationActionUI; import fr.ifremer.shared.application.swing.util.ApplicationErrorHelper; import fr.ifremer.tutti.TuttiConfiguration; +import fr.ifremer.tutti.ichtyometer.feed.FeedReader; import fr.ifremer.tutti.persistence.RessourceClassLoader; import fr.ifremer.tutti.service.ClosedPersistenceService; import fr.ifremer.tutti.service.DecoratorService; @@ -129,6 +130,8 @@ public static final String PROPERTY_VALIDATION_CONTEXT = "validationContext"; + public static final String PROPERTY_ICHTYOMETER_CONNECTED = "ichtyometerConnected"; + public static final String PROPERTY_BUSY = "busy"; public static final String PROPERTY_HIDE_BODY = "hideBody"; @@ -267,8 +270,20 @@ private final ApplicationActionEngine tuttiActionEngine; + /** + * To keep authentication credential in memory. + * + * @since 3.1 + */ private final Map<String, AuthenticationInfo> updateAuthenticationStore; + /** + * Ichtyometer Reader. + * + * @since 3.1 + */ + private FeedReader ichtyometerReader; + public static TuttiUIContext newContext(TuttiConfiguration config) { Preconditions.checkNotNull(config); Preconditions.checkState(applicationContext == null, @@ -545,6 +560,7 @@ setScreen(null); IOUtils.closeQuietly(serviceContext); + IOUtils.closeQuietly(ichtyometerReader); // remove listeners PropertyChangeListener[] listeners = getPropertyChangeListeners(); @@ -716,8 +732,6 @@ public void clearDbContext() { dataContext.clearContext(); - -// saveContextToConfig(); } public void checkDbContext() { @@ -793,6 +807,27 @@ return actionUI; } + public ApplicationActionUI getExistingActionUI() { + while (actionUI == null) { + + try { + Thread.sleep(50); + } catch (InterruptedException e) { + // ignore this one + } + } + return actionUI; + } + + public ApplicationActionUI getExistingActionUIWhenMainUINotNull() { + ApplicationActionUI result = null; + if (mainUI != null) { + result = getExistingActionUI(); + } + return result; + } + + public void setActionUI(ApplicationActionUI actionUI) { this.actionUI = actionUI; } @@ -948,6 +983,23 @@ } //------------------------------------------------------------------------// + //-- Ichtyometer methods --// + //------------------------------------------------------------------------// + + public FeedReader getIchtyometerReader() { + return ichtyometerReader; + } + + public void setIchtyometerReader(FeedReader ichtyometerReader) { + this.ichtyometerReader = ichtyometerReader; + firePropertyChange(PROPERTY_ICHTYOMETER_CONNECTED, null, isIchtyometerConnected()); + } + + public boolean isIchtyometerConnected() { + return ichtyometerReader != null; + } + + //------------------------------------------------------------------------// //-- Other methods --// //------------------------------------------------------------------------// Added: trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/action/ConnectIchtyometerAction.java =================================================================== --- trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/action/ConnectIchtyometerAction.java (rev 0) +++ trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/action/ConnectIchtyometerAction.java 2014-01-29 17:47:27 UTC (rev 1538) @@ -0,0 +1,90 @@ +package fr.ifremer.tutti.ui.swing.action; + +/* + * #%L + * Tutti :: UI + * $Id$ + * $HeadURL:$ + * %% + * 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.shared.application.ApplicationBusinessException; +import fr.ifremer.tutti.ichtyometer.IchtyometerClient; +import fr.ifremer.tutti.ichtyometer.LocalDeviceNotFoundException; +import fr.ifremer.tutti.ichtyometer.RemoteDeviceChooser; +import fr.ifremer.tutti.ichtyometer.RemoteDeviceNotFoundException; +import fr.ifremer.tutti.ichtyometer.RemoteDeviceServiceNotFoundException; +import fr.ifremer.tutti.ichtyometer.feed.FeedReader; +import fr.ifremer.tutti.ui.swing.content.MainUIHandler; + +import javax.swing.JOptionPane; +import java.util.Set; + +import static org.nuiton.i18n.I18n._; + +/** + * Establish a connection to an ichtyometer. + * <p/> + * Created on 1/29/14. + * + * @author Tony Chemit <chemit@codelutin.com> + * @since 3.1 + */ +public class ConnectIchtyometerAction extends AbstractMainUITuttiAction { + + public ConnectIchtyometerAction(MainUIHandler handler) { + super(handler, false); + } + + @Override + public void doAction() throws Exception { + + IchtyometerClient client = new IchtyometerClient(); + + RemoteDeviceChooser remoteDeviceChooser = new RemoteDeviceChooser() { + @Override + public String chooseRemoteDevice(Set<String> remoteDeviceNames) { + String selectedDevice = (String) JOptionPane.showInputDialog( + getContext().getExistingActionUI(), + _("tutti.ichtyometer.choose.remote.device.found"), + _("tutti.ichtyometer.title.choose.remote.device"), + JOptionPane.QUESTION_MESSAGE, + null, + remoteDeviceNames.toArray(new String[remoteDeviceNames.size()]), + null + ); + return selectedDevice; + } + }; + try { + client.open(remoteDeviceChooser); + } catch (LocalDeviceNotFoundException e) { + throw new ApplicationBusinessException(_("tutti.ichtyometer.error.no.local.device")); + } catch (RemoteDeviceNotFoundException e) { + throw new ApplicationBusinessException(_("tutti.ichtyometer.error.no.remote.device")); + } catch (RemoteDeviceServiceNotFoundException e) { + throw new ApplicationBusinessException(_("tutti.ichtyometer.error.no.remote.device.service")); + } + FeedReader ichtyometerReader = new FeedReader(); + ichtyometerReader.start(client); + sendMessage(_("tutti.ichtyometer.connection.establish", client.getName())); + + getContext().setIchtyometerReader(ichtyometerReader); + } +} Property changes on: trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/action/ConnectIchtyometerAction.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Added: trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/action/DisconnectIchtyometerAction.java =================================================================== --- trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/action/DisconnectIchtyometerAction.java (rev 0) +++ trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/action/DisconnectIchtyometerAction.java 2014-01-29 17:47:27 UTC (rev 1538) @@ -0,0 +1,58 @@ +package fr.ifremer.tutti.ui.swing.action; + +/* + * #%L + * Tutti :: UI + * $Id$ + * $HeadURL:$ + * %% + * 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.ichtyometer.feed.FeedReader; +import fr.ifremer.tutti.ui.swing.content.MainUIHandler; +import org.apache.commons.io.IOUtils; + +import static org.nuiton.i18n.I18n._; + +/** + * Close the connection to ichtyometer. + * <p/> + * Created on 1/29/14. + * + * @author Tony Chemit <chemit@codelutin.com> + * @since 3.1 + */ +public class DisconnectIchtyometerAction extends AbstractMainUITuttiAction { + + public DisconnectIchtyometerAction(MainUIHandler handler) { + super(handler, false); + } + + @Override + public void doAction() throws Exception { + + FeedReader ichtyometerReader = getContext().getIchtyometerReader(); + + // there is a feed reader, stop it now + IOUtils.closeQuietly(ichtyometerReader); + getContext().setIchtyometerReader(null); + + sendMessage(_("tutti.ichtyometer.connection.stop", ichtyometerReader.getClientName())); + } +} Property changes on: trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/action/DisconnectIchtyometerAction.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Modified: trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/MainUI.css =================================================================== --- trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/MainUI.css 2014-01-29 17:41:11 UTC (rev 1537) +++ trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/MainUI.css 2014-01-29 17:47:27 UTC (rev 1538) @@ -89,6 +89,26 @@ _help: {"tutti.main.menu.action.updateReport.help"}; } +#menuFileConnectIchtyometer { + actionIcon: bluetooth-down; + text: "tutti.main.action.connectIchtyometer"; + toolTipText: "tutti.main.action.connectIchtyometer.tip"; + i18nMnemonic: "tutti.main.action.connectIchtyometer.mnemonic"; + visible: {!model.isIchtyometerConnected()}; + _applicationAction: {fr.ifremer.tutti.ui.swing.action.ConnectIchtyometerAction.class}; + _help: {"tutti.main.menu.action.connectIchtyometer.help"}; +} + +#menuFileDisconnectIchtyometer { + actionIcon: bluetooth-up; + text: "tutti.main.action.disconnectIchtyometer"; + toolTipText: "tutti.main.action.disconnectIchtyometer.tip"; + i18nMnemonic: "tutti.main.action.disconnectIchtyometer.mnemonic"; + visible: {model.isIchtyometerConnected()}; + _applicationAction: {fr.ifremer.tutti.ui.swing.action.DisconnectIchtyometerAction.class}; + _help: {"tutti.main.menu.action.disconnectIchtyometer.help"}; +} + #menuFileManageDb { actionIcon: manage-db; text: "tutti.main.action.manageDb"; @@ -260,8 +280,17 @@ #validatorMessageWidget { focusPainted: false; + _help: {"tutti.main.status.validation.help"}; } +#ichtyometerStatus { + actionIcon: "bluetooth-up"; + disabledIcon: {jaxx.runtime.SwingUtil.createActionIcon("bluetooth-down")}; + enabled: {model.isIchtyometerConnected()}; + toolTipText: {handler.getIchtyometerStatusTip(model.isIchtyometerConnected())}; + _help: {"tutti.main.status.ichtyometer.help"}; +} + #showHelp { actionIcon:"show-help"; toolTipText:"tutti.main.action.showHelp.tip"; Modified: trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/MainUI.jaxx =================================================================== --- trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/MainUI.jaxx 2014-01-29 17:41:11 UTC (rev 1537) +++ trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/MainUI.jaxx 2014-01-29 17:47:27 UTC (rev 1538) @@ -42,27 +42,17 @@ java.awt.BorderLayout </import> - <TuttiUIContext id='model' - initializer='getContextValue(TuttiUIContext.class)'/> - <!--<MainUIHandler id='handler'--> - <!--initializer='getContextValue(MainUIHandler.class)'/>--> - <TuttiHelpBroker id='broker' - constructorParams='"tutti.main.help"'/> + <TuttiUIContext id='model' initializer='getContextValue(TuttiUIContext.class)'/> + <TuttiHelpBroker id='broker' constructorParams='"tutti.main.help"'/> + <BlockingLayerUI id='busyBlockLayerUI'/> <script><![CDATA[ public MainUI(TuttiUIContext context) { TuttiUIUtil.setApplicationContext(this, context); - //setContextValue(context); - //MainUIHandler handler = new MainUIHandler(context, this); - //setContextValue(handler); - //handler.beforeInitUI(); } - /*protected void $afterCompleteSetup() { - handler.afterInitUI(); - }*/ ]]></script> <!-- menu --> @@ -72,6 +62,9 @@ <JMenuItem id='menuFileUpdateApplication'/> <JMenuItem id='menuFileUpdateReport'/> <JSeparator/> + <JMenuItem id='menuFileConnectIchtyometer'/> + <JMenuItem id='menuFileDisconnectIchtyometer'/> + <JSeparator/> <JMenuItem id='menuFileManageDb'/> <JSeparator/> <JMenuItem id='menuFileExit'/> @@ -106,6 +99,7 @@ </JMenuBar> <JToolBar id='bottomBar'> + <JLabel id='ichtyometerStatus'/> <SwingValidatorMessageWidget id='validatorMessageWidget'/> </JToolBar> Modified: trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/MainUIHandler.java =================================================================== --- trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/MainUIHandler.java 2014-01-29 17:41:11 UTC (rev 1537) +++ trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/MainUIHandler.java 2014-01-29 17:47:27 UTC (rev 1538) @@ -28,6 +28,7 @@ import fr.ifremer.shared.application.swing.action.ApplicationActionUI; import fr.ifremer.shared.application.swing.util.CloseableUI; import fr.ifremer.tutti.TuttiConfiguration; +import fr.ifremer.tutti.ichtyometer.feed.FeedReader; import fr.ifremer.tutti.persistence.entities.data.Cruise; import fr.ifremer.tutti.persistence.entities.data.Program; import fr.ifremer.tutti.persistence.entities.protocol.TuttiProtocol; @@ -96,6 +97,16 @@ } } + public String getIchtyometerStatusTip(boolean connected) { + String result; + if (connected) { + FeedReader ichtyometerReader = getModel().getIchtyometerReader(); + result =_("tutti.ichtyometer.status.connected.tip", ichtyometerReader.getClientName()); + } else { + result=_("tutti.ichtyometer.status.not.connected.tip"); + } + return result; + } //------------------------------------------------------------------------// //-- AbstractTuttiUIHandler methods --// //------------------------------------------------------------------------// Modified: trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SpeciesFrequencyUIHandler.java =================================================================== --- trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SpeciesFrequencyUIHandler.java 2014-01-29 17:41:11 UTC (rev 1537) +++ trunk/tutti-ui-swing/src/main/java/fr/ifremer/tutti/ui/swing/content/operation/catches/species/frequency/SpeciesFrequencyUIHandler.java 2014-01-29 17:47:27 UTC (rev 1538) @@ -27,13 +27,18 @@ import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; +import fr.ifremer.shared.application.ApplicationBusinessException; import fr.ifremer.shared.application.swing.util.Cancelable; import fr.ifremer.shared.application.type.WeightUnit; +import fr.ifremer.tutti.ichtyometer.feed.FeedReaderEvent; +import fr.ifremer.tutti.ichtyometer.feed.FeedReaderListener; +import fr.ifremer.tutti.ichtyometer.feed.FeedReaderRecord; import fr.ifremer.tutti.persistence.entities.TuttiEntities; import fr.ifremer.tutti.persistence.entities.data.SampleCategoryModel; import fr.ifremer.tutti.persistence.entities.protocol.SpeciesProtocol; import fr.ifremer.tutti.persistence.entities.referential.Caracteristic; import fr.ifremer.tutti.persistence.entities.referential.Species; +import fr.ifremer.tutti.ui.swing.TuttiUIContext; 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.FrequencyConfigurationMode; @@ -90,11 +95,34 @@ */ protected WeightUnit weightUnit; + /** + * To consume measures when they arrive from the ichtyometer. + */ + protected final FeedReaderListener feedReaderListener; + public SpeciesFrequencyUIHandler() { super(SpeciesFrequencyRowModel.PROPERTY_LENGTH_STEP, SpeciesFrequencyRowModel.PROPERTY_NUMBER, SpeciesFrequencyRowModel.PROPERTY_WEIGHT); + this.feedReaderListener = new FeedReaderListener() { + + @Override + public void recordRead(FeedReaderEvent event) { + + final FeedReaderRecord record = event.getRecord(); + + SwingUtilities.invokeLater( + new Runnable() { + @Override + public void run() { + consumeFeedRecord(record); + } + } + ); + } + }; + } //------------------------------------------------------------------------// @@ -212,6 +240,20 @@ weightUnit, sampleCategoryModel); this.ui.setContextValue(model); + + // listen when ichtyometer is connected or not and adjust the listener + getContext().addPropertyChangeListener(TuttiUIContext.PROPERTY_ICHTYOMETER_CONNECTED, new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + boolean connected = (boolean) evt.getNewValue(); + + if (connected && SpeciesFrequencyUIHandler.this.frequencyEditor != null) { + + // listen when itchtyometer is connected and this ui is showing + listenItchtyometer(); + } + } + }); } @Override @@ -261,7 +303,7 @@ e.consume(); Float step = (Float) SpeciesFrequencyUIHandler.this.ui.getRafaleStepField().getModel(); - applyRafaleStep(step); + applyRafaleStep(step, false); //select text JTextField field = (JTextField) e.getSource(); @@ -387,6 +429,11 @@ EditCatchesUI parent = getParentContainer(EditCatchesUI.class); parent.getHandler().setSpeciesSelectedCard(EditCatchesUIHandler.MAIN_CARD); + + if (getContext().isIchtyometerConnected()) { + + getContext().getIchtyometerReader().removeFeedModeReaderListener(feedReaderListener); + } } //------------------------------------------------------------------------// @@ -428,7 +475,7 @@ int response = JOptionPane.showConfirmDialog( getTopestUI(), editor, - _("tutti.editBenthosFrequencies.title.addLengthStepCaracteristic"), + _("tutti.editSpeciesFrequencies.title.addLengthStepCaracteristic"), JOptionPane.OK_CANCEL_OPTION); Caracteristic selectedItem; @@ -479,7 +526,7 @@ TuttiUIUtil.doSelectCell(getUI().getTable(), 0, 1); } - public void applyRafaleStep(Float step) { + public void applyRafaleStep(Float step, boolean fromIchtyometer) { if (log.isDebugEnabled()) { log.debug("Will apply rafale step: " + step); @@ -528,6 +575,10 @@ model.setTotalNumber(totalNumber + 1); getTable().scrollRowToVisible(rowIndex); + + if (fromIchtyometer) { + showInformationMessage(_("tutti.editSpeciesFrequencies.addMeasure", step, aroundLengthStep)); + } } public void editBatch(FrequencyCellEditor editor) { @@ -634,6 +685,12 @@ } } } + + if (getContext().isIchtyometerConnected()) { + + // let's listen the ichtyometer + listenItchtyometer(); + } } if (log.isDebugEnabled()) { @@ -721,6 +778,28 @@ //-- Internal methods --// //------------------------------------------------------------------------// + protected void consumeFeedRecord(FeedReaderRecord record) { + if (record.isValid()) { + + float length = record.getLength(); + applyRafaleStep(length, true); + } else { + throw new ApplicationBusinessException( + _("tutti.editSpeciesFrequencies.error.itchyometer.bad.record", + record.getRecord(), record.getCrc(), record.getComputedCrc())); + } + } + + protected void listenItchtyometer() { + + // always remove the listener before adding it to be sure it will not be there twice + getContext().getIchtyometerReader().removeFeedModeReaderListener(feedReaderListener); + if (log.isInfoEnabled()) { + log.info("Start listen ichtyometer"); + } + getContext().getIchtyometerReader().addFeedModeReaderListener(feedReaderListener); + } + protected void recomputeTotalNumberAndWeight() { SpeciesFrequencyUIModel model = getModel(); List<SpeciesFrequencyRowModel> rows = model.getRows(); 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 2014-01-29 17:41:11 UTC (rev 1537) +++ trunk/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_en_GB.properties 2014-01-29 17:47:27 UTC (rev 1538) @@ -971,6 +971,9 @@ tutti.editSpeciesBatch.action.exportMultiPost.mnemonic= tutti.editSpeciesBatch.action.exportMultiPost.success= tutti.editSpeciesBatch.action.exportMultiPost.tip= +tutti.editSpeciesBatch.action.ichtyometer= +tutti.editSpeciesBatch.action.ichtyometer.mnemonic= +tutti.editSpeciesBatch.action.ichtyometer.tip= tutti.editSpeciesBatch.action.importMultiPost= tutti.editSpeciesBatch.action.importMultiPost.mnemonic= tutti.editSpeciesBatch.action.importMultiPost.sourceFile.button= @@ -1075,9 +1078,11 @@ tutti.editSpeciesFrequencies.action.saveAndContinue= tutti.editSpeciesFrequencies.action.saveAndContinue.mnemonic= tutti.editSpeciesFrequencies.action.saveAndContinue.tip= +tutti.editSpeciesFrequencies.addMeasure= tutti.editSpeciesFrequencies.askBeforeSave.help= tutti.editSpeciesFrequencies.askBeforeSave.message= tutti.editSpeciesFrequencies.askBeforeSave.title= +tutti.editSpeciesFrequencies.error.itchyometer.bad.record= tutti.editSpeciesFrequencies.error.length.doublon= tutti.editSpeciesFrequencies.field.lengthStepCaracteristic= tutti.editSpeciesFrequencies.field.lengthStepCaracteristic.tip= @@ -1102,12 +1107,14 @@ tutti.editSpeciesFrequencies.field.totalNumber.tip= tutti.editSpeciesFrequencies.field.totalWeight= tutti.editSpeciesFrequencies.field.totalWeight.tip= +tutti.editSpeciesFrequencies.ichtyometerConnected= tutti.editSpeciesFrequencies.label.no.configuration= tutti.editSpeciesFrequencies.simpleCountingAndFrequencies= tutti.editSpeciesFrequencies.table.header.lengthStep= tutti.editSpeciesFrequencies.table.header.number= tutti.editSpeciesFrequencies.table.header.weight= tutti.editSpeciesFrequencies.title= +tutti.editSpeciesFrequencies.title.addLengthStepCaracteristic= tutti.error.delete.startActionFile=Could not delete start action file %s tutti.error.read.startActionFile=Could not read start action file content %s tutti.error.update.bad.url.syntax= @@ -1185,6 +1192,18 @@ tutti.help.mkDir.error= tutti.i18n.deleteCache.error= tutti.i18n.mkDir.error= +tutti.ichtyometer.choose.remote.device.found= +tutti.ichtyometer.connection.establish= +tutti.ichtyometer.connection.stop= +tutti.ichtyometer.error.no.local.device= +tutti.ichtyometer.error.no.remote.device= +tutti.ichtyometer.error.no.remote.device.service= +tutti.ichtyometer.status.connected.tip= +tutti.ichtyometer.status.not.connected.tip= +tutti.ichtyometer.status.start= +tutti.ichtyometer.status.stop= +tutti.ichtyometer.status.tip= +tutti.ichtyometer.title.choose.remote.device= tutti.importDb.step.check.dbContext= tutti.importDb.step.checkSchemaVersion= tutti.importDb.step.closeDb= @@ -1227,6 +1246,12 @@ tutti.main.action.configuration= tutti.main.action.configuration.mnemonic= tutti.main.action.configuration.tip= +tutti.main.action.connectIchtyometer= +tutti.main.action.connectIchtyometer.mnemonic= +tutti.main.action.connectIchtyometer.tip= +tutti.main.action.disconnectIchtyometer= +tutti.main.action.disconnectIchtyometer.mnemonic= +tutti.main.action.disconnectIchtyometer.tip= tutti.main.action.editCatches= tutti.main.action.editCatches.mnemonic= tutti.main.action.editCatches.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 2014-01-29 17:41:11 UTC (rev 1537) +++ trunk/tutti-ui-swing/src/main/resources/i18n/tutti-ui-swing_fr_FR.properties 2014-01-29 17:47:27 UTC (rev 1538) @@ -974,7 +974,7 @@ tutti.editSpeciesBatch.action.importPsion.existingData.title=Données existantes tutti.editSpeciesBatch.action.importPsion.invalidSampleCategoryModel.message=<html><body>Le modèle de catégorisation n'est pas compatible pour un import psion.<br> Il manque les catégories suivantes \: <ul>%s</ul><hr/>Veuillez ajouter cette catégorie dans la configuration de catégorisation (menu administration).</body></html> tutti.editSpeciesBatch.action.importPsion.invalidSampleCategoryModel.title=Modèle de catégorisation non compatible -tutti.editSpeciesBatch.action.importPsion.mnemonic=P +tutti.editSpeciesBatch.action.importPsion.mnemonic=m tutti.editSpeciesBatch.action.importPsion.no.matching.data=Import psion non réalisé (des erreurs ont été détectées lors de la lecture du fichier) tutti.editSpeciesBatch.action.importPsion.no.matching.fishingOperation=L'import Psion n'a pas été réalisé, des erreurs ont été détectées \:<ul>%s</ul><br/>Aucun lot n'a donc été importé. tutti.editSpeciesBatch.action.importPsion.no.matching.fishingOperation.title=Import Psion @@ -986,7 +986,7 @@ tutti.editSpeciesBatch.action.importPupitri.existingData.title=Données existantes tutti.editSpeciesBatch.action.importPupitri.invalidSampleCategoryModel.message=<html><body>Le modèle de catégorisation n'est pas compatible pour un import pupitri.<br> Il manque les catégories suivantes \: <ul>%s</ul><hr/>Veuillez ajouter cette catégorie dans la configuration de catégorisation (menu administration).</body></html> tutti.editSpeciesBatch.action.importPupitri.invalidSampleCategoryModel.title=Modèle de catégorisation non compatible -tutti.editSpeciesBatch.action.importPupitri.mnemonic=I +tutti.editSpeciesBatch.action.importPupitri.mnemonic=u tutti.editSpeciesBatch.action.importPupitri.no.matching.data=Import pupitri non réalisé (Les identifiants de Station et/ ou de Date du trait ne correspondent pas) tutti.editSpeciesBatch.action.importPupitri.no.matching.fishingOperation=L'application n'a pas trouvé dans les fichiers Trunk et Carrousel les identifiants de Station et/ou de Date du trait en cours de saisie.<br/>Aucun lot n'a donc été importé. tutti.editSpeciesBatch.action.importPupitri.no.matching.fishingOperation.title=Import Pupitri @@ -1066,9 +1066,11 @@ tutti.editSpeciesFrequencies.action.saveAndContinue=Enregistrer et Continuer tutti.editSpeciesFrequencies.action.saveAndContinue.mnemonic=C tutti.editSpeciesFrequencies.action.saveAndContinue.tip=Enregistrer les mensurations et saisir les mensurations pour le lot suivant +tutti.editSpeciesFrequencies.addMeasure=Ajout d'un individu de taille <strong>%s</strong> (classe de taille <strong>%s</strong>) tutti.editSpeciesFrequencies.askBeforeSave.help=Que voulez-vous faire?<ul><li><strong>Non</strong> pour rester sur cet écran</li><li><strong>Oui</strong> pour enregisrer les mensurations avec poids</li></ul> tutti.editSpeciesFrequencies.askBeforeSave.message=La saisie comporte des classes de taille avec et sans poids associés.<br/><strong>Seules les classes de taille avec poids seront dans ce cas sauvegardées.</strong> tutti.editSpeciesFrequencies.askBeforeSave.title=Confirmer l'enregistrement des mensurations +tutti.editSpeciesFrequencies.error.itchyometer.bad.record=La mesure provenant de l'ichtyomètre n'est pas valide (la donnée est peut-être corrompue) \:<br/><ul><li>Enregistrement \: <strong>%s</strong></li><li>CRC \: <strong>%s</strong></li><li>CRC calculé \: <strong>%s</strong></li></ul> tutti.editSpeciesFrequencies.error.length.doublon=La classe de taille <strong>%s</strong> est utilisée plusieurs fois (deuxième occurrence trouvée à la ligne <strong>%s</strong>), ce qui n'est pas autorisé.<hr/>Veuillez corriger cela pour pouvoir enregistrer les mensurations. tutti.editSpeciesFrequencies.field.lengthStepCaracteristic=Type de mesure tutti.editSpeciesFrequencies.field.lengthStepCaracteristic.tip=Méthode de mensuration des individus @@ -1093,12 +1095,14 @@ tutti.editSpeciesFrequencies.field.totalNumber.tip=Nombre total d'individus des lignes valides tutti.editSpeciesFrequencies.field.totalWeight=Poids total tutti.editSpeciesFrequencies.field.totalWeight.tip=Poids total des lignes valides +tutti.editSpeciesFrequencies.ichtyometerConnected=Un ichtyomètre est connecté, les mensurations peuvent être directement renseignées depuis celui-ci. tutti.editSpeciesFrequencies.label.no.configuration=< Pas de configuration > tutti.editSpeciesFrequencies.simpleCountingAndFrequencies=Des mensurations ont été saisies dans le tableau. Saisir un simple dénombrement les effacera. tutti.editSpeciesFrequencies.table.header.lengthStep=Classe de taille tutti.editSpeciesFrequencies.table.header.number=Nombre tutti.editSpeciesFrequencies.table.header.weight=Poids observé tutti.editSpeciesFrequencies.title=Mensuration +tutti.editSpeciesFrequencies.title.addLengthStepCaracteristic=Choisir une autre caractéristique tutti.error.delete.startActionFile=Impossible de supprimer le fichier %s tutti.error.read.startActionFile=Impossible de lire le contenu du fichier %s tutti.error.update.bad.url.syntax=Mise à jour impossible (le format de l'url <strong>%s</strong> n'est pas valide) @@ -1176,6 +1180,15 @@ tutti.help.mkDir.error=Erreur à la création du dossier d'aide tutti.i18n.deleteCache.error=Erreur à la suppression du cache de l'internationalisation tutti.i18n.mkDir.error=Erreur à la création du dossier d'internationalisation +tutti.ichtyometer.choose.remote.device.found=Veuillez choisir le périphérique bluetooth qui correspond à l'ichtyomètre parmis ceux détectés +tutti.ichtyometer.connection.establish=Connexion à l'ichtyomètre <strong>%s</strong> établie +tutti.ichtyometer.connection.stop=Connexion à l'ichtyomètre <strong>%s</strong> arrêtée +tutti.ichtyometer.error.no.local.device=Le bluetooth n'est pas activé sur la machine +tutti.ichtyometer.error.no.remote.device=Aucun périphérique bluetooth détecté ou abandon de l'utilisateur +tutti.ichtyometer.error.no.remote.device.service=Aucun service détecté sur le périphérique bluetooth +tutti.ichtyometer.status.connected.tip=<html><body>L'ichtyomètre <strong>%s</strong> est connecté.</body></html> +tutti.ichtyometer.status.not.connected.tip=<html><body>Aucun ichtyomètre connecté.</body></html> +tutti.ichtyometer.title.choose.remote.device=Choisir l'ichtyomètre parmis les périphériques trouvés tutti.importDb.step.check.dbContext=Vérification du context de saisie tutti.importDb.step.checkSchemaVersion=Vérification de la version de la base tutti.importDb.step.closeDb=Fermeture de la base @@ -1218,6 +1231,12 @@ tutti.main.action.configuration=Configuration tutti.main.action.configuration.mnemonic=C tutti.main.action.configuration.tip=Configurer l'application +tutti.main.action.connectIchtyometer=Ichtyomètre +tutti.main.action.connectIchtyometer.mnemonic=y +tutti.main.action.connectIchtyometer.tip=Se connecter à un ichtyomètre +tutti.main.action.disconnectIchtyometer=Ichtyomètre +tutti.main.action.disconnectIchtyometer.mnemonic=y +tutti.main.action.disconnectIchtyometer.tip=Se déconnecter de l'ichtyomètre tutti.main.action.editCatches=Saisir les captures tutti.main.action.editCatches.mnemonic=S tutti.main.action.editCatches.tip=Éditer les captures