From 8d74a5a25907253d2bf71da140eb0794ac87a8e6 Mon Sep 17 00:00:00 2001
From: Jonathan Bernard <jdbernard@gmail.com>
Date: Sun, 19 Oct 2008 19:00:34 -0500
Subject: [PATCH] Added about dialog, bug fixes Fixed edge cases in
 TimelineDayDisplay (first/last/no markers) Fixed bug in
 PunchcardDisplayDialog - timeline not changed when loaded.

committer: Jonathan Bernard <jdbernard@gmail.com>
---
 nbproject/private/private.xml                 |   8 +
 nbproject/project.properties                  |   2 +-
 src/jdbernard/timestamper/AboutDialog.form    | 180 +++++++++++++++++
 src/jdbernard/timestamper/AboutDialog.java    | 185 ++++++++++++++++++
 .../timestamper/PunchcardDisplayDialog.form   |   2 +
 .../timestamper/PunchcardDisplayDialog.java   |  11 ++
 .../timestamper/TimeStamperView.form          |  13 ++
 .../timestamper/TimeStamperView.java          |  24 +++
 .../timestamper/TimelineDayDisplay.java       |  14 +-
 .../resources/AboutDialog.properties          |   5 +
 .../resources/TimeStamperApp.properties       |   4 +-
 .../resources/TimeStamperView.properties      |   9 +-
 .../resources/icons/24-message-info.png       | Bin 0 -> 746 bytes
 .../resources/icons/appointment-new-32x32.png | Bin 0 -> 2399 bytes
 14 files changed, 449 insertions(+), 8 deletions(-)
 create mode 100755 src/jdbernard/timestamper/AboutDialog.form
 create mode 100755 src/jdbernard/timestamper/AboutDialog.java
 create mode 100755 src/jdbernard/timestamper/resources/AboutDialog.properties
 create mode 100755 src/jdbernard/timestamper/resources/icons/24-message-info.png
 create mode 100644 src/jdbernard/timestamper/resources/icons/appointment-new-32x32.png

diff --git a/nbproject/private/private.xml b/nbproject/private/private.xml
index c1f155a..0940f1c 100755
--- a/nbproject/private/private.xml
+++ b/nbproject/private/private.xml
@@ -1,4 +1,12 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <project-private xmlns="http://www.netbeans.org/ns/project-private/1">
     <editor-bookmarks xmlns="http://www.netbeans.org/ns/editor-bookmarks/1"/>
+    <open-files xmlns="http://www.netbeans.org/ns/projectui-open-files/1">
+        <file>file:/C:/Documents%20and%20Settings/jbernard/My%20Documents/Development/TimeStamper/src/jdbernard/timestamper/AboutDialog.java</file>
+        <file>file:/C:/Documents%20and%20Settings/jbernard/My%20Documents/Development/TimeStamper/src/jdbernard/timestamper/PunchcardDisplayDialog.java</file>
+        <file>file:/C:/Documents%20and%20Settings/jbernard/My%20Documents/Development/TimeStamper/src/jdbernard/timestamper/TimeStamperApp.java</file>
+        <file>file:/C:/Documents%20and%20Settings/jbernard/My%20Documents/Development/TimeStamper/src/jdbernard/timestamper/TimeStamperView.java</file>
+        <file>file:/C:/Documents%20and%20Settings/jbernard/My%20Documents/Development/TimeStamper/src/jdbernard/timestamper/Timeline.java</file>
+        <file>file:/C:/Documents%20and%20Settings/jbernard/My%20Documents/Development/TimeStamper/src/jdbernard/timestamper/TimelineDayDisplay.java</file>
+    </open-files>
 </project-private>
diff --git a/nbproject/project.properties b/nbproject/project.properties
index 10359c7..2c2089c 100755
--- a/nbproject/project.properties
+++ b/nbproject/project.properties
@@ -2,7 +2,7 @@ application.desc=Simple application used to track activities throughout time.
 application.homepage=
 application.title=TimeStamper
 application.vendor=Jonathan Bernard
-application.version=1.4
+application.version=1.5
 build.classes.dir=${build.dir}/classes
 build.classes.excludes=**/*.java,**/*.form
 # This directory is removed when the project is cleaned:
