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)
{