#5 Playlist Editor With Radio Reference Support (#760)

* WIP - Adds support for aliasing P25 Phase 2 tones.Playlist editor - adds editor support for alias actions

* Playlist editor implementation and integration into application is complete. Adds JavaFX window monitoring to persist window size/location across application runs.

Co-authored-by: Denny <denny@denny-desktop>
This commit is contained in:
Denny Sheirer
2020-04-26 11:53:43 +00:00
committed by GitHub
parent 39f6d6c831
commit cc52ae5bd7
290 changed files with 31251 additions and 15306 deletions

View File

@@ -40,43 +40,126 @@ import io.github.dsheirer.alias.id.priority.Priority;
import io.github.dsheirer.alias.id.radio.Radio;
import io.github.dsheirer.alias.id.radio.RadioRange;
import io.github.dsheirer.alias.id.record.Record;
import io.github.dsheirer.alias.id.status.StatusID;
import io.github.dsheirer.alias.id.status.UnitStatusID;
import io.github.dsheirer.alias.id.status.UserStatusID;
import io.github.dsheirer.alias.id.talkgroup.Talkgroup;
import io.github.dsheirer.alias.id.talkgroup.TalkgroupRange;
import io.github.dsheirer.alias.id.tone.TonesID;
import javafx.beans.Observable;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.util.Callback;
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
@JsonSubTypes({
@JsonSubTypes.Type(value = BroadcastChannel.class, name = "broadcastChannel"),
@JsonSubTypes.Type(value = Esn.class, name = "esn"),
@JsonSubTypes.Type(value = FleetsyncID.class, name = "fleetsyncID"),
@JsonSubTypes.Type(value = LegacyTalkgroupID.class, name = "talkgroupID"),
@JsonSubTypes.Type(value = LoJackFunctionAndID.class, name = "loJackFunctionAndID"),
@JsonSubTypes.Type(value = MDC1200ID.class, name = "mdc1200ID"),
@JsonSubTypes.Type(value = Min.class, name = "min"),
@JsonSubTypes.Type(value = MPT1327ID.class, name = "mpt1327ID"),
@JsonSubTypes.Type(value = NonRecordable.class, name = "nonRecordable"),
@JsonSubTypes.Type(value = Priority.class, name = "priority"),
@JsonSubTypes.Type(value = Radio.class, name = "radio"),
@JsonSubTypes.Type(value = RadioRange.class, name = "radioRange"),
@JsonSubTypes.Type(value = Talkgroup.class, name = "talkgroup"),
@JsonSubTypes.Type(value = TalkgroupRange.class, name = "talkgroupRange"),
@JsonSubTypes.Type(value = Priority.class, name = "priority"),
@JsonSubTypes.Type(value = Record.class, name = "record"),
@JsonSubTypes.Type(value = SiteID.class, name = "siteID"),
@JsonSubTypes.Type(value = StatusID.class, name = "statusID"),
@JsonSubTypes.Type(value = LegacyTalkgroupID.class, name = "talkgroupID"),
@JsonSubTypes.Type(value = Talkgroup.class, name = "talkgroup"),
@JsonSubTypes.Type(value = TalkgroupRange.class, name = "talkgroupRange"),
@JsonSubTypes.Type(value = TonesID.class, name = "tones"),
@JsonSubTypes.Type(value = UserStatusID.class, name = "statusID"),
@JsonSubTypes.Type(value = UnitStatusID.class, name = "unitStatusID"),
@JsonSubTypes.Type(value = UniqueID.class, name = "uniqueID")
})
@JacksonXmlRootElement(localName = "id")
public abstract class AliasID
{
private SimpleStringProperty mValueProperty = new SimpleStringProperty();
private BooleanProperty mOverlapProperty = new SimpleBooleanProperty();
public AliasID()
{
}
/**
* String property representation of this alias ID
*/
@JsonIgnore
public SimpleStringProperty valueProperty()
{
return mValueProperty;
}
/**
* Indicates if this alias identifier overlaps with any other alias identifier in the same alias list
*/
@JsonIgnore
public BooleanProperty overlapProperty()
{
return mOverlapProperty;
}
/**
* Sets the overlap flag for this alias id. Overlap indicates that this identifier collides with another
* identifier within the same alias list.
*/
public void setOverlap(boolean overlap)
{
mOverlapProperty.set(overlap);
updateValueProperty();
}
/**
* Updates the value property for this alias ID. Note: this method is intended to be invoked by all subclasses
* each time that any of the subclass member variable values change.
*/
public void updateValueProperty()
{
if(overlapProperty().get())
{
valueProperty().set(toString() + " - Error: Overlap");
}
else
{
valueProperty().set(toString());
}
//Hack: harmless, but the list extractor does not consistently update unless we do this.
valueProperty().get();
}
@JsonIgnore
public abstract AliasIDType getType();
public abstract boolean matches(AliasID id);
/**
* Indicates if this alias ID overlaps with another alias ID.
* Note: this method is intended to be overridden by certain subclass implementations.
*/
@JsonIgnore
public boolean overlaps(AliasID id)
{
return false;
}
@JsonIgnore
public abstract boolean isValid();
/**
* Indicates if the identifier is an audio identifier (monitor, record, stream)
*/
@JsonIgnore
public abstract boolean isAudioIdentifier();
/**
* Creates an observable property extractor for use with observable lists to detect changes internal to this object.
*/
public static Callback<AliasID,Observable[]> extractor()
{
return (AliasID aid) -> new Observable[] {aid.valueProperty(), aid.overlapProperty()};
}
}

View File

@@ -21,6 +21,8 @@
*/
package io.github.dsheirer.alias.id;
import java.util.EnumSet;
public enum AliasIDType
{
BROADCAST_CHANNEL("Audio Broadcast Channel"),
@@ -34,7 +36,9 @@ public enum AliasIDType
RADIO_ID_RANGE("Radio ID Range"),
RECORD("Record"),
SITE("Site"),
STATUS("Status"),
STATUS("User Status"),
TONES("Tone Sequence"),
UNIT_STATUS("Unit Status"),
TALKGROUP("Talkgroup"),
TALKGROUP_RANGE("Talkgroup Range"),
@@ -52,6 +56,10 @@ public enum AliasIDType
mLabel = label;
}
//Values used by the View-By alias editor
public static EnumSet<AliasIDType> VIEW_BY_VALUES = EnumSet.of(TALKGROUP, TALKGROUP_RANGE, RADIO_ID, RADIO_ID_RANGE,
UNIT_STATUS, STATUS, TONES);
public String toString()
{
return mLabel;

View File

@@ -1,370 +0,0 @@
/*
*
* * ******************************************************************************
* * Copyright (C) 2014-2019 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.alias.id;
import io.github.dsheirer.alias.Alias;
import io.github.dsheirer.alias.AliasEvent;
import io.github.dsheirer.alias.AliasFactory;
import io.github.dsheirer.alias.AliasModel;
import io.github.dsheirer.audio.broadcast.BroadcastModel;
import io.github.dsheirer.gui.editor.Editor;
import io.github.dsheirer.gui.editor.EmptyEditor;
import net.miginfocom.swing.MigLayout;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JList;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.ListModel;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class AliasIdentifierEditor extends Editor<Alias>
{
private static final long serialVersionUID = 1L;
private static ListModel<AliasID> EMPTY_MODEL = new DefaultListModel<>();
private JList<AliasID> mAliasIDList = new JList<>(EMPTY_MODEL);
private JButton mNewIDButton;
private JButton mCloneIDButton;
private JButton mDeleteIDButton;
private EditorContainer mEditorContainer = new EditorContainer();
private AliasModel mAliasModel;
private BroadcastModel mBroadcastModel;
public AliasIdentifierEditor(AliasModel aliasModel, BroadcastModel broadcastModel)
{
mAliasModel = aliasModel;
mBroadcastModel = broadcastModel;
init();
}
private void init()
{
setLayout(new MigLayout("fill,wrap 3",
"[grow,fill][grow,fill][grow,fill]", "[][grow,fill][]"));
mAliasIDList.setVisibleRowCount(6);
mAliasIDList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
mAliasIDList.setLayoutOrientation(JList.VERTICAL);
mAliasIDList.addListSelectionListener(new ListSelectionListener()
{
@Override
public void valueChanged(ListSelectionEvent event)
{
if(!event.getValueIsAdjusting())
{
JList<?> list = (JList<?>)event.getSource();
Object selectedItem = list.getSelectedValue();
if(selectedItem != null && selectedItem instanceof AliasID)
{
AliasID selected = (AliasID)selectedItem;
mEditorContainer.setAliasID(selected);
mCloneIDButton.setEnabled(true);
mDeleteIDButton.setEnabled(true);
}
else
{
mCloneIDButton.setEnabled(false);
mDeleteIDButton.setEnabled(false);
}
}
}
});
JScrollPane scroller = new JScrollPane(mAliasIDList);
add(scroller, "span,grow");
add(mEditorContainer, "span,grow");
mNewIDButton = new JButton("New ...");
mNewIDButton.setToolTipText("Create a new Alias Identifier");
mNewIDButton.addMouseListener(new MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent e)
{
JPopupMenu menu = new JPopupMenu();
menu.add(new AddAliasIdentifierItem(AliasIDType.TALKGROUP));
menu.add(new AddAliasIdentifierItem(AliasIDType.TALKGROUP_RANGE));
menu.add(new AddAliasIdentifierItem(AliasIDType.RADIO_ID));
menu.add(new AddAliasIdentifierItem(AliasIDType.RADIO_ID_RANGE));
menu.add(new AddAliasIdentifierItem(AliasIDType.ESN));
// menu.add(new AddAliasIdentifierItem(AliasIDType.LOJACK));
menu.add(new AddAliasIdentifierItem(AliasIDType.STATUS));
menu.addSeparator();
menu.add(new AddAliasIdentifierItem(AliasIDType.BROADCAST_CHANNEL));
if(hasItem())
{
Alias alias = getItem();
if(!alias.isRecordable())
{
menu.add(new AddAliasIdentifierItem(AliasIDType.RECORD));
}
if(!alias.hasCallPriority())
{
menu.add(new AddAliasIdentifierItem(AliasIDType.PRIORITY));
}
}
menu.show(e.getComponent(), e.getX(), e.getY());
}
});
add(mNewIDButton);
mCloneIDButton = new JButton("Clone");
mCloneIDButton.setToolTipText("Create a copy of the currently selected identifier");
mCloneIDButton.setEnabled(false);
mCloneIDButton.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
AliasID selected = mAliasIDList.getSelectedValue();
if(selected != null)
{
AliasID clone = AliasFactory.copyOf(selected);
if(clone != null)
{
addAliasIDToList(clone);
}
}
}
});
add(mCloneIDButton);
mDeleteIDButton = new JButton("Delete");
mDeleteIDButton.setToolTipText("Delete the currently selected identifier");
mDeleteIDButton.setEnabled(false);
mDeleteIDButton.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
final AliasID selected = mAliasIDList.getSelectedValue();
if(selected != null)
{
int choice = JOptionPane.showConfirmDialog(mDeleteIDButton,
"Do you want to delete [" + selected.toString() + "]",
"Are you sure?", JOptionPane.YES_NO_OPTION);
if(choice == JOptionPane.YES_OPTION && hasItem())
{
Alias alias = getItem();
alias.removeAliasID(selected);
mAliasModel.broadcast(new AliasEvent(alias, AliasEvent.Event.CHANGE));
setItem(alias);
}
}
}
});
add(mDeleteIDButton, "wrap");
}
@Override
public void setItem(Alias alias)
{
super.setItem(alias);
if(alias == null || alias.getId().isEmpty())
{
mAliasIDList.setModel(EMPTY_MODEL);
}
else
{
DefaultListModel<AliasID> model = new DefaultListModel<AliasID>();
List<AliasID> ids = alias.getId();
ids.sort(Comparator.comparing(Object::toString));
for(AliasID id : ids)
{
model.addElement(id);
}
mAliasIDList.setModel(model);
}
mEditorContainer.setAliasID(null);
}
@Override
public void save()
{
if(isModified() || mEditorContainer.isModified())
{
if(mEditorContainer.isModified())
{
mEditorContainer.save();
}
setModified(false);
if(hasItem())
{
mAliasModel.broadcast(new AliasEvent(getItem(), AliasEvent.Event.CHANGE));
}
}
}
public class EditorContainer extends JPanel
{
private static final long serialVersionUID = 1L;
private Editor<AliasID> mEditor = new EmptyEditor<>();
public EditorContainer()
{
setLayout(new MigLayout("", "[grow,fill]", "[grow,fill]"));
add(mEditor);
}
public boolean isModified()
{
if(mEditor != null)
{
return mEditor.isModified();
}
return false;
}
public void save()
{
if(mEditor != null)
{
mEditor.save();
}
}
public void setAliasID(AliasID aliasID)
{
if(mEditor != null)
{
if(mEditor.isModified())
{
int option = JOptionPane.showConfirmDialog(
EditorContainer.this,
"Identifier settings have changed. Do you want to save these changes?",
"Save Changes?",
JOptionPane.YES_NO_OPTION,
JOptionPane.QUESTION_MESSAGE);
if(option == JOptionPane.YES_OPTION)
{
mEditor.save();
}
}
}
removeAll();
//This will always give us an editor
mEditor = AliasFactory.getEditor(aliasID, mBroadcastModel);
add(mEditor);
revalidate();
}
}
private void addAliasIDToList(final AliasID id)
{
if(id != null && hasItem())
{
final Alias alias = getItem();
alias.addAliasID(id);
EventQueue.invokeLater(new Runnable()
{
@Override
public void run()
{
setItem(alias);
mAliasIDList.setSelectedValue(id, true);
AliasIdentifierEditor.this.setModified(true);
}
});
}
}
public class AddAliasIdentifierItem extends JMenuItem
{
private static final long serialVersionUID = 1L;
private AliasIDType mAliasIDType;
public AddAliasIdentifierItem(AliasIDType type)
{
super(type.toString());
mAliasIDType = type;
addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
final AliasID id = AliasFactory.getAliasID(mAliasIDType);
addAliasIDToList(id);
}
});
}
}
}

View File

@@ -1,120 +0,0 @@
/*******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2016 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.alias.id;
import org.apache.commons.lang3.Validate;
import org.apache.commons.math3.util.FastMath;
import java.util.regex.Pattern;
public class WildcardID implements Comparable<WildcardID>
{
public static final String WILDCARD = "*";
public static final String REGEX_WILDCARD = ".";
private String mValue;
private Pattern mPattern;
private int mWeight;
/**
* Wildcard identifier for matching to string identifiers containing single-character (*) wildcard values.
*
* Supports ordering from most-specific to least-specific using the build-in weighting calculation where identifier
* patterns containing fewer wildcards closer to the least significant digit will be weighted more heavily than
* identifier patterns containing more wildcards, or wildcard characters in the most significant digits.
*
* @param value is a string value containing one or more asterisk (*) single character wildcard with a maximum
* length of 10 characters.
*
* @throws AssertionError if the value is null, longer than 10 characters, or doesn't contain at least 1 asterisk
* @throws IllegalArgumentException if the value cannot be compiled as a regular expression after converting the
* asterisk characters to the regex single-character wildcard value (.)
*/
public WildcardID(String value)
{
Validate.isTrue(value != null && value.contains(WILDCARD) && value.length() < 10);
mValue = value;
try
{
mPattern = Pattern.compile(value.replace(WILDCARD, REGEX_WILDCARD));
}
catch(Exception e)
{
throw new IllegalArgumentException("Invalid regex pattern for alias ID value [" + value + "]", e);
}
mWeight = calculateWeight();
}
public String value()
{
return mValue;
}
/**
* Indicates if the id matches the internal regex pattern for this wildcard alias ID
* @param id
* @return
*/
public boolean matches(String id)
{
return id != null && mPattern.matcher(id).matches();
}
public int weight()
{
return mWeight;
}
/**
* Calculates a weighting value for wildcard character quantity and significant digit location
*/
private int calculateWeight()
{
int weight = 0;
int characterCount = -1;
for( int x = 0; x < mValue.length(); x++)
{
if(mValue.substring(x, x + 1).equals(WILDCARD))
{
weight += (int)(FastMath.pow(2, mValue.length() - x - 1)); //Position weight
characterCount++;
}
}
weight += (int)(FastMath.pow(2, characterCount)) * 1000; //Character count weight
return weight;
}
@Override
public int compareTo(WildcardID otherWildcardID)
{
return Integer.compare(this.weight(), otherWildcardID.weight());
}
@Override
public boolean equals(Object o) {
if (!(o instanceof WildcardID)) return false;
return compareTo((WildcardID) o) == 0;
}
}

