Files
sdrtrunk/src/main/java/io/github/dsheirer/audio/playback/AudioChannelPanel.java
Denny Sheirer 3a39ae76ba Updates alias list to provide a list of aliases for an identifier so that (#474)
we can account for multi-alias identifiers like patch groups and ensure
that patch group alias intentions are carried throughout the system for
recording, streaming, etc.

Updates all consumers of alias list data to ensure it can operate with
a list of aliases versus an assumed single alias.

Refactors APCO25 unit/user status identifiers from a base status class
so that alias list can support status identifiers.
2018-12-31 07:24:25 -05:00

317 lines
10 KiB
Java

/*
* ******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2018 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 <http://www.gnu.org/licenses/>
* *****************************************************************************
*/
package io.github.dsheirer.audio.playback;
import com.google.common.base.Joiner;
import com.google.common.eventbus.Subscribe;
import io.github.dsheirer.alias.Alias;
import io.github.dsheirer.alias.AliasList;
import io.github.dsheirer.alias.AliasModel;
import io.github.dsheirer.audio.AudioEvent;
import io.github.dsheirer.eventbus.MyEventBus;
import io.github.dsheirer.icon.IconManager;
import io.github.dsheirer.identifier.Identifier;
import io.github.dsheirer.identifier.IdentifierClass;
import io.github.dsheirer.identifier.IdentifierCollection;
import io.github.dsheirer.identifier.Role;
import io.github.dsheirer.preference.PreferenceType;
import io.github.dsheirer.preference.UserPreferences;
import io.github.dsheirer.preference.identifier.TalkgroupFormatPreference;
import io.github.dsheirer.properties.SystemProperties;
import io.github.dsheirer.sample.Listener;
import io.github.dsheirer.settings.ColorSetting;
import io.github.dsheirer.settings.Setting;
import io.github.dsheirer.settings.SettingChangeListener;
import io.github.dsheirer.settings.SettingsManager;
import net.miginfocom.swing.MigLayout;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;
import java.util.Collections;
import java.util.List;
public class AudioChannelPanel extends JPanel implements Listener<AudioEvent>, SettingChangeListener
{
private static final long serialVersionUID = 1L;
private static final Logger mLog = LoggerFactory.getLogger(AudioChannelPanel.class);
public static final String PROPERTY_PREFIX = "audio.channel.panel.color.";
public static final String PROPERTY_COLOR_BACKGROUND = PROPERTY_PREFIX + "background";
public static final String PROPERTY_COLOR_LABEL = PROPERTY_PREFIX + "label";
public static final String PROPERTY_COLOR_MUTED = PROPERTY_PREFIX + "muted";
public static final String PROPERTY_COLOR_VALUE = PROPERTY_PREFIX + "value";
private Font mFont = new Font(Font.MONOSPACED, Font.PLAIN, 16);
private Color mBackgroundColor;
private Color mLabelColor;
private Color mMutedColor;
private Color mValueColor;
private IconManager mIconManager;
private SettingsManager mSettingsManager;
private UserPreferences mUserPreferences;
private TalkgroupFormatPreference mTalkgroupFormatPreference;
private AudioOutput mAudioOutput;
private JLabel mMutedLabel = new JLabel("M");
private JLabel mChannelName = new JLabel(" ");
private JLabel mIconLabel = new JLabel(" ");
private JLabel mIdentifierLabel = new JLabel("-----");
private Identifier mIdentifier;
private List<Alias> mAliases = Collections.EMPTY_LIST;
private boolean mConfigured = false;
private AliasModel mAliasModel;
public AudioChannelPanel(IconManager iconManager, UserPreferences userPreferences, SettingsManager settingsManager,
AudioOutput audioOutput, AliasModel aliasModel)
{
mIconManager = iconManager;
mSettingsManager = settingsManager;
mSettingsManager.addListener(this);
mAliasModel = aliasModel;
mUserPreferences = userPreferences;
mTalkgroupFormatPreference = mUserPreferences.getTalkgroupFormatPreference();
mAudioOutput = audioOutput;
if(mAudioOutput != null)
{
mAudioOutput.addAudioEventListener(this);
mAudioOutput.setIdentifierCollectionListener(new AudioMetadataProcessor());
}
mBackgroundColor = SystemProperties.getInstance().get(PROPERTY_COLOR_BACKGROUND, Color.BLACK);
mLabelColor = SystemProperties.getInstance().get(PROPERTY_COLOR_LABEL, Color.LIGHT_GRAY);
mMutedColor = SystemProperties.getInstance().get(PROPERTY_COLOR_MUTED, Color.RED);
mValueColor = SystemProperties.getInstance().get(PROPERTY_COLOR_VALUE, Color.GREEN);
init();
}
/**
* Receives preference update notifications via the event bus
* @param preferenceType that was updated
*/
@Subscribe
public void preferenceUpdated(PreferenceType preferenceType)
{
if(preferenceType == PreferenceType.IDENTIFIER)
{
updateLabels();
}
}
public void dispose()
{
//Deregister from receiving preference update notifications
MyEventBus.getEventBus().unregister(this);
}
private void init()
{
//Register to receive preference updates
MyEventBus.getEventBus().register(this);
setLayout(new MigLayout("align center center, insets 0 0 0 0",
"[][][align right]0[grow,fill]", ""));
setBackground(mBackgroundColor);
mMutedLabel.setFont(mFont);
mMutedLabel.setForeground(mMutedColor);
mMutedLabel.setVisible(false);
add(mMutedLabel);
mChannelName = new JLabel(mAudioOutput != null ? mAudioOutput.getChannelName() : " ");
mChannelName.setFont(mFont);
mChannelName.setForeground(mLabelColor);
add(mChannelName);
mIconLabel.setFont(mFont);
mIconLabel.setForeground(mValueColor);
add(mIconLabel);
mIdentifierLabel.setFont(mFont);
mIdentifierLabel.setForeground(mValueColor);
add(mIdentifierLabel, "wmin 10lp");
}
@Override
public void receive(final AudioEvent audioEvent)
{
switch(audioEvent.getType())
{
case AUDIO_STOPPED:
EventQueue.invokeLater(new Runnable()
{
@Override
public void run()
{
resetLabels();
}
});
break;
case AUDIO_MUTED:
case AUDIO_UNMUTED:
EventQueue.invokeLater(new Runnable()
{
@Override
public void run()
{
mMutedLabel.setVisible(mAudioOutput.isMuted());
}
});
break;
default:
break;
}
}
/**
* Resets the from and to labels. Note: this does not happen on the swing
* event thread. Only invoke from the swing thread.
*/
private void resetLabels()
{
mIdentifier = null;
mAliases = Collections.EMPTY_LIST;
updateLabels();
mConfigured = false;
}
/**
* Truncates the string to the specified length using an ellipses at the end
* @param value to optionally truncate
* @param length of the final formatted string
* @return formatted string or null
*/
private static String truncate(String value, int length)
{
if(value != null && value.length() > length)
{
return value.substring(0, length - 3) + "...";
}
return value;
}
/**
* Updates the alias label with text and icon from the alias. Note: this
* does not occur on the Swing event thread -- wrap any calls to this
* method with an event thread call.
*/
private void updateLabels()
{
String identifier = null;
String iconName = null;
if(mAliases.size() == 1)
{
identifier = mAliases.get(0).getName();
iconName = mAliases.get(0).getIconName();
}
else if(mAliases.size() > 1)
{
identifier = Joiner.on(", ").skipNulls().join(mAliases);
}
if(identifier == null)
{
identifier = "-----";
}
final ImageIcon icon = iconName != null ? mIconManager.getIcon(iconName, 18) : null;
final String identifierText = truncate(identifier, 33);
EventQueue.invokeLater(new Runnable()
{
@Override
public void run()
{
mIdentifierLabel.setText(identifierText);
mIconLabel.setIcon(icon);
mConfigured = true;
}
});
}
/**
* Processes audio metadata to update this panel's display values
*/
public class AudioMetadataProcessor implements Listener<IdentifierCollection>
{
@Override
public void receive(final IdentifierCollection identifierCollection)
{
if(identifierCollection != null && (identifierCollection.isUpdated() || !mConfigured))
{
List<Identifier> toIds = identifierCollection.getIdentifiers(IdentifierClass.USER, Role.TO);
mIdentifier = !toIds.isEmpty() ? toIds.get(0) : null;
AliasList aliasList = mAliasModel.getAliasList(identifierCollection);
if(aliasList != null)
{
mAliases = aliasList.getAliases(mIdentifier);
}
updateLabels();
}
}
}
@Override
public void settingChanged(Setting setting)
{
if(setting instanceof ColorSetting)
{
ColorSetting colorSetting = (ColorSetting)setting;
switch(colorSetting.getColorSettingName())
{
case CHANNEL_STATE_LABEL_DECODER:
if(mIdentifierLabel != null)
{
mIdentifierLabel.setForeground(mLabelColor);
}
if(mIconLabel != null)
{
mIconLabel.setForeground(mLabelColor);
}
break;
default:
break;
}
}
}
@Override
public void settingDeleted(Setting setting)
{
}
}