diff --git a/src/channel/details/ChannelDetailPanel.java b/src/channel/details/ChannelDetailPanel.java new file mode 100644 index 00000000..3ed53b2f --- /dev/null +++ b/src/channel/details/ChannelDetailPanel.java @@ -0,0 +1,133 @@ +/******************************************************************************* + * sdrtrunk + * Copyright (C) 2014-2017 Dennis Sheirer + * + * 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 + * + ******************************************************************************/ +package channel.details; + +import channel.state.DecoderState; +import controller.channel.Channel; +import controller.channel.ChannelProcessingManager; +import module.ProcessingChain; +import net.miginfocom.swing.MigLayout; +import sample.Listener; + +import javax.swing.*; +import javax.swing.text.DefaultCaret; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public class ChannelDetailPanel extends JPanel implements Listener +{ + private static final String EMPTY_DETAILS = "Please select a channel to view details"; + + private JLabel mSystemLabel; + private JLabel mSiteLabel; + private JLabel mNameLabel; + private JTextArea mDetailTextArea; + + private ChannelProcessingManager mChannelProcessingManager; + private ProcessingChain mProcessingChain; + + public ChannelDetailPanel(ChannelProcessingManager channelProcessingManager) + { + mChannelProcessingManager = channelProcessingManager; + + init(); + } + + private void init() + { + setLayout(new MigLayout("insets 0 0 0 0", "[grow,fill]", "[]0[grow,fill]")); + + JPanel buttonPanel = new JPanel(); + buttonPanel.setLayout(new MigLayout("insets 1 1 1 1", "[][grow,fill][][grow,fill][][grow,fill][]", "")); + + buttonPanel.add(new JLabel("System:")); + mSystemLabel = new JLabel(" "); + buttonPanel.add(mSystemLabel); + + buttonPanel.add(new JLabel("Site:")); + mSiteLabel = new JLabel(" "); + buttonPanel.add(mSiteLabel); + + buttonPanel.add(new JLabel("Channel Name:")); + mNameLabel = new JLabel(" "); + buttonPanel.add(mNameLabel); + + JButton refreshButton = new JButton("Refresh"); + refreshButton.addActionListener(new ActionListener() + { + @Override + public void actionPerformed(ActionEvent e) + { + receive(mProcessingChain); + } + }); + buttonPanel.add(refreshButton); + + add(buttonPanel, "wrap"); + + mDetailTextArea = new JTextArea(EMPTY_DETAILS); + DefaultCaret caret = (DefaultCaret)mDetailTextArea.getCaret(); + caret.setUpdatePolicy(DefaultCaret.NEVER_UPDATE); + add(new JScrollPane(mDetailTextArea)); + } + + @Override + public void receive(ProcessingChain processingChain) + { + mProcessingChain = processingChain; + + Channel channel = mChannelProcessingManager.getChannel(processingChain); + + final String system = channel != null ? channel.getSystem() : null; + final String site = channel != null ? channel.getSite() : null; + final String name = channel != null ? + (channel.getChannelType() == Channel.ChannelType.TRAFFIC ? "Traffic Channel" : channel.getName()) : null; + + final String details; + + if(processingChain != null) + { + StringBuilder sb = new StringBuilder(); + + for(DecoderState decoderState : processingChain.getDecoderStates()) + { + sb.append(decoderState.getActivitySummary()); + } + + details = sb.toString(); + } + else + { + details = EMPTY_DETAILS; + } + + EventQueue.invokeLater(new Runnable() + { + @Override + public void run() + { + mSystemLabel.setText(system); + mSiteLabel.setText(site); + mNameLabel.setText(name); + mDetailTextArea.setText(details); + } + }); + } +} diff --git a/src/channel/metadata/ChannelMetadataViewer.java b/src/channel/metadata/ChannelMetadataViewer.java index e40b0b00..53996650 100644 --- a/src/channel/metadata/ChannelMetadataViewer.java +++ b/src/channel/metadata/ChannelMetadataViewer.java @@ -18,6 +18,7 @@ ******************************************************************************/ package channel.metadata; +import channel.details.ChannelDetailPanel; import com.jidesoft.swing.JideSplitPane; import com.jidesoft.swing.JideTabbedPane; import controller.channel.ChannelProcessingManager; @@ -33,10 +34,12 @@ import java.awt.*; public class ChannelMetadataViewer extends JPanel { + private ChannelMetadataPanel mChannelMetadataPanel; + + private ChannelDetailPanel mChannelDetailPanel; private CallEventPanel mCallEventPanel; private MessageActivityPanel mMessageActivityPanel; private ChannelSpectrumPanel mChannelSpectrumPanel; - private ChannelMetadataPanel mChannelMetadataPanel; /** * GUI panel that combines the currently decoding channels metadata table and viewers for channel details, @@ -45,6 +48,7 @@ public class ChannelMetadataViewer extends JPanel public ChannelMetadataViewer(ChannelProcessingManager channelProcessingManager, IconManager iconManager, SettingsManager settingsManager) { + mChannelDetailPanel = new ChannelDetailPanel(channelProcessingManager); mCallEventPanel = new CallEventPanel(iconManager); mMessageActivityPanel = new MessageActivityPanel(channelProcessingManager); mChannelSpectrumPanel = new ChannelSpectrumPanel(settingsManager, channelProcessingManager); @@ -58,7 +62,7 @@ public class ChannelMetadataViewer extends JPanel setLayout( new MigLayout( "insets 0 0 0 0", "[grow,fill]", "[grow,fill]") ); JideTabbedPane tabbedPane = new JideTabbedPane(); -// tabbedPane.addTab("Details", new JPanel()); + tabbedPane.addTab("Details", mChannelDetailPanel); tabbedPane.addTab("Events", mCallEventPanel); tabbedPane.addTab("Messages", mMessageActivityPanel); // tabbedPane.addTab("Spectrum", mChannelSpectrumPanel); @@ -71,6 +75,7 @@ public class ChannelMetadataViewer extends JPanel splitPane.add(tabbedPane); add(splitPane); + mChannelMetadataPanel.addProcessingChainSelectionListener(mChannelDetailPanel); mChannelMetadataPanel.addProcessingChainSelectionListener(mCallEventPanel); mChannelMetadataPanel.addProcessingChainSelectionListener(mMessageActivityPanel); } diff --git a/src/controller/channel/ChannelModel.java b/src/controller/channel/ChannelModel.java index 638c9a59..d7b87ca8 100644 --- a/src/controller/channel/ChannelModel.java +++ b/src/controller/channel/ChannelModel.java @@ -72,6 +72,25 @@ public class ChannelModel extends AbstractTableModel implements IChannelEventBro return null; } + /** + * Returns the channel identified by the id argument + */ + public Channel getChannelFromChannelID(Integer id) + { + if(id != null) + { + for(Channel channel: mChannels) + { + if(channel.getChannelID() == id) + { + return channel; + } + } + } + + return null; + } + /** * Returns a list of unique system values from across the channel set */ diff --git a/src/controller/channel/ChannelProcessingManager.java b/src/controller/channel/ChannelProcessingManager.java index aed91534..04c65e49 100644 --- a/src/controller/channel/ChannelProcessingManager.java +++ b/src/controller/channel/ChannelProcessingManager.java @@ -109,6 +109,35 @@ public class ChannelProcessingManager implements ChannelEventListener return mProcessingChains.get(channel.getChannelID()); } + /** + * Returns the channel associated with the processing chain + * @param processingChain + * @return channel associated with the processing chain or null + */ + public Channel getChannel(ProcessingChain processingChain) + { + return mChannelModel.getChannelFromChannelID(getChannelID(processingChain)); + } + + /** + * Returns the channel ID associated with the processing chain + */ + private Integer getChannelID(ProcessingChain processingChain) + { + if(processingChain != null) + { + for(Map.Entry entry: mProcessingChains.entrySet()) + { + if(entry.getValue() == processingChain) + { + return entry.getKey(); + } + } + } + + return null; + } + @Override public synchronized void channelChanged(ChannelEvent event) {