package view;
import java.awt.Desktop;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.List;
import javafx.application.Platform;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.scene.control.Button;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.Label;
import javafx.scene.control.SelectionMode;
import javafx.scene.control.Tooltip;
import javafx.scene.control.TreeCell;
import javafx.scene.control.TreeItem;
import javafx.scene.control.TreeView;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.util.Callback;
import model.IliasFile;
import model.IliasFolder;
import model.IliasForum;
import model.IliasTreeNode;
import model.persistance.IliasTreeProvider;
import model.persistance.Settings;
import utils.DesktopHelper;
import download.IliasFolderDownloaderTask;
import download.IliasPdfDownloadCaller;
public class CoursesTreeView extends TreeView<IliasTreeNode> {
private final TreeItem<IliasTreeNode> rootItem;
private ContextMenu menu;
private final Dashboard dashboard;
public CoursesTreeView(Dashboard dashboard) {
super();
setId("coursesTree");
setMinWidth(270);
this.dashboard = dashboard;
rootItem = new TreeItem<IliasTreeNode>(new IliasFolder("Übersicht", null, null));
rootItem.setExpanded(true);
setRoot(rootItem);
setShowRoot(false);
getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
menu = new ContextMenu();
setCellFactory(new Callback<TreeView<IliasTreeNode>, TreeCell<IliasTreeNode>>() {
@Override
public TreeCell<IliasTreeNode> call(TreeView<IliasTreeNode> arg0) {
return new IliasTreeCell();
}
});
setOnMouseClicked(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
menu.hide();
final TreeItem<IliasTreeNode> selectedItem = getSelectionModel().getSelectedItem();
if (selectedItem == null) {
return;
}
if (event.getButton() == MouseButton.PRIMARY && event.getClickCount() == 2) {
if (selectedItem.getValue() instanceof IliasForum) {
openForum();
return;
} else if (selectedItem.getValue() instanceof IliasFile) {
if (Settings.getInstance().getFlags().isUserLoggedIn()) {
new Thread(new IliasPdfDownloadCaller(
((CoursesTreeView) event.getSource()).getSelectionModel()
.getSelectedItem().getValue())).start();
}
}
} else if (event.getButton() == MouseButton.SECONDARY) {
showContextMenu(getSelectionModel().getSelectedItems(), event);
}
};
});
}
private void openForum() {
final IliasForum forum = (IliasForum) this.getSelectionModel().getSelectedItem().getValue();
if (Desktop.isDesktopSupported()) {
try {
Desktop.getDesktop().browse(new URI(forum.getUrl()));
} catch (IOException | URISyntaxException e) {
e.printStackTrace();
}
} else {
dashboard.browse(forum.getUrl());
}
}
private void showContextMenu(ObservableList<TreeItem<IliasTreeNode>> selectedItems,
MouseEvent event) {
menu.getItems().clear();
List<IliasTreeNode> selectedIliasTreeNodes = new ArrayList<IliasTreeNode>();
for (TreeItem<IliasTreeNode> treeItem : selectedItems) {
selectedIliasTreeNodes.add(treeItem.getValue());
}
menu = new FileContextMenu(dashboard).createMenu(selectedIliasTreeNodes, event);
menu.show(this, event.getScreenX(), event.getScreenY());
}
public void update() {
rootItem.getChildren().clear();
setCourses(rootItem, IliasTreeProvider.getTree());
}
private void setCourses(TreeItem<IliasTreeNode> rootItem, List<? extends IliasTreeNode> kurse) {
for (IliasTreeNode node : kurse) {
TreeItem<IliasTreeNode> item = new TreeItem<IliasTreeNode>(node);
rootItem.getChildren().add(item);
if (node instanceof IliasFolder) {
IliasFolder folder = (IliasFolder) node;
setCourses(item, folder.getChildNodes());
item.setGraphic(node.getGraphic());
} else if (node instanceof IliasFile) {
item.setGraphic(node.getGraphic());
} else if (node instanceof IliasForum) {
item.setGraphic(node.getGraphic());
}
}
}
public void collapse() {
collapse(rootItem.getChildren());
}
private void collapse(ObservableList<TreeItem<IliasTreeNode>> items) {
for (TreeItem<IliasTreeNode> item : items) {
item.setExpanded(false);
collapse(item.getChildren());
}
dashboard.setStatusText("");
}
public void selectFile(IliasFile selectedDirectory) {
collapse();
final TreeItem<IliasTreeNode> linkedTreeItem = getItem(selectedDirectory);
linkedTreeItem.setExpanded(true);
getSelectionModel().clearSelection();
getSelectionModel().select(linkedTreeItem);
scrollTo(getSelectionModel().getSelectedIndex());
}
public TreeItem<IliasTreeNode> getItem(final IliasFile file) {
return search(rootItem, file);
}
private TreeItem<IliasTreeNode> search(TreeItem<IliasTreeNode> item, final IliasFile file) {
for (TreeItem<IliasTreeNode> treeItem : item.getChildren()) {
if (treeItem.getValue().equals(file)) {
return treeItem;
}
final TreeItem<IliasTreeNode> searchResult = search(treeItem, file);
if (searchResult != null) {
return searchResult;
}
}
return null;
}
public void fileStatusChanged(IliasFile iliasFile) {
TreeItem<IliasTreeNode> treeItem = getItem(iliasFile);
setGraphic(treeItem, iliasFile.getGraphic());
while (treeItem.getParent() != null) {
treeItem = treeItem.getParent();
IliasFolder folder = (IliasFolder) treeItem.getValue();
setGraphic(treeItem, folder.getGraphic());
}
}
private void setGraphic(final TreeItem<IliasTreeNode> treeItem, final ImageView image) {
Platform.runLater(new Runnable() {
@Override
public void run() {
treeItem.setExpanded(!treeItem.isExpanded());
treeItem.setGraphic(image);
treeItem.setExpanded(!treeItem.isExpanded());
}
});
}
/**
* This class draws the ListCells.
* http://stackoverflow.com/questions/23137131
* /javafx-listview-with-button-in-each-cell
*
* @author deoldsax
*
*/
private class IliasTreeCell extends TreeCell<IliasTreeNode> {
private IliasTreeNode node;
private int i = 0;
private BorderPane pane;
private Label box;
private Button downloadButton;
private Button ignoreButton;
private Button openerButton;
private Button printerButton;
private HBox actions;
private boolean calledfirsttime = true;
public IliasTreeCell() {
pane = buildCell();
EventHandler<MouseEvent> mouseHandler = new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent arg0) {
if (node != null) {
// redraw();
update();
}
}
};
// setOnMouseEntered(mouseHandler);
// setOnMouseExited(mouseHandler);
}
@Override
protected void updateItem(final IliasTreeNode node, final boolean empty) {
super.updateItem(node, empty);
if (empty || (node == null)) {
// this.node = null;
setGraphic(null);
} else {
this.node = node;
update();
setGraphic(pane);
}
// redraw();
}
private BorderPane buildCell() {
final BorderPane pane = new BorderPane();
box = new Label();
box.setAlignment(Pos.TOP_LEFT);
pane.setLeft(box);
createAndAddActions(pane);
// setGraphic(pane);
createToolTip();
return pane;
}
private void update() {
if (node instanceof IliasFolder) {
IliasFolder folder = (IliasFolder) node;
box.setGraphic(folder.getGraphic());
} else if (node instanceof IliasFile) {
IliasFile file = (IliasFile) node;
box.setGraphic(file.getGraphic());
} else if (node instanceof IliasForum) {
box.setGraphic(new ImageView("img/forum.png"));
}
box.setText(node.toString());
actions.getChildren().clear();
if (!(node instanceof IliasForum)) {
actions.getChildren().add(downloadButton);
}
if (node instanceof IliasFile) {
if (((IliasFile) node).isIgnored()) {
ignoreButton.setGraphic(new ImageView("img/check.png"));
} else {
ignoreButton.setGraphic(new ImageView("img/ignore.png"));
}
actions.getChildren().add(ignoreButton);
actions.getChildren().add(openerButton);
actions.getChildren().add(printerButton);
}
downloadButton.visibleProperty().bind(hoverProperty());
downloadButton.mouseTransparentProperty().bind(hoverProperty().not());
ignoreButton.visibleProperty().bind(hoverProperty());
ignoreButton.mouseTransparentProperty().bind(hoverProperty().not());
openerButton.visibleProperty().bind(hoverProperty());
openerButton.mouseTransparentProperty().bind(hoverProperty().not());
printerButton.visibleProperty().bind(hoverProperty());
printerButton.mouseTransparentProperty().bind(hoverProperty().not());
}
private void redraw() {
if (node == null) {
setGraphic(null);
return;
}
final BorderPane pane = new BorderPane();
final Label box = new Label();
box.setAlignment(Pos.TOP_LEFT);
if (node instanceof IliasFolder) {
IliasFolder folder = (IliasFolder) node;
box.setGraphic(folder.getGraphic());
} else if (node instanceof IliasFile) {
IliasFile file = (IliasFile) node;
box.setGraphic(file.getGraphic());
} else if (node instanceof IliasForum) {
box.setGraphic(new ImageView("img/forum.png"));
}
box.setText(node.toString());
pane.setLeft(box);
createAndAddActions(pane);
setGraphic(pane);
createToolTip();
}
private void createToolTip() {
if (node instanceof IliasFile) {
Tooltip tooltip = new Tooltip();
String fileExtension = ((IliasFile) this.node).getExtension();
String fileSizeLabel = ((IliasFile) this.node).getSizeLabel();
tooltip.setText("Elementtyp: " + fileExtension + "\n" + "Größe: " + fileSizeLabel);
this.setTooltip(tooltip);
}
}
private void createAndAddActions(final BorderPane pane) {
downloadButton = new Button();
downloadButton.setGraphic(new ImageView("img/downloadArrow.png"));
downloadButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent arg0) {
download(node);
}
});
ignoreButton = new Button();
ignoreButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
toggleIgnoredState(node);
}
});
openerButton = new Button();
openerButton.setGraphic(new ImageView("img/folder_small.png"));
openerButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
DesktopHelper.openFile((IliasFile) node);
}
});
printerButton = new Button();
printerButton.setGraphic(new ImageView("img/printer.png"));
printerButton.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
DesktopHelper.print((IliasFile) node);
}
});
actions = new HBox();
actions.setId("actionBar");
actions.setSpacing(10);
if (!(node instanceof IliasForum)) {
actions.getChildren().add(downloadButton);
}
if (node instanceof IliasFile) {
if (((IliasFile) node).isIgnored()) {
ignoreButton.setGraphic(new ImageView("img/check.png"));
} else {
ignoreButton.setGraphic(new ImageView("img/ignore.png"));
}
actions.getChildren().add(ignoreButton);
actions.getChildren().add(openerButton);
actions.getChildren().add(printerButton);
}
pane.setRight(actions);
}
private void download(IliasTreeNode node) {
if (node instanceof IliasFile) {
new Thread(new IliasPdfDownloadCaller(node)).start();
} else if (node instanceof IliasFolder) {
new Thread(new IliasFolderDownloaderTask(node)).start();
}
}
private void toggleIgnoredState(final IliasTreeNode node) {
IliasFile file = (IliasFile) node;
Settings.getInstance().toggleFileIgnored(file);
dashboard.pdfIgnoredStateChanged(file);
dashboard.getResultList().pdfIgnoredStateChanged(file);
fileStatusChanged(file);
}
}
}