Dave Jarvis' Repositories

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

Updated source code comments.

Authordjarvis <email>
Date2018-11-07 21:09:49 GMT-0800
Commit01e29751bb446e94ea19675a053c64880af89cf7
Parent0ca55bd
.idea/codeStyles/codeStyleConfig.xml
-
+<component name="ProjectCodeStyleConfiguration">
+ <state>
+ <option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
+ </state>
+</component>
.idea/gradle.xml
-
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="GradleSettings">
+ <option name="linkedExternalProjectsSettings">
+ <GradleProjectSettings>
+ <option name="distributionType" value="LOCAL" />
+ <option name="externalProjectPath" value="$PROJECT_DIR$" />
+ <option name="gradleHome" value="/opt/gradle" />
+ <option name="gradleJvm" value="#JAVA_HOME" />
+ <option name="modules">
+ <set>
+ <option value="$PROJECT_DIR$" />
+ </set>
+ </option>
+ </GradleProjectSettings>
+ </option>
+ </component>
+</project>
.idea/misc.xml
-
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="ExternalStorageConfigurationManager" enabled="true" />
+ <component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="JDK1.8" project-jdk-type="JavaSDK">
+ <output url="file://$PROJECT_DIR$/out" />
+ </component>
+</project>
.idea/vcs.xml
-
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="VcsDirectoryMappings">
+ <mapping directory="$PROJECT_DIR$" vcs="Git" />
+ </component>
+</project>
.idea/workspace.xml
-
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="ChangeListManager">
+ <list default="true" id="3dcf7c8f-87b5-4d25-a804-39da40a621b8" name="Default Changelist" comment="">
+ <change afterPath="$PROJECT_DIR$/.idea/codeStyles/codeStyleConfig.xml" afterDir="false" />
+ <change afterPath="$PROJECT_DIR$/.idea/vcs.xml" afterDir="false" />
+ <change beforePath="$PROJECT_DIR$/README.md" beforeDir="false" afterPath="$PROJECT_DIR$/README.md" afterDir="false" />
+ <change beforePath="$PROJECT_DIR$/build.gradle" beforeDir="false" afterPath="$PROJECT_DIR$/build.gradle" afterDir="false" />
+ <change beforePath="$PROJECT_DIR$/executable.txt" beforeDir="false" />
+ <change beforePath="$PROJECT_DIR$/gradle.properties" beforeDir="false" afterPath="$PROJECT_DIR$/gradle.properties" afterDir="false" />
+ <change beforePath="$PROJECT_DIR$/libs/renjin-script-engine-0.9.2592-jar-with-dependencies.jar" beforeDir="false" afterPath="$PROJECT_DIR$/libs/renjin-script-engine-0.9.2707-jar-with-dependencies.jar" afterDir="false" />
+ <change beforePath="$PROJECT_DIR$/licenses/MARKDOWN-WRITER-FX" beforeDir="false" afterPath="$PROJECT_DIR$/licenses/MARKDOWN-WRITER-FX.md" afterDir="false" />
+ <change beforePath="$PROJECT_DIR$/src/main/java/com/scrivenvar/AbstractFileFactory.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/com/scrivenvar/AbstractFileFactory.java" afterDir="false" />
+ <change beforePath="$PROJECT_DIR$/src/main/java/com/scrivenvar/AbstractPane.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/com/scrivenvar/AbstractPane.java" afterDir="false" />
+ <change beforePath="$PROJECT_DIR$/src/main/java/com/scrivenvar/Constants.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/com/scrivenvar/Constants.java" afterDir="false" />
+ <change beforePath="$PROJECT_DIR$/src/main/java/com/scrivenvar/FileEditorTab.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/com/scrivenvar/FileEditorTab.java" afterDir="false" />
+ <change beforePath="$PROJECT_DIR$/src/main/java/com/scrivenvar/FileEditorTabPane.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/com/scrivenvar/FileEditorTabPane.java" afterDir="false" />
+ <change beforePath="$PROJECT_DIR$/src/main/java/com/scrivenvar/FileType.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/com/scrivenvar/FileType.java" afterDir="false" />
+ <change beforePath="$PROJECT_DIR$/src/main/java/com/scrivenvar/Main.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/com/scrivenvar/Main.java" afterDir="false" />
+ <change beforePath="$PROJECT_DIR$/src/main/java/com/scrivenvar/processors/IdentityProcessor.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/com/scrivenvar/processors/IdentityProcessor.java" afterDir="false" />
+ <change beforePath="$PROJECT_DIR$/src/main/java/com/scrivenvar/processors/InlineRProcessor.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/com/scrivenvar/processors/InlineRProcessor.java" afterDir="false" />
+ <change beforePath="$PROJECT_DIR$/src/main/java/com/scrivenvar/service/Options.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/com/scrivenvar/service/Options.java" afterDir="false" />
+ <change beforePath="$PROJECT_DIR$/src/main/java/com/scrivenvar/service/Settings.java" beforeDir="false" afterPath="$PROJECT_DIR$/src/main/java/com/scrivenvar/service/Settings.java" afterDir="false" />
+ </list>
+ <ignored path="$PROJECT_DIR$/.gradle/" />
+ <ignored path="$PROJECT_DIR$/build/" />
+ <ignored path="$PROJECT_DIR$/out/" />
+ <option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
+ <option name="SHOW_DIALOG" value="false" />
+ <option name="HIGHLIGHT_CONFLICTS" value="true" />
+ <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
+ <option name="LAST_RESOLUTION" value="IGNORE" />
+ </component>
+ <component name="ExternalProjectsData">
+ <projectState path="$PROJECT_DIR$">
+ <ProjectState />
+ </projectState>
+ </component>
+ <component name="ExternalProjectsManager">
+ <system id="GRADLE">
+ <state>
+ <task path="$PROJECT_DIR$">
+ <activation />
+ </task>
+ <projects_view />
+ </state>
+ </system>
+ </component>
+ <component name="FUSProjectUsageTrigger">
+ <session id="332180848">
+ <usages-collector id="statistics.lifecycle.project">
+ <counts>
+ <entry key="project.open.time.2" value="1" />
+ <entry key="project.opened" value="1" />
+ </counts>
+ </usages-collector>
+ <usages-collector id="statistics.file.extensions.open">
+ <counts>
+ <entry key="java" value="17" />
+ </counts>
+ </usages-collector>
+ <usages-collector id="statistics.file.types.open">
+ <counts>
+ <entry key="JAVA" value="17" />
+ </counts>
+ </usages-collector>
+ <usages-collector id="statistics.file.extensions.edit">
+ <counts>
+ <entry key="java" value="1995" />
+ <entry key="txt" value="19" />
+ </counts>
+ </usages-collector>
+ <usages-collector id="statistics.file.types.edit">
+ <counts>
+ <entry key="JAVA" value="1995" />
+ <entry key="PLAIN_TEXT" value="19" />
+ </counts>
+ </usages-collector>
+ </session>
+ </component>
+ <component name="FileEditorManager">
+ <leaf>
+ <file pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/main/java/com/scrivenvar/processors/AbstractProcessor.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state relative-caret-position="180">
+ <caret line="38" column="22" selection-start-line="38" selection-start-column="22" selection-end-line="38" selection-end-column="22" />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/main/java/com/scrivenvar/processors/CaretInsertionProcessor.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state relative-caret-position="-135">
+ <caret line="41" column="22" selection-start-line="41" selection-start-column="22" selection-end-line="41" selection-end-column="22" />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/main/java/com/scrivenvar/processors/CaretReplacementProcessor.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state relative-caret-position="165">
+ <caret line="38" column="13" selection-start-line="38" selection-start-column="13" selection-end-line="38" selection-end-column="13" />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/main/java/com/scrivenvar/processors/DefaultVariableProcessor.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state relative-caret-position="-101">
+ <caret line="38" column="13" selection-start-line="38" selection-start-column="13" selection-end-line="38" selection-end-column="13" />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/main/java/com/scrivenvar/processors/HTMLPreviewProcessor.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state relative-caret-position="439">
+ <caret line="71" lean-forward="true" selection-start-line="71" selection-end-line="71" />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file pinned="false" current-in-tab="false">
+ <entry file="file://$PROJECT_DIR$/src/main/java/com/scrivenvar/processors/MarkdownCaretInsertionProcessor.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state relative-caret-position="150">
+ <caret line="38" column="13" selection-start-line="38" selection-start-column="13" selection-end-line="38" selection-end-column="13" />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ <file pinned="false" current-in-tab="true">
+ <entry file="file://$PROJECT_DIR$/src/main/java/com/scrivenvar/processors/InlineRProcessor.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state relative-caret-position="300">
+ <caret line="104" selection-start-line="104" selection-end-line="104" />
+ </state>
+ </provider>
+ </entry>
+ </file>
+ </leaf>
+ </component>
+ <component name="Git.Settings">
+ <option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
+ </component>
+ <component name="GradleLocalSettings">
+ <option name="myGradleHomes">
+ <map>
+ <entry key="$PROJECT_DIR$" value="/opt/gradle-4.10.2" />
+ </map>
+ </option>
+ <option name="myGradleVersions">
+ <map>
+ <entry key="$PROJECT_DIR$" value="4.10.2" />
+ </map>
+ </option>
+ <option name="availableProjects">
+ <map>
+ <entry>
+ <key>
+ <ExternalProjectPojo>
+ <option name="name" value="scrivenvar" />
+ <option name="path" value="$PROJECT_DIR$" />
+ </ExternalProjectPojo>
+ </key>
+ <value>
+ <list>
+ <ExternalProjectPojo>
+ <option name="name" value="scrivenvar" />
+ <option name="path" value="$PROJECT_DIR$" />
+ </ExternalProjectPojo>
+ </list>
+ </value>
+ </entry>
+ </map>
+ </option>
+ <option name="availableTasks">
+ <map>
+ <entry key="$PROJECT_DIR$">
+ <value>
+ <list>
+ <ExternalTaskPojo>
+ <option name="description" value="Displays the components produced by root project 'scrivenvar'. [incubating]" />
+ <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+ <option name="name" value="components" />
+ </ExternalTaskPojo>
+ <ExternalTaskPojo>
+ <option name="description" value="Assembles and tests this project and all projects that depend on it." />
+ <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+ <option name="name" value="buildDependents" />
+ </ExternalTaskPojo>
+ <ExternalTaskPojo>
+ <option name="description" value="Displays the sub-projects of root project 'scrivenvar'." />
+ <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+ <option name="name" value="projects" />
+ </ExternalTaskPojo>
+ <ExternalTaskPojo>
+ <option name="description" value="Assembles main classes." />
+ <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+ <option name="name" value="classes" />
+ </ExternalTaskPojo>
+ <ExternalTaskPojo>
+ <option name="description" value="Displays the dependent components of components in root project 'scrivenvar'. [incubating]" />
+ <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+ <option name="name" value="dependentComponents" />
+ </ExternalTaskPojo>
+ <ExternalTaskPojo>
+ <option name="description" value="Displays all buildscript dependencies declared in root project 'scrivenvar'." />
+ <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+ <option name="name" value="buildEnvironment" />
+ </ExternalTaskPojo>
+ <ExternalTaskPojo>
+ <option name="description" value="Runs this project as a JVM application" />
+ <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+ <option name="name" value="run" />
+ </ExternalTaskPojo>
+ <ExternalTaskPojo>
+ <option name="description" value="Generates Gradle wrapper files." />
+ <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+ <option name="name" value="wrapper" />
+ </ExternalTaskPojo>
+ <ExternalTaskPojo>
+ <option name="description" value="Assembles test classes." />
+ <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+ <option name="name" value="testClasses" />
+ </ExternalTaskPojo>
+ <ExternalTaskPojo>
+ <option name="description" value="Generates Javadoc API documentation for the main source code." />
+ <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+ <option name="name" value="javadoc" />
+ </ExternalTaskPojo>
+ <ExternalTaskPojo>
+ <option name="description" value="Creates OS specific scripts to run the project as a JVM application." />
+ <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+ <option name="name" value="startScripts" />
+ </ExternalTaskPojo>
+ <ExternalTaskPojo>
+ <option name="description" value="Assembles a jar archive containing the main classes." />
+ <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+ <option name="name" value="jar" />
+ </ExternalTaskPojo>
+ <ExternalTaskPojo>
+ <option name="description" value="Displays the configuration model of root project 'scrivenvar'. [incubating]" />
+ <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+ <option name="name" value="model" />
+ </ExternalTaskPojo>
+ <ExternalTaskPojo>
+ <option name="description" value="Installs the project as a distribution as-is." />
+ <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+ <option name="name" value="installDist" />
+ </ExternalTaskPojo>
+ <ExternalTaskPojo>
+ <option name="description" value="Processes main resources." />
+ <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+ <option name="name" value="processResources" />
+ </ExternalTaskPojo>
+ <ExternalTaskPojo>
+ <option name="description" value="Displays the tasks runnable from root project 'scrivenvar'." />
+ <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+ <option name="name" value="tasks" />
+ </ExternalTaskPojo>
+ <ExternalTaskPojo>
+ <option name="description" value="Assembles the main distributions" />
+ <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+ <option name="name" value="assembleDist" />
+ </ExternalTaskPojo>
+ <ExternalTaskPojo>
+ <option name="description" value="Initializes a new Gradle build." />
+ <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+ <option name="name" value="init" />
+ </ExternalTaskPojo>
+ <ExternalTaskPojo>
+ <option name="description" value="Runs the unit tests." />
+ <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+ <option name="name" value="test" />
+ </ExternalTaskPojo>
+ <ExternalTaskPojo>
+ <option name="description" value="Compiles main Java source." />
+ <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+ <option name="name" value="compileJava" />
+ </ExternalTaskPojo>
+ <ExternalTaskPojo>
+ <option name="description" value="Displays the insight into a specific dependency in root project 'scrivenvar'." />
+ <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+ <option name="name" value="dependencyInsight" />
+ </ExternalTaskPojo>
+ <ExternalTaskPojo>
+ <option name="description" value="Runs all checks." />
+ <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+ <option name="name" value="check" />
+ </ExternalTaskPojo>
+ <ExternalTaskPojo>
+ <option name="description" value="Assembles the outputs of this project." />
+ <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+ <option name="name" value="assemble" />
+ </ExternalTaskPojo>
+ <ExternalTaskPojo>
+ <option name="description" value="Deletes the build directory." />
+ <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+ <option name="name" value="clean" />
+ </ExternalTaskPojo>
+ <ExternalTaskPojo>
+ <option name="description" value="Compiles test Java source." />
+ <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+ <option name="name" value="compileTestJava" />
+ </ExternalTaskPojo>
+ <ExternalTaskPojo>
+ <option name="description" value="Displays all dependencies declared in root project 'scrivenvar'." />
+ <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+ <option name="name" value="dependencies" />
+ </ExternalTaskPojo>
+ <ExternalTaskPojo>
+ <option name="description" value="Processes test resources." />
+ <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+ <option name="name" value="processTestResources" />
+ </ExternalTaskPojo>
+ <ExternalTaskPojo>
+ <option name="description" value="Displays a help message." />
+ <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+ <option name="name" value="help" />
+ </ExternalTaskPojo>
+ <ExternalTaskPojo>
+ <option name="description" value="Assembles and tests this project." />
+ <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+ <option name="name" value="build" />
+ </ExternalTaskPojo>
+ <ExternalTaskPojo>
+ <option name="description" value="Assembles and tests this project and all projects it depends on." />
+ <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+ <option name="name" value="buildNeeded" />
+ </ExternalTaskPojo>
+ <ExternalTaskPojo>
+ <option name="description" value="Bundles the project as a distribution." />
+ <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+ <option name="name" value="distTar" />
+ </ExternalTaskPojo>
+ <ExternalTaskPojo>
+ <option name="description" value="Bundles the project as a distribution." />
+ <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+ <option name="name" value="distZip" />
+ </ExternalTaskPojo>
+ <ExternalTaskPojo>
+ <option name="description" value="Displays the properties of root project 'scrivenvar'." />
+ <option name="linkedExternalProjectPath" value="$PROJECT_DIR$" />
+ <option name="name" value="properties" />
+ </ExternalTaskPojo>
+ </list>
+ </value>
+ </entry>
+ </map>
+ </option>
+ <option name="modificationStamps">
+ <map>
+ <entry key="$PROJECT_DIR$" value="6106128056000" />
+ <entry key="$PROJECT_DIR$/.gradle" value="0" />
+ <entry key="$PROJECT_DIR$/build.gradle" value="3956035851" />
+ <entry key="$PROJECT_DIR$/gradle.properties" value="4254081835" />
+ <entry key="$PROJECT_DIR$/settings.gradle" value="0" />
+ </map>
+ </option>
+ <option name="projectBuildClasspath">
+ <map>
+ <entry key="$PROJECT_DIR$">
+ <value>
+ <ExternalProjectBuildClasspathPojo>
+ <option name="modulesBuildClasspath">
+ <map>
+ <entry key="$PROJECT_DIR$">
+ <value>
+ <ExternalModuleBuildClasspathPojo>
+ <option name="path" value="$PROJECT_DIR$" />
+ </ExternalModuleBuildClasspathPojo>
+ </value>
+ </entry>
+ </map>
+ </option>
+ <option name="name" value="scrivenvar" />
+ <option name="projectBuildClasspath">
+ <list>
+ <option value="/opt/gradle/lib/gradle-api-metadata-4.10.2.jar" />
+ <option value="/opt/gradle/lib/gradle-wrapper-4.10.2.jar" />
+ <option value="/opt/gradle/lib/gradle-docs-4.10.2.jar" />
+ <option value="/opt/gradle/lib/gradle-kotlin-dsl-1.0-rc-6.jar" />
+ <option value="/opt/gradle/lib/gradle-kotlin-dsl-tooling-models-1.0-rc-6.jar" />
+ <option value="/opt/gradle/lib/gradle-core-4.10.2.jar" />
+ <option value="/opt/gradle/lib/ant-1.9.11.jar" />
+ <option value="/opt/gradle/lib/gradle-base-services-4.10.2.jar" />
+ <option value="/opt/gradle/lib/ant-launcher-1.9.11.jar" />
+ <option value="/opt/gradle/lib/groovy-all-2.4.15.jar" />
+ <option value="/opt/gradle/lib/gradle-core-api-4.10.2.jar" />
+ <option value="/opt/gradle/lib/gradle-runtime-api-info-4.10.2.jar" />
+ <option value="/opt/gradle/lib/gradle-build-option-4.10.2.jar" />
+ <option value="/opt/gradle/lib/gradle-base-services-groovy-4.10.2.jar" />
+ <option value="/opt/gradle/lib/gradle-persistent-cache-4.10.2.jar" />
+ <option value="/opt/gradle/lib/gradle-launcher-4.10.2.jar" />
+ <option value="/opt/gradle/lib/gradle-installation-beacon-4.10.2.jar" />
+ <option value="/opt/gradle/lib/gradle-cli-4.10.2.jar" />
+ <option value="/opt/gradle/lib/gradle-model-core-4.10.2.jar" />
+ <option value="/opt/gradle/lib/gradle-kotlin-dsl-tooling-builders-1.0-rc-6.jar" />
+ <option value="/opt/gradle/lib/gradle-native-4.10.2.jar" />
+ <option value="/opt/gradle/lib/gradle-tooling-api-4.10.2.jar" />
+ <option value="/opt/gradle/lib/gradle-build-cache-4.10.2.jar" />
+ <option value="/opt/gradle/lib/gradle-process-services-4.10.2.jar" />
+ <option value="/opt/gradle/lib/gradle-kotlin-dsl-provider-plugins-1.0-rc-6.jar" />
+ <option value="/opt/gradle/lib/gradle-resources-4.10.2.jar" />
+ <option value="/opt/gradle/lib/gradle-messaging-4.10.2.jar" />
+ <option value="/opt/gradle/lib/gradle-model-groovy-4.10.2.jar" />
+ <option value="/opt/gradle/lib/gradle-logging-4.10.2.jar" />
+ <option value="/opt/gradle/lib/gradle-jvm-services-4.10.2.jar" />
+ <option value="/opt/gradle/lib/plugins/gradle-testing-junit-platform-4.10.2.jar" />
+ <option value="/opt/gradle/lib/plugins/gradle-osgi-4.10.2.jar" />
+ <option value="/opt/gradle/lib/plugins/gradle-plugins-4.10.2.jar" />
+ <option value="/opt/gradle/lib/plugins/gradle-version-control-4.10.2.jar" />
+ <option value="/opt/gradle/lib/plugins/gradle-test-kit-4.10.2.jar" />
+ <option value="/opt/gradle/lib/plugins/gradle-diagnostics-4.10.2.jar" />
+ <option value="/opt/gradle/lib/plugins/gradle-resources-s3-4.10.2.jar" />
+ <option value="/opt/gradle/lib/plugins/gradle-composite-builds-4.10.2.jar" />
+ <option value="/opt/gradle/lib/plugins/gradle-language-scala-4.10.2.jar" />
+ <option value="/opt/gradle/lib/plugins/gradle-signing-4.10.2.jar" />
+ <option value="/opt/gradle/lib/plugins/gradle-plugin-use-4.10.2.jar" />
+ <option value="/opt/gradle/lib/plugins/ivy-2.2.0.jar" />
+ <option value="/opt/gradle/lib/plugins/gradle-code-quality-4.10.2.jar" />
+ <option value="/opt/gradle/lib/plugins/gradle-publish-4.10.2.jar" />
+ <option value="/opt/gradle/lib/plugins/gradle-platform-base-4.10.2.jar" />
+ <option value="/opt/gradle/lib/plugins/gradle-ivy-4.10.2.jar" />
+ <option value="/opt/gradle/lib/plugins/gradle-testing-native-4.10.2.jar" />
+ <option value="/opt/gradle/lib/plugins/gradle-language-java-4.10.2.jar" />
+ <option value="/opt/gradle/lib/plugins/gradle-ide-native-4.10.2.jar" />
+ <option value="/opt/gradle/lib/plugins/gradle-plugin-development-4.10.2.jar" />
+ <option value="/opt/gradle/lib/plugins/gradle-language-native-4.10.2.jar" />
+ <option value="/opt/gradle/lib/plugins/gradle-ear-4.10.2.jar" />
+ <option value="/opt/gradle/lib/plugins/gradle-resources-sftp-4.10.2.jar" />
+ <option value="/opt/gradle/lib/plugins/gradle-scala-4.10.2.jar" />
+ <option value="/opt/gradle/lib/plugins/gradle-testing-jvm-4.10.2.jar" />
+ <option value="/opt/gradle/lib/plugins/gradle-jacoco-4.10.2.jar" />
+ <option value="/opt/gradle/lib/plugins/gradle-antlr-4.10.2.jar" />
+ <option value="/opt/gradle/lib/plugins/gradle-dependency-management-4.10.2.jar" />
+ <option value="/opt/gradle/lib/plugins/gradle-tooling-native-4.10.2.jar" />
+ <option value="/opt/gradle/lib/plugins/gradle-tooling-api-builders-4.10.2.jar" />
+ <option value="/opt/gradle/lib/plugins/gradle-reporting-4.10.2.jar" />
+ <option value="/opt/gradle/lib/plugins/gradle-workers-4.10.2.jar" />
+ <option value="/opt/gradle/lib/plugins/gradle-resources-http-4.10.2.jar" />
+ <option value="/opt/gradle/lib/plugins/gradle-platform-native-4.10.2.jar" />
+ <option value="/opt/gradle/lib/plugins/gradle-resources-gcs-4.10.2.jar" />
+ <option value="/opt/gradle/lib/plugins/gradle-build-comparison-4.10.2.jar" />
+ <option value="/opt/gradle/lib/plugins/gradle-build-init-4.10.2.jar" />
+ <option value="/opt/gradle/lib/plugins/gradle-platform-jvm-4.10.2.jar" />
+ <option value="/opt/gradle/lib/plugins/gradle-testing-base-4.10.2.jar" />
+ <option value="/opt/gradle/lib/plugins/gradle-ide-4.10.2.jar" />
+ <option value="/opt/gradle/lib/plugins/gradle-ide-play-4.10.2.jar" />
+ <option value="/opt/gradle/lib/plugins/gradle-maven-4.10.2.jar" />
+ <option value="/opt/gradle/lib/plugins/gradle-build-cache-http-4.10.2.jar" />
+ <option value="/opt/gradle/lib/plugins/gradle-javascript-4.10.2.jar" />
+ <option value="/opt/gradle/lib/plugins/gradle-announce-4.10.2.jar" />
+ <option value="/opt/gradle/lib/plugins/gradle-language-groovy-4.10.2.jar" />
+ <option value="/opt/gradle/lib/plugins/gradle-platform-play-4.10.2.jar" />
+ <option value="/opt/gradle/lib/plugins/gradle-language-jvm-4.10.2.jar" />
+ </list>
+ </option>
+ </ExternalProjectBuildClasspathPojo>
+ </value>
+ </entry>
+ </map>
+ </option>
+ <option name="projectSyncType">
+ <map>
+ <entry key="$PROJECT_DIR$" value="RE_IMPORT" />
+ </map>
+ </option>
+ </component>
+ <component name="IdeDocumentHistory">
+ <option name="CHANGED_PATHS">
+ <list>
+ <option value="$PROJECT_DIR$/src/main/java/com/scrivenvar/AbstractFileFactory.java" />
+ <option value="$PROJECT_DIR$/src/main/java/com/scrivenvar/AbstractPane.java" />
+ <option value="$PROJECT_DIR$/src/main/java/com/scrivenvar/service/Options.java" />
+ <option value="$PROJECT_DIR$/src/main/java/com/scrivenvar/Constants.java" />
+ <option value="$PROJECT_DIR$/src/main/java/com/scrivenvar/FileEditorTabPane.java" />
+ <option value="$PROJECT_DIR$/src/main/java/com/scrivenvar/FileType.java" />
+ <option value="$PROJECT_DIR$/src/main/java/com/scrivenvar/Main.java" />
+ <option value="$PROJECT_DIR$/src/main/java/com/scrivenvar/processors/IdentityProcessor.java" />
+ <option value="$PROJECT_DIR$/src/main/java/com/scrivenvar/processors/InlineRProcessor.java" />
+ </list>
+ </option>
+ </component>
+ <component name="ProjectFrameBounds">
+ <option name="x" value="238" />
+ <option name="y" value="312" />
+ <option name="width" value="1685" />
+ <option name="height" value="1141" />
+ </component>
+ <component name="ProjectLevelVcsManager" settingsEditedManually="true" />
+ <component name="ProjectView">
+ <navigator proportions="" version="1">
+ <foldersAlwaysOnTop value="true" />
+ </navigator>
+ <panes>
+ <pane id="PackagesPane" />
+ <pane id="Scope" />
+ <pane id="ProjectPane">
+ <subPane>
+ <expand>
+ <path>
+ <item name="scrivenvar" type="b2602c69:ProjectViewProjectNode" />
+ <item name="scrivenvar" type="8a07ba80:GradleTreeStructureProvider$GradleModuleDirectoryNode" />
+ </path>
+ <path>
+ <item name="scrivenvar" type="b2602c69:ProjectViewProjectNode" />
+ <item name="scrivenvar" type="8a07ba80:GradleTreeStructureProvider$GradleModuleDirectoryNode" />
+ <item name="src" type="462c0819:PsiDirectoryNode" />
+ </path>
+ <path>
+ <item name="scrivenvar" type="b2602c69:ProjectViewProjectNode" />
+ <item name="scrivenvar" type="8a07ba80:GradleTreeStructureProvider$GradleModuleDirectoryNode" />
+ <item name="src" type="462c0819:PsiDirectoryNode" />
+ <item name="main" type="8a07ba80:GradleTreeStructureProvider$GradleModuleDirectoryNode" />
+ </path>
+ <path>
+ <item name="scrivenvar" type="b2602c69:ProjectViewProjectNode" />
+ <item name="scrivenvar" type="8a07ba80:GradleTreeStructureProvider$GradleModuleDirectoryNode" />
+ <item name="src" type="462c0819:PsiDirectoryNode" />
+ <item name="main" type="8a07ba80:GradleTreeStructureProvider$GradleModuleDirectoryNode" />
+ <item name="java" type="462c0819:PsiDirectoryNode" />
+ </path>
+ <path>
+ <item name="scrivenvar" type="b2602c69:ProjectViewProjectNode" />
+ <item name="scrivenvar" type="8a07ba80:GradleTreeStructureProvider$GradleModuleDirectoryNode" />
+ <item name="src" type="462c0819:PsiDirectoryNode" />
+ <item name="main" type="8a07ba80:GradleTreeStructureProvider$GradleModuleDirectoryNode" />
+ <item name="java" type="462c0819:PsiDirectoryNode" />
+ <item name="scrivenvar" type="462c0819:PsiDirectoryNode" />
+ </path>
+ <path>
+ <item name="scrivenvar" type="b2602c69:ProjectViewProjectNode" />
+ <item name="scrivenvar" type="8a07ba80:GradleTreeStructureProvider$GradleModuleDirectoryNode" />
+ <item name="src" type="462c0819:PsiDirectoryNode" />
+ <item name="main" type="8a07ba80:GradleTreeStructureProvider$GradleModuleDirectoryNode" />
+ <item name="java" type="462c0819:PsiDirectoryNode" />
+ <item name="scrivenvar" type="462c0819:PsiDirectoryNode" />
+ <item name="processors" type="462c0819:PsiDirectoryNode" />
+ </path>
+ </expand>
+ <select />
+ </subPane>
+ </pane>
+ </panes>
+ </component>
+ <component name="PropertiesComponent">
+ <property name="com.android.tools.idea.instantapp.provision.ProvisionBeforeRunTaskProvider.myTimeStamp" value="1541653415064" />
+ <property name="settings.editor.selected.configurable" value="preferences.sourceCode.Java" />
+ </component>
+ <component name="RunDashboard">
+ <option name="ruleStates">
+ <list>
+ <RuleState>
+ <option name="name" value="ConfigurationTypeDashboardGroupingRule" />
+ </RuleState>
+ <RuleState>
+ <option name="name" value="StatusDashboardGroupingRule" />
+ </RuleState>
+ </list>
+ </option>
+ </component>
+ <component name="RunManager">
+ <configuration name="Scrivenvar" type="GradleRunConfiguration" factoryName="Gradle">
+ <ExternalSystemSettings>
+ <option name="executionName" />
+ <option name="externalProjectPath" value="$PROJECT_DIR$" />
+ <option name="externalSystemIdString" value="GRADLE" />
+ <option name="scriptParameters" value="" />
+ <option name="taskDescriptions">
+ <list />
+ </option>
+ <option name="taskNames">
+ <list>
+ <option value="run" />
+ </list>
+ </option>
+ <option name="vmOptions" value="" />
+ </ExternalSystemSettings>
+ <method v="2" />
+ </configuration>
+ <configuration default="true" type="GradleRunConfiguration" factoryName="Gradle">
+ <ExternalSystemSettings>
+ <option name="executionName" />
+ <option name="externalProjectPath" value="" />
+ <option name="externalSystemIdString" value="GRADLE" />
+ <option name="scriptParameters" value="" />
+ <option name="taskDescriptions">
+ <list />
+ </option>
+ <option name="taskNames">
+ <list />
+ </option>
+ <option name="vmOptions" value="" />
+ </ExternalSystemSettings>
+ <method v="2" />
+ </configuration>
+ </component>
+ <component name="SvnConfiguration">
+ <configuration />
+ </component>
+ <component name="TaskManager">
+ <task active="true" id="Default" summary="Default task">
+ <changelist id="3dcf7c8f-87b5-4d25-a804-39da40a621b8" name="Default Changelist" comment="" />
+ <created>1541651873782</created>
+ <option name="number" value="Default" />
+ <option name="presentableId" value="Default" />
+ <updated>1541651873782</updated>
+ </task>
+ <servers />
+ </component>
+ <component name="ToolWindowManager">
+ <frame x="238" y="312" width="1685" height="1141" extended-state="0" />
+ <editor active="true" />
+ <layout>
+ <window_info id="Image Layers" />
+ <window_info id="Designer" />
+ <window_info id="UI Designer" />
+ <window_info id="Capture Tool" />
+ <window_info id="Favorites" side_tool="true" />
+ <window_info active="true" content_ui="combo" id="Project" order="0" visible="true" weight="0.20626152" />
+ <window_info id="Structure" order="1" side_tool="true" weight="0.25" />
+ <window_info anchor="bottom" id="Version Control" show_stripe_button="false" />
+ <window_info anchor="bottom" id="Terminal" />
+ <window_info anchor="bottom" id="Event Log" side_tool="true" />
+ <window_info anchor="bottom" id="Build" weight="0.2127451" />
+ <window_info anchor="bottom" id="Message" order="0" />
+ <window_info anchor="bottom" id="Find" order="1" />
+ <window_info anchor="bottom" id="Run" order="2" visible="true" weight="0.32941177" />
+ <window_info anchor="bottom" id="Debug" order="3" weight="0.4" />
+ <window_info anchor="bottom" id="Cvs" order="4" weight="0.25" />
+ <window_info anchor="bottom" id="Inspection" order="5" weight="0.4" />
+ <window_info anchor="bottom" id="TODO" order="6" />
+ <window_info anchor="right" id="Palette" />
+ <window_info anchor="right" id="Gradle" />
+ <window_info anchor="right" id="Theme Preview" />
+ <window_info anchor="right" id="Capture Analysis" />
+ <window_info anchor="right" id="Palette&#9;" />
+ <window_info anchor="right" id="Maven Projects" />
+ <window_info anchor="right" id="Commander" internal_type="SLIDING" order="0" type="SLIDING" weight="0.4" />
+ <window_info anchor="right" id="Ant Build" order="1" weight="0.25" />
+ <window_info anchor="right" content_ui="combo" id="Hierarchy" order="2" weight="0.25" />
+ </layout>
+ </component>
+ <component name="VcsContentAnnotationSettings">
+ <option name="myLimit" value="2678400000" />
+ </component>
+ <component name="editorHistoryManager">
+ <entry file="file://$PROJECT_DIR$/src/main/java/com/scrivenvar/AbstractFileFactory.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state relative-caret-position="350">
+ <caret line="101" column="6" lean-forward="true" selection-start-line="101" selection-start-column="6" selection-end-line="101" selection-end-column="6" />
+ </state>
+ </provider>
+ </entry>
+ <entry file="jar:///opt/jdk/src.zip!/java/util/prefs/Preferences.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state relative-caret-position="2775">
+ <caret line="223" column="22" selection-start-line="223" selection-start-column="22" selection-end-line="223" selection-end-column="22" />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/main/java/com/scrivenvar/AbstractPane.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state>
+ <folding>
+ <element signature="e#1865#1866#0" expanded="true" />
+ <element signature="e#1894#1895#0" expanded="true" />
+ <element signature="e#2106#2107#0" expanded="true" />
+ <element signature="e#2146#2147#0" expanded="true" />
+ </folding>
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/main/java/com/scrivenvar/service/Options.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state relative-caret-position="90">
+ <caret line="33" selection-start-line="33" selection-end-line="33" />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/main/java/com/scrivenvar/FileType.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state relative-caret-position="558">
+ <caret line="95" column="33" selection-start-line="95" selection-start-column="33" selection-end-line="95" selection-end-column="33" />
+ <folding>
+ <element signature="e#1987#1988#0" expanded="true" />
+ <element signature="e#2013#2014#0" expanded="true" />
+ </folding>
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/main/java/com/scrivenvar/FileEditorTabPane.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state relative-caret-position="483">
+ <caret line="637" column="3" lean-forward="true" selection-start-line="637" selection-start-column="3" selection-end-line="637" selection-end-column="3" />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/main/java/com/scrivenvar/Constants.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state relative-caret-position="240">
+ <caret line="44" column="5" lean-forward="true" selection-start-line="44" selection-start-column="5" selection-end-line="44" selection-end-column="5" />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/main/java/com/scrivenvar/MainWindow.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state relative-caret-position="150">
+ <caret line="98" column="13" selection-start-line="98" selection-start-column="13" selection-end-line="98" selection-end-column="13" />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/main/java/com/scrivenvar/Main.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state relative-caret-position="195">
+ <caret line="50" column="26" lean-forward="true" selection-start-line="50" selection-start-column="26" selection-end-line="50" selection-end-column="26" />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/main/java/com/scrivenvar/processors/AbstractProcessor.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state relative-caret-position="180">
+ <caret line="38" column="22" selection-start-line="38" selection-start-column="22" selection-end-line="38" selection-end-column="22" />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/main/java/com/scrivenvar/processors/CaretInsertionProcessor.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state relative-caret-position="-135">
+ <caret line="41" column="22" selection-start-line="41" selection-start-column="22" selection-end-line="41" selection-end-column="22" />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/main/java/com/scrivenvar/processors/CaretReplacementProcessor.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state relative-caret-position="165">
+ <caret line="38" column="13" selection-start-line="38" selection-start-column="13" selection-end-line="38" selection-end-column="13" />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/main/java/com/scrivenvar/processors/DefaultVariableProcessor.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state relative-caret-position="-101">
+ <caret line="38" column="13" selection-start-line="38" selection-start-column="13" selection-end-line="38" selection-end-column="13" />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/main/java/com/scrivenvar/processors/MarkdownCaretInsertionProcessor.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state relative-caret-position="150">
+ <caret line="38" column="13" selection-start-line="38" selection-start-column="13" selection-end-line="38" selection-end-column="13" />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/main/java/com/scrivenvar/processors/IdentityProcessor.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state relative-caret-position="210">
+ <caret line="40" column="76" lean-forward="true" selection-start-line="40" selection-start-column="76" selection-end-line="40" selection-end-column="76" />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/main/java/com/scrivenvar/processors/HTMLPreviewProcessor.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state relative-caret-position="439">
+ <caret line="71" lean-forward="true" selection-start-line="71" selection-end-line="71" />
+ </state>
+ </provider>
+ </entry>
+ <entry file="file://$PROJECT_DIR$/src/main/java/com/scrivenvar/processors/InlineRProcessor.java">
+ <provider selected="true" editor-type-id="text-editor">
+ <state relative-caret-position="300">
+ <caret line="104" selection-start-line="104" selection-end-line="104" />
+ </state>
+ </provider>
+ </entry>
+ </component>
+ <component name="masterDetails">
+ <states>
+ <state key="ProjectJDKs.UI">
+ <settings>
+ <last-edited>JDK1.8</last-edited>
+ <splitter-proportions>
+ <option name="proportions">
+ <list>
+ <option value="0.2" />
+ </list>
+ </option>
+ </splitter-proportions>
+ </settings>
+ </state>
+ </states>
+ </component>
+</project>
README.md
* [Java 8u40](http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html) (or newer)
-* [Gradle 4.4.1](https://gradle.org/) (or newer)
+* [Gradle 4.4.1](https://gradle.org/)
Quick Start
build.gradle
compile 'com.googlecode.juniversalchardet:juniversalchardet:1.0.3'
compile 'org.apache.commons:commons-configuration2:2.2'
- compile files('libs/renjin-script-engine-0.9.2592-jar-with-dependencies.jar')
+ compile files('libs/renjin-script-engine-0.9.2707-jar-with-dependencies.jar')
}
-version = '1.3.6'
+version = '1.3.7'
applicationName = 'scrivenvar'
mainClassName = 'com.scrivenvar.Main'
baseName = applicationName
contents {
- from { ['LICENSE', 'README.md'] }
+ from { ['LICENSE.md', 'README.md'] }
into( 'images' ) {
from { 'images' }
executable.txt
-https://github.com/bmuschko/gradle-izpack-plugin
- http://izpack.org/
-
-https://github.com/TheBoegl/gradle-launch4j
- http://launch4j.sourceforge.net/
-
-https://github.com/FibreFoX/javafx-gradle-plugin
- https://docs.oracle.com/javase/8/docs/technotes/guides/deploy/self-contained-packaging.html#A1324980
-
-http://www.jwrapper.com/java-to-exe-free.html
-
-https://github.com/libgdx/packr
-
-
gradle.properties
+org.gradle.jvmargs=-Xmx1G -XX:MaxPermSize=512m
+
libs/renjin-script-engine-0.9.2592-jar-with-dependencies.jar
Binary files differ
libs/renjin-script-engine-0.9.2707-jar-with-dependencies.jar
Binary files differ
licenses/MARKDOWN-WRITER-FX
-Copyright (c) 2015 Karl Tauber <karl at jformdesigner dot com>
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-* Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
-* Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
licenses/MARKDOWN-WRITER-FX.md
+Copyright (c) 2015 Karl Tauber <karl@jformdesigner.com>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+* Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
src/main/java/com/scrivenvar/AbstractFileFactory.java
* Return the singleton Settings instance.
*
- * @return The settings for
+ * @return A non-null instance.
*/
private Settings getSettings() {
src/main/java/com/scrivenvar/AbstractPane.java
import com.scrivenvar.service.Options;
+
import java.util.prefs.Preferences;
+
import org.tbee.javafx.scene.layout.fxml.MigPane;
/**
* Provides options to all subclasses.
*
* @author White Magic Software, Ltd.
*/
public abstract class AbstractPane extends MigPane {
+ /**
+ * The options loaded from the service.
+ */
private final Options options = Services.load( Options.class );
+ /**
+ * Returns the persistent options for user settings.
+ *
+ * @return A non-null instance.
+ */
protected Options getOptions() {
return this.options;
}
-
+
+ /**
+ * Returns a hierarchical set of preferences.
+ *
+ * @return A non-null instance.
+ */
protected Preferences getState() {
return getOptions().getState();
src/main/java/com/scrivenvar/Constants.java
import com.scrivenvar.service.Settings;
+
import java.util.Collection;
/**
+ * Defines application-wide default values.
+ *
* @author White Magic Software, Ltd.
*/
public static final String APP_TITLE = get( "application.title" );
public static final String APP_BUNDLE_NAME = get( "application.messages" );
+
// Prevent double events when updating files on Linux (save and timestamp).
public static final int APP_WATCHDOG_TIMEOUT = get( "application.watchdog.timeout", 100 );
// Takes two parameters: line number and column number.
public static final String STATUS_BAR_LINE = "Main.statusbar.line";
+
// "OK" text
public static final String STATUS_BAR_DEFAULT = get( "Main.statusbar.state.default" );
public static final String STATUS_PARSE_ERROR = "Main.statusbar.parse.error";
- // Persistent storage settings.
-
/**
* Location of the definition source file.
*/
public static final String PERSIST_DEFINITION_SOURCE = "definitionSource";
-
-
+
/**
* Content of the R startup script.
src/main/java/com/scrivenvar/FileEditorTab.java
public final class FileEditorTab extends Tab {
+ /**
+ *
+ */
private final Notifier alertService = Services.load( Notifier.class );
private EditorPane editorPane;
src/main/java/com/scrivenvar/FileEditorTabPane.java
import static com.scrivenvar.FileType.*;
import static com.scrivenvar.Messages.get;
-import com.scrivenvar.predicates.files.FileTypePredicate;
-import com.scrivenvar.service.Options;
-import com.scrivenvar.service.Settings;
-import com.scrivenvar.service.events.Notification;
-import com.scrivenvar.service.events.Notifier;
-import static com.scrivenvar.service.events.Notifier.NO;
-import static com.scrivenvar.service.events.Notifier.YES;
-import com.scrivenvar.util.Utils;
-import java.io.File;
-import java.nio.file.Path;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.function.Consumer;
-import java.util.prefs.Preferences;
-import java.util.stream.Collectors;
-import javafx.beans.property.ReadOnlyBooleanProperty;
-import javafx.beans.property.ReadOnlyBooleanWrapper;
-import javafx.beans.property.ReadOnlyObjectProperty;
-import javafx.beans.property.ReadOnlyObjectWrapper;
-import javafx.beans.value.ChangeListener;
-import javafx.beans.value.ObservableValue;
-import javafx.collections.ListChangeListener;
-import javafx.collections.ObservableList;
-import javafx.event.Event;
-import javafx.scene.Node;
-import javafx.scene.control.Alert;
-import javafx.scene.control.ButtonType;
-import javafx.scene.control.Tab;
-import javafx.scene.control.TabPane;
-import javafx.scene.control.TabPane.TabClosingPolicy;
-import javafx.scene.input.InputEvent;
-import javafx.stage.FileChooser;
-import javafx.stage.FileChooser.ExtensionFilter;
-import javafx.stage.Window;
-import org.fxmisc.richtext.StyledTextArea;
-import org.fxmisc.wellbehaved.event.EventPattern;
-import org.fxmisc.wellbehaved.event.InputMap;
-
-/**
- * Tab pane for file editors.
- *
- * @author Karl Tauber and White Magic Software, Ltd.
- */
-public final class FileEditorTabPane extends TabPane {
-
- private final static String FILTER_EXTENSION_TITLES = "Dialog.file.choose.filter";
-
- private final Options options = Services.load( Options.class );
- private final Settings settings = Services.load( Settings.class );
- private final Notifier notifyService = Services.load( Notifier.class );
-
- private final ReadOnlyObjectWrapper<Path> openDefinition = new ReadOnlyObjectWrapper<>();
- private final ReadOnlyObjectWrapper<FileEditorTab> activeFileEditor = new ReadOnlyObjectWrapper<>();
- private final ReadOnlyBooleanWrapper anyFileEditorModified = new ReadOnlyBooleanWrapper();
-
- /**
- * Constructs a new file editor tab pane.
- */
- public FileEditorTabPane() {
- final ObservableList<Tab> tabs = getTabs();
-
- setFocusTraversable( false );
- setTabClosingPolicy( TabClosingPolicy.ALL_TABS );
-
- addTabSelectionListener(
- (ObservableValue<? extends Tab> tabPane,
- final Tab oldTab, final Tab newTab) -> {
-
- if( newTab != null ) {
- activeFileEditor.set( (FileEditorTab)newTab );
- }
- }
- );
-
- final ChangeListener<Boolean> modifiedListener = (observable, oldValue, newValue) -> {
- for( final Tab tab : tabs ) {
- if( ((FileEditorTab)tab).isModified() ) {
- this.anyFileEditorModified.set( true );
- break;
- }
- }
- };
-
- tabs.addListener(
- (ListChangeListener<Tab>)change -> {
- while( change.next() ) {
- if( change.wasAdded() ) {
- change.getAddedSubList().stream().forEach( (tab) -> {
- ((FileEditorTab)tab).modifiedProperty().addListener( modifiedListener );
- } );
- }
- else if( change.wasRemoved() ) {
- change.getRemoved().stream().forEach( (tab) -> {
- ((FileEditorTab)tab).modifiedProperty().removeListener( modifiedListener );
- } );
- }
- }
-
- // Changes in the tabs may also change anyFileEditorModified property
- // (e.g. closed modified file)
- modifiedListener.changed( null, null, null );
- }
- );
- }
-
- /**
- * Delegates to the active file editor.
- *
- * @param <T> Event type.
- * @param <U> Consumer type.
- * @param event Event to pass to the editor.
- * @param consumer Consumer to pass to the editor.
- */
- public <T extends Event, U extends T> void addEventListener(
- final EventPattern<? super T, ? extends U> event,
- final Consumer<? super U> consumer ) {
- getActiveFileEditor().addEventListener( event, consumer );
- }
-
- /**
- * Delegates to the active file editor pane, and, ultimately, to its text
- * area.
- *
- * @param map The map of methods to events.
- */
- public void addEventListener( final InputMap<InputEvent> map ) {
- getActiveFileEditor().addEventListener( map );
- }
-
- /**
- * Remove a keyboard event listener from the active file editor.
- *
- * @param map The keyboard events to remove.
- */
- public void removeEventListener( final InputMap<InputEvent> map ) {
- getActiveFileEditor().removeEventListener( map );
- }
-
- /**
- * Allows observers to be notified when the current file editor tab changes.
- *
- * @param listener The listener to notify of tab change events.
- */
- public void addTabSelectionListener( final ChangeListener<Tab> listener ) {
- // Observe the tab so that when a new tab is opened or selected,
- // a notification is kicked off.
- getSelectionModel().selectedItemProperty().addListener( listener );
- }
-
- /**
- * Allows clients to manipulate the editor content directly.
- *
- * @return The text area for the active file editor.
- */
- public StyledTextArea getEditor() {
- return getActiveFileEditor().getEditorPane().getEditor();
- }
-
- public FileEditorTab getActiveFileEditor() {
- return this.activeFileEditor.get();
- }
-
- public ReadOnlyObjectProperty<FileEditorTab> activeFileEditorProperty() {
- return this.activeFileEditor.getReadOnlyProperty();
- }
-
- ReadOnlyBooleanProperty anyFileEditorModifiedProperty() {
- return this.anyFileEditorModified.getReadOnlyProperty();
- }
-
- private FileEditorTab createFileEditor( final Path path ) {
- final FileEditorTab tab = new FileEditorTab( path );
-
- tab.setOnCloseRequest( e -> {
- if( !canCloseEditor( tab ) ) {
- e.consume();
- }
- } );
-
- return tab;
- }
-
- /**
- * Called when the user selects New from the File menu.
- *
- * @return The newly added tab.
- */
- void newEditor() {
- final FileEditorTab tab = createFileEditor( null );
-
- getTabs().add( tab );
- getSelectionModel().select( tab );
- }
-
- void openFileDialog() {
- final String title = get( "Dialog.file.choose.open.title" );
- final FileChooser dialog = createFileChooser( title );
- final List<File> files = dialog.showOpenMultipleDialog( getWindow() );
-
- if( files != null ) {
- openFiles( files );
- }
- }
-
- /**
- * Opens the files into new editors, unless one of those files was a
- * definition file. The definition file is loaded into the definition pane,
- * but only the first one selected (multiple definition files will result in a
- * warning).
- *
- * @param files The list of non-definition files that the were requested to
- * open.
- *
- * @return A list of files that can be opened in text editors.
- */
- private void openFiles( final List<File> files ) {
- final FileTypePredicate predicate
- = new FileTypePredicate( createExtensionFilter( DEFINITION ).getExtensions() );
-
- // The user might have opened multiple definitions files. These will
- // be discarded from the text editable files.
- final List<File> definitions
- = files.stream().filter( predicate ).collect( Collectors.toList() );
-
- // Create a modifiable list to remove any definition files that were
- // opened.
- final List<File> editors = new ArrayList<>( files );
-
- if( editors.size() > 0 ) {
- saveLastDirectory( editors.get( 0 ) );
- }
-
- editors.removeAll( definitions );
-
- // Open editor-friendly files (e.g,. Markdown, XML) in new tabs.
- if( editors.size() > 0 ) {
- openEditors( editors, 0 );
- }
-
- if( definitions.size() > 0 ) {
- openDefinition( definitions.get( 0 ) );
- }
- }
-
- private void openEditors( final List<File> files, final int activeIndex ) {
- final int fileTally = files.size();
- final List<Tab> tabs = getTabs();
-
- // Close single unmodified "Untitled" tab.
- if( tabs.size() == 1 ) {
- final FileEditorTab fileEditor = (FileEditorTab)(tabs.get( 0 ));
-
- if( fileEditor.getPath() == null && !fileEditor.isModified() ) {
- closeEditor( fileEditor, false );
- }
- }
-
- for( int i = 0; i < fileTally; i++ ) {
- final Path path = files.get( i ).toPath();
-
- FileEditorTab fileEditorTab = findEditor( path );
-
- // Only open new files.
- if( fileEditorTab == null ) {
- fileEditorTab = createFileEditor( path );
- getTabs().add( fileEditorTab );
- }
-
- // Select the first file in the list.
- if( i == activeIndex ) {
- getSelectionModel().select( fileEditorTab );
- }
- }
- }
-
- /**
- * Returns a property that changes when a new definition file is opened.
- *
- * @return The path to a definition file that was opened.
- */
- public ReadOnlyObjectProperty<Path> onOpenDefinitionFileProperty() {
- return getOnOpenDefinitionFile().getReadOnlyProperty();
- }
-
- private ReadOnlyObjectWrapper<Path> getOnOpenDefinitionFile() {
- return this.openDefinition;
- }
-
- /**
- * Called when the user has opened a definition file (using the file open
- * dialog box). This will replace the current set of definitions for the
- * active tab.
- *
- * @param definition The file to open.
- */
- private void openDefinition( final File definition ) {
- // TODO: Prevent reading this file twice when a new text document is opened.
- // (might be a matter of checking the value first).
- getOnOpenDefinitionFile().set( definition.toPath() );
- }
-
- boolean saveEditor( final FileEditorTab tab ) {
- if( tab == null || !tab.isModified() ) {
- return true;
- }
-
- return tab.getPath() == null ? saveEditorAs( tab ) : tab.save();
- }
-
- boolean saveEditorAs( final FileEditorTab tab ) {
- if( tab == null ) {
- return true;
- }
-
- getSelectionModel().select( tab );
-
- final FileChooser fileChooser = createFileChooser( get( "Dialog.file.choose.save.title" ) );
- final File file = fileChooser.showSaveDialog( getWindow() );
- if( file == null ) {
- return false;
- }
-
- saveLastDirectory( file );
- tab.setPath( file.toPath() );
-
- return tab.save();
- }
-
- boolean saveAllEditors() {
- boolean success = true;
-
- for( FileEditorTab fileEditor : getAllEditors() ) {
- if( !saveEditor( fileEditor ) ) {
- success = false;
- }
- }
-
- return success;
- }
-
- /**
- * Answers whether the file has had modifications. '
- *
- * @param tab THe tab to check for modifications.
- *
- * @return false The file is unmodified.
- */
- boolean canCloseEditor( final FileEditorTab tab ) {
- if( !tab.isModified() ) {
- return true;
- }
-
- final Notification message = getNotifyService().createNotification(
- Messages.get( "Alert.file.close.title" ),
- Messages.get( "Alert.file.close.text" ),
- tab.getText()
- );
-
- final Alert alert = getNotifyService().createConfirmation(
- getWindow(), message );
- final ButtonType response = alert.showAndWait().get();
-
- return response == YES ? saveEditor( tab ) : response == NO;
- }
-
- private Notifier getNotifyService() {
- return this.notifyService;
- }
-
- boolean closeEditor( FileEditorTab fileEditor, boolean save ) {
- if( fileEditor == null ) {
- return true;
- }
-
- final Tab tab = fileEditor;
-
- if( save ) {
- Event event = new Event( tab, tab, Tab.TAB_CLOSE_REQUEST_EVENT );
- Event.fireEvent( tab, event );
-
- if( event.isConsumed() ) {
- return false;
- }
- }
-
- getTabs().remove( tab );
-
- if( tab.getOnClosed() != null ) {
- Event.fireEvent( tab, new Event( Tab.CLOSED_EVENT ) );
- }
-
- return true;
- }
-
- boolean closeAllEditors() {
- final FileEditorTab[] allEditors = getAllEditors();
- final FileEditorTab activeEditor = getActiveFileEditor();
-
- // try to save active tab first because in case the user decides to cancel,
- // then it stays active
- if( activeEditor != null && !canCloseEditor( activeEditor ) ) {
- return false;
- }
-
- // This should be called any time a tab changes.
- persistPreferences();
-
- // save modified tabs
- for( int i = 0; i < allEditors.length; i++ ) {
- final FileEditorTab fileEditor = allEditors[ i ];
-
- if( fileEditor == activeEditor ) {
- continue;
- }
-
- if( fileEditor.isModified() ) {
- // activate the modified tab to make its modified content visible to the user
- getSelectionModel().select( i );
-
- if( !canCloseEditor( fileEditor ) ) {
- return false;
- }
- }
- }
-
- // Close all tabs.
- for( final FileEditorTab fileEditor : allEditors ) {
- if( !closeEditor( fileEditor, false ) ) {
- return false;
- }
- }
-
- return getTabs().isEmpty();
- }
-
- private FileEditorTab[] getAllEditors() {
- final ObservableList<Tab> tabs = getTabs();
- final int length = tabs.size();
- final FileEditorTab[] allEditors = new FileEditorTab[ length ];
-
- for( int i = 0; i < length; i++ ) {
- allEditors[ i ] = (FileEditorTab)tabs.get( i );
- }
-
- return allEditors;
- }
-
- /**
- * Returns the file editor tab that has the given path.
- *
- * @return null No file editor tab for the given path was found.
- */
- private FileEditorTab findEditor( final Path path ) {
- for( final Tab tab : getTabs() ) {
- final FileEditorTab fileEditor = (FileEditorTab)tab;
-
- if( fileEditor.isPath( path ) ) {
- return fileEditor;
- }
- }
-
- return null;
- }
-
- private FileChooser createFileChooser( String title ) {
- final FileChooser fileChooser = new FileChooser();
-
- fileChooser.setTitle( title );
- fileChooser.getExtensionFilters().addAll(
- createExtensionFilters() );
-
- final String lastDirectory = getPreferences().get( "lastDirectory", null );
- File file = new File( (lastDirectory != null) ? lastDirectory : "." );
-
- if( !file.isDirectory() ) {
- file = new File( "." );
- }
-
- fileChooser.setInitialDirectory( file );
- return fileChooser;
- }
-
- private List<ExtensionFilter> createExtensionFilters() {
- final List<ExtensionFilter> list = new ArrayList<>();
-
- // TODO: Return a list of all properties that match the filter prefix.
- // This will allow dynamic filters to be added and removed just by
- // updating the properties file.
- list.add( createExtensionFilter( SOURCE ) );
- list.add( createExtensionFilter( DEFINITION ) );
- list.add( createExtensionFilter( XML ) );
- list.add( createExtensionFilter( ALL ) );
- return list;
- }
-
- /**
- * Returns a filter for file name extensions recognized by the application
- * that can be opened by the user.
- *
- * @param filetype Used to find the globbing pattern for extensions.
- *
- * @return A filename filter suitable for use by a FileDialog instance.
- */
- private ExtensionFilter createExtensionFilter( final FileType filetype ) {
- final String tKey = String.format( "%s.title.%s", FILTER_EXTENSION_TITLES, filetype );
- final String eKey = String.format( "%s.%s", GLOB_PREFIX_FILE, filetype );
-
- return new ExtensionFilter( Messages.get( tKey ), getExtensions( eKey ) );
- }
-
- private List<String> getExtensions( final String key ) {
- return getSettings().getStringSettingList( key );
- }
-
- private void saveLastDirectory( final File file ) {
- getPreferences().put( "lastDirectory", file.getParent() );
- }
-
- public void restorePreferences() {
- int activeIndex = 0;
-
- final Preferences preferences = getPreferences();
- final String[] fileNames = Utils.getPrefsStrings( preferences, "file" );
- final String activeFileName = preferences.get( "activeFile", null );
-
- final ArrayList<File> files = new ArrayList<>( fileNames.length );
-
- for( final String fileName : fileNames ) {
- final File file = new File( fileName );
-
- if( file.exists() ) {
- files.add( file );
-
- if( fileName.equals( activeFileName ) ) {
- activeIndex = files.size() - 1;
- }
- }
- }
-
- if( files.isEmpty() ) {
- newEditor();
- }
- else {
- openEditors( files, activeIndex );
- }
- }
-
- public void persistPreferences() {
- final ObservableList<Tab> allEditors = getTabs();
- final List<String> fileNames = new ArrayList<>( allEditors.size() );
-
- for( final Tab tab : allEditors ) {
- final FileEditorTab fileEditor = (FileEditorTab)tab;
- final Path filePath = fileEditor.getPath();
-
- if( filePath != null ) {
- fileNames.add( filePath.toString() );
- }
- }
-
- final Preferences preferences = getPreferences();
- Utils.putPrefsStrings( preferences, "file", fileNames.toArray( new String[ fileNames.size() ] ) );
-
- final FileEditorTab activeEditor = getActiveFileEditor();
- final Path filePath = activeEditor == null ? null : activeEditor.getPath();
-
- if( filePath == null ) {
- preferences.remove( "activeFile" );
- }
- else {
+
+import com.scrivenvar.predicates.files.FileTypePredicate;
+import com.scrivenvar.service.Options;
+import com.scrivenvar.service.Settings;
+import com.scrivenvar.service.events.Notification;
+import com.scrivenvar.service.events.Notifier;
+
+import static com.scrivenvar.service.events.Notifier.NO;
+import static com.scrivenvar.service.events.Notifier.YES;
+
+import com.scrivenvar.util.Utils;
+
+import java.io.File;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Consumer;
+import java.util.prefs.Preferences;
+import java.util.stream.Collectors;
+
+import javafx.beans.property.ReadOnlyBooleanProperty;
+import javafx.beans.property.ReadOnlyBooleanWrapper;
+import javafx.beans.property.ReadOnlyObjectProperty;
+import javafx.beans.property.ReadOnlyObjectWrapper;
+import javafx.beans.value.ChangeListener;
+import javafx.beans.value.ObservableValue;
+import javafx.collections.ListChangeListener;
+import javafx.collections.ObservableList;
+import javafx.event.Event;
+import javafx.scene.Node;
+import javafx.scene.control.Alert;
+import javafx.scene.control.ButtonType;
+import javafx.scene.control.Tab;
+import javafx.scene.control.TabPane;
+import javafx.scene.control.TabPane.TabClosingPolicy;
+import javafx.scene.input.InputEvent;
+import javafx.stage.FileChooser;
+import javafx.stage.FileChooser.ExtensionFilter;
+import javafx.stage.Window;
+import org.fxmisc.richtext.StyledTextArea;
+import org.fxmisc.wellbehaved.event.EventPattern;
+import org.fxmisc.wellbehaved.event.InputMap;
+
+/**
+ * Tab pane for file editors.
+ *
+ * @author Karl Tauber and White Magic Software, Ltd.
+ */
+public final class FileEditorTabPane extends TabPane {
+
+ private final static String FILTER_EXTENSION_TITLES = "Dialog.file.choose.filter";
+
+ private final Options options = Services.load( Options.class );
+ private final Settings settings = Services.load( Settings.class );
+ private final Notifier notifyService = Services.load( Notifier.class );
+
+ private final ReadOnlyObjectWrapper<Path> openDefinition = new ReadOnlyObjectWrapper<>();
+ private final ReadOnlyObjectWrapper<FileEditorTab> activeFileEditor = new ReadOnlyObjectWrapper<>();
+ private final ReadOnlyBooleanWrapper anyFileEditorModified = new ReadOnlyBooleanWrapper();
+
+ /**
+ * Constructs a new file editor tab pane.
+ */
+ public FileEditorTabPane() {
+ final ObservableList<Tab> tabs = getTabs();
+
+ setFocusTraversable( false );
+ setTabClosingPolicy( TabClosingPolicy.ALL_TABS );
+
+ addTabSelectionListener(
+ ( ObservableValue<? extends Tab> tabPane,
+ final Tab oldTab, final Tab newTab ) -> {
+
+ if( newTab != null ) {
+ activeFileEditor.set( (FileEditorTab) newTab );
+ }
+ }
+ );
+
+ final ChangeListener<Boolean> modifiedListener = ( observable, oldValue, newValue ) -> {
+ for( final Tab tab : tabs ) {
+ if( ((FileEditorTab) tab).isModified() ) {
+ this.anyFileEditorModified.set( true );
+ break;
+ }
+ }
+ };
+
+ tabs.addListener(
+ (ListChangeListener<Tab>) change -> {
+ while( change.next() ) {
+ if( change.wasAdded() ) {
+ change.getAddedSubList().stream().forEach( ( tab ) -> {
+ ((FileEditorTab) tab).modifiedProperty().addListener( modifiedListener );
+ } );
+ } else if( change.wasRemoved() ) {
+ change.getRemoved().stream().forEach( ( tab ) -> {
+ ((FileEditorTab) tab).modifiedProperty().removeListener( modifiedListener );
+ } );
+ }
+ }
+
+ // Changes in the tabs may also change anyFileEditorModified property
+ // (e.g. closed modified file)
+ modifiedListener.changed( null, null, null );
+ }
+ );
+ }
+
+ /**
+ * Delegates to the active file editor.
+ *
+ * @param <T> Event type.
+ * @param <U> Consumer type.
+ * @param event Event to pass to the editor.
+ * @param consumer Consumer to pass to the editor.
+ */
+ public <T extends Event, U extends T> void addEventListener(
+ final EventPattern<? super T, ? extends U> event,
+ final Consumer<? super U> consumer ) {
+ getActiveFileEditor().addEventListener( event, consumer );
+ }
+
+ /**
+ * Delegates to the active file editor pane, and, ultimately, to its text
+ * area.
+ *
+ * @param map The map of methods to events.
+ */
+ public void addEventListener( final InputMap<InputEvent> map ) {
+ getActiveFileEditor().addEventListener( map );
+ }
+
+ /**
+ * Remove a keyboard event listener from the active file editor.
+ *
+ * @param map The keyboard events to remove.
+ */
+ public void removeEventListener( final InputMap<InputEvent> map ) {
+ getActiveFileEditor().removeEventListener( map );
+ }
+
+ /**
+ * Allows observers to be notified when the current file editor tab changes.
+ *
+ * @param listener The listener to notify of tab change events.
+ */
+ public void addTabSelectionListener( final ChangeListener<Tab> listener ) {
+ // Observe the tab so that when a new tab is opened or selected,
+ // a notification is kicked off.
+ getSelectionModel().selectedItemProperty().addListener( listener );
+ }
+
+ /**
+ * Allows clients to manipulate the editor content directly.
+ *
+ * @return The text area for the active file editor.
+ */
+ public StyledTextArea getEditor() {
+ return getActiveFileEditor().getEditorPane().getEditor();
+ }
+
+ /**
+ * Returns the tab that has keyboard focus.
+ *
+ * @return A non-null instance.
+ */
+ public FileEditorTab getActiveFileEditor() {
+ return this.activeFileEditor.get();
+ }
+
+ /**
+ * Returns the property corresponding to the tab that has focus.
+ *
+ * @return A non-null instance.
+ */
+ public ReadOnlyObjectProperty<FileEditorTab> activeFileEditorProperty() {
+ return this.activeFileEditor.getReadOnlyProperty();
+ }
+
+ /**
+ * Property that can answer whether the text has been modified.
+ *
+ * @return A non-null instance, true meaning the content has not been saved.
+ */
+ ReadOnlyBooleanProperty anyFileEditorModifiedProperty() {
+ return this.anyFileEditorModified.getReadOnlyProperty();
+ }
+
+ /**
+ * Creates a new editor instance from the given path.
+ *
+ * @param path The file to open.
+ * @return A non-null instance.
+ */
+ private FileEditorTab createFileEditor( final Path path ) {
+ final FileEditorTab tab = new FileEditorTab( path );
+
+ tab.setOnCloseRequest( e -> {
+ if( !canCloseEditor( tab ) ) {
+ e.consume();
+ }
+ } );
+
+ return tab;
+ }
+
+ /**
+ * Called when the user selects New from the File menu.
+ *
+ * @return The newly added tab.
+ */
+ void newEditor() {
+ final FileEditorTab tab = createFileEditor( null );
+
+ getTabs().add( tab );
+ getSelectionModel().select( tab );
+ }
+
+ void openFileDialog() {
+ final String title = get( "Dialog.file.choose.open.title" );
+ final FileChooser dialog = createFileChooser( title );
+ final List<File> files = dialog.showOpenMultipleDialog( getWindow() );
+
+ if( files != null ) {
+ openFiles( files );
+ }
+ }
+
+ /**
+ * Opens the files into new editors, unless one of those files was a
+ * definition file. The definition file is loaded into the definition pane,
+ * but only the first one selected (multiple definition files will result in a
+ * warning).
+ *
+ * @param files The list of non-definition files that the were requested to
+ * open.
+ * @return A list of files that can be opened in text editors.
+ */
+ private void openFiles( final List<File> files ) {
+ final FileTypePredicate predicate
+ = new FileTypePredicate( createExtensionFilter( DEFINITION ).getExtensions() );
+
+ // The user might have opened multiple definitions files. These will
+ // be discarded from the text editable files.
+ final List<File> definitions
+ = files.stream().filter( predicate ).collect( Collectors.toList() );
+
+ // Create a modifiable list to remove any definition files that were
+ // opened.
+ final List<File> editors = new ArrayList<>( files );
+
+ if( editors.size() > 0 ) {
+ saveLastDirectory( editors.get( 0 ) );
+ }
+
+ editors.removeAll( definitions );
+
+ // Open editor-friendly files (e.g,. Markdown, XML) in new tabs.
+ if( editors.size() > 0 ) {
+ openEditors( editors, 0 );
+ }
+
+ if( definitions.size() > 0 ) {
+ openDefinition( definitions.get( 0 ) );
+ }
+ }
+
+ private void openEditors( final List<File> files, final int activeIndex ) {
+ final int fileTally = files.size();
+ final List<Tab> tabs = getTabs();
+
+ // Close single unmodified "Untitled" tab.
+ if( tabs.size() == 1 ) {
+ final FileEditorTab fileEditor = (FileEditorTab) (tabs.get( 0 ));
+
+ if( fileEditor.getPath() == null && !fileEditor.isModified() ) {
+ closeEditor( fileEditor, false );
+ }
+ }
+
+ for( int i = 0; i < fileTally; i++ ) {
+ final Path path = files.get( i ).toPath();
+
+ FileEditorTab fileEditorTab = findEditor( path );
+
+ // Only open new files.
+ if( fileEditorTab == null ) {
+ fileEditorTab = createFileEditor( path );
+ getTabs().add( fileEditorTab );
+ }
+
+ // Select the first file in the list.
+ if( i == activeIndex ) {
+ getSelectionModel().select( fileEditorTab );
+ }
+ }
+ }
+
+ /**
+ * Returns a property that changes when a new definition file is opened.
+ *
+ * @return The path to a definition file that was opened.
+ */
+ public ReadOnlyObjectProperty<Path> onOpenDefinitionFileProperty() {
+ return getOnOpenDefinitionFile().getReadOnlyProperty();
+ }
+
+ private ReadOnlyObjectWrapper<Path> getOnOpenDefinitionFile() {
+ return this.openDefinition;
+ }
+
+ /**
+ * Called when the user has opened a definition file (using the file open
+ * dialog box). This will replace the current set of definitions for the
+ * active tab.
+ *
+ * @param definition The file to open.
+ */
+ private void openDefinition( final File definition ) {
+ // TODO: Prevent reading this file twice when a new text document is opened.
+ // (might be a matter of checking the value first).
+ getOnOpenDefinitionFile().set( definition.toPath() );
+ }
+
+ /**
+ * Called when the contents of the editor are to be saved.
+ *
+ * @param tab The tab containing content to save.
+ * @return true The contents were saved (or needn't be saved).
+ */
+ public boolean saveEditor( final FileEditorTab tab ) {
+ if( tab == null || !tab.isModified() ) {
+ return true;
+ }
+
+ return tab.getPath() == null ? saveEditorAs( tab ) : tab.save();
+ }
+
+ /**
+ * Opens the Save As dialog for the user to save the content under a new
+ * path.
+ *
+ * @param tab The tab with contents to save.
+ * @return true The contents were saved, or the tab was null.
+ */
+ public boolean saveEditorAs( final FileEditorTab tab ) {
+ if( tab == null ) {
+ return true;
+ }
+
+ getSelectionModel().select( tab );
+
+ final FileChooser fileChooser = createFileChooser( get( "Dialog.file.choose.save.title" ) );
+ final File file = fileChooser.showSaveDialog( getWindow() );
+ if( file == null ) {
+ return false;
+ }
+
+ saveLastDirectory( file );
+ tab.setPath( file.toPath() );
+
+ return tab.save();
+ }
+
+ boolean saveAllEditors() {
+ boolean success = true;
+
+ for( FileEditorTab fileEditor : getAllEditors() ) {
+ if( !saveEditor( fileEditor ) ) {
+ success = false;
+ }
+ }
+
+ return success;
+ }
+
+ /**
+ * Answers whether the file has had modifications. '
+ *
+ * @param tab THe tab to check for modifications.
+ * @return false The file is unmodified.
+ */
+ boolean canCloseEditor( final FileEditorTab tab ) {
+ if( !tab.isModified() ) {
+ return true;
+ }
+
+ final Notification message = getNotifyService().createNotification(
+ Messages.get( "Alert.file.close.title" ),
+ Messages.get( "Alert.file.close.text" ),
+ tab.getText()
+ );
+
+ final Alert alert = getNotifyService().createConfirmation(
+ getWindow(), message );
+ final ButtonType response = alert.showAndWait().get();
+
+ return response == YES ? saveEditor( tab ) : response == NO;
+ }
+
+ private Notifier getNotifyService() {
+ return this.notifyService;
+ }
+
+ boolean closeEditor( FileEditorTab fileEditor, boolean save ) {
+ if( fileEditor == null ) {
+ return true;
+ }
+
+ final Tab tab = fileEditor;
+
+ if( save ) {
+ Event event = new Event( tab, tab, Tab.TAB_CLOSE_REQUEST_EVENT );
+ Event.fireEvent( tab, event );
+
+ if( event.isConsumed() ) {
+ return false;
+ }
+ }
+
+ getTabs().remove( tab );
+
+ if( tab.getOnClosed() != null ) {
+ Event.fireEvent( tab, new Event( Tab.CLOSED_EVENT ) );
+ }
+
+ return true;
+ }
+
+ boolean closeAllEditors() {
+ final FileEditorTab[] allEditors = getAllEditors();
+ final FileEditorTab activeEditor = getActiveFileEditor();
+
+ // try to save active tab first because in case the user decides to cancel,
+ // then it stays active
+ if( activeEditor != null && !canCloseEditor( activeEditor ) ) {
+ return false;
+ }
+
+ // This should be called any time a tab changes.
+ persistPreferences();
+
+ // save modified tabs
+ for( int i = 0; i < allEditors.length; i++ ) {
+ final FileEditorTab fileEditor = allEditors[ i ];
+
+ if( fileEditor == activeEditor ) {
+ continue;
+ }
+
+ if( fileEditor.isModified() ) {
+ // activate the modified tab to make its modified content visible to the user
+ getSelectionModel().select( i );
+
+ if( !canCloseEditor( fileEditor ) ) {
+ return false;
+ }
+ }
+ }
+
+ // Close all tabs.
+ for( final FileEditorTab fileEditor : allEditors ) {
+ if( !closeEditor( fileEditor, false ) ) {
+ return false;
+ }
+ }
+
+ return getTabs().isEmpty();
+ }
+
+ private FileEditorTab[] getAllEditors() {
+ final ObservableList<Tab> tabs = getTabs();
+ final int length = tabs.size();
+ final FileEditorTab[] allEditors = new FileEditorTab[ length ];
+
+ for( int i = 0; i < length; i++ ) {
+ allEditors[ i ] = (FileEditorTab) tabs.get( i );
+ }
+
+ return allEditors;
+ }
+
+ /**
+ * Returns the file editor tab that has the given path.
+ *
+ * @return null No file editor tab for the given path was found.
+ */
+ private FileEditorTab findEditor( final Path path ) {
+ for( final Tab tab : getTabs() ) {
+ final FileEditorTab fileEditor = (FileEditorTab) tab;
+
+ if( fileEditor.isPath( path ) ) {
+ return fileEditor;
+ }
+ }
+
+ return null;
+ }
+
+ private FileChooser createFileChooser( String title ) {
+ final FileChooser fileChooser = new FileChooser();
+
+ fileChooser.setTitle( title );
+ fileChooser.getExtensionFilters().addAll(
+ createExtensionFilters() );
+
+ final String lastDirectory = getPreferences().get( "lastDirectory", null );
+ File file = new File( (lastDirectory != null) ? lastDirectory : "." );
+
+ if( !file.isDirectory() ) {
+ file = new File( "." );
+ }
+
+ fileChooser.setInitialDirectory( file );
+ return fileChooser;
+ }
+
+ private List<ExtensionFilter> createExtensionFilters() {
+ final List<ExtensionFilter> list = new ArrayList<>();
+
+ // TODO: Return a list of all properties that match the filter prefix.
+ // This will allow dynamic filters to be added and removed just by
+ // updating the properties file.
+ list.add( createExtensionFilter( SOURCE ) );
+ list.add( createExtensionFilter( DEFINITION ) );
+ list.add( createExtensionFilter( XML ) );
+ list.add( createExtensionFilter( ALL ) );
+ return list;
+ }
+
+ /**
+ * Returns a filter for file name extensions recognized by the application
+ * that can be opened by the user.
+ *
+ * @param filetype Used to find the globbing pattern for extensions.
+ * @return A filename filter suitable for use by a FileDialog instance.
+ */
+ private ExtensionFilter createExtensionFilter( final FileType filetype ) {
+ final String tKey = String.format( "%s.title.%s", FILTER_EXTENSION_TITLES, filetype );
+ final String eKey = String.format( "%s.%s", GLOB_PREFIX_FILE, filetype );
+
+ return new ExtensionFilter( Messages.get( tKey ), getExtensions( eKey ) );
+ }
+
+ private List<String> getExtensions( final String key ) {
+ return getSettings().getStringSettingList( key );
+ }
+
+ private void saveLastDirectory( final File file ) {
+ getPreferences().put( "lastDirectory", file.getParent() );
+ }
+
+ public void restorePreferences() {
+ int activeIndex = 0;
+
+ final Preferences preferences = getPreferences();
+ final String[] fileNames = Utils.getPrefsStrings( preferences, "file" );
+ final String activeFileName = preferences.get( "activeFile", null );
+
+ final ArrayList<File> files = new ArrayList<>( fileNames.length );
+
+ for( final String fileName : fileNames ) {
+ final File file = new File( fileName );
+
+ if( file.exists() ) {
+ files.add( file );
+
+ if( fileName.equals( activeFileName ) ) {
+ activeIndex = files.size() - 1;
+ }
+ }
+ }
+
+ if( files.isEmpty() ) {
+ newEditor();
+ } else {
+ openEditors( files, activeIndex );
+ }
+ }
+
+ public void persistPreferences() {
+ final ObservableList<Tab> allEditors = getTabs();
+ final List<String> fileNames = new ArrayList<>( allEditors.size() );
+
+ for( final Tab tab : allEditors ) {
+ final FileEditorTab fileEditor = (FileEditorTab) tab;
+ final Path filePath = fileEditor.getPath();
+
+ if( filePath != null ) {
+ fileNames.add( filePath.toString() );
+ }
+ }
+
+ final Preferences preferences = getPreferences();
+ Utils.putPrefsStrings( preferences, "file", fileNames.toArray( new String[ fileNames.size() ] ) );
+
+ final FileEditorTab activeEditor = getActiveFileEditor();
+ final Path filePath = activeEditor == null ? null : activeEditor.getPath();
+
+ if( filePath == null ) {
+ preferences.remove( "activeFile" );
+ } else {
preferences.put( "activeFile", filePath.toString() );
}
src/main/java/com/scrivenvar/FileType.java
private final String type;
+ /**
+ * Default constructor for enumerated file type.
+ *
+ * @param type Human-readable name for the file type.
+ */
private FileType( final String type ) {
this.type = type;
}
+ /**
+ * Returns the human-readable name for the file type.
+ *
+ * @return A non-null instance.
+ */
private String getType() {
return this.type;
src/main/java/com/scrivenvar/Main.java
}
+ /**
+ * Watch for file system changes.
+ */
private void initSnitch() {
setSnitchThread( new Thread( getSnitch() ) );
src/main/java/com/scrivenvar/processors/IdentityProcessor.java
* @param t The string to return, enclosed in "pre" tags.
*
- * @return t
+ * @return The value of t wrapped in "pre" tags.
*/
@Override
src/main/java/com/scrivenvar/processors/InlineRProcessor.java
/**
+ * Initialises the R code so that R can find imported libraries.
*
- * @param workingDirectory
+ * @param workingDirectory Location where R is to look for imports.
*/
private void init( final Path workingDirectory ) {
}
+ /**
+ * Loads the R init script from the applciation's persisted preferences.
+ *
+ * @return A non-null String, possibly empty.
+ * @throws IOException Could not load the init script.
+ */
private String getInitScript() throws IOException {
return getOptions().get( PERSIST_R_STARTUP, "" );
}
+ /**
+ * Evaluates all R statements in the source document and inserts the
+ * calculated value into the generated document.
+ *
+ * @param text The document text that includes variables that should be
+ * replaced with values when rendered as HTML.
+ *
+ * @return The generated document with output from all R statements
+ * substituted with value returned from their execution.
+ */
@Override
public String processLink( final String text ) {
src/main/java/com/scrivenvar/service/Options.java
/**
- * Responsible for persistent options.
+ * Responsible for persisting options.
*
* @author White Magic Software, Ltd.
src/main/java/com/scrivenvar/service/Settings.java
public List<String> getStringSettingList( String property );
-
/**
* Changes key's value. This will clear the old value before setting the
Delta1528 lines added, 627 lines removed, 901-line increase