package org.jabref.gui.errorconsole;
import javax.inject.Inject;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.Label;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.control.SelectionMode;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.util.Callback;
import org.jabref.gui.AbstractController;
import org.jabref.gui.ClipBoardManager;
import org.jabref.gui.DialogService;
import org.jabref.gui.IconTheme;
import org.jabref.gui.keyboard.KeyBinding;
import org.jabref.gui.keyboard.KeyBindingRepository;
import org.jabref.logic.util.BuildInfo;
public class ErrorConsoleController extends AbstractController<ErrorConsoleViewModel> {
@FXML private Button copyLogButton;
@FXML private Button clearLogButton;
@FXML private Button createIssueButton;
@FXML private ListView<LogEventViewModel> messagesListView;
@FXML private Label descriptionLabel;
@Inject private DialogService dialogService;
@Inject private ClipBoardManager clipBoardManager;
@Inject private BuildInfo buildInfo;
@Inject private KeyBindingRepository keyBindingRepository;
@FXML
private void initialize() {
viewModel = new ErrorConsoleViewModel(dialogService, clipBoardManager, buildInfo);
messagesListView.setCellFactory(createCellFactory());
messagesListView.itemsProperty().bind(viewModel.allMessagesDataProperty());
messagesListView.scrollTo(viewModel.allMessagesDataProperty().getSize() - 1);
messagesListView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
viewModel.allMessagesDataProperty().addListener((ListChangeListener<LogEventViewModel>) (change -> {
int size = viewModel.allMessagesDataProperty().size();
if (size > 0) {
messagesListView.scrollTo(size - 1);
}
}));
descriptionLabel.setGraphic(IconTheme.JabRefIcon.CONSOLE.getGraphicNode());
}
private Callback<ListView<LogEventViewModel>, ListCell<LogEventViewModel>> createCellFactory() {
return cell -> new ListCell<LogEventViewModel>() {
private HBox graphic;
private Node icon;
private VBox message;
private Label heading;
private Label stacktrace;
{
graphic = new HBox(10);
heading = new Label();
stacktrace = new Label();
message = new VBox();
message.getChildren().setAll(heading, stacktrace);
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
}
@Override
public void updateItem(LogEventViewModel event, boolean empty) {
super.updateItem(event, empty);
if (event == null || empty) {
setGraphic(null);
} else {
icon = event.getIcon().getGraphicNode();
heading.setText(event.getDisplayText());
heading.getStyleClass().setAll(event.getStyleClass());
stacktrace.setText(event.getStackTrace().orElse(""));
graphic.getStyleClass().setAll(event.getStyleClass());
graphic.getChildren().setAll(icon, message);
setGraphic(graphic);
}
}
};
}
@FXML
private void copySelectedLogEntries(KeyEvent event) {
if (keyBindingRepository.checkKeyCombinationEquality(KeyBinding.COPY, event)) {
ObservableList<LogEventViewModel> selectedEntries = messagesListView.getSelectionModel().getSelectedItems();
viewModel.copyLog(selectedEntries);
}
}
@FXML
private void copyLog() {
viewModel.copyLog();
}
@FXML
private void clearLog() {
viewModel.clearLog();
}
@FXML
private void createIssue() {
viewModel.reportIssue();
}
@FXML
private void closeErrorDialog() {
getStage().close();
}
}