| Author | djarvis <email> |
|---|---|
| Date | 2018-11-07 21:09:49 GMT-0800 |
| Commit | 01e29751bb446e94ea19675a053c64880af89cf7 |
| Parent | 0ca55bd |
| - | ||
| +<component name="ProjectCodeStyleConfiguration"> | ||
| + <state> | ||
| + <option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" /> | ||
| + </state> | ||
| +</component> |
| - | ||
| +<?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> |
| - | ||
| +<?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> |
| - | ||
| +<?xml version="1.0" encoding="UTF-8"?> | ||
| +<project version="4"> | ||
| + <component name="VcsDirectoryMappings"> | ||
| + <mapping directory="$PROJECT_DIR$" vcs="Git" /> | ||
| + </component> | ||
| +</project> |
| - | ||
| +<?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	" /> | ||
| + <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> |
| * [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 |
| 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' } | ||
| -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 | ||
| - | ||
| - |
| +org.gradle.jvmargs=-Xmx1G -XX:MaxPermSize=512m | ||
| + | ||
| -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. | ||
| +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. | ||
| * Return the singleton Settings instance. | ||
| * | ||
| - * @return The settings for | ||
| + * @return A non-null instance. | ||
| */ | ||
| private Settings getSettings() { |
| 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(); |
| 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. | ||
| public final class FileEditorTab extends Tab { | ||
| + /** | ||
| + * | ||
| + */ | ||
| private final Notifier alertService = Services.load( Notifier.class ); | ||
| private EditorPane editorPane; |
| 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() ); | ||
| } |
| 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; | ||
| } | ||
| + /** | ||
| + * Watch for file system changes. | ||
| + */ | ||
| private void initSnitch() { | ||
| setSnitchThread( new Thread( getSnitch() ) ); |
| * @param t The string to return, enclosed in "pre" tags. | ||
| * | ||
| - * @return t | ||
| + * @return The value of t wrapped in "pre" tags. | ||
| */ | ||
| @Override |
| /** | ||
| + * 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 ) { | ||
| /** | ||
| - * Responsible for persistent options. | ||
| + * Responsible for persisting options. | ||
| * | ||
| * @author White Magic Software, Ltd. |
| public List<String> getStringSettingList( String property ); | ||
| - | ||
| /** | ||
| * Changes key's value. This will clear the old value before setting the |
| Delta | 1528 lines added, 627 lines removed, 901-line increase |
|---|