Dave Jarvis' Repositories

git clone https://repo.autonoma.ca/repo/keenwrite.git

Reduce Workspace visibility, convert strings to file paths

AuthorDaveJarvis <email>
Date2020-12-20 17:44:50 GMT-0800
Commitabaedc9c7017a6f6db076e8a56b3f7c96f59181d
Parent8c6c5a9
Delta347 lines added, 352 lines removed, 5-line decrease
src/main/java/com/keenwrite/ui/actions/ApplicationActions.java
import com.keenwrite.io.File;
import com.keenwrite.preferences.UserPreferencesView;
-import com.keenwrite.preferences.Workspace;
-import com.keenwrite.preferences.WorkspacePreferences;
-import com.keenwrite.processors.ProcessorContext;
-import com.keenwrite.search.SearchModel;
-import com.keenwrite.ui.controls.SearchBar;
-import javafx.scene.control.Alert;
-import javafx.scene.image.ImageView;
-import javafx.stage.Window;
-import javafx.stage.WindowEvent;
-
-import static com.keenwrite.Bootstrap.APP_TITLE;
-import static com.keenwrite.Constants.ICON_DIALOG;
-import static com.keenwrite.ExportFormat.*;
-import static com.keenwrite.Messages.get;
-import static com.keenwrite.StatusBarNotifier.clue;
-import static com.keenwrite.StatusBarNotifier.getStatusBar;
-import static com.keenwrite.preferences.WorkspacePreferences.KEY_UI_RECENT_DIR;
-import static com.keenwrite.processors.ProcessorFactory.createProcessors;
-import static java.nio.file.Files.writeString;
-import static javafx.event.Event.fireEvent;
-import static javafx.scene.control.Alert.AlertType.INFORMATION;
-import static javafx.stage.WindowEvent.WINDOW_CLOSE_REQUEST;
-
-/**
- * Responsible for abstracting how functionality is mapped to the application.
- * This allows users to customize accelerator keys and will provide pluggable
- * functionality so that different text markup languages can change documents
- * using their respective syntax.
- */
-@SuppressWarnings("NonAsciiCharacters")
-public class ApplicationActions {
- private static final String STYLE_SEARCH = "search";
-
- /**
- * When an action is executed, this is one of the recipients.
- */
- private final MainPane mMainPane;
-
- /**
- * Tracks finding text in the active document.
- */
- private final SearchModel mSearchModel;
-
- public ApplicationActions( final MainPane mainPane ) {
- mMainPane = mainPane;
- mSearchModel = new SearchModel();
- mSearchModel.matchOffsetProperty().addListener( ( c, o, n ) -> {
- final var editor = getActiveTextEditor();
-
- // Clear highlighted areas before adding highlighting to a new region.
- if( o != null ) {
- editor.unstylize( STYLE_SEARCH );
- }
-
- if( n != null ) {
- editor.moveTo( n.getStart() );
- editor.stylize( n, STYLE_SEARCH );
- }
- } );
-
- // When the active text editor changes, update the haystack.
- mMainPane.activeTextEditorProperty().addListener(
- ( c, o, n ) -> mSearchModel.search( getActiveTextEditor().getText() )
- );
- }
-
- public void file‿new() {
- getMainPane().newTextEditor();
- }
-
- public void file‿open() {
- getMainPane().open( createFileChooser().openFiles() );
- }
-
- public void file‿close() {
- getMainPane().close();
- }
-
- public void file‿close_all() {
- getMainPane().closeAll();
- }
-
- public void file‿save() {
- getMainPane().save();
- }
-
- public void file‿save_as() {
- final var file = createFileChooser().saveAs();
- file.ifPresent( ( f ) -> getMainPane().saveAs( f ) );
- }
-
- public void file‿save_all() {
- getMainPane().saveAll();
- }
-
- public void file‿export‿html_svg() {
- file‿export( HTML_TEX_SVG );
- }
-
- public void file‿export‿html_tex() {
- file‿export( HTML_TEX_DELIMITED );
- }
-
- public void file‿export‿markdown() {
- file‿export( MARKDOWN_PLAIN );
- }
-
- private void file‿export( final ExportFormat format ) {
- final var editor = getActiveTextEditor();
- final var context = createProcessorContext( editor );
- final var chain = createProcessors( context );
- final var doc = editor.getText();
- final var export = chain.apply( doc );
- final var filename = format.toExportFilename( editor.getPath() );
- final var chooser = createFileChooser();
- final var file = chooser.exportAs( new File( filename ) );
-
- file.ifPresent( ( f ) -> {
- try {
- writeString( f.toPath(), export );
- final var m = get( "Main.status.export.success", f.toString() );
- clue( m );
- } catch( final Exception e ) {
- clue( e );
- }
- } );
- }
-
- private ProcessorContext createProcessorContext( final TextEditor editor ) {
- return getMainPane().createProcessorContext( editor );
- }
-
- public void file‿exit() {
- final var window = getWindow();
- fireEvent( window, new WindowEvent( window, WINDOW_CLOSE_REQUEST ) );
- }
-
- public void edit‿undo() {
- getActiveTextEditor().undo();
- }
-
- public void edit‿redo() {
- getActiveTextEditor().redo();
- }
-
- public void edit‿cut() {
- getActiveTextEditor().cut();
- }
-
- public void edit‿copy() {
- getActiveTextEditor().copy();
- }
-
- public void edit‿paste() {
- getActiveTextEditor().paste();
- }
-
- public void edit‿select_all() {
- getActiveTextEditor().selectAll();
- }
-
- public void edit‿find() {
- final var nodes = getStatusBar().getLeftItems();
-
- if( nodes.isEmpty() ) {
- final var searchBar = new SearchBar();
-
- searchBar.matchIndexProperty().bind( mSearchModel.matchIndexProperty() );
- searchBar.matchCountProperty().bind( mSearchModel.matchCountProperty() );
-
- searchBar.setOnCancelAction( ( event ) -> {
- final var editor = getActiveTextEditor();
- nodes.remove( searchBar );
- editor.unstylize( STYLE_SEARCH );
- editor.getNode().requestFocus();
- } );
-
- searchBar.addInputListener( ( c, o, n ) -> {
- if( n != null && !n.isEmpty() ) {
- mSearchModel.search( n, getActiveTextEditor().getText() );
- }
- } );
-
- searchBar.setOnNextAction( ( event ) -> edit‿find_next() );
- searchBar.setOnPrevAction( ( event ) -> edit‿find_prev() );
-
- nodes.add( searchBar );
- searchBar.requestFocus();
- }
- else {
- nodes.clear();
- }
- }
-
- public void edit‿find_next() {
- mSearchModel.advance();
- }
-
- public void edit‿find_prev() {
- mSearchModel.retreat();
- }
-
- public void edit‿preferences() {
- UserPreferencesView.getInstance().show();
- }
-
- public void format‿bold() {
- getActiveTextEditor().bold();
- }
-
- public void format‿italic() {
- getActiveTextEditor().italic();
- }
-
- public void format‿superscript() {
- getActiveTextEditor().superscript();
- }
-
- public void format‿subscript() {
- getActiveTextEditor().subscript();
- }
-
- public void format‿strikethrough() {
- getActiveTextEditor().strikethrough();
- }
-
- public void insert‿blockquote() {
- getActiveTextEditor().blockquote();
- }
-
- public void insert‿code() {
- getActiveTextEditor().code();
- }
-
- public void insert‿fenced_code_block() {
- getActiveTextEditor().fencedCodeBlock();
- }
-
- public void insert‿link() {
- createMarkdownDialog().insertLink( getActiveTextEditor().getTextArea() );
- }
-
- public void insert‿image() {
- createMarkdownDialog().insertImage( getActiveTextEditor().getTextArea() );
- }
-
- private MarkdownCommands createMarkdownDialog() {
- return new MarkdownCommands( getWindow(), getActiveTextEditor().getPath() );
- }
-
- public void insert‿heading_1() {
- insert‿heading( 1 );
- }
-
- public void insert‿heading_2() {
- insert‿heading( 2 );
- }
-
- public void insert‿heading_3() {
- insert‿heading( 3 );
- }
-
- private void insert‿heading( final int level ) {
- getActiveTextEditor().heading( level );
- }
-
- public void insert‿unordered_list() {
- getActiveTextEditor().unorderedList();
- }
-
- public void insert‿ordered_list() {
- getActiveTextEditor().orderedList();
- }
-
- public void insert‿horizontal_rule() {
- getActiveTextEditor().horizontalRule();
- }
-
- public void definition‿create() {
- getActiveTextDefinition().createDefinition();
- }
-
- public void definition‿rename() {
- getActiveTextDefinition().renameDefinition();
- }
-
- public void definition‿delete() {
- getActiveTextDefinition().deleteDefinitions();
- }
-
- public void definition‿autoinsert() {
- getMainPane().autoinsert();
- }
-
- public void view‿refresh() {
- }
-
- public void view‿preview() {
- }
-
- public void help‿about() {
- final Alert alert = new Alert( INFORMATION );
- alert.setTitle( get( "Dialog.about.title", APP_TITLE ) );
- alert.setHeaderText( get( "Dialog.about.header", APP_TITLE ) );
- alert.setContentText( get( "Dialog.about.content" ) );
- alert.setGraphic( new ImageView( ICON_DIALOG ) );
- alert.initOwner( getWindow() );
- alert.showAndWait();
- }
-
- private FileChooserCommand createFileChooser() {
- final var dir = getPreferences().fileProperty( KEY_UI_RECENT_DIR );
- return new FileChooserCommand( getWindow(), dir );
- }
-
- private MainPane getMainPane() {
- return mMainPane;
- }
-
- private TextEditor getActiveTextEditor() {
- return getMainPane().getActiveTextEditor();
- }
-
- private TextDefinition getActiveTextDefinition() {
- return getMainPane().getActiveTextDefinition();
- }
-
- private Workspace getWorkspace() {
- return mMainPane.getWorkspace();
- }
-
- private WorkspacePreferences getPreferences() {
- return getWorkspace().getPreferences();
+import com.keenwrite.preferences.WorkspacePreferences;
+import com.keenwrite.processors.ProcessorContext;
+import com.keenwrite.search.SearchModel;
+import com.keenwrite.ui.controls.SearchBar;
+import javafx.scene.control.Alert;
+import javafx.scene.image.ImageView;
+import javafx.stage.Window;
+import javafx.stage.WindowEvent;
+
+import static com.keenwrite.Bootstrap.APP_TITLE;
+import static com.keenwrite.Constants.ICON_DIALOG;
+import static com.keenwrite.ExportFormat.*;
+import static com.keenwrite.Messages.get;
+import static com.keenwrite.StatusBarNotifier.clue;
+import static com.keenwrite.StatusBarNotifier.getStatusBar;
+import static com.keenwrite.preferences.WorkspacePreferences.KEY_UI_RECENT_DIR;
+import static com.keenwrite.processors.ProcessorFactory.createProcessors;
+import static java.nio.file.Files.writeString;
+import static javafx.event.Event.fireEvent;
+import static javafx.scene.control.Alert.AlertType.INFORMATION;
+import static javafx.stage.WindowEvent.WINDOW_CLOSE_REQUEST;
+
+/**
+ * Responsible for abstracting how functionality is mapped to the application.
+ * This allows users to customize accelerator keys and will provide pluggable
+ * functionality so that different text markup languages can change documents
+ * using their respective syntax.
+ */
+@SuppressWarnings("NonAsciiCharacters")
+public class ApplicationActions {
+ private static final String STYLE_SEARCH = "search";
+
+ /**
+ * When an action is executed, this is one of the recipients.
+ */
+ private final MainPane mMainPane;
+
+ /**
+ * Tracks finding text in the active document.
+ */
+ private final SearchModel mSearchModel;
+
+ public ApplicationActions( final MainPane mainPane ) {
+ mMainPane = mainPane;
+ mSearchModel = new SearchModel();
+ mSearchModel.matchOffsetProperty().addListener( ( c, o, n ) -> {
+ final var editor = getActiveTextEditor();
+
+ // Clear highlighted areas before adding highlighting to a new region.
+ if( o != null ) {
+ editor.unstylize( STYLE_SEARCH );
+ }
+
+ if( n != null ) {
+ editor.moveTo( n.getStart() );
+ editor.stylize( n, STYLE_SEARCH );
+ }
+ } );
+
+ // When the active text editor changes, update the haystack.
+ mMainPane.activeTextEditorProperty().addListener(
+ ( c, o, n ) -> mSearchModel.search( getActiveTextEditor().getText() )
+ );
+ }
+
+ public void file‿new() {
+ getMainPane().newTextEditor();
+ }
+
+ public void file‿open() {
+ getMainPane().open( createFileChooser().openFiles() );
+ }
+
+ public void file‿close() {
+ getMainPane().close();
+ }
+
+ public void file‿close_all() {
+ getMainPane().closeAll();
+ }
+
+ public void file‿save() {
+ getMainPane().save();
+ }
+
+ public void file‿save_as() {
+ final var file = createFileChooser().saveAs();
+ file.ifPresent( ( f ) -> getMainPane().saveAs( f ) );
+ }
+
+ public void file‿save_all() {
+ getMainPane().saveAll();
+ }
+
+ public void file‿export‿html_svg() {
+ file‿export( HTML_TEX_SVG );
+ }
+
+ public void file‿export‿html_tex() {
+ file‿export( HTML_TEX_DELIMITED );
+ }
+
+ public void file‿export‿markdown() {
+ file‿export( MARKDOWN_PLAIN );
+ }
+
+ private void file‿export( final ExportFormat format ) {
+ final var editor = getActiveTextEditor();
+ final var context = createProcessorContext( editor );
+ final var chain = createProcessors( context );
+ final var doc = editor.getText();
+ final var export = chain.apply( doc );
+ final var filename = format.toExportFilename( editor.getPath() );
+ final var chooser = createFileChooser();
+ final var file = chooser.exportAs( new File( filename ) );
+
+ file.ifPresent( ( f ) -> {
+ try {
+ writeString( f.toPath(), export );
+ final var m = get( "Main.status.export.success", f.toString() );
+ clue( m );
+ } catch( final Exception e ) {
+ clue( e );
+ }
+ } );
+ }
+
+ private ProcessorContext createProcessorContext( final TextEditor editor ) {
+ return getMainPane().createProcessorContext( editor );
+ }
+
+ public void file‿exit() {
+ final var window = getWindow();
+ fireEvent( window, new WindowEvent( window, WINDOW_CLOSE_REQUEST ) );
+ }
+
+ public void edit‿undo() {
+ getActiveTextEditor().undo();
+ }
+
+ public void edit‿redo() {
+ getActiveTextEditor().redo();
+ }
+
+ public void edit‿cut() {
+ getActiveTextEditor().cut();
+ }
+
+ public void edit‿copy() {
+ getActiveTextEditor().copy();
+ }
+
+ public void edit‿paste() {
+ getActiveTextEditor().paste();
+ }
+
+ public void edit‿select_all() {
+ getActiveTextEditor().selectAll();
+ }
+
+ public void edit‿find() {
+ final var nodes = getStatusBar().getLeftItems();
+
+ if( nodes.isEmpty() ) {
+ final var searchBar = new SearchBar();
+
+ searchBar.matchIndexProperty().bind( mSearchModel.matchIndexProperty() );
+ searchBar.matchCountProperty().bind( mSearchModel.matchCountProperty() );
+
+ searchBar.setOnCancelAction( ( event ) -> {
+ final var editor = getActiveTextEditor();
+ nodes.remove( searchBar );
+ editor.unstylize( STYLE_SEARCH );
+ editor.getNode().requestFocus();
+ } );
+
+ searchBar.addInputListener( ( c, o, n ) -> {
+ if( n != null && !n.isEmpty() ) {
+ mSearchModel.search( n, getActiveTextEditor().getText() );
+ }
+ } );
+
+ searchBar.setOnNextAction( ( event ) -> edit‿find_next() );
+ searchBar.setOnPrevAction( ( event ) -> edit‿find_prev() );
+
+ nodes.add( searchBar );
+ searchBar.requestFocus();
+ }
+ else {
+ nodes.clear();
+ }
+ }
+
+ public void edit‿find_next() {
+ mSearchModel.advance();
+ }
+
+ public void edit‿find_prev() {
+ mSearchModel.retreat();
+ }
+
+ public void edit‿preferences() {
+ UserPreferencesView.getInstance().show();
+ }
+
+ public void format‿bold() {
+ getActiveTextEditor().bold();
+ }
+
+ public void format‿italic() {
+ getActiveTextEditor().italic();
+ }
+
+ public void format‿superscript() {
+ getActiveTextEditor().superscript();
+ }
+
+ public void format‿subscript() {
+ getActiveTextEditor().subscript();
+ }
+
+ public void format‿strikethrough() {
+ getActiveTextEditor().strikethrough();
+ }
+
+ public void insert‿blockquote() {
+ getActiveTextEditor().blockquote();
+ }
+
+ public void insert‿code() {
+ getActiveTextEditor().code();
+ }
+
+ public void insert‿fenced_code_block() {
+ getActiveTextEditor().fencedCodeBlock();
+ }
+
+ public void insert‿link() {
+ createMarkdownDialog().insertLink( getActiveTextEditor().getTextArea() );
+ }
+
+ public void insert‿image() {
+ createMarkdownDialog().insertImage( getActiveTextEditor().getTextArea() );
+ }
+
+ private MarkdownCommands createMarkdownDialog() {
+ return new MarkdownCommands( getWindow(), getActiveTextEditor().getPath() );
+ }
+
+ public void insert‿heading_1() {
+ insert‿heading( 1 );
+ }
+
+ public void insert‿heading_2() {
+ insert‿heading( 2 );
+ }
+
+ public void insert‿heading_3() {
+ insert‿heading( 3 );
+ }
+
+ private void insert‿heading( final int level ) {
+ getActiveTextEditor().heading( level );
+ }
+
+ public void insert‿unordered_list() {
+ getActiveTextEditor().unorderedList();
+ }
+
+ public void insert‿ordered_list() {
+ getActiveTextEditor().orderedList();
+ }
+
+ public void insert‿horizontal_rule() {
+ getActiveTextEditor().horizontalRule();
+ }
+
+ public void definition‿create() {
+ getActiveTextDefinition().createDefinition();
+ }
+
+ public void definition‿rename() {
+ getActiveTextDefinition().renameDefinition();
+ }
+
+ public void definition‿delete() {
+ getActiveTextDefinition().deleteDefinitions();
+ }
+
+ public void definition‿autoinsert() {
+ getMainPane().autoinsert();
+ }
+
+ public void view‿refresh() {
+ }
+
+ public void view‿preview() {
+ }
+
+ public void help‿about() {
+ final Alert alert = new Alert( INFORMATION );
+ alert.setTitle( get( "Dialog.about.title", APP_TITLE ) );
+ alert.setHeaderText( get( "Dialog.about.header", APP_TITLE ) );
+ alert.setContentText( get( "Dialog.about.content" ) );
+ alert.setGraphic( new ImageView( ICON_DIALOG ) );
+ alert.initOwner( getWindow() );
+ alert.showAndWait();
+ }
+
+ private FileChooserCommand createFileChooser() {
+ final var dir = getPreferences().fileProperty( KEY_UI_RECENT_DIR );
+ return new FileChooserCommand( getWindow(), dir );
+ }
+
+ private MainPane getMainPane() {
+ return mMainPane;
+ }
+
+ private TextEditor getActiveTextEditor() {
+ return getMainPane().getActiveTextEditor();
+ }
+
+ private TextDefinition getActiveTextDefinition() {
+ return getMainPane().getActiveTextDefinition();
+ }
+
+ private WorkspacePreferences getPreferences() {
+ return mMainPane.getPreferences();
}
src/main/java/com/keenwrite/preferences/WorkspacePreferences.java
//@formatter:on
- private final Map<Key, SetProperty<?>> SETS = Map.ofEntries(
- entry( KEY_UI_FILES_PATH, new SimpleSetProperty<File>() )
+ private final Map<Key, ListProperty<?>> LISTS = Map.ofEntries(
+ entry( KEY_UI_FILES_PATH, new SimpleListProperty<File>() )
);
*/
@SuppressWarnings("unchecked")
- public <T> Property<T> fromValues( final Key key ) {
+ public <T> Property<T> valuesProperty( final Key key ) {
// The type that goes into the map must come out.
return (Property<T>) VALUES.get( key );
*/
@SuppressWarnings("unchecked")
- public <T> SetProperty<T> fromSets( final Key key ) {
+ public <T> ListProperty<T> listsProperty( final Key key ) {
// The type that goes into the map must come out.
- return (SetProperty<T>) SETS.get( key );
+ return (ListProperty<T>) LISTS.get( key );
}
*/
public double toDouble( final Key key ) {
- return (double) fromValues( key ).getValue();
+ return (double) valuesProperty( key ).getValue();
}
*/
public boolean toBoolean( final Key key ) {
- return (boolean) fromValues( key ).getValue();
+ return (boolean) valuesProperty( key ).getValue();
}
*/
public Property<File> fileProperty( final Key key ) {
- return fromValues( key );
+ return valuesProperty( key );
}
/**
* Calls the given consumer for all single-value keys. For lists, see
- * {@link #consumeSets(BiConsumer)}.
+ * {@link #consumeLists(BiConsumer)}.
*
* @param consumer Called to accept each preference key value.
* @param consumer Called to accept each preference key list.
*/
- public void consumeSets( final BiConsumer<Key, SetProperty<?>> consumer ) {
- SETS.forEach( consumer );
+ public void consumeLists( final BiConsumer<Key, ListProperty<?>> consumer ) {
+ LISTS.forEach( consumer );
}
public void consumeValueKeys( final Consumer<Key> consumer ) {
VALUES.keySet().forEach( consumer );
}
- public void consumeSetKeys( final Consumer<Key> consumer ) {
- SETS.keySet().forEach( consumer );
+ public void consumeListKeys( final Consumer<Key> consumer ) {
+ LISTS.keySet().forEach( consumer );
}
runLater( () -> {
if( enabled.getAsBoolean() ) {
- fromValues( key ).setValue( n );
+ valuesProperty( key ).setValue( n );
}
} )
src/main/java/com/keenwrite/MainScene.java
package com.keenwrite;
-import com.keenwrite.preferences.Workspace;
+import com.keenwrite.preferences.WorkspacePreferences;
import com.keenwrite.ui.actions.ApplicationActions;
import com.keenwrite.ui.actions.ApplicationMenuBar;
private final Scene mScene;
- public MainScene( final Workspace workspace ) {
- final var mainPane = createMainPane( workspace );
+ public MainScene( final WorkspacePreferences preferences ) {
+ final var mainPane = createMainPane( preferences );
final var actions = createApplicationActions( mainPane );
final var menuBar = createMenuBar( actions );
}
- private MainPane createMainPane( final Workspace workspace ) {
- return new MainPane( workspace );
+ private MainPane createMainPane( final WorkspacePreferences preferences ) {
+ return new MainPane( preferences );
}