package com.noticeditorteam.noticeditor.controller;
import com.noticeditorteam.noticeditor.Main;
import com.noticeditorteam.noticeditor.model.*;
import com.noticeditorteam.noticeditor.view.Chooser;
import com.noticeditorteam.noticeditor.view.EditNoticeTreeCell;
import com.noticeditorteam.noticeditor.view.Notification;
import java.io.File;
import java.net.URL;
import java.util.ResourceBundle;
import java.util.logging.Level;
import javafx.beans.binding.Bindings;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.*;
import javafx.scene.input.KeyEvent;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
public class NoticeTreeViewController implements Initializable {
@FXML
private MenuItem addBranchItem, addNoticeItem, deleteItem;
@FXML
private SplitMenuButton addItem;
@FXML
private Menu addChild, addNeighbour;
@FXML
private MenuItem addChildBranch, addChildNotice, addNeighbourBranch, addNeighbourNotice, addWrapperBranch;
@FXML
private TextField searchField;
@FXML
private Button searchButton, renameButton, addFileButton, deleteButton;
@FXML
private MenuButton statusSelectButton;
@FXML
private ToolBar manageItemBar;
@FXML
private TreeView<NoticeItem> noticeTreeView;
private NoticeTree noticeTree;
private NoticeTreeItem currentTreeItem;
private String newnotice;
private String newbranch;
private String openfile;
private String searcherror;
private String erroraddfile;
private Main main;
@Override
public void initialize(URL url, ResourceBundle resources) {
final EventHandler<ActionEvent> onStatusChangeAction = event -> {
final MenuItem newStatus = (MenuItem) event.getSource();
statusSelectButton.setText(newStatus.getText());
NoticeTreeItem currentNotice = getCurrentNotice();
if (currentNotice != null && newStatus.getUserData() != null && currentNotice.isLeaf()) {
currentNotice.setStatus(((NoticeStatus) newStatus.getUserData()).getCode());
}
};
NoticeStatusList.add(resources.getString("normal"));
NoticeStatusList.add(resources.getString("important"));
NoticeStatusList.save();
for (NoticeStatus status : NoticeStatusList.asObservable()) {
MenuItem statusItem = new MenuItem(status.getName());
statusItem.setUserData(status);
statusItem.setOnAction(onStatusChangeAction);
statusSelectButton.getItems().add(statusItem);
}
statusSelectButton.setGraphic(new Circle(5, Color.AQUAMARINE));
statusSelectButton.setTooltip(new Tooltip(resources.getString("status")));
noticeTreeView.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
noticeTreeView.getSelectionModel().selectedItemProperty().addListener( (o, oldValue, newValue) -> {
currentTreeItem = (NoticeTreeItem) newValue;
open();
});
noticeTreeView.setCellFactory(p -> new EditNoticeTreeCell());
newnotice = resources.getString("newnotice");
newbranch = resources.getString("newbranch");
openfile = resources.getString("openfile");
searcherror = resources.getString("errors.search");
erroraddfile = resources.getString("errors.addfiletobranch");
}
public void rebuildTree(String initialNotice) {
final NoticeTreeItem root = new NoticeTreeItem("Root");
noticeTree = new NoticeTree(root);
currentTreeItem = new NoticeTreeItem(newnotice, initialNotice, NoticeItem.STATUS_NORMAL);
noticeTree.addItem(currentTreeItem, root);
noticeTreeView.setRoot(root);
createSearchBinding(root);
noticeTreeView.getSelectionModel().select(currentTreeItem);
open();
}
public void rebuildTree(NoticeTree noticeTree) {
this.noticeTree = noticeTree;
noticeTreeView.setRoot(noticeTree.getRoot());
createSearchBinding(noticeTree.getRoot());
currentTreeItem = null;
open();
}
private void createSearchBinding(final NoticeTreeItem root) {
searchField.clear();
root.predicateProperty().bind(
Bindings.createObjectBinding(this::searchTreeItemPredicate, searchField.textProperty()));
}
private NoticeTreeItem.Predicate<NoticeItem> searchTreeItemPredicate() {
if ((searchField.getText() == null) || (searchField.getText().isEmpty())) {
return null;
}
return this::noticeSearch;
}
/**
* Search by title and content
*
* @return true if found
*/
private boolean noticeSearch(TreeItem<NoticeItem> parent, NoticeItem note) {
final String searchString = searchField.getText().toLowerCase();
final String title = note.getTitle().toLowerCase();
if (title.contains(searchString))
return true;
final String content = note.getContent();
if (content == null || content.isEmpty())
return false;
return content.toLowerCase().contains(searchString);
}
/**
* Open current item in UI. If current item == null or isBranch, interface will be cleared from last data.
*/
public void open() {
boolean isCurrentBranch = currentTreeItem == null || currentTreeItem.isBranch();
if (isCurrentBranch) {
NoticeController.getNoticeViewController().getEditor().setDisable(true);
NoticeController.getNoticeViewController().getEditor().setText("");
statusSelectButton.setText(null);
statusSelectButton.setDisable(true);
} else {
NoticeController.getNoticeViewController().getEditor().setDisable(false);
NoticeController.getNoticeViewController().getEditor().setText(currentTreeItem.getContent());
statusSelectButton.setText(NoticeStatusList.getStatus(currentTreeItem.getStatus()).getName());
statusSelectButton.setDisable(false);
}
manageItemBar.setDisable(currentTreeItem == null);
addChild.setDisable(!isCurrentBranch);
addNeighbour.setDisable(currentTreeItem == null);
NoticeController.getNoticeViewController().rebuildAttachsView();
}
@FXML
private void handleContextMenu(ActionEvent event) {
final Object source = event.getSource();
if (source == addBranchItem) {
noticeTree.addItem(new NoticeTreeItem(newbranch), currentTreeItem);
} else if (source == addNoticeItem) {
noticeTree.addItem(new NoticeTreeItem(newnotice, "", NoticeItem.STATUS_NORMAL), currentTreeItem);
} else if (source == deleteItem) {
noticeTree.removeItem(currentTreeItem);
if (currentTreeItem != null && currentTreeItem.getParent() == null) {
currentTreeItem = null;
open();
}
}
}
@FXML
private void handleAddItem(ActionEvent event) {
Object source = event.getSource();
if (source == addItem) {
noticeTree.addItem(new NoticeTreeItem(newnotice, "", NoticeItem.STATUS_NORMAL), currentTreeItem);
} else if (source == addChildNotice) {
noticeTree.addItem(new NoticeTreeItem(newnotice, "", NoticeItem.STATUS_NORMAL), currentTreeItem);
} else if (source == addChildBranch) {
noticeTree.addItem(new NoticeTreeItem(newbranch), currentTreeItem);
} else if (source == addNeighbourNotice) {
noticeTree.addItem(new NoticeTreeItem(newnotice, "", NoticeItem.STATUS_NORMAL), (NoticeTreeItem) currentTreeItem.getParent());
} else if (source == addNeighbourBranch) {
noticeTree.addItem(new NoticeTreeItem(newbranch), (NoticeTreeItem) currentTreeItem.getParent());
} else if (source == addWrapperBranch) {
NoticeTreeItem wrapper = new NoticeTreeItem(newbranch);
NoticeTreeItem item = currentTreeItem;
NoticeTreeItem parent = (NoticeTreeItem) currentTreeItem.getParent();
noticeTree.removeItem(currentTreeItem);
noticeTree.addItem(wrapper, parent);
noticeTree.addItem(item, wrapper);
noticeTreeView.getSelectionModel().select(item);
}
}
@FXML
private void handleSearch(ActionEvent event) {
Notification.error(searcherror);
}
@FXML
private void handleRename(ActionEvent event) {
noticeTreeView.edit(currentTreeItem);
}
@FXML
private void handleAddFile(ActionEvent event) {
boolean isCurrentBranch = (currentTreeItem == null) || (currentTreeItem.isBranch());
if (isCurrentBranch)
Notification.error(erroraddfile);
else {
File fileInjected = Chooser.file().open()
.filter(Chooser.ALL)
.title(openfile)
.show(main.getPrimaryStage());
if (fileInjected != null) {
try {
currentTreeItem.addAttachment(fileInjected);
} catch (Exception e) {
NoticeController.getLogger().log(Level.SEVERE, "addFile", e);
}
}
NoticeController.getNoticeViewController().rebuildAttachsView();
}
}
@FXML
private void handleDelete(ActionEvent event) {
noticeTree.removeItem(currentTreeItem);
if (currentTreeItem != null && currentTreeItem.getParent() == null) {
currentTreeItem = null;
open();
}
}
@FXML
private void handleKey(KeyEvent event) {
if (event.isControlDown()) {
switch (event.getCode()) {
case N:
noticeTree.addItem(new NoticeTreeItem(newnotice, "", NoticeItem.STATUS_NORMAL), currentTreeItem);
break;
case B:
noticeTree.addItem(new NoticeTreeItem(newbranch), currentTreeItem);
break;
}
}
}
public NoticeTreeItem getCurrentNotice() {
return currentTreeItem;
}
public NoticeTree getNoticeTree() {
return noticeTree;
}
public void setMain(Main main) {
this.main = main;
}
}