From cff5494db4793d142d17baee12a4ef926759f430 Mon Sep 17 00:00:00 2001 From: Denny Sheirer Date: Sat, 2 May 2020 13:53:44 +0000 Subject: [PATCH] #775 Playlist Editor Cleanup (#779) * #775 Adds frequency column to channel editor * #775 Resolves issue with changing channel processing flag on FX event thread * #775 Removes auto-detect channel settings for P25 Phase 2 configurations. * #775 Playlist editor cleanup actions. Changes style of segmented buttons. Fix issue with channel set processing not on FX thread. Removes P25P2 auto-detect settings feature. Adds frequency column to channel editor. Co-authored-by: Denny --- .../channel/ChannelProcessingManager.java | 11 ++-- .../channel/ChannelConfigurationEditor.java | 3 + .../gui/playlist/channel/ChannelEditor.java | 57 ++++++++++++++++++- .../channel/LTRConfigurationEditor.java | 1 + .../channel/LTRNetConfigurationEditor.java | 1 + .../channel/NBFMConfigurationEditor.java | 1 + .../channel/P25P1ConfigurationEditor.java | 1 + .../channel/P25P2ConfigurationEditor.java | 55 ++++-------------- .../playlist/radioreference/SiteEditor.java | 2 + .../decode/p25/phase2/P25P2DecoderHDQPSK.java | 5 +- 10 files changed, 82 insertions(+), 55 deletions(-) diff --git a/src/main/java/io/github/dsheirer/controller/channel/ChannelProcessingManager.java b/src/main/java/io/github/dsheirer/controller/channel/ChannelProcessingManager.java index 61e3025e..e5a61f98 100644 --- a/src/main/java/io/github/dsheirer/controller/channel/ChannelProcessingManager.java +++ b/src/main/java/io/github/dsheirer/controller/channel/ChannelProcessingManager.java @@ -49,6 +49,7 @@ import io.github.dsheirer.source.Source; import io.github.dsheirer.source.SourceEvent; import io.github.dsheirer.source.SourceException; import io.github.dsheirer.source.SourceManager; +import javafx.application.Platform; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -234,7 +235,6 @@ public class ChannelProcessingManager implements Listener public void start(Channel channel) throws ChannelException { startProcessing(new ChannelEvent(channel, ChannelEvent.Event.REQUEST_ENABLE)); - } /** @@ -278,7 +278,8 @@ public class ChannelProcessingManager implements Listener if(source == null) { - channel.setProcessing(false); + //This has to be done on the FX event thread when the playlist editor is constructed + Platform.runLater(() -> channel.setProcessing(false)); mChannelEventBroadcaster.broadcast(new ChannelEvent(channel, ChannelEvent.Event.NOTIFICATION_PROCESSING_START_REJECTED, TUNER_UNAVAILABLE_DESCRIPTION)); @@ -417,7 +418,8 @@ public class ChannelProcessingManager implements Listener } processingChain.start(); - channel.setProcessing(true); + //This has to be done on the FX event thread when the playlist editor is constructed + Platform.runLater(() -> channel.setProcessing(true)); getChannelMetadataModel().add(processingChain.getChannelState().getChannelMetadata(), channel); @@ -434,7 +436,8 @@ public class ChannelProcessingManager implements Listener */ private void stopProcessing(Channel channel, boolean remove) throws ChannelException { - channel.setProcessing(false); + //This has to be done on the FX event thread when the playlist editor is constructed + Platform.runLater(() -> channel.setProcessing(false)); if(mProcessingChains.containsKey(channel)) { diff --git a/src/main/java/io/github/dsheirer/gui/playlist/channel/ChannelConfigurationEditor.java b/src/main/java/io/github/dsheirer/gui/playlist/channel/ChannelConfigurationEditor.java index 5ef07065..ae39a60b 100644 --- a/src/main/java/io/github/dsheirer/gui/playlist/channel/ChannelConfigurationEditor.java +++ b/src/main/java/io/github/dsheirer/gui/playlist/channel/ChannelConfigurationEditor.java @@ -242,6 +242,9 @@ public abstract class ChannelConfigurationEditor extends Editor { getItem().setSystem(getSystemField().getText()); getItem().setSite(getSiteField().getText()); + + //Hack - change the name to something else and then set it to the real value to trigger change events + getItem().setName(" "); getItem().setName(getNameField().getText()); getItem().setAliasListName(getAliasListComboBox().getSelectionModel().getSelectedItem()); getItem().setAutoStart(getAutoStartSwitch().isSelected()); diff --git a/src/main/java/io/github/dsheirer/gui/playlist/channel/ChannelEditor.java b/src/main/java/io/github/dsheirer/gui/playlist/channel/ChannelEditor.java index b07d4a04..56a79650 100644 --- a/src/main/java/io/github/dsheirer/gui/playlist/channel/ChannelEditor.java +++ b/src/main/java/io/github/dsheirer/gui/playlist/channel/ChannelEditor.java @@ -22,10 +22,13 @@ package io.github.dsheirer.gui.playlist.channel; +import com.google.common.base.Joiner; import io.github.dsheirer.controller.channel.Channel; import io.github.dsheirer.module.decode.DecoderFactory; import io.github.dsheirer.module.decode.DecoderType; import io.github.dsheirer.playlist.PlaylistManager; +import io.github.dsheirer.source.config.SourceConfigTuner; +import io.github.dsheirer.source.config.SourceConfigTunerMultipleFrequency; import javafx.application.Platform; import javafx.beans.property.SimpleStringProperty; import javafx.beans.value.ObservableValue; @@ -62,7 +65,9 @@ import org.controlsfx.control.textfield.TextFields; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Optional; import java.util.function.Predicate; @@ -231,6 +236,7 @@ public class ChannelEditor extends SplitPane { mViewSegmentedButton = new SegmentedButton(getAllToggleButton(), getPlayingToggleButton(), getAutoStartToggleButton()); + mViewSegmentedButton.getStyleClass().add(SegmentedButton.STYLE_CLASS_DARK); getAllToggleButton().setSelected(true); mViewSegmentedButton.getToggleGroup().selectedToggleProperty() .addListener((observable, oldValue, newValue) -> { @@ -439,12 +445,16 @@ public class ChannelEditor extends SplitPane nameColumn.setCellValueFactory(new PropertyValueFactory<>("name")); nameColumn.setPrefWidth(200); + TableColumn frequencyColumn = new TableColumn("Frequency"); + frequencyColumn.setCellValueFactory(new FrequencyCellValueFactory()); + frequencyColumn.setPrefWidth(100); + TableColumn protocolColumn = new TableColumn("Protocol"); protocolColumn.setCellValueFactory(new ProtocolCellValueFactory()); protocolColumn.setPrefWidth(100); - mChannelTableView.getColumns().addAll(systemColumn, siteColumn, nameColumn, protocolColumn, playingColumn, - autoStartColumn); + mChannelTableView.getColumns().addAll(systemColumn, siteColumn, nameColumn, frequencyColumn, protocolColumn, + playingColumn, autoStartColumn); mChannelTableView.setPlaceholder(getPlaceholderLabel()); //Sorting and filtering for the table @@ -629,7 +639,48 @@ public class ChannelEditor extends SplitPane } /** - * Filter predicate for a filterec channel list + * Channel tuner channel source frequencies value factory + */ + public class FrequencyCellValueFactory implements Callback, + ObservableValue> + { + private SimpleStringProperty mFrequency = new SimpleStringProperty(); + + @Override + public ObservableValue call(TableColumn.CellDataFeatures param) + { + Channel channel = param.getValue(); + + if(channel != null) + { + if(channel.getSourceConfiguration() instanceof SourceConfigTuner) + { + long frequency = ((SourceConfigTuner)channel.getSourceConfiguration()).getFrequency(); + mFrequency.set(String.valueOf(frequency / 1E6)); + } + else if(channel.getSourceConfiguration() instanceof SourceConfigTunerMultipleFrequency) + { + List frequencies = ((SourceConfigTunerMultipleFrequency)channel.getSourceConfiguration()).getFrequencies(); + + List formatted = new ArrayList<>(); + for(Long frequency: frequencies) + { + formatted.add(String.valueOf(frequency / 1E6)); + } + mFrequency.set(Joiner.on(",").join(formatted)); + } + } + else + { + mFrequency.set(null); + } + + return mFrequency; + } + } + + /** + * Filter predicate for a filtered channel list */ public static class ChannelListFilter implements Predicate { diff --git a/src/main/java/io/github/dsheirer/gui/playlist/channel/LTRConfigurationEditor.java b/src/main/java/io/github/dsheirer/gui/playlist/channel/LTRConfigurationEditor.java index 6136d26b..57054ff8 100644 --- a/src/main/java/io/github/dsheirer/gui/playlist/channel/LTRConfigurationEditor.java +++ b/src/main/java/io/github/dsheirer/gui/playlist/channel/LTRConfigurationEditor.java @@ -254,6 +254,7 @@ public class LTRConfigurationEditor extends ChannelConfigurationEditor if(mDirectionButton == null) { mDirectionButton = new SegmentedButton(); + mDirectionButton.getStyleClass().add(SegmentedButton.STYLE_CLASS_DARK); mDirectionButton.setDisable(true); for(MessageDirection messageDirection: MessageDirection.ORDERED_VALUES) diff --git a/src/main/java/io/github/dsheirer/gui/playlist/channel/LTRNetConfigurationEditor.java b/src/main/java/io/github/dsheirer/gui/playlist/channel/LTRNetConfigurationEditor.java index a5eee2e6..72ef6936 100644 --- a/src/main/java/io/github/dsheirer/gui/playlist/channel/LTRNetConfigurationEditor.java +++ b/src/main/java/io/github/dsheirer/gui/playlist/channel/LTRNetConfigurationEditor.java @@ -254,6 +254,7 @@ public class LTRNetConfigurationEditor extends ChannelConfigurationEditor if(mDirectionButton == null) { mDirectionButton = new SegmentedButton(); + mDirectionButton.getStyleClass().add(SegmentedButton.STYLE_CLASS_DARK); mDirectionButton.setDisable(true); for(MessageDirection messageDirection: MessageDirection.ORDERED_VALUES) diff --git a/src/main/java/io/github/dsheirer/gui/playlist/channel/NBFMConfigurationEditor.java b/src/main/java/io/github/dsheirer/gui/playlist/channel/NBFMConfigurationEditor.java index e9ceb73c..564f885a 100644 --- a/src/main/java/io/github/dsheirer/gui/playlist/channel/NBFMConfigurationEditor.java +++ b/src/main/java/io/github/dsheirer/gui/playlist/channel/NBFMConfigurationEditor.java @@ -241,6 +241,7 @@ public class NBFMConfigurationEditor extends ChannelConfigurationEditor if(mBandwidthButton == null) { mBandwidthButton = new SegmentedButton(); + mBandwidthButton.getStyleClass().add(SegmentedButton.STYLE_CLASS_DARK); mBandwidthButton.setDisable(true); for(DecodeConfigNBFM.Bandwidth bandwidth : DecodeConfigNBFM.Bandwidth.values()) diff --git a/src/main/java/io/github/dsheirer/gui/playlist/channel/P25P1ConfigurationEditor.java b/src/main/java/io/github/dsheirer/gui/playlist/channel/P25P1ConfigurationEditor.java index 8026ddac..8182ebe9 100644 --- a/src/main/java/io/github/dsheirer/gui/playlist/channel/P25P1ConfigurationEditor.java +++ b/src/main/java/io/github/dsheirer/gui/playlist/channel/P25P1ConfigurationEditor.java @@ -222,6 +222,7 @@ public class P25P1ConfigurationEditor extends ChannelConfigurationEditor if(mModulationSegmentedButton == null) { mModulationSegmentedButton = new SegmentedButton(); + mModulationSegmentedButton.getStyleClass().add(SegmentedButton.STYLE_CLASS_DARK); mModulationSegmentedButton.getButtons().addAll(getC4FMToggleButton(), getLSMToggleButton()); mModulationSegmentedButton.getToggleGroup().selectedToggleProperty().addListener(new ChangeListener() { diff --git a/src/main/java/io/github/dsheirer/gui/playlist/channel/P25P2ConfigurationEditor.java b/src/main/java/io/github/dsheirer/gui/playlist/channel/P25P2ConfigurationEditor.java index c0609254..b7cb2a0d 100644 --- a/src/main/java/io/github/dsheirer/gui/playlist/channel/P25P2ConfigurationEditor.java +++ b/src/main/java/io/github/dsheirer/gui/playlist/channel/P25P2ConfigurationEditor.java @@ -44,7 +44,6 @@ import javafx.scene.control.Label; import javafx.scene.control.TitledPane; import javafx.scene.layout.GridPane; import javafx.scene.layout.VBox; -import org.controlsfx.control.ToggleSwitch; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -64,7 +63,6 @@ public class P25P2ConfigurationEditor extends ChannelConfigurationEditor private SourceConfigurationEditor mSourceConfigurationEditor; private EventLogConfigurationEditor mEventLogConfigurationEditor; private RecordConfigurationEditor mRecordConfigurationEditor; - private ToggleSwitch mAutoDetectScrambleParameters; private IntegerTextField mWacnTextField; private IntegerTextField mSystemTextField; private IntegerTextField mNacTextField; @@ -112,36 +110,30 @@ public class P25P2ConfigurationEditor extends ChannelConfigurationEditor gridPane.setHgap(10); gridPane.setVgap(10); - GridPane.setConstraints(getAutoDetectScrambleParameters(), 0, 0); - gridPane.getChildren().add(getAutoDetectScrambleParameters()); - - Label directionLabel = new Label("Auto-Detect (WACN/System/NAC)"); - GridPane.setHalignment(directionLabel, HPos.LEFT); - GridPane.setConstraints(directionLabel, 1, 0); - gridPane.getChildren().add(directionLabel); + int row = 0; Label wacnLabel = new Label("WACN"); GridPane.setHalignment(wacnLabel, HPos.RIGHT); - GridPane.setConstraints(wacnLabel, 0, 1); + GridPane.setConstraints(wacnLabel, 0, ++row); gridPane.getChildren().add(wacnLabel); - GridPane.setConstraints(getWacnTextField(), 1, 1); + GridPane.setConstraints(getWacnTextField(), 1, row); gridPane.getChildren().add(getWacnTextField()); Label systemLabel = new Label("System"); GridPane.setHalignment(systemLabel, HPos.RIGHT); - GridPane.setConstraints(systemLabel, 0, 2); + GridPane.setConstraints(systemLabel, 0, ++row); gridPane.getChildren().add(systemLabel); - GridPane.setConstraints(getSystemTextField(), 1, 2); + GridPane.setConstraints(getSystemTextField(), 1, row); gridPane.getChildren().add(getSystemTextField()); Label nacLabel = new Label("NAC"); GridPane.setHalignment(nacLabel, HPos.RIGHT); - GridPane.setConstraints(nacLabel, 0, 3); + GridPane.setConstraints(nacLabel, 0, ++row); gridPane.getChildren().add(nacLabel); - GridPane.setConstraints(getNacTextField(), 1, 3); + GridPane.setConstraints(getNacTextField(), 1, row); gridPane.getChildren().add(getNacTextField()); mDecoderPane.setContent(gridPane); @@ -211,27 +203,6 @@ public class P25P2ConfigurationEditor extends ChannelConfigurationEditor return mEventLogConfigurationEditor; } - private ToggleSwitch getAutoDetectScrambleParameters() - { - if(mAutoDetectScrambleParameters == null) - { - mAutoDetectScrambleParameters = new ToggleSwitch(); - - //This messes up too many users. Hiding it. - mAutoDetectScrambleParameters.setVisible(false); - mAutoDetectScrambleParameters.setDisable(true); - mAutoDetectScrambleParameters.selectedProperty() - .addListener((observable, oldValue, newValue) -> { - modifiedProperty().set(true); - getWacnTextField().setDisable(mAutoDetectScrambleParameters.isSelected()); - getSystemTextField().setDisable(mAutoDetectScrambleParameters.isSelected()); - getNacTextField().setDisable(mAutoDetectScrambleParameters.isSelected()); - }); - } - - return mAutoDetectScrambleParameters; - } - private IntegerTextField getWacnTextField() { if(mWacnTextField == null) @@ -288,15 +259,12 @@ public class P25P2ConfigurationEditor extends ChannelConfigurationEditor @Override protected void setDecoderConfiguration(DecodeConfiguration config) { - getAutoDetectScrambleParameters().setDisable(config == null); - if(config instanceof DecodeConfigP25Phase2) { DecodeConfigP25Phase2 decodeConfig = (DecodeConfigP25Phase2)config; - getAutoDetectScrambleParameters().setSelected(decodeConfig.isAutoDetectScrambleParameters()); - getWacnTextField().setDisable(decodeConfig.isAutoDetectScrambleParameters()); - getSystemTextField().setDisable(decodeConfig.isAutoDetectScrambleParameters()); - getNacTextField().setDisable(decodeConfig.isAutoDetectScrambleParameters()); + getWacnTextField().setDisable(false); + getSystemTextField().setDisable(false); + getNacTextField().setDisable(false); ScrambleParameters scrambleParameters = decodeConfig.getScrambleParameters(); @@ -318,7 +286,6 @@ public class P25P2ConfigurationEditor extends ChannelConfigurationEditor getWacnTextField().set(0); getSystemTextField().set(0); getNacTextField().set(0); - getAutoDetectScrambleParameters().setSelected(false); getWacnTextField().setDisable(true); getSystemTextField().setDisable(true); getNacTextField().setDisable(true); @@ -333,7 +300,7 @@ public class P25P2ConfigurationEditor extends ChannelConfigurationEditor if(getItem().getDecodeConfiguration() instanceof DecodeConfigP25Phase2) { config = (DecodeConfigP25Phase2)getItem().getDecodeConfiguration(); - config.setAutoDetectScrambleParameters(getAutoDetectScrambleParameters().isSelected()); + config.setAutoDetectScrambleParameters(false); int wacn = getWacnTextField().get(); int system = getSystemTextField().get(); int nac = getSystemTextField().get(); diff --git a/src/main/java/io/github/dsheirer/gui/playlist/radioreference/SiteEditor.java b/src/main/java/io/github/dsheirer/gui/playlist/radioreference/SiteEditor.java index 829b6d9b..586775b7 100644 --- a/src/main/java/io/github/dsheirer/gui/playlist/radioreference/SiteEditor.java +++ b/src/main/java/io/github/dsheirer/gui/playlist/radioreference/SiteEditor.java @@ -804,6 +804,7 @@ public class SiteEditor extends GridPane if(mConfigurationsSegmentedButton == null) { mConfigurationsSegmentedButton = new SegmentedButton(getSingleToggleButton(), getForEachToggleButton()); + mConfigurationsSegmentedButton.getStyleClass().add(SegmentedButton.STYLE_CLASS_DARK); mConfigurationsSegmentedButton.setDisable(true); mConfigurationsSegmentedButton.getToggleGroup().selectedToggleProperty() .addListener((observable, oldValue, newValue) -> { @@ -848,6 +849,7 @@ public class SiteEditor extends GridPane { mFrequenciesSegmentedButton = new SegmentedButton(getControlToggleButton(), getControlAndAltToggleButton(), getSelectedToggleButton(), getAllToggleButton()); + mFrequenciesSegmentedButton.getStyleClass().add(SegmentedButton.STYLE_CLASS_DARK); mFrequenciesSegmentedButton.setDisable(true); mFrequenciesSegmentedButton.getToggleGroup().selectedToggleProperty() .addListener((observable, oldValue, newValue) -> { diff --git a/src/main/java/io/github/dsheirer/module/decode/p25/phase2/P25P2DecoderHDQPSK.java b/src/main/java/io/github/dsheirer/module/decode/p25/phase2/P25P2DecoderHDQPSK.java index a97b9e66..66db22b8 100644 --- a/src/main/java/io/github/dsheirer/module/decode/p25/phase2/P25P2DecoderHDQPSK.java +++ b/src/main/java/io/github/dsheirer/module/decode/p25/phase2/P25P2DecoderHDQPSK.java @@ -95,10 +95,7 @@ public class P25P2DecoderHDQPSK extends P25P2Decoder implements IdentifierUpdate //The Costas Loop receives symbol-inversion correction requests when detected. //The PLL gain monitor receives sync detect/loss signals from the message framer mMessageFramer = new P25P2MessageFramer(mCostasLoop, DecoderType.P25_PHASE2.getProtocol().getBitRate()); - if(mDecodeConfigP25Phase2 != null && !mDecodeConfigP25Phase2.isAutoDetectScrambleParameters()) - { - mMessageFramer.setScrambleParameters(mDecodeConfigP25Phase2.getScrambleParameters()); - } + mMessageFramer.setScrambleParameters(mDecodeConfigP25Phase2.getScrambleParameters()); mFrequencyCorrectionSyncMonitor = new FrequencyCorrectionSyncMonitor(mCostasLoop, this); mMessageFramer.setSyncDetectListener(mFrequencyCorrectionSyncMonitor);