mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-10 15:47:25 -05:00
* WIP - Adds support for aliasing P25 Phase 2 tones.Playlist editor - adds editor support for alias actions * Playlist editor implementation and integration into application is complete. Adds JavaFX window monitoring to persist window size/location across application runs. Co-authored-by: Denny <denny@denny-desktop>
This commit is contained in:
@@ -1,29 +1,54 @@
|
||||
/*******************************************************************************
|
||||
* 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
|
||||
* later version.
|
||||
* * ******************************************************************************
|
||||
* * Copyright (C) 2014-2020 Dennis Sheirer
|
||||
* *
|
||||
* * This program is free software: you can redistribute it and/or modify
|
||||
* * it under the terms of the GNU General Public License as published by
|
||||
* * the Free Software Foundation, either version 3 of the License, or
|
||||
* * (at your option) any later version.
|
||||
* *
|
||||
* * This program is distributed in the hope that it will be useful,
|
||||
* * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* * GNU General Public License for more details.
|
||||
* *
|
||||
* * You should have received a copy of the GNU General Public License
|
||||
* * along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* * *****************************************************************************
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied
|
||||
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with this program.
|
||||
* If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
******************************************************************************/
|
||||
*/
|
||||
|
||||
package io.github.dsheirer.gui;
|
||||
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
import io.github.dsheirer.alias.AliasModel;
|
||||
import io.github.dsheirer.controller.channel.map.ChannelMap;
|
||||
import io.github.dsheirer.controller.channel.map.ChannelRange;
|
||||
import io.github.dsheirer.eventbus.MyEventBus;
|
||||
import io.github.dsheirer.gui.preference.PreferenceEditorViewRequest;
|
||||
import io.github.dsheirer.gui.preference.PreferencesEditor;
|
||||
import io.github.dsheirer.gui.playlist.PlaylistEditor;
|
||||
import io.github.dsheirer.gui.playlist.PlaylistEditorRequest;
|
||||
import io.github.dsheirer.gui.playlist.ViewPlaylistRequest;
|
||||
import io.github.dsheirer.gui.playlist.channelMap.ChannelMapEditor;
|
||||
import io.github.dsheirer.gui.playlist.channelMap.ChannelMapEditorViewRequest;
|
||||
import io.github.dsheirer.gui.preference.PreferenceEditorType;
|
||||
import io.github.dsheirer.gui.preference.UserPreferenceEditorViewRequest;
|
||||
import io.github.dsheirer.gui.preference.UserPreferencesEditor;
|
||||
import io.github.dsheirer.icon.IconManager;
|
||||
import io.github.dsheirer.module.log.EventLogManager;
|
||||
import io.github.dsheirer.playlist.PlaylistManager;
|
||||
import io.github.dsheirer.preference.UserPreferences;
|
||||
import io.github.dsheirer.settings.SettingsManager;
|
||||
import io.github.dsheirer.source.SourceManager;
|
||||
import io.github.dsheirer.source.tuner.TunerModel;
|
||||
import io.github.dsheirer.source.tuner.configuration.TunerConfigurationModel;
|
||||
import javafx.application.Application;
|
||||
import javafx.application.Platform;
|
||||
import javafx.embed.swing.JFXPanel;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.stage.Stage;
|
||||
import jiconfont.javafx.IconFontFX;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@@ -31,68 +56,325 @@ import org.slf4j.LoggerFactory;
|
||||
* Java FX window manager. Handles all secondary Java FX windows that are used within this primarily
|
||||
* Swing application.
|
||||
*/
|
||||
public class JavaFxWindowManager
|
||||
public class JavaFxWindowManager extends Application
|
||||
{
|
||||
private final static Logger mLog = LoggerFactory.getLogger(JavaFxWindowManager.class);
|
||||
|
||||
private UserPreferences mUserPreferences;
|
||||
private PreferencesEditor mPreferencesEditor;
|
||||
public static final String CHANNEL_MAP_EDITOR = "channelmap";
|
||||
public static final String PLAYLIST_EDITOR = "playlist";
|
||||
public static final String USER_PREFERENCES_EDITOR = "preferences";
|
||||
public static final String STAGE_MONITOR_KEY_CHANNEL_MAP_EDITOR = "channel.map";
|
||||
public static final String STAGE_MONITOR_KEY_PLAYLIST_EDITOR = "playlist";
|
||||
public static final String STAGE_MONITOR_KEY_USER_PREFERENCES_EDITOR = "user.preferences";
|
||||
|
||||
public JavaFxWindowManager(UserPreferences userPreferences)
|
||||
private JFXPanel mJFXPanel;
|
||||
private PlaylistManager mPlaylistManager;
|
||||
private ChannelMapEditor mChannelMapEditor;
|
||||
private PlaylistEditor mPlaylistEditor;
|
||||
private UserPreferences mUserPreferences;
|
||||
private UserPreferencesEditor mUserPreferencesEditor;
|
||||
|
||||
private Stage mChannelMapStage;
|
||||
private Stage mPlaylistStage;
|
||||
private Stage mUserPreferencesStage;
|
||||
|
||||
/**
|
||||
* Constructs an instance. Note: this constructor is used for Swing applications.
|
||||
*/
|
||||
public JavaFxWindowManager(UserPreferences userPreferences, PlaylistManager playlistManager)
|
||||
{
|
||||
mUserPreferences = userPreferences;
|
||||
mPlaylistManager = playlistManager;
|
||||
|
||||
//Register this class to receive events via each method annotated with @Subscribe
|
||||
MyEventBus.getEventBus().register(this);
|
||||
setup();
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes all JavaFX windows and shuts down the FX thread
|
||||
* Constructs an instance. Note: this constructor is used for standalone JavaFX application testing
|
||||
*/
|
||||
public void shutdown()
|
||||
public JavaFxWindowManager()
|
||||
{
|
||||
Platform.exit();
|
||||
mUserPreferences = new UserPreferences();
|
||||
AliasModel aliasModel = new AliasModel();
|
||||
TunerConfigurationModel tunerConfigurationModel = new TunerConfigurationModel();
|
||||
TunerModel tunerModel = new TunerModel(tunerConfigurationModel);
|
||||
SourceManager sourceManager = new SourceManager(tunerModel, new SettingsManager(tunerConfigurationModel),
|
||||
mUserPreferences);
|
||||
EventLogManager eventLogManager = new EventLogManager(aliasModel, mUserPreferences);
|
||||
mPlaylistManager = new PlaylistManager(mUserPreferences, sourceManager, aliasModel, eventLogManager, new IconManager());
|
||||
mPlaylistManager.init();
|
||||
setup();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void process(final PreferenceEditorViewRequest request)
|
||||
private void setup()
|
||||
{
|
||||
if(mPreferencesEditor == null)
|
||||
{
|
||||
new JFXPanel();
|
||||
Platform.setImplicitExit(false);
|
||||
Platform.runLater(() -> {
|
||||
try
|
||||
{
|
||||
mPreferencesEditor = new PreferencesEditor(mUserPreferences);
|
||||
//Register this class to receive events via each method annotated with @Subscribe
|
||||
MyEventBus.getEventBus().register(this);
|
||||
|
||||
Stage stage = new Stage();
|
||||
stage.setOnHidden(event -> mPreferencesEditor = null);
|
||||
mPreferencesEditor.start(stage);
|
||||
mPreferencesEditor.showEditor(request);
|
||||
}
|
||||
catch(Throwable e)
|
||||
{
|
||||
mLog.error("Error launching user preferences window", e);
|
||||
}
|
||||
});
|
||||
//Register JavaFX icon fonts
|
||||
IconFontFX.register(jiconfont.icons.font_awesome.FontAwesome.getIconFont());
|
||||
|
||||
createJFXPanel();
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the runnable on the JavaFX application thread
|
||||
*/
|
||||
private void execute(Runnable runnable)
|
||||
{
|
||||
createJFXPanel();
|
||||
|
||||
if(Platform.isFxApplicationThread())
|
||||
{
|
||||
runnable.run();
|
||||
}
|
||||
else
|
||||
{
|
||||
Platform.runLater(() -> {
|
||||
try
|
||||
{
|
||||
Stage stage = mPreferencesEditor.getStage();
|
||||
stage.show();
|
||||
stage.toFront();
|
||||
stage.requestFocus();
|
||||
mPreferencesEditor.showEditor(request);
|
||||
}
|
||||
catch(Throwable t)
|
||||
{
|
||||
mLog.error("Error showing existing preferences editor window", t);
|
||||
}
|
||||
});
|
||||
Platform.runLater(runnable);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a JavaFX panel for Swing application compatibility
|
||||
*/
|
||||
private void createJFXPanel()
|
||||
{
|
||||
if(mJFXPanel == null)
|
||||
{
|
||||
mJFXPanel = new JFXPanel();
|
||||
Platform.setImplicitExit(false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes monitoring for all JavaFX stages and shuts down the FX thread, killing all FX windows.
|
||||
*/
|
||||
public void shutdown()
|
||||
{
|
||||
if(mPlaylistStage != null)
|
||||
{
|
||||
mUserPreferences.getJavaFxPreferences().unmonitor(mPlaylistStage);
|
||||
}
|
||||
|
||||
if(mUserPreferencesStage != null)
|
||||
{
|
||||
mUserPreferences.getJavaFxPreferences().unmonitor(mUserPreferencesStage);
|
||||
}
|
||||
|
||||
if(mChannelMapStage != null)
|
||||
{
|
||||
mUserPreferences.getJavaFxPreferences().unmonitor(mChannelMapStage);
|
||||
}
|
||||
|
||||
Platform.exit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Lazy construct and access the playlist editor
|
||||
*/
|
||||
public PlaylistEditor getPlaylistEditor()
|
||||
{
|
||||
if(mPlaylistEditor == null)
|
||||
{
|
||||
mPlaylistEditor = new PlaylistEditor(mPlaylistManager, mUserPreferences);
|
||||
}
|
||||
|
||||
return mPlaylistEditor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Access the playlist stage.
|
||||
*/
|
||||
private Stage getPlaylistStage()
|
||||
{
|
||||
if(mPlaylistStage == null)
|
||||
{
|
||||
createJFXPanel();
|
||||
Scene scene = new Scene(getPlaylistEditor(), 1000, 750);
|
||||
mPlaylistStage = new Stage();
|
||||
mPlaylistStage.setTitle("sdrtrunk - Playlist Editor");
|
||||
mPlaylistStage.setScene(scene);
|
||||
mUserPreferences.getJavaFxPreferences().monitor(mPlaylistStage, STAGE_MONITOR_KEY_PLAYLIST_EDITOR);
|
||||
}
|
||||
|
||||
return mPlaylistStage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes a playlist editor request and brings the playlist editor into focus
|
||||
*/
|
||||
@Subscribe
|
||||
public void process(PlaylistEditorRequest request)
|
||||
{
|
||||
execute(() -> {
|
||||
try
|
||||
{
|
||||
getPlaylistStage().show();
|
||||
getPlaylistStage().requestFocus();
|
||||
getPlaylistStage().toFront();
|
||||
getPlaylistEditor().process(request);
|
||||
}
|
||||
catch(Throwable t)
|
||||
{
|
||||
mLog.error("Error processing show playlist editor request", t);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* User Preferences Editor
|
||||
*/
|
||||
private UserPreferencesEditor getUserPreferencesEditor()
|
||||
{
|
||||
if(mUserPreferencesEditor == null)
|
||||
{
|
||||
mUserPreferencesEditor = new UserPreferencesEditor(mUserPreferences);
|
||||
}
|
||||
|
||||
return mUserPreferencesEditor;
|
||||
}
|
||||
|
||||
/**
|
||||
* User Preferences Stage
|
||||
*/
|
||||
private Stage getUserPreferencesStage()
|
||||
{
|
||||
if(mUserPreferencesStage == null)
|
||||
{
|
||||
createJFXPanel();
|
||||
Scene scene = new Scene(getUserPreferencesEditor(), 900, 500);
|
||||
mUserPreferencesStage = new Stage();
|
||||
mUserPreferencesStage.setTitle("sdrtrunk - User Preferences");
|
||||
mUserPreferencesStage.setScene(scene);
|
||||
mUserPreferences.getJavaFxPreferences().monitor(mUserPreferencesStage, STAGE_MONITOR_KEY_USER_PREFERENCES_EDITOR);
|
||||
}
|
||||
|
||||
return mUserPreferencesStage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes a user preferences editor request
|
||||
*/
|
||||
@Subscribe
|
||||
public void process(final UserPreferenceEditorViewRequest request)
|
||||
{
|
||||
execute(() -> {
|
||||
getUserPreferencesStage().show();
|
||||
getUserPreferencesStage().requestFocus();
|
||||
getUserPreferencesStage().toFront();
|
||||
getUserPreferencesEditor().process(request);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Channel Map Editor
|
||||
*/
|
||||
private ChannelMapEditor getChannelMapEditor()
|
||||
{
|
||||
if(mChannelMapEditor == null)
|
||||
{
|
||||
mChannelMapEditor = new ChannelMapEditor(mPlaylistManager.getChannelMapModel());
|
||||
}
|
||||
|
||||
return mChannelMapEditor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Channel Map Stage
|
||||
*/
|
||||
private Stage getChannelMapStage()
|
||||
{
|
||||
if(mChannelMapStage == null)
|
||||
{
|
||||
createJFXPanel();
|
||||
Scene scene = new Scene(getChannelMapEditor(), 500, 500);
|
||||
mChannelMapStage = new Stage();
|
||||
mChannelMapStage.setTitle("sdrtrunk - Channel Map Editor");
|
||||
mChannelMapStage.setScene(scene);
|
||||
mUserPreferences.getJavaFxPreferences().monitor(mChannelMapStage, STAGE_MONITOR_KEY_CHANNEL_MAP_EDITOR);
|
||||
}
|
||||
|
||||
return mChannelMapStage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process a channel map editor request
|
||||
*/
|
||||
@Subscribe
|
||||
public void process(final ChannelMapEditorViewRequest request)
|
||||
{
|
||||
execute(() -> {
|
||||
getChannelMapStage().show();
|
||||
getChannelMapStage().requestFocus();
|
||||
getChannelMapStage().toFront();
|
||||
getChannelMapEditor().process(request);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start(Stage primaryStage) throws Exception
|
||||
{
|
||||
mLog.debug("Starting ...");
|
||||
Parameters parameters = getParameters();
|
||||
mLog.debug("Parameters: " + (parameters != null));
|
||||
|
||||
boolean valid = false;
|
||||
|
||||
if(parameters != null && parameters.getRaw().size() == 1)
|
||||
{
|
||||
String window = parameters.getRaw().get(0);
|
||||
|
||||
if(window != null)
|
||||
{
|
||||
switch(window)
|
||||
{
|
||||
case CHANNEL_MAP_EDITOR:
|
||||
//Generate some test data for the editor
|
||||
ChannelMap channelMap1 = new ChannelMap("Test Map 1");
|
||||
channelMap1.addRange(new ChannelRange(1,199,150000000, 12500));
|
||||
channelMap1.addRange(new ChannelRange(200,299,160000000, 25000));
|
||||
channelMap1.addRange(new ChannelRange(300,399,170000000, 12500));
|
||||
channelMap1.addRange(new ChannelRange(400,499,180000000, 25000));
|
||||
mPlaylistManager.getChannelMapModel().addChannelMap(channelMap1);
|
||||
|
||||
ChannelMap channelMap2 = new ChannelMap("Test Map 2");
|
||||
channelMap2.addRange(new ChannelRange(1,199,450000000, 12500));
|
||||
channelMap2.addRange(new ChannelRange(200,299,460000000, 25000));
|
||||
channelMap2.addRange(new ChannelRange(300,399,470000000, 12500));
|
||||
channelMap2.addRange(new ChannelRange(400,499,480000000, 25000));
|
||||
mPlaylistManager.getChannelMapModel().addChannelMap(channelMap2);
|
||||
valid = true;
|
||||
process(new ChannelMapEditorViewRequest());
|
||||
break;
|
||||
case PLAYLIST_EDITOR:
|
||||
valid = true;
|
||||
process(new ViewPlaylistRequest());
|
||||
break;
|
||||
case USER_PREFERENCES_EDITOR:
|
||||
valid = true;
|
||||
process(new UserPreferenceEditorViewRequest(PreferenceEditorType.DEFAULT));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!valid)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("An argument is required to launch JavaFX windows from this window manager. " +
|
||||
"Valid options are:\n\tplaylist\tPlaylist Editor\n\tpreferences\tUser Preferences Editor\n\tchannelmap\t" +
|
||||
"Channel Map Editor\n");
|
||||
sb.append("Supplied Argument(s): ").append(parameters.getRaw());
|
||||
|
||||
mLog.error(sb.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
mLog.info("Application Start - Parameters: " + args);
|
||||
launch(args);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user