diff --git a/client/src/main/java/ctbrec/ui/controls/table/SettingTableViewStateStore.java b/client/src/main/java/ctbrec/ui/controls/table/SettingTableViewStateStore.java index 1c59195c..f2aaedea 100644 --- a/client/src/main/java/ctbrec/ui/controls/table/SettingTableViewStateStore.java +++ b/client/src/main/java/ctbrec/ui/controls/table/SettingTableViewStateStore.java @@ -7,6 +7,7 @@ import java.util.Map; import ctbrec.Config; import ctbrec.Settings; +import ctbrec.StringUtil; import javafx.scene.control.TableColumn.SortType; public class SettingTableViewStateStore implements TableViewStateStore { @@ -51,7 +52,12 @@ public class SettingTableViewStateStore implements TableViewStateStore { @Override public SortType loadSortType() { - return SortType.valueOf(loadSetting(sortTypeSetting)); + String sortType = loadSetting(sortTypeSetting); + if (StringUtil.isBlank(sortType)) { + return SortType.ASCENDING; + } else { + return SortType.valueOf(sortType); + } } @SuppressWarnings("unchecked") diff --git a/client/src/main/java/ctbrec/ui/tabs/recorded/AbstractRecordedModelsTab.java b/client/src/main/java/ctbrec/ui/tabs/recorded/AbstractRecordedModelsTab.java index 2c9f60b7..08c27585 100644 --- a/client/src/main/java/ctbrec/ui/tabs/recorded/AbstractRecordedModelsTab.java +++ b/client/src/main/java/ctbrec/ui/tabs/recorded/AbstractRecordedModelsTab.java @@ -1,5 +1,7 @@ package ctbrec.ui.tabs.recorded; +import static ctbrec.ui.action.AbstractPortraitAction.*; + import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; @@ -32,7 +34,6 @@ import ctbrec.ui.PreviewPopupHandler; import ctbrec.ui.action.AbstractPortraitAction.PortraitChangedEvent; import ctbrec.ui.action.MarkForLaterRecordingAction; import ctbrec.ui.action.PlayAction; -import ctbrec.ui.action.SetPortraitAction; import ctbrec.ui.action.StartRecordingAction; import ctbrec.ui.controls.CustomMouseBehaviorContextMenu; import ctbrec.ui.controls.DateTimeCellFactory; @@ -40,6 +41,8 @@ import ctbrec.ui.controls.Dialogs; import ctbrec.ui.controls.SearchBox; import ctbrec.ui.controls.autocomplete.AutoFillTextField; import ctbrec.ui.controls.autocomplete.ObservableListSuggester; +import ctbrec.ui.controls.table.SettingTableViewStateStore; +import ctbrec.ui.controls.table.StatePersistingTableView; import ctbrec.ui.menu.ModelMenuContributor; import ctbrec.ui.tabs.TabSelectionListener; import javafx.application.Platform; @@ -50,11 +53,9 @@ import javafx.collections.FXCollections; import javafx.collections.ObservableList; import javafx.event.ActionEvent; import javafx.geometry.Insets; -import javafx.geometry.Point2D; import javafx.geometry.Pos; import javafx.scene.control.Alert; import javafx.scene.control.Button; -import javafx.scene.control.CheckMenuItem; import javafx.scene.control.ContextMenu; import javafx.scene.control.Label; import javafx.scene.control.ScrollPane; @@ -62,9 +63,7 @@ import javafx.scene.control.SelectionMode; import javafx.scene.control.Tab; import javafx.scene.control.TableCell; import javafx.scene.control.TableColumn; -import javafx.scene.control.TableColumn.SortType; import javafx.scene.control.TableRow; -import javafx.scene.control.TableView; import javafx.scene.control.TextField; import javafx.scene.control.Tooltip; import javafx.scene.control.cell.PropertyValueFactory; @@ -89,7 +88,8 @@ public abstract class AbstractRecordedModelsTab extends Tab implements TabSelect protected ObservableList observableModels = FXCollections.observableArrayList(); protected ObservableList filteredModels = FXCollections.observableArrayList(); - protected TableView table = new TableView<>(); + protected SettingTableViewStateStore tableStateStore; + protected StatePersistingTableView table; protected List> columns = new ArrayList<>(); protected LoadingCache portraitCache = CacheBuilder.newBuilder() .expireAfterAccess(1, TimeUnit.DAYS) @@ -113,9 +113,11 @@ public abstract class AbstractRecordedModelsTab extends Tab implements TabSelect protected Config config; - AbstractRecordedModelsTab(String text) { + AbstractRecordedModelsTab(String text, String stateStorePrefix) { super(text); config = Config.getInstance(); + tableStateStore = new SettingTableViewStateStore(config, stateStorePrefix); + table = new StatePersistingTableView<>(tableStateStore); registerPortraitListener(); } @@ -215,13 +217,7 @@ public abstract class AbstractRecordedModelsTab extends Tab implements TabSelect }); filter.getStyleClass().remove("search-box-icon"); - var columnSelection = new Button("⚙"); - columnSelection.setOnAction(this::showColumnSelection); - columnSelection.setTooltip(new Tooltip("Select columns")); - columnSelection.prefHeightProperty().bind(filter.prefHeightProperty()); - columnSelection.prefWidthProperty().bind(columnSelection.prefHeightProperty()); - - filterContainer.getChildren().addAll(columnSelection, filter); + filterContainer.getChildren().addAll(filter); addModelBox.getChildren().add(filterContainer); } @@ -229,9 +225,6 @@ public abstract class AbstractRecordedModelsTab extends Tab implements TabSelect TableColumn preview = addTableColumn("preview", "🎥", columnIdx, 35); preview.setCellValueFactory(cdf -> new SimpleStringProperty(" ▶ ")); preview.setEditable(false); - if (!Config.getInstance().getSettings().livePreviews) { - preview.setVisible(false); - } } protected void addPortraitColumn(int columnIdx) { @@ -311,16 +304,10 @@ public abstract class AbstractRecordedModelsTab extends Tab implements TabSelect tc.setPrefWidth(width); tc.setStyle("-fx-alignment: CENTER-LEFT;"); columns.add(tc); - addTableColumnIfEnabled(tc); + table.getColumns().add(tc); return tc; } - protected void addTableColumnIfEnabled(TableColumn tc) { - if(isColumnEnabled(tc)) { - table.getColumns().add(tc); - } - } - protected ContextMenu createContextMenu() { List selectedModels = table.getSelectionModel().getSelectedItems().stream().map(JavaFxModel::getDelegate).collect(Collectors.toList()); if (selectedModels.isEmpty()) { @@ -486,74 +473,14 @@ public abstract class AbstractRecordedModelsTab extends Tab implements TabSelect } } - abstract String getSortColumn(); - abstract void setSortColumn(String column); - abstract String getSortType(); - abstract void setSortType(String sortType); - abstract String[] getColumnIds(); - abstract void setColumnIds(String[] ids); - abstract double[] getColumnWidths(); - abstract void setColumnWidths(double[] widths); - abstract List getDisabledColumns(); - public void saveState() { - if (!table.getSortOrder().isEmpty()) { - TableColumn col = table.getSortOrder().get(0); - setSortColumn(col.getText()); - setSortType(col.getSortType().toString()); - } - int tableColumns = table.getColumns().size(); - var columnWidths = new double[tableColumns]; - var columnIds = new String[tableColumns]; - for (var i = 0; i < columnWidths.length; i++) { - columnWidths[i] = table.getColumns().get(i).getWidth(); - columnIds[i] = table.getColumns().get(i).getId(); - } - setColumnWidths(columnWidths); - setColumnIds(columnIds); + table.saveState(); } protected void restoreState() { - restoreColumnOrder(); - restoreColumnWidths(); - restoreSorting(); - } - - - private void restoreSorting() { - String sortCol = getSortColumn(); - if (StringUtil.isNotBlank(sortCol)) { - for (TableColumn col : table.getColumns()) { - if (Objects.equals(sortCol, col.getText())) { - col.setSortType(SortType.valueOf(getSortType())); - table.getSortOrder().clear(); - table.getSortOrder().add(col); - break; - } - } - } - } - - private void restoreColumnOrder() { - String[] columnIds = getColumnIds(); - ObservableList> tableColumns = table.getColumns(); - for (var i = 0; i < columnIds.length; i++) { - for (var j = 0; j < table.getColumns().size(); j++) { - if(Objects.equals(columnIds[i], tableColumns.get(j).getId())) { - TableColumn col = tableColumns.get(j); - tableColumns.remove(j); // NOSONAR - tableColumns.add(Math.min(i, tableColumns.size()), col); - } - } - } - } - - private void restoreColumnWidths() { - double[] columnWidths = getColumnWidths(); - if (columnWidths != null && columnWidths.length == table.getColumns().size()) { - for (var i = 0; i < columnWidths.length; i++) { - table.getColumns().get(i).setPrefWidth(columnWidths[i]); - } + table.restoreState(); + if (!config.getSettings().livePreviews) { + table.getColumns().stream().filter(tc -> Objects.equals(tc.getId(), "preview")).findFirst().ifPresent(tc -> tc.setVisible(false)); } } @@ -584,7 +511,7 @@ public abstract class AbstractRecordedModelsTab extends Tab implements TabSelect if (StringUtil.isNotBlank(portraitId)) { File configDir = Config.getInstance().getConfigDir(); File portraitDir = new File(configDir, "portraits"); - File portraitFile = new File(portraitDir, portraitId + '.' + SetPortraitAction.FORMAT); + File portraitFile = new File(portraitDir, portraitId + '.' + FORMAT); try { return new Image(new FileInputStream(portraitFile)); } catch (FileNotFoundException e) { @@ -593,51 +520,4 @@ public abstract class AbstractRecordedModelsTab extends Tab implements TabSelect } return SILHOUETTE; } - - protected void showColumnSelection(ActionEvent evt) { - ContextMenu menu = new CustomMouseBehaviorContextMenu(); - for (TableColumn tc : columns) { - var item = new CheckMenuItem(tc.getText()); - item.setSelected(isColumnEnabled(tc)); - menu.getItems().add(item); - item.setOnAction(e -> { - try { - if (item.isSelected()) { - getDisabledColumns().remove(tc.getText()); - boolean added = false; - for (int i = table.getColumns().size() - 1; i >= 0; i--) { - TableColumn other = table.getColumns().get(i); - if (!other.isVisible()) { - continue; - } - int idx = (int) tc.getUserData(); - int otherIdx = (int) other.getUserData(); - if (otherIdx < idx) { - table.getColumns().add(i + 1, tc); - added = true; - break; - } - } - if (!added) { - table.getColumns().add(0, tc); - } - } else { - getDisabledColumns().add(tc.getText()); - table.getColumns().remove(tc); - } - } catch (Exception ex) { - LOG.error("Couldn't activate column {}", tc, ex); - } - }); - } - Button src = (Button) evt.getSource(); - Point2D location = src.localToScreen(src.getTranslateX(), src.getTranslateY()); - menu.show(getTabPane().getScene().getWindow(), location.getX(), location.getY() + src.getHeight() + 5); - } - - private boolean isColumnEnabled(TableColumn tc) { - return !getDisabledColumns().contains(tc.getText()); - } - - } diff --git a/client/src/main/java/ctbrec/ui/tabs/recorded/RecordLaterTab.java b/client/src/main/java/ctbrec/ui/tabs/recorded/RecordLaterTab.java index ddadc02f..7d70bf3f 100644 --- a/client/src/main/java/ctbrec/ui/tabs/recorded/RecordLaterTab.java +++ b/client/src/main/java/ctbrec/ui/tabs/recorded/RecordLaterTab.java @@ -37,7 +37,7 @@ public class RecordLaterTab extends AbstractRecordedModelsTab implements TabSele private ScheduledService> updateService; public RecordLaterTab(String title, Recorder recorder, List sites) { - super(title); + super(title, "recordLaterTable"); this.recorder = recorder; this.sites = sites; createGui(); @@ -179,51 +179,6 @@ public class RecordLaterTab extends AbstractRecordedModelsTab implements TabSele } } - @Override - String getSortColumn() { - return Config.getInstance().getSettings().recordLaterSortColumn; - } - - @Override - void setSortColumn(String column) { - Config.getInstance().getSettings().recordLaterSortColumn = column; - } - - @Override - String getSortType() { - return Config.getInstance().getSettings().recordLaterSortType; - } - - @Override - void setSortType(String sortType) { - Config.getInstance().getSettings().recordLaterSortType = sortType; - } - - @Override - String[] getColumnIds() { - return Config.getInstance().getSettings().recordLaterColumnIds; - } - - @Override - void setColumnIds(String[] columnIds) { - Config.getInstance().getSettings().recordLaterColumnIds = columnIds; - } - - @Override - double[] getColumnWidths() { - return Config.getInstance().getSettings().recordLaterColumnWidths; - } - - @Override - void setColumnWidths(double[] widths) { - Config.getInstance().getSettings().recordLaterColumnWidths = widths; - } - - @Override - List getDisabledColumns() { - return Config.getInstance().getSettings().recordLaterDisabledColumns; - } - @Override boolean getMarkModelsForLaterRecording() { return true; diff --git a/client/src/main/java/ctbrec/ui/tabs/recorded/RecordedModelsTab.java b/client/src/main/java/ctbrec/ui/tabs/recorded/RecordedModelsTab.java index 36bbc7b9..0827e4da 100644 --- a/client/src/main/java/ctbrec/ui/tabs/recorded/RecordedModelsTab.java +++ b/client/src/main/java/ctbrec/ui/tabs/recorded/RecordedModelsTab.java @@ -67,7 +67,7 @@ public class RecordedModelsTab extends AbstractRecordedModelsTab implements TabS ToggleButton toggleRecording = new ToggleButton("Pause Recording"); public RecordedModelsTab(String title, Recorder recorder, List sites) { - super(title); + super(title, "recordedModelsTable"); this.recorder = recorder; this.sites = sites; createGui(); @@ -95,7 +95,7 @@ public class RecordedModelsTab extends AbstractRecordedModelsTab implements TabS online.setUserData(idx++); online.setStyle(STYLE_ALIGN_CENTER); columns.add(online); - addTableColumnIfEnabled(online); + table.getColumns().add(online); TableColumn recording = new TableColumn<>("Recording"); recording.setCellValueFactory(cdf -> cdf.getValue().getRecordingProperty()); recording.setCellFactory(tc -> new RecordingTableCell()); @@ -105,7 +105,7 @@ public class RecordedModelsTab extends AbstractRecordedModelsTab implements TabS recording.setUserData(idx++); recording.setStyle(STYLE_ALIGN_CENTER); columns.add(recording); - addTableColumnIfEnabled(recording); + table.getColumns().add(recording); TableColumn paused = new TableColumn<>("Paused"); paused.setCellValueFactory(cdf -> cdf.getValue().getPausedProperty()); paused.setCellFactory(CheckBoxTableCell.forTableColumn(paused)); @@ -115,7 +115,7 @@ public class RecordedModelsTab extends AbstractRecordedModelsTab implements TabS paused.setUserData(idx++); paused.setStyle(STYLE_ALIGN_CENTER); columns.add(paused); - addTableColumnIfEnabled(paused); + table.getColumns().add(paused); TableColumn priority = new TableColumn<>("Priority"); priority.setCellValueFactory(param -> param.getValue().getPriorityProperty()); priority.setCellFactory(new PriorityCellFactory()); @@ -127,7 +127,7 @@ public class RecordedModelsTab extends AbstractRecordedModelsTab implements TabS priority.setId("priority"); priority.setUserData(idx++); columns.add(priority); - addTableColumnIfEnabled(priority); + table.getColumns().add(priority); TableColumn lastSeen = new TableColumn<>("last seen"); lastSeen.setCellValueFactory(cdf -> cdf.getValue().lastSeenProperty()); lastSeen.setCellFactory(new DateTimeCellFactory<>()); @@ -137,7 +137,7 @@ public class RecordedModelsTab extends AbstractRecordedModelsTab implements TabS lastSeen.setUserData(idx++); lastSeen.setStyle(STYLE_ALIGN_CENTER); columns.add(lastSeen); - addTableColumnIfEnabled(lastSeen); + table.getColumns().add(lastSeen); TableColumn lastRecorded = new TableColumn<>("last recorded"); lastRecorded.setCellValueFactory(cdf -> cdf.getValue().lastRecordedProperty()); lastRecorded.setCellFactory(new DateTimeCellFactory<>()); @@ -147,7 +147,7 @@ public class RecordedModelsTab extends AbstractRecordedModelsTab implements TabS lastRecorded.setUserData(idx++); lastRecorded.setStyle(STYLE_ALIGN_CENTER); columns.add(lastRecorded); - addTableColumnIfEnabled(lastRecorded); + table.getColumns().add(lastRecorded); addAddedTimestampColumn(idx++); addNotesColumn(idx); @@ -409,49 +409,4 @@ public class RecordedModelsTab extends AbstractRecordedModelsTab implements TabS boolean getMarkModelsForLaterRecording() { return false; } - - @Override - String getSortColumn() { - return Config.getInstance().getSettings().recordedModelsSortColumn; - } - - @Override - void setSortColumn(String column) { - Config.getInstance().getSettings().recordedModelsSortColumn = column; - } - - @Override - String getSortType() { - return Config.getInstance().getSettings().recordedModelsSortType; - } - - @Override - void setSortType(String sortType) { - Config.getInstance().getSettings().recordedModelsSortType = sortType; - } - - @Override - String[] getColumnIds() { - return Config.getInstance().getSettings().recordedModelsColumnIds; - } - - @Override - void setColumnIds(String[] ids) { - Config.getInstance().getSettings().recordedModelsColumnIds = ids; - } - - @Override - double[] getColumnWidths() { - return Config.getInstance().getSettings().recordedModelsColumnWidths; - } - - @Override - void setColumnWidths(double[] widths) { - Config.getInstance().getSettings().recordedModelsColumnWidths = widths; - } - - @Override - List getDisabledColumns() { - return Config.getInstance().getSettings().recordedModelsDisabledTableColumns; - } } diff --git a/common/src/main/java/ctbrec/Settings.java b/common/src/main/java/ctbrec/Settings.java index 337b09fd..6d22966c 100644 --- a/common/src/main/java/ctbrec/Settings.java +++ b/common/src/main/java/ctbrec/Settings.java @@ -138,16 +138,16 @@ public class Settings { public ProxyType proxyType = ProxyType.DIRECT; public String proxyUser; public boolean recentlyWatched = true; - public double[] recordLaterColumnWidths = new double[0]; - public String[] recordLaterColumnIds = new String[0]; - public List recordLaterDisabledColumns = new ArrayList<>(); - public String recordLaterSortColumn = ""; - public String recordLaterSortType = ""; - public double[] recordedModelsColumnWidths = new double[0]; - public String[] recordedModelsColumnIds = new String[0]; - public List recordedModelsDisabledTableColumns = new ArrayList<>(); - public String recordedModelsSortColumn = ""; - public String recordedModelsSortType = ""; + public List recordLaterTableColumnOrder = new ArrayList<>(); + public Map recordLaterTableColumnVisibility = new HashMap<>(); + public Map recordLaterTableColumnWidth = new HashMap<>(); + public String recordLaterTableSortColumn = ""; + public String recordLaterTableSortType = ""; + public List recordedModelsTableColumnOrder = new ArrayList<>(); + public Map recordedModelsTableColumnVisibility = new HashMap<>(); + public Map recordedModelsTableColumnWidth = new HashMap<>(); + public String recordedModelsTableSortColumn = ""; + public String recordedModelsTableSortType = ""; public List recordingsTableColumnOrder = new ArrayList<>(); public Map recordingsTableColumnVisibility = new HashMap<>(); public Map recordingsTableColumnWidth = new HashMap<>();