/** * Copyright [2015] [Christian Loehnert] * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package de.ks.blogging.grav.ui.post.edit; import de.ks.BaseController; import de.ks.blogging.grav.posts.BasePost; import de.ks.blogging.grav.posts.Header; import de.ks.blogging.grav.posts.HeaderContainer; import de.ks.blogging.grav.posts.HeaderElement; import de.ks.reflection.PropertyPath; import javafx.fxml.FXML; import javafx.scene.control.TreeItem; import javafx.scene.control.TreeTableColumn; import javafx.scene.control.TreeTableView; import javafx.scene.control.cell.TextFieldTreeTableCell; import javafx.scene.control.cell.TreeItemPropertyValueFactory; import javafx.scene.layout.StackPane; import java.net.URL; import java.util.ArrayList; import java.util.List; import java.util.ResourceBundle; import java.util.Stack; import java.util.function.Consumer; public class AdvancedHeader extends BaseController<BasePost> { @FXML protected StackPane root; @FXML protected TreeTableColumn<HeaderElement, String> keyColumn; @FXML protected TreeTableColumn<HeaderElement, String> valueColumn; @FXML protected TreeTableView<HeaderElement> table; protected final List<Consumer<BasePost>> actions = new ArrayList<>(); @Override public void initialize(URL location, ResourceBundle resources) { valueColumn.setCellFactory(TextFieldTreeTableCell.forTreeTableColumn()); valueColumn.setEditable(true); table.setEditable(true); keyColumn.setCellValueFactory(new TreeItemPropertyValueFactory<>(PropertyPath.property(HeaderElement.class, c -> c.getKey()))); valueColumn.setCellValueFactory(new TreeItemPropertyValueFactory<>(PropertyPath.property(HeaderElement.class, c -> c.getValue()))); valueColumn.setOnEditCommit(e -> { String newValue = e.getNewValue(); HeaderElement headerElement = e.getRowValue().getValue(); HeaderContainer owner = headerElement.getOwner(); actions.add(post -> { HeaderContainer resolved = null; if (headerElement.getKey() == null) { resolved = post.getHeader(); } else { Stack<HeaderContainer> headerContainers = new Stack<>(); headerContainers.addAll(post.getHeader().getChildContainers()); while (resolved == null && !headerContainers.isEmpty()) { HeaderContainer container = headerContainers.pop(); if (container.equals(owner)) { resolved = container; } headerContainers.addAll(container.getChildContainers()); } } resolved.setHeaderElement(headerElement.getKey(), newValue); }); }); } @Override public void duringSave(BasePost model) { this.actions.forEach(a -> a.accept(model)); this.actions.clear(); } @Override protected void onRefresh(BasePost model) { Header header = model.getHeader(); TreeItem<HeaderElement> root = new TreeItem<>(new HeaderElement("/", "", header)); root.setExpanded(true); addContainerToTable(header, root); table.setRoot(root); } @Override public void onSuspend() { actions.clear(); } private void addContainerToTable(HeaderContainer header, TreeItem<HeaderElement> root) { for (HeaderElement headerElement : header.getHeaderElements()) { root.getChildren().add(new TreeItem<>(headerElement)); } List<HeaderContainer> childContainers = header.getChildContainers(); for (HeaderContainer childContainer : childContainers) { TreeItem<HeaderElement> childRoot = new TreeItem<>(new HeaderElement(childContainer.getKey(), "", header)); root.getChildren().add(childRoot); addContainerToTable(childContainer, childRoot); } } }