Restructured the project. Moving to multiple-source timelines
that can automatically sync with one another.
This commit is contained in:
parent
42d2d82c74
commit
89ad2ac447
BIN
doc/feed.pdf
Normal file
BIN
doc/feed.pdf
Normal file
Binary file not shown.
77
doc/feed.rst
Normal file
77
doc/feed.rst
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
Centralized vs. decentralized
|
||||||
|
-----------------------------
|
||||||
|
|
||||||
|
Centralized
|
||||||
|
```````````
|
||||||
|
|
||||||
|
- one central list
|
||||||
|
- remote apps that sync with central?
|
||||||
|
|
||||||
|
Decentralized
|
||||||
|
`````````````
|
||||||
|
|
||||||
|
- sync to URL(s)?
|
||||||
|
|
||||||
|
- need a network protocol
|
||||||
|
- HTTP?
|
||||||
|
- SSL?
|
||||||
|
|
||||||
|
- group-wise sync?
|
||||||
|
|
||||||
|
- establish master/slaves?
|
||||||
|
- easier than coordinated group-update:::
|
||||||
|
|
||||||
|
map each URL to synch -> the last time updated.
|
||||||
|
if (update_period):
|
||||||
|
forall URLs: synch
|
||||||
|
else if (incoming_update):
|
||||||
|
forall (URLs older than incoming update): synch
|
||||||
|
|
||||||
|
- synch based on hash of updates?
|
||||||
|
|
||||||
|
- need canonicalizer for text. Use XML?
|
||||||
|
- hash algorithm:::
|
||||||
|
|
||||||
|
SHA-1 of:
|
||||||
|
concatenate:
|
||||||
|
date (YYYYMMDDhhmmssSSS)
|
||||||
|
name
|
||||||
|
notes
|
||||||
|
|
||||||
|
External Feeds
|
||||||
|
--------------
|
||||||
|
|
||||||
|
Item format
|
||||||
|
```````````
|
||||||
|
|
||||||
|
- time started
|
||||||
|
- name/description
|
||||||
|
- notes
|
||||||
|
- category?
|
||||||
|
|
||||||
|
Pull from
|
||||||
|
`````````
|
||||||
|
|
||||||
|
- needs to be optional
|
||||||
|
- standardized input format
|
||||||
|
|
||||||
|
- easy to parse
|
||||||
|
- no errors, false positives
|
||||||
|
- restrictive.
|
||||||
|
|
||||||
|
- flexible input format
|
||||||
|
|
||||||
|
- matches regex's?
|
||||||
|
- map groups to fields
|
||||||
|
|
||||||
|
Push to
|
||||||
|
```````
|
||||||
|
|
||||||
|
- optional
|
||||||
|
- standardized output
|
||||||
|
|
||||||
|
- cannot be flexible to match output medium
|
||||||
|
|
||||||
|
- flexible input format
|
||||||
|
|
||||||
|
- choose fields and format values
|
8
doc/sample-txt-timeline-with-sync-info.txt
Normal file
8
doc/sample-txt-timeline-with-sync-info.txt
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# sync-options:
|
||||||
|
# LOCAL TIMELINE: this file
|
||||||
|
# SYNC TO: ssh://jdbernard@jdbernard.no-ip.org/timelines/jdbernard.timeline.txt
|
||||||
|
# SYNC TO: http://www.twitter.com/jdbernard
|
||||||
|
# pull only
|
||||||
|
# update every 30 sec
|
||||||
|
# SYNC TO: file:///home/jdbernard/timelines/jdbernard.timeline.bak
|
||||||
|
# push only
|
@ -21,6 +21,13 @@ is divided into following sections:
|
|||||||
-->
|
-->
|
||||||
<project xmlns:j2seproject1="http://www.netbeans.org/ns/j2se-project/1" xmlns:j2seproject3="http://www.netbeans.org/ns/j2se-project/3" xmlns:jaxrpc="http://www.netbeans.org/ns/j2se-project/jax-rpc" basedir=".." default="default" name="TimeStamper-impl">
|
<project xmlns:j2seproject1="http://www.netbeans.org/ns/j2se-project/1" xmlns:j2seproject3="http://www.netbeans.org/ns/j2se-project/3" xmlns:jaxrpc="http://www.netbeans.org/ns/j2se-project/jax-rpc" basedir=".." default="default" name="TimeStamper-impl">
|
||||||
<import file="jnlp-impl.xml"/>
|
<import file="jnlp-impl.xml"/>
|
||||||
|
<fail message="Please build using Ant 1.7.1 or higher.">
|
||||||
|
<condition>
|
||||||
|
<not>
|
||||||
|
<antversion atleast="1.7.1"/>
|
||||||
|
</not>
|
||||||
|
</condition>
|
||||||
|
</fail>
|
||||||
<target depends="test,jar,javadoc" description="Build and test whole project." name="default"/>
|
<target depends="test,jar,javadoc" description="Build and test whole project." name="default"/>
|
||||||
<!--
|
<!--
|
||||||
======================
|
======================
|
||||||
@ -153,10 +160,18 @@ is divided into following sections:
|
|||||||
<attribute default="${includes}" name="includes"/>
|
<attribute default="${includes}" name="includes"/>
|
||||||
<attribute default="${excludes}" name="excludes"/>
|
<attribute default="${excludes}" name="excludes"/>
|
||||||
<attribute default="${javac.debug}" name="debug"/>
|
<attribute default="${javac.debug}" name="debug"/>
|
||||||
<attribute default="" name="sourcepath"/>
|
<attribute default="${empty.dir}" name="sourcepath"/>
|
||||||
|
<attribute default="${empty.dir}" name="gensrcdir"/>
|
||||||
<element name="customize" optional="true"/>
|
<element name="customize" optional="true"/>
|
||||||
<sequential>
|
<sequential>
|
||||||
|
<property location="${build.dir}/empty" name="empty.dir"/>
|
||||||
|
<mkdir dir="${empty.dir}"/>
|
||||||
<javac debug="@{debug}" deprecation="${javac.deprecation}" destdir="@{destdir}" encoding="${source.encoding}" excludes="@{excludes}" includeantruntime="false" includes="@{includes}" source="${javac.source}" sourcepath="@{sourcepath}" srcdir="@{srcdir}" target="${javac.target}">
|
<javac debug="@{debug}" deprecation="${javac.deprecation}" destdir="@{destdir}" encoding="${source.encoding}" excludes="@{excludes}" includeantruntime="false" includes="@{includes}" source="${javac.source}" sourcepath="@{sourcepath}" srcdir="@{srcdir}" target="${javac.target}">
|
||||||
|
<src>
|
||||||
|
<dirset dir="@{gensrcdir}" erroronmissingdir="false">
|
||||||
|
<include name="*"/>
|
||||||
|
</dirset>
|
||||||
|
</src>
|
||||||
<classpath>
|
<classpath>
|
||||||
<path path="@{classpath}"/>
|
<path path="@{classpath}"/>
|
||||||
</classpath>
|
</classpath>
|
||||||
@ -219,13 +234,13 @@ is divided into following sections:
|
|||||||
</sequential>
|
</sequential>
|
||||||
</macrodef>
|
</macrodef>
|
||||||
</target>
|
</target>
|
||||||
<target name="-init-macrodef-nbjpda">
|
<target depends="-init-debug-args" name="-init-macrodef-nbjpda">
|
||||||
<macrodef name="nbjpdastart" uri="http://www.netbeans.org/ns/j2se-project/1">
|
<macrodef name="nbjpdastart" uri="http://www.netbeans.org/ns/j2se-project/1">
|
||||||
<attribute default="${main.class}" name="name"/>
|
<attribute default="${main.class}" name="name"/>
|
||||||
<attribute default="${debug.classpath}" name="classpath"/>
|
<attribute default="${debug.classpath}" name="classpath"/>
|
||||||
<attribute default="" name="stopclassname"/>
|
<attribute default="" name="stopclassname"/>
|
||||||
<sequential>
|
<sequential>
|
||||||
<nbjpdastart addressproperty="jpda.address" name="@{name}" stopclassname="@{stopclassname}" transport="dt_socket">
|
<nbjpdastart addressproperty="jpda.address" name="@{name}" stopclassname="@{stopclassname}" transport="${debug-transport}">
|
||||||
<classpath>
|
<classpath>
|
||||||
<path path="@{classpath}"/>
|
<path path="@{classpath}"/>
|
||||||
</classpath>
|
</classpath>
|
||||||
@ -256,6 +271,12 @@ is divided into following sections:
|
|||||||
<condition else="-Xdebug" property="debug-args-line" value="-Xdebug -Xnoagent -Djava.compiler=none">
|
<condition else="-Xdebug" property="debug-args-line" value="-Xdebug -Xnoagent -Djava.compiler=none">
|
||||||
<istrue value="${have-jdk-older-than-1.4}"/>
|
<istrue value="${have-jdk-older-than-1.4}"/>
|
||||||
</condition>
|
</condition>
|
||||||
|
<condition else="dt_socket" property="debug-transport-by-os" value="dt_shmem">
|
||||||
|
<os family="windows"/>
|
||||||
|
</condition>
|
||||||
|
<condition else="${debug-transport-by-os}" property="debug-transport" value="${debug.transport}">
|
||||||
|
<isset property="debug.transport"/>
|
||||||
|
</condition>
|
||||||
</target>
|
</target>
|
||||||
<target depends="-init-debug-args" name="-init-macrodef-debug">
|
<target depends="-init-debug-args" name="-init-macrodef-debug">
|
||||||
<macrodef name="debug" uri="http://www.netbeans.org/ns/j2se-project/3">
|
<macrodef name="debug" uri="http://www.netbeans.org/ns/j2se-project/3">
|
||||||
@ -265,7 +286,9 @@ is divided into following sections:
|
|||||||
<sequential>
|
<sequential>
|
||||||
<java classname="@{classname}" dir="${work.dir}" fork="true">
|
<java classname="@{classname}" dir="${work.dir}" fork="true">
|
||||||
<jvmarg line="${debug-args-line}"/>
|
<jvmarg line="${debug-args-line}"/>
|
||||||
<jvmarg value="-Xrunjdwp:transport=dt_socket,address=${jpda.address}"/>
|
<jvmarg value="-Xrunjdwp:transport=${debug-transport},address=${jpda.address}"/>
|
||||||
|
<jvmarg value="-Dfile.encoding=${source.encoding}"/>
|
||||||
|
<redirector errorencoding="${source.encoding}" inputencoding="${source.encoding}" outputencoding="${source.encoding}"/>
|
||||||
<jvmarg line="${run.jvmargs}"/>
|
<jvmarg line="${run.jvmargs}"/>
|
||||||
<classpath>
|
<classpath>
|
||||||
<path path="@{classpath}"/>
|
<path path="@{classpath}"/>
|
||||||
@ -282,12 +305,15 @@ is divided into following sections:
|
|||||||
<target name="-init-macrodef-java">
|
<target name="-init-macrodef-java">
|
||||||
<macrodef name="java" uri="http://www.netbeans.org/ns/j2se-project/1">
|
<macrodef name="java" uri="http://www.netbeans.org/ns/j2se-project/1">
|
||||||
<attribute default="${main.class}" name="classname"/>
|
<attribute default="${main.class}" name="classname"/>
|
||||||
|
<attribute default="${run.classpath}" name="classpath"/>
|
||||||
<element name="customize" optional="true"/>
|
<element name="customize" optional="true"/>
|
||||||
<sequential>
|
<sequential>
|
||||||
<java classname="@{classname}" dir="${work.dir}" fork="true">
|
<java classname="@{classname}" dir="${work.dir}" fork="true">
|
||||||
|
<jvmarg value="-Dfile.encoding=${source.encoding}"/>
|
||||||
|
<redirector errorencoding="${source.encoding}" inputencoding="${source.encoding}" outputencoding="${source.encoding}"/>
|
||||||
<jvmarg line="${run.jvmargs}"/>
|
<jvmarg line="${run.jvmargs}"/>
|
||||||
<classpath>
|
<classpath>
|
||||||
<path path="${run.classpath}"/>
|
<path path="@{classpath}"/>
|
||||||
</classpath>
|
</classpath>
|
||||||
<syspropertyset>
|
<syspropertyset>
|
||||||
<propertyref prefix="run-sys-prop."/>
|
<propertyref prefix="run-sys-prop."/>
|
||||||
@ -312,6 +338,13 @@ is divided into following sections:
|
|||||||
===================
|
===================
|
||||||
-->
|
-->
|
||||||
<target depends="init" name="deps-jar" unless="no.deps"/>
|
<target depends="init" name="deps-jar" unless="no.deps"/>
|
||||||
|
<target depends="init,-check-automatic-build,-clean-after-automatic-build" name="-verify-automatic-build"/>
|
||||||
|
<target depends="init" name="-check-automatic-build">
|
||||||
|
<available file="${build.classes.dir}/.netbeans_automatic_build" property="netbeans.automatic.build"/>
|
||||||
|
</target>
|
||||||
|
<target depends="init" if="netbeans.automatic.build" name="-clean-after-automatic-build">
|
||||||
|
<antcall target="clean"/>
|
||||||
|
</target>
|
||||||
<target depends="init,deps-jar" name="-pre-pre-compile">
|
<target depends="init,deps-jar" name="-pre-pre-compile">
|
||||||
<mkdir dir="${build.classes.dir}"/>
|
<mkdir dir="${build.classes.dir}"/>
|
||||||
</target>
|
</target>
|
||||||
@ -320,10 +353,15 @@ is divided into following sections:
|
|||||||
<!-- You can override this target in the ../build.xml file. -->
|
<!-- You can override this target in the ../build.xml file. -->
|
||||||
</target>
|
</target>
|
||||||
<target if="do.depend.true" name="-compile-depend">
|
<target if="do.depend.true" name="-compile-depend">
|
||||||
<j2seproject3:depend/>
|
<pathconvert property="build.generated.subdirs">
|
||||||
|
<dirset dir="${build.generated.sources.dir}" erroronmissingdir="false">
|
||||||
|
<include name="*"/>
|
||||||
|
</dirset>
|
||||||
|
</pathconvert>
|
||||||
|
<j2seproject3:depend srcdir="${src.dir}:${build.generated.subdirs}"/>
|
||||||
</target>
|
</target>
|
||||||
<target depends="init,deps-jar,-pre-pre-compile,-pre-compile,-compile-depend" if="have.sources" name="-do-compile">
|
<target depends="init,deps-jar,-pre-pre-compile,-pre-compile,-compile-depend" if="have.sources" name="-do-compile">
|
||||||
<j2seproject3:javac/>
|
<j2seproject3:javac gensrcdir="${build.generated.sources.dir}"/>
|
||||||
<copy todir="${build.classes.dir}">
|
<copy todir="${build.classes.dir}">
|
||||||
<fileset dir="${src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
|
<fileset dir="${src.dir}" excludes="${build.classes.excludes},${excludes}" includes="${includes}"/>
|
||||||
</copy>
|
</copy>
|
||||||
@ -332,7 +370,7 @@ is divided into following sections:
|
|||||||
<!-- Empty placeholder for easier customization. -->
|
<!-- Empty placeholder for easier customization. -->
|
||||||
<!-- You can override this target in the ../build.xml file. -->
|
<!-- You can override this target in the ../build.xml file. -->
|
||||||
</target>
|
</target>
|
||||||
<target depends="init,deps-jar,-pre-pre-compile,-pre-compile,-do-compile,-post-compile" description="Compile project." name="compile"/>
|
<target depends="init,deps-jar,-verify-automatic-build,-pre-pre-compile,-pre-compile,-do-compile,-post-compile" description="Compile project." name="compile"/>
|
||||||
<target name="-pre-compile-single">
|
<target name="-pre-compile-single">
|
||||||
<!-- Empty placeholder for easier customization. -->
|
<!-- Empty placeholder for easier customization. -->
|
||||||
<!-- You can override this target in the ../build.xml file. -->
|
<!-- You can override this target in the ../build.xml file. -->
|
||||||
@ -340,13 +378,13 @@ is divided into following sections:
|
|||||||
<target depends="init,deps-jar,-pre-pre-compile" name="-do-compile-single">
|
<target depends="init,deps-jar,-pre-pre-compile" name="-do-compile-single">
|
||||||
<fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>
|
<fail unless="javac.includes">Must select some files in the IDE or set javac.includes</fail>
|
||||||
<j2seproject3:force-recompile/>
|
<j2seproject3:force-recompile/>
|
||||||
<j2seproject3:javac excludes="" includes="${javac.includes}" sourcepath="${src.dir}"/>
|
<j2seproject3:javac excludes="" gensrcdir="${build.generated.sources.dir}" includes="${javac.includes}" sourcepath="${src.dir}"/>
|
||||||
</target>
|
</target>
|
||||||
<target name="-post-compile-single">
|
<target name="-post-compile-single">
|
||||||
<!-- Empty placeholder for easier customization. -->
|
<!-- Empty placeholder for easier customization. -->
|
||||||
<!-- You can override this target in the ../build.xml file. -->
|
<!-- You can override this target in the ../build.xml file. -->
|
||||||
</target>
|
</target>
|
||||||
<target depends="init,deps-jar,-pre-pre-compile,-pre-compile-single,-do-compile-single,-post-compile-single" name="compile-single"/>
|
<target depends="init,deps-jar,-verify-automatic-build,-pre-pre-compile,-pre-compile-single,-do-compile-single,-post-compile-single" name="compile-single"/>
|
||||||
<!--
|
<!--
|
||||||
====================
|
====================
|
||||||
JAR BUILDING SECTION
|
JAR BUILDING SECTION
|
||||||
@ -406,11 +444,29 @@ is divided into following sections:
|
|||||||
<property location="${dist.jar}" name="dist.jar.resolved"/>
|
<property location="${dist.jar}" name="dist.jar.resolved"/>
|
||||||
<echo>java -jar "${dist.jar.resolved}"</echo>
|
<echo>java -jar "${dist.jar.resolved}"</echo>
|
||||||
</target>
|
</target>
|
||||||
|
<target depends="init,compile,-pre-pre-jar,-pre-jar" if="libs.CopyLibs.classpath" name="-do-jar-with-libraries-without-manifest" unless="manifest.available+main.class">
|
||||||
|
<property location="${build.classes.dir}" name="build.classes.dir.resolved"/>
|
||||||
|
<pathconvert property="run.classpath.without.build.classes.dir">
|
||||||
|
<path path="${run.classpath}"/>
|
||||||
|
<map from="${build.classes.dir.resolved}" to=""/>
|
||||||
|
</pathconvert>
|
||||||
|
<pathconvert pathsep=" " property="jar.classpath">
|
||||||
|
<path path="${run.classpath.without.build.classes.dir}"/>
|
||||||
|
<chainedmapper>
|
||||||
|
<flattenmapper/>
|
||||||
|
<globmapper from="*" to="lib/*"/>
|
||||||
|
</chainedmapper>
|
||||||
|
</pathconvert>
|
||||||
|
<taskdef classname="org.netbeans.modules.java.j2seproject.copylibstask.CopyLibs" classpath="${libs.CopyLibs.classpath}" name="copylibs"/>
|
||||||
|
<copylibs compress="${jar.compress}" jarfile="${dist.jar}" runtimeclasspath="${run.classpath.without.build.classes.dir}">
|
||||||
|
<fileset dir="${build.classes.dir}"/>
|
||||||
|
</copylibs>
|
||||||
|
</target>
|
||||||
<target name="-post-jar">
|
<target name="-post-jar">
|
||||||
<!-- Empty placeholder for easier customization. -->
|
<!-- Empty placeholder for easier customization. -->
|
||||||
<!-- You can override this target in the ../build.xml file. -->
|
<!-- You can override this target in the ../build.xml file. -->
|
||||||
</target>
|
</target>
|
||||||
<target depends="init,compile,-pre-jar,-do-jar-with-manifest,-do-jar-without-manifest,-do-jar-with-mainclass,-do-jar-with-libraries,-post-jar,jnlp" description="Build JAR." name="jar"/>
|
<target depends="init,compile,-pre-jar,-do-jar-with-manifest,-do-jar-without-manifest,-do-jar-with-mainclass,-do-jar-with-libraries,-do-jar-with-libraries-without-manifest,-post-jar,jnlp" description="Build JAR." name="jar"/>
|
||||||
<!--
|
<!--
|
||||||
=================
|
=================
|
||||||
EXECUTION SECTION
|
EXECUTION SECTION
|
||||||
@ -430,6 +486,10 @@ is divided into following sections:
|
|||||||
<fail unless="run.class">Must select one file in the IDE or set run.class</fail>
|
<fail unless="run.class">Must select one file in the IDE or set run.class</fail>
|
||||||
<j2seproject1:java classname="${run.class}"/>
|
<j2seproject1:java classname="${run.class}"/>
|
||||||
</target>
|
</target>
|
||||||
|
<target depends="init,-do-not-recompile,compile-test-single" name="run-test-with-main">
|
||||||
|
<fail unless="run.class">Must select one file in the IDE or set run.class</fail>
|
||||||
|
<j2seproject1:java classname="${run.class}" classpath="${run.test.classpath}"/>
|
||||||
|
</target>
|
||||||
<!--
|
<!--
|
||||||
=================
|
=================
|
||||||
DEBUGGING SECTION
|
DEBUGGING SECTION
|
||||||
@ -438,6 +498,9 @@ is divided into following sections:
|
|||||||
<target depends="init" if="netbeans.home" name="-debug-start-debugger">
|
<target depends="init" if="netbeans.home" name="-debug-start-debugger">
|
||||||
<j2seproject1:nbjpdastart name="${debug.class}"/>
|
<j2seproject1:nbjpdastart name="${debug.class}"/>
|
||||||
</target>
|
</target>
|
||||||
|
<target depends="init" if="netbeans.home" name="-debug-start-debugger-main-test">
|
||||||
|
<j2seproject1:nbjpdastart classpath="${debug.test.classpath}" name="${debug.class}"/>
|
||||||
|
</target>
|
||||||
<target depends="init,compile" name="-debug-start-debuggee">
|
<target depends="init,compile" name="-debug-start-debuggee">
|
||||||
<j2seproject3:debug>
|
<j2seproject3:debug>
|
||||||
<customize>
|
<customize>
|
||||||
@ -455,6 +518,11 @@ is divided into following sections:
|
|||||||
<j2seproject3:debug classname="${debug.class}"/>
|
<j2seproject3:debug classname="${debug.class}"/>
|
||||||
</target>
|
</target>
|
||||||
<target depends="init,-do-not-recompile,compile-single,-debug-start-debugger,-debug-start-debuggee-single" if="netbeans.home" name="debug-single"/>
|
<target depends="init,-do-not-recompile,compile-single,-debug-start-debugger,-debug-start-debuggee-single" if="netbeans.home" name="debug-single"/>
|
||||||
|
<target depends="init,compile-test-single" if="netbeans.home" name="-debug-start-debuggee-main-test">
|
||||||
|
<fail unless="debug.class">Must select one file in the IDE or set debug.class</fail>
|
||||||
|
<j2seproject3:debug classname="${debug.class}" classpath="${debug.test.classpath}"/>
|
||||||
|
</target>
|
||||||
|
<target depends="init,-do-not-recompile,compile-test-single,-debug-start-debugger-main-test,-debug-start-debuggee-main-test" if="netbeans.home" name="debug-test-with-main"/>
|
||||||
<target depends="init" name="-pre-debug-fix">
|
<target depends="init" name="-pre-debug-fix">
|
||||||
<fail unless="fix.includes">Must set fix.includes</fail>
|
<fail unless="fix.includes">Must set fix.includes</fail>
|
||||||
<property name="javac.includes" value="${fix.includes}.java"/>
|
<property name="javac.includes" value="${fix.includes}.java"/>
|
||||||
@ -477,6 +545,9 @@ is divided into following sections:
|
|||||||
<fileset dir="${src.dir}" excludes="${excludes}" includes="${includes}">
|
<fileset dir="${src.dir}" excludes="${excludes}" includes="${includes}">
|
||||||
<filename name="**/*.java"/>
|
<filename name="**/*.java"/>
|
||||||
</fileset>
|
</fileset>
|
||||||
|
<fileset dir="${build.generated.sources.dir}" erroronmissingdir="false">
|
||||||
|
<include name="**/*.java"/>
|
||||||
|
</fileset>
|
||||||
</javadoc>
|
</javadoc>
|
||||||
</target>
|
</target>
|
||||||
<target depends="init,-javadoc-build" if="netbeans.home" name="-javadoc-browse" unless="no.javadoc.preview">
|
<target depends="init,-javadoc-build" if="netbeans.home" name="-javadoc-browse" unless="no.javadoc.preview">
|
||||||
@ -538,7 +609,7 @@ is divided into following sections:
|
|||||||
<j2seproject3:junit testincludes="**/*Test.java"/>
|
<j2seproject3:junit testincludes="**/*Test.java"/>
|
||||||
</target>
|
</target>
|
||||||
<target depends="init,compile-test,-pre-test-run,-do-test-run" if="have.tests" name="-post-test-run">
|
<target depends="init,compile-test,-pre-test-run,-do-test-run" if="have.tests" name="-post-test-run">
|
||||||
<fail if="tests.failed">Some tests failed; see details above.</fail>
|
<fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>
|
||||||
</target>
|
</target>
|
||||||
<target depends="init" if="have.tests" name="test-report"/>
|
<target depends="init" if="have.tests" name="test-report"/>
|
||||||
<target depends="init" if="netbeans.home+have.tests" name="-test-browse"/>
|
<target depends="init" if="netbeans.home+have.tests" name="-test-browse"/>
|
||||||
@ -551,7 +622,7 @@ is divided into following sections:
|
|||||||
<j2seproject3:junit excludes="" includes="${test.includes}"/>
|
<j2seproject3:junit excludes="" includes="${test.includes}"/>
|
||||||
</target>
|
</target>
|
||||||
<target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single" if="have.tests" name="-post-test-run-single">
|
<target depends="init,compile-test-single,-pre-test-run-single,-do-test-run-single" if="have.tests" name="-post-test-run-single">
|
||||||
<fail if="tests.failed">Some tests failed; see details above.</fail>
|
<fail if="tests.failed" unless="ignore.failing.tests">Some tests failed; see details above.</fail>
|
||||||
</target>
|
</target>
|
||||||
<target depends="init,-do-not-recompile,compile-test-single,-pre-test-run-single,-do-test-run-single,-post-test-run-single" description="Run single unit test." name="test-single"/>
|
<target depends="init,-do-not-recompile,compile-test-single,-pre-test-run-single,-do-test-run-single,-post-test-run-single" description="Run single unit test." name="test-single"/>
|
||||||
<!--
|
<!--
|
||||||
|
@ -3,6 +3,6 @@ build.xml.script.CRC32=6e5ad54e
|
|||||||
build.xml.stylesheet.CRC32=be360661
|
build.xml.stylesheet.CRC32=be360661
|
||||||
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
|
# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml.
|
||||||
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
|
# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you.
|
||||||
nbproject/build-impl.xml.data.CRC32=52850847
|
nbproject/build-impl.xml.data.CRC32=618e720f
|
||||||
nbproject/build-impl.xml.script.CRC32=adeac2b5
|
nbproject/build-impl.xml.script.CRC32=70e39602
|
||||||
nbproject/build-impl.xml.stylesheet.CRC32=487672f9
|
nbproject/build-impl.xml.stylesheet.CRC32=5c621a33@1.26.2.45
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
|
compile.on.save=false
|
||||||
do.depend=false
|
do.depend=false
|
||||||
do.jar=true
|
do.jar=true
|
||||||
javac.debug=true
|
javac.debug=true
|
||||||
javadoc.preview=true
|
javadoc.preview=true
|
||||||
jaxws.endorsed.dir=C:\\Program Files\\NetBeans 6.5\\java2\\modules\\ext\\jaxws21\\api:C:\\Program Files\\NetBeans 6.5\\ide10\\modules\\ext\\jaxb\\api
|
jaxws.endorsed.dir=C:\\Program Files\\NetBeans 6.7.1\\java2\\modules\\ext\\jaxws21\\api:C:\\Program Files\\NetBeans 6.7.1\\ide11\\modules\\ext\\jaxb\\api
|
||||||
user.properties.file=C:\\Documents and Settings\\jbernard\\.netbeans\\6.5\\build.properties
|
user.properties.file=C:\\Documents and Settings\\jbernard\\.netbeans\\6.7\\build.properties
|
||||||
axis2.deploy.war=C:\\Program Files\\glassfish-v2ur2\\domains\\domain1\\autodeploy\\axis2.war
|
axis2.deploy.war=C:\\Program Files\\glassfish-v2ur2\\domains\\domain1\\autodeploy\\axis2.war
|
||||||
|
@ -8,6 +8,7 @@ build.classes.excludes=**/*.java,**/*.form
|
|||||||
# This directory is removed when the project is cleaned:
|
# This directory is removed when the project is cleaned:
|
||||||
build.dir=build
|
build.dir=build
|
||||||
build.generated.dir=${build.dir}/generated
|
build.generated.dir=${build.dir}/generated
|
||||||
|
build.generated.sources.dir=${build.dir}/generated-sources
|
||||||
# Only compile against the classpath explicitly listed here:
|
# Only compile against the classpath explicitly listed here:
|
||||||
build.sysclasspath=ignore
|
build.sysclasspath=ignore
|
||||||
build.test.classes.dir=${build.dir}/test/classes
|
build.test.classes.dir=${build.dir}/test/classes
|
||||||
@ -57,7 +58,7 @@ jnlp.enabled=false
|
|||||||
jnlp.icon=C:\\Documents and Settings\\jbernard\\My Documents\\Development\\TimeStamper\\src\\jdbernard\\timestamper\\resources\\icons\\appointment-new-16x16.png
|
jnlp.icon=C:\\Documents and Settings\\jbernard\\My Documents\\Development\\TimeStamper\\src\\jdbernard\\timestamper\\resources\\icons\\appointment-new-16x16.png
|
||||||
jnlp.offline-allowed=true
|
jnlp.offline-allowed=true
|
||||||
jnlp.signed=true
|
jnlp.signed=true
|
||||||
main.class=jdbernard.timestamper.TimeStamperApp
|
main.class=jdbernard.timestamper.gui.TimeStamperApp
|
||||||
manifest.file=manifest.mf
|
manifest.file=manifest.mf
|
||||||
meta.inf.dir=${src.dir}/META-INF
|
meta.inf.dir=${src.dir}/META-INF
|
||||||
platform.active=default_platform
|
platform.active=default_platform
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
</test-roots>
|
</test-roots>
|
||||||
</data>
|
</data>
|
||||||
<swingapp xmlns="http://www.netbeans.org/ns/form-swingapp/1">
|
<swingapp xmlns="http://www.netbeans.org/ns/form-swingapp/1">
|
||||||
<application-class name="jdbernard.timestamper.TimeStamperApp"/>
|
<application-class name="jdbernard.timestamper.gui.TimeStamperApp"/>
|
||||||
</swingapp>
|
</swingapp>
|
||||||
</configuration>
|
</configuration>
|
||||||
</project>
|
</project>
|
||||||
|
@ -1,77 +1,26 @@
|
|||||||
package jdbernard.timestamper;
|
package jdbernard.timestamper;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.io.BufferedReader;
|
||||||
import java.util.Scanner;
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import jdbernard.timestamper.core.TimelineProperties;
|
||||||
|
|
||||||
public class Test {
|
public class Test {
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
|
|
||||||
Timeline t = new Timeline();
|
System.out.println("Enter config file, terminate with EOF");
|
||||||
String choice;
|
BufferedReader bin = new BufferedReader(new InputStreamReader(System.in));
|
||||||
Scanner in = new Scanner(System.in);
|
|
||||||
|
|
||||||
boolean loop = true;
|
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
PrintWriter pw = new PrintWriter(baos);
|
||||||
|
|
||||||
while(loop) {
|
for(String line = bin.readLine(); line != null && !"EOF".equals(line); line = bin.readLine())
|
||||||
System.out.println("[N]ew Timestamp, [S]ave, [L]oad, [P]rint, [Q]uit: ");
|
pw.println(line);
|
||||||
choice = in.nextLine();
|
|
||||||
String filename;
|
|
||||||
|
|
||||||
switch (choice.toLowerCase().charAt(0)) {
|
pw.flush();
|
||||||
case 'n':
|
pw.close();
|
||||||
System.out.println("Enter time (HH:mm:ss) ");
|
|
||||||
Date d = new Date();
|
|
||||||
d.setHours(0);
|
|
||||||
d.setMinutes(0);
|
|
||||||
d.setSeconds(0);
|
|
||||||
d.setTime(d.getTime() + Timeline.shortFormat.parse(in.nextLine()).getTime());
|
|
||||||
|
|
||||||
System.out.println("Enter mark ('EOM' to end) ");
|
|
||||||
String line = "";
|
|
||||||
StringBuilder mark = new StringBuilder();
|
|
||||||
line = in.nextLine();
|
|
||||||
while (!line.endsWith("EOM")) {
|
|
||||||
mark.append(line);
|
|
||||||
line = in.nextLine();
|
|
||||||
}
|
|
||||||
mark.append(line.substring(0, line.length() - 3));
|
|
||||||
|
|
||||||
System.out.println("Enter notes ('EON' to end) ");
|
|
||||||
StringBuilder notes = new StringBuilder();
|
|
||||||
line = in.nextLine();
|
|
||||||
while (!line.endsWith("EON")) {
|
|
||||||
notes.append(line);
|
|
||||||
line = in.nextLine();
|
|
||||||
}
|
|
||||||
notes.append(line.substring(0, line.length() - 3));
|
|
||||||
|
|
||||||
t.addMarker(d, mark.toString(), notes.toString());
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 's':
|
|
||||||
System.out.print("Enter filename to save: ");
|
|
||||||
filename = in.nextLine();
|
|
||||||
|
|
||||||
Timeline.writeToFile(filename, t);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'l':
|
|
||||||
System.out.println("Enter filename to load: ");
|
|
||||||
filename = in.nextLine();
|
|
||||||
|
|
||||||
t = Timeline.readFromFile(filename);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'p':
|
|
||||||
Timeline.writeToStream(System.out, t);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'q':
|
|
||||||
loop = false;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,281 +0,0 @@
|
|||||||
package jdbernard.timestamper;
|
|
||||||
|
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.FileNotFoundException;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.io.OutputStreamWriter;
|
|
||||||
import java.io.Writer;
|
|
||||||
|
|
||||||
import java.text.ParseException;
|
|
||||||
import java.text.SimpleDateFormat;
|
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Scanner;
|
|
||||||
import java.util.TreeSet;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Jonathan Bernard <jdbernard@gmail.com>
|
|
||||||
* A Timeline object represents a series of markers at specific points in time.
|
|
||||||
* The markers have a name or symbol (the 'mark') and notes associated with that
|
|
||||||
* mark.
|
|
||||||
*/
|
|
||||||
public class Timeline implements Iterable<Timeline.TimelineMarker> {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This represents a marker on the timeline.
|
|
||||||
* The date of the marker and the mark cannot be changed once assigned.
|
|
||||||
*/
|
|
||||||
public class TimelineMarker implements Comparable<TimelineMarker> {
|
|
||||||
private final Date timestamp;
|
|
||||||
private final String mark;
|
|
||||||
private String notes;
|
|
||||||
|
|
||||||
public TimelineMarker(Date timestamp, String mark, String notes) {
|
|
||||||
if (timestamp == null || mark == null)
|
|
||||||
throw new IllegalArgumentException("Null timestamp or mark"
|
|
||||||
+ " is not permitted.");
|
|
||||||
|
|
||||||
this.timestamp = timestamp;
|
|
||||||
this.mark = mark;
|
|
||||||
this.notes = notes;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Date getTimestamp() { return timestamp; }
|
|
||||||
|
|
||||||
public String getMark() { return mark; }
|
|
||||||
|
|
||||||
public String getNotes() { return notes; }
|
|
||||||
|
|
||||||
public void setNotes(String notes) { this.notes = notes; }
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int compareTo(TimelineMarker that) {
|
|
||||||
if (that == null) return Integer.MAX_VALUE;
|
|
||||||
|
|
||||||
return this.timestamp.compareTo(that.timestamp);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object that) {
|
|
||||||
if (that == null) return false;
|
|
||||||
if (!(that instanceof TimelineMarker)) return false;
|
|
||||||
|
|
||||||
return this.timestamp.equals(((TimelineMarker)that).timestamp);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
int hash = 5;
|
|
||||||
hash = 53 * hash + (this.timestamp != null ? this.timestamp.hashCode() : 0);
|
|
||||||
return hash;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private static enum ReadingState {
|
|
||||||
NewMarker,
|
|
||||||
StartMark,
|
|
||||||
ReadMark,
|
|
||||||
StartNotes,
|
|
||||||
ReadNotes,
|
|
||||||
EndMarker
|
|
||||||
};
|
|
||||||
|
|
||||||
public static SimpleDateFormat shortFormat = new SimpleDateFormat("HH:mm:ss");
|
|
||||||
public static SimpleDateFormat longFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy");
|
|
||||||
|
|
||||||
private static int lineWrap = 78;
|
|
||||||
private TreeSet<TimelineMarker> timelineList;
|
|
||||||
|
|
||||||
public Timeline() {
|
|
||||||
timelineList = new TreeSet<TimelineMarker>();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addMarker(Date timestamp, String name, String notes) {
|
|
||||||
timelineList.add(new TimelineMarker(timestamp, name, notes));
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getLastName(Date timestamp) {
|
|
||||||
TimelineMarker lastMarker = getLastMarker(timestamp);
|
|
||||||
return (lastMarker == null ?
|
|
||||||
"No previous marker." :
|
|
||||||
lastMarker.getMark());
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getLastNotes(Date timestamp) {
|
|
||||||
TimelineMarker lastMarker = getLastMarker(timestamp);
|
|
||||||
return (lastMarker == null ?
|
|
||||||
"No previous marker." :
|
|
||||||
lastMarker.getNotes());
|
|
||||||
}
|
|
||||||
|
|
||||||
public TimelineMarker getLastMarker(Date timestamp) {
|
|
||||||
TimelineMarker lastMarker = null;
|
|
||||||
for (TimelineMarker tm : timelineList) {
|
|
||||||
if (tm.getTimestamp().after(timestamp))
|
|
||||||
break;
|
|
||||||
lastMarker = tm;
|
|
||||||
}
|
|
||||||
|
|
||||||
return lastMarker;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeMarker(TimelineMarker marker) {
|
|
||||||
timelineList.remove(marker);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Iterator<TimelineMarker> iterator() {
|
|
||||||
return timelineList.iterator();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Write the a representation of the timeline to a stream. This method
|
|
||||||
* flushes the stream after it finishes writing but does not close the
|
|
||||||
* stream.
|
|
||||||
* @param stream An open stream to write the timeline representation to.
|
|
||||||
* @param timeline The timeline to write.
|
|
||||||
* @throws java.io.IOException
|
|
||||||
*/
|
|
||||||
public static void writeToStream(OutputStream stream, Timeline timeline)
|
|
||||||
throws IOException {
|
|
||||||
Writer out = new OutputStreamWriter(stream);
|
|
||||||
for (TimelineMarker tm : timeline.timelineList) {
|
|
||||||
|
|
||||||
// write timestamp
|
|
||||||
out.write(longFormat.format(tm.getTimestamp()) + "\n");
|
|
||||||
|
|
||||||
// write mark
|
|
||||||
String mark = tm.getMark().replace('\n', '\u0000');
|
|
||||||
if (mark.length() < lineWrap) out.write(mark + "\n");
|
|
||||||
else {
|
|
||||||
// wrap lines if neccessary
|
|
||||||
int i;
|
|
||||||
for (i = 0; (i + lineWrap) < mark.length(); i+=lineWrap)
|
|
||||||
out.write(mark.substring(i, i+lineWrap) + "\\\n");
|
|
||||||
if (i < mark.length())
|
|
||||||
out.write(mark.substring(i, mark.length()) + "\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
// write notes
|
|
||||||
String notes = tm.getNotes().replace('\n', '\u0000');
|
|
||||||
if (notes.length() < lineWrap) out.write(notes + "\n");
|
|
||||||
else {
|
|
||||||
// wrap lines if neccessary
|
|
||||||
int i;
|
|
||||||
for (i = 0; (i + lineWrap) < notes.length(); i+=lineWrap)
|
|
||||||
out.write(notes.substring(i, i+lineWrap) + "\\\n");
|
|
||||||
if (i < notes.length())
|
|
||||||
out.write(notes.substring(i, notes.length()) + "\n");
|
|
||||||
}
|
|
||||||
out.write("\n");
|
|
||||||
}
|
|
||||||
out.flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Write a representation of a timeline to a file.
|
|
||||||
* @param filename The path to the destination file.
|
|
||||||
* @param timeline The timeline to write.
|
|
||||||
* @throws java.io.IOException
|
|
||||||
* @throws java.io.FileNotFoundException
|
|
||||||
*/
|
|
||||||
public static void writeToFile(String filename, Timeline timeline)
|
|
||||||
throws IOException, FileNotFoundException {
|
|
||||||
OutputStream out = new FileOutputStream(filename);
|
|
||||||
writeToStream(out, timeline);
|
|
||||||
out.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a <b>Timeline</b> instance from a given stream.
|
|
||||||
* @param stream The stream to read from.
|
|
||||||
* @return A new <b>Timeline</b> instance specified by the input stream.
|
|
||||||
* @throws java.io.IOException
|
|
||||||
* @throws java.io.FileNotFoundException
|
|
||||||
*/
|
|
||||||
public static Timeline readFromStream(InputStream stream)
|
|
||||||
throws IOException, FileNotFoundException {
|
|
||||||
Scanner in = new Scanner(stream);
|
|
||||||
Timeline timeline = new Timeline();
|
|
||||||
|
|
||||||
ReadingState readingState = ReadingState.NewMarker;
|
|
||||||
Date d = null;
|
|
||||||
StringBuilder mark = null;
|
|
||||||
StringBuilder notes = null;
|
|
||||||
String line;
|
|
||||||
int lineNumber = 0;
|
|
||||||
|
|
||||||
while (in.hasNextLine()) {
|
|
||||||
line = in.nextLine();
|
|
||||||
lineNumber++;
|
|
||||||
|
|
||||||
switch (readingState) {
|
|
||||||
|
|
||||||
case NewMarker:
|
|
||||||
try { d = longFormat.parse(line); }
|
|
||||||
catch (ParseException pe) {
|
|
||||||
throw new IOException("Error parsing timeline file at line "
|
|
||||||
+ lineNumber + ": expected a new marker date but could not parse"
|
|
||||||
+ " the date. Error: " + pe.getLocalizedMessage());
|
|
||||||
}
|
|
||||||
readingState = ReadingState.StartMark;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case StartMark:
|
|
||||||
mark = new StringBuilder();
|
|
||||||
// fall through to ReadMark
|
|
||||||
case ReadMark:
|
|
||||||
if (line.endsWith("\\")) {
|
|
||||||
readingState = ReadingState.ReadMark;
|
|
||||||
line = line.substring(0, line.length() - 1);
|
|
||||||
}
|
|
||||||
else readingState = ReadingState.StartNotes;
|
|
||||||
mark.append(line);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case StartNotes:
|
|
||||||
notes = new StringBuilder();
|
|
||||||
// fall through to ReadNotes
|
|
||||||
case ReadNotes:
|
|
||||||
if (line.endsWith("\\")) {
|
|
||||||
readingState = ReadingState.ReadNotes;
|
|
||||||
line = line.substring(0, line.length() - 1);
|
|
||||||
}
|
|
||||||
else readingState = ReadingState.EndMarker;
|
|
||||||
notes.append(line);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EndMarker:
|
|
||||||
String sMark = mark.toString().replace('\u0000', '\n');
|
|
||||||
String sNotes = notes.toString().replace('\u0000', '\n');
|
|
||||||
timeline.addMarker(d, sMark, sNotes);
|
|
||||||
readingState = ReadingState.NewMarker;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//if (readingState != ReadingState.NewMarker)
|
|
||||||
//TODO: warning of invalid marker file
|
|
||||||
|
|
||||||
return timeline;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a Timline instance from a file representation.
|
|
||||||
* @param filename The path of the source file.
|
|
||||||
* @return The new Timeline instance.
|
|
||||||
* @throws java.io.IOException
|
|
||||||
* @throws java.io.FileNotFoundException
|
|
||||||
*/
|
|
||||||
public static Timeline readFromFile(String filename)
|
|
||||||
throws IOException, FileNotFoundException {
|
|
||||||
InputStream in = new FileInputStream(filename);
|
|
||||||
Timeline t = readFromStream(in);
|
|
||||||
in.close();
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
}
|
|
21
src/jdbernard/timestamper/core/AuthenticationException.java
Normal file
21
src/jdbernard/timestamper/core/AuthenticationException.java
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package jdbernard.timestamper.core;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Jonathan Bernard ({@literal jonathan.bernard@gemalto.com})
|
||||||
|
*/
|
||||||
|
public class AuthenticationException extends IOException {
|
||||||
|
|
||||||
|
public AuthenticationException() { super(); }
|
||||||
|
|
||||||
|
public AuthenticationException(String message) { super(message); }
|
||||||
|
|
||||||
|
public AuthenticationException(Throwable t) { super(t); }
|
||||||
|
|
||||||
|
public AuthenticationException(String message, Throwable t) {
|
||||||
|
super(message, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
64
src/jdbernard/timestamper/core/FileTimelineSource.java
Normal file
64
src/jdbernard/timestamper/core/FileTimelineSource.java
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
package jdbernard.timestamper.core;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Jonathan Bernard ({@literal jonathan.bernard@gemalto.com})
|
||||||
|
*/
|
||||||
|
public class FileTimelineSource extends TimelineSource {
|
||||||
|
|
||||||
|
private File file;
|
||||||
|
|
||||||
|
public FileTimelineSource(URI uri) {
|
||||||
|
super(uri);
|
||||||
|
this.file = new File(uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** * {@inheritDoc } */
|
||||||
|
public Timeline read() throws IOException {
|
||||||
|
FileInputStream fin = new FileInputStream(file);
|
||||||
|
Timeline t = StreamBasedTimelineSource.readFromStream(fin);
|
||||||
|
fin.close();
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Timeline readWithComments(OutputStream commentStream)
|
||||||
|
throws IOException {
|
||||||
|
FileInputStream fin = new FileInputStream(file);
|
||||||
|
Timeline t = StreamBasedTimelineSource.readFromStream(fin, commentStream);
|
||||||
|
fin.close();
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** * {@inheritDoc } */
|
||||||
|
public void persist(Timeline t) throws IOException {
|
||||||
|
FileOutputStream fout = new FileOutputStream(file);
|
||||||
|
StreamBasedTimelineSource.writeToStream(fout, t);
|
||||||
|
fout.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAuthenticated() {
|
||||||
|
File dir = file.getParentFile();
|
||||||
|
return (dir.canRead() && dir.canWrite());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void authenticate() throws AuthenticationException {
|
||||||
|
File dir = file.getParentFile();
|
||||||
|
if (!dir.canRead())
|
||||||
|
throw new AuthenticationException("This FileTimelineSource does not"
|
||||||
|
+ " have read access to the parent directory for the "
|
||||||
|
+ "given file (" + file.getAbsolutePath() + ".");
|
||||||
|
|
||||||
|
if (!dir.canWrite())
|
||||||
|
throw new AuthenticationException("This FileTimelineSource does not"
|
||||||
|
+ " have write access to the parent directory for the "
|
||||||
|
+ "given file (" + file.getAbsolutePath() + ".");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
203
src/jdbernard/timestamper/core/StreamBasedTimelineSource.java
Normal file
203
src/jdbernard/timestamper/core/StreamBasedTimelineSource.java
Normal file
@ -0,0 +1,203 @@
|
|||||||
|
package jdbernard.timestamper.core;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.FileNotFoundException;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.io.OutputStreamWriter;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.io.Writer;
|
||||||
|
import java.text.ParseException;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.Scanner;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Jonathan Bernard ({@literal jonathan.bernard@gemalto.com})
|
||||||
|
*/
|
||||||
|
public class StreamBasedTimelineSource extends TimelineSource {
|
||||||
|
|
||||||
|
private static final int lineWrap = 78;
|
||||||
|
|
||||||
|
private static enum ReadingState {
|
||||||
|
NewMarker,
|
||||||
|
StartMark,
|
||||||
|
ReadMark,
|
||||||
|
StartNotes,
|
||||||
|
ReadNotes,
|
||||||
|
EndMarker
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
private InputStream in;
|
||||||
|
private OutputStream out;
|
||||||
|
private ByteArrayOutputStream comments;
|
||||||
|
|
||||||
|
public StreamBasedTimelineSource(InputStream inStream,
|
||||||
|
OutputStream outStream) {
|
||||||
|
super(null);
|
||||||
|
this.in = inStream;
|
||||||
|
this.out = outStream;
|
||||||
|
this.comments = new ByteArrayOutputStream();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc } */
|
||||||
|
public Timeline read() throws IOException {
|
||||||
|
return readFromStream(in, comments);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc } */
|
||||||
|
public void persist(Timeline t) throws IOException {
|
||||||
|
writeToStream(out, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void authenticate() throws AuthenticationException { }
|
||||||
|
public boolean isAuthenticated() { return true; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows a user to extract the comments from the last parsed file.
|
||||||
|
* @return a <code>byte[]</code> representing the portions of the file
|
||||||
|
* which were comments.
|
||||||
|
*/
|
||||||
|
public byte[] getCommentBytes() {
|
||||||
|
return comments.toByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write the a representation of the timeline to a stream. This method
|
||||||
|
* flushes the stream after it finishes writing but does not close the
|
||||||
|
* stream.
|
||||||
|
* @param stream An open stream to write the timeline representation to.
|
||||||
|
* @param timeline The timeline to write.
|
||||||
|
* @throws java.io.IOException
|
||||||
|
*/
|
||||||
|
public static void writeToStream(OutputStream stream, Timeline timeline)
|
||||||
|
throws IOException {
|
||||||
|
Writer out = new OutputStreamWriter(stream);
|
||||||
|
for (TimelineMarker tm : timeline) {
|
||||||
|
|
||||||
|
// write timestamp
|
||||||
|
out.write(Timeline.longFormat.format(tm.getTimestamp()) + "\n");
|
||||||
|
|
||||||
|
// write mark
|
||||||
|
String mark = tm.getMark().replace('\n', '\u0000');
|
||||||
|
if (mark.length() < lineWrap) out.write(mark + "\n");
|
||||||
|
else {
|
||||||
|
// wrap lines if neccessary
|
||||||
|
int i;
|
||||||
|
for (i = 0; (i + lineWrap) < mark.length(); i+=lineWrap)
|
||||||
|
out.write(mark.substring(i, i+lineWrap) + "\\\n");
|
||||||
|
if (i < mark.length())
|
||||||
|
out.write(mark.substring(i, mark.length()) + "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// write notes
|
||||||
|
String notes = tm.getNotes().replace('\n', '\u0000');
|
||||||
|
if (notes.length() < lineWrap) out.write(notes + "\n");
|
||||||
|
else {
|
||||||
|
// wrap lines if neccessary
|
||||||
|
int i;
|
||||||
|
for (i = 0; (i + lineWrap) < notes.length(); i+=lineWrap)
|
||||||
|
out.write(notes.substring(i, i+lineWrap) + "\\\n");
|
||||||
|
if (i < notes.length())
|
||||||
|
out.write(notes.substring(i, notes.length()) + "\n");
|
||||||
|
}
|
||||||
|
out.write("\n");
|
||||||
|
}
|
||||||
|
out.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a <b>Timeline</b> instance from a given stream.
|
||||||
|
* @param stream The stream to read from.
|
||||||
|
* @return A new <b>Timeline</b> instance specified by the input stream.
|
||||||
|
* @throws java.io.IOException
|
||||||
|
* @throws java.io.FileNotFoundException
|
||||||
|
*/
|
||||||
|
public static Timeline readFromStream(InputStream stream)
|
||||||
|
throws IOException {
|
||||||
|
return readFromStream(stream, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a <b>Timeline</b> instance from a given stream.
|
||||||
|
* @param stream The stream to read from.
|
||||||
|
* @param commentStream A stream to write comments found in the file. This
|
||||||
|
* parameter may be <b>null</b>, in which case comments are ignored.
|
||||||
|
* @return A new <b>Timeline</b> instance specified by the input stream.
|
||||||
|
* @throws java.io.IOException
|
||||||
|
* @throws java.io.FileNotFoundException
|
||||||
|
*/
|
||||||
|
public static Timeline readFromStream(InputStream stream,
|
||||||
|
OutputStream commentStream) throws IOException {
|
||||||
|
Scanner in = new Scanner(stream);
|
||||||
|
Timeline timeline = new Timeline();
|
||||||
|
PrintWriter commentsWriter = commentStream == null ?
|
||||||
|
null : new PrintWriter(commentStream);
|
||||||
|
|
||||||
|
ReadingState readingState = ReadingState.NewMarker;
|
||||||
|
Date d = null;
|
||||||
|
StringBuilder mark = null;
|
||||||
|
StringBuilder notes = null;
|
||||||
|
String line;
|
||||||
|
int lineNumber = 0;
|
||||||
|
|
||||||
|
while (in.hasNextLine()) {
|
||||||
|
line = in.nextLine();
|
||||||
|
lineNumber++;
|
||||||
|
|
||||||
|
// line is a comment
|
||||||
|
if (line.startsWith("#")) {
|
||||||
|
if (commentsWriter != null) commentsWriter.println(line);
|
||||||
|
continue; // don't parse this line as part of the timeline
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (readingState) {
|
||||||
|
|
||||||
|
case NewMarker:
|
||||||
|
try { d = Timeline.longFormat.parse(line); }
|
||||||
|
catch (ParseException pe) {
|
||||||
|
throw new IOException("Error parsing timeline file at line "
|
||||||
|
+ lineNumber + ": expected a new marker date but could not parse"
|
||||||
|
+ " the date. Error: " + pe.getLocalizedMessage());
|
||||||
|
}
|
||||||
|
readingState = ReadingState.StartMark;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case StartMark:
|
||||||
|
mark = new StringBuilder();
|
||||||
|
// fall through to ReadMark
|
||||||
|
case ReadMark:
|
||||||
|
if (line.endsWith("\\")) {
|
||||||
|
readingState = ReadingState.ReadMark;
|
||||||
|
line = line.substring(0, line.length() - 1);
|
||||||
|
}
|
||||||
|
else readingState = ReadingState.StartNotes;
|
||||||
|
mark.append(line);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case StartNotes:
|
||||||
|
notes = new StringBuilder();
|
||||||
|
// fall through to ReadNotes
|
||||||
|
case ReadNotes:
|
||||||
|
if (line.endsWith("\\")) {
|
||||||
|
readingState = ReadingState.ReadNotes;
|
||||||
|
line = line.substring(0, line.length() - 1);
|
||||||
|
}
|
||||||
|
else readingState = ReadingState.EndMarker;
|
||||||
|
notes.append(line);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EndMarker:
|
||||||
|
String sMark = mark.toString().replace('\u0000', '\n');
|
||||||
|
String sNotes = notes.toString().replace('\u0000', '\n');
|
||||||
|
timeline.addMarker(d, sMark, sNotes);
|
||||||
|
readingState = ReadingState.NewMarker;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return timeline;
|
||||||
|
}
|
||||||
|
}
|
129
src/jdbernard/timestamper/core/SyncTarget.java
Normal file
129
src/jdbernard/timestamper/core/SyncTarget.java
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
package jdbernard.timestamper.core;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Timer;
|
||||||
|
import java.util.TimerTask;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Jonathan Bernard ({@literal jonathan.bernard@gemalto.com})
|
||||||
|
*/
|
||||||
|
public class SyncTarget {
|
||||||
|
|
||||||
|
protected final TimelineSource source;
|
||||||
|
protected final Timeline localTimeline;
|
||||||
|
protected final String name;
|
||||||
|
|
||||||
|
protected Timer syncTimer;
|
||||||
|
protected SyncTask syncTask;
|
||||||
|
|
||||||
|
protected long syncInterval= 30 * 60 * 1000; // 30 minutes converted to ms
|
||||||
|
protected boolean pushEnabled = true;
|
||||||
|
protected boolean pullEnabled = true;
|
||||||
|
protected boolean syncOnExit = true;
|
||||||
|
|
||||||
|
protected class SyncTask extends TimerTask {
|
||||||
|
@Override public void run() {
|
||||||
|
synchronized(this) {
|
||||||
|
try { SyncTarget.this.sync(); }
|
||||||
|
catch (IOException ioe) { /* TODO */ }
|
||||||
|
}}}
|
||||||
|
|
||||||
|
protected SyncTarget(String name, TimelineSource source,
|
||||||
|
Timeline localTimeline) {
|
||||||
|
this.name = name;
|
||||||
|
this.source = source;
|
||||||
|
this.localTimeline = localTimeline;
|
||||||
|
|
||||||
|
syncTimer = new Timer(source.toString() + " sync-timer");
|
||||||
|
syncTask = new SyncTask();
|
||||||
|
syncTimer.schedule(syncTask, syncInterval, syncInterval);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sync the local timeline with the remote timeline represented by this
|
||||||
|
* SyncTarget object.
|
||||||
|
* @return <b>true</b> if the two timelines were out of sync and have
|
||||||
|
* been put into synch, <b>false</b> if the timelines were already in
|
||||||
|
* sync and no action was requried.
|
||||||
|
* @throws IOException if there is an error communicating with the remote
|
||||||
|
* timeline. This includes AuthenticationException.
|
||||||
|
*/
|
||||||
|
protected boolean sync() throws IOException {
|
||||||
|
assert (pullEnabled || pushEnabled);
|
||||||
|
|
||||||
|
Timeline remoteTimeline;
|
||||||
|
boolean syncPerformed = false;
|
||||||
|
|
||||||
|
// make sure we're authenticated to whatever source we're using
|
||||||
|
if (!SyncTarget.this.source.isAuthenticated()) {
|
||||||
|
SyncTarget.this.source.authenticate();
|
||||||
|
}
|
||||||
|
|
||||||
|
// try to copy the remote timeline locally
|
||||||
|
remoteTimeline = SyncTarget.this.source.read();
|
||||||
|
|
||||||
|
// if we are pulling markers from the remote line
|
||||||
|
if (SyncTarget.this.pullEnabled) {
|
||||||
|
// get all markers in the remote timeline not in the local one
|
||||||
|
Collection<TimelineMarker> diffFromRemote =
|
||||||
|
remoteTimeline.difference(localTimeline);
|
||||||
|
|
||||||
|
if (diffFromRemote.size() != 0) {
|
||||||
|
// add all markers in the remote tline to the local one
|
||||||
|
localTimeline.addAll(diffFromRemote);
|
||||||
|
syncPerformed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we are pushing markers to the remote timeline
|
||||||
|
if (SyncTarget.this.pushEnabled) {
|
||||||
|
// get all markers in the local timeline but not in the remote
|
||||||
|
Collection<TimelineMarker> diffFromLocal =
|
||||||
|
localTimeline.difference(remoteTimeline);
|
||||||
|
|
||||||
|
if (diffFromLocal.size() != 0) {
|
||||||
|
// add the difference to the remote timeline
|
||||||
|
remoteTimeline.addAll(diffFromLocal);
|
||||||
|
syncPerformed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return syncPerformed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() { return name; }
|
||||||
|
|
||||||
|
public TimelineSource getSource() { return source; }
|
||||||
|
|
||||||
|
public synchronized void setSyncInterval(long syncInterval) {
|
||||||
|
this.syncInterval= syncInterval;
|
||||||
|
|
||||||
|
syncTask.cancel();
|
||||||
|
syncTask = new SyncTask();
|
||||||
|
|
||||||
|
syncTimer.purge();
|
||||||
|
syncTimer.schedule(syncTask, syncInterval, syncInterval);
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getSyncInterval() { return syncInterval; }
|
||||||
|
|
||||||
|
public synchronized void enablePush(boolean enablePush) {
|
||||||
|
this.pullEnabled = enablePush;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isPushEnabled() { return pushEnabled; }
|
||||||
|
|
||||||
|
public synchronized void enablePull(boolean enablePull) {
|
||||||
|
this.pullEnabled = enablePull;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isPullEnabled() { return pullEnabled; }
|
||||||
|
|
||||||
|
public synchronized void enableSyncOnExit(boolean syncOnExit) {
|
||||||
|
this.syncOnExit = syncOnExit;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isSyncOnExitEnabled() { return syncOnExit; }
|
||||||
|
}
|
95
src/jdbernard/timestamper/core/Timeline.java
Normal file
95
src/jdbernard/timestamper/core/Timeline.java
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
package jdbernard.timestamper.core;
|
||||||
|
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.TreeSet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Jonathan Bernard {@literal <jdbernard@gmail.com>}
|
||||||
|
* A Timeline object represents a series of markers at specific points in time.
|
||||||
|
* The markers have a name or symbol (the 'mark') and notes associated with that
|
||||||
|
* mark.
|
||||||
|
*/
|
||||||
|
public class Timeline implements Iterable<TimelineMarker> {
|
||||||
|
|
||||||
|
public static SimpleDateFormat shortFormat = new SimpleDateFormat("HH:mm:ss");
|
||||||
|
public static SimpleDateFormat longFormat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy");
|
||||||
|
private TreeSet<TimelineMarker> timelineList;
|
||||||
|
|
||||||
|
public Timeline() {
|
||||||
|
timelineList = new TreeSet<TimelineMarker>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addMarker(Date timestamp, String name, String notes) {
|
||||||
|
timelineList.add(new TimelineMarker(timestamp, name, notes));
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLastName(Date timestamp) {
|
||||||
|
TimelineMarker lastMarker = getLastMarker(timestamp);
|
||||||
|
return (lastMarker == null ?
|
||||||
|
"No previous marker." :
|
||||||
|
lastMarker.getMark());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLastNotes(Date timestamp) {
|
||||||
|
TimelineMarker lastMarker = getLastMarker(timestamp);
|
||||||
|
return (lastMarker == null ?
|
||||||
|
"No previous marker." :
|
||||||
|
lastMarker.getNotes());
|
||||||
|
}
|
||||||
|
|
||||||
|
public TimelineMarker getLastMarker(Date timestamp) {
|
||||||
|
TimelineMarker lastMarker = null;
|
||||||
|
for (TimelineMarker tm : timelineList) {
|
||||||
|
if (tm.getTimestamp().after(timestamp))
|
||||||
|
break;
|
||||||
|
lastMarker = tm;
|
||||||
|
}
|
||||||
|
|
||||||
|
return lastMarker;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeMarker(TimelineMarker marker) {
|
||||||
|
timelineList.remove(marker);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Iterator<TimelineMarker> iterator() {
|
||||||
|
return timelineList.iterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the difference of the this timeline relative to another timeline.
|
||||||
|
* More specifically, return the set of all
|
||||||
|
* {@link jdbernard.timestamper.core.TimelineMarker}s that are present in
|
||||||
|
* the <b>this</b> timeline but not present in the given timeline.
|
||||||
|
* timeline.
|
||||||
|
* @param t
|
||||||
|
* @return A collection representing the TimelineMarkers present in
|
||||||
|
* <b>this</b> timeline but not in the given timeline.
|
||||||
|
*/
|
||||||
|
public Collection<TimelineMarker> difference(Timeline t) {
|
||||||
|
TreeSet<TimelineMarker> difference = new TreeSet<TimelineMarker>();
|
||||||
|
|
||||||
|
for (TimelineMarker tm : timelineList) {
|
||||||
|
if (!t.timelineList.contains(tm))
|
||||||
|
difference.add(tm);
|
||||||
|
}
|
||||||
|
|
||||||
|
return difference;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addAll(Timeline t) {
|
||||||
|
for (TimelineMarker tm : t) {
|
||||||
|
if (!timelineList.contains(tm))
|
||||||
|
timelineList.add(tm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addAll(Collection<TimelineMarker> c) {
|
||||||
|
timelineList.addAll(c);
|
||||||
|
}
|
||||||
|
}
|
63
src/jdbernard/timestamper/core/TimelineMarker.java
Normal file
63
src/jdbernard/timestamper/core/TimelineMarker.java
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
package jdbernard.timestamper.core;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Jonathan Bernard {@literal <jdbernard@gmail.com>}
|
||||||
|
* This represents a marker on the timeline.
|
||||||
|
* The date of the marker and the mark cannot be changed once assigned.
|
||||||
|
*/
|
||||||
|
public class TimelineMarker implements Comparable<TimelineMarker> {
|
||||||
|
|
||||||
|
private final Date timestamp;
|
||||||
|
private final String mark;
|
||||||
|
private String notes;
|
||||||
|
|
||||||
|
public TimelineMarker(Date timestamp, String mark, String notes) {
|
||||||
|
if (timestamp == null || mark == null)
|
||||||
|
throw new IllegalArgumentException("Null timestamp or mark"
|
||||||
|
+ " is not permitted.");
|
||||||
|
|
||||||
|
this.timestamp = timestamp;
|
||||||
|
this.mark = mark;
|
||||||
|
this.notes = notes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Date getTimestamp() { return timestamp; }
|
||||||
|
|
||||||
|
public String getMark() { return mark; }
|
||||||
|
|
||||||
|
public String getNotes() { return notes; }
|
||||||
|
|
||||||
|
public void setNotes(String notes) { this.notes = notes; }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(TimelineMarker that) {
|
||||||
|
if (that == null) return Integer.MAX_VALUE;
|
||||||
|
|
||||||
|
int val = this.timestamp.compareTo(that.timestamp);
|
||||||
|
if (val == 0) val = this.mark.compareTo(that.mark);
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (o == null) return false;
|
||||||
|
if (!(o instanceof TimelineMarker)) return false;
|
||||||
|
|
||||||
|
TimelineMarker that = (TimelineMarker) o;
|
||||||
|
return this.timestamp.equals(that.timestamp) &&
|
||||||
|
this.mark.equals(that.mark);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int hash = 7;
|
||||||
|
hash = 61 * hash + (this.timestamp != null ? this.timestamp.hashCode() : 0);
|
||||||
|
hash = 61 * hash + (this.mark != null ? this.mark.hashCode() : 0);
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,13 +1,17 @@
|
|||||||
package jdbernard.timestamper.core;
|
package jdbernard.timestamper.core;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStreamReader;
|
||||||
import java.io.OutputStream;
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.Scanner;
|
import java.util.Properties;
|
||||||
import java.util.StringTokenizer;
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -16,145 +20,144 @@ import java.util.StringTokenizer;
|
|||||||
*/
|
*/
|
||||||
public class TimelineProperties {
|
public class TimelineProperties {
|
||||||
|
|
||||||
|
public static final String LOCAL_TIMELINE_URI = "timeline.uri";
|
||||||
|
public static final String REMOTE_TIMELINE_BASE = "remote.timeline.";
|
||||||
|
|
||||||
|
private static final Pattern remoteTimelinePropPattern =
|
||||||
|
Pattern.compile("\\Q" + REMOTE_TIMELINE_BASE + "\\E([^\\s\\.=]+?)[\\.=].*");
|
||||||
|
|
||||||
|
private File propertyFile;
|
||||||
private Timeline timeline;
|
private Timeline timeline;
|
||||||
private TimelineSource timelineSource;
|
private TimelineSource timelineSource;
|
||||||
private LinkedList<SyncTarget> syncTargets = new LinkedList<SyncTarget>();
|
private LinkedList<SyncTarget> syncTargets = new LinkedList<SyncTarget>();
|
||||||
|
|
||||||
public TimelineProperties(InputStream in) throws IOException {
|
public TimelineProperties() {
|
||||||
parseConfig(in);
|
this.propertyFile = new File("timeline.default.properties");
|
||||||
|
Properties config = new Properties();
|
||||||
|
|
||||||
|
File timelineFile = new File("timeline.default.txt");
|
||||||
|
URI timelineURI = timelineFile.toURI();
|
||||||
|
|
||||||
|
timeline = new Timeline();
|
||||||
|
timelineSource = TimelineSourceFactory.newInstance(timelineURI);
|
||||||
|
try { timelineSource.persist(timeline); }
|
||||||
|
catch (IOException ioe) {
|
||||||
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
private static enum ReadingState {
|
config.setProperty(LOCAL_TIMELINE_URI, timelineURI.toString());
|
||||||
LocalTimelineDef, // expecting LOCAL TIMELINE definition
|
|
||||||
NewSync, // expecting a SYNC TO def
|
|
||||||
NewSyncOrOptions // either a NewDef, or a block of options
|
|
||||||
}
|
|
||||||
|
|
||||||
private void parseConfig(InputStream is) throws IOException {
|
try { config.store(new FileOutputStream(propertyFile), ""); }
|
||||||
Scanner in = new Scanner(is);
|
catch (IOException ioe) {
|
||||||
URI sourceURI;
|
// TODO
|
||||||
|
|
||||||
// read the information for the local timeline
|
|
||||||
if (!nextExtendedToken(in, "LOCAL TIMELINE:")) {
|
|
||||||
throw new IOException("Missing 'LOCAL TIMELINE:' definition."
|
|
||||||
+ " This must be the first line of the options file.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// parse the source URI
|
|
||||||
timelineSource = parseSource(in);
|
|
||||||
|
|
||||||
// load timeline from source
|
|
||||||
timeline = timelineSource.read(); // TODO: authentication
|
|
||||||
|
|
||||||
// add as many Syncs as we find
|
|
||||||
for (SyncTarget st = parseSync(in); st != null; st = parseSync(in))
|
|
||||||
syncTargets.add(st);
|
|
||||||
}
|
|
||||||
|
|
||||||
private SyncTarget parseSync(Scanner in) throws IOException {
|
|
||||||
SyncTarget st;
|
|
||||||
String token;
|
|
||||||
|
|
||||||
if (!nextExtendedToken(in, "SYNC WITH:")) { return null; }
|
|
||||||
|
|
||||||
st = new SyncTarget(parseSource(in), timeline);
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
if (nextExtendedToken(in, "PULL ONLY")) {
|
|
||||||
st.enablePull(true);
|
|
||||||
st.enablePush(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (nextExtendedToken(in, "PUSH ONLY")) {
|
|
||||||
st.enablePull(false);
|
|
||||||
st.enablePush(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (nextExtendedToken(in, "PUSH AND PULL") ||
|
|
||||||
nextExtendedToken(in, "PULL AND PUSH")) {
|
|
||||||
st.enablePull(true);
|
|
||||||
st.enablePush(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (nextExtendedToken(in, "SYNC ON EXIT")) {
|
|
||||||
st.enableSyncOnExit(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (nextExtendedToken(in, "UPDATE EVERY")) {
|
|
||||||
long updateAmount = 1;
|
|
||||||
|
|
||||||
// parse the time amount if present
|
|
||||||
token = in.next("\\d+");
|
|
||||||
if (token != null) { updateAmount = Long.parseLong(token); }
|
|
||||||
|
|
||||||
token = in.next();
|
|
||||||
if ("seconds".startsWith(token.toLowerCase()))
|
|
||||||
updateAmount *= 1000;
|
|
||||||
else if ("minutes".startsWith(token.toLowerCase()))
|
|
||||||
updateAmount *= 1000 * 60;
|
|
||||||
else if ("hours".startsWith(token.toLowerCase()))
|
|
||||||
updateAmount *= 1000 * 60 * 60;
|
|
||||||
else if ("days".startsWith(token.toLowerCase()))
|
|
||||||
updateAmount *= 1000 * 60 * 60 * 24;
|
|
||||||
else if ("weeks".startsWith(token.toLowerCase()))
|
|
||||||
updateAmount *= 1000 * 60 * 60 * 24 * 7;
|
|
||||||
else throw new IOException("'" + token + "' is not a supported"
|
|
||||||
+ " measure of time. The supported measures are "
|
|
||||||
+ "'seconds', 'minutes', 'hours', 'days', and 'weeks'.");
|
|
||||||
}
|
|
||||||
|
|
||||||
else return st;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private TimelineSource parseSource(Scanner in) throws IOException {
|
public TimelineProperties(File propertyFile) throws IOException {
|
||||||
String strURI;
|
String strURI;
|
||||||
URI sourceURI;
|
URI timelineURI;
|
||||||
|
|
||||||
if (!in.hasNext()) {
|
this.propertyFile = propertyFile;
|
||||||
throw new IOException("Expected the URI of a timeline source, but "
|
Properties config = new Properties();
|
||||||
+ "ran out of input.");
|
try {
|
||||||
|
config.load(new InputStreamReader(new FileInputStream(propertyFile)));
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
strURI = in.next();
|
// load local timeline
|
||||||
try { sourceURI = new URI(strURI); }
|
strURI = config.getProperty(LOCAL_TIMELINE_URI, "");
|
||||||
|
if ("".equals(strURI)) {
|
||||||
|
timelineURI = new File("timeline.default.txt").toURI();
|
||||||
|
} else {
|
||||||
|
try { timelineURI = new URI(strURI); }
|
||||||
catch (URISyntaxException urise) {
|
catch (URISyntaxException urise) {
|
||||||
throw new IOException("The source link '" + strURI + "' is not a"
|
throw new IOException("Unable to load the timeline: the timeline "
|
||||||
+ " valid URI.", urise);
|
+ "URI is invalid.", urise);
|
||||||
}
|
|
||||||
|
|
||||||
return TimelineSourceFactory.newInstance(sourceURI);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean nextExtendedToken(Scanner in, String expectedToken)
|
|
||||||
throws IOException {
|
|
||||||
StringTokenizer st = new StringTokenizer(expectedToken);
|
|
||||||
|
|
||||||
if (st.countTokens() < 1 || !in.hasNext()) { return false; }
|
|
||||||
|
|
||||||
// read one token
|
|
||||||
String curToken = st.nextToken();
|
|
||||||
String inToken = in.next("(?i)\\Q" + curToken + "\\E");
|
|
||||||
if (inToken == null) return false;
|
|
||||||
|
|
||||||
while (st.hasMoreTokens()) {
|
|
||||||
curToken = st.nextToken();
|
|
||||||
if (!in.hasNext()) {
|
|
||||||
throw new IOException("Ran out of input while expecting '"
|
|
||||||
+ curToken + "' from '" + expectedToken + "'.");
|
|
||||||
}
|
|
||||||
|
|
||||||
inToken = in.next("(?i)\\Q" + curToken + "\\E");
|
|
||||||
if (inToken == null) {
|
|
||||||
throw new IOException("Found '" + in.next() + "' but expected '"
|
|
||||||
+ curToken + "' from '" + expectedToken + "'.");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
timelineSource = TimelineSourceFactory.newInstance(timelineURI);
|
||||||
}
|
timeline = timelineSource.read();
|
||||||
|
|
||||||
public void writeToStream(OutputStream out) throws IOException {
|
// search keys for remote timeline entries
|
||||||
|
for (Object keyObj : config.keySet()) {
|
||||||
|
if (!(keyObj instanceof String)) continue;
|
||||||
|
|
||||||
|
String key = (String) keyObj;
|
||||||
|
String stName;
|
||||||
|
String remoteBase;
|
||||||
|
SyncTarget st;
|
||||||
|
|
||||||
|
Matcher m = remoteTimelinePropPattern.matcher(key);
|
||||||
|
if (!m.matches()) continue;
|
||||||
|
|
||||||
|
stName = m.group(1);
|
||||||
|
remoteBase = REMOTE_TIMELINE_BASE + stName;
|
||||||
|
|
||||||
|
strURI = config.getProperty(remoteBase + ".uri", "");
|
||||||
|
try { timelineURI = new URI(strURI); }
|
||||||
|
catch (URISyntaxException urise) { /* TODO */ }
|
||||||
|
|
||||||
|
// add a new SyncTarget to the list
|
||||||
|
st = new SyncTarget(stName, TimelineSourceFactory
|
||||||
|
.newInstance(timelineURI), timeline);
|
||||||
|
syncTargets.add(st);
|
||||||
|
|
||||||
|
// check for synch options
|
||||||
|
st.enablePull(Boolean.parseBoolean(
|
||||||
|
config.getProperty(remoteBase + ".pull", "true")));
|
||||||
|
st.enablePush(Boolean.parseBoolean(
|
||||||
|
config.getProperty(remoteBase + ".push", "true")));
|
||||||
|
st.enableSyncOnExit(Boolean.parseBoolean(
|
||||||
|
config.getProperty(remoteBase + ".sync-on-exit", "true")));
|
||||||
|
st.setSyncInterval(Long.parseLong(
|
||||||
|
config.getProperty(remoteBase + ".update-interval",
|
||||||
|
"1800000"))); // thirty minutes
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void save() throws IOException {
|
||||||
|
Properties config = new Properties();
|
||||||
|
timelineSource.persist(timeline);
|
||||||
|
|
||||||
|
config.setProperty(LOCAL_TIMELINE_URI,
|
||||||
|
timelineSource.getURI().toString());
|
||||||
|
|
||||||
|
for (SyncTarget st : syncTargets) {
|
||||||
|
String remoteBase = REMOTE_TIMELINE_BASE + st.getName();
|
||||||
|
config.setProperty(remoteBase + ".uri",
|
||||||
|
st.getSource().getURI().toString());
|
||||||
|
config.setProperty(remoteBase + ".pull",
|
||||||
|
Boolean.toString(st.isPullEnabled()));
|
||||||
|
config.setProperty(remoteBase + ".push",
|
||||||
|
Boolean.toString(st.isPushEnabled()));
|
||||||
|
config.setProperty(remoteBase + ".sync-on-exit",
|
||||||
|
Boolean.toString(st.isSyncOnExitEnabled()));
|
||||||
|
config.setProperty(remoteBase + ".update-interval",
|
||||||
|
Long.toString(st.getSyncInterval()));
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
config.store(new FileOutputStream(propertyFile), "");
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void save(File newFile) throws IOException {
|
||||||
|
propertyFile = newFile;
|
||||||
|
save();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Timeline getTimeline() { return timeline; }
|
||||||
|
|
||||||
|
public void setTimelineSource(TimelineSource newSource) {
|
||||||
|
this.timelineSource = newSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TimelineSource getTimelineSource() { return timelineSource; }
|
||||||
|
|
||||||
|
public Collection<SyncTarget> getSyncTargets() { return syncTargets; }
|
||||||
}
|
}
|
||||||
|
25
src/jdbernard/timestamper/core/TimelineSource.java
Normal file
25
src/jdbernard/timestamper/core/TimelineSource.java
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
package jdbernard.timestamper.core;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Jonathan Bernard ({@literal jonathan.bernard@gemalto.com})
|
||||||
|
*/
|
||||||
|
public abstract class TimelineSource {
|
||||||
|
|
||||||
|
protected final URI uri;
|
||||||
|
|
||||||
|
public TimelineSource(URI uri) { this.uri = uri; }
|
||||||
|
|
||||||
|
public abstract Timeline read() throws IOException;
|
||||||
|
public abstract void persist(Timeline t) throws IOException;
|
||||||
|
public abstract boolean isAuthenticated();
|
||||||
|
public abstract void authenticate() throws AuthenticationException;
|
||||||
|
|
||||||
|
public URI getURI() {
|
||||||
|
return uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
38
src/jdbernard/timestamper/core/TimelineSourceFactory.java
Normal file
38
src/jdbernard/timestamper/core/TimelineSourceFactory.java
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
package jdbernard.timestamper.core;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Jonathan Bernard ({@literal jonathan.bernard@gemalto.com})
|
||||||
|
*/
|
||||||
|
public class TimelineSourceFactory {
|
||||||
|
|
||||||
|
public static TimelineSource newInstance(URI uri) {
|
||||||
|
// File based
|
||||||
|
if ("file".equalsIgnoreCase(uri.getScheme())) {
|
||||||
|
return new FileTimelineSource(uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Twitter
|
||||||
|
else if ("http".equalsIgnoreCase(uri.getScheme()) &&
|
||||||
|
("twitter.com".equalsIgnoreCase(uri.getHost())
|
||||||
|
|| "www.twitter.com".equalsIgnoreCase(uri.getHost()))) {
|
||||||
|
throw new UnsupportedOperationException("Twitter based timeline "
|
||||||
|
+ "sources are not yet supported.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// SSH
|
||||||
|
else if ("ssh".equalsIgnoreCase(uri.getScheme())) {
|
||||||
|
throw new UnsupportedOperationException("SSH based timeline sources"
|
||||||
|
+ " are not yet supported.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// unknown
|
||||||
|
else {
|
||||||
|
throw new UnsupportedOperationException("Timeline sources for the"
|
||||||
|
+ " " + uri.getScheme() + " are not currently supported.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
34
src/jdbernard/timestamper/core/TwitterTimelineSource.java
Normal file
34
src/jdbernard/timestamper/core/TwitterTimelineSource.java
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
package jdbernard.timestamper.core;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Jonathan Bernard ({@literal jonathan.bernard@gemalto.com})
|
||||||
|
*/
|
||||||
|
public class TwitterTimelineSource extends TimelineSource {
|
||||||
|
|
||||||
|
private String username;
|
||||||
|
private char[] password;
|
||||||
|
|
||||||
|
public TwitterTimelineSource(URI uri) {
|
||||||
|
super(uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Timeline read() throws IOException {
|
||||||
|
throw new UnsupportedOperationException("Not supported yet.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void persist(Timeline t) throws IOException {
|
||||||
|
throw new UnsupportedOperationException("Not supported yet.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAuthenticated() {
|
||||||
|
throw new UnsupportedOperationException("Not supported yet.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void authenticate() throws AuthenticationException {
|
||||||
|
throw new UnsupportedOperationException("Not supported yet.");
|
||||||
|
}
|
||||||
|
}
|
1
src/jdbernard/timestamper/AboutDialog.form → src/jdbernard/timestamper/gui/AboutDialog.form
Executable file → Normal file
1
src/jdbernard/timestamper/AboutDialog.form → src/jdbernard/timestamper/gui/AboutDialog.form
Executable file → Normal file
@ -12,6 +12,7 @@
|
|||||||
<AuxValues>
|
<AuxValues>
|
||||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="2"/>
|
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="2"/>
|
||||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="true"/>
|
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||||
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
|
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
|
||||||
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
|
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
|
||||||
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
4
src/jdbernard/timestamper/AboutDialog.java → src/jdbernard/timestamper/gui/AboutDialog.java
Executable file → Normal file
4
src/jdbernard/timestamper/AboutDialog.java → src/jdbernard/timestamper/gui/AboutDialog.java
Executable file → Normal file
@ -4,7 +4,7 @@
|
|||||||
* Created on October 19, 2008, 3:14 PM
|
* Created on October 19, 2008, 3:14 PM
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package jdbernard.timestamper;
|
package jdbernard.timestamper.gui;
|
||||||
|
|
||||||
import java.awt.Frame;
|
import java.awt.Frame;
|
||||||
import java.awt.Point;
|
import java.awt.Point;
|
||||||
@ -56,7 +56,7 @@ public class AboutDialog extends JDialog implements MouseMotionListener {
|
|||||||
});
|
});
|
||||||
aboutPanel.addMouseMotionListener(this);
|
aboutPanel.addMouseMotionListener(this);
|
||||||
|
|
||||||
org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(jdbernard.timestamper.TimeStamperApp.class).getContext().getResourceMap(AboutDialog.class);
|
org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(jdbernard.timestamper.gui.TimeStamperApp.class).getContext().getResourceMap(AboutDialog.class);
|
||||||
iconLabel.setIcon(resourceMap.getIcon("iconLabel.icon")); // NOI18N
|
iconLabel.setIcon(resourceMap.getIcon("iconLabel.icon")); // NOI18N
|
||||||
iconLabel.setText(resourceMap.getString("iconLabel.text")); // NOI18N
|
iconLabel.setText(resourceMap.getString("iconLabel.text")); // NOI18N
|
||||||
iconLabel.setName("iconLabel"); // NOI18N
|
iconLabel.setName("iconLabel"); // NOI18N
|
1
src/jdbernard/timestamper/NotesDialog.form → src/jdbernard/timestamper/gui/NotesDialog.form
Executable file → Normal file
1
src/jdbernard/timestamper/NotesDialog.form → src/jdbernard/timestamper/gui/NotesDialog.form
Executable file → Normal file
@ -12,6 +12,7 @@
|
|||||||
<AuxValues>
|
<AuxValues>
|
||||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="2"/>
|
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="2"/>
|
||||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="true"/>
|
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||||
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
|
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
|
||||||
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
|
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
|
||||||
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
4
src/jdbernard/timestamper/NotesDialog.java → src/jdbernard/timestamper/gui/NotesDialog.java
Executable file → Normal file
4
src/jdbernard/timestamper/NotesDialog.java → src/jdbernard/timestamper/gui/NotesDialog.java
Executable file → Normal file
@ -4,7 +4,7 @@
|
|||||||
* Created on September 3, 2008, 4:53 PM
|
* Created on September 3, 2008, 4:53 PM
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package jdbernard.timestamper;
|
package jdbernard.timestamper.gui;
|
||||||
|
|
||||||
import java.awt.Font;
|
import java.awt.Font;
|
||||||
import java.awt.Point;
|
import java.awt.Point;
|
||||||
@ -61,7 +61,7 @@ public class NotesDialog extends JDialog implements MouseMotionListener {
|
|||||||
setUndecorated(true);
|
setUndecorated(true);
|
||||||
|
|
||||||
mainPanel.setBorder(javax.swing.BorderFactory.createMatteBorder(2, 2, 2, 2, new java.awt.Color(0, 0, 0)));
|
mainPanel.setBorder(javax.swing.BorderFactory.createMatteBorder(2, 2, 2, 2, new java.awt.Color(0, 0, 0)));
|
||||||
org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(jdbernard.timestamper.TimeStamperApp.class).getContext().getResourceMap(NotesDialog.class);
|
org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(jdbernard.timestamper.gui.TimeStamperApp.class).getContext().getResourceMap(NotesDialog.class);
|
||||||
mainPanel.setToolTipText(resourceMap.getString("mainPanel.toolTipText")); // NOI18N
|
mainPanel.setToolTipText(resourceMap.getString("mainPanel.toolTipText")); // NOI18N
|
||||||
mainPanel.setName("mainPanel"); // NOI18N
|
mainPanel.setName("mainPanel"); // NOI18N
|
||||||
mainPanel.addMouseListener(new java.awt.event.MouseAdapter() {
|
mainPanel.addMouseListener(new java.awt.event.MouseAdapter() {
|
39
src/jdbernard/timestamper/PunchcardDisplayDialog.form → src/jdbernard/timestamper/gui/PunchcardDisplayDialog.form
Executable file → Normal file
39
src/jdbernard/timestamper/PunchcardDisplayDialog.form → src/jdbernard/timestamper/gui/PunchcardDisplayDialog.form
Executable file → Normal file
@ -1,6 +1,26 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" ?>
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
|
||||||
<Form version="1.5" maxVersion="1.6" type="org.netbeans.modules.form.forminfo.JDialogFormInfo">
|
<Form version="1.5" maxVersion="1.6" type="org.netbeans.modules.form.forminfo.JDialogFormInfo">
|
||||||
|
<NonVisualComponents>
|
||||||
|
<Container class="jdbernard.timestamper.gui.TimelineDayDisplay" name="dayDisplay">
|
||||||
|
<Properties>
|
||||||
|
<Property name="name" type="java.lang.String" value="dayDisplay" noResource="true"/>
|
||||||
|
</Properties>
|
||||||
|
|
||||||
|
<Layout>
|
||||||
|
<DimensionLayout dim="0">
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<EmptySpace min="0" pref="100" max="32767" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
</DimensionLayout>
|
||||||
|
<DimensionLayout dim="1">
|
||||||
|
<Group type="103" groupAlignment="0" attributes="0">
|
||||||
|
<EmptySpace min="0" pref="100" max="32767" attributes="0"/>
|
||||||
|
</Group>
|
||||||
|
</DimensionLayout>
|
||||||
|
</Layout>
|
||||||
|
</Container>
|
||||||
|
</NonVisualComponents>
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="defaultCloseOperation" type="int" value="2"/>
|
<Property name="defaultCloseOperation" type="int" value="2"/>
|
||||||
<Property name="name" type="java.lang.String" value="Form" noResource="true"/>
|
<Property name="name" type="java.lang.String" value="Form" noResource="true"/>
|
||||||
@ -12,6 +32,7 @@
|
|||||||
<AuxValues>
|
<AuxValues>
|
||||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="2"/>
|
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="2"/>
|
||||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="true"/>
|
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||||
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
|
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
|
||||||
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
|
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
|
||||||
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
||||||
@ -48,6 +69,8 @@
|
|||||||
<AuxValues>
|
<AuxValues>
|
||||||
<AuxValue name="JavaCodeGenerator_ListenersCodePost" type="java.lang.String" value="mainPanel.addMouseMotionListener(this);"/>
|
<AuxValue name="JavaCodeGenerator_ListenersCodePost" type="java.lang.String" value="mainPanel.addMouseMotionListener(this);"/>
|
||||||
</AuxValues>
|
</AuxValues>
|
||||||
|
|
||||||
|
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/>
|
||||||
<SubComponents>
|
<SubComponents>
|
||||||
<Container class="javax.swing.JPanel" name="detailPanel">
|
<Container class="javax.swing.JPanel" name="detailPanel">
|
||||||
<Properties>
|
<Properties>
|
||||||
@ -179,7 +202,7 @@
|
|||||||
<Component class="javax.swing.JButton" name="prevWeekButton">
|
<Component class="javax.swing.JButton" name="prevWeekButton">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="action" type="javax.swing.Action" editor="org.netbeans.modules.swingapp.ActionEditor">
|
<Property name="action" type="javax.swing.Action" editor="org.netbeans.modules.swingapp.ActionEditor">
|
||||||
<action class="jdbernard.timestamper.PunchcardDisplayDialog" id="previousWeek" methodName="previousWeek"/>
|
<action class="jdbernard.timestamper.gui.PunchcardDisplayDialog" id="previousWeek" methodName="previousWeek"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="hideActionText" type="boolean" value="true"/>
|
<Property name="hideActionText" type="boolean" value="true"/>
|
||||||
<Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor">
|
<Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor">
|
||||||
@ -196,7 +219,7 @@
|
|||||||
<Component class="javax.swing.JButton" name="prevDayButton">
|
<Component class="javax.swing.JButton" name="prevDayButton">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="action" type="javax.swing.Action" editor="org.netbeans.modules.swingapp.ActionEditor">
|
<Property name="action" type="javax.swing.Action" editor="org.netbeans.modules.swingapp.ActionEditor">
|
||||||
<action class="jdbernard.timestamper.PunchcardDisplayDialog" id="previousDay" methodName="previousDay"/>
|
<action class="jdbernard.timestamper.gui.PunchcardDisplayDialog" id="previousDay" methodName="previousDay"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="hideActionText" type="boolean" value="true"/>
|
<Property name="hideActionText" type="boolean" value="true"/>
|
||||||
<Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor">
|
<Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor">
|
||||||
@ -213,7 +236,7 @@
|
|||||||
<Component class="javax.swing.JButton" name="currentDayButton">
|
<Component class="javax.swing.JButton" name="currentDayButton">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="action" type="javax.swing.Action" editor="org.netbeans.modules.swingapp.ActionEditor">
|
<Property name="action" type="javax.swing.Action" editor="org.netbeans.modules.swingapp.ActionEditor">
|
||||||
<action class="jdbernard.timestamper.PunchcardDisplayDialog" id="currentDay" methodName="currentDay"/>
|
<action class="jdbernard.timestamper.gui.PunchcardDisplayDialog" id="currentDay" methodName="currentDay"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor">
|
<Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor">
|
||||||
<Insets value="[0, 2, 0, 2]"/>
|
<Insets value="[0, 2, 0, 2]"/>
|
||||||
@ -229,7 +252,7 @@
|
|||||||
<Component class="javax.swing.JButton" name="nextDayButton">
|
<Component class="javax.swing.JButton" name="nextDayButton">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="action" type="javax.swing.Action" editor="org.netbeans.modules.swingapp.ActionEditor">
|
<Property name="action" type="javax.swing.Action" editor="org.netbeans.modules.swingapp.ActionEditor">
|
||||||
<action class="jdbernard.timestamper.PunchcardDisplayDialog" id="nextDay" methodName="nextDay"/>
|
<action class="jdbernard.timestamper.gui.PunchcardDisplayDialog" id="nextDay" methodName="nextDay"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="hideActionText" type="boolean" value="true"/>
|
<Property name="hideActionText" type="boolean" value="true"/>
|
||||||
<Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor">
|
<Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor">
|
||||||
@ -246,7 +269,7 @@
|
|||||||
<Component class="javax.swing.JButton" name="nextWeekButton">
|
<Component class="javax.swing.JButton" name="nextWeekButton">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="action" type="javax.swing.Action" editor="org.netbeans.modules.swingapp.ActionEditor">
|
<Property name="action" type="javax.swing.Action" editor="org.netbeans.modules.swingapp.ActionEditor">
|
||||||
<action class="jdbernard.timestamper.PunchcardDisplayDialog" id="nextWeek" methodName="nextWeek"/>
|
<action class="jdbernard.timestamper.gui.PunchcardDisplayDialog" id="nextWeek" methodName="nextWeek"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="hideActionText" type="boolean" value="true"/>
|
<Property name="hideActionText" type="boolean" value="true"/>
|
||||||
<Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor">
|
<Property name="margin" type="java.awt.Insets" editor="org.netbeans.beaninfo.editors.InsetsEditor">
|
||||||
@ -265,7 +288,7 @@
|
|||||||
<Component class="javax.swing.JButton" name="newMarkerButton">
|
<Component class="javax.swing.JButton" name="newMarkerButton">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="action" type="javax.swing.Action" editor="org.netbeans.modules.swingapp.ActionEditor">
|
<Property name="action" type="javax.swing.Action" editor="org.netbeans.modules.swingapp.ActionEditor">
|
||||||
<action class="jdbernard.timestamper.PunchcardDisplayDialog" id="newMarker" methodName="newMarker"/>
|
<action class="jdbernard.timestamper.gui.PunchcardDisplayDialog" id="newMarker" methodName="newMarker"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="name" type="java.lang.String" value="newMarkerButton" noResource="true"/>
|
<Property name="name" type="java.lang.String" value="newMarkerButton" noResource="true"/>
|
||||||
</Properties>
|
</Properties>
|
||||||
@ -278,7 +301,7 @@
|
|||||||
<Component class="javax.swing.JButton" name="deleteMarkerButton">
|
<Component class="javax.swing.JButton" name="deleteMarkerButton">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="action" type="javax.swing.Action" editor="org.netbeans.modules.swingapp.ActionEditor">
|
<Property name="action" type="javax.swing.Action" editor="org.netbeans.modules.swingapp.ActionEditor">
|
||||||
<action class="jdbernard.timestamper.PunchcardDisplayDialog" id="deleteMarker" methodName="deleteMarker"/>
|
<action class="jdbernard.timestamper.gui.PunchcardDisplayDialog" id="deleteMarker" methodName="deleteMarker"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="name" type="java.lang.String" value="deleteMarkerButton" noResource="true"/>
|
<Property name="name" type="java.lang.String" value="deleteMarkerButton" noResource="true"/>
|
||||||
</Properties>
|
</Properties>
|
||||||
@ -291,7 +314,7 @@
|
|||||||
<Component class="javax.swing.JButton" name="saveMarkerChanges">
|
<Component class="javax.swing.JButton" name="saveMarkerChanges">
|
||||||
<Properties>
|
<Properties>
|
||||||
<Property name="action" type="javax.swing.Action" editor="org.netbeans.modules.swingapp.ActionEditor">
|
<Property name="action" type="javax.swing.Action" editor="org.netbeans.modules.swingapp.ActionEditor">
|
||||||
<action class="jdbernard.timestamper.PunchcardDisplayDialog" id="saveMarkerChanges" methodName="saveMarkerChanges"/>
|
<action class="jdbernard.timestamper.gui.PunchcardDisplayDialog" id="saveMarkerChanges" methodName="saveMarkerChanges"/>
|
||||||
</Property>
|
</Property>
|
||||||
<Property name="name" type="java.lang.String" value="saveMarkerChanges" noResource="true"/>
|
<Property name="name" type="java.lang.String" value="saveMarkerChanges" noResource="true"/>
|
||||||
</Properties>
|
</Properties>
|
61
src/jdbernard/timestamper/PunchcardDisplayDialog.java → src/jdbernard/timestamper/gui/PunchcardDisplayDialog.java
Executable file → Normal file
61
src/jdbernard/timestamper/PunchcardDisplayDialog.java → src/jdbernard/timestamper/gui/PunchcardDisplayDialog.java
Executable file → Normal file
@ -4,8 +4,9 @@
|
|||||||
* Created on October 16, 2008, 4:37 PM
|
* Created on October 16, 2008, 4:37 PM
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package jdbernard.timestamper;
|
package jdbernard.timestamper.gui;
|
||||||
|
|
||||||
|
import jdbernard.timestamper.core.TimelineMarker;
|
||||||
import java.awt.Point;
|
import java.awt.Point;
|
||||||
import java.awt.Rectangle;
|
import java.awt.Rectangle;
|
||||||
import java.awt.Toolkit;
|
import java.awt.Toolkit;
|
||||||
@ -64,8 +65,8 @@ implements MouseMotionListener, ChangeListener {
|
|||||||
private void initComponents() {
|
private void initComponents() {
|
||||||
java.awt.GridBagConstraints gridBagConstraints;
|
java.awt.GridBagConstraints gridBagConstraints;
|
||||||
|
|
||||||
|
dayDisplay = new jdbernard.timestamper.gui.TimelineDayDisplay();
|
||||||
mainPanel = new javax.swing.JPanel();
|
mainPanel = new javax.swing.JPanel();
|
||||||
dayDisplay = new jdbernard.timestamper.TimelineDayDisplay();
|
|
||||||
detailPanel = new javax.swing.JPanel();
|
detailPanel = new javax.swing.JPanel();
|
||||||
textPane = new javax.swing.JPanel();
|
textPane = new javax.swing.JPanel();
|
||||||
markTextField = new javax.swing.JTextField();
|
markTextField = new javax.swing.JTextField();
|
||||||
@ -84,6 +85,19 @@ implements MouseMotionListener, ChangeListener {
|
|||||||
deleteMarkerButton = new javax.swing.JButton();
|
deleteMarkerButton = new javax.swing.JButton();
|
||||||
saveMarkerChanges = new javax.swing.JButton();
|
saveMarkerChanges = new javax.swing.JButton();
|
||||||
|
|
||||||
|
dayDisplay.setName("dayDisplay"); // NOI18N
|
||||||
|
|
||||||
|
javax.swing.GroupLayout dayDisplayLayout = new javax.swing.GroupLayout(dayDisplay);
|
||||||
|
dayDisplay.setLayout(dayDisplayLayout);
|
||||||
|
dayDisplayLayout.setHorizontalGroup(
|
||||||
|
dayDisplayLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addGap(0, 100, Short.MAX_VALUE)
|
||||||
|
);
|
||||||
|
dayDisplayLayout.setVerticalGroup(
|
||||||
|
dayDisplayLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
||||||
|
.addGap(0, 100, Short.MAX_VALUE)
|
||||||
|
);
|
||||||
|
|
||||||
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
|
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
|
||||||
setName("Form"); // NOI18N
|
setName("Form"); // NOI18N
|
||||||
setUndecorated(true);
|
setUndecorated(true);
|
||||||
@ -97,26 +111,12 @@ implements MouseMotionListener, ChangeListener {
|
|||||||
});
|
});
|
||||||
mainPanel.addMouseMotionListener(this);
|
mainPanel.addMouseMotionListener(this);
|
||||||
|
|
||||||
dayDisplay.setName("dayDisplay"); // NOI18N
|
|
||||||
dayDisplay.setPreferredSize(new java.awt.Dimension(100, 100));
|
|
||||||
|
|
||||||
javax.swing.GroupLayout dayDisplayLayout = new javax.swing.GroupLayout(dayDisplay);
|
|
||||||
dayDisplay.setLayout(dayDisplayLayout);
|
|
||||||
dayDisplayLayout.setHorizontalGroup(
|
|
||||||
dayDisplayLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
||||||
.addGap(0, 405, Short.MAX_VALUE)
|
|
||||||
);
|
|
||||||
dayDisplayLayout.setVerticalGroup(
|
|
||||||
dayDisplayLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
||||||
.addGap(0, 339, Short.MAX_VALUE)
|
|
||||||
);
|
|
||||||
|
|
||||||
detailPanel.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
|
detailPanel.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0)));
|
||||||
detailPanel.setName("detailPanel"); // NOI18N
|
detailPanel.setName("detailPanel"); // NOI18N
|
||||||
|
|
||||||
textPane.setName("textPane"); // NOI18N
|
textPane.setName("textPane"); // NOI18N
|
||||||
|
|
||||||
org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(jdbernard.timestamper.TimeStamperApp.class).getContext().getResourceMap(PunchcardDisplayDialog.class);
|
org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(jdbernard.timestamper.gui.TimeStamperApp.class).getContext().getResourceMap(PunchcardDisplayDialog.class);
|
||||||
markTextField.setText(resourceMap.getString("markTextField.text")); // NOI18N
|
markTextField.setText(resourceMap.getString("markTextField.text")); // NOI18N
|
||||||
markTextField.setName("markTextField"); // NOI18N
|
markTextField.setName("markTextField"); // NOI18N
|
||||||
|
|
||||||
@ -175,7 +175,7 @@ implements MouseMotionListener, ChangeListener {
|
|||||||
gridBagConstraints.weightx = 1.0;
|
gridBagConstraints.weightx = 1.0;
|
||||||
datePanel.add(dateLabel, gridBagConstraints);
|
datePanel.add(dateLabel, gridBagConstraints);
|
||||||
|
|
||||||
javax.swing.ActionMap actionMap = org.jdesktop.application.Application.getInstance(jdbernard.timestamper.TimeStamperApp.class).getContext().getActionMap(PunchcardDisplayDialog.class, this);
|
javax.swing.ActionMap actionMap = org.jdesktop.application.Application.getInstance(jdbernard.timestamper.gui.TimeStamperApp.class).getContext().getActionMap(PunchcardDisplayDialog.class, this);
|
||||||
prevWeekButton.setAction(actionMap.get("previousWeek")); // NOI18N
|
prevWeekButton.setAction(actionMap.get("previousWeek")); // NOI18N
|
||||||
prevWeekButton.setHideActionText(true);
|
prevWeekButton.setHideActionText(true);
|
||||||
prevWeekButton.setMargin(new java.awt.Insets(0, 2, 0, 2));
|
prevWeekButton.setMargin(new java.awt.Insets(0, 2, 0, 2));
|
||||||
@ -270,26 +270,7 @@ implements MouseMotionListener, ChangeListener {
|
|||||||
.addComponent(textPane, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
.addComponent(textPane, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
|
||||||
);
|
);
|
||||||
|
|
||||||
javax.swing.GroupLayout mainPanelLayout = new javax.swing.GroupLayout(mainPanel);
|
mainPanel.add(detailPanel);
|
||||||
mainPanel.setLayout(mainPanelLayout);
|
|
||||||
mainPanelLayout.setHorizontalGroup(
|
|
||||||
mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
||||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, mainPanelLayout.createSequentialGroup()
|
|
||||||
.addContainerGap()
|
|
||||||
.addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
|
|
||||||
.addComponent(dayDisplay, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 405, Short.MAX_VALUE)
|
|
||||||
.addComponent(detailPanel, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
|
|
||||||
.addContainerGap())
|
|
||||||
);
|
|
||||||
mainPanelLayout.setVerticalGroup(
|
|
||||||
mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
|
|
||||||
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, mainPanelLayout.createSequentialGroup()
|
|
||||||
.addContainerGap()
|
|
||||||
.addComponent(dayDisplay, javax.swing.GroupLayout.DEFAULT_SIZE, 339, Short.MAX_VALUE)
|
|
||||||
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
|
|
||||||
.addComponent(detailPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
|
|
||||||
.addContainerGap())
|
|
||||||
);
|
|
||||||
|
|
||||||
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
|
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
|
||||||
getContentPane().setLayout(layout);
|
getContentPane().setLayout(layout);
|
||||||
@ -315,7 +296,7 @@ private void mainPanelMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:e
|
|||||||
private javax.swing.JButton currentDayButton;
|
private javax.swing.JButton currentDayButton;
|
||||||
private javax.swing.JLabel dateLabel;
|
private javax.swing.JLabel dateLabel;
|
||||||
private javax.swing.JPanel datePanel;
|
private javax.swing.JPanel datePanel;
|
||||||
private jdbernard.timestamper.TimelineDayDisplay dayDisplay;
|
private jdbernard.timestamper.gui.TimelineDayDisplay dayDisplay;
|
||||||
private javax.swing.JButton deleteMarkerButton;
|
private javax.swing.JButton deleteMarkerButton;
|
||||||
private javax.swing.JPanel detailPanel;
|
private javax.swing.JPanel detailPanel;
|
||||||
private javax.swing.JPanel mainPanel;
|
private javax.swing.JPanel mainPanel;
|
||||||
@ -418,7 +399,7 @@ private void mainPanelMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:e
|
|||||||
|
|
||||||
public void stateChanged(ChangeEvent e) {
|
public void stateChanged(ChangeEvent e) {
|
||||||
if (e.getSource() == dayDisplay) {
|
if (e.getSource() == dayDisplay) {
|
||||||
Timeline.TimelineMarker marker = dayDisplay.getSelectedTimelineMarker();
|
TimelineMarker marker = dayDisplay.getSelectedTimelineMarker();
|
||||||
|
|
||||||
if (marker == null) {
|
if (marker == null) {
|
||||||
timestampDateChooser.setDate(null);
|
timestampDateChooser.setDate(null);
|
1
src/jdbernard/timestamper/TimeStamperAboutBox.form → src/jdbernard/timestamper/gui/TimeStamperAboutBox.form
Executable file → Normal file
1
src/jdbernard/timestamper/TimeStamperAboutBox.form → src/jdbernard/timestamper/gui/TimeStamperAboutBox.form
Executable file → Normal file
@ -14,6 +14,7 @@
|
|||||||
<AuxValues>
|
<AuxValues>
|
||||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="2"/>
|
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="2"/>
|
||||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="true"/>
|
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||||
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
|
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
|
||||||
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
|
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
|
||||||
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
6
src/jdbernard/timestamper/TimeStamperAboutBox.java → src/jdbernard/timestamper/gui/TimeStamperAboutBox.java
Executable file → Normal file
6
src/jdbernard/timestamper/TimeStamperAboutBox.java → src/jdbernard/timestamper/gui/TimeStamperAboutBox.java
Executable file → Normal file
@ -2,7 +2,7 @@
|
|||||||
* TimeStamperAboutBox.java
|
* TimeStamperAboutBox.java
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package jdbernard.timestamper;
|
package jdbernard.timestamper.gui;
|
||||||
|
|
||||||
import org.jdesktop.application.Action;
|
import org.jdesktop.application.Action;
|
||||||
|
|
||||||
@ -37,13 +37,13 @@ public class TimeStamperAboutBox extends javax.swing.JDialog {
|
|||||||
javax.swing.JLabel appDescLabel = new javax.swing.JLabel();
|
javax.swing.JLabel appDescLabel = new javax.swing.JLabel();
|
||||||
|
|
||||||
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
|
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
|
||||||
org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(jdbernard.timestamper.TimeStamperApp.class).getContext().getResourceMap(TimeStamperAboutBox.class);
|
org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(jdbernard.timestamper.gui.TimeStamperApp.class).getContext().getResourceMap(TimeStamperAboutBox.class);
|
||||||
setTitle(resourceMap.getString("title")); // NOI18N
|
setTitle(resourceMap.getString("title")); // NOI18N
|
||||||
setModal(true);
|
setModal(true);
|
||||||
setName("aboutBox"); // NOI18N
|
setName("aboutBox"); // NOI18N
|
||||||
setResizable(false);
|
setResizable(false);
|
||||||
|
|
||||||
javax.swing.ActionMap actionMap = org.jdesktop.application.Application.getInstance(jdbernard.timestamper.TimeStamperApp.class).getContext().getActionMap(TimeStamperAboutBox.class, this);
|
javax.swing.ActionMap actionMap = org.jdesktop.application.Application.getInstance(jdbernard.timestamper.gui.TimeStamperApp.class).getContext().getActionMap(TimeStamperAboutBox.class, this);
|
||||||
closeButton.setAction(actionMap.get("closeAboutBox")); // NOI18N
|
closeButton.setAction(actionMap.get("closeAboutBox")); // NOI18N
|
||||||
closeButton.setName("closeButton"); // NOI18N
|
closeButton.setName("closeButton"); // NOI18N
|
||||||
|
|
75
src/jdbernard/timestamper/TimeStamperApp.java → src/jdbernard/timestamper/gui/TimeStamperApp.java
Executable file → Normal file
75
src/jdbernard/timestamper/TimeStamperApp.java → src/jdbernard/timestamper/gui/TimeStamperApp.java
Executable file → Normal file
@ -2,7 +2,7 @@
|
|||||||
* TimeStamperApp.java
|
* TimeStamperApp.java
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package jdbernard.timestamper;
|
package jdbernard.timestamper.gui;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
@ -16,6 +16,7 @@ import java.util.logging.Handler;
|
|||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import java.util.logging.SimpleFormatter;
|
import java.util.logging.SimpleFormatter;
|
||||||
|
import jdbernard.timestamper.core.TimelineProperties;
|
||||||
import org.jdesktop.application.Application;
|
import org.jdesktop.application.Application;
|
||||||
import org.jdesktop.application.SingleFrameApplication;
|
import org.jdesktop.application.SingleFrameApplication;
|
||||||
|
|
||||||
@ -25,16 +26,14 @@ import org.jdesktop.application.SingleFrameApplication;
|
|||||||
public class TimeStamperApp extends SingleFrameApplication
|
public class TimeStamperApp extends SingleFrameApplication
|
||||||
implements Application.ExitListener {
|
implements Application.ExitListener {
|
||||||
|
|
||||||
private Timeline activeTimeline;
|
private TimelineProperties timelineProperties;
|
||||||
private String currentTimelineFile;
|
|
||||||
private Logger log;
|
private Logger log;
|
||||||
private Properties config;
|
private Properties config;
|
||||||
|
|
||||||
public TimeStamperApp() {
|
public TimeStamperApp() {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
// set defaults for fields
|
timelineProperties = new TimelineProperties();
|
||||||
activeTimeline = new Timeline();
|
|
||||||
|
|
||||||
// set up logger
|
// set up logger
|
||||||
log = Logger.getLogger("jdbernard.timestamper");
|
log = Logger.getLogger("jdbernard.timestamper");
|
||||||
@ -71,25 +70,14 @@ implements Application.ExitListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// load the last used timeline
|
// load the last used timeline
|
||||||
loadTimeline(config.getProperty("lastUsedTimelineFilename"));
|
// TODO: fix
|
||||||
|
loadTimelineProperties(config.getProperty("lastUsedTimelineProperties", "timeline.default.properties"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@Override protected void initialize(String[] args) {
|
@Override protected void initialize(String[] args) {
|
||||||
if (args.length > 0) {
|
|
||||||
File inFile = new File(args[0]);
|
|
||||||
if (!inFile.exists())
|
|
||||||
try { inFile.createNewFile(); }
|
|
||||||
catch (IOException ioe) {
|
|
||||||
log.warning("No file '" + args[0] + " exists and an error"
|
|
||||||
+ " occurred trying to create it.");
|
|
||||||
}
|
|
||||||
|
|
||||||
currentTimelineFile = args[0];
|
|
||||||
loadTimeline(currentTimelineFile);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -124,48 +112,45 @@ implements Application.ExitListener {
|
|||||||
launch(TimeStamperApp.class, args);
|
launch(TimeStamperApp.class, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void saveTimeline() {
|
public TimelineProperties getTimelineProperties() {
|
||||||
saveTimelineToFile(currentTimelineFile);
|
return timelineProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void saveTimelineToFile(String filename) {
|
public void saveTimelineProperties() {
|
||||||
if (filename == null || filename.equals(""))
|
|
||||||
filename = "default-timeline.txt";
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Timeline.writeToFile(filename, activeTimeline);
|
timelineProperties.save();
|
||||||
currentTimelineFile = filename;
|
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
log.warning("Could not save timeline file: "
|
log.warning("Could not save the timeline to <"
|
||||||
+ ioe.getLocalizedMessage());
|
+ timelineProperties.getTimelineSource().getURI().toString()
|
||||||
|
+ ">:" + ioe.getLocalizedMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void saveTimelinePropertiesAs(File propertyFile) {
|
||||||
|
try { timelineProperties.save(propertyFile); }
|
||||||
|
catch (IOException ioe) {
|
||||||
|
// TODO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void loadTimeline(String filename) {
|
public void loadTimelineProperties(String filename) {
|
||||||
|
loadTimelineProperties(new File(filename));
|
||||||
if (filename == null || filename.equals("")) {
|
|
||||||
activeTimeline = new Timeline();
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
public void loadTimelineProperties(File propertyFile) {
|
||||||
activeTimeline = Timeline.readFromFile(filename);
|
try { timelineProperties = new TimelineProperties(propertyFile); }
|
||||||
currentTimelineFile = filename;
|
catch (IOException ioe) {
|
||||||
} catch (IOException ioe) {
|
// TODO
|
||||||
log.warning("Could not load from the file: " +
|
|
||||||
ioe.getLocalizedMessage());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Timeline getActiveTimeline() {
|
|
||||||
return activeTimeline;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void willExit(EventObject e) {
|
public void willExit(EventObject e) {
|
||||||
saveTimeline();
|
saveTimelineProperties();
|
||||||
|
|
||||||
config.setProperty("lastUsedTimelineFilename", currentTimelineFile);
|
config.setProperty("lastUsedTimelineProperties",
|
||||||
|
timelineProperties.getTimelineSource().getURI().toString());
|
||||||
try {
|
try {
|
||||||
FileOutputStream out = new FileOutputStream("timestamper.config");
|
FileOutputStream out = new FileOutputStream("timestamper.config");
|
||||||
config.store(out, "");
|
config.store(out, "");
|
1
src/jdbernard/timestamper/TimeStamperView.form → src/jdbernard/timestamper/gui/TimeStamperView.form
Executable file → Normal file
1
src/jdbernard/timestamper/TimeStamperView.form → src/jdbernard/timestamper/gui/TimeStamperView.form
Executable file → Normal file
@ -267,6 +267,7 @@
|
|||||||
<AuxValues>
|
<AuxValues>
|
||||||
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="2"/>
|
<AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="2"/>
|
||||||
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="true"/>
|
<AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="true"/>
|
||||||
|
<AuxValue name="FormSettings_generateFQN" type="java.lang.Boolean" value="true"/>
|
||||||
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
|
<AuxValue name="FormSettings_generateMnemonicsCode" type="java.lang.Boolean" value="false"/>
|
||||||
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
|
<AuxValue name="FormSettings_i18nAutoMode" type="java.lang.Boolean" value="false"/>
|
||||||
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
<AuxValue name="FormSettings_layoutCodeTarget" type="java.lang.Integer" value="1"/>
|
31
src/jdbernard/timestamper/TimeStamperView.java → src/jdbernard/timestamper/gui/TimeStamperView.java
Executable file → Normal file
31
src/jdbernard/timestamper/TimeStamperView.java → src/jdbernard/timestamper/gui/TimeStamperView.java
Executable file → Normal file
@ -2,8 +2,10 @@
|
|||||||
* TimeStamperView.java
|
* TimeStamperView.java
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package jdbernard.timestamper;
|
package jdbernard.timestamper.gui;
|
||||||
|
|
||||||
|
import jdbernard.timestamper.core.TimelineMarker;
|
||||||
|
import jdbernard.timestamper.core.Timeline;
|
||||||
import java.awt.Font;
|
import java.awt.Font;
|
||||||
import java.awt.Point;
|
import java.awt.Point;
|
||||||
import java.awt.Rectangle;
|
import java.awt.Rectangle;
|
||||||
@ -16,7 +18,6 @@ import java.util.Calendar;
|
|||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Timer;
|
import java.util.Timer;
|
||||||
import java.util.TimerTask;
|
import java.util.TimerTask;
|
||||||
import javax.swing.ButtonGroup;
|
|
||||||
import javax.swing.JFileChooser;
|
import javax.swing.JFileChooser;
|
||||||
import javax.swing.event.ChangeEvent;
|
import javax.swing.event.ChangeEvent;
|
||||||
import javax.swing.event.ChangeListener;
|
import javax.swing.event.ChangeListener;
|
||||||
@ -24,7 +25,6 @@ import org.jdesktop.application.Action;
|
|||||||
import org.jdesktop.application.ResourceMap;
|
import org.jdesktop.application.ResourceMap;
|
||||||
import org.jdesktop.application.SingleFrameApplication;
|
import org.jdesktop.application.SingleFrameApplication;
|
||||||
import org.jdesktop.application.FrameView;
|
import org.jdesktop.application.FrameView;
|
||||||
import sun.security.jca.GetInstance;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The application's main frame.
|
* The application's main frame.
|
||||||
@ -129,11 +129,11 @@ ChangeListener {
|
|||||||
mainPanel.addMouseMotionListener(this);
|
mainPanel.addMouseMotionListener(this);
|
||||||
|
|
||||||
currentTaskLabel.setFont(currentTaskLabel.getFont().deriveFont(currentTaskLabel.getFont().getStyle() | java.awt.Font.BOLD, currentTaskLabel.getFont().getSize()+2));
|
currentTaskLabel.setFont(currentTaskLabel.getFont().deriveFont(currentTaskLabel.getFont().getStyle() | java.awt.Font.BOLD, currentTaskLabel.getFont().getSize()+2));
|
||||||
org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(jdbernard.timestamper.TimeStamperApp.class).getContext().getResourceMap(TimeStamperView.class);
|
org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(jdbernard.timestamper.gui.TimeStamperApp.class).getContext().getResourceMap(TimeStamperView.class);
|
||||||
currentTaskLabel.setText(resourceMap.getString("currentTaskLabel.text")); // NOI18N
|
currentTaskLabel.setText(resourceMap.getString("currentTaskLabel.text")); // NOI18N
|
||||||
currentTaskLabel.setName("currentTaskLabel"); // NOI18N
|
currentTaskLabel.setName("currentTaskLabel"); // NOI18N
|
||||||
|
|
||||||
javax.swing.ActionMap actionMap = org.jdesktop.application.Application.getInstance(jdbernard.timestamper.TimeStamperApp.class).getContext().getActionMap(TimeStamperView.class, this);
|
javax.swing.ActionMap actionMap = org.jdesktop.application.Application.getInstance(jdbernard.timestamper.gui.TimeStamperApp.class).getContext().getActionMap(TimeStamperView.class, this);
|
||||||
exitButton.setAction(actionMap.get("quit")); // NOI18N
|
exitButton.setAction(actionMap.get("quit")); // NOI18N
|
||||||
exitButton.setBorder(null);
|
exitButton.setBorder(null);
|
||||||
exitButton.setContentAreaFilled(false);
|
exitButton.setContentAreaFilled(false);
|
||||||
@ -269,7 +269,8 @@ ChangeListener {
|
|||||||
|
|
||||||
private void taskTextFieldKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_taskTextFieldKeyReleased
|
private void taskTextFieldKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_taskTextFieldKeyReleased
|
||||||
if (evt.getKeyCode() == KeyEvent.VK_ENTER) {
|
if (evt.getKeyCode() == KeyEvent.VK_ENTER) {
|
||||||
Timeline t = ((TimeStamperApp) getApplication()).getActiveTimeline();
|
Timeline t = ((TimeStamperApp) getApplication())
|
||||||
|
.getTimelineProperties().getTimeline();
|
||||||
Date d = new Date();
|
Date d = new Date();
|
||||||
t.addMarker(d, taskTextField.getText(), "No comments.");
|
t.addMarker(d, taskTextField.getText(), "No comments.");
|
||||||
startTimeLabel.setText(Timeline.shortFormat.format(d));
|
startTimeLabel.setText(Timeline.shortFormat.format(d));
|
||||||
@ -312,8 +313,9 @@ ChangeListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setNotesForActiveTask(String notes) {
|
public void setNotesForActiveTask(String notes) {
|
||||||
Timeline t = ((TimeStamperApp) getApplication()).getActiveTimeline();
|
Timeline t = ((TimeStamperApp) getApplication())
|
||||||
Timeline.TimelineMarker tm = t.getLastMarker(new Date());
|
.getTimelineProperties().getTimeline();
|
||||||
|
TimelineMarker tm = t.getLastMarker(new Date());
|
||||||
if (tm == null) return;
|
if (tm == null) return;
|
||||||
tm.setNotes(notes);
|
tm.setNotes(notes);
|
||||||
}
|
}
|
||||||
@ -472,7 +474,7 @@ ChangeListener {
|
|||||||
|
|
||||||
@Action
|
@Action
|
||||||
public void saveTimeline() {
|
public void saveTimeline() {
|
||||||
((TimeStamperApp) getApplication()).saveTimeline();
|
((TimeStamperApp) getApplication()).saveTimelineProperties();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Action
|
@Action
|
||||||
@ -480,8 +482,8 @@ ChangeListener {
|
|||||||
if (fileChooser.showSaveDialog(getFrame())!=JFileChooser.APPROVE_OPTION)
|
if (fileChooser.showSaveDialog(getFrame())!=JFileChooser.APPROVE_OPTION)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
((TimeStamperApp) getApplication()).saveTimelineToFile(
|
((TimeStamperApp) getApplication()).saveTimelinePropertiesAs(
|
||||||
fileChooser.getSelectedFile().getAbsolutePath());
|
fileChooser.getSelectedFile());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Action
|
@Action
|
||||||
@ -489,15 +491,16 @@ ChangeListener {
|
|||||||
if (fileChooser.showOpenDialog(getFrame())!=JFileChooser.APPROVE_OPTION)
|
if (fileChooser.showOpenDialog(getFrame())!=JFileChooser.APPROVE_OPTION)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
((TimeStamperApp) getApplication()).loadTimeline(
|
((TimeStamperApp) getApplication()).loadTimelineProperties(
|
||||||
fileChooser.getSelectedFile().getAbsolutePath());
|
fileChooser.getSelectedFile().getAbsolutePath());
|
||||||
|
|
||||||
fireChangeEvent();
|
fireChangeEvent();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void refreshDialog() {
|
public void refreshDialog() {
|
||||||
Timeline t = ((TimeStamperApp) getApplication()).getActiveTimeline();
|
Timeline t = ((TimeStamperApp) getApplication())
|
||||||
Timeline.TimelineMarker lastMarker = t.getLastMarker(new Date());
|
.getTimelineProperties().getTimeline();
|
||||||
|
TimelineMarker lastMarker = t.getLastMarker(new Date());
|
||||||
|
|
||||||
if (lastMarker != null) {
|
if (lastMarker != null) {
|
||||||
mostRecentTask = lastMarker.getTimestamp();
|
mostRecentTask = lastMarker.getTimestamp();
|
25
src/jdbernard/timestamper/TimelineDayDisplay.java → src/jdbernard/timestamper/gui/TimelineDayDisplay.java
Executable file → Normal file
25
src/jdbernard/timestamper/TimelineDayDisplay.java → src/jdbernard/timestamper/gui/TimelineDayDisplay.java
Executable file → Normal file
@ -2,8 +2,10 @@
|
|||||||
* Author: Jonathan Bernard - jonathan.bernard@gemalto.com
|
* Author: Jonathan Bernard - jonathan.bernard@gemalto.com
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package jdbernard.timestamper;
|
package jdbernard.timestamper.gui;
|
||||||
|
|
||||||
|
import jdbernard.timestamper.core.TimelineMarker;
|
||||||
|
import jdbernard.timestamper.core.Timeline;
|
||||||
import java.awt.BasicStroke;
|
import java.awt.BasicStroke;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Font;
|
import java.awt.Font;
|
||||||
@ -31,7 +33,7 @@ public class TimelineDayDisplay extends JComponent implements MouseListener,
|
|||||||
ChangeListener {
|
ChangeListener {
|
||||||
|
|
||||||
private class MarkerDisplayEntry {
|
private class MarkerDisplayEntry {
|
||||||
public Timeline.TimelineMarker marker;
|
public TimelineMarker marker;
|
||||||
public float relY;
|
public float relY;
|
||||||
public float relHeight;
|
public float relHeight;
|
||||||
public Rectangle2D markBounds;
|
public Rectangle2D markBounds;
|
||||||
@ -186,7 +188,7 @@ public class TimelineDayDisplay extends JComponent implements MouseListener,
|
|||||||
|
|
||||||
private ArrayList<MarkerDisplayEntry> markerEntries;
|
private ArrayList<MarkerDisplayEntry> markerEntries;
|
||||||
private ArrayList<TimeLegendEntry> timeLegendLocations;
|
private ArrayList<TimeLegendEntry> timeLegendLocations;
|
||||||
private Timeline.TimelineMarker currentMarker;
|
private TimelineMarker currentMarker;
|
||||||
private ArrayList<ChangeListener> changeListeners = new ArrayList<ChangeListener>();
|
private ArrayList<ChangeListener> changeListeners = new ArrayList<ChangeListener>();
|
||||||
|
|
||||||
private Point lastMousePress;
|
private Point lastMousePress;
|
||||||
@ -318,18 +320,20 @@ public class TimelineDayDisplay extends JComponent implements MouseListener,
|
|||||||
return selectedOpaque;
|
return selectedOpaque;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Timeline.TimelineMarker getSelectedTimelineMarker() {
|
public TimelineMarker getSelectedTimelineMarker() {
|
||||||
return currentMarker;
|
return currentMarker;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addMarker(Date timestamp, String mark, String notes) {
|
public void addMarker(Date timestamp, String mark, String notes) {
|
||||||
Timeline timeline = TimeStamperApp.getApplication().getActiveTimeline();
|
Timeline timeline = TimeStamperApp.getApplication()
|
||||||
|
.getTimelineProperties().getTimeline();
|
||||||
timeline.addMarker(timestamp, mark, notes);
|
timeline.addMarker(timestamp, mark, notes);
|
||||||
updateMarkers(getGraphics());
|
updateMarkers(getGraphics());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void deleteSelectedMarker() {
|
public void deleteSelectedMarker() {
|
||||||
Timeline timeline = TimeStamperApp.getApplication().getActiveTimeline();
|
Timeline timeline = TimeStamperApp.getApplication()
|
||||||
|
.getTimelineProperties().getTimeline();
|
||||||
timeline.removeMarker(currentMarker);
|
timeline.removeMarker(currentMarker);
|
||||||
updateMarkers(getGraphics());
|
updateMarkers(getGraphics());
|
||||||
}
|
}
|
||||||
@ -348,7 +352,8 @@ public class TimelineDayDisplay extends JComponent implements MouseListener,
|
|||||||
*/
|
*/
|
||||||
private void updateMarkers(Graphics g) {
|
private void updateMarkers(Graphics g) {
|
||||||
|
|
||||||
Timeline timeline = TimeStamperApp.getApplication().getActiveTimeline();
|
Timeline timeline = TimeStamperApp.getApplication()
|
||||||
|
.getTimelineProperties().getTimeline();
|
||||||
Insets insets = this.getInsets();
|
Insets insets = this.getInsets();
|
||||||
Rectangle bounds = this.getBounds();
|
Rectangle bounds = this.getBounds();
|
||||||
Rectangle canvasBounds = new Rectangle(insets.left, insets.top,
|
Rectangle canvasBounds = new Rectangle(insets.left, insets.top,
|
||||||
@ -396,7 +401,7 @@ public class TimelineDayDisplay extends JComponent implements MouseListener,
|
|||||||
|
|
||||||
// get all relevant markers starting from the marker just before the
|
// get all relevant markers starting from the marker just before the
|
||||||
// visible start of the display
|
// visible start of the display
|
||||||
Timeline.TimelineMarker tm = timeline.getLastMarker(rangeStartDate);
|
TimelineMarker tm = timeline.getLastMarker(rangeStartDate);
|
||||||
|
|
||||||
// If there is no previous marker
|
// If there is no previous marker
|
||||||
if (tm == null)
|
if (tm == null)
|
||||||
@ -408,11 +413,11 @@ public class TimelineDayDisplay extends JComponent implements MouseListener,
|
|||||||
|
|
||||||
// Now we want to step through the timeline, capturing all markers
|
// Now we want to step through the timeline, capturing all markers
|
||||||
// between the visible ranges.
|
// between the visible ranges.
|
||||||
Iterator<Timeline.TimelineMarker> itr = timeline.iterator();
|
Iterator<TimelineMarker> itr = timeline.iterator();
|
||||||
|
|
||||||
while (!itr.next().equals(tm));
|
while (!itr.next().equals(tm));
|
||||||
|
|
||||||
ArrayList<Timeline.TimelineMarker> markers = new ArrayList<Timeline.TimelineMarker>();
|
ArrayList<TimelineMarker> markers = new ArrayList<TimelineMarker>();
|
||||||
while (rangeEndDate.after(tm.getTimestamp())) {
|
while (rangeEndDate.after(tm.getTimestamp())) {
|
||||||
markers.add(tm);
|
markers.add(tm);
|
||||||
if (itr.hasNext()) tm = itr.next();
|
if (itr.hasNext()) tm = itr.next();
|
0
src/jdbernard/timestamper/resources/AboutDialog.properties → src/jdbernard/timestamper/gui/resources/AboutDialog.properties
Executable file → Normal file
0
src/jdbernard/timestamper/resources/AboutDialog.properties → src/jdbernard/timestamper/gui/resources/AboutDialog.properties
Executable file → Normal file
0
src/jdbernard/timestamper/resources/NotesDialog.properties → src/jdbernard/timestamper/gui/resources/NotesDialog.properties
Executable file → Normal file
0
src/jdbernard/timestamper/resources/NotesDialog.properties → src/jdbernard/timestamper/gui/resources/NotesDialog.properties
Executable file → Normal file
@ -0,0 +1,42 @@
|
|||||||
|
markTextField.text=
|
||||||
|
previousWeek.Action.text=<<
|
||||||
|
previousWeek.Action.shortDescription=Go back one week.
|
||||||
|
dateLabel.text=date
|
||||||
|
#NOI18N
|
||||||
|
dateLabel.background=255, 255, 153
|
||||||
|
prevWeekButton.text=jButton1
|
||||||
|
previousWeek.Action.icon=icons/media-seek-backward.png
|
||||||
|
previousWeek.Action.smallIcon=icons/media-seek-backward.png
|
||||||
|
prevDayButton.text=jButton1
|
||||||
|
previousDay.Action.smallIcon=icons/media-playback-reverse.png
|
||||||
|
previousDay.Action.icon=icons/media-playback-reverse.png
|
||||||
|
previousDay.Action.shortDescription=Go back one day.
|
||||||
|
previousDay.Action.text=Previous Day
|
||||||
|
currentDay.Action.text=Today
|
||||||
|
currentDay.Action.shortDescription=Go to today's date.
|
||||||
|
jButton2.text=jButton2
|
||||||
|
nextDay.Action.smallIcon=icons/media-playback-start.png
|
||||||
|
nextDay.Action.icon=icons/media-playback-start.png
|
||||||
|
nextDay.Action.shortDescription=Go one day forward.
|
||||||
|
nextDay.Action.text=Next Day
|
||||||
|
nextWeekButton.text=jButton3
|
||||||
|
nextWeek.Action.text=Next Week
|
||||||
|
nextWeek.Action.smallIcon=icons/media-seek-forward.png
|
||||||
|
nextWeek.Action.icon=icons/media-seek-forward.png
|
||||||
|
nextWeek.Action.shortDescription=Go one week forward.
|
||||||
|
newMarkerButton.text=jButton1
|
||||||
|
newMarker.Action.smallIcon=icons/16-square-green-add.png
|
||||||
|
newMarker.Action.icon=icons/16-square-green-add.png
|
||||||
|
newMarker.Action.shortDescription=Create a new timestamp mark.
|
||||||
|
newMarker.Action.text=New Marker
|
||||||
|
deleteMarkerButton.text=jButton1
|
||||||
|
deleteMarker.Action.text=Delete Marker
|
||||||
|
deleteMarker.Action.shortDescription=Delete a timestamp mark.
|
||||||
|
deleteMarker.Action.smallIcon=icons/16-square-red-delete.png
|
||||||
|
deleteMarker.Action.icon=icons/16-square-red-delete.png
|
||||||
|
saveMarkerChanges.text=jButton1
|
||||||
|
saveMarkerChanges.Action.smallIcon=icons/document-save-16x16.png
|
||||||
|
saveMarkerChanges.Action.icon=icons/document-save-16x16.png
|
||||||
|
saveMarkerChanges.Action.shortDescription=Save timeline marker changes.
|
||||||
|
saveMarkerChanges.Action.text=Save Changes
|
||||||
|
timestampDateChooser.dateFormatString=MMM d, yyyy HH:mm
|
@ -9,9 +9,9 @@ Application.description = Simple application used to track activities throughout
|
|||||||
Application.vendorId = Jonathan Bernard
|
Application.vendorId = Jonathan Bernard
|
||||||
Application.id = TimeStamper
|
Application.id = TimeStamper
|
||||||
Application.lookAndFeel = system
|
Application.lookAndFeel = system
|
||||||
Application.icon=/jdbernard/timestamper/resources/icons/appointment-new-32x32.png
|
Application.icon=icons/appointment-new-32x32.png
|
||||||
quit.Action.text=Exit
|
quit.Action.text=Exit
|
||||||
quit.Action.accelerator=ctrl pressed Q
|
quit.Action.accelerator=ctrl pressed Q
|
||||||
quit.Action.smallIcon=/jdbernard/timestamper/resources/icons/16-em-cross.png
|
quit.Action.smallIcon=icons/16-em-cross.png
|
||||||
quit.Action.icon=/jdbernard/timestamper/resources/icons/16-em-cross.png
|
quit.Action.icon=icons/16-em-cross.png
|
||||||
quit.Action.shortDescription=Exit the application
|
quit.Action.shortDescription=Exit the application
|
28
src/jdbernard/timestamper/resources/TimeStamperView.properties → src/jdbernard/timestamper/gui/resources/TimeStamperView.properties
Executable file → Normal file
28
src/jdbernard/timestamper/resources/TimeStamperView.properties → src/jdbernard/timestamper/gui/resources/TimeStamperView.properties
Executable file → Normal file
@ -14,36 +14,36 @@ totalTimeNow.text=3day 2hr 50min 25sec
|
|||||||
#NOI18N
|
#NOI18N
|
||||||
totalTimeNow.foreground=0, 153, 0
|
totalTimeNow.foreground=0, 153, 0
|
||||||
notesButton.text=jButton1
|
notesButton.text=jButton1
|
||||||
editNotes.Action.smallIcon=/jdbernard/timestamper/resources/icons/16-em-pencil.png
|
editNotes.Action.smallIcon=icons/16-em-pencil.png
|
||||||
editNotes.Action.icon=/jdbernard/timestamper/resources/icons/16-em-pencil.png
|
editNotes.Action.icon=icons/16-em-pencil.png
|
||||||
editNotes.Action.shortDescription=Edit notes for this task
|
editNotes.Action.shortDescription=Edit notes for this task
|
||||||
editNotes.Action.text=Show Notes...
|
editNotes.Action.text=Show Notes...
|
||||||
jButton1.text=
|
jButton1.text=
|
||||||
showOptionsMenu.Action.text=Options menu
|
showOptionsMenu.Action.text=Options menu
|
||||||
showOptionsMenu.Action.shortDescription=Show the application's options menu.
|
showOptionsMenu.Action.shortDescription=Show the application's options menu.
|
||||||
showOptionsMenu.Action.smallIcon=/jdbernard/timestamper/resources/icons/16-tool-a.png
|
showOptionsMenu.Action.smallIcon=icons/16-tool-a.png
|
||||||
showOptionsMenu.Action.icon=/jdbernard/timestamper/resources/icons/16-tool-a.png
|
showOptionsMenu.Action.icon=icons/16-tool-a.png
|
||||||
saveTimelineMenuItem.text=Item
|
saveTimelineMenuItem.text=Item
|
||||||
saveTimeline.Action.text=Save Timeline...
|
saveTimeline.Action.text=Save Timeline...
|
||||||
saveTimeline.Action.smallIcon=/jdbernard/timestamper/resources/icons/document-save-16x16.png
|
saveTimeline.Action.smallIcon=icons/document-save-16x16.png
|
||||||
saveTimeline.Action.icon=/jdbernard/timestamper/resources/icons/document-save-16x16.png
|
saveTimeline.Action.icon=icons/document-save-16x16.png
|
||||||
saveTimeline.Action.shortDescription=Save all actions to a timeline file.
|
saveTimeline.Action.shortDescription=Save all actions to a timeline file.
|
||||||
saveTimelineAs.Action.smallIcon=/jdbernard/timestamper/resources/icons/document-save-as-16x16.png
|
saveTimelineAs.Action.smallIcon=icons/document-save-as-16x16.png
|
||||||
saveTimelineAs.Action.icon=/jdbernard/timestamper/resources/icons/document-save-as-16x16.png
|
saveTimelineAs.Action.icon=icons/document-save-as-16x16.png
|
||||||
saveTimelineAs.Action.shortDescription=Save actions to a new timeline file.
|
saveTimelineAs.Action.shortDescription=Save actions to a new timeline file.
|
||||||
saveTimelineAs.Action.text=Save Timeline As...
|
saveTimelineAs.Action.text=Save Timeline As...
|
||||||
loadTimelineMenuItem.text=Item
|
loadTimelineMenuItem.text=Item
|
||||||
loadTimeline.Action.text=Load Timeline...
|
loadTimeline.Action.text=Load Timeline...
|
||||||
loadTimeline.Action.shortDescription=Load a set of actions from a timeline file
|
loadTimeline.Action.shortDescription=Load a set of actions from a timeline file
|
||||||
loadTimeline.Action.smallIcon=/jdbernard/timestamper/resources/icons/document-open-16x16.png
|
loadTimeline.Action.smallIcon=icons/document-open-16x16.png
|
||||||
loadTimeline.Action.icon=/jdbernard/timestamper/resources/icons/document-open-16x16.png
|
loadTimeline.Action.icon=icons/document-open-16x16.png
|
||||||
currentTimeLabel.text=12:00:00
|
currentTimeLabel.text=12:00:00
|
||||||
#NOI18N
|
#NOI18N
|
||||||
currentTimeLabel.foreground=204, 0, 0
|
currentTimeLabel.foreground=204, 0, 0
|
||||||
exit.Action.text=Exit
|
exit.Action.text=Exit
|
||||||
exit.Action.smallIcon=/jdbernard/timestamper/resources/icons/16-em-cross.png
|
exit.Action.smallIcon=icons/16-em-cross.png
|
||||||
exit.Action.shortDescription=Close the application.
|
exit.Action.shortDescription=Close the application.
|
||||||
exit.Action.icon=/jdbernard/timestamper/resources/icons/16-em-cross.png
|
exit.Action.icon=icons/16-em-cross.png
|
||||||
notesButton2.text=jToggleButton1
|
notesButton2.text=jToggleButton1
|
||||||
#NOI18N
|
#NOI18N
|
||||||
optionsButton.rolloverIcon=icons/16-tool-a-hover.png
|
optionsButton.rolloverIcon=icons/16-tool-a-hover.png
|
||||||
@ -53,8 +53,8 @@ showNotesDialogCheckBoxMenuItem.text=CheckBox
|
|||||||
showPunchcardCheckBoxMenuItem.text=CheckBox
|
showPunchcardCheckBoxMenuItem.text=CheckBox
|
||||||
showPunchcard.Action.shortDescription=View the timeline
|
showPunchcard.Action.shortDescription=View the timeline
|
||||||
showPunchcard.Action.text=Show Timeline...
|
showPunchcard.Action.text=Show Timeline...
|
||||||
showPunchcard.Action.smallIcon=/jdbernard/timestamper/resources/icons/16-file-archive.png
|
showPunchcard.Action.smallIcon=icons/16-file-archive.png
|
||||||
showPunchcard.Action.icon=/jdbernard/timestamper/resources/icons/16-file-archive.png
|
showPunchcard.Action.icon=icons/16-file-archive.png
|
||||||
editNotes.Action.accelerator=ctrl pressed N
|
editNotes.Action.accelerator=ctrl pressed N
|
||||||
showPunchcard.Action.accelerator=ctrl pressed T
|
showPunchcard.Action.accelerator=ctrl pressed T
|
||||||
showAboutCheckBoxMenuItem.text=CheckBox
|
showAboutCheckBoxMenuItem.text=CheckBox
|
@ -1,42 +0,0 @@
|
|||||||
markTextField.text=
|
|
||||||
previousWeek.Action.text=<<
|
|
||||||
previousWeek.Action.shortDescription=Go back one week.
|
|
||||||
dateLabel.text=date
|
|
||||||
#NOI18N
|
|
||||||
dateLabel.background=255, 255, 153
|
|
||||||
prevWeekButton.text=jButton1
|
|
||||||
previousWeek.Action.icon=/jdbernard/timestamper/resources/icons/media-seek-backward.png
|
|
||||||
previousWeek.Action.smallIcon=/jdbernard/timestamper/resources/icons/media-seek-backward.png
|
|
||||||
prevDayButton.text=jButton1
|
|
||||||
previousDay.Action.smallIcon=/jdbernard/timestamper/resources/icons/media-playback-reverse.png
|
|
||||||
previousDay.Action.icon=/jdbernard/timestamper/resources/icons/media-playback-reverse.png
|
|
||||||
previousDay.Action.shortDescription=Go back one day.
|
|
||||||
previousDay.Action.text=Previous Day
|
|
||||||
currentDay.Action.text=Today
|
|
||||||
currentDay.Action.shortDescription=Go to today's date.
|
|
||||||
jButton2.text=jButton2
|
|
||||||
nextDay.Action.smallIcon=/jdbernard/timestamper/resources/icons/media-playback-start.png
|
|
||||||
nextDay.Action.icon=/jdbernard/timestamper/resources/icons/media-playback-start.png
|
|
||||||
nextDay.Action.shortDescription=Go one day forward.
|
|
||||||
nextDay.Action.text=Next Day
|
|
||||||
nextWeekButton.text=jButton3
|
|
||||||
nextWeek.Action.text=Next Week
|
|
||||||
nextWeek.Action.smallIcon=/jdbernard/timestamper/resources/icons/media-seek-forward.png
|
|
||||||
nextWeek.Action.icon=/jdbernard/timestamper/resources/icons/media-seek-forward.png
|
|
||||||
nextWeek.Action.shortDescription=Go one week forward.
|
|
||||||
newMarkerButton.text=jButton1
|
|
||||||
newMarker.Action.smallIcon=/jdbernard/timestamper/resources/icons/16-square-green-add.png
|
|
||||||
newMarker.Action.icon=/jdbernard/timestamper/resources/icons/16-square-green-add.png
|
|
||||||
newMarker.Action.shortDescription=Create a new timestamp mark.
|
|
||||||
newMarker.Action.text=New Marker
|
|
||||||
deleteMarkerButton.text=jButton1
|
|
||||||
deleteMarker.Action.text=Delete Marker
|
|
||||||
deleteMarker.Action.shortDescription=Delete a timestamp mark.
|
|
||||||
deleteMarker.Action.smallIcon=/jdbernard/timestamper/resources/icons/16-square-red-delete.png
|
|
||||||
deleteMarker.Action.icon=/jdbernard/timestamper/resources/icons/16-square-red-delete.png
|
|
||||||
saveMarkerChanges.text=jButton1
|
|
||||||
saveMarkerChanges.Action.smallIcon=/jdbernard/timestamper/resources/icons/document-save-16x16.png
|
|
||||||
saveMarkerChanges.Action.icon=/jdbernard/timestamper/resources/icons/document-save-16x16.png
|
|
||||||
saveMarkerChanges.Action.shortDescription=Save timeline marker changes.
|
|
||||||
saveMarkerChanges.Action.text=Save Changes
|
|
||||||
timestampDateChooser.dateFormatString=MMM d, yyyy HH:mm
|
|
Loading…
x
Reference in New Issue
Block a user