package xmltool;
import com.sun.javafx.scene.control.behavior.TabPaneBehavior;
import com.sun.javafx.scene.control.skin.TabPaneSkin;
import java.awt.Desktop;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.net.URL;
import java.util.Arrays;
import java.util.ResourceBundle;
import java.util.Scanner;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.collections.ObservableList;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.geometry.Rectangle2D;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.stage.Screen;
import javafx.stage.Stage;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import org.apache.fop.apps.FOPException;
import org.fxmisc.richtext.CodeArea;
import xmltool.beans.UIBean;
import xmltool.printing.PrintHelperXML;
import xmltool.transformation.FOTransformer;
import xmltool.transformation.NormTransformer;
import xmltool.utils.FileChooserUtil;
import xmltool.utils.FileReaderUtil;
import xmltool.utils.FileSaverUtil;
import xmltool.utils.UIHelperUtil;
import xmltool.validation.Validator;
public class MainController implements Initializable {
private double mouseDragOffsetX = 0;
private double mouseDragOffsetY = 0;
private Rectangle2D backupWindowBounds = null;
private boolean maximized = false;
private final Image restore = new Image("/xmltool/resources/restore.png");
private final Image maximize = new Image("/xmltool/resources/maximize.png");
private final String fileList = "XML/XSD/XSL File";
private final String[] fileArray = {"*.xml", "*.xsd", "*.xsl"};
private double dragOffsetX, dragOffsetY;
//fields from FXML
@FXML
private Pane anchorPane;//use this to get ref to stage like this: (Stage)anchorPane.getScene().getWindow()
@FXML
private TabPane tabPane;
@FXML
private ImageView maximizeRestoreImg;
@FXML
protected void fileNew() {
try {
Tab newTab = FXMLLoader.load(getClass().getResource("Tab.fxml"));
tabPane.getTabs().add(newTab);
TabPaneSkin skin = (TabPaneSkin) tabPane.getSkin();
TabPaneBehavior tabPaneBehavior = skin.getBehavior();
tabPaneBehavior.selectTab(newTab);
CodeArea textArea = (CodeArea) newTab.getContent().lookup("#textArea");
textArea.requestFocus();
UIHelperUtil.setOnCloseRequest(tabPane, (Stage) anchorPane.getScene().getWindow(), this);
} catch (IOException ex) {
Stage stage = (Stage) anchorPane.getScene().getWindow();
MessageBoxFactory.showErrorDialog(stage, "Check Details for more info", "System I/O error occured", "Error", ex);
Logger.getLogger(MainController.class.getName()).log(Level.SEVERE, null, ex);
}
}
@FXML
protected void fileOpen() {
FileChooserUtil.setFilter(fileList, fileArray);
File choosenFile = FileChooserUtil.getFile((Stage) anchorPane.getScene().getWindow());
if (choosenFile != null && choosenFile.isFile()) {
CodeArea textArea = UIBean.getCurCodeArea();
if (!textArea.getText().isEmpty()) {
fileNew();
textArea = UIBean.getCurCodeArea();
}
Tab currTab = tabPane.getSelectionModel().getSelectedItem();
currTab.setText(choosenFile.getName());
textArea.replaceText(FileReaderUtil.getTextFromXML(choosenFile));
UIHelperUtil.addFile(choosenFile);
}
}
public void fileOpenByString(String filePath) {
File choosenFile = new File(filePath);
if (choosenFile.isFile()) {
CodeArea textArea = UIBean.getCurCodeArea();
if (!textArea.getText().isEmpty()) {
fileNew();
textArea = UIBean.getCurCodeArea();
}
Tab currTab = tabPane.getSelectionModel().getSelectedItem();
currTab.setText(choosenFile.getName());
textArea.replaceText(FileReaderUtil.getTextFromXML(choosenFile));
UIHelperUtil.addFile(choosenFile);
}
}
@FXML
public void fileSave() {
CodeArea textArea = UIBean.getCurCodeArea();
Tab currTab = tabPane.getSelectionModel().getSelectedItem();
String tabName = currTab.getText();
if (tabName.equals("newFile")) {//if the file doesn't exist
fileSaveAs();
} else {
FileSaverUtil.setFile(tabName);
FileSaverUtil.writeFile(textArea.getText());
}
}
@FXML
protected void fileSaveAs() {
CodeArea textArea = UIBean.getCurCodeArea();
Tab currTab = tabPane.getSelectionModel().getSelectedItem();
FileSaverUtil.setFilter(fileList, fileArray);
boolean isFileSaved = FileSaverUtil.saveFile((Stage) anchorPane.getScene().getWindow(), textArea.getText());
if (isFileSaved) {
currTab.setText(FileSaverUtil.getFile().getName());
}
}
@FXML
protected void exitProgram() {
UIHelperUtil.exitProgram();
}
@FXML
protected void dragWindowStarted(MouseEvent event) {
mouseDragOffsetX = event.getSceneX();
mouseDragOffsetY = event.getSceneY();
}
@FXML
protected void dragWindowDragged(MouseEvent event) {
if (!maximized) {
anchorPane.getScene().getWindow().setX(event.getScreenX() - mouseDragOffsetX);
anchorPane.getScene().getWindow().setY(event.getScreenY() - mouseDragOffsetY);
}
}
@FXML
protected void minimize() {
Stage stage = (Stage) anchorPane.getScene().getWindow();
stage.setIconified(true);
}
@FXML
protected void toogleMaximize() {
Stage stage = (Stage) anchorPane.getScene().getWindow();
final Screen screen = Screen.getScreensForRectangle(stage.getX(), stage.getY(), 1, 1).get(0);
if (maximized) {
maximized = false;
if (backupWindowBounds != null) {
stage.setX(backupWindowBounds.getMinX());
stage.setY(backupWindowBounds.getMinY());
stage.setWidth(backupWindowBounds.getWidth());
stage.setHeight(backupWindowBounds.getHeight());
maximizeRestoreImg.setImage(maximize);
}
} else {
maximized = true;
backupWindowBounds = new Rectangle2D(stage.getX(), stage.getY(), stage.getWidth(), stage.getHeight());
stage.setX(screen.getVisualBounds().getMinX());
stage.setY(screen.getVisualBounds().getMinY());
stage.setWidth(screen.getVisualBounds().getWidth());
stage.setHeight(screen.getVisualBounds().getHeight());
maximizeRestoreImg.setImage(restore);
}
}
@FXML
protected void toogleMaximizeDoubleClick(MouseEvent event) {
if (event.getClickCount() == 2) {
toogleMaximize();
}
}
@FXML
protected void stripWhiteSpaces() {
CodeArea textArea = UIBean.getCurCodeArea();
String text = textArea.getText();
StringBuilder sb = new StringBuilder();
Scanner sc = new Scanner(text);
while (sc.hasNextLine()) {
sb.append(sc.nextLine().trim());
}
textArea.replaceText(sb.toString());
}
@FXML
protected void prettyPrint() {
stripWhiteSpaces();
CodeArea textArea = UIBean.getCurCodeArea();
String text = textArea.getText();
Source xmlInput = new StreamSource(new StringReader(text));
StreamResult xmlOutput = new StreamResult(new StringWriter());
try {
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
transformer.transform(xmlInput, xmlOutput);
textArea.replaceText(xmlOutput.getWriter().toString());
} catch (TransformerException ex) {
Stage stage = (Stage) anchorPane.getScene().getWindow();
MessageBoxFactory.showErrorDialog(stage, "Check Details for more info", "Transformation error occured", "Error", ex);
Logger.getLogger(MainController.class.getName()).log(Level.SEVERE, null, ex);
}
}
@FXML
protected void validate() {
Stage stage = (Stage) anchorPane.getScene().getWindow();
String filePathXSD = MessageBoxFactory.showDropDownListDialog(stage, "", "Please choose XSD to validate the file", "Select file", UIHelperUtil.getOpenFiles());
if (filePathXSD == null) {
return;
}
String fileShortPathXML = tabPane.getSelectionModel().getSelectedItem().getText();
String filePathXML = UIHelperUtil.getAbsolutePathFromOpenFiles(fileShortPathXML);
try {
String result = Validator.doValidate(filePathXML, filePathXSD);
if (result != null && !result.isEmpty()) {
String[] lines = result.split("<br/>");
MessageBoxFactory.showErrorDialog(stage, "Check Details for all validation errors", "The file is NOT valid for this XSD", "Invalid XML", Arrays.toString(lines));
} else {
MessageBoxFactory.showInfoDialog(stage, "", "The file is valid according to the selected XSD", "Valid XML");
}
} catch (FileNotFoundException ex) {
MessageBoxFactory.showErrorDialog(stage, "Check Details for more info", "System I/O error occured", "Error", ex);
Logger.getLogger(MainController.class.getName()).log(Level.SEVERE, null, ex);
}
}
@FXML
protected void transform() {
NormTransformer normTransformer = new NormTransformer();
String fileShortPathXML = tabPane.getSelectionModel().getSelectedItem().getText();
String filePathXML = UIHelperUtil.getAbsolutePathFromOpenFiles(fileShortPathXML);
normTransformer.setInPath(filePathXML);
Stage stage = (Stage) anchorPane.getScene().getWindow();
String filePathXSL = MessageBoxFactory.showDropDownListDialog(stage, "", "Please choose XSL to transform the file", "Select file", UIHelperUtil.getOpenFiles());
if (filePathXSL == null) {
return;
}
normTransformer.setTransformatorPath(filePathXSL);
//REFACTOR THIS SHIT:
File file = new File(filePathXML);
file = file.getParentFile();
normTransformer.setResultDir(file.getAbsolutePath());
try {
String transformedFile = normTransformer.normaliseXSLT();
fileOpenByString(transformedFile);
prettyPrint();
} catch (TransformerException | IOException ex) {
MessageBoxFactory.showErrorDialog(stage, "Check Details for more info", "The transformation was unsuccessful", "Tranformation failed", ex);
Logger.getLogger(MainController.class.getName()).log(Level.SEVERE, null, ex);
}
}
@FXML
protected void FOTransform() {
FOTransformer foTransformer = new FOTransformer();
String fileShortPathXML = tabPane.getSelectionModel().getSelectedItem().getText();
String filePathXML = UIHelperUtil.getAbsolutePathFromOpenFiles(fileShortPathXML);
foTransformer.setXmlFilePath(filePathXML);
Stage stage = (Stage) anchorPane.getScene().getWindow();
String filePathXSL = MessageBoxFactory.showDropDownListDialog(stage, "", "Please choose XSL for FO transformation", "Select file", UIHelperUtil.getOpenFiles());
if (filePathXSL == null) {
return;
}
foTransformer.setXslFilePath(filePathXSL);
//REFACTOR THIS SHIT:
File file = new File(filePathXML);
file = file.getParentFile();
foTransformer.setPdfFilePath(file.getAbsolutePath());
try {
//transform and show the file
File pdf = foTransformer.transform();
Desktop desktop = Desktop.getDesktop();
desktop.open(pdf);
} catch (IOException | IllegalArgumentException | FOPException | NullPointerException ex) {
MessageBoxFactory.showErrorDialog(stage, "Check Details for more info", "The FO transformation was unsuccessful", "PDF generation failed", ex);
Logger.getLogger(MainController.class.getName()).log(Level.SEVERE, null, ex);
}
}
@FXML
protected void cut() {
CodeArea textArea = UIBean.getCurCodeArea();
textArea.cut();
}
@FXML
protected void copy() {
CodeArea textArea = UIBean.getCurCodeArea();
textArea.copy();
}
@FXML
protected void paste() {
CodeArea textArea = UIBean.getCurCodeArea();
textArea.paste();
}
@FXML
protected void undo() {
CodeArea textArea = UIBean.getCurCodeArea();
textArea.undo();
}
@FXML
protected void redo() {
CodeArea textArea = UIBean.getCurCodeArea();
textArea.redo();
}
@FXML
protected void winResizeOnMousePressed(MouseEvent e) {
Stage stage = (Stage) anchorPane.getScene().getWindow();
dragOffsetX = (stage.getX() + stage.getWidth()) - e.getScreenX();
dragOffsetY = (stage.getY() + stage.getHeight()) - e.getScreenY();
e.consume();
}
@FXML
protected void winResizeOnMouseDragged(MouseEvent e) {
Stage stage = (Stage) anchorPane.getScene().getWindow();
double stageMinimumWidth = 1020.0;
double stageMinimumHeight = 700.0;
ObservableList<Screen> screens = Screen.getScreensForRectangle(stage.getX(), stage.getY(), 1, 1);
final Screen screen;
if (screens.size() > 0) {
screen = Screen.getScreensForRectangle(stage.getX(), stage.getY(), 1, 1).get(0);
} else {
screen = Screen.getScreensForRectangle(0, 0, 1, 1).get(0);
}
Rectangle2D visualBounds = screen.getVisualBounds();
double maxX = Math.min(visualBounds.getMaxX(), e.getScreenX() + dragOffsetX);
double maxY = Math.min(visualBounds.getMaxY(), e.getScreenY() - dragOffsetY);
stage.setWidth(Math.max(stageMinimumWidth, maxX - stage.getX()));
stage.setHeight(Math.max(stageMinimumHeight, maxY - stage.getY()));
e.consume();
}
@FXML
protected void print() {
CodeArea textArea = UIBean.getCurCodeArea();
boolean success = PrintHelperXML.scaleAndPrintA4(textArea);
Stage stage = (Stage) anchorPane.getScene().getWindow();
if (success) {
MessageBoxFactory.showInfoDialog(stage, "", "The document was sent to the default printer", "Print job done!");
} else {
MessageBoxFactory.showErrorDialog(stage, "", "The document was NOT printed successfully", "Printing failed!");
}
}
@FXML
private void closeTab() {
Tab currTab = tabPane.getSelectionModel().getSelectedItem();
EventHandler<Event> handler = currTab.getOnClosed();
if (null != handler) {
handler.handle(null);
} else {
currTab.getTabPane().getTabs().remove(currTab);
}
}
@Override
public void initialize(URL url, ResourceBundle rb) {
}
}