forked from j62/ctbrec
Add a lot of model groups tweaks
This commit is contained in:
parent
e78ae2685a
commit
0c4f37f950
|
@ -2,6 +2,7 @@ package ctbrec.ui;
|
||||||
|
|
||||||
public enum Icon {
|
public enum Icon {
|
||||||
|
|
||||||
|
BLANK_16(Icon.class.getResource("/16/blank.png").toExternalForm()),
|
||||||
GROUP_16(Icon.class.getResource("/16/users.png").toExternalForm()),
|
GROUP_16(Icon.class.getResource("/16/users.png").toExternalForm()),
|
||||||
CHECK_16(Icon.class.getResource("/16/check-small.png").toExternalForm()),
|
CHECK_16(Icon.class.getResource("/16/check-small.png").toExternalForm()),
|
||||||
CLOCK_16(Icon.class.getResource("/16/clock.png").toExternalForm());
|
CLOCK_16(Icon.class.getResource("/16/clock.png").toExternalForm());
|
||||||
|
|
|
@ -43,8 +43,7 @@ public class AddToGroupAction {
|
||||||
source.setCursor(Cursor.WAIT);
|
source.setCursor(Cursor.WAIT);
|
||||||
try {
|
try {
|
||||||
var dialog = new AddModelGroupDialog();
|
var dialog = new AddModelGroupDialog();
|
||||||
boolean ok = Dialogs.showCustomInput(source.getScene(), "Add model to group", dialog.getMainPane());
|
boolean ok = Dialogs.showCustomInput(source.getScene(), "Add model to group", dialog.getMainPane(), (obs, ov, nv) -> dialog.requestFocus());
|
||||||
dialog.requestFocus();
|
|
||||||
if (ok) {
|
if (ok) {
|
||||||
String text = dialog.getText();
|
String text = dialog.getText();
|
||||||
if (StringUtil.isBlank(text)) {
|
if (StringUtil.isBlank(text)) {
|
||||||
|
@ -80,18 +79,19 @@ public class AddToGroupAction {
|
||||||
return comboBox.getEditor().getText();
|
return comboBox.getEditor().getText();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void requestFocus() {
|
void requestFocus() {
|
||||||
comboBox.requestFocus();
|
System.err.println("request focus");
|
||||||
editor.requestFocus();
|
editor.requestFocus();
|
||||||
|
editor.positionCaret(0);
|
||||||
|
editor.selectAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
Region getMainPane() throws InvalidKeyException, NoSuchAlgorithmException, IOException {
|
Region getMainPane() {
|
||||||
var dialogPane = new GridPane();
|
var dialogPane = new GridPane();
|
||||||
Set<ModelGroup> modelGroups;
|
Set<ModelGroup> modelGroups;
|
||||||
modelGroups = recorder.getModelGroups();
|
modelGroups = recorder.getModelGroups();
|
||||||
List<ModelGroupListItem> comboBoxItems = modelGroups.stream().map(ModelGroupListItem::new).sorted().collect(Collectors.toList());
|
List<ModelGroupListItem> comboBoxItems = modelGroups.stream().map(ModelGroupListItem::new).sorted().collect(Collectors.toList());
|
||||||
ObservableList<ModelGroupListItem> comboBoxModel = FXCollections.observableArrayList(comboBoxItems);
|
ObservableList<ModelGroupListItem> comboBoxModel = FXCollections.observableArrayList(comboBoxItems);
|
||||||
suggester = new ObservableListSuggester(comboBoxModel);
|
|
||||||
comboBox = new ComboBox<>(comboBoxModel);
|
comboBox = new ComboBox<>(comboBoxModel);
|
||||||
comboBox.setEditable(true);
|
comboBox.setEditable(true);
|
||||||
editor = comboBox.getEditor();
|
editor = comboBox.getEditor();
|
||||||
|
@ -112,9 +112,22 @@ public class AddToGroupAction {
|
||||||
comboBox.setPlaceholder(new Label(" type in a name to a add a new group "));
|
comboBox.setPlaceholder(new Label(" type in a name to a add a new group "));
|
||||||
dialogPane.add(new Label("Model group "), 0, 0);
|
dialogPane.add(new Label("Model group "), 0, 0);
|
||||||
dialogPane.add(comboBox, 1, 0);
|
dialogPane.add(comboBox, 1, 0);
|
||||||
|
suggestInitialName(modelGroups);
|
||||||
|
suggester = new ObservableListSuggester(comboBoxModel);
|
||||||
return dialogPane;
|
return dialogPane;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void suggestInitialName(Set<ModelGroup> modelGroups) {
|
||||||
|
String bestName = model.getDisplayName();
|
||||||
|
for (ModelGroup modelGroup : modelGroups) {
|
||||||
|
if (StringUtil.percentageOfEquality(bestName, modelGroup.getName()) > 70) {
|
||||||
|
bestName = modelGroup.getName();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
editor.setText(bestName);
|
||||||
|
}
|
||||||
|
|
||||||
private void autocomplete(boolean fulltextSearch) {
|
private void autocomplete(boolean fulltextSearch) {
|
||||||
String oldtext = getOldText();
|
String oldtext = getOldText();
|
||||||
if(oldtext.isEmpty()) {
|
if(oldtext.isEmpty()) {
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
package ctbrec.ui.action;
|
package ctbrec.ui.action;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.security.InvalidKeyException;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
@ -71,18 +68,13 @@ public class EditGroupAction {
|
||||||
private List<String> urls;
|
private List<String> urls;
|
||||||
|
|
||||||
public EditModelGroupDialog(Model model) {
|
public EditModelGroupDialog(Model model) {
|
||||||
Optional<ModelGroup> optionalModelGroup;
|
Optional<ModelGroup> optionalModelGroup = recorder.getModelGroup(model);
|
||||||
try {
|
if (optionalModelGroup.isPresent()) {
|
||||||
optionalModelGroup = recorder.getModelGroup(model);
|
modelGroup = optionalModelGroup.get();
|
||||||
if (optionalModelGroup.isPresent()) {
|
urls = new ArrayList<>(modelGroup.getModelUrls());
|
||||||
modelGroup = optionalModelGroup.get();
|
createGui(modelGroup);
|
||||||
urls = new ArrayList<>(modelGroup.getModelUrls());
|
} else {
|
||||||
createGui(modelGroup);
|
Dialogs.showError(getScene(), DIALOG_TITLE, "No group found for model", null);
|
||||||
} else {
|
|
||||||
Dialogs.showError(getScene(), DIALOG_TITLE, "No group found for model", null);
|
|
||||||
}
|
|
||||||
} catch (InvalidKeyException | NoSuchAlgorithmException | IOException e) {
|
|
||||||
Dialogs.showError(getScene(), DIALOG_TITLE, "Couldn't edit model group", e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,14 +95,12 @@ public class EditGroupAction {
|
||||||
vgapProperty().bind(hgapProperty());
|
vgapProperty().bind(hgapProperty());
|
||||||
|
|
||||||
groupName = new TextField(modelGroup.getName());
|
groupName = new TextField(modelGroup.getName());
|
||||||
Button up = createUpButton();
|
var up = createUpButton();
|
||||||
Button down = createDownButton();
|
var down = createDownButton();
|
||||||
Button remove = createRemoveButton();
|
var remove = createRemoveButton();
|
||||||
var buttons = new VBox(3, up, down, remove);
|
var buttons = new VBox(3, up, down, remove);
|
||||||
urlList = FXCollections.observableList(modelGroup.getModelUrls());
|
urlList = FXCollections.observableList(modelGroup.getModelUrls());
|
||||||
urlList.addListener((ListChangeListener<String>) change -> {
|
urlList.addListener((ListChangeListener<String>) change -> urls = new ArrayList<>(urlList));
|
||||||
urls = new ArrayList<>(urlList);
|
|
||||||
});
|
|
||||||
urlListView = new ListView<>(urlList);
|
urlListView = new ListView<>(urlList);
|
||||||
GridPane.setHgrow(urlListView, Priority.ALWAYS);
|
GridPane.setHgrow(urlListView, Priority.ALWAYS);
|
||||||
|
|
||||||
|
|
|
@ -10,5 +10,8 @@ public class CustomMouseBehaviorContextMenu extends ContextMenu {
|
||||||
super(items);
|
super(items);
|
||||||
UiUtils.disableRightClickFor(this);
|
UiUtils.disableRightClickFor(this);
|
||||||
UiUtils.ignoreMouseReleasedIfMouseExited(this);
|
UiUtils.ignoreMouseReleasedIfMouseExited(this);
|
||||||
|
setAutoHide(true);
|
||||||
|
setHideOnEscape(true);
|
||||||
|
setAutoFix(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ import ctbrec.ModelGroup;
|
||||||
import ctbrec.StringUtil;
|
import ctbrec.StringUtil;
|
||||||
import ctbrec.ui.AutosizeAlert;
|
import ctbrec.ui.AutosizeAlert;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
|
import javafx.beans.value.ChangeListener;
|
||||||
import javafx.collections.FXCollections;
|
import javafx.collections.FXCollections;
|
||||||
import javafx.collections.ObservableList;
|
import javafx.collections.ObservableList;
|
||||||
import javafx.geometry.Insets;
|
import javafx.geometry.Insets;
|
||||||
|
@ -105,7 +106,8 @@ public class Dialogs {
|
||||||
return dialog.showAndWait();
|
return dialog.showAndWait();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Boolean showCustomInput(Scene parent, String title, Region region) {
|
@SafeVarargs
|
||||||
|
public static Boolean showCustomInput(Scene parent, String title, Region region, ChangeListener<Boolean> ...showingListener) {
|
||||||
Dialog<?> dialog = new Dialog<>();
|
Dialog<?> dialog = new Dialog<>();
|
||||||
dialog.setTitle(title);
|
dialog.setTitle(title);
|
||||||
dialog.getDialogPane().getButtonTypes().addAll(OK, CANCEL);
|
dialog.getDialogPane().getButtonTypes().addAll(OK, CANCEL);
|
||||||
|
@ -118,6 +120,9 @@ public class Dialogs {
|
||||||
stage.getScene().getStylesheets().addAll(parent.getStylesheets());
|
stage.getScene().getStylesheets().addAll(parent.getStylesheets());
|
||||||
}
|
}
|
||||||
dialog.getDialogPane().setContent(region);
|
dialog.getDialogPane().setContent(region);
|
||||||
|
for (ChangeListener<Boolean> changeListener : showingListener) {
|
||||||
|
dialog.showingProperty().addListener(changeListener);
|
||||||
|
}
|
||||||
dialog.showAndWait();
|
dialog.showAndWait();
|
||||||
return dialog.getResult() == OK;
|
return dialog.getResult() == OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,8 +4,6 @@ import static ctbrec.ui.controls.Dialogs.*;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.SocketTimeoutException;
|
import java.net.SocketTimeoutException;
|
||||||
import java.security.InvalidKeyException;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.text.DecimalFormat;
|
import java.text.DecimalFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -48,7 +46,6 @@ import ctbrec.ui.action.IgnoreModelsAction;
|
||||||
import ctbrec.ui.action.OpenRecordingsDir;
|
import ctbrec.ui.action.OpenRecordingsDir;
|
||||||
import ctbrec.ui.action.SetStopDateAction;
|
import ctbrec.ui.action.SetStopDateAction;
|
||||||
import ctbrec.ui.controls.CustomMouseBehaviorContextMenu;
|
import ctbrec.ui.controls.CustomMouseBehaviorContextMenu;
|
||||||
import ctbrec.ui.controls.Dialogs;
|
|
||||||
import ctbrec.ui.controls.FasterVerticalScrollPaneSkin;
|
import ctbrec.ui.controls.FasterVerticalScrollPaneSkin;
|
||||||
import ctbrec.ui.controls.SearchBox;
|
import ctbrec.ui.controls.SearchBox;
|
||||||
import ctbrec.ui.controls.SearchPopover;
|
import ctbrec.ui.controls.SearchPopover;
|
||||||
|
@ -472,6 +469,14 @@ public class ThumbOverviewTab extends Tab implements TabSelectionListener {
|
||||||
return newCell;
|
return newCell;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// private ContextMenu createContextMenu(ThumbCell cell) {
|
||||||
|
// return new ModelContextMenu.Builder()
|
||||||
|
// .model(cell.getModel())
|
||||||
|
// .node(grid)
|
||||||
|
// .recorder(recorder)
|
||||||
|
// .build();
|
||||||
|
// }
|
||||||
|
|
||||||
private ContextMenu createContextMenu(ThumbCell cell) {
|
private ContextMenu createContextMenu(ThumbCell cell) {
|
||||||
var model = cell.getModel();
|
var model = cell.getModel();
|
||||||
boolean modelIsTrackedByRecorder = recorder.isTracked(model);
|
boolean modelIsTrackedByRecorder = recorder.isTracked(model);
|
||||||
|
@ -546,7 +551,7 @@ public class ThumbOverviewTab extends Tab implements TabSelectionListener {
|
||||||
if (site.supportsTips()) {
|
if (site.supportsTips()) {
|
||||||
contextMenu.getItems().add(sendTip);
|
contextMenu.getItems().add(sendTip);
|
||||||
}
|
}
|
||||||
Optional<ModelGroup> modelGroup = getModelGroup(model);
|
Optional<ModelGroup> modelGroup = recorder.getModelGroup(model);
|
||||||
contextMenu.getItems().add(modelGroup.isEmpty() ? addToGroup : editGroup);
|
contextMenu.getItems().add(modelGroup.isEmpty() ? addToGroup : editGroup);
|
||||||
contextMenu.getItems().addAll(copyUrl, openInBrowser, ignore, refresh, openRecDir);
|
contextMenu.getItems().addAll(copyUrl, openInBrowser, ignore, refresh, openRecDir);
|
||||||
if (model instanceof MyFreeCamsModel && Objects.equals(System.getenv("CTBREC_DEV"), "1")) {
|
if (model instanceof MyFreeCamsModel && Objects.equals(System.getenv("CTBREC_DEV"), "1")) {
|
||||||
|
@ -558,15 +563,6 @@ public class ThumbOverviewTab extends Tab implements TabSelectionListener {
|
||||||
return contextMenu;
|
return contextMenu;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Optional<ModelGroup> getModelGroup(Model model) {
|
|
||||||
try {
|
|
||||||
return recorder.getModelGroup(model);
|
|
||||||
} catch (InvalidKeyException | NoSuchAlgorithmException | IOException e) {
|
|
||||||
Dialogs.showError(grid.getScene(), "Error", "Couldn't get model group for model " + model, e);
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void editGroup(Model model) {
|
private void editGroup(Model model) {
|
||||||
new EditGroupAction(this.getContent(), recorder, model).execute();
|
new EditGroupAction(this.getContent(), recorder, model).execute();
|
||||||
}
|
}
|
||||||
|
@ -900,14 +896,14 @@ public class ThumbOverviewTab extends Tab implements TabSelectionListener {
|
||||||
private boolean modelPropertiesMatchToken(String token, Model m) throws IOException, ExecutionException {
|
private boolean modelPropertiesMatchToken(String token, Model m) throws IOException, ExecutionException {
|
||||||
int[] resolution = Optional.ofNullable(ThumbCell.resolutionCache.getIfPresent(m)).orElse(new int[2]);
|
int[] resolution = Optional.ofNullable(ThumbCell.resolutionCache.getIfPresent(m)).orElse(new int[2]);
|
||||||
String searchText = createSearchText(m);
|
String searchText = createSearchText(m);
|
||||||
boolean tokensMissing = false;
|
var tokensMissing = false;
|
||||||
if (token.matches(">\\d+")) {
|
if (token.matches(">\\d+")) {
|
||||||
int res = Integer.parseInt(token.substring(1));
|
var res = Integer.parseInt(token.substring(1));
|
||||||
if (resolution[1] < res) {
|
if (resolution[1] < res) {
|
||||||
tokensMissing = true;
|
tokensMissing = true;
|
||||||
}
|
}
|
||||||
} else if (token.matches("<\\d+")) {
|
} else if (token.matches("<\\d+")) {
|
||||||
int res = Integer.parseInt(token.substring(1));
|
var res = Integer.parseInt(token.substring(1));
|
||||||
if (resolution[1] > res) {
|
if (resolution[1] > res) {
|
||||||
tokensMissing = true;
|
tokensMissing = true;
|
||||||
}
|
}
|
||||||
|
@ -916,7 +912,7 @@ public class ThumbOverviewTab extends Tab implements TabSelectionListener {
|
||||||
tokensMissing = true;
|
tokensMissing = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
boolean negated = false;
|
var negated = false;
|
||||||
if(token.startsWith("!")) {
|
if(token.startsWith("!")) {
|
||||||
negated = true;
|
negated = true;
|
||||||
token = token.substring(1);
|
token = token.substring(1);
|
||||||
|
@ -928,7 +924,7 @@ public class ThumbOverviewTab extends Tab implements TabSelectionListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
private String createSearchText(Model m) {
|
private String createSearchText(Model m) {
|
||||||
StringBuilder searchTextBuilder = new StringBuilder(m.getName());
|
var searchTextBuilder = new StringBuilder(m.getName());
|
||||||
searchTextBuilder.append(' ');
|
searchTextBuilder.append(' ');
|
||||||
searchTextBuilder.append(m.getDisplayName());
|
searchTextBuilder.append(m.getDisplayName());
|
||||||
searchTextBuilder.append(' ');
|
searchTextBuilder.append(' ');
|
||||||
|
@ -939,6 +935,8 @@ public class ThumbOverviewTab extends Tab implements TabSelectionListener {
|
||||||
searchTextBuilder.append(resolution[1]);
|
searchTextBuilder.append(resolution[1]);
|
||||||
searchTextBuilder.append(' ');
|
searchTextBuilder.append(' ');
|
||||||
searchTextBuilder.append(Optional.ofNullable(m.getDescription()).orElse(""));
|
searchTextBuilder.append(Optional.ofNullable(m.getDescription()).orElse(""));
|
||||||
|
searchTextBuilder.append(' ');
|
||||||
|
searchTextBuilder.append(recorder.getModelGroup(m).map(ModelGroup::getName).orElse(""));
|
||||||
return searchTextBuilder.toString().trim();
|
return searchTextBuilder.toString().trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,55 +2,42 @@ package ctbrec.ui.tabs.recorded;
|
||||||
|
|
||||||
import static ctbrec.ui.Icon.*;
|
import static ctbrec.ui.Icon.*;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.security.InvalidKeyException;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import ctbrec.Model;
|
import ctbrec.Model;
|
||||||
import ctbrec.ModelGroup;
|
|
||||||
import ctbrec.recorder.Recorder;
|
import ctbrec.recorder.Recorder;
|
||||||
import ctbrec.ui.controls.Dialogs;
|
import ctbrec.ui.tabs.recorded.RecordedModelsTab.ModelName;
|
||||||
import javafx.scene.image.ImageView;
|
import javafx.scene.image.ImageView;
|
||||||
|
|
||||||
public class ModelNameTableCell extends IconTableCell<String> {
|
public class ModelNameTableCell extends IconTableCell<ModelName> {
|
||||||
|
|
||||||
private Recorder recorder;
|
private Recorder recorder;
|
||||||
|
|
||||||
public ModelNameTableCell(Recorder recorder) {
|
public ModelNameTableCell(Recorder recorder) {
|
||||||
super(Map.of(GROUP_16, new ImageView(GROUP_16.url())));
|
super(Map.of( //
|
||||||
|
GROUP_16, new ImageView(GROUP_16.url()), //
|
||||||
|
BLANK_16, new ImageView(BLANK_16.url())));
|
||||||
this.recorder = recorder;
|
this.recorder = recorder;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void updateItem(String item, boolean empty) {
|
protected void updateItem(ModelName modelName, boolean empty) {
|
||||||
setText(null);
|
setText(null);
|
||||||
tooltip = null;
|
tooltip = null;
|
||||||
|
show(BLANK_16);
|
||||||
hide(GROUP_16);
|
hide(GROUP_16);
|
||||||
|
|
||||||
if (item != null && !empty) {
|
if (modelName != null && !empty) {
|
||||||
setText(item);
|
setText(modelName.toString());
|
||||||
Model m = getTableView().getItems().get(getTableRow().getIndex());
|
Model m = getTableView().getItems().get(getTableRow().getIndex());
|
||||||
Optional<ModelGroup> optionalGroup = getModelGroup(m);
|
recorder.getModelGroup(m).ifPresent(group -> {
|
||||||
if (optionalGroup.isPresent()) {
|
hide(BLANK_16);
|
||||||
ModelGroup group = optionalGroup.get();
|
|
||||||
setText(group.getName() + " (aka " + item + ')');
|
|
||||||
show(GROUP_16);
|
show(GROUP_16);
|
||||||
tooltip = group.getModelUrls().size() + " models:\n";
|
tooltip = group.getModelUrls().size() + " models:\n";
|
||||||
tooltip += group.getModelUrls().stream().collect(Collectors.joining("\n"));
|
tooltip += group.getModelUrls().stream().collect(Collectors.joining("\n"));
|
||||||
}
|
});
|
||||||
}
|
|
||||||
super.updateItem(item, empty);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Optional<ModelGroup> getModelGroup(Model model) {
|
|
||||||
try {
|
|
||||||
return recorder.getModelGroup(model);
|
|
||||||
} catch (InvalidKeyException | NoSuchAlgorithmException | IOException e) {
|
|
||||||
Dialogs.showError(getScene(), "Error", "Couldn't get model group for model " + model, e);
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
}
|
||||||
|
super.updateItem(modelName, empty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,16 +16,11 @@ public class OnlineTableCell extends IconTableCell<Boolean> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void updateItem(Boolean value, boolean empty) {
|
protected void updateItem(Boolean value, boolean empty) {
|
||||||
if (!empty) {
|
hide(CHECK_16);
|
||||||
if (Objects.equal(value, Boolean.TRUE)) {
|
tooltip = null;
|
||||||
show(CHECK_16);
|
if (!empty && Objects.equal(value, Boolean.TRUE)) {
|
||||||
tooltip = "Online";
|
show(CHECK_16);
|
||||||
} else {
|
tooltip = "Online";
|
||||||
hide(CHECK_16);
|
|
||||||
tooltip = null;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
tooltip = null;
|
|
||||||
}
|
}
|
||||||
super.updateItem(value, empty);
|
super.updateItem(value, empty);
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,6 +59,7 @@ import ctbrec.ui.controls.autocomplete.AutoFillTextField;
|
||||||
import ctbrec.ui.controls.autocomplete.ObservableListSuggester;
|
import ctbrec.ui.controls.autocomplete.ObservableListSuggester;
|
||||||
import ctbrec.ui.tabs.TabSelectionListener;
|
import ctbrec.ui.tabs.TabSelectionListener;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
|
import javafx.beans.property.SimpleObjectProperty;
|
||||||
import javafx.beans.property.SimpleStringProperty;
|
import javafx.beans.property.SimpleStringProperty;
|
||||||
import javafx.beans.property.StringPropertyBase;
|
import javafx.beans.property.StringPropertyBase;
|
||||||
import javafx.beans.value.ChangeListener;
|
import javafx.beans.value.ChangeListener;
|
||||||
|
@ -170,9 +171,12 @@ public class RecordedModelsTab extends Tab implements TabSelectionListener {
|
||||||
if(!Config.getInstance().getSettings().livePreviews) {
|
if(!Config.getInstance().getSettings().livePreviews) {
|
||||||
preview.setVisible(false);
|
preview.setVisible(false);
|
||||||
}
|
}
|
||||||
TableColumn<JavaFxModel, String> name = new TableColumn<>("Model");
|
TableColumn<JavaFxModel, ModelName> name = new TableColumn<>("Model");
|
||||||
name.setPrefWidth(200);
|
name.setPrefWidth(200);
|
||||||
name.setCellValueFactory(new PropertyValueFactory<>("displayName"));
|
name.setCellValueFactory(param -> {
|
||||||
|
ModelName modelName = new ModelName(param.getValue(), recorder);
|
||||||
|
return new SimpleObjectProperty<>(modelName);
|
||||||
|
});
|
||||||
name.setCellFactory(param -> new ModelNameTableCell(recorder));
|
name.setCellFactory(param -> new ModelNameTableCell(recorder));
|
||||||
name.setEditable(false);
|
name.setEditable(false);
|
||||||
name.setId("name");
|
name.setId("name");
|
||||||
|
@ -694,7 +698,7 @@ public class RecordedModelsTab extends Tab implements TabSelectionListener {
|
||||||
} else {
|
} else {
|
||||||
menu.getItems().addAll(resumeRecording, pauseRecording);
|
menu.getItems().addAll(resumeRecording, pauseRecording);
|
||||||
}
|
}
|
||||||
Optional<ModelGroup> modelGroup = getModelGroup(selectedModels.get(0));
|
Optional<ModelGroup> modelGroup = recorder.getModelGroup(selectedModels.get(0));
|
||||||
menu.getItems().add(modelGroup.isEmpty() ? addToGroup : editGroup);
|
menu.getItems().add(modelGroup.isEmpty() ? addToGroup : editGroup);
|
||||||
menu.getItems().addAll(copyUrl, openInPlayer, openInBrowser, openRecDir, switchStreamSource, follow, notes, ignore);
|
menu.getItems().addAll(copyUrl, openInPlayer, openInBrowser, openRecDir, switchStreamSource, follow, notes, ignore);
|
||||||
|
|
||||||
|
@ -709,15 +713,6 @@ public class RecordedModelsTab extends Tab implements TabSelectionListener {
|
||||||
return menu;
|
return menu;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Optional<ModelGroup> getModelGroup(Model model) {
|
|
||||||
try {
|
|
||||||
return recorder.getModelGroup(model);
|
|
||||||
} catch (InvalidKeyException | NoSuchAlgorithmException | IOException e) {
|
|
||||||
Dialogs.showError(grid.getScene(), "Error", "Couldn't get model group for model " + model, e);
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void addToGroup(Model model) {
|
private void addToGroup(Model model) {
|
||||||
new AddToGroupAction(this.getContent(), recorder, model).execute();
|
new AddToGroupAction(this.getContent(), recorder, model).execute();
|
||||||
table.refresh();
|
table.refresh();
|
||||||
|
@ -952,4 +947,26 @@ public class RecordedModelsTab extends Tab implements TabSelectionListener {
|
||||||
return tableCell;
|
return tableCell;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class ModelName {
|
||||||
|
private Model mdl;
|
||||||
|
private Recorder rec;
|
||||||
|
|
||||||
|
public ModelName(Model model, Recorder recorder) {
|
||||||
|
mdl = model;
|
||||||
|
rec = recorder;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
Optional<ModelGroup> modelGroup = rec.getModelGroup(mdl);
|
||||||
|
String s;
|
||||||
|
if (modelGroup.isPresent()) {
|
||||||
|
s = modelGroup.get().getName() + " (aka " + mdl.getDisplayName() + ')';
|
||||||
|
} else {
|
||||||
|
return mdl.toString();
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 533 B |
Binary file not shown.
After Width: | Height: | Size: 541 B |
|
@ -88,4 +88,107 @@ public class StringUtil {
|
||||||
}
|
}
|
||||||
return result.toString();
|
return result.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int percentageOfEquality(String s, String t) {
|
||||||
|
// check if strings are empty
|
||||||
|
if (s == null || t == null || s.length() == 0 || t.length() == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if the strings are equal
|
||||||
|
if (s.equals(t)) {
|
||||||
|
return 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if one string is a substring of the other
|
||||||
|
String shorter;
|
||||||
|
String longer;
|
||||||
|
if (s.length() > t.length()) {
|
||||||
|
shorter = t;
|
||||||
|
longer = s;
|
||||||
|
} else {
|
||||||
|
shorter = s;
|
||||||
|
longer = t;
|
||||||
|
}
|
||||||
|
if (longer.startsWith(shorter) && longer.length() > shorter.length()) {
|
||||||
|
if (longer.charAt(shorter.length()) == ' ') {
|
||||||
|
return 99;
|
||||||
|
} else {
|
||||||
|
return 98;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
s = s.toLowerCase();
|
||||||
|
s = s.replaceAll("-", " ");
|
||||||
|
s = s.replaceAll(":", " ");
|
||||||
|
s = s.replaceAll(";", " ");
|
||||||
|
s = s.replaceAll("\\|", " ");
|
||||||
|
s = s.replaceAll("_", " ");
|
||||||
|
s = s.replaceAll("\\.", "\\. ");
|
||||||
|
s = s.trim();
|
||||||
|
t = t.toLowerCase();
|
||||||
|
t = t.replaceAll("-", " ");
|
||||||
|
t = t.replaceAll(":", " ");
|
||||||
|
t = t.replaceAll(";", " ");
|
||||||
|
t = t.replaceAll("\\|", " ");
|
||||||
|
t = t.replaceAll("_", " ");
|
||||||
|
t = t.replaceAll("\\.", "\\. ");
|
||||||
|
t = t.trim();
|
||||||
|
|
||||||
|
// calculate levenshteinDistance
|
||||||
|
int levenshteinDistance = StringUtil.getLevenshteinDistance(s, t);
|
||||||
|
int length = Math.max(s.length(), t.length());
|
||||||
|
|
||||||
|
// calculate the percentage of equality
|
||||||
|
int percentage = 100 - (int) ((double) levenshteinDistance * 100 / length);
|
||||||
|
return percentage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int getLevenshteinDistance(String s, String t) {
|
||||||
|
int n = s.length();
|
||||||
|
int m = t.length();
|
||||||
|
int d[][] = new int[n + 1][m + 1];
|
||||||
|
int i;
|
||||||
|
int j;
|
||||||
|
int cost;
|
||||||
|
|
||||||
|
if (n == 0) {
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
if (m == 0) {
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i <= n; i++) {
|
||||||
|
d[i][0] = i;
|
||||||
|
}
|
||||||
|
for (j = 0; j <= m; j++) {
|
||||||
|
d[0][j] = j;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 1; i <= n; i++) {
|
||||||
|
for (j = 1; j <= m; j++) {
|
||||||
|
if (s.charAt(i - 1) == t.charAt(j - 1)) {
|
||||||
|
cost = 0;
|
||||||
|
} else {
|
||||||
|
cost = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
d[i][j] = min(d[i - 1][j] + 1, // insertion
|
||||||
|
d[i][j - 1] + 1, // deletion
|
||||||
|
d[i - 1][j - 1] + cost); // substitution
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return d[n][m];
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int min(int a, int b, int c) {
|
||||||
|
if (b < a) {
|
||||||
|
a = b;
|
||||||
|
}
|
||||||
|
if (c < a) {
|
||||||
|
a = c;
|
||||||
|
}
|
||||||
|
return a;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -152,7 +152,7 @@ public interface Recorder {
|
||||||
*/
|
*/
|
||||||
public int getModelCount();
|
public int getModelCount();
|
||||||
|
|
||||||
public Set<ModelGroup> getModelGroups() throws InvalidKeyException, NoSuchAlgorithmException, IOException;
|
public Set<ModelGroup> getModelGroups();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Saves a model group. If the group already exists, it will be overwritten. Otherwise it will
|
* Saves a model group. If the group already exists, it will be overwritten. Otherwise it will
|
||||||
|
@ -166,7 +166,7 @@ public interface Recorder {
|
||||||
|
|
||||||
public void deleteModelGroup(ModelGroup group) throws IOException, InvalidKeyException, NoSuchAlgorithmException;
|
public void deleteModelGroup(ModelGroup group) throws IOException, InvalidKeyException, NoSuchAlgorithmException;
|
||||||
|
|
||||||
default Optional<ModelGroup> getModelGroup(Model model) throws InvalidKeyException, NoSuchAlgorithmException, IOException {
|
default Optional<ModelGroup> getModelGroup(Model model) {
|
||||||
return getModelGroups().stream()
|
return getModelGroups().stream()
|
||||||
.filter(mg -> mg.getModelUrls().contains(model.getUrl()))
|
.filter(mg -> mg.getModelUrls().contains(model.getUrl()))
|
||||||
.findFirst();
|
.findFirst();
|
||||||
|
|
|
@ -690,7 +690,7 @@ public class RemoteRecorder implements Recorder {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<ModelGroup> getModelGroups() throws InvalidKeyException, NoSuchAlgorithmException, IOException {
|
public Set<ModelGroup> getModelGroups() {
|
||||||
return modelGroups;
|
return modelGroups;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,9 +3,6 @@ package ctbrec.recorder.postprocessing;
|
||||||
import static ctbrec.StringUtil.*;
|
import static ctbrec.StringUtil.*;
|
||||||
import static java.util.Optional.*;
|
import static java.util.Optional.*;
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.security.InvalidKeyException;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
import java.time.ZoneOffset;
|
import java.time.ZoneOffset;
|
||||||
|
@ -18,9 +15,6 @@ import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import ctbrec.Config;
|
import ctbrec.Config;
|
||||||
import ctbrec.Model;
|
import ctbrec.Model;
|
||||||
import ctbrec.ModelGroup;
|
import ctbrec.ModelGroup;
|
||||||
|
@ -30,18 +24,10 @@ import ctbrec.sites.Site;
|
||||||
|
|
||||||
public abstract class AbstractPlaceholderAwarePostProcessor extends AbstractPostProcessor {
|
public abstract class AbstractPlaceholderAwarePostProcessor extends AbstractPostProcessor {
|
||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(AbstractPlaceholderAwarePostProcessor.class);
|
|
||||||
|
|
||||||
public String fillInPlaceHolders(String input, PostProcessingContext ctx) {
|
public String fillInPlaceHolders(String input, PostProcessingContext ctx) {
|
||||||
Recording rec = ctx.getRecording();
|
Recording rec = ctx.getRecording();
|
||||||
Config config = ctx.getConfig();
|
Config config = ctx.getConfig();
|
||||||
Optional<ModelGroup> modelGroup;
|
Optional<ModelGroup> modelGroup = ctx.getRecorder().getModelGroup(rec.getModel());
|
||||||
try {
|
|
||||||
modelGroup = ctx.getRecorder().getModelGroup(rec.getModel());
|
|
||||||
} catch (InvalidKeyException | NoSuchAlgorithmException | IOException e) {
|
|
||||||
LOG.error("Couldn't get model group for {}", rec.getModel(), e);
|
|
||||||
return input;
|
|
||||||
}
|
|
||||||
|
|
||||||
Map<String, Function<String, Optional<String>>> placeholderValueSuppliers = new HashMap<>();
|
Map<String, Function<String, Optional<String>>> placeholderValueSuppliers = new HashMap<>();
|
||||||
placeholderValueSuppliers.put("modelName", r -> ofNullable(rec.getModel().getName()));
|
placeholderValueSuppliers.put("modelName", r -> ofNullable(rec.getModel().getName()));
|
||||||
|
|
Loading…
Reference in New Issue