mirror of
https://github.com/DSheirer/sdrtrunk.git
synced 2026-11-12 16:47:31 -05:00
Co-authored-by: Denny <denny@denny-desktop>
This commit is contained in:
@@ -0,0 +1,343 @@
|
||||
/*
|
||||
* *****************************************************************************
|
||||
* Copyright (C) 2014-2020 Dennis Sheirer
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
* ****************************************************************************
|
||||
*/
|
||||
|
||||
package io.github.dsheirer.gui.playlist.alias;
|
||||
|
||||
import com.google.common.collect.Ordering;
|
||||
import io.github.dsheirer.alias.Alias;
|
||||
import io.github.dsheirer.gui.playlist.Editor;
|
||||
import io.github.dsheirer.icon.Icon;
|
||||
import io.github.dsheirer.playlist.PlaylistManager;
|
||||
import javafx.collections.transformation.SortedList;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.event.EventHandler;
|
||||
import javafx.geometry.HPos;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.ColorPicker;
|
||||
import javafx.scene.control.ComboBox;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.ListCell;
|
||||
import javafx.scene.control.ListView;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.layout.ColumnConstraints;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import javafx.scene.paint.Color;
|
||||
import javafx.util.Callback;
|
||||
import org.controlsfx.control.ToggleSwitch;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Editor for multiple selected aliases providing limited options for changing attributes of multiple aliases
|
||||
*/
|
||||
public class AliasBulkEditor extends Editor<List<Alias>>
|
||||
{
|
||||
private PlaylistManager mPlaylistManager;
|
||||
private Label mEditingLabel;
|
||||
private ColorPicker mColorPicker;
|
||||
private Button mApplyColorButton;
|
||||
private ComboBox<Icon> mIconNodeComboBox;
|
||||
private Button mApplyIconButton;
|
||||
private ToggleSwitch mMonitorAudioToggleSwitch;
|
||||
private ComboBox<Integer> mMonitorPriorityComboBox;
|
||||
private Button mApplyMonitorButton;
|
||||
|
||||
/**
|
||||
* Constructs an instance
|
||||
* @param playlistManager for accessing icon manager
|
||||
*/
|
||||
public AliasBulkEditor(PlaylistManager playlistManager)
|
||||
{
|
||||
mPlaylistManager = playlistManager;
|
||||
|
||||
GridPane gridPane = new GridPane();
|
||||
gridPane.setPadding(new Insets(10,10,10,10));
|
||||
gridPane.setHgap(10);
|
||||
gridPane.setVgap(10);
|
||||
|
||||
int row = 0;
|
||||
|
||||
GridPane.setConstraints(getEditingLabel(), 1, row, 2, 1);
|
||||
gridPane.getChildren().add(getEditingLabel());
|
||||
|
||||
Label colorLabel = new Label("Color");
|
||||
GridPane.setHalignment(colorLabel, HPos.RIGHT);
|
||||
GridPane.setConstraints(colorLabel, 0, ++row);
|
||||
gridPane.getChildren().add(colorLabel);
|
||||
|
||||
GridPane.setConstraints(getColorPicker(), 1, row, 3, 1);
|
||||
gridPane.getChildren().add(getColorPicker());
|
||||
|
||||
GridPane.setConstraints(getApplyColorButton(), 4, row);
|
||||
gridPane.getChildren().add(getApplyColorButton());
|
||||
|
||||
Label iconLabel = new Label("Icon");
|
||||
GridPane.setHalignment(iconLabel, HPos.RIGHT);
|
||||
GridPane.setConstraints(iconLabel, 0, ++row);
|
||||
gridPane.getChildren().add(iconLabel);
|
||||
|
||||
GridPane.setConstraints(getIconNodeComboBox(), 1, row, 3, 1);
|
||||
gridPane.getChildren().add(getIconNodeComboBox());
|
||||
|
||||
GridPane.setConstraints(getApplyIconButton(), 4, row);
|
||||
gridPane.getChildren().add(getApplyIconButton());
|
||||
|
||||
Label listenLabel = new Label("Listen");
|
||||
GridPane.setHalignment(listenLabel, HPos.RIGHT);
|
||||
GridPane.setConstraints(listenLabel, 0, ++row);
|
||||
gridPane.getChildren().add(listenLabel);
|
||||
|
||||
GridPane.setConstraints(getMonitorAudioToggleSwitch(), 1, row);
|
||||
gridPane.getChildren().add(getMonitorAudioToggleSwitch());
|
||||
|
||||
Label priorityLabel = new Label("Priority");
|
||||
GridPane.setHalignment(priorityLabel, HPos.RIGHT);
|
||||
GridPane.setConstraints(priorityLabel, 2, row);
|
||||
gridPane.getChildren().add(priorityLabel);
|
||||
|
||||
GridPane.setConstraints(getMonitorPriorityComboBox(), 3, row);
|
||||
gridPane.getChildren().add(getMonitorPriorityComboBox());
|
||||
|
||||
GridPane.setConstraints(getApplyMonitorButton(), 4, row);
|
||||
gridPane.getChildren().add(getApplyMonitorButton());
|
||||
|
||||
getChildren().add(gridPane);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Alias> getItem()
|
||||
{
|
||||
return super.getItem();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setItem(List<Alias> item)
|
||||
{
|
||||
super.setItem(item);
|
||||
getEditingLabel().setText("Editing " + item.size() + " Aliases");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save()
|
||||
{
|
||||
//no-op
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose()
|
||||
{
|
||||
//no-op
|
||||
}
|
||||
|
||||
private Label getEditingLabel()
|
||||
{
|
||||
if(mEditingLabel== null)
|
||||
{
|
||||
mEditingLabel = new Label("Editing 0 Aliases");
|
||||
}
|
||||
|
||||
return mEditingLabel;
|
||||
}
|
||||
|
||||
private ColorPicker getColorPicker()
|
||||
{
|
||||
if(mColorPicker == null)
|
||||
{
|
||||
mColorPicker = new ColorPicker(Color.BLACK);
|
||||
mColorPicker.setEditable(true);
|
||||
mColorPicker.setStyle("-fx-color-rect-width: 60px; -fx-color-label-visible: false;");
|
||||
}
|
||||
|
||||
return mColorPicker;
|
||||
}
|
||||
|
||||
private Button getApplyColorButton()
|
||||
{
|
||||
if(mApplyColorButton == null)
|
||||
{
|
||||
mApplyColorButton = new Button("Apply");
|
||||
mApplyColorButton.setOnAction(event -> {
|
||||
int colorValue = ColorUtil.toInteger(getColorPicker().getValue());
|
||||
|
||||
for(Alias alias: getItem())
|
||||
{
|
||||
alias.setColor(colorValue);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return mApplyColorButton;
|
||||
}
|
||||
|
||||
private ComboBox<Icon> getIconNodeComboBox()
|
||||
{
|
||||
if(mIconNodeComboBox == null)
|
||||
{
|
||||
mIconNodeComboBox = new ComboBox<>();
|
||||
mIconNodeComboBox.setMaxWidth(Double.MAX_VALUE);
|
||||
mIconNodeComboBox.setItems(new SortedList(mPlaylistManager.getIconModel().iconsProperty(), Ordering.natural()));
|
||||
mIconNodeComboBox.setCellFactory(new IconCellFactory());
|
||||
mIconNodeComboBox.getSelectionModel().selectedItemProperty()
|
||||
.addListener((observable, oldValue, newValue) ->
|
||||
{
|
||||
getApplyIconButton().setDisable(newValue == null);
|
||||
});
|
||||
}
|
||||
|
||||
return mIconNodeComboBox;
|
||||
}
|
||||
|
||||
private Button getApplyIconButton()
|
||||
{
|
||||
if(mApplyIconButton == null)
|
||||
{
|
||||
mApplyIconButton = new Button("Apply");
|
||||
mApplyIconButton.setDisable(true);
|
||||
mApplyIconButton.setOnAction(new EventHandler<ActionEvent>()
|
||||
{
|
||||
@Override
|
||||
public void handle(ActionEvent event)
|
||||
{
|
||||
Icon icon = getIconNodeComboBox().getSelectionModel().getSelectedItem();
|
||||
|
||||
if(icon != null)
|
||||
{
|
||||
for(Alias alias: getItem())
|
||||
{
|
||||
alias.setIconName(icon.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return mApplyIconButton;
|
||||
}
|
||||
|
||||
private ToggleSwitch getMonitorAudioToggleSwitch()
|
||||
{
|
||||
if(mMonitorAudioToggleSwitch == null)
|
||||
{
|
||||
mMonitorAudioToggleSwitch = new ToggleSwitch();
|
||||
mMonitorAudioToggleSwitch.setSelected(true);
|
||||
mMonitorAudioToggleSwitch.selectedProperty()
|
||||
.addListener((observable, oldValue, newValue) -> modifiedProperty().set(true));
|
||||
}
|
||||
|
||||
return mMonitorAudioToggleSwitch;
|
||||
}
|
||||
|
||||
private ComboBox<Integer> getMonitorPriorityComboBox()
|
||||
{
|
||||
if(mMonitorPriorityComboBox == null)
|
||||
{
|
||||
mMonitorPriorityComboBox = new ComboBox<>();
|
||||
mMonitorPriorityComboBox.getItems().add(null);
|
||||
for(int x = io.github.dsheirer.alias.id.priority.Priority.MIN_PRIORITY;
|
||||
x < io.github.dsheirer.alias.id.priority.Priority.MAX_PRIORITY; x++)
|
||||
{
|
||||
mMonitorPriorityComboBox.getItems().add(x);
|
||||
}
|
||||
|
||||
mMonitorPriorityComboBox.disableProperty().bind(getMonitorAudioToggleSwitch().selectedProperty().not());
|
||||
mMonitorPriorityComboBox.getSelectionModel().selectedItemProperty()
|
||||
.addListener((observable, oldValue, newValue) -> modifiedProperty().set(true));
|
||||
}
|
||||
|
||||
return mMonitorPriorityComboBox;
|
||||
}
|
||||
|
||||
private Button getApplyMonitorButton()
|
||||
{
|
||||
if(mApplyMonitorButton == null)
|
||||
{
|
||||
mApplyMonitorButton = new Button("Apply");
|
||||
mApplyMonitorButton.setOnAction(new EventHandler<ActionEvent>()
|
||||
{
|
||||
@Override
|
||||
public void handle(ActionEvent event)
|
||||
{
|
||||
boolean canMonitor = getMonitorAudioToggleSwitch().isSelected();
|
||||
Integer priority = getMonitorPriorityComboBox().getSelectionModel().getSelectedItem();
|
||||
if(canMonitor)
|
||||
{
|
||||
if(priority == null)
|
||||
{
|
||||
priority = io.github.dsheirer.alias.id.priority.Priority.DEFAULT_PRIORITY;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
priority = io.github.dsheirer.alias.id.priority.Priority.DO_NOT_MONITOR;
|
||||
}
|
||||
|
||||
for(Alias alias: getItem())
|
||||
{
|
||||
alias.setCallPriority(priority);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return mApplyMonitorButton;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cell factory for combo box for dislaying icon name and graphic
|
||||
*/
|
||||
public class IconCellFactory implements Callback<ListView<Icon>, ListCell<Icon>>
|
||||
{
|
||||
@Override
|
||||
public ListCell<Icon> call(ListView<Icon> param)
|
||||
{
|
||||
Label iconLabel = new Label();
|
||||
Label textLabel = new Label();
|
||||
GridPane gridPane = new GridPane();
|
||||
gridPane.setHgap(5);
|
||||
GridPane.setHalignment(iconLabel, HPos.RIGHT);
|
||||
gridPane.getColumnConstraints().add(new ColumnConstraints(50));
|
||||
gridPane.add(iconLabel, 0, 0);
|
||||
gridPane.add(textLabel,1,0);
|
||||
|
||||
ListCell<Icon> cell = new ListCell<>()
|
||||
{
|
||||
@Override
|
||||
protected void updateItem(Icon item, boolean empty)
|
||||
{
|
||||
super.updateItem(item, empty);
|
||||
|
||||
if(empty)
|
||||
{
|
||||
setText(null);
|
||||
setGraphic(null);
|
||||
}
|
||||
else
|
||||
{
|
||||
textLabel.setText(item.getName());
|
||||
iconLabel.setGraphic(new ImageView(item.getFxImage()));
|
||||
setGraphic(gridPane);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return cell;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -27,12 +27,14 @@ import io.github.dsheirer.alias.AliasFactory;
|
||||
import io.github.dsheirer.alias.AliasList;
|
||||
import io.github.dsheirer.alias.AliasModel;
|
||||
import io.github.dsheirer.gui.control.MaxLengthUnaryOperator;
|
||||
import io.github.dsheirer.gui.playlist.Editor;
|
||||
import io.github.dsheirer.icon.Icon;
|
||||
import io.github.dsheirer.playlist.PlaylistManager;
|
||||
import io.github.dsheirer.preference.UserPreferences;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.property.ReadOnlyObjectWrapper;
|
||||
import javafx.beans.value.ObservableValue;
|
||||
import javafx.collections.ListChangeListener;
|
||||
import javafx.collections.transformation.FilteredList;
|
||||
import javafx.collections.transformation.SortedList;
|
||||
import javafx.geometry.Insets;
|
||||
@@ -85,6 +87,8 @@ public class AliasConfigurationEditor extends SplitPane
|
||||
private PlaylistManager mPlaylistManager;
|
||||
private UserPreferences mUserPreferences;
|
||||
private AliasItemEditor mAliasItemEditor;
|
||||
private AliasBulkEditor mAliasBulkEditor;
|
||||
private Editor mCurrentEditor;
|
||||
private TableView<Alias> mAliasTableView;
|
||||
private Label mPlaceholderLabel;
|
||||
private Button mNewAliasButton;
|
||||
@@ -114,6 +118,7 @@ public class AliasConfigurationEditor extends SplitPane
|
||||
topBox.getChildren().addAll(leftBox, getButtonBox());
|
||||
|
||||
setOrientation(Orientation.VERTICAL);
|
||||
mCurrentEditor = getAliasItemEditor();
|
||||
getItems().addAll(topBox, getAliasItemEditor());
|
||||
}
|
||||
|
||||
@@ -141,7 +146,20 @@ public class AliasConfigurationEditor extends SplitPane
|
||||
}
|
||||
}
|
||||
|
||||
private void setAlias(Alias alias)
|
||||
/**
|
||||
* Sets the editor as the bottom alias editor, either single alias or bulk alias editor.
|
||||
*/
|
||||
private void setEditor(Editor editor)
|
||||
{
|
||||
if(editor != mCurrentEditor)
|
||||
{
|
||||
getItems().remove(mCurrentEditor);
|
||||
mCurrentEditor = editor;
|
||||
getItems().add(mCurrentEditor);
|
||||
}
|
||||
}
|
||||
|
||||
private void setAliases(List<Alias> aliases)
|
||||
{
|
||||
//Prompt the user to save if the contents of the current channel editor have been modified
|
||||
if(getAliasItemEditor().modifiedProperty().get())
|
||||
@@ -168,18 +186,27 @@ public class AliasConfigurationEditor extends SplitPane
|
||||
}
|
||||
}
|
||||
|
||||
getCloneAliasButton().setDisable(alias == null || getAliasTableView().getSelectionModel().getSelectedItems().size() > 1);
|
||||
getDeleteAliasButton().setDisable(alias == null);
|
||||
getMoveToAliasButton().setDisable(alias == null);
|
||||
|
||||
if(getAliasTableView().getSelectionModel().getSelectedItems().size() <= 1)
|
||||
if(aliases.size() <= 1)
|
||||
{
|
||||
getAliasItemEditor().setItem(alias);
|
||||
setEditor(getAliasItemEditor());
|
||||
if(aliases.size() == 1)
|
||||
{
|
||||
getAliasItemEditor().setItem(aliases.get(0));
|
||||
}
|
||||
else
|
||||
{
|
||||
getAliasItemEditor().setItem(null);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
getAliasItemEditor().setItem(null);
|
||||
setEditor(getAliasBulkEditor());
|
||||
getAliasBulkEditor().setItem(aliases);
|
||||
}
|
||||
|
||||
getCloneAliasButton().setDisable(aliases.isEmpty() || aliases.size() > 1);
|
||||
getDeleteAliasButton().setDisable(aliases.isEmpty());
|
||||
getMoveToAliasButton().setDisable(aliases.isEmpty());
|
||||
}
|
||||
|
||||
private AliasItemEditor getAliasItemEditor()
|
||||
@@ -192,6 +219,16 @@ public class AliasConfigurationEditor extends SplitPane
|
||||
return mAliasItemEditor;
|
||||
}
|
||||
|
||||
private AliasBulkEditor getAliasBulkEditor()
|
||||
{
|
||||
if(mAliasBulkEditor == null)
|
||||
{
|
||||
mAliasBulkEditor = new AliasBulkEditor(mPlaylistManager);
|
||||
}
|
||||
|
||||
return mAliasBulkEditor;
|
||||
}
|
||||
|
||||
private HBox getSearchAndListSelectionBox()
|
||||
{
|
||||
if(mSearchAndListSelectionBox == null)
|
||||
@@ -384,10 +421,9 @@ public class AliasConfigurationEditor extends SplitPane
|
||||
mAliasTableView.setPlaceholder(getPlaceholderLabel());
|
||||
mAliasTableView.setItems(getAliasSortedList());
|
||||
mAliasTableView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
|
||||
mAliasTableView.getSelectionModel().selectedItemProperty()
|
||||
.addListener((observable, oldValue, newValue) -> {
|
||||
setAlias(newValue);
|
||||
});
|
||||
mAliasTableView.getSelectionModel().getSelectedItems().addListener((ListChangeListener<Alias>)c -> {
|
||||
setAliases(mAliasTableView.getSelectionModel().getSelectedItems());
|
||||
});
|
||||
}
|
||||
|
||||
return mAliasTableView;
|
||||
|
||||
@@ -335,12 +335,12 @@ public class AliasItemEditor extends Editor<Alias>
|
||||
alias.setRecordable(getRecordAudioToggleSwitch().isSelected());
|
||||
alias.setColor(ColorUtil.toInteger(getColorPicker().getValue()));
|
||||
|
||||
boolean canMonitor = getMonitorAudioToggleSwitch().isSelected();
|
||||
Integer priority = getMonitorPriorityComboBox().getSelectionModel().getSelectedItem();
|
||||
|
||||
Icon icon = getIconNodeComboBox().getSelectionModel().getSelectedItem();
|
||||
alias.setIconName(icon != null ? icon.getName() : null);
|
||||
|
||||
boolean canMonitor = getMonitorAudioToggleSwitch().isSelected();
|
||||
Integer priority = getMonitorPriorityComboBox().getSelectionModel().getSelectedItem();
|
||||
if(canMonitor)
|
||||
{
|
||||
if(priority == null)
|
||||
|
||||
Reference in New Issue
Block a user