mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-14 09:37:36 -05:00
Compare commits
18 Commits
v0.4.0-alp
...
v0.4.0-alp
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
139227e46d | ||
|
|
2394d51a51 | ||
|
|
d9fa2bea5b | ||
|
|
0cb360eeed | ||
|
|
ea472f873f | ||
|
|
8cbdbd527e | ||
|
|
ff0d893bd9 | ||
|
|
7b924d0486 | ||
|
|
712eb07f4b | ||
|
|
d5c3ecc7df | ||
|
|
c4bf089667 | ||
|
|
378b03e06e | ||
|
|
34235382fb | ||
|
|
c05aff0768 | ||
|
|
f0c3e0fd1a | ||
|
|
d601cbda0e | ||
|
|
2653dc6b38 | ||
|
|
48cbbfc656 |
129
build.gradle
129
build.gradle
@@ -1,37 +1,30 @@
|
|||||||
/*
|
/*
|
||||||
* ******************************************************************************
|
|
||||||
* 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
|
* * Copyright (C) 2014-2019 Dennis Sheirer
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* *
|
||||||
* (at your option) any later version.
|
* * 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/>
|
|
||||||
* *****************************************************************************
|
|
||||||
*/
|
*/
|
||||||
buildscript {
|
|
||||||
repositories {
|
|
||||||
jcenter()
|
|
||||||
mavenCentral()
|
|
||||||
}
|
|
||||||
dependencies {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id 'application'
|
id 'application'
|
||||||
id 'java'
|
id 'java'
|
||||||
id 'idea'
|
id 'idea'
|
||||||
id 'org.openjfx.javafxplugin' version '0.0.6'
|
id 'org.openjfx.javafxplugin' version '0.0.6'
|
||||||
id 'org.beryx.runtime' version '1.1.1'
|
id 'org.beryx.runtime' version '1.1.5'
|
||||||
}
|
}
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
@@ -39,7 +32,7 @@ repositories {
|
|||||||
mavenCentral()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
|
|
||||||
version = '0.4.0-alpha.7'
|
version = '0.4.0-alpha.9'
|
||||||
sourceCompatibility = '11'
|
sourceCompatibility = '11'
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
@@ -61,10 +54,9 @@ dependencies {
|
|||||||
compile 'com.google.guava:guava:27.0.1-jre'
|
compile 'com.google.guava:guava:27.0.1-jre'
|
||||||
compile 'com.jidesoft:jide-oss:3.6.18'
|
compile 'com.jidesoft:jide-oss:3.6.18'
|
||||||
compile 'com.miglayout:miglayout-swing:5.2'
|
compile 'com.miglayout:miglayout-swing:5.2'
|
||||||
|
compile 'io.github.dsheirer:radio-reference-api:15.0.1'
|
||||||
compile 'javax.usb:usb-api:1.0.2'
|
compile 'javax.usb:usb-api:1.0.2'
|
||||||
compile 'net.coderazzi:tablefilter-swing:5.4.0'
|
compile 'net.coderazzi:tablefilter-swing:5.4.0'
|
||||||
compile 'org.apache.axis:axis:1.4'
|
|
||||||
compile 'org.apache.axis:axis-jaxrpc:1.4'
|
|
||||||
compile 'org.apache.commons:commons-lang3:3.8.1'
|
compile 'org.apache.commons:commons-lang3:3.8.1'
|
||||||
compile 'org.apache.commons:commons-io:1.3.2'
|
compile 'org.apache.commons:commons-io:1.3.2'
|
||||||
compile 'org.apache.mina:mina-core:2.0.19'
|
compile 'org.apache.mina:mina-core:2.0.19'
|
||||||
@@ -103,15 +95,6 @@ javafx {
|
|||||||
modules = ['javafx.base', 'javafx.controls', 'javafx.graphics', 'javafx.swing']
|
modules = ['javafx.base', 'javafx.controls', 'javafx.graphics', 'javafx.swing']
|
||||||
}
|
}
|
||||||
|
|
||||||
runtime {
|
|
||||||
targetPlatform('linux-x64', '/media/denny/WD250GB/java/linux/jdk-11.0.1')
|
|
||||||
targetPlatform('osx-x64', '/media/denny/WD250GB/java/osx/jdk-11.0.1.jdk/Contents/Home')
|
|
||||||
targetPlatform('windows-x64', '/media/denny/WD250GB/java/windows/jdk-11.0.1')
|
|
||||||
options = ['--strip-debug', '--compress', '2', '--no-header-files', '--no-man-pages']
|
|
||||||
modules = ['java.desktop', 'java.naming', 'jdk.unsupported', 'jdk.unsupported.desktop']
|
|
||||||
imageZip = file("$buildDir/image/sdr-trunk-" + version + ".zip")
|
|
||||||
}
|
|
||||||
|
|
||||||
task buildSdr(type: Jar) {
|
task buildSdr(type: Jar) {
|
||||||
manifest {
|
manifest {
|
||||||
attributes 'Implementation-Title': 'SdrTrunk project',
|
attributes 'Implementation-Title': 'SdrTrunk project',
|
||||||
@@ -123,3 +106,77 @@ task buildSdr(type: Jar) {
|
|||||||
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
|
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
|
||||||
with jar
|
with jar
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Java Development Kit (JDK) locations. These paths must point to the 'bin' directory
|
||||||
|
* within a JDK for each of the specified architectures. These JDKs are used by the
|
||||||
|
* runtime and runtimeZip tasks to produce platform-specific builds
|
||||||
|
*/
|
||||||
|
def jdkLinux_aarch64 = '/media/denny/WD250GB/java/bellsoft/linux-aarch64/jdk-11.0.2'
|
||||||
|
def jdkLinux_x64 = '/media/denny/WD250GB/java/bellsoft/linux-x64/jdk-11.0.2'
|
||||||
|
def jdkOsx_x64 = '/media/denny/WD250GB/java/bellsoft/osx-x64/jdk-11.0.2.jdk'
|
||||||
|
def jdkWindows_x64 = '/media/denny/WD250GB/java/bellsoft/windows-x64/jdk-11.0.2'
|
||||||
|
|
||||||
|
runtime {
|
||||||
|
targetPlatform('linux-aarch64', jdkLinux_aarch64)
|
||||||
|
targetPlatform('linux-x64', jdkLinux_x64)
|
||||||
|
targetPlatform('osx-x64', jdkOsx_x64)
|
||||||
|
targetPlatform('windows-x64', jdkWindows_x64)
|
||||||
|
|
||||||
|
options = ['--strip-debug', '--compress', '2', '--no-header-files', '--no-man-pages']
|
||||||
|
modules = ['java.desktop', 'java.naming', 'jdk.unsupported', 'jdk.unsupported.desktop']
|
||||||
|
imageZip = file("$buildDir/image/sdr-trunk-" + version + ".zip")
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check for existence of JDK folders for each supported platform before creating runtime images
|
||||||
|
*/
|
||||||
|
tasks.runtime.doFirst {
|
||||||
|
def linux_aarch64 = new File(jdkLinux_aarch64)
|
||||||
|
|
||||||
|
if(!linux_aarch64.exists())
|
||||||
|
{
|
||||||
|
println("Linux aarch64 JDK was not found at " + jdkLinux_aarch64)
|
||||||
|
throw new GradleException("Cannot find Java Development Kit (JDK) for linux-aarch64 architecture. " +
|
||||||
|
"Please update the build.gradle script to provide the correct path")
|
||||||
|
}
|
||||||
|
|
||||||
|
def linux_x64 = new File(jdkLinux_x64)
|
||||||
|
|
||||||
|
if(!linux_x64.exists())
|
||||||
|
{
|
||||||
|
println("Linux x64 JDK was not found at " + jdkLinux_x64)
|
||||||
|
throw new GradleException("Cannot find Java Development Kit (JDK) for linux-x64 architecture. " +
|
||||||
|
"Please update the build.gradle script to provide the correct path")
|
||||||
|
}
|
||||||
|
|
||||||
|
def osx_x64 = new File(jdkOsx_x64)
|
||||||
|
|
||||||
|
if(!osx_x64.exists())
|
||||||
|
{
|
||||||
|
println("OSX x64 JDK was not found at " + jdkOsx_x64);
|
||||||
|
throw new GradleException("Cannot find Java Development Kit (JDK) for osx-x64 architecture. " +
|
||||||
|
"Please update the build.gradle script to provide the correct path")
|
||||||
|
}
|
||||||
|
|
||||||
|
def windows_x64 = new File(jdkWindows_x64)
|
||||||
|
|
||||||
|
if(!windows_x64.exists())
|
||||||
|
{
|
||||||
|
println("Windows x64 JDK was not found at " + jdkWindows_x64)
|
||||||
|
throw new GradleException("Cannot find Java Development Kit (JDK) for windows-x64 architecture. " +
|
||||||
|
"Please update the build.gradle script to provide the correct path")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Since we have to list each of the platform-specific JavaFX libraries as dependencies,
|
||||||
|
* remove them from each build image
|
||||||
|
*/
|
||||||
|
tasks.runtime.doLast {
|
||||||
|
delete(fileTree('build/image/sdr-trunk-linux-aarch64/lib').include { it.name ==~ /javafx.*-(win|mac)\.jar/ })
|
||||||
|
delete(fileTree('build/image/sdr-trunk-linux-x64/lib').include { it.name ==~ /javafx.*-(win|mac)\.jar/ })
|
||||||
|
delete(fileTree('build/image/sdr-trunk-osx-x64/lib').include { it.name ==~ /javafx.*-(win|linux)\.jar/ })
|
||||||
|
delete(fileTree('build/image/sdr-trunk-windows-x64/lib').include { it.name ==~ /javafx.*-(linux|mac)\.jar/ })
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -1,34 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* ******************************************************************************
|
||||||
|
* 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;
|
package io.github.dsheirer.alias;
|
||||||
|
|
||||||
import com.jidesoft.swing.JideSplitPane;
|
import com.jidesoft.swing.JideSplitPane;
|
||||||
import io.github.dsheirer.audio.broadcast.BroadcastModel;
|
import io.github.dsheirer.audio.broadcast.BroadcastModel;
|
||||||
import io.github.dsheirer.gui.editor.Editor;
|
import io.github.dsheirer.gui.editor.Editor;
|
||||||
import io.github.dsheirer.icon.IconManager;
|
import io.github.dsheirer.icon.IconManager;
|
||||||
|
import io.github.dsheirer.preference.UserPreferences;
|
||||||
|
import io.github.dsheirer.preference.swing.JTableColumnWidthMonitor;
|
||||||
import net.coderazzi.filters.gui.AutoChoices;
|
import net.coderazzi.filters.gui.AutoChoices;
|
||||||
import net.coderazzi.filters.gui.TableFilterHeader;
|
import net.coderazzi.filters.gui.TableFilterHeader;
|
||||||
import net.miginfocom.swing.MigLayout;
|
import net.miginfocom.swing.MigLayout;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.ImageIcon;
|
||||||
|
import javax.swing.JButton;
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
import javax.swing.JOptionPane;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.JScrollPane;
|
||||||
|
import javax.swing.JTable;
|
||||||
|
import javax.swing.ListSelectionModel;
|
||||||
import javax.swing.event.ListSelectionEvent;
|
import javax.swing.event.ListSelectionEvent;
|
||||||
import javax.swing.event.ListSelectionListener;
|
import javax.swing.event.ListSelectionListener;
|
||||||
import javax.swing.table.DefaultTableCellRenderer;
|
import javax.swing.table.DefaultTableCellRenderer;
|
||||||
import java.awt.*;
|
import java.awt.Color;
|
||||||
|
import java.awt.Component;
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.Rectangle;
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class AliasController extends JPanel
|
public class AliasController extends JPanel implements ActionListener, ListSelectionListener
|
||||||
implements ActionListener, ListSelectionListener
|
|
||||||
{
|
{
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private static final String TABLE_PREFERENCE_KEY = "alias.controller";
|
||||||
private AliasModel mAliasModel;
|
private AliasModel mAliasModel;
|
||||||
private JTable mAliasTable;
|
private JTable mAliasTable;
|
||||||
private TableFilterHeader mTableFilterHeader;
|
private TableFilterHeader mTableFilterHeader;
|
||||||
private AliasEditor mAliasEditor;
|
private AliasEditor mAliasEditor;
|
||||||
private MultipleAliasEditor mMultipleAliasEditor;
|
private MultipleAliasEditor mMultipleAliasEditor;
|
||||||
private JideSplitPane mSplitPane;
|
private JideSplitPane mSplitPane;
|
||||||
|
private UserPreferences mUserPreferences;
|
||||||
|
|
||||||
private static final String NEW_ALIAS = "New";
|
private static final String NEW_ALIAS = "New";
|
||||||
private static final String COPY_ALIAS = "Copy";
|
private static final String COPY_ALIAS = "Copy";
|
||||||
@@ -39,15 +72,16 @@ public class AliasController extends JPanel
|
|||||||
private JButton mDeleteButton = new JButton(DELETE_ALIAS);
|
private JButton mDeleteButton = new JButton(DELETE_ALIAS);
|
||||||
|
|
||||||
private IconCellRenderer mIconCellRenderer;
|
private IconCellRenderer mIconCellRenderer;
|
||||||
|
private JTableColumnWidthMonitor mColumnWidthMonitor;
|
||||||
|
|
||||||
public AliasController(AliasModel aliasModel, BroadcastModel broadcastModel, IconManager iconManager)
|
public AliasController(AliasModel aliasModel, BroadcastModel broadcastModel, IconManager iconManager,
|
||||||
|
UserPreferences userPreferences)
|
||||||
{
|
{
|
||||||
mAliasModel = aliasModel;
|
mAliasModel = aliasModel;
|
||||||
|
|
||||||
mAliasEditor = new AliasEditor(mAliasModel, broadcastModel, iconManager);
|
mAliasEditor = new AliasEditor(mAliasModel, broadcastModel, iconManager);
|
||||||
mMultipleAliasEditor = new MultipleAliasEditor(mAliasModel, broadcastModel, iconManager);
|
mMultipleAliasEditor = new MultipleAliasEditor(mAliasModel, broadcastModel, iconManager);
|
||||||
|
|
||||||
mIconCellRenderer = new IconCellRenderer(iconManager);
|
mIconCellRenderer = new IconCellRenderer(iconManager);
|
||||||
|
mUserPreferences = userPreferences;
|
||||||
|
|
||||||
init();
|
init();
|
||||||
|
|
||||||
@@ -56,9 +90,7 @@ public class AliasController extends JPanel
|
|||||||
|
|
||||||
private void init()
|
private void init()
|
||||||
{
|
{
|
||||||
setLayout(new MigLayout("insets 0 0 0 0",
|
setLayout(new MigLayout("insets 0 0 0 0", "[grow,fill]", "[grow,fill]"));
|
||||||
"[grow,fill]",
|
|
||||||
"[grow,fill]"));
|
|
||||||
|
|
||||||
//System Configuration View and Editor
|
//System Configuration View and Editor
|
||||||
mAliasTable = new JTable(mAliasModel);
|
mAliasTable = new JTable(mAliasModel);
|
||||||
@@ -66,11 +98,11 @@ public class AliasController extends JPanel
|
|||||||
mAliasTable.getSelectionModel().addListSelectionListener(this);
|
mAliasTable.getSelectionModel().addListSelectionListener(this);
|
||||||
mAliasTable.setAutoCreateRowSorter(true);
|
mAliasTable.setAutoCreateRowSorter(true);
|
||||||
|
|
||||||
mAliasTable.getColumnModel().getColumn(AliasModel.COLUMN_COLOR)
|
mAliasTable.getColumnModel().getColumn(AliasModel.COLUMN_COLOR).setCellRenderer(new ColorCellRenderer());
|
||||||
.setCellRenderer(new ColorCellRenderer());
|
|
||||||
|
|
||||||
mAliasTable.getColumnModel().getColumn(AliasModel.COLUMN_ICON)
|
mAliasTable.getColumnModel().getColumn(AliasModel.COLUMN_ICON).setCellRenderer(mIconCellRenderer);
|
||||||
.setCellRenderer(mIconCellRenderer);
|
|
||||||
|
mColumnWidthMonitor = new JTableColumnWidthMonitor(mUserPreferences, mAliasTable, TABLE_PREFERENCE_KEY);
|
||||||
|
|
||||||
mTableFilterHeader = new TableFilterHeader(mAliasTable, AutoChoices.ENABLED);
|
mTableFilterHeader = new TableFilterHeader(mAliasTable, AutoChoices.ENABLED);
|
||||||
mTableFilterHeader.setFilterOnUpdates(true);
|
mTableFilterHeader.setFilterOnUpdates(true);
|
||||||
@@ -79,8 +111,8 @@ public class AliasController extends JPanel
|
|||||||
|
|
||||||
JPanel buttonsPanel = new JPanel();
|
JPanel buttonsPanel = new JPanel();
|
||||||
|
|
||||||
buttonsPanel.setLayout(
|
buttonsPanel.setLayout(new MigLayout("insets 0 0 0 0",
|
||||||
new MigLayout("insets 0 0 0 0", "[grow,fill][grow,fill][grow,fill]", "[]"));
|
"[grow,fill][grow,fill][grow,fill]", "[]"));
|
||||||
|
|
||||||
mNewButton.addActionListener(this);
|
mNewButton.addActionListener(this);
|
||||||
mNewButton.setToolTipText("Adds a new alias");
|
mNewButton.setToolTipText("Adds a new alias");
|
||||||
@@ -98,8 +130,8 @@ public class AliasController extends JPanel
|
|||||||
|
|
||||||
JPanel listAndButtonsPanel = new JPanel();
|
JPanel listAndButtonsPanel = new JPanel();
|
||||||
|
|
||||||
listAndButtonsPanel.setLayout(
|
listAndButtonsPanel.setLayout(new MigLayout("insets 0 0 0 0", "[grow,fill]",
|
||||||
new MigLayout("insets 0 0 0 0", "[grow,fill]", "[grow,fill][]"));
|
"[grow,fill][]"));
|
||||||
|
|
||||||
listAndButtonsPanel.add(tableScroller, "wrap");
|
listAndButtonsPanel.add(tableScroller, "wrap");
|
||||||
listAndButtonsPanel.add(buttonsPanel);
|
listAndButtonsPanel.add(buttonsPanel);
|
||||||
@@ -212,18 +244,11 @@ public class AliasController extends JPanel
|
|||||||
*/
|
*/
|
||||||
private void addAlias(Alias alias)
|
private void addAlias(Alias alias)
|
||||||
{
|
{
|
||||||
//HACK: when inserting a row to the model, the JTable gets
|
//Remove any column headers so that the newly added alias shows correctly.
|
||||||
//notified and attempts to tell the coderazzi table filter
|
mTableFilterHeader.resetFilter();
|
||||||
//adaptive choices filter to refresh before the table filter is
|
|
||||||
//notified of the row additions, causing an index out of bounds
|
|
||||||
//exception. We turn off adaptive choices temporarily, add the
|
|
||||||
//channel, and turn on adaptive choices again.
|
|
||||||
mTableFilterHeader.setAdaptiveChoices(false);
|
|
||||||
|
|
||||||
int index = mAliasModel.addAlias(alias);
|
int index = mAliasModel.addAlias(alias);
|
||||||
|
|
||||||
mTableFilterHeader.setAdaptiveChoices(true);
|
|
||||||
|
|
||||||
if(index >= 0)
|
if(index >= 0)
|
||||||
{
|
{
|
||||||
int translatedIndex = mAliasTable.convertRowIndexToView(index);
|
int translatedIndex = mAliasTable.convertRowIndexToView(index);
|
||||||
|
|||||||
@@ -505,11 +505,32 @@ public class AliasList implements Listener<AliasEvent>
|
|||||||
|
|
||||||
public void add(Talkgroup talkgroup, Alias alias)
|
public void add(Talkgroup talkgroup, Alias alias)
|
||||||
{
|
{
|
||||||
|
//Detect talkgroup collisions
|
||||||
|
if(mTalkgroupAliasMap.containsKey(talkgroup.getValue()))
|
||||||
|
{
|
||||||
|
Alias existing = mTalkgroupAliasMap.get(talkgroup.getValue());
|
||||||
|
|
||||||
|
mLog.warn("Alias [" + alias.getName() + "] talkgroup [" + talkgroup.getValue() +
|
||||||
|
"] has the same talkgroup value as alias [" + existing.getName() +
|
||||||
|
"] - alias [" + alias.getName() + "] will be used for alias list [" + getName() + "]");
|
||||||
|
}
|
||||||
|
|
||||||
mTalkgroupAliasMap.put(talkgroup.getValue(), alias);
|
mTalkgroupAliasMap.put(talkgroup.getValue(), alias);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void add(TalkgroupRange talkgroupRange, Alias alias)
|
public void add(TalkgroupRange talkgroupRange, Alias alias)
|
||||||
{
|
{
|
||||||
|
//Log warning if the new talkgroup range overlaps with any existing ranges
|
||||||
|
for(Map.Entry<TalkgroupRange,Alias> entry: mTalkgroupRangeAliasMap.entrySet())
|
||||||
|
{
|
||||||
|
if(talkgroupRange.overlaps(entry.getKey()))
|
||||||
|
{
|
||||||
|
mLog.warn("Alias [" + alias.getName() + "] with talkgroup range [" + talkgroupRange.toString() +
|
||||||
|
"] overlaps with alias [" + entry.getValue().getName() +
|
||||||
|
"] with talkgroup range [" + entry.getKey().toString() + "] for alias list [" + getName() + "]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mTalkgroupRangeAliasMap.put(talkgroupRange, alias);
|
mTalkgroupRangeAliasMap.put(talkgroupRange, alias);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -193,6 +193,11 @@ public class TalkgroupEditor extends DocumentListenerEditor<AliasID>
|
|||||||
{
|
{
|
||||||
Protocol protocol = mComboProtocol.getItemAt(mComboProtocol.getSelectedIndex());
|
Protocol protocol = mComboProtocol.getItemAt(mComboProtocol.getSelectedIndex());
|
||||||
|
|
||||||
|
if(protocol == null)
|
||||||
|
{
|
||||||
|
protocol = Protocol.UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
int value = -1;
|
int value = -1;
|
||||||
|
|
||||||
try
|
try
|
||||||
|
|||||||
@@ -83,6 +83,14 @@ public enum TalkgroupFormat
|
|||||||
return mMaximumValue;
|
return mMaximumValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates if the value is valid for the protocol
|
||||||
|
*/
|
||||||
|
public boolean isValid(int value)
|
||||||
|
{
|
||||||
|
return getMinimumValidValue() <= value && value <= getMaximumValidValue();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Short description of the valid value range
|
* Short description of the valid value range
|
||||||
*/
|
*/
|
||||||
@@ -99,9 +107,14 @@ public enum TalkgroupFormat
|
|||||||
return mValidRangeHelpText;
|
return mValidRangeHelpText;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TalkgroupFormat get(Protocol prococol)
|
public static TalkgroupFormat get(Protocol protocol)
|
||||||
{
|
{
|
||||||
switch(prococol)
|
if(protocol == null)
|
||||||
|
{
|
||||||
|
return UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(protocol)
|
||||||
{
|
{
|
||||||
case APCO25:
|
case APCO25:
|
||||||
return APCO25;
|
return APCO25;
|
||||||
|
|||||||
@@ -140,6 +140,21 @@ public class TalkgroupRange extends AliasID
|
|||||||
return getMinTalkgroup() <= talkgroupValue && talkgroupValue <= getMaxTalkgroup();
|
return getMinTalkgroup() <= talkgroupValue && talkgroupValue <= getMaxTalkgroup();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates if this talkgroup range overlaps the talkgroup range argument.
|
||||||
|
* @param talkgroupRange to check for overlap
|
||||||
|
* @return true if the ranges overlap
|
||||||
|
*/
|
||||||
|
public boolean overlaps(TalkgroupRange talkgroupRange)
|
||||||
|
{
|
||||||
|
return contains(talkgroupRange.getMinTalkgroup()) ||
|
||||||
|
contains(talkgroupRange.getMaxTalkgroup()) ||
|
||||||
|
(getMinTalkgroup() < talkgroupRange.getMinTalkgroup() &&
|
||||||
|
talkgroupRange.getMaxTalkgroup() < getMaxTalkgroup()) ||
|
||||||
|
(talkgroupRange.getMinTalkgroup() < getMinTalkgroup() &&
|
||||||
|
getMaxTalkgroup() < talkgroupRange.getMaxTalkgroup());
|
||||||
|
}
|
||||||
|
|
||||||
@JacksonXmlProperty(isAttribute = true, localName = "type", namespace = "http://www.w3.org/2001/XMLSchema-instance")
|
@JacksonXmlProperty(isAttribute = true, localName = "type", namespace = "http://www.w3.org/2001/XMLSchema-instance")
|
||||||
@Override
|
@Override
|
||||||
public AliasIDType getType()
|
public AliasIDType getType()
|
||||||
|
|||||||
@@ -174,6 +174,8 @@ public class TalkgroupRangeEditor extends DocumentListenerEditor<AliasID>
|
|||||||
|
|
||||||
TalkgroupRange talkgroupRange = getTalkgroupRange();
|
TalkgroupRange talkgroupRange = getTalkgroupRange();
|
||||||
|
|
||||||
|
updateEditor(talkgroupRange.getProtocol());
|
||||||
|
|
||||||
if(talkgroupRange != null)
|
if(talkgroupRange != null)
|
||||||
{
|
{
|
||||||
mComboProtocol.getModel().setSelectedItem(talkgroupRange.getProtocol());
|
mComboProtocol.getModel().setSelectedItem(talkgroupRange.getProtocol());
|
||||||
@@ -202,6 +204,12 @@ public class TalkgroupRangeEditor extends DocumentListenerEditor<AliasID>
|
|||||||
if(talkgroupRange != null)
|
if(talkgroupRange != null)
|
||||||
{
|
{
|
||||||
Protocol protocol = mComboProtocol.getItemAt(mComboProtocol.getSelectedIndex());
|
Protocol protocol = mComboProtocol.getItemAt(mComboProtocol.getSelectedIndex());
|
||||||
|
|
||||||
|
if(protocol == null)
|
||||||
|
{
|
||||||
|
protocol = Protocol.UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
talkgroupRange.setProtocol(protocol);
|
talkgroupRange.setProtocol(protocol);
|
||||||
|
|
||||||
int minValue = -1;
|
int minValue = -1;
|
||||||
|
|||||||
@@ -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
|
* * Copyright (C) 2014-2019 Dennis Sheirer
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* *
|
||||||
* (at your option) any later version.
|
* * 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.audio.broadcast;
|
package io.github.dsheirer.audio.broadcast;
|
||||||
|
|
||||||
import io.github.dsheirer.alias.AliasModel;
|
import io.github.dsheirer.alias.AliasModel;
|
||||||
@@ -40,6 +43,7 @@ import io.github.dsheirer.audio.convert.MP3SilenceGenerator;
|
|||||||
import io.github.dsheirer.gui.editor.Editor;
|
import io.github.dsheirer.gui.editor.Editor;
|
||||||
import io.github.dsheirer.gui.editor.EmptyEditor;
|
import io.github.dsheirer.gui.editor.EmptyEditor;
|
||||||
import io.github.dsheirer.icon.IconManager;
|
import io.github.dsheirer.icon.IconManager;
|
||||||
|
import io.github.dsheirer.preference.UserPreferences;
|
||||||
import io.github.dsheirer.record.AudioRecorder;
|
import io.github.dsheirer.record.AudioRecorder;
|
||||||
import io.github.dsheirer.record.mp3.MP3Recorder;
|
import io.github.dsheirer.record.mp3.MP3Recorder;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@@ -147,7 +151,8 @@ public class BroadcastFactory
|
|||||||
* @param broadcastModel model for broadcastAudio configurations
|
* @param broadcastModel model for broadcastAudio configurations
|
||||||
* @return an editor for the specified broadcastAudio configuration
|
* @return an editor for the specified broadcastAudio configuration
|
||||||
*/
|
*/
|
||||||
public static Editor<BroadcastConfiguration> getEditor(BroadcastConfiguration configuration,
|
public static Editor<BroadcastConfiguration> getEditor(UserPreferences userPreferences,
|
||||||
|
BroadcastConfiguration configuration,
|
||||||
BroadcastModel broadcastModel,
|
BroadcastModel broadcastModel,
|
||||||
AliasModel aliasModel,
|
AliasModel aliasModel,
|
||||||
IconManager iconManager)
|
IconManager iconManager)
|
||||||
@@ -157,7 +162,7 @@ public class BroadcastFactory
|
|||||||
switch(configuration.getBroadcastServerType())
|
switch(configuration.getBroadcastServerType())
|
||||||
{
|
{
|
||||||
case BROADCASTIFY:
|
case BROADCASTIFY:
|
||||||
editor = new BroadcastifyConfigurationEditor(broadcastModel, aliasModel, iconManager);
|
editor = new BroadcastifyConfigurationEditor(userPreferences, broadcastModel, aliasModel, iconManager);
|
||||||
break;
|
break;
|
||||||
case ICECAST_TCP:
|
case ICECAST_TCP:
|
||||||
editor = new IcecastTCPConfigurationEditor(broadcastModel, aliasModel, iconManager);
|
editor = new IcecastTCPConfigurationEditor(broadcastModel, aliasModel, iconManager);
|
||||||
|
|||||||
@@ -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
|
* * Copyright (C) 2014-2019 Dennis Sheirer
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* *
|
||||||
* (at your option) any later version.
|
* * 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.audio.broadcast;
|
package io.github.dsheirer.audio.broadcast;
|
||||||
|
|
||||||
@@ -586,12 +588,20 @@ public class BroadcastModel extends AbstractTableModel implements Listener<Reusa
|
|||||||
@Override
|
@Override
|
||||||
public Class<?> getColumnClass(int columnIndex)
|
public Class<?> getColumnClass(int columnIndex)
|
||||||
{
|
{
|
||||||
if(columnIndex == COLUMN_SERVER_ICON)
|
switch(columnIndex)
|
||||||
{
|
{
|
||||||
return ImageIcon.class;
|
case COLUMN_BROADCASTER_STATUS:
|
||||||
|
return BroadcastState.class;
|
||||||
|
case COLUMN_BROADCASTER_AGED_OFF_COUNT:
|
||||||
|
case COLUMN_BROADCASTER_QUEUE_SIZE:
|
||||||
|
case COLUMN_BROADCASTER_STREAMED_COUNT:
|
||||||
|
return Integer.class;
|
||||||
|
case COLUMN_SERVER_ICON:
|
||||||
|
return ImageIcon.class;
|
||||||
|
case COLUMN_STREAM_NAME:
|
||||||
|
default:
|
||||||
|
return String.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
return String.class;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -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
|
* * Copyright (C) 2014-2019 Dennis Sheirer
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* *
|
||||||
* (at your option) any later version.
|
* * 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.audio.broadcast;
|
package io.github.dsheirer.audio.broadcast;
|
||||||
|
|
||||||
import com.jidesoft.swing.JideSplitPane;
|
import com.jidesoft.swing.JideSplitPane;
|
||||||
@@ -23,6 +26,7 @@ import io.github.dsheirer.alias.AliasModel;
|
|||||||
import io.github.dsheirer.gui.editor.Editor;
|
import io.github.dsheirer.gui.editor.Editor;
|
||||||
import io.github.dsheirer.gui.editor.EmptyEditor;
|
import io.github.dsheirer.gui.editor.EmptyEditor;
|
||||||
import io.github.dsheirer.icon.IconManager;
|
import io.github.dsheirer.icon.IconManager;
|
||||||
|
import io.github.dsheirer.preference.UserPreferences;
|
||||||
import net.miginfocom.swing.MigLayout;
|
import net.miginfocom.swing.MigLayout;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
@@ -51,6 +55,7 @@ public class BroadcastPanel extends JPanel implements ActionListener, ListSelect
|
|||||||
private BroadcastModel mBroadcastModel;
|
private BroadcastModel mBroadcastModel;
|
||||||
private AliasModel mAliasModel;
|
private AliasModel mAliasModel;
|
||||||
private IconManager mIconManager;
|
private IconManager mIconManager;
|
||||||
|
private UserPreferences mUserPreferences;
|
||||||
|
|
||||||
private BroadcastStatusPanel mBroadcastStatusPanel;
|
private BroadcastStatusPanel mBroadcastStatusPanel;
|
||||||
private JideSplitPane mSplitPane;
|
private JideSplitPane mSplitPane;
|
||||||
@@ -60,12 +65,14 @@ public class BroadcastPanel extends JPanel implements ActionListener, ListSelect
|
|||||||
private JButton mCopyButton = new JButton(COPY_BROADCAST_CONFIGURATION);
|
private JButton mCopyButton = new JButton(COPY_BROADCAST_CONFIGURATION);
|
||||||
private JButton mDeleteButton = new JButton(DELETE_BROADCAST_CONFIGURATION);
|
private JButton mDeleteButton = new JButton(DELETE_BROADCAST_CONFIGURATION);
|
||||||
|
|
||||||
public BroadcastPanel(BroadcastModel broadcastModel, AliasModel aliasModel, IconManager iconManager)
|
public BroadcastPanel(BroadcastModel broadcastModel, AliasModel aliasModel, IconManager iconManager,
|
||||||
|
UserPreferences userPreferences)
|
||||||
{
|
{
|
||||||
mBroadcastModel = broadcastModel;
|
mBroadcastModel = broadcastModel;
|
||||||
mAliasModel = aliasModel;
|
mAliasModel = aliasModel;
|
||||||
mIconManager = iconManager;
|
mIconManager = iconManager;
|
||||||
mEditor = mEmptyEditor;
|
mEditor = mEmptyEditor;
|
||||||
|
mUserPreferences = userPreferences;
|
||||||
|
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
@@ -74,7 +81,8 @@ public class BroadcastPanel extends JPanel implements ActionListener, ListSelect
|
|||||||
{
|
{
|
||||||
setLayout(new MigLayout("insets 0 0 0 0 ", "[grow,fill]", "[grow,fill]"));
|
setLayout(new MigLayout("insets 0 0 0 0 ", "[grow,fill]", "[grow,fill]"));
|
||||||
|
|
||||||
mBroadcastStatusPanel = new BroadcastStatusPanel(mBroadcastModel);
|
mBroadcastStatusPanel = new BroadcastStatusPanel(mBroadcastModel, mUserPreferences,
|
||||||
|
"broadcast.panel.broadcast.status.panel");
|
||||||
|
|
||||||
mBroadcastStatusPanel.getTable().setAutoCreateRowSorter(true);
|
mBroadcastStatusPanel.getTable().setAutoCreateRowSorter(true);
|
||||||
mBroadcastStatusPanel.getTable().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
mBroadcastStatusPanel.getTable().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||||
@@ -210,8 +218,8 @@ public class BroadcastPanel extends JPanel implements ActionListener, ListSelect
|
|||||||
|
|
||||||
if (selectedConfiguration != null)
|
if (selectedConfiguration != null)
|
||||||
{
|
{
|
||||||
mEditor = BroadcastFactory.getEditor(selectedConfiguration, mBroadcastModel, mAliasModel,
|
mEditor = BroadcastFactory.getEditor(mUserPreferences, selectedConfiguration, mBroadcastModel,
|
||||||
mIconManager);
|
mAliasModel, mIconManager);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
/*******************************************************************************
|
/*
|
||||||
|
* ******************************************************************************
|
||||||
* sdrtrunk
|
* sdrtrunk
|
||||||
* Copyright (C) 2014-2017 Dennis Sheirer
|
* Copyright (C) 2014-2019 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -14,10 +15,12 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
*
|
* *****************************************************************************
|
||||||
******************************************************************************/
|
*/
|
||||||
package io.github.dsheirer.audio.broadcast;
|
package io.github.dsheirer.audio.broadcast;
|
||||||
|
|
||||||
|
import io.github.dsheirer.preference.UserPreferences;
|
||||||
|
import io.github.dsheirer.preference.swing.JTableColumnWidthMonitor;
|
||||||
import net.miginfocom.swing.MigLayout;
|
import net.miginfocom.swing.MigLayout;
|
||||||
|
|
||||||
import javax.swing.JLabel;
|
import javax.swing.JLabel;
|
||||||
@@ -32,12 +35,17 @@ import java.awt.Component;
|
|||||||
public class BroadcastStatusPanel extends JPanel
|
public class BroadcastStatusPanel extends JPanel
|
||||||
{
|
{
|
||||||
private JTable mTable;
|
private JTable mTable;
|
||||||
|
private JTableColumnWidthMonitor mColumnWidthMonitor;
|
||||||
private JScrollPane mScrollPane;
|
private JScrollPane mScrollPane;
|
||||||
private BroadcastModel mBroadcastModel;
|
private BroadcastModel mBroadcastModel;
|
||||||
|
private UserPreferences mUserPreferences;
|
||||||
|
private String mPreferenceKey;
|
||||||
|
|
||||||
public BroadcastStatusPanel(BroadcastModel broadcastModel)
|
public BroadcastStatusPanel(BroadcastModel broadcastModel, UserPreferences userPreferences, String preferenceKey)
|
||||||
{
|
{
|
||||||
mBroadcastModel = broadcastModel;
|
mBroadcastModel = broadcastModel;
|
||||||
|
mUserPreferences = userPreferences;
|
||||||
|
mPreferenceKey = preferenceKey;
|
||||||
|
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
@@ -57,6 +65,7 @@ public class BroadcastStatusPanel extends JPanel
|
|||||||
renderer.setHorizontalAlignment(SwingConstants.CENTER);
|
renderer.setHorizontalAlignment(SwingConstants.CENTER);
|
||||||
|
|
||||||
mTable.getColumnModel().getColumn(BroadcastModel.COLUMN_BROADCASTER_STATUS).setCellRenderer(new StatusCellRenderer());
|
mTable.getColumnModel().getColumn(BroadcastModel.COLUMN_BROADCASTER_STATUS).setCellRenderer(new StatusCellRenderer());
|
||||||
|
mColumnWidthMonitor = new JTableColumnWidthMonitor(mUserPreferences, mTable, mPreferenceKey);
|
||||||
|
|
||||||
mScrollPane = new JScrollPane(mTable);
|
mScrollPane = new JScrollPane(mTable);
|
||||||
|
|
||||||
|
|||||||
@@ -1,24 +1,26 @@
|
|||||||
/*******************************************************************************
|
/*
|
||||||
* 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
|
* * Copyright (C) 2014-2019 Dennis Sheirer
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* *
|
||||||
* (at your option) any later version.
|
* * 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.audio.broadcast.broadcastify;
|
package io.github.dsheirer.audio.broadcast.broadcastify;
|
||||||
|
|
||||||
import com.radioreference.api.soap2.UserFeedBroadcast;
|
|
||||||
import io.github.dsheirer.alias.AliasModel;
|
import io.github.dsheirer.alias.AliasModel;
|
||||||
import io.github.dsheirer.audio.broadcast.BroadcastConfiguration;
|
import io.github.dsheirer.audio.broadcast.BroadcastConfiguration;
|
||||||
import io.github.dsheirer.audio.broadcast.BroadcastConfigurationEditor;
|
import io.github.dsheirer.audio.broadcast.BroadcastConfigurationEditor;
|
||||||
@@ -26,6 +28,8 @@ import io.github.dsheirer.audio.broadcast.BroadcastEvent;
|
|||||||
import io.github.dsheirer.audio.broadcast.BroadcastModel;
|
import io.github.dsheirer.audio.broadcast.BroadcastModel;
|
||||||
import io.github.dsheirer.audio.broadcast.BroadcastServerType;
|
import io.github.dsheirer.audio.broadcast.BroadcastServerType;
|
||||||
import io.github.dsheirer.icon.IconManager;
|
import io.github.dsheirer.icon.IconManager;
|
||||||
|
import io.github.dsheirer.preference.UserPreferences;
|
||||||
|
import io.github.dsheirer.rrapi.type.UserFeedBroadcast;
|
||||||
import io.github.dsheirer.sample.Listener;
|
import io.github.dsheirer.sample.Listener;
|
||||||
import net.miginfocom.swing.MigLayout;
|
import net.miginfocom.swing.MigLayout;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@@ -64,10 +68,13 @@ public class BroadcastifyConfigurationEditor extends BroadcastConfigurationEdito
|
|||||||
private JCheckBox mEnabled;
|
private JCheckBox mEnabled;
|
||||||
private JButton mSaveButton;
|
private JButton mSaveButton;
|
||||||
private JButton mResetButton;
|
private JButton mResetButton;
|
||||||
|
private UserPreferences mUserPreferences;
|
||||||
|
|
||||||
public BroadcastifyConfigurationEditor(BroadcastModel broadcastModel, AliasModel aliasModel, IconManager iconManager)
|
public BroadcastifyConfigurationEditor(UserPreferences userPreferences, BroadcastModel broadcastModel,
|
||||||
|
AliasModel aliasModel, IconManager iconManager)
|
||||||
{
|
{
|
||||||
super(broadcastModel, aliasModel, iconManager);
|
super(broadcastModel, aliasModel, iconManager);
|
||||||
|
mUserPreferences = userPreferences;
|
||||||
|
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
@@ -91,7 +98,7 @@ public class BroadcastifyConfigurationEditor extends BroadcastConfigurationEdito
|
|||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent e)
|
public void actionPerformed(ActionEvent e)
|
||||||
{
|
{
|
||||||
final UserFeedSelectionDialog dialog = new UserFeedSelectionDialog(BroadcastifyConfigurationEditor.this);
|
final UserFeedSelectionDialog dialog = new UserFeedSelectionDialog(mUserPreferences,BroadcastifyConfigurationEditor.this);
|
||||||
|
|
||||||
EventQueue.invokeLater(new Runnable()
|
EventQueue.invokeLater(new Runnable()
|
||||||
{
|
{
|
||||||
@@ -391,7 +398,7 @@ public class BroadcastifyConfigurationEditor extends BroadcastConfigurationEdito
|
|||||||
@Override
|
@Override
|
||||||
public void receive(UserFeedBroadcast userFeedBroadcast)
|
public void receive(UserFeedBroadcast userFeedBroadcast)
|
||||||
{
|
{
|
||||||
mName.setText(userFeedBroadcast.getDescr());
|
mName.setText(userFeedBroadcast.getDescription());
|
||||||
mServer.setText(userFeedBroadcast.getHostname());
|
mServer.setText(userFeedBroadcast.getHostname());
|
||||||
mPort.setText(userFeedBroadcast.getPort());
|
mPort.setText(userFeedBroadcast.getPort());
|
||||||
mMountPoint.setText(userFeedBroadcast.getMount());
|
mMountPoint.setText(userFeedBroadcast.getMount());
|
||||||
|
|||||||
@@ -1,78 +1,155 @@
|
|||||||
/*******************************************************************************
|
/*
|
||||||
* 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
|
* * Copyright (C) 2014-2019 Dennis Sheirer
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* *
|
||||||
* (at your option) any later version.
|
* * 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.audio.broadcast.broadcastify;
|
package io.github.dsheirer.audio.broadcast.broadcastify;
|
||||||
|
|
||||||
import com.radioreference.api.soap2.UserFeedBroadcast;
|
import com.google.common.eventbus.Subscribe;
|
||||||
import io.github.dsheirer.radioreference.RadioReferenceService;
|
import io.github.dsheirer.eventbus.MyEventBus;
|
||||||
|
import io.github.dsheirer.preference.PreferenceType;
|
||||||
|
import io.github.dsheirer.preference.UserPreferences;
|
||||||
|
import io.github.dsheirer.rrapi.RadioReferenceException;
|
||||||
|
import io.github.dsheirer.rrapi.RadioReferenceService;
|
||||||
|
import io.github.dsheirer.rrapi.type.AuthorizationInformation;
|
||||||
|
import io.github.dsheirer.rrapi.type.UserFeedBroadcast;
|
||||||
|
import io.github.dsheirer.rrapi.type.UserInfo;
|
||||||
import io.github.dsheirer.sample.Listener;
|
import io.github.dsheirer.sample.Listener;
|
||||||
import net.miginfocom.swing.MigLayout;
|
import net.miginfocom.swing.MigLayout;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.JButton;
|
||||||
|
import javax.swing.JCheckBox;
|
||||||
|
import javax.swing.JDialog;
|
||||||
|
import javax.swing.JFrame;
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
import javax.swing.JList;
|
||||||
|
import javax.swing.JOptionPane;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.JScrollPane;
|
||||||
|
import javax.swing.JTextField;
|
||||||
|
import javax.swing.ListCellRenderer;
|
||||||
import javax.swing.event.DocumentEvent;
|
import javax.swing.event.DocumentEvent;
|
||||||
import javax.swing.event.DocumentListener;
|
import javax.swing.event.DocumentListener;
|
||||||
import javax.swing.event.ListSelectionEvent;
|
import javax.swing.event.ListSelectionEvent;
|
||||||
import javax.swing.event.ListSelectionListener;
|
import javax.swing.event.ListSelectionListener;
|
||||||
import javax.xml.rpc.ServiceException;
|
import java.awt.BorderLayout;
|
||||||
import java.awt.*;
|
import java.awt.Component;
|
||||||
|
import java.awt.EventQueue;
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
import java.net.UnknownHostException;
|
import java.util.List;
|
||||||
import java.rmi.RemoteException;
|
|
||||||
|
|
||||||
public class UserFeedSelectionDialog extends JDialog implements DocumentListener
|
public class UserFeedSelectionDialog extends JDialog implements DocumentListener
|
||||||
{
|
{
|
||||||
private final static Logger mLog = LoggerFactory.getLogger( UserFeedSelectionDialog.class );
|
private final static Logger mLog = LoggerFactory.getLogger( UserFeedSelectionDialog.class );
|
||||||
|
|
||||||
|
public static final String SDRTRUNK_APP_KEY = "88969092";
|
||||||
|
|
||||||
private Listener<UserFeedBroadcast> mListener;
|
private Listener<UserFeedBroadcast> mListener;
|
||||||
|
private UserPreferences mUserPreferences;
|
||||||
private JTextField mUserNameText;
|
private JTextField mUserNameText;
|
||||||
private JTextField mPasswordText;
|
private JTextField mPasswordText;
|
||||||
|
private JCheckBox mSaveCredentialsCheckBox;
|
||||||
|
private JButton mClearStoredCredentialsButton;
|
||||||
private JButton mLookupButton;
|
private JButton mLookupButton;
|
||||||
private JList mUserFeedBroadcastList;
|
private JList mUserFeedBroadcastList;
|
||||||
private JButton mOKButton;
|
private JButton mOKButton;
|
||||||
|
|
||||||
public UserFeedSelectionDialog(Listener<UserFeedBroadcast> listener)
|
public UserFeedSelectionDialog(UserPreferences userPreferences, Listener<UserFeedBroadcast> listener)
|
||||||
{
|
{
|
||||||
|
mUserPreferences = userPreferences;
|
||||||
mListener = listener;
|
mListener = listener;
|
||||||
|
|
||||||
|
//Register to receive radio reference preferences updates
|
||||||
|
MyEventBus.getEventBus().register(this);
|
||||||
|
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void init()
|
private void init()
|
||||||
{
|
{
|
||||||
JPanel panel = new JPanel();
|
JPanel panel = new JPanel();
|
||||||
panel.setLayout(new MigLayout("","[align right,grow,fill][align left,grow,fill][]","[][][][][grow][]"));
|
panel.setLayout(new MigLayout("","[align right,grow,fill][align left,grow,fill][]","[][][][][][grow][]"));
|
||||||
|
|
||||||
panel.add(new JLabel("Please enter your credentials"), "align left,span");
|
panel.add(new JLabel("Please enter your credentials"), "align left,span");
|
||||||
|
|
||||||
panel.add(new JLabel("User Name:"));
|
panel.add(new JLabel("User Name:"));
|
||||||
mUserNameText = new JTextField();
|
mUserNameText = new JTextField();
|
||||||
|
String storedUserName = mUserPreferences.getRadioReferencePreference().getUserName();
|
||||||
|
if(storedUserName != null)
|
||||||
|
{
|
||||||
|
mUserNameText.setText(storedUserName);
|
||||||
|
}
|
||||||
mUserNameText.getDocument().addDocumentListener(this);
|
mUserNameText.getDocument().addDocumentListener(this);
|
||||||
panel.add(mUserNameText, "wrap");
|
panel.add(mUserNameText, "wrap");
|
||||||
|
|
||||||
panel.add(new JLabel("Password:"));
|
panel.add(new JLabel("Password:"));
|
||||||
mPasswordText = new JTextField();
|
mPasswordText = new JTextField();
|
||||||
|
String storedPassword = mUserPreferences.getRadioReferencePreference().getPassword();
|
||||||
|
if(storedPassword != null)
|
||||||
|
{
|
||||||
|
mPasswordText.setText(storedPassword);
|
||||||
|
}
|
||||||
mPasswordText.getDocument().addDocumentListener(this);
|
mPasswordText.getDocument().addDocumentListener(this);
|
||||||
panel.add(mPasswordText, "wrap");
|
panel.add(mPasswordText, "wrap");
|
||||||
|
|
||||||
|
mSaveCredentialsCheckBox = new JCheckBox("Store Credentials");
|
||||||
|
mSaveCredentialsCheckBox.setSelected(mUserPreferences.getRadioReferencePreference().isStoreCredentials());
|
||||||
|
mSaveCredentialsCheckBox.addActionListener(new ActionListener()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e)
|
||||||
|
{
|
||||||
|
//If user unchecks box and there are stored credentials, prompt to clear them
|
||||||
|
if(!mSaveCredentialsCheckBox.isSelected() && mUserPreferences.getRadioReferencePreference().hasStoredCredentials())
|
||||||
|
{
|
||||||
|
int choice = JOptionPane.showOptionDialog(UserFeedSelectionDialog.this,
|
||||||
|
"Would you like to remove previously stored credentials from this computer?",
|
||||||
|
"Clear Stored Credentials?", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE,
|
||||||
|
null, null, 0);
|
||||||
|
|
||||||
|
if(choice == JOptionPane.YES_OPTION)
|
||||||
|
{
|
||||||
|
mUserPreferences.getRadioReferencePreference().removeStoreCredentials();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
panel.add(mSaveCredentialsCheckBox);
|
||||||
|
|
||||||
|
mClearStoredCredentialsButton = new JButton("Remove");
|
||||||
|
mClearStoredCredentialsButton.setToolTipText("Clear stored credentials");
|
||||||
|
mClearStoredCredentialsButton.setEnabled(mUserPreferences.getRadioReferencePreference().hasStoredCredentials());
|
||||||
|
mClearStoredCredentialsButton.addActionListener(new ActionListener()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e)
|
||||||
|
{
|
||||||
|
mUserPreferences.getRadioReferencePreference().removeStoreCredentials();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
panel.add(mClearStoredCredentialsButton, "wrap");
|
||||||
|
|
||||||
mLookupButton = new JButton("Get Feeds");
|
mLookupButton = new JButton("Get Feeds");
|
||||||
mLookupButton.setEnabled(false);
|
mLookupButton.setEnabled(storedPassword != null && storedPassword != null);
|
||||||
mLookupButton.addActionListener(new ActionListener()
|
mLookupButton.addActionListener(new ActionListener()
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
@@ -87,45 +164,25 @@ public class UserFeedSelectionDialog extends JDialog implements DocumentListener
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
RadioReferenceService service =
|
AuthorizationInformation authorizationInformation = new AuthorizationInformation(SDRTRUNK_APP_KEY,
|
||||||
new RadioReferenceService(mUserNameText.getText(), mPasswordText.getText());
|
mUserNameText.getText(), mPasswordText.getText());
|
||||||
|
|
||||||
UserFeedBroadcast[] feeds = service.getUserFeedBroadcasts();
|
mLog.debug("User:" + authorizationInformation.getUserName() + " Pass:" + authorizationInformation.getPassword() + " Key:" + authorizationInformation.getApplicationKey());
|
||||||
|
|
||||||
mUserFeedBroadcastList.setListData(feeds);
|
RadioReferenceService service = new RadioReferenceService(authorizationInformation);
|
||||||
|
UserInfo userInfo = service.getUserInfo();
|
||||||
|
mLog.info("RR User:" + userInfo.getUserName() + " Expiration Date:" + userInfo.getExpirationDate());
|
||||||
|
List<UserFeedBroadcast> feeds = service.getUserFeeds();
|
||||||
|
|
||||||
|
mUserFeedBroadcastList.setListData(feeds.toArray(new UserFeedBroadcast[feeds.size()]));
|
||||||
}
|
}
|
||||||
catch(ServiceException se)
|
catch(RadioReferenceException rre)
|
||||||
{
|
{
|
||||||
JOptionPane.showMessageDialog(UserFeedSelectionDialog.this,
|
JOptionPane.showMessageDialog(UserFeedSelectionDialog.this,
|
||||||
"Unable to create radio reference web service client. See log file.",
|
"Unable to create radio reference web service client. See log file.",
|
||||||
"Error", JOptionPane.ERROR_MESSAGE);
|
"Error", JOptionPane.ERROR_MESSAGE);
|
||||||
|
|
||||||
mLog.error("Error creating the radio reference web service client", se);
|
mLog.error("Error creating the radio reference web service client", rre);
|
||||||
}
|
|
||||||
catch(RemoteException re)
|
|
||||||
{
|
|
||||||
Throwable cause = re.getCause();
|
|
||||||
|
|
||||||
if(cause == null)
|
|
||||||
{
|
|
||||||
JOptionPane.showMessageDialog(UserFeedSelectionDialog.this,
|
|
||||||
re.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
|
|
||||||
}
|
|
||||||
else if(cause instanceof UnknownHostException)
|
|
||||||
{
|
|
||||||
JOptionPane.showMessageDialog(UserFeedSelectionDialog.this,
|
|
||||||
"Broadcastify server is unavailable", "No Server",
|
|
||||||
JOptionPane.ERROR_MESSAGE);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
JOptionPane.showMessageDialog(UserFeedSelectionDialog.this,
|
|
||||||
"An unknown error has occurred. Please see log file.", "" +
|
|
||||||
"Unknown Error", JOptionPane.ERROR_MESSAGE);
|
|
||||||
|
|
||||||
mLog.error("Error retrieving user broadcast feed configurations from radio reference " +
|
|
||||||
"service: ", re);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mLookupButton.setEnabled(true);
|
mLookupButton.setEnabled(true);
|
||||||
@@ -160,6 +217,7 @@ public class UserFeedSelectionDialog extends JDialog implements DocumentListener
|
|||||||
{
|
{
|
||||||
if(mListener != null)
|
if(mListener != null)
|
||||||
{
|
{
|
||||||
|
storeCredentials();
|
||||||
mListener.receive((UserFeedBroadcast)mUserFeedBroadcastList.getSelectedValue());
|
mListener.receive((UserFeedBroadcast)mUserFeedBroadcastList.getSelectedValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -182,11 +240,37 @@ public class UserFeedSelectionDialog extends JDialog implements DocumentListener
|
|||||||
setTitle("Broadcastify Feed Lookup");
|
setTitle("Broadcastify Feed Lookup");
|
||||||
setLayout(new BorderLayout());
|
setLayout(new BorderLayout());
|
||||||
add(panel, BorderLayout.CENTER);
|
add(panel, BorderLayout.CENTER);
|
||||||
setSize(300,250);
|
setSize(400,450);
|
||||||
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
|
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
|
||||||
setModalityType(ModalityType.APPLICATION_MODAL);
|
setModalityType(ModalityType.APPLICATION_MODAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores login credentials in the user preferences
|
||||||
|
*/
|
||||||
|
private void storeCredentials()
|
||||||
|
{
|
||||||
|
boolean store = mSaveCredentialsCheckBox.isSelected();
|
||||||
|
mUserPreferences.getRadioReferencePreference().setStoreCredentials(store);
|
||||||
|
|
||||||
|
if(store)
|
||||||
|
{
|
||||||
|
String userName = mUserNameText.getText();
|
||||||
|
|
||||||
|
if(userName != null)
|
||||||
|
{
|
||||||
|
mUserPreferences.getRadioReferencePreference().setUserName(userName);
|
||||||
|
}
|
||||||
|
|
||||||
|
String password = mPasswordText.getText();
|
||||||
|
|
||||||
|
if(password != null)
|
||||||
|
{
|
||||||
|
mUserPreferences.getRadioReferencePreference().setPassword(password);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void updateButtons()
|
private void updateButtons()
|
||||||
{
|
{
|
||||||
String username = mUserNameText.getText();
|
String username = mUserNameText.getText();
|
||||||
@@ -240,8 +324,20 @@ public class UserFeedSelectionDialog extends JDialog implements DocumentListener
|
|||||||
setForeground(list.getForeground());
|
setForeground(list.getForeground());
|
||||||
}
|
}
|
||||||
|
|
||||||
setText(value.getDescr());
|
setText(value.getDescription());
|
||||||
|
|
||||||
return this; }
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void preferenceUpdated(PreferenceType preferenceType)
|
||||||
|
{
|
||||||
|
if(preferenceType == PreferenceType.RADIO_REFERENCE)
|
||||||
|
{
|
||||||
|
//Update the store-credentials checkbox only, so we don't change the username or password currently displayed
|
||||||
|
mSaveCredentialsCheckBox.setSelected(mUserPreferences.getRadioReferencePreference().isStoreCredentials());
|
||||||
|
mClearStoredCredentialsButton.setEnabled(mUserPreferences.getRadioReferencePreference().hasStoredCredentials());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
* * Copyright (C) 2014-2019 Dennis Sheirer
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* *
|
||||||
* (at your option) any later version.
|
* * 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.audio.broadcast.icecast;
|
package io.github.dsheirer.audio.broadcast.icecast;
|
||||||
|
|
||||||
import io.github.dsheirer.alias.AliasModel;
|
import io.github.dsheirer.alias.AliasModel;
|
||||||
@@ -30,11 +33,9 @@ import org.apache.mina.core.service.IoHandlerAdapter;
|
|||||||
import org.apache.mina.core.session.IoSession;
|
import org.apache.mina.core.session.IoSession;
|
||||||
import org.apache.mina.filter.codec.ProtocolDecoderException;
|
import org.apache.mina.filter.codec.ProtocolDecoderException;
|
||||||
import org.apache.mina.http.HttpClientCodec;
|
import org.apache.mina.http.HttpClientCodec;
|
||||||
import org.apache.mina.http.HttpException;
|
|
||||||
import org.apache.mina.http.HttpRequestImpl;
|
import org.apache.mina.http.HttpRequestImpl;
|
||||||
import org.apache.mina.http.api.DefaultHttpResponse;
|
import org.apache.mina.http.api.DefaultHttpResponse;
|
||||||
import org.apache.mina.http.api.HttpMethod;
|
import org.apache.mina.http.api.HttpMethod;
|
||||||
import org.apache.mina.http.api.HttpStatus;
|
|
||||||
import org.apache.mina.http.api.HttpVersion;
|
import org.apache.mina.http.api.HttpVersion;
|
||||||
import org.apache.mina.transport.socket.nio.NioSocketConnector;
|
import org.apache.mina.transport.socket.nio.NioSocketConnector;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@@ -51,6 +52,7 @@ public class IcecastHTTPAudioBroadcaster extends IcecastAudioBroadcaster
|
|||||||
{
|
{
|
||||||
private static final Logger mLog = LoggerFactory.getLogger(IcecastHTTPAudioBroadcaster.class);
|
private static final Logger mLog = LoggerFactory.getLogger(IcecastHTTPAudioBroadcaster.class);
|
||||||
private static final long RECONNECT_INTERVAL_MILLISECONDS = 30000; //30 seconds
|
private static final long RECONNECT_INTERVAL_MILLISECONDS = 30000; //30 seconds
|
||||||
|
private static final String HTTP_1_0_OK_HEX_DUMP = "48 54 54 50 2F 31 2E 30 20 32 30 30 20 4F 4B";
|
||||||
|
|
||||||
private NioSocketConnector mSocketConnector;
|
private NioSocketConnector mSocketConnector;
|
||||||
private IoSession mStreamingSession = null;
|
private IoSession mStreamingSession = null;
|
||||||
@@ -113,7 +115,7 @@ public class IcecastHTTPAudioBroadcaster extends IcecastAudioBroadcaster
|
|||||||
mSocketConnector.setConnectTimeoutCheckInterval(10000);
|
mSocketConnector.setConnectTimeoutCheckInterval(10000);
|
||||||
|
|
||||||
// mSocketConnector.getFilterChain().addLast("logger",
|
// mSocketConnector.getFilterChain().addLast("logger",
|
||||||
// new LoggingFilter(IcecastTCPAudioBroadcaster.class));
|
// new LoggingFilter(IcecastHTTPAudioBroadcaster.class));
|
||||||
|
|
||||||
mSocketConnector.getFilterChain().addLast("codec", new HttpClientCodec());
|
mSocketConnector.getFilterChain().addLast("codec", new HttpClientCodec());
|
||||||
mSocketConnector.setHandler(new IcecastHTTPIOHandler());
|
mSocketConnector.setHandler(new IcecastHTTPIOHandler());
|
||||||
@@ -146,12 +148,12 @@ public class IcecastHTTPAudioBroadcaster extends IcecastAudioBroadcaster
|
|||||||
}
|
}
|
||||||
else if(throwableCause != null)
|
else if(throwableCause != null)
|
||||||
{
|
{
|
||||||
setBroadcastState(BroadcastState.ERROR);
|
setBroadcastState(BroadcastState.DISCONNECTED);
|
||||||
mLog.debug("Failed to connect", rie);
|
mLog.debug("Failed to connect", rie);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
setBroadcastState(BroadcastState.ERROR);
|
setBroadcastState(BroadcastState.DISCONNECTED);
|
||||||
mLog.debug("Failed to connect - no exception is available");
|
mLog.debug("Failed to connect - no exception is available");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -266,25 +268,30 @@ public class IcecastHTTPAudioBroadcaster extends IcecastAudioBroadcaster
|
|||||||
{
|
{
|
||||||
if(throwable instanceof ProtocolDecoderException)
|
if(throwable instanceof ProtocolDecoderException)
|
||||||
{
|
{
|
||||||
Throwable cause = ((ProtocolDecoderException) throwable).getCause();
|
Throwable cause = throwable.getCause();
|
||||||
|
|
||||||
if(cause instanceof HttpException &&
|
/**
|
||||||
((HttpException) cause).getStatusCode() == HttpStatus.CLIENT_ERROR_LENGTH_REQUIRED.code())
|
* Warning: Hack. Icecast 2.4.2+ doesn't like to send HTTP headers along with their HTTP/1.0 OK
|
||||||
|
* message which causes Apache Mina to think that it hasn't received the full HTTP response. So, we
|
||||||
|
* intercept the out of bounds exception and then inspect the message hex dump to see if it's an
|
||||||
|
* OK response and then play like everything is well and good.
|
||||||
|
*/
|
||||||
|
if(cause instanceof ArrayIndexOutOfBoundsException &&
|
||||||
|
((ProtocolDecoderException)throwable).getHexdump().startsWith(HTTP_1_0_OK_HEX_DUMP))
|
||||||
{
|
{
|
||||||
//Ignore - Icecast 2.4 sometimes doesn't send any headers with their HTTP responses. Mina expects a
|
setBroadcastState(BroadcastState.CONNECTED);
|
||||||
//content-length for HTTP responses.
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mLog.error("HTTP protocol decoder error", throwable);
|
mLog.error("HTTP protocol decoder error", throwable);
|
||||||
setBroadcastState(BroadcastState.TEMPORARY_BROADCAST_ERROR);
|
setBroadcastState(BroadcastState.DISCONNECTED);
|
||||||
disconnect();
|
disconnect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mLog.error("Broadcast error", throwable);
|
mLog.error("Broadcast error", throwable);
|
||||||
setBroadcastState(BroadcastState.TEMPORARY_BROADCAST_ERROR);
|
setBroadcastState(BroadcastState.DISCONNECTED);
|
||||||
disconnect();
|
disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -83,8 +83,6 @@ public class AudioChannelPanel extends JPanel implements Listener<AudioEvent>, S
|
|||||||
private JLabel mIdentifierLabel = new JLabel("-----");
|
private JLabel mIdentifierLabel = new JLabel("-----");
|
||||||
private Identifier mIdentifier;
|
private Identifier mIdentifier;
|
||||||
private List<Alias> mAliases = Collections.EMPTY_LIST;
|
private List<Alias> mAliases = Collections.EMPTY_LIST;
|
||||||
|
|
||||||
private boolean mConfigured = false;
|
|
||||||
private AliasModel mAliasModel;
|
private AliasModel mAliasModel;
|
||||||
|
|
||||||
public AudioChannelPanel(IconManager iconManager, UserPreferences userPreferences, SettingsManager settingsManager,
|
public AudioChannelPanel(IconManager iconManager, UserPreferences userPreferences, SettingsManager settingsManager,
|
||||||
@@ -191,31 +189,70 @@ public class AudioChannelPanel extends JPanel implements Listener<AudioEvent>, S
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resets the from and to labels. Note: this does not happen on the swing
|
* Resets the from and to labels.
|
||||||
* event thread. Only invoke from the swing thread.
|
|
||||||
*/
|
*/
|
||||||
private void resetLabels()
|
private void resetLabels()
|
||||||
{
|
{
|
||||||
|
boolean updated = mIdentifier != null;
|
||||||
mIdentifier = null;
|
mIdentifier = null;
|
||||||
mAliases = Collections.EMPTY_LIST;
|
mAliases = Collections.EMPTY_LIST;
|
||||||
updateLabels();
|
|
||||||
mConfigured = false;
|
if(updated)
|
||||||
|
{
|
||||||
|
updateLabels();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private void updateIdentifiers(IdentifierCollection identifierCollection)
|
||||||
* Truncates the string to the specified length using an ellipses at the end
|
|
||||||
* @param value to optionally truncate
|
|
||||||
* @param length of the final formatted string
|
|
||||||
* @return formatted string or null
|
|
||||||
*/
|
|
||||||
private static String truncate(String value, int length)
|
|
||||||
{
|
{
|
||||||
if(value != null && value.length() > length)
|
if(identifierCollection == null || identifierCollection.isEmpty())
|
||||||
{
|
{
|
||||||
return value.substring(0, length - 3) + "...";
|
resetLabels();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return value;
|
List<Identifier> toIds = identifierCollection.getIdentifiers(IdentifierClass.USER, Role.TO);
|
||||||
|
|
||||||
|
if(toIds.isEmpty())
|
||||||
|
{
|
||||||
|
resetLabels();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean updated = false;
|
||||||
|
|
||||||
|
if(toIds.size() == 1)
|
||||||
|
{
|
||||||
|
Identifier currentIdentifier = mIdentifier;
|
||||||
|
|
||||||
|
if(currentIdentifier == null || currentIdentifier != toIds.get(0))
|
||||||
|
{
|
||||||
|
mIdentifier = toIds.get(0);
|
||||||
|
AliasList aliasList = mAliasModel.getAliasList(identifierCollection);
|
||||||
|
|
||||||
|
if(aliasList != null)
|
||||||
|
{
|
||||||
|
mAliases = aliasList.getAliases(mIdentifier);
|
||||||
|
}
|
||||||
|
updated = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mIdentifier = toIds.get(0);
|
||||||
|
AliasList aliasList = mAliasModel.getAliasList(identifierCollection);
|
||||||
|
|
||||||
|
if(aliasList != null)
|
||||||
|
{
|
||||||
|
mAliases = aliasList.getAliases(mIdentifier);
|
||||||
|
}
|
||||||
|
updated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(updated)
|
||||||
|
{
|
||||||
|
updateLabels();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -249,7 +286,8 @@ public class AudioChannelPanel extends JPanel implements Listener<AudioEvent>, S
|
|||||||
}
|
}
|
||||||
|
|
||||||
final ImageIcon icon = iconName != null ? mIconManager.getIcon(iconName, 18) : null;
|
final ImageIcon icon = iconName != null ? mIconManager.getIcon(iconName, 18) : null;
|
||||||
final String identifierText = truncate(identifier, 33);
|
|
||||||
|
final String identifierText = identifier;
|
||||||
|
|
||||||
EventQueue.invokeLater(new Runnable()
|
EventQueue.invokeLater(new Runnable()
|
||||||
{
|
{
|
||||||
@@ -258,7 +296,6 @@ public class AudioChannelPanel extends JPanel implements Listener<AudioEvent>, S
|
|||||||
{
|
{
|
||||||
mIdentifierLabel.setText(identifierText);
|
mIdentifierLabel.setText(identifierText);
|
||||||
mIconLabel.setIcon(icon);
|
mIconLabel.setIcon(icon);
|
||||||
mConfigured = true;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -272,23 +309,10 @@ public class AudioChannelPanel extends JPanel implements Listener<AudioEvent>, S
|
|||||||
@Override
|
@Override
|
||||||
public void receive(final IdentifierCollection identifierCollection)
|
public void receive(final IdentifierCollection identifierCollection)
|
||||||
{
|
{
|
||||||
if(identifierCollection != null && (identifierCollection.isUpdated() || !mConfigured))
|
updateIdentifiers(identifierCollection);
|
||||||
{
|
|
||||||
List<Identifier> toIds = identifierCollection.getIdentifiers(IdentifierClass.USER, Role.TO);
|
|
||||||
mIdentifier = !toIds.isEmpty() ? toIds.get(0) : null;
|
|
||||||
AliasList aliasList = mAliasModel.getAliasList(identifierCollection);
|
|
||||||
|
|
||||||
if(aliasList != null)
|
|
||||||
{
|
|
||||||
mAliases = aliasList.getAliases(mIdentifier);
|
|
||||||
}
|
|
||||||
|
|
||||||
updateLabels();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void settingChanged(Setting setting)
|
public void settingChanged(Setting setting)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* ******************************************************************************
|
* ******************************************************************************
|
||||||
* sdrtrunk
|
* sdrtrunk
|
||||||
* Copyright (C) 2014-2018 Dennis Sheirer
|
* Copyright (C) 2014-2019 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -39,7 +39,8 @@ public class AudioChannelsPanel extends JPanel
|
|||||||
public AudioChannelsPanel(IconManager iconManager, UserPreferences userPreferences, SettingsManager settingsManager,
|
public AudioChannelsPanel(IconManager iconManager, UserPreferences userPreferences, SettingsManager settingsManager,
|
||||||
IAudioController controller, AliasModel aliasModel)
|
IAudioController controller, AliasModel aliasModel)
|
||||||
{
|
{
|
||||||
setLayout(new MigLayout("insets 0 0 0 0", "[][sg abc,grow,fill][][sg abc,grow,fill]", "[grow,fill]"));
|
setLayout(new MigLayout("insets 0 0 0 0",
|
||||||
|
"[][sizegroup abc,grow,fill][][sizegroup abc,grow,fill]", "[grow,fill]"));
|
||||||
|
|
||||||
setBackground(Color.BLACK);
|
setBackground(Color.BLACK);
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* ******************************************************************************
|
* ******************************************************************************
|
||||||
* sdrtrunk
|
* sdrtrunk
|
||||||
* Copyright (C) 2014-2018 Dennis Sheirer
|
* Copyright (C) 2014-2019 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -54,6 +54,11 @@ public abstract class AudioOutput implements Listener<ReusableAudioPacket>, Line
|
|||||||
private LinkedTransferQueue<ReusableAudioPacket> mBuffer = new LinkedTransferQueue<>();
|
private LinkedTransferQueue<ReusableAudioPacket> mBuffer = new LinkedTransferQueue<>();
|
||||||
private int mBufferStartThreshold;
|
private int mBufferStartThreshold;
|
||||||
private int mBufferStopThreshold;
|
private int mBufferStopThreshold;
|
||||||
|
private static IdentifierCollection EMPTY_IDENTIFIER_COLLECTION = new IdentifierCollection();
|
||||||
|
static
|
||||||
|
{
|
||||||
|
EMPTY_IDENTIFIER_COLLECTION.setUpdated(true);
|
||||||
|
}
|
||||||
|
|
||||||
private Listener<IdentifierCollection> mIdentifierCollectionListener;
|
private Listener<IdentifierCollection> mIdentifierCollectionListener;
|
||||||
private Broadcaster<AudioEvent> mAudioEventBroadcaster = new Broadcaster<>();
|
private Broadcaster<AudioEvent> mAudioEventBroadcaster = new Broadcaster<>();
|
||||||
@@ -380,12 +385,11 @@ public abstract class AudioOutput implements Listener<ReusableAudioPacket>, Line
|
|||||||
*/
|
*/
|
||||||
private void checkStop()
|
private void checkStop()
|
||||||
{
|
{
|
||||||
if(mCanProcessAudio &&
|
if(mCanProcessAudio && mOutput.isRunning() && mOutput.available() >= mBufferStopThreshold)
|
||||||
mOutput.isRunning() &&
|
|
||||||
mOutput.available() >= mBufferStopThreshold)
|
|
||||||
{
|
{
|
||||||
mOutput.drain();
|
mOutput.drain();
|
||||||
mOutput.stop();
|
mOutput.stop();
|
||||||
|
broadcast(EMPTY_IDENTIFIER_COLLECTION);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import io.github.dsheirer.identifier.decoder.ChannelStateIdentifier;
|
|||||||
import io.github.dsheirer.module.ProcessingChain;
|
import io.github.dsheirer.module.ProcessingChain;
|
||||||
import io.github.dsheirer.preference.UserPreferences;
|
import io.github.dsheirer.preference.UserPreferences;
|
||||||
import io.github.dsheirer.preference.identifier.TalkgroupFormatPreference;
|
import io.github.dsheirer.preference.identifier.TalkgroupFormatPreference;
|
||||||
|
import io.github.dsheirer.preference.swing.JTableColumnWidthMonitor;
|
||||||
import io.github.dsheirer.sample.Broadcaster;
|
import io.github.dsheirer.sample.Broadcaster;
|
||||||
import io.github.dsheirer.sample.Listener;
|
import io.github.dsheirer.sample.Listener;
|
||||||
import net.miginfocom.swing.MigLayout;
|
import net.miginfocom.swing.MigLayout;
|
||||||
@@ -58,6 +59,7 @@ import java.util.Map;
|
|||||||
|
|
||||||
public class ChannelMetadataPanel extends JPanel implements ListSelectionListener
|
public class ChannelMetadataPanel extends JPanel implements ListSelectionListener
|
||||||
{
|
{
|
||||||
|
private static final String TABLE_PREFERENCE_KEY = "channel.metadata.panel";
|
||||||
private ChannelModel mChannelModel;
|
private ChannelModel mChannelModel;
|
||||||
private ChannelProcessingManager mChannelProcessingManager;
|
private ChannelProcessingManager mChannelProcessingManager;
|
||||||
private IconManager mIconManager;
|
private IconManager mIconManager;
|
||||||
@@ -66,6 +68,7 @@ public class ChannelMetadataPanel extends JPanel implements ListSelectionListene
|
|||||||
private Broadcaster<ProcessingChain> mSelectedProcessingChainBroadcaster = new Broadcaster<>();
|
private Broadcaster<ProcessingChain> mSelectedProcessingChainBroadcaster = new Broadcaster<>();
|
||||||
private Map<State,Color> mBackgroundColors = new HashMap<>();
|
private Map<State,Color> mBackgroundColors = new HashMap<>();
|
||||||
private Map<State,Color> mForegroundColors = new HashMap<>();
|
private Map<State,Color> mForegroundColors = new HashMap<>();
|
||||||
|
private JTableColumnWidthMonitor mTableColumnMonitor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Table view for currently decoding channel metadata
|
* Table view for currently decoding channel metadata
|
||||||
@@ -108,6 +111,9 @@ public class ChannelMetadataPanel extends JPanel implements ListSelectionListene
|
|||||||
mTable.getColumnModel().getColumn(ChannelMetadataModel.COLUMN_CONFIGURATION_FREQUENCY)
|
mTable.getColumnModel().getColumn(ChannelMetadataModel.COLUMN_CONFIGURATION_FREQUENCY)
|
||||||
.setCellRenderer(new FrequencyCellRenderer());
|
.setCellRenderer(new FrequencyCellRenderer());
|
||||||
|
|
||||||
|
//Add a table column width monitor to store/restore column widths
|
||||||
|
mTableColumnMonitor = new JTableColumnWidthMonitor(mUserPreferences, mTable, TABLE_PREFERENCE_KEY);
|
||||||
|
|
||||||
JScrollPane scrollPane = new JScrollPane(mTable, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
|
JScrollPane scrollPane = new JScrollPane(mTable, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
|
||||||
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
|
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
/*******************************************************************************
|
/*
|
||||||
|
* ******************************************************************************
|
||||||
* sdrtrunk
|
* sdrtrunk
|
||||||
* Copyright (C) 2014-2017 Dennis Sheirer
|
* Copyright (C) 2014-2019 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -14,8 +15,8 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
*
|
* *****************************************************************************
|
||||||
******************************************************************************/
|
*/
|
||||||
package io.github.dsheirer.channel.metadata;
|
package io.github.dsheirer.channel.metadata;
|
||||||
|
|
||||||
import com.jidesoft.swing.JideSplitPane;
|
import com.jidesoft.swing.JideSplitPane;
|
||||||
@@ -33,10 +34,9 @@ import net.miginfocom.swing.MigLayout;
|
|||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
|
|
||||||
public class ChannelMetadataViewer extends JPanel
|
public class NowPlayingPanel extends JPanel
|
||||||
{
|
{
|
||||||
private ChannelMetadataPanel mChannelMetadataPanel;
|
private ChannelMetadataPanel mChannelMetadataPanel;
|
||||||
|
|
||||||
private ChannelDetailPanel mChannelDetailPanel;
|
private ChannelDetailPanel mChannelDetailPanel;
|
||||||
private DecodeEventPanel mDecodeEventPanel;
|
private DecodeEventPanel mDecodeEventPanel;
|
||||||
private MessageActivityPanel mMessageActivityPanel;
|
private MessageActivityPanel mMessageActivityPanel;
|
||||||
@@ -45,12 +45,12 @@ public class ChannelMetadataViewer extends JPanel
|
|||||||
* GUI panel that combines the currently decoding channels metadata table and viewers for channel details,
|
* GUI panel that combines the currently decoding channels metadata table and viewers for channel details,
|
||||||
* messages, events, and spectral view.
|
* messages, events, and spectral view.
|
||||||
*/
|
*/
|
||||||
public ChannelMetadataViewer(ChannelModel channelModel, ChannelProcessingManager channelProcessingManager,
|
public NowPlayingPanel(ChannelModel channelModel, ChannelProcessingManager channelProcessingManager,
|
||||||
IconManager iconManager, AliasModel aliasModel, UserPreferences userPreferences)
|
IconManager iconManager, AliasModel aliasModel, UserPreferences userPreferences)
|
||||||
{
|
{
|
||||||
mChannelDetailPanel = new ChannelDetailPanel(channelProcessingManager);
|
mChannelDetailPanel = new ChannelDetailPanel(channelProcessingManager);
|
||||||
mDecodeEventPanel = new DecodeEventPanel(iconManager, userPreferences, aliasModel);
|
mDecodeEventPanel = new DecodeEventPanel(iconManager, userPreferences, aliasModel);
|
||||||
mMessageActivityPanel = new MessageActivityPanel(channelProcessingManager);
|
mMessageActivityPanel = new MessageActivityPanel(userPreferences);
|
||||||
mChannelMetadataPanel = new ChannelMetadataPanel(channelModel, channelProcessingManager, iconManager, userPreferences);
|
mChannelMetadataPanel = new ChannelMetadataPanel(channelModel, channelProcessingManager, iconManager, userPreferences);
|
||||||
|
|
||||||
init();
|
init();
|
||||||
@@ -64,7 +64,6 @@ public class ChannelMetadataViewer extends JPanel
|
|||||||
tabbedPane.addTab("Details", mChannelDetailPanel);
|
tabbedPane.addTab("Details", mChannelDetailPanel);
|
||||||
tabbedPane.addTab("Events", mDecodeEventPanel);
|
tabbedPane.addTab("Events", mDecodeEventPanel);
|
||||||
tabbedPane.addTab("Messages", mMessageActivityPanel);
|
tabbedPane.addTab("Messages", mMessageActivityPanel);
|
||||||
// tabbedPane.addTab("Spectrum", mChannelSpectrumPanel);
|
|
||||||
tabbedPane.setFont(this.getFont());
|
tabbedPane.setFont(this.getFont());
|
||||||
tabbedPane.setForeground(Color.BLACK);
|
tabbedPane.setForeground(Color.BLACK);
|
||||||
|
|
||||||
@@ -28,6 +28,7 @@ import io.github.dsheirer.controller.channel.Channel;
|
|||||||
import io.github.dsheirer.controller.channel.Channel.ChannelType;
|
import io.github.dsheirer.controller.channel.Channel.ChannelType;
|
||||||
import io.github.dsheirer.controller.channel.ChannelEvent;
|
import io.github.dsheirer.controller.channel.ChannelEvent;
|
||||||
import io.github.dsheirer.controller.channel.IChannelEventProvider;
|
import io.github.dsheirer.controller.channel.IChannelEventProvider;
|
||||||
|
import io.github.dsheirer.identifier.IdentifierClass;
|
||||||
import io.github.dsheirer.identifier.IdentifierUpdateListener;
|
import io.github.dsheirer.identifier.IdentifierUpdateListener;
|
||||||
import io.github.dsheirer.identifier.IdentifierUpdateNotification;
|
import io.github.dsheirer.identifier.IdentifierUpdateNotification;
|
||||||
import io.github.dsheirer.identifier.IdentifierUpdateProvider;
|
import io.github.dsheirer.identifier.IdentifierUpdateProvider;
|
||||||
@@ -203,6 +204,7 @@ public class ChannelState extends Module implements IChannelEventProvider, IDeco
|
|||||||
{
|
{
|
||||||
mState = State.IDLE;
|
mState = State.IDLE;
|
||||||
broadcast(new DecoderStateEvent(this, Event.RESET, State.IDLE));
|
broadcast(new DecoderStateEvent(this, Event.RESET, State.IDLE));
|
||||||
|
mIdentifierCollection.remove(IdentifierClass.USER);
|
||||||
mIdentifierCollection.update(ChannelStateIdentifier.IDLE);
|
mIdentifierCollection.update(ChannelStateIdentifier.IDLE);
|
||||||
mSourceOverflow = false;
|
mSourceOverflow = false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
/*******************************************************************************
|
/*
|
||||||
|
* ******************************************************************************
|
||||||
* sdrtrunk
|
* sdrtrunk
|
||||||
* Copyright (C) 2014-2017 Dennis Sheirer
|
* Copyright (C) 2014-2019 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -14,8 +15,8 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
*
|
* *****************************************************************************
|
||||||
******************************************************************************/
|
*/
|
||||||
package io.github.dsheirer.controller;
|
package io.github.dsheirer.controller;
|
||||||
|
|
||||||
import com.jidesoft.swing.JideTabbedPane;
|
import com.jidesoft.swing.JideTabbedPane;
|
||||||
@@ -25,7 +26,7 @@ import io.github.dsheirer.audio.broadcast.BroadcastModel;
|
|||||||
import io.github.dsheirer.audio.broadcast.BroadcastPanel;
|
import io.github.dsheirer.audio.broadcast.BroadcastPanel;
|
||||||
import io.github.dsheirer.audio.playback.AudioPanel;
|
import io.github.dsheirer.audio.playback.AudioPanel;
|
||||||
import io.github.dsheirer.audio.playback.AudioPlaybackManager;
|
import io.github.dsheirer.audio.playback.AudioPlaybackManager;
|
||||||
import io.github.dsheirer.channel.metadata.ChannelMetadataViewer;
|
import io.github.dsheirer.channel.metadata.NowPlayingPanel;
|
||||||
import io.github.dsheirer.controller.channel.ChannelController;
|
import io.github.dsheirer.controller.channel.ChannelController;
|
||||||
import io.github.dsheirer.controller.channel.ChannelModel;
|
import io.github.dsheirer.controller.channel.ChannelModel;
|
||||||
import io.github.dsheirer.controller.channel.ChannelProcessingManager;
|
import io.github.dsheirer.controller.channel.ChannelProcessingManager;
|
||||||
@@ -41,7 +42,6 @@ import io.github.dsheirer.source.tuner.TunerViewPanel;
|
|||||||
import net.miginfocom.swing.MigLayout;
|
import net.miginfocom.swing.MigLayout;
|
||||||
|
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
import javax.swing.JTable;
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
|
|
||||||
@@ -53,27 +53,18 @@ public class ControllerPanel extends JPanel
|
|||||||
private AudioPanel mAudioPanel;
|
private AudioPanel mAudioPanel;
|
||||||
private BroadcastPanel mBroadcastPanel;
|
private BroadcastPanel mBroadcastPanel;
|
||||||
private ChannelController mChannelController;
|
private ChannelController mChannelController;
|
||||||
private ChannelMetadataViewer mChannelMetadataViewer;
|
private NowPlayingPanel mNowPlayingPanel;
|
||||||
private ChannelModel mChannelModel;
|
private ChannelModel mChannelModel;
|
||||||
private MapPanel mMapPanel;
|
private MapPanel mMapPanel;
|
||||||
private TunerViewPanel mTunerManagerPanel;
|
private TunerViewPanel mTunerManagerPanel;
|
||||||
private BroadcastModel mBroadcastModel;
|
private BroadcastModel mBroadcastModel;
|
||||||
|
|
||||||
private JideTabbedPane mTabbedPane;
|
private JideTabbedPane mTabbedPane;
|
||||||
protected JTable mChannelActivityTable = new JTable();
|
|
||||||
|
|
||||||
public ControllerPanel(AudioPlaybackManager audioPlaybackManager,
|
public ControllerPanel(AudioPlaybackManager audioPlaybackManager, AliasModel aliasModel, BroadcastModel broadcastModel,
|
||||||
AliasModel aliasModel,
|
ChannelModel channelModel, ChannelMapModel channelMapModel, ChannelProcessingManager channelProcessingManager,
|
||||||
BroadcastModel broadcastModel,
|
IconManager iconManager, MapService mapService, SettingsManager settingsManager,
|
||||||
ChannelModel channelModel,
|
SourceManager sourceManager, TunerModel tunerModel, UserPreferences userPreferences)
|
||||||
ChannelMapModel channelMapModel,
|
|
||||||
ChannelProcessingManager channelProcessingManager,
|
|
||||||
IconManager iconManager,
|
|
||||||
MapService mapService,
|
|
||||||
SettingsManager settingsManager,
|
|
||||||
SourceManager sourceManager,
|
|
||||||
TunerModel tunerModel,
|
|
||||||
UserPreferences userPreferences)
|
|
||||||
{
|
{
|
||||||
mBroadcastModel = broadcastModel;
|
mBroadcastModel = broadcastModel;
|
||||||
mChannelModel = channelModel;
|
mChannelModel = channelModel;
|
||||||
@@ -81,19 +72,19 @@ public class ControllerPanel extends JPanel
|
|||||||
mAudioPanel = new AudioPanel(iconManager, userPreferences, settingsManager, sourceManager, audioPlaybackManager,
|
mAudioPanel = new AudioPanel(iconManager, userPreferences, settingsManager, sourceManager, audioPlaybackManager,
|
||||||
aliasModel);
|
aliasModel);
|
||||||
|
|
||||||
mChannelMetadataViewer = new ChannelMetadataViewer(channelModel, channelProcessingManager, iconManager,
|
mNowPlayingPanel = new NowPlayingPanel(channelModel, channelProcessingManager, iconManager,
|
||||||
aliasModel, userPreferences);
|
aliasModel, userPreferences);
|
||||||
|
|
||||||
mMapPanel = new MapPanel(mapService, aliasModel, iconManager, settingsManager);
|
mMapPanel = new MapPanel(mapService, aliasModel, iconManager, settingsManager);
|
||||||
|
|
||||||
mBroadcastPanel = new BroadcastPanel(broadcastModel, aliasModel, iconManager);
|
mBroadcastPanel = new BroadcastPanel(broadcastModel, aliasModel, iconManager, userPreferences);
|
||||||
|
|
||||||
mChannelController = new ChannelController(channelModel, channelProcessingManager, channelMapModel,
|
mChannelController = new ChannelController(channelModel, channelProcessingManager, channelMapModel,
|
||||||
sourceManager, aliasModel);
|
sourceManager, aliasModel, userPreferences);
|
||||||
|
|
||||||
mAliasController = new AliasController(aliasModel, broadcastModel, iconManager);
|
mAliasController = new AliasController(aliasModel, broadcastModel, iconManager, userPreferences);
|
||||||
|
|
||||||
mTunerManagerPanel = new TunerViewPanel(tunerModel);
|
mTunerManagerPanel = new TunerViewPanel(tunerModel, userPreferences);
|
||||||
|
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
@@ -108,7 +99,7 @@ public class ControllerPanel extends JPanel
|
|||||||
mTabbedPane = new JideTabbedPane();
|
mTabbedPane = new JideTabbedPane();
|
||||||
mTabbedPane.setFont(this.getFont());
|
mTabbedPane.setFont(this.getFont());
|
||||||
mTabbedPane.setForeground(Color.BLACK);
|
mTabbedPane.setForeground(Color.BLACK);
|
||||||
mTabbedPane.addTab("Now Playing", mChannelMetadataViewer);
|
mTabbedPane.addTab("Now Playing", mNowPlayingPanel);
|
||||||
mTabbedPane.addTab("Aliases", mAliasController);
|
mTabbedPane.addTab("Aliases", mAliasController);
|
||||||
mTabbedPane.addTab("Channels", mChannelController);
|
mTabbedPane.addTab("Channels", mChannelController);
|
||||||
mTabbedPane.addTab("Map", mMapPanel);
|
mTabbedPane.addTab("Map", mMapPanel);
|
||||||
|
|||||||
@@ -1,23 +1,29 @@
|
|||||||
/*******************************************************************************
|
/*
|
||||||
* sdr-trunk
|
* ******************************************************************************
|
||||||
* Copyright (C) 2014-2018 Dennis Sheirer
|
* 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
|
* This program is free software: you can redistribute it and/or modify
|
||||||
* License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any
|
* it under the terms of the GNU General Public License as published by
|
||||||
* later version.
|
* 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
|
* This program is distributed in the hope that it will be useful,
|
||||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
* 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.
|
* You should have received a copy of the GNU General Public License
|
||||||
* If not, see <http://www.gnu.org/licenses/>
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
*
|
* *****************************************************************************
|
||||||
******************************************************************************/
|
*/
|
||||||
package io.github.dsheirer.controller.channel;
|
package io.github.dsheirer.controller.channel;
|
||||||
|
|
||||||
import com.jidesoft.swing.JideSplitPane;
|
import com.jidesoft.swing.JideSplitPane;
|
||||||
import io.github.dsheirer.alias.AliasModel;
|
import io.github.dsheirer.alias.AliasModel;
|
||||||
import io.github.dsheirer.controller.channel.map.ChannelMapModel;
|
import io.github.dsheirer.controller.channel.map.ChannelMapModel;
|
||||||
|
import io.github.dsheirer.preference.UserPreferences;
|
||||||
|
import io.github.dsheirer.preference.swing.JTableColumnWidthMonitor;
|
||||||
import io.github.dsheirer.source.SourceManager;
|
import io.github.dsheirer.source.SourceManager;
|
||||||
import net.coderazzi.filters.gui.AutoChoices;
|
import net.coderazzi.filters.gui.AutoChoices;
|
||||||
import net.coderazzi.filters.gui.TableFilterHeader;
|
import net.coderazzi.filters.gui.TableFilterHeader;
|
||||||
@@ -43,11 +49,14 @@ public class ChannelController extends JPanel implements ActionListener, ListSel
|
|||||||
{
|
{
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private static final String TABLE_PREFERENCE_KEY = "channel.controller";
|
||||||
private ChannelModel mChannelModel;
|
private ChannelModel mChannelModel;
|
||||||
private ChannelProcessingManager mChannelProcessingManager;
|
private ChannelProcessingManager mChannelProcessingManager;
|
||||||
private JTable mChannelTable;
|
private JTable mChannelTable;
|
||||||
|
private JTableColumnWidthMonitor mColumnWidthMonitor;
|
||||||
private TableFilterHeader mTableFilterHeader;
|
private TableFilterHeader mTableFilterHeader;
|
||||||
private ChannelEditor mEditor;
|
private ChannelEditor mEditor;
|
||||||
|
private UserPreferences mUserPreferences;
|
||||||
|
|
||||||
private static final String NEW_CHANNEL = "New";
|
private static final String NEW_CHANNEL = "New";
|
||||||
private static final String COPY_CHANNEL = "Copy";
|
private static final String COPY_CHANNEL = "Copy";
|
||||||
@@ -57,17 +66,16 @@ public class ChannelController extends JPanel implements ActionListener, ListSel
|
|||||||
private JButton mCopyChannelButton = new JButton(COPY_CHANNEL);
|
private JButton mCopyChannelButton = new JButton(COPY_CHANNEL);
|
||||||
private JButton mDeleteChannelButton = new JButton(DELETE_CHANNEL);
|
private JButton mDeleteChannelButton = new JButton(DELETE_CHANNEL);
|
||||||
|
|
||||||
public ChannelController(ChannelModel channelModel,
|
public ChannelController(ChannelModel channelModel, ChannelProcessingManager channelProcessingManager,
|
||||||
ChannelProcessingManager channelProcessingManager,
|
ChannelMapModel channelMapModel, SourceManager sourceManager, AliasModel aliasModel,
|
||||||
ChannelMapModel channelMapModel,
|
UserPreferences userPreferences)
|
||||||
SourceManager sourceManager,
|
|
||||||
AliasModel aliasModel)
|
|
||||||
{
|
{
|
||||||
mChannelModel = channelModel;
|
mChannelModel = channelModel;
|
||||||
mChannelProcessingManager = channelProcessingManager;
|
mChannelProcessingManager = channelProcessingManager;
|
||||||
mEditor = new ChannelEditor(channelModel, channelProcessingManager, channelMapModel, sourceManager, aliasModel);
|
mEditor = new ChannelEditor(channelModel, channelProcessingManager, channelMapModel, sourceManager, aliasModel);
|
||||||
mChannelModel.addListener(mEditor);
|
mChannelModel.addListener(mEditor);
|
||||||
mChannelProcessingManager.addChannelEventListener(mEditor);
|
mChannelProcessingManager.addChannelEventListener(mEditor);
|
||||||
|
mUserPreferences = userPreferences;
|
||||||
|
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
@@ -82,6 +90,7 @@ public class ChannelController extends JPanel implements ActionListener, ListSel
|
|||||||
mChannelTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
mChannelTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||||
mChannelTable.getSelectionModel().addListSelectionListener(this);
|
mChannelTable.getSelectionModel().addListSelectionListener(this);
|
||||||
mChannelTable.setAutoCreateRowSorter(true);
|
mChannelTable.setAutoCreateRowSorter(true);
|
||||||
|
mColumnWidthMonitor = new JTableColumnWidthMonitor(mUserPreferences, mChannelTable, TABLE_PREFERENCE_KEY);
|
||||||
|
|
||||||
mTableFilterHeader = new TableFilterHeader(mChannelTable, AutoChoices.ENABLED);
|
mTableFilterHeader = new TableFilterHeader(mChannelTable, AutoChoices.ENABLED);
|
||||||
mTableFilterHeader.setFilterOnUpdates(true);
|
mTableFilterHeader.setFilterOnUpdates(true);
|
||||||
|
|||||||
@@ -1,21 +1,23 @@
|
|||||||
/*
|
/*
|
||||||
* ******************************************************************************
|
|
||||||
* 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
|
* * Copyright (C) 2014-2019 Dennis Sheirer
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* *
|
||||||
* (at your option) any later version.
|
* * 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.gui;
|
package io.github.dsheirer.gui;
|
||||||
|
|
||||||
@@ -78,6 +80,7 @@ import java.awt.AWTException;
|
|||||||
import java.awt.Desktop;
|
import java.awt.Desktop;
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.awt.EventQueue;
|
import java.awt.EventQueue;
|
||||||
|
import java.awt.Point;
|
||||||
import java.awt.Robot;
|
import java.awt.Robot;
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
@@ -97,8 +100,12 @@ public class SDRTrunk implements Listener<TunerEvent>
|
|||||||
private final static Logger mLog = LoggerFactory.getLogger(SDRTrunk.class);
|
private final static Logger mLog = LoggerFactory.getLogger(SDRTrunk.class);
|
||||||
|
|
||||||
private static final String PROPERTY_BROADCAST_STATUS_VISIBLE = "main.broadcast.status.visible";
|
private static final String PROPERTY_BROADCAST_STATUS_VISIBLE = "main.broadcast.status.visible";
|
||||||
private boolean mBroadcastStatusVisible;
|
private static final String BASE_WINDOW_NAME = "sdrtrunk.main.window";
|
||||||
|
private static final String CONTROLLER_PANEL_IDENTIFIER = BASE_WINDOW_NAME + ".control.panel";
|
||||||
|
private static final String SPECTRAL_PANEL_IDENTIFIER = BASE_WINDOW_NAME + ".spectral.panel";
|
||||||
|
private static final String WINDOW_FRAME_IDENTIFIER = BASE_WINDOW_NAME + ".frame";
|
||||||
|
|
||||||
|
private boolean mBroadcastStatusVisible;
|
||||||
private AudioPacketManager mAudioPacketManager;
|
private AudioPacketManager mAudioPacketManager;
|
||||||
private IconManager mIconManager;
|
private IconManager mIconManager;
|
||||||
private BroadcastStatusPanel mBroadcastStatusPanel;
|
private BroadcastStatusPanel mBroadcastStatusPanel;
|
||||||
@@ -271,15 +278,45 @@ public class SDRTrunk implements Listener<TunerEvent>
|
|||||||
*/
|
*/
|
||||||
mTitle = SystemProperties.getInstance().getApplicationName();
|
mTitle = SystemProperties.getInstance().getApplicationName();
|
||||||
mMainGui.setTitle(mTitle);
|
mMainGui.setTitle(mTitle);
|
||||||
mMainGui.setSize(new Dimension(1280, 800));
|
|
||||||
mMainGui.setLocationRelativeTo(null);
|
Point location = mUserPreferences.getSwingPreference().getLocation(WINDOW_FRAME_IDENTIFIER);
|
||||||
|
if(location != null)
|
||||||
|
{
|
||||||
|
mMainGui.setLocation(location);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mMainGui.setLocationRelativeTo(null);
|
||||||
|
}
|
||||||
mMainGui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
mMainGui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||||
mMainGui.addWindowListener(new ShutdownMonitor());
|
mMainGui.addWindowListener(new ShutdownMonitor());
|
||||||
|
|
||||||
//Set preferred sizes to influence the split
|
Dimension dimension = mUserPreferences.getSwingPreference().getDimension(WINDOW_FRAME_IDENTIFIER);
|
||||||
|
|
||||||
mSpectralPanel.setPreferredSize(new Dimension(1280, 300));
|
mSpectralPanel.setPreferredSize(new Dimension(1280, 300));
|
||||||
mControllerPanel.setPreferredSize(new Dimension(1280, 500));
|
mControllerPanel.setPreferredSize(new Dimension(1280, 500));
|
||||||
|
|
||||||
|
if(dimension != null)
|
||||||
|
{
|
||||||
|
Dimension spectral = mUserPreferences.getSwingPreference().getDimension(SPECTRAL_PANEL_IDENTIFIER);
|
||||||
|
if(spectral != null)
|
||||||
|
{
|
||||||
|
mSpectralPanel.setSize(spectral);
|
||||||
|
}
|
||||||
|
|
||||||
|
Dimension controller = mUserPreferences.getSwingPreference().getDimension(CONTROLLER_PANEL_IDENTIFIER);
|
||||||
|
if(controller != null)
|
||||||
|
{
|
||||||
|
mControllerPanel.setSize(controller);
|
||||||
|
}
|
||||||
|
|
||||||
|
mMainGui.setSize(dimension);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mMainGui.setSize(new Dimension(1280, 800));
|
||||||
|
}
|
||||||
|
|
||||||
mSplitPane = new JideSplitPane(JideSplitPane.VERTICAL_SPLIT);
|
mSplitPane = new JideSplitPane(JideSplitPane.VERTICAL_SPLIT);
|
||||||
mSplitPane.setDividerSize(5);
|
mSplitPane.setDividerSize(5);
|
||||||
mSplitPane.add(mSpectralPanel);
|
mSplitPane.add(mSpectralPanel);
|
||||||
@@ -360,9 +397,9 @@ public class SDRTrunk implements Listener<TunerEvent>
|
|||||||
viewMenu.add(new BroadcastStatusVisibleMenuItem(mControllerPanel));
|
viewMenu.add(new BroadcastStatusVisibleMenuItem(mControllerPanel));
|
||||||
viewMenu.add(new JSeparator());
|
viewMenu.add(new JSeparator());
|
||||||
|
|
||||||
for(Tuner tuner: mSourceManager.getTunerModel().getTuners())
|
for(Tuner tuner : mSourceManager.getTunerModel().getTuners())
|
||||||
{
|
{
|
||||||
viewMenu.add(new ShowTunerMenuItem(mSpectralPanel, tuner));
|
viewMenu.add(new ShowTunerMenuItem(mSourceManager.getTunerModel(), tuner));
|
||||||
}
|
}
|
||||||
|
|
||||||
viewMenu.add(new JSeparator());
|
viewMenu.add(new JSeparator());
|
||||||
@@ -371,7 +408,7 @@ public class SDRTrunk implements Listener<TunerEvent>
|
|||||||
viewMenu.add(new JSeparator());
|
viewMenu.add(new JSeparator());
|
||||||
JMenuItem preferencesItem = new JMenuItem("Preferences");
|
JMenuItem preferencesItem = new JMenuItem("Preferences");
|
||||||
preferencesItem.addActionListener(e -> MyEventBus.getEventBus()
|
preferencesItem.addActionListener(e -> MyEventBus.getEventBus()
|
||||||
.post(new PreferenceEditorViewRequest(PreferenceEditorType.CHANNEL_EVENT)));
|
.post(new PreferenceEditorViewRequest(PreferenceEditorType.CHANNEL_EVENT)));
|
||||||
viewMenu.add(preferencesItem);
|
viewMenu.add(preferencesItem);
|
||||||
|
|
||||||
menuBar.add(viewMenu);
|
menuBar.add(viewMenu);
|
||||||
@@ -424,6 +461,10 @@ public class SDRTrunk implements Listener<TunerEvent>
|
|||||||
private void processShutdown()
|
private void processShutdown()
|
||||||
{
|
{
|
||||||
mLog.info("Application shutdown started ...");
|
mLog.info("Application shutdown started ...");
|
||||||
|
mUserPreferences.getSwingPreference().setLocation(WINDOW_FRAME_IDENTIFIER, mMainGui.getLocation());
|
||||||
|
mUserPreferences.getSwingPreference().setDimension(WINDOW_FRAME_IDENTIFIER, mMainGui.getSize());
|
||||||
|
mUserPreferences.getSwingPreference().setDimension(SPECTRAL_PANEL_IDENTIFIER, mSpectralPanel.getSize());
|
||||||
|
mUserPreferences.getSwingPreference().setDimension(CONTROLLER_PANEL_IDENTIFIER, mControllerPanel.getSize());
|
||||||
mJavaFxWindowManager.shutdown();
|
mJavaFxWindowManager.shutdown();
|
||||||
mLog.info("Stopping channels ...");
|
mLog.info("Stopping channels ...");
|
||||||
mChannelProcessingManager.shutdown();
|
mChannelProcessingManager.shutdown();
|
||||||
@@ -443,7 +484,8 @@ public class SDRTrunk implements Listener<TunerEvent>
|
|||||||
{
|
{
|
||||||
if(mBroadcastStatusPanel == null)
|
if(mBroadcastStatusPanel == null)
|
||||||
{
|
{
|
||||||
mBroadcastStatusPanel = new BroadcastStatusPanel(mBroadcastModel);
|
mBroadcastStatusPanel = new BroadcastStatusPanel(mBroadcastModel, mUserPreferences,
|
||||||
|
"application.broadcast.status.panel");
|
||||||
mBroadcastStatusPanel.setPreferredSize(new Dimension(880, 70));
|
mBroadcastStatusPanel.setPreferredSize(new Dimension(880, 70));
|
||||||
mBroadcastStatusPanel.getTable().setEnabled(false);
|
mBroadcastStatusPanel.getTable().setEnabled(false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* ******************************************************************************
|
* ******************************************************************************
|
||||||
* sdrtrunk
|
* sdrtrunk
|
||||||
* Copyright (C) 2014-2018 Dennis Sheirer
|
* Copyright (C) 2014-2019 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -84,7 +84,7 @@ public class IdentifierCollection
|
|||||||
return mUpdated;
|
return mUpdated;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void setUpdated(boolean updated)
|
public void setUpdated(boolean updated)
|
||||||
{
|
{
|
||||||
mUpdated = updated;
|
mUpdated = updated;
|
||||||
}
|
}
|
||||||
@@ -114,6 +114,14 @@ public class IdentifierCollection
|
|||||||
return Collections.unmodifiableList(mIdentifiers);
|
return Collections.unmodifiableList(mIdentifiers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates if this collection has no identifiers
|
||||||
|
*/
|
||||||
|
public boolean isEmpty()
|
||||||
|
{
|
||||||
|
return mIdentifiers.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a list of identifiers by identifier class from this collection.
|
* Get a list of identifiers by identifier class from this collection.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ package io.github.dsheirer.identifier;
|
|||||||
|
|
||||||
import io.github.dsheirer.identifier.configuration.AliasListConfigurationIdentifier;
|
import io.github.dsheirer.identifier.configuration.AliasListConfigurationIdentifier;
|
||||||
import io.github.dsheirer.sample.Listener;
|
import io.github.dsheirer.sample.Listener;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
@@ -32,6 +34,7 @@ import java.util.Iterator;
|
|||||||
public class MutableIdentifierCollection extends IdentifierCollection implements IdentifierUpdateProvider,
|
public class MutableIdentifierCollection extends IdentifierCollection implements IdentifierUpdateProvider,
|
||||||
Listener<IdentifierUpdateNotification>
|
Listener<IdentifierUpdateNotification>
|
||||||
{
|
{
|
||||||
|
private final static Logger mLog = LoggerFactory.getLogger(MutableIdentifierCollection.class);
|
||||||
private Listener<IdentifierUpdateNotification> mListener;
|
private Listener<IdentifierUpdateNotification> mListener;
|
||||||
|
|
||||||
public MutableIdentifierCollection()
|
public MutableIdentifierCollection()
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* ******************************************************************************
|
* ******************************************************************************
|
||||||
* sdrtrunk
|
* sdrtrunk
|
||||||
* Copyright (C) 2014-2018 Dennis Sheirer
|
* Copyright (C) 2014-2019 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -23,7 +23,6 @@ package io.github.dsheirer.identifier.patch;
|
|||||||
import io.github.dsheirer.identifier.Identifier;
|
import io.github.dsheirer.identifier.Identifier;
|
||||||
import io.github.dsheirer.identifier.IdentifierClass;
|
import io.github.dsheirer.identifier.IdentifierClass;
|
||||||
import io.github.dsheirer.identifier.Role;
|
import io.github.dsheirer.identifier.Role;
|
||||||
import io.github.dsheirer.identifier.talkgroup.TalkgroupIdentifier;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@@ -32,6 +31,14 @@ import java.util.Map;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Manager for (temporary) patch groups and related identifiers.
|
* Manager for (temporary) patch groups and related identifiers.
|
||||||
|
*
|
||||||
|
* Patch groups are primarily used on Motorola P25 systems. This manager monitors patch group additions and deletions
|
||||||
|
* and maintains a map of the current patch groups.
|
||||||
|
*
|
||||||
|
* Traffic channel calls will sometimes reference a patch group by simply using the patch group identifier. This
|
||||||
|
* manager will replace that reference with the full patch group so that the call event has the full patch group
|
||||||
|
* including all of the patched groups, which may not have been included in the patch group reference on the
|
||||||
|
* traffic channel.
|
||||||
*/
|
*/
|
||||||
public class PatchGroupManager
|
public class PatchGroupManager
|
||||||
{
|
{
|
||||||
@@ -127,7 +134,7 @@ public class PatchGroupManager
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks the TALKGROUP or PATCH GROUP identifier and replaces the identifier with the current patch group
|
* Checks the PATCH GROUP identifier and replaces the identifier with the current patch group
|
||||||
* if the identifier matches a currently managed patch group.
|
* if the identifier matches a currently managed patch group.
|
||||||
*
|
*
|
||||||
* @param identifier for a talkgroup or a patch group.
|
* @param identifier for a talkgroup or a patch group.
|
||||||
@@ -144,22 +151,6 @@ public class PatchGroupManager
|
|||||||
{
|
{
|
||||||
switch(identifier.getForm())
|
switch(identifier.getForm())
|
||||||
{
|
{
|
||||||
case TALKGROUP:
|
|
||||||
if(identifier instanceof TalkgroupIdentifier)
|
|
||||||
{
|
|
||||||
TalkgroupIdentifier tgi = (TalkgroupIdentifier)identifier;
|
|
||||||
|
|
||||||
if(tgi.isGroup())
|
|
||||||
{
|
|
||||||
int talkgroupId = ((TalkgroupIdentifier)identifier).getValue();
|
|
||||||
|
|
||||||
if(mPatchGroupMap.containsKey(talkgroupId))
|
|
||||||
{
|
|
||||||
return mPatchGroupMap.get(talkgroupId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case PATCH_GROUP:
|
case PATCH_GROUP:
|
||||||
if(identifier instanceof PatchGroupIdentifier)
|
if(identifier instanceof PatchGroupIdentifier)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* ******************************************************************************
|
* ******************************************************************************
|
||||||
* sdrtrunk
|
* sdrtrunk
|
||||||
* Copyright (C) 2014-2018 Dennis Sheirer
|
* Copyright (C) 2014-2019 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -34,6 +34,7 @@ import io.github.dsheirer.identifier.Role;
|
|||||||
import io.github.dsheirer.module.ProcessingChain;
|
import io.github.dsheirer.module.ProcessingChain;
|
||||||
import io.github.dsheirer.preference.PreferenceType;
|
import io.github.dsheirer.preference.PreferenceType;
|
||||||
import io.github.dsheirer.preference.UserPreferences;
|
import io.github.dsheirer.preference.UserPreferences;
|
||||||
|
import io.github.dsheirer.preference.swing.JTableColumnWidthMonitor;
|
||||||
import io.github.dsheirer.sample.Listener;
|
import io.github.dsheirer.sample.Listener;
|
||||||
import net.miginfocom.swing.MigLayout;
|
import net.miginfocom.swing.MigLayout;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@@ -55,10 +56,12 @@ import java.util.List;
|
|||||||
|
|
||||||
public class DecodeEventPanel extends JPanel implements Listener<ProcessingChain>
|
public class DecodeEventPanel extends JPanel implements Listener<ProcessingChain>
|
||||||
{
|
{
|
||||||
private final static Logger mLog = LoggerFactory.getLogger(DecodeEventPanel.class);
|
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
private final static Logger mLog = LoggerFactory.getLogger(DecodeEventPanel.class);
|
||||||
|
private static final String TABLE_PREFERENCE_KEY = "decode.event.panel";
|
||||||
|
|
||||||
private JTable mTable;
|
private JTable mTable;
|
||||||
|
private JTableColumnWidthMonitor mTableColumnWidthMonitor;
|
||||||
private DecodeEventModel mEmptyDecodeEventModel;
|
private DecodeEventModel mEmptyDecodeEventModel;
|
||||||
private JScrollPane mEmptyScroller;
|
private JScrollPane mEmptyScroller;
|
||||||
private IconManager mIconManager;
|
private IconManager mIconManager;
|
||||||
@@ -83,6 +86,7 @@ public class DecodeEventPanel extends JPanel implements Listener<ProcessingChain
|
|||||||
mTable = new JTable(mEmptyDecodeEventModel);
|
mTable = new JTable(mEmptyDecodeEventModel);
|
||||||
mTable.setAutoCreateRowSorter(true);
|
mTable.setAutoCreateRowSorter(true);
|
||||||
mTable.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
|
mTable.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
|
||||||
|
mTableColumnWidthMonitor = new JTableColumnWidthMonitor(mUserPreferences, mTable, TABLE_PREFERENCE_KEY);
|
||||||
updateCellRenderers();
|
updateCellRenderers();
|
||||||
|
|
||||||
mEmptyScroller = new JScrollPane(mTable);
|
mEmptyScroller = new JScrollPane(mTable);
|
||||||
@@ -127,12 +131,17 @@ public class DecodeEventPanel extends JPanel implements Listener<ProcessingChain
|
|||||||
public void receive(ProcessingChain processingChain)
|
public void receive(ProcessingChain processingChain)
|
||||||
{
|
{
|
||||||
EventQueue.invokeLater(() -> {
|
EventQueue.invokeLater(() -> {
|
||||||
|
|
||||||
|
//Dispose the current column width monitor and recreate after we swap out the table model
|
||||||
|
mTableColumnWidthMonitor.dispose();
|
||||||
mTable.setModel(processingChain != null ? processingChain.getDecodeEventModel() : mEmptyDecodeEventModel);
|
mTable.setModel(processingChain != null ? processingChain.getDecodeEventModel() : mEmptyDecodeEventModel);
|
||||||
|
|
||||||
if(processingChain != null)
|
if(processingChain != null)
|
||||||
{
|
{
|
||||||
updateCellRenderers();
|
updateCellRenderers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mTableColumnWidthMonitor = new JTableColumnWidthMonitor(mUserPreferences, mTable, TABLE_PREFERENCE_KEY);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,17 +171,6 @@ public class DecodeEventPanel extends JPanel implements Listener<ProcessingChain
|
|||||||
if(value instanceof IdentifierCollection)
|
if(value instanceof IdentifierCollection)
|
||||||
{
|
{
|
||||||
List<Identifier> identifiers = ((IdentifierCollection)value).getIdentifiers(mRole);
|
List<Identifier> identifiers = ((IdentifierCollection)value).getIdentifiers(mRole);
|
||||||
|
|
||||||
// if(identifiers.size() > 1)
|
|
||||||
// {
|
|
||||||
// StringBuilder sb = new StringBuilder();
|
|
||||||
// sb.append("Multiple Identifiers:\n");
|
|
||||||
// for(Identifier identifier: identifiers)
|
|
||||||
// {
|
|
||||||
// sb.append("ID:").append(identifier.debug()).append("\n");
|
|
||||||
// }
|
|
||||||
// mLog.debug(sb.toString());
|
|
||||||
// }
|
|
||||||
label.setText(format(identifiers));
|
label.setText(format(identifiers));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
/*******************************************************************************
|
/*
|
||||||
|
* ******************************************************************************
|
||||||
* sdrtrunk
|
* sdrtrunk
|
||||||
* Copyright (C) 2014-2017 Dennis Sheirer
|
* Copyright (C) 2014-2019 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -14,17 +15,18 @@
|
|||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
*
|
* *****************************************************************************
|
||||||
******************************************************************************/
|
*/
|
||||||
package io.github.dsheirer.module.decode.event;
|
package io.github.dsheirer.module.decode.event;
|
||||||
|
|
||||||
import com.jidesoft.swing.JideButton;
|
import com.jidesoft.swing.JideButton;
|
||||||
import com.jidesoft.swing.JideSplitButton;
|
import com.jidesoft.swing.JideSplitButton;
|
||||||
import io.github.dsheirer.controller.channel.ChannelProcessingManager;
|
|
||||||
import io.github.dsheirer.filter.FilterEditorPanel;
|
import io.github.dsheirer.filter.FilterEditorPanel;
|
||||||
import io.github.dsheirer.filter.FilterSet;
|
import io.github.dsheirer.filter.FilterSet;
|
||||||
import io.github.dsheirer.message.IMessage;
|
import io.github.dsheirer.message.IMessage;
|
||||||
import io.github.dsheirer.module.ProcessingChain;
|
import io.github.dsheirer.module.ProcessingChain;
|
||||||
|
import io.github.dsheirer.preference.UserPreferences;
|
||||||
|
import io.github.dsheirer.preference.swing.JTableColumnWidthMonitor;
|
||||||
import io.github.dsheirer.sample.Listener;
|
import io.github.dsheirer.sample.Listener;
|
||||||
import net.miginfocom.swing.MigLayout;
|
import net.miginfocom.swing.MigLayout;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@@ -49,26 +51,24 @@ import java.awt.event.MouseListener;
|
|||||||
public class MessageActivityPanel extends JPanel implements Listener<ProcessingChain>
|
public class MessageActivityPanel extends JPanel implements Listener<ProcessingChain>
|
||||||
{
|
{
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
private final static Logger mLog = LoggerFactory.getLogger(MessageActivityPanel.class);
|
private final static Logger mLog = LoggerFactory.getLogger(MessageActivityPanel.class);
|
||||||
|
private static final String TABLE_PREFERENCE_KEY = "message.activity.panel";
|
||||||
private static MessageActivityModel EMPTY_MODEL = new MessageActivityModel();
|
private static MessageActivityModel EMPTY_MODEL = new MessageActivityModel();
|
||||||
|
|
||||||
private JTable mTable = new JTable(EMPTY_MODEL);
|
private JTable mTable = new JTable(EMPTY_MODEL);
|
||||||
|
private JTableColumnWidthMonitor mTableColumnWidthMonitor;
|
||||||
|
private UserPreferences mUserPreferences;
|
||||||
private MessageManagementPanel mManagementPanel = new MessageManagementPanel();
|
private MessageManagementPanel mManagementPanel = new MessageManagementPanel();
|
||||||
|
|
||||||
private ChannelProcessingManager mChannelProcessingManager;
|
public MessageActivityPanel(UserPreferences userPreferences)
|
||||||
|
|
||||||
public MessageActivityPanel(ChannelProcessingManager channelProcessingManager)
|
|
||||||
{
|
{
|
||||||
mChannelProcessingManager = channelProcessingManager;
|
mUserPreferences = userPreferences;
|
||||||
|
|
||||||
setLayout(new MigLayout("insets 0 0 0 0", "[][grow,fill]", "[]0[grow,fill]"));
|
setLayout(new MigLayout("insets 0 0 0 0", "[][grow,fill]", "[]0[grow,fill]"));
|
||||||
|
|
||||||
add(mManagementPanel, "span,growx");
|
add(mManagementPanel, "span,growx");
|
||||||
|
|
||||||
add(new JScrollPane(mTable), "span,grow");
|
add(new JScrollPane(mTable), "span,grow");
|
||||||
|
mTableColumnWidthMonitor = new JTableColumnWidthMonitor(mUserPreferences, mTable, TABLE_PREFERENCE_KEY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -79,6 +79,8 @@ public class MessageActivityPanel extends JPanel implements Listener<ProcessingC
|
|||||||
@Override
|
@Override
|
||||||
public void run()
|
public void run()
|
||||||
{
|
{
|
||||||
|
//Remove the existing table column width monitor and replace after swapping the table model
|
||||||
|
mTableColumnWidthMonitor.dispose();
|
||||||
mTable.setModel(processingChain != null ? processingChain.getMessageActivityModel() : EMPTY_MODEL);
|
mTable.setModel(processingChain != null ? processingChain.getMessageActivityModel() : EMPTY_MODEL);
|
||||||
|
|
||||||
mTable.getColumnModel().getColumn(0).setPreferredWidth(18);
|
mTable.getColumnModel().getColumn(0).setPreferredWidth(18);
|
||||||
@@ -93,6 +95,7 @@ public class MessageActivityPanel extends JPanel implements Listener<ProcessingC
|
|||||||
{
|
{
|
||||||
mManagementPanel.disableButtons();
|
mManagementPanel.disableButtons();
|
||||||
}
|
}
|
||||||
|
mTableColumnWidthMonitor = new JTableColumnWidthMonitor(mUserPreferences, mTable, TABLE_PREFERENCE_KEY);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* ******************************************************************************
|
* ******************************************************************************
|
||||||
* sdrtrunk
|
* sdrtrunk
|
||||||
* Copyright (C) 2014-2018 Dennis Sheirer
|
* Copyright (C) 2014-2019 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -33,8 +33,6 @@ import io.github.dsheirer.module.decode.p25.message.pdu.packet.sndcp.SNDCPPacket
|
|||||||
import io.github.dsheirer.module.decode.p25.reference.DataUnitID;
|
import io.github.dsheirer.module.decode.p25.reference.DataUnitID;
|
||||||
import io.github.dsheirer.module.decode.p25.reference.IPHeaderCompression;
|
import io.github.dsheirer.module.decode.p25.reference.IPHeaderCompression;
|
||||||
import io.github.dsheirer.module.decode.p25.reference.UDPHeaderCompression;
|
import io.github.dsheirer.module.decode.p25.reference.UDPHeaderCompression;
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -44,7 +42,7 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public class PacketMessage extends P25Message
|
public class PacketMessage extends P25Message
|
||||||
{
|
{
|
||||||
private final static Logger mLog = LoggerFactory.getLogger(PacketMessage.class);
|
// private final static Logger mLog = LoggerFactory.getLogger(PacketMessage.class);
|
||||||
|
|
||||||
private PDUSequence mPDUSequence;
|
private PDUSequence mPDUSequence;
|
||||||
private BinaryMessage mPayload;
|
private BinaryMessage mPayload;
|
||||||
@@ -88,7 +86,6 @@ public class PacketMessage extends P25Message
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
mLog.debug("***************** 2 byte SNDCP header with no data blocks header: " + getPDUSequence().getHeader().getMessage().toHexString());
|
|
||||||
mSNDCPPacketHeader = new SNDCPPacketHeader(getHeader().isOutbound());
|
mSNDCPPacketHeader = new SNDCPPacketHeader(getHeader().isOutbound());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -162,7 +159,7 @@ public class PacketMessage extends P25Message
|
|||||||
{
|
{
|
||||||
List<Integer> numbers = new ArrayList<>();
|
List<Integer> numbers = new ArrayList<>();
|
||||||
|
|
||||||
for(DataBlock dataBlock: getPDUSequence().getDataBlocks())
|
for(DataBlock dataBlock : getPDUSequence().getDataBlocks())
|
||||||
{
|
{
|
||||||
if(dataBlock instanceof ConfirmedDataBlock)
|
if(dataBlock instanceof ConfirmedDataBlock)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -371,8 +371,8 @@ public class P25NetworkConfigurationMonitor
|
|||||||
}
|
}
|
||||||
else if(mLCSystemServiceBroadcast != null)
|
else if(mLCSystemServiceBroadcast != null)
|
||||||
{
|
{
|
||||||
sb.append(" AVAILABLE SERVICES:").append(mTSBKSystemServiceBroadcast.getAvailableServices());
|
sb.append(" AVAILABLE SERVICES:").append(mLCSystemServiceBroadcast.getAvailableServices());
|
||||||
sb.append(" SUPPORTED SERVICES:").append(mTSBKSystemServiceBroadcast.getSupportedServices());
|
sb.append(" SUPPORTED SERVICES:").append(mLCSystemServiceBroadcast.getSupportedServices());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,21 +1,23 @@
|
|||||||
/*
|
/*
|
||||||
* ******************************************************************************
|
|
||||||
* 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
|
* * Copyright (C) 2014-2019 Dennis Sheirer
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* *
|
||||||
* (at your option) any later version.
|
* * 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.preference;
|
package io.github.dsheirer.preference;
|
||||||
@@ -26,9 +28,10 @@ package io.github.dsheirer.preference;
|
|||||||
public enum PreferenceType
|
public enum PreferenceType
|
||||||
{
|
{
|
||||||
DECODE_EVENT,
|
DECODE_EVENT,
|
||||||
JMBE_LIBRARY,
|
|
||||||
DIRECTORY,
|
DIRECTORY,
|
||||||
IDENTIFIER,
|
IDENTIFIER,
|
||||||
|
JMBE_LIBRARY,
|
||||||
MULTI_FREQUENCY,
|
MULTI_FREQUENCY,
|
||||||
|
RADIO_REFERENCE,
|
||||||
TUNER;
|
TUNER;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +1,23 @@
|
|||||||
/*
|
/*
|
||||||
* ******************************************************************************
|
|
||||||
* 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
|
* * Copyright (C) 2014-2019 Dennis Sheirer
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* *
|
||||||
* (at your option) any later version.
|
* * 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.preference;
|
package io.github.dsheirer.preference;
|
||||||
@@ -26,8 +28,10 @@ import io.github.dsheirer.preference.directory.DirectoryPreference;
|
|||||||
import io.github.dsheirer.preference.event.DecodeEventPreference;
|
import io.github.dsheirer.preference.event.DecodeEventPreference;
|
||||||
import io.github.dsheirer.preference.identifier.TalkgroupFormatPreference;
|
import io.github.dsheirer.preference.identifier.TalkgroupFormatPreference;
|
||||||
import io.github.dsheirer.preference.playlist.PlaylistPreference;
|
import io.github.dsheirer.preference.playlist.PlaylistPreference;
|
||||||
|
import io.github.dsheirer.preference.radioreference.RadioReferencePreference;
|
||||||
import io.github.dsheirer.preference.source.ChannelMultiFrequencyPreference;
|
import io.github.dsheirer.preference.source.ChannelMultiFrequencyPreference;
|
||||||
import io.github.dsheirer.preference.source.TunerPreference;
|
import io.github.dsheirer.preference.source.TunerPreference;
|
||||||
|
import io.github.dsheirer.preference.swing.SwingPreference;
|
||||||
import io.github.dsheirer.sample.Listener;
|
import io.github.dsheirer.sample.Listener;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -53,8 +57,10 @@ public class UserPreferences implements Listener<PreferenceType>
|
|||||||
private DirectoryPreference mDirectoryPreference;
|
private DirectoryPreference mDirectoryPreference;
|
||||||
private ChannelMultiFrequencyPreference mChannelMultiFrequencyPreference;
|
private ChannelMultiFrequencyPreference mChannelMultiFrequencyPreference;
|
||||||
private PlaylistPreference mPlaylistPreference;
|
private PlaylistPreference mPlaylistPreference;
|
||||||
|
private RadioReferencePreference mRadioReferencePreference;
|
||||||
private TalkgroupFormatPreference mTalkgroupFormatPreference;
|
private TalkgroupFormatPreference mTalkgroupFormatPreference;
|
||||||
private TunerPreference mTunerPreference;
|
private TunerPreference mTunerPreference;
|
||||||
|
private SwingPreference mSwingPreference = new SwingPreference();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new user preferences instance
|
* Constructs a new user preferences instance
|
||||||
@@ -104,6 +110,14 @@ public class UserPreferences implements Listener<PreferenceType>
|
|||||||
return mPlaylistPreference;
|
return mPlaylistPreference;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Radio reference web services preferences
|
||||||
|
*/
|
||||||
|
public RadioReferencePreference getRadioReferencePreference()
|
||||||
|
{
|
||||||
|
return mRadioReferencePreference;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Identifier preferences
|
* Identifier preferences
|
||||||
*/
|
*/
|
||||||
@@ -120,6 +134,15 @@ public class UserPreferences implements Listener<PreferenceType>
|
|||||||
return mTunerPreference;
|
return mTunerPreference;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Swing window location/size user preferences
|
||||||
|
*/
|
||||||
|
public SwingPreference getSwingPreference()
|
||||||
|
{
|
||||||
|
return mSwingPreference;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads the managed preferences
|
* Loads the managed preferences
|
||||||
*/
|
*/
|
||||||
@@ -130,6 +153,7 @@ public class UserPreferences implements Listener<PreferenceType>
|
|||||||
mDirectoryPreference = new DirectoryPreference(this::receive);
|
mDirectoryPreference = new DirectoryPreference(this::receive);
|
||||||
mChannelMultiFrequencyPreference = new ChannelMultiFrequencyPreference(this::receive);
|
mChannelMultiFrequencyPreference = new ChannelMultiFrequencyPreference(this::receive);
|
||||||
mPlaylistPreference = new PlaylistPreference(this::receive, mDirectoryPreference);
|
mPlaylistPreference = new PlaylistPreference(this::receive, mDirectoryPreference);
|
||||||
|
mRadioReferencePreference = new RadioReferencePreference(this::receive);
|
||||||
mTalkgroupFormatPreference = new TalkgroupFormatPreference(this::receive);
|
mTalkgroupFormatPreference = new TalkgroupFormatPreference(this::receive);
|
||||||
mTunerPreference = new TunerPreference(this::receive);
|
mTunerPreference = new TunerPreference(this::receive);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* ******************************************************************************
|
* ******************************************************************************
|
||||||
* sdrtrunk
|
* sdrtrunk
|
||||||
* Copyright (C) 2014-2018 Dennis Sheirer
|
* Copyright (C) 2014-2019 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -42,6 +42,7 @@ public class APCO25TalkgroupFormatter extends IntegerFormatter
|
|||||||
switch(format)
|
switch(format)
|
||||||
{
|
{
|
||||||
case DECIMAL:
|
case DECIMAL:
|
||||||
|
case FORMATTED:
|
||||||
return toDecimal(identifier.getValue(),
|
return toDecimal(identifier.getValue(),
|
||||||
(identifier.isGroup() ? GROUP_DECIMAL_WIDTH : UNIT_DECIMAL_WIDTH));
|
(identifier.isGroup() ? GROUP_DECIMAL_WIDTH : UNIT_DECIMAL_WIDTH));
|
||||||
case HEXADECIMAL:
|
case HEXADECIMAL:
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ public class MDC1200TalkgroupFormatter extends IntegerFormatter
|
|||||||
switch(format)
|
switch(format)
|
||||||
{
|
{
|
||||||
case DECIMAL:
|
case DECIMAL:
|
||||||
|
case FORMATTED:
|
||||||
return toDecimal(identifier.getValue(), DECIMAL_WIDTH);
|
return toDecimal(identifier.getValue(), DECIMAL_WIDTH);
|
||||||
case HEXADECIMAL:
|
case HEXADECIMAL:
|
||||||
return toHex(identifier.getValue(), HEXADECIMAL_WIDTH);
|
return toHex(identifier.getValue(), HEXADECIMAL_WIDTH);
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ public class PassportTalkgroupFormatter extends IntegerFormatter
|
|||||||
switch(format)
|
switch(format)
|
||||||
{
|
{
|
||||||
case DECIMAL:
|
case DECIMAL:
|
||||||
|
case FORMATTED:
|
||||||
return toDecimal(identifier.getValue(), DECIMAL_WIDTH);
|
return toDecimal(identifier.getValue(), DECIMAL_WIDTH);
|
||||||
case HEXADECIMAL:
|
case HEXADECIMAL:
|
||||||
return toHex(identifier.getValue(), HEXADECIMAL_WIDTH);
|
return toHex(identifier.getValue(), HEXADECIMAL_WIDTH);
|
||||||
|
|||||||
@@ -0,0 +1,181 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* * ******************************************************************************
|
||||||
|
* * 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.preference.radioreference;
|
||||||
|
|
||||||
|
import io.github.dsheirer.preference.Preference;
|
||||||
|
import io.github.dsheirer.preference.PreferenceType;
|
||||||
|
import io.github.dsheirer.sample.Listener;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.util.prefs.Preferences;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User preferences for the display of channel decode events
|
||||||
|
*/
|
||||||
|
public class RadioReferencePreference extends Preference
|
||||||
|
{
|
||||||
|
private final static Logger mLog = LoggerFactory.getLogger(RadioReferencePreference.class);
|
||||||
|
private Preferences mPreferences = Preferences.userNodeForPackage(RadioReferencePreference.class);
|
||||||
|
private static final String STORE_CREDENTIALS = "store.credentials";
|
||||||
|
private static final String USER_NAME = "user.name";
|
||||||
|
private static final String PASSWORD = "user.authorization";
|
||||||
|
|
||||||
|
private String mUserName;
|
||||||
|
private String mPassword;
|
||||||
|
private Boolean mStoreCredentials;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs an instance.
|
||||||
|
* @param updateListener to receive notifications when preferences are updated.
|
||||||
|
*/
|
||||||
|
public RadioReferencePreference(Listener<PreferenceType> updateListener)
|
||||||
|
{
|
||||||
|
super(updateListener);
|
||||||
|
loadSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PreferenceType getPreferenceType()
|
||||||
|
{
|
||||||
|
return PreferenceType.RADIO_REFERENCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadSettings()
|
||||||
|
{
|
||||||
|
mStoreCredentials = mPreferences.getBoolean(STORE_CREDENTIALS, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears user credentials and resets username and password to null
|
||||||
|
*/
|
||||||
|
public void removeStoreCredentials()
|
||||||
|
{
|
||||||
|
setStoreCredentials(false);
|
||||||
|
setUserName(null);
|
||||||
|
setPassword(null);
|
||||||
|
notifyPreferenceUpdated();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates if there are any non-null values stored for user name or password
|
||||||
|
* @return true if there are values stored
|
||||||
|
*/
|
||||||
|
public boolean hasStoredCredentials()
|
||||||
|
{
|
||||||
|
return mPreferences.get(USER_NAME, null) != null || mPreferences.get(PASSWORD, null) != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User name
|
||||||
|
*/
|
||||||
|
public String getUserName()
|
||||||
|
{
|
||||||
|
if(mUserName == null)
|
||||||
|
{
|
||||||
|
mUserName = mPreferences.get(USER_NAME, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
return mUserName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets user name
|
||||||
|
* @param username to store or null to remove any stored value
|
||||||
|
*/
|
||||||
|
public void setUserName(String username)
|
||||||
|
{
|
||||||
|
mUserName = username;
|
||||||
|
|
||||||
|
if(mUserName == null)
|
||||||
|
{
|
||||||
|
mPreferences.remove(USER_NAME);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mPreferences.put(USER_NAME, mUserName);
|
||||||
|
}
|
||||||
|
|
||||||
|
notifyPreferenceUpdated();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Password
|
||||||
|
* @return password
|
||||||
|
*/
|
||||||
|
public String getPassword()
|
||||||
|
{
|
||||||
|
if(mPassword == null)
|
||||||
|
{
|
||||||
|
mPassword = mPreferences.get(PASSWORD, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
return mPassword;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the preferences persisted password.
|
||||||
|
* @param password to store or null to remove any stored value
|
||||||
|
*/
|
||||||
|
public void setPassword(String password)
|
||||||
|
{
|
||||||
|
mPassword = password;
|
||||||
|
|
||||||
|
if(mPassword == null)
|
||||||
|
{
|
||||||
|
mPreferences.remove(PASSWORD);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mPreferences.put(PASSWORD, mPassword);
|
||||||
|
}
|
||||||
|
|
||||||
|
notifyPreferenceUpdated();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates if the credentials should be persisted in the preferences store.
|
||||||
|
*
|
||||||
|
* @return true if credentials should be stored.
|
||||||
|
*/
|
||||||
|
public boolean isStoreCredentials()
|
||||||
|
{
|
||||||
|
if(mStoreCredentials == null)
|
||||||
|
{
|
||||||
|
mStoreCredentials = mPreferences.getBoolean(STORE_CREDENTIALS, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return mStoreCredentials;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the store credentials option
|
||||||
|
* @param store true to store credentials
|
||||||
|
*/
|
||||||
|
public void setStoreCredentials(boolean store)
|
||||||
|
{
|
||||||
|
mStoreCredentials = store;
|
||||||
|
mPreferences.putBoolean(STORE_CREDENTIALS, store);
|
||||||
|
notifyPreferenceUpdated();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,154 @@
|
|||||||
|
/*
|
||||||
|
* ******************************************************************************
|
||||||
|
* 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.preference.swing;
|
||||||
|
|
||||||
|
import io.github.dsheirer.preference.UserPreferences;
|
||||||
|
import io.github.dsheirer.util.ThreadPool;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import javax.swing.JTable;
|
||||||
|
import javax.swing.event.ChangeEvent;
|
||||||
|
import javax.swing.event.ListSelectionEvent;
|
||||||
|
import javax.swing.event.TableColumnModelEvent;
|
||||||
|
import javax.swing.event.TableColumnModelListener;
|
||||||
|
import javax.swing.table.TableColumnModel;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Monitors a JTable column model and persists column width changes to the user preferences. Restores
|
||||||
|
* previous column width preferred sizes on application restart.
|
||||||
|
*/
|
||||||
|
public class JTableColumnWidthMonitor
|
||||||
|
{
|
||||||
|
private static final Logger mLog = LoggerFactory.getLogger(JTableColumnWidthMonitor.class);
|
||||||
|
private UserPreferences mUserPreferences;
|
||||||
|
private JTable mTable;
|
||||||
|
private String mKey;
|
||||||
|
private ColumnResizeListener mColumnResizeListener = new ColumnResizeListener();
|
||||||
|
private AtomicBoolean mSaveInProgress = new AtomicBoolean();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a column width monitor.
|
||||||
|
*
|
||||||
|
* @param userPreferences to store column widths
|
||||||
|
* @param table to monitor for column width changes
|
||||||
|
* @param key that uniquely identifies the table to monitor
|
||||||
|
*/
|
||||||
|
public JTableColumnWidthMonitor(UserPreferences userPreferences, JTable table, String key)
|
||||||
|
{
|
||||||
|
mUserPreferences = userPreferences;
|
||||||
|
mTable = table;
|
||||||
|
mKey = key;
|
||||||
|
|
||||||
|
restoreColumnWidths();
|
||||||
|
mTable.getColumnModel().addColumnModelListener(mColumnResizeListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepares this monitor for disposal by unregistering as a listener to the table column model.
|
||||||
|
*/
|
||||||
|
public void dispose()
|
||||||
|
{
|
||||||
|
if(mTable != null && mColumnResizeListener != null)
|
||||||
|
{
|
||||||
|
mTable.getColumnModel().removeColumnModelListener(mColumnResizeListener);
|
||||||
|
}
|
||||||
|
|
||||||
|
mTable = null;
|
||||||
|
mUserPreferences = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the preferred column widths on the table from persisted settings
|
||||||
|
*/
|
||||||
|
private void restoreColumnWidths()
|
||||||
|
{
|
||||||
|
TableColumnModel model = mTable.getColumnModel();
|
||||||
|
|
||||||
|
for(int x = 0; x < model.getColumnCount(); x++)
|
||||||
|
{
|
||||||
|
int width = mUserPreferences.getSwingPreference().getInt(getColumnKey(x), Integer.MAX_VALUE);
|
||||||
|
|
||||||
|
if(width != Integer.MAX_VALUE)
|
||||||
|
{
|
||||||
|
model.getColumn(x).setPreferredWidth(width);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores the current column widths to the user preferences
|
||||||
|
*/
|
||||||
|
private void storeColumnWidths()
|
||||||
|
{
|
||||||
|
TableColumnModel model = mTable.getColumnModel();
|
||||||
|
|
||||||
|
for(int x = 0; x < model.getColumnCount(); x++)
|
||||||
|
{
|
||||||
|
mUserPreferences.getSwingPreference().setInt(getColumnKey(x), model.getColumn(x).getWidth());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a preference key for the column number
|
||||||
|
*/
|
||||||
|
private String getColumnKey(int column)
|
||||||
|
{
|
||||||
|
return mKey + ".column." + column;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Table column model listener.
|
||||||
|
*/
|
||||||
|
class ColumnResizeListener implements TableColumnModelListener
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void columnMarginChanged(ChangeEvent e)
|
||||||
|
{
|
||||||
|
if(mSaveInProgress.compareAndSet(false, true))
|
||||||
|
{
|
||||||
|
ThreadPool.SCHEDULED.schedule(new ColumnWidthSaveTask(), 2, TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void columnAdded(TableColumnModelEvent e){}
|
||||||
|
@Override
|
||||||
|
public void columnRemoved(TableColumnModelEvent e){}
|
||||||
|
@Override
|
||||||
|
public void columnMoved(TableColumnModelEvent e){}
|
||||||
|
@Override
|
||||||
|
public void columnSelectionChanged(ListSelectionEvent e){}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ColumnWidthSaveTask implements Runnable
|
||||||
|
{
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
storeColumnWidths();
|
||||||
|
mSaveInProgress.set(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,148 @@
|
|||||||
|
/*
|
||||||
|
* ******************************************************************************
|
||||||
|
* 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.preference.swing;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.GraphicsDevice;
|
||||||
|
import java.awt.GraphicsEnvironment;
|
||||||
|
import java.awt.Point;
|
||||||
|
import java.util.prefs.Preferences;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* User preference settings for Swing windows and components.
|
||||||
|
*/
|
||||||
|
public class SwingPreference
|
||||||
|
{
|
||||||
|
private static final Logger mLog = LoggerFactory.getLogger(SwingPreference.class);
|
||||||
|
|
||||||
|
private static final String LOCATION_X = ".x";
|
||||||
|
private static final String LOCATION_Y = ".y";
|
||||||
|
private static final String SIZE_HEIGHT = ".height";
|
||||||
|
private static final String SIZE_WIDTH = ".width";
|
||||||
|
|
||||||
|
private Preferences mPreferences = Preferences.userNodeForPackage(SwingPreference.class);
|
||||||
|
|
||||||
|
public SwingPreference()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the stored swing related integer value
|
||||||
|
* @param key for accessing the value
|
||||||
|
* @param defaultValue to return if the value has not yet been persisted
|
||||||
|
* @return value or default value
|
||||||
|
*/
|
||||||
|
public int getInt(String key, int defaultValue)
|
||||||
|
{
|
||||||
|
return mPreferences.getInt(key, defaultValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores the swing related integer value
|
||||||
|
* @param key to reference the value
|
||||||
|
*/
|
||||||
|
public void setInt(String key, int value)
|
||||||
|
{
|
||||||
|
mPreferences.putInt(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the persisted window location for the specified preference key.
|
||||||
|
* @param key identifying the window
|
||||||
|
* @return location or null
|
||||||
|
*/
|
||||||
|
public Point getLocation(String key)
|
||||||
|
{
|
||||||
|
int x = mPreferences.getInt(key + LOCATION_X, Integer.MAX_VALUE);
|
||||||
|
int y = mPreferences.getInt(key + LOCATION_Y, Integer.MAX_VALUE);
|
||||||
|
|
||||||
|
if(x != Integer.MAX_VALUE && y != Integer.MAX_VALUE)
|
||||||
|
{
|
||||||
|
Point location = new Point(x,y);
|
||||||
|
|
||||||
|
if(isValidWindowLocation(location))
|
||||||
|
{
|
||||||
|
return location;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores the current window location
|
||||||
|
* @param key to identify the window
|
||||||
|
* @param location to persist
|
||||||
|
*/
|
||||||
|
public void setLocation(String key, Point location)
|
||||||
|
{
|
||||||
|
mPreferences.putInt(key + LOCATION_X, location.x);
|
||||||
|
mPreferences.putInt(key + LOCATION_Y, location.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the stored size/dimension of the window identified by the key argument.
|
||||||
|
* @param key to identify the window
|
||||||
|
* @return dimension or null
|
||||||
|
*/
|
||||||
|
public Dimension getDimension(String key)
|
||||||
|
{
|
||||||
|
int height = mPreferences.getInt(key + SIZE_HEIGHT, Integer.MAX_VALUE);
|
||||||
|
int width = mPreferences.getInt(key + SIZE_WIDTH, Integer.MAX_VALUE);
|
||||||
|
|
||||||
|
if(height != Integer.MAX_VALUE && width != Integer.MAX_VALUE)
|
||||||
|
{
|
||||||
|
return new Dimension(width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDimension(String key, Dimension dimension)
|
||||||
|
{
|
||||||
|
mPreferences.putInt(key + SIZE_HEIGHT, dimension.height);
|
||||||
|
mPreferences.putInt(key + SIZE_WIDTH, dimension.width);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests a stored window location to determine if it can be displayed on the currently available
|
||||||
|
* graphics display devices so that we don't position a window at a previously available location
|
||||||
|
* that is not currently available.
|
||||||
|
*
|
||||||
|
* @param location to test
|
||||||
|
* @return true if the location is displayable.
|
||||||
|
*/
|
||||||
|
private boolean isValidWindowLocation(Point location)
|
||||||
|
{
|
||||||
|
for(GraphicsDevice gd:GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices())
|
||||||
|
{
|
||||||
|
if(gd.getDefaultConfiguration().getBounds().contains(location))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,153 +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.radioreference;
|
|
||||||
|
|
||||||
import com.radioreference.api.soap2.AuthInfo;
|
|
||||||
import com.radioreference.api.soap2.RRWsdlLocator;
|
|
||||||
import com.radioreference.api.soap2.RRWsdlPortType;
|
|
||||||
import com.radioreference.api.soap2.UserFeedBroadcast;
|
|
||||||
import com.radioreference.api.soap2.UserInfo;
|
|
||||||
import org.apache.axis.AxisFault;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import javax.xml.rpc.ServiceException;
|
|
||||||
import java.rmi.RemoteException;
|
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
|
|
||||||
public class RadioReferenceService
|
|
||||||
{
|
|
||||||
private final static Logger mLog = LoggerFactory.getLogger( RadioReferenceService.class );
|
|
||||||
private final SimpleDateFormat SDF = new SimpleDateFormat("MM-dd-yyyy");
|
|
||||||
|
|
||||||
public static final String SDRTRUNK_APP_KEY = "88969092";
|
|
||||||
public static final String RADIO_REFERENCE_API_VERSION = "14";
|
|
||||||
public static final String SOAP_RPC_RESPONSE_STYLE = "rpc";
|
|
||||||
|
|
||||||
private RRWsdlLocator mService = new RRWsdlLocator();
|
|
||||||
private RRWsdlPortType mClient;
|
|
||||||
private Long mAccountExpiration;
|
|
||||||
|
|
||||||
private AuthInfo mUserAuthorization;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a SOAP web service client for interaction with the radioreference.com server.
|
|
||||||
*
|
|
||||||
* @param username for a premium subscriber
|
|
||||||
* @param password for a premium subscriber
|
|
||||||
* @throws ServiceException if the client can't be created
|
|
||||||
* @throws IllegalArgumentException if either the username or password is null or empty
|
|
||||||
*/
|
|
||||||
public RadioReferenceService(String username, String password) throws ServiceException
|
|
||||||
{
|
|
||||||
mClient = mService.getRRWsdlPort();
|
|
||||||
|
|
||||||
setAuthorizationInformation(username, password);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets new premium subscriber user credentials to authenticate to the server.
|
|
||||||
* @param username for a premium subscriber on radioreference.com
|
|
||||||
* @param password for a premium subscriber
|
|
||||||
*/
|
|
||||||
public void setAuthorizationInformation(String username, String password) throws IllegalArgumentException
|
|
||||||
{
|
|
||||||
if(username == null || username.isEmpty() || password == null || password.isEmpty())
|
|
||||||
{
|
|
||||||
throw new IllegalArgumentException("Username [" + username + "] and/or password [" + password +
|
|
||||||
"] cannot be null or empty");
|
|
||||||
}
|
|
||||||
|
|
||||||
mUserAuthorization = new AuthInfo(username, password, SDRTRUNK_APP_KEY, RADIO_REFERENCE_API_VERSION,
|
|
||||||
SOAP_RPC_RESPONSE_STYLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates if the service has a non-null user authorization
|
|
||||||
*/
|
|
||||||
public void checkCredentials() throws IllegalArgumentException
|
|
||||||
{
|
|
||||||
if(mUserAuthorization == null)
|
|
||||||
{
|
|
||||||
throw new IllegalStateException("Authorization information (username/password) required");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Account expiration date
|
|
||||||
*
|
|
||||||
* @return expiration date in millis since epoch
|
|
||||||
* @throws AxisFault for remote server errors
|
|
||||||
* @throws IllegalStateException for null or empty login credentials
|
|
||||||
* @throws RemoteException for web service client errors
|
|
||||||
*/
|
|
||||||
public long getAccountExpirationDate() throws IllegalStateException, RemoteException
|
|
||||||
{
|
|
||||||
checkCredentials();
|
|
||||||
|
|
||||||
if(mAccountExpiration == null)
|
|
||||||
{
|
|
||||||
UserInfo userInfo = mClient.getUserData(mUserAuthorization);
|
|
||||||
|
|
||||||
if(userInfo != null)
|
|
||||||
{
|
|
||||||
String expiration = userInfo.getSubExpireDate();
|
|
||||||
|
|
||||||
if(expiration != null)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
mAccountExpiration = SDF.parse(expiration).getTime();
|
|
||||||
}
|
|
||||||
catch(Exception e)
|
|
||||||
{
|
|
||||||
mLog.error("Couldn't parse account expiration date from web service response: " + expiration, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return mAccountExpiration;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Indicates if the radio reference user account is active (ie not expired)
|
|
||||||
*
|
|
||||||
* @throws IllegalStateException for null or empty login credentials
|
|
||||||
* @throws RemoteException for web service client errors
|
|
||||||
*/
|
|
||||||
public boolean isAccountActive() throws IllegalStateException, RemoteException
|
|
||||||
{
|
|
||||||
Long expiration = getAccountExpirationDate();
|
|
||||||
|
|
||||||
if(expiration != null)
|
|
||||||
{
|
|
||||||
return System.currentTimeMillis() < expiration;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public UserFeedBroadcast[] getUserFeedBroadcasts() throws IllegalArgumentException, RemoteException
|
|
||||||
{
|
|
||||||
checkCredentials();
|
|
||||||
|
|
||||||
return mClient.getUserFeedBroadcasts(mUserAuthorization);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,24 +1,28 @@
|
|||||||
/*******************************************************************************
|
/*
|
||||||
* SDR Trunk
|
* ******************************************************************************
|
||||||
* Copyright (C) 2014-2016 Dennis Sheirer
|
* sdrtrunk
|
||||||
|
* Copyright (C) 2014-2019 Dennis Sheirer
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
* GNU General Public License for more details.
|
* GNU General Public License for more details.
|
||||||
*
|
*
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
******************************************************************************/
|
* *****************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
package io.github.dsheirer.source.tuner;
|
package io.github.dsheirer.source.tuner;
|
||||||
|
|
||||||
import com.jidesoft.swing.JideSplitPane;
|
import com.jidesoft.swing.JideSplitPane;
|
||||||
|
import io.github.dsheirer.preference.UserPreferences;
|
||||||
|
import io.github.dsheirer.preference.swing.JTableColumnWidthMonitor;
|
||||||
import io.github.dsheirer.sample.Listener;
|
import io.github.dsheirer.sample.Listener;
|
||||||
import io.github.dsheirer.source.tuner.TunerEvent.Event;
|
import io.github.dsheirer.source.tuner.TunerEvent.Event;
|
||||||
import net.miginfocom.swing.MigLayout;
|
import net.miginfocom.swing.MigLayout;
|
||||||
@@ -49,17 +53,21 @@ public class TunerViewPanel extends JPanel
|
|||||||
{
|
{
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
private final static Logger mLog = LoggerFactory.getLogger(TunerViewPanel.class);
|
private final static Logger mLog = LoggerFactory.getLogger(TunerViewPanel.class);
|
||||||
|
private static final String TABLE_PREFERENCE_KEY = "tuner.view.panel";
|
||||||
|
|
||||||
private TunerModel mTunerModel;
|
private TunerModel mTunerModel;
|
||||||
private JTable mTunerTable;
|
private JTable mTunerTable;
|
||||||
|
private JTableColumnWidthMonitor mColumnWidthMonitor;
|
||||||
private TableRowSorter<TunerModel> mRowSorter;
|
private TableRowSorter<TunerModel> mRowSorter;
|
||||||
private JideSplitPane mSplitPane;
|
private JideSplitPane mSplitPane;
|
||||||
private TunerEditor mTunerEditor;
|
private TunerEditor mTunerEditor;
|
||||||
|
private UserPreferences mUserPreferences;
|
||||||
|
|
||||||
public TunerViewPanel(TunerModel tunerModel)
|
public TunerViewPanel(TunerModel tunerModel, UserPreferences userPreferences)
|
||||||
{
|
{
|
||||||
mTunerModel = tunerModel;
|
mTunerModel = tunerModel;
|
||||||
mTunerEditor = new TunerEditor(mTunerModel.getTunerConfigurationModel());
|
mTunerEditor = new TunerEditor(mTunerModel.getTunerConfigurationModel());
|
||||||
|
mUserPreferences = userPreferences;
|
||||||
|
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
@@ -149,6 +157,7 @@ public class TunerViewPanel extends JPanel
|
|||||||
TableCellRenderer renderer = new LinkCellRenderer();
|
TableCellRenderer renderer = new LinkCellRenderer();
|
||||||
mTunerTable.getColumnModel().getColumn(TunerModel.SPECTRAL_DISPLAY_NEW).setCellRenderer(renderer);
|
mTunerTable.getColumnModel().getColumn(TunerModel.SPECTRAL_DISPLAY_NEW).setCellRenderer(renderer);
|
||||||
|
|
||||||
|
mColumnWidthMonitor = new JTableColumnWidthMonitor(mUserPreferences, mTunerTable, TABLE_PREFERENCE_KEY);
|
||||||
JScrollPane listScroller = new JScrollPane(mTunerTable);
|
JScrollPane listScroller = new JScrollPane(mTunerTable);
|
||||||
listScroller.setPreferredSize(new Dimension(400, 20));
|
listScroller.setPreferredSize(new Dimension(400, 20));
|
||||||
|
|
||||||
|
|||||||
@@ -1,22 +1,30 @@
|
|||||||
/*******************************************************************************
|
/*
|
||||||
* sdr-trunk
|
|
||||||
* 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
|
* * Copyright (C) 2014-2019 Dennis Sheirer
|
||||||
* later version.
|
* *
|
||||||
|
* * 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.spectrum;
|
package io.github.dsheirer.spectrum;
|
||||||
|
|
||||||
import io.github.dsheirer.properties.SystemProperties;
|
import io.github.dsheirer.properties.SystemProperties;
|
||||||
import io.github.dsheirer.source.tuner.Tuner;
|
import io.github.dsheirer.source.tuner.Tuner;
|
||||||
|
import io.github.dsheirer.source.tuner.TunerEvent;
|
||||||
|
import io.github.dsheirer.source.tuner.TunerModel;
|
||||||
|
|
||||||
import javax.swing.JMenuItem;
|
import javax.swing.JMenuItem;
|
||||||
import java.awt.EventQueue;
|
import java.awt.EventQueue;
|
||||||
@@ -25,13 +33,13 @@ import java.awt.event.ActionListener;
|
|||||||
|
|
||||||
public class ShowTunerMenuItem extends JMenuItem
|
public class ShowTunerMenuItem extends JMenuItem
|
||||||
{
|
{
|
||||||
private SpectralDisplayPanel mSpectralDisplayPanel;
|
private TunerModel mTunerModel;
|
||||||
private Tuner mTuner;
|
private Tuner mTuner;
|
||||||
|
|
||||||
public ShowTunerMenuItem(SpectralDisplayPanel spectralDisplayPanel, Tuner tuner)
|
public ShowTunerMenuItem(TunerModel tunerModel, Tuner tuner)
|
||||||
{
|
{
|
||||||
super(tuner != null ? "Show: " + tuner.getName() : "(empty)");
|
super(tuner != null ? "Show: " + tuner.getName() : "(empty)");
|
||||||
mSpectralDisplayPanel = spectralDisplayPanel;
|
mTunerModel = tunerModel;
|
||||||
mTuner = tuner;
|
mTuner = tuner;
|
||||||
|
|
||||||
addActionListener(new ActionListener()
|
addActionListener(new ActionListener()
|
||||||
@@ -44,7 +52,7 @@ public class ShowTunerMenuItem extends JMenuItem
|
|||||||
@Override
|
@Override
|
||||||
public void run()
|
public void run()
|
||||||
{
|
{
|
||||||
mSpectralDisplayPanel.showTuner(mTuner);
|
mTunerModel.broadcast(new TunerEvent(mTuner, TunerEvent.Event.REQUEST_MAIN_SPECTRAL_DISPLAY));
|
||||||
SystemProperties properties = SystemProperties.getInstance();
|
SystemProperties properties = SystemProperties.getInstance();
|
||||||
properties.set(SpectralDisplayPanel.SPECTRAL_DISPLAY_ENABLED, true);
|
properties.set(SpectralDisplayPanel.SPECTRAL_DISPLAY_ENABLED, true);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +1,23 @@
|
|||||||
/*
|
/*
|
||||||
* ******************************************************************************
|
|
||||||
* 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
|
* * Copyright (C) 2014-2019 Dennis Sheirer
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
* *
|
||||||
* (at your option) any later version.
|
* * 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.spectrum;
|
package io.github.dsheirer.spectrum;
|
||||||
|
|
||||||
@@ -806,7 +808,7 @@ public class SpectralDisplayPanel extends JPanel implements Listener<ReusableCom
|
|||||||
separatorAdded = true;
|
separatorAdded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
contextMenu.add(new ShowTunerMenuItem(SpectralDisplayPanel.this, tuner));
|
contextMenu.add(new ShowTunerMenuItem(mTunerModel, tuner));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user