View File

@@ -1,21 +1,24 @@
/*******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2016 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.
* * ******************************************************************************
* * Copyright (C) 2014-2020 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/>
* * *****************************************************************************
*
* 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.alias.id.broadcast;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
@@ -31,6 +34,12 @@ public class BroadcastChannel extends AliasID implements Comparable<BroadcastCha
//JAXB Constructor
}
@Override
public boolean isAudioIdentifier()
{
return true;
}
@Override
public int compareTo(BroadcastChannel other)
{
@@ -94,6 +103,7 @@ public class BroadcastChannel extends AliasID implements Comparable<BroadcastCha
public void setChannelName(String channel)
{
mChannelName = channel;
updateValueProperty();
}
@JacksonXmlProperty(isAttribute = true, localName = "type", namespace = "http://www.w3.org/2001/XMLSchema-instance")
@@ -118,13 +128,6 @@ public class BroadcastChannel extends AliasID implements Comparable<BroadcastCha
@Override
public String toString()
{
if(isValid())
{
return "Broadcast Channel: " + mChannelName;
}
else
{
return "Broadcast Channel: None Selected";
}
return isValid() ? mChannelName : "(invalid)";
}
}

View File

@@ -1,129 +0,0 @@
/*******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2016 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.alias.id.broadcast;
import io.github.dsheirer.alias.id.AliasID;
import io.github.dsheirer.audio.broadcast.BroadcastConfiguration;
import io.github.dsheirer.audio.broadcast.BroadcastModel;
import io.github.dsheirer.gui.editor.DocumentListenerEditor;
import net.miginfocom.swing.MigLayout;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.List;
public class BroadcastChannelEditor extends DocumentListenerEditor<AliasID>
{
private static final long serialVersionUID = 1L;
private static final String HELP_TEXT = "<html>"
+ "<h3>Audio Broadcast Channel</h3>"
+ "Name of a audio streaming broadcast configuration<br>"
+ "to be used for streaming audio to an external<br>"
+ "streaming server";
private JComboBox<String> mBroadcastConfigurations;
private BroadcastModel mBroadcastModel;
public BroadcastChannelEditor(AliasID aliasID, BroadcastModel broadcastModel)
{
mBroadcastModel = broadcastModel;
initGUI();
setItem( aliasID );
}
private void initGUI()
{
setLayout( new MigLayout( "fill,wrap 1", "[]", "[][]" ) );
add( new JLabel( "Broadcast Channel" ), "grow" );
List<String> channelNames = mBroadcastModel.getBroadcastConfigurationNames();
mBroadcastConfigurations = new JComboBox<String>(channelNames.toArray(new String[0]));
mBroadcastConfigurations.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
setModified(true);
}
});
add(mBroadcastConfigurations, "grow");
JLabel help = new JLabel( "Help ..." );
help.setForeground( Color.BLUE.brighter() );
help.setCursor( new Cursor( Cursor.HAND_CURSOR ) );
help.addMouseListener( new MouseAdapter()
{
@Override
public void mouseClicked( MouseEvent e )
{
JOptionPane.showMessageDialog( BroadcastChannelEditor.this,
HELP_TEXT, "Help", JOptionPane.INFORMATION_MESSAGE );
}
} );
add( help, "align left" );
}
@Override
public void setItem(AliasID item)
{
super.setItem(item);
if(item instanceof BroadcastChannel)
{
BroadcastChannel channel = (BroadcastChannel)item;
if(channel.isValid())
{
mBroadcastConfigurations.setSelectedItem(channel.getChannelName());
}
}
setModified(false);
}
@Override
public void save()
{
String channel = (String)mBroadcastConfigurations.getSelectedItem();
BroadcastConfiguration selectedConfiguration = mBroadcastModel.getBroadcastConfiguration(channel);
if(selectedConfiguration != null)
{
((BroadcastChannel)getItem()).setChannelName(selectedConfiguration.getName());
}
else
{
((BroadcastChannel)getItem()).setChannelName(null);
}
}
}

View File

@@ -1,113 +0,0 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014-2016 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.alias.id.esn;
import io.github.dsheirer.alias.id.AliasID;
import io.github.dsheirer.gui.editor.DocumentListenerEditor;
import net.miginfocom.swing.MigLayout;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class ESNEditor extends DocumentListenerEditor<AliasID>
{
private static final long serialVersionUID = 1L;
private static final String HELP_TEXT =
"<html><h3>Electronic Serial Number (ESN)</h3>"
+ "<b>ESN:</b> hexadecimal 0-9, A-F (e.g. <u>ABCD1234</u> )<br>"
+ "<b>Wildcard:</b> use an asterisk (*) to wildcard individual<br>"
+ "digits (e.g. <u>ABCD123*</u> or <u>AB**1**4</u>)"
+ "</html>";
private JTextField mTextField;
public ESNEditor( AliasID aliasID )
{
initGUI();
setItem( aliasID );
}
private void initGUI()
{
setLayout( new MigLayout( "fill,wrap 2", "[right][left]", "[][]" ) );
add( new JLabel( "ESN:" ) );
mTextField = new JTextField();
mTextField.getDocument().addDocumentListener( this );
mTextField.setToolTipText( HELP_TEXT );
add( mTextField, "growx,push" );
JLabel help = new JLabel( "Help ..." );
help.setForeground( Color.BLUE.brighter() );
help.setCursor( new Cursor( Cursor.HAND_CURSOR ) );
help.addMouseListener( new MouseAdapter()
{
@Override
public void mouseClicked( MouseEvent e )
{
JOptionPane.showMessageDialog( ESNEditor.this,
HELP_TEXT, "Help", JOptionPane.INFORMATION_MESSAGE );
}
} );
add( help, "align left" );
}
public Esn getEsn()
{
if( getItem() instanceof Esn )
{
return (Esn)getItem();
}
return null;
}
@Override
public void setItem( AliasID aliasID )
{
super.setItem( aliasID );
Esn esn = getEsn();
if( esn != null )
{
mTextField.setText( esn.getEsn() );
}
setModified( false );
repaint();
}
@Override
public void save()
{
Esn esn = getEsn();
if( esn != null )
{
esn.setEsn( mTextField.getText() );
}
setModified( false );
}
}

View File

@@ -29,6 +29,12 @@ public class Esn extends AliasID
{
}
@Override
public boolean isAudioIdentifier()
{
return false;
}
@JacksonXmlProperty(isAttribute = true, localName = "esn")
public String getEsn()
{
@@ -44,6 +50,7 @@ public class Esn extends AliasID
public void setEsn(String esn )
{
mEsn = esn;
updateValueProperty();
}
public String toString()

View File

@@ -31,6 +31,12 @@ public class FleetsyncID extends AliasID
{
}
@Override
public boolean isAudioIdentifier()
{
return false;
}
@JacksonXmlProperty(isAttribute = true, localName = "ident")
public String getIdent()
{

View File

@@ -1,137 +0,0 @@
/*
* ******************************************************************************
* 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.alias.id.legacy.fleetsync;
import io.github.dsheirer.alias.id.AliasID;
import io.github.dsheirer.gui.editor.DocumentListenerEditor;
import net.miginfocom.swing.MigLayout;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.swing.JFormattedTextField;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import javax.swing.text.MaskFormatter;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class FleetsyncIDEditor extends DocumentListenerEditor<AliasID>
{
private final static Logger mLog = LoggerFactory.getLogger( FleetsyncIDEditor.class );
private static final long serialVersionUID = 1L;
private static final String HELP_TEXT = "<html>"
+ "<h3>Fleetsync Identifier</h3>"
+ "<b>Fleetsync:</b> ggg-uuuu where g=Group and u=Unit (e.g. <u>001-0001</u>)<br>"
+ "<b>Wildcard:</b> use an asterisk (*) for each digit (e.g. <u>001-****</u>)"
+ "</html>";
private JTextField mTextField;
public FleetsyncIDEditor( AliasID aliasID )
{
initGUI();
setItem( aliasID );
}
private void initGUI()
{
setLayout( new MigLayout( "fill,wrap 2", "[right][left]", "[][]" ) );
add( new JLabel( "Fleetsync ID:" ) );
MaskFormatter formatter = null;
try
{
//Mask: 3 digits - 4 digits
formatter = new MaskFormatter( "###-####" );
}
catch( Exception e )
{
//Do nothing, the mask was invalid
}
mTextField = new JFormattedTextField( formatter );
mTextField.getDocument().addDocumentListener( this );
mTextField.setToolTipText( HELP_TEXT );
add( mTextField, "growx,push" );
JLabel help = new JLabel( "Help ..." );
help.setForeground( Color.BLUE.brighter() );
help.setCursor( new Cursor( Cursor.HAND_CURSOR ) );
help.addMouseListener( new MouseAdapter()
{
@Override
public void mouseClicked( MouseEvent e )
{
JOptionPane.showMessageDialog( FleetsyncIDEditor.this,
HELP_TEXT, "Help", JOptionPane.INFORMATION_MESSAGE );
}
} );
add( help, "align left" );
}
public FleetsyncID getFleetsyncID()
{
if( getItem() instanceof FleetsyncID )
{
return (FleetsyncID)getItem();
}
return null;
}
@Override
public void setItem( AliasID aliasID )
{
super.setItem( aliasID );
FleetsyncID fleetsync = getFleetsyncID();
if( fleetsync != null )
{
mTextField.setText( fleetsync.getIdent() );
}
setModified( false );
repaint();
}
@Override
public void save()
{
FleetsyncID fleetsync = getFleetsyncID();
if( fleetsync != null )
{
fleetsync.setIdent( mTextField.getText() );
}
setModified( false );
}
}

View File

@@ -32,6 +32,12 @@ public class MDC1200ID extends AliasID
{
}
@Override
public boolean isAudioIdentifier()
{
return false;
}
@JacksonXmlProperty(isAttribute = true, localName = "ident")
public String getIdent()
{

View File

@@ -1,133 +0,0 @@
/*
* ******************************************************************************
* 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.alias.id.legacy.mdc;
import io.github.dsheirer.alias.id.AliasID;
import io.github.dsheirer.gui.editor.DocumentListenerEditor;
import net.miginfocom.swing.MigLayout;
import javax.swing.JFormattedTextField;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import javax.swing.text.MaskFormatter;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class MDC1200IDEditor extends DocumentListenerEditor<AliasID>
{
private static final long serialVersionUID = 1L;
private static final String HELP_TEXT = "<html>"
+ "<h3>MDC-1200 Identifier</h3>"
+ "<b>MDC-1200:</b> four digit [0-9] value (e.g. <u>1234</u>)<br>"
+ "<b>Wildcard:</b> use an asterisk (*) to wildcard individual<br>"
+ "digits (e.g. <u>123*</u> or <u>**34</u>)"
+ "</html>";
private JTextField mTextField;
public MDC1200IDEditor(AliasID aliasID)
{
initGUI();
setItem(aliasID);
}
private void initGUI()
{
setLayout(new MigLayout("fill,wrap 2", "[right][left]", "[][]"));
add(new JLabel("MDC-1200 ID:"));
MaskFormatter formatter = null;
try
{
//Mask: 4 digits
formatter = new MaskFormatter("####");
}
catch(Exception e)
{
//Do nothing, the mask was invalid
}
mTextField = new JFormattedTextField(formatter);
mTextField.getDocument().addDocumentListener(this);
mTextField.setToolTipText(HELP_TEXT);
add(mTextField, "growx,push");
JLabel help = new JLabel("Help ...");
help.setForeground(Color.BLUE.brighter());
help.setCursor(new Cursor(Cursor.HAND_CURSOR));
help.addMouseListener(new MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent e)
{
JOptionPane.showMessageDialog(MDC1200IDEditor.this,
HELP_TEXT, "Help", JOptionPane.INFORMATION_MESSAGE);
}
});
add(help, "align left");
}
public MDC1200ID getMDC1200ID()
{
if(getItem() instanceof MDC1200ID)
{
return (MDC1200ID)getItem();
}
return null;
}
@Override
public void setItem(AliasID aliasID)
{
super.setItem(aliasID);
MDC1200ID mdc = getMDC1200ID();
if(mdc != null)
{
mTextField.setText(mdc.getIdent());
}
setModified(false);
repaint();
}
@Override
public void save()
{
MDC1200ID mdc = getMDC1200ID();
if(mdc != null)
{
mdc.setIdent(mTextField.getText());
}
setModified(false);
}
}

View File

@@ -1,127 +0,0 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014-2016 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.alias.id.legacy.mobileID;
import io.github.dsheirer.alias.id.AliasID;
import io.github.dsheirer.gui.editor.DocumentListenerEditor;
import net.miginfocom.swing.MigLayout;
import javax.swing.*;
import javax.swing.text.MaskFormatter;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class MINEditor extends DocumentListenerEditor<AliasID>
{
private static final long serialVersionUID = 1L;
private static final String HELP_TEXT = "<html>"
+ "<h3>Passport Mobile ID (MIN)</h3>"
+ "<b>MIN:</b> six character hex value (e.g. <u>AB12CD</u>)<br>"
+ "<b>Wildcard:</b> use an asterisk (*) to wildcard individual<br>"
+ "digits (e.g. <u>AB**CD</u> or <u>AB12**</u>)"
+ "</html>";
private JTextField mTextField;
public MINEditor( AliasID aliasID )
{
initGUI();
setItem( aliasID );
}
private void initGUI()
{
setLayout( new MigLayout( "fill,wrap 2", "[right][left]", "[][]" ) );
add( new JLabel( "MIN:" ) );
MaskFormatter formatter = null;
try
{
//Mask: 6 hex characters
formatter = new MaskFormatter( "HHHHHH" );
}
catch( Exception e )
{
//Do nothing, the mask was invalid
}
mTextField = new JFormattedTextField( formatter );
mTextField.getDocument().addDocumentListener( this );
mTextField.setToolTipText( HELP_TEXT );
add( mTextField, "growx,push" );
JLabel help = new JLabel( "Help ..." );
help.setForeground( Color.BLUE.brighter() );
help.setCursor( new Cursor( Cursor.HAND_CURSOR ) );
help.addMouseListener( new MouseAdapter()
{
@Override
public void mouseClicked( MouseEvent e )
{
JOptionPane.showMessageDialog( MINEditor.this,
HELP_TEXT, "Help", JOptionPane.INFORMATION_MESSAGE );
}
} );
add( help, "align left" );
}
public Min getMin()
{
if( getItem() instanceof Min )
{
return (Min)getItem();
}
return null;
}
@Override
public void setItem( AliasID aliasID )
{
super.setItem( aliasID );
Min min = getMin();
if( min != null )
{
mTextField.setText( min.getMin() );
}
setModified( false );
repaint();
}
@Override
public void save()
{
Min min = getMin();
if( min != null )
{
min.setMin( mTextField.getText() );
}
setModified( false );
}
}

View File

@@ -33,6 +33,12 @@ public class Min extends AliasID
{
}
@Override
public boolean isAudioIdentifier()
{
return false;
}
@JacksonXmlProperty(isAttribute = true, localName = "min")
public String getMin()
{

View File

@@ -32,6 +32,12 @@ public class MPT1327ID extends AliasID
{
}
@Override
public boolean isAudioIdentifier()
{
return false;
}
@JacksonXmlProperty(isAttribute = true, localName = "ident")
public String getIdent()
{

View File

@@ -1,135 +0,0 @@
/*
* ******************************************************************************
* 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.alias.id.legacy.mpt1327;
import io.github.dsheirer.alias.id.AliasID;
import io.github.dsheirer.gui.editor.DocumentListenerEditor;
import net.miginfocom.swing.MigLayout;
import javax.swing.JFormattedTextField;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import javax.swing.text.MaskFormatter;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class MPT1327IDEditor extends DocumentListenerEditor<AliasID>
{
private static final long serialVersionUID = 1L;
private static final String HELP_TEXT = "<html>"
+ "<h3>MPT-1327 Identifier</h3>"
+ "<b>MPT-1327:</b> decimal (0-9) format ppp-iiii where<br>"
+ "p=Prefix and i=Ident (e.g. <u>123-0001</u>)<br>"
+ "<b>Wildcard:</b> use an asterisk (*) to wildcard individual<br>"
+ "digits (e.g. <u>ABCD123*</u> or <u>AB**1**4</u>)"
+ "</html>";
private JTextField mTextField;
public MPT1327IDEditor( AliasID aliasID )
{
initGUI();
setItem( aliasID );
}
private void initGUI()
{
setLayout( new MigLayout( "fill,wrap 2", "[right][left]", "[][]" ) );
add( new JLabel( "MPT-1327 ID:" ) );
MaskFormatter formatter = null;
try
{
//Mask: 3 digits - 4 digits
formatter = new MaskFormatter( "***-****" );
}
catch( Exception e )
{
//Do nothing, the mask was invalid
}
mTextField = new JFormattedTextField( formatter );
mTextField.getDocument().addDocumentListener( this );
mTextField.setToolTipText( HELP_TEXT );
add( mTextField, "growx,push" );
JLabel help = new JLabel( "Help ..." );
help.setForeground( Color.BLUE.brighter() );
help.setCursor( new Cursor( Cursor.HAND_CURSOR ) );
help.addMouseListener( new MouseAdapter()
{
@Override
public void mouseClicked( MouseEvent e )
{
JOptionPane.showMessageDialog( MPT1327IDEditor.this,
HELP_TEXT, "Help", JOptionPane.INFORMATION_MESSAGE );
}
} );
add( help, "align left" );
}
public MPT1327ID getMPT1327ID()
{
if( getItem() instanceof MPT1327ID )
{
return (MPT1327ID)getItem();
}
return null;
}
@Override
public void setItem( AliasID aliasID )
{
super.setItem( aliasID );
MPT1327ID mpt = getMPT1327ID();
if( mpt != null )
{
mTextField.setText( mpt.getIdent() );
}
setModified( false );
repaint();
}
@Override
public void save()
{
MPT1327ID mpt = getMPT1327ID();
if( mpt != null )
{
mpt.setIdent( mTextField.getText() );
}
setModified( false );
}
}

View File

@@ -33,6 +33,12 @@ public class NonRecordable extends AliasID
return AliasIDType.NON_RECORDABLE;
}
@Override
public boolean isAudioIdentifier()
{
return true;
}
@Override
public boolean isValid()
{

View File

@@ -1,78 +0,0 @@
/*
* ******************************************************************************
* 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.alias.id.legacy.nonrecordable;
import io.github.dsheirer.alias.id.AliasID;
import io.github.dsheirer.gui.editor.DocumentListenerEditor;
import net.miginfocom.swing.MigLayout;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class NonRecordableEditor extends DocumentListenerEditor<AliasID>
{
private static final long serialVersionUID = 1L;
private static final String HELP_TEXT = "<html>"
+ "<h3>Audio Non-Recordable</h3>"
+ "This identifies an alias as non-recordable.<br><br>"
+ "The alias can still be monitored but associated audio will<br>"
+ "not be recorded.<br><br>"
+ "The default behavior when audio recording is enabled for a<br>"
+ "channel is to record all aliases except any alias with a<br>"
+ "non-recordable identifier";
public NonRecordableEditor(AliasID aliasID)
{
initGUI();
setItem(aliasID);
}
private void initGUI()
{
setLayout(new MigLayout("fill,wrap 1", "[]", "[][]"));
add(new JLabel("Non-Recordable"), "wrap");
JLabel help = new JLabel("Help ...");
help.setForeground(Color.BLUE.brighter());
help.setCursor(new Cursor(Cursor.HAND_CURSOR));
help.addMouseListener(new MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent e)
{
JOptionPane.showMessageDialog(NonRecordableEditor.this,
HELP_TEXT, "Help", JOptionPane.INFORMATION_MESSAGE);
}
});
add(help, "align left");
}
@Override
public void save()
{
}
}

View File

@@ -29,6 +29,12 @@ public class SiteID extends AliasID
{
}
@Override
public boolean isAudioIdentifier()
{
return false;
}
@JacksonXmlProperty(isAttribute = true, localName = "site")
public String getSite()
{

View File

@@ -1,116 +0,0 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014-2016 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.alias.id.legacy.siteID;
import io.github.dsheirer.alias.id.AliasID;
import io.github.dsheirer.gui.editor.DocumentListenerEditor;
import net.miginfocom.swing.MigLayout;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class SiteIDEditor extends DocumentListenerEditor<AliasID>
{
private static final long serialVersionUID = 1L;
private static final String HELP_TEXT = "<html>"
+ "<h3>Site Identifier</h3>"
+ "<b>LTR-Net:</b> decimal (0-9) (e.g. <u>019</u>)<br>"
+ "<b>MPT-1327:</b> 5 digits (0-9) (e.g. <u>23619</u>)<br>"
+ "<b>Passport:</b> 3 digits (0-9) (e.g. <u>019</u>)<br>"
+ "<b>P25:</b> hex (0-9, A-F) format RR-SS where RR = RF Subsystem<br>"
+ "and SS = Site Number (e.g. RFSS 1 Site 1F: <u>01-1F</u>)"
+ "</html>";
private JTextField mTextField;
public SiteIDEditor( AliasID aliasID )
{
initGUI();
setItem( aliasID );
}
private void initGUI()
{
setLayout( new MigLayout( "fill,wrap 2", "[right][left]", "[][]" ) );
add( new JLabel( "Site ID:" ) );
mTextField = new JTextField();
mTextField.getDocument().addDocumentListener( this );
mTextField.setToolTipText( HELP_TEXT );
add( mTextField, "growx,push" );
JLabel help = new JLabel( "Help ..." );
help.setForeground( Color.BLUE.brighter() );
help.setCursor( new Cursor( Cursor.HAND_CURSOR ) );
help.addMouseListener( new MouseAdapter()
{
@Override
public void mouseClicked( MouseEvent e )
{
JOptionPane.showMessageDialog( SiteIDEditor.this,
HELP_TEXT, "Help", JOptionPane.INFORMATION_MESSAGE );
}
} );
add( help, "align left" );
}
public SiteID getSiteID()
{
if( getItem() instanceof SiteID )
{
return (SiteID)getItem();
}
return null;
}
@Override
public void setItem( AliasID aliasID )
{
super.setItem( aliasID );
SiteID siteID = getSiteID();
if( siteID != null )
{
mTextField.setText( siteID.getSite() );
}
setModified( false );
repaint();
}
@Override
public void save()
{
SiteID siteID = getSiteID();
if( siteID != null )
{
siteID.setSite( mTextField.getText() );
}
setModified( false );
}
}

View File

@@ -38,6 +38,12 @@ public class LegacyTalkgroupID extends AliasID
mTalkgroup = talkgroup;
}
@Override
public boolean isAudioIdentifier()
{
return false;
}
@JacksonXmlProperty(isAttribute = true, localName = "talkgroup")
public String getTalkgroup()
{

View File

@@ -1,121 +0,0 @@
/*
* ******************************************************************************
* 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.alias.id.legacy.talkgroup;
import io.github.dsheirer.alias.id.AliasID;
import io.github.dsheirer.gui.editor.DocumentListenerEditor;
import net.miginfocom.swing.MigLayout;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class LegacyTalkgroupIDEditor extends DocumentListenerEditor<AliasID>
{
private static final long serialVersionUID = 1L;
private static final String HELP_TEXT =
"<html><h3>Talkgroup Identifier</h3>"
+ "<b>P25:</b> 4 or 6 hex characters (e.g. <u>AB12</u> or <u>ABC123</u>)<br>"
+ "<b>LTR:</b> A-HH-TTT where A=Area H=Home T=Talkgroup (<u>0-01-128</u>)<br>"
+ "<b>Passport</b>: 5-digit number (<u>12345</u> or <u>00023</u>)<br>"
+ "<br>"
+ "<b>Wildcard:</b> use an asterisk (*) in place of each talkgroup digit (e.g. <u>0*1*5</u>)"
+ "</html>";
private JTextField mTextField;
public LegacyTalkgroupIDEditor(AliasID aliasID)
{
initGUI();
setItem(aliasID);
}
private void initGUI()
{
setLayout(new MigLayout("fill,wrap 2", "[right][left]", "[][]"));
add(new JLabel("Talkgroup:"));
mTextField = new JTextField();
mTextField.getDocument().addDocumentListener(this);
mTextField.setToolTipText(HELP_TEXT);
add(mTextField, "growx,push");
JLabel help = new JLabel("Help ...");
help.setForeground(Color.BLUE.brighter());
help.setCursor(new Cursor(Cursor.HAND_CURSOR));
help.addMouseListener(new MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent e)
{
JOptionPane.showMessageDialog(LegacyTalkgroupIDEditor.this,
HELP_TEXT, "Help", JOptionPane.INFORMATION_MESSAGE);
}
});
add(help, "align left");
}
public LegacyTalkgroupID getTalkgroupID()
{
if(getItem() instanceof LegacyTalkgroupID)
{
return (LegacyTalkgroupID)getItem();
}
return null;
}
@Override
public void setItem(AliasID aliasID)
{
super.setItem(aliasID);
LegacyTalkgroupID talkgroup = getTalkgroupID();
if(talkgroup != null)
{
mTextField.setText(talkgroup.getTalkgroup());
}
setModified(false);
repaint();
}
@Override
public void save()
{
LegacyTalkgroupID talkgroup = getTalkgroupID();
if(talkgroup != null)
{
talkgroup.setTalkgroup(mTextField.getText());
}
setModified(false);
}
}

View File

@@ -29,6 +29,12 @@ public class UniqueID extends AliasID
{
}
@Override
public boolean isAudioIdentifier()
{
return false;
}
@JacksonXmlProperty(isAttribute = true, localName = "uid")
public int getUid()
{

View File

@@ -1,123 +0,0 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014-2016 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.alias.id.legacy.uniqueID;
import io.github.dsheirer.alias.id.AliasID;
import io.github.dsheirer.gui.editor.DocumentListenerEditor;
import net.miginfocom.swing.MigLayout;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class UniqueIDEditor extends DocumentListenerEditor<AliasID>
{
private static final long serialVersionUID = 1L;
private static final String HELP_TEXT = "<html>"
+ "<h3>LTR-Net Unique ID (UID)</h3>"
+ "<b>UID:</b> identifier assigned to each radio in<br>"
+ "the range <u>1 - 2097152</u>"
+ "</html>";
private JTextField mTextField;
public UniqueIDEditor( AliasID aliasID )
{
initGUI();
setItem( aliasID );
}
private void initGUI()
{
setLayout( new MigLayout( "fill,wrap 2", "[right][left]", "[][]" ) );
add( new JLabel( "Unique ID:" ) );
mTextField = new JTextField();
mTextField.getDocument().addDocumentListener( this );
mTextField.setToolTipText( HELP_TEXT );
add( mTextField, "growx,push" );
JLabel help = new JLabel( "Help ..." );
help.setForeground( Color.BLUE.brighter() );
help.setCursor( new Cursor( Cursor.HAND_CURSOR ) );
help.addMouseListener( new MouseAdapter()
{
@Override
public void mouseClicked( MouseEvent e )
{
JOptionPane.showMessageDialog( UniqueIDEditor.this,
HELP_TEXT, "Help", JOptionPane.INFORMATION_MESSAGE );
}
} );
add( help, "align left" );
}
public UniqueID getUniqueID()
{
if( getItem() instanceof UniqueID )
{
return (UniqueID)getItem();
}
return null;
}
@Override
public void setItem( AliasID aliasID )
{
super.setItem( aliasID );
UniqueID uid = getUniqueID();
if( uid != null )
{
mTextField.setText( String.valueOf( uid.getUid() ) );
}
setModified( false );
repaint();
}
@Override
public void save()
{
UniqueID uid = getUniqueID();
if( uid != null )
{
int id = 0;
try
{
id = Integer.parseInt( mTextField.getText() );
}
catch( Exception e )
{
//Do nothing, we couldn't parse the value
}
uid.setUid( id );
}
setModified( false );
}
}

View File

@@ -32,6 +32,12 @@ public class LoJackFunctionAndID extends AliasID
{
}
@Override
public boolean isAudioIdentifier()
{
return false;
}
@JacksonXmlProperty(isAttribute = true, localName = "id")
public String getID()
{
@@ -41,6 +47,7 @@ public class LoJackFunctionAndID extends AliasID
public void setID(String id)
{
mID = id;
updateValueProperty();
}
@JacksonXmlProperty(isAttribute = true, localName = "function")
@@ -52,6 +59,7 @@ public class LoJackFunctionAndID extends AliasID
public void setFunction(LJ1200Message.Function function)
{
mFunction = function;
updateValueProperty();
}
@Override

View File

@@ -1,160 +0,0 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014-2016 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.alias.id.lojack;
import io.github.dsheirer.alias.id.AliasID;
import io.github.dsheirer.gui.editor.DocumentListenerEditor;
import io.github.dsheirer.module.decode.lj1200.LJ1200Message;
import io.github.dsheirer.module.decode.lj1200.LJ1200Message.Function;
import net.miginfocom.swing.MigLayout;
import javax.swing.*;
import javax.swing.text.MaskFormatter;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class LoJackIDEditor extends DocumentListenerEditor<AliasID>
{
private static final long serialVersionUID = 1L;
private JTextField mTextField;
private JComboBox<LJ1200Message.Function> mFunctionCombo;
private static final String HELP_TEXT = "<html>"
+ "<h3>LoJack Function and Identifier</h3>"
+ "<b>Function Code:</b> <u>1Y-SITE ID</u><br>"
+ "<b>ID:</b> 5 numbers or characters (e.g. <u>1BN47</u>)<br>"
+ "<br>"
+ "<b>Wildcard:</b> use an asterisk (*) to wildcard ID<br>"
+ "characters (e.g. <u>AB*CD</u> or <u>***12</u> or <u>*****</u>)<br><br>"
+ "The middle character in a reply ID code identifies the<br>"
+ "entity. Valid ID middle characters are:<br>"
+ "<li><b>Tower:</b> X,Y</li>"
+ "<li><b>Transponder:</b> 0-9,A,C-H,J-N,P-W</li>"
+ "<li><b>Not Used:</b> B,I,O,Z</li>"
+ "</html>";
public LoJackIDEditor( AliasID aliasID )
{
initGUI();
setItem( aliasID );
}
private void initGUI()
{
setLayout( new MigLayout( "fill,wrap 2", "[right][left]", "[][][]" ) );
add( new JLabel( "Function:" ) );
mFunctionCombo = new JComboBox<LJ1200Message.Function>( Function.values() );
mFunctionCombo.addActionListener( new ActionListener()
{
@Override
public void actionPerformed( ActionEvent e )
{
setModified( true );
}
} );
mFunctionCombo.setToolTipText( HELP_TEXT );
add( mFunctionCombo, "growx, push" );
add( new JLabel( "ID:" ) );
MaskFormatter formatter = null;
try
{
//Mask: any character or number, 5 places
formatter = new MaskFormatter( "AAAAA" );
}
catch( Exception e )
{
//Do nothing, the mask was invalid
}
mTextField = new JFormattedTextField( formatter );
mTextField.getDocument().addDocumentListener( this );
mTextField.setToolTipText( HELP_TEXT );
add( mTextField, "growx,push" );
JLabel help = new JLabel( "Help ..." );
help.setForeground( Color.BLUE.brighter() );
help.setCursor( new Cursor( Cursor.HAND_CURSOR ) );
help.addMouseListener( new MouseAdapter()
{
@Override
public void mouseClicked( MouseEvent e )
{
JOptionPane.showMessageDialog( LoJackIDEditor.this,
HELP_TEXT, "Help", JOptionPane.INFORMATION_MESSAGE );
}
} );
add( help, "align left" );
}
public LoJackFunctionAndID getLoJackID()
{
if( getItem() instanceof LoJackFunctionAndID )
{
return (LoJackFunctionAndID)getItem();
}
return null;
}
@Override
public void setItem( AliasID aliasID )
{
super.setItem( aliasID );
LoJackFunctionAndID lojack = getLoJackID();
if( lojack != null )
{
mFunctionCombo.setSelectedItem( lojack.getFunction() );
mTextField.setText( lojack.getID() );
}
else
{
mFunctionCombo.setSelectedItem( null );
mTextField.setText( null );
}
setModified( false );
repaint();
}
@Override
public void save()
{
LoJackFunctionAndID lojack = getLoJackID();
if( lojack != null )
{
lojack.setID( mTextField.getText() );
lojack.setFunction( (Function)mFunctionCombo.getSelectedItem() );
}
setModified( false );
}
}

View File

@@ -39,6 +39,17 @@ public class Priority extends AliasID
{
}
public Priority(int priority)
{
mPriority = priority;
}
@Override
public boolean isAudioIdentifier()
{
return true;
}
@Override
public boolean isValid()
{
@@ -63,6 +74,7 @@ public class Priority extends AliasID
public void setPriority(int priority)
{
mPriority = priority;
updateValueProperty();
}
public String toString()

View File

@@ -1,163 +0,0 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014-2016 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.alias.id.priority;
import io.github.dsheirer.alias.id.AliasID;
import io.github.dsheirer.gui.editor.DocumentListenerEditor;
import net.miginfocom.swing.MigLayout;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class PriorityEditor extends DocumentListenerEditor<AliasID>
{
private static final long serialVersionUID = 1L;
public static final String DO_NOT_MONITOR = "Do Not Monitor";
private static final String HELP_TEXT = "<html>"
+ "<h3>Call Audio Priority</h3>"
+ "Priority determines which calls have priority for playback<br>"
+ "over your computer speakers, or designates an alias for<br>"
+ "no-monitoring if you don't want to hear calls from an alias.<br><br>"
+ "Lower values indicate higher priority levels.<br><br>"
+ "<b>Do Not Monitor: </b> slide priority all the way to the right"
+ "</html>";
private JSlider mPrioritySlider;
private JLabel mPrioritySliderLabel;
public PriorityEditor( AliasID aliasID )
{
initGUI();
setItem( aliasID );
}
private void initGUI()
{
setLayout( new MigLayout( "fill,wrap 2", "[right][left]", "[][]" ) );
mPrioritySlider = new JSlider( JSlider.HORIZONTAL,
Priority.MIN_PRIORITY,
Priority.MAX_PRIORITY + 1,
Priority.MIN_PRIORITY );
mPrioritySlider.setMajorTickSpacing( 20 );
mPrioritySlider.setMinorTickSpacing( 5 );
mPrioritySlider.setPaintTicks( true );
mPrioritySlider.setLabelTable( mPrioritySlider.createStandardLabels( 20, 20 ) );
mPrioritySlider.setPaintLabels( true );
mPrioritySlider.addChangeListener( new ChangeListener()
{
@Override
public void stateChanged( ChangeEvent e )
{
int priority = mPrioritySlider.getValue();
if( priority == Priority.MAX_PRIORITY + 1 )
{
mPrioritySliderLabel.setText( "Priority: Do Not Monitor" );
}
else
{
mPrioritySliderLabel.setText( "Priority: " + priority );
}
setModified( true );
}
} );
mPrioritySlider.setToolTipText( HELP_TEXT );
mPrioritySliderLabel = new JLabel( "Priority: " + mPrioritySlider.getValue() + " " );
add( mPrioritySliderLabel, "span,align center" );
add( mPrioritySlider, "span,grow" );
JLabel help = new JLabel( "Help ..." );
help.setForeground( Color.BLUE.brighter() );
help.setCursor( new Cursor( Cursor.HAND_CURSOR ) );
help.addMouseListener( new MouseAdapter()
{
@Override
public void mouseClicked( MouseEvent e )
{
JOptionPane.showMessageDialog( PriorityEditor.this,
HELP_TEXT, "Help", JOptionPane.INFORMATION_MESSAGE );
}
} );
add( help, "align left" );
}
public Priority getPriority()
{
if( getItem() instanceof Priority )
{
return (Priority)getItem();
}
return null;
}
@Override
public void setItem( AliasID aliasID )
{
super.setItem( aliasID );
Priority priority = getPriority();
if( priority != null )
{
int value = priority.getPriority();
if( value == Priority.DO_NOT_MONITOR )
{
value = Priority.MAX_PRIORITY + 1;
}
mPrioritySlider.setValue( value );
}
setModified( false );
repaint();
}
@Override
public void save()
{
Priority priority = getPriority();
if( priority != null )
{
int value = mPrioritySlider.getValue();
if( value == Priority.MAX_PRIORITY + 1 )
{
value = Priority.DO_NOT_MONITOR;
}
priority.setPriority( value );
}
setModified( false );
}
}

View File

@@ -25,14 +25,13 @@ package io.github.dsheirer.alias.id.radio;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import io.github.dsheirer.alias.id.AliasID;
import io.github.dsheirer.alias.id.AliasIDType;
import io.github.dsheirer.alias.id.talkgroup.TalkgroupFormat;
import io.github.dsheirer.alias.id.talkgroup.TalkgroupFormatter;
import io.github.dsheirer.protocol.Protocol;
/**
* Integer radio identifier with protocol.
*/
public class Radio extends AliasID
public class Radio extends AliasID implements Comparable<Radio>
{
private Protocol mProtocol = Protocol.UNKNOWN;
private int mValue;
@@ -48,6 +47,12 @@ public class Radio extends AliasID
mValue = value;
}
@Override
public boolean isAudioIdentifier()
{
return false;
}
@JacksonXmlProperty(isAttribute = true, localName = "value")
public int getValue()
{
@@ -57,6 +62,7 @@ public class Radio extends AliasID
public void setValue(int value)
{
mValue = value;
updateValueProperty();
}
@JacksonXmlProperty(isAttribute = true, localName = "protocol")
@@ -68,6 +74,7 @@ public class Radio extends AliasID
public void setProtocol(Protocol protocol)
{
mProtocol = protocol;
updateValueProperty();
}
@Override
@@ -115,4 +122,22 @@ public class Radio extends AliasID
{
return AliasIDType.RADIO_ID;
}
@Override
public int compareTo(Radio other)
{
if(other == null)
{
return -1;
}
if(getProtocol().equals(other.getProtocol()))
{
return Integer.compare(getValue(), other.getValue());
}
else
{
return getProtocol().compareTo(other.getProtocol());
}
}
}