diff --git a/src/jdbernard/timestamper/AboutDialog.form b/src/jdbernard/timestamper/AboutDialog.form
new file mode 100755
index 0000000..7889d96
--- /dev/null
+++ b/src/jdbernard/timestamper/AboutDialog.form
@@ -0,0 +1,180 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<Form version="1.5" maxVersion="1.6" type="org.netbeans.modules.form.forminfo.JDialogFormInfo">
+  <Properties>
+    <Property name="defaultCloseOperation" type="int" value="2"/>
+    <Property name="name" type="java.lang.String" value="Form" noResource="true"/>
+    <Property name="undecorated" type="boolean" value="true"/>
+  </Properties>
+  <SyntheticProperties>
+    <SyntheticProperty name="formSizePolicy" type="int" value="1"/>
+  </SyntheticProperties>
+  <AuxValues>
+    <AuxValue name="FormSettings_autoResourcing" type="java.lang.Integer" value="2"/>
+    <AuxValue name="FormSettings_autoSetComponentName" type="java.lang.Boolean" value="true"/>
+    <AuxValue name="FormSettings_generateMnemonicsCode" 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_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
+    <AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
+    <AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
+  </AuxValues>
+
+  <Layout>
+    <DimensionLayout dim="0">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Component id="aboutPanel" alignment="0" max="32767" attributes="0"/>
+      </Group>
+    </DimensionLayout>
+    <DimensionLayout dim="1">
+      <Group type="103" groupAlignment="0" attributes="0">
+          <Component id="aboutPanel" alignment="0" max="32767" attributes="0"/>
+      </Group>
+    </DimensionLayout>
+  </Layout>
+  <SubComponents>
+    <Container class="javax.swing.JPanel" name="aboutPanel">
+      <Properties>
+        <Property name="border" type="javax.swing.border.Border" editor="org.netbeans.modules.form.editors2.BorderEditor">
+          <Border info="org.netbeans.modules.form.compat2.border.LineBorderInfo">
+            <LineBorder thickness="2"/>
+          </Border>
+        </Property>
+        <Property name="name" type="java.lang.String" value="aboutPanel" noResource="true"/>
+      </Properties>
+      <Events>
+        <EventHandler event="mousePressed" listener="java.awt.event.MouseListener" parameters="java.awt.event.MouseEvent" handler="aboutPanelMousePressed"/>
+      </Events>
+      <AuxValues>
+        <AuxValue name="JavaCodeGenerator_ListenersCodePost" type="java.lang.String" value="aboutPanel.addMouseMotionListener(this);"/>
+      </AuxValues>
+
+      <Layout>
+        <DimensionLayout dim="0">
+          <Group type="103" groupAlignment="0" attributes="0">
+              <Group type="102" attributes="0">
+                  <EmptySpace max="-2" attributes="0"/>
+                  <Group type="103" groupAlignment="0" attributes="0">
+                      <Group type="102" alignment="0" attributes="0">
+                          <Component id="iconLabel" min="-2" max="-2" attributes="0"/>
+                          <EmptySpace max="-2" attributes="0"/>
+                          <Component id="nameLabel" min="-2" max="-2" attributes="0"/>
+                      </Group>
+                      <Group type="102" alignment="0" attributes="0">
+                          <EmptySpace min="10" pref="10" max="10" attributes="0"/>
+                          <Group type="103" groupAlignment="0" attributes="0">
+                              <Group type="102" alignment="0" attributes="0">
+                                  <Component id="versionLabel" min="-2" max="-2" attributes="0"/>
+                                  <EmptySpace max="-2" attributes="0"/>
+                                  <Component id="versionValueLabel" min="-2" max="-2" attributes="0"/>
+                              </Group>
+                              <Group type="102" alignment="0" attributes="0">
+                                  <Component id="authorLabel" min="-2" max="-2" attributes="0"/>
+                                  <EmptySpace type="separate" max="-2" attributes="0"/>
+                                  <Component id="websiteLabel" min="-2" max="-2" attributes="0"/>
+                              </Group>
+                          </Group>
+                      </Group>
+                  </Group>
+                  <EmptySpace max="32767" attributes="0"/>
+              </Group>
+          </Group>
+        </DimensionLayout>
+        <DimensionLayout dim="1">
+          <Group type="103" groupAlignment="0" attributes="0">
+              <Group type="102" attributes="0">
+                  <EmptySpace max="-2" attributes="0"/>
+                  <Group type="103" groupAlignment="0" max="-2" attributes="0">
+                      <Component id="nameLabel" max="32767" attributes="1"/>
+                      <Component id="iconLabel" alignment="0" max="32767" attributes="1"/>
+                  </Group>
+                  <EmptySpace max="-2" attributes="0"/>
+                  <Group type="103" groupAlignment="0" attributes="0">
+                      <Group type="102" attributes="0">
+                          <Component id="authorLabel" min="-2" max="-2" attributes="0"/>
+                          <EmptySpace max="-2" attributes="0"/>
+                          <Group type="103" groupAlignment="3" attributes="0">
+                              <Component id="versionLabel" alignment="3" min="-2" max="-2" attributes="0"/>
+                              <Component id="versionValueLabel" alignment="3" min="-2" max="-2" attributes="0"/>
+                          </Group>
+                      </Group>
+                      <Component id="websiteLabel" min="-2" max="-2" attributes="0"/>
+                  </Group>
+                  <EmptySpace max="32767" attributes="0"/>
+              </Group>
+          </Group>
+        </DimensionLayout>
+      </Layout>
+      <SubComponents>
+        <Component class="javax.swing.JLabel" name="iconLabel">
+          <Properties>
+            <Property name="icon" type="javax.swing.Icon" resourceKey="iconLabel.icon"/>
+            <Property name="text" type="java.lang.String" resourceKey="iconLabel.text"/>
+            <Property name="name" type="java.lang.String" value="iconLabel" noResource="true"/>
+          </Properties>
+        </Component>
+        <Component class="javax.swing.JLabel" name="nameLabel">
+          <Properties>
+            <Property name="font" type="java.awt.Font" noResource="true" editor="org.netbeans.modules.form.editors2.FontEditor">
+              <FontInfo relative="true">
+                <Font bold="true" component="nameLabel" property="font" relativeSize="true" size="5"/>
+              </FontInfo>
+            </Property>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="jdbernard/timestamper/resources/TimeStamperApp.properties" key="Application.name" replaceFormat="java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)"/>
+            </Property>
+            <Property name="name" type="java.lang.String" value="nameLabel" noResource="true"/>
+          </Properties>
+        </Component>
+        <Component class="javax.swing.JLabel" name="authorLabel">
+          <Properties>
+            <Property name="font" type="java.awt.Font" noResource="true" editor="org.netbeans.modules.form.editors2.FontEditor">
+              <FontInfo relative="true">
+                <Font component="authorLabel" property="font" relativeSize="true" size="1"/>
+              </FontInfo>
+            </Property>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="jdbernard/timestamper/resources/TimeStamperApp.properties" key="Application.vendor" replaceFormat="java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)"/>
+            </Property>
+            <Property name="name" type="java.lang.String" value="authorLabel" noResource="true"/>
+          </Properties>
+        </Component>
+        <Component class="javax.swing.JLabel" name="versionLabel">
+          <Properties>
+            <Property name="font" type="java.awt.Font" noResource="true" editor="org.netbeans.modules.form.editors2.FontEditor">
+              <FontInfo relative="true">
+                <Font component="versionLabel" property="font" relativeSize="true" size="1"/>
+              </FontInfo>
+            </Property>
+            <Property name="text" type="java.lang.String" resourceKey="versionLabel.text"/>
+            <Property name="name" type="java.lang.String" value="versionLabel" noResource="true"/>
+          </Properties>
+        </Component>
+        <Component class="javax.swing.JLabel" name="versionValueLabel">
+          <Properties>
+            <Property name="font" type="java.awt.Font" noResource="true" editor="org.netbeans.modules.form.editors2.FontEditor">
+              <FontInfo relative="true">
+                <Font component="versionValueLabel" property="font" relativeSize="true" size="1"/>
+              </FontInfo>
+            </Property>
+            <Property name="text" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
+              <ResourceString bundle="jdbernard/timestamper/resources/TimeStamperApp.properties" key="Application.version" replaceFormat="java.util.ResourceBundle.getBundle(&quot;{bundleNameSlashes}&quot;).getString(&quot;{key}&quot;)"/>
+            </Property>
+            <Property name="name" type="java.lang.String" value="versionValueLabel" noResource="true"/>
+          </Properties>
+        </Component>
+        <Component class="javax.swing.JLabel" name="websiteLabel">
+          <Properties>
+            <Property name="font" type="java.awt.Font" noResource="true" editor="org.netbeans.modules.form.editors2.FontEditor">
+              <FontInfo relative="true">
+                <Font component="websiteLabel" property="font" relativeSize="true" size="1"/>
+              </FontInfo>
+            </Property>
+            <Property name="text" type="java.lang.String" resourceKey="websiteLabel.text"/>
+            <Property name="name" type="java.lang.String" value="websiteLabel" noResource="true"/>
+          </Properties>
+        </Component>
+      </SubComponents>
+    </Container>
+  </SubComponents>
+</Form>
diff --git a/src/jdbernard/timestamper/AboutDialog.java b/src/jdbernard/timestamper/AboutDialog.java
new file mode 100755
index 0000000..30c63c6
--- /dev/null
+++ b/src/jdbernard/timestamper/AboutDialog.java
@@ -0,0 +1,185 @@
+/*
+ * AboutDialog.java
+ *
+ * Created on October 19, 2008, 3:14 PM
+ */
+
+package jdbernard.timestamper;
+
+import java.awt.Frame;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.Toolkit;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseMotionListener;
+import javax.swing.JDialog;
+
+/**
+ *
+ * @author  jbernard
+ */
+public class AboutDialog extends JDialog implements MouseMotionListener {
+
+    /** Creates new form AboutDialog */
+    public AboutDialog(Frame parent, boolean modal) {
+        super(parent, modal);
+        initComponents();
+    }
+
+    /** This method is called from within the constructor to
+     * initialize the form.
+     * WARNING: Do NOT modify this code. The content of this method is
+     * always regenerated by the Form Editor.
+     */
+    @SuppressWarnings("unchecked")
+    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
+    private void initComponents() {
+
+        aboutPanel = new javax.swing.JPanel();
+        iconLabel = new javax.swing.JLabel();
+        nameLabel = new javax.swing.JLabel();
+        authorLabel = new javax.swing.JLabel();
+        versionLabel = new javax.swing.JLabel();
+        versionValueLabel = new javax.swing.JLabel();
+        websiteLabel = new javax.swing.JLabel();
+
+        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
+        setName("Form"); // NOI18N
+        setUndecorated(true);
+
+        aboutPanel.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(0, 0, 0), 2));
+        aboutPanel.setName("aboutPanel"); // NOI18N
+        aboutPanel.addMouseListener(new java.awt.event.MouseAdapter() {
+            public void mousePressed(java.awt.event.MouseEvent evt) {
+                aboutPanelMousePressed(evt);
+            }
+        });
+        aboutPanel.addMouseMotionListener(this);
+
+        org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(jdbernard.timestamper.TimeStamperApp.class).getContext().getResourceMap(AboutDialog.class);
+        iconLabel.setIcon(resourceMap.getIcon("iconLabel.icon")); // NOI18N
+        iconLabel.setText(resourceMap.getString("iconLabel.text")); // NOI18N
+        iconLabel.setName("iconLabel"); // NOI18N
+
+        nameLabel.setFont(nameLabel.getFont().deriveFont(nameLabel.getFont().getStyle() | java.awt.Font.BOLD, nameLabel.getFont().getSize()+5));
+        java.util.ResourceBundle bundle = java.util.ResourceBundle.getBundle("jdbernard/timestamper/resources/TimeStamperApp"); // NOI18N
+        nameLabel.setText(bundle.getString("Application.name")); // NOI18N
+        nameLabel.setName("nameLabel"); // NOI18N
+
+        authorLabel.setFont(authorLabel.getFont().deriveFont(authorLabel.getFont().getSize()+1f));
+        authorLabel.setText(bundle.getString("Application.vendor")); // NOI18N
+        authorLabel.setName("authorLabel"); // NOI18N
+
+        versionLabel.setFont(versionLabel.getFont().deriveFont(versionLabel.getFont().getSize()+1f));
+        versionLabel.setText(resourceMap.getString("versionLabel.text")); // NOI18N
+        versionLabel.setName("versionLabel"); // NOI18N
+
+        versionValueLabel.setFont(versionValueLabel.getFont().deriveFont(versionValueLabel.getFont().getSize()+1f));
+        versionValueLabel.setText(bundle.getString("Application.version")); // NOI18N
+        versionValueLabel.setName("versionValueLabel"); // NOI18N
+
+        websiteLabel.setFont(websiteLabel.getFont().deriveFont(websiteLabel.getFont().getSize()+1f));
+        websiteLabel.setText(resourceMap.getString("websiteLabel.text")); // NOI18N
+        websiteLabel.setName("websiteLabel"); // NOI18N
+
+        javax.swing.GroupLayout aboutPanelLayout = new javax.swing.GroupLayout(aboutPanel);
+        aboutPanel.setLayout(aboutPanelLayout);
+        aboutPanelLayout.setHorizontalGroup(
+            aboutPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(aboutPanelLayout.createSequentialGroup()
+                .addContainerGap()
+                .addGroup(aboutPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                    .addGroup(aboutPanelLayout.createSequentialGroup()
+                        .addComponent(iconLabel)
+                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                        .addComponent(nameLabel))
+                    .addGroup(aboutPanelLayout.createSequentialGroup()
+                        .addGap(10, 10, 10)
+                        .addGroup(aboutPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                            .addGroup(aboutPanelLayout.createSequentialGroup()
+                                .addComponent(versionLabel)
+                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                                .addComponent(versionValueLabel))
+                            .addGroup(aboutPanelLayout.createSequentialGroup()
+                                .addComponent(authorLabel)
+                                .addGap(18, 18, 18)
+                                .addComponent(websiteLabel)))))
+                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+        );
+        aboutPanelLayout.setVerticalGroup(
+            aboutPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addGroup(aboutPanelLayout.createSequentialGroup()
+                .addContainerGap()
+                .addGroup(aboutPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
+                    .addComponent(nameLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+                    .addComponent(iconLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                .addGroup(aboutPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+                    .addGroup(aboutPanelLayout.createSequentialGroup()
+                        .addComponent(authorLabel)
+                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
+                        .addGroup(aboutPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
+                            .addComponent(versionLabel)
+                            .addComponent(versionValueLabel)))
+                    .addComponent(websiteLabel))
+                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
+        );
+
+        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
+        getContentPane().setLayout(layout);
+        layout.setHorizontalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addComponent(aboutPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+        );
+        layout.setVerticalGroup(
+            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
+            .addComponent(aboutPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
+        );
+
+        pack();
+    }// </editor-fold>//GEN-END:initComponents
+
+private void aboutPanelMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_aboutPanelMousePressed
+    mousePressRelativeToWindow = evt.getPoint();//GEN-LAST:event_aboutPanelMousePressed
+}
+
+    /**
+    * @param args the command line arguments
+    */
+    public static void main(String args[]) {
+        java.awt.EventQueue.invokeLater(new Runnable() {
+            public void run() {
+                AboutDialog dialog = new AboutDialog(new javax.swing.JFrame(), true);
+                dialog.addWindowListener(new java.awt.event.WindowAdapter() {
+                    public void windowClosing(java.awt.event.WindowEvent e) {
+                        System.exit(0);
+                    }
+                });
+                dialog.setVisible(true);
+            }
+        });
+    }
+
+    // Variables declaration - do not modify//GEN-BEGIN:variables
+    private javax.swing.JPanel aboutPanel;
+    private javax.swing.JLabel authorLabel;
+    private javax.swing.JLabel iconLabel;
+    private javax.swing.JLabel nameLabel;
+    private javax.swing.JLabel versionLabel;
+    private javax.swing.JLabel versionValueLabel;
+    private javax.swing.JLabel websiteLabel;
+    // End of variables declaration//GEN-END:variables
+
+    private Point mousePressRelativeToWindow;
+
+    public void mouseDragged(MouseEvent e) {
+        setLocation(TimeStamperView.calculateWindowMovement(
+                e.getLocationOnScreen(),
+                mousePressRelativeToWindow, getBounds(),
+                new Rectangle(Toolkit.getDefaultToolkit().getScreenSize())));
+    }
+
+    public void mouseMoved(MouseEvent e) {
+    }
+
+}
diff --git a/src/jdbernard/timestamper/PunchcardDisplayDialog.form b/src/jdbernard/timestamper/PunchcardDisplayDialog.form
index fb11481..c36814b 100755
--- a/src/jdbernard/timestamper/PunchcardDisplayDialog.form
+++ b/src/jdbernard/timestamper/PunchcardDisplayDialog.form
@@ -174,7 +174,9 @@
                     <Component class="javax.swing.JTextArea" name="notesTextArea">
                       <Properties>
                         <Property name="columns" type="int" value="20"/>
+                        <Property name="lineWrap" type="boolean" value="true"/>
                         <Property name="rows" type="int" value="5"/>
+                        <Property name="wrapStyleWord" type="boolean" value="true"/>
                         <Property name="name" type="java.lang.String" value="notesTextArea" noResource="true"/>
                       </Properties>
                     </Component>
diff --git a/src/jdbernard/timestamper/PunchcardDisplayDialog.java b/src/jdbernard/timestamper/PunchcardDisplayDialog.java
index f438f45..a5a966a 100755
--- a/src/jdbernard/timestamper/PunchcardDisplayDialog.java
+++ b/src/jdbernard/timestamper/PunchcardDisplayDialog.java
@@ -110,7 +110,9 @@ implements MouseMotionListener, ChangeListener {
         notesScrollPane.setName("notesScrollPane"); // NOI18N
 
         notesTextArea.setColumns(20);
+        notesTextArea.setLineWrap(true);
         notesTextArea.setRows(5);
+        notesTextArea.setWrapStyleWord(true);
         notesTextArea.setName("notesTextArea"); // NOI18N
         notesScrollPane.setViewportView(notesTextArea);
 
@@ -294,6 +296,15 @@ private void mainPanelMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:e
     mousePressRelativeToWindow = evt.getPoint();
 }//GEN-LAST:event_mainPanelMousePressed
 
+    public void setTimeline(Timeline t) {
+        timeline = t;
+        dayDisplay.setTimeline(t);
+    }
+
+    public Timeline getTimeline() {
+        return timeline;
+    }
+
     /**
     * @param args the command line arguments
     */
diff --git a/src/jdbernard/timestamper/TimeStamperView.form b/src/jdbernard/timestamper/TimeStamperView.form
index b4d2ebd..af864aa 100755
--- a/src/jdbernard/timestamper/TimeStamperView.form
+++ b/src/jdbernard/timestamper/TimeStamperView.form
@@ -243,6 +243,19 @@
             <Property name="name" type="java.lang.String" value="showPunchcardCheckBoxMenuItem" noResource="true"/>
           </Properties>
         </MenuItem>
+        <Component class="javax.swing.JSeparator" name="seperator2">
+          <Properties>
+            <Property name="name" type="java.lang.String" value="seperator2" noResource="true"/>
+          </Properties>
+        </Component>
+        <MenuItem class="javax.swing.JCheckBoxMenuItem" name="showAboutCheckBoxMenuItem">
+          <Properties>
+            <Property name="action" type="javax.swing.Action" editor="org.netbeans.modules.swingapp.ActionEditor">
+              <action class="jdbernard.timestamper.TimeStamperView" id="showAboutDialog" methodName="showAboutDialog"/>
+            </Property>
+            <Property name="name" type="java.lang.String" value="showAboutCheckBoxMenuItem" noResource="true"/>
+          </Properties>
+        </MenuItem>
       </SubComponents>
     </Container>
   </NonVisualComponents>
diff --git a/src/jdbernard/timestamper/TimeStamperView.java b/src/jdbernard/timestamper/TimeStamperView.java
index 07f18c3..d5f1c81 100755
--- a/src/jdbernard/timestamper/TimeStamperView.java
+++ b/src/jdbernard/timestamper/TimeStamperView.java
@@ -42,6 +42,7 @@ public class TimeStamperView extends FrameView implements MouseMotionListener {
 
         fileChooser = new JFileChooser();
         notesDialog = new NotesDialog(this, false);
+        aboutDialog = new AboutDialog(this.getFrame(), false);
 
         updateTimer = new Timer();
         updateTimer.scheduleAtFixedRate(new TimerTask() {
@@ -103,6 +104,8 @@ public class TimeStamperView extends FrameView implements MouseMotionListener {
         seperator1 = new javax.swing.JSeparator();
         showNotesDialogCheckBoxMenuItem = new javax.swing.JCheckBoxMenuItem();
         showPunchcardCheckBoxMenuItem = new javax.swing.JCheckBoxMenuItem();
+        seperator2 = new javax.swing.JSeparator();
+        showAboutCheckBoxMenuItem = new javax.swing.JCheckBoxMenuItem();
 
         mainPanel.setBorder(javax.swing.BorderFactory.createMatteBorder(2, 2, 2, 2, new java.awt.Color(0, 0, 0)));
         mainPanel.setName("mainPanel"); // NOI18N
@@ -242,6 +245,13 @@ public class TimeStamperView extends FrameView implements MouseMotionListener {
         showPunchcardCheckBoxMenuItem.setName("showPunchcardCheckBoxMenuItem"); // NOI18N
         optionsMenu.add(showPunchcardCheckBoxMenuItem);
 
+        seperator2.setName("seperator2"); // NOI18N
+        optionsMenu.add(seperator2);
+
+        showAboutCheckBoxMenuItem.setAction(actionMap.get("showAboutDialog")); // NOI18N
+        showAboutCheckBoxMenuItem.setName("showAboutCheckBoxMenuItem"); // NOI18N
+        optionsMenu.add(showAboutCheckBoxMenuItem);
+
         setComponent(mainPanel);
     }// </editor-fold>//GEN-END:initComponents
 
@@ -281,6 +291,13 @@ public class TimeStamperView extends FrameView implements MouseMotionListener {
         getPunchcardDisplayDialog().setVisible(punchcardVisible);
     }
 
+    @Action
+    public void showAboutDialog() {
+        aboutDialogVisible = !aboutDialogVisible;
+        showAboutCheckBoxMenuItem.setSelected(aboutDialogVisible);
+        aboutDialog.setVisible(aboutDialogVisible);
+    }
+
     public void setNotesForActiveTask(String notes) {
         Timeline t = ((TimeStamperApp) getApplication()).getActiveTimeline();
         Timeline.TimelineMarker tm = t.getLastMarker(new Date());
@@ -300,6 +317,8 @@ public class TimeStamperView extends FrameView implements MouseMotionListener {
     private javax.swing.JMenuItem saveTimelineAsMenuItem;
     private javax.swing.JMenuItem saveTimelineMenuItem;
     private javax.swing.JSeparator seperator1;
+    private javax.swing.JSeparator seperator2;
+    private javax.swing.JCheckBoxMenuItem showAboutCheckBoxMenuItem;
     private javax.swing.JCheckBoxMenuItem showNotesDialogCheckBoxMenuItem;
     private javax.swing.JCheckBoxMenuItem showPunchcardCheckBoxMenuItem;
     private javax.swing.JLabel startTimeLabel;
@@ -315,8 +334,10 @@ public class TimeStamperView extends FrameView implements MouseMotionListener {
     private Date mostRecentTask;
     private NotesDialog notesDialog;
     private PunchcardDisplayDialog punchcardDisplayDialog;
+    private AboutDialog aboutDialog;
     private boolean notesVisible = false;
     private boolean punchcardVisible = false;
+    private boolean aboutDialogVisible = false;
 
     private PunchcardDisplayDialog getPunchcardDisplayDialog() {
         if (punchcardDisplayDialog == null) {
@@ -442,6 +463,9 @@ public class TimeStamperView extends FrameView implements MouseMotionListener {
         Timeline t = ((TimeStamperApp) getApplication()).getActiveTimeline();
         Timeline.TimelineMarker lastMarker = t.getLastMarker(new Date());
 
+        if (punchcardDisplayDialog != null)
+            punchcardDisplayDialog.setTimeline(t);
+
         if (lastMarker != null) {
             mostRecentTask = lastMarker.getTimestamp();
             startTimeLabel.setText(Timeline.shortFormat.format(lastMarker.getTimestamp()));
diff --git a/src/jdbernard/timestamper/TimelineDayDisplay.java b/src/jdbernard/timestamper/TimelineDayDisplay.java
index 58b8621..6d34631 100755
--- a/src/jdbernard/timestamper/TimelineDayDisplay.java
+++ b/src/jdbernard/timestamper/TimelineDayDisplay.java
@@ -178,6 +178,10 @@ public class TimelineDayDisplay extends JComponent implements MouseListener {
 
         // get all relevant markers
         Timeline.TimelineMarker tm = timeline.getLastMarker(day.getTime());
+        if (tm == null)
+            try { tm = timeline.iterator().next(); }
+            catch (Exception e) { return; }
+
         Iterator<Timeline.TimelineMarker> itr = timeline.iterator();
 
         while (!itr.next().equals(tm));
@@ -203,7 +207,7 @@ public class TimelineDayDisplay extends JComponent implements MouseListener {
                     .getStringBounds(markers.get(i).getNotes(), g);
 
             // calculate upper bound
-            if (i == 0) {
+            if ((i == 0) && day.getTime().after(markerEntry.marker.getTimestamp())) {
                 markerEntry.relY = 0;
             } else {
                 // calculate time in ms since the beginning of the day
@@ -214,7 +218,7 @@ public class TimelineDayDisplay extends JComponent implements MouseListener {
             }
 
             // calculate lower bound
-            if (i == 0)
+            if ((i == 0) && day.getTime().after(markerEntry.marker.getTimestamp()))
                 markerEntry.relHeight =
                         markers.get(i + 1).getTimestamp().getTime()
                         - day.getTimeInMillis();
@@ -229,6 +233,7 @@ public class TimelineDayDisplay extends JComponent implements MouseListener {
 
             markerEntries.add(markerEntry);
         }
+        repaint();
     }
 
     @Override
@@ -348,12 +353,15 @@ public class TimelineDayDisplay extends JComponent implements MouseListener {
         for (MarkerDisplayEntry markerEntry : markerEntries) {
             Rectangle absBounds = new Rectangle(markerEntry.bounds);
             absBounds.translate(topLeft.x, topLeft.y);
+
+            // should only match one entry
             if (absBounds.contains(e.getLocationOnScreen())) {
                 currentMarker = markerEntry.marker;
                 repaint();
+                fireChangeEvent();
+                break;
             }
         }
-        fireChangeEvent();
     }
 
     public void mousePressed(MouseEvent e) {
diff --git a/src/jdbernard/timestamper/resources/AboutDialog.properties b/src/jdbernard/timestamper/resources/AboutDialog.properties
new file mode 100755
index 0000000..26207c9
--- /dev/null
+++ b/src/jdbernard/timestamper/resources/AboutDialog.properties
@@ -0,0 +1,5 @@
+iconLabel.text=
+#NOI18N
+iconLabel.icon=icons/appointment-new-32x32.png
+versionLabel.text=Version
+websiteLabel.text=www.jdbernard.com
diff --git a/src/jdbernard/timestamper/resources/TimeStamperApp.properties b/src/jdbernard/timestamper/resources/TimeStamperApp.properties
index d7e5dd5..32b4d51 100755
--- a/src/jdbernard/timestamper/resources/TimeStamperApp.properties
+++ b/src/jdbernard/timestamper/resources/TimeStamperApp.properties
@@ -2,14 +2,14 @@
 
 Application.name = TimeStamper
 Application.title = TimeStamper
-Application.version = 1.4
+Application.version = 1.5
 Application.vendor = Jonathan Bernard
 Application.homepage =
 Application.description = Simple application used to track activities throughout time.
 Application.vendorId = Jonathan Bernard
 Application.id = TimeStamper
 Application.lookAndFeel = system
-Application.icon=/jdbernard/timestamper/resources/icons/appointment-new-16x16.png
+Application.icon=/jdbernard/timestamper/resources/icons/appointment-new-32x32.png
 quit.Action.text=Exit
 quit.Action.accelerator=ctrl pressed Q
 quit.Action.smallIcon=/jdbernard/timestamper/resources/icons/16-em-cross.png
diff --git a/src/jdbernard/timestamper/resources/TimeStamperView.properties b/src/jdbernard/timestamper/resources/TimeStamperView.properties
index e4829c7..d816a1e 100755
--- a/src/jdbernard/timestamper/resources/TimeStamperView.properties
+++ b/src/jdbernard/timestamper/resources/TimeStamperView.properties
@@ -17,7 +17,7 @@ notesButton.text=jButton1
 editNotes.Action.smallIcon=/jdbernard/timestamper/resources/icons/16-em-pencil.png
 editNotes.Action.icon=/jdbernard/timestamper/resources/icons/16-em-pencil.png
 editNotes.Action.shortDescription=Edit notes for this task
-editNotes.Action.text=Show Notes
+editNotes.Action.text=Show Notes...
 jButton1.text=
 showOptionsMenu.Action.text=Options menu
 showOptionsMenu.Action.shortDescription=Show the application's options menu.
@@ -52,6 +52,11 @@ exitButton.rolloverIcon=icons/16-em-cross-hover.png
 showNotesDialogCheckBoxMenuItem.text=CheckBox
 showPunchcardCheckBoxMenuItem.text=CheckBox
 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.icon=/jdbernard/timestamper/resources/icons/16-file-archive.png
+editNotes.Action.accelerator=ctrl pressed N
+showPunchcard.Action.accelerator=ctrl pressed T
+showAboutCheckBoxMenuItem.text=CheckBox
+showAboutDialog.Action.shortDescription=
+showAboutDialog.Action.text=About...
diff --git a/src/jdbernard/timestamper/resources/icons/24-message-info.png b/src/jdbernard/timestamper/resources/icons/24-message-info.png
new file mode 100755
index 0000000000000000000000000000000000000000..78cee3060319174cbdf1c1cdbe79887b054cd4b3
GIT binary patch
literal 746
zcmV<G0u}v<P)<h;3K|Lk000e1NJLTq000;O000;W1^@s6;CDUv0000PbVXQnQ*UN;
zcVTj606}DLVr3vnZDD6+Qe|Oed2z{QJOBU!j7da6RCwCdmCI`rQ543%dnd`HS`BH&
zwuw|)8&Qf68c|VjAqwqU@PBcacIW?6a9zQT8^MSRHzi^Vm4I#Ya8T0bHFL*%?#&Fb
znar%Ra7e;r=6v7p+;i@Od7g)9UK~@t5~F|K?Y<ogs5EntLwsnp*!gE0n=iuwVaBB!
z1#CVjLjCbkOntEXc^{SU`e_(wB7n@-i+Q}bUxbi7>JEf@?)Qr^?e%Q^I-ZwS@&1bh
z?ZXR$B*M(^t>*Fc?g~zOt^$zn$GsY=wWf->wPfMR+7gJv<qyRQ8B;kJhlGyc@$F@_
zrMcsJ3LvDK%wNBHq~5>T`Gh+wi{P9oK*C^3^Y!2;x<r)y+VTS0T^BuB76MRNL`a+4
zT_MeNxd>n;J&?9?2ya8TD0~E^o7ZIajsgr^0e_j~t&Gatzd!9e!+rosgJU4L((WCe
zME9W67wE|Hbo#CYX!jq-4K(aO|CFe3#R}3)8bX%QfWcV&ETYWM2+|h;VAOmx5d;7x
z=PFa6SU~l-jh}W8_Sry<g05MfQdy5eK74Bh_cJL2*$YV&vS$2NVbILr&<*q(D$)~I
zGR06VX-FFjpoY<qHHgJ;W?aXThP1JOdi@0Hq@jWpB!WTjv^iHA(nbR0D%`HOY-DB<
zxRf?jZ4*OKSSjfp#ZWA1NJ}13P2Q5<@^8C|xyv~nAdP4}IF1>t1BaQoXzEdt`P^&@
zq#5y;Jc}rUN(1G*ykE>(GDAmhcC;oka<1zblk2HTWueT;{HXD3Ec;1&(UuGZK}a;8
z%i`+%f*OT8+%x>TQ_ZV2J4oz&_EG17g6RDTWvXq&fwLV}n%D!!7x<vKxQXlJzd!V+
c4)`m;08siH#jLRQ>i_@%07*qoM6N<$g5%F*N&o-=

literal 0
HcmV?d00001

diff --git a/src/jdbernard/timestamper/resources/icons/appointment-new-32x32.png b/src/jdbernard/timestamper/resources/icons/appointment-new-32x32.png
new file mode 100644
index 0000000000000000000000000000000000000000..85daef3b0b519c8d4fe6cc1efc1c67e660e0f8e9
GIT binary patch
literal 2399
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
RQpNxP002ovPDHLkV1kVygbx4!

literal 0
HcmV?d00001