#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

@@ -1,21 +1,23 @@
/*
* ******************************************************************************
* 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.
* * ******************************************************************************
* * 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.controller.channel;
@@ -39,6 +41,14 @@ import io.github.dsheirer.source.config.SourceConfigRecording;
import io.github.dsheirer.source.config.SourceConfigTuner;
import io.github.dsheirer.source.config.SourceConfiguration;
import io.github.dsheirer.source.tuner.channel.TunerChannel;
import javafx.beans.Observable;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.util.Callback;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -64,14 +74,14 @@ public class Channel extends Configuration implements Listener<SourceEvent>
private EventLogConfiguration mEventLogConfiguration = new EventLogConfiguration();
private RecordConfiguration mRecordConfiguration = new RecordConfiguration();
private String mAliasListName;
private String mSystem = "System";
private String mSite = "Site";
private String mName = "Channel";
private StringProperty mAliasListName = new SimpleStringProperty();
private StringProperty mSystem = new SimpleStringProperty();
private StringProperty mSite = new SimpleStringProperty();
private StringProperty mName = new SimpleStringProperty();
private boolean mProcessing;
private boolean mAutoStart;
private Integer mAutoStartOrder;
private BooleanProperty mProcessing = new SimpleBooleanProperty();
private BooleanProperty mAutoStart = new SimpleBooleanProperty();
private IntegerProperty mAutoStartOrder = new SimpleIntegerProperty();
private boolean mSelected;
private TunerChannel mTunerChannel = null;
@@ -100,7 +110,7 @@ public class Channel extends Configuration implements Listener<SourceEvent>
public Channel(String channelName)
{
this();
mName = channelName;
mName.set(channelName);
}
/**
@@ -111,52 +121,119 @@ public class Channel extends Configuration implements Listener<SourceEvent>
mChannelID = UNIQUE_ID++;
}
/**
* Creates a (new) deep copy of this channel
*/
public Channel copyOf()
{
Channel channel = new Channel(mName);
channel.setSystem(mSystem);
channel.setSite(mSite);
channel.setAliasListName(mAliasListName);
channel.setAutoStart(mAutoStart);
channel.setAutoStartOrder(mAutoStartOrder);
Channel channel = new Channel(mName.get());
channel.setSystem(mSystem.get());
channel.setSite(mSite.get());
channel.setAliasListName(mAliasListName.get());
channel.setAutoStart(mAutoStart.get());
channel.setAutoStartOrder(mAutoStartOrder.get());
AuxDecodeConfiguration aux = new AuxDecodeConfiguration();
AuxDecodeConfiguration auxCopy = new AuxDecodeConfiguration();
for(DecoderType auxType : aux.getAuxDecoders())
if(getAuxDecodeConfiguration() != null)
{
aux.addAuxDecoder(auxType);
for(DecoderType auxType : getAuxDecodeConfiguration().getAuxDecoders())
{
auxCopy.addAuxDecoder(auxType);
}
}
channel.setAuxDecodeConfiguration(aux);
channel.setAuxDecodeConfiguration(auxCopy);
channel.setDecodeConfiguration(DecoderFactory.copy(mDecodeConfiguration));
EventLogConfiguration log = new EventLogConfiguration();
EventLogConfiguration logCopy = new EventLogConfiguration();
for(EventLogType logType : mEventLogConfiguration.getLoggers())
if(mEventLogConfiguration != null)
{
log.addLogger(logType);
for(EventLogType logType : mEventLogConfiguration.getLoggers())
{
logCopy.addLogger(logType);
}
}
channel.setEventLogConfiguration(log);
channel.setEventLogConfiguration(logCopy);
RecordConfiguration record = new RecordConfiguration();
RecordConfiguration recordCopy = new RecordConfiguration();
for(RecorderType recordType : mRecordConfiguration.getRecorders())
if(mRecordConfiguration != null)
{
record.addRecorder(recordType);
for(RecorderType recordType : mRecordConfiguration.getRecorders())
{
recordCopy.addRecorder(recordType);
}
}
channel.setRecordConfiguration(record);
channel.setRecordConfiguration(recordCopy);
channel.setSourceConfiguration(SourceConfigFactory.copy(mSourceConfiguration));
return channel;
}
/**
* Alias list name property
*/
public StringProperty aliasListNameProperty()
{
return mAliasListName;
}
/**
* System property
*/
public StringProperty systemProperty()
{
return mSystem;
}
/**
* Site property
*/
public StringProperty siteProperty()
{
return mSite;
}
/**
* Channel name property
*/
public StringProperty nameProperty()
{
return mName;
}
/**
* Processing property. Indicates if this channel configuration is currently processing.
*/
public BooleanProperty processingProperty()
{
return mProcessing;
}
/**
* Auto-Start property. Indicates if this channel is setup for auto-start
*/
public BooleanProperty autoStartProperty()
{
return mAutoStart;
}
/**
* Auto-start order property. Indicates the order for starting channels that are flagged for auto-start.
*/
public IntegerProperty autoStartOrderProperty()
{
return mAutoStartOrder;
}
/**
* Unique identifier for this channel. Value is transient (not persisted).
*/
@@ -214,17 +291,17 @@ public class Channel extends Configuration implements Listener<SourceEvent>
@JacksonXmlProperty(isAttribute = true, localName = "system")
public String getSystem()
{
return mSystem;
return mSystem.get();
}
public void setSystem(String system)
{
mSystem = system;
mSystem.set(system);
}
public boolean hasSystem()
{
return mSystem != null;
return mSystem != null && mSystem.get() != null;
}
/**
@@ -233,17 +310,17 @@ public class Channel extends Configuration implements Listener<SourceEvent>
@JacksonXmlProperty(isAttribute = true, localName = "site")
public String getSite()
{
return mSite;
return mSite.get();
}
public void setSite(String site)
{
mSite = site;
mSite.set(site);
}
public boolean hasSite()
{
return mSite != null;
return mSite != null && mSite.get() != null;
}
/**
@@ -252,7 +329,7 @@ public class Channel extends Configuration implements Listener<SourceEvent>
@JacksonXmlProperty(isAttribute = true, localName = "name")
public String getName()
{
return mName;
return mName.get();
}
/**
@@ -260,7 +337,7 @@ public class Channel extends Configuration implements Listener<SourceEvent>
*/
public void setName(String name)
{
mName = name;
mName.set(name);
}
/**
@@ -284,7 +361,7 @@ public class Channel extends Configuration implements Listener<SourceEvent>
@JsonIgnore
public boolean isProcessing()
{
return mProcessing;
return mProcessing.get();
}
/**
@@ -296,7 +373,7 @@ public class Channel extends Configuration implements Listener<SourceEvent>
*/
void setProcessing(boolean processing)
{
mProcessing = processing;
mProcessing.set(processing);
}
/**
@@ -310,7 +387,7 @@ public class Channel extends Configuration implements Listener<SourceEvent>
@JacksonXmlProperty(isAttribute = true, localName = "enabled")
public boolean getAutoStart()
{
return mAutoStart;
return mAutoStart.get();
}
/**
@@ -319,7 +396,7 @@ public class Channel extends Configuration implements Listener<SourceEvent>
@JsonIgnore
public boolean isAutoStart()
{
return mAutoStart;
return mAutoStart.get();
}
/**
@@ -329,7 +406,7 @@ public class Channel extends Configuration implements Listener<SourceEvent>
*/
public void setAutoStart(boolean autoStart)
{
mAutoStart = autoStart;
mAutoStart.set(autoStart);
}
/**
@@ -341,7 +418,7 @@ public class Channel extends Configuration implements Listener<SourceEvent>
@JacksonXmlProperty(isAttribute = true, localName = "order")
public Integer getAutoStartOrder()
{
return mAutoStartOrder;
return mAutoStartOrder.get();
}
/**
@@ -351,7 +428,14 @@ public class Channel extends Configuration implements Listener<SourceEvent>
*/
public void setAutoStartOrder(Integer order)
{
mAutoStartOrder = order;
if(order != null)
{
mAutoStartOrder.set(order);
}
else
{
mAutoStartOrder.setValue(null);
}
}
/**
@@ -362,7 +446,7 @@ public class Channel extends Configuration implements Listener<SourceEvent>
@JsonIgnore
public boolean hasAutoStartOrder()
{
return mAutoStartOrder != null;
return mAutoStartOrder != null && mAutoStartOrder.getValue() != null;
}
/**
@@ -372,7 +456,7 @@ public class Channel extends Configuration implements Listener<SourceEvent>
@JacksonXmlProperty(isAttribute = false, localName = "alias_list_name")
public String getAliasListName()
{
return mAliasListName;
return mAliasListName.get();
}
/**
@@ -381,15 +465,7 @@ public class Channel extends Configuration implements Listener<SourceEvent>
*/
public void setAliasListName(String name)
{
mAliasListName = name;
}
/**
* Indicates if this channel has a non-null, non-empty alias list name specified.
*/
public boolean hasAliasList()
{
return mAliasListName != null && !mAliasListName.isEmpty();
mAliasListName.set(name);
}
/**
@@ -558,8 +634,6 @@ public class Channel extends Configuration implements Listener<SourceEvent>
/**
* Current channel frequency correction value (when this channel is processing)
*
* @return
*/
@JsonIgnore
public int getChannelFrequencyCorrection()
@@ -595,4 +669,13 @@ public class Channel extends Configuration implements Listener<SourceEvent>
{
return Objects.hash(getChannelID());
}
/**
* Creates an observable property extractor for use with observable lists to detect changes internal to this object.
*/
public static Callback<Channel,Observable[]> extractor()
{
return (Channel c) -> new Observable[] {c.processingProperty(), c.nameProperty(), c.aliasListNameProperty(),
c.autoStartOrderProperty(), c.autoStartProperty(), c.siteProperty(), c.systemProperty()};
}
}