View File

@@ -1,235 +0,0 @@
/*
*
* * ******************************************************************************
* * Copyright (C) 2014-2019 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.alias.id.radio;
import io.github.dsheirer.alias.id.AliasID;
import io.github.dsheirer.gui.editor.DocumentListenerEditor;
import io.github.dsheirer.protocol.Protocol;
import net.miginfocom.swing.MigLayout;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JFormattedTextField;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.text.MaskFormatter;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.text.ParseException;
public class RadioEditor extends DocumentListenerEditor<AliasID>
{
private final static Logger mLog = LoggerFactory.getLogger(RadioEditor.class);
private static final long serialVersionUID = 1L;
private static final String VALID_CHARACTERS_FOR_ASTERISK_MASKS = "0123456789 ";
private MaskFormatter mMaskFormatter = new MaskFormatter();
private JComboBox<Protocol> mComboProtocol;
private JFormattedTextField mRadioIdField;
public RadioEditor(AliasID aliasID)
{
initGUI();
setItem(aliasID);
}
private void initGUI()
{
setLayout(new MigLayout("fill,wrap 2", "[right][left]", "[][]"));
add(new JLabel("Protocol:"));
mComboProtocol = new JComboBox<>();
DefaultComboBoxModel<Protocol> model = new DefaultComboBoxModel<>();
for(Protocol protocol : Protocol.RADIO_ID_PROTOCOLS)
{
model.addElement(protocol);
}
mComboProtocol.setModel(model);
mComboProtocol.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
Protocol protocol = (Protocol)mComboProtocol.getSelectedItem();
updateEditor(protocol);
setModified(true);
}
});
add(mComboProtocol);
add(new JLabel("Value:"));
mRadioIdField = new JFormattedTextField(mMaskFormatter);
mRadioIdField.getDocument().addDocumentListener(this);
add(mRadioIdField, "growx,push");
JLabel help = new JLabel("Help ...");
help.setForeground(Color.BLUE.brighter());
help.setCursor(new Cursor(Cursor.HAND_CURSOR));
help.addMouseListener(new MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent e)
{
RadioFormat radioFormat = RadioFormat.get(getCurrentProtocol());
JOptionPane.showMessageDialog(RadioEditor.this,
radioFormat.getValidRangeHelpText(), "Help", JOptionPane.INFORMATION_MESSAGE);
}
});
add(help, "align left");
}
private void updateEditor(Protocol protocol)
{
RadioFormat mask = RadioFormat.get(protocol);
int currentValue = 0;
Radio radio = getRadio();
if(radio != null)
{
currentValue = radio.getValue();
}
try
{
mRadioIdField.setValue(null);
mRadioIdField.setToolTipText(mask.getValidRangeHelpText());
mMaskFormatter.setMask(mask.getMask());
if(mask.getMask().contains("*"))
{
mMaskFormatter.setValidCharacters(VALID_CHARACTERS_FOR_ASTERISK_MASKS);
}
mRadioIdField.setValue(RadioFormatter.format(protocol, currentValue));
}
catch(ParseException pe)
{
mLog.error("Error applying talkgroup editor mask to mask formatter [" + mask.getMask() + "]");
}
}
private Protocol getCurrentProtocol()
{
return mComboProtocol.getItemAt(mComboProtocol.getSelectedIndex());
}
/**
* Current talkgroup alias id
*/
public Radio getRadio()
{
if(getItem() instanceof Radio)
{
return (Radio)getItem();
}
return null;
}
@Override
public void setItem(AliasID aliasID)
{
super.setItem(aliasID);
Radio radio = getRadio();
if(radio != null)
{
Protocol currentProtocol = getCurrentProtocol();
if(currentProtocol == radio.getProtocol())
{
updateEditor(radio.getProtocol());
}
mComboProtocol.getModel().setSelectedItem(radio.getProtocol());
String formatted = RadioFormatter.format(radio.getProtocol(), radio.getValue());
mRadioIdField.setValue(formatted);
}
else
{
mComboProtocol.getModel().setSelectedItem(Protocol.UNKNOWN);
mRadioIdField.setValue(RadioFormatter.format(getCurrentProtocol(), 0));
}
setModified(false);
repaint();
}
@Override
public void save()
{
Radio radio = getRadio();
if(radio != null)
{
Protocol protocol = mComboProtocol.getItemAt(mComboProtocol.getSelectedIndex());
if(protocol == null)
{
protocol = Protocol.UNKNOWN;
}
int value = -1;
try
{
value = RadioFormatter.parse(protocol, mRadioIdField.getText());
}
catch(ParseException pe)
{
//ignore ... value is still -1 and outside valid value range
}
RadioFormat mask = RadioFormat.get(protocol);
//Check for valid value within range ... notify user but allow value to persist
if(value < mask.getMinimumValidValue() || value > mask.getMaximumValidValue())
{
String message = "Invalid value [" + mRadioIdField.getText() + "]. " + protocol.name() +
" valid range is [" + mask.getValidRangeDescription() + "]";
JOptionPane.showMessageDialog(RadioEditor.this, message, "Invalid Radio ID Value",
JOptionPane.ERROR_MESSAGE);
}
else
{
radio.setValue(value);
}
radio.setProtocol(protocol);
}
setModified(false);
}
}

