| | import javafx.stage.WindowEvent; |
| | import org.controlsfx.control.StatusBar; |
| | -import org.fxmisc.richtext.StyleClassedTextArea; |
| | -import org.fxmisc.richtext.model.TwoDimensional.Position; |
| | - |
| | -import java.io.File; |
| | -import java.nio.file.Path; |
| | -import java.util.*; |
| | -import java.util.function.Function; |
| | -import java.util.prefs.Preferences; |
| | - |
| | -import static com.scrivenvar.Constants.*; |
| | -import static com.scrivenvar.Messages.get; |
| | -import static com.scrivenvar.Messages.getLiteral; |
| | -import static com.scrivenvar.util.StageState.*; |
| | -import static de.jensd.fx.glyphs.fontawesome.FontAwesomeIcon.*; |
| | -import static javafx.event.Event.fireEvent; |
| | -import static javafx.scene.input.KeyCode.ENTER; |
| | -import static javafx.stage.WindowEvent.WINDOW_CLOSE_REQUEST; |
| | - |
| | -/** |
| | - * Main window containing a tab pane in the center for file editors. |
| | - * |
| | - * @author Karl Tauber and White Magic Software, Ltd. |
| | - */ |
| | -public class MainWindow implements Observer { |
| | - |
| | - private final Options mOptions = Services.load( Options.class ); |
| | - private final Snitch mSnitch = Services.load( Snitch.class ); |
| | - private final Settings mSettings = Services.load( Settings.class ); |
| | - private final Notifier mNotifier = Services.load( Notifier.class ); |
| | - |
| | - private final Scene mScene; |
| | - private final StatusBar mStatusBar; |
| | - private final Text mLineNumberText; |
| | - private final TextField mFindTextField; |
| | - |
| | - private DefinitionSource mDefinitionSource = createDefaultDefinitionSource(); |
| | - private final DefinitionPane mDefinitionPane = new DefinitionPane(); |
| | - private final HTMLPreviewPane mPreviewPane = new HTMLPreviewPane(); |
| | - private FileEditorTabPane fileEditorPane; |
| | - |
| | - /** |
| | - * Prevents re-instantiation of processing classes. |
| | - */ |
| | - private final Map<FileEditorTab, Processor<String>> mProcessors = |
| | - new HashMap<>(); |
| | - |
| | - private final Map<String, String> mResolvedMap = |
| | - new HashMap<>( DEFAULT_MAP_SIZE ); |
| | - |
| | - /** |
| | - * Listens on the definition pane for double-click events. |
| | - */ |
| | - private VariableNameInjector variableNameInjector; |
| | - |
| | - /** |
| | - * Called when the definition data is changed. |
| | - */ |
| | - final EventHandler<TreeItem.TreeModificationEvent<Event>> mTreeHandler = |
| | - event -> { |
| | - exportDefinitions( getDefinitionPath() ); |
| | - interpolateResolvedMap(); |
| | - refreshActiveTab(); |
| | - }; |
| | - |
| | - final EventHandler<? super KeyEvent> mKeyHandler = |
| | - event -> { |
| | - if( event.getCode() == ENTER ) { |
| | - getVariableNameInjector().injectSelectedItem(); |
| | - } |
| | - }; |
| | - |
| | - public MainWindow() { |
| | - mStatusBar = createStatusBar(); |
| | - mLineNumberText = createLineNumberText(); |
| | - mFindTextField = createFindTextField(); |
| | - mScene = createScene(); |
| | - |
| | - initLayout(); |
| | - initFindInput(); |
| | - initSnitch(); |
| | - initDefinitionListener(); |
| | - initTabAddedListener(); |
| | - initTabChangedListener(); |
| | - initPreferences(); |
| | - } |
| | - |
| | - /** |
| | - * Watch for changes to external files. In particular, this awaits |
| | - * modifications to any XSL files associated with XML files being edited. When |
| | - * an XSL file is modified (external to the application), the snitch's ears |
| | - * perk up and the file is reloaded. This keeps the XSL transformation up to |
| | - * date with what's on the file system. |
| | - */ |
| | - private void initSnitch() { |
| | - getSnitch().addObserver( this ); |
| | - } |
| | - |
| | - /** |
| | - * Initialize the find input text field to listen on F3, ENTER, and ESCAPE key |
| | - * presses. |
| | - */ |
| | - private void initFindInput() { |
| | - final TextField input = getFindTextField(); |
| | - |
| | - input.setOnKeyPressed( ( KeyEvent event ) -> { |
| | - switch( event.getCode() ) { |
| | - case F3: |
| | - case ENTER: |
| | - findNext(); |
| | - break; |
| | - case F: |
| | - if( !event.isControlDown() ) { |
| | - break; |
| | - } |
| | - case ESCAPE: |
| | - getStatusBar().setGraphic( null ); |
| | - getActiveFileEditor().getEditorPane().requestFocus(); |
| | - break; |
| | - } |
| | - } ); |
| | - |
| | - // Remove when the input field loses focus. |
| | - input.focusedProperty().addListener( |
| | - ( |
| | - final ObservableValue<? extends Boolean> focused, |
| | - final Boolean oFocus, |
| | - final Boolean nFocus ) -> { |
| | - if( !nFocus ) { |
| | - getStatusBar().setGraphic( null ); |
| | - } |
| | - } |
| | - ); |
| | - } |
| | - |
| | - /** |
| | - * Listen for {@link FileEditorTabPane} to receive open definition file event. |
| | - */ |
| | - private void initDefinitionListener() { |
| | - getFileEditorPane().onOpenDefinitionFileProperty().addListener( |
| | - ( final ObservableValue<? extends Path> file, |
| | - final Path oldPath, final Path newPath ) -> { |
| | - // Indirectly refresh the resolved map. |
| | - resetProcessors(); |
| | - |
| | - openDefinitions( newPath ); |
| | - |
| | - // Will create new processors and therefore a new resolved map. |
| | - refreshActiveTab(); |
| | - } |
| | - ); |
| | - } |
| | - |
| | - /** |
| | - * When tabs are added, hook the various change listeners onto the new tab so |
| | - * that the preview pane refreshes as necessary. |
| | - */ |
| | - private void initTabAddedListener() { |
| | - final FileEditorTabPane editorPane = getFileEditorPane(); |
| | - |
| | - // Make sure the text processor kicks off when new files are opened. |
| | - final ObservableList<Tab> tabs = editorPane.getTabs(); |
| | - |
| | - // Update the preview pane on tab changes. |
| | - tabs.addListener( |
| | - ( final Change<? extends Tab> change ) -> { |
| | - while( change.next() ) { |
| | - if( change.wasAdded() ) { |
| | - // Multiple tabs can be added simultaneously. |
| | - for( final Tab newTab : change.getAddedSubList() ) { |
| | - final FileEditorTab tab = (FileEditorTab) newTab; |
| | - |
| | - initTextChangeListener( tab ); |
| | - initCaretParagraphListener( tab ); |
| | - initKeyboardEventListeners( tab ); |
| | -// initSyntaxListener( tab ); |
| | - } |
| | - } |
| | - } |
| | - } |
| | - ); |
| | - } |
| | - |
| | - /** |
| | - * Reloads the preferences from the previous session. |
| | - */ |
| | - private void initPreferences() { |
| | - restoreDefinitionPane(); |
| | - getFileEditorPane().restorePreferences(); |
| | - } |
| | - |
| | - /** |
| | - * Listen for new tab selection events. |
| | - */ |
| | - private void initTabChangedListener() { |
| | - final FileEditorTabPane editorPane = getFileEditorPane(); |
| | - |
| | - // Update the preview pane changing tabs. |
| | - editorPane.addTabSelectionListener( |
| | - ( ObservableValue<? extends Tab> tabPane, |
| | - final Tab oldTab, final Tab newTab ) -> { |
| | - updateVariableNameInjector(); |
| | - |
| | - // If there was no old tab, then this is a first time load, which |
| | - // can be ignored. |
| | - if( oldTab != null ) { |
| | - if( newTab == null ) { |
| | - closeRemainingTab(); |
| | - } |
| | - else { |
| | - // Update the preview with the edited text. |
| | - refreshSelectedTab( (FileEditorTab) newTab ); |
| | - } |
| | - } |
| | - } |
| | - ); |
| | - } |
| | - |
| | - /** |
| | - * Ensure that the keyboard events are received when a new tab is added |
| | - * to the user interface. |
| | - * |
| | - * @param tab The tab that can trigger keyboard events, such as control+space. |
| | - */ |
| | - private void initKeyboardEventListeners( final FileEditorTab tab ) { |
| | - final VariableNameInjector vin = getVariableNameInjector(); |
| | - vin.initKeyboardEventListeners( tab ); |
| | - } |
| | - |
| | - private void initTextChangeListener( final FileEditorTab tab ) { |
| | - tab.addTextChangeListener( |
| | - ( ObservableValue<? extends String> editor, |
| | - final String oldValue, final String newValue ) -> |
| | - refreshSelectedTab( tab ) |
| | - ); |
| | - } |
| | - |
| | - private void initCaretParagraphListener( final FileEditorTab tab ) { |
| | - tab.addCaretParagraphListener( |
| | - ( ObservableValue<? extends Integer> editor, |
| | - final Integer oldValue, final Integer newValue ) -> |
| | - refreshSelectedTab( tab ) |
| | - ); |
| | - } |
| | - |
| | - private void updateVariableNameInjector() { |
| | - getVariableNameInjector().setFileEditorTab( getActiveFileEditor() ); |
| | - } |
| | - |
| | - private void setVariableNameInjector( final VariableNameInjector injector ) { |
| | - this.variableNameInjector = injector; |
| | - } |
| | - |
| | - private synchronized VariableNameInjector getVariableNameInjector() { |
| | - if( this.variableNameInjector == null ) { |
| | - final VariableNameInjector vin = createVariableNameInjector(); |
| | - setVariableNameInjector( vin ); |
| | - } |
| | - |
| | - return this.variableNameInjector; |
| | - } |
| | - |
| | - private VariableNameInjector createVariableNameInjector() { |
| | - final FileEditorTab tab = getActiveFileEditor(); |
| | - final DefinitionPane pane = getDefinitionPane(); |
| | - |
| | - return new VariableNameInjector( tab, pane ); |
| | - } |
| | - |
| | - /** |
| | - * Called whenever the preview pane becomes out of sync with the file editor |
| | - * tab. This can be called when the text changes, the caret paragraph changes, |
| | - * or the file tab changes. |
| | - * |
| | - * @param tab The file editor tab that has been changed in some fashion. |
| | - */ |
| | - private void refreshSelectedTab( final FileEditorTab tab ) { |
| | - if( tab == null ) { |
| | - return; |
| | - } |
| | - |
| | - getPreviewPane().setPath( tab.getPath() ); |
| | - |
| | - // TODO: https://github.com/DaveJarvis/scrivenvar/issues/29 |
| | - final Position p = tab.getCaretOffset(); |
| | - getLineNumberText().setText( |
| | - get( STATUS_BAR_LINE, |
| | - p.getMajor() + 1, |
| | - p.getMinor() + 1, |
| | - tab.getCaretPosition() + 1 |
| | - ) |
| | - ); |
| | - |
| | - Processor<String> processor = getProcessors().get( tab ); |
| | - |
| | - if( processor == null ) { |
| | - processor = createProcessor( tab ); |
| | - getProcessors().put( tab, processor ); |
| | - } |
| | - |
| | - try { |
| | - processor.processChain( tab.getEditorText() ); |
| | - } catch( final Exception ex ) { |
| | - error( ex ); |
| | - } |
| | - } |
| | - |
| | - private void refreshActiveTab() { |
| | - refreshSelectedTab( getActiveFileEditor() ); |
| | - } |
| | - |
| | - /** |
| | - * Used to find text in the active file editor window. |
| | - */ |
| | - private void find() { |
| | - final TextField input = getFindTextField(); |
| | - getStatusBar().setGraphic( input ); |
| | - input.requestFocus(); |
| | - } |
| | - |
| | - public void findNext() { |
| | - getActiveFileEditor().searchNext( getFindTextField().getText() ); |
| | - } |
| | - |
| | - /** |
| | - * Returns the variable map of interpolated definitions. |
| | - * |
| | - * @return A map to help dereference variables. |
| | - */ |
| | - private Map<String, String> getResolvedMap() { |
| | - return mResolvedMap; |
| | - } |
| | - |
| | - private void interpolateResolvedMap() { |
| | - final Map<String, String> treeMap = getDefinitionPane().toMap(); |
| | - final Map<String, String> map = new HashMap<>( treeMap ); |
| | - MapInterpolator.interpolate( map ); |
| | - |
| | - getResolvedMap().clear(); |
| | - getResolvedMap().putAll( map ); |
| | - } |
| | - |
| | - /** |
| | - * Called when a definition source is opened. |
| | - * |
| | - * @param path Path to the definition source that was opened. |
| | - */ |
| | - private void openDefinitions( final Path path ) { |
| | - try { |
| | - final DefinitionSource ds = createDefinitionSource( path ); |
| | - setDefinitionSource( ds ); |
| | - storeDefinitionSourceFilename( path ); |
| | - |
| | - final DefinitionPane pane = getDefinitionPane(); |
| | - pane.update( ds ); |
| | - pane.addTreeChangeHandler( mTreeHandler ); |
| | - pane.addKeyEventHandler( mKeyHandler ); |
| | +import org.fxmisc.richtext.model.TwoDimensional.Position; |
| | + |
| | +import java.io.File; |
| | +import java.nio.file.Path; |
| | +import java.util.*; |
| | +import java.util.function.Function; |
| | +import java.util.prefs.Preferences; |
| | + |
| | +import static com.scrivenvar.Constants.*; |
| | +import static com.scrivenvar.Messages.get; |
| | +import static com.scrivenvar.Messages.getLiteral; |
| | +import static com.scrivenvar.util.StageState.*; |
| | +import static de.jensd.fx.glyphs.fontawesome.FontAwesomeIcon.*; |
| | +import static javafx.event.Event.fireEvent; |
| | +import static javafx.scene.input.KeyCode.ENTER; |
| | +import static javafx.scene.input.KeyCode.TAB; |
| | +import static javafx.stage.WindowEvent.WINDOW_CLOSE_REQUEST; |
| | + |
| | +/** |
| | + * Main window containing a tab pane in the center for file editors. |
| | + * |
| | + * @author Karl Tauber and White Magic Software, Ltd. |
| | + */ |
| | +public class MainWindow implements Observer { |
| | + |
| | + private final Options mOptions = Services.load( Options.class ); |
| | + private final Snitch mSnitch = Services.load( Snitch.class ); |
| | + private final Settings mSettings = Services.load( Settings.class ); |
| | + private final Notifier mNotifier = Services.load( Notifier.class ); |
| | + |
| | + private final Scene mScene; |
| | + private final StatusBar mStatusBar; |
| | + private final Text mLineNumberText; |
| | + private final TextField mFindTextField; |
| | + |
| | + private DefinitionSource mDefinitionSource = createDefaultDefinitionSource(); |
| | + private final DefinitionPane mDefinitionPane = new DefinitionPane(); |
| | + private final HTMLPreviewPane mPreviewPane = new HTMLPreviewPane(); |
| | + private FileEditorTabPane fileEditorPane; |
| | + |
| | + /** |
| | + * Prevents re-instantiation of processing classes. |
| | + */ |
| | + private final Map<FileEditorTab, Processor<String>> mProcessors = |
| | + new HashMap<>(); |
| | + |
| | + private final Map<String, String> mResolvedMap = |
| | + new HashMap<>( DEFAULT_MAP_SIZE ); |
| | + |
| | + /** |
| | + * Listens on the definition pane for double-click events. |
| | + */ |
| | + private VariableNameInjector variableNameInjector; |
| | + |
| | + /** |
| | + * Called when the definition data is changed. |
| | + */ |
| | + final EventHandler<TreeItem.TreeModificationEvent<Event>> mTreeHandler = |
| | + event -> { |
| | + exportDefinitions( getDefinitionPath() ); |
| | + interpolateResolvedMap(); |
| | + refreshActiveTab(); |
| | + }; |
| | + |
| | + final EventHandler<? super KeyEvent> mDefinitionKeyHandler = |
| | + event -> { |
| | + if( event.getCode() == ENTER ) { |
| | + getVariableNameInjector().injectSelectedItem(); |
| | + } |
| | + }; |
| | + |
| | + final EventHandler<? super KeyEvent> mEditorKeyHandler = |
| | + (EventHandler<KeyEvent>) event -> { |
| | + if( event.getCode() == TAB ) { |
| | + getDefinitionPane().requestFocus(); |
| | + event.consume(); |
| | + } |
| | + }; |
| | + |
| | + public MainWindow() { |
| | + mStatusBar = createStatusBar(); |
| | + mLineNumberText = createLineNumberText(); |
| | + mFindTextField = createFindTextField(); |
| | + mScene = createScene(); |
| | + |
| | + initLayout(); |
| | + initFindInput(); |
| | + initSnitch(); |
| | + initDefinitionListener(); |
| | + initTabAddedListener(); |
| | + initTabChangedListener(); |
| | + initPreferences(); |
| | + } |
| | + |
| | + /** |
| | + * Watch for changes to external files. In particular, this awaits |
| | + * modifications to any XSL files associated with XML files being edited. When |
| | + * an XSL file is modified (external to the application), the snitch's ears |
| | + * perk up and the file is reloaded. This keeps the XSL transformation up to |
| | + * date with what's on the file system. |
| | + */ |
| | + private void initSnitch() { |
| | + getSnitch().addObserver( this ); |
| | + } |
| | + |
| | + /** |
| | + * Initialize the find input text field to listen on F3, ENTER, and ESCAPE key |
| | + * presses. |
| | + */ |
| | + private void initFindInput() { |
| | + final TextField input = getFindTextField(); |
| | + |
| | + input.setOnKeyPressed( ( KeyEvent event ) -> { |
| | + switch( event.getCode() ) { |
| | + case F3: |
| | + case ENTER: |
| | + findNext(); |
| | + break; |
| | + case F: |
| | + if( !event.isControlDown() ) { |
| | + break; |
| | + } |
| | + case ESCAPE: |
| | + getStatusBar().setGraphic( null ); |
| | + getActiveFileEditor().getEditorPane().requestFocus(); |
| | + break; |
| | + } |
| | + } ); |
| | + |
| | + // Remove when the input field loses focus. |
| | + input.focusedProperty().addListener( |
| | + ( |
| | + final ObservableValue<? extends Boolean> focused, |
| | + final Boolean oFocus, |
| | + final Boolean nFocus ) -> { |
| | + if( !nFocus ) { |
| | + getStatusBar().setGraphic( null ); |
| | + } |
| | + } |
| | + ); |
| | + } |
| | + |
| | + /** |
| | + * Listen for {@link FileEditorTabPane} to receive open definition file event. |
| | + */ |
| | + private void initDefinitionListener() { |
| | + getFileEditorPane().onOpenDefinitionFileProperty().addListener( |
| | + ( final ObservableValue<? extends Path> file, |
| | + final Path oldPath, final Path newPath ) -> { |
| | + // Indirectly refresh the resolved map. |
| | + resetProcessors(); |
| | + |
| | + openDefinitions( newPath ); |
| | + |
| | + // Will create new processors and therefore a new resolved map. |
| | + refreshActiveTab(); |
| | + } |
| | + ); |
| | + } |
| | + |
| | + /** |
| | + * When tabs are added, hook the various change listeners onto the new tab so |
| | + * that the preview pane refreshes as necessary. |
| | + */ |
| | + private void initTabAddedListener() { |
| | + final FileEditorTabPane editorPane = getFileEditorPane(); |
| | + |
| | + // Make sure the text processor kicks off when new files are opened. |
| | + final ObservableList<Tab> tabs = editorPane.getTabs(); |
| | + |
| | + // Update the preview pane on tab changes. |
| | + tabs.addListener( |
| | + ( final Change<? extends Tab> change ) -> { |
| | + while( change.next() ) { |
| | + if( change.wasAdded() ) { |
| | + // Multiple tabs can be added simultaneously. |
| | + for( final Tab newTab : change.getAddedSubList() ) { |
| | + final FileEditorTab tab = (FileEditorTab) newTab; |
| | + |
| | + initTextChangeListener( tab ); |
| | + initCaretParagraphListener( tab ); |
| | + initKeyboardEventListeners( tab ); |
| | +// initSyntaxListener( tab ); |
| | + } |
| | + } |
| | + } |
| | + } |
| | + ); |
| | + } |
| | + |
| | + /** |
| | + * Reloads the preferences from the previous session. |
| | + */ |
| | + private void initPreferences() { |
| | + restoreDefinitionPane(); |
| | + getFileEditorPane().restorePreferences(); |
| | + } |
| | + |
| | + /** |
| | + * Listen for new tab selection events. |
| | + */ |
| | + private void initTabChangedListener() { |
| | + final FileEditorTabPane editorPane = getFileEditorPane(); |
| | + |
| | + // Update the preview pane changing tabs. |
| | + editorPane.addTabSelectionListener( |
| | + ( ObservableValue<? extends Tab> tabPane, |
| | + final Tab oldTab, final Tab newTab ) -> { |
| | + updateVariableNameInjector(); |
| | + |
| | + // If there was no old tab, then this is a first time load, which |
| | + // can be ignored. |
| | + if( oldTab != null ) { |
| | + if( newTab == null ) { |
| | + closeRemainingTab(); |
| | + } |
| | + else { |
| | + // Update the preview with the edited text. |
| | + refreshSelectedTab( (FileEditorTab) newTab ); |
| | + } |
| | + } |
| | + } |
| | + ); |
| | + } |
| | + |
| | + /** |
| | + * Ensure that the keyboard events are received when a new tab is added |
| | + * to the user interface. |
| | + * |
| | + * @param tab The tab that can trigger keyboard events, such as control+space. |
| | + */ |
| | + private void initKeyboardEventListeners( final FileEditorTab tab ) { |
| | + final VariableNameInjector vin = getVariableNameInjector(); |
| | + vin.initKeyboardEventListeners( tab ); |
| | + |
| | + tab.addEventFilter( KeyEvent.KEY_PRESSED, mEditorKeyHandler ); |
| | + } |
| | + |
| | + private void initTextChangeListener( final FileEditorTab tab ) { |
| | + tab.addTextChangeListener( |
| | + ( ObservableValue<? extends String> editor, |
| | + final String oldValue, final String newValue ) -> |
| | + refreshSelectedTab( tab ) |
| | + ); |
| | + } |
| | + |
| | + private void initCaretParagraphListener( final FileEditorTab tab ) { |
| | + tab.addCaretParagraphListener( |
| | + ( ObservableValue<? extends Integer> editor, |
| | + final Integer oldValue, final Integer newValue ) -> |
| | + refreshSelectedTab( tab ) |
| | + ); |
| | + } |
| | + |
| | + private void updateVariableNameInjector() { |
| | + getVariableNameInjector().setFileEditorTab( getActiveFileEditor() ); |
| | + } |
| | + |
| | + private void setVariableNameInjector( final VariableNameInjector injector ) { |
| | + this.variableNameInjector = injector; |
| | + } |
| | + |
| | + private synchronized VariableNameInjector getVariableNameInjector() { |
| | + if( this.variableNameInjector == null ) { |
| | + final VariableNameInjector vin = createVariableNameInjector(); |
| | + setVariableNameInjector( vin ); |
| | + } |
| | + |
| | + return this.variableNameInjector; |
| | + } |
| | + |
| | + private VariableNameInjector createVariableNameInjector() { |
| | + final FileEditorTab tab = getActiveFileEditor(); |
| | + final DefinitionPane pane = getDefinitionPane(); |
| | + |
| | + return new VariableNameInjector( tab, pane ); |
| | + } |
| | + |
| | + /** |
| | + * Called whenever the preview pane becomes out of sync with the file editor |
| | + * tab. This can be called when the text changes, the caret paragraph changes, |
| | + * or the file tab changes. |
| | + * |
| | + * @param tab The file editor tab that has been changed in some fashion. |
| | + */ |
| | + private void refreshSelectedTab( final FileEditorTab tab ) { |
| | + if( tab == null ) { |
| | + return; |
| | + } |
| | + |
| | + getPreviewPane().setPath( tab.getPath() ); |
| | + |
| | + // TODO: https://github.com/DaveJarvis/scrivenvar/issues/29 |
| | + final Position p = tab.getCaretOffset(); |
| | + getLineNumberText().setText( |
| | + get( STATUS_BAR_LINE, |
| | + p.getMajor() + 1, |
| | + p.getMinor() + 1, |
| | + tab.getCaretPosition() + 1 |
| | + ) |
| | + ); |
| | + |
| | + Processor<String> processor = getProcessors().get( tab ); |
| | + |
| | + if( processor == null ) { |
| | + processor = createProcessor( tab ); |
| | + getProcessors().put( tab, processor ); |
| | + } |
| | + |
| | + try { |
| | + processor.processChain( tab.getEditorText() ); |
| | + } catch( final Exception ex ) { |
| | + error( ex ); |
| | + } |
| | + } |
| | + |
| | + private void refreshActiveTab() { |
| | + refreshSelectedTab( getActiveFileEditor() ); |
| | + } |
| | + |
| | + /** |
| | + * Used to find text in the active file editor window. |
| | + */ |
| | + private void find() { |
| | + final TextField input = getFindTextField(); |
| | + getStatusBar().setGraphic( input ); |
| | + input.requestFocus(); |
| | + } |
| | + |
| | + public void findNext() { |
| | + getActiveFileEditor().searchNext( getFindTextField().getText() ); |
| | + } |
| | + |
| | + /** |
| | + * Returns the variable map of interpolated definitions. |
| | + * |
| | + * @return A map to help dereference variables. |
| | + */ |
| | + private Map<String, String> getResolvedMap() { |
| | + return mResolvedMap; |
| | + } |
| | + |
| | + private void interpolateResolvedMap() { |
| | + final Map<String, String> treeMap = getDefinitionPane().toMap(); |
| | + final Map<String, String> map = new HashMap<>( treeMap ); |
| | + MapInterpolator.interpolate( map ); |
| | + |
| | + getResolvedMap().clear(); |
| | + getResolvedMap().putAll( map ); |
| | + } |
| | + |
| | + /** |
| | + * Called when a definition source is opened. |
| | + * |
| | + * @param path Path to the definition source that was opened. |
| | + */ |
| | + private void openDefinitions( final Path path ) { |
| | + try { |
| | + final DefinitionSource ds = createDefinitionSource( path ); |
| | + setDefinitionSource( ds ); |
| | + storeDefinitionSourceFilename( path ); |
| | + |
| | + final DefinitionPane pane = getDefinitionPane(); |
| | + pane.update( ds ); |
| | + pane.addTreeChangeHandler( mTreeHandler ); |
| | + pane.addKeyEventHandler( mDefinitionKeyHandler ); |
| | |
| | interpolateResolvedMap(); |