Dave Jarvis' Repositories

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

Add log view for message history

AuthorDaveJarvis <email>
Date2021-01-02 15:01:21 GMT-0800
Commitc9dbef776822a58c1429bc5e86855053cfe52b0b
Parentd8c47c0
src/main/java/com/keenwrite/AbstractFileFactory.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite;
src/main/java/com/keenwrite/Bootstrap.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite;
src/main/java/com/keenwrite/Caret.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite;
src/main/java/com/keenwrite/Constants.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite;
src/main/java/com/keenwrite/DefinitionNameInjector.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite;
import com.keenwrite.editors.TextDefinition;
import com.keenwrite.editors.TextEditor;
import com.keenwrite.editors.definition.DefinitionTreeItem;
import com.keenwrite.sigils.SigilOperator;
import static com.keenwrite.Constants.*;
-import static com.keenwrite.StatusBarNotifier.clue;
+import static com.keenwrite.StatusNotifier.clue;
/**
src/main/java/com/keenwrite/ExportFormat.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite;
src/main/java/com/keenwrite/Launcher.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite;
src/main/java/com/keenwrite/MainApp.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite;
src/main/java/com/keenwrite/MainPane.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite;
import static com.keenwrite.ExportFormat.NONE;
import static com.keenwrite.Messages.get;
-import static com.keenwrite.StatusBarNotifier.clue;
+import static com.keenwrite.StatusNotifier.clue;
import static com.keenwrite.io.MediaType.*;
import static com.keenwrite.preferences.Workspace.*;
src/main/java/com/keenwrite/MainScene.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite;
final var menuBar = createMenuBar( actions );
final var appPane = new BorderPane();
- final var statusBar = StatusBarNotifier.getStatusBar();
+ final var statusBar = StatusNotifier.getStatusBar();
final var caretListener = createCaretListener( mainPane );
src/main/java/com/keenwrite/Messages.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite;
src/main/java/com/keenwrite/ScrollEventHandler.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite;
src/main/java/com/keenwrite/Services.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite;
src/main/java/com/keenwrite/StatusBarNotifier.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
-package com.keenwrite;
-
-import com.keenwrite.service.events.Notifier;
-import org.controlsfx.control.StatusBar;
-
-import static com.keenwrite.Constants.STATUS_BAR_OK;
-import static com.keenwrite.Messages.get;
-import static javafx.application.Platform.runLater;
-
-/**
- * Responsible for passing notifications about exceptions (or other error
- * messages) through the application. Once the Event Bus is implemented, this
- * class can go away.
- */
-public class StatusBarNotifier {
- private static final String OK = get( STATUS_BAR_OK, "OK" );
-
- private static final Notifier sNotifier = Services.load( Notifier.class );
- private static final StatusBar sStatusBar = new StatusBar();
-
- /**
- * Resets the status bar to a default message.
- */
- public static void clue() {
- // Don't burden the repaint thread if there's no status bar change.
- if( !OK.equals( sStatusBar.getText() ) ) {
- update( OK );
- }
- }
-
- /**
- * Updates the status bar with a custom message.
- *
- * @param key The resource bundle key associated with a message (typically
- * to inform the user about an error).
- */
- public static void clue( final String key ) {
- update( get( key ) );
- }
-
- /**
- * Updates the status bar with a custom message.
- *
- * @param key The property key having a value to populate with arguments.
- * @param args The placeholder values to substitute into the key's value.
- */
- public static void clue( final String key, final Object... args ) {
- update( get( key, args ) );
- }
-
- /**
- * Called when an exception occurs that warrants the user's attention.
- *
- * @param t The exception with a message that the user should know about.
- */
- public static void clue( final Throwable t ) {
- update( t.getMessage() );
- }
-
- /**
- * Returns the global {@link Notifier} instance that can be used for opening
- * pop-up alert messages.
- *
- * @return The pop-up {@link Notifier} dispatcher.
- */
- public static Notifier getNotifier() {
- return sNotifier;
- }
-
- public static StatusBar getStatusBar() {
- return sStatusBar;
- }
-
- /**
- * Updates the status bar to show the first line of the given message.
- *
- * @param message The message to show in the status bar.
- */
- private static void update( final String message ) {
- runLater(
- () -> {
- final var s = message == null ? "" : message;
- final var i = s.indexOf( '\n' );
- sStatusBar.setText( s.substring( 0, i > 0 ? i : s.length() ) );
- }
- );
- }
-}
src/main/java/com/keenwrite/StatusNotifier.java
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
+package com.keenwrite;
+
+import com.keenwrite.service.events.Notifier;
+import com.keenwrite.ui.logging.LogView;
+import org.controlsfx.control.StatusBar;
+
+import static com.keenwrite.Constants.STATUS_BAR_OK;
+import static com.keenwrite.Messages.get;
+import static javafx.application.Platform.runLater;
+
+/**
+ * Responsible for passing notifications about exceptions (or other error
+ * messages) through the application. Once the Event Bus is implemented, this
+ * class can go away.
+ */
+public class StatusNotifier {
+ private static final String OK = get( STATUS_BAR_OK, "OK" );
+
+ private static final Notifier sNotifier = Services.load( Notifier.class );
+ private static final StatusBar sStatusBar = new StatusBar();
+ private static final LogView sLogView = new LogView();
+
+ /**
+ * Resets the status bar to a default message.
+ */
+ public static void clue() {
+ // Don't burden the repaint thread if there's no status bar change.
+ if( !OK.equals( sStatusBar.getText() ) ) {
+ update( OK );
+ }
+ }
+
+ /**
+ * Updates the status bar with a custom message.
+ *
+ * @param key The property key having a value to populate with arguments.
+ * @param args The placeholder values to substitute into the key's value.
+ */
+ public static void clue( final String key, final Object... args ) {
+ final var message = get( key, args );
+ update( message );
+ sLogView.log( message );
+ }
+
+ /**
+ * Update the status bar with a pre-parsed message and exception.
+ *
+ * @param message The custom message to log.
+ * @param t The exception that triggered the status update.
+ */
+ public static void clue( final String message, final Throwable t ) {
+ update( message );
+ sLogView.log( message, t );
+ }
+
+ /**
+ * Called when an exception occurs that warrants the user's attention.
+ *
+ * @param t The exception with a message that the user should know about.
+ */
+ public static void clue( final Throwable t ) {
+ update( t.getMessage() );
+ sLogView.log( t );
+ }
+
+ /**
+ * Returns the global {@link Notifier} instance that can be used for opening
+ * pop-up alert messages.
+ *
+ * @return The pop-up {@link Notifier} dispatcher.
+ */
+ public static Notifier getNotifier() {
+ return sNotifier;
+ }
+
+ public static StatusBar getStatusBar() {
+ return sStatusBar;
+ }
+
+ /**
+ * Updates the status bar to show the first line of the given message.
+ *
+ * @param message The message to show in the status bar.
+ */
+ private static void update( final String message ) {
+ runLater(
+ () -> {
+ final var s = message == null ? "" : message;
+ final var i = s.indexOf( '\n' );
+ sStatusBar.setText( s.substring( 0, i > 0 ? i : s.length() ) );
+ }
+ );
+ }
+
+ public static void viewIssues() {
+ sLogView.view();
+ }
+}
src/main/java/com/keenwrite/editors/TextDefinition.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.editors;
src/main/java/com/keenwrite/editors/TextEditor.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.editors;
src/main/java/com/keenwrite/editors/TextResource.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.editors;
import static com.keenwrite.Constants.DEFAULT_CHARSET;
-import static com.keenwrite.StatusBarNotifier.clue;
+import static com.keenwrite.StatusNotifier.clue;
import static java.nio.charset.Charset.forName;
import static java.nio.file.Files.readAllBytes;
src/main/java/com/keenwrite/editors/definition/DefinitionEditor.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.editors.definition;
import static com.keenwrite.Constants.DEFINITION_DEFAULT;
import static com.keenwrite.Messages.get;
-import static com.keenwrite.StatusBarNotifier.clue;
+import static com.keenwrite.StatusNotifier.clue;
import static java.lang.String.format;
import static java.util.regex.Pattern.compile;
src/main/java/com/keenwrite/editors/definition/DefinitionTabSceneFactory.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.editors.definition;
src/main/java/com/keenwrite/editors/definition/DefinitionTreeItem.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.editors.definition;
src/main/java/com/keenwrite/editors/definition/FocusAwareTextFieldTreeCell.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.editors.definition;
src/main/java/com/keenwrite/editors/definition/RootTreeItem.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.editors.definition;
src/main/java/com/keenwrite/editors/definition/TreeCellFactory.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.editors.definition;
src/main/java/com/keenwrite/editors/definition/TreeItemMapper.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.editors.definition;
src/main/java/com/keenwrite/editors/definition/TreeTransformer.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.editors.definition;
src/main/java/com/keenwrite/editors/definition/package-info.java
-/* Copyright 2020 White Magic Software, Ltd.
+/* Copyright 2020-2021 White Magic Software, Ltd.
*
* All rights reserved.
src/main/java/com/keenwrite/editors/definition/yaml/YamlParser.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.editors.definition.yaml;
src/main/java/com/keenwrite/editors/definition/yaml/YamlTreeTransformer.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.editors.definition.yaml;
src/main/java/com/keenwrite/editors/definition/yaml/package-info.java
-/* Copyright 2020 White Magic Software, Ltd.
+/* Copyright 2020-2021 White Magic Software, Ltd.
*
* All rights reserved.
src/main/java/com/keenwrite/editors/markdown/HyperlinkModel.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.editors.markdown;
src/main/java/com/keenwrite/editors/markdown/LinkVisitor.java
/*
- * Copyright 2020 White Magic Software, Ltd.
+ * Copyright 2020-2021 White Magic Software, Ltd.
*
* All rights reserved.
public class LinkVisitor {
- private NodeVisitor visitor;
- private Link link;
- private final int offset;
+ private NodeVisitor mVisitor;
+ private Link mLink;
+ private final int mOffset;
/**
* Creates a hyperlink given an offset into a paragraph and the Markdown AST
* link node.
*
* @param index Index into the paragraph that indicates the hyperlink to
* change.
*/
public LinkVisitor( final int index ) {
- this.offset = index;
+ mOffset = index;
}
private synchronized NodeVisitor getVisitor() {
- if( this.visitor == null ) {
- this.visitor = createVisitor();
+ if( mVisitor == null ) {
+ mVisitor = createVisitor();
}
- return this.visitor;
+ return mVisitor;
}
protected NodeVisitor createVisitor() {
return new NodeVisitor(
- new VisitHandler<>( Link.class, LinkVisitor.this::visit ) );
+ new VisitHandler<>( Link.class, LinkVisitor.this::visit ) );
}
private Link getLink() {
- return this.link;
+ return mLink;
}
private void setLink( final Link link ) {
- this.link = link;
+ mLink = link;
}
public int getOffset() {
- return this.offset;
+ return mOffset;
}
}
src/main/java/com/keenwrite/editors/markdown/MarkdownEditor.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.editors.markdown;
import static com.keenwrite.Constants.*;
import static com.keenwrite.Messages.get;
-import static com.keenwrite.StatusBarNotifier.clue;
+import static com.keenwrite.StatusNotifier.clue;
import static com.keenwrite.preferences.Workspace.*;
import static java.lang.Character.isWhitespace;
src/main/java/com/keenwrite/exceptions/MissingFileException.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.exceptions;
src/main/java/com/keenwrite/io/FileType.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.io;
src/main/java/com/keenwrite/io/HttpMediaType.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.io;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
-import static com.keenwrite.StatusBarNotifier.clue;
+import static com.keenwrite.StatusNotifier.clue;
import static com.keenwrite.io.MediaType.UNDEFINED;
import static java.net.http.HttpClient.Redirect.NORMAL;
src/main/java/com/keenwrite/io/MediaType.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.io;
src/main/java/com/keenwrite/io/MediaTypeExtensions.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.io;
src/main/java/com/keenwrite/predicates/PredicateFactory.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.predicates;
src/main/java/com/keenwrite/preferences/FileProperty.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.preferences;
src/main/java/com/keenwrite/preferences/Key.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.preferences;
src/main/java/com/keenwrite/preferences/LocaleProperty.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.preferences;
src/main/java/com/keenwrite/preferences/LocaleScripts.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.preferences;
src/main/java/com/keenwrite/preferences/PreferencesController.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.preferences;
src/main/java/com/keenwrite/preferences/SimpleFontControl.java
import static com.keenwrite.Constants.ICON_DIALOG;
-import static com.keenwrite.StatusBarNotifier.clue;
+import static com.keenwrite.StatusNotifier.clue;
import static java.lang.System.currentTimeMillis;
import static javafx.geometry.Pos.CENTER_LEFT;
src/main/java/com/keenwrite/preferences/Workspace.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.preferences;
import static com.keenwrite.Constants.*;
import static com.keenwrite.Launcher.getVersion;
-import static com.keenwrite.StatusBarNotifier.clue;
+import static com.keenwrite.StatusNotifier.clue;
import static com.keenwrite.preferences.Key.key;
import static java.util.Map.entry;
src/main/java/com/keenwrite/preferences/XmlStorageHandler.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.preferences;
src/main/java/com/keenwrite/preview/ChainedReplacedElementFactory.java
/* Copyright 2006 Patrick Wright
* Copyright 2007 Wisconsin Court System
- * Copyright 2020 White Magic Software, Ltd.
+ * Copyright 2020-2021 White Magic Software, Ltd.
*
* This program is free software; you can redistribute it and/or
src/main/java/com/keenwrite/preview/DomConverter.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.preview;
import java.util.Map;
-import static com.keenwrite.StatusBarNotifier.clue;
+import static com.keenwrite.StatusNotifier.clue;
import static com.keenwrite.processors.text.TextReplacementFactory.replace;
src/main/java/com/keenwrite/preview/HtmlPanel.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.preview;
import java.net.URI;
-import static com.keenwrite.StatusBarNotifier.clue;
+import static com.keenwrite.StatusNotifier.clue;
import static com.keenwrite.util.ProtocolScheme.getProtocol;
import static java.awt.Desktop.Action.BROWSE;
src/main/java/com/keenwrite/preview/HtmlPreview.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.preview;
src/main/java/com/keenwrite/preview/MathRenderer.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.preview;
import com.whitemagicsoftware.tex.*;
import com.whitemagicsoftware.tex.graphics.SvgDomGraphics2D;
import org.w3c.dom.Document;
import java.util.function.Supplier;
-import static com.keenwrite.StatusBarNotifier.clue;
+import static com.keenwrite.StatusNotifier.clue;
/**
src/main/java/com/keenwrite/preview/RenderingSettings.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.preview;
src/main/java/com/keenwrite/preview/SvgRasterizer.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.preview;
import java.text.NumberFormat;
-import static com.keenwrite.StatusBarNotifier.clue;
+import static com.keenwrite.StatusNotifier.clue;
import static com.keenwrite.preview.RenderingSettings.RENDERING_HINTS;
import static java.awt.image.BufferedImage.TYPE_INT_RGB;
src/main/java/com/keenwrite/preview/SvgReplacedElementFactory.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.preview;
import java.nio.file.Paths;
-import static com.keenwrite.StatusBarNotifier.clue;
+import static com.keenwrite.StatusNotifier.clue;
import static com.keenwrite.io.MediaType.*;
import static com.keenwrite.preview.MathRenderer.MATH_RENDERER;
src/main/java/com/keenwrite/processors/DefinitionProcessor.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.processors;
src/main/java/com/keenwrite/processors/ExecutorProcessor.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.processors;
src/main/java/com/keenwrite/processors/HtmlPreviewProcessor.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.processors;
src/main/java/com/keenwrite/processors/IdentityProcessor.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.processors;
src/main/java/com/keenwrite/processors/InlineRProcessor.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.processors;
import static com.keenwrite.Constants.STATUS_PARSE_ERROR;
-import static com.keenwrite.StatusBarNotifier.clue;
+import static com.keenwrite.Messages.get;
+import static com.keenwrite.StatusNotifier.clue;
import static com.keenwrite.preferences.Workspace.*;
import static com.keenwrite.processors.text.TextReplacementFactory.replace;
return ENGINE.eval( r ).toString();
} catch( final Exception ex ) {
- final var expr = r.substring( 0, min( r.length(), 30 ) );
- clue( "Main.status.error.r", expr, ex.getMessage() );
+ final var expr = r.substring( 0, min( r.length(), 50 ) );
+ clue( get( "Main.status.error.r", expr, ex.getMessage() ), ex );
return "";
}
src/main/java/com/keenwrite/processors/PreformattedProcessor.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.processors;
src/main/java/com/keenwrite/processors/Processor.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.processors;
src/main/java/com/keenwrite/processors/ProcessorContext.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.processors;
src/main/java/com/keenwrite/processors/ProcessorFactory.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.processors;
src/main/java/com/keenwrite/processors/RVariableProcessor.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.processors;
src/main/java/com/keenwrite/processors/XmlProcessor.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.processors;
src/main/java/com/keenwrite/processors/markdown/MarkdownProcessor.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.processors.markdown;
src/main/java/com/keenwrite/processors/markdown/extensions/FencedBlockExtension.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.processors.markdown.extensions;
import java.util.zip.Deflater;
-import static com.keenwrite.StatusBarNotifier.clue;
+import static com.keenwrite.StatusNotifier.clue;
import static com.keenwrite.processors.IdentityProcessor.IDENTITY;
import static com.vladsch.flexmark.html.HtmlRenderer.Builder;
src/main/java/com/keenwrite/processors/markdown/extensions/HtmlRendererAdapter.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.processors.markdown.extensions;
src/main/java/com/keenwrite/processors/markdown/extensions/ImageLinkExtension.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.processors.markdown.extensions;
import java.nio.file.Paths;
-import static com.keenwrite.StatusBarNotifier.clue;
+import static com.keenwrite.StatusNotifier.clue;
import static com.keenwrite.preferences.Workspace.KEY_IMAGES_DIR;
import static com.keenwrite.preferences.Workspace.KEY_IMAGES_ORDER;
src/main/java/com/keenwrite/processors/markdown/extensions/caret/CaretExtension.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.processors.markdown.extensions.caret;
src/main/java/com/keenwrite/processors/markdown/extensions/r/RExtension.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.processors.markdown.extensions.r;
src/main/java/com/keenwrite/processors/markdown/extensions/r/ROutputProcessor.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.processors.markdown.extensions.r;
src/main/java/com/keenwrite/processors/markdown/extensions/tex/TeXExtension.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.processors.markdown.extensions.tex;
src/main/java/com/keenwrite/processors/markdown/extensions/tex/TeXInlineDelimiterProcessor.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.processors.markdown.extensions.tex;
src/main/java/com/keenwrite/processors/markdown/extensions/tex/TexNode.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.processors.markdown.extensions.tex;
src/main/java/com/keenwrite/processors/markdown/extensions/tex/TexNodeRenderer.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.processors.markdown.extensions.tex;
src/main/java/com/keenwrite/processors/text/AbstractTextReplacer.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.processors.text;
src/main/java/com/keenwrite/processors/text/AhoCorasickReplacer.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.processors.text;
src/main/java/com/keenwrite/processors/text/StringUtilsReplacer.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.processors.text;
src/main/java/com/keenwrite/processors/text/TextReplacementFactory.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.processors.text;
src/main/java/com/keenwrite/processors/text/TextReplacer.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.processors.text;
src/main/java/com/keenwrite/search/SearchModel.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.search;
src/main/java/com/keenwrite/service/Service.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.service;
src/main/java/com/keenwrite/service/Settings.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.service;
src/main/java/com/keenwrite/service/Snitch.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.service;
src/main/java/com/keenwrite/service/events/Notification.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.service.events;
src/main/java/com/keenwrite/service/events/Notifier.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.service.events;
src/main/java/com/keenwrite/service/events/impl/ButtonOrderPane.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.service.events.impl;
import javafx.scene.Node;
import javafx.scene.control.ButtonBar;
import javafx.scene.control.DialogPane;
+import javafx.stage.Stage;
+import static com.keenwrite.Constants.ICON_DIALOG;
import static com.keenwrite.Constants.sSettings;
import static javafx.scene.control.ButtonBar.BUTTON_ORDER_WINDOWS;
/**
* Ensures a consistent button order for alert dialogs across platforms (because
* the default button order on Linux defies all logic).
*/
public class ButtonOrderPane extends DialogPane {
+ public ButtonOrderPane() {
+ ((Stage) getScene().getWindow()).getIcons().add( ICON_DIALOG );
+ }
@Override
protected Node createButtonBar() {
final var node = (ButtonBar) super.createButtonBar();
node.setButtonOrder( getButtonOrder() );
return node;
}
private String getButtonOrder() {
- return getSetting( "dialog.alert.button.order.windows",
- BUTTON_ORDER_WINDOWS );
- }
-
- @SuppressWarnings("SameParameterValue")
- private String getSetting( final String key, final String defaultValue ) {
- return sSettings.getSetting( key, defaultValue );
+ return sSettings.getSetting(
+ "dialog.alert.button.order.windows", BUTTON_ORDER_WINDOWS );
}
}
src/main/java/com/keenwrite/service/events/impl/DefaultNotification.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.service.events.impl;
src/main/java/com/keenwrite/service/events/impl/DefaultNotifier.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.service.events.impl;
import java.nio.file.Path;
+import static com.keenwrite.Constants.ICON_DIALOG_NODE;
import static com.keenwrite.Messages.get;
import static javafx.scene.control.Alert.AlertType.CONFIRMATION;
alert.setContentText( message.getContent() );
alert.initOwner( parent );
+ alert.setGraphic( ICON_DIALOG_NODE );
return alert;
src/main/java/com/keenwrite/service/impl/DefaultSettings.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.service.impl;
src/main/java/com/keenwrite/service/impl/DefaultSnitch.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.service.impl;
import static com.keenwrite.Constants.APP_WATCHDOG_TIMEOUT;
-import static com.keenwrite.StatusBarNotifier.clue;
+import static com.keenwrite.StatusNotifier.clue;
import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY;
src/main/java/com/keenwrite/sigils/RSigilOperator.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.sigils;
src/main/java/com/keenwrite/sigils/SigilOperator.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.sigils;
src/main/java/com/keenwrite/sigils/Tokens.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.sigils;
src/main/java/com/keenwrite/sigils/YamlSigilOperator.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.sigils;
src/main/java/com/keenwrite/spelling/api/SpellCheckListener.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.spelling.api;
src/main/java/com/keenwrite/spelling/api/SpellChecker.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.spelling.api;
src/main/java/com/keenwrite/spelling/api/package-info.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved.
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
src/main/java/com/keenwrite/spelling/impl/PermissiveSpeller.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.spelling.impl;
src/main/java/com/keenwrite/spelling/impl/SymSpellSpeller.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.spelling.impl;
import static com.keenwrite.Constants.LEXICONS_DIRECTORY;
-import static com.keenwrite.StatusBarNotifier.clue;
+import static com.keenwrite.StatusNotifier.clue;
import static io.gitlab.rxp90.jsymspell.SymSpell.Verbosity;
import static io.gitlab.rxp90.jsymspell.SymSpell.Verbosity.ALL;
src/main/java/com/keenwrite/spelling/impl/TextEditorSpeller.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.spelling.impl;
src/main/java/com/keenwrite/spelling/impl/package-info.java
-/* Copyright 2020 White Magic Software, Ltd.
+/* Copyright 2020-2021 White Magic Software, Ltd.
*
* All rights reserved.
src/main/java/com/keenwrite/ui/actions/Action.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.ui.actions;
src/main/java/com/keenwrite/ui/actions/ApplicationActions.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
-package com.keenwrite.ui.actions;
-
-import com.keenwrite.ExportFormat;
-import com.keenwrite.MainPane;
-import com.keenwrite.editors.TextDefinition;
-import com.keenwrite.editors.TextEditor;
-import com.keenwrite.editors.markdown.HyperlinkModel;
-import com.keenwrite.editors.markdown.LinkVisitor;
-import com.keenwrite.preferences.PreferencesController;
-import com.keenwrite.preferences.Workspace;
-import com.keenwrite.processors.markdown.MarkdownProcessor;
-import com.keenwrite.search.SearchModel;
-import com.keenwrite.ui.controls.SearchBar;
-import com.keenwrite.ui.dialogs.ImageDialog;
-import com.keenwrite.ui.dialogs.LinkDialog;
-import com.vladsch.flexmark.ast.Link;
-import javafx.scene.control.Alert;
-import javafx.scene.control.Dialog;
-import javafx.stage.Window;
-import javafx.stage.WindowEvent;
-
-import static com.keenwrite.Bootstrap.APP_TITLE;
-import static com.keenwrite.Constants.ICON_DIALOG_NODE;
-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.Workspace.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 main = getMainPane();
- final var context = main.createProcessorContext();
- final var chain = createProcessors( context );
- final var editor = main.getActiveTextEditor();
- 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( 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 );
- }
- } );
- }
-
- 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() {
- new PreferencesController( getWorkspace() ).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() {
- insertObject( createLinkDialog() );
- }
-
- public void insert‿image() {
- insertObject( createImageDialog() );
- }
-
- private void insertObject( final Dialog<String> dialog ) {
- final var textArea = getActiveTextEditor().getTextArea();
- dialog.showAndWait().ifPresent( textArea::replaceSelection );
- }
-
- private Dialog<String> createLinkDialog() {
- return new LinkDialog( getWindow(), createHyperlinkModel() );
- }
-
- private Dialog<String> createImageDialog() {
- final var path = getActiveTextEditor().getPath();
- final var parentDir = path.getParent();
- return new ImageDialog( getWindow(), parentDir );
- }
-
- /**
- * Returns one of: selected text, word under cursor, or parsed hyperlink from
- * the Markdown AST.
- *
- * @return An instance containing the link URL and display text.
- */
- private HyperlinkModel createHyperlinkModel() {
- final var context = getMainPane().createProcessorContext();
- final var editor = getActiveTextEditor();
- final var textArea = editor.getTextArea();
- final var selectedText = textArea.getSelectedText();
-
- // Convert current paragraph to Markdown nodes.
- final var mp = MarkdownProcessor.create( context );
- final var p = textArea.getCurrentParagraph();
- final var paragraph = textArea.getText( p );
- final var node = mp.toNode( paragraph );
- final var visitor = new LinkVisitor( textArea.getCaretColumn() );
- final var link = visitor.process( node );
-
- if( link != null ) {
- textArea.selectRange( p, link.getStartOffset(), p, link.getEndOffset() );
- }
-
- return createHyperlinkModel( link, selectedText );
- }
-
- private HyperlinkModel createHyperlinkModel(
- final Link link, final String selection ) {
-
- return link == null
- ? new HyperlinkModel( selection, "https://localhost" )
- : new HyperlinkModel( link );
- }
-
- 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() {
- getMainPane().viewRefresh();
- }
-
- public void view‿preview() {
- getMainPane().viewPreview();
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
+package com.keenwrite.ui.actions;
+
+import com.keenwrite.ExportFormat;
+import com.keenwrite.MainPane;
+import com.keenwrite.StatusNotifier;
+import com.keenwrite.editors.TextDefinition;
+import com.keenwrite.editors.TextEditor;
+import com.keenwrite.editors.markdown.HyperlinkModel;
+import com.keenwrite.editors.markdown.LinkVisitor;
+import com.keenwrite.preferences.PreferencesController;
+import com.keenwrite.preferences.Workspace;
+import com.keenwrite.processors.markdown.MarkdownProcessor;
+import com.keenwrite.search.SearchModel;
+import com.keenwrite.ui.controls.SearchBar;
+import com.keenwrite.ui.dialogs.ImageDialog;
+import com.keenwrite.ui.dialogs.LinkDialog;
+import com.vladsch.flexmark.ast.Link;
+import javafx.scene.control.Alert;
+import javafx.scene.control.Dialog;
+import javafx.stage.Window;
+import javafx.stage.WindowEvent;
+
+import static com.keenwrite.Bootstrap.APP_TITLE;
+import static com.keenwrite.Constants.ICON_DIALOG_NODE;
+import static com.keenwrite.ExportFormat.*;
+import static com.keenwrite.Messages.get;
+import static com.keenwrite.StatusNotifier.clue;
+import static com.keenwrite.StatusNotifier.getStatusBar;
+import static com.keenwrite.preferences.Workspace.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 main = getMainPane();
+ final var context = main.createProcessorContext();
+ final var chain = createProcessors( context );
+ final var editor = main.getActiveTextEditor();
+ 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( filename );
+
+ file.ifPresent( ( f ) -> {
+ try {
+ writeString( f.toPath(), export );
+ final var m = get( "Main.status.export.success", f.toString() );
+ clue( m );
+ } catch( final Exception ex ) {
+ clue( ex );
+ }
+ } );
+ }
+
+ 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() {
+ new PreferencesController( getWorkspace() ).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() {
+ insertObject( createLinkDialog() );
+ }
+
+ public void insert‿image() {
+ insertObject( createImageDialog() );
+ }
+
+ private void insertObject( final Dialog<String> dialog ) {
+ final var textArea = getActiveTextEditor().getTextArea();
+ dialog.showAndWait().ifPresent( textArea::replaceSelection );
+ }
+
+ private Dialog<String> createLinkDialog() {
+ return new LinkDialog( getWindow(), createHyperlinkModel() );
+ }
+
+ private Dialog<String> createImageDialog() {
+ final var path = getActiveTextEditor().getPath();
+ final var parentDir = path.getParent();
+ return new ImageDialog( getWindow(), parentDir );
+ }
+
+ /**
+ * Returns one of: selected text, word under cursor, or parsed hyperlink from
+ * the Markdown AST.
+ *
+ * @return An instance containing the link URL and display text.
+ */
+ private HyperlinkModel createHyperlinkModel() {
+ final var context = getMainPane().createProcessorContext();
+ final var editor = getActiveTextEditor();
+ final var textArea = editor.getTextArea();
+ final var selectedText = textArea.getSelectedText();
+
+ // Convert current paragraph to Markdown nodes.
+ final var mp = MarkdownProcessor.create( context );
+ final var p = textArea.getCurrentParagraph();
+ final var paragraph = textArea.getText( p );
+ final var node = mp.toNode( paragraph );
+ final var visitor = new LinkVisitor( textArea.getCaretColumn() );
+ final var link = visitor.process( node );
+
+ if( link != null ) {
+ textArea.selectRange( p, link.getStartOffset(), p, link.getEndOffset() );
+ }
+
+ return createHyperlinkModel( link, selectedText );
+ }
+
+ private HyperlinkModel createHyperlinkModel(
+ final Link link, final String selection ) {
+
+ return link == null
+ ? new HyperlinkModel( selection, "https://localhost" )
+ : new HyperlinkModel( link );
+ }
+
+ 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() {
+ getMainPane().viewRefresh();
+ }
+
+ public void view‿preview() {
+ getMainPane().viewPreview();
+ }
+
+ public void view‿issues() {
+ StatusNotifier.viewIssues();
}
src/main/java/com/keenwrite/ui/actions/ApplicationMenuBar.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.ui.actions;
addAction( "view.refresh", e -> actions.view‿refresh() ),
SEPARATOR_ACTION,
- addAction( "view.preview", e -> actions.view‿preview() )
+ addAction( "view.preview", e -> actions.view‿preview() ),
+ addAction( "view.issues", e -> actions.view‿issues() )
),
createMenu(
src/main/java/com/keenwrite/ui/actions/FileChooserCommand.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.ui.actions;
src/main/java/com/keenwrite/ui/actions/MenuAction.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.ui.actions;
src/main/java/com/keenwrite/ui/actions/SeparatorAction.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.ui.actions;
src/main/java/com/keenwrite/ui/actions/package-info.java
-/* Copyright 2020 White Magic Software, Ltd.
+/* Copyright 2020-2021 White Magic Software, Ltd.
*
* All rights reserved.
src/main/java/com/keenwrite/ui/adapters/DocumentAdapter.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.ui.adapters;
import org.xhtmlrenderer.event.DocumentListener;
-import static com.keenwrite.StatusBarNotifier.clue;
+import static com.keenwrite.StatusNotifier.clue;
/**
src/main/java/com/keenwrite/ui/adapters/ReplacedElementAdapter.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.ui.adapters;
src/main/java/com/keenwrite/ui/controls/SearchBar.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.ui.controls;
src/main/java/com/keenwrite/ui/logging/LogView.java
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
+package com.keenwrite.ui.logging;
+
+import javafx.beans.property.SimpleStringProperty;
+import javafx.beans.property.StringProperty;
+import javafx.collections.ObservableList;
+import javafx.scene.control.Alert;
+import javafx.scene.control.TableColumn;
+import javafx.scene.control.TableView;
+import javafx.scene.input.ClipboardContent;
+import javafx.scene.input.KeyCodeCombination;
+import javafx.stage.Stage;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.time.LocalDateTime;
+import java.util.TreeSet;
+
+import static com.keenwrite.Constants.ICON_DIALOG;
+import static com.keenwrite.Messages.get;
+import static java.time.LocalDateTime.now;
+import static java.time.format.DateTimeFormatter.ofPattern;
+import static javafx.collections.FXCollections.observableArrayList;
+import static javafx.scene.control.Alert.AlertType.INFORMATION;
+import static javafx.scene.control.SelectionMode.MULTIPLE;
+import static javafx.scene.input.Clipboard.getSystemClipboard;
+import static javafx.scene.input.KeyCode.C;
+import static javafx.scene.input.KeyCode.INSERT;
+import static javafx.scene.input.KeyCombination.CONTROL_ANY;
+import static javafx.stage.Modality.NONE;
+
+/**
+ * Responsible for logging application issues to {@link TableView} entries.
+ */
+public class LogView extends Alert {
+ /**
+ * Number of error messages to retain in the {@link TableView}, must be
+ * greater than zero.
+ */
+ private static final int CACHE_SIZE = 150;
+
+ private final ObservableList<LogEntry> mEntries = observableArrayList();
+ private final TableView<LogEntry> mTable = new TableView<>( mEntries );
+
+ public LogView() {
+ super( INFORMATION );
+ setTitle( get( "App.action.view.issues.text" ) );
+ initModality( NONE );
+ initTableView();
+ setResizable( true );
+ }
+
+ /**
+ * Brings the dialog to the foreground, showing it if needed.
+ */
+ public void view() {
+ super.show();
+ getStage().toFront();
+ }
+
+ public void log( final String message ) {
+ log( new LogEntry( message ) );
+ }
+
+ public void log( final Throwable error ) {
+ log( new LogEntry( error ) );
+ }
+
+ public void log( final String message, final Throwable trace ) {
+ log( new LogEntry( message, trace ) );
+ }
+
+ private void log( final LogEntry logEntry ) {
+ mEntries.add( logEntry );
+
+ while( mEntries.size() > CACHE_SIZE ) {
+ mEntries.remove( 0 );
+ }
+
+ mTable.scrollTo( logEntry );
+ }
+
+ private void initTableView() {
+ final var ctrlC = new KeyCodeCombination( C, CONTROL_ANY );
+ final var ctrlInsert = new KeyCodeCombination( INSERT, CONTROL_ANY );
+
+ final var colDate = new TableColumn<LogEntry, String>( "Date" );
+ final var colMessage = new TableColumn<LogEntry, String>( "Message" );
+ final var colTrace = new TableColumn<LogEntry, String>( "Trace" );
+
+ colDate.setCellValueFactory( log -> log.getValue().dateProperty() );
+ colMessage.setCellValueFactory( log -> log.getValue().messageProperty() );
+ colTrace.setCellValueFactory( log -> log.getValue().traceProperty() );
+
+ final var columns = mTable.getColumns();
+ columns.add( colDate );
+ columns.add( colMessage );
+ columns.add( colTrace );
+
+ mTable.setMaxWidth( Double.MAX_VALUE );
+ mTable.setPrefWidth( 1024 );
+ mTable.getSelectionModel().setSelectionMode( MULTIPLE);
+ mTable.setOnKeyPressed( event -> {
+ if( ctrlC.match( event ) || ctrlInsert.match( event ) ) {
+ copyToClipboard( mTable );
+ }
+ } );
+
+ final var pane = getDialogPane();
+ pane.setContent( mTable );
+
+ final var stage = getStage();
+ stage.getIcons().add( ICON_DIALOG );
+ }
+
+ private Stage getStage() {
+ return (Stage) getDialogPane().getScene().getWindow();
+ }
+
+ private static final class LogEntry {
+ private final StringProperty mDate;
+ private final StringProperty mMessage;
+ private final StringProperty mTrace;
+
+ /**
+ * Constructs a new {@link LogEntry} for the current time, and having
+ * no associated stack trace.
+ *
+ * @param message The error message.
+ */
+ public LogEntry( final String message ) {
+ this( message, null );
+ }
+
+ /**
+ * Constructs a new {@link LogEntry} for the current time, and using
+ * the given error's message.
+ *
+ * @param error The stack trace, must not be {@code null}.
+ */
+ public LogEntry( final Throwable error ) {
+ this( error.getMessage(), error );
+ }
+
+ /**
+ * Constructs a new {@link LogEntry} with the current date and time.
+ *
+ * @param message The error message.
+ * @param trace The stack trace associated with the message, may be
+ * {@code null}.
+ */
+ public LogEntry( final String message, final Throwable trace ) {
+ mDate = new SimpleStringProperty( toString( now() ) );
+ mMessage = new SimpleStringProperty( message );
+ mTrace = new SimpleStringProperty( toString( trace ) );
+ }
+
+ private StringProperty messageProperty() {return mMessage;}
+
+ private StringProperty dateProperty() { return mDate;}
+
+ private StringProperty traceProperty() { return mTrace;}
+
+ private String toString( final LocalDateTime date ) {
+ return date.format( ofPattern( "d MMM u HH:mm:ss" ) );
+ }
+
+ private String toString( final Throwable trace ) {
+ try( final StringWriter sw = new StringWriter();
+ final PrintWriter pw = new PrintWriter( sw ) ) {
+ if( trace != null ) {
+ trace.printStackTrace( pw );
+ }
+ return sw.toString();
+ } catch( final Exception ex ) {
+ return "";
+ }
+ }
+ }
+
+ public void copyToClipboard( final TableView<?> table ) {
+ final var sb = new StringBuilder();
+ final var rows = new TreeSet<Integer>();
+ boolean firstRow = true;
+
+ for( final var position : table.getSelectionModel().getSelectedCells() ) {
+ rows.add( position.getRow() );
+ }
+
+ for( final var row : rows ) {
+ if( !firstRow ) {
+ sb.append( '\n' );
+ }
+ firstRow = false;
+ boolean firstCol = true;
+ for( final var column : table.getColumns() ) {
+ if( !firstCol ) {
+ sb.append( '\t' );
+ }
+ firstCol = false;
+ final var data = column.getCellData( row );
+ sb.append( data == null ? "" : data.toString() );
+ }
+ }
+
+ final var contents = new ClipboardContent();
+ contents.putString( sb.toString() );
+ getSystemClipboard().setContent( contents );
+ }
+}
src/main/java/com/keenwrite/util/BoundedCache.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.util;
src/main/java/com/keenwrite/util/CyclicIterator.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.util;
src/main/java/com/keenwrite/util/FontLoader.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.util;
import static com.keenwrite.Constants.FONT_DIRECTORY;
-import static com.keenwrite.StatusBarNotifier.clue;
+import static com.keenwrite.StatusNotifier.clue;
import static com.keenwrite.util.ProtocolScheme.valueFrom;
import static com.keenwrite.util.ResourceWalker.GLOB_FONTS;
src/main/java/com/keenwrite/util/GenericBuilder.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.util;
src/main/java/com/keenwrite/util/ProtocolScheme.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.util;
src/main/java/com/keenwrite/util/ResourceWalker.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.util;
src/main/resources/com/keenwrite/messages.properties
App.action.view.refresh.text=Refresh
+App.action.view.issues.description=Open document issues
+App.action.view.issues.accelerator=F6
+App.action.view.issues.text=Issues
+
App.action.view.preview.description=Open document preview
App.action.view.preview.accelerator=F7
App.action.view.preview.text=Preview
App.action.view.outline.description=Open document outline
App.action.view.outline.accelerator=F8
App.action.view.outline.text=Outline
-
App.action.view.files.description=Open file system browser
src/test/java/com/keenwrite/definition/TreeViewTest.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.definition;
src/test/java/com/keenwrite/io/MediaTypeTest.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.io;
src/test/java/com/keenwrite/processors/markdown/ImageLinkExtensionTest.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.processors.markdown;
src/test/java/com/keenwrite/r/PluralizeTest.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.r;
src/test/java/com/keenwrite/tex/TeXRasterization.java
/*
- * Copyright 2020 White Magic Software, Ltd.
+ * Copyright 2020-2021 White Magic Software, Ltd.
*
* All rights reserved.
src/test/java/com/keenwrite/util/CyclicIteratorTest.java
-/* Copyright 2020 White Magic Software, Ltd. -- All rights reserved. */
+/* Copyright 2020-2021 White Magic Software, Ltd. -- All rights reserved. */
package com.keenwrite.util;
Delta841 lines added, 609 lines removed, 232-line increase