View File

@@ -36,6 +36,8 @@ public enum RadioFormat
{
APCO25("********", 0, 0xFFFFFF, "0 to 16,777,215",
"<html>APCO25 valid range is 0 to 16,777,215"),
PASSPORT("********", 0, 0x7FFFFF, "0 to 8,388,607",
"<html>PASSPORT valid range is 0 to 8,388,607"),
UNKNOWN("********", 1, 0xFFFFFF, "1 to 16,777,215",
"Unknown protocol valid value range is 1-16,777,215");
@@ -110,6 +112,8 @@ public enum RadioFormat
{
case APCO25:
return APCO25;
case PASSPORT:
return PASSPORT;
default:
return UNKNOWN;
}

View File

@@ -22,8 +22,10 @@
package io.github.dsheirer.alias.id.radio;
import io.github.dsheirer.preference.identifier.IntegerFormat;
import io.github.dsheirer.preference.identifier.talkgroup.APCO25TalkgroupFormatter;
import io.github.dsheirer.preference.identifier.talkgroup.IntegerFormatter;
import io.github.dsheirer.preference.identifier.talkgroup.AbstractIntegerFormatter;
import io.github.dsheirer.preference.identifier.talkgroup.UnknownTalkgroupFormatter;
import io.github.dsheirer.protocol.Protocol;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -39,12 +41,12 @@ import java.util.Map;
public class RadioFormatter
{
private final static Logger mLog = LoggerFactory.getLogger(RadioFormatter.class);
private static Map<Protocol,IntegerFormatter> mFormatterMap = new EnumMap<>(Protocol.class);
private static Map<Protocol,AbstractIntegerFormatter> mFormatterMap = new EnumMap<>(Protocol.class);
static
{
mFormatterMap.put(Protocol.APCO25, new APCO25TalkgroupFormatter());
mFormatterMap.put(Protocol.UNKNOWN, new IntegerFormatter());
mFormatterMap.put(Protocol.UNKNOWN, new UnknownTalkgroupFormatter());
}
public RadioFormatter()
@@ -56,7 +58,7 @@ public class RadioFormatter
*/
public static int parse(Protocol protocol, String value) throws ParseException
{
IntegerFormatter formatter = mFormatterMap.get(protocol);
AbstractIntegerFormatter formatter = mFormatterMap.get(protocol);
if(formatter == null)
{
@@ -71,7 +73,7 @@ public class RadioFormatter
*/
public static String format(Protocol protocol, int value)
{
IntegerFormatter formatter = mFormatterMap.get(protocol);
AbstractIntegerFormatter formatter = mFormatterMap.get(protocol);
if(formatter == null)
{
@@ -80,4 +82,19 @@ public class RadioFormatter
return formatter.format(value);
}
/**
* Formats the integer value to the specified integer format using the protocol specific formatter
*/
public static String format(Protocol protocol, int value, IntegerFormat format)
{
AbstractIntegerFormatter formatter = mFormatterMap.get(protocol);
if(formatter == null)
{
formatter = mFormatterMap.get(Protocol.UNKNOWN);
}
return formatter.format(value, format);
}
}

View File

@@ -30,7 +30,7 @@ import io.github.dsheirer.protocol.Protocol;
/**
* Integer radio identifier range of values with protocol.
*/
public class RadioRange extends AliasID
public class RadioRange extends AliasID implements Comparable<RadioRange>
{
private Protocol mProtocol = Protocol.UNKNOWN;
private int mMinRadio;
@@ -41,6 +41,12 @@ public class RadioRange extends AliasID
//No arg JAXB constructor
}
@Override
public boolean isAudioIdentifier()
{
return false;
}
/**
* Creates a radio range of from - to radio values (inclusive) for the specified protocol
* @param protocol for the radio range
@@ -63,6 +69,7 @@ public class RadioRange extends AliasID
public void setMinRadio(int minRadio)
{
mMinRadio = minRadio;
updateValueProperty();
}
@JacksonXmlProperty(isAttribute = true, localName = "max")
@@ -74,6 +81,7 @@ public class RadioRange extends AliasID
public void setMaxRadio(int maxRadio)
{
mMaxRadio = maxRadio;
updateValueProperty();
}
@JacksonXmlProperty(isAttribute = true, localName = "protocol")
@@ -99,7 +107,8 @@ public class RadioRange extends AliasID
return radioFormat.getMinimumValidValue() <= mMinRadio &&
mMinRadio <= radioFormat.getMaximumValidValue() &&
radioFormat.getMinimumValidValue() <= mMaxRadio &&
mMaxRadio <= radioFormat.getMaximumValidValue();
mMaxRadio <= radioFormat.getMaximumValidValue() &&
mMinRadio < mMaxRadio;
}
public String toString()
@@ -142,6 +151,13 @@ public class RadioRange extends AliasID
return getMinRadio() <= radioValue && radioValue <= getMaxRadio();
}
@Override
public boolean overlaps(AliasID other)
{
return other instanceof RadioRange && overlaps((RadioRange)other);
}
/**
* Indicates if this talkgroup range overlaps the talkgroup range argument.
* @param radioRange to check for overlap
@@ -163,4 +179,30 @@ public class RadioRange extends AliasID
{
return AliasIDType.RADIO_ID_RANGE;
}
@Override
public int compareTo(RadioRange other)
{
if(other == null)
{
return -1;
}
if(getProtocol().equals(other.getProtocol()))
{
if(getMinRadio() == other.getMinRadio())
{
return Integer.compare(getMaxRadio(), other.getMaxRadio());
}
else
{
return Integer.compare(getMinRadio(), other.getMinRadio());
}
}
else
{
return getProtocol().compareTo(other.getProtocol());
}
}
}

View File

@@ -1,273 +0,0 @@
/*
*
* * ******************************************************************************
* * Copyright (C) 2014-2019 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.alias.id.radio;
import io.github.dsheirer.alias.id.AliasID;
import io.github.dsheirer.gui.editor.DocumentListenerEditor;
import io.github.dsheirer.protocol.Protocol;
import net.miginfocom.swing.MigLayout;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JFormattedTextField;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.text.MaskFormatter;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.text.ParseException;
public class RadioRangeEditor extends DocumentListenerEditor<AliasID>
{
private final static Logger mLog = LoggerFactory.getLogger(RadioRangeEditor.class);
private static final long serialVersionUID = 1L;
private static final String VALID_CHARACTERS_FOR_ASTERISK_MASKS = "0123456789 ";
private MaskFormatter mMaskFormatter = new MaskFormatter();
private JComboBox<Protocol> mComboProtocol;
private JFormattedTextField mMinRadioField;
private JFormattedTextField mMaxRadioField;
public RadioRangeEditor(AliasID aliasID)
{
initGUI();
setItem(aliasID);
}
private void initGUI()
{
setLayout(new MigLayout("fill,wrap 2", "[right][left]", "[][]"));
add(new JLabel("Protocol:"));
mComboProtocol = new JComboBox<Protocol>();
DefaultComboBoxModel<Protocol> model = new DefaultComboBoxModel<>();
for(Protocol protocol : Protocol.RADIO_ID_PROTOCOLS)
{
model.addElement(protocol);
}
mComboProtocol.setModel(model);
mComboProtocol.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
Protocol protocol = (Protocol)mComboProtocol.getSelectedItem();
updateEditor(protocol);
setModified(true);
}
});
add(mComboProtocol);
add(new JLabel("Min:"));
mMinRadioField = new JFormattedTextField(mMaskFormatter);
mMinRadioField.getDocument().addDocumentListener(this);
add(mMinRadioField, "growx,push");
add(new JLabel("Max:"));
mMaxRadioField = new JFormattedTextField(mMaskFormatter);
mMaxRadioField.getDocument().addDocumentListener(this);
add(mMaxRadioField, "growx,push");
JLabel help = new JLabel("Help ...");
help.setForeground(Color.BLUE.brighter());
help.setCursor(new Cursor(Cursor.HAND_CURSOR));
help.addMouseListener(new MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent e)
{
RadioFormat radioFormat = RadioFormat.get(getCurrentProtocol());
JOptionPane.showMessageDialog(RadioRangeEditor.this,
radioFormat.getValidRangeHelpText(), "Help", JOptionPane.INFORMATION_MESSAGE);
}
});
add(help, "align left");
}
private void updateEditor(Protocol protocol)
{
RadioFormat mask = RadioFormat.get(protocol);
int currentMinValue = 0;
int currentMaxValue = 0;
RadioRange radioRange = getRadioRange();
if(radioRange != null)
{
currentMinValue = radioRange.getMinRadio();
currentMaxValue = radioRange.getMaxRadio();
}
try
{
mMinRadioField.setValue(null);
mMaxRadioField.setValue(null);
mMinRadioField.setToolTipText(mask.getValidRangeHelpText());
mMaxRadioField.setToolTipText(mask.getValidRangeHelpText());
mMaskFormatter.setMask(mask.getMask());
if(mask.getMask().contains("*"))
{
mMaskFormatter.setValidCharacters(VALID_CHARACTERS_FOR_ASTERISK_MASKS);
}
mMinRadioField.setValue(RadioFormatter.format(protocol, currentMinValue));
mMaxRadioField.setValue(RadioFormatter.format(protocol, currentMaxValue));
}
catch(ParseException pe)
{
mLog.error("Error applying radio editor mask to mask formatter [" + mask.getMask() + "]");
}
}
private Protocol getCurrentProtocol()
{
return mComboProtocol.getItemAt(mComboProtocol.getSelectedIndex());
}
public RadioRange getRadioRange()
{
if(getItem() instanceof RadioRange)
{
return (RadioRange)getItem();
}
return null;
}
@Override
public void setItem(AliasID aliasID)
{
super.setItem(aliasID);
RadioRange radioRange = getRadioRange();
updateEditor(radioRange.getProtocol());
if(radioRange != null)
{
mComboProtocol.getModel().setSelectedItem(radioRange.getProtocol());
String minFormatted = RadioFormatter.format(radioRange.getProtocol(), radioRange.getMinRadio());
mMinRadioField.setValue(minFormatted);
String maxFormatted = RadioFormatter.format(radioRange.getProtocol(), radioRange.getMaxRadio());
mMaxRadioField.setValue(maxFormatted);
}
else
{
mComboProtocol.getModel().setSelectedItem(Protocol.UNKNOWN);
mMinRadioField.setValue(RadioFormatter.format(getCurrentProtocol(), 0));
mMaxRadioField.setValue(RadioFormatter.format(getCurrentProtocol(), 0));
}
setModified(false);
repaint();
}
@Override
public void save()
{
RadioRange radioRange = getRadioRange();
if(radioRange != null)
{
Protocol protocol = mComboProtocol.getItemAt(mComboProtocol.getSelectedIndex());
if(protocol == null)
{
protocol = Protocol.UNKNOWN;
}
radioRange.setProtocol(protocol);
int minValue = -1;
int maxValue = -1;
try
{
minValue = RadioFormatter.parse(protocol, mMinRadioField.getText());
}
catch(ParseException pe)
{
//ignore ... value is still -1 and outside valid value range
}
try
{
maxValue = RadioFormatter.parse(protocol, mMaxRadioField.getText());
}
catch(ParseException pe)
{
//ignore ... value is still -1 and outside valid value range
}
RadioFormat mask = RadioFormat.get(protocol);
//Check for valid value within range ... notify user but allow value to persist
if(minValue < mask.getMinimumValidValue() || minValue > mask.getMaximumValidValue())
{
String message = "Invalid minimum value [" + mMinRadioField.getText() + "]. " + protocol.name() +
" valid range is [" + mask.getValidRangeDescription() + "]";
JOptionPane.showMessageDialog(RadioRangeEditor.this, message,
"Invalid Radio Value", JOptionPane.ERROR_MESSAGE);
}
else
{
radioRange.setMinRadio(minValue);
}
//Check for valid value within range ... notify user but allow value to persist
if(maxValue < mask.getMinimumValidValue() || maxValue > mask.getMaximumValidValue())
{
String message = "Invalid maximum value [" + mMaxRadioField.getText() + "]. " + protocol.name() +
" valid range is [" + mask.getValidRangeDescription() + "]";
JOptionPane.showMessageDialog(RadioRangeEditor.this, message,
"Invalid Radio Value", JOptionPane.ERROR_MESSAGE);
}
else
{
radioRange.setMaxRadio(maxValue);
}
radioRange.setProtocol(protocol);
}
setModified(false);
}
}

View File

@@ -36,6 +36,12 @@ public class Record extends AliasID
return AliasIDType.RECORD;
}
@Override
public boolean isAudioIdentifier()
{
return true;
}
@Override
public boolean isValid()
{

View File

@@ -1,73 +0,0 @@
/*
* ******************************************************************************
* 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.alias.id.record;
import io.github.dsheirer.alias.id.AliasID;
import io.github.dsheirer.gui.editor.DocumentListenerEditor;
import net.miginfocom.swing.MigLayout;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class RecordEditor extends DocumentListenerEditor<AliasID>
{
private static final long serialVersionUID = 1L;
private static final String HELP_TEXT = "<html>"
+ "<h3>Record Audio</h3>"
+ "Any audio associated with this alias will be recorded.<br><br>";
public RecordEditor(AliasID aliasID )
{
initGUI();
setItem( aliasID );
}
private void initGUI()
{
setLayout( new MigLayout( "fill,wrap 1", "[]", "[][]" ) );
add( new JLabel( "Record Audio" ), "wrap" );
JLabel help = new JLabel( "Help ..." );
help.setForeground( Color.BLUE.brighter() );
help.setCursor( new Cursor( Cursor.HAND_CURSOR ) );
help.addMouseListener( new MouseAdapter()
{
@Override
public void mouseClicked( MouseEvent e )
{
JOptionPane.showMessageDialog( RecordEditor.this,
HELP_TEXT, "Help", JOptionPane.INFORMATION_MESSAGE );
}
} );
add( help, "align left" );
}
@Override
public void save()
{
}
}

View File

@@ -1,75 +0,0 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014 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.alias.id.status;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import io.github.dsheirer.alias.id.AliasID;
import io.github.dsheirer.alias.id.AliasIDType;
public class StatusID extends AliasID
{
private int mStatus;
public StatusID()
{
}
@JacksonXmlProperty(isAttribute = true, localName = "status")
public int getStatus()
{
return mStatus;
}
public void setStatus(int status)
{
this.mStatus = status;
}
@Override
public boolean isValid()
{
return true;
}
public String toString()
{
return "Status: " + String.format("%03d", mStatus);
}
@Override
public boolean matches(AliasID id)
{
boolean retVal = false;
if(id instanceof StatusID)
{
StatusID statusId = (StatusID)id;
retVal = (mStatus == statusId.getStatus());
}
return retVal;
}
@JacksonXmlProperty(isAttribute = true, localName = "type", namespace = "http://www.w3.org/2001/XMLSchema-instance")
@Override
public AliasIDType getType()
{
return AliasIDType.STATUS;
}
}

View File

@@ -1,140 +0,0 @@
/*******************************************************************************
* SDR Trunk
* Copyright (C) 2014-2016 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.alias.id.status;
import io.github.dsheirer.alias.id.AliasID;
import io.github.dsheirer.gui.editor.DocumentListenerEditor;
import net.miginfocom.swing.MigLayout;
import javax.swing.*;
import javax.swing.text.MaskFormatter;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class StatusIDEditor extends DocumentListenerEditor<AliasID>
{
private static final long serialVersionUID = 1L;
private static final String HELP_TEXT = "<html>"
+ "<h3>Status Identifier</h3>"
+ "Status numbers are used in some protocols like Fleetsync.<br><br>"
+ "The status number is assigned a meaning in the radio. You<br>"
+ "can assign a 3 digit status code (use leading zeros) to an<br>"
+ "alias where the alias contains the status meaning.<br><br>"
+ "<b>Status:</b> <u>001</u> engine start"
+ "</html>";
private JTextField mTextField;
public StatusIDEditor( AliasID aliasID )
{
initGUI();
setItem( aliasID );
}
private void initGUI()
{
setLayout( new MigLayout( "fill,wrap 2", "[right][left]", "[][]" ) );
add( new JLabel( "Status:" ) );
MaskFormatter formatter = null;
try
{
//Mask: 3 digits
formatter = new MaskFormatter( "###" );
}
catch( Exception e )
{
//Do nothing, the mask was invalid
}
mTextField = new JFormattedTextField( formatter );
mTextField.getDocument().addDocumentListener( this );
mTextField.setToolTipText( HELP_TEXT );
add( mTextField, "growx,push" );
JLabel help = new JLabel( "Help ..." );
help.setForeground( Color.BLUE.brighter() );
help.setCursor( new Cursor( Cursor.HAND_CURSOR ) );
help.addMouseListener( new MouseAdapter()
{
@Override
public void mouseClicked( MouseEvent e )
{
JOptionPane.showMessageDialog( StatusIDEditor.this,
HELP_TEXT, "Help", JOptionPane.INFORMATION_MESSAGE );
}
} );
add( help, "align left" );
}
public StatusID getStatusID()
{
if( getItem() instanceof StatusID )
{
return (StatusID)getItem();
}
return null;
}
@Override
public void setItem( AliasID aliasID )
{
super.setItem( aliasID );
StatusID statusID = getStatusID();
if( statusID != null )
{
mTextField.setText( String.format( "%03d", statusID.getStatus() ) );
}
setModified( false );
repaint();
}
@Override
public void save()
{
StatusID statusID = getStatusID();
if( statusID != null )
{
int status = 0;
try
{
status = Integer.valueOf( mTextField.getText() );
}
catch( Exception e )
{
//Do nothing, we couldn't parse the value
}
statusID.setStatus( status );
}
setModified( false );
}
}

View File

@@ -0,0 +1,88 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2020 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.alias.id.status;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import io.github.dsheirer.alias.id.AliasID;
import io.github.dsheirer.alias.id.AliasIDType;
/**
* Unit Status
*/
public class UnitStatusID extends AliasID
{
private int mStatus;
public UnitStatusID()
{
}
@Override
public boolean isAudioIdentifier()
{
return false;
}
@JacksonXmlProperty(isAttribute = true, localName = "status")
public int getStatus()
{
return mStatus;
}
public void setStatus(int status)
{
mStatus = status;
updateValueProperty();
}
@Override
public boolean isValid()
{
return true;
}
public String toString()
{
StringBuilder sb = new StringBuilder();
sb.append("Unit Status: ").append(String.format("%03d", mStatus));
return sb.toString();
}
@Override
public boolean matches(AliasID id)
{
boolean retVal = false;
if(id instanceof UnitStatusID)
{
UnitStatusID userStatusId = (UnitStatusID)id;
retVal = (mStatus == userStatusId.getStatus());
}
return retVal;
}
@JacksonXmlProperty(isAttribute = true, localName = "type", namespace = "http://www.w3.org/2001/XMLSchema-instance")
@Override
public AliasIDType getType()
{
return AliasIDType.UNIT_STATUS;
}
}

View File

@@ -0,0 +1,88 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2020 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.alias.id.status;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import io.github.dsheirer.alias.id.AliasID;
import io.github.dsheirer.alias.id.AliasIDType;
/**
* User Status
*/
public class UserStatusID extends AliasID
{
private int mStatus;
public UserStatusID()
{
}
@Override
public boolean isAudioIdentifier()
{
return false;
}
@JacksonXmlProperty(isAttribute = true, localName = "status")
public int getStatus()
{
return mStatus;
}
public void setStatus(int status)
{
mStatus = status;
updateValueProperty();
}
@Override
public boolean isValid()
{
return true;
}
public String toString()
{
StringBuilder sb = new StringBuilder();
sb.append("User Status: ").append(String.format("%03d", mStatus));
return sb.toString();
}
@Override
public boolean matches(AliasID id)
{
boolean retVal = false;
if(id instanceof UserStatusID)
{
UserStatusID userStatusId = (UserStatusID)id;
retVal = (mStatus == userStatusId.getStatus());
}
return retVal;
}
@JacksonXmlProperty(isAttribute = true, localName = "type", namespace = "http://www.w3.org/2001/XMLSchema-instance")
@Override
public AliasIDType getType()
{
return AliasIDType.STATUS;
}
}

View File

@@ -24,12 +24,15 @@ import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import io.github.dsheirer.alias.id.AliasID;
import io.github.dsheirer.alias.id.AliasIDType;
import io.github.dsheirer.protocol.Protocol;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* Integer talkgroup identifier with protocol.
*/
public class Talkgroup extends AliasID
public class Talkgroup extends AliasID implements Comparable<Talkgroup>
{
private static final Logger mLog = LoggerFactory.getLogger(Talkgroup.class);
private Protocol mProtocol = Protocol.UNKNOWN;
private int mValue;
@@ -44,6 +47,12 @@ public class Talkgroup extends AliasID
mValue = value;
}
@Override
public boolean isAudioIdentifier()
{
return false;
}
@JacksonXmlProperty(isAttribute = true, localName = "value")
public int getValue()
{
@@ -53,6 +62,7 @@ public class Talkgroup extends AliasID
public void setValue(int value)
{
mValue = value;
updateValueProperty();
}
@JacksonXmlProperty(isAttribute = true, localName = "protocol")
@@ -64,6 +74,7 @@ public class Talkgroup extends AliasID
public void setProtocol(Protocol protocol)
{
mProtocol = protocol;
updateValueProperty();
}
@Override
@@ -82,7 +93,18 @@ public class Talkgroup extends AliasID
{
StringBuilder sb = new StringBuilder();
sb.append("Talkgroup:").append(TalkgroupFormatter.format(mProtocol, mValue));
String talkgroup = null;
try
{
talkgroup = TalkgroupFormatter.format(mProtocol, mValue);
}
catch(Exception e)
{
mLog.error("Error formatting Talkgroup Protocol [" + mProtocol + "] value [" + mValue + "]", e);
}
sb.append("Talkgroup:").append(talkgroup != null ? talkgroup : "error");
sb.append(" Protocol:").append((mProtocol));
if(!isValid())
@@ -111,4 +133,22 @@ public class Talkgroup extends AliasID
{
return AliasIDType.TALKGROUP;
}
@Override
public int compareTo(Talkgroup other)
{
if(other == null)
{
return -1;
}
if(getProtocol().equals(other.getProtocol()))
{
return Integer.compare(getValue(), other.getValue());
}
else
{
return getProtocol().compareTo(other.getProtocol());
}
}
}

View File

@@ -1,233 +0,0 @@
/*
* ******************************************************************************
* sdrtrunk
* Copyright (C) 2014-2019 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.alias.id.talkgroup;
import io.github.dsheirer.alias.id.AliasID;
import io.github.dsheirer.gui.editor.DocumentListenerEditor;
import io.github.dsheirer.protocol.Protocol;
import net.miginfocom.swing.MigLayout;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JFormattedTextField;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.text.MaskFormatter;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.text.ParseException;
public class TalkgroupEditor extends DocumentListenerEditor<AliasID>
{
private final static Logger mLog = LoggerFactory.getLogger(TalkgroupEditor.class);
private static final long serialVersionUID = 1L;
private static final String VALID_CHARACTERS_FOR_ASTERISK_MASKS = "0123456789 ";
private MaskFormatter mMaskFormatter = new MaskFormatter();
private JComboBox<Protocol> mComboProtocol;
private JFormattedTextField mTalkgroupField;
public TalkgroupEditor(AliasID aliasID)
{
initGUI();
setItem(aliasID);
}
private void initGUI()
{
setLayout(new MigLayout("fill,wrap 2", "[right][left]", "[][]"));
add(new JLabel("Protocol:"));
mComboProtocol = new JComboBox<>();
DefaultComboBoxModel<Protocol> model = new DefaultComboBoxModel<>();
for(Protocol protocol : Protocol.TALKGROUP_PROTOCOLS)
{
model.addElement(protocol);
}
mComboProtocol.setModel(model);
mComboProtocol.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
Protocol protocol = (Protocol)mComboProtocol.getSelectedItem();
updateEditor(protocol);
setModified(true);
}
});
add(mComboProtocol);
add(new JLabel("Value:"));
mTalkgroupField = new JFormattedTextField(mMaskFormatter);
mTalkgroupField.getDocument().addDocumentListener(this);
add(mTalkgroupField, "growx,push");
JLabel help = new JLabel("Help ...");
help.setForeground(Color.BLUE.brighter());
help.setCursor(new Cursor(Cursor.HAND_CURSOR));
help.addMouseListener(new MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent e)
{
TalkgroupFormat talkgroupFormat = TalkgroupFormat.get(getCurrentProtocol());
JOptionPane.showMessageDialog(TalkgroupEditor.this,
talkgroupFormat.getValidRangeHelpText(), "Help", JOptionPane.INFORMATION_MESSAGE);
}
});
add(help, "align left");
}
private void updateEditor(Protocol protocol)
{
TalkgroupFormat mask = TalkgroupFormat.get(protocol);
int currentValue = 0;
Talkgroup talkgroup = getTalkgroup();
if(talkgroup != null)
{
currentValue = talkgroup.getValue();
}
try
{
mTalkgroupField.setValue(null);
mTalkgroupField.setToolTipText(mask.getValidRangeHelpText());
mMaskFormatter.setMask(mask.getMask());
if(mask.getMask().contains("*"))
{
mMaskFormatter.setValidCharacters(VALID_CHARACTERS_FOR_ASTERISK_MASKS);
}
mTalkgroupField.setValue(TalkgroupFormatter.format(protocol, currentValue));
}
catch(ParseException pe)
{
mLog.error("Error applying talkgroup editor mask to mask formatter [" + mask.getMask() + "]");
}
}
private Protocol getCurrentProtocol()
{
return mComboProtocol.getItemAt(mComboProtocol.getSelectedIndex());
}
/**
* Current talkgroup alias id
*/
public Talkgroup getTalkgroup()
{
if(getItem() instanceof Talkgroup)
{
return (Talkgroup)getItem();
}
return null;
}
@Override
public void setItem(AliasID aliasID)
{
super.setItem(aliasID);
Talkgroup talkgroup = getTalkgroup();
if(talkgroup != null)
{
Protocol currentProtocol = getCurrentProtocol();
if(currentProtocol == talkgroup.getProtocol())
{
updateEditor(talkgroup.getProtocol());
}
mComboProtocol.getModel().setSelectedItem(talkgroup.getProtocol());
String formatted = TalkgroupFormatter.format(talkgroup.getProtocol(), talkgroup.getValue());
mTalkgroupField.setValue(formatted);
}
else
{
mComboProtocol.getModel().setSelectedItem(Protocol.UNKNOWN);
mTalkgroupField.setValue(TalkgroupFormatter.format(getCurrentProtocol(), 0));
}
setModified(false);
repaint();
}
@Override
public void save()
{
Talkgroup talkgroup = getTalkgroup();
if(talkgroup != null)
{
Protocol protocol = mComboProtocol.getItemAt(mComboProtocol.getSelectedIndex());
if(protocol == null)
{
protocol = Protocol.UNKNOWN;
}
int value = -1;
try
{
value = TalkgroupFormatter.parse(protocol, mTalkgroupField.getText());
}
catch(ParseException pe)
{
//ignore ... value is still -1 and outside valid value range
}
TalkgroupFormat mask = TalkgroupFormat.get(protocol);
//Check for valid value within range ... notify user but allow value to persist
if(value < mask.getMinimumValidValue() || value > mask.getMaximumValidValue())
{
String message = "Invalid value [" + mTalkgroupField.getText() + "]. " + protocol.name() +
" valid range is [" + mask.getValidRangeDescription() + "]";
JOptionPane.showMessageDialog(TalkgroupEditor.this, message, "Invalid Talkgroup Value",
JOptionPane.ERROR_MESSAGE);
}
else
{
talkgroup.setValue(value);
}
talkgroup.setProtocol(protocol);
}
setModified(false);
}
}

View File

@@ -36,9 +36,9 @@ public enum TalkgroupFormat
{
APCO25("********", 0, 0xFFFFFF, "0 to 65,535",
"<html>APCO25 talkgroup valid range is 0 to 65,535"),
FLEETSYNC("###-####", 1, 0x7FFFFF, "001-0001 to 127-8192",
FLEETSYNC("###-####", 0, 0x7FFFFF, "001-0001 to 127-8192",
"<html>Fleetsync valid ranges are 1-127(prefix)<br>and 1-8192(ident) (ie. 001-0001 to 127-8192)"),
LTR("##-###", 257, 5375, "01-001 to 20-255",
LTR("##-###", 0x101, 0x3FFF, "01-001 to 20-255",
"<html>LTR valid ranges are 1-20(repeater) and 1-255(talkgroup) (ie. 01-001 to 20-255)"),
MDC1200("*****", 1, 0xFFFF, "1 to 65,535",
"MDC-1200 valid value range is 1-65,535"),
@@ -124,7 +124,6 @@ public enum TalkgroupFormat
return FLEETSYNC;
case LTR:
case LTR_NET:
case LTR_STANDARD:
return LTR;
case MDC1200:
return MDC1200;

View File

@@ -20,13 +20,15 @@
package io.github.dsheirer.alias.id.talkgroup;
import io.github.dsheirer.preference.identifier.IntegerFormat;
import io.github.dsheirer.preference.identifier.talkgroup.APCO25TalkgroupFormatter;
import io.github.dsheirer.preference.identifier.talkgroup.AbstractIntegerFormatter;
import io.github.dsheirer.preference.identifier.talkgroup.FleetsyncTalkgroupFormatter;
import io.github.dsheirer.preference.identifier.talkgroup.IntegerFormatter;
import io.github.dsheirer.preference.identifier.talkgroup.LTRTalkgroupFormatter;
import io.github.dsheirer.preference.identifier.talkgroup.MDC1200TalkgroupFormatter;
import io.github.dsheirer.preference.identifier.talkgroup.MPT1327TalkgroupFormatter;
import io.github.dsheirer.preference.identifier.talkgroup.PassportTalkgroupFormatter;
import io.github.dsheirer.preference.identifier.talkgroup.UnknownTalkgroupFormatter;
import io.github.dsheirer.protocol.Protocol;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -42,7 +44,7 @@ import java.util.Map;
public class TalkgroupFormatter
{
private final static Logger mLog = LoggerFactory.getLogger(TalkgroupFormatter.class);
private static Map<Protocol,IntegerFormatter> mFormatterMap = new EnumMap<>(Protocol.class);
private static Map<Protocol,AbstractIntegerFormatter> mFormatterMap = new EnumMap<>(Protocol.class);
static
{
@@ -51,11 +53,10 @@ public class TalkgroupFormatter
LTRTalkgroupFormatter ltr = new LTRTalkgroupFormatter();
mFormatterMap.put(Protocol.LTR, ltr);
mFormatterMap.put(Protocol.LTR_NET, ltr);
mFormatterMap.put(Protocol.LTR_STANDARD, ltr);
mFormatterMap.put(Protocol.MDC1200, new MDC1200TalkgroupFormatter());
mFormatterMap.put(Protocol.MPT1327, new MPT1327TalkgroupFormatter());
mFormatterMap.put(Protocol.PASSPORT, new PassportTalkgroupFormatter());
mFormatterMap.put(Protocol.UNKNOWN, new IntegerFormatter());
mFormatterMap.put(Protocol.UNKNOWN, new UnknownTalkgroupFormatter());
}
public TalkgroupFormatter()
@@ -67,7 +68,7 @@ public class TalkgroupFormatter
*/
public static int parse(Protocol protocol, String value) throws ParseException
{
IntegerFormatter formatter = mFormatterMap.get(protocol);
AbstractIntegerFormatter formatter = mFormatterMap.get(protocol);
if(formatter == null)
{
@@ -82,7 +83,7 @@ public class TalkgroupFormatter
*/
public static String format(Protocol protocol, int value)
{
IntegerFormatter formatter = mFormatterMap.get(protocol);
AbstractIntegerFormatter formatter = mFormatterMap.get(protocol);
if(formatter == null)
{
@@ -91,4 +92,19 @@ public class TalkgroupFormatter
return formatter.format(value);
}
/**
* Formats the integer value to the specified integer format using the protocol specific formatter
*/
public static String format(Protocol protocol, int value, IntegerFormat format)
{
AbstractIntegerFormatter formatter = mFormatterMap.get(protocol);
if(formatter == null)
{
formatter = mFormatterMap.get(Protocol.UNKNOWN);
}
return formatter.format(value, format);
}
}

View File

@@ -28,7 +28,7 @@ import io.github.dsheirer.protocol.Protocol;
/**
* Integer talkgroup identifier range of values with protocol.
*/
public class TalkgroupRange extends AliasID
public class TalkgroupRange extends AliasID implements Comparable<TalkgroupRange>
{
private Protocol mProtocol = Protocol.UNKNOWN;
private int mMinTalkgroup;
@@ -52,6 +52,12 @@ public class TalkgroupRange extends AliasID
mMaxTalkgroup = maxTalkgroup;
}
@Override
public boolean isAudioIdentifier()
{
return false;
}
@JacksonXmlProperty(isAttribute = true, localName = "min")
public int getMinTalkgroup()
{
@@ -61,6 +67,7 @@ public class TalkgroupRange extends AliasID
public void setMinTalkgroup(int minTalkgroup)
{
mMinTalkgroup = minTalkgroup;
updateValueProperty();
}
@JacksonXmlProperty(isAttribute = true, localName = "max")
@@ -72,6 +79,7 @@ public class TalkgroupRange extends AliasID
public void setMaxTalkgroup(int maxTalkgroup)
{
mMaxTalkgroup = maxTalkgroup;
updateValueProperty();
}
@JacksonXmlProperty(isAttribute = true, localName = "protocol")
@@ -83,6 +91,7 @@ public class TalkgroupRange extends AliasID
public void setProtocol(Protocol protocol)
{
mProtocol = protocol;
updateValueProperty();
}
@Override
@@ -97,7 +106,8 @@ public class TalkgroupRange extends AliasID
return talkgroupFormat.getMinimumValidValue() <= mMinTalkgroup &&
mMinTalkgroup <= talkgroupFormat.getMaximumValidValue() &&
talkgroupFormat.getMinimumValidValue() <= mMaxTalkgroup &&
mMaxTalkgroup <= talkgroupFormat.getMaximumValidValue();
mMaxTalkgroup <= talkgroupFormat.getMaximumValidValue() &&
mMinTalkgroup < mMaxTalkgroup;
}
public String toString()
@@ -140,6 +150,12 @@ public class TalkgroupRange extends AliasID
return getMinTalkgroup() <= talkgroupValue && talkgroupValue <= getMaxTalkgroup();
}
@Override
public boolean overlaps(AliasID other)
{
return other instanceof TalkgroupRange && overlaps((TalkgroupRange)other);
}
/**
* Indicates if this talkgroup range overlaps the talkgroup range argument.
* @param talkgroupRange to check for overlap
@@ -161,4 +177,29 @@ public class TalkgroupRange extends AliasID
{
return AliasIDType.TALKGROUP_RANGE;
}
@Override
public int compareTo(TalkgroupRange other)
{
if(other == null)
{
return -1;
}
if(getProtocol().equals(other.getProtocol()))
{
if(getMinTalkgroup() == other.getMinTalkgroup())
{
return Integer.compare(getMaxTalkgroup(), other.getMaxTalkgroup());
}
else
{
return Integer.compare(getMinTalkgroup(), other.getMinTalkgroup());
}
}
else
{
return getProtocol().compareTo(other.getProtocol());
}
}
}

View File

@@ -1,271 +0,0 @@
/*
* ******************************************************************************
* 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.alias.id.talkgroup;
import io.github.dsheirer.alias.id.AliasID;
import io.github.dsheirer.gui.editor.DocumentListenerEditor;
import io.github.dsheirer.protocol.Protocol;
import net.miginfocom.swing.MigLayout;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JFormattedTextField;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.text.MaskFormatter;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.text.ParseException;
public class TalkgroupRangeEditor extends DocumentListenerEditor<AliasID>
{
private final static Logger mLog = LoggerFactory.getLogger(TalkgroupRangeEditor.class);
private static final long serialVersionUID = 1L;
private static final String VALID_CHARACTERS_FOR_ASTERISK_MASKS = "0123456789 ";
private MaskFormatter mMaskFormatter = new MaskFormatter();
private JComboBox<Protocol> mComboProtocol;
private JFormattedTextField mMinTalkgroupField;
private JFormattedTextField mMaxTalkgroupField;
public TalkgroupRangeEditor(AliasID aliasID)
{
initGUI();
setItem(aliasID);
}
private void initGUI()
{
setLayout(new MigLayout("fill,wrap 2", "[right][left]", "[][]"));
add(new JLabel("Protocol:"));
mComboProtocol = new JComboBox<Protocol>();
DefaultComboBoxModel<Protocol> model = new DefaultComboBoxModel<>();
for(Protocol protocol : Protocol.TALKGROUP_PROTOCOLS)
{
model.addElement(protocol);
}
mComboProtocol.setModel(model);
mComboProtocol.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
Protocol protocol = (Protocol)mComboProtocol.getSelectedItem();
updateEditor(protocol);
setModified(true);
}
});
add(mComboProtocol);
add(new JLabel("Min:"));
mMinTalkgroupField = new JFormattedTextField(mMaskFormatter);
mMinTalkgroupField.getDocument().addDocumentListener(this);
add(mMinTalkgroupField, "growx,push");
add(new JLabel("Max:"));
mMaxTalkgroupField = new JFormattedTextField(mMaskFormatter);
mMaxTalkgroupField.getDocument().addDocumentListener(this);
add(mMaxTalkgroupField, "growx,push");
JLabel help = new JLabel("Help ...");
help.setForeground(Color.BLUE.brighter());
help.setCursor(new Cursor(Cursor.HAND_CURSOR));
help.addMouseListener(new MouseAdapter()
{
@Override
public void mouseClicked(MouseEvent e)
{
TalkgroupFormat talkgroupFormat = TalkgroupFormat.get(getCurrentProtocol());
JOptionPane.showMessageDialog(TalkgroupRangeEditor.this,
talkgroupFormat.getValidRangeHelpText(), "Help", JOptionPane.INFORMATION_MESSAGE);
}
});
add(help, "align left");
}
private void updateEditor(Protocol protocol)
{
TalkgroupFormat mask = TalkgroupFormat.get(protocol);
int currentMinValue = 0;
int currentMaxValue = 0;
TalkgroupRange talkgroupRange = getTalkgroupRange();
if(talkgroupRange != null)
{
currentMinValue = talkgroupRange.getMinTalkgroup();
currentMaxValue = talkgroupRange.getMaxTalkgroup();
}
try
{
mMinTalkgroupField.setValue(null);
mMaxTalkgroupField.setValue(null);
mMinTalkgroupField.setToolTipText(mask.getValidRangeHelpText());
mMaxTalkgroupField.setToolTipText(mask.getValidRangeHelpText());
mMaskFormatter.setMask(mask.getMask());
if(mask.getMask().contains("*"))
{
mMaskFormatter.setValidCharacters(VALID_CHARACTERS_FOR_ASTERISK_MASKS);
}
mMinTalkgroupField.setValue(TalkgroupFormatter.format(protocol, currentMinValue));
mMaxTalkgroupField.setValue(TalkgroupFormatter.format(protocol, currentMaxValue));
}
catch(ParseException pe)
{
mLog.error("Error applying talkgroup editor mask to mask formatter [" + mask.getMask() + "]");
}
}
private Protocol getCurrentProtocol()
{
return mComboProtocol.getItemAt(mComboProtocol.getSelectedIndex());
}
public TalkgroupRange getTalkgroupRange()
{
if(getItem() instanceof TalkgroupRange)
{
return (TalkgroupRange)getItem();
}
return null;
}
@Override
public void setItem(AliasID aliasID)
{
super.setItem(aliasID);
TalkgroupRange talkgroupRange = getTalkgroupRange();
updateEditor(talkgroupRange.getProtocol());
if(talkgroupRange != null)
{
mComboProtocol.getModel().setSelectedItem(talkgroupRange.getProtocol());
String minFormatted = TalkgroupFormatter.format(talkgroupRange.getProtocol(), talkgroupRange.getMinTalkgroup());
mMinTalkgroupField.setValue(minFormatted);
String maxFormatted = TalkgroupFormatter.format(talkgroupRange.getProtocol(), talkgroupRange.getMaxTalkgroup());
mMaxTalkgroupField.setValue(maxFormatted);
}
else
{
mComboProtocol.getModel().setSelectedItem(Protocol.UNKNOWN);
mMinTalkgroupField.setValue(TalkgroupFormatter.format(getCurrentProtocol(), 0));
mMaxTalkgroupField.setValue(TalkgroupFormatter.format(getCurrentProtocol(), 0));
}
setModified(false);
repaint();
}
@Override
public void save()
{
TalkgroupRange talkgroupRange = getTalkgroupRange();
if(talkgroupRange != null)
{
Protocol protocol = mComboProtocol.getItemAt(mComboProtocol.getSelectedIndex());
if(protocol == null)
{
protocol = Protocol.UNKNOWN;
}
talkgroupRange.setProtocol(protocol);
int minValue = -1;
int maxValue = -1;
try
{
minValue = TalkgroupFormatter.parse(protocol, mMinTalkgroupField.getText());
}
catch(ParseException pe)
{
//ignore ... value is still -1 and outside valid value range
}
try
{
maxValue = TalkgroupFormatter.parse(protocol, mMaxTalkgroupField.getText());
}
catch(ParseException pe)
{
//ignore ... value is still -1 and outside valid value range
}
TalkgroupFormat mask = TalkgroupFormat.get(protocol);
//Check for valid value within range ... notify user but allow value to persist
if(minValue < mask.getMinimumValidValue() || minValue > mask.getMaximumValidValue())
{
String message = "Invalid minimum value [" + mMinTalkgroupField.getText() + "]. " + protocol.name() +
" valid range is [" + mask.getValidRangeDescription() + "]";
JOptionPane.showMessageDialog(TalkgroupRangeEditor.this, message,
"Invalid Talkgroup Value", JOptionPane.ERROR_MESSAGE);
}
else
{
talkgroupRange.setMinTalkgroup(minValue);
}
//Check for valid value within range ... notify user but allow value to persist
if(maxValue < mask.getMinimumValidValue() || maxValue > mask.getMaximumValidValue())
{
String message = "Invalid maximum value [" + mMaxTalkgroupField.getText() + "]. " + protocol.name() +
" valid range is [" + mask.getValidRangeDescription() + "]";
JOptionPane.showMessageDialog(TalkgroupRangeEditor.this, message,
"Invalid Talkgroup Value", JOptionPane.ERROR_MESSAGE);
}
else
{
talkgroupRange.setMaxTalkgroup(maxValue);
}
talkgroupRange.setProtocol(protocol);
}
setModified(false);
}
}

View File

@@ -0,0 +1,150 @@
/*
* *****************************************************************************
* Copyright (C) 2014-2020 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.alias.id.tone;
import io.github.dsheirer.alias.id.AliasID;
import io.github.dsheirer.alias.id.AliasIDType;
import io.github.dsheirer.identifier.tone.Tone;
import io.github.dsheirer.identifier.tone.ToneSequence;
import javafx.collections.ListChangeListener;
import java.util.List;
/**
* Tone sequence alias identifier. This is used for matching tone sequences produced by the AMBE audio CODEC. Some
* examples include DTMF dialed numbers, KNOX tones, 2-Tone, Tone-outs, etc.
*/
public class TonesID extends AliasID implements ListChangeListener<Tone>
{
private ToneSequence mToneSequence;
public TonesID()
{
setToneSequence(new ToneSequence());
//Empty serialization constructor
}
/**
* Constructs an instance with the specified tone sequence
*/
public TonesID(ToneSequence toneSequence)
{
setToneSequence(toneSequence);
}
@Override
public AliasIDType getType()
{
return AliasIDType.TONES;
}
/**
* List of tones that define this identifier
*/
public ToneSequence getToneSequence()
{
return mToneSequence;
}
/**
* Sets the tone sequence(s) for this ID
*/
public void setToneSequence(ToneSequence toneSequence)
{
if(mToneSequence != null)
{
mToneSequence.tonesProperty().removeListener(this);
}
mToneSequence = toneSequence;
mToneSequence.tonesProperty().addListener(this);
}
/**
* Indicates if the other id is a tones identifier and has the exact same sequence of tones. However, it does not
* compare each of the tone duration value.
* @param id to check for match
* @return true if the identifiers match
*/
@Override
public boolean matches(AliasID id)
{
boolean match = true;
if(mToneSequence.getTones().isEmpty() || !(id instanceof TonesID))
{
match = false;
}
else
{
List<Tone> otherTones = ((TonesID)id).getToneSequence().getTones();
List<Tone> thisTones = mToneSequence.getTones();
if(thisTones.size() == otherTones.size())
{
for(int x = 0; x < thisTones.size(); x++)
{
if(thisTones.get(x).getAmbeTone() != otherTones.get(x).getAmbeTone())
{
match = false;
continue;
}
}
}
else
{
match = false;
}
}
return match;
}
@Override
public boolean isValid()
{
return getToneSequence() != null && getToneSequence().hasTones();
}
@Override
public boolean isAudioIdentifier()
{
//This is not an audio identifier in the context that this method is used for.
return false;
}
@Override
public String toString()
{
if(getToneSequence() != null)
{
return "Tones: " + getToneSequence().toString();
}
return "Tones: (empty)";
}
@Override
public void onChanged(Change<? extends Tone> c)
{
updateValueProperty();
}
}