package com.digiarea.closurefx; import java.io.File; import java.io.FileOutputStream; import java.net.URL; import java.text.MessageFormat; import java.util.Iterator; import java.util.ResourceBundle; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.collections.ObservableList; import javafx.event.ActionEvent; import javafx.event.EventHandler; import javafx.fxml.FXML; import javafx.fxml.Initializable; import javafx.scene.Scene; import javafx.scene.control.Button; import javafx.scene.control.ContentDisplay; import javafx.scene.control.Control; import javafx.scene.control.Tab; import javafx.scene.control.TabPane; import javafx.scene.control.Tooltip; import javafx.scene.image.ImageView; import javafx.scene.input.KeyCode; import javafx.scene.input.KeyCodeCombination; import javafx.scene.input.KeyCombination; import javafx.scene.input.MouseEvent; import javafx.scene.layout.HBox; import javafx.scene.layout.Priority; import javafx.scene.layout.VBox; import javafx.stage.FileChooser; import javafx.stage.Stage; import javafx.stage.WindowEvent; import com.digiarea.closure.core.Path; import com.digiarea.closure.help.model.controller.HelpController; import com.digiarea.closure.help.model.controller.HelpFactory; import com.digiarea.closure.model.Closure; import com.digiarea.closure.model.controller.dialogs.DialogFactory; import com.digiarea.closure.model.controller.dialogs.ExportCLIDialogController; import com.digiarea.closure.model.controller.dialogs.FolderDialogController; import com.digiarea.closure.model.export.ClosureCLExporter; import com.digiarea.closure.preferences.model.controller.PreferencesFactory; import com.digiarea.closurefx.build.validation.IStatus; import com.digiarea.closurefx.build.validation.IStatus.StatusType; import com.digiarea.closurefx.build.validation.Status; /** * * @author norb */ public class ClosureFXController implements Initializable { private Stage stage; private ResourceBundle bundle; private DocumentManager documentManager; private TooltipManager tooltipManager; @FXML private TabPane docTabPane; @FXML private Button newButton; @FXML private Button openButton; @FXML private Button saveButton; @FXML private Button runButton; @FXML private VBox controlTooltips; public static ClosureFXController APPLICATION; private HelpController help; public ClosureFXController() { APPLICATION = this; } @Override public void initialize(URL url, ResourceBundle rb) { bundle = rb; documentManager = new DocumentManager(); tooltipManager = new TooltipManager(controlTooltips); } @FXML private void handleAboutButtonAction(ActionEvent event) { DialogFactory.getAboutDialog(bundle, bundle.getString(IConstants.About_Title)); } @FXML private void handleHelpContentsButtonAction(ActionEvent event) { openHelp(); } public HelpController openHelp() { if (help == null) { help = HelpFactory.getHelp(bundle, IConstants.Help_Title); } help.getStage().show(); return help; } @FXML private void handleRunButton(ActionEvent event) { Document document = getDocument(getActiveTab()); if (document != null) { document.getModelFacade().getJsConsole().start(); document.getModelFacade().getSoyConsole().start(); document.getModelFacade().getGssConsole().start(); } } @FXML private void handleExportCommandLineButtonAction(ActionEvent event) { Tab activeTab = getActiveTab(); if (activeTab != null) { Document document = getDocument(activeTab); if (document != null) { DialogFactory.getExportCLIDialog(bundle, IConstants.ExportDialog_CLI, IConstants.ExportDialog_CLI_desc, document); } } } @FXML private void handleDuplicateButtonAction(ActionEvent event) { Tab activeTab = getActiveTab(); if (activeTab != null) { Document document = getDocument(activeTab); if (document != null) { try { Closure closure = (Closure) document.getClosure().clone(); openNewTab(null, closure); } catch (CloneNotSupportedException e) { e.printStackTrace(); } } } } @FXML private void handleSettingsButtonAction(ActionEvent event) { PreferencesFactory.getPreferenceDialog(bundle); } @FXML private void handleNewButtonAction(ActionEvent event) { openNewTab(null, null); } @FXML private void handleOpenButtonAction(ActionEvent event) { FileChooser fileChooser = new FileChooser(); FileChooser.ExtensionFilter mwFilter = new FileChooser.ExtensionFilter( IConstants.CLOSURE_BUILD_FILE, IConstants.EXTENSION__CLOSURE); fileChooser.getExtensionFilters().add(mwFilter); File file = fileChooser.showOpenDialog(null); if (file != null) { openNewTab(file, null); } } @FXML private void handleSaveButtonAction(ActionEvent event) { Document document = getDocument(getActiveTab()); IStatus status = documentManager.saveWithoutPromt(document, bundle); if (document != null && status.getSeverity() == StatusType.OK) { tooltipManager.addTooltip(new Status(StatusType.WARNING, MessageFormat.format( bundle.getString(IConstants.TooltipMsg_Saved), document.getName()), null)); } } @FXML private void handleSaveAllButtonAction(ActionEvent event) { for (Tab tab : docTabPane.getTabs()) { Document document = getDocument(tab); documentManager.saveDocument(document, bundle); } } @FXML private void handleExitButtonAction(ActionEvent event) { Iterator<Tab> iterator = docTabPane.getTabs().iterator(); while (iterator.hasNext()) { Tab tab = iterator.next(); Document document = getDocument(tab); IStatus result = documentManager.saveDocument(document, bundle); // process result if (result.getSeverity() != StatusType.CANCEL) { iterator.remove(); documentManager.removeDocument(document); } else { return; } } stage.close(); } @FXML private void handleCloseButtonAction(ActionEvent event) { Tab tab = getActiveTab(); if (tab != null) { closeTab(tab, getDocument(tab)); } } @FXML private void handleCloseAllButtonAction(ActionEvent event) { Iterator<Tab> iterator = docTabPane.getTabs().iterator(); while (iterator.hasNext()) { Tab tab = iterator.next(); Document document = getDocument(tab); IStatus result = documentManager.saveDocument(document, bundle); // process result if (result.getSeverity() != StatusType.CANCEL) { iterator.remove(); documentManager.removeDocument(document); } else { return; } } } private void openNewTab(File file, Closure closure) { final Document document = new Document(file); document.setClosure(closure); document.setBundle(bundle); document.setName(getNewName(file)); boolean result = documentManager.addDocument(document); // if file is already open if (!result) { Tab existedTab = docTabPane.getTabs().get( documentManager.getIndex(document)); docTabPane.getSelectionModel().select(existedTab); tooltipManager.addTooltip(new Status(StatusType.WARNING, bundle .getString(IConstants.TooltipMsg_DocumentExist), null)); } else { // MAKE NEW TAB final Tab tab = new Tab(document.getName()); tab.setClosable(false); tab.setGraphic(new ImageView(ResourceUtils.CLOSURE_ICON)); tab.setTooltip(new Tooltip(getTooltip(file))); document.nameProperty().addListener(new ChangeListener<String>() { @Override public void changed( ObservableValue<? extends String> observable, String oldValue, String newValue) { tab.setText(newValue); } }); // document.dirtyProperty().addListener(new // ChangeListener<Boolean>() { // @Override // public void changed( // ObservableValue<? extends Boolean> observable, // Boolean oldValue, Boolean newValue) { // if (newValue) { // tab.getStyleClass().add(IConstants.CSS_TAB_BOLD); // } else { // tab.getStyleClass().add(IConstants.CSS_TAB_NORMAL); // } // } // }); // CLOSURE EDITOR TabPane editor = document.load(); Button closeButton = new Button(); closeButton.setGraphic(new ImageView(ResourceUtils.BUTTON_CLOSE)); closeButton.setContentDisplay(ContentDisplay.GRAPHIC_ONLY); closeButton.getStyleClass().addAll(IConstants.CSS_INVISIBLE_BUTTON, IConstants.CSS_CLOSE_BUTTON); // Handler for the close button. closeButton.setOnMouseReleased(new EventHandler<MouseEvent>() { @Override public void handle(MouseEvent paramT) { closeTab(tab, document); } }); tab.setGraphic(closeButton); if (editor != null) { editor.setMinHeight(Control.USE_COMPUTED_SIZE); editor.setMinWidth(Control.USE_COMPUTED_SIZE); editor.setPrefHeight(Control.USE_COMPUTED_SIZE); editor.setPrefWidth(Control.USE_COMPUTED_SIZE); editor.setMaxHeight(1.7976931348623157E308); editor.setPrefWidth(Control.USE_COMPUTED_SIZE); HBox.setHgrow(editor, Priority.ALWAYS); VBox.setVgrow(editor, Priority.ALWAYS); VBox pane = new VBox(); pane.setMinHeight(Control.USE_COMPUTED_SIZE); pane.setMinWidth(Control.USE_COMPUTED_SIZE); pane.setPrefHeight(Control.USE_COMPUTED_SIZE); pane.setPrefWidth(Control.USE_COMPUTED_SIZE); pane.setMaxHeight(Control.USE_COMPUTED_SIZE); pane.setMinHeight(Control.USE_COMPUTED_SIZE); pane.getChildren().add(editor); tab.setContent(pane); } docTabPane.getTabs().add(tab); docTabPane.getSelectionModel().select(tab); } } private String getNewName(File file) { if (file != null) { return file.getName(); } else { return getNewName(); } } public String getTooltip(File file) { if (file != null) { return file.getAbsolutePath(); } else { return getNewName(); } } private String getNewName() { return MessageFormat.format(bundle.getString(IConstants.Tab_Untitled), documentManager.getDocumentsCount()); } public void setStage(Stage stage) { this.stage = stage; this.stage.setOnCloseRequest(new EventHandler<WindowEvent>() { @Override public void handle(WindowEvent event) { Iterator<Tab> iterator = docTabPane.getTabs().iterator(); while (iterator.hasNext()) { Tab tab = iterator.next(); Document document = getDocument(tab); IStatus result = documentManager.saveDocument(document, bundle); // process result if (result.getSeverity() != StatusType.CANCEL) { iterator.remove(); documentManager.removeDocument(document); } else { event.consume(); return; } } } }); Scene scene = this.stage.getScene(); if (scene != null) { scene.getAccelerators().put( new KeyCodeCombination(KeyCode.R, KeyCombination.CONTROL_DOWN), new Runnable() { @Override public void run() { runButton.fireEvent(new ActionEvent()); } }); } } private IStatus closeTab(Tab tab, Document document) { IStatus result = documentManager.saveDocument(document, bundle); if (result.getSeverity() != StatusType.CANCEL) { docTabPane.getTabs().remove(tab); documentManager.removeDocument(document); } return result; } private Tab getActiveTab() { final ObservableList<Tab> tabs = docTabPane.getTabs(); if (!tabs.isEmpty()) { for (Tab tab : tabs) { if (tab.isSelected()) { return tab; } } } return null; } private Document getDocument(Tab tab) { int index = docTabPane.getTabs().indexOf(tab); return documentManager.getDocument(index